From 14865b5c4521502ab1049bd00d19cdeff986a719 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, 16 Oct 2025 08:21:14 +0800 Subject: [PATCH 1/8] cmake: update tesseract & lept no longer need to specify `-DUNIX_LINK_TESSERACT:BOOL=true` when invocking cmake --- SerialPrograms/CMakeLists.txt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/SerialPrograms/CMakeLists.txt b/SerialPrograms/CMakeLists.txt index 8b6c4d982a..050cfb9d4c 100644 --- a/SerialPrograms/CMakeLists.txt +++ b/SerialPrograms/CMakeLists.txt @@ -445,16 +445,16 @@ else() # macOS and Linux #we hope to use our own Tesseract build in future so we can rid that dependency #but right now to run on Linux and Mac we need to use external Tesseract library - if (UNIX_LINK_TESSERACT) + pkg_search_module(TESSERACT REQUIRED tesseract) + pkg_search_module(LEPTONICA REQUIRED lept) + if (TESSERACT_FOUND AND LEPTONICA_FOUND) target_compile_definitions(SerialProgramsLib PRIVATE PA_TESSERACT UNIX_LINK_TESSERACT) - pkg_search_module(TESSERACT REQUIRED tesseract) - pkg_search_module(LEPTONICA REQUIRED lept) - include_directories(${TESSERACT_INCLUDE_DIRS}) - include_directories(${LEPTONICA_INCLUDE_DIRS}) - link_directories(${TESSERACT_LIBRARY_DIRS}) - link_directories(${LEPTONICA_LIBRARY_DIRS}) - target_link_libraries(SerialProgramsLib PRIVATE ${TESSERACT_LINK_LIBRARIES}) - target_link_libraries(SerialProgramsLib PRIVATE ${LEPTONICA_LINK_LIBRARIES}) + target_include_directories(SerialProgramsLib SYSTEM PRIVATE ${TESSERACT_INCLUDE_DIRS}) + target_include_directories(SerialProgramsLib SYSTEM PRIVATE ${LEPTONICA_INCLUDE_DIRS}) + target_link_directories(SerialProgramsLib PUBLIC ${TESSERACT_LIBRARY_DIRS}) + target_link_directories(SerialProgramsLib PUBLIC ${LEPTONICA_LIBRARY_DIRS}) + target_link_libraries(SerialProgramsLib PUBLIC ${TESSERACT_LINK_LIBRARIES}) + target_link_libraries(SerialProgramsLib PUBLIC ${LEPTONICA_LINK_LIBRARIES}) endif() pkg_search_module(DPP dpp=10.0.22) From 20af7ef3e84c367fe578c7362f023f1703943456 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, 5 Oct 2025 20:33:35 +0800 Subject: [PATCH 2/8] cmake: tidy up opencv for macOS/Linux --- SerialPrograms/CMakeLists.txt | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/SerialPrograms/CMakeLists.txt b/SerialPrograms/CMakeLists.txt index 050cfb9d4c..fe658e9395 100644 --- a/SerialPrograms/CMakeLists.txt +++ b/SerialPrograms/CMakeLists.txt @@ -352,12 +352,6 @@ else() # macOS and Linux target_link_directories(SerialProgramsLib PUBLIC ${ONNXRUNTIME_LIBRARY_DIRS}) target_link_libraries(SerialProgramsLib PUBLIC ${ONNXRUNTIME_LINK_LIBRARIES}) endif() - # Find OpenCV - if(CMAKE_SYSTEM_PROCESSOR MATCHES "(arm64)|(ARM64)") - find_package(OpenCV REQUIRED HINTS "/opt/homebrew/opt/opencv/lib/cmake/opencv4/") - else() - find_package(OpenCV REQUIRED HINTS "/usr/local/opt/opencv/lib/cmake/opencv4/") - endif() else() # Linux # ONNX RUNTIME LINUX CONFIG # NOTE: users can specify their own ONNX_ROOT_PATH (this is the base folder for ONNX) on the command line when evoking cmake. @@ -435,13 +429,13 @@ else() # macOS and Linux else() message(FATAL_ERROR "Could not find ONNX Runtime headers or library.") endif() - # Find OpenCV - find_package(OpenCV REQUIRED HINTS "/usr/local/opt/opencv/lib/cmake/opencv4/") endif() # end Linux - include_directories(${OpenCV_INCLUDE_DIRS}) - link_directories(${OpenCV_LIBRARY_DIRS}) - target_link_libraries(SerialProgramsLib PRIVATE ${OpenCV_LIBS}) + # Find OpenCV + pkg_search_module(OpenCV REQUIRED opencv4 opencv) + target_include_directories(SerialProgramsLib SYSTEM PRIVATE ${OpenCV_INCLUDE_DIRS}) # "SYSTEM" to suppress warnings + target_link_directories(SerialProgramsLib PUBLIC ${OpenCV_LIBRARY_DIRS}) + target_link_libraries(SerialProgramsLib PUBLIC ${OpenCV_LINK_LIBRARIES}) #we hope to use our own Tesseract build in future so we can rid that dependency #but right now to run on Linux and Mac we need to use external Tesseract library @@ -468,10 +462,6 @@ else() # macOS and Linux endif() if (APPLE) - # Add -Wno-c11-extensions to avoid clang gives - # /usr/local/Cellar/opencv/4.5.5_3/include/opencv4/opencv2/core/mat.inl.hpp:2116:9: error: '_Atomic' is a C11 extension - # when compiling OpenCV - # target_compile_options(SerialProgramsLib PRIVATE -Wall -Wextra -Wpedantic -Werror -Wno-c11-extensions) target_compile_options(SerialProgramsLib PRIVATE -Wall -Wextra -Wpedantic -Werror -Wshorten-64-to-32) # on macOS, need this framework to query OS API to control display sleep and system sleep behavior target_link_libraries(SerialProgramsLib PRIVATE "-framework IOKit -framework CoreFoundation") From 7780141b1355d01153917d6139c0753011cc0ff6 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: Tue, 28 Oct 2025 11:48:40 +0800 Subject: [PATCH 3/8] cmake: unmark tesseract&lept as required --- SerialPrograms/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SerialPrograms/CMakeLists.txt b/SerialPrograms/CMakeLists.txt index fe658e9395..43b59c88b9 100644 --- a/SerialPrograms/CMakeLists.txt +++ b/SerialPrograms/CMakeLists.txt @@ -439,8 +439,8 @@ else() # macOS and Linux #we hope to use our own Tesseract build in future so we can rid that dependency #but right now to run on Linux and Mac we need to use external Tesseract library - pkg_search_module(TESSERACT REQUIRED tesseract) - pkg_search_module(LEPTONICA REQUIRED lept) + pkg_search_module(TESSERACT tesseract) + pkg_search_module(LEPTONICA lept) if (TESSERACT_FOUND AND LEPTONICA_FOUND) target_compile_definitions(SerialProgramsLib PRIVATE PA_TESSERACT UNIX_LINK_TESSERACT) target_include_directories(SerialProgramsLib SYSTEM PRIVATE ${TESSERACT_INCLUDE_DIRS}) From a9be649a99aa28893bbcc327f4c39e51432f99a0 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: Mon, 27 Oct 2025 10:29:04 +0800 Subject: [PATCH 4/8] LZA: add shiny hunt wild zone entrance --- .../Source/PokemonLZA/PokemonLZA_Panels.cpp | 2 + .../PokemonLZA_ShinyHunt_WildZoneEntrance.cpp | 167 ++++++++++++++++++ .../PokemonLZA_ShinyHunt_WildZoneEntrance.h | 48 +++++ SerialPrograms/SourceFiles.cmake | 2 + 4 files changed, 219 insertions(+) create mode 100644 SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.cpp create mode 100644 SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.h diff --git a/SerialPrograms/Source/PokemonLZA/PokemonLZA_Panels.cpp b/SerialPrograms/Source/PokemonLZA/PokemonLZA_Panels.cpp index b4f2503dd0..37eaa29477 100644 --- a/SerialPrograms/Source/PokemonLZA/PokemonLZA_Panels.cpp +++ b/SerialPrograms/Source/PokemonLZA/PokemonLZA_Panels.cpp @@ -20,6 +20,7 @@ #include "Programs/ShinyHunting/PokemonLZA_ShinyHunt_OverworldReset.h" #include "Programs/ShinyHunting/PokemonLZA_BeldumHunter.h" #include "Programs/ShinyHunting/PokemonLZA_AutoFossil.h" +#include "Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.h" // Developer #include "Programs/TestPrograms/PokemonLZA_OverworldWatcher.h" @@ -52,6 +53,7 @@ std::vector PanelListFactory::make_panels() const{ ret.emplace_back("---- Shiny Hunting ----"); ret.emplace_back(make_single_switch_program()); ret.emplace_back(make_single_switch_program()); + ret.emplace_back(make_single_switch_program()); if (PreloadSettings::instance().DEVELOPER_MODE){ ret.emplace_back(make_single_switch_program()); diff --git a/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.cpp b/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.cpp new file mode 100644 index 0000000000..8f2d667c95 --- /dev/null +++ b/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.cpp @@ -0,0 +1,167 @@ +/* Shiny Hunt - Wild Zone Entrance + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#include "CommonFramework/Exceptions/OperationFailedException.h" +#include "CommonFramework/ProgramStats/StatsTracking.h" +#include "CommonFramework/Notifications/ProgramNotifications.h" +#include "CommonTools/Async/InferenceRoutines.h" +#include "CommonTools/VisualDetectors/BlackScreenDetector.h" +#include "NintendoSwitch/Programs/NintendoSwitch_GameEntry.h" +#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" +#include "Pokemon/Pokemon_Strings.h" +#include "PokemonLA/Inference/Sounds/PokemonLA_ShinySoundDetector.h" +#include "PokemonLZA/Inference/PokemonLZA_ButtonDetector.h" +#include "PokemonLZA/Programs/PokemonLZA_BasicNavigation.h" +#include "PokemonLZA_ShinyHunt_WildZoneEntrance.h" + +namespace PokemonAutomation { +namespace NintendoSwitch { +namespace PokemonLZA { + +using namespace Pokemon; + + +ShinyHunt_WildZoneEntrance_Descriptor::ShinyHunt_WildZoneEntrance_Descriptor() + : SingleSwitchProgramDescriptor("PokemonLZA:ShinyHunt-WildZoneEntrance", STRING_POKEMON + " LZA", + "Shiny Hunt - Wild Zone Entrance", + "Programs/PokemonLZA/ShinyHunt-WildZoneEntrance.html", + "Shiny hunt by repeatedly entering Wild Zone from its entrance.", + ProgramControllerClass::StandardController_NoRestrictions, FeedbackType::REQUIRED, + AllowCommandsWhenRunning::DISABLE_COMMANDS, {}) {} +class ShinyHunt_WildZoneEntrance_Descriptor::Stats : public StatsTracker { +public: + Stats() : resets(m_stats["Wild Zone"]), shinies(m_stats["Shiny Sounds"]), errors(m_stats["Errors"]) { + m_display_order.emplace_back("Wild Zone"); + m_display_order.emplace_back("Shiny Sounds"); + m_display_order.emplace_back("Errors", HIDDEN_IF_ZERO); + + m_aliases["Shinies"] = "Shiny Sounds"; + m_aliases["Shinies Detected"] = "Shiny Sounds"; + } + + std::atomic& resets; + std::atomic& shinies; + std::atomic& errors; +}; +std::unique_ptr ShinyHunt_WildZoneEntrance_Descriptor::make_stats() const { + return std::unique_ptr(new Stats()); +} + + +ShinyHunt_WildZoneEntrance::ShinyHunt_WildZoneEntrance() + : SHINY_DETECTED("Shiny Detected", "", "2000 ms", ShinySoundDetectedAction::NOTIFY_ON_FIRST_ONLY), + NOTIFICATION_STATUS("Status Update", true, false, std::chrono::seconds(3600)), + NOTIFICATIONS({ + &NOTIFICATION_STATUS, + &SHINY_DETECTED.NOTIFICATIONS, + &NOTIFICATION_PROGRAM_FINISH, + &NOTIFICATION_ERROR_RECOVERABLE, + &NOTIFICATION_ERROR_FATAL, + }) { + PA_ADD_STATIC(SHINY_REQUIRES_AUDIO); + PA_ADD_OPTION(SHINY_DETECTED); + PA_ADD_OPTION(NOTIFICATIONS); +} + + +void run_to_gate(ConsoleHandle& console, ProControllerContext& context) { + ButtonWatcher buttonA(COLOR_RED, ButtonType::ButtonA, {0, 0, 1, 1}, &console.overlay()); + int ret = run_until(console, context, + [](ProControllerContext& context) { + for (int c = 0; c < 10; c++) { + pbf_move_left_joystick(context, 128, 0, 800ms, 200ms); + } + }, + {{buttonA}}); + + switch (ret) { + case 0: + break; + default: + OperationFailedException::fire(ErrorReport::SEND_ERROR_REPORT, + "run_to_gate(): Unable to detect entrance after 10 seconds.", console); + } +} + +void enter_wild_zone_entrance(ConsoleHandle& console, ProControllerContext& context) { + BlackScreenOverWatcher black_screen(COLOR_BLUE); + int ret = run_until(console, context, + [&](ProControllerContext& context) { + pbf_mash_button(context, BUTTON_B, 200ms); // dismiss menu if any + run_to_gate(console, context); + pbf_mash_button(context, BUTTON_A, 2000ms); + pbf_move_left_joystick(context, 128, 0, 500ms, 200ms); + context.wait_for_all_requests(); + pbf_press_button(context, BUTTON_PLUS, 100ms, 100ms); // open map + }, + {{black_screen}}); + if (ret == 0) { + console.log("[WildZoneEntrance] Detected day/night change after entering."); + context.wait_for(std::chrono::milliseconds(2000)); + pbf_mash_button(context, BUTTON_B, 200ms); // dismiss menu if any + pbf_press_button(context, BUTTON_PLUS, 100ms, 100ms); // open map again + } + pbf_mash_button(context, BUTTON_A, 800ms); // teleporting or just mashing button + pbf_mash_button(context, BUTTON_B, 200ms); // in case need to dismiss map + context.wait_for_all_requests(); + context.wait_for(std::chrono::milliseconds(4000)); // TODO: differ NS1 wait time from NS2 +} + +void ShinyHunt_WildZoneEntrance::program(SingleSwitchProgramEnvironment& env, ProControllerContext& context) { + ShinyHunt_WildZoneEntrance_Descriptor::Stats& stats = + env.current_stats(); + + uint8_t shiny_count = 0; + + while (true) { + float shiny_coefficient = 1.0; + PokemonLA::ShinySoundDetector shiny_detector(env.console, [&](float error_coefficient) -> bool { + // Warning: This callback will be run from a different thread than this function. + shiny_count++; + stats.shinies++; + env.update_stats(); + shiny_coefficient = error_coefficient; + return true; + }); + + int ret = run_until(env.console, context, + [&](ProControllerContext& context) { + while (true) { + send_program_status_notification(env, NOTIFICATION_STATUS); + stats.resets++; + enter_wild_zone_entrance(env.console, context); + env.update_stats(); + } + }, + {{shiny_detector}}); + + // This should never happen. + if (ret != 0) { + continue; + } + + context.wait_for(std::chrono::milliseconds(1000)); + + // when shiny sound is detected, it's most likely happened inside the zone + // now try to reset position + pbf_mash_button(context, BUTTON_B, 200ms); // dismiss menu if any + pbf_press_button(context, BUTTON_PLUS, 100ms, 100ms); // open map + pbf_mash_button(context, BUTTON_A, 600ms); // teleporting or just mashing button + pbf_mash_button(context, BUTTON_B, 200ms); // in case need to dismiss map + + if (SHINY_DETECTED.on_shiny_sound(env, env.console, context, shiny_count, shiny_coefficient)) { + break; + } + } + + go_home(env.console, context); + send_program_finished_notification(env, NOTIFICATION_PROGRAM_FINISH); +} + + +} // namespace PokemonLZA +} // namespace NintendoSwitch +} // namespace PokemonAutomation diff --git a/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.h b/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.h new file mode 100644 index 0000000000..89ae1d624d --- /dev/null +++ b/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.h @@ -0,0 +1,48 @@ +/* Shiny Hunt - Wild Zone Entrance + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#ifndef PokemonAutomation_PokemonLZA_ShinyHunt_WildZoneEntrance_H +#define PokemonAutomation_PokemonLZA_ShinyHunt_WildZoneEntrance_H + +#include "CommonFramework/Notifications/EventNotificationsTable.h" +#include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h" +#include "PokemonLA/Options/PokemonLA_ShinyDetectedAction.h" +#include "PokemonLZA/Options/PokemonLZA_ShinyDetectedAction.h" + +namespace PokemonAutomation { +namespace NintendoSwitch { +namespace PokemonLZA { + + +class ShinyHunt_WildZoneEntrance_Descriptor : public SingleSwitchProgramDescriptor { +public: + ShinyHunt_WildZoneEntrance_Descriptor(); + + class Stats; + virtual std::unique_ptr make_stats() const override; +}; + + +class ShinyHunt_WildZoneEntrance : public SingleSwitchProgramInstance { +public: + ShinyHunt_WildZoneEntrance(); + + virtual void program(SingleSwitchProgramEnvironment& env, ProControllerContext& context) override; + +private: + PokemonLA::ShinyRequiresAudioText SHINY_REQUIRES_AUDIO; + + ShinySoundDetectedActionOption SHINY_DETECTED; + + EventNotificationOption NOTIFICATION_STATUS; + EventNotificationsOption NOTIFICATIONS; +}; + + +} // namespace PokemonLZA +} // namespace NintendoSwitch +} // namespace PokemonAutomation +#endif diff --git a/SerialPrograms/SourceFiles.cmake b/SerialPrograms/SourceFiles.cmake index 192d927d8e..81d22a89d3 100644 --- a/SerialPrograms/SourceFiles.cmake +++ b/SerialPrograms/SourceFiles.cmake @@ -1579,6 +1579,8 @@ file(GLOB LIBRARY_SOURCES Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_BenchSit.h Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_OverworldReset.cpp Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_OverworldReset.h + Source/PokemonLZA/Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.cpp + Source/PokemonLZA/Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.h Source/PokemonLZA/Programs/TestPrograms/PokemonLZA_MoveBoxArrow.cpp Source/PokemonLZA/Programs/TestPrograms/PokemonLZA_MoveBoxArrow.h Source/PokemonLZA/Programs/TestPrograms/PokemonLZA_OverworldWatcher.cpp From be237f6c523dd27673d23370d5d19bca07bb8195 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, 30 Oct 2025 11:03:16 +0800 Subject: [PATCH 5/8] only detect shiny sound at most once --- .../PokemonLZA_ShinyHunt_WildZoneEntrance.cpp | 39 ++++++++++--------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.cpp b/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.cpp index 8f2d667c95..7b0b68f52c 100644 --- a/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.cpp +++ b/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.cpp @@ -116,7 +116,7 @@ void ShinyHunt_WildZoneEntrance::program(SingleSwitchProgramEnvironment& env, Pr uint8_t shiny_count = 0; - while (true) { + { // first run with shiny detection float shiny_coefficient = 1.0; PokemonLA::ShinySoundDetector shiny_detector(env.console, [&](float error_coefficient) -> bool { // Warning: This callback will be run from a different thread than this function. @@ -127,21 +127,16 @@ void ShinyHunt_WildZoneEntrance::program(SingleSwitchProgramEnvironment& env, Pr return true; }); - int ret = run_until(env.console, context, - [&](ProControllerContext& context) { - while (true) { - send_program_status_notification(env, NOTIFICATION_STATUS); - stats.resets++; - enter_wild_zone_entrance(env.console, context); - env.update_stats(); - } - }, - {{shiny_detector}}); - - // This should never happen. - if (ret != 0) { - continue; - } + run_until(env.console, context, + [&](ProControllerContext& context) { + while (true) { + send_program_status_notification(env, NOTIFICATION_STATUS); + stats.resets++; + enter_wild_zone_entrance(env.console, context); + env.update_stats(); + } + }, + {{shiny_detector}}); context.wait_for(std::chrono::milliseconds(1000)); @@ -152,8 +147,16 @@ void ShinyHunt_WildZoneEntrance::program(SingleSwitchProgramEnvironment& env, Pr pbf_mash_button(context, BUTTON_A, 600ms); // teleporting or just mashing button pbf_mash_button(context, BUTTON_B, 200ms); // in case need to dismiss map - if (SHINY_DETECTED.on_shiny_sound(env, env.console, context, shiny_count, shiny_coefficient)) { - break; + SHINY_DETECTED.on_shiny_sound(env, env.console, context, shiny_count, shiny_coefficient); + } + + // continue with shiny detection if pointless + if (SHINY_DETECTED.ACTION != ShinySoundDetectedAction::STOP_PROGRAM) { + while (true) { + send_program_status_notification(env, NOTIFICATION_STATUS); + stats.resets++; + enter_wild_zone_entrance(env.console, context); + env.update_stats(); } } From 4cdb2d6a94ae318caaf2c894c0e60a86b7c87c8a 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, 30 Oct 2025 15:58:09 +0800 Subject: [PATCH 6/8] walk_in_zone duration as an option --- .../PokemonLZA_ShinyHunt_WildZoneEntrance.cpp | 13 ++++++++----- .../PokemonLZA_ShinyHunt_WildZoneEntrance.h | 1 + 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.cpp b/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.cpp index 7b0b68f52c..6de43230d5 100644 --- a/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.cpp +++ b/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.cpp @@ -52,7 +52,9 @@ std::unique_ptr ShinyHunt_WildZoneEntrance_Descriptor::make_stats( ShinyHunt_WildZoneEntrance::ShinyHunt_WildZoneEntrance() - : SHINY_DETECTED("Shiny Detected", "", "2000 ms", ShinySoundDetectedAction::NOTIFY_ON_FIRST_ONLY), + : WALK_IN_ZONE("WALK IN ZONE:
Walk this long in the zone after passing through the gate.", + LockMode::UNLOCK_WHILE_RUNNING, "500 ms"), + SHINY_DETECTED("Shiny Detected", "", "2000 ms", ShinySoundDetectedAction::NOTIFY_ON_FIRST_ONLY), NOTIFICATION_STATUS("Status Update", true, false, std::chrono::seconds(3600)), NOTIFICATIONS({ &NOTIFICATION_STATUS, @@ -62,6 +64,7 @@ ShinyHunt_WildZoneEntrance::ShinyHunt_WildZoneEntrance() &NOTIFICATION_ERROR_FATAL, }) { PA_ADD_STATIC(SHINY_REQUIRES_AUDIO); + PA_ADD_OPTION(WALK_IN_ZONE); PA_ADD_OPTION(SHINY_DETECTED); PA_ADD_OPTION(NOTIFICATIONS); } @@ -86,14 +89,14 @@ void run_to_gate(ConsoleHandle& console, ProControllerContext& context) { } } -void enter_wild_zone_entrance(ConsoleHandle& console, ProControllerContext& context) { +void enter_wild_zone_entrance(ConsoleHandle& console, ProControllerContext& context, Milliseconds walk_in_zone) { BlackScreenOverWatcher black_screen(COLOR_BLUE); int ret = run_until(console, context, [&](ProControllerContext& context) { pbf_mash_button(context, BUTTON_B, 200ms); // dismiss menu if any run_to_gate(console, context); pbf_mash_button(context, BUTTON_A, 2000ms); - pbf_move_left_joystick(context, 128, 0, 500ms, 200ms); + pbf_move_left_joystick(context, 128, 0, walk_in_zone, 200ms); context.wait_for_all_requests(); pbf_press_button(context, BUTTON_PLUS, 100ms, 100ms); // open map }, @@ -132,7 +135,7 @@ void ShinyHunt_WildZoneEntrance::program(SingleSwitchProgramEnvironment& env, Pr while (true) { send_program_status_notification(env, NOTIFICATION_STATUS); stats.resets++; - enter_wild_zone_entrance(env.console, context); + enter_wild_zone_entrance(env.console, context, WALK_IN_ZONE); env.update_stats(); } }, @@ -155,7 +158,7 @@ void ShinyHunt_WildZoneEntrance::program(SingleSwitchProgramEnvironment& env, Pr while (true) { send_program_status_notification(env, NOTIFICATION_STATUS); stats.resets++; - enter_wild_zone_entrance(env.console, context); + enter_wild_zone_entrance(env.console, context, WALK_IN_ZONE); env.update_stats(); } } diff --git a/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.h b/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.h index 89ae1d624d..26c5a39606 100644 --- a/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.h +++ b/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.h @@ -34,6 +34,7 @@ class ShinyHunt_WildZoneEntrance : public SingleSwitchProgramInstance { private: PokemonLA::ShinyRequiresAudioText SHINY_REQUIRES_AUDIO; + MillisecondsOption WALK_IN_ZONE; ShinySoundDetectedActionOption SHINY_DETECTED; From aa8a26ab5547a31140685021b5a548bf5aa76818 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, 30 Oct 2025 17:31:34 +0800 Subject: [PATCH 7/8] move into shiny hunting folder --- SerialPrograms/Source/PokemonLZA/PokemonLZA_Panels.cpp | 2 +- .../PokemonLZA_WildZoneEntrance.cpp} | 2 +- .../PokemonLZA_WildZoneEntrance.h} | 4 ++-- SerialPrograms/SourceFiles.cmake | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) rename SerialPrograms/Source/PokemonLZA/Programs/{PokemonLZA_ShinyHunt_WildZoneEntrance.cpp => ShinyHunting/PokemonLZA_WildZoneEntrance.cpp} (99%) rename SerialPrograms/Source/PokemonLZA/Programs/{PokemonLZA_ShinyHunt_WildZoneEntrance.h => ShinyHunting/PokemonLZA_WildZoneEntrance.h} (90%) diff --git a/SerialPrograms/Source/PokemonLZA/PokemonLZA_Panels.cpp b/SerialPrograms/Source/PokemonLZA/PokemonLZA_Panels.cpp index 37eaa29477..0b6853a560 100644 --- a/SerialPrograms/Source/PokemonLZA/PokemonLZA_Panels.cpp +++ b/SerialPrograms/Source/PokemonLZA/PokemonLZA_Panels.cpp @@ -20,7 +20,7 @@ #include "Programs/ShinyHunting/PokemonLZA_ShinyHunt_OverworldReset.h" #include "Programs/ShinyHunting/PokemonLZA_BeldumHunter.h" #include "Programs/ShinyHunting/PokemonLZA_AutoFossil.h" -#include "Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.h" +#include "Programs/ShinyHunting/PokemonLZA_WildZoneEntrance.h" // Developer #include "Programs/TestPrograms/PokemonLZA_OverworldWatcher.h" diff --git a/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.cpp b/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_WildZoneEntrance.cpp similarity index 99% rename from SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.cpp rename to SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_WildZoneEntrance.cpp index 6de43230d5..723c66e83e 100644 --- a/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.cpp +++ b/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_WildZoneEntrance.cpp @@ -15,7 +15,7 @@ #include "PokemonLA/Inference/Sounds/PokemonLA_ShinySoundDetector.h" #include "PokemonLZA/Inference/PokemonLZA_ButtonDetector.h" #include "PokemonLZA/Programs/PokemonLZA_BasicNavigation.h" -#include "PokemonLZA_ShinyHunt_WildZoneEntrance.h" +#include "PokemonLZA_WildZoneEntrance.h" namespace PokemonAutomation { namespace NintendoSwitch { diff --git a/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.h b/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_WildZoneEntrance.h similarity index 90% rename from SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.h rename to SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_WildZoneEntrance.h index 26c5a39606..a74d6272e2 100644 --- a/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.h +++ b/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_WildZoneEntrance.h @@ -4,8 +4,8 @@ * */ -#ifndef PokemonAutomation_PokemonLZA_ShinyHunt_WildZoneEntrance_H -#define PokemonAutomation_PokemonLZA_ShinyHunt_WildZoneEntrance_H +#ifndef PokemonAutomation_PokemonLZA_WildZoneEntrance_H +#define PokemonAutomation_PokemonLZA_WildZoneEntrance_H #include "CommonFramework/Notifications/EventNotificationsTable.h" #include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h" diff --git a/SerialPrograms/SourceFiles.cmake b/SerialPrograms/SourceFiles.cmake index 81d22a89d3..2ffaa2804d 100644 --- a/SerialPrograms/SourceFiles.cmake +++ b/SerialPrograms/SourceFiles.cmake @@ -1579,8 +1579,8 @@ file(GLOB LIBRARY_SOURCES Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_BenchSit.h Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_OverworldReset.cpp Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_ShinyHunt_OverworldReset.h - Source/PokemonLZA/Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.cpp - Source/PokemonLZA/Programs/PokemonLZA_ShinyHunt_WildZoneEntrance.h + Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_WildZoneEntrance.cpp + Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_WildZoneEntrance.h Source/PokemonLZA/Programs/TestPrograms/PokemonLZA_MoveBoxArrow.cpp Source/PokemonLZA/Programs/TestPrograms/PokemonLZA_MoveBoxArrow.h Source/PokemonLZA/Programs/TestPrograms/PokemonLZA_OverworldWatcher.cpp From f4e81932c46cec3e0e581ff4dfd0e29becfd7ebf 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, 30 Oct 2025 18:14:34 +0800 Subject: [PATCH 8/8] warn use if shiny detection options set to notify all --- .../Programs/ShinyHunting/PokemonLZA_WildZoneEntrance.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_WildZoneEntrance.cpp b/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_WildZoneEntrance.cpp index 723c66e83e..568593d4e2 100644 --- a/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_WildZoneEntrance.cpp +++ b/SerialPrograms/Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_WildZoneEntrance.cpp @@ -116,6 +116,10 @@ void enter_wild_zone_entrance(ConsoleHandle& console, ProControllerContext& cont void ShinyHunt_WildZoneEntrance::program(SingleSwitchProgramEnvironment& env, ProControllerContext& context) { ShinyHunt_WildZoneEntrance_Descriptor::Stats& stats = env.current_stats(); + + if (SHINY_DETECTED.ACTION == ShinySoundDetectedAction::NOTIFY_ON_ALL) { + throw UserSetupError(env.console, "Shiny would be detected/notified at most once. Choose one of the other 2 options"); + } uint8_t shiny_count = 0; @@ -153,7 +157,7 @@ void ShinyHunt_WildZoneEntrance::program(SingleSwitchProgramEnvironment& env, Pr SHINY_DETECTED.on_shiny_sound(env, env.console, context, shiny_count, shiny_coefficient); } - // continue with shiny detection if pointless + // continue with shiny sound detection is pointless if (SHINY_DETECTED.ACTION != ShinySoundDetectedAction::STOP_PROGRAM) { while (true) { send_program_status_notification(env, NOTIFICATION_STATUS);