diff --git a/SerialPrograms/CMakeLists.txt b/SerialPrograms/CMakeLists.txt index 9929b1374a..28e2e9f453 100644 --- a/SerialPrograms/CMakeLists.txt +++ b/SerialPrograms/CMakeLists.txt @@ -1319,8 +1319,14 @@ file(GLOB MAIN_SOURCES Source/PokemonRSE/Inference/Sounds/PokemonRSE_ShinySoundDetector.h Source/PokemonRSE/Inference/PokemonRSE_ShinyNumberDetector.cpp Source/PokemonRSE/Inference/PokemonRSE_ShinyNumberDetector.h + Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_AudioStarterReset.cpp + Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_AudioStarterReset.h + Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_StarterReset.cpp + Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_StarterReset.h Source/PokemonRSE/Programs/TestPrograms/PokemonRSE_SoundListener.cpp Source/PokemonRSE/Programs/TestPrograms/PokemonRSE_SoundListener.h + Source/PokemonRSE/PokemonRSE_Navigation.cpp + Source/PokemonRSE/PokemonRSE_Navigation.h Source/PokemonRSE/PokemonRSE_Panels.cpp Source/PokemonRSE/PokemonRSE_Panels.h Source/PokemonRSE/PokemonRSE_Settings.cpp diff --git a/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_SingleSwitchProgramSession.cpp b/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_SingleSwitchProgramSession.cpp index 7a4a8e760f..7a6d423518 100644 --- a/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_SingleSwitchProgramSession.cpp +++ b/SerialPrograms/Source/NintendoSwitch/Framework/NintendoSwitch_SingleSwitchProgramSession.cpp @@ -15,6 +15,7 @@ #include "NintendoSwitch/Controllers/NintendoSwitch_Controller.h" #include "NintendoSwitch_SingleSwitchProgramOption.h" #include "NintendoSwitch_SingleSwitchProgramSession.h" +#include "Pokemon/Pokemon_Strings.h" namespace PokemonAutomation{ namespace NintendoSwitch{ @@ -61,7 +62,10 @@ void SingleSwitchProgramSession::run_program_instance(SingleSwitchProgramEnviron // Startup Checks m_option.instance().start_program_controller_check(scope, m_system.controller_session()); m_option.instance().start_program_feedback_check(scope, env.console, m_option.descriptor().feedback()); - m_option.instance().start_program_border_check(scope, env.console); + if (m_option.descriptor().category() != Pokemon::STRING_POKEMON + " RSE" + && m_option.descriptor().category() != Pokemon::STRING_POKEMON + " FRLG"){ + m_option.instance().start_program_border_check(scope, env.console); + } m_scope.store(&scope, std::memory_order_release); diff --git a/SerialPrograms/Source/PokemonRSE/PokemonRSE_Navigation.cpp b/SerialPrograms/Source/PokemonRSE/PokemonRSE_Navigation.cpp new file mode 100644 index 0000000000..e9eb0cf8de --- /dev/null +++ b/SerialPrograms/Source/PokemonRSE/PokemonRSE_Navigation.cpp @@ -0,0 +1,54 @@ +/* Pokemon RSE Navigation + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + * Soft reset, menus, etc. + * + */ + +#include "CommonFramework/Exceptions/OperationFailedException.h" +#include "CommonTools/Async/InferenceRoutines.h" +#include "CommonTools/VisualDetectors/BlackScreenDetector.h" +#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" +#include "NintendoSwitch/Commands/NintendoSwitch_Commands_Superscalar.h" +#include "PokemonRSE/PokemonRSE_Settings.h" +#include "PokemonRSE_Navigation.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonRSE{ + + +void soft_reset(const ProgramInfo& info, VideoStream& stream, SwitchControllerContext& context){ + // A + B + Select + Start + pbf_press_button(context, BUTTON_B | BUTTON_Y | BUTTON_MINUS | BUTTON_PLUS, 10, 180); + + pbf_mash_button(context, BUTTON_PLUS, GameSettings::instance().START_BUTTON_MASH); + context.wait_for_all_requests(); + + pbf_press_button(context, BUTTON_A, 20, 40); + + //Wait for game to load in + BlackScreenOverWatcher detector(COLOR_RED, {0.282, 0.064, 0.448, 0.871}); + int ret = wait_until( + stream, context, + std::chrono::milliseconds(GameSettings::instance().ENTER_GAME_WAIT * (1000 / TICKS_PER_SECOND)), + {{detector}} + ); + if (ret == 0){ + stream.log("Entered game!"); + }else{ + stream.log("Timed out waiting to enter game.", COLOR_RED); + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "soft_reset(): Timed out waiting to enter game.", + stream + ); + } + context.wait_for_all_requests(); +} + + +} +} +} diff --git a/SerialPrograms/Source/PokemonRSE/PokemonRSE_Navigation.h b/SerialPrograms/Source/PokemonRSE/PokemonRSE_Navigation.h new file mode 100644 index 0000000000..9e3fffa68a --- /dev/null +++ b/SerialPrograms/Source/PokemonRSE/PokemonRSE_Navigation.h @@ -0,0 +1,29 @@ +/* Pokemon RSE Navigation + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + * Soft reset, menus, etc. + * + */ + +#ifndef PokemonAutomation_PokemonRSE_Navigation_H +#define PokemonAutomation_PokemonRSE_Navigation_H + +#include "CommonFramework/Tools/VideoStream.h" +#include "Common/NintendoSwitch/NintendoSwitch_ControllerDefs.h" +#include "NintendoSwitch/Controllers/NintendoSwitch_Controller.h" + +namespace PokemonAutomation{ + struct ProgramInfo; +namespace NintendoSwitch{ +namespace PokemonRSE{ + +// 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, SwitchControllerContext &context); + + +} +} +} +#endif diff --git a/SerialPrograms/Source/PokemonRSE/PokemonRSE_Panels.cpp b/SerialPrograms/Source/PokemonRSE/PokemonRSE_Panels.cpp index b756ecb002..b112bd936e 100644 --- a/SerialPrograms/Source/PokemonRSE/PokemonRSE_Panels.cpp +++ b/SerialPrograms/Source/PokemonRSE/PokemonRSE_Panels.cpp @@ -10,8 +10,8 @@ #include "PokemonRSE_Settings.h" -//#include "Programs/ShinyHunting/PokemonRSE_AudioStarterReset.h" -//#include "Programs/ShinyHunting/PokemonRSE_StarterReset.h" +#include "Programs/ShinyHunting/PokemonRSE_AudioStarterReset.h" +#include "Programs/ShinyHunting/PokemonRSE_StarterReset.h" #include "Programs/TestPrograms/PokemonRSE_SoundListener.h" namespace PokemonAutomation{ @@ -33,12 +33,12 @@ std::vector PanelListFactory::make_panels() const{ //ret.emplace_back("---- General ----"); ret.emplace_back("---- Shiny Hunting ----"); - //ret.emplace_back(make_single_switch_program()); + ret.emplace_back(make_single_switch_program()); if (PreloadSettings::instance().DEVELOPER_MODE){ ret.emplace_back("---- Test ----"); - //ret.emplace_back(make_single_switch_program()); //outdated early test program + ret.emplace_back(make_single_switch_program()); //outdated early test program ret.emplace_back("---- Developer Tools ----"); ret.emplace_back(make_single_switch_program()); diff --git a/SerialPrograms/Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_AudioStarterReset.cpp b/SerialPrograms/Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_AudioStarterReset.cpp new file mode 100644 index 0000000000..345cc968d4 --- /dev/null +++ b/SerialPrograms/Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_AudioStarterReset.cpp @@ -0,0 +1,221 @@ +/* RS Starter Reset + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#include "CommonFramework/Exceptions/OperationFailedException.h" +#include "CommonFramework/ProgramStats/StatsTracking.h" +#include "CommonFramework/VideoPipeline/VideoFeed.h" +#include "CommonTools/Async/InferenceRoutines.h" +#include "CommonFramework/Notifications/ProgramNotifications.h" +#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" +#include "Pokemon/Pokemon_Strings.h" +#include "PokemonRSE/Inference/Dialogs/PokemonRSE_DialogDetector.h" +#include "PokemonRSE/Inference/Sounds/PokemonRSE_ShinySoundDetector.h" +#include "PokemonRSE/PokemonRSE_Navigation.h" +#include "PokemonRSE_AudioStarterReset.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonRSE{ + +AudioStarterReset_Descriptor::AudioStarterReset_Descriptor() + : SingleSwitchProgramDescriptor( + "PokemonRSE:AudioStarterReset", + Pokemon::STRING_POKEMON + " RSE", "Starter Reset (Ruby/Sapphire)", + "ComputerControl/blob/master/Wiki/Programs/PokemonRSE/AudioStarterReset.md", + "Soft reset for a shiny starter. Ruby and Sapphire only.", + FeedbackType::VIDEO_AUDIO, + AllowCommandsWhenRunning::DISABLE_COMMANDS, + {SerialPABotBase::OLD_NINTENDO_SWITCH_DEFAULT_REQUIREMENTS} + ) +{} + +struct AudioStarterReset_Descriptor::Stats : public StatsTracker{ + Stats() + : resets(m_stats["Resets"]) + , poochyena(m_stats["Shiny Poochyena"]) + , shinystarter(m_stats["Shiny Starter"]) + { + m_display_order.emplace_back("Resets"); + m_display_order.emplace_back("Shiny Poochyena"); + m_display_order.emplace_back("Shiny Starter"); + } + std::atomic& resets; + std::atomic& poochyena; + std::atomic& shinystarter; +}; +std::unique_ptr AudioStarterReset_Descriptor::make_stats() const{ + return std::unique_ptr(new Stats()); +} + +AudioStarterReset::AudioStarterReset() + : TARGET( + "Starter:
", + { + {Target::treecko, "treecko", "Treecko"}, + {Target::torchic, "torchic", "Torchic"}, + {Target::mudkip, "mudkip", "Mudkip"}, + }, + LockMode::LOCK_WHILE_RUNNING, + Target::treecko + ) + , NOTIFICATION_SHINY_POOCH( + "Shiny Poochyena", + false, false, ImageAttachmentMode::JPG, + {"Notifs"} + ) + , NOTIFICATION_SHINY_STARTER( + "Shiny Starter", + true, true, ImageAttachmentMode::JPG, + {"Notifs", "Showcase"} + ) + , NOTIFICATION_STATUS_UPDATE("Status Update", true, false, std::chrono::seconds(3600)) + , NOTIFICATIONS({ + &NOTIFICATION_SHINY_POOCH, + &NOTIFICATION_SHINY_STARTER, + &NOTIFICATION_STATUS_UPDATE, + &NOTIFICATION_PROGRAM_FINISH, + }) +{ + PA_ADD_OPTION(TARGET); + PA_ADD_OPTION(NOTIFICATIONS); +} + +void AudioStarterReset::program(SingleSwitchProgramEnvironment& env, SwitchControllerContext& context){ + AudioStarterReset_Descriptor::Stats& stats = env.current_stats(); + + /* + * Settings: Text Speed fast. + * Full screen, no filter? The device I'm using to test has similar looking output, but I don't have switch online+. + * If on a retro handheld, make sure the screen matches that of NSO+. + * + * Setup: Stand in front of the Professor's bag and save the game. + * + * Required to fight, so have to do the SR method instead of run away + * Soft reset programs are only for Ruby/Sapphire, as Emerald has the 0 seed issue. + * + * This also assumes no dry battery. + */ + + bool shiny_starter = false; + while (!shiny_starter) { + float shiny_coefficient = 1.0; + ShinySoundDetector pooch_detector(env.console, [&](float error_coefficient) -> bool{ + shiny_coefficient = error_coefficient; + return true; + }); + + env.log("Opening bag and selecting starter."); + pbf_press_button(context, BUTTON_A, 40, 180); + + switch (TARGET) { + case Target::treecko: + pbf_press_dpad(context, DPAD_LEFT, 40, 100); + break; + case Target::torchic: + //Default cursor position, do nothing. + break; + case Target::mudkip: + pbf_press_dpad(context, DPAD_RIGHT, 40, 100); + break; + default: + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "AudioStarterReset: Invalid target.", + env.console + ); + break; + } + pbf_mash_button(context, BUTTON_A, 540); + context.wait_for_all_requests(); + + env.log("Starter selected. Checking for shiny Poochyena."); + AdvanceBattleDialogWatcher pooch_appeared(COLOR_YELLOW); + + int res = run_until( + env.console, context, + [&](SwitchControllerContext& context) { + int ret = wait_until( + env.console, context, + std::chrono::seconds(20), + {{pooch_appeared}} + ); + if (ret == 0) { + env.log("Advance arrow detected."); + } + pbf_wait(context, 125); + context.wait_for_all_requests(); + }, + {{pooch_detector}} + ); + pooch_detector.throw_if_no_sound(); + if (res == 0){ + env.log("Shiny Poochyena detected!"); + stats.poochyena++; + env.update_stats(); + send_program_notification(env, NOTIFICATION_SHINY_POOCH, COLOR_YELLOW, "Shiny Poochyena found", {}, "", env.console.video().snapshot(), true); + } + else { + env.log("Poochyena is not shiny."); + } + context.wait_for_all_requests(); + + float shiny_coefficient2 = 1.0; + ShinySoundDetector starter_detector(env.console, [&](float error_coefficient) -> bool{ + shiny_coefficient2 = error_coefficient; + return true; + }); + + BattleMenuWatcher battle_menu(COLOR_RED); + int res2 = run_until( + env.console, context, + [&](SwitchControllerContext& context) { + env.log("Sending out selected starter."); + pbf_press_button(context, BUTTON_A, 40, 40); + + int ret = wait_until( + env.console, context, + std::chrono::seconds(20), + {{battle_menu}} + ); + if (ret == 0) { + env.log("Battle menu detecteed!"); + } + pbf_wait(context, 125); + context.wait_for_all_requests(); + }, + {{starter_detector}} + ); + starter_detector.throw_if_no_sound(); + context.wait_for_all_requests(); + if (res2 == 0){ + env.log("Shiny starter detected!"); + stats.shinystarter++; + env.update_stats(); + send_program_notification(env, NOTIFICATION_SHINY_STARTER, COLOR_YELLOW, "Shiny starter found!", {}, "", env.console.video().snapshot(), true); + shiny_starter = true; + } + else { + env.log("Starter is not shiny."); + env.log("Soft resetting."); + send_program_status_notification( + env, NOTIFICATION_STATUS_UPDATE, + "Soft resetting." + ); + stats.resets++; + env.update_stats(); + soft_reset(env.program_info(), env.console, context); + } + } + + //if system set to nintendo switch, have go home when done option? + + send_program_finished_notification(env, NOTIFICATION_PROGRAM_FINISH); +} + +} +} +} + diff --git a/SerialPrograms/Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_AudioStarterReset.h b/SerialPrograms/Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_AudioStarterReset.h new file mode 100644 index 0000000000..678027d89a --- /dev/null +++ b/SerialPrograms/Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_AudioStarterReset.h @@ -0,0 +1,51 @@ +/* RS Starter Reset + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#ifndef PokemonAutomation_PokemonRSE_AudioStarterReset_H +#define PokemonAutomation_PokemonRSE_AudioStarterReset_H + +#include "Common/Cpp/Options/SimpleIntegerOption.h" +#include "Common/Cpp/Options/TimeExpressionOption.h" +#include "CommonFramework/Notifications/EventNotificationsTable.h" +#include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonRSE{ + +class AudioStarterReset_Descriptor : public SingleSwitchProgramDescriptor{ +public: + AudioStarterReset_Descriptor(); + struct Stats; + virtual std::unique_ptr make_stats() const override; +}; + +class AudioStarterReset : public SingleSwitchProgramInstance{ +public: + AudioStarterReset(); + virtual void program(SingleSwitchProgramEnvironment& env, SwitchControllerContext& context) override; + +private: + enum class Target{ + treecko, + torchic, + mudkip, + }; + EnumDropdownOption TARGET; + + EventNotificationOption NOTIFICATION_SHINY_POOCH; + EventNotificationOption NOTIFICATION_SHINY_STARTER; + EventNotificationOption NOTIFICATION_STATUS_UPDATE; + EventNotificationsOption NOTIFICATIONS; +}; + +} +} +} +#endif + + + diff --git a/SerialPrograms/Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_StarterReset.cpp b/SerialPrograms/Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_StarterReset.cpp new file mode 100644 index 0000000000..4ee337f776 --- /dev/null +++ b/SerialPrograms/Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_StarterReset.cpp @@ -0,0 +1,208 @@ +/* RS Starter Reset + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#include "CommonFramework/Exceptions/OperationFailedException.h" +#include "CommonFramework/ProgramStats/StatsTracking.h" +#include "CommonTools/Async/InferenceRoutines.h" +#include "CommonTools/VisualDetectors/BlackScreenDetector.h" +#include "CommonFramework/Notifications/ProgramNotifications.h" +#include "CommonFramework/ProgramStats/StatsTracking.h" +#include "CommonFramework/VideoPipeline/VideoFeed.h" +#include "Pokemon/Pokemon_Strings.h" +#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" +#include "PokemonRSE/Inference/Dialogs/PokemonRSE_DialogDetector.h" +#include "PokemonRSE/Inference/PokemonRSE_ShinyNumberDetector.h" +#include "PokemonRSE/PokemonRSE_Navigation.h" +#include "PokemonRSE_StarterReset.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonRSE{ + +StarterReset_Descriptor::StarterReset_Descriptor() + : SingleSwitchProgramDescriptor( + "PokemonRSE:StarterReset", + Pokemon::STRING_POKEMON + " RSE", "[RS]Starter Reset - Video", + "ComputerControl/blob/master/Wiki/Programs/PokemonRSE/StarterReset.md", + "Soft reset for a shiny starter. Ruby and Sapphire only.", + FeedbackType::REQUIRED, + AllowCommandsWhenRunning::DISABLE_COMMANDS, + {SerialPABotBase::OLD_NINTENDO_SWITCH_DEFAULT_REQUIREMENTS} + ) +{} + +struct StarterReset_Descriptor::Stats : public StatsTracker{ + Stats() + : resets(m_stats["Resets"]) + , shinystarter(m_stats["Shiny Starter"]) + { + m_display_order.emplace_back("Resets"); + m_display_order.emplace_back("Shiny Starter"); + } + std::atomic& resets; + std::atomic& shinystarter; +}; +std::unique_ptr StarterReset_Descriptor::make_stats() const{ + return std::unique_ptr(new Stats()); +} + +StarterReset::StarterReset() + : TARGET( + "Starter:
", + { + {Target::treecko, "treecko", "Treecko"}, + {Target::torchic, "torchic", "Torchic"}, + {Target::mudkip, "mudkip", "Mudkip"}, + }, + LockMode::LOCK_WHILE_RUNNING, + Target::treecko + ) + , STARTER_WAIT( + "Send out starter wait:
After pressing A to send out your selected starter, wait this long for the animation. Make sure to add extra time in case it is shiny.", + LockMode::LOCK_WHILE_RUNNING, + TICKS_PER_SECOND, + "6 * TICKS_PER_SECOND" + ) + , NOTIFICATION_SHINY_STARTER( + "Shiny Starter", + true, true, ImageAttachmentMode::JPG, + {"Notifs", "Showcase"} + ) + , NOTIFICATION_STATUS_UPDATE("Status Update", true, false, std::chrono::seconds(3600)) + , NOTIFICATIONS({ + &NOTIFICATION_SHINY_STARTER, + &NOTIFICATION_STATUS_UPDATE, + &NOTIFICATION_PROGRAM_FINISH, + }) +{ + PA_ADD_OPTION(TARGET); + PA_ADD_OPTION(NOTIFICATIONS); +} + +void StarterReset::program(SingleSwitchProgramEnvironment& env, SwitchControllerContext& context){ + StarterReset_Descriptor::Stats& stats = env.current_stats(); + + /* + * Settings: Text Speed fast. + * Full screen, no filter? The device I'm using to test has similar looking output, but I don't have switch online+. + * If on a retro handheld, make sure the screen matches that of NSO+. + * + * Setup: Stand in front of the Professor's bag and save the game. + * + * Required to fight, so have to do the SR method instead of run away + * Soft reset programs are only for Ruby/Sapphire, as Emerald has the 0 seed issue. + * + * This also assumes no dry battery. + * + * WARNING: Timings in Emerald for the battle menu are slightly different. This won't work with Emerald at all. + */ + + bool shiny_starter = false; + while (!shiny_starter) { + env.log("Opening bag and selecting starter."); + pbf_press_button(context, BUTTON_A, 40, 180); + + switch (TARGET) { + case Target::treecko: + pbf_press_dpad(context, DPAD_LEFT, 40, 100); + break; + case Target::torchic: + //Default cursor position, do nothing. + break; + case Target::mudkip: + pbf_press_dpad(context, DPAD_RIGHT, 40, 100); + break; + default: + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "StarterReset: Invalid target.", + env.console + ); + break; + } + pbf_mash_button(context, BUTTON_A, 540); + context.wait_for_all_requests(); + + env.log("Starting battle."); + + //Now mash B until the battle menu appears + BattleMenuWatcher battle_menu(COLOR_RED); + int ret = run_until( + env.console, context, + [](SwitchControllerContext& context){ + pbf_mash_button(context, BUTTON_B, 1000); + }, + {battle_menu} + ); + context.wait_for_all_requests(); + if (ret != 0){ + env.console.log("Failed to detect battle menu.", COLOR_RED); + } + else { + env.log("Battle menu detected."); + } + + //Open the summary and check the color of the number + pbf_press_dpad(context, DPAD_DOWN, 40, 80); + pbf_press_button(context, BUTTON_A, 40, 80); + + BlackScreenOverWatcher detector(COLOR_RED, {0.282, 0.064, 0.448, 0.871}); + int ret2 = wait_until( + env.console, context, + std::chrono::milliseconds(3000), + {{detector}} + ); + if (ret2 == 0){ + env.log("Entered party menu."); + }else{ + env.log("Timed out waiting to enter party menu.", COLOR_RED); + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "StarterReset: Timed out waiting to enter party menu.", + env.console + ); + } + + pbf_press_button(context, BUTTON_A, 20, 180); + pbf_press_dpad(context, DPAD_DOWN, 40, 80); + pbf_press_button(context, BUTTON_A, 40, 80); + + //Check second party member - used for testing with hacked in shiny starter + //pbf_press_dpad(context, DPAD_DOWN, 40, 80); + + pbf_wait(context, 125); + context.wait_for_all_requests(); + + VideoSnapshot screen = env.console.video().snapshot(); + ShinyNumberDetector shiny_checker(COLOR_YELLOW); + shiny_starter = shiny_checker.read(env.console.logger(), screen); + + if (shiny_starter) { + env.log("Shiny starter detected!"); + stats.shinystarter++; + send_program_status_notification(env, NOTIFICATION_SHINY_STARTER, "Shiny starter found!", screen, true); + } + else { + env.log("Starter 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++; + } + } + + //if system set to nintendo switch, have go home when done option? + + send_program_finished_notification(env, NOTIFICATION_PROGRAM_FINISH); +} + +} +} +} + diff --git a/SerialPrograms/Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_StarterReset.h b/SerialPrograms/Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_StarterReset.h new file mode 100644 index 0000000000..9f189a6ef7 --- /dev/null +++ b/SerialPrograms/Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_StarterReset.h @@ -0,0 +1,52 @@ +/* RS Starter Reset + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#ifndef PokemonAutomation_PokemonRSE_StarterReset_H +#define PokemonAutomation_PokemonRSE_StarterReset_H + +#include "Common/Cpp/Options/SimpleIntegerOption.h" +#include "Common/Cpp/Options/TimeExpressionOption.h" +#include "CommonFramework/Notifications/EventNotificationsTable.h" +#include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonRSE{ + +class StarterReset_Descriptor : public SingleSwitchProgramDescriptor{ +public: + StarterReset_Descriptor(); + struct Stats; + virtual std::unique_ptr make_stats() const override; +}; + +class StarterReset : public SingleSwitchProgramInstance{ +public: + StarterReset(); + virtual void program(SingleSwitchProgramEnvironment& env, SwitchControllerContext &context) override; + +private: + enum class Target{ + treecko, + torchic, + mudkip, + }; + EnumDropdownOption TARGET; + + TimeExpressionOption STARTER_WAIT; + + EventNotificationOption NOTIFICATION_SHINY_STARTER; + EventNotificationOption NOTIFICATION_STATUS_UPDATE; + EventNotificationsOption NOTIFICATIONS; +}; + +} +} +} +#endif + + +