Skip to content

Commit 5104348

Browse files
committed
Segment 11 (Olive roll) and update AutoStoryTools
1 parent e5cf988 commit 5104348

File tree

6 files changed

+852
-54
lines changed

6 files changed

+852
-54
lines changed

SerialPrograms/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1459,7 +1459,9 @@ file(GLOB MAIN_SOURCES
14591459
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_09.cpp
14601460
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_09.h
14611461
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_10.cpp
1462-
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_10.h
1462+
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_10.h
1463+
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_11.cpp
1464+
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_11.h
14631465
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp
14641466
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.h
14651467
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp

SerialPrograms/SerialPrograms.pro

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,7 @@ SOURCES += \
729729
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_08.cpp \
730730
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_09.cpp \
731731
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_10.cpp \
732+
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_11.cpp \
732733
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp \
733734
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp \
734735
Source/PokemonSV/Programs/AutoStory/PokemonSV_MenuOption.cpp \
@@ -1832,6 +1833,7 @@ HEADERS += \
18321833
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_08.h \
18331834
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_09.h \
18341835
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_10.h \
1836+
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_11.h \
18351837
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.h \
18361838
Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h \
18371839
Source/PokemonSV/Programs/AutoStory/PokemonSV_MenuOption.h \

SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp

Lines changed: 146 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,25 @@
1212
#include "CommonFramework/Notifications/ProgramNotifications.h"
1313
#include "CommonFramework/Tools/StatsTracking.h"
1414
#include "CommonFramework/ImageTools/SolidColorTest.h"
15+
#include "CommonFramework/ImageTools/ImageBoxes.h"
16+
#include "CommonFramework/ImageTools/ImageFilter.h"
17+
#include "CommonFramework/OCR/OCR_NumberReader.h"
1518
#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h"
1619
#include "NintendoSwitch/Commands/NintendoSwitch_Commands_Superscalar.h"
20+
#include "NintendoSwitch/Inference/NintendoSwitch_DateReader.h"
21+
#include "NintendoSwitch/Inference/NintendoSwitch_DetectHome.h"
22+
#include "NintendoSwitch/NintendoSwitch_Settings.h"
23+
#include "NintendoSwitch/Programs/NintendoSwitch_GameEntry.h"
1724
#include "NintendoSwitch/Programs/NintendoSwitch_SnapshotDumper.h"
1825
#include "PokemonSwSh/Inference/PokemonSwSh_IvJudgeReader.h"
26+
#include "PokemonSwSh/Commands/PokemonSwSh_Commands_DateSpam.h"
1927
#include "PokemonSV/Inference/Battles/PokemonSV_NormalBattleMenus.h"
2028
#include "PokemonSV/Inference/Dialogs/PokemonSV_DialogDetector.h"
2129
#include "PokemonSV/Inference/Overworld/PokemonSV_OverworldDetector.h"
22-
// #include "PokemonSV/Inference/Overworld/PokemonSV_StationaryOverworldWatcher.h"
30+
#include "PokemonSV/Inference/Overworld/PokemonSV_StationaryOverworldWatcher.h"
2331
#include "PokemonSV/Inference/PokemonSV_MainMenuDetector.h"
2432
#include "PokemonSV/Inference/Map/PokemonSV_MapMenuDetector.h"
33+
#include "PokemonSV/PokemonSV_Settings.h"
2534
#include "PokemonSV/Programs/PokemonSV_Navigation.h"
2635
#include "PokemonSV/Programs/PokemonSV_GameEntry.h"
2736
#include "PokemonSV/Programs/PokemonSV_SaveGame.h"
@@ -380,7 +389,7 @@ bool confirm_marker_present(
380389

381390
int ret = wait_until(
382391
console, context,
383-
std::chrono::seconds(10),
392+
std::chrono::seconds(5),
384393
{marker, battle}
385394
);
386395
switch (ret){
@@ -454,9 +463,11 @@ void overworld_navigation(
454463
}
455464
}
456465
}
466+
context.wait_for_all_requests();
457467
if (should_realign){
458468
try {
459469
realign_player(info, console, context, PlayerRealignMode::REALIGN_OLD_MARKER);
470+
460471
}catch (UnexpectedBattleException&){
461472
pbf_wait(context, 30 * TICKS_PER_SECOND); // catch exception to allow the battle callback to take over.
462473
}
@@ -479,10 +490,9 @@ void overworld_navigation(
479490
if (auto_heal){
480491
auto_heal_from_menu_or_overworld(info, console, context, 0, true);
481492
}
482-
493+
context.wait_for_all_requests();
483494
try {
484495
realign_player(info, console, context, PlayerRealignMode::REALIGN_OLD_MARKER);
485-
486496
if (!confirm_marker_present(info, console, context)){
487497
// if marker not present, don't keep walking forward.
488498
return;
@@ -682,7 +692,7 @@ void do_action_and_monitor_for_battles(
682692
{battle_menu}
683693
);
684694
if (ret == 0){ // battle detected
685-
throw OperationFailedException(
695+
throw UnexpectedBattleException(
686696
ErrorReport::SEND_ERROR_REPORT, console,
687697
"do_action_and_monitor_for_battles(): Detected battle. Failed to complete action.",
688698
true
@@ -713,52 +723,65 @@ void handle_unexpected_battles(
713723
}
714724
}
715725

716-
// void handle_when_stationary_in_overworld(
717-
// const ProgramInfo& info,
718-
// ConsoleHandle& console,
719-
// BotBaseContext& context,
720-
// std::function<
721-
// void(const ProgramInfo& info,
722-
// ConsoleHandle& console,
723-
// BotBaseContext& context)
724-
// >&& action,
725-
// std::function<
726-
// void(const ProgramInfo& info,
727-
// ConsoleHandle& console,
728-
// BotBaseContext& context)
729-
// >&& recovery_action,
730-
// size_t seconds_stationary,
731-
// uint16_t minutes_timeout
732-
// ){
733-
// StationaryOverworldWatcher stationary_overworld(COLOR_RED, {0.865, 0.82, 0.08, 0.1}, seconds_stationary);
734-
// WallClock start = current_time();
735-
// while (true){
736-
// if (current_time() - start > std::chrono::minutes(minutes_timeout)){
737-
// throw OperationFailedException(
738-
// ErrorReport::SEND_ERROR_REPORT, console,
739-
// "handle_when_stationary_in_overworld(): Failed to complete action after 5 minutes.",
740-
// true
741-
// );
742-
// }
743-
744-
// int ret = run_until(
745-
// console, context,
746-
// [&](BotBaseContext& context){
747-
// context.wait_for_all_requests();
748-
// action(info, console, context);
749-
// },
750-
// {stationary_overworld}
751-
// );
752-
// if (ret < 0){
753-
// // successfully completed action without being stuck in a position where the overworld is stationary.
754-
// return;
755-
// }else if (ret == 0){
756-
// // if stationary in overworld, run recovery action then try action again
757-
// context.wait_for_all_requests();
758-
// recovery_action(info, console, context);
759-
// }
760-
// }
761-
// }
726+
void handle_when_stationary_in_overworld(
727+
const ProgramInfo& info,
728+
ConsoleHandle& console,
729+
BotBaseContext& context,
730+
std::function<
731+
void(const ProgramInfo& info,
732+
ConsoleHandle& console,
733+
BotBaseContext& context)
734+
>&& action,
735+
std::function<
736+
void(const ProgramInfo& info,
737+
ConsoleHandle& console,
738+
BotBaseContext& context)
739+
>&& recovery_action,
740+
size_t seconds_stationary,
741+
uint16_t minutes_timeout,
742+
size_t max_failures
743+
){
744+
745+
WallClock start = current_time();
746+
size_t num_failures = 0;
747+
while (true){
748+
if (current_time() - start > std::chrono::minutes(minutes_timeout)){
749+
throw OperationFailedException(
750+
ErrorReport::SEND_ERROR_REPORT, console,
751+
"handle_when_stationary_in_overworld(): Failed to complete action after " + std::to_string(minutes_timeout) + " minutes.",
752+
true
753+
);
754+
}
755+
StationaryOverworldWatcher stationary_overworld(COLOR_RED, {0.865, 0.825, 0.08, 0.1}, seconds_stationary);
756+
757+
int ret = run_until(
758+
console, context,
759+
[&](BotBaseContext& context){
760+
context.wait_for_all_requests();
761+
action(info, console, context);
762+
},
763+
{stationary_overworld}
764+
);
765+
if (ret < 0){
766+
// successfully completed action without being stuck in a position where the overworld is stationary.
767+
return;
768+
}else if (ret == 0){
769+
// if stationary in overworld, run recovery action then try action again
770+
console.log("Detected stationary overworld.");
771+
num_failures++;
772+
if (num_failures > max_failures){
773+
throw OperationFailedException(
774+
ErrorReport::SEND_ERROR_REPORT, console,
775+
"handle_when_stationary_in_overworld(): Failed to complete action within " + std::to_string(max_failures) + " attempts.",
776+
true
777+
);
778+
}
779+
context.wait_for_all_requests();
780+
recovery_action(info, console, context);
781+
}
782+
}
783+
}
784+
762785

763786
void wait_for_gradient_arrow(
764787
const ProgramInfo& info,
@@ -860,6 +883,8 @@ bool check_ride_active(const ProgramInfo& info, ConsoleHandle& console, BotBaseC
860883
}
861884

862885
void get_on_ride(const ProgramInfo& info, ConsoleHandle& console, BotBaseContext& context){
886+
pbf_press_button(context, BUTTON_PLUS, 20, 20);
887+
863888
WallClock start = current_time();
864889
while (!check_ride_active(info, console, context)){
865890
if (current_time() - start > std::chrono::minutes(3)){
@@ -1065,6 +1090,76 @@ void move_cursor_towards_flypoint_and_go_there(
10651090
}
10661091

10671092

1093+
1094+
void change_date(
1095+
SingleSwitchProgramEnvironment& env, BotBaseContext& context,
1096+
const DateTime& date
1097+
){
1098+
while (true){
1099+
context.wait_for_all_requests();
1100+
1101+
HomeWatcher home;
1102+
DateChangeWatcher date_reader;
1103+
int ret = wait_until(
1104+
env.console, context, std::chrono::seconds(120),
1105+
{
1106+
home,
1107+
date_reader
1108+
}
1109+
);
1110+
switch (ret){
1111+
case 0:
1112+
home_to_date_time(context, true, false);
1113+
pbf_press_button(context, BUTTON_A, 10, 30);
1114+
context.wait_for_all_requests();
1115+
continue;
1116+
case 1:{
1117+
env.log("Detected date change.");
1118+
1119+
// Set the date
1120+
VideoOverlaySet overlays(env.console.overlay());
1121+
date_reader.make_overlays(overlays);
1122+
date_reader.set_date(env.program_info(), env.console, context, date);
1123+
1124+
// Commit the date.
1125+
pbf_press_button(context, BUTTON_A, 20, 30);
1126+
1127+
// Re-enter the game.
1128+
pbf_press_button(context, BUTTON_HOME, 20, ConsoleSettings::instance().SETTINGS_TO_HOME_DELAY);
1129+
1130+
return;
1131+
}
1132+
default:
1133+
throw OperationFailedException(
1134+
ErrorReport::SEND_ERROR_REPORT,
1135+
env.logger(),
1136+
"Failed to set date"
1137+
);
1138+
}
1139+
}
1140+
}
1141+
1142+
void check_num_sunflora_found(SingleSwitchProgramEnvironment& env, BotBaseContext& context, int expected_number){
1143+
context.wait_for_all_requests();
1144+
VideoSnapshot screen = env.console.video().snapshot();
1145+
ImageFloatBox num_sunflora_box = {0.27, 0.02, 0.04, 0.055};
1146+
int number = OCR::read_number_waterfill(env.console, extract_box_reference(screen, num_sunflora_box), 0xff000000, 0xff808080);
1147+
1148+
if (number != expected_number){
1149+
throw OperationFailedException(
1150+
ErrorReport::SEND_ERROR_REPORT,
1151+
env.logger(),
1152+
"The number of sunflora found is different than expected."
1153+
);
1154+
}else{
1155+
env.console.log("Number of sunflora found: " + std::to_string(number));
1156+
}
1157+
1158+
1159+
}
1160+
1161+
1162+
10681163
}
10691164
}
10701165
}

SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#ifndef PokemonAutomation_PokemonSV_AutoStoryTools_H
88
#define PokemonAutomation_PokemonSV_AutoStoryTools_H
99

10+
#include "Common/Cpp/DateTime.h"
1011
#include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h"
1112
#include "CommonFramework/Tools/StatsTracking.h"
1213
#include "CommonFramework/Language.h"
@@ -191,6 +192,8 @@ void handle_unexpected_battles(
191192
// if stationary in overworld for an amount of time (seconds_stationary), run `recovery_action` then try `action` again
192193
// return once successfully completed `action`
193194
// throw exception if fails to complete `action` within a certain amount of time (minutes_timeout).
195+
// NOTE: if using this function to wrap overworld_navigation(), keep in mind that
196+
// 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.
194197
void handle_when_stationary_in_overworld(
195198
const ProgramInfo& info,
196199
ConsoleHandle& console,
@@ -205,8 +208,9 @@ void handle_when_stationary_in_overworld(
205208
ConsoleHandle& console,
206209
BotBaseContext& context)
207210
>&& recovery_action,
208-
size_t seconds_stationary = 5,
209-
uint16_t minutes_timeout = 5
211+
size_t seconds_stationary = 6,
212+
uint16_t minutes_timeout = 5,
213+
size_t max_attempts = 2
210214
);
211215

212216
void wait_for_gradient_arrow(
@@ -283,6 +287,16 @@ void move_cursor_towards_flypoint_and_go_there(
283287
MoveCursor move_cursor_near_flypoint
284288
);
285289

290+
// starting from Home screen, change the date to the desired date
291+
// then go back to the home screen
292+
void change_date(
293+
SingleSwitchProgramEnvironment& env,
294+
BotBaseContext& context,
295+
const DateTime& date
296+
);
297+
298+
void check_num_sunflora_found(SingleSwitchProgramEnvironment& env, BotBaseContext& context, int expected_number);
299+
286300
}
287301
}
288302
}

0 commit comments

Comments
 (0)