Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segment 11 (Olive roll) and update AutoStoryTools #510

Merged
merged 2 commits into from
Nov 16, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 3 additions & 1 deletion SerialPrograms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1459,7 +1459,9 @@ file(GLOB MAIN_SOURCES
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_09.cpp
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_09.h
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_10.cpp
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_10.h
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_10.h
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_11.cpp
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_11.h
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.h
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp
Expand Down
2 changes: 2 additions & 0 deletions SerialPrograms/SerialPrograms.pro
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,7 @@ SOURCES += \
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_08.cpp \
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_09.cpp \
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_10.cpp \
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_11.cpp \
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp \
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp \
Source/PokemonSV/Programs/AutoStory/PokemonSV_MenuOption.cpp \
Expand Down Expand Up @@ -1832,6 +1833,7 @@ HEADERS += \
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_08.h \
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_09.h \
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_10.h \
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_11.h \
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.h \
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h \
Source/PokemonSV/Programs/AutoStory/PokemonSV_MenuOption.h \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,25 @@
#include "CommonFramework/Notifications/ProgramNotifications.h"
#include "CommonFramework/Tools/StatsTracking.h"
#include "CommonFramework/ImageTools/SolidColorTest.h"
#include "CommonFramework/ImageTools/ImageBoxes.h"
#include "CommonFramework/ImageTools/ImageFilter.h"
#include "CommonFramework/OCR/OCR_NumberReader.h"
#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h"
#include "NintendoSwitch/Commands/NintendoSwitch_Commands_Superscalar.h"
#include "NintendoSwitch/Inference/NintendoSwitch_DateReader.h"
#include "NintendoSwitch/Inference/NintendoSwitch_DetectHome.h"
#include "NintendoSwitch/NintendoSwitch_Settings.h"
#include "NintendoSwitch/Programs/NintendoSwitch_GameEntry.h"
#include "NintendoSwitch/Programs/NintendoSwitch_SnapshotDumper.h"
#include "PokemonSwSh/Inference/PokemonSwSh_IvJudgeReader.h"
#include "PokemonSwSh/Commands/PokemonSwSh_Commands_DateSpam.h"
#include "PokemonSV/Inference/Battles/PokemonSV_NormalBattleMenus.h"
#include "PokemonSV/Inference/Dialogs/PokemonSV_DialogDetector.h"
#include "PokemonSV/Inference/Overworld/PokemonSV_OverworldDetector.h"
// #include "PokemonSV/Inference/Overworld/PokemonSV_StationaryOverworldWatcher.h"
#include "PokemonSV/Inference/Overworld/PokemonSV_StationaryOverworldWatcher.h"
#include "PokemonSV/Inference/PokemonSV_MainMenuDetector.h"
#include "PokemonSV/Inference/Map/PokemonSV_MapMenuDetector.h"
#include "PokemonSV/PokemonSV_Settings.h"
#include "PokemonSV/Programs/PokemonSV_Navigation.h"
#include "PokemonSV/Programs/PokemonSV_GameEntry.h"
#include "PokemonSV/Programs/PokemonSV_SaveGame.h"
Expand Down Expand Up @@ -380,7 +389,7 @@ bool confirm_marker_present(

int ret = wait_until(
console, context,
std::chrono::seconds(10),
std::chrono::seconds(5),
{marker, battle}
);
switch (ret){
Expand Down Expand Up @@ -454,9 +463,11 @@ void overworld_navigation(
}
}
}
context.wait_for_all_requests();
if (should_realign){
try {
realign_player(info, console, context, PlayerRealignMode::REALIGN_OLD_MARKER);

}catch (UnexpectedBattleException&){
pbf_wait(context, 30 * TICKS_PER_SECOND); // catch exception to allow the battle callback to take over.
}
Expand All @@ -479,10 +490,9 @@ void overworld_navigation(
if (auto_heal){
auto_heal_from_menu_or_overworld(info, console, context, 0, true);
}

context.wait_for_all_requests();
try {
realign_player(info, console, context, PlayerRealignMode::REALIGN_OLD_MARKER);

if (!confirm_marker_present(info, console, context)){
// if marker not present, don't keep walking forward.
return;
Expand Down Expand Up @@ -682,7 +692,7 @@ void do_action_and_monitor_for_battles(
{battle_menu}
);
if (ret == 0){ // battle detected
throw OperationFailedException(
throw UnexpectedBattleException(
ErrorReport::SEND_ERROR_REPORT, console,
"do_action_and_monitor_for_battles(): Detected battle. Failed to complete action.",
true
Expand Down Expand Up @@ -713,52 +723,65 @@ void handle_unexpected_battles(
}
}

// void handle_when_stationary_in_overworld(
// const ProgramInfo& info,
// ConsoleHandle& console,
// BotBaseContext& context,
// std::function<
// void(const ProgramInfo& info,
// ConsoleHandle& console,
// BotBaseContext& context)
// >&& action,
// std::function<
// void(const ProgramInfo& info,
// ConsoleHandle& console,
// BotBaseContext& context)
// >&& recovery_action,
// size_t seconds_stationary,
// uint16_t minutes_timeout
// ){
// StationaryOverworldWatcher stationary_overworld(COLOR_RED, {0.865, 0.82, 0.08, 0.1}, seconds_stationary);
// WallClock start = current_time();
// while (true){
// if (current_time() - start > std::chrono::minutes(minutes_timeout)){
// throw OperationFailedException(
// ErrorReport::SEND_ERROR_REPORT, console,
// "handle_when_stationary_in_overworld(): Failed to complete action after 5 minutes.",
// true
// );
// }

// int ret = run_until(
// console, context,
// [&](BotBaseContext& context){
// context.wait_for_all_requests();
// action(info, console, context);
// },
// {stationary_overworld}
// );
// if (ret < 0){
// // successfully completed action without being stuck in a position where the overworld is stationary.
// return;
// }else if (ret == 0){
// // if stationary in overworld, run recovery action then try action again
// context.wait_for_all_requests();
// recovery_action(info, console, context);
// }
// }
// }
void handle_when_stationary_in_overworld(
const ProgramInfo& info,
ConsoleHandle& console,
BotBaseContext& context,
std::function<
void(const ProgramInfo& info,
ConsoleHandle& console,
BotBaseContext& context)
>&& action,
std::function<
void(const ProgramInfo& info,
ConsoleHandle& console,
BotBaseContext& context)
>&& recovery_action,
size_t seconds_stationary,
uint16_t minutes_timeout,
size_t max_failures
){

WallClock start = current_time();
size_t num_failures = 0;
while (true){
if (current_time() - start > std::chrono::minutes(minutes_timeout)){
throw OperationFailedException(
ErrorReport::SEND_ERROR_REPORT, console,
"handle_when_stationary_in_overworld(): Failed to complete action after " + std::to_string(minutes_timeout) + " minutes.",
true
);
}
StationaryOverworldWatcher stationary_overworld(COLOR_RED, {0.865, 0.825, 0.08, 0.1}, seconds_stationary);

int ret = run_until(
console, context,
[&](BotBaseContext& context){
context.wait_for_all_requests();
action(info, console, context);
},
{stationary_overworld}
);
if (ret < 0){
// successfully completed action without being stuck in a position where the overworld is stationary.
return;
}else if (ret == 0){
// if stationary in overworld, run recovery action then try action again
console.log("Detected stationary overworld.");
num_failures++;
if (num_failures > max_failures){
throw OperationFailedException(
ErrorReport::SEND_ERROR_REPORT, console,
"handle_when_stationary_in_overworld(): Failed to complete action within " + std::to_string(max_failures) + " attempts.",
true
);
}
context.wait_for_all_requests();
recovery_action(info, console, context);
}
}
}


void wait_for_gradient_arrow(
const ProgramInfo& info,
Expand Down Expand Up @@ -860,6 +883,8 @@ bool check_ride_active(const ProgramInfo& info, ConsoleHandle& console, BotBaseC
}

void get_on_ride(const ProgramInfo& info, ConsoleHandle& console, BotBaseContext& context){
pbf_press_button(context, BUTTON_PLUS, 20, 20);

WallClock start = current_time();
while (!check_ride_active(info, console, context)){
if (current_time() - start > std::chrono::minutes(3)){
Expand Down Expand Up @@ -1065,6 +1090,76 @@ void move_cursor_towards_flypoint_and_go_there(
}



void change_date(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function looked familiar. Then I realized the ItemPrinterRNG does something different since it needs to keep track of when it commits.

Let's move this function into somewhere in NintendoSwitch/ since I feel like a lot of things can use it.

SingleSwitchProgramEnvironment& env, BotBaseContext& context,
const DateTime& date
){
while (true){
context.wait_for_all_requests();

HomeWatcher home;
DateChangeWatcher date_reader;
int ret = wait_until(
env.console, context, std::chrono::seconds(120),
{
home,
date_reader
}
);
switch (ret){
case 0:
home_to_date_time(context, true, false);
pbf_press_button(context, BUTTON_A, 10, 30);
context.wait_for_all_requests();
continue;
case 1:{
env.log("Detected date change.");

// Set the date
VideoOverlaySet overlays(env.console.overlay());
date_reader.make_overlays(overlays);
date_reader.set_date(env.program_info(), env.console, context, date);

// Commit the date.
pbf_press_button(context, BUTTON_A, 20, 30);

// Re-enter the game.
pbf_press_button(context, BUTTON_HOME, 20, ConsoleSettings::instance().SETTINGS_TO_HOME_DELAY);

return;
}
default:
throw OperationFailedException(
ErrorReport::SEND_ERROR_REPORT,
env.logger(),
"Failed to set date"
);
}
}
}

void check_num_sunflora_found(SingleSwitchProgramEnvironment& env, BotBaseContext& context, int expected_number){
context.wait_for_all_requests();
VideoSnapshot screen = env.console.video().snapshot();
ImageFloatBox num_sunflora_box = {0.27, 0.02, 0.04, 0.055};
int number = OCR::read_number_waterfill(env.console, extract_box_reference(screen, num_sunflora_box), 0xff000000, 0xff808080);

if (number != expected_number){
throw OperationFailedException(
ErrorReport::SEND_ERROR_REPORT,
env.logger(),
"The number of sunflora found is different than expected."
);
}else{
env.console.log("Number of sunflora found: " + std::to_string(number));
}


}



}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#ifndef PokemonAutomation_PokemonSV_AutoStoryTools_H
#define PokemonAutomation_PokemonSV_AutoStoryTools_H

#include "Common/Cpp/DateTime.h"
#include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h"
#include "CommonFramework/Tools/StatsTracking.h"
#include "CommonFramework/Language.h"
Expand Down Expand Up @@ -191,6 +192,8 @@ void handle_unexpected_battles(
// 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).
// NOTE: if using this function to wrap overworld_navigation(), keep in mind that
// confirm_marker_present() will keep the player still for 5 seconds before moving. Therefore, seconds_stationary should be greater than 5 seconds in this case.
void handle_when_stationary_in_overworld(
const ProgramInfo& info,
ConsoleHandle& console,
Expand All @@ -205,8 +208,9 @@ void handle_when_stationary_in_overworld(
ConsoleHandle& console,
BotBaseContext& context)
>&& recovery_action,
size_t seconds_stationary = 5,
uint16_t minutes_timeout = 5
size_t seconds_stationary = 6,
uint16_t minutes_timeout = 5,
size_t max_attempts = 2
);

void wait_for_gradient_arrow(
Expand Down Expand Up @@ -283,6 +287,16 @@ void move_cursor_towards_flypoint_and_go_there(
MoveCursor move_cursor_near_flypoint
);

// starting from Home screen, change the date to the desired date
// then go back to the home screen
void change_date(
SingleSwitchProgramEnvironment& env,
BotBaseContext& context,
const DateTime& date
);

void check_num_sunflora_found(SingleSwitchProgramEnvironment& env, BotBaseContext& context, int expected_number);

}
}
}
Expand Down
Loading
Loading