From ae6683bebf78f75ebbf398b88af006bccdb57c74 Mon Sep 17 00:00:00 2001 From: jw098 Date: Fri, 15 Nov 2024 23:56:54 -0800 Subject: [PATCH] Segments 12 to 13 --- SerialPrograms/CMakeLists.txt | 6 +- SerialPrograms/SerialPrograms.pro | 4 + .../Dialogs/PokemonSV_DialogDetector.h | 1 + .../PokemonSV_DestinationMarkerDetector.cpp | 4 +- .../Overworld/PokemonSV_DirectionDetector.cpp | 18 +- .../Overworld/PokemonSV_OverworldDetector.cpp | 2 +- .../AutoStory/PokemonSV_AutoStory.cpp | 24 +- .../PokemonSV_AutoStory_Segment_12.cpp | 156 ++++++++ .../PokemonSV_AutoStory_Segment_12.h | 41 +++ .../PokemonSV_AutoStory_Segment_13.cpp | 334 ++++++++++++++++++ .../PokemonSV_AutoStory_Segment_13.h | 45 +++ .../Programs/PokemonSV_Navigation.cpp | 9 +- 12 files changed, 620 insertions(+), 24 deletions(-) create mode 100644 SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_12.cpp create mode 100644 SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_12.h create mode 100644 SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_13.cpp create mode 100644 SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_13.h diff --git a/SerialPrograms/CMakeLists.txt b/SerialPrograms/CMakeLists.txt index 741a10173..52b9658a3 100644 --- a/SerialPrograms/CMakeLists.txt +++ b/SerialPrograms/CMakeLists.txt @@ -1461,7 +1461,11 @@ file(GLOB MAIN_SOURCES Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_10.cpp Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_10.h Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_11.cpp - Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_11.h + Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_11.h + Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_12.cpp + Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_12.h + Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_13.cpp + Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_13.h Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.h Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp diff --git a/SerialPrograms/SerialPrograms.pro b/SerialPrograms/SerialPrograms.pro index 02af50cb2..e16dc32cd 100644 --- a/SerialPrograms/SerialPrograms.pro +++ b/SerialPrograms/SerialPrograms.pro @@ -730,6 +730,8 @@ SOURCES += \ Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_09.cpp \ Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_10.cpp \ Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_11.cpp \ + Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_12.cpp \ + Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_13.cpp \ Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp \ Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp \ Source/PokemonSV/Programs/AutoStory/PokemonSV_MenuOption.cpp \ @@ -1834,6 +1836,8 @@ HEADERS += \ Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_09.h \ Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_10.h \ Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_11.h \ + Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_12.h \ + Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_13.h \ Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.h \ Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h \ Source/PokemonSV/Programs/AutoStory/PokemonSV_MenuOption.h \ diff --git a/SerialPrograms/Source/PokemonSV/Inference/Dialogs/PokemonSV_DialogDetector.h b/SerialPrograms/Source/PokemonSV/Inference/Dialogs/PokemonSV_DialogDetector.h index bbb8e1208..3973407a0 100644 --- a/SerialPrograms/Source/PokemonSV/Inference/Dialogs/PokemonSV_DialogDetector.h +++ b/SerialPrograms/Source/PokemonSV/Inference/Dialogs/PokemonSV_DialogDetector.h @@ -80,6 +80,7 @@ class AdvanceDialogWatcher : public DetectorToFinder{ // Detect dialog that prompts the player to make a choice. +// i.e. detects that Dialog box and Gradient arrow are present class PromptDialogDetector : public StaticScreenDetector{ public: // Will catch any prompt. diff --git a/SerialPrograms/Source/PokemonSV/Inference/Map/PokemonSV_DestinationMarkerDetector.cpp b/SerialPrograms/Source/PokemonSV/Inference/Map/PokemonSV_DestinationMarkerDetector.cpp index 8ad27cd56..67909e255 100644 --- a/SerialPrograms/Source/PokemonSV/Inference/Map/PokemonSV_DestinationMarkerDetector.cpp +++ b/SerialPrograms/Source/PokemonSV/Inference/Map/PokemonSV_DestinationMarkerDetector.cpp @@ -88,7 +88,7 @@ std::vector DestinationMarkerDetector::detect_all(const ImageView }; - const double rmsd_threshold = 80.0; // from my testing: RMSD is 15 at 1080p, 60 at 720p + const double rmsd_threshold = 65.0; // from my testing: RMSD is 15 at 1080p, 60 at 720p const double min_object_size = 150.0; const double screen_rel_size = (screen.height() / 1080.0); @@ -123,7 +123,7 @@ std::vector DestinationMarkerDetector::detect_all_yellow(const Im }; - const double rmsd_threshold = 80.0; // from my testing, RMSD ranges from 15-50, even at 720p + const double rmsd_threshold = 60.0; // from my testing, RMSD ranges from 15-50, even at 720p /* - min object size restrictions also helps to filter out false positives at pokemon centers diff --git a/SerialPrograms/Source/PokemonSV/Inference/Overworld/PokemonSV_DirectionDetector.cpp b/SerialPrograms/Source/PokemonSV/Inference/Overworld/PokemonSV_DirectionDetector.cpp index 20663bce4..9bb74b3fe 100644 --- a/SerialPrograms/Source/PokemonSV/Inference/Overworld/PokemonSV_DirectionDetector.cpp +++ b/SerialPrograms/Source/PokemonSV/Inference/Overworld/PokemonSV_DirectionDetector.cpp @@ -170,13 +170,16 @@ void DirectionDetector::change_direction( double direction ) const{ size_t i = 0; - size_t MAX_ATTEMPTS = 10; + size_t MAX_ATTEMPTS = 20; bool is_minimap_definitely_unlocked = false; + uint8_t scale_factor = 80; + double push_magnitude_scale_factor = 1; while (i < MAX_ATTEMPTS){ // 10 attempts to move the direction to the target context.wait_for_all_requests(); VideoSnapshot screen = console.video().snapshot(); double current = get_current_direction(console, screen); if (current < 0){ + console.log("Unable to detect current direction."); return; } double target = std::fmod(direction, (2 * PI)); @@ -212,16 +215,23 @@ void DirectionDetector::change_direction( } is_minimap_definitely_unlocked = true; - if (abs_diff < 0.02){ + if (abs_diff < 0.01){ // return when we're close enough to the target return; } - uint8_t scale_factor = 80; + + if (scale_factor > 40 && abs_diff < 0.05){ + scale_factor = 40; + } + + if (abs_diff < 0.05){ + push_magnitude_scale_factor = 0.5; + } uint16_t push_duration = std::max(uint16_t(std::abs(diff * scale_factor)), uint16_t(8)); int16_t push_direction = (diff > 0) ? -1 : 1; - double push_magnitude = std::max(double(128 / (i + 1)), double(20)); // push less with each iteration/attempt + double push_magnitude = std::max(double((128 * push_magnitude_scale_factor) / (i + 1)), double(15)); // push less with each iteration/attempt uint8_t push_x = uint8_t(std::max(std::min(int(128 + (push_direction * push_magnitude)), 255), 0)); console.log("push magnitude: " + std::to_string(push_x) + ", push duration: " + std::to_string(push_duration)); pbf_move_right_joystick(context, push_x, 128, push_duration, 100); diff --git a/SerialPrograms/Source/PokemonSV/Inference/Overworld/PokemonSV_OverworldDetector.cpp b/SerialPrograms/Source/PokemonSV/Inference/Overworld/PokemonSV_OverworldDetector.cpp index fd86db67e..728cf1114 100644 --- a/SerialPrograms/Source/PokemonSV/Inference/Overworld/PokemonSV_OverworldDetector.cpp +++ b/SerialPrograms/Source/PokemonSV/Inference/Overworld/PokemonSV_OverworldDetector.cpp @@ -94,7 +94,7 @@ std::pair OverworldDetector::locate_ball(const ImageViewRGB32& s // yellow arrow has area of 70-80. the yellow ball, when only partially filled (i.e. only the outer ring is waterfilled), has an area of 200. // when the ball is fully filled in, it has an area of 550 - const double min_object_size = strict_requirements ? 150.0 : 0; + const double min_object_size = strict_requirements ? 150.0 : 50; const double rmsd_threshold = strict_requirements ? 35.0 : 50.0; const double screen_rel_size = (screen.height() / 1080.0); diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp index 14e45d3cb..2bf081f83 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp @@ -26,9 +26,9 @@ #include "PokemonSV_AutoStory_Segment_08.h" #include "PokemonSV_AutoStory_Segment_09.h" #include "PokemonSV_AutoStory_Segment_10.h" -// #include "PokemonSV_AutoStory_Segment_11.h" -// #include "PokemonSV_AutoStory_Segment_12.h" -// #include "PokemonSV_AutoStory_Segment_13.h" +#include "PokemonSV_AutoStory_Segment_11.h" +#include "PokemonSV_AutoStory_Segment_12.h" +#include "PokemonSV_AutoStory_Segment_13.h" // #include "PokemonSV_AutoStory_Segment_14.h" // #include "PokemonSV_AutoStory_Segment_15.h" #include "PokemonSV_AutoStory.h" @@ -61,9 +61,9 @@ std::vector> make_autoStory_segment_list(){ segment_list.emplace_back(std::make_unique()); segment_list.emplace_back(std::make_unique()); segment_list.emplace_back(std::make_unique()); - // segment_list.emplace_back(std::make_unique()); - // segment_list.emplace_back(std::make_unique()); - // segment_list.emplace_back(std::make_unique()); + segment_list.emplace_back(std::make_unique()); + segment_list.emplace_back(std::make_unique()); + segment_list.emplace_back(std::make_unique()); // segment_list.emplace_back(std::make_unique()); return segment_list; @@ -483,12 +483,12 @@ void AutoStory::test_checkpoints( checkpoint_list.push_back([&](){checkpoint_21(env, context, notif_status_update);}); checkpoint_list.push_back([&](){checkpoint_22(env, context, notif_status_update);}); checkpoint_list.push_back([&](){checkpoint_23(env, context, notif_status_update);}); - // checkpoint_list.push_back([&](){checkpoint_24(env, context, notif_status_update);}); - // checkpoint_list.push_back([&](){checkpoint_25(env, context, notif_status_update);}); - // checkpoint_list.push_back([&](){checkpoint_26(env, context, notif_status_update);}); - // checkpoint_list.push_back([&](){checkpoint_27(env, context, notif_status_update);}); - // checkpoint_list.push_back([&](){checkpoint_28(env, context, notif_status_update);}); - // checkpoint_list.push_back([&](){checkpoint_29(env, context, notif_status_update);}); + checkpoint_list.push_back([&](){checkpoint_24(env, context, notif_status_update);}); + checkpoint_list.push_back([&](){checkpoint_25(env, context, notif_status_update);}); + checkpoint_list.push_back([&](){checkpoint_26(env, context, notif_status_update);}); + checkpoint_list.push_back([&](){checkpoint_27(env, context, notif_status_update);}); + checkpoint_list.push_back([&](){checkpoint_28(env, context, notif_status_update);}); + checkpoint_list.push_back([&](){checkpoint_29(env, context, notif_status_update);}); // checkpoint_list.push_back([&](){checkpoint_30(env, context, notif_status_update);}); // checkpoint_list.push_back([&](){checkpoint_31(env, context, notif_status_update);}); // checkpoint_list.push_back([&](){checkpoint_32(env, context, notif_status_update);}); diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_12.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_12.cpp new file mode 100644 index 000000000..030691300 --- /dev/null +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_12.cpp @@ -0,0 +1,156 @@ +/* AutoStory + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#include "CommonFramework/GlobalSettingsPanel.h" +#include "CommonFramework/Exceptions/FatalProgramException.h" +#include "CommonFramework/Exceptions/OperationFailedException.h" +#include "CommonFramework/InferenceInfra/InferenceRoutines.h" +#include "CommonFramework/Notifications/ProgramNotifications.h" +#include "CommonFramework/Tools/StatsTracking.h" +#include "CommonFramework/Tools/VideoResolutionCheck.h" +#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" +#include "Pokemon/Pokemon_Strings.h" +#include "PokemonSwSh/Inference/PokemonSwSh_IvJudgeReader.h" +#include "PokemonSV/Programs/PokemonSV_GameEntry.h" +#include "PokemonSV/Programs/PokemonSV_SaveGame.h" +#include "PokemonSV/Inference/PokemonSV_TutorialDetector.h" +#include "PokemonSV/Inference/Overworld/PokemonSV_DirectionDetector.h" +#include "PokemonSV/Inference/Overworld/PokemonSV_NoMinimapDetector.h" +#include "PokemonSV_AutoStoryTools.h" +#include "PokemonSV_AutoStory_Segment_12.h" + +//#include +//using std::cout; +//using std::endl; +//#include +//#include + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonSV{ + +using namespace Pokemon; + + + + +std::string AutoStory_Segment_12::name() const{ + return "10.3: Cortondo Gym - Gym battle"; +} + +std::string AutoStory_Segment_12::start_text() const{ + return "Start: Beat Cortondo Gym challenge."; +} + +std::string AutoStory_Segment_12::end_text() const{ + return "End: Beat Cortondo Gym battle. At Cortondo West Pokecenter."; +} + + +void AutoStory_Segment_12::run_segment(SingleSwitchProgramEnvironment& env, BotBaseContext& context, AutoStoryOptions options) const{ + AutoStoryStats& stats = env.current_stats(); + + context.wait_for_all_requests(); + env.console.overlay().add_log("Start Segment 10.3: Cortondo Gym - Gym battle", COLOR_ORANGE); + + checkpoint_28(env, context, options.notif_status_update); + + context.wait_for_all_requests(); + env.console.log("End Segment 10.3: Cortondo Gym - Gym battle", COLOR_GREEN); + stats.m_segment++; + env.update_stats(); + +} + + +void checkpoint_28( + SingleSwitchProgramEnvironment& env, + BotBaseContext& context, + EventNotificationOption& notif_status_update +){ + AutoStoryStats& stats = env.current_stats(); + bool first_attempt = true; + while (true){ + try{ + if (first_attempt){ + checkpoint_save(env, context, notif_status_update); + first_attempt = false; + } + context.wait_for_all_requests(); + DirectionDetector direction; + do_action_and_monitor_for_battles(env.program_info(), env.console, context, + [&](const ProgramInfo& info, ConsoleHandle& console, BotBaseContext& context){ + direction.change_direction(env.program_info(), env.console, context, 2.71); + pbf_move_left_joystick(context, 128, 0, 375, 100); + direction.change_direction(env.program_info(), env.console, context, 1.26); + pbf_move_left_joystick(context, 128, 0, 1750, 100); + }); + + direction.change_direction(env.program_info(), env.console, context, 2.73); + + NoMinimapWatcher no_minimap(env.console, COLOR_RED, Milliseconds(2000)); + int ret = run_until( + env.console, context, + [&](BotBaseContext& context){ + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, ConsoleHandle& console, BotBaseContext& context){ + pbf_move_left_joystick(context, 128, 0, 10 * TICKS_PER_SECOND, 100); + }, + [&](const ProgramInfo& info, ConsoleHandle& console, BotBaseContext& context){ + pbf_move_left_joystick(context, 0, 0, 100, 20); + }, + 5, 3 + ); + }, + {no_minimap} + ); + if (ret < 0){ + throw OperationFailedException( + ErrorReport::SEND_ERROR_REPORT, + env.logger(), + "Failed to enter Cortondo Gym." + ); + } + + wait_for_overworld(env.program_info(), env.console, context); + + // talk to receptionist + walk_forward_until_dialog(env.program_info(), env.console, context, NavigationMovementMode::DIRECTIONAL_SPAM_A, 10); + clear_dialog(env.console, context, ClearDialogMode::STOP_BATTLE, 60, {CallbackEnum::BATTLE, CallbackEnum::PROMPT_DIALOG, CallbackEnum::DIALOG_ARROW}); + + // battle Katy + run_battle_press_A(env.console, context, BattleStopCondition::STOP_DIALOG, {CallbackEnum::GRADIENT_ARROW}, true); + mash_button_till_overworld(env.console, context, BUTTON_A, 360); + + // leave gym building + pbf_move_left_joystick(context, 128, 255, 500, 100); + pbf_wait(context, 3 * TICKS_PER_SECOND); + // wait for overworld after leaving gym + wait_for_overworld(env.program_info(), env.console, context, 30); + + pbf_move_left_joystick(context, 128, 0, 450, 100); + direction.change_direction(env.program_info(), env.console, context, 1.26); + pbf_move_left_joystick(context, 128, 0, 1600, 100); + fly_to_overlapping_flypoint(env.program_info(), env.console, context); + + break; + }catch (...){ + context.wait_for_all_requests(); + env.console.log("Resetting from checkpoint."); + reset_game(env.program_info(), env.console, context); + stats.m_reset++; + env.update_stats(); + } + } + +} + + + + +} +} +} diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_12.h b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_12.h new file mode 100644 index 000000000..0af71061a --- /dev/null +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_12.h @@ -0,0 +1,41 @@ +/* Autostory + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#ifndef PokemonAutomation_PokemonSV_AutoStory_Segment_12_H +#define PokemonAutomation_PokemonSV_AutoStory_Segment_12_H + +#include +#include "Common/Cpp/Options/EnumDropdownOption.h" +#include "CommonFramework/Notifications/EventNotificationsTable.h" +#include "CommonFramework/Options/LanguageOCROption.h" +#include "NintendoSwitch/Options/NintendoSwitch_GoHomeWhenDoneOption.h" +#include "Common/NintendoSwitch/NintendoSwitch_ControllerDefs.h" +#include "PokemonSV/Programs/PokemonSV_Navigation.h" +#include "PokemonSV_AutoStoryTools.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonSV{ + +class AutoStory_Segment_12 : public AutoStory_Segment{ +public: + virtual std::string name() const override; + virtual std::string start_text() const override; + virtual std::string end_text() const override; + virtual void run_segment( + SingleSwitchProgramEnvironment& env, + BotBaseContext& context, + AutoStoryOptions options) const override; +}; + +// start: At Cortondo East Pokecenter. +// end: Beat Cortondo Gym. At Cortondo West Pokecenter. +void checkpoint_28(SingleSwitchProgramEnvironment& env, BotBaseContext& context, EventNotificationOption& notif_status_update); + +} +} +} +#endif diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_13.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_13.cpp new file mode 100644 index 000000000..6cb0c08bb --- /dev/null +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_13.cpp @@ -0,0 +1,334 @@ +/* AutoStory + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#include "CommonFramework/GlobalSettingsPanel.h" +#include "CommonFramework/Exceptions/FatalProgramException.h" +#include "CommonFramework/Exceptions/OperationFailedException.h" +#include "CommonFramework/InferenceInfra/InferenceRoutines.h" +#include "CommonFramework/Notifications/ProgramNotifications.h" +#include "CommonFramework/Tools/StatsTracking.h" +#include "CommonFramework/Tools/VideoResolutionCheck.h" +#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" +#include "Pokemon/Pokemon_Strings.h" +#include "PokemonSwSh/Inference/PokemonSwSh_IvJudgeReader.h" +#include "PokemonSV/Programs/PokemonSV_GameEntry.h" +#include "PokemonSV/Programs/PokemonSV_SaveGame.h" +#include "PokemonSV_AutoStoryTools.h" +#include "PokemonSV_AutoStory_Segment_13.h" + +//#include +//using std::cout; +//using std::endl; +//#include +//#include + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonSV{ + +using namespace Pokemon; + + + + +std::string AutoStory_Segment_13::name() const{ + return "11.1: Bombirdier Titan: Go to West Province Area One Central Pokecenter"; +} + +std::string AutoStory_Segment_13::start_text() const{ + return "Start: At Cortondo West Pokecenter"; +} + +std::string AutoStory_Segment_13::end_text() const{ + return "End: At West Province Area One Central Pokecenter"; +} + +void AutoStory_Segment_13::run_segment(SingleSwitchProgramEnvironment& env, BotBaseContext& context, AutoStoryOptions options) const{ + AutoStoryStats& stats = env.current_stats(); + + context.wait_for_all_requests(); + env.console.overlay().add_log("Start Segment 11.1: Bombirdier Titan: Go to West Province Area One Central Pokecenter", COLOR_ORANGE); + + checkpoint_29(env, context, options.notif_status_update); + + context.wait_for_all_requests(); + env.console.log("End Segment 11.1: Bombirdier Titan: Go to West Province Area One Central Pokecenter", COLOR_GREEN); + stats.m_segment++; + env.update_stats(); + +} + +// todo: shift all checkpoint numbers to make space for the Cortondo checkpoints +void checkpoint_29( + SingleSwitchProgramEnvironment& env, + BotBaseContext& context, + EventNotificationOption& notif_status_update +){ + AutoStoryStats& stats = env.current_stats(); + bool first_attempt = true; + while (true){ + try{ + if (first_attempt){ + checkpoint_save(env, context, notif_status_update); + first_attempt = false; + } + context.wait_for_all_requests(); + + fly_to_overlapping_flypoint(env.program_info(), env.console, context); + + // align for long stretch 1, part 1 + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_NEW_MARKER, 70, 0, 60); + + + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 30, 15, false); + + // align for long stretch 1, part 2 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::ZOOM_IN, 128, 255, 40}, + {ZoomChange::KEEP_ZOOM, 80, 0, 75} + ); + + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 12, 12, false); + + // align for long stretch 1, part 3 + + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::ZOOM_IN, 128, 255, 60}, + {ZoomChange::KEEP_ZOOM, 95, 0, 115} + ); + + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 36, 12, false); + + // align for long stretch 2 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::ZOOM_IN, 128, 255, 100}, + {ZoomChange::KEEP_ZOOM, 0, 105, 65} + ); + + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 45, 15, false); + + // align for long stretch 3, part 1 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::ZOOM_IN, 255, 128, 65}, + {ZoomChange::KEEP_ZOOM, 0, 50, 87} + ); + + + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 20, 10, false); + + // align for long stretch 3, part 2 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::ZOOM_IN, 255, 160, 65}, + {ZoomChange::KEEP_ZOOM, 20, 0, 110} + ); + + + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 30, 10, false); + + // align for long stretch 3, part 3 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::ZOOM_IN, 0, 60, 110}, + {ZoomChange::KEEP_ZOOM, 255, 128, 115} + ); + + + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 30, 10, false); + + // align for long stretch 3, part 4 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::ZOOM_IN, 0, 128, 100}, + {ZoomChange::KEEP_ZOOM, 255, 67, 90} //{ZoomChange::KEEP_ZOOM, 255, 70, 90} + ); + + + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 36, 12, false); + + // align to cross bridge + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::ZOOM_IN, 0, 128, 90}, + {ZoomChange::KEEP_ZOOM, 255, 35, 67} + ); + + + // attempt to cross bridge. If fall into water, go back to start position (just before bridge) and try again + WallClock start_to_cross_bridge = current_time(); + while (true){ + if (current_time() - start_to_cross_bridge > std::chrono::minutes(6)){ + throw OperationFailedException( + ErrorReport::SEND_ERROR_REPORT, env.console, + "checkpoint_26(): Failed to cross bridge after 6 minutes.", + true + ); + } + + try { + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::CLEAR_WITH_LETS_GO, + 128, 0, 20, 20, false); + + break; + + }catch (...){ // try again if fall into water + pbf_mash_button(context, BUTTON_A, 250); + + // walk back to start position before bridge + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::ZOOM_IN, 255, 255, 180}, + {ZoomChange::KEEP_ZOOM, 33, 0, 180} + ); + + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::CLEAR_WITH_LETS_GO, + 128, 0, 20, 20, false); + + + // align to cross bridge + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::ZOOM_IN, 0, 128, 90}, + {ZoomChange::KEEP_ZOOM, 255, 35, 67} + ); + + + } + } + + confirm_no_overlapping_flypoint(env.program_info(), env.console, context); + pbf_press_button(context, BUTTON_B, 20, 100); + handle_unexpected_battles(env.program_info(), env.console, context, + [&](const ProgramInfo& info, ConsoleHandle& console, BotBaseContext& context){ + press_Bs_to_back_to_overworld(env.program_info(), env.console, context); + }); + + env.console.log("Successfully crossed the bridge."); + + // align for post-bridge section 1 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::ZOOM_IN, 0, 150, 60}, + {ZoomChange::KEEP_ZOOM, 255, 60, 50} // {ZoomChange::KEEP_ZOOM, 255, 60, 50} + ); + + + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 20, 10, false); + + // align for post-bridge section 2 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::ZOOM_IN, 0, 150, 60}, + {ZoomChange::KEEP_ZOOM, 255, 105, 50} + ); + + + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 20, 10, false); + + // align for post-bridge section 3. move up towards tree + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::ZOOM_IN, 0, 128, 50}, + {ZoomChange::KEEP_ZOOM, 255, 90, 35} + ); + + + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 20, 10, false); + + // align for post-bridge section 4 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::ZOOM_IN, 0, 128, 50}, + {ZoomChange::KEEP_ZOOM, 255, 55, 25} + ); + + + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 20, 10, false); + + + + // align for post-bridge section 5. set marker to pokecenter. + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::ZOOM_IN, 0, 128, 50}, + {ZoomChange::KEEP_ZOOM, 128, 128, 0} + ); + + + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 30, 10, false); + + + // align for post-bridge section 6. set marker past pokecenter + handle_unexpected_battles(env.program_info(), env.console, context, + [&](const ProgramInfo& info, ConsoleHandle& console, BotBaseContext& context){ + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_NEW_MARKER, 0, 200, 30); + }); + // realign_player_from_landmark( + // env.program_info(), env.console, context, + // {ZoomChange::ZOOM_IN, 128, 128, 0}, + // {ZoomChange::KEEP_ZOOM, 0, 180, 20} + // ); + + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_TIME, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 15, 12, 12, false); + + + + fly_to_overlapping_flypoint(env.program_info(), env.console, context); + + + break; + }catch (...){ + context.wait_for_all_requests(); + env.console.log("Resetting from checkpoint."); + reset_game(env.program_info(), env.console, context); + stats.m_reset++; + env.update_stats(); + } + } + +} + + + + + +} +} +} diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_13.h b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_13.h new file mode 100644 index 000000000..a5a7bd866 --- /dev/null +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_13.h @@ -0,0 +1,45 @@ +/* Autostory + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#ifndef PokemonAutomation_PokemonSV_AutoStory_Segment_13_H +#define PokemonAutomation_PokemonSV_AutoStory_Segment_13_H + +#include +#include "Common/Cpp/Options/EnumDropdownOption.h" +#include "CommonFramework/Notifications/EventNotificationsTable.h" +#include "CommonFramework/Options/LanguageOCROption.h" +#include "NintendoSwitch/Options/NintendoSwitch_GoHomeWhenDoneOption.h" +#include "Common/NintendoSwitch/NintendoSwitch_ControllerDefs.h" +#include "PokemonSV/Programs/PokemonSV_Navigation.h" +#include "PokemonSV_AutoStoryTools.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonSV{ + +class AutoStory_Segment_13 : public AutoStory_Segment{ +public: + virtual std::string name() const override; + virtual std::string start_text() const override; + virtual std::string end_text() const override; + virtual void run_segment( + SingleSwitchProgramEnvironment& env, + BotBaseContext& context, + AutoStoryOptions options) const override; +}; + + +// start: At Cortondo West Pokecenter. +// end: At West Province Area One Central Pokecenter +void checkpoint_29(SingleSwitchProgramEnvironment& env, BotBaseContext& context, EventNotificationOption& notif_status_update); + + + + +} +} +} +#endif diff --git a/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_Navigation.cpp b/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_Navigation.cpp index 388fd3b6c..5d98f7d12 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_Navigation.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_Navigation.cpp @@ -553,7 +553,7 @@ void leave_phone_to_overworld(const ProgramInfo& info, ConsoleHandle& console, B ErrorReport::SEND_ERROR_REPORT, console, "leave_phone_to_overworld(): Unknown state after 10 button Y presses.", true - ); + ); } } @@ -832,9 +832,10 @@ void walk_forward_until_dialog( if (movement_mode == NavigationMovementMode::DIRECTIONAL_ONLY){ pbf_wait(context, seconds_timeout * TICKS_PER_SECOND); } else if (movement_mode == NavigationMovementMode::DIRECTIONAL_SPAM_A){ - for (size_t j = 0; j < seconds_timeout; j++){ - pbf_press_button(context, BUTTON_A, 20, 105); - } + pbf_mash_button(context, BUTTON_A, seconds_timeout * TICKS_PER_SECOND); + // for (size_t j = 0; j < seconds_timeout; j++){ + // pbf_press_button(context, BUTTON_A, 20, 105); + // } } }, {dialog}