From 0edaca82b6904471b748262c6fa1bf5a84775826 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 00:17:30 +0800 Subject: [PATCH 1/2] move wild zone 19 route to FlySpotReset --- .../PokemonLZA_ShinyHunt_FlySpotReset.cpp | 115 +++++++++++++----- .../PokemonLZA_ShinyHunt_FlySpotReset.h | 11 +- .../ShinyHunting/PokemonLZA_ShuttleRun.cpp | 34 ++---- .../ShinyHunting/PokemonLZA_ShuttleRun.h | 5 +- 4 files changed, 105 insertions(+), 60 deletions(-) diff --git a/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_FlySpotReset.cpp b/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_FlySpotReset.cpp index 594ea3ea8..f257f4a59 100644 --- a/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_FlySpotReset.cpp +++ b/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_FlySpotReset.cpp @@ -58,6 +58,17 @@ std::unique_ptr ShinyHunt_FlySpotReset_Descriptor::make_stats() co ShinyHunt_FlySpotReset::ShinyHunt_FlySpotReset() : SHINY_DETECTED("Shiny Detected", "", "2000 ms", ShinySoundDetectedAction::NOTIFY_ON_FIRST_ONLY) + , ROUTE("Hunt Route:", + { + {Route::NO_MOVEMENT, "no_movement", "No Movement"}, + {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::CUSTOMISED_MACRO, "customised_macro", "Customised Macro"}, + }, + LockMode::LOCK_WHILE_RUNNING, + Route::NO_MOVEMENT + ) , NOTIFICATION_STATUS("Status Update", true, false, std::chrono::seconds(3600)) , NOTIFICATIONS({ &NOTIFICATION_STATUS, @@ -68,10 +79,69 @@ ShinyHunt_FlySpotReset::ShinyHunt_FlySpotReset() }) { PA_ADD_STATIC(SHINY_REQUIRES_AUDIO); + PA_ADD_OPTION(ROUTE); PA_ADD_OPTION(SHINY_DETECTED); PA_ADD_OPTION(NOTIFICATIONS); } +namespace { + +typedef std::function route_func; + +void route_default( + SingleSwitchProgramEnvironment& env, + ProControllerContext& context, + ShinyHunt_FlySpotReset_Descriptor::Stats& stats, + bool to_zoom_to_max){ + // Open map + bool can_fast_travel = open_map(env.console, context, to_zoom_to_max); + if (!can_fast_travel){ + stats.errors++; + env.update_stats(); + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "FlySpotReset: Cannot open map for fast travel.", + env.console + ); + } + + // Move map cursor upwards a little bit + pbf_move_left_joystick(context, 128, 64, 100ms, 200ms); + + // Fly from map to reset spawns + FastTravelState travel_status = fly_from_map(env.console, context); + if (travel_status != FastTravelState::SUCCESS){ + stats.errors++; + env.update_stats(); + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "FlySpotReset: Cannot fast travel after moving map cursor.", + env.console + ); + } +} + +void route_wild_zone_19( + SingleSwitchProgramEnvironment& env, + ProControllerContext& context, + ShinyHunt_FlySpotReset_Descriptor::Stats& stats, + bool to_zoom_to_max){ + if (run_a_straight_path_in_overworld(env.console, context, 0, 80, 6500ms) == 0) { + open_map(env.console, context, to_zoom_to_max); + pbf_move_left_joystick(context, 0, 64, 100ms, 100ms); + if (fly_from_map(env.console, context) == FastTravelState::NOT_AT_FLY_SPOT) { + pbf_move_left_joystick(context, 128, 192, 100ms, 100ms); + fly_from_map(env.console, context); + } + } else { + open_map(env.console, context, to_zoom_to_max); + pbf_move_left_joystick(context, 0, 64, 100ms, 100ms); + fly_from_map(env.console, context); + } + wait_until_overworld(env.console, context, 50s); +} + +} // namespace void ShinyHunt_FlySpotReset::program(SingleSwitchProgramEnvironment& env, ProControllerContext& context){ assert_16_9_720p_min(env.logger(), env.console); @@ -96,6 +166,22 @@ void ShinyHunt_FlySpotReset::program(SingleSwitchProgramEnvironment& env, ProCon ); }); + route_func route; + switch (ROUTE) { + case Route::NO_MOVEMENT: + route = route_default; + break; + case Route::WILD_ZONE_19: + route = route_wild_zone_19; + break; + default: + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "route not implemented", + env.console + ); + } + bool to_zoom_to_max = true; run_until( env.console, context, @@ -103,35 +189,8 @@ void ShinyHunt_FlySpotReset::program(SingleSwitchProgramEnvironment& env, ProCon while (true){ context.wait_for_all_requests(); shiny_sound_handler.process_pending(context); - - // Open map - bool can_fast_travel = open_map(env.console, context, to_zoom_to_max); + route(env, context, stats, to_zoom_to_max); to_zoom_to_max = false; - if (!can_fast_travel){ - stats.errors++; - env.update_stats(); - OperationFailedException::fire( - ErrorReport::SEND_ERROR_REPORT, - "FlySpotReset: Cannot open map for fast travel.", - env.console - ); - } - - // Move map cursor upwards a little bit - pbf_move_left_joystick(context, 128, 64, 100ms, 200ms); - - // Fly from map to reset spawns - FastTravelState travel_status = fly_from_map(env.console, context); - if (travel_status != FastTravelState::SUCCESS){ - stats.errors++; - env.update_stats(); - OperationFailedException::fire( - ErrorReport::SEND_ERROR_REPORT, - "FlySpotReset: Cannot fast travel after moving map cursor.", - env.console - ); - } - stats.resets++; env.update_stats(); if (stats.resets.load(std::memory_order_relaxed) % 10 == 0){ diff --git a/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_FlySpotReset.h b/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_FlySpotReset.h index e0fbeea22..5f7f9fed2 100644 --- a/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_FlySpotReset.h +++ b/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_FlySpotReset.h @@ -34,9 +34,18 @@ class ShinyHunt_FlySpotReset : public SingleSwitchProgramInstance{ virtual void program(SingleSwitchProgramEnvironment& env, ProControllerContext& context) override; -private: + enum class Route{ + NO_MOVEMENT, + WILD_ZONE_19, + ALPHA_PIDGEY, + ALPHA_PIKACHU, + CUSTOMISED_MACRO = 255, + }; + + private: PokemonLA::ShinyRequiresAudioText SHINY_REQUIRES_AUDIO; ShinySoundDetectedActionOption SHINY_DETECTED; + EnumDropdownOption ROUTE; EventNotificationOption NOTIFICATION_STATUS; EventNotificationsOption NOTIFICATIONS; diff --git a/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShuttleRun.cpp b/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShuttleRun.cpp index 8816af1e3..be77fd7bb 100644 --- a/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShuttleRun.cpp +++ b/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShuttleRun.cpp @@ -10,10 +10,10 @@ #include "Common/Cpp/PrettyPrint.h" #include "CommonFramework/VideoPipeline/VideoOverlay.h" #include "CommonTools/Async/InferenceRoutines.h" -#include "CommonTools/VisualDetectors/BlackScreenDetector.h" +// #include "CommonTools/VisualDetectors/BlackScreenDetector.h" #include "NintendoSwitch/Programs/NintendoSwitch_GameEntry.h" #include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" -#include "NintendoSwitch/Commands/NintendoSwitch_Commands_Superscalar.h" +// #include "NintendoSwitch/Commands/NintendoSwitch_Commands_Superscalar.h" #include "Pokemon/Pokemon_Strings.h" #include "PokemonLA/Inference/Sounds/PokemonLA_ShinySoundDetector.h" #include "PokemonLZA/Programs/PokemonLZA_BasicNavigation.h" @@ -61,12 +61,11 @@ ShinyHunt_ShuttleRun::ShinyHunt_ShuttleRun() : DURATION("Duration:
Run the program this long.", LockMode::UNLOCK_WHILE_RUNNING, "5 h") , ROUTE("Hunt Route:", { - // {Route::SCRAGGY, "scraggy", "Sewers: Scraggy"}, - {Route::WILD_ZONE_19, "wild_zone_19", "Wild Zone 19"}, {Route::WILD_ZONE_3_TOWER, "wild_zone_3_tower", "Wild Zone 3 Tower"}, + {Route::ALPHA_PIDGEOT, "alpha_pidgeot", "Alpha Pidgeot (Jaune Sector 4)"}, }, LockMode::LOCK_WHILE_RUNNING, - Route::WILD_ZONE_19 + Route::WILD_ZONE_3_TOWER ) , SHINY_DETECTED("Shiny Detected", "", "1000 ms", ShinySoundDetectedAction::NOTIFY_ON_FIRST_ONLY) , NOTIFICATION_STATUS("Status Update", true, false, std::chrono::seconds(3600)) @@ -87,26 +86,10 @@ ShinyHunt_ShuttleRun::ShinyHunt_ShuttleRun() namespace { -void route_scraggy(SingleSwitchProgramEnvironment& env, ProControllerContext& context){ +void route_alpha_pidgeot(SingleSwitchProgramEnvironment& env, ProControllerContext& context){ //TODO } -void route_wild_zone_19(SingleSwitchProgramEnvironment& env, ProControllerContext& context){ - if (run_a_straight_path_in_overworld(env.console, context, 0, 80, 6500ms) == 0) { - open_map(env.console, context, false); - pbf_move_left_joystick(context, 0, 128, 100ms, 100ms); - if (fly_from_map(env.console, context) == FastTravelState::NOT_AT_FLY_SPOT) { - pbf_move_left_joystick(context, 128, 255, 100ms, 100ms); - fly_from_map(env.console, context); - } - } else { - open_map(env.console, context, false); - pbf_move_left_joystick(context, 0, 128, 100ms, 100ms); - fly_from_map(env.console, context); - } - wait_until_overworld(env.console, context, 50s); -} - void route_wild_zone_3_tower(SingleSwitchProgramEnvironment& env, ProControllerContext& context){ for(int i = 0; i < 6; i++){ // if there is no day/night change and no button drop, this loop should only have three iterations @@ -155,11 +138,8 @@ void ShinyHunt_ShuttleRun::program(SingleSwitchProgramEnvironment& env, ProContr }); std::function route; switch (ROUTE) { - case Route::SCRAGGY: - route = route_scraggy; - break; - case Route::WILD_ZONE_19: - route = route_wild_zone_19; + case Route::ALPHA_PIDGEOT: + route = route_alpha_pidgeot; break; case Route:: WILD_ZONE_3_TOWER: route = route_wild_zone_3_tower; diff --git a/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShuttleRun.h b/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShuttleRun.h index 621689f80..130957a52 100644 --- a/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShuttleRun.h +++ b/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShuttleRun.h @@ -35,11 +35,8 @@ class ShinyHunt_ShuttleRun : public SingleSwitchProgramInstance { virtual void program(SingleSwitchProgramEnvironment& env, ProControllerContext& context) override; enum class Route{ - SCRAGGY, - WILD_ZONE_19, - FIRE_STARTERS, - DRATINI, WILD_ZONE_3_TOWER, + ALPHA_PIDGEOT, CUSTOMISED_MACRO = 255, }; From 6caba53d71822a802e63112ae904b05a1f359d49 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 13:21:10 +0800 Subject: [PATCH 2/2] fly sport reset: add route for alpha pidgey --- .../PokemonLZA_ShinyHunt_FlySpotReset.cpp | 41 ++++++++++++++++++- 1 file changed, 40 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 f257f4a59..b71527780 100644 --- a/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_FlySpotReset.cpp +++ b/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_FlySpotReset.cpp @@ -9,8 +9,10 @@ #include "CommonFramework/Notifications/ProgramNotifications.h" #include "CommonFramework/VideoPipeline/VideoOverlay.h" #include "CommonTools/Async/InferenceRoutines.h" +#include "CommonTools/VisualDetectors/BlackScreenDetector.h" #include "CommonTools/StartupChecks/VideoResolutionCheck.h" #include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" +#include "NintendoSwitch/Commands/NintendoSwitch_Commands_Superscalar.h" #include "Pokemon/Pokemon_Strings.h" #include "PokemonLA/Inference/Sounds/PokemonLA_ShinySoundDetector.h" #include "PokemonLZA/Programs/PokemonLZA_BasicNavigation.h" @@ -62,7 +64,7 @@ ShinyHunt_FlySpotReset::ShinyHunt_FlySpotReset() { {Route::NO_MOVEMENT, "no_movement", "No Movement"}, {Route::WILD_ZONE_19, "wild_zone_19", "Wild Zone 19"}, - // {Route::ALPHA_PIDGEY, "alpha_pidgey", "Alpha Pidgey (Wild Zone 1)"}, + {Route::ALPHA_PIDGEY, "alpha_pidgey", "Alpha Pidgey (Wild Zone 1)"}, // {Route::ALPHA_PIKACHU, "alpha_pikachu", "Alpha Pikachu (Wild Zone 6)"}, // {Route::CUSTOMISED_MACRO, "customised_macro", "Customised Macro"}, }, @@ -141,6 +143,40 @@ void route_wild_zone_19( wait_until_overworld(env.console, context, 50s); } +void route_alpha_pidgey( + 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(context, 255, 128, 4000ms, 0ms); + pbf_move_left_joystick(context, 128, 255, 7400ms, 0ms); + pbf_move_left_joystick(context, 0, 128, 3000ms, 0ms); + pbf_press_button(context, BUTTON_A, 500ms, 2500ms); // elevator up + pbf_move_left_joystick(context, 255, 128, 100ms, 0ms); + pbf_press_button(context, BUTTON_L, 100ms, 1000ms); + }, + {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(context, 128, 255, 200ms, 100ms); + if (fly_from_map(env.console, context) == FastTravelState::NOT_AT_FLY_SPOT) { + pbf_move_left_joystick(context, 255, 128, 100ms, 100ms); + fly_from_map(env.console, context); + } + wait_until_overworld(env.console, context); +} + } // namespace void ShinyHunt_FlySpotReset::program(SingleSwitchProgramEnvironment& env, ProControllerContext& context){ @@ -174,6 +210,9 @@ void ShinyHunt_FlySpotReset::program(SingleSwitchProgramEnvironment& env, ProCon case Route::WILD_ZONE_19: route = route_wild_zone_19; break; + case Route::ALPHA_PIDGEY: + route = route_alpha_pidgey; + break; default: OperationFailedException::fire( ErrorReport::SEND_ERROR_REPORT,