diff --git a/SerialPrograms/CMakeLists.txt b/SerialPrograms/CMakeLists.txt index f77fddf39e..f3608098ee 100644 --- a/SerialPrograms/CMakeLists.txt +++ b/SerialPrograms/CMakeLists.txt @@ -1364,10 +1364,14 @@ file(GLOB MAIN_SOURCES Source/PokemonLA/Resources/PokemonLA_WeatherAndTimeIcons.h Source/PokemonLGPE/Inference/PokemonLGPE_ShinySymbolDetector.cpp Source/PokemonLGPE/Inference/PokemonLGPE_ShinySymbolDetector.h - Source/PokemonLGPE/Programs/PokemonLGPE_AlolanTrade.cpp - Source/PokemonLGPE/Programs/PokemonLGPE_AlolanTrade.h + Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.cpp + Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.h + Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp + Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.h Source/PokemonLGPE/PokemonLGPE_Panels.cpp Source/PokemonLGPE/PokemonLGPE_Panels.h + Source/PokemonLGPE/PokemonLGPE_Settings.cpp + Source/PokemonLGPE/PokemonLGPE_Settings.h Source/PokemonRSE/Inference/Dialogs/PokemonRSE_DialogDetector.cpp Source/PokemonRSE/Inference/Dialogs/PokemonRSE_DialogDetector.h Source/PokemonRSE/Inference/Sounds/PokemonRSE_ShinySoundDetector.cpp diff --git a/SerialPrograms/SerialPrograms.pro b/SerialPrograms/SerialPrograms.pro index 9fb53ce8dd..38263c21cb 100644 --- a/SerialPrograms/SerialPrograms.pro +++ b/SerialPrograms/SerialPrograms.pro @@ -669,8 +669,10 @@ SOURCES += \ Source/PokemonLA/Resources/PokemonLA_PokemonSprites.cpp \ Source/PokemonLA/Resources/PokemonLA_WeatherAndTimeIcons.cpp \ Source/PokemonLGPE/Inference/PokemonLGPE_ShinySymbolDetector.cpp \ - Source/PokemonLGPE/Programs/PokemonLGPE_AlolanTrade.cpp \ + Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.cpp \ + Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp \ Source/PokemonLGPE/PokemonLGPE_Panels.cpp \ + Source/PokemonLGPE/PokemonLGPE_Settings.cpp \ Source/PokemonRSE/Inference/Dialogs/PokemonRSE_DialogDetector.cpp \ Source/PokemonRSE/Inference/PokemonRSE_ShinyNumberDetector.cpp \ Source/PokemonRSE/Inference/Sounds/PokemonRSE_ShinySoundDetector.cpp \ @@ -1852,8 +1854,10 @@ HEADERS += \ Source/PokemonLA/Resources/PokemonLA_PokemonSprites.h \ Source/PokemonLA/Resources/PokemonLA_WeatherAndTimeIcons.h \ Source/PokemonLGPE/Inference/PokemonLGPE_ShinySymbolDetector.h \ - Source/PokemonLGPE/Programs/PokemonLGPE_AlolanTrade.h \ + Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.h \ + Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.h \ Source/PokemonLGPE/PokemonLGPE_Panels.h \ + Source/PokemonLGPE/PokemonLGPE_Settings.h \ Source/PokemonRSE/Inference/Dialogs/PokemonRSE_DialogDetector.h \ Source/PokemonRSE/Inference/PokemonRSE_ShinyNumberDetector.h \ Source/PokemonRSE/Inference/Sounds/PokemonRSE_ShinySoundDetector.h \ diff --git a/SerialPrograms/Source/NintendoSwitch/Commands/NintendoSwitch_Commands_Routines.cpp b/SerialPrograms/Source/NintendoSwitch/Commands/NintendoSwitch_Commands_Routines.cpp index cc625bd07a..b5cc55736e 100644 --- a/SerialPrograms/Source/NintendoSwitch/Commands/NintendoSwitch_Commands_Routines.cpp +++ b/SerialPrograms/Source/NintendoSwitch/Commands/NintendoSwitch_Commands_Routines.cpp @@ -72,6 +72,40 @@ void close_game(VideoStream& stream, ProControllerContext& context){ pbf_mash_button(context, BUTTON_B, 350); } +void close_game(VideoStream& stream, JoyconContext& context){ + // Use mashing to ensure that the X press succeeds. If it fails, the SR + // will fail and can kill a den for the autohosts. + + // this sequence will close the game from the home screen, + // regardless of whether the game is initially open or closed. + + // if game initially open. | if game initially closed + pbf_mash_button(context, BUTTON_X, 800ms); // - Close game. | - does nothing + pbf_move_joystick(context, 128, 255, 100ms, 10ms); // - Does nothing. | - moves selector away from the closed game to avoid opening it. + pbf_move_joystick(context, 128, 255, 100ms, 10ms); // - Does nothing. | - Press Down a second time in case we drop one. + pbf_mash_button(context, BUTTON_A, 400ms); // - Confirm close game. | - opens an app on the home screen (e.g. Online) + // - Does nothing. | - goes back to home screen. + pbf_press_button(context, BUTTON_HOME, 160ms, ConsoleSettings::instance().SETTINGS_TO_HOME_DELAY0); + context.wait_for_all_requests(); + + HomeWatcher detector; + int ret = wait_until( + stream, context, + std::chrono::milliseconds(5000), + { detector } + ); + if (ret == 0){ + stream.log("Detected Home screen."); + }else{ // if game initially open. | if game initially closed + // initial Home button press was dropped + // - Does nothing. | - goes back to home screen, from opened app + pbf_press_button(context, BUTTON_HOME, 160ms, ConsoleSettings::instance().SETTINGS_TO_HOME_DELAY0); + } + + // fail-safe against button drops and unexpected error messages. + pbf_mash_button(context, BUTTON_X, 400ms); + pbf_mash_button(context, BUTTON_B, 2000ms); +} } diff --git a/SerialPrograms/Source/NintendoSwitch/Commands/NintendoSwitch_Commands_Routines.h b/SerialPrograms/Source/NintendoSwitch/Commands/NintendoSwitch_Commands_Routines.h index b4c475627a..e4571562f3 100644 --- a/SerialPrograms/Source/NintendoSwitch/Commands/NintendoSwitch_Commands_Routines.h +++ b/SerialPrograms/Source/NintendoSwitch/Commands/NintendoSwitch_Commands_Routines.h @@ -9,6 +9,7 @@ #include "CommonFramework/Tools/VideoStream.h" #include "NintendoSwitch/Controllers/NintendoSwitch_ProController.h" +#include "NintendoSwitch/Controllers/NintendoSwitch_Joycon.h" namespace PokemonAutomation{ namespace NintendoSwitch{ @@ -16,6 +17,8 @@ namespace NintendoSwitch{ void close_game(VideoStream& stream, ProControllerContext& device); +void close_game(VideoStream& stream, JoyconContext& device); + diff --git a/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_GameEntry.cpp b/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_GameEntry.cpp index 9dfad6a947..7a0c3b46c4 100644 --- a/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_GameEntry.cpp +++ b/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_GameEntry.cpp @@ -12,6 +12,7 @@ #include "CommonTools/InferenceCallbacks/VisualInferenceCallback.h" #include "CommonTools/Async/InferenceRoutines.h" #include "CommonTools/VisualDetectors/BlackScreenDetector.h" +#include "Controllers/ControllerTypes.h" #include "NintendoSwitch/NintendoSwitch_Settings.h" #include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" #include "NintendoSwitch/Commands/NintendoSwitch_Commands_Superscalar.h" @@ -312,6 +313,156 @@ bool openedgame_to_gamemenu( +void move_to_user(JoyconContext& context, uint8_t user_slot){ + if (user_slot != 0){ + // Move to correct user. + for (uint8_t c = 0; c < 9; c++){ // Extra iteration in case one gets dropped. + pbf_move_joystick(context, 0, 128, 160ms, 160ms); + } + for (uint8_t c = 1; c < user_slot; c++){ + pbf_move_joystick(context, 0, 128, 160ms, 160ms); + } + } +} + +void start_game_from_home_with_inference( + VideoStream& stream, JoyconContext& context, + uint8_t game_slot, + uint8_t user_slot, + Milliseconds start_game_wait +){ + context.wait_for_all_requests(); + + if (!(context.controller().controller_type() == ControllerType::NintendoSwitch_RightJoycon)) { + stream.log("Right Joycon required!", COLOR_RED); + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "start_game_from_home_with_inference(): Right Joycon required.", + stream + ); + } + + { + HomeWatcher detector; + int ret = run_until( + stream, context, + [](JoyconContext& context){ + pbf_mash_button(context, BUTTON_B, 10000ms); + }, + { detector } + ); + if (ret == 0){ + stream.log("Detected Home screen."); + }else{ + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "start_game_from_home_with_inference(): Failed to detect Home screen after 10 seconds.", + stream + ); + } + context.wait_for(std::chrono::milliseconds(100)); + } + + if (game_slot != 0){ + ssf_press_button(context, BUTTON_HOME, ConsoleSettings::instance().SETTINGS_TO_HOME_DELAY0, 160ms); + for (uint8_t c = 1; c < game_slot; c++){ + pbf_move_joystick(context, 255, 128, 160ms, 0ms); + } + context.wait_for_all_requests(); + } + + pbf_press_button(context, BUTTON_A, 160ms, 840ms); + + while (true){ + HomeWatcher home(std::chrono::milliseconds(2000)); + StartGameUserSelectWatcher user_select(COLOR_GREEN); + UpdateMenuWatcher update_menu(COLOR_PURPLE); + CheckOnlineWatcher check_online(COLOR_CYAN); + BlackScreenWatcher black_screen(COLOR_BLUE); + context.wait_for_all_requests(); + int ret = wait_until( + stream, context, + std::chrono::seconds(30), + { + home, + user_select, + update_menu, + check_online, + black_screen, + } + ); + + // Wait for screen to stabilize. + context.wait_for(std::chrono::milliseconds(100)); + + switch (ret){ + case 0: + stream.log("Detected home screen (again).", COLOR_RED); + pbf_press_button(context, BUTTON_A, 160ms, 840ms); + break; + case 1: + stream.log("Detected user-select screen."); + move_to_user(context, user_slot); + pbf_press_button(context, BUTTON_A, 80ms, start_game_wait); + break; + case 2: + stream.log("Detected update menu.", COLOR_RED); + pbf_move_joystick(context, 128, 0, 50ms, 0ms); + pbf_press_button(context, BUTTON_A, 160ms, 840ms); + break; + case 3: + stream.log("Detected check online.", COLOR_RED); + context.wait_for(std::chrono::seconds(1)); + break; + case 4: + stream.log("Detected black screen. Game started..."); + return; + default: + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "start_game_from_home_with_inference(): No recognizable state after 30 seconds.", + stream + ); + } + } +} + +bool openedgame_to_gamemenu( + VideoStream& stream, JoyconContext& context, + Milliseconds timeout +){ + { + stream.log("Waiting to load game..."); + GameLoadingDetector detector(false); + int ret = wait_until( + stream, context, + timeout, + {{detector}} + ); + if (ret < 0){ + stream.log("Timed out waiting to enter game.", COLOR_RED); + return false; + } + } + { + stream.log("Waiting for game menu..."); + GameLoadingDetector detector(true); + int ret = wait_until( + stream, context, + timeout, + {{detector}} + ); + if (ret < 0){ + stream.log("Timed out waiting for game menu.", COLOR_RED); + return false; + } + } + return true; +} + + + + diff --git a/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_GameEntry.h b/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_GameEntry.h index 500ccb14f2..8ff307bacb 100644 --- a/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_GameEntry.h +++ b/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_GameEntry.h @@ -9,6 +9,7 @@ #include "CommonFramework/Tools/VideoStream.h" #include "NintendoSwitch/Controllers/NintendoSwitch_ProController.h" +#include "NintendoSwitch/Controllers/NintendoSwitch_Joycon.h" namespace PokemonAutomation{ namespace NintendoSwitch{ @@ -35,6 +36,19 @@ bool openedgame_to_gamemenu( +void start_game_from_home_with_inference( + VideoStream& stream, JoyconContext& context, + uint8_t game_slot, + uint8_t user_slot, + Milliseconds start_game_mash +); + +bool openedgame_to_gamemenu( + VideoStream& stream, JoyconContext& context, + Milliseconds timeout +); + + } } #endif diff --git a/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Panels.cpp b/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Panels.cpp index 27183a59bd..39b64fd114 100644 --- a/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Panels.cpp +++ b/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Panels.cpp @@ -7,8 +7,9 @@ #include "CommonFramework/GlobalSettingsPanel.h" #include "Pokemon/Pokemon_Strings.h" #include "PokemonLGPE_Panels.h" +#include "PokemonLGPE_Settings.h" -#include "Programs/PokemonLGPE_AlolanTrade.h" +#include "Programs/ShinyHunting/PokemonLGPE_AlolanTrade.h" namespace PokemonAutomation{ namespace NintendoSwitch{ @@ -22,7 +23,7 @@ std::vector PanelListFactory::make_panels() const{ std::vector ret; ret.emplace_back("---- Settings ----"); - //ret.emplace_back(make_settings()); + ret.emplace_back(make_settings()); //ret.emplace_back("---- General ----"); diff --git a/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Settings.cpp b/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Settings.cpp new file mode 100644 index 0000000000..cf99cdc421 --- /dev/null +++ b/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Settings.cpp @@ -0,0 +1,99 @@ +/* Pokemon Let's Go Settings + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#include "Pokemon/Pokemon_Strings.h" +#include "PokemonLGPE_Settings.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonLGPE{ + using namespace Pokemon; + + + +GameSettings& GameSettings::instance(){ + static GameSettings settings; + return settings; +} +GameSettings::GameSettings() + : BatchOption(LockMode::LOCK_WHILE_RUNNING) + , m_general("General Settings:") + , m_menu_navigation("Menu Navigation Timings:") + , GAME_TO_HOME_DELAY0( + "Game to Home Delay:
Delay from pressing home to entering the the Switch home menu.", + LockMode::LOCK_WHILE_RUNNING, + "1000 ms" + ) + , m_start_game_timings("Start Game Timings:") + , START_GAME_MASH0( + "1. Start Game Mash:
Mash A for this long to start the game.", + LockMode::LOCK_WHILE_RUNNING, + "2000 ms" + ) + , START_GAME_WAIT1( + "2. Start Game Wait:
Wait this long for the game to load.", + LockMode::LOCK_WHILE_RUNNING, + "20 s" + ) + , ENTER_GAME_MASH0( + "3. Enter Game Mash:
Mash A for this long to enter the game.", + LockMode::LOCK_WHILE_RUNNING, + "5 s" + ) + , ENTER_GAME_WAIT0( + "4. Enter Game Wait:
Wait this long for the opening animations to finish.", + LockMode::LOCK_WHILE_RUNNING, + "15 s" + ) +{ + PA_ADD_STATIC(m_general); + + PA_ADD_STATIC(m_menu_navigation); + PA_ADD_OPTION(GAME_TO_HOME_DELAY0); + + PA_ADD_STATIC(m_start_game_timings); + PA_ADD_OPTION(START_GAME_MASH0); + PA_ADD_OPTION(START_GAME_WAIT1); + PA_ADD_OPTION(ENTER_GAME_MASH0); + PA_ADD_OPTION(ENTER_GAME_WAIT0); +} + + + + + +GameSettings_Descriptor::GameSettings_Descriptor() + : PanelDescriptor( + Color(), + "PokemonLGPE:GlobalSettings", + STRING_POKEMON + " LGPE", "Game Settings", + "ComputerControl/blob/master/Wiki/Programs/PokemonLGPE/PokemonSettings.md", + "Global " + STRING_POKEMON + " Let's Go Settings" + ) +{} + + + +GameSettingsPanel::GameSettingsPanel(const GameSettings_Descriptor& descriptor) + : SettingsPanelInstance(descriptor) + , settings(GameSettings::instance()) +{ + PA_ADD_OPTION(settings); +} + + + + + +} +} +} + + + + + + diff --git a/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Settings.h b/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Settings.h new file mode 100644 index 0000000000..792dd6e0a4 --- /dev/null +++ b/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Settings.h @@ -0,0 +1,57 @@ +/* Pokemon Let's Go Settings + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#ifndef PokemonAutomation_PokemonLGPE_Settings_H +#define PokemonAutomation_PokemonLGPE_Settings_H + +#include "Common/Cpp/Options/StaticTextOption.h" +#include "Common/Cpp/Options/FloatingPointOption.h" +#include "Common/Cpp/Options/TimeDurationOption.h" +#include "CommonFramework/Panels/SettingsPanel.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonLGPE{ + + +class GameSettings : public BatchOption{ + GameSettings(); +public: + static GameSettings& instance(); + + SectionDividerOption m_general; + + SectionDividerOption m_menu_navigation; + MillisecondsOption GAME_TO_HOME_DELAY0; + + SectionDividerOption m_start_game_timings; + MillisecondsOption START_GAME_MASH0; + MillisecondsOption START_GAME_WAIT1; + MillisecondsOption ENTER_GAME_MASH0; + MillisecondsOption ENTER_GAME_WAIT0; +}; + + + + +class GameSettings_Descriptor : public PanelDescriptor{ +public: + GameSettings_Descriptor(); +}; + + +class GameSettingsPanel : public SettingsPanelInstance{ +public: + GameSettingsPanel(const GameSettings_Descriptor& descriptor); +private: + GameSettings& settings; +}; + + +} +} +} +#endif diff --git a/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp b/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp new file mode 100644 index 0000000000..d4a2cacd55 --- /dev/null +++ b/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp @@ -0,0 +1,134 @@ +/* Game Entry + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#include "CommonFramework/VideoPipeline/VideoFeed.h" +#include "CommonFramework/Tools/ErrorDumper.h" +#include "CommonFramework/Tools/ProgramEnvironment.h" +#include "CommonFramework/Exceptions/OperationFailedException.h" +#include "CommonTools/Async/InferenceRoutines.h" +#include "CommonTools/VisualDetectors/BlackScreenDetector.h" +#include "Controllers/ControllerCapability.h" +#include "NintendoSwitch/NintendoSwitch_Settings.h" +#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" +#include "NintendoSwitch/Commands/NintendoSwitch_Commands_Routines.h" +#include "NintendoSwitch/Programs/NintendoSwitch_GameEntry.h" +#include "NintendoSwitch/Inference/NintendoSwitch_DetectHome.h" +#include "PokemonLGPE/PokemonLGPE_Settings.h" +#include "PokemonLGPE_GameEntry.h" + +//#include +//using std::cout; +//using std::endl; + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonLGPE{ + + +bool reset_game_to_gamemenu( + VideoStream& stream, JoyconContext& context +){ + close_game(stream, context); + start_game_from_home_with_inference( + stream, + context, + 0, 0, + GameSettings::instance().START_GAME_MASH0 + ); + + // Now the game has opened: + return openedgame_to_gamemenu(stream, context, GameSettings::instance().START_GAME_WAIT1); +} + +bool gamemenu_to_ingame( + VideoStream& stream, JoyconContext& context, + Milliseconds mash_duration, Milliseconds enter_game_timeout +){ + //Includes choosing the controller. + //Controllers are disconnected? on selection screen so make sure to mash. + stream.log("Mashing A to enter game and select controller..."); + pbf_mash_button(context, BUTTON_A, mash_duration); + context.wait_for_all_requests(); + + //White screen, Pikachu/Eevee running across the screen. Mash will not speed it up. + //Mash A at then end to enter continue screen + BlackScreenOverWatcher detector(COLOR_RED, {0.2, 0.2, 0.6, 0.6}); + stream.log("Waiting to enter game..."); + int ret = run_until( + stream, context, + [&enter_game_timeout](JoyconContext& context){ + pbf_wait(context, enter_game_timeout); + pbf_press_button(context, BUTTON_A, 400ms, 10ms); + pbf_wait(context, 5000ms); + }, + {detector} + ); + context.wait_for_all_requests(); + if (ret == 0){ + stream.log("At continue screen."); + }else{ + stream.log("Timed out waiting to enter game and select continue.", COLOR_RED); + return false; + } + pbf_wait(context, 1000ms); + context.wait_for_all_requests(); + + //Continue your adventure. + BlackScreenOverWatcher detector2(COLOR_YELLOW, {0.2, 0.2, 0.6, 0.6}); + int ret2 = run_until( + stream, context, + [](JoyconContext& context){ + pbf_press_button(context, BUTTON_A, 400ms, 10ms); + pbf_wait(context, 5000ms); + }, + {detector2} + ); + context.wait_for_all_requests(); + if (ret2 == 0){ + stream.log("Entered game!"); + return true; + }else{ + stream.log("Timed out waiting to enter game.", COLOR_RED); + return false; + } +} + +bool reset_game_from_home( + ProgramEnvironment& env, VideoStream& stream, JoyconContext& context, + Milliseconds post_wait_time +){ + if (!(context.controller().controller_type() == ControllerType::NintendoSwitch_RightJoycon)) { + stream.log("Right Joycon required!", COLOR_RED); + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "reset_game_from_home(): Right Joycon required.", + stream + ); + return false; + } + bool ok = true; + ok &= reset_game_to_gamemenu(stream, context); + ok &= gamemenu_to_ingame( + stream, context, + GameSettings::instance().ENTER_GAME_MASH0, + GameSettings::instance().ENTER_GAME_WAIT0 + ); + if (!ok){ + dump_image(stream.logger(), env.program_info(), stream.video(), "StartGame"); + } + stream.log("Entered game! Waiting out grace period."); + pbf_wait(context, post_wait_time); + context.wait_for_all_requests(); + return ok; +} + + + + + +} +} +} diff --git a/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.h b/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.h new file mode 100644 index 0000000000..54f245edcc --- /dev/null +++ b/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.h @@ -0,0 +1,47 @@ +/* Game Entry + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#ifndef PokemonAutomation_PokemonLGPE_GameEntry_H +#define PokemonAutomation_PokemonLGPE_GameEntry_H + +#include +#include "CommonFramework/Tools/VideoStream.h" +#include "NintendoSwitch/Controllers/NintendoSwitch_Joycon.h" + +namespace PokemonAutomation{ + class ProgramEnvironment; +namespace NintendoSwitch{ +namespace PokemonLGPE{ + + + +// From Switch Home menu, reset game and wait until the game menu screen (where +// "Press A" is displayed to enter the game) is shown. +bool reset_game_to_gamemenu( + VideoStream& stream, JoyconContext& context +); + +// From the game menu screen (where "Press A" is displayed to enter the game), +// mash A to enter the game and wait until the black screen is gone. +bool gamemenu_to_ingame( + VideoStream& stream, JoyconContext& context, + Milliseconds mash_duration, Milliseconds enter_game_timeout +); + +// From Switch Home menu, start game and wait until the player character appears in game. +// post_wait_time: how many ticks to wait after the black screen (shown when loading the map) is over. +bool reset_game_from_home( + ProgramEnvironment& env, VideoStream& stream, JoyconContext& context, + Milliseconds post_wait_time = 125ms +); + + + + +} +} +} +#endif diff --git a/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_AlolanTrade.cpp b/SerialPrograms/Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.cpp similarity index 89% rename from SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_AlolanTrade.cpp rename to SerialPrograms/Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.cpp index b6d0efb72b..1cbb33b04a 100644 --- a/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_AlolanTrade.cpp +++ b/SerialPrograms/Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.cpp @@ -16,6 +16,7 @@ #include "Pokemon/Pokemon_Strings.h" #include "CommonTools/VisualDetectors/BlackScreenDetector.h" #include "PokemonLGPE/Inference/PokemonLGPE_ShinySymbolDetector.h" +#include "PokemonLGPE/Programs/PokemonLGPE_GameEntry.h" #include "PokemonLGPE_AlolanTrade.h" namespace PokemonAutomation{ @@ -135,7 +136,7 @@ void AlolanTrade::program(SingleSwitchProgramEnvironment& env, CancellableScope& /* WARNING: JOYCON TEST PROGRAM. Not well tested. Bare minimum in general. - Only works with Right joycon atm. Do not update right joycon. + Only works with Right joycon atm. Do not update right joycon. Decline the update before running this. Right joycon required for home button (this means no on-switch screenshots). Also don't remap any of the buttons in the switch button mapping settings. Yet? Could use this to add Home and Screenshot. @@ -156,7 +157,7 @@ void AlolanTrade::program(SingleSwitchProgramEnvironment& env, CancellableScope& "you don't have any pokemon your trading partner wants" detect dialog box, detect yes/no confirm box actual enter game and start screen detectors - menu detectors, reset game from home, etc. + menu detectors, etc. get rid of all this blindly mashing A in general...so need everything really. */ @@ -164,6 +165,7 @@ void AlolanTrade::program(SingleSwitchProgramEnvironment& env, CancellableScope& while (!shiny_found) { //Run trades for (uint16_t i = 0; i < NUM_TRADES; i++) { + env.log("Running trade."); run_trade(env, context); stats.trades++; @@ -178,11 +180,10 @@ void AlolanTrade::program(SingleSwitchProgramEnvironment& env, CancellableScope& //To check pokemon in menu boxes //Open menu - always defaults to center (Party) - /* Menu: - Play with Partner - Pokedex - Bag - Party - Communicate - Save (these all have a colored line under when selected) - (Press Y for options) - */ + //Menu: + // --Play with Partner--(centered) + //Pokedex - Bag - Party - Communicate - Save (these all have a colored line under when selected + an arrow to indicate) + //(Press Y for options) //Wait a bit. pbf_wait(context, 2500ms); @@ -191,8 +192,8 @@ void AlolanTrade::program(SingleSwitchProgramEnvironment& env, CancellableScope& //Open menu, open party, open boxes env.log("Opening boxes."); pbf_press_button(context, BUTTON_X, 200ms, 500ms); - pbf_press_button(context, BUTTON_A, 200ms, 1000ms); - pbf_press_button(context, BUTTON_Y, 200ms, 1500ms); + pbf_press_button(context, BUTTON_A, 200ms, 1500ms); + pbf_press_button(context, BUTTON_Y, 200ms, 2000ms); context.wait_for_all_requests(); //Sort by order caught @@ -236,10 +237,10 @@ void AlolanTrade::program(SingleSwitchProgramEnvironment& env, CancellableScope& //Move left, check next. pbf_move_joystick(context, 0, 128, 100ms, 100ms); - pbf_press_button(context, BUTTON_X, 0ms, 2000ms); + pbf_press_button(context, BUTTON_X, 0ms, 1000ms); context.wait_for_all_requests(); } - /* + if (!shiny_found) { env.log("Out of Pokemon to trade and no shiny found. Resetting game."); send_program_status_notification( @@ -247,23 +248,14 @@ void AlolanTrade::program(SingleSwitchProgramEnvironment& env, CancellableScope& "Out of Pokemon to trade and no shiny found. Resetting game." ); - //TODO: Need to make proper GameEntry eventually - //Thankfully, Joycon is upright after going to home. - //Go to home and close game - pbf_press_button(context, BUTTON_HOME, 200ms, 3000ms); - pbf_press_button(context, BUTTON_X, 200ms, 200ms); - pbf_press_button(context, BUTTON_A, 200ms, 1000ms); - - //TODO: - //joycon context->pro controller context? - start_game_from_home(env.console, context, true, 0, 0, std::chrono::milliseconds(2000)); + //Reset game + pbf_press_button(context, BUTTON_HOME, 200ms, 2000ms); + reset_game_from_home(env, env.console, context, 3000ms); + context.wait_for_all_requests(); stats.resets++; env.update_stats(); } - */ - //Break for now since resetting the game doesn't work. - break; } if (GO_HOME_WHEN_DONE) { diff --git a/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_AlolanTrade.h b/SerialPrograms/Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.h similarity index 100% rename from SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_AlolanTrade.h rename to SerialPrograms/Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.h