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();
}
};