diff --git a/SerialPrograms/CMakeLists.txt b/SerialPrograms/CMakeLists.txt index b64048ddc..40ce1e56c 100644 --- a/SerialPrograms/CMakeLists.txt +++ b/SerialPrograms/CMakeLists.txt @@ -1426,6 +1426,10 @@ file(GLOB MAIN_SOURCES Source/PokemonSV/PokemonSV_Panels.h Source/PokemonSV/PokemonSV_Settings.cpp Source/PokemonSV/PokemonSV_Settings.h + Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_00.cpp + Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_00.h + Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp + Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.h Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h Source/PokemonSV/Programs/AutoStory/PokemonSV_MenuOption.cpp diff --git a/SerialPrograms/SerialPrograms.pro b/SerialPrograms/SerialPrograms.pro index 980bd1082..f405ca508 100644 --- a/SerialPrograms/SerialPrograms.pro +++ b/SerialPrograms/SerialPrograms.pro @@ -712,6 +712,8 @@ SOURCES += \ Source/PokemonSV/Options/PokemonSV_TournamentPrizeTable.cpp \ Source/PokemonSV/PokemonSV_Panels.cpp \ Source/PokemonSV/PokemonSV_Settings.cpp \ + Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_00.cpp \ + Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp \ Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp \ Source/PokemonSV/Programs/AutoStory/PokemonSV_MenuOption.cpp \ Source/PokemonSV/Programs/AutoStory/PokemonSV_MenuOptionDatabase.cpp \ @@ -1797,6 +1799,8 @@ HEADERS += \ Source/PokemonSV/Options/PokemonSV_TournamentPrizeTable.h \ Source/PokemonSV/PokemonSV_Panels.h \ Source/PokemonSV/PokemonSV_Settings.h \ + Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_00.h \ + Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.h \ Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h \ Source/PokemonSV/Programs/AutoStory/PokemonSV_MenuOption.h \ Source/PokemonSV/Programs/AutoStory/PokemonSV_MenuOptionDatabase.h \ diff --git a/SerialPrograms/Source/PokemonSV/PokemonSV_Panels.cpp b/SerialPrograms/Source/PokemonSV/PokemonSV_Panels.cpp index 7ce4f650b..f9645cec3 100644 --- a/SerialPrograms/Source/PokemonSV/PokemonSV_Panels.cpp +++ b/SerialPrograms/Source/PokemonSV/PokemonSV_Panels.cpp @@ -54,6 +54,8 @@ #include "Programs/ShinyHunting/PokemonSV_ShinyHunt-AreaZeroPlatform.h" #include "Programs/ShinyHunting/PokemonSV_ShinyHunt-Scatterbug.h" +#include "Programs/AutoStory/PokemonSV_AutoStory.h" + #include "Programs/Glitches/PokemonSV_RideCloner-1.0.1.h" #include "Programs/Glitches/PokemonSV_CloneItems-1.0.1.h" @@ -144,6 +146,8 @@ std::vector PanelListFactory::make_panels() const{ // || IS_BETA_VERSION ){ ret.emplace_back("---- Untested/Beta/WIP ----"); + ret.emplace_back("---- Story Automation ----"); + ret.emplace_back(make_single_switch_program()); } if (IS_BETA_VERSION){ } diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp new file mode 100644 index 000000000..e01cf5bb4 --- /dev/null +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp @@ -0,0 +1,630 @@ +/* AutoStory + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#include "CommonFramework/GlobalSettingsPanel.h" +#include "CommonFramework/Exceptions/FatalProgramException.h" +#include "CommonFramework/Exceptions/OperationFailedException.h" +#include "CommonFramework/InferenceInfra/InferenceRoutines.h" +#include "CommonFramework/Notifications/ProgramNotifications.h" +#include "CommonFramework/Tools/StatsTracking.h" +#include "CommonFramework/Tools/VideoResolutionCheck.h" +#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" +#include "Pokemon/Pokemon_Strings.h" +#include "PokemonSwSh/Inference/PokemonSwSh_IvJudgeReader.h" +#include "PokemonSV/Programs/PokemonSV_GameEntry.h" +#include "PokemonSV_AutoStory_Segment_00.h" +// #include "PokemonSV_AutoStory_Segment_01.h" +// #include "PokemonSV_AutoStory_Segment_02.h" +// #include "PokemonSV_AutoStory_Segment_03.h" +// #include "PokemonSV_AutoStory_Segment_04.h" +// #include "PokemonSV_AutoStory_Segment_05.h" +// #include "PokemonSV_AutoStory_Segment_06.h" +// #include "PokemonSV_AutoStory_Segment_07.h" +// #include "PokemonSV_AutoStory_Segment_08.h" +// #include "PokemonSV_AutoStory_Segment_09.h" +// #include "PokemonSV_AutoStory_Segment_10.h" +// #include "PokemonSV_AutoStory_Segment_11.h" +// #include "PokemonSV_AutoStory_Segment_12.h" +// #include "PokemonSV_AutoStory_Segment_13.h" +// #include "PokemonSV_AutoStory_Segment_14.h" +// #include "PokemonSV_AutoStory_Segment_15.h" +#include "PokemonSV_AutoStory.h" + +//#include +//using std::cout; +//using std::endl; +//#include +//#include + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonSV{ + +using namespace Pokemon; + + +std::vector> make_autoStory_segment_list(){ + std::vector> segment_list; + segment_list.emplace_back(std::make_unique()); + // segment_list.emplace_back(std::make_unique()); + // segment_list.emplace_back(std::make_unique()); + // segment_list.emplace_back(std::make_unique()); + // segment_list.emplace_back(std::make_unique()); + // segment_list.emplace_back(std::make_unique()); + // segment_list.emplace_back(std::make_unique()); + // segment_list.emplace_back(std::make_unique()); + // segment_list.emplace_back(std::make_unique()); + // segment_list.emplace_back(std::make_unique()); + // segment_list.emplace_back(std::make_unique()); + // segment_list.emplace_back(std::make_unique()); + // segment_list.emplace_back(std::make_unique()); + // segment_list.emplace_back(std::make_unique()); + // segment_list.emplace_back(std::make_unique()); + + return segment_list; +}; + +const std::vector>& ALL_AUTO_STORY_SEGMENT_LIST(){ + static std::vector> segment_list = make_autoStory_segment_list(); + return segment_list; +} + + +StringSelectDatabase make_all_segments_database(){ + StringSelectDatabase ret; + int index_num = 0; + for (const auto& segment : ALL_AUTO_STORY_SEGMENT_LIST()){ + ret.add_entry(StringSelectEntry(std::to_string(index_num), segment->name())); + index_num++; + } + return ret; +} +const StringSelectDatabase& ALL_SEGMENTS_SELECT_DATABASE(){ + static StringSelectDatabase database = make_all_segments_database(); + return database; +} + +StringSelectDatabase make_tutorial_segments_database(){ + StringSelectDatabase ret; + const StringSelectDatabase& all_segments = ALL_SEGMENTS_SELECT_DATABASE(); + size_t start = 0; + size_t end = all_segments.case_list().size(); // 10. size() is the placeholder value. will be 10 when rest of segments merged. + for (size_t i = start; i < end; i++){ + const auto& segment = all_segments[i]; + ret.add_entry(segment); + } + return ret; +} + +const StringSelectDatabase& TUTORIAL_SEGMENTS_SELECT_DATABASE(){ + static StringSelectDatabase database = make_tutorial_segments_database(); + return database; +} + +StringSelectDatabase make_mainstory_segments_database(){ + StringSelectDatabase ret; + const StringSelectDatabase& all_segments = ALL_SEGMENTS_SELECT_DATABASE(); + size_t start = 0; // 10. 0 is the placeholder value. will be 10 when rest of segments merged. + size_t end = all_segments.case_list().size(); + for (size_t i = start; i < end; i++){ + const auto& segment = all_segments[i]; + ret.add_entry(segment); + } + return ret; +} + +const StringSelectDatabase& MAINSTORY_SEGMENTS_SELECT_DATABASE(){ + static StringSelectDatabase database = make_mainstory_segments_database(); + return database; +} + + +AutoStory_Descriptor::AutoStory_Descriptor() + : SingleSwitchProgramDescriptor( + "PokemonSV:AutoStory", + STRING_POKEMON + " SV", "Auto Story", + "ComputerControl/blob/master/Wiki/Programs/PokemonSV/AutoStory.md", + "Progress through the mainstory of SV.", + FeedbackType::VIDEO_AUDIO, + AllowCommandsWhenRunning::DISABLE_COMMANDS, + PABotBaseLevel::PABOTBASE_12KB + ) +{} + +std::unique_ptr AutoStory_Descriptor::make_stats() const{ + return std::unique_ptr(new AutoStoryStats()); +} + + + +AutoStory::~AutoStory(){ + STARTPOINT_TUTORIAL.remove_listener(*this); + ENDPOINT_TUTORIAL.remove_listener(*this); +} + +AutoStory::AutoStory() + : LANGUAGE( + "Game Language:", + PokemonSwSh::IV_READER().languages(), + LockMode::UNLOCK_WHILE_RUNNING, + true + ) + , STORY_SECTION( + "Story Section:", + { + {StorySection::TUTORIAL, "tutorial", "Tutorial"}, + {StorySection::MAIN_STORY, "main-story", "Main Story"}, + }, + LockMode::LOCK_WHILE_RUNNING, + StorySection::TUTORIAL + ) + , STARTPOINT_TUTORIAL( + "Start Point:
Program will start with this segment.", + TUTORIAL_SEGMENTS_SELECT_DATABASE(), + LockMode::UNLOCK_WHILE_RUNNING, + "0" + ) + , ENDPOINT_TUTORIAL( + "End Point:
Program will stop after completing this segment.", + TUTORIAL_SEGMENTS_SELECT_DATABASE(), + LockMode::UNLOCK_WHILE_RUNNING, + "0" //"9" + ) + // , STARTPOINT_MAINSTORY( + // "Start Point:
Program will start with this segment.", + // MAINSTORY_SEGMENTS_SELECT_DATABASE(), + // LockMode::UNLOCK_WHILE_RUNNING, + // "10" + // ) + // , ENDPOINT_MAINSTORY( + // "End Point:
Program will stop after completing this segment.", + // MAINSTORY_SEGMENTS_SELECT_DATABASE(), + // LockMode::UNLOCK_WHILE_RUNNING, + // "10" + // ) + , MAINSTORY_NOTE{ + "Ensure you have a level 100 Gardevoir with the moves in the following order: Moonblast, Dazzling Gleam, Psychic, Mystical Fire.
" + "Refer to the documentation on github for more details." + } + , START_DESCRIPTION( + "" + ) + , END_DESCRIPTION( + "" + ) + , STARTERCHOICE( + "Starter " + STRING_POKEMON + ":", + { + {StarterChoice::SPRIGATITO, "sprigatito", "Sprigatito (Grass)"}, + {StarterChoice::FUECOCO, "fuecoco", "Fuecoco (Fire)"}, + {StarterChoice::QUAXLY, "quaxly", "Quaxly (Water)"}, + }, + LockMode::LOCK_WHILE_RUNNING, + StarterChoice::FUECOCO + ) + , GO_HOME_WHEN_DONE(true) + , NOTIFICATION_STATUS_UPDATE("Status Update", true, false, std::chrono::seconds(30)) + , NOTIFICATIONS({ + &NOTIFICATION_STATUS_UPDATE, + &NOTIFICATION_PROGRAM_FINISH, + &NOTIFICATION_ERROR_RECOVERABLE, + &NOTIFICATION_ERROR_FATAL, + }) + , m_advanced_options( + "Advanced Options: (developer only)" + ) + , CHANGE_SETTINGS( + "Change settings at Program Start:
" + "This is to ensure the program has the correct settings, particularly with Autosave turned off.", + LockMode::UNLOCK_WHILE_RUNNING, + true + ) + , ENABLE_TEST_CHECKPOINTS( + "TEST: test_checkpoints():", + LockMode::UNLOCK_WHILE_RUNNING, + false + ) + , START_CHECKPOINT( + "--Start checkpoint:
Start testing with this checkpoint number.", + LockMode::UNLOCK_WHILE_RUNNING, + 0 + ) + , END_CHECKPOINT( + "--End checkpoint:
Stop testing when done this checkpoint number.", + LockMode::UNLOCK_WHILE_RUNNING, + 11 + ) + , LOOP_CHECKPOINT( + "--Loop checkpoints:
Loop the checkpoints from \"Start loop\" to \"End loop\", inclusive. Loop these checkpoints this number of times.", + LockMode::UNLOCK_WHILE_RUNNING, + 1, 1 + ) + , START_LOOP( + "--Start loop:
Start looping with this checkpoint number.", + LockMode::UNLOCK_WHILE_RUNNING, + 0 + ) + , END_LOOP( + "--End loop:
Stop looping when done this checkpoint number.", + LockMode::UNLOCK_WHILE_RUNNING, + 11 + ) + , ENABLE_TEST_REALIGN( + "TEST: realign_player():", + LockMode::UNLOCK_WHILE_RUNNING, + false + ) + , REALIGN_MODE( + "--REALIGN_MODE:", + { + {PlayerRealignMode::REALIGN_NEW_MARKER, "realign_new", "Realign New Marker"}, + {PlayerRealignMode::REALIGN_NO_MARKER, "realign_no", "Realign No Marker"}, + {PlayerRealignMode::REALIGN_OLD_MARKER, "realign_old", "Realign Old Marker"}, + }, + LockMode::UNLOCK_WHILE_RUNNING, + PlayerRealignMode::REALIGN_NEW_MARKER + ) + , X_REALIGN( + "--X_REALIGN:
x = 0 : left, x = 128 : neutral, x = 255 : right.", + LockMode::UNLOCK_WHILE_RUNNING, + 128 + ) + , Y_REALIGN( + "--Y_REALIGN:
y = 0 : up, y = 128 : neutral, y = 255 : down.", + LockMode::UNLOCK_WHILE_RUNNING, + 128 + ) + , REALIGN_DURATION( + "--REALIGN_DURATION", + LockMode::UNLOCK_WHILE_RUNNING, + 0 + ) + , ENABLE_TEST_OVERWORLD_MOVE( + "TEST: walk_forward_while_clear_front_path():", + LockMode::UNLOCK_WHILE_RUNNING, + false + ) + , FORWARD_TICKS( + "--FORWARD_TICKS:", + LockMode::UNLOCK_WHILE_RUNNING, + 0 + ) + , TEST_PBF_LEFT_JOYSTICK( + "TEST: pbf_move_left_joystick():", + LockMode::UNLOCK_WHILE_RUNNING, + false + ) + , X_MOVE( + "--X_MOVE:
x = 0 : left, x = 128 : neutral, x = 255 : right.", + LockMode::UNLOCK_WHILE_RUNNING, + 128 + ) + , Y_MOVE( + "--Y_MOVE:
y = 0 : up, y = 128 : neutral, y = 255 : down.", + LockMode::UNLOCK_WHILE_RUNNING, + 128 + ) + , HOLD_TICKS( + "--HOLD_TICKS:", + LockMode::UNLOCK_WHILE_RUNNING, + 0 + ) + , RELEASE_TICKS( + "--RELEASE_TICKS:", + LockMode::UNLOCK_WHILE_RUNNING, + 0 + ) +{ + PA_ADD_OPTION(LANGUAGE); + PA_ADD_OPTION(STORY_SECTION); + PA_ADD_OPTION(STARTPOINT_TUTORIAL); + PA_ADD_OPTION(MAINSTORY_NOTE); + // PA_ADD_OPTION(STARTPOINT_MAINSTORY); + PA_ADD_OPTION(START_DESCRIPTION); + PA_ADD_OPTION(ENDPOINT_TUTORIAL); + // PA_ADD_OPTION(ENDPOINT_MAINSTORY); + PA_ADD_OPTION(END_DESCRIPTION); + PA_ADD_OPTION(STARTERCHOICE); + PA_ADD_OPTION(GO_HOME_WHEN_DONE); + PA_ADD_OPTION(NOTIFICATIONS); + + if (PreloadSettings::instance().DEVELOPER_MODE){ + PA_ADD_OPTION(m_advanced_options); + PA_ADD_OPTION(CHANGE_SETTINGS); + PA_ADD_OPTION(ENABLE_TEST_CHECKPOINTS); + PA_ADD_OPTION(START_CHECKPOINT); + PA_ADD_OPTION(END_CHECKPOINT); + PA_ADD_OPTION(LOOP_CHECKPOINT); + PA_ADD_OPTION(START_LOOP); + PA_ADD_OPTION(END_LOOP); + + PA_ADD_OPTION(ENABLE_TEST_REALIGN); + PA_ADD_OPTION(REALIGN_MODE); + PA_ADD_OPTION(X_REALIGN); + PA_ADD_OPTION(Y_REALIGN); + PA_ADD_OPTION(REALIGN_DURATION); + + PA_ADD_OPTION(ENABLE_TEST_OVERWORLD_MOVE); + PA_ADD_OPTION(FORWARD_TICKS); + + PA_ADD_OPTION(TEST_PBF_LEFT_JOYSTICK); + PA_ADD_OPTION(X_MOVE); + PA_ADD_OPTION(Y_MOVE); + PA_ADD_OPTION(HOLD_TICKS); + PA_ADD_OPTION(RELEASE_TICKS); + } + + AutoStory::value_changed(this); + + STORY_SECTION.add_listener(*this); + STARTPOINT_TUTORIAL.add_listener(*this); + ENDPOINT_TUTORIAL.add_listener(*this); + // STARTPOINT_MAINSTORY.add_listener(*this); + // ENDPOINT_MAINSTORY.add_listener(*this); + ENABLE_TEST_CHECKPOINTS.add_listener(*this); + ENABLE_TEST_REALIGN.add_listener(*this); + ENABLE_TEST_OVERWORLD_MOVE.add_listener(*this); + TEST_PBF_LEFT_JOYSTICK.add_listener(*this); +} + +void AutoStory::value_changed(void* object){ + ConfigOptionState state = (STARTPOINT_TUTORIAL.index() <= 1) + ? ConfigOptionState::ENABLED + : ConfigOptionState::HIDDEN; + STARTERCHOICE.set_visibility(state); + + if (STORY_SECTION == StorySection::TUTORIAL){ + STARTPOINT_TUTORIAL.set_visibility(ConfigOptionState::ENABLED); + ENDPOINT_TUTORIAL.set_visibility(ConfigOptionState::ENABLED); + + // STARTPOINT_MAINSTORY.set_visibility(ConfigOptionState::HIDDEN); + // ENDPOINT_MAINSTORY.set_visibility(ConfigOptionState::HIDDEN); + }else if (STORY_SECTION == StorySection::MAIN_STORY){ + STARTPOINT_TUTORIAL.set_visibility(ConfigOptionState::HIDDEN); + ENDPOINT_TUTORIAL.set_visibility(ConfigOptionState::HIDDEN); + + // STARTPOINT_MAINSTORY.set_visibility(ConfigOptionState::ENABLED); + // ENDPOINT_MAINSTORY.set_visibility(ConfigOptionState::ENABLED); + } + + MAINSTORY_NOTE.set_visibility(STORY_SECTION == StorySection::TUTORIAL ? ConfigOptionState::HIDDEN : ConfigOptionState::ENABLED); + START_DESCRIPTION.set_text(start_segment_description()); + END_DESCRIPTION.set_text(end_segment_description()); + + if (ENABLE_TEST_CHECKPOINTS){ + START_CHECKPOINT.set_visibility(ConfigOptionState::ENABLED); + END_CHECKPOINT.set_visibility(ConfigOptionState::ENABLED); + LOOP_CHECKPOINT.set_visibility(ConfigOptionState::ENABLED); + START_LOOP.set_visibility(ConfigOptionState::ENABLED); + END_LOOP.set_visibility(ConfigOptionState::ENABLED); + }else{ + START_CHECKPOINT.set_visibility(ConfigOptionState::DISABLED); + END_CHECKPOINT.set_visibility(ConfigOptionState::DISABLED); + LOOP_CHECKPOINT.set_visibility(ConfigOptionState::DISABLED); + START_LOOP.set_visibility(ConfigOptionState::DISABLED); + END_LOOP.set_visibility(ConfigOptionState::DISABLED); + } + + if (ENABLE_TEST_REALIGN){ + REALIGN_MODE.set_visibility(ConfigOptionState::ENABLED); + X_REALIGN.set_visibility(ConfigOptionState::ENABLED); + Y_REALIGN.set_visibility(ConfigOptionState::ENABLED); + REALIGN_DURATION.set_visibility(ConfigOptionState::ENABLED); + }else{ + REALIGN_MODE.set_visibility(ConfigOptionState::DISABLED); + X_REALIGN.set_visibility(ConfigOptionState::DISABLED); + Y_REALIGN.set_visibility(ConfigOptionState::DISABLED); + REALIGN_DURATION.set_visibility(ConfigOptionState::DISABLED); + } + + if (ENABLE_TEST_OVERWORLD_MOVE){ + FORWARD_TICKS.set_visibility(ConfigOptionState::ENABLED); + }else{ + FORWARD_TICKS.set_visibility(ConfigOptionState::DISABLED); + } + + if (TEST_PBF_LEFT_JOYSTICK){ + X_MOVE.set_visibility(ConfigOptionState::ENABLED); + Y_MOVE.set_visibility(ConfigOptionState::ENABLED); + HOLD_TICKS.set_visibility(ConfigOptionState::ENABLED); + RELEASE_TICKS.set_visibility(ConfigOptionState::ENABLED); + }else{ + X_MOVE.set_visibility(ConfigOptionState::DISABLED); + Y_MOVE.set_visibility(ConfigOptionState::DISABLED); + HOLD_TICKS.set_visibility(ConfigOptionState::DISABLED); + RELEASE_TICKS.set_visibility(ConfigOptionState::DISABLED); + } + + +} + + + + + + +void AutoStory::test_checkpoints( + SingleSwitchProgramEnvironment& env, + ConsoleHandle& console, + BotBaseContext& context, + int start, int end, + int loop, int start_loop, int end_loop +){ + // EventNotificationOption& notif_status_update = NOTIFICATION_STATUS_UPDATE; + // Language language = LANGUAGE; + // StarterChoice starter_choice = STARTERCHOICE; + std::vector> checkpoint_list; + checkpoint_list.push_back([&](){checkpoint_00(env, context);}); + // checkpoint_list.push_back([&](){checkpoint_01(env, context, notif_status_update, language);}); + // checkpoint_list.push_back([&](){checkpoint_02(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_03(env, context, notif_status_update, language, starter_choice);}); + // checkpoint_list.push_back([&](){checkpoint_04(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_05(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_06(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_07(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_08(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_09(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_10(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_11(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_12(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_13(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_14(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_15(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_16(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_17(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_18(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_19(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_20(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_21(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_22(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_23(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_24(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_25(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_26(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_27(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_28(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_29(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_30(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_31(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_32(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_33(env, context, notif_status_update);}); + // checkpoint_list.push_back([&](){checkpoint_34(env, context, notif_status_update);}); + + for (int checkpoint = start; checkpoint <= end; checkpoint++){ + if (checkpoint == 0){ + console.log("checkpoint_0"); + checkpoint_list[checkpoint](); + continue; + } + + const size_t DIGITS = 3; + std::string number = std::to_string(checkpoint); + if (number.size() < DIGITS){ + number = std::string(DIGITS - number.size(), '0') + number; + } + if (checkpoint >= start_loop && checkpoint <= end_loop){ + for (int i = 0; i < loop; i++){ + if (i > 0){ + reset_game(env.program_info(), console, context); + } + console.log("checkpoint_" + number + ": loop " + std::to_string(i)); + checkpoint_list[checkpoint](); + } + }else{ + console.log("checkpoint_" + number + "."); + checkpoint_list[checkpoint](); + } + + } + +} + +std::string AutoStory::start_segment_description(){ + size_t segment_index = 0; + if (STORY_SECTION == StorySection::TUTORIAL){ + segment_index = STARTPOINT_TUTORIAL.index(); + }else if (STORY_SECTION == StorySection::MAIN_STORY){ + // segment_index = STARTPOINT_MAINSTORY.index() + 10; + } + return ALL_AUTO_STORY_SEGMENT_LIST()[segment_index]->start_text(); +} + +std::string AutoStory::end_segment_description(){ + size_t segment_index = 0; + if (STORY_SECTION == StorySection::TUTORIAL){ + segment_index = ENDPOINT_TUTORIAL.index(); + }else if (STORY_SECTION == StorySection::MAIN_STORY){ + // segment_index = ENDPOINT_MAINSTORY.index() + 10; + } + return ALL_AUTO_STORY_SEGMENT_LIST()[segment_index]->end_text(); +} + + +void AutoStory::run_autostory(SingleSwitchProgramEnvironment& env, BotBaseContext& context){ + AutoStoryOptions options{ + LANGUAGE, + STARTERCHOICE, + NOTIFICATION_STATUS_UPDATE + }; + + size_t start = STARTPOINT_TUTORIAL.index(); + size_t end = ENDPOINT_TUTORIAL.index(); + for (size_t segment_index = start; segment_index <= end; segment_index++){ + ALL_AUTO_STORY_SEGMENT_LIST()[segment_index]->run_segment(env, context, options); + } +} + +void AutoStory::test_code(SingleSwitchProgramEnvironment& env, BotBaseContext& context){ + + if (ENABLE_TEST_CHECKPOINTS){ + // test individual checkpoints + test_checkpoints(env, env.console, context, START_CHECKPOINT, END_CHECKPOINT, LOOP_CHECKPOINT, START_LOOP, END_LOOP); + return; + } + + + if (ENABLE_TEST_REALIGN){ + // clear realign marker + // realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_NEW_MARKER, 128, 128, 0); + realign_player(env.program_info(), env.console, context, REALIGN_MODE, X_REALIGN, Y_REALIGN, REALIGN_DURATION); + return; + } + + if (ENABLE_TEST_OVERWORLD_MOVE){ + // walk_forward_while_clear_front_path(env.program_info(), env.console, context, FORWARD_TICKS); + + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::CLEAR_WITH_LETS_GO, + 128, 0, 60, 10, false); + + // overworld_navigation(env.program_info(), env.console, context, + // NavigationStopCondition::STOP_TIME, NavigationMovementMode::CLEAR_WITH_LETS_GO, + // 128, 0, 25, 10, false); + return; + } + + if (TEST_PBF_LEFT_JOYSTICK){ + pbf_move_left_joystick(context, X_MOVE, Y_MOVE, HOLD_TICKS, RELEASE_TICKS); + return; + } + + // context.wait_for(Milliseconds(1000000)); + + +} + +void AutoStory::program(SingleSwitchProgramEnvironment& env, BotBaseContext& context){ + assert_16_9_720p_min(env.logger(), env.console); + // AutoStoryStats& stats = env.current_stats(); + + // Connect controller + pbf_press_button(context, BUTTON_L, 20, 20); + + // test code + if (ENABLE_TEST_CHECKPOINTS || ENABLE_TEST_REALIGN || ENABLE_TEST_OVERWORLD_MOVE || TEST_PBF_LEFT_JOYSTICK){ + test_code(env, context); + return; + } + + // Set settings. to ensure autosave is off. + if (CHANGE_SETTINGS){ + change_settings_prior_to_autostory(env, context, STARTPOINT_TUTORIAL.index(), LANGUAGE); + } + + run_autostory(env, context); + + send_program_finished_notification(env, NOTIFICATION_PROGRAM_FINISH); + GO_HOME_WHEN_DONE.run_end_of_program(context); +} + + + + + + +} +} +} diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.h b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.h new file mode 100644 index 000000000..a6715346b --- /dev/null +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.h @@ -0,0 +1,123 @@ +/* Autostory + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#ifndef PokemonAutomation_PokemonSV_AutoStory_H +#define PokemonAutomation_PokemonSV_AutoStory_H + +#include +#include "Common/Cpp/Options/EnumDropdownOption.h" +#include "CommonFramework/Notifications/EventNotificationsTable.h" +#include "CommonFramework/Options/LanguageOCROption.h" +#include "CommonFramework/Options/StringSelectOption.h" +#include "NintendoSwitch/Options/NintendoSwitch_GoHomeWhenDoneOption.h" +#include "Common/NintendoSwitch/NintendoSwitch_ControllerDefs.h" +#include "PokemonSV/Programs/PokemonSV_Navigation.h" +#include "PokemonSV_AutoStoryTools.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonSV{ + + + +class AutoStory_Descriptor : public SingleSwitchProgramDescriptor{ +public: + AutoStory_Descriptor(); + + struct Stats; + virtual std::unique_ptr make_stats() const override; +}; + +class AutoStory : public SingleSwitchProgramInstance, public ConfigOption::Listener{ +public: + ~AutoStory(); + AutoStory(); + + virtual void program(SingleSwitchProgramEnvironment& env, BotBaseContext& context) override; + + void test_code(SingleSwitchProgramEnvironment& env, BotBaseContext& context); + + // test the checkpoints from start to end, inclusive + // test each checkpoints "loop" number of times + void test_checkpoints( + SingleSwitchProgramEnvironment& env, + ConsoleHandle& console, + BotBaseContext& context, + int start, int end, + int loop, int start_loop, int end_loop + ); + + void run_autostory(SingleSwitchProgramEnvironment& env, BotBaseContext& context); + +private: + virtual void value_changed(void* object) override; + + std::string start_segment_description(); + std::string end_segment_description(); + +private: + OCR::LanguageOCROption LANGUAGE; + + enum class StorySection{ + TUTORIAL, + MAIN_STORY, + }; + + EnumDropdownOption STORY_SECTION; + + StringSelectOption STARTPOINT_TUTORIAL; + StringSelectOption ENDPOINT_TUTORIAL; + + // StringSelectOption STARTPOINT_MAINSTORY; + // StringSelectOption ENDPOINT_MAINSTORY; + + StaticTextOption MAINSTORY_NOTE; + + StaticTextOption START_DESCRIPTION; + StaticTextOption END_DESCRIPTION; + + + EnumDropdownOption STARTERCHOICE; + + GoHomeWhenDoneOption GO_HOME_WHEN_DONE; + + EventNotificationOption NOTIFICATION_STATUS_UPDATE; + EventNotificationsOption NOTIFICATIONS; + + SectionDividerOption m_advanced_options; + BooleanCheckBoxOption CHANGE_SETTINGS; + + BooleanCheckBoxOption ENABLE_TEST_CHECKPOINTS; + SimpleIntegerOption START_CHECKPOINT; + SimpleIntegerOption END_CHECKPOINT; + SimpleIntegerOption LOOP_CHECKPOINT; + SimpleIntegerOption START_LOOP; + SimpleIntegerOption END_LOOP; + + BooleanCheckBoxOption ENABLE_TEST_REALIGN; + EnumDropdownOption REALIGN_MODE; + SimpleIntegerOption X_REALIGN; + SimpleIntegerOption Y_REALIGN; + SimpleIntegerOption REALIGN_DURATION; + + BooleanCheckBoxOption ENABLE_TEST_OVERWORLD_MOVE; + SimpleIntegerOption FORWARD_TICKS; + + BooleanCheckBoxOption TEST_PBF_LEFT_JOYSTICK; + SimpleIntegerOption X_MOVE; + SimpleIntegerOption Y_MOVE; + SimpleIntegerOption HOLD_TICKS; + SimpleIntegerOption RELEASE_TICKS; +}; + + + + + +} +} +} +#endif diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp index aa2d026f0..16e9143b7 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp @@ -447,43 +447,37 @@ void swap_starter_moves(const ProgramInfo& info, ConsoleHandle& console, BotBase } -void change_settings_prior_to_autostory(SingleSwitchProgramEnvironment& env, BotBaseContext& context, StartPoint current_segment, Language language){ - if (current_segment == StartPoint::INTRO_CUTSCENE){ +void change_settings_prior_to_autostory(SingleSwitchProgramEnvironment& env, BotBaseContext& context, size_t current_segment_num, Language language){ + if (current_segment_num == 0){ // can't change settings in the intro cutscene return; } - // get index of `Options` in the Main Menu, depending on where you are in Autostory - int8_t index; - switch(current_segment){ - // case StartPoint::INTRO_CUTSCENE: - case StartPoint::PICK_STARTER: - index = 0; - case StartPoint::NEMONA_FIRST_BATTLE: - index = 1; - case StartPoint::CATCH_TUTORIAL: - case StartPoint::LEGENDARY_RESCUE: - case StartPoint::ARVEN_FIRST_BATTLE: - case StartPoint::LOS_PLATOS: - case StartPoint::MESAGOZA_SOUTH: - index = 2; - default: - index = -1; + // get index of `Options` in the Main Menu, which depends on where you are in Autostory + int8_t options_index; + switch(current_segment_num){ + case 0: + options_index = 0; + break; + case 1: + options_index = 1; + break; + default: + options_index = 2; + break; } - if (index < 0){ - return; - } - bool has_minimap = current_segment != StartPoint::PICK_STARTER; // and also not equal to StartPoint::INTRO_CUTSCENE: + bool has_minimap = current_segment_num > 1; // the minimap only shows up in segment 2 and beyond - enter_menu_from_overworld(env.program_info(), env.console, context, index, MenuSide::RIGHT, has_minimap); + enter_menu_from_overworld(env.program_info(), env.console, context, options_index, MenuSide::RIGHT, has_minimap); change_settings(env, context, language); - if(current_segment == StartPoint::PICK_STARTER){ + if(has_minimap){ pbf_mash_button(context, BUTTON_B, 2 * TICKS_PER_SECOND); }else{ press_Bs_to_back_to_overworld(env.program_info(), env.console, context); } } + void change_settings(SingleSwitchProgramEnvironment& env, BotBaseContext& context, Language language, bool use_inference){ env.console.log("Update settings."); if (use_inference){ diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h index c228fdf72..64557058b 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h @@ -8,6 +8,8 @@ #define PokemonAutomation_PokemonSV_AutoStoryTools_H #include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h" +#include "CommonFramework/Tools/StatsTracking.h" +#include "CommonFramework/Language.h" #include "PokemonSV/Programs/PokemonSV_Navigation.h" namespace PokemonAutomation{ namespace NintendoSwitch{ @@ -72,6 +74,24 @@ enum class StarterChoice{ QUAXLY, }; +struct AutoStoryOptions{ + Language language; + StarterChoice starter_choice; + EventNotificationOption& notif_status_update; +}; + +class AutoStory_Segment { +public: + virtual ~AutoStory_Segment() = default; + virtual std::string name() const = 0; + virtual std::string start_text() const = 0; + virtual std::string end_text() const = 0; + virtual void run_segment( + SingleSwitchProgramEnvironment& env, + BotBaseContext& context, + AutoStoryOptions options) const = 0; +}; + // spam A button to choose the first move // throw exception if wipeout. void run_battle_press_A( @@ -138,7 +158,7 @@ void get_on_ride(const ProgramInfo& info, ConsoleHandle& console, BotBaseContext // change the settings prior to Autostory // Assumes that `current_segment` represents where we currently are in the story. -void change_settings_prior_to_autostory(SingleSwitchProgramEnvironment& env, BotBaseContext& context, StartPoint current_segment, Language language); +void change_settings_prior_to_autostory(SingleSwitchProgramEnvironment& env, BotBaseContext& context, size_t current_segment_num, Language language); // from within the Settings/Options menu, change the settings void change_settings(SingleSwitchProgramEnvironment& env, BotBaseContext& context, Language language, bool use_inference = true); @@ -146,7 +166,6 @@ void change_settings(SingleSwitchProgramEnvironment& env, BotBaseContext& contex void checkpoint_save(SingleSwitchProgramEnvironment& env, BotBaseContext& context, EventNotificationOption& notif_status_update); - } diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_00.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_00.cpp new file mode 100644 index 000000000..1dbcd24a6 --- /dev/null +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_00.cpp @@ -0,0 +1,92 @@ +/* AutoStory + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#include "CommonFramework/GlobalSettingsPanel.h" +#include "CommonFramework/Exceptions/FatalProgramException.h" +#include "CommonFramework/Exceptions/OperationFailedException.h" +#include "CommonFramework/InferenceInfra/InferenceRoutines.h" +#include "CommonFramework/Notifications/ProgramNotifications.h" +#include "CommonFramework/Tools/StatsTracking.h" +#include "CommonFramework/Tools/VideoResolutionCheck.h" +#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" +#include "Pokemon/Pokemon_Strings.h" +#include "PokemonSwSh/Inference/PokemonSwSh_IvJudgeReader.h" +#include "PokemonSV/Programs/PokemonSV_GameEntry.h" +#include "PokemonSV/Programs/PokemonSV_SaveGame.h" +#include "PokemonSV/Inference/PokemonSV_TutorialDetector.h" +#include "PokemonSV/Inference/PokemonSV_WhiteButtonDetector.h" +#include "PokemonSV_AutoStoryTools.h" +#include "PokemonSV_AutoStory_Segment_00.h" + +//#include +//using std::cout; +//using std::endl; +//#include +//#include + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonSV{ + +using namespace Pokemon; + + +std::string AutoStory_Segment_00::name() const{ + return "00: Intro Cutscene"; +} + + +std::string AutoStory_Segment_00::start_text() const{ + return "Start: Intro cutscene."; +} + +std::string AutoStory_Segment_00::end_text() const{ + return "End: Finished cutscene."; +} + +void AutoStory_Segment_00::run_segment(SingleSwitchProgramEnvironment& env, BotBaseContext& context, AutoStoryOptions options) const{ + AutoStoryStats& stats = env.current_stats(); + + context.wait_for_all_requests(); + env.console.log("Start Segment 00: Intro Cutscene", COLOR_ORANGE); + env.console.overlay().add_log("Start Segment 00: Intro Cutscene", COLOR_ORANGE); + + checkpoint_00(env, context); + + context.wait_for_all_requests(); + env.console.log("End Segment 00: Intro Cutscene", COLOR_GREEN); + env.console.overlay().add_log("End Segment 00: Intro Cutscene", COLOR_GREEN); + stats.m_segment++; + env.update_stats(); +} + + +void checkpoint_00(SingleSwitchProgramEnvironment& env, BotBaseContext& context){ + + + // Mash A through intro cutscene, until the L stick button is detected + WhiteButtonWatcher leftstick(COLOR_GREEN, WhiteButton::ButtonLStick, {0.435, 0.912, 0.046, 0.047}); + context.wait_for_all_requests(); + run_until( + env.console, context, + [](BotBaseContext& context){ + pbf_mash_button(context, BUTTON_A, 240 * TICKS_PER_SECOND); + }, + {leftstick} + ); + + // Stand up from chair and walk to left side of room + pbf_move_left_joystick(context, 128, 255, 3 * TICKS_PER_SECOND, 5 * TICKS_PER_SECOND); + pbf_move_left_joystick(context, 0, 128, 6 * TICKS_PER_SECOND, 1 * TICKS_PER_SECOND); + +} + + + + +} +} +} diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_00.h b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_00.h new file mode 100644 index 000000000..5de78a990 --- /dev/null +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_00.h @@ -0,0 +1,42 @@ +/* Autostory + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#ifndef PokemonAutomation_PokemonSV_AutoStory_Segment_00_H +#define PokemonAutomation_PokemonSV_AutoStory_Segment_00_H + +#include +#include "Common/Cpp/Options/EnumDropdownOption.h" +#include "CommonFramework/Notifications/EventNotificationsTable.h" +#include "CommonFramework/Options/LanguageOCROption.h" +#include "NintendoSwitch/Options/NintendoSwitch_GoHomeWhenDoneOption.h" +#include "Common/NintendoSwitch/NintendoSwitch_ControllerDefs.h" +#include "PokemonSV/Programs/PokemonSV_Navigation.h" +#include "PokemonSV_AutoStoryTools.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonSV{ + +class AutoStory_Segment_00 : public AutoStory_Segment{ +public: + virtual std::string name() const override; + virtual std::string start_text() const override; + virtual std::string end_text() const override; + virtual void run_segment( + SingleSwitchProgramEnvironment& env, + BotBaseContext& context, + AutoStoryOptions options) const override; +}; + +// start: after selecting character name, style and the cutscene has started +// end: stood up from chair. Walked to left side of room. +void checkpoint_00(SingleSwitchProgramEnvironment& env, BotBaseContext& context); + + +} +} +} +#endif