From 49b21f6a63bce1ac12b6d8729fa7ff0e8f662957 Mon Sep 17 00:00:00 2001 From: dayfine Date: Mon, 9 Nov 2026 20:51:29 -0800 Subject: [PATCH] PokemonSV AutoStory: shared checkpoint range options and log lines The tutorial and main story checkpoint dropdowns are now the shared StoryRangeOptions, added under the same keys (START_CHECKPOINT_TUTORIAL, END_CHECKPOINT_TUTORIAL, START_CHECKPOINT_MAINSTORY, END_CHECKPOINT_MAINSTORY) over the same databases, so saved settings load unchanged; the end stays unlocked while running. The start-before-end check is the range's. The checkpoint loops log the shared attempt and reset lines, and the run logs the shared checkpoint start line. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_013VUubhHeYSMGSSDXZkKZss --- .../AutoStory/PokemonSV_AutoStory.cpp | 76 ++++++++----------- .../Programs/AutoStory/PokemonSV_AutoStory.h | 14 ++-- .../AutoStory/PokemonSV_AutoStoryTools.cpp | 8 +- .../AutoStory/PokemonSV_AutoStoryTools.h | 3 +- 4 files changed, 46 insertions(+), 55 deletions(-) diff --git a/SerialPrograms/Source/VideoGames/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp b/SerialPrograms/Source/VideoGames/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp index 130271139b..945731d147 100644 --- a/SerialPrograms/Source/VideoGames/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp +++ b/SerialPrograms/Source/VideoGames/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp @@ -28,6 +28,7 @@ #include "NintendoSwitch/Programs/NintendoSwitch_GameEntry.h" #include "Pokemon/Pokemon_Strings.h" #include "Pokemon/AutoStory/Pokemon_AutoStorySelect.h" +#include "Pokemon/AutoStory/Pokemon_StoryLog.h" #include "VideoGames/PokemonSwSh/Inference/PokemonSwSh_IvJudgeReader.h" #include "VideoGames/PokemonSV/PokemonSV_Settings.h" #include "VideoGames/PokemonSV/Inference/Overworld/PokemonSV_DirectionDetector.h" @@ -347,6 +348,10 @@ AutoStory::~AutoStory(){ ENDPOINT_TUTORIAL.remove_listener(*this); STARTPOINT_MAINSTORY.remove_listener(*this); ENDPOINT_MAINSTORY.remove_listener(*this); + TUTORIAL_CHECKPOINTS.START_CHECKPOINT.remove_listener(*this); + TUTORIAL_CHECKPOINTS.END_CHECKPOINT.remove_listener(*this); + MAINSTORY_CHECKPOINTS.START_CHECKPOINT.remove_listener(*this); + MAINSTORY_CHECKPOINTS.END_CHECKPOINT.remove_listener(*this); ENABLE_TEST_CHECKPOINTS.remove_listener(*this); ENABLE_MISC_TEST.remove_listener(*this); TEST_PBF_LEFT_JOYSTICK.remove_listener(*this); @@ -395,30 +400,9 @@ AutoStory::AutoStory() LockMode::UNLOCK_WHILE_RUNNING, std::to_string(ALL_SEGMENTS_SELECT_DATABASE().case_list().size()-1) ) - , START_CHECKPOINT_TUTORIAL( - "Start Checkpoint:", //
Program will start with this checkpoint. - TUTORIAL_CHECKPOINTS_SELECT_DATABASE(), - LockMode::LOCK_WHILE_RUNNING, - "0" - ) - , END_CHECKPOINT_TUTORIAL( - "End Checkpoint:", //
Program will stop after completing this checkpoint. - TUTORIAL_CHECKPOINTS_SELECT_DATABASE(), - LockMode::UNLOCK_WHILE_RUNNING, - std::to_string(INDEX_OF_LAST_TUTORIAL_CHECKPOINT) - ) - , START_CHECKPOINT_MAINSTORY( - "Start Checkpoint:", //
Program will start with this checkpoint. - MAINSTORY_CHECKPOINTS_SELECT_DATABASE(), - LockMode::LOCK_WHILE_RUNNING, - std::to_string(INDEX_OF_LAST_TUTORIAL_CHECKPOINT+1) - ) - , END_CHECKPOINT_MAINSTORY( - "End Checkpoint:", //
Program will stop after completing this checkpoint. - MAINSTORY_CHECKPOINTS_SELECT_DATABASE(), - LockMode::UNLOCK_WHILE_RUNNING, - std::to_string(ALL_CHECKPOINTS_SELECT_DATABASE().case_list().size()-1) - ) + // The end is read after each checkpoint, so it stays unlocked. + , TUTORIAL_CHECKPOINTS("Tutorial Checkpoints", TUTORIAL_CHECKPOINTS_SELECT_DATABASE(), LockMode::UNLOCK_WHILE_RUNNING) + , MAINSTORY_CHECKPOINTS("Main Story Checkpoints", MAINSTORY_CHECKPOINTS_SELECT_DATABASE(), LockMode::UNLOCK_WHILE_RUNNING) , SETUP_NOTE{ "NOTE: Make sure you have selected the correct Start Point. " "Make sure your player character is in the exact correct start position for that Start Point, " @@ -710,11 +694,11 @@ AutoStory::AutoStory() PA_ADD_OPTION(ENDPOINT_MAINSTORY); PA_ADD_OPTION(END_DESCRIPTION); - PA_ADD_OPTION(START_CHECKPOINT_TUTORIAL); - PA_ADD_OPTION(START_CHECKPOINT_MAINSTORY); + add_option(TUTORIAL_CHECKPOINTS.START_CHECKPOINT, "START_CHECKPOINT_TUTORIAL"); + add_option(MAINSTORY_CHECKPOINTS.START_CHECKPOINT, "START_CHECKPOINT_MAINSTORY"); PA_ADD_OPTION(START_CHECKPOINT_DESCRIPTION); - PA_ADD_OPTION(END_CHECKPOINT_TUTORIAL); - PA_ADD_OPTION(END_CHECKPOINT_MAINSTORY); + add_option(TUTORIAL_CHECKPOINTS.END_CHECKPOINT, "END_CHECKPOINT_TUTORIAL"); + add_option(MAINSTORY_CHECKPOINTS.END_CHECKPOINT, "END_CHECKPOINT_MAINSTORY"); PA_ADD_OPTION(END_CHECKPOINT_DESCRIPTION); PA_ADD_OPTION(STARTERCHOICE); @@ -738,10 +722,10 @@ AutoStory::AutoStory() STARTPOINT_MAINSTORY.add_listener(*this); ENDPOINT_MAINSTORY.add_listener(*this); - START_CHECKPOINT_TUTORIAL.add_listener(*this); - END_CHECKPOINT_TUTORIAL.add_listener(*this); - START_CHECKPOINT_MAINSTORY.add_listener(*this); - END_CHECKPOINT_MAINSTORY.add_listener(*this); + TUTORIAL_CHECKPOINTS.START_CHECKPOINT.add_listener(*this); + TUTORIAL_CHECKPOINTS.END_CHECKPOINT.add_listener(*this); + MAINSTORY_CHECKPOINTS.START_CHECKPOINT.add_listener(*this); + MAINSTORY_CHECKPOINTS.END_CHECKPOINT.add_listener(*this); ENABLE_ADVANCED_MODE.add_listener(*this); @@ -769,10 +753,10 @@ void AutoStory::on_config_value_changed(void* object){ STARTPOINT_MAINSTORY.set_visibility(mainstory_segments ? ConfigOptionState::ENABLED : ConfigOptionState::HIDDEN); ENDPOINT_MAINSTORY.set_visibility(mainstory_segments ? ConfigOptionState::ENABLED : ConfigOptionState::HIDDEN); - START_CHECKPOINT_TUTORIAL.set_visibility(tutorial_checkpoints ? ConfigOptionState::ENABLED : ConfigOptionState::HIDDEN); - END_CHECKPOINT_TUTORIAL.set_visibility(tutorial_checkpoints ? ConfigOptionState::ENABLED : ConfigOptionState::HIDDEN); - START_CHECKPOINT_MAINSTORY.set_visibility(mainstory_checkpoints ? ConfigOptionState::ENABLED : ConfigOptionState::HIDDEN); - END_CHECKPOINT_MAINSTORY.set_visibility(mainstory_checkpoints ? ConfigOptionState::ENABLED : ConfigOptionState::HIDDEN); + TUTORIAL_CHECKPOINTS.START_CHECKPOINT.set_visibility(tutorial_checkpoints ? ConfigOptionState::ENABLED : ConfigOptionState::HIDDEN); + TUTORIAL_CHECKPOINTS.END_CHECKPOINT.set_visibility(tutorial_checkpoints ? ConfigOptionState::ENABLED : ConfigOptionState::HIDDEN); + MAINSTORY_CHECKPOINTS.START_CHECKPOINT.set_visibility(mainstory_checkpoints ? ConfigOptionState::ENABLED : ConfigOptionState::HIDDEN); + MAINSTORY_CHECKPOINTS.END_CHECKPOINT.set_visibility(mainstory_checkpoints ? ConfigOptionState::ENABLED : ConfigOptionState::HIDDEN); MAINSTORY_NOTE.set_visibility(STORY_SECTION == StorySection::TUTORIAL ? ConfigOptionState::HIDDEN : ConfigOptionState::ENABLED); START_DESCRIPTION.set_text(start_segment_description()); @@ -1063,20 +1047,22 @@ std::string AutoStory::end_checkpoint_description(){ return " End: " + ALL_AUTO_STORY_CHECKPOINT_LIST()[checkpoint_index]->end_text(); } +const Pokemon::StoryRangeOptions& AutoStory::checkpoint_range() const{ + return STORY_SECTION == StorySection::MAIN_STORY ? MAINSTORY_CHECKPOINTS : TUTORIAL_CHECKPOINTS; +} + size_t AutoStory::get_start_checkpoint_index(){ - const bool main_story = STORY_SECTION == StorySection::MAIN_STORY; return story_index( - main_story, - main_story ? START_CHECKPOINT_MAINSTORY.index() : START_CHECKPOINT_TUTORIAL.index(), + STORY_SECTION == StorySection::MAIN_STORY, + checkpoint_range().start_index(), INDEX_OF_LAST_TUTORIAL_CHECKPOINT + 1 ); } size_t AutoStory::get_end_checkpoint_index(){ - const bool main_story = STORY_SECTION == StorySection::MAIN_STORY; return story_index( - main_story, - main_story ? END_CHECKPOINT_MAINSTORY.index() : END_CHECKPOINT_TUTORIAL.index(), + STORY_SECTION == StorySection::MAIN_STORY, + checkpoint_range().end_index(), INDEX_OF_LAST_TUTORIAL_CHECKPOINT + 1 ); } @@ -1216,8 +1202,8 @@ void AutoStory::program(SingleSwitchProgramEnvironment& env, ProControllerContex } if (ENABLE_ADVANCED_MODE){ - if (get_start_checkpoint_index() > get_end_checkpoint_index()){ - throw UserSetupError(env.logger(), "The start checkpoint cannot be later than the end segment."); + if (!checkpoint_range().check_validity().empty()){ + throw UserSetupError(env.logger(), checkpoint_range().check_validity()); } }else{ @@ -1230,7 +1216,7 @@ void AutoStory::program(SingleSwitchProgramEnvironment& env, ProControllerContex require_player(env.console, context, BUTTON_L); if (ENABLE_ADVANCED_MODE){ - env.console.log("Start Checkpoint " + ALL_AUTO_STORY_CHECKPOINT_LIST()[get_start_checkpoint_index()]->name(), COLOR_ORANGE); + env.console.log(Pokemon::checkpoint_start_line(ALL_AUTO_STORY_CHECKPOINT_LIST()[get_start_checkpoint_index()]->name()), COLOR_ORANGE); }else{ env.console.log("Start Segment " + ALL_AUTO_STORY_SEGMENT_LIST()[get_start_segment_index()]->name(), COLOR_ORANGE); } diff --git a/SerialPrograms/Source/VideoGames/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.h b/SerialPrograms/Source/VideoGames/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.h index d62d9b2ad2..b2ca877499 100644 --- a/SerialPrograms/Source/VideoGames/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.h +++ b/SerialPrograms/Source/VideoGames/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.h @@ -16,6 +16,7 @@ #include "CommonTools/Options/StringSelectOption.h" #include "CommonTools/Options/LanguageOCROption.h" #include "NintendoSwitch/Options/NintendoSwitch_GoHomeWhenDoneOption.h" +#include "Pokemon/Options/Pokemon_StoryRangeOptions.h" #include "PokemonSV_AutoStoryTools.h" namespace PokemonAutomation{ @@ -69,6 +70,9 @@ class AutoStory : public SingleSwitchProgramInstance, public ConfigOption::Liste std::string start_checkpoint_description(); std::string end_checkpoint_description(); + // The checkpoint range of the chosen section. + const Pokemon::StoryRangeOptions& checkpoint_range() const; + private: OCR::LanguageOCROption LANGUAGE; @@ -85,11 +89,11 @@ class AutoStory : public SingleSwitchProgramInstance, public ConfigOption::Liste StringSelectOption STARTPOINT_MAINSTORY; StringSelectOption ENDPOINT_MAINSTORY; - StringSelectOption START_CHECKPOINT_TUTORIAL; - StringSelectOption END_CHECKPOINT_TUTORIAL; - - StringSelectOption START_CHECKPOINT_MAINSTORY; - StringSelectOption END_CHECKPOINT_MAINSTORY; + // The shared start/end checkpoint range of each section. Their + // dropdowns are added to this program's options directly, under the + // keys saved settings already use. + Pokemon::StoryRangeOptions TUTORIAL_CHECKPOINTS; + Pokemon::StoryRangeOptions MAINSTORY_CHECKPOINTS; StaticTextOption SETUP_NOTE; StaticTextOption MAINSTORY_NOTE; diff --git a/SerialPrograms/Source/VideoGames/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp b/SerialPrograms/Source/VideoGames/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp index c2d61152df..759350295e 100644 --- a/SerialPrograms/Source/VideoGames/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp +++ b/SerialPrograms/Source/VideoGames/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp @@ -1445,7 +1445,7 @@ void checkpoint_reattempt_loop( save_game_from_overworld(env.program_info(), env.console, context); } - env.console.log(checkpoint_text + " Num attempts: " + std::to_string(i)); + env.console.log(Pokemon::checkpoint_attempt_line(checkpoint_text, i + 1)); context.wait_for_all_requests(); action(i); @@ -1479,7 +1479,7 @@ void checkpoint_reattempt_loop( ); } context.wait_for_all_requests(); - env.console.log("Resetting from checkpoint."); + env.console.log(Pokemon::checkpoint_reset_line(checkpoint_text, i + 2)); reset_game(env.program_info(), env.console, context); stats.m_reset++; env.update_stats(); @@ -1507,7 +1507,7 @@ void checkpoint_reattempt_loop_tutorial( send_program_status_notification(env, notif_status_update, "Saved at checkpoint."); } - env.console.log(checkpoint_text + " Num attempts: " + std::to_string(i)); + env.console.log(Pokemon::checkpoint_attempt_line(checkpoint_text, i + 1)); context.wait_for_all_requests(); action(i); @@ -1538,7 +1538,7 @@ void checkpoint_reattempt_loop_tutorial( ); } context.wait_for_all_requests(); - env.console.log("Resetting from checkpoint."); + env.console.log(Pokemon::checkpoint_reset_line(checkpoint_text, i + 2)); reset_game(env.program_info(), env.console, context); stats.m_reset++; env.update_stats(); diff --git a/SerialPrograms/Source/VideoGames/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h b/SerialPrograms/Source/VideoGames/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h index e39d8a47da..4d446d266f 100644 --- a/SerialPrograms/Source/VideoGames/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h +++ b/SerialPrograms/Source/VideoGames/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h @@ -15,6 +15,7 @@ #include "ML/Inference/ML_YOLONavigation.h" #include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h" #include "Pokemon/AutoStory/Pokemon_AutoStoryStats.h" +#include "Pokemon/AutoStory/Pokemon_StoryLog.h" #include "VideoGames/PokemonSV/Programs/PokemonSV_WorldNavigation.h" namespace PokemonAutomation{ @@ -108,7 +109,7 @@ class AutoStory_Checkpoint { AutoStoryStats& stats) const = 0; std::string checkpoint_text() const { - return "Checkpoint:: " + name() + ". Start point: " + start_text(); + return name() + ". Start point: " + start_text(); } };