diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_ShinySymbolDetector.cpp b/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_ShinySymbolDetector.cpp index 3dee1db8c..30bd5b718 100644 --- a/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_ShinySymbolDetector.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_ShinySymbolDetector.cpp @@ -22,7 +22,7 @@ namespace NintendoSwitch{ namespace PokemonFRLG{ ShinySymbolDetector::ShinySymbolDetector(Color color) - : m_box_symbol(0.430, 0.208, 0.048, 0.078) + : m_box_symbol(0.436, 0.211, 0.033, 0.060) {} void ShinySymbolDetector::make_overlays(VideoOverlaySet& items) const{ items.add(COLOR_RED, m_box_symbol); diff --git a/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.cpp b/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.cpp index 9ae5ef76f..d9b3f4071 100644 --- a/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.cpp +++ b/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.cpp @@ -13,6 +13,7 @@ #include "NintendoSwitch/Commands/NintendoSwitch_Commands_Superscalar.h" #include "NintendoSwitch/Controllers/Procon/NintendoSwitch_ProController.h" #include "NintendoSwitch/NintendoSwitch_ConsoleHandle.h" +#include "PokemonSwSh/MaxLair/Ai/PokemonSwSh_MaxLair_AI.h" #include "PokemonFRLG/Inference/Dialogs/PokemonFRLG_DialogDetector.h" #include "PokemonFRLG/Inference/Sounds/PokemonFRLG_ShinySoundDetector.h" #include "PokemonFRLG/Inference/Menus/PokemonFRLG_StartMenuDetector.h" @@ -24,37 +25,78 @@ namespace NintendoSwitch{ namespace PokemonFRLG{ -void soft_reset(const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ +void soft_reset(ConsoleHandle& console, ProControllerContext& context){ // A + B + Select + Start pbf_press_button(context, BUTTON_B | BUTTON_A | BUTTON_MINUS | BUTTON_PLUS, 360ms, 1440ms); - pbf_mash_button(context, BUTTON_PLUS, GameSettings::instance().START_BUTTON_MASH1); + pbf_mash_button(context, BUTTON_MINUS, GameSettings::instance().SELECT_BUTTON_MASH0); context.wait_for_all_requests(); + //Random wait before pressing start/A + console.log("Randomly waiting..."); + Milliseconds rng_wait = std::chrono::milliseconds(PokemonSwSh::MaxLairInternal::random(0, 5000)); + pbf_wait(context, rng_wait); + context.wait_for_all_requests(); + + //Mash A until white screen to game load menu + WhiteScreenOverWatcher whitescreen(COLOR_RED, {0.282, 0.064, 0.448, 0.871}); + + int ls = run_until( + console, context, + [](ProControllerContext& context) { + pbf_mash_button(context, BUTTON_A, 1000ms); + pbf_wait(context, 5000ms); + context.wait_for_all_requests(); + }, + { whitescreen } + ); + context.wait_for_all_requests(); + if (ls == 0){ + console.log("Entered load menu."); + }else{ + console.log("Unable to enter load menu.", COLOR_RED); + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "soft_reset(): Unable to enter load menu.", + console + ); + } + //Let the animation finish + pbf_wait(context, 500ms); + context.wait_for_all_requests(); + + //Load game pbf_press_button(context, BUTTON_A, 160ms, 320ms); //Wait for game to load in BlackScreenOverWatcher detector(COLOR_RED, {0.282, 0.064, 0.448, 0.871}); int ret = wait_until( - stream, context, + console, context, GameSettings::instance().ENTER_GAME_WAIT0, {detector} ); if (ret == 0){ - stream.log("Entered game!"); + console.log("Entered game!"); }else{ - stream.log("Timed out waiting to enter game.", COLOR_RED); + console.log("Timed out waiting to enter game.", COLOR_RED); OperationFailedException::fire( ErrorReport::SEND_ERROR_REPORT, "soft_reset(): Timed out waiting to enter game.", - stream + console ); } //Mash past "previously on..." pbf_mash_button(context, BUTTON_B, GameSettings::instance().ENTER_GAME_MASH0); + context.wait_for_all_requests(); + //Random wait no.2 + console.log("Randomly waiting..."); + Milliseconds rng_wait2 = std::chrono::milliseconds(PokemonSwSh::MaxLairInternal::random(0, 5000)); + pbf_wait(context, rng_wait2); context.wait_for_all_requests(); + + console.log("Soft reset completed."); } void open_slot_six(ConsoleHandle& console, ProControllerContext& context){ @@ -85,20 +127,23 @@ void open_slot_six(ConsoleHandle& console, ProControllerContext& context){ } 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(); - - pbf_press_button(context, BUTTON_A, 320ms, 640ms); - BlackScreenOverWatcher blk1(COLOR_RED, {0.282, 0.064, 0.448, 0.871}); - int ret1 = wait_until( + + int pm = run_until( console, context, - 5s, - {blk1} + [](ProControllerContext& context) { + pbf_wait(context, 200ms); + context.wait_for_all_requests(); + pbf_press_dpad(context, DPAD_DOWN, 320ms, 320ms); + context.wait_for_all_requests(); + + pbf_press_button(context, BUTTON_A, 320ms, 640ms); + pbf_wait(context, 5000ms); + context.wait_for_all_requests(); + }, + { blk1 } ); - if (ret1 == 0){ + if (pm == 0){ console.log("Entered party menu."); }else{ console.log("Unable to enter Party menu.", COLOR_RED); @@ -115,16 +160,18 @@ void open_slot_six(ConsoleHandle& console, ProControllerContext& context){ 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( + int sm = run_until( console, context, - 5s, - {blk2} + [](ProControllerContext& context) { + pbf_press_button(context, BUTTON_A, 320ms, 640ms); + pbf_press_button(context, BUTTON_A, 320ms, 640ms); + pbf_wait(context, 5000ms); + context.wait_for_all_requests(); + }, + { blk2 } ); - if (ret2 == 0){ + if (sm == 0){ console.log("Entered summary."); }else{ console.log("Unable to enter summary.", COLOR_RED); diff --git a/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.h b/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.h index 29f1fcf50..1ce2ade4b 100644 --- a/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.h +++ b/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.h @@ -20,8 +20,10 @@ namespace NintendoSwitch{ namespace PokemonFRLG{ // Press A+B+Select+Start at the same time to soft reset, then re-enters the game. +// There are two random waits, one before pressing start and another after loading in the game. +// This is to prevent repeatedly getting the same pokemon, due to FRLG's RNG // For now this assumes no dry battery. -void soft_reset(const ProgramInfo& info, VideoStream& stream, ProControllerContext &context); +void soft_reset(ConsoleHandle& console, 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); diff --git a/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Settings.cpp b/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Settings.cpp index 5445b4bb9..e9cb60b16 100644 --- a/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Settings.cpp +++ b/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Settings.cpp @@ -23,10 +23,10 @@ GameSettings& GameSettings::instance(){ GameSettings::GameSettings() : BatchOption(LockMode::LOCK_WHILE_RUNNING) , m_soft_reset_timings("Soft Reset Timings:") - , START_BUTTON_MASH1( - "Start Button Mash:
Mash Start for this long after a soft reset to get to the main menu.", + , SELECT_BUTTON_MASH0( + "Start Button Mash:
Mash select for this long after a soft reset to get to Press Start.", LockMode::LOCK_WHILE_RUNNING, - "6000 ms" + "5000 ms" ) , ENTER_GAME_WAIT0( "Enter Game Wait:
Wait this long for the game to load.", @@ -51,7 +51,7 @@ GameSettings::GameSettings() ) { PA_ADD_STATIC(m_soft_reset_timings); - PA_ADD_OPTION(START_BUTTON_MASH1); + PA_ADD_OPTION(SELECT_BUTTON_MASH0); PA_ADD_OPTION(ENTER_GAME_WAIT0); PA_ADD_STATIC(m_shiny_audio_settings); PA_ADD_OPTION(SHINY_SOUND_THRESHOLD); diff --git a/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Settings.h b/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Settings.h index 4d2f4b07b..f899ccc96 100644 --- a/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Settings.h +++ b/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Settings.h @@ -23,7 +23,7 @@ class GameSettings : public BatchOption{ static GameSettings& instance(); SectionDividerOption m_soft_reset_timings; - MillisecondsOption START_BUTTON_MASH1; + MillisecondsOption SELECT_BUTTON_MASH0; MillisecondsOption ENTER_GAME_WAIT0; MillisecondsOption ENTER_GAME_MASH0; diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/ShinyHunting/PokemonFRLG_GiftReset.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/ShinyHunting/PokemonFRLG_GiftReset.cpp index c8da7bc4b..4e013a25f 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/ShinyHunting/PokemonFRLG_GiftReset.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Programs/ShinyHunting/PokemonFRLG_GiftReset.cpp @@ -246,15 +246,19 @@ void GiftReset::open_summary(SingleSwitchProgramEnvironment& env, ProControllerC } //For starters, no Pokedex yet, do Pokemon is on top and we skip this //Open party menu - pbf_press_button(context, BUTTON_A, 320ms, 640ms); - BlackScreenOverWatcher blk1(COLOR_RED, {0.282, 0.064, 0.448, 0.871}); - int ret1 = wait_until( + + int pm = run_until( env.console, context, - 5s, - {blk1} + [](ProControllerContext& context) { + pbf_press_button(context, BUTTON_A, 320ms, 640ms); + pbf_wait(context, 5000ms); + context.wait_for_all_requests(); + }, + { blk1 } ); - if (ret1 == 0){ + context.wait_for_all_requests(); + if (pm == 0){ env.log("Entered party menu."); }else{ env.log("Unable to enter party menu.", COLOR_RED); @@ -264,7 +268,6 @@ void GiftReset::open_summary(SingleSwitchProgramEnvironment& env, ProControllerC env.console ); } - context.wait_for_all_requests(); //Press up twice to get to the last slot if (TARGET != Target::starters) { @@ -273,16 +276,18 @@ void GiftReset::open_summary(SingleSwitchProgramEnvironment& env, ProControllerC } //Two presses to open summary - pbf_press_button(context, BUTTON_A, 320ms, 320ms); - pbf_press_button(context, BUTTON_A, 320ms, 320ms); - BlackScreenOverWatcher blk2(COLOR_RED, {0.282, 0.064, 0.448, 0.871}); - int ret2 = wait_until( + int sm = run_until( env.console, context, - 5s, - {blk2} + [](ProControllerContext& context) { + pbf_press_button(context, BUTTON_A, 320ms, 320ms); + pbf_press_button(context, BUTTON_A, 320ms, 320ms); + pbf_wait(context, 5000ms); + context.wait_for_all_requests(); + }, + { blk2 } ); - if (ret2 == 0){ + if (sm == 0){ env.log("Entered summary."); }else{ env.log("Unable to enter summary.", COLOR_RED); @@ -339,7 +344,7 @@ void GiftReset::program(SingleSwitchProgramEnvironment& env, ProControllerContex env, NOTIFICATION_STATUS_UPDATE, "Soft resetting." ); - soft_reset(env.program_info(), env.console, context); + soft_reset(env.console, context); stats.resets++; env.update_stats(); context.wait_for_all_requests(); diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/ShinyHunting/PokemonFRLG_LegendaryReset.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/ShinyHunting/PokemonFRLG_LegendaryReset.cpp index 293ebec96..643d4e51f 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/ShinyHunting/PokemonFRLG_LegendaryReset.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Programs/ShinyHunting/PokemonFRLG_LegendaryReset.cpp @@ -140,7 +140,7 @@ void LegendaryReset::program(SingleSwitchProgramEnvironment& env, ProControllerC "Soft resetting." ); - soft_reset(env.program_info(), env.console, context); + soft_reset(env.console, context); stats.resets++; env.update_stats(); context.wait_for_all_requests(); diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/ShinyHunting/PokemonFRLG_PrizeCornerReset.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/ShinyHunting/PokemonFRLG_PrizeCornerReset.cpp index 097d5c3c5..bb1d2c46e 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/ShinyHunting/PokemonFRLG_PrizeCornerReset.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Programs/ShinyHunting/PokemonFRLG_PrizeCornerReset.cpp @@ -165,7 +165,7 @@ void PrizeCornerReset::program(SingleSwitchProgramEnvironment& env, ProControlle env, NOTIFICATION_STATUS_UPDATE, "Soft resetting." ); - soft_reset(env.program_info(), env.console, context); + soft_reset(env.console, context); stats.resets++; context.wait_for_all_requests(); }