Skip to content

Commit c491c50

Browse files
authored
Autostory: Finish the main story. Some bugfixes: fixed clear_dialog(), added recovery routine when minimap Pokemon block the DirectionDetector. (#886)
* checkpoint_104: defeat AI professor * fix mash_button_till_overworld() * comment out unused checkpoints * convert ticks to seconds * update checkpoint 29: navigation routine from Cortondo West Pokecenter to West Province Area One Central Pokecenter * another fix for mash_button_till_overworld() * update checkpoint 61: add routine to clear minimap pokemon. * revert change to clear_dialog(... STOP_TIMEOUT ...) in segment 9 * update clear_dialog(): mash_A is done at a lower frequency. * revert change to clear_dialog(... STOP_TIMEOUT ...) in segment 26 * more updates to clear_dialog * final checkpoint: handle Koraidon/Miraidon form change tutorial * confirm able to detect direction. * update note on Gardevoir
1 parent 371e591 commit c491c50

29 files changed

+557
-103
lines changed

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

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ std::vector<std::unique_ptr<AutoStory_Segment>> make_autoStory_segment_list(){
135135
segment_list.emplace_back(std::make_unique<AutoStory_Segment_37>());
136136
segment_list.emplace_back(std::make_unique<AutoStory_Segment_38>());
137137
segment_list.emplace_back(std::make_unique<AutoStory_Segment_39>());
138-
// segment_list.emplace_back(std::make_unique<AutoStory_Segment_40>());
138+
segment_list.emplace_back(std::make_unique<AutoStory_Segment_40>());
139139
}
140140
return segment_list;
141141
};
@@ -311,7 +311,7 @@ std::vector<std::unique_ptr<AutoStory_Checkpoint>> make_autoStory_checkpoint_lis
311311
checkpoint_list.emplace_back(std::make_unique<AutoStory_Checkpoint_101>());
312312
checkpoint_list.emplace_back(std::make_unique<AutoStory_Checkpoint_102>());
313313
checkpoint_list.emplace_back(std::make_unique<AutoStory_Checkpoint_103>());
314-
// checkpoint_list.emplace_back(std::make_unique<AutoStory_Checkpoint_104>());
314+
checkpoint_list.emplace_back(std::make_unique<AutoStory_Checkpoint_104>());
315315
// checkpoint_list.emplace_back(std::make_unique<AutoStory_Checkpoint_105>());
316316

