Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h"
#include "CommonTools/Images/ImageFilter.h"
#include "CommonTools/Async/InferenceRoutines.h"
#include "NintendoSwitch/Programs/NintendoSwitch_GameEntry.h"
#include "NintendoSwitch/NintendoSwitch_Settings.h"
#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h"
#include "NintendoSwitch/Inference/NintendoSwitch_HomeMenuDetector.h"
Expand Down Expand Up @@ -233,6 +234,32 @@ void change_date(
}
}

void ensure_time_unsynced(SingleSwitchProgramEnvironment& env, ProControllerContext& context){
Milliseconds timing_variation = context->timing_variation();
ensure_at_home(env.console, context);
home_to_date_time(env.console, context, true);
pbf_press_button(context, BUTTON_A, 80ms + timing_variation, 240ms + timing_variation);

context.wait_for_all_requests();

DateChangeWatcher date_reader(env.console);
int ret = wait_until(
env.console, context, std::chrono::seconds(10),
{
date_reader
}
);

if (ret < 0){
OperationFailedException::fire(
ErrorReport::SEND_ERROR_REPORT,
"Failed to enter Date Change window. Ensure that System Time is not synced to the internet.",
env.console
);
}

}




Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ void change_date(
const DateTime& date
);

// starting from home screen, ensure that the time is unsyced
// i.e. confirm we can enter the Date change window
void ensure_time_unsynced(SingleSwitchProgramEnvironment& env, ProControllerContext& context);



}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
#include "CommonTools/StartupChecks/StartProgramChecks.h"
#include "CommonTools/StartupChecks/VideoResolutionCheck.h"
#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h"
#include "NintendoSwitch/Programs/DateManip/NintendoSwitch_DateManip.h"
#include "NintendoSwitch/Programs/NintendoSwitch_GameEntry.h"
#include "PokemonSV/PokemonSV_Settings.h"
#include "Pokemon/Pokemon_Strings.h"
#include "PokemonSwSh/Inference/PokemonSwSh_IvJudgeReader.h"
#include "PokemonSV/Inference/PokemonSV_MainMenuDetector.h"
Expand Down Expand Up @@ -475,7 +478,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, Mystical Fire, Misty Terrain.<br>"
"Ensure you have a level 100 Gardevoir with the moves in the following order: Moonblast, Mystical Fire, Psychic, Misty Terrain.<br>"
"Also, make sure you have two other strong pokemon (e.g. level 100 Talonflames)<br>"
"Refer to the documentation on github for more details."
}
Expand Down Expand Up @@ -508,6 +511,25 @@ AutoStory::AutoStory()
LockMode::UNLOCK_WHILE_RUNNING,
false
)
, CHANGE_SETTINGS(
"<b>Pre-check: Update game settings:</b><br>"
"This is to ensure the game has the correct settings, particularly with Autosave turned off, and Camera Support off.<br>"
"WARNING: if you disable this, make sure you manually set the in-game settings as laid out in the wiki.",
LockMode::UNLOCK_WHILE_RUNNING,
true
)
, ENSURE_TIME_UNSYNCED(
"<b>Pre-check: Ensure time unsynced:</b><br>"
"This is to ensure the Switch has time unsynced from the internet, so it can be changed. This is run prior to the main story.",
LockMode::UNLOCK_WHILE_RUNNING,
true
)
, ENSURE_CORRECT_MOVES(
"<b>Pre-check: Ensure correct moves:</b><br>"
"This is to ensure the lead Gardevoir has the correct moves in the correct order: Moonblast, Mystical Fire, Psychic, Misty Terrain. This is run prior to the main story.",
LockMode::UNLOCK_WHILE_RUNNING,
true
)
, GO_HOME_WHEN_DONE(true)
, NOTIFICATION_STATUS_UPDATE("Status Update", true, false, std::chrono::seconds(30))
, NOTIFICATIONS({
Expand All @@ -522,13 +544,6 @@ AutoStory::AutoStory()
, m_advanced_options_end(
""
)
, CHANGE_SETTINGS(
"<b>Change settings at Program Start:</b><br>"
"This is to ensure the program has the correct settings, particularly with Autosave turned off, and Camera Support off.<br>"
"WARNING: if you disable this, make sure you manually set the in-game settings as laid out in the wiki.",
LockMode::UNLOCK_WHILE_RUNNING,
true
)
, ENABLE_TEST_CHECKPOINTS(
"<b>TEST: test_checkpoints():</b>",
LockMode::UNLOCK_WHILE_RUNNING,
Expand Down Expand Up @@ -788,6 +803,8 @@ AutoStory::AutoStory()

PA_ADD_OPTION(ENABLE_ADVANCED_MODE);
PA_ADD_OPTION(CHANGE_SETTINGS);
PA_ADD_OPTION(ENSURE_TIME_UNSYNCED);
PA_ADD_OPTION(ENSURE_CORRECT_MOVES);

PA_ADD_OPTION(NOTIFICATIONS);

Expand Down Expand Up @@ -1336,6 +1353,19 @@ void AutoStory::program(SingleSwitchProgramEnvironment& env, ProControllerContex
}
}

if (ENSURE_TIME_UNSYNCED && STORY_SECTION == StorySection::MAIN_STORY){
env.console.log("Ensure time is not synchronized to the internet.");
pbf_press_button(context, BUTTON_HOME, 160ms, GameSettings::instance().GAME_TO_HOME_DELAY1);
ensure_time_unsynced(env, context);
go_home(env.console, context);
resume_game_from_home(env.console, context, true);
}

if (ENSURE_CORRECT_MOVES && STORY_SECTION == StorySection::MAIN_STORY){
env.console.log("Ensure lead Gardevoir has the correct moves.");
confirm_lead_pokemon_moves(env, context, LANGUAGE);
}

run_autostory(env, context);

send_program_finished_notification(env, NOTIFICATION_PROGRAM_FINISH);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ class AutoStory : public SingleSwitchProgramInstance, public ConfigOption::Liste
EnumDropdownOption<StarterChoice> STARTERCHOICE;

BooleanCheckBoxOption ENABLE_ADVANCED_MODE;
BooleanCheckBoxOption CHANGE_SETTINGS;
BooleanCheckBoxOption ENSURE_TIME_UNSYNCED;
BooleanCheckBoxOption ENSURE_CORRECT_MOVES;

GoHomeWhenDoneOption GO_HOME_WHEN_DONE;

Expand All @@ -109,7 +112,6 @@ class AutoStory : public SingleSwitchProgramInstance, public ConfigOption::Liste

SectionDividerOption m_advanced_options;
SectionDividerOption m_advanced_options_end;
BooleanCheckBoxOption CHANGE_SETTINGS;

BooleanCheckBoxOption ENABLE_TEST_CHECKPOINTS;
SimpleIntegerOption<uint16_t> START_CHECKPOINT;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,9 @@ void clear_dialog(VideoStream& stream, ProControllerContext& context,
break;
case CallbackEnum::TUTORIAL:
stream.log("clear_dialog: Detected tutorial.");
if (mode == ClearDialogMode::STOP_TUTORIAL){
return;
}
pbf_press_button(context, BUTTON_A, 20, 105);
break;
case CallbackEnum::BLACK_DIALOG_BOX:
Expand Down Expand Up @@ -488,6 +491,50 @@ void swap_starter_moves(SingleSwitchProgramEnvironment& env, ProControllerContex

}


void confirm_lead_pokemon_moves(SingleSwitchProgramEnvironment& env, ProControllerContext& context, Language language){
const ProgramInfo& info = env.program_info();
VideoStream& stream = env.console;

// start in the overworld
press_Bs_to_back_to_overworld(info, stream, context);

// open menu, select your lead pokemon
enter_menu_from_overworld(info, stream, context, 0, MenuSide::LEFT);

// enter Pokemon summary screen
pbf_press_button(context, BUTTON_A, 20, 5 * TICKS_PER_SECOND);
pbf_press_dpad(context, DPAD_RIGHT, 15, 1 * TICKS_PER_SECOND);
pbf_press_button(context, BUTTON_Y, 20, 40);

// confirm that moves are: Moonblast, Mystical Fire, Psychic, Misty Terrain
context.wait_for_all_requests();
VideoSnapshot screen = stream.video().snapshot();
PokemonMovesReader reader(language);
std::string move_0 = reader.read_move(stream.logger(), screen, 0);
std::string move_1 = reader.read_move(stream.logger(), screen, 1);
std::string move_2 = reader.read_move(stream.logger(), screen, 2);
std::string move_3 = reader.read_move(stream.logger(), screen, 3);
stream.log("Current first move: " + move_0);
stream.log("Current second move: " + move_1);
stream.log("Current third move: " + move_2);
stream.log("Current fourth move: " + move_3);

if (move_0 != "moonblast" || move_1 != "mystical-fire" || move_2 != "psychic" || move_3 != "misty-terrain"){
stream.log("Lead Pokemon's moves are wrong. They are supposed to be: Moonblast, Mystical Fire, Psychic, Misty Terrain.");
OperationFailedException::fire(
ErrorReport::SEND_ERROR_REPORT,
"We expect your lead Pokemon to be a Gardevoir with moves in this order: Moonblast, Mystical Fire, Psychic, Misty Terrain. "
"But we see something else instead. If you confirm that your lead Gardevoir does indeed have these moves in this order, "
"and are still getting this error, you can uncheck 'Pre-check: Ensure correct moves', under Advanced mode.\n" + language_warning(language),
stream
);
}

press_Bs_to_back_to_overworld(info, stream, context);

}

void change_settings_prior_to_autostory_segment_mode(SingleSwitchProgramEnvironment& env, ProControllerContext& context, size_t current_segment_num, Language language){
// get index of `Options` in the Main Menu, which depends on where you are in Autostory
int8_t options_index;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ enum class ClearDialogMode{
STOP_WHITEBUTTON,
STOP_TIMEOUT,
STOP_BATTLE,
STOP_TUTORIAL,
};


Expand Down Expand Up @@ -174,6 +175,10 @@ void config_option(ProControllerContext& context, int change_option_value);
// enter menu and swap the first and third moves for your starter
void swap_starter_moves(SingleSwitchProgramEnvironment& env, ProControllerContext& context, Language language);

// confirm the moves for the Lead pokemon: Moonblast, Mystical Fire, Psychic, Misty Terrain
// start and end in the overworld
void confirm_lead_pokemon_moves(SingleSwitchProgramEnvironment& env, ProControllerContext& context, Language language);

// run the given `action`. if detect a battle, stop the action, and throw exception
void do_action_and_monitor_for_battles(
const ProgramInfo& info,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,10 +211,11 @@ void checkpoint_18(
pbf_mash_button(context, BUTTON_A, 6 * TICKS_PER_SECOND);

env.console.log("Talk to Clavell in his office, and the professor.");
clear_dialog(env.console, context, ClearDialogMode::STOP_TIMEOUT, 25,
{CallbackEnum::PROMPT_DIALOG}); // max time between dialog: 17s. set timeout to 25 seconds for buffer.
// mash A to get through the Random A press that you need. when the professor shows you area zero.
pbf_mash_button(context, BUTTON_A, 3 * TICKS_PER_SECOND);
// clear_dialog(env.console, context, ClearDialogMode::STOP_TIMEOUT, 25,
// {CallbackEnum::PROMPT_DIALOG}); // max time between dialog: 17s. set timeout to 25 seconds for buffer.
// // mash A to get through the Random A press that you need. when the professor shows you area zero.
// pbf_mash_button(context, BUTTON_A, 3 * TICKS_PER_SECOND);

clear_dialog(env.console, context, ClearDialogMode::STOP_OVERWORLD, 60,
{CallbackEnum::OVERWORLD, CallbackEnum::PROMPT_DIALOG});

Expand Down Expand Up @@ -279,11 +280,14 @@ void checkpoint_20(
walk_forward_until_dialog(env.program_info(), env.console, context, NavigationMovementMode::DIRECTIONAL_ONLY, 60, 128, 0);

env.console.log("Talk to Nemona, Arven, Cassiopeia.");
clear_dialog(env.console, context, ClearDialogMode::STOP_TIMEOUT, 16,
{CallbackEnum::PROMPT_DIALOG, CallbackEnum::BLACK_DIALOG_BOX}); // max time between dialog: 11
// clear_dialog(env.console, context, ClearDialogMode::STOP_TIMEOUT, 16,
// {CallbackEnum::PROMPT_DIALOG, CallbackEnum::BLACK_DIALOG_BOX}); // max time between dialog: 11

// mash A to get through the Random A press that you need. when the Nemona shows you a Poke Gym.
pbf_mash_button(context, BUTTON_A, 250);
// // mash A to get through the Random A press that you need. when the Nemona shows you a Poke Gym.
// pbf_mash_button(context, BUTTON_A, 250);

clear_dialog(env.console, context, ClearDialogMode::STOP_TUTORIAL, 20,
{CallbackEnum::TUTORIAL, CallbackEnum::PROMPT_DIALOG, CallbackEnum::BLACK_DIALOG_BOX});

clear_dialog(env.console, context, ClearDialogMode::STOP_TIMEOUT, 10,
{CallbackEnum::TUTORIAL}); // max time between dialog: 3
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,8 @@ void checkpoint_62(

env.console.log("Battle Normal Gym leader.");
run_trainer_battle_press_A(env.console, context, BattleStopCondition::STOP_DIALOG);
clear_dialog(env.console, context, ClearDialogMode::STOP_TIMEOUT, 60);
pbf_mash_button(context, BUTTON_A, 1000ms);
// clear_dialog(env.console, context, ClearDialogMode::STOP_TIMEOUT, 60);
// pbf_mash_button(context, BUTTON_A, 1000ms);

env.console.log("Finish up with Larry, then speak to Geeta and Nemona.");
clear_dialog(env.console, context, ClearDialogMode::STOP_BATTLE, 60, {CallbackEnum::WHITE_A_BUTTON, CallbackEnum::PROMPT_DIALOG, CallbackEnum::BATTLE, CallbackEnum:: DIALOG_ARROW});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ 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 move2{SinglesMoveType::Move2, false}; // Mystical Fire
SinglesMoveEntry move4{SinglesMoveType::Move4, false}; // Misty Terrain
std::vector<SinglesMoveEntry> move_table1 = {move1, move4, move1};
bool terastallized = false;
Expand Down Expand Up @@ -366,8 +366,8 @@ void checkpoint_88(SingleSwitchProgramEnvironment& env, ProControllerContext& co
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<SinglesMoveEntry> move_table2 = {move3};
env.console.log("Battle Elite Four 2."); // select move 2, which should be a fire move. to battle the steel trainer
std::vector<SinglesMoveEntry> move_table2 = {move2};
is_won = run_pokemon(env.console, context, move_table2, true, terastallized);
if (!is_won){// throw exception if we lose
OperationFailedException::fire(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ void checkpoint_91(SingleSwitchProgramEnvironment& env, ProControllerContext& co
if (!is_won){// throw exception if we lose
OperationFailedException::fire(
ErrorReport::SEND_ERROR_REPORT,
"Failed to beat the Ground trainer. Reset.",
"Failed to beat the Penny. Reset.",
env.console
);
}
Expand Down