From b19bdb65f80e438fd1b113cbfbf1ae3ffe124af1 Mon Sep 17 00:00:00 2001 From: kichithewolf Date: Sun, 22 Feb 2026 11:41:58 -0500 Subject: [PATCH 1/3] FRLG sound detection --- .../Inference/Sounds/PokemonFRLG_ShinySoundDetector.cpp | 2 +- SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Settings.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/Sounds/PokemonFRLG_ShinySoundDetector.cpp b/SerialPrograms/Source/PokemonFRLG/Inference/Sounds/PokemonFRLG_ShinySoundDetector.cpp index 077fca53e..8ec2b8d2a 100644 --- a/SerialPrograms/Source/PokemonFRLG/Inference/Sounds/PokemonFRLG_ShinySoundDetector.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Inference/Sounds/PokemonFRLG_ShinySoundDetector.cpp @@ -34,7 +34,7 @@ float ShinySoundDetector::get_score_threshold() const{ std::unique_ptr ShinySoundDetector::build_spectrogram_matcher(size_t sample_rate){ return std::make_unique( "Shiny Sound", - AudioTemplateCache::instance().get_throw("PokemonRSE/ShinySound", sample_rate), + AudioTemplateCache::instance().get_throw("PokemonFRLG/ShinySound", sample_rate), SpectrogramMatcher::Mode::SPIKE_CONV, sample_rate, GameSettings::instance().SHINY_SOUND_LOW_FREQUENCY ); diff --git a/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Settings.cpp b/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Settings.cpp index 22c975aae..6730519cd 100644 --- a/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Settings.cpp +++ b/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Settings.cpp @@ -42,12 +42,12 @@ GameSettings::GameSettings() , SHINY_SOUND_THRESHOLD( "Shiny Sound Threshold:
Maximum error coefficient to trigger a shiny detection.", LockMode::LOCK_WHILE_RUNNING, - 0.97, 0, 1.0 + 0.80, 0, 1.0 //0.87 ) , SHINY_SOUND_LOW_FREQUENCY( "Shiny Sound Low Frequency (Hz):
High pass filter frequency for shiny sound.", LockMode::LOCK_WHILE_RUNNING, - 5000, 0, 48000 + 1000, 0, 48000 //2000 ) { PA_ADD_STATIC(m_soft_reset_timings); From da2cc6cf27dca847e33b19044b7c8f7906555a44 Mon Sep 17 00:00:00 2001 From: kichithewolf Date: Sun, 22 Feb 2026 15:49:45 -0500 Subject: [PATCH 2/3] prizeselect detector, open_slot_six --- .../PokemonFRLG_PrizeSelectDetector.cpp | 54 +++++++++++++ .../Dialogs/PokemonFRLG_PrizeSelectDetector.h | 56 +++++++++++++ .../PokemonFRLG/PokemonFRLG_Navigation.cpp | 80 +++++++++++++++++++ .../PokemonFRLG/PokemonFRLG_Navigation.h | 7 +- 4 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 SerialPrograms/Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_PrizeSelectDetector.cpp create mode 100644 SerialPrograms/Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_PrizeSelectDetector.h diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_PrizeSelectDetector.cpp b/SerialPrograms/Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_PrizeSelectDetector.cpp new file mode 100644 index 000000000..29e02d253 --- /dev/null +++ b/SerialPrograms/Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_PrizeSelectDetector.cpp @@ -0,0 +1,54 @@ +/* Prize Select Detector + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#include "CommonTools/Images/SolidColorTest.h" +#include "CommonTools/Images/ImageFilter.h" +#include "CommonFramework/ImageTools/ImageBoxes.h" +#include "CommonFramework/ImageTypes/ImageRGB32.h" +#include "CommonFramework/ImageTools/ImageStats.h" +#include "CommonFramework/ImageTypes/ImageViewRGB32.h" +#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h" +#include "CommonTools/Images/SolidColorTest.h" +#include "CommonTools/Images/WaterfillUtilities.h" +#include "CommonTools/ImageMatch/WaterfillTemplateMatcher.h" +#include "CommonFramework/VideoPipeline/VideoOverlay.h" +#include "PokemonFRLG_PrizeSelectDetector.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonFRLG{ + +PrizeSelectDetector::PrizeSelectDetector(Color color) + : m_right_box(0.812, 0.726, 0.013, 0.169) + , m_top_box(0.175, 0.715, 0.649, 0.005) + , m_bottom_box(0.177, 0.896, 0.645, 0.008) + , m_selection_box(0.667, 0.514, 0.173, 0.058) +{} +void PrizeSelectDetector::make_overlays(VideoOverlaySet& items) const{ + items.add(COLOR_RED, m_right_box); + items.add(COLOR_RED, m_top_box); + items.add(COLOR_RED, m_bottom_box); + items.add(COLOR_RED, m_selection_box); +} +bool PrizeSelectDetector::detect(const ImageViewRGB32& screen){ + ImageViewRGB32 right_image = extract_box_reference(screen, m_right_box); + ImageViewRGB32 top_image = extract_box_reference(screen, m_top_box); + ImageViewRGB32 bottom_image = extract_box_reference(screen, m_bottom_box); + ImageViewRGB32 selection_image = extract_box_reference(screen, m_selection_box); + if (is_solid(right_image, { 0.25, 0.38, 0.369 }) + && is_solid(top_image, { 0.25, 0.38, 0.369 }) + && is_solid(bottom_image, { 0.25, 0.38, 0.369 }) + && is_solid(selection_image, { 0.25, 0.38, 0.369 }) + ){ + return true; + } + return false; +} + + +} +} +} diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_PrizeSelectDetector.h b/SerialPrograms/Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_PrizeSelectDetector.h new file mode 100644 index 000000000..62f9c34da --- /dev/null +++ b/SerialPrograms/Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_PrizeSelectDetector.h @@ -0,0 +1,56 @@ +/* Prize Select Detector + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#ifndef PokemonAutomation_PokemonFRLG_PrizeSelectDetector_H +#define PokemonAutomation_PokemonFRLG_PrizeSelectDetector_H + +#include +#include +#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h" +#include "Common/Cpp/Color.h" +#include "CommonFramework/ImageTools/ImageBoxes.h" +#include "CommonTools/VisualDetector.h" +#include "CommonTools/InferenceCallbacks/VisualInferenceCallback.h" + +namespace PokemonAutomation{ + class CancellableScope; + class VideoFeed; +namespace NintendoSwitch{ +namespace PokemonFRLG{ + +// Same as WhiteDialogDetector, but also looks for the white on the final line of the prize select box +// All 3 prize booths have 5 items, however the width of the box varies so we have to go by height +// (also I'm not sure if width varies by language) +// can't use the coin count in the top left, as that appears as soon as you talk to the booth +// a future improvement might be to look for the selection arrow, but keep in mind width varies +class PrizeSelectDetector : public StaticScreenDetector{ +public: + PrizeSelectDetector(Color color); + + virtual void make_overlays(VideoOverlaySet& items) const override; + virtual bool detect(const ImageViewRGB32& screen) override; + +private: + ImageFloatBox m_right_box; + ImageFloatBox m_top_box; + ImageFloatBox m_bottom_box; + ImageFloatBox m_selection_box; +}; +class PrizeSelectWatcher : public DetectorToFinder{ +public: + PrizeSelectWatcher(Color color) + : DetectorToFinder("PrizeSelectWatcher", std::chrono::milliseconds(250), color) + {} +}; + + + + +} +} +} + +#endif diff --git a/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.cpp b/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.cpp index 291125f72..d4fa7003d 100644 --- a/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.cpp +++ b/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.cpp @@ -11,8 +11,11 @@ #include "CommonTools/VisualDetectors/BlackScreenDetector.h" #include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" #include "NintendoSwitch/Commands/NintendoSwitch_Commands_Superscalar.h" +#include "NintendoSwitch/Controllers/Procon/NintendoSwitch_ProController.h" +#include "NintendoSwitch/NintendoSwitch_ConsoleHandle.h" #include "PokemonFRLG/Inference/Dialogs/PokemonFRLG_DialogDetector.h" #include "PokemonFRLG/Inference/Sounds/PokemonFRLG_ShinySoundDetector.h" +#include "PokemonFRLG/Inference/Menus/PokemonFRLG_StartMenuDetector.h" #include "PokemonFRLG/PokemonFRLG_Settings.h" #include "PokemonFRLG_Navigation.h" @@ -54,6 +57,83 @@ void soft_reset(const ProgramInfo& info, VideoStream& stream, ProControllerConte context.wait_for_all_requests(); } +void open_slot_six(ConsoleHandle& console, ProControllerContext& context){ + //Attempt to exit any dialog and open the start menu + StartMenuWatcher start_menu(COLOR_RED); + + int ret = run_until( + console, context, + [](ProControllerContext& context) { + for (int i = 0; i < 10; i++) { + pbf_press_button(context, BUTTON_B, 320ms, 640ms); + pbf_wait(context, 100ms); + context.wait_for_all_requests(); + pbf_press_button(context, BUTTON_PLUS, 320ms, 640ms); + } + }, + { start_menu } + ); + context.wait_for_all_requests(); + if (ret < 0){ + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "open_slot_six(): Unable to open Start menu.", + console + ); + } + + console.log("Navigating to party menu."); + pbf_wait(context, 200ms); + context.wait_for_all_requests(); + pbf_press_dpad(context, DPAD_DOWN, 320ms, 320ms); + context.wait_for_all_requests(); + + BlackScreenOverWatcher blk1(COLOR_RED, {0.282, 0.064, 0.448, 0.871}); + int ret1 = wait_until( + console, context, + 5s, + {blk1} + ); + if (ret1 == 0){ + console.log("Entered party menu."); + }else{ + console.log("Unable to enter Party menu.", COLOR_RED); + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "open_slot_six(): Unable to enter Party menu.", + console + ); + } + context.wait_for_all_requests(); + + //Press up twice to get to the last slot + pbf_press_dpad(context, DPAD_UP, 320ms, 320ms); + pbf_press_dpad(context, DPAD_UP, 320ms, 320ms); + + //Two presses to open summary + pbf_press_button(context, BUTTON_A, 320ms, 640ms); + pbf_press_button(context, BUTTON_A, 320ms, 640ms); + + BlackScreenOverWatcher blk2(COLOR_RED, {0.282, 0.064, 0.448, 0.871}); + int ret2 = wait_until( + console, context, + 5s, + {blk2} + ); + if (ret2 == 0){ + console.log("Entered summary."); + }else{ + console.log("Unable to enter summary.", COLOR_RED); + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "open_slot_six(): Unable to enter summary.", + console + ); + } + pbf_wait(context, 1000ms); + context.wait_for_all_requests(); +} + /* bool handle_encounter(VideoStream& stream, ProControllerContext& context, bool send_out_lead) { float shiny_coefficient = 1.0; diff --git a/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.h b/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.h index 832b31629..46389e4b8 100644 --- a/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.h +++ b/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.h @@ -13,14 +13,19 @@ #include "NintendoSwitch/Controllers/Procon/NintendoSwitch_ProController.h" namespace PokemonAutomation{ - struct ProgramInfo; namespace NintendoSwitch{ + class ConsoleHandle; + class ProController; + using ProControllerContext = ControllerContext; namespace PokemonFRLG{ // Press A+B+Select+Start at the same time to soft reset, then re-enters the game. // For now this assumes no dry battery. void soft_reset(const ProgramInfo& info, VideoStream& stream, ProControllerContext &context); +// From the overworld, open the summary of the Pokemon in slot 6. This assumes the menu cursor is in the top slot (POKEDEX) +void open_slot_six(ConsoleHandle& console, ProControllerContext& context); + // After press A/walking up to enter a battle, run this handle the battle start and to check if opponent is shiny. // Set send_out_lead to true and then use flee_battle() after if game is Emerald. // For R/S, send_out_lead as false and then soft_reset() to save time. From 8bfb45f26a3d9b71903d0c17e65764d503107161 Mon Sep 17 00:00:00 2001 From: kichithewolf Date: Sun, 22 Feb 2026 16:09:59 -0500 Subject: [PATCH 3/3] prize corner reset --- .../PokemonFRLG/PokemonFRLG_Navigation.cpp | 2 + .../Source/PokemonFRLG/PokemonFRLG_Panels.cpp | 2 + .../PokemonFRLG_PrizeCornerReset.cpp | 183 ++++++++++++++++++ .../PokemonFRLG_PrizeCornerReset.h | 54 ++++++ SerialPrograms/cmake/SourceFiles.cmake | 4 + 5 files changed, 245 insertions(+) create mode 100644 SerialPrograms/Source/PokemonFRLG/Programs/ShinyHunting/PokemonFRLG_PrizeCornerReset.cpp create mode 100644 SerialPrograms/Source/PokemonFRLG/Programs/ShinyHunting/PokemonFRLG_PrizeCornerReset.h diff --git a/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.cpp b/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.cpp index d4fa7003d..c446dd02d 100644 --- a/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.cpp +++ b/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.cpp @@ -88,6 +88,8 @@ void open_slot_six(ConsoleHandle& console, ProControllerContext& context){ pbf_press_dpad(context, DPAD_DOWN, 320ms, 320ms); context.wait_for_all_requests(); + pbf_press_button(context, BUTTON_A, 320ms, 640ms); + BlackScreenOverWatcher blk1(COLOR_RED, {0.282, 0.064, 0.448, 0.871}); int ret1 = wait_until( console, context, diff --git a/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Panels.cpp b/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Panels.cpp index e6fc6bd06..0a13424a5 100644 --- a/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Panels.cpp +++ b/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Panels.cpp @@ -11,6 +11,7 @@ #include "PokemonFRLG_Settings.h" #include "Programs/ShinyHunting/PokemonFRLG_GiftReset.h" +#include "Programs/ShinyHunting/PokemonFRLG_PrizeCornerReset.h" #include "Programs/TestPrograms/PokemonFRLG_SoundListener.h" namespace PokemonAutomation{ @@ -33,6 +34,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()); if (PreloadSettings::instance().DEVELOPER_MODE){ diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/ShinyHunting/PokemonFRLG_PrizeCornerReset.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/ShinyHunting/PokemonFRLG_PrizeCornerReset.cpp new file mode 100644 index 000000000..092a5614c --- /dev/null +++ b/SerialPrograms/Source/PokemonFRLG/Programs/ShinyHunting/PokemonFRLG_PrizeCornerReset.cpp @@ -0,0 +1,183 @@ +/* Prize Corner Reset + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#include "CommonFramework/Exceptions/OperationFailedException.h" +#include "CommonFramework/ProgramStats/StatsTracking.h" +#include "CommonFramework/Notifications/ProgramNotifications.h" +#include "CommonFramework/ProgramStats/StatsTracking.h" +#include "CommonFramework/VideoPipeline/VideoFeed.h" +#include "CommonTools/Async/InferenceRoutines.h" +#include "CommonTools/VisualDetectors/BlackScreenDetector.h" +#include "CommonTools/StartupChecks/StartProgramChecks.h" +#include "Pokemon/Pokemon_Strings.h" +#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" +#include "PokemonFRLG/Inference/Dialogs/PokemonFRLG_DialogDetector.h" +#include "PokemonFRLG/Inference/Dialogs/PokemonFRLG_PrizeSelectDetector.h" +#include "PokemonFRLG/Inference/Menus/PokemonFRLG_StartMenuDetector.h" +#include "PokemonFRLG/Inference/PokemonFRLG_ShinySymbolDetector.h" +#include "PokemonFRLG/PokemonFRLG_Navigation.h" +#include "PokemonFRLG_PrizeCornerReset.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonFRLG{ + +PrizeCornerReset_Descriptor::PrizeCornerReset_Descriptor() + : SingleSwitchProgramDescriptor( + "PokemonFRLG:PrizeCornerReset", + Pokemon::STRING_POKEMON + " FRLG", "Prize Corner Reset", + "Programs/PokemonFRLG/PrizeCornerReset.html", + "Redeem and soft reset for a shiny Game Corner prize.", + ProgramControllerClass::StandardController_RequiresPrecision, + FeedbackType::REQUIRED, + AllowCommandsWhenRunning::DISABLE_COMMANDS + ) +{} + +struct PrizeCornerReset_Descriptor::Stats : public StatsTracker{ + Stats() + : resets(m_stats["Resets"]) + , shinies(m_stats["Shinies"]) + , errors(m_stats["Errors"]) + { + m_display_order.emplace_back("Resets"); + m_display_order.emplace_back("Shinies"); + m_display_order.emplace_back("Errors", HIDDEN_IF_ZERO); + } + std::atomic& resets; + std::atomic& shinies; + std::atomic& errors; +}; +std::unique_ptr PrizeCornerReset_Descriptor::make_stats() const{ + return std::unique_ptr(new Stats()); +} + +PrizeCornerReset::PrizeCornerReset() + : SLOT( + "Slot:
Position of the prize in the selection dialog.", + { + {0, "slot0", "Slot 1 (Abra)"}, + {1, "slot1", "Slot 2 (Clefairy)"}, + {2, "slot2", "Slot 3 (FR: Dratini / LG: Pinsir)"}, + {3, "slot3", "Slot 4 (FR: Scyther / LG: Dratini)"}, + {4, "slot4", "Slot 5 (Porygon)"}, + }, + LockMode::LOCK_WHILE_RUNNING, + 0 + ) + , GO_HOME_WHEN_DONE(true) + , NOTIFICATION_SHINY( + "Shiny", + true, true, ImageAttachmentMode::JPG, + {"Notifs", "Showcase"} + ) + , NOTIFICATION_STATUS_UPDATE("Status Update", true, false, std::chrono::seconds(3600)) + , NOTIFICATIONS({ + &NOTIFICATION_SHINY, + &NOTIFICATION_STATUS_UPDATE, + &NOTIFICATION_PROGRAM_FINISH, + }) +{ + PA_ADD_OPTION(SLOT); + PA_ADD_OPTION(GO_HOME_WHEN_DONE); + PA_ADD_OPTION(NOTIFICATIONS); +} + +void PrizeCornerReset::obtain_prize(SingleSwitchProgramEnvironment& env, ProControllerContext& context){ + PrizeCornerReset_Descriptor::Stats& stats = env.current_stats(); + + env.log("Talking to booth."); + pbf_press_button(context, BUTTON_A, 320ms, 640ms); + + PrizeSelectWatcher prize_dialog(COLOR_RED); + + //Only 1 line to press through in english, not sure about other languages? + int ret = run_until( + env.console, context, + [](ProControllerContext& context) { + for (int i = 0; i < 5; i++) { + pbf_press_button(context, BUTTON_B, 320ms, 320ms); + pbf_wait(context, 600ms); //Don't go too fast, have to let the box pop up + context.wait_for_all_requests(); + } + }, + { prize_dialog } + ); + context.wait_for_all_requests(); + if (ret < 0){ + stats.errors++; + env.update_stats(); + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "obtain_prize(): Unable to find prize menu.", + env.console + ); + } + + //Select prize slot + env.log("Selecting prize."); + for (uint16_t c = 0; c < (uint16_t)SLOT.current_value(); c++){ + pbf_press_dpad(context, DPAD_DOWN, 320ms, 320ms); + } + context.wait_for_all_requests(); + + //Select prize + pbf_press_button(context, BUTTON_A, 320ms, 640ms); + pbf_press_button(context, BUTTON_A, 320ms, 640ms); + + //Exit dialog + pbf_mash_button(context, BUTTON_B, 2000ms); + context.wait_for_all_requests(); +} + +void PrizeCornerReset::program(SingleSwitchProgramEnvironment& env, ProControllerContext& context){ + PrizeCornerReset_Descriptor::Stats& stats = env.current_stats(); + + /* + * Settings: Text Speed fast. Default borders. + * Setup: Have a party of 5. Stand in front of the prize redemption. Save game. Move cursor back to top. + * Make sure you can afford the prize. + */ + + bool shiny_found = false; + + while (!shiny_found) { + obtain_prize(env, context); + open_slot_six(env.console, context); + + VideoSnapshot screen = env.console.video().snapshot(); + + ShinySymbolDetector shiny_checker(COLOR_YELLOW); + shiny_found = shiny_checker.read(env.console.logger(), screen); + + if (shiny_found) { + env.log("Shiny found!"); + stats.shinies++; + send_program_notification(env, NOTIFICATION_SHINY, COLOR_YELLOW, "Shiny found!", {}, "", screen, true); + break; + } else { + env.log("Prize is not shiny."); + env.log("Soft resetting."); + send_program_status_notification( + env, NOTIFICATION_STATUS_UPDATE, + "Soft resetting." + ); + soft_reset(env.program_info(), env.console, context); + stats.resets++; + context.wait_for_all_requests(); + } + } + + if (GO_HOME_WHEN_DONE) { + pbf_press_button(context, BUTTON_HOME, 200ms, 1000ms); + } + send_program_finished_notification(env, NOTIFICATION_PROGRAM_FINISH); +} + +} +} +} + diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/ShinyHunting/PokemonFRLG_PrizeCornerReset.h b/SerialPrograms/Source/PokemonFRLG/Programs/ShinyHunting/PokemonFRLG_PrizeCornerReset.h new file mode 100644 index 000000000..1fc518c5e --- /dev/null +++ b/SerialPrograms/Source/PokemonFRLG/Programs/ShinyHunting/PokemonFRLG_PrizeCornerReset.h @@ -0,0 +1,54 @@ +/* Prize Corner Reset + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#ifndef PokemonAutomation_PokemonFRLG_PrizeCornerReset_H +#define PokemonAutomation_PokemonFRLG_PrizeCornerReset_H + +#include "CommonFramework/Notifications/EventNotificationsTable.h" +#include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h" +#include "NintendoSwitch/Options/NintendoSwitch_GoHomeWhenDoneOption.h" +#include "Common/Cpp/Options/EnumDropdownOption.h" +#include "Common/Cpp/Options/SimpleIntegerOption.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonFRLG{ + +class PrizeCornerReset_Descriptor : public SingleSwitchProgramDescriptor{ +public: + PrizeCornerReset_Descriptor(); + struct Stats; + virtual std::unique_ptr make_stats() const override; +}; + +class PrizeCornerReset : public SingleSwitchProgramInstance{ +public: + PrizeCornerReset(); + virtual void program(SingleSwitchProgramEnvironment& env, ProControllerContext &context) override; + + virtual void start_program_border_check( + VideoStream& stream, + FeedbackType feedback_type + ) override{} + +private: + void obtain_prize(SingleSwitchProgramEnvironment& env, ProControllerContext& context); + + IntegerEnumDropdownOption SLOT; + + GoHomeWhenDoneOption GO_HOME_WHEN_DONE; + + EventNotificationOption NOTIFICATION_SHINY; + EventNotificationOption NOTIFICATION_STATUS_UPDATE; + EventNotificationsOption NOTIFICATIONS; +}; + +} +} +} +#endif + + diff --git a/SerialPrograms/cmake/SourceFiles.cmake b/SerialPrograms/cmake/SourceFiles.cmake index e2ec68075..73970aacb 100644 --- a/SerialPrograms/cmake/SourceFiles.cmake +++ b/SerialPrograms/cmake/SourceFiles.cmake @@ -1401,6 +1401,8 @@ file(GLOB LIBRARY_SOURCES Source/PokemonBDSP/Resources/PokemonBDSP_NameDatabase.h Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_DialogDetector.cpp Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_DialogDetector.h + Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_PrizeSelectDetector.cpp + Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_PrizeSelectDetector.h Source/PokemonFRLG/Inference/Menus/PokemonFRLG_StartMenuDetector.cpp Source/PokemonFRLG/Inference/Menus/PokemonFRLG_StartMenuDetector.h Source/PokemonFRLG/Inference/Sounds/PokemonFRLG_ShinySoundDetector.cpp @@ -1415,6 +1417,8 @@ file(GLOB LIBRARY_SOURCES Source/PokemonFRLG/PokemonFRLG_Settings.h Source/PokemonFRLG/Programs/ShinyHunting/PokemonFRLG_GiftReset.cpp Source/PokemonFRLG/Programs/ShinyHunting/PokemonFRLG_GiftReset.h + Source/PokemonFRLG/Programs/ShinyHunting/PokemonFRLG_PrizeCornerReset.cpp + Source/PokemonFRLG/Programs/ShinyHunting/PokemonFRLG_PrizeCornerReset.h Source/PokemonFRLG/Programs/TestPrograms/PokemonFRLG_SoundListener.cpp Source/PokemonFRLG/Programs/TestPrograms/PokemonFRLG_SoundListener.h Source/PokemonHome/Inference/PokemonHome_BallReader.cpp