317317
}
@@ -479,8 +479,9 @@ AutoStory::AutoStory()
479479
}
480480
, MAINSTORY_NOTE{
481481
"Ensure you have a level 100 Gardevoir with the moves in the following order: Moonblast, Mystical Fire, Psychic, Misty Terrain."
482-
"Ensure PP is maxed out. Ensure Modest nature with max Special Attack and Speed EVs, with max IVs.<br>"
483-
"Also, make sure you have two other strong pokemon (e.g. level 100 Talonflames)<br>"
482+
"Ensure PP is maxed out (Moonblast should have 24 PP). Ensure Modest nature with max Special Attack and Speed EVs, with max IVs. "
483+
"After vitamins, mint and hypertraining, the stats should be as follows: HP 277, Attack [doesn't matter], Defense 167, Speed 259, Sp. Def 266, Sp. Atk 383.<br>"
484+
"Also, make sure you have two other strong pokemon (e.g. level 100 Talonflames), ideally with a strong first move (e.g. Acrobatics for Talonflame).<br>"
484485
"Refer to the documentation on github for more details."
485486
}
486487
, START_DESCRIPTION(
@@ -1053,7 +1054,7 @@ void AutoStory::test_checkpoints(
10531054
checkpoint_list.push_back([&](){checkpoint_101(env, context, notif_status_update, stats);});
10541055
checkpoint_list.push_back([&](){checkpoint_102(env, context, notif_status_update, stats);});
10551056
checkpoint_list.push_back([&](){checkpoint_103(env, context, notif_status_update, stats);});
1056-
// checkpoint_list.push_back([&](){checkpoint_104(env, context, notif_status_update, stats);});
1057+
checkpoint_list.push_back([&](){checkpoint_104(env, context, notif_status_update, stats);});
10571058
// checkpoint_list.push_back([&](){checkpoint_105(env, context, notif_status_update, stats);});
10581059

10591060

@@ -1303,7 +1304,7 @@ void AutoStory::test_code(SingleSwitchProgramEnvironment& env, ProControllerCont
13031304
// move_camera_yolo(env, context, CameraAxis::Y, yolo_detector, "tree-tera", 0.294444);
13041305
// move_camera_yolo(env, context, CameraAxis::X, yolo_detector, "tree-tera", 0.604688);
13051306

1306-
1307+
13071308

13081309
return;
13091310
}

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

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ void clear_tutorial(VideoStream& stream, ProControllerContext& context, uint16_t
7979

8080
void clear_dialog(VideoStream& stream, ProControllerContext& context,
8181
ClearDialogMode mode, uint16_t seconds_timeout,
82-
std::vector<CallbackEnum> enum_optional_callbacks
82+
std::vector<CallbackEnum> enum_optional_callbacks,
83+
bool press_A
8384
){
8485
bool seen_dialog = false;
8586
WallClock start = current_time();
@@ -148,12 +149,12 @@ void clear_dialog(VideoStream& stream, ProControllerContext& context,
148149
stream, context,
149150
[&](ProControllerContext& context){
150151

151-
if (mode == ClearDialogMode::STOP_TIMEOUT){
152+
if (mode == ClearDialogMode::STOP_TIMEOUT || !press_A){
152153
context.wait_for(Seconds(seconds_timeout));
153-
}else{ // press A every 8 seconds, until we time out.
154-
auto button_press_period = Seconds(8);
154+
}else{ // press A every 25 seconds, until we time out.
155+
auto button_press_period = Seconds(25);
155156
while (true){
156-
if (current_time() - start_inference + button_press_period > Seconds(seconds_timeout)){
157+
if (current_time() - start_inference > Seconds(seconds_timeout)){
157158
break;
158159
}
159160
context.wait_for(button_press_period);
@@ -208,6 +209,9 @@ void clear_dialog(VideoStream& stream, ProControllerContext& context,
208209
case CallbackEnum::DIALOG_ARROW:
209210
stream.log("clear_dialog: Detected dialog arrow.");
210211
seen_dialog = true;
212+
if (mode == ClearDialogMode::STOP_BATTLE_DIALOG_ARROW){
213+
return;
214+
}
211215
pbf_press_button(context, BUTTON_A, 20, 105);
212216
break;
213217
case CallbackEnum::BATTLE:
@@ -358,9 +362,9 @@ void overworld_navigation(
358362
if (movement_mode == NavigationMovementMode::CLEAR_WITH_LETS_GO){
359363
walk_forward_while_clear_front_path(info, stream, context, forward_ticks, y);
360364
}else{
361-
ssf_press_left_joystick(context, x, y, 0, seconds_realign * TICKS_PER_SECOND);
365+
ssf_press_left_joystick(context, x, y, 0ms, Seconds(seconds_realign));
362366
if (movement_mode == NavigationMovementMode::DIRECTIONAL_ONLY){
363-
pbf_wait(context, seconds_realign * TICKS_PER_SECOND);
367+
pbf_wait(context, Seconds(seconds_realign));
364368
} else if (movement_mode == NavigationMovementMode::DIRECTIONAL_SPAM_A){
365369
for (size_t j = 0; j < 5 * seconds_realign; j++){
366370
pbf_press_button(context, BUTTON_A, 20, 5);
@@ -1059,9 +1063,9 @@ void press_A_until_dialog(
10591063
int ret = run_until<ProControllerContext>(
10601064
stream, context,
10611065
[seconds_between_button_presses](ProControllerContext& context){
1062-
pbf_wait(context, seconds_between_button_presses * TICKS_PER_SECOND); // avoiding pressing A if dialog already present
1066+
pbf_wait(context, Seconds(seconds_between_button_presses)); // avoiding pressing A if dialog already present
10631067
for (size_t c = 0; c < 10; c++){
1064-
pbf_press_button(context, BUTTON_A, 20, seconds_between_button_presses * TICKS_PER_SECOND);
1068+
pbf_press_button(context, BUTTON_A, 20*8ms, Seconds(seconds_between_button_presses));
10651069
}
10661070
},
10671071
{advance_dialog}

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ enum class ClearDialogMode{
4545
STOP_TIMEOUT,
4646
STOP_BATTLE,
4747
STOP_TUTORIAL,
48+
STOP_BATTLE_DIALOG_ARROW,
4849
};
4950

5051

@@ -123,9 +124,11 @@ void clear_tutorial(VideoStream& stream, ProControllerContext& context, uint16_t
123124
// stop depending on ClearDialogMode: stop when detect overworld, or dialog prompt, or A button prompt. Or if times out
124125
// throw exception if times out, unless this is the intended stop condition.
125126
// also throw exception if dialog is never detected.
127+
// NOTE: seconds_timeout is rounded up to a multiple of 25, unless press_A is false or ClearDialogMode == STOP_TIMEOUT
126128
void clear_dialog(VideoStream& stream, ProControllerContext& context,
127-
ClearDialogMode mode, uint16_t seconds_timeout = 60,
128-
std::vector<CallbackEnum> optional_callbacks = {}
129+
ClearDialogMode mode, uint16_t seconds_timeout = 75,
130+
std::vector<CallbackEnum> optional_callbacks = {},
131+
bool press_A = true
129132
);
130133

131134

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -211,10 +211,10 @@ void checkpoint_18(
211211
pbf_mash_button(context, BUTTON_A, 6 * TICKS_PER_SECOND);
212212

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

219219
clear_dialog(env.console, context, ClearDialogMode::STOP_OVERWORLD, 60,
220220
{CallbackEnum::OVERWORLD, CallbackEnum::PROMPT_DIALOG});
@@ -280,11 +280,11 @@ void checkpoint_20(
280280
walk_forward_until_dialog(env.program_info(), env.console, context, NavigationMovementMode::DIRECTIONAL_ONLY, 60, 128, 0);
281281

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

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

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

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
*
55
*/
66

7+
#include "CommonFramework/VideoPipeline/VideoFeed.h"
8+
79
#include "CommonTools/Async/InferenceRoutines.h"
810
#include "NintendoSwitch/NintendoSwitch_Settings.h"
911
#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h"
@@ -113,6 +115,13 @@ void checkpoint_24(
113115
[&](size_t attempt_number){
114116
context.wait_for_all_requests();
115117
DirectionDetector direction;
118+
VideoSnapshot snapshot = env.console.video().snapshot();
119+
double current_direction = direction.get_current_direction(env.console, snapshot);
120+
if (current_direction == -1){ // if unable to detect current direction, fly to neighbouring Pokecenter, then fly back. To hopefully clear any pokemon covering the Minimap.
121+
move_cursor_towards_flypoint_and_go_there(env.program_info(), env.console, context, {ZoomChange::KEEP_ZOOM, 0, 0, 0});
122+
move_cursor_towards_flypoint_and_go_there(env.program_info(), env.console, context, {ZoomChange::KEEP_ZOOM, 0, 0, 0});
123+
}
124+
116125
do_action_and_monitor_for_battles(env.program_info(), env.console, context,
117126
[&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){
118127
direction.change_direction(env.program_info(), env.console, context, 2.71);
@@ -188,6 +197,8 @@ void checkpoint_25(
188197

189198
// section 3
190199
DirectionDetector direction;
200+
// we just hope the minimap Direction isn't covered
201+
191202
direction.change_direction(env.program_info(), env.console, context, 6.0);
192203
pbf_move_left_joystick(context, 128, 0, 700, 100);
193204

@@ -292,6 +303,8 @@ void checkpoint_26(
292303

293304
// section 1b. realign using fence corner
294305
DirectionDetector direction;
306+
// we just hope the minimap Direction isn't covered
307+
295308
direction.change_direction(env.program_info(), env.console, context, 2.74);
296309
pbf_move_left_joystick(context, 128, 0, 200, 50);
297310
direction.change_direction(env.program_info(), env.console, context, 4.328);

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
*
55
*/
66

7+
#include "CommonFramework/VideoPipeline/VideoFeed.h"
8+
79
#include "CommonFramework/Exceptions/OperationFailedException.h"
810
#include "CommonFramework/VideoPipeline/VideoOverlay.h"
911
#include "CommonTools/Async/InferenceRoutines.h"
@@ -83,6 +85,13 @@ void checkpoint_28(
8385
[&](size_t attempt_number){
8486
context.wait_for_all_requests();
8587
DirectionDetector direction;
88+
VideoSnapshot snapshot = env.console.video().snapshot();
89+
double current_direction = direction.get_current_direction(env.console, snapshot);
90+
if (current_direction == -1){ // if unable to detect current direction, fly to neighbouring Pokecenter, then fly back. To hopefully clear any pokemon covering the Minimap.
91+
move_cursor_towards_flypoint_and_go_there(env.program_info(), env.console, context, {ZoomChange::KEEP_ZOOM, 0, 0, 0});
92+
move_cursor_towards_flypoint_and_go_there(env.program_info(), env.console, context, {ZoomChange::KEEP_ZOOM, 0, 0, 0});
93+
}
94+
8695
do_action_and_monitor_for_battles(env.program_info(), env.console, context,
8796
[&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){
8897
direction.change_direction(env.program_info(), env.console, context, 2.71);

0 commit comments

Comments
 (0)