diff --git a/SerialPrograms/Source/PokemonLZA/PokemonLZA_Panels.cpp b/SerialPrograms/Source/PokemonLZA/PokemonLZA_Panels.cpp index 71a4b0fd6f..870ab5f524 100644 --- a/SerialPrograms/Source/PokemonLZA/PokemonLZA_Panels.cpp +++ b/SerialPrograms/Source/PokemonLZA/PokemonLZA_Panels.cpp @@ -15,6 +15,7 @@ #include "Programs/PokemonLZA_ClothingBuyer.h" #include "Programs/PokemonLZA_StallBuyer.h" #include "Programs/PokemonLZA_PostKillCatcher.h" +#include "Programs/PokemonLZA_TurboMacro.h" // Trading #include "Programs/Trading/PokemonLZA_SelfBoxTrade.h" @@ -79,6 +80,7 @@ std::vector PanelListFactory::make_panels() const{ ret.emplace_back(make_single_switch_program()); ret.emplace_back(make_single_switch_program()); if (IS_BETA_VERSION){ + ret.emplace_back(make_single_switch_program()); } ret.emplace_back("---- Farming ----"); diff --git a/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_TurboMacro.cpp b/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_TurboMacro.cpp new file mode 100644 index 0000000000..1cddbc0f0a --- /dev/null +++ b/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_TurboMacro.cpp @@ -0,0 +1,155 @@ +/* Turbo Macro + * + * From: https://github.com/PokemonAutomation/ + * + */ + + +#include "CommonTools/Async/InferenceRoutines.h" +#include "PokemonLA/Inference/Sounds/PokemonLA_ShinySoundDetector.h" +#include "PokemonLZA/Options/PokemonLZA_ShinyDetectedAction.h" +#include "NintendoSwitch/Programs/NintendoSwitch_GameEntry.h" +#include "Pokemon/Pokemon_Strings.h" +#include "CommonFramework/ProgramStats/StatsTracking.h" +#include "CommonFramework/Notifications/ProgramNotifications.h" +#include "PokemonLZA_TurboMacro.h" + +//#include +//using std::cout; +//using std::endl; + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonLZA{ + +using namespace Pokemon; + +LZA_TurboMacro_Descriptor::LZA_TurboMacro_Descriptor() + : SingleSwitchProgramDescriptor( + "PokemonLZA:TurboMacro", STRING_POKEMON + " LZA", + "Turbo Macro", + "Programs/NintendoSwitch/TurboMacro.html", + "Create macros. Stops with specific trigger (e.g. shiny sound).", + ProgramControllerClass::StandardController_NoRestrictions, + FeedbackType::NONE, + AllowCommandsWhenRunning::DISABLE_COMMANDS + ) +{} + +class LZA_TurboMacro_Descriptor::Stats : public StatsTracker{ +public: + Stats() + : loops(m_stats["Loops"]) + , shinies(m_stats["Shiny Sounds"]) + , errors(m_stats["Errors"]) + { + m_display_order.emplace_back("Loops"); + m_display_order.emplace_back("Shiny Sounds"); + m_display_order.emplace_back("Errors", HIDDEN_IF_ZERO); + } + + std::atomic& loops; + std::atomic& shinies; + std::atomic& errors; +}; +std::unique_ptr LZA_TurboMacro_Descriptor::make_stats() const{ + return std::unique_ptr(new Stats()); +} + +LZA_TurboMacro::LZA_TurboMacro() + : LOOP( + "Number of times to loop:", + LockMode::UNLOCK_WHILE_RUNNING, + 100, 0 + ) + , TABLE( + "Command Schedule:", + { + ControllerClass::NintendoSwitch_ProController, + ControllerClass::NintendoSwitch_LeftJoycon, + ControllerClass::NintendoSwitch_RightJoycon, + } + ) + , GO_HOME_WHEN_DONE(true) + , RUN_UNTIL_CALLBACK( + "Trigger to stop program:", + { + {RunUntilCallback::NONE, "none", "None (stop when done all loops)"}, + {RunUntilCallback::SHINY_SOUND, "shiny-sound", "Shiny Sound Detected"}, + }, + LockMode::LOCK_WHILE_RUNNING, + RunUntilCallback::NONE + ) +{ + PA_ADD_OPTION(LOOP); + PA_ADD_OPTION(GO_HOME_WHEN_DONE); + PA_ADD_OPTION(RUN_UNTIL_CALLBACK); + PA_ADD_OPTION(TABLE); +} + + +void LZA_TurboMacro::program(SingleSwitchProgramEnvironment& env, CancellableScope& scope){ + ProControllerContext context(scope, env.console.controller()); + + switch (RUN_UNTIL_CALLBACK){ + case RunUntilCallback::NONE: + run_table(env, scope); + break; + case RunUntilCallback::SHINY_SOUND: + run_table_stop_when_shiny_sound(env, scope); + break; + default: + throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "TurboMacro::program(): Unknown RunUntilCallback"); + + } + + if (GO_HOME_WHEN_DONE){ + go_home(env.console, context); + } + send_program_finished_notification(env, NOTIFICATION_PROGRAM_FINISH); +} + + +void LZA_TurboMacro::run_table(SingleSwitchProgramEnvironment& env, CancellableScope& scope){ + LZA_TurboMacro_Descriptor::Stats& stats = + env.current_stats(); + for (uint32_t c = 0; c < LOOP; c++){ + TABLE.run(scope, env.console.controller()); + stats.loops++; + env.update_stats(); + } +} + +void LZA_TurboMacro::run_table_stop_when_shiny_sound(SingleSwitchProgramEnvironment& env, CancellableScope& scope){ + LZA_TurboMacro_Descriptor::Stats& stats = + env.current_stats(); + ShinySoundDetectedActionOption shiny_detected_option("Shiny Detected", "", "1000 ms", ShinySoundDetectedAction::NOTIFY_ON_FIRST_ONLY); + ShinySoundHandler shiny_sound_handler(shiny_detected_option); + PokemonLA::ShinySoundDetector shiny_detector(env.console, [&](float error_coefficient) -> bool { + // Warning: This callback will be run from a different thread than this function. + // env.console.overlay().add_log("Shiny Sound Detected!", COLOR_YELLOW); + return shiny_sound_handler.on_shiny_sound( + env, env.console, + 0, + error_coefficient + ); + }); + + int ret = run_until( + env.console, scope, + [&](CancellableScope& scope){ + run_table(env, scope); + }, + {shiny_detector} + ); + + if (ret == 0){ + stats.shinies++; + env.update_stats(); + return; + } +} + +} +} +} diff --git a/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_TurboMacro.h b/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_TurboMacro.h new file mode 100644 index 0000000000..c4ebda8b90 --- /dev/null +++ b/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_TurboMacro.h @@ -0,0 +1,57 @@ +/* Turbo Macro + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#ifndef PokemonAutomation_PokemonLZA_TurboMacro_H +#define PokemonAutomation_PokemonLZA_TurboMacro_H + +#include "Common/Cpp/Options/SimpleIntegerOption.h" +#include "Controllers/ControllerStateTable.h" +#include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h" +#include "NintendoSwitch/Options/NintendoSwitch_GoHomeWhenDoneOption.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonLZA{ + + +class LZA_TurboMacro_Descriptor : public SingleSwitchProgramDescriptor{ +public: + LZA_TurboMacro_Descriptor(); + + class Stats; + virtual std::unique_ptr make_stats() const override; +}; + + +class LZA_TurboMacro : public SingleSwitchProgramInstance{ +public: + LZA_TurboMacro(); + + virtual void program(SingleSwitchProgramEnvironment& env, CancellableScope& scope) override; + + void run_table(SingleSwitchProgramEnvironment& env, CancellableScope& scope); + + void run_table_stop_when_shiny_sound(SingleSwitchProgramEnvironment& env, CancellableScope& scope); + + +private: + SimpleIntegerOption LOOP; + ControllerCommandTables TABLE; + GoHomeWhenDoneOption GO_HOME_WHEN_DONE; + + enum class RunUntilCallback{ + NONE, + SHINY_SOUND, + }; + EnumDropdownOption RUN_UNTIL_CALLBACK; +}; + + + +} +} +} +#endif // PokemonAutomation_PokemonLZA_TurboMacro_H diff --git a/SerialPrograms/cmake/SourceFiles.cmake b/SerialPrograms/cmake/SourceFiles.cmake index 170a19dca2..56846c99fc 100644 --- a/SerialPrograms/cmake/SourceFiles.cmake +++ b/SerialPrograms/cmake/SourceFiles.cmake @@ -1753,6 +1753,8 @@ file(GLOB LIBRARY_SOURCES Source/PokemonLZA/Programs/PokemonLZA_StallBuyer.h Source/PokemonLZA/Programs/PokemonLZA_TrainerBattle.cpp Source/PokemonLZA/Programs/PokemonLZA_TrainerBattle.h + Source/PokemonLZA/Programs/PokemonLZA_TurboMacro.cpp + Source/PokemonLZA/Programs/PokemonLZA_TurboMacro.h Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_AutoFossil.cpp Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_AutoFossil.h Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_BeldumHunter.cpp