From 73990d676839b7d09313f3ce28768668a0158acc Mon Sep 17 00:00:00 2001 From: adlopp Date: Tue, 25 Aug 2026 16:52:34 +0200 Subject: [PATCH] Fix FRLG RoamingLegendaryRng: leave_pokecenter() never actually exits travel_from_celio_to_kanto() sends a single 1280ms left-hold before calling leave_pokecenter(), assuming the game is immediately controllable right after activate_roamer()'s dialogue finishes. In practice (confirmed via testing, including on Spanish game text) the character never even attempts to turn left -- it goes straight into leave_pokecenter()'s blind "walk down" phase and misses the exit every time, eventually throwing "Failed to exit PokeCenter." Root cause: a leftover dialogue box from activate_roamer() blocks movement input until dismissed with A. Idle waiting (tested up to 30s) does not help since it never closes the dialogue; blindly mashing A does have an effect, confirming the game is responsive, but risks re-triggering a fresh conversation with Celio if no dialogue is actually left. Fix: - Check via screenshot whether a dialogue box is present before moving, and press A only once if so, re-checking after each single press (never pressing blind). - Move left in 5 discrete steps instead of one continuous hold, so a single dropped input doesn't eat the whole movement. Not RNG-sensitive: this all happens after activate_roamer() has already fixed the roamer's PID, so the extra checks/time here do not affect the RNG result. --- .../PokemonFRLG_RngNavigation.cpp | 38 ++++++++++++++++++- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngNavigation.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngNavigation.cpp index 9ed2ad7711..603b54f394 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngNavigation.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngNavigation.cpp @@ -345,8 +345,42 @@ void hatch_daycare_egg(ConsoleHandle& console, ProControllerContext& context){ void travel_from_celio_to_kanto(ConsoleHandle& console, ProControllerContext& context){ - // assumes the player is standing on Celio's left (west) side - pbf_move_left_joystick(context, {-1, 0}, 1280ms, 300ms); + // assumes the player is standing on Celio's left (west) side. + // + // Confirmed by testing: the character never even turns left -- it goes + // straight into the "walk down" phase of leave_pokecenter(). Blind waiting + // (tried up to 30s) does not fix it, but blindly mashing A does have an + // effect (it re-opens Celio's dialogue), proving the game is responsive + // and a leftover dialogue box is the blocker, not an unresponsive game. + // So: check via screenshot whether a dialogue box is actually on screen, + // and only press A once if so, re-checking after each single press. + // Never press A when no dialogue is detected, to avoid re-triggering a + // fresh conversation with Celio. + { + WhiteDialogDetector dialog_detector(COLOR_RED); + bool cleared = false; + for (int attempts = 0; attempts < 10; attempts++){ + context.wait_for_all_requests(); + VideoSnapshot screen = console.video().snapshot(); + if (!dialog_detector.detect(screen)){ + cleared = true; + break; + } + pbf_press_button(context, BUTTON_A, 200ms, 800ms); + } + if (!cleared){ + console.log("travel_from_celio_to_kanto(): Dialogue box did not clear after 10 checks. Continuing anyway.", COLOR_RED); + } + context.wait_for_all_requests(); + } + // 5 discrete steps left (matches manual testing), instead of one continuous + // hold, so a single dropped input doesn't eat the whole movement. + // 400ms/step measured as ~9 tiles for 5 iterations; scaled down to land on + // ~5 tiles for 5 iterations (400 * 5/9 ~= 220ms). + for (int i = 0; i < 5; i++){ + pbf_move_left_joystick(context, {-1, 0}, 220ms, 200ms); + } + context.wait_for_all_requests(); leave_pokecenter(console, context); // walk down to the One Island sign WhiteDialogWatcher dialog_detected(COLOR_RED);