Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
43ac578
FRLG: watch for wild battles only on steps where one can start
dayfine Nov 1, 2026
f11a566
FRLG: never plan a hold into a sign moving north or south
dayfine Nov 1, 2026
d1afca9
Merge frlg/mvp (20291b6c8, #117) into frlg/walk-wild-legs
dayfine Nov 1, 2026
4f23edf
Merge frlg/mvp (b2e6af2de, #117) into frlg/walk-wild-legs
dayfine Nov 1, 2026
e60819a
FRLG: run the overworld route tests on maps compiled into the program
dayfine Nov 1, 2026
876c201
Merge frlg/mvp (9a8924bb8, #117) into frlg/walk-wild-legs
dayfine Nov 1, 2026
b3c7414
FRLG: count a leg's grass on every map it crosses
dayfine Nov 1, 2026
bf5618e
FRLG: never plan a hold into a ledge
dayfine Nov 1, 2026
b8db754
FRLG: wait out a late-seen battle after each leg through grass
dayfine Nov 1, 2026
1797366
FRLG: tell a warp's fade from a wild battle's, by its battle screen
dayfine Nov 1, 2026
b284191
Merge frlg/mvp (a31833dd4, #117) into frlg/walk-wild-legs
dayfine Nov 1, 2026
365aff4
Merge frlg/mvp (165e9075b, #117) into frlg/walk-wild-legs
dayfine Nov 1, 2026
910c460
FRLG: the overworld maps as .json files in the repo, built into the p…
dayfine Nov 1, 2026
6fb5b39
FRLG: route tests read the built-in .json maps; drop the generated C+…
dayfine Nov 1, 2026
42d7e0a
FRLG: the program loads the overworld maps built in from Overworld/Maps
dayfine Nov 1, 2026
bdc7814
Merge frlg/mvp (e5136bffc, #117) into frlg/walk-wild-legs
dayfine Nov 1, 2026
91b12a2
FRLG: regenerate the overworld maps without all-ground elevation grids
dayfine Nov 1, 2026
79420ed
Merge frlg/mvp (1195b1be3) into frlg/walk-wild-legs
dayfine Nov 1, 2026
0319629
Merge frlg/mvp (bbc9ae2fa) into frlg/walk-wild-legs
dayfine Nov 1, 2026
e5de4f5
Merge frlg/mvp (878f88461) into frlg/walk-wild-legs
dayfine Nov 1, 2026
fd25e04
Merge frlg/mvp (2172b9e4f, #117: maps and planner; the walker moves h…
dayfine Nov 1, 2026
65c8324
Merge frlg/mvp (32acef6b2) into frlg/walk-wild-legs
dayfine Nov 1, 2026
07bccca
Merge frlg/mvp (a6c81dada) into frlg/walk-wild-legs
dayfine Nov 1, 2026
6b85581
Merge frlg/mvp (232d71833) into frlg/walk-wild-legs
dayfine Nov 1, 2026
85fea60
FRLG walker: the D-pad mover as a function; the facing read on its own
dayfine Nov 1, 2026
e77925f
Merge frlg/mvp (dc99cf1c9) into frlg/walk-wild-legs
dayfine Nov 1, 2026
4741f0e
Merge frlg/mvp (82c740faf, #117: maps in the shared Pokemon::MapData …
dayfine Nov 2, 2026
11371dc
Merge frlg/mvp (#117: route wall holds moved from #119) into frlg/wal…
dayfine Nov 2, 2026
79b0377
FRLG walker: expose its steps and timings in OverworldWalkSteps
dayfine Nov 2, 2026
a280449
Merge origin/frlg/mvp into frlg/walk-wild-legs
dayfine Nov 2, 2026
c7ef69e
FRLG walker: a run speed, B held with the D-pad
dayfine Nov 2, 2026
f801b23
FRLG walker tests: no bool-parameter helper
dayfine Nov 2, 2026
b2e7d13
Merge frlg/mvp into frlg/walk-wild-legs
dayfine Nov 2, 2026
d6c7cb3
Merge branch 'frlg/mvp' into frlg/walk-wild-legs
dayfine Nov 3, 2026
51ea454
Merge branch 'frlg/mvp' into frlg/walk-wild-legs
dayfine Nov 3, 2026
2070951
Merge frlg/mvp (#117) into frlg/walk-wild-legs
dayfine Nov 3, 2026
9ed8ba5
FRLG walker: hand a message open before a leg to the interrupts once
dayfine Nov 3, 2026
80fb368
Merge remote-tracking branch 'origin/frlg/mvp' into HEAD
dayfine Nov 3, 2026
6e12b0c
Merge frlg/mvp (3414eafb7, #117: a stopped open leg's timing estimate…
dayfine Nov 3, 2026
4a4f671
Merge frlg/mvp (#117: verify mode from #122) into frlg/walk-wild-legs
dayfine Nov 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/* Battle Flash Watcher
*
* From: https://github.com/PokemonAutomation/
*
*/

#include <algorithm>
#include "CommonFramework/ImageTools/ImageBoxes.h"
#include "CommonFramework/ImageTools/ImageStats.h"
#include "CommonFramework/ImageTypes/ImageViewRGB32.h"
#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h"
#include "VideoGames/PokemonFRLG/PokemonFRLG_Settings.h"
#include "PokemonFRLG_BattleFlashWatcher.h"

namespace PokemonAutomation{
namespace NintendoSwitch{
namespace PokemonFRLG{

using namespace std::chrono_literals;


namespace{

// On the console a flash took the screen from 145 to 98 (two thirds) and
// back within 80ms, twice in about 300ms.
constexpr std::chrono::milliseconds FLASH_WINDOW = 400ms;
constexpr double FLASH_DARKER = 0.8; // the dip is below this much of the brightness before it
constexpr double FLASH_FLOOR = 0.4; // and above this much: lower is a fade to black
constexpr double FLASH_RECOVERY = 1.1; // then the screen comes back to this much of the dip

}


BattleFlashWatcher::BattleFlashWatcher(Color color)
: VisualInferenceCallback("BattleFlashWatcher")
, m_color(color)
{}

void BattleFlashWatcher::make_overlays(VideoOverlaySet& items) const{
items.add(m_color, GameSettings::instance().GAME_BOX);
}

bool BattleFlashWatcher::process_frame(const ImageViewRGB32& frame, WallClock timestamp){

Check warning on line 43 in SerialPrograms/Source/VideoGames/PokemonFRLG/Inference/PokemonFRLG_BattleFlashWatcher.cpp

View workflow job for this annotation

GitHub Actions / code-health

Code health (advisory)

PokemonAutomation::NintendoSwitch::PokemonFRLG::BattleFlashWatcher::process_frame( const ImageViewRGB32 & frame , WallClock timestamp): function_lines=28 (advisory above 25, limit 50)
const ImageViewRGB32 game_screen = extract_box_reference(frame, GameSettings::instance().GAME_BOX);
const double brightness = image_stats(game_screen).average.sum();
while (!m_history.empty() && timestamp - m_history.front().first > FLASH_WINDOW){
m_history.pop_front();
}

// The brightest frame before the screen first dips, and the darkest
// frame since.
double before = 0;
double dip = -1;
for (const auto& item : m_history){
if (dip < 0){
if (item.second < before * FLASH_DARKER){
dip = item.second;
}else{
before = std::max(before, item.second);
}
}else{
dip = std::min(dip, item.second);
}
}
m_history.emplace_back(timestamp, brightness);

return dip >= 0
&& dip > before * FLASH_FLOOR
&& brightness > dip * FLASH_RECOVERY;
}



}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/* Battle Flash Watcher
*
* From: https://github.com/PokemonAutomation/
*
* Every wild battle starts with the overworld flashing dark twice, within
* half a second of the step that set it off, before the battle's own wipe.
* The wipe and the battle screen differ by map and come seconds later, so
* the flash is the earliest and the same sign of a battle everywhere.
*
*/

#ifndef PokemonAutomation_PokemonFRLG_BattleFlashWatcher_H
#define PokemonAutomation_PokemonFRLG_BattleFlashWatcher_H

#include <deque>
#include <utility>
#include "Common/Cpp/Color.h"
#include "CommonTools/InferenceCallbacks/VisualInferenceCallback.h"

namespace PokemonAutomation{
namespace NintendoSwitch{
namespace PokemonFRLG{


// Fires when the game screen darkens by a fifth or more and starts to come
// back within a moment. A warp's fade, or the Switch dimming its screen,
// only darkens and so doesn't count.
class BattleFlashWatcher : public VisualInferenceCallback{
public:
BattleFlashWatcher(Color color);

virtual void make_overlays(VideoOverlaySet& items) const override;
virtual bool process_frame(const ImageViewRGB32& frame, WallClock timestamp) override;

private:
Color m_color;
// Recent brightness of the game screen.
std::deque<std::pair<WallClock, double>> m_history;
};



}
}
}
#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/* Battle Screen Detector
*
* From: https://github.com/PokemonAutomation/
*
*/

#include "PokemonFRLG_BattleScreenDetector.h"

namespace PokemonAutomation{
namespace NintendoSwitch{
namespace PokemonFRLG{


BattleScreenDetector::BattleScreenDetector(Color color)
: m_dialog(color)
, m_menu(color)
, m_opponent(color)
, m_player(color)
{}
void BattleScreenDetector::make_overlays(VideoOverlaySet& items) const{
m_dialog.make_overlays(items);
m_opponent.make_overlays(items);
m_player.make_overlays(items);
}
bool BattleScreenDetector::detect(const ImageViewRGB32& screen){
if (m_menu.detect(screen)){
return true;
}
return m_dialog.detect(screen) && (m_opponent.detect(screen) || m_player.detect(screen));
}



}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/* Battle Screen Detector
*
* From: https://github.com/PokemonAutomation/
*
* A battle on screen: the battle text box, and with it the opponent's HP
* box, the player's or the battle menu. The text box alone also reads on
* the black below a small indoor map (console B, 2026-11-01: Oak's Lab's
* mat, Viridian Forest's north gate).
*
*/

#ifndef PokemonAutomation_PokemonFRLG_BattleScreenDetector_H
#define PokemonAutomation_PokemonFRLG_BattleScreenDetector_H

#include <chrono>
#include "Common/Cpp/Color.h"
#include "CommonFramework/ImageTypes/ImageViewRGB32.h"
#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h"
#include "CommonTools/VisualDetector.h"
#include "VideoGames/PokemonFRLG/Inference/Dialogs/PokemonFRLG_BattleDialogs.h"
#include "VideoGames/PokemonFRLG/Inference/PokemonFRLG_BattlePokemonDetector.h"

namespace PokemonAutomation{
namespace NintendoSwitch{
namespace PokemonFRLG{


class BattleScreenDetector : public StaticScreenDetector{
public:
BattleScreenDetector(Color color = COLOR_RED);

virtual void make_overlays(VideoOverlaySet& items) const override;
virtual bool detect(const ImageViewRGB32& screen) override;

private:
BattleDialogDetector m_dialog;
BattleMenuDetector m_menu;
BattleOpponentDetector m_opponent;
BattlePokemonDetector m_player;
};

class BattleScreenWatcher : public DetectorToFinder<BattleScreenDetector>{
public:
BattleScreenWatcher(Color color = COLOR_RED)
: DetectorToFinder("BattleScreenWatcher", std::chrono::milliseconds(250), color)
{}
};



}
}
}
#endif
Loading
Loading