From 104ead58e3afe79f01edda5f163b816876a2ba8d Mon Sep 17 00:00:00 2001 From: theAstrogoth Date: Mon, 17 Aug 2026 15:18:34 -0500 Subject: [PATCH 1/3] egg RNG pickup fix --- .../Dialogs/PokemonFRLG_DialogDetector.h | 7 +++ .../PokemonFRLG_RngNavigation.cpp | 59 +++++++++++++++++-- 2 files changed, 60 insertions(+), 6 deletions(-) diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_DialogDetector.h b/SerialPrograms/Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_DialogDetector.h index 9ba4ba069b..08f40de7f4 100644 --- a/SerialPrograms/Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_DialogDetector.h +++ b/SerialPrograms/Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_DialogDetector.h @@ -81,6 +81,13 @@ class WhiteDialogWatcher : public DetectorToFinder{ {} }; +class WhiteDialogOverWatcher : public DetectorToFinder{ +public: + WhiteDialogOverWatcher(Color color) + : DetectorToFinder("WhiteDialogOverWatcher", FinderType::GONE, std::chrono::milliseconds(250), color) + {} +}; + // Same as WhiteDialogDetector, but filter for the red arrow // Detect the red advancement arrow by filtering for DARK red. // There is red/pink color text for female npcs in non-japan versions diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngNavigation.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngNavigation.cpp index 4e3745f9be..9a85d3739e 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngNavigation.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngNavigation.cpp @@ -806,25 +806,72 @@ void walk_from_pond_to_daycare_man(ConsoleHandle& console, ProControllerContext& void egg_pickup(ConsoleHandle& console, ProControllerContext& context){ console.log("Picking up egg..."); - WhiteDialogWatcher dialogue(COLOR_RED); + + // This may be called right after saving the game, in which case the save dialogue is + // still on screen. Clear it first so that it isn't mistaken for the daycare man's dialogue. + WhiteDialogOverWatcher dialogue_cleared(COLOR_RED); context.wait_for_all_requests(); int ret = run_until( console, context, [](ProControllerContext& context) { - pbf_mash_button(context, BUTTON_A, 5000ms); + pbf_mash_button(context, BUTTON_B, 5000ms); + }, + { dialogue_cleared } + ); + if (ret < 0){ + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "egg_pickup(): Failed to clear dialogue before talking to the daycare man.", + console + ); + } + + // Talk to the daycare man and wait for the egg prompt. The selection box always appears in + // response to an A press, so press A slowly rather than mashing. That leaves enough time to + // detect the box before the next press accepts the egg. + SelectionDialogWatcher egg_prompt(COLOR_RED); + context.wait_for_all_requests(); + ret = run_until( + console, context, + [](ProControllerContext& context) { + for (int i=0; i<12; i++){ + pbf_press_button(context, BUTTON_A, 200ms, 800ms); + } }, - { dialogue } + { egg_prompt } ); if (ret < 0){ OperationFailedException::fire( ErrorReport::SEND_ERROR_REPORT, - "egg_pickup(): Failed to initiate dialogue.", + "egg_pickup(): Failed to detect the egg selection dialogue.", console ); } + console.log("Egg selection dialogue detected. Taking the egg..."); + + // accept the egg + pbf_mash_button(context, BUTTON_A, 1000ms); + + // clear the rest of the dialogue + WhiteDialogOverWatcher dialogue_over(COLOR_RED); + context.wait_for_all_requests(); + ret = run_until( + console, context, + [](ProControllerContext& context) { + pbf_mash_button(context, BUTTON_B, 10000ms); + }, + { dialogue_over } + ); + if (ret < 0){ + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "egg_pickup(): Failed to return to the overworld after taking the egg.", + console + ); + } + context.wait_for_all_requests(); - pbf_mash_button(context, BUTTON_A, 5000ms); - pbf_mash_button(context, BUTTON_B, 2500ms); + console.log("Egg picked up."); } bool walk_from_daycare_man_to_pond(ConsoleHandle& console, ProControllerContext& context){ From 1041f8b79b6f861123c2267ddd19d1b0e8e23c03 Mon Sep 17 00:00:00 2001 From: theAstrogoth Date: Mon, 17 Aug 2026 20:53:29 -0500 Subject: [PATCH 2/3] concise comments --- .../Programs/RngManipulation/PokemonFRLG_RngNavigation.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngNavigation.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngNavigation.cpp index 9a85d3739e..a52f98a9a4 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngNavigation.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngNavigation.cpp @@ -807,8 +807,7 @@ void walk_from_pond_to_daycare_man(ConsoleHandle& console, ProControllerContext& void egg_pickup(ConsoleHandle& console, ProControllerContext& context){ console.log("Picking up egg..."); - // This may be called right after saving the game, in which case the save dialogue is - // still on screen. Clear it first so that it isn't mistaken for the daycare man's dialogue. + // Clear the save dialogue, if it is open WhiteDialogOverWatcher dialogue_cleared(COLOR_RED); context.wait_for_all_requests(); int ret = run_until( @@ -826,9 +825,7 @@ void egg_pickup(ConsoleHandle& console, ProControllerContext& context){ ); } - // Talk to the daycare man and wait for the egg prompt. The selection box always appears in - // response to an A press, so press A slowly rather than mashing. That leaves enough time to - // detect the box before the next press accepts the egg. + // Talk to the daycare man and wait for the egg prompt. SelectionDialogWatcher egg_prompt(COLOR_RED); context.wait_for_all_requests(); ret = run_until( From 058f37841f82604af72b3ddb17fdea1c3a38fc8e Mon Sep 17 00:00:00 2001 From: theAstrogoth Date: Tue, 18 Aug 2026 00:54:05 -0500 Subject: [PATCH 3/3] reset starting point on held frame miss --- .../PokemonFRLG/Programs/RngManipulation/PokemonFRLG_EggRng.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_EggRng.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_EggRng.cpp index 75e23b0dbc..257575708d 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_EggRng.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_EggRng.cpp @@ -599,6 +599,7 @@ bool EggRng::held_frame_check( } if (locked_in && !(definitely_hit_held_frame || possibly_hit_held_frame)){ + STARTING_POINT.set(EggProgramState::held_prep); OperationFailedException::fire( ErrorReport::SEND_ERROR_REPORT, "EggRng(): Missed held frame after saving. Restart the program after repeating the manual in-game setup.",