From ca11cef1365ee5c19930b7904e701e3bb6f8b36c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C8=86=E2=9C=A0Sa=CD=A5b=CD=A3e=CD=ABr=F0=9F=91=91?= =?UTF-8?q?=E2=B0=80?= Date: Sun, 7 Dec 2025 14:08:34 +0800 Subject: [PATCH 1/2] FlySpotReset: add routes for alpha pikachu & alpha Patrat --- .../PokemonLZA_ShinyHunt_FlySpotReset.cpp | 97 ++++++++++++++++++- .../PokemonLZA_ShinyHunt_FlySpotReset.h | 1 + 2 files changed, 97 insertions(+), 1 deletion(-) diff --git a/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_FlySpotReset.cpp b/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_FlySpotReset.cpp index 9b0ce14e6..eddf7ab12 100644 --- a/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_FlySpotReset.cpp +++ b/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_FlySpotReset.cpp @@ -17,6 +17,7 @@ #include "Pokemon/Pokemon_Strings.h" #include "PokemonLZA/Inference/PokemonLZA_HyperspaceCalorieDetector.h" #include "PokemonLA/Inference/Sounds/PokemonLA_ShinySoundDetector.h" +#include "PokemonLZA/Inference/PokemonLZA_AlertEyeDetector.h" #include "PokemonLZA/Programs/PokemonLZA_BasicNavigation.h" #include "PokemonLZA_ShinyHunt_FlySpotReset.h" @@ -68,7 +69,8 @@ ShinyHunt_FlySpotReset::ShinyHunt_FlySpotReset() {Route::HYPERSPACE_WILD_ZONE, "hyperspace_wild_zone", "Hyperspace Wild Zone"}, {Route::WILD_ZONE_19, "wild_zone_19", "Wild Zone 19"}, {Route::ALPHA_PIDGEY, "alpha_pidgey", "Alpha Pidgey (Wild Zone 1)"}, - // {Route::ALPHA_PIKACHU, "alpha_pikachu", "Alpha Pikachu (Wild Zone 6)"}, + {Route::ALPHA_PATRAT, "alpha_patrat", "Alpha Patrat (Cafe Cyclone)"}, + {Route::ALPHA_PIKACHU, "alpha_pikachu", "Alpha Pikachu (Wild Zone 6)"}, // {Route::CUSTOMISED_MACRO, "customised_macro", "Customised Macro"}, }, LockMode::LOCK_WHILE_RUNNING, @@ -260,6 +262,93 @@ bool route_hyperspace_wild_zone( } +void route_alpha_patrat( + SingleSwitchProgramEnvironment& env, + ProControllerContext& context, + ShinyHunt_FlySpotReset_Descriptor::Stats& stats, + bool to_zoom_to_max){ + { + BlackScreenOverWatcher black_screen(COLOR_BLUE); + int ret = run_until( + env.console, context, + [](ProControllerContext& context){ + ssf_press_button(context, BUTTON_B, 0ms, 500ms, 0ms); + pbf_move_left_joystick_old(context, 0, 128, 2000ms, 0ms); + pbf_move_left_joystick_old(context, 96, 0, 3500ms, 0ms); + }, + {black_screen} + ); + if (ret == 0){ + wait_until_overworld(env.console, context, 50s); + } + } + open_map(env.console, context, to_zoom_to_max); + pbf_move_left_joystick_old(context, 128, 255, 50ms, 100ms); + if (fly_from_map(env.console, context) != FastTravelState::SUCCESS){ + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "fly_from_map(): Unable to fast travel", + env.console); + } + wait_until_overworld(env.console, context, 50s); +} + + +void route_alpha_pikachu( + SingleSwitchProgramEnvironment& env, + ProControllerContext& context, + ShinyHunt_FlySpotReset_Descriptor::Stats& stats, + bool to_zoom_to_max){ + int ret = -1; + { + BlackScreenOverWatcher black_screen(COLOR_BLUE); + ret = run_until( + env.console, context, + [&](ProControllerContext& context){ + ssf_press_button(context, BUTTON_B, 0ms, 500ms, 0ms); + pbf_move_left_joystick_old(context, 0, 128, 2000ms, 0ms); + pbf_move_left_joystick_old(context, 128, 0, 2700ms, 0ms); + pbf_move_left_joystick_old(context, 255, 128, 1000ms, 0ms); + pbf_mash_button(context, BUTTON_A, 500ms); // ladder + pbf_move_left_joystick_old(context, 128, 0, 5300ms, 0ms); + }, + {black_screen} + ); + } + if (ret == 0){ + wait_until_overworld(env.console, context, 50s); + //TODO: reset game if still get caught by wild pokémon + } + { + AlertEyeOverWatcher eye_watcher(COLOR_WHITE, &env.console.overlay()); + ret = run_until(env.console, context, [&](ProControllerContext& context){ + pbf_move_left_joystick_old(context, 255, 128, 3600ms, 0ms); + pbf_move_left_joystick_old(context, 128, 0, 3000ms, 0ms); + }, {{eye_watcher}}); + } + if (ret < 0){ + AlertEyeOverWatcher eye_watcher(COLOR_WHITE, &env.console.overlay()); + ret = wait_until(env.console, context, 30s, {{eye_watcher}}); + } + if (ret < 0){ + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "AlertEyeOverWatcher: Unable to fast travel after 30s", + env.console); + } + open_map(env.console, context, to_zoom_to_max); + pbf_move_left_joystick_old(context, 148, 20, 100ms, 200ms); + if (fly_from_map(env.console, context) == FastTravelState::SUCCESS) { + wait_until_overworld(env.console, context); + return; + } else { + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "fly_from_map(): Unable to fast travel", + env.console); + } +} + } // namespace void ShinyHunt_FlySpotReset::program(SingleSwitchProgramEnvironment& env, ProControllerContext& context){ @@ -299,6 +388,12 @@ void ShinyHunt_FlySpotReset::program(SingleSwitchProgramEnvironment& env, ProCon case Route::ALPHA_PIDGEY: route = route_alpha_pidgey; break; + case Route::ALPHA_PATRAT: + route = route_alpha_patrat; + break; + case Route::ALPHA_PIKACHU: + route = route_alpha_pikachu; + break; default: OperationFailedException::fire( ErrorReport::SEND_ERROR_REPORT, diff --git a/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_FlySpotReset.h b/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_FlySpotReset.h index 82d44da6f..9f3aeb9fc 100644 --- a/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_FlySpotReset.h +++ b/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_FlySpotReset.h @@ -40,6 +40,7 @@ class ShinyHunt_FlySpotReset : public SingleSwitchProgramInstance{ HYPERSPACE_WILD_ZONE, WILD_ZONE_19, ALPHA_PIDGEY, + ALPHA_PATRAT, ALPHA_PIKACHU, CUSTOMISED_MACRO = 255, }; From 2c72d065e5d4e178aaf4129e55f4467438aec171 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C8=86=E2=9C=A0Sa=CD=A5b=CD=A3e=CD=ABr=F0=9F=91=91?= =?UTF-8?q?=E2=B0=80?= Date: Thu, 25 Dec 2025 12:04:40 +0800 Subject: [PATCH 2/2] imporved day/night handling for pikachu route --- .../PokemonLZA_ShinyHunt_FlySpotReset.cpp | 49 +++++++++++++++---- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_FlySpotReset.cpp b/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_FlySpotReset.cpp index eddf7ab12..3054f5790 100644 --- a/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_FlySpotReset.cpp +++ b/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_FlySpotReset.cpp @@ -19,6 +19,7 @@ #include "PokemonLA/Inference/Sounds/PokemonLA_ShinySoundDetector.h" #include "PokemonLZA/Inference/PokemonLZA_AlertEyeDetector.h" #include "PokemonLZA/Programs/PokemonLZA_BasicNavigation.h" +#include "PokemonLZA/Programs/PokemonLZA_GameEntry.h" #include "PokemonLZA_ShinyHunt_FlySpotReset.h" namespace PokemonAutomation { @@ -112,9 +113,9 @@ ShinyHunt_FlySpotReset::ShinyHunt_FlySpotReset() namespace { // Return if the loop should stop -typedef std::function route_func; +typedef std::function route_func; -void route_default( +bool route_default( SingleSwitchProgramEnvironment& env, ProControllerContext& context, ShinyHunt_FlySpotReset_Descriptor::Stats& stats, @@ -145,9 +146,10 @@ void route_default( env.console ); } + return false; } -void route_wild_zone_19( +bool route_wild_zone_19( SingleSwitchProgramEnvironment& env, ProControllerContext& context, ShinyHunt_FlySpotReset_Descriptor::Stats& stats, @@ -165,9 +167,10 @@ void route_wild_zone_19( fly_from_map(env.console, context); } wait_until_overworld(env.console, context, 50s); + return false; } -void route_alpha_pidgey( +bool route_alpha_pidgey( SingleSwitchProgramEnvironment& env, ProControllerContext& context, ShinyHunt_FlySpotReset_Descriptor::Stats& stats, @@ -199,6 +202,7 @@ void route_alpha_pidgey( fly_from_map(env.console, context); } wait_until_overworld(env.console, context); + return false; } bool route_hyperspace_wild_zone( @@ -262,7 +266,7 @@ bool route_hyperspace_wild_zone( } -void route_alpha_patrat( +bool route_alpha_patrat( SingleSwitchProgramEnvironment& env, ProControllerContext& context, ShinyHunt_FlySpotReset_Descriptor::Stats& stats, @@ -291,10 +295,11 @@ void route_alpha_patrat( env.console); } wait_until_overworld(env.console, context, 50s); + return false; } -void route_alpha_pikachu( +bool route_alpha_pikachu( SingleSwitchProgramEnvironment& env, ProControllerContext& context, ShinyHunt_FlySpotReset_Descriptor::Stats& stats, @@ -317,7 +322,32 @@ void route_alpha_pikachu( } if (ret == 0){ wait_until_overworld(env.console, context, 50s); - //TODO: reset game if still get caught by wild pokémon + { + AlertEyeOverWatcher eye_watcher(COLOR_YELLOW, &env.console.overlay()); + ret = wait_until(env.console, context, 2s, {{eye_watcher}}); + } + if (ret < 0) { // still get caught by wild pokémon after day/night change + stats.errors++; + env.update_stats(); + env.add_overlay_log("Error after DNC. Reset Game", COLOR_YELLOW); + go_home(env.console, context); + reset_game_from_home(env, env.console, context); + { + BlackScreenOverWatcher black_screen(COLOR_CYAN); + ret = wait_until(env.console, context, 30s, {{black_screen}}); // wait for incoming day/night change + } + if (ret < 0) { + stats.errors++; + env.update_stats(); + env.add_overlay_log("Unable to detect DNC after reset", COLOR_RED); + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "Unable to detect day/night change after reset", + env.console); + } + wait_until_overworld(env.console, context); // wait till day/night change over + return true; // reset to_zoom_to_max + } } { AlertEyeOverWatcher eye_watcher(COLOR_WHITE, &env.console.overlay()); @@ -340,7 +370,7 @@ void route_alpha_pikachu( pbf_move_left_joystick_old(context, 148, 20, 100ms, 200ms); if (fly_from_map(env.console, context) == FastTravelState::SUCCESS) { wait_until_overworld(env.console, context); - return; + return false; } else { OperationFailedException::fire( ErrorReport::SEND_ERROR_REPORT, @@ -416,9 +446,8 @@ void ShinyHunt_FlySpotReset::program(SingleSwitchProgramEnvironment& env, ProCon if (ROUTE == Route::HYPERSPACE_WILD_ZONE){ should_stop = route_hyperspace_wild_zone(env, context, stats, to_zoom_to_max, MIN_CALORIE_REMAINING, ready_to_stop_counter); } else{ - route(env, context, stats, to_zoom_to_max); + to_zoom_to_max = route(env, context, stats, to_zoom_to_max); } - to_zoom_to_max = false; num_resets++; stats.resets++; env.update_stats();