From 0667087344d185dbe71dd7213af9173a951055d6 Mon Sep 17 00:00:00 2001 From: jw098 Date: Thu, 16 Oct 2025 20:30:02 -0700 Subject: [PATCH 01/10] checkpoint 85 --- .../PokemonSV_AutoStory_Segment_33.cpp | 18 ++++++++++++++---- .../AutoStory/PokemonSV_AutoStory_Segment_33.h | 2 +- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp index 10c6f52dd8..a7ac9a5835 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp @@ -28,15 +28,15 @@ namespace PokemonSV{ std::string AutoStory_Segment_33::name() const{ - return ""; + return "33: Starfall Street: Clavell battle"; } std::string AutoStory_Segment_33::start_text() const{ - return "Start: "; + return "Start: Beat Alfornada Gym (Psychic). At Alfornada Pokecenter."; } std::string AutoStory_Segment_33::end_text() const{ - return "End: "; + return "End: Beat Clavell. At Academy fly point."; } void AutoStory_Segment_33::run_segment( @@ -52,7 +52,7 @@ void AutoStory_Segment_33::run_segment( context.wait_for_all_requests(); env.console.log("Start Segment " + name(), COLOR_ORANGE); - // checkpoint_(env, context, options.notif_status_update, stats); + checkpoint_85(env, context, options.notif_status_update, stats); context.wait_for_all_requests(); env.console.log("End Segment " + name(), COLOR_GREEN); @@ -63,8 +63,18 @@ void AutoStory_Segment_33::run_segment( void checkpoint_85(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats){ checkpoint_reattempt_loop(env, context, notif_status_update, stats, [&](size_t attempt_number){ + move_cursor_towards_flypoint_and_go_there(env.program_info(), env.console, context, {ZoomChange::KEEP_ZOOM, 255, 50, 320}, FlyPoint::FAST_TRAVEL); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_NEW_MARKER, 128, 0, 80); + walk_forward_until_dialog(env.program_info(), env.console, context, NavigationMovementMode::DIRECTIONAL_ONLY, 30); + clear_dialog(env.console, context, ClearDialogMode::STOP_BATTLE, 60, {CallbackEnum::PROMPT_DIALOG, CallbackEnum::BATTLE, CallbackEnum:: DIALOG_ARROW}); + + env.console.log("Battle Clavell."); + run_trainer_battle_press_A(env.console, context, BattleStopCondition::STOP_DIALOG); + mash_button_till_overworld(env.console, context, BUTTON_A); + + move_cursor_towards_flypoint_and_go_there(env.program_info(), env.console, context, {ZoomChange::ZOOM_IN, 0, 0, 0}, FlyPoint::FAST_TRAVEL); }); } diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.h b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.h index ae91b4335e..39b2d83cd3 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.h +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.h @@ -27,7 +27,7 @@ class AutoStory_Segment_33 : public AutoStory_Segment{ }; // start: Beat Alfornada gym challenge. Beat Alfornada gym. At Alfronada Pokecenter. -// end: +// end: Beat Clavell. At Naranja Academy fly point. void checkpoint_85(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats); // start: From 1907decd17756075b9f07fcee46bcac42573b4da Mon Sep 17 00:00:00 2001 From: jw098 Date: Thu, 16 Oct 2025 21:13:24 -0700 Subject: [PATCH 02/10] segment 34 setup --- .../AutoStory/PokemonSV_AutoStory.cpp | 2 +- .../PokemonSV_AutoStory_Segment_33.cpp | 16 ------ .../PokemonSV_AutoStory_Segment_33.h | 23 +------- .../PokemonSV_AutoStory_Segment_34.cpp | 57 +++++++++++++++++-- .../PokemonSV_AutoStory_Segment_34.h | 21 +++++++ 5 files changed, 76 insertions(+), 43 deletions(-) diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp index bded3f8e97..6ae22048b3 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp @@ -729,7 +729,7 @@ void AutoStory::test_checkpoints( checkpoint_list.push_back([&](){checkpoint_83(env, context, notif_status_update, stats);}); checkpoint_list.push_back([&](){checkpoint_84(env, context, notif_status_update, stats);}); checkpoint_list.push_back([&](){checkpoint_85(env, context, notif_status_update, stats);}); - checkpoint_list.push_back([&](){checkpoint_86(env, context, notif_status_update, stats);}); + checkpoint_list.push_back([&](){checkpoint_86(env, context, notif_status_update, stats, language, starter_choice);}); checkpoint_list.push_back([&](){checkpoint_87(env, context, notif_status_update, stats);}); checkpoint_list.push_back([&](){checkpoint_88(env, context, notif_status_update, stats);}); checkpoint_list.push_back([&](){checkpoint_89(env, context, notif_status_update, stats);}); diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp index a7ac9a5835..5eadb74166 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp @@ -80,22 +80,6 @@ void checkpoint_85(SingleSwitchProgramEnvironment& env, ProControllerContext& co -void checkpoint_86(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats){ -} - -void checkpoint_87(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats){ -} - -void checkpoint_88(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats){ -} - -void checkpoint_89(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats){ -} - -void checkpoint_90(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats){ -} - - diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.h b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.h index 39b2d83cd3..2c673dc932 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.h +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.h @@ -27,30 +27,9 @@ class AutoStory_Segment_33 : public AutoStory_Segment{ }; // start: Beat Alfornada gym challenge. Beat Alfornada gym. At Alfronada Pokecenter. -// end: Beat Clavell. At Naranja Academy fly point. +// end: Beat Clavell. At Academy fly point. void checkpoint_85(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats); -// start: -// end: -void checkpoint_86(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats); - -// start: -// end: -void checkpoint_87(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats); - -// start: -// end: -void checkpoint_88(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats); - -// start: -// end: -void checkpoint_89(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats); - -// start: -// end: -void checkpoint_90(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats); - - } diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.cpp index 01bdc929f1..5462bad5f5 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.cpp @@ -3,6 +3,9 @@ * From: https://github.com/PokemonAutomation/ * */ +#include "CommonFramework/VideoPipeline/VideoFeed.h" +#include "Pokemon/Inference/Pokemon_NameReader.h" +#include "CommonFramework/Notifications/ProgramInfo.h" #include "CommonFramework/Exceptions/OperationFailedException.h" #include "CommonTools/Async/InferenceRoutines.h" @@ -28,15 +31,15 @@ namespace PokemonSV{ std::string AutoStory_Segment_34::name() const{ - return ""; + return "34: Elite Four"; } std::string AutoStory_Segment_34::start_text() const{ - return "Start: "; + return "Start: Beat Clavell. At Academy fly point."; } std::string AutoStory_Segment_34::end_text() const{ - return "End: "; + return "End: Beat Elite Four. At Pokemon League Pokecenter."; } void AutoStory_Segment_34::run_segment( @@ -52,7 +55,7 @@ void AutoStory_Segment_34::run_segment( context.wait_for_all_requests(); env.console.log("Start Segment " + name(), COLOR_ORANGE); - // checkpoint_(env, context, options.notif_status_update, stats); + checkpoint_86(env, context, options.notif_status_update, stats, options.language, options.starter_choice); context.wait_for_all_requests(); env.console.log("End Segment " + name(), COLOR_GREEN); @@ -60,6 +63,52 @@ void AutoStory_Segment_34::run_segment( } +void checkpoint_86(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats, Language language, StarterChoice starter_choice){ + checkpoint_reattempt_loop(env, context, notif_status_update, stats, + [&](size_t attempt_number){ + + ImageFloatBox box = {0.116223, 0.895000, 0.194915, 0.051724}; + ImageViewRGB32 image = extract_box_reference(env.console.video().snapshot(), box); + + std::set ret; + + OCR::StringMatchResult result = Pokemon::PokemonNameReader::instance().read_substring( + env.console.logger(), language, image, + OCR::WHITE_TEXT_FILTERS() + ); + if (result.results.empty()){ + env.console.log("Unable to check whether we are riding Miraidon or Koraidon."); + OperationFailedException exception( + ErrorReport::SEND_ERROR_REPORT, + "Unable to check whether we are riding Miraidon or Koraidon.\n" + language_warning(language), + env.console + ); + exception.send_recoverable_notification(env); + }else{ + for (const auto& item : result.results){ + ret.insert(item.second.token); + } + } + + + + }); +} + +void checkpoint_87(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats){ +} + +void checkpoint_88(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats){ +} + +void checkpoint_89(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats){ +} + +void checkpoint_90(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats){ +} + + + } } diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.h b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.h index e38ad1621f..9ec1088fa5 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.h +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.h @@ -26,6 +26,27 @@ class AutoStory_Segment_34 : public AutoStory_Segment{ ) const override; }; +// start: Beat Clavell. At Academy fly point. +// end: +void checkpoint_86(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats, Language language, StarterChoice starter_choice); + +// start: +// end: +void checkpoint_87(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats); + +// start: +// end: +void checkpoint_88(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats); + +// start: +// end: +void checkpoint_89(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats); + +// start: +// end: +void checkpoint_90(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats); + + From 88381922d4f34b2b41445f5799c2f9379d7056fb Mon Sep 17 00:00:00 2001 From: jw098 Date: Thu, 16 Oct 2025 22:49:26 -0700 Subject: [PATCH 03/10] checkpoint 86 --- .../AutoStory/PokemonSV_AutoStory.cpp | 4 +- .../PokemonSV_AutoStory_Segment_34.cpp | 136 +++++++++++++++--- .../PokemonSV_AutoStory_Segment_34.h | 12 +- 3 files changed, 123 insertions(+), 29 deletions(-) diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp index 6ae22048b3..ae31557a60 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp @@ -729,8 +729,8 @@ void AutoStory::test_checkpoints( checkpoint_list.push_back([&](){checkpoint_83(env, context, notif_status_update, stats);}); checkpoint_list.push_back([&](){checkpoint_84(env, context, notif_status_update, stats);}); checkpoint_list.push_back([&](){checkpoint_85(env, context, notif_status_update, stats);}); - checkpoint_list.push_back([&](){checkpoint_86(env, context, notif_status_update, stats, language, starter_choice);}); - checkpoint_list.push_back([&](){checkpoint_87(env, context, notif_status_update, stats);}); + checkpoint_list.push_back([&](){checkpoint_86(env, context, notif_status_update, stats);}); + checkpoint_list.push_back([&](){checkpoint_87(env, context, notif_status_update, stats, language, starter_choice);}); checkpoint_list.push_back([&](){checkpoint_88(env, context, notif_status_update, stats);}); checkpoint_list.push_back([&](){checkpoint_89(env, context, notif_status_update, stats);}); checkpoint_list.push_back([&](){checkpoint_90(env, context, notif_status_update, stats);}); diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.cpp index 5462bad5f5..5176c90fc7 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.cpp @@ -6,6 +6,7 @@ #include "CommonFramework/VideoPipeline/VideoFeed.h" #include "Pokemon/Inference/Pokemon_NameReader.h" #include "CommonFramework/Notifications/ProgramInfo.h" +#include "PokemonSV/Inference/Overworld/PokemonSV_DirectionDetector.h" #include "CommonFramework/Exceptions/OperationFailedException.h" #include "CommonTools/Async/InferenceRoutines.h" @@ -55,7 +56,8 @@ void AutoStory_Segment_34::run_segment( context.wait_for_all_requests(); env.console.log("Start Segment " + name(), COLOR_ORANGE); - checkpoint_86(env, context, options.notif_status_update, stats, options.language, options.starter_choice); + checkpoint_86(env, context, options.notif_status_update, stats); + checkpoint_87(env, context, options.notif_status_update, stats, options.language, options.starter_choice); context.wait_for_all_requests(); env.console.log("End Segment " + name(), COLOR_GREEN); @@ -63,41 +65,131 @@ void AutoStory_Segment_34::run_segment( } -void checkpoint_86(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats, Language language, StarterChoice starter_choice){ +void checkpoint_86(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats){ checkpoint_reattempt_loop(env, context, notif_status_update, stats, [&](size_t attempt_number){ - ImageFloatBox box = {0.116223, 0.895000, 0.194915, 0.051724}; - ImageViewRGB32 image = extract_box_reference(env.console.video().snapshot(), box); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_NEW_MARKER, 0, 128, 50); + DirectionDetector direction; + direction.change_direction(env.program_info(), env.console, context, 1.222127); + pbf_move_left_joystick(context, 128, 0, 1100, 50); - std::set ret; + get_on_ride(env.program_info(), env.console, context); + direction.change_direction(env.program_info(), env.console, context, 1.484555); - OCR::StringMatchResult result = Pokemon::PokemonNameReader::instance().read_substring( - env.console.logger(), language, image, - OCR::WHITE_TEXT_FILTERS() + pbf_move_left_joystick(context, 128, 0, 1506ms, 0ms); + pbf_controller_state(context, BUTTON_B, DPAD_NONE, 128, 0, 128, 128, 703ms); + pbf_move_left_joystick(context, 128, 0, 233ms, 0ms); + pbf_controller_state(context, BUTTON_B, DPAD_NONE, 128, 0, 128, 128, 5098ms); + pbf_move_left_joystick(context, 128, 0, 1000ms, 0ms); + + wait_for_overworld(env.program_info(), env.console, context); + + // marker 1 {0.429688, 0.299074} + place_marker_offset_from_flypoint(env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 0, 0, 0}, + FlyPoint::POKECENTER, + {0.429688, 0.299074} ); - if (result.results.empty()){ - env.console.log("Unable to check whether we are riding Miraidon or Koraidon."); - OperationFailedException exception( - ErrorReport::SEND_ERROR_REPORT, - "Unable to check whether we are riding Miraidon or Koraidon.\n" + language_warning(language), - env.console - ); - exception.send_recoverable_notification(env); - }else{ - for (const auto& item : result.results){ - ret.insert(item.second.token); + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 30, 10, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); } - } - + ); + + + // marker 2 {0.482812, 0.378704} + place_marker_offset_from_flypoint(env.program_info(), env.console, context, + {ZoomChange::ZOOM_IN, 0, 0, 50}, + FlyPoint::POKECENTER, + {0.482812, 0.378704} + ); + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 40, 10, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + + // marker 3 {0.638021, 0.676852} + place_marker_offset_from_flypoint(env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 0, 0, 50}, + FlyPoint::POKECENTER, + {0.638021, 0.676852} + ); + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_DIALOG, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 60, 30, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + // clear_dialog(env.console, context, ClearDialogMode::STOP_OVERWORLD, 60, {CallbackEnum::OVERWORLD}); + mash_button_till_overworld(env.console, context, BUTTON_A); }); } -void checkpoint_87(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats){ +void checkpoint_87(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats, Language language, StarterChoice starter_choice){ } +std::string get_ride_pokemon_name(SingleSwitchProgramEnvironment& env, ProControllerContext& context, Language language){ + enter_menu_from_overworld(env.program_info(), env.console, context, -1); + + ImageFloatBox box = {0.116223, 0.895000, 0.194915, 0.051724}; + ImageViewRGB32 image = extract_box_reference(env.console.video().snapshot(), box); + + OCR::StringMatchResult ocr_result = Pokemon::PokemonNameReader::instance().read_substring( + env.console.logger(), language, image, + OCR::WHITE_TEXT_FILTERS() + ); + std::multimap results; + if (!ocr_result.results.empty()){ + for (const auto& result : ocr_result.results){ + results.emplace(result.first, result.second); + } + } + + if (results.empty()){ + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "AutoStory_Segment_34::checkpoint_86(): Unable to read selected item. No valid results.\n" + language_warning(language), + env.console + ); + } + + if (results.size() > 1){ + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "AutoStory_Segment_34::checkpoint_86(): Unable to read selected item. Ambiguous or multiple results.\n" + language_warning(language), + env.console + ); + } + + std::string ride_pokemon = results.begin()->second.token; + + // cout << ride_pokemon << endl; + return ride_pokemon; +} + + void checkpoint_88(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats){ } diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.h b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.h index 9ec1088fa5..bd9c906f76 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.h +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.h @@ -27,12 +27,14 @@ class AutoStory_Segment_34 : public AutoStory_Segment{ }; // start: Beat Clavell. At Academy fly point. -// end: -void checkpoint_86(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats, Language language, StarterChoice starter_choice); +// end: At Pokemon League entrance. +void checkpoint_86(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats); -// start: -// end: -void checkpoint_87(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats); +// start: At Pokemon League entrance. +// end: Beat Elite Four. At Pokemon League Pokecenter. +void checkpoint_87(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats, Language language, StarterChoice starter_choice); + +std::string get_ride_pokemon_name(SingleSwitchProgramEnvironment& env, ProControllerContext& context, Language language); // start: // end: From 6f18e3690847139adab43a2cc6d4ebcdbe1cf102 Mon Sep 17 00:00:00 2001 From: jw098 Date: Fri, 17 Oct 2025 12:37:28 -0700 Subject: [PATCH 04/10] merge Elite Four and Clavell battle checkpoints into the same segment. --- .../AutoStory/PokemonSV_AutoStory.cpp | 2 +- .../PokemonSV_AutoStory_Segment_33.cpp | 135 ++++++++++++++++- .../PokemonSV_AutoStory_Segment_33.h | 10 ++ .../PokemonSV_AutoStory_Segment_34.cpp | 139 +----------------- .../PokemonSV_AutoStory_Segment_34.h | 9 -- 5 files changed, 149 insertions(+), 146 deletions(-) diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp index ae31557a60..9345e7b961 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp @@ -109,7 +109,7 @@ 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()); diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp index 5eadb74166..34388d96e5 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp @@ -3,6 +3,10 @@ * From: https://github.com/PokemonAutomation/ * */ +#include "CommonFramework/VideoPipeline/VideoFeed.h" +#include "Pokemon/Inference/Pokemon_NameReader.h" +#include "CommonFramework/Notifications/ProgramInfo.h" +#include "PokemonSV/Inference/Overworld/PokemonSV_DirectionDetector.h" #include "CommonFramework/Exceptions/OperationFailedException.h" #include "CommonTools/Async/InferenceRoutines.h" @@ -28,7 +32,7 @@ namespace PokemonSV{ std::string AutoStory_Segment_33::name() const{ - return "33: Starfall Street: Clavell battle"; + return "33: Clavell battle, Elite Four"; } std::string AutoStory_Segment_33::start_text() const{ @@ -36,7 +40,7 @@ std::string AutoStory_Segment_33::start_text() const{ } std::string AutoStory_Segment_33::end_text() const{ - return "End: Beat Clavell. At Academy fly point."; + return "End: Beat Clavell. Beat Elite Four. At Pokemon League Pokecenter."; } void AutoStory_Segment_33::run_segment( @@ -53,6 +57,8 @@ void AutoStory_Segment_33::run_segment( env.console.log("Start Segment " + name(), COLOR_ORANGE); checkpoint_85(env, context, options.notif_status_update, stats); + checkpoint_86(env, context, options.notif_status_update, stats); + checkpoint_87(env, context, options.notif_status_update, stats, options.language, options.starter_choice); context.wait_for_all_requests(); env.console.log("End Segment " + name(), COLOR_GREEN); @@ -79,6 +85,131 @@ void checkpoint_85(SingleSwitchProgramEnvironment& env, ProControllerContext& co } +void checkpoint_86(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats){ + checkpoint_reattempt_loop(env, context, notif_status_update, stats, + [&](size_t attempt_number){ + + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_NEW_MARKER, 0, 128, 50); + DirectionDetector direction; + direction.change_direction(env.program_info(), env.console, context, 1.222127); + pbf_move_left_joystick(context, 128, 0, 1100, 50); + + get_on_ride(env.program_info(), env.console, context); + direction.change_direction(env.program_info(), env.console, context, 1.484555); + + pbf_move_left_joystick(context, 128, 0, 1506ms, 0ms); + pbf_controller_state(context, BUTTON_B, DPAD_NONE, 128, 0, 128, 128, 703ms); + pbf_move_left_joystick(context, 128, 0, 233ms, 0ms); + pbf_controller_state(context, BUTTON_B, DPAD_NONE, 128, 0, 128, 128, 5098ms); + pbf_move_left_joystick(context, 128, 0, 1000ms, 0ms); + + wait_for_overworld(env.program_info(), env.console, context); + + // marker 1 {0.429688, 0.299074} + place_marker_offset_from_flypoint(env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 0, 0, 0}, + FlyPoint::POKECENTER, + {0.429688, 0.299074} + ); + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 30, 10, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + + // marker 2 {0.482812, 0.378704} + place_marker_offset_from_flypoint(env.program_info(), env.console, context, + {ZoomChange::ZOOM_IN, 0, 0, 50}, + FlyPoint::POKECENTER, + {0.482812, 0.378704} + ); + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 40, 10, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + + // marker 3 {0.638021, 0.676852} + place_marker_offset_from_flypoint(env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 0, 0, 50}, + FlyPoint::POKECENTER, + {0.638021, 0.676852} + ); + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_DIALOG, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 60, 30, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // clear_dialog(env.console, context, ClearDialogMode::STOP_OVERWORLD, 60, {CallbackEnum::OVERWORLD}); + mash_button_till_overworld(env.console, context, BUTTON_A); + + }); +} + +void checkpoint_87(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats, Language language, StarterChoice starter_choice){ +} + +std::string get_ride_pokemon_name(SingleSwitchProgramEnvironment& env, ProControllerContext& context, Language language){ + enter_menu_from_overworld(env.program_info(), env.console, context, -1); + + ImageFloatBox box = {0.116223, 0.895000, 0.194915, 0.051724}; + ImageViewRGB32 image = extract_box_reference(env.console.video().snapshot(), box); + + OCR::StringMatchResult ocr_result = Pokemon::PokemonNameReader::instance().read_substring( + env.console.logger(), language, image, + OCR::WHITE_TEXT_FILTERS() + ); + std::multimap results; + if (!ocr_result.results.empty()){ + for (const auto& result : ocr_result.results){ + results.emplace(result.first, result.second); + } + } + + if (results.empty()){ + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "AutoStory_Segment_34::checkpoint_86(): Unable to read selected item. No valid results.\n" + language_warning(language), + env.console + ); + } + + if (results.size() > 1){ + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "AutoStory_Segment_34::checkpoint_86(): Unable to read selected item. Ambiguous or multiple results.\n" + language_warning(language), + env.console + ); + } + + std::string ride_pokemon = results.begin()->second.token; + + // cout << ride_pokemon << endl; + return ride_pokemon; +} + + diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.h b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.h index 2c673dc932..e9f06f2915 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.h +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.h @@ -30,6 +30,16 @@ class AutoStory_Segment_33 : public AutoStory_Segment{ // end: Beat Clavell. At Academy fly point. void checkpoint_85(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats); +// start: Beat Clavell. At Academy fly point. +// end: At Pokemon League entrance. +void checkpoint_86(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats); + +// start: At Pokemon League entrance. +// end: Beat Elite Four. At Pokemon League Pokecenter. +void checkpoint_87(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats, Language language, StarterChoice starter_choice); + +std::string get_ride_pokemon_name(SingleSwitchProgramEnvironment& env, ProControllerContext& context, Language language); + } diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.cpp index 5176c90fc7..838a7abfd2 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.cpp @@ -3,10 +3,7 @@ * From: https://github.com/PokemonAutomation/ * */ -#include "CommonFramework/VideoPipeline/VideoFeed.h" -#include "Pokemon/Inference/Pokemon_NameReader.h" -#include "CommonFramework/Notifications/ProgramInfo.h" -#include "PokemonSV/Inference/Overworld/PokemonSV_DirectionDetector.h" + #include "CommonFramework/Exceptions/OperationFailedException.h" #include "CommonTools/Async/InferenceRoutines.h" @@ -32,15 +29,15 @@ namespace PokemonSV{ std::string AutoStory_Segment_34::name() const{ - return "34: Elite Four"; + return "35: "; } std::string AutoStory_Segment_34::start_text() const{ - return "Start: Beat Clavell. At Academy fly point."; + return "Start: Beat Clavell. Beat Elite Four. At Pokemon League Pokecenter."; } std::string AutoStory_Segment_34::end_text() const{ - return "End: Beat Elite Four. At Pokemon League Pokecenter."; + return "End: "; } void AutoStory_Segment_34::run_segment( @@ -56,8 +53,7 @@ void AutoStory_Segment_34::run_segment( context.wait_for_all_requests(); env.console.log("Start Segment " + name(), COLOR_ORANGE); - checkpoint_86(env, context, options.notif_status_update, stats); - checkpoint_87(env, context, options.notif_status_update, stats, options.language, options.starter_choice); + checkpoint_88(env, context, options.notif_status_update, stats); context.wait_for_all_requests(); env.console.log("End Segment " + name(), COLOR_GREEN); @@ -65,131 +61,6 @@ void AutoStory_Segment_34::run_segment( } -void checkpoint_86(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats){ - checkpoint_reattempt_loop(env, context, notif_status_update, stats, - [&](size_t attempt_number){ - - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_NEW_MARKER, 0, 128, 50); - DirectionDetector direction; - direction.change_direction(env.program_info(), env.console, context, 1.222127); - pbf_move_left_joystick(context, 128, 0, 1100, 50); - - get_on_ride(env.program_info(), env.console, context); - direction.change_direction(env.program_info(), env.console, context, 1.484555); - - pbf_move_left_joystick(context, 128, 0, 1506ms, 0ms); - pbf_controller_state(context, BUTTON_B, DPAD_NONE, 128, 0, 128, 128, 703ms); - pbf_move_left_joystick(context, 128, 0, 233ms, 0ms); - pbf_controller_state(context, BUTTON_B, DPAD_NONE, 128, 0, 128, 128, 5098ms); - pbf_move_left_joystick(context, 128, 0, 1000ms, 0ms); - - wait_for_overworld(env.program_info(), env.console, context); - - // marker 1 {0.429688, 0.299074} - place_marker_offset_from_flypoint(env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 0, 0, 0}, - FlyPoint::POKECENTER, - {0.429688, 0.299074} - ); - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 30, 10, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 0, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - - // marker 2 {0.482812, 0.378704} - place_marker_offset_from_flypoint(env.program_info(), env.console, context, - {ZoomChange::ZOOM_IN, 0, 0, 50}, - FlyPoint::POKECENTER, - {0.482812, 0.378704} - ); - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 40, 10, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 0, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - - // marker 3 {0.638021, 0.676852} - place_marker_offset_from_flypoint(env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 0, 0, 50}, - FlyPoint::POKECENTER, - {0.638021, 0.676852} - ); - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_DIALOG, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 60, 30, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 0, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // clear_dialog(env.console, context, ClearDialogMode::STOP_OVERWORLD, 60, {CallbackEnum::OVERWORLD}); - mash_button_till_overworld(env.console, context, BUTTON_A); - - }); -} - -void checkpoint_87(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats, Language language, StarterChoice starter_choice){ -} - -std::string get_ride_pokemon_name(SingleSwitchProgramEnvironment& env, ProControllerContext& context, Language language){ - enter_menu_from_overworld(env.program_info(), env.console, context, -1); - - ImageFloatBox box = {0.116223, 0.895000, 0.194915, 0.051724}; - ImageViewRGB32 image = extract_box_reference(env.console.video().snapshot(), box); - - OCR::StringMatchResult ocr_result = Pokemon::PokemonNameReader::instance().read_substring( - env.console.logger(), language, image, - OCR::WHITE_TEXT_FILTERS() - ); - std::multimap results; - if (!ocr_result.results.empty()){ - for (const auto& result : ocr_result.results){ - results.emplace(result.first, result.second); - } - } - - if (results.empty()){ - OperationFailedException::fire( - ErrorReport::SEND_ERROR_REPORT, - "AutoStory_Segment_34::checkpoint_86(): Unable to read selected item. No valid results.\n" + language_warning(language), - env.console - ); - } - - if (results.size() > 1){ - OperationFailedException::fire( - ErrorReport::SEND_ERROR_REPORT, - "AutoStory_Segment_34::checkpoint_86(): Unable to read selected item. Ambiguous or multiple results.\n" + language_warning(language), - env.console - ); - } - - std::string ride_pokemon = results.begin()->second.token; - - // cout << ride_pokemon << endl; - return ride_pokemon; -} - - void checkpoint_88(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats){ } diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.h b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.h index bd9c906f76..db5959d111 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.h +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.h @@ -26,15 +26,6 @@ class AutoStory_Segment_34 : public AutoStory_Segment{ ) const override; }; -// start: Beat Clavell. At Academy fly point. -// end: At Pokemon League entrance. -void checkpoint_86(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats); - -// start: At Pokemon League entrance. -// end: Beat Elite Four. At Pokemon League Pokecenter. -void checkpoint_87(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats, Language language, StarterChoice starter_choice); - -std::string get_ride_pokemon_name(SingleSwitchProgramEnvironment& env, ProControllerContext& context, Language language); // start: // end: From 15a21514d45c405ff372b409c27a9d0482aca6e8 Mon Sep 17 00:00:00 2001 From: jw098 Date: Fri, 17 Oct 2025 19:07:11 -0700 Subject: [PATCH 05/10] checkpoint 87: Elite Four test --- .../AutoStory/PokemonSV_AutoStory.cpp | 8 +- .../AutoStory/PokemonSV_AutoStoryTools.cpp | 2 +- .../PokemonSV_AutoStory_Segment_33.cpp | 143 ++++++++++++++++++ .../PokemonSV_AutoStory_Segment_33.h | 8 + 4 files changed, 156 insertions(+), 5 deletions(-) diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp index 9345e7b961..bfd43710b0 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp @@ -537,10 +537,10 @@ AutoStory::AutoStory() } void AutoStory::on_config_value_changed(void* object){ - ConfigOptionState state = (STARTPOINT_TUTORIAL.index() <= 1 && STORY_SECTION == StorySection::TUTORIAL) - ? ConfigOptionState::ENABLED - : ConfigOptionState::HIDDEN; - STARTERCHOICE.set_visibility(state); + // ConfigOptionState state = (STARTPOINT_TUTORIAL.index() <= 1 && STORY_SECTION == StorySection::TUTORIAL) + // ? ConfigOptionState::ENABLED + // : ConfigOptionState::HIDDEN; + // STARTERCHOICE.set_visibility(state); if (STORY_SECTION == StorySection::TUTORIAL){ STARTPOINT_TUTORIAL.set_visibility(ConfigOptionState::ENABLED); diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp index 0752a60a4c..cd2b28819e 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp @@ -92,7 +92,7 @@ void clear_dialog(VideoStream& stream, ProControllerContext& context, AdvanceDialogWatcher advance_dialog(COLOR_RED); OverworldWatcher overworld(stream.logger(), COLOR_CYAN); - PromptDialogWatcher prompt(COLOR_YELLOW, {0.50, 0.30, 0.40, 0.60}); + PromptDialogWatcher prompt(COLOR_YELLOW, {0.50, 0.25, 0.40, 0.65}); WhiteButtonWatcher whitebutton(COLOR_GREEN, WhiteButton::ButtonA_DarkBackground, {0.725, 0.833, 0.024, 0.045}); // {0.650, 0.650, 0.140, 0.240} DialogArrowWatcher dialog_arrow(COLOR_RED, stream.overlay(), {0.850, 0.820, 0.020, 0.050}, 0.8365, 0.846); NormalBattleMenuWatcher battle(COLOR_ORANGE); diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp index 34388d96e5..3f2c9f6264 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp @@ -4,6 +4,7 @@ * */ #include "CommonFramework/VideoPipeline/VideoFeed.h" +#include "CommonTools/Images/SolidColorTest.h" #include "Pokemon/Inference/Pokemon_NameReader.h" #include "CommonFramework/Notifications/ProgramInfo.h" #include "PokemonSV/Inference/Overworld/PokemonSV_DirectionDetector.h" @@ -168,8 +169,150 @@ void checkpoint_86(SingleSwitchProgramEnvironment& env, ProControllerContext& co } void checkpoint_87(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats, Language language, StarterChoice starter_choice){ + GameTitle game_title = GameTitle::UNKNOWN; + checkpoint_reattempt_loop(env, context, notif_status_update, stats, + [&](size_t attempt_number){ + if (game_title == GameTitle::UNKNOWN){ + game_title = get_game_title(env, context); + press_Bs_to_back_to_overworld(env.program_info(), env.console, context); + } + + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + + do_action_and_monitor_for_battles(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + walk_forward_while_clear_front_path(env.program_info(), env.console, context, 100); + walk_forward_until_dialog(env.program_info(), env.console, context, NavigationMovementMode::DIRECTIONAL_SPAM_A); + } + ); + // talk to door man + // clear_dialog(env.console, context, ClearDialogMode::STOP_OVERWORLD, 60, {CallbackEnum::OVERWORLD, CallbackEnum::PROMPT_DIALOG}); + mash_button_till_overworld(env.console, context, BUTTON_A); + + // move left to sit down + pbf_move_left_joystick(context, 0, 128, 100, 50); + + // talk to Rika 1. Choose first option. Walked here. + clear_dialog(env.console, context, ClearDialogMode::STOP_PROMPT, 60, {CallbackEnum::PROMPT_DIALOG}); + pbf_mash_button(context, BUTTON_A, 1000ms); + + // talk to Rika 2. Choose option based on your game title + clear_dialog(env.console, context, ClearDialogMode::STOP_PROMPT, 60, {CallbackEnum::PROMPT_DIALOG}); + + switch(game_title){ + case GameTitle::SCARLET: + pbf_press_dpad(context, DPAD_DOWN, 13, 20); + break; + case GameTitle::VIOLET: + pbf_press_dpad(context, DPAD_DOWN, 13, 20); + pbf_press_dpad(context, DPAD_DOWN, 13, 20); + break; + default: + throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "We don't know what game we are playing. We should know at this point."); + break; + } + pbf_mash_button(context, BUTTON_A, 1000ms); + + // talk to Rika 3. Came to become a Champion + clear_dialog(env.console, context, ClearDialogMode::STOP_PROMPT, 60, {CallbackEnum::PROMPT_DIALOG}); + pbf_press_dpad(context, DPAD_DOWN, 13, 20); + pbf_mash_button(context, BUTTON_A, 1000ms); + + // talk to Rika 4. Become stronger + clear_dialog(env.console, context, ClearDialogMode::STOP_PROMPT, 60, {CallbackEnum::PROMPT_DIALOG}); + pbf_mash_button(context, BUTTON_A, 1000ms); + + // talk to Rika 5. Difficult gym: Alfornada + clear_dialog(env.console, context, ClearDialogMode::STOP_PROMPT, 60, {CallbackEnum::PROMPT_DIALOG}); + pbf_press_dpad(context, DPAD_UP, 13, 20); + pbf_mash_button(context, BUTTON_A, 1000ms); + + // talk to Rika 6. Difficult gym leader name: Tulip + clear_dialog(env.console, context, ClearDialogMode::STOP_PROMPT, 60, {CallbackEnum::PROMPT_DIALOG}); + pbf_press_dpad(context, DPAD_UP, 13, 20); + pbf_mash_button(context, BUTTON_A, 1000ms); + + // talk to Rika 7. Difficult gym leader type: Psychic + clear_dialog(env.console, context, ClearDialogMode::STOP_PROMPT, 60, {CallbackEnum::PROMPT_DIALOG}); + pbf_press_dpad(context, DPAD_UP, 13, 20); + pbf_press_dpad(context, DPAD_UP, 13, 20); + pbf_mash_button(context, BUTTON_A, 1000ms); + + // talk to Rika 8. Starter pokemon: Grass/Fire/Water + clear_dialog(env.console, context, ClearDialogMode::STOP_PROMPT, 60, {CallbackEnum::PROMPT_DIALOG}); + switch(starter_choice){ + case StarterChoice::SPRIGATITO: + break; + case StarterChoice::FUECOCO: + pbf_press_dpad(context, DPAD_DOWN, 13, 20); + break; + case StarterChoice::QUAXLY: + pbf_press_dpad(context, DPAD_DOWN, 13, 20); + pbf_press_dpad(context, DPAD_DOWN, 13, 20); + break; + default: + throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "Invalid starter pokemon type. This shouldn't happen."); + break; + } + size_t num_extra_clicks = attempt_number % 3; // we add extra clicks when attempt_number > 0, to account for the fact that the user might not be enterint the correct starter. + for (size_t i = 0; i < num_extra_clicks; i++){ + pbf_press_dpad(context, DPAD_DOWN, 13, 20); + } + + pbf_mash_button(context, BUTTON_A, 1000ms); + + // talk to Rika 9. Become stronger + // talk to Rika 10. do you like pokemon + clear_dialog(env.console, context, ClearDialogMode::STOP_TIMEOUT, 20, {CallbackEnum::PROMPT_DIALOG}); + + // now done talking to Rika. walk around Rika's desk. + pbf_move_left_joystick(context, 128, 0, 100, 50); // stand up + pbf_move_left_joystick(context, 0, 128, 50, 50); // go left + pbf_move_left_joystick(context, 128, 0, 200, 50); // straight + pbf_move_left_joystick(context, 255, 128, 50, 50); // right + + walk_forward_until_dialog(env.program_info(), env.console, context, NavigationMovementMode::DIRECTIONAL_ONLY, 60); + clear_dialog(env.console, context, ClearDialogMode::STOP_BATTLE, 60, {CallbackEnum::BATTLE, CallbackEnum::DIALOG_ARROW}); + + + env.console.log("Battle Elite Four 1."); + run_trainer_battle_press_A(env.console, context, BattleStopCondition::STOP_DIALOG); + mash_button_till_overworld(env.console, context, BUTTON_A); + + // todo: run the third move when battling the Steel trainer + + + + }); } + +GameTitle get_game_title(SingleSwitchProgramEnvironment& env, ProControllerContext& context){ + GameTitle game_title = GameTitle::UNKNOWN; + enter_menu_from_overworld(env.program_info(), env.console, context, 0, MenuSide::RIGHT); + context.wait_for_all_requests(); + + VideoSnapshot screen = env.console.video().snapshot(); + ImageFloatBox box = {0.03, 0.94, 0.40, 0.04}; + ImageStats bottom_stats = image_stats(extract_box_reference(screen, box)); + + if (is_solid(bottom_stats, {0.648549, 0.2861580, 0.0652928}, 0.15, 25)){ + game_title = GameTitle::SCARLET; + env.console.log("Game title detected: Scarlet"); + } else if (is_solid(bottom_stats, {0.367816, 0.0746615, 0.5575230}, 0.15, 25)){ + game_title = GameTitle::VIOLET; + env.console.log("Game title detected: Violet"); + } + + if (game_title == GameTitle::UNKNOWN){ + throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "Unable to determine what game we are playing. The color of the bottom bar in the Pokemon Summary page doesn't match of the expected colors."); + } + + return game_title; + +} + + std::string get_ride_pokemon_name(SingleSwitchProgramEnvironment& env, ProControllerContext& context, Language language){ enter_menu_from_overworld(env.program_info(), env.console, context, -1); diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.h b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.h index e9f06f2915..29d3d651f1 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.h +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.h @@ -26,6 +26,12 @@ class AutoStory_Segment_33 : public AutoStory_Segment{ ) const override; }; +enum class GameTitle{ + UNKNOWN, + SCARLET, + VIOLET, +}; + // start: Beat Alfornada gym challenge. Beat Alfornada gym. At Alfronada Pokecenter. // end: Beat Clavell. At Academy fly point. void checkpoint_85(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats); @@ -38,6 +44,8 @@ void checkpoint_86(SingleSwitchProgramEnvironment& env, ProControllerContext& co // end: Beat Elite Four. At Pokemon League Pokecenter. void checkpoint_87(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats, Language language, StarterChoice starter_choice); +GameTitle get_game_title(SingleSwitchProgramEnvironment& env, ProControllerContext& context); + std::string get_ride_pokemon_name(SingleSwitchProgramEnvironment& env, ProControllerContext& context, Language language); From 304c4c01608a351cb8e8e008733fb3a8fd663496 Mon Sep 17 00:00:00 2001 From: jw098 Date: Fri, 17 Oct 2025 21:31:09 -0700 Subject: [PATCH 06/10] add more blank checkpoints --- .../AutoStory/PokemonSV_AutoStory.cpp | 5 ++++ .../PokemonSV_AutoStory_Segment_33.cpp | 27 +++++++++++++++++-- .../PokemonSV_AutoStory_Segment_33.h | 11 +++++++- .../PokemonSV_AutoStory_Segment_34.cpp | 18 ++++++++++--- .../PokemonSV_AutoStory_Segment_34.h | 19 ++++++++++--- 5 files changed, 70 insertions(+), 10 deletions(-) diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp index bfd43710b0..51272430f3 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp @@ -734,6 +734,11 @@ void AutoStory::test_checkpoints( checkpoint_list.push_back([&](){checkpoint_88(env, context, notif_status_update, stats);}); checkpoint_list.push_back([&](){checkpoint_89(env, context, notif_status_update, stats);}); checkpoint_list.push_back([&](){checkpoint_90(env, context, notif_status_update, stats);}); + checkpoint_list.push_back([&](){checkpoint_91(env, context, notif_status_update, stats);}); + checkpoint_list.push_back([&](){checkpoint_92(env, context, notif_status_update, stats);}); + checkpoint_list.push_back([&](){checkpoint_93(env, context, notif_status_update, stats);}); + checkpoint_list.push_back([&](){checkpoint_94(env, context, notif_status_update, stats);}); + checkpoint_list.push_back([&](){checkpoint_95(env, context, notif_status_update, stats);}); if (end == 0){ diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp index 3f2c9f6264..aceb53ae0a 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp @@ -265,8 +265,19 @@ void checkpoint_87(SingleSwitchProgramEnvironment& env, ProControllerContext& co // talk to Rika 10. do you like pokemon clear_dialog(env.console, context, ClearDialogMode::STOP_TIMEOUT, 20, {CallbackEnum::PROMPT_DIALOG}); - // now done talking to Rika. walk around Rika's desk. pbf_move_left_joystick(context, 128, 0, 100, 50); // stand up + + + }); +} + + +void checkpoint_88(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats){ + checkpoint_reattempt_loop(env, context, notif_status_update, stats, + [&](size_t attempt_number){ + // standing in front of Rika + // now done talking to Rika. walk around Rika's desk. + pbf_move_left_joystick(context, 0, 128, 50, 50); // go left pbf_move_left_joystick(context, 128, 0, 200, 50); // straight pbf_move_left_joystick(context, 255, 128, 50, 50); // right @@ -279,14 +290,26 @@ void checkpoint_87(SingleSwitchProgramEnvironment& env, ProControllerContext& co run_trainer_battle_press_A(env.console, context, BattleStopCondition::STOP_DIALOG); mash_button_till_overworld(env.console, context, BUTTON_A); + walk_forward_until_dialog(env.program_info(), env.console, context, NavigationMovementMode::DIRECTIONAL_ONLY, 60); + clear_dialog(env.console, context, ClearDialogMode::STOP_BATTLE, 60, {CallbackEnum::BATTLE, CallbackEnum::DIALOG_ARROW}); + + env.console.log("Battle Elite Four 2."); // todo: run the third move when battling the Steel trainer + }); +} - }); +void checkpoint_89(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats){ + checkpoint_reattempt_loop(env, context, notif_status_update, stats, + [&](size_t attempt_number){ + + + }); } + GameTitle get_game_title(SingleSwitchProgramEnvironment& env, ProControllerContext& context){ GameTitle game_title = GameTitle::UNKNOWN; enter_menu_from_overworld(env.program_info(), env.console, context, 0, MenuSide::RIGHT); diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.h b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.h index 29d3d651f1..8a699641bf 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.h +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.h @@ -41,9 +41,18 @@ void checkpoint_85(SingleSwitchProgramEnvironment& env, ProControllerContext& co void checkpoint_86(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats); // start: At Pokemon League entrance. -// end: Beat Elite Four. At Pokemon League Pokecenter. +// end: Finished the Entrance quiz. Standing in front of Rika. void checkpoint_87(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats, Language language, StarterChoice starter_choice); +// start: Finished the Entrance quiz. Standing in front of Rika. +// end: Beat Elite Four. +void checkpoint_88(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats); + +// start: Beat Elite Four. +// end: Beat Geeta. At Pokemon League Pokecenter. +void checkpoint_89(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats); + + GameTitle get_game_title(SingleSwitchProgramEnvironment& env, ProControllerContext& context); std::string get_ride_pokemon_name(SingleSwitchProgramEnvironment& env, ProControllerContext& context, Language language); diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.cpp index 838a7abfd2..b38c7af64e 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.cpp @@ -53,7 +53,7 @@ void AutoStory_Segment_34::run_segment( context.wait_for_all_requests(); env.console.log("Start Segment " + name(), COLOR_ORANGE); - checkpoint_88(env, context, options.notif_status_update, stats); + // checkpoint_(env, context, options.notif_status_update, stats); context.wait_for_all_requests(); env.console.log("End Segment " + name(), COLOR_GREEN); @@ -61,13 +61,23 @@ void AutoStory_Segment_34::run_segment( } -void checkpoint_88(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats){ + +void checkpoint_90(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats){ } -void checkpoint_89(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats){ +void checkpoint_91(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats){ } -void checkpoint_90(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats){ +void checkpoint_92(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats){ +} + +void checkpoint_93(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats){ +} + +void checkpoint_94(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats){ +} + +void checkpoint_95(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats){ } diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.h b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.h index db5959d111..8c374db0fd 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.h +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_34.h @@ -27,17 +27,30 @@ class AutoStory_Segment_34 : public AutoStory_Segment{ }; + // start: // end: -void checkpoint_88(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats); +void checkpoint_90(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats); // start: // end: -void checkpoint_89(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats); +void checkpoint_91(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats); // start: // end: -void checkpoint_90(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats); +void checkpoint_92(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats); + +// start: +// end: +void checkpoint_93(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats); + +// start: +// end: +void checkpoint_94(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats); + +// start: +// end: +void checkpoint_95(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats); From 628bad7a949f5dec7533de3c921a9b7b877d203f Mon Sep 17 00:00:00 2001 From: jw098 Date: Fri, 17 Oct 2025 21:45:51 -0700 Subject: [PATCH 07/10] update checkpoint 87: elite four test --- .../AutoStory/PokemonSV_AutoStoryTools.cpp | 30 ++++ .../AutoStory/PokemonSV_AutoStoryTools.h | 8 + .../PokemonSV_AutoStory_Segment_33.cpp | 148 +++++++++--------- 3 files changed, 114 insertions(+), 72 deletions(-) diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp index cd2b28819e..31bc17b0c2 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp @@ -653,6 +653,36 @@ void handle_unexpected_battles( } } +void do_action_and_monitor_for_overworld( + const ProgramInfo& info, + VideoStream& stream, + ProControllerContext& context, + std::function&& action +){ + + OverworldWatcher overworld(stream.logger(), COLOR_CYAN); + + int ret = run_until( + stream, context, + [&](ProControllerContext& context){ + context.wait_for_all_requests(); + action(); + }, + {overworld} + ); + if (ret < 0){ + // successfully completed action detecting the overworld + return; + }else if (ret == 0){ + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "do_action_and_monitor_for_overworld(): Failed to complete action. Detected overworld.", + stream + ); + } + +} + void handle_when_stationary_in_overworld( const ProgramInfo& info, VideoStream& stream, diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h index eac63b9ad0..dc3e2db314 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h @@ -180,6 +180,14 @@ void handle_unexpected_battles( >&& action ); +// run the given `action`. if detect the overworld, stop the action, and throw exception +void do_action_and_monitor_for_overworld( + const ProgramInfo& info, + VideoStream& stream, + ProControllerContext& context, + std::function&& action +); + // if stationary in overworld for an amount of time (seconds_stationary), run `recovery_action` then try `action` again // return once successfully completed `action` // throw exception if fails to complete `action` within a certain amount of time (minutes_timeout). diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp index aceb53ae0a..6ead0f6f92 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp @@ -189,81 +189,85 @@ void checkpoint_87(SingleSwitchProgramEnvironment& env, ProControllerContext& co // clear_dialog(env.console, context, ClearDialogMode::STOP_OVERWORLD, 60, {CallbackEnum::OVERWORLD, CallbackEnum::PROMPT_DIALOG}); mash_button_till_overworld(env.console, context, BUTTON_A); - // move left to sit down - pbf_move_left_joystick(context, 0, 128, 100, 50); - - // talk to Rika 1. Choose first option. Walked here. - clear_dialog(env.console, context, ClearDialogMode::STOP_PROMPT, 60, {CallbackEnum::PROMPT_DIALOG}); - pbf_mash_button(context, BUTTON_A, 1000ms); - - // talk to Rika 2. Choose option based on your game title - clear_dialog(env.console, context, ClearDialogMode::STOP_PROMPT, 60, {CallbackEnum::PROMPT_DIALOG}); - - switch(game_title){ - case GameTitle::SCARLET: - pbf_press_dpad(context, DPAD_DOWN, 13, 20); - break; - case GameTitle::VIOLET: - pbf_press_dpad(context, DPAD_DOWN, 13, 20); - pbf_press_dpad(context, DPAD_DOWN, 13, 20); - break; - default: - throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "We don't know what game we are playing. We should know at this point."); - break; - } - pbf_mash_button(context, BUTTON_A, 1000ms); - - // talk to Rika 3. Came to become a Champion - clear_dialog(env.console, context, ClearDialogMode::STOP_PROMPT, 60, {CallbackEnum::PROMPT_DIALOG}); - pbf_press_dpad(context, DPAD_DOWN, 13, 20); - pbf_mash_button(context, BUTTON_A, 1000ms); - - // talk to Rika 4. Become stronger - clear_dialog(env.console, context, ClearDialogMode::STOP_PROMPT, 60, {CallbackEnum::PROMPT_DIALOG}); - pbf_mash_button(context, BUTTON_A, 1000ms); - - // talk to Rika 5. Difficult gym: Alfornada - clear_dialog(env.console, context, ClearDialogMode::STOP_PROMPT, 60, {CallbackEnum::PROMPT_DIALOG}); - pbf_press_dpad(context, DPAD_UP, 13, 20); - pbf_mash_button(context, BUTTON_A, 1000ms); - - // talk to Rika 6. Difficult gym leader name: Tulip - clear_dialog(env.console, context, ClearDialogMode::STOP_PROMPT, 60, {CallbackEnum::PROMPT_DIALOG}); - pbf_press_dpad(context, DPAD_UP, 13, 20); - pbf_mash_button(context, BUTTON_A, 1000ms); - - // talk to Rika 7. Difficult gym leader type: Psychic - clear_dialog(env.console, context, ClearDialogMode::STOP_PROMPT, 60, {CallbackEnum::PROMPT_DIALOG}); - pbf_press_dpad(context, DPAD_UP, 13, 20); - pbf_press_dpad(context, DPAD_UP, 13, 20); - pbf_mash_button(context, BUTTON_A, 1000ms); - - // talk to Rika 8. Starter pokemon: Grass/Fire/Water - clear_dialog(env.console, context, ClearDialogMode::STOP_PROMPT, 60, {CallbackEnum::PROMPT_DIALOG}); - switch(starter_choice){ - case StarterChoice::SPRIGATITO: - break; - case StarterChoice::FUECOCO: - pbf_press_dpad(context, DPAD_DOWN, 13, 20); - break; - case StarterChoice::QUAXLY: - pbf_press_dpad(context, DPAD_DOWN, 13, 20); - pbf_press_dpad(context, DPAD_DOWN, 13, 20); - break; - default: - throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "Invalid starter pokemon type. This shouldn't happen."); - break; - } - size_t num_extra_clicks = attempt_number % 3; // we add extra clicks when attempt_number > 0, to account for the fact that the user might not be enterint the correct starter. - for (size_t i = 0; i < num_extra_clicks; i++){ + do_action_and_monitor_for_overworld(env.program_info(), env.console, context, + [&](){ + // move left to sit down + pbf_move_left_joystick(context, 0, 128, 100, 50); + + // talk to Rika 1. Choose first option. Walked here. + clear_dialog(env.console, context, ClearDialogMode::STOP_PROMPT, 60, {CallbackEnum::PROMPT_DIALOG}); + pbf_mash_button(context, BUTTON_A, 1000ms); + + // talk to Rika 2. Choose option based on your game title + clear_dialog(env.console, context, ClearDialogMode::STOP_PROMPT, 60, {CallbackEnum::PROMPT_DIALOG}); + + switch(game_title){ + case GameTitle::SCARLET: + pbf_press_dpad(context, DPAD_DOWN, 13, 20); + break; + case GameTitle::VIOLET: + pbf_press_dpad(context, DPAD_DOWN, 13, 20); + pbf_press_dpad(context, DPAD_DOWN, 13, 20); + break; + default: + throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "We don't know what game we are playing. We should know at this point."); + break; + } + pbf_mash_button(context, BUTTON_A, 1000ms); + + // talk to Rika 3. Came to become a Champion + clear_dialog(env.console, context, ClearDialogMode::STOP_PROMPT, 60, {CallbackEnum::PROMPT_DIALOG}); pbf_press_dpad(context, DPAD_DOWN, 13, 20); - } + pbf_mash_button(context, BUTTON_A, 1000ms); + + // talk to Rika 4. Become stronger + clear_dialog(env.console, context, ClearDialogMode::STOP_PROMPT, 60, {CallbackEnum::PROMPT_DIALOG}); + pbf_mash_button(context, BUTTON_A, 1000ms); + + // talk to Rika 5. Difficult gym: Alfornada + clear_dialog(env.console, context, ClearDialogMode::STOP_PROMPT, 60, {CallbackEnum::PROMPT_DIALOG}); + pbf_press_dpad(context, DPAD_UP, 13, 20); + pbf_mash_button(context, BUTTON_A, 1000ms); + + // talk to Rika 6. Difficult gym leader name: Tulip + clear_dialog(env.console, context, ClearDialogMode::STOP_PROMPT, 60, {CallbackEnum::PROMPT_DIALOG}); + pbf_press_dpad(context, DPAD_UP, 13, 20); + pbf_mash_button(context, BUTTON_A, 1000ms); + + // talk to Rika 7. Difficult gym leader type: Psychic + clear_dialog(env.console, context, ClearDialogMode::STOP_PROMPT, 60, {CallbackEnum::PROMPT_DIALOG}); + pbf_press_dpad(context, DPAD_UP, 13, 20); + pbf_press_dpad(context, DPAD_UP, 13, 20); + pbf_mash_button(context, BUTTON_A, 1000ms); + + // talk to Rika 8. Starter pokemon: Grass/Fire/Water + clear_dialog(env.console, context, ClearDialogMode::STOP_PROMPT, 60, {CallbackEnum::PROMPT_DIALOG}); + switch(starter_choice){ + case StarterChoice::SPRIGATITO: + break; + case StarterChoice::FUECOCO: + pbf_press_dpad(context, DPAD_DOWN, 13, 20); + break; + case StarterChoice::QUAXLY: + pbf_press_dpad(context, DPAD_DOWN, 13, 20); + pbf_press_dpad(context, DPAD_DOWN, 13, 20); + break; + default: + throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "Invalid starter pokemon type. This shouldn't happen."); + break; + } + size_t num_extra_clicks = attempt_number % 3; // we add extra clicks when attempt_number > 0, to account for the fact that the user might not be enterint the correct starter. + for (size_t i = 0; i < num_extra_clicks; i++){ + pbf_press_dpad(context, DPAD_DOWN, 13, 20); + } + + pbf_mash_button(context, BUTTON_A, 1000ms); - pbf_mash_button(context, BUTTON_A, 1000ms); + // talk to Rika 9. Become stronger + // talk to Rika 10. do you like pokemon + clear_dialog(env.console, context, ClearDialogMode::STOP_TIMEOUT, 20, {CallbackEnum::PROMPT_DIALOG}); - // talk to Rika 9. Become stronger - // talk to Rika 10. do you like pokemon - clear_dialog(env.console, context, ClearDialogMode::STOP_TIMEOUT, 20, {CallbackEnum::PROMPT_DIALOG}); + }); pbf_move_left_joystick(context, 128, 0, 100, 50); // stand up From 4a3b6bfa97c24760d26060f564fc558686760159 Mon Sep 17 00:00:00 2001 From: jw098 Date: Fri, 17 Oct 2025 22:50:58 -0700 Subject: [PATCH 08/10] update do_action_and_monitor_for_overworld() --- .../Programs/AutoStory/PokemonSV_AutoStoryTools.cpp | 8 ++++++-- .../Programs/AutoStory/PokemonSV_AutoStoryTools.h | 4 +++- .../Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp index 31bc17b0c2..9177558492 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp @@ -657,7 +657,11 @@ void do_action_and_monitor_for_overworld( const ProgramInfo& info, VideoStream& stream, ProControllerContext& context, - std::function&& action + std::function< + void(const ProgramInfo& info, + VideoStream& stream, + ProControllerContext& context) + >&& action ){ OverworldWatcher overworld(stream.logger(), COLOR_CYAN); @@ -666,7 +670,7 @@ void do_action_and_monitor_for_overworld( stream, context, [&](ProControllerContext& context){ context.wait_for_all_requests(); - action(); + action(info, stream, context); }, {overworld} ); diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h index dc3e2db314..f8a69121b6 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h @@ -185,7 +185,9 @@ void do_action_and_monitor_for_overworld( const ProgramInfo& info, VideoStream& stream, ProControllerContext& context, - std::function&& action + std::function&& action ); // if stationary in overworld for an amount of time (seconds_stationary), run `recovery_action` then try `action` again diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp index 6ead0f6f92..c16cd9f162 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp @@ -190,7 +190,7 @@ void checkpoint_87(SingleSwitchProgramEnvironment& env, ProControllerContext& co mash_button_till_overworld(env.console, context, BUTTON_A); do_action_and_monitor_for_overworld(env.program_info(), env.console, context, - [&](){ + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ // move left to sit down pbf_move_left_joystick(context, 0, 128, 100, 50); From 1fd4c90d9a83c669cce3187303461b60be730636 Mon Sep 17 00:00:00 2001 From: jw098 Date: Sun, 19 Oct 2025 17:04:00 -0700 Subject: [PATCH 09/10] checkpoint_88: beat Elite four. --- .../PokemonSV_AutoStory_Segment_33.cpp | 52 +++++++++++++++++-- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp index c16cd9f162..60c4a94a4f 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp @@ -8,6 +8,8 @@ #include "Pokemon/Inference/Pokemon_NameReader.h" #include "CommonFramework/Notifications/ProgramInfo.h" #include "PokemonSV/Inference/Overworld/PokemonSV_DirectionDetector.h" +#include "PokemonSV/Programs/Battles/PokemonSV_SinglesBattler.h" +#include "PokemonSV/Programs/Battles/PokemonSV_Battles.h" #include "CommonFramework/Exceptions/OperationFailedException.h" #include "CommonTools/Async/InferenceRoutines.h" @@ -291,15 +293,59 @@ void checkpoint_88(SingleSwitchProgramEnvironment& env, ProControllerContext& co env.console.log("Battle Elite Four 1."); + SinglesMoveEntry move1{SinglesMoveType::Move1, false}; // Moonblast + SinglesMoveEntry move3{SinglesMoveType::Move3, false}; // Mystical Fire + SinglesMoveEntry move4{SinglesMoveType::Move4, false}; // Misty Terrain + std::vector move_table1 = {move1, move4, move1}; + bool terastallized = false; + bool is_won = run_pokemon(env.console, context, move_table1, true, terastallized); + + // finished battle + mash_button_till_overworld(env.console, context, BUTTON_A); + + // heal + auto_heal_from_menu_or_overworld(env.program_info(), env.console, context, 0, true); + + // engage next battle + walk_forward_until_dialog(env.program_info(), env.console, context, NavigationMovementMode::DIRECTIONAL_ONLY, 60); + clear_dialog(env.console, context, ClearDialogMode::STOP_BATTLE, 60, {CallbackEnum::BATTLE, CallbackEnum::DIALOG_ARROW, CallbackEnum::PROMPT_DIALOG}); + + env.console.log("Battle Elite Four 2."); // select move 3, which should be a fire move. to battle the steel trainer + std::vector move_table2 = {move3}; + is_won = run_pokemon(env.console, context, move_table2, true, terastallized); + if (!is_won){// throw exception if we lose + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "Failed to beat the Steel trainer. Reset.", + env.console + ); + } + + // finished battle + mash_button_till_overworld(env.console, context, BUTTON_A); + + // heal + auto_heal_from_menu_or_overworld(env.program_info(), env.console, context, 0, true); + + // engage next battle + walk_forward_until_dialog(env.program_info(), env.console, context, NavigationMovementMode::DIRECTIONAL_ONLY, 60); + clear_dialog(env.console, context, ClearDialogMode::STOP_BATTLE, 60, {CallbackEnum::BATTLE, CallbackEnum::DIALOG_ARROW, CallbackEnum::PROMPT_DIALOG}); + + env.console.log("Battle Elite Four 3."); run_trainer_battle_press_A(env.console, context, BattleStopCondition::STOP_DIALOG); + + // finished battle mash_button_till_overworld(env.console, context, BUTTON_A); + // engage next battle walk_forward_until_dialog(env.program_info(), env.console, context, NavigationMovementMode::DIRECTIONAL_ONLY, 60); - clear_dialog(env.console, context, ClearDialogMode::STOP_BATTLE, 60, {CallbackEnum::BATTLE, CallbackEnum::DIALOG_ARROW}); + clear_dialog(env.console, context, ClearDialogMode::STOP_BATTLE, 60, {CallbackEnum::BATTLE, CallbackEnum::DIALOG_ARROW, CallbackEnum::PROMPT_DIALOG}); - env.console.log("Battle Elite Four 2."); - // todo: run the third move when battling the Steel trainer + env.console.log("Battle Elite Four 4."); + run_trainer_battle_press_A(env.console, context, BattleStopCondition::STOP_DIALOG); + // finished battle + clear_dialog(env.console, context, ClearDialogMode::STOP_OVERWORLD, 60, {CallbackEnum::OVERWORLD}); }); } From 5a27954c4b38b39bae42518cb1c4fa7cadd688d7 Mon Sep 17 00:00:00 2001 From: jw098 Date: Sun, 19 Oct 2025 17:51:51 -0700 Subject: [PATCH 10/10] checkpoint 89: beat Geeta --- .../AutoStory/PokemonSV_AutoStory.cpp | 2 +- .../PokemonSV_AutoStory_Segment_33.cpp | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp index 51272430f3..f2aafabb2d 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp @@ -253,7 +253,7 @@ AutoStory::AutoStory() "For Start Points that are at Pokecenters, ensure that you fly there so that your character is in the exactly correct start position." } , MAINSTORY_NOTE{ - "Ensure you have a level 100 Gardevoir with the moves in the following order: Moonblast, Dazzling Gleam, Psychic, Mystical Fire.
" + "Ensure you have a level 100 Gardevoir with the moves in the following order: Moonblast, Dazzling Gleam, Mystical Fire, Misty Terrain.
" "Also, make sure you have two other strong pokemon (e.g. level 100 Talonflames)
" "Refer to the documentation on github for more details." } diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp index 60c4a94a4f..276d4939e7 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_33.cpp @@ -353,7 +353,26 @@ void checkpoint_88(SingleSwitchProgramEnvironment& env, ProControllerContext& co void checkpoint_89(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats){ checkpoint_reattempt_loop(env, context, notif_status_update, stats, [&](size_t attempt_number){ + walk_forward_until_dialog(env.program_info(), env.console, context, NavigationMovementMode::DIRECTIONAL_ONLY, 60); + clear_dialog(env.console, context, ClearDialogMode::STOP_BATTLE, 60, {CallbackEnum::BATTLE, CallbackEnum::DIALOG_ARROW, CallbackEnum::PROMPT_DIALOG}); + + env.console.log("Battle Elite Four 4."); + run_trainer_battle_press_A(env.console, context, BattleStopCondition::STOP_DIALOG); + + // finished battle + mash_button_till_overworld(env.console, context, BUTTON_A); + + // move to Pokecenter + handle_unexpected_battles(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_NEW_MARKER, 255, 50, 50); + }); + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_TIME, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 15, 12, 12, false); // can't wrap in handle_when_stationary_in_overworld(), since we expect to be stationary when walking into the pokecenter + + fly_to_overlapping_flypoint(env.program_info(), env.console, context); }); }