From 9a8603bf923affbb79d17b2637c46133070587e7 Mon Sep 17 00:00:00 2001 From: jw098 Date: Sat, 20 Sep 2025 00:10:49 -0700 Subject: [PATCH 01/10] adjust checkpoint 54 for Switch 2 --- .../PokemonSV_AutoStory_Segment_23.cpp | 834 ++++++++++++------ 1 file changed, 571 insertions(+), 263 deletions(-) diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_23.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_23.cpp index b78efb9911..f755aa3134 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_23.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_23.cpp @@ -9,6 +9,7 @@ #include "CommonFramework/Exceptions/OperationFailedException.h" #include "CommonTools/Async/InferenceRoutines.h" #include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" +#include "NintendoSwitch/Inference/NintendoSwitch_ConsoleTypeDetector.h" #include "PokemonSV/Programs/PokemonSV_GameEntry.h" #include "PokemonSV/Programs/PokemonSV_SaveGame.h" #include "PokemonSV/Programs/PokemonSV_MenuNavigation.h" @@ -59,6 +60,556 @@ void AutoStory_Segment_23::run_segment( context.wait_for_all_requests(); env.console.log("End Segment " + name(), COLOR_GREEN); +} + +void checkpoint_54_switch1(SingleSwitchProgramEnvironment& env, ProControllerContext& context){ + DirectionDetector direction; + direction.change_direction(env.program_info(), env.console, context, 1.341); + pbf_move_left_joystick(context, 128, 0, 450, 100); + + // marker 1 + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_NEW_MARKER, 160, 0, 35); + + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 24, 8, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 2 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 0, 0, 0}, + {ZoomChange::ZOOM_IN, 200, 0, 80} + ); + + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 40, 10, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 3 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 0, 0, 0}, + {ZoomChange::ZOOM_IN, 190, 0, 115} + ); + + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 24, 8, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 4 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 128, 255, 50}, + {ZoomChange::ZOOM_IN, 150, 0, 112} + ); + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 20, 10, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 5 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 128, 255, 50}, + {ZoomChange::ZOOM_IN, 135, 0, 107} + ); + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 16, 8, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 6 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 128, 255, 50}, + {ZoomChange::ZOOM_IN, 120, 0, 95} + ); + + // walk forward until dialog + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_DIALOG, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 16, 8, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 255, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + mash_button_till_overworld(env.console, context, BUTTON_A); + + // resume marker 6 + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 16, 8, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 255, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 7 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 128, 255, 50}, + {ZoomChange::ZOOM_IN, 110, 0, 55} + ); + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 20, 10, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 255, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 8 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 0, 0, 0}, + {ZoomChange::ZOOM_IN, 0, 50, 60} + ); + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 30, 10, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 9. at crossroads + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 0, 0, 0}, + {ZoomChange::ZOOM_IN, 0, 110, 115} + ); + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 40, 10, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 10 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 0, 0, 0}, + {ZoomChange::ZOOM_IN, 0, 80, 125} + ); + + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 10, 10, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 11 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 255, 128, 50}, + {ZoomChange::ZOOM_IN, 0, 85, 135} + ); + + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 24, 8, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 255, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 12 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 255, 128, 50}, + {ZoomChange::ZOOM_IN, 0, 70, 140} + ); + + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 24, 8, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 255, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 13 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 255, 128, 50}, + {ZoomChange::ZOOM_IN, 0, 45, 130} + ); + + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 20, 10, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 255, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + fly_to_overlapping_flypoint(env.program_info(), env.console, context); + +} + +void checkpoint_54_switch2(SingleSwitchProgramEnvironment& env, ProControllerContext& context){ + + DirectionDetector direction; + direction.change_direction(env.program_info(), env.console, context, 1.341); + pbf_move_left_joystick(context, 128, 0, 450, 100); + + // marker 1 + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_NEW_MARKER, 160, 0, 35); + + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 24, 8, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 2 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 0, 0, 0}, + {ZoomChange::ZOOM_IN, 200, 0, 80} + ); + + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 40, 10, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 3 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 0, 0, 0}, + {ZoomChange::ZOOM_IN, 190, 0, 115} + ); + + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 24, 8, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 4 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 128, 255, 50}, + {ZoomChange::ZOOM_IN, 150, 0, 112} + ); + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 20, 10, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 5 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 128, 255, 50}, + {ZoomChange::ZOOM_IN, 135, 0, 107} + ); + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 16, 8, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 6 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 128, 255, 40}, + {ZoomChange::ZOOM_IN, 120, 0, 95} + ); + + // walk forward until dialog + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_DIALOG, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 16, 8, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 255, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + mash_button_till_overworld(env.console, context, BUTTON_A); + + // resume marker 6 + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 32, 8, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 255, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 7 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 128, 255, 50}, + {ZoomChange::ZOOM_IN, 110, 0, 55} + ); + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 20, 10, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 255, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 8 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 0, 0, 0}, + {ZoomChange::ZOOM_IN, 0, 50, 60} + ); + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 30, 10, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 9 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 0, 0, 0}, + {ZoomChange::ZOOM_IN, 0, 85, 100} + ); + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 40, 10, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 10. at crossroads + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 0, 0, 0}, + {ZoomChange::ZOOM_IN, 0, 110, 123} + ); + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 40, 10, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 11 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 0, 0, 0}, + {ZoomChange::ZOOM_IN, 0, 80, 125} + ); + + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 10, 10, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + , 6, 5, 5 + ); + + // marker 12 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 255, 128, 50}, + {ZoomChange::ZOOM_IN, 0, 85, 148} + ); + + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 24, 8, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 255, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 13 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 255, 128, 50}, + {ZoomChange::ZOOM_IN, 0, 70, 155} + ); + + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 24, 8, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 255, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 14 + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 255, 128, 50}, + {ZoomChange::ZOOM_IN, 0, 45, 137} + ); + + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 20, 10, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 255, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + fly_to_overlapping_flypoint(env.program_info(), env.console, context); + + + } void checkpoint_54( @@ -67,273 +618,30 @@ void checkpoint_54( EventNotificationOption& notif_status_update, AutoStoryStats& stats ){ + ConsoleType console_type = env.console.state().console_type(); checkpoint_reattempt_loop(env, context, notif_status_update, stats, [&](size_t attempt_number){ - - DirectionDetector direction; - direction.change_direction(env.program_info(), env.console, context, 1.341); - pbf_move_left_joystick(context, 128, 0, 450, 100); - - // marker 1 - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_NEW_MARKER, 160, 0, 35); - - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 24, 8, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 0, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 2 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 0, 0, 0}, - {ZoomChange::ZOOM_IN, 200, 0, 80} - ); - - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 40, 10, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 0, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 3 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 0, 0, 0}, - {ZoomChange::ZOOM_IN, 190, 0, 115} - ); - - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 24, 8, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 0, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 4 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 128, 255, 50}, - {ZoomChange::ZOOM_IN, 150, 0, 112} - ); - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 20, 10, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 0, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 5 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 128, 255, 50}, - {ZoomChange::ZOOM_IN, 135, 0, 107} - ); - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 16, 8, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 0, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 6 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 128, 255, 50}, - {ZoomChange::ZOOM_IN, 120, 0, 95} - ); - // walk forward until dialog - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_DIALOG, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 16, 8, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 255, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - mash_button_till_overworld(env.console, context, BUTTON_A); - - // resume marker 6 - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 16, 8, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 255, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 7 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 128, 255, 50}, - {ZoomChange::ZOOM_IN, 110, 0, 55} - ); - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 20, 10, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 255, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 8 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 0, 0, 0}, - {ZoomChange::ZOOM_IN, 0, 50, 60} - ); - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 30, 10, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 0, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 9. at crossroads - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 0, 0, 0}, - {ZoomChange::ZOOM_IN, 0, 110, 115} - ); - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 40, 10, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 0, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 10 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 0, 0, 0}, - {ZoomChange::ZOOM_IN, 0, 80, 125} - ); - - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 10, 10, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 0, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 11 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 255, 128, 50}, - {ZoomChange::ZOOM_IN, 0, 85, 135} - ); - - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 24, 8, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 255, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 12 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 255, 128, 50}, - {ZoomChange::ZOOM_IN, 0, 70, 140} - ); - - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 24, 8, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 255, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 13 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 255, 128, 50}, - {ZoomChange::ZOOM_IN, 0, 45, 130} - ); - - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 20, 10, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 255, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - fly_to_overlapping_flypoint(env.program_info(), env.console, context); - - - }); + if (console_type == ConsoleType::Unknown){ + env.console.log("Unknown Switch type. Try to detect."); + console_type = detect_console_type_from_in_game(env.console, context); + } + + if (is_switch1(console_type)){ + checkpoint_54_switch1(env, context); + }else if (is_switch2(console_type)){ + checkpoint_54_switch2(env, context); + }else{ + throw UserSetupError( + env.console, + "Please select a valid Switch console type." + ); + } + + }); + + } From 5f49e2a66d9c639fadfb7be7f53c4b10b408208f Mon Sep 17 00:00:00 2001 From: jw098 Date: Mon, 22 Sep 2025 21:49:18 -0700 Subject: [PATCH 02/10] checkpoint_55: Orthworm phase 1 --- .../AutoStory/PokemonSV_AutoStory.cpp | 2 +- .../PokemonSV_AutoStory_Segment_24.cpp | 93 ++++++++++--------- 2 files changed, 48 insertions(+), 47 deletions(-) diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp index 592df5efe8..0783ea754b 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp @@ -94,7 +94,7 @@ std::vector> make_autoStory_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()); diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_24.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_24.cpp index f55e48b3bb..f1b25acd9b 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_24.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_24.cpp @@ -3,6 +3,7 @@ * From: https://github.com/PokemonAutomation/ * */ +#include "PokemonSV/Inference/Overworld/PokemonSV_DirectionDetector.h" #include "CommonFramework/Exceptions/OperationFailedException.h" #include "CommonTools/Async/InferenceRoutines.h" @@ -28,15 +29,15 @@ namespace PokemonSV{ std::string AutoStory_Segment_24::name() const{ - return ""; + return "24: Orthworm Titan: Battle Orthworm Titan"; } std::string AutoStory_Segment_24::start_text() const{ - return "Start: "; + return "Start: At East Province (Area Three) Watchtower."; } std::string AutoStory_Segment_24::end_text() const{ - return "End: "; + return "End: Beat Orthworm Titan. At East Province (Area Three) Watchtower."; } void AutoStory_Segment_24::run_segment( @@ -52,7 +53,7 @@ void AutoStory_Segment_24::run_segment( context.wait_for_all_requests(); env.console.log("Start Segment " + name(), COLOR_ORANGE); - // checkpoint_(env, context, options.notif_status_update, stats); + checkpoint_55(env, context, options.notif_status_update, stats); context.wait_for_all_requests(); env.console.log("End Segment " + name(), COLOR_GREEN); @@ -69,66 +70,66 @@ void checkpoint_55( checkpoint_reattempt_loop(env, context, notif_status_update, stats, [&](size_t attempt_number){ - // todo: try to align to left side of tunnel. then charge at Orthworm - // reset if caught in battle. - ///////////////////// + handle_unexpected_battles(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + + DirectionDetector direction; - // get_off_ride(env.program_info(), env.console, context); + direction.change_direction(env.program_info(), env.console, context, 3.909067); + pbf_move_left_joystick(context, 128, 0, 1000, 100); - - // direction.change_direction(env.program_info(), env.console, context, 0.261); - // pbf_move_left_joystick(context, 128, 0, 500, 100); - // pbf_move_left_joystick(context, 0, 0, 500, 100); + direction.change_direction(env.program_info(), env.console, context, 5.061720); + pbf_move_left_joystick(context, 128, 0, 500, 100); + pbf_move_left_joystick(context, 255, 0, 200, 100); - // // now aligned to corner. + // now aligned to the wall next to the hole/passage - // direction.change_direction(env.program_info(), env.console, context, 3.736); - // pbf_move_left_joystick(context, 128, 0, 400, 100); + // walk away from wall slightly + pbf_move_left_joystick(context, 128, 255, 50, 100); + get_on_ride(env.program_info(), env.console, context); - // direction.change_direction(env.program_info(), env.console, context, 5.306); - // pbf_move_left_joystick(context, 128, 0, 700, 100); + direction.change_direction(env.program_info(), env.console, context, 0.366); + pbf_move_left_joystick(context, 128, 0, 250, 100); - - // direction.change_direction(env.program_info(), env.console, context, 4.988); - // pbf_move_left_joystick(context, 128, 0, 800, 100); - // pbf_move_left_joystick(context, 255, 0, 500, 100); + direction.change_direction(env.program_info(), env.console, context, 2.565); + // run at Orthworm. run into its second position as well. + pbf_move_left_joystick(context, 128, 0, 50, 0); + pbf_controller_state(context, BUTTON_LCLICK, DPAD_NONE, 128, 0, 128, 128, 500); + pbf_move_left_joystick(context, 255, 0, 300, 500); - // // now aligned to the wall next to the hole/passage + get_off_ride(env.program_info(), env.console, context); - // // walk away from wall slightly - // pbf_move_left_joystick(context, 128, 255, 50, 100); - // get_on_ride(env.program_info(), env.console, context); + direction.change_direction(env.program_info(), env.console, context, 0.261); + pbf_move_left_joystick(context, 128, 0, 500, 100); + pbf_move_left_joystick(context, 0, 0, 500, 100); - // direction.change_direction(env.program_info(), env.console, context, 0.366); - // pbf_move_left_joystick(context, 128, 0, 250, 100); + // now aligned to corner. - // direction.change_direction(env.program_info(), env.console, context, 2.565); - // // run at Orthworm. run into its second position as well. - // pbf_move_left_joystick(context, 128, 0, 50, 0); - // pbf_controller_state(context, BUTTON_LCLICK, DPAD_NONE, 128, 0, 128, 128, 500); - // pbf_move_left_joystick(context, 255, 0, 500, 500); + direction.change_direction(env.program_info(), env.console, context, 3.736); + pbf_move_left_joystick(context, 128, 0, 400, 100); - // get_off_ride(env.program_info(), env.console, context); + direction.change_direction(env.program_info(), env.console, context, 5.306); + pbf_move_left_joystick(context, 128, 0, 700, 100); - // direction.change_direction(env.program_info(), env.console, context, 0.261); - // pbf_move_left_joystick(context, 128, 0, 500, 100); - // pbf_move_left_joystick(context, 0, 0, 500, 100); + + direction.change_direction(env.program_info(), env.console, context, 4.988); + pbf_move_left_joystick(context, 128, 0, 800, 100); + pbf_move_left_joystick(context, 255, 0, 500, 100); - // // now aligned to corner. + // now aligned to the wall next to the hole/passage - // direction.change_direction(env.program_info(), env.console, context, 3.736); - // pbf_move_left_joystick(context, 128, 0, 400, 100); + // walk away from wall slightly + pbf_move_left_joystick(context, 128, 255, 100, 100); - // direction.change_direction(env.program_info(), env.console, context, 5.306); - // pbf_move_left_joystick(context, 128, 0, 700, 100); + direction.change_direction(env.program_info(), env.console, context, 5.722795); + pbf_move_left_joystick(context, 128, 0, 600, 100); - - // direction.change_direction(env.program_info(), env.console, context, 4.988); - // pbf_move_left_joystick(context, 128, 0, 800, 100); - // pbf_move_left_joystick(context, 255, 0, 500, 100); + direction.change_direction(env.program_info(), env.console, context, 0.625226); + }); - // // now aligned to the wall next to the hole/passage + walk_forward_until_dialog(env.program_info(), env.console, context, NavigationMovementMode::DIRECTIONAL_ONLY, 30); + run_wild_battle_press_A(env.console, context, BattleStopCondition::STOP_OVERWORLD); }); From 7b71ed2bfdeff4ac9d45aa66b0a09d07f99c42ce Mon Sep 17 00:00:00 2001 From: jw098 Date: Tue, 23 Sep 2025 16:18:15 -0700 Subject: [PATCH 03/10] checkpoint 56: beat Orthworm --- .../PokemonSV_AutoStory_Segment_24.cpp | 60 ++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_24.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_24.cpp index f1b25acd9b..6cf86e8fda 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_24.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_24.cpp @@ -54,6 +54,8 @@ void AutoStory_Segment_24::run_segment( env.console.log("Start Segment " + name(), COLOR_ORANGE); checkpoint_55(env, context, options.notif_status_update, stats); + checkpoint_56(env, context, options.notif_status_update, stats); + // checkpoint_57(env, context, options.notif_status_update, stats); context.wait_for_all_requests(); env.console.log("End Segment " + name(), COLOR_GREEN); @@ -70,7 +72,7 @@ void checkpoint_55( checkpoint_reattempt_loop(env, context, notif_status_update, stats, [&](size_t attempt_number){ - handle_unexpected_battles(env.program_info(), env.console, context, + do_action_and_monitor_for_battles(env.program_info(), env.console, context, [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ DirectionDetector direction; @@ -129,6 +131,7 @@ void checkpoint_55( walk_forward_until_dialog(env.program_info(), env.console, context, NavigationMovementMode::DIRECTIONAL_ONLY, 30); + env.console.log("Battle Orthworm Titan phase 1."); run_wild_battle_press_A(env.console, context, BattleStopCondition::STOP_OVERWORLD); }); @@ -144,6 +147,61 @@ void checkpoint_56( checkpoint_reattempt_loop(env, context, notif_status_update, stats, [&](size_t attempt_number){ + do_action_and_monitor_for_battles(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + + DirectionDetector direction; + + direction.change_direction(env.program_info(), env.console, context, 5.042435); + pbf_move_left_joystick(context, 128, 0, 900, 100); + + direction.change_direction(env.program_info(), env.console, context, 5.360763); + pbf_move_left_joystick(context, 128, 0, 500, 100); + + direction.change_direction(env.program_info(), env.console, context, 5.85); + pbf_move_left_joystick(context, 128, 0, 700, 100); + + direction.change_direction(env.program_info(), env.console, context, 5.428); + pbf_move_left_joystick(context, 128, 0, 600, 100); + + direction.change_direction(env.program_info(), env.console, context, 4.908646); + pbf_move_left_joystick(context, 128, 0, 300, 100); + + direction.change_direction(env.program_info(), env.console, context, 1.169728); + pbf_move_left_joystick(context, 128, 0, 200, 100); + pbf_move_left_joystick(context, 255, 0, 200, 100); + pbf_move_left_joystick(context, 0, 0, 200, 100); + + // now aligned to the wall next to the hole/passage + + // walk backwards + direction.change_direction(env.program_info(), env.console, context, 2.303077); + pbf_move_left_joystick(context, 128, 255, 400, 100); + direction.change_direction(env.program_info(), env.console, context, 3.908360); + + get_on_ride(env.program_info(), env.console, context); + + // charge at orthworm + pbf_move_left_joystick(context, 128, 0, 408ms, 0ms); + pbf_controller_state(context, BUTTON_LCLICK, DPAD_NONE, 128, 0, 128, 128, 102ms); + pbf_move_left_joystick(context, 128, 0, 1970ms, 0ms); + pbf_controller_state(context, BUTTON_NONE, DPAD_NONE, 128, 0, 0, 128, 432ms); + pbf_move_left_joystick(context, 128, 0, 1993ms, 0ms); + pbf_controller_state(context, BUTTON_NONE, DPAD_NONE, 128, 0, 0, 128, 301ms); + pbf_move_left_joystick(context, 128, 0, 307ms, 0ms); + pbf_controller_state(context, BUTTON_NONE, DPAD_NONE, 128, 0, 0, 128, 194ms); + pbf_move_left_joystick(context, 128, 0, 886ms, 0ms); + pbf_controller_state(context, BUTTON_NONE, DPAD_NONE, 128, 0, 0, 128, 626ms); + pbf_move_left_joystick(context, 128, 0, 2651ms, 0ms); + }); + + walk_forward_until_dialog(env.program_info(), env.console, context, NavigationMovementMode::DIRECTIONAL_ONLY, 30); + + // battle the titan phase 2 + clear_dialog(env.console, context, ClearDialogMode::STOP_BATTLE, 60, {CallbackEnum::BATTLE}); + env.console.log("Battle Orthworm Titan phase 2."); + run_wild_battle_press_A(env.console, context, BattleStopCondition::STOP_DIALOG, {CallbackEnum::DIALOG_ARROW}); + mash_button_till_overworld(env.console, context, BUTTON_A, 360); }); From 2f313c70697839c46eb522c3bca5722efdcc6589 Mon Sep 17 00:00:00 2001 From: jw098 Date: Tue, 23 Sep 2025 22:21:14 -0700 Subject: [PATCH 04/10] refactor AutostoryTools and Worldnavigation to avoid circular dependency. Refactor detect_closest_flypoint_and_move_map_cursor_there() so that it can detect both Pokecenters and Fast Travel points. --- .../Map/PokemonSV_FastTravelDetector.cpp | 11 +- .../Map/PokemonSV_FastTravelDetector.h | 4 +- .../AutoStory/PokemonSV_AutoStoryTools.cpp | 179 +------------- .../AutoStory/PokemonSV_AutoStoryTools.h | 60 +---- .../Programs/Eggs/PokemonSV_EggAutonomous.cpp | 1 + .../Programs/Eggs/PokemonSV_EggRoutines.cpp | 1 + .../Farming/PokemonSV_MaterialFarmerTools.cpp | 1 + .../Programs/PokemonSV_WorldNavigation.cpp | 228 +++++++++++++++++- .../Programs/PokemonSV_WorldNavigation.h | 68 +++++- 9 files changed, 302 insertions(+), 251 deletions(-) diff --git a/SerialPrograms/Source/PokemonSV/Inference/Map/PokemonSV_FastTravelDetector.cpp b/SerialPrograms/Source/PokemonSV/Inference/Map/PokemonSV_FastTravelDetector.cpp index e54dcbc86f..b226e9a1c3 100644 --- a/SerialPrograms/Source/PokemonSV/Inference/Map/PokemonSV_FastTravelDetector.cpp +++ b/SerialPrograms/Source/PokemonSV/Inference/Map/PokemonSV_FastTravelDetector.cpp @@ -122,14 +122,13 @@ void FastTravelWatcher::make_overlays(VideoOverlaySet& items) const{ } bool FastTravelWatcher::process_frame(const ImageViewRGB32& screen, WallClock timestamp){ - std::vector hits = m_detector.detect_all(screen); + m_hits = m_detector.detect_all(screen); - m_hits.reset(hits.size()); - for (const ImageFloatBox& hit : hits){ - m_hits.emplace_back(m_overlay, hit, COLOR_MAGENTA); + m_hit_boxes.reset(m_hits.size()); + for (const ImageFloatBox& hit : m_hits){ + m_hit_boxes.emplace_back(m_overlay, hit, COLOR_MAGENTA); } - - return !hits.empty(); + return !m_hits.empty(); } diff --git a/SerialPrograms/Source/PokemonSV/Inference/Map/PokemonSV_FastTravelDetector.h b/SerialPrograms/Source/PokemonSV/Inference/Map/PokemonSV_FastTravelDetector.h index 14a13d7edf..ac68e42cc8 100644 --- a/SerialPrograms/Source/PokemonSV/Inference/Map/PokemonSV_FastTravelDetector.h +++ b/SerialPrograms/Source/PokemonSV/Inference/Map/PokemonSV_FastTravelDetector.h @@ -58,11 +58,13 @@ class FastTravelWatcher : public VisualInferenceCallback{ virtual void make_overlays(VideoOverlaySet& items) const override; virtual bool process_frame(const ImageViewRGB32& frame, WallClock timestamp) override; + const std::vector& found_locations() const { return m_hits; } protected: VideoOverlay& m_overlay; FastTravelDetector m_detector; - FixedLimitVector m_hits; + std::vector m_hits; + FixedLimitVector m_hit_boxes; }; diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp index e7eadc9924..7bbafb4e30 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.cpp @@ -19,7 +19,6 @@ #include "PokemonSV/Inference/Overworld/PokemonSV_StationaryOverworldWatcher.h" #include "PokemonSV/Inference/PokemonSV_MainMenuDetector.h" #include "PokemonSV/Programs/PokemonSV_MenuNavigation.h" -#include "PokemonSV/Programs/PokemonSV_WorldNavigation.h" #include "PokemonSV/Programs/PokemonSV_GameEntry.h" #include "PokemonSV/Programs/PokemonSV_SaveGame.h" #include "PokemonSV/Programs/Battles/PokemonSV_Battles.h" @@ -41,178 +40,7 @@ namespace PokemonSV{ -// spam A button to choose the first move -// throw exception if wipeout or if your lead faints. -void run_battle_press_A( - VideoStream& stream, - ProControllerContext& context, - BattleStopCondition stop_condition, - std::unordered_set enum_optional_callbacks, - bool detect_wipeout -){ - int16_t num_times_seen_overworld = 0; - size_t consecutive_move_select = 0; - while (true){ - NormalBattleMenuWatcher battle(COLOR_BLUE); - SwapMenuWatcher fainted(COLOR_PURPLE); - OverworldWatcher overworld(stream.logger(), COLOR_CYAN); - AdvanceDialogWatcher dialog(COLOR_RED); - DialogArrowWatcher dialog_arrow(COLOR_RED, stream.overlay(), {0.850, 0.820, 0.020, 0.050}, 0.8365, 0.846); - GradientArrowWatcher next_pokemon(COLOR_BLUE, GradientArrowType::RIGHT, {0.50, 0.51, 0.30, 0.10}); - MoveSelectWatcher move_select_menu(COLOR_YELLOW); - - std::vector callbacks; - std::vector enum_all_callbacks; - // mandatory callbacks: Battle, Overworld, Advance Dialog, Swap menu, Move select - // optional callbacks: DIALOG_ARROW, NEXT_POKEMON - - // merge the mandatory and optional callbacks as a set, to avoid duplicates. then convert to vector - std::unordered_set enum_all_callbacks_set{CallbackEnum::BATTLE, CallbackEnum::OVERWORLD, CallbackEnum::ADVANCE_DIALOG, CallbackEnum::SWAP_MENU, CallbackEnum::MOVE_SELECT}; // mandatory callbacks - enum_all_callbacks_set.insert(enum_optional_callbacks.begin(), enum_optional_callbacks.end()); // append the mandatory and optional callback sets together - enum_all_callbacks.assign(enum_all_callbacks_set.begin(), enum_all_callbacks_set.end()); - - for (const CallbackEnum& enum_callback : enum_all_callbacks){ - switch(enum_callback){ - case CallbackEnum::ADVANCE_DIALOG: - callbacks.emplace_back(dialog); - break; - case CallbackEnum::OVERWORLD: - callbacks.emplace_back(overworld); - break; - case CallbackEnum::DIALOG_ARROW: - callbacks.emplace_back(dialog_arrow); - break; - case CallbackEnum::BATTLE: - callbacks.emplace_back(battle); - break; - case CallbackEnum::NEXT_POKEMON: // to detect the "next pokemon" prompt. - callbacks.emplace_back(next_pokemon); - break; - case CallbackEnum::SWAP_MENU: // detecting Swap Menu implies your lead fainted. - callbacks.emplace_back(fainted); - break; - case CallbackEnum::MOVE_SELECT: - callbacks.emplace_back(move_select_menu); - break; - default: - throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "run_battle_press_A: Unknown callback requested."); - } - } - context.wait_for_all_requests(); - - int ret = wait_until( - stream, context, - std::chrono::seconds(90), - callbacks - ); - context.wait_for(std::chrono::milliseconds(100)); - if (ret < 0){ - OperationFailedException::fire( - ErrorReport::SEND_ERROR_REPORT, - "run_battle_press_A(): Timed out. Did not detect expected stop condition.", - stream - ); - } - CallbackEnum enum_callback = enum_all_callbacks[ret]; - switch (enum_callback){ - case CallbackEnum::BATTLE: // battle - stream.log("Detected battle menu."); - consecutive_move_select = 0; - pbf_press_button(context, BUTTON_A, 20, 105); - break; - case CallbackEnum::MOVE_SELECT: - stream.log("Detected move select. Spam first move"); - consecutive_move_select++; - select_top_move(stream, context, consecutive_move_select); - break; - case CallbackEnum::OVERWORLD: // overworld - stream.log("Detected overworld, battle over."); - num_times_seen_overworld++; - if (stop_condition == BattleStopCondition::STOP_OVERWORLD){ - return; - } - if(num_times_seen_overworld > 30){ - OperationFailedException::fire( - ErrorReport::SEND_ERROR_REPORT, - "run_battle_press_A(): Stuck in overworld. Did not detect expected stop condition.", - stream - ); - } - break; - case CallbackEnum::ADVANCE_DIALOG: // advance dialog - stream.log("Detected dialog."); - - if (detect_wipeout){ - context.wait_for_all_requests(); - WipeoutDetector wipeout; - VideoSnapshot screen = stream.video().snapshot(); - // dump_snapshot(console); - if (wipeout.detect(screen)){ - OperationFailedException::fire( - ErrorReport::SEND_ERROR_REPORT, - "run_battle_press_A(): Detected wipeout. All pokemon fainted.", - stream - ); - } - } - - if (stop_condition == BattleStopCondition::STOP_DIALOG){ - return; - } - pbf_press_button(context, BUTTON_A, 20, 105); - break; - case CallbackEnum::DIALOG_ARROW: // dialog arrow - stream.log("run_battle_press_A: Detected dialog arrow."); - pbf_press_button(context, BUTTON_A, 20, 105); - break; - case CallbackEnum::NEXT_POKEMON: - stream.log("run_battle_press_A: Detected prompt for bringing in next pokemon. Keep current pokemon."); - pbf_mash_button(context, BUTTON_B, 100); - break; - case CallbackEnum::SWAP_MENU: - OperationFailedException::fire( - ErrorReport::SEND_ERROR_REPORT, - "run_battle_press_A(): Lead pokemon fainted.", - stream - ); - default: - throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "run_battle_press_A: Unknown callback triggered."); - - } - } -} - -void run_trainer_battle_press_A( - VideoStream& stream, - ProControllerContext& context, - BattleStopCondition stop_condition, - std::unordered_set enum_optional_callbacks, - bool detect_wipeout -){ - enum_optional_callbacks.insert(CallbackEnum::NEXT_POKEMON); // always check for the "Next pokemon" prompt when in trainer battles - run_battle_press_A(stream, context, stop_condition, enum_optional_callbacks, detect_wipeout); -} - -void run_wild_battle_press_A( - VideoStream& stream, - ProControllerContext& context, - BattleStopCondition stop_condition, - std::unordered_set enum_optional_callbacks, - bool detect_wipeout -){ - run_battle_press_A(stream, context, stop_condition, enum_optional_callbacks, detect_wipeout); -} - -void select_top_move(VideoStream& stream, ProControllerContext& context, size_t consecutive_move_select){ - if (consecutive_move_select > 3){ - // to handle case where move is disabled/out of PP/taunted - stream.log("Failed to select a move 3 times. Choosing a different move.", COLOR_RED); - pbf_press_dpad(context, DPAD_DOWN, 20, 40); - } - pbf_mash_button(context, BUTTON_A, 100); - -} void clear_tutorial(VideoStream& stream, ProControllerContext& context, uint16_t seconds_timeout){ bool seen_tutorial = false; @@ -1060,7 +888,7 @@ void realign_player_from_landmark( pbf_move_left_joystick(context, move_x1, move_y1, move_duration1, 1 * TICKS_PER_SECOND); // move cursor to pokecenter - if (!detect_closest_pokecenter_and_move_map_cursor_there(info, stream, context, 0.29)){ + if (!detect_closest_flypoint_and_move_map_cursor_there(info, stream, context, FlyPoint::POKECENTER, 0.29)){ OperationFailedException::fire( ErrorReport::SEND_ERROR_REPORT, "realign_player_from_landmark(): No visible pokecenter found on map.", @@ -1133,7 +961,8 @@ void move_cursor_towards_flypoint_and_go_there( const ProgramInfo& info, VideoStream& stream, ProControllerContext& context, - MoveCursor move_cursor_near_flypoint + MoveCursor move_cursor_near_flypoint, + FlyPoint fly_point ){ WallClock start = current_time(); @@ -1173,7 +1002,7 @@ void move_cursor_towards_flypoint_and_go_there( uint16_t move_duration1 = move_cursor_near_flypoint.move_duration; pbf_move_left_joystick(context, move_x1, move_y1, move_duration1, 1 * TICKS_PER_SECOND); - if (!fly_to_visible_closest_pokecenter_cur_zoom_level(info, stream, context)){ + if (!fly_to_visible_closest_flypoint_cur_zoom_level(info, stream, context, fly_point)){ OperationFailedException::fire( ErrorReport::SEND_ERROR_REPORT, "move_cursor_towards_flypoint_and_go_there(): No visible pokecenter found on map.", diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h index 6f6bc40c96..1f7d403068 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h @@ -8,11 +8,11 @@ #define PokemonAutomation_PokemonSV_AutoStoryTools_H #include -#include #include "CommonFramework/Language.h" #include "CommonFramework/ImageTools/ImageBoxes.h" #include "CommonFramework/ProgramStats/StatsTracking.h" #include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h" +#include "PokemonSV/Programs/PokemonSV_WorldNavigation.h" // #include "PokemonSV/Programs/PokemonSV_Navigation.h" namespace PokemonAutomation{ @@ -36,10 +36,6 @@ struct AutoStoryStats : public StatsTracker{ }; -enum class BattleStopCondition{ - STOP_OVERWORLD, - STOP_DIALOG, -}; enum class ClearDialogMode{ STOP_OVERWORLD, @@ -50,19 +46,7 @@ enum class ClearDialogMode{ }; -enum class CallbackEnum{ - ADVANCE_DIALOG, - OVERWORLD, - PROMPT_DIALOG, - WHITE_A_BUTTON, - DIALOG_ARROW, - BATTLE, - TUTORIAL, - BLACK_DIALOG_BOX, - NEXT_POKEMON, - SWAP_MENU, - MOVE_SELECT, -}; + enum class StartPoint{ INTRO_CUTSCENE, @@ -81,11 +65,7 @@ enum class StarterChoice{ QUAXLY, }; -enum class PlayerRealignMode{ - REALIGN_NEW_MARKER, - REALIGN_OLD_MARKER, - REALIGN_NO_MARKER, -}; + enum class NavigationStopCondition{ STOP_DIALOG, @@ -94,11 +74,7 @@ enum class NavigationStopCondition{ STOP_BATTLE, }; -enum class NavigationMovementMode{ - DIRECTIONAL_ONLY, - DIRECTIONAL_SPAM_A, - CLEAR_WITH_LETS_GO, -}; + struct AutoStoryOptions{ Language language; @@ -119,29 +95,6 @@ class AutoStory_Segment { AutoStoryStats& stats) const = 0; }; -// spam A button to choose the first move for trainer battles -// detect_wipeout: can be false if you have multiple pokemon in your party, since an exception will be thrown if your lead faints. -// throw exception if wipeout or if your lead faints. -void run_trainer_battle_press_A( - VideoStream& stream, - ProControllerContext& context, - BattleStopCondition stop_condition, - std::unordered_set enum_optional_callbacks = {}, - bool detect_wipeout = false -); - -// spam A button to choose the first move for wild battles -// detect_wipeout: can be false if you have multiple pokemon in your party, since an exception will be thrown if your lead faints. -// throw exception if wipeout or if your lead faints. -void run_wild_battle_press_A( - VideoStream& stream, - ProControllerContext& context, - BattleStopCondition stop_condition, - std::unordered_set enum_optional_callbacks = {}, - bool detect_wipeout = false -); - -void select_top_move(VideoStream& stream, ProControllerContext& context, size_t consecutive_move_select); // press A to clear tutorial screens // throw exception if tutorial screen never detected @@ -310,7 +263,7 @@ struct MoveCursor{ // place a marker on the map, not relative to the current player position, but based on a fixed landmark, such as a pokecenter // How this works: // - cursor is moved to a point near the landmark, as per `move_cursor_near_landmark` -// - move the cursor onto the landmark using `detect_closest_pokecenter_and_move_map_cursor_there`. +// - move the cursor onto the landmark using `detect_closest_flypoint_and_move_map_cursor_there`. // - confirm that the pokecenter is centered within cursor. If not, close map app, and re-try. // - cursor is moved to target location, as per `move_cursor_to_target`. A marker is placed down here. void realign_player_from_landmark( @@ -331,7 +284,8 @@ void move_cursor_towards_flypoint_and_go_there( const ProgramInfo& info, VideoStream& stream, ProControllerContext& context, - MoveCursor move_cursor_near_flypoint + MoveCursor move_cursor_near_flypoint, + FlyPoint fly_point = FlyPoint::POKECENTER ); diff --git a/SerialPrograms/Source/PokemonSV/Programs/Eggs/PokemonSV_EggAutonomous.cpp b/SerialPrograms/Source/PokemonSV/Programs/Eggs/PokemonSV_EggAutonomous.cpp index dd47a8282e..0004f9a070 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/Eggs/PokemonSV_EggAutonomous.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/Eggs/PokemonSV_EggAutonomous.cpp @@ -30,6 +30,7 @@ #include "PokemonSV/Programs/Boxes/PokemonSV_BoxRelease.h" #include "PokemonSV/Programs/Sandwiches/PokemonSV_SandwichRoutines.h" #include "PokemonSV/Programs/AutoStory/PokemonSV_MenuOption.h" +#include "PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h" #include "PokemonSV_EggAutonomous.h" namespace PokemonAutomation{ diff --git a/SerialPrograms/Source/PokemonSV/Programs/Eggs/PokemonSV_EggRoutines.cpp b/SerialPrograms/Source/PokemonSV/Programs/Eggs/PokemonSV_EggRoutines.cpp index 2717834cc1..25e74d1024 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/Eggs/PokemonSV_EggRoutines.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/Eggs/PokemonSV_EggRoutines.cpp @@ -13,6 +13,7 @@ #include "CommonTools/Async/InferenceRoutines.h" #include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" #include "NintendoSwitch/Commands/NintendoSwitch_Commands_Superscalar.h" +#include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h" #include "Pokemon/Options/Pokemon_StatsHuntFilter.h" #include "Pokemon/Pokemon_Strings.h" #include "PokemonSV/Inference/PokemonSV_WhiteButtonDetector.h" diff --git a/SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_MaterialFarmerTools.cpp b/SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_MaterialFarmerTools.cpp index fa5caa6d70..7a50b7c745 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_MaterialFarmerTools.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_MaterialFarmerTools.cpp @@ -14,6 +14,7 @@ #include "CommonFramework/Notifications/ProgramNotifications.h" #include "CommonTools/Async/InferenceRoutines.h" #include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" +#include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h" #include "PokemonSV/Inference/Boxes/PokemonSV_IvJudgeReader.h" #include "PokemonSV/Inference/Dialogs/PokemonSV_GradientArrowDetector.h" #include "PokemonSV/Inference/Overworld/PokemonSV_OverworldDetector.h" diff --git a/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.cpp b/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.cpp index 7156c3aaa1..40007be95c 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.cpp @@ -16,6 +16,7 @@ #include "PokemonSV/Inference/Map/PokemonSV_MapDetector.h" #include "PokemonSV/Inference/Map/PokemonSV_MapMenuDetector.h" #include "PokemonSV/Inference/Map/PokemonSV_MapPokeCenterIconDetector.h" +#include "PokemonSV/Inference/Map/PokemonSV_FastTravelDetector.h" #include "PokemonSV/Inference/Picnics/PokemonSV_PicnicDetector.h" #include "PokemonSV/Inference/PokemonSV_MainMenuDetector.h" #include "PokemonSV/Inference/PokemonSV_ZeroGateWarpPromptDetector.h" @@ -32,6 +33,9 @@ #include #include #include +// using std::cout; +// using std::endl; + namespace PokemonAutomation{ namespace NintendoSwitch{ namespace PokemonSV{ @@ -221,10 +225,11 @@ void leave_picnic(const ProgramInfo& info, VideoStream& stream, ProControllerCon // While in the current map zoom level, detect pokecenter icons and move the map cursor there. // Return true if succeed. Return false if no visible pokcenter on map -bool detect_closest_pokecenter_and_move_map_cursor_there( +bool detect_closest_flypoint_and_move_map_cursor_there( const ProgramInfo& info, VideoStream& stream, ProControllerContext& context, + FlyPoint fly_point, double push_scale ){ context.wait_for_all_requests(); @@ -236,21 +241,41 @@ bool detect_closest_pokecenter_and_move_map_cursor_there( double max_dist = DBL_MAX; const double center_x = 0.5 * screen_width, center_y = 0.5 * screen_height; { + int ret = -1; + std::string fly_point_string; MapPokeCenterIconWatcher pokecenter_watcher(COLOR_RED, stream.overlay(), MAP_READABLE_AREA); - int ret = wait_until(stream, context, std::chrono::seconds(2), {pokecenter_watcher}); + FastTravelWatcher fast_travel_watcher(COLOR_RED, stream.overlay(), MAP_READABLE_AREA); + const std::vector* found_locations = nullptr; + if (fly_point == FlyPoint::POKECENTER){ + fly_point_string = "Pokecenter"; + ret = wait_until(stream, context, std::chrono::seconds(2), {pokecenter_watcher}); + if (ret == 0){ + found_locations = &pokecenter_watcher.found_locations(); + } + }else if(fly_point == FlyPoint::FAST_TRAVEL){ + fly_point_string = "Fast Travel"; + ret = wait_until(stream, context, std::chrono::seconds(2), {fast_travel_watcher}); + if (ret == 0){ + found_locations = &fast_travel_watcher.found_locations(); + } + } if (ret != 0){ - stream.log("No visible pokecetner found on map"); - stream.overlay().add_log("No whole PokeCenter icon"); + stream.log("No visible " + fly_point_string + " found on map"); + stream.overlay().add_log("No whole " + fly_point_string + " icon"); return false; } + + if (found_locations == nullptr){ + throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "detect_closest_flypoint_and_move_map_cursor_there: Fly points have been found, but found_locations remains a nullptr."); + } // Find the detected PokeCenter icon closest to the screen center (where player character is on the map). - for(const auto& box: pokecenter_watcher.found_locations()){ + for(const auto& box: *found_locations){ const double loc_x = (box.x + box.width/2) * screen_width; const double loc_y = (box.y + box.height/2) * screen_height; const double x_diff = loc_x - center_x, y_diff = loc_y - center_y; const double dist2 = x_diff * x_diff + y_diff * y_diff; std::ostringstream os; - os << "Found pokecenter at box: x=" << box.x << ", y=" << box.y << ", width=" << box.width << ", height=" << box.height << + os << "Found " + fly_point_string + " at box: x=" << box.x << ", y=" << box.y << ", width=" << box.width << ", height=" << box.height << ", dist to center " << std::sqrt(dist2) << " pixels"; stream.log(os.str()); @@ -259,8 +284,8 @@ bool detect_closest_pokecenter_and_move_map_cursor_there( closest_icon_x = loc_x; closest_icon_y = loc_y; } } - stream.log("Found closest pokecenter icon on map: (" + std::to_string(closest_icon_x) + ", " + std::to_string(closest_icon_y) + ")."); - stream.overlay().add_log("Detected PokeCenter icon"); + stream.log("Found closest " + fly_point_string + " icon on map: (" + std::to_string(closest_icon_x) + ", " + std::to_string(closest_icon_y) + ")."); + stream.overlay().add_log("Detected " + fly_point_string + " icon"); } // Convert the vector from center to the PokeCenter icon into a left joystick movement @@ -285,13 +310,14 @@ bool detect_closest_pokecenter_and_move_map_cursor_there( // While in the current map zoom level, detect pokecenter icons and fly to the closest one. // Return true if succeed. Return false if no visible pokcenter on map // Throw Operation failed Exception if detected pokecenter, but failed to fly there. -bool fly_to_visible_closest_pokecenter_cur_zoom_level( +bool fly_to_visible_closest_flypoint_cur_zoom_level( const ProgramInfo& info, VideoStream& stream, ProControllerContext& context, + FlyPoint fly_point, double push_scale ){ - if (!detect_closest_pokecenter_and_move_map_cursor_there(info, stream, context, push_scale)){ + if (!detect_closest_flypoint_and_move_map_cursor_there(info, stream, context, fly_point, push_scale)){ return false; } bool check_fly_menuitem = true; @@ -302,7 +328,7 @@ bool fly_to_visible_closest_pokecenter_cur_zoom_level( // detected pokecenter, but failed to fly there. OperationFailedException::fire( ErrorReport::SEND_ERROR_REPORT, - "fly_to_visible_closest_pokecenter_cur_zoom_level(): Detected pokecenter, but failed to fly there as no \"Fly\" menuitem.", + "fly_to_visible_closest_flypoint_cur_zoom_level(): Detected pokecenter, but failed to fly there as no \"Fly\" menuitem.", stream ); } @@ -327,7 +353,7 @@ void fly_to_closest_pokecenter_on_map(const ProgramInfo& info, VideoStream& stre // try different magnitudes of cursor push with each failure. double push_scale = 0.29 * adjustment_table[try_count]; // std::cout << "push_scale: " << std::to_string(push_scale) << std::endl; - if (fly_to_visible_closest_pokecenter_cur_zoom_level(info, stream, context, push_scale)){ + if (fly_to_visible_closest_flypoint_cur_zoom_level(info, stream, context, FlyPoint::POKECENTER, push_scale)){ return; // success in finding the closest pokecenter. Return. } @@ -374,7 +400,7 @@ void fly_to_closest_pokecenter_on_map(const ProgramInfo& info, VideoStream& stre double push_scale = 0.29 * adjustment_table[try_count]; // std::cout << "push_scale: " << std::to_string(push_scale) << std::endl; // Now try finding the closest pokecenter at the max warpable level - if (fly_to_visible_closest_pokecenter_cur_zoom_level(info, stream, context, push_scale)){ + if (fly_to_visible_closest_flypoint_cur_zoom_level(info, stream, context, FlyPoint::POKECENTER, push_scale)){ return; // success in finding the closest pokecenter. Return. }else{ // Does not detect any pokecenter on map @@ -662,6 +688,182 @@ void heal_at_pokecenter( } +// spam A button to choose the first move +// throw exception if wipeout or if your lead faints. +void run_battle_press_A( + VideoStream& stream, + ProControllerContext& context, + BattleStopCondition stop_condition, + std::unordered_set enum_optional_callbacks, + bool detect_wipeout +){ + int16_t num_times_seen_overworld = 0; + size_t consecutive_move_select = 0; + while (true){ + NormalBattleMenuWatcher battle(COLOR_BLUE); + SwapMenuWatcher fainted(COLOR_PURPLE); + OverworldWatcher overworld(stream.logger(), COLOR_CYAN); + AdvanceDialogWatcher dialog(COLOR_RED); + DialogArrowWatcher dialog_arrow(COLOR_RED, stream.overlay(), {0.850, 0.820, 0.020, 0.050}, 0.8365, 0.846); + GradientArrowWatcher next_pokemon(COLOR_BLUE, GradientArrowType::RIGHT, {0.50, 0.51, 0.30, 0.10}); + MoveSelectWatcher move_select_menu(COLOR_YELLOW); + + std::vector callbacks; + std::vector enum_all_callbacks; + // mandatory callbacks: Battle, Overworld, Advance Dialog, Swap menu, Move select + // optional callbacks: DIALOG_ARROW, NEXT_POKEMON + + // merge the mandatory and optional callbacks as a set, to avoid duplicates. then convert to vector + std::unordered_set enum_all_callbacks_set{CallbackEnum::BATTLE, CallbackEnum::OVERWORLD, CallbackEnum::ADVANCE_DIALOG, CallbackEnum::SWAP_MENU, CallbackEnum::MOVE_SELECT}; // mandatory callbacks + enum_all_callbacks_set.insert(enum_optional_callbacks.begin(), enum_optional_callbacks.end()); // append the mandatory and optional callback sets together + enum_all_callbacks.assign(enum_all_callbacks_set.begin(), enum_all_callbacks_set.end()); + + for (const CallbackEnum& enum_callback : enum_all_callbacks){ + switch(enum_callback){ + case CallbackEnum::ADVANCE_DIALOG: + callbacks.emplace_back(dialog); + break; + case CallbackEnum::OVERWORLD: + callbacks.emplace_back(overworld); + break; + case CallbackEnum::DIALOG_ARROW: + callbacks.emplace_back(dialog_arrow); + break; + case CallbackEnum::BATTLE: + callbacks.emplace_back(battle); + break; + case CallbackEnum::NEXT_POKEMON: // to detect the "next pokemon" prompt. + callbacks.emplace_back(next_pokemon); + break; + case CallbackEnum::SWAP_MENU: // detecting Swap Menu implies your lead fainted. + callbacks.emplace_back(fainted); + break; + case CallbackEnum::MOVE_SELECT: + callbacks.emplace_back(move_select_menu); + break; + default: + throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "run_battle_press_A: Unknown callback requested."); + } + } + context.wait_for_all_requests(); + + int ret = wait_until( + stream, context, + std::chrono::seconds(90), + callbacks + ); + context.wait_for(std::chrono::milliseconds(100)); + if (ret < 0){ + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "run_battle_press_A(): Timed out. Did not detect expected stop condition.", + stream + ); + } + + CallbackEnum enum_callback = enum_all_callbacks[ret]; + switch (enum_callback){ + case CallbackEnum::BATTLE: // battle + stream.log("Detected battle menu."); + consecutive_move_select = 0; + pbf_press_button(context, BUTTON_A, 20, 105); + break; + case CallbackEnum::MOVE_SELECT: + stream.log("Detected move select. Spam first move"); + consecutive_move_select++; + select_top_move(stream, context, consecutive_move_select); + break; + case CallbackEnum::OVERWORLD: // overworld + stream.log("Detected overworld, battle over."); + num_times_seen_overworld++; + if (stop_condition == BattleStopCondition::STOP_OVERWORLD){ + return; + } + if(num_times_seen_overworld > 30){ + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "run_battle_press_A(): Stuck in overworld. Did not detect expected stop condition.", + stream + ); + } + break; + case CallbackEnum::ADVANCE_DIALOG: // advance dialog + stream.log("Detected dialog."); + + if (detect_wipeout){ + context.wait_for_all_requests(); + WipeoutDetector wipeout; + VideoSnapshot screen = stream.video().snapshot(); + // dump_snapshot(console); + if (wipeout.detect(screen)){ + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "run_battle_press_A(): Detected wipeout. All pokemon fainted.", + stream + ); + } + } + + if (stop_condition == BattleStopCondition::STOP_DIALOG){ + return; + } + pbf_press_button(context, BUTTON_A, 20, 105); + break; + case CallbackEnum::DIALOG_ARROW: // dialog arrow + stream.log("run_battle_press_A: Detected dialog arrow."); + pbf_press_button(context, BUTTON_A, 20, 105); + break; + case CallbackEnum::NEXT_POKEMON: + stream.log("run_battle_press_A: Detected prompt for bringing in next pokemon. Keep current pokemon."); + pbf_mash_button(context, BUTTON_B, 100); + break; + case CallbackEnum::SWAP_MENU: + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "run_battle_press_A(): Lead pokemon fainted.", + stream + ); + default: + throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "run_battle_press_A: Unknown callback triggered."); + + } + } +} + +void run_trainer_battle_press_A( + VideoStream& stream, + ProControllerContext& context, + BattleStopCondition stop_condition, + std::unordered_set enum_optional_callbacks, + bool detect_wipeout +){ + enum_optional_callbacks.insert(CallbackEnum::NEXT_POKEMON); // always check for the "Next pokemon" prompt when in trainer battles + run_battle_press_A(stream, context, stop_condition, enum_optional_callbacks, detect_wipeout); +} + +void run_wild_battle_press_A( + VideoStream& stream, + ProControllerContext& context, + BattleStopCondition stop_condition, + std::unordered_set enum_optional_callbacks, + bool detect_wipeout +){ + run_battle_press_A(stream, context, stop_condition, enum_optional_callbacks, detect_wipeout); +} + + + +void select_top_move(VideoStream& stream, ProControllerContext& context, size_t consecutive_move_select){ + if (consecutive_move_select > 3){ + // to handle case where move is disabled/out of PP/taunted + stream.log("Failed to select a move 3 times. Choosing a different move.", COLOR_RED); + pbf_press_dpad(context, DPAD_DOWN, 20, 40); + } + pbf_mash_button(context, BUTTON_A, 100); + +} + + } } } diff --git a/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.h b/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.h index e858a7b71d..50e11f91a5 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.h +++ b/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.h @@ -9,16 +9,51 @@ #ifndef PokemonAutomation_PokemonSV_WorldNavigation_H #define PokemonAutomation_PokemonSV_WorldNavigation_H +#include #include "CommonFramework/Tools/VideoStream.h" #include "NintendoSwitch/Controllers/NintendoSwitch_ProController.h" #include "PokemonSV/Inference/PokemonSV_MainMenuDetector.h" -#include "PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h" namespace PokemonAutomation{ struct ProgramInfo; namespace NintendoSwitch{ namespace PokemonSV{ +enum class PlayerRealignMode{ + REALIGN_NEW_MARKER, + REALIGN_OLD_MARKER, + REALIGN_NO_MARKER, +}; + +enum class NavigationMovementMode{ + DIRECTIONAL_ONLY, + DIRECTIONAL_SPAM_A, + CLEAR_WITH_LETS_GO, +}; + +enum class FlyPoint{ + POKECENTER, + FAST_TRAVEL, +}; + +enum class BattleStopCondition{ + STOP_OVERWORLD, + STOP_DIALOG, +}; + +enum class CallbackEnum{ + ADVANCE_DIALOG, + OVERWORLD, + PROMPT_DIALOG, + WHITE_A_BUTTON, + DIALOG_ARROW, + BATTLE, + TUTORIAL, + BLACK_DIALOG_BOX, + NEXT_POKEMON, + SWAP_MENU, + MOVE_SELECT, +}; // From map, press A to fly to a travel spot. // check_fly_menuitem == true: will detect if the "Fly" menuitem is available. Return false if no "Fly" menuitem (the game @@ -36,17 +71,19 @@ void leave_picnic(const ProgramInfo& info, VideoStream& stream, ProControllerCon // While in the current map zoom level, detect pokecenter icons and move the map cursor there. // Return true if succeed. Return false if no visible pokcenter on map -bool detect_closest_pokecenter_and_move_map_cursor_there( +bool detect_closest_flypoint_and_move_map_cursor_there( const ProgramInfo& info, VideoStream& stream, ProControllerContext& context, + FlyPoint fly_point, double push_scale = 0.29 ); -bool fly_to_visible_closest_pokecenter_cur_zoom_level( +bool fly_to_visible_closest_flypoint_cur_zoom_level( const ProgramInfo& info, VideoStream& stream, ProControllerContext& context, + FlyPoint fly_point, double push_scale = 0.29 ); @@ -137,6 +174,31 @@ void heal_at_pokecenter( ); +// spam A button to choose the first move for trainer battles +// detect_wipeout: can be false if you have multiple pokemon in your party, since an exception will be thrown if your lead faints. +// throw exception if wipeout or if your lead faints. +void run_trainer_battle_press_A( + VideoStream& stream, + ProControllerContext& context, + BattleStopCondition stop_condition, + std::unordered_set enum_optional_callbacks = {}, + bool detect_wipeout = false +); + +// spam A button to choose the first move for wild battles +// detect_wipeout: can be false if you have multiple pokemon in your party, since an exception will be thrown if your lead faints. +// throw exception if wipeout or if your lead faints. +void run_wild_battle_press_A( + VideoStream& stream, + ProControllerContext& context, + BattleStopCondition stop_condition, + std::unordered_set enum_optional_callbacks = {}, + bool detect_wipeout = false +); + +void select_top_move(VideoStream& stream, ProControllerContext& context, size_t consecutive_move_select); + + } } } From 5be05a17d01f447b7daa0c8d5fba4755051f06e6 Mon Sep 17 00:00:00 2001 From: jw098 Date: Wed, 24 Sep 2025 09:48:38 -0700 Subject: [PATCH 05/10] add comments to checkpoints 55-57 --- .../Programs/AutoStory/PokemonSV_AutoStory_Segment_24.cpp | 5 +++-- .../Programs/AutoStory/PokemonSV_AutoStory_Segment_24.h | 8 ++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_24.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_24.cpp index 6cf86e8fda..dca10d2545 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_24.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_24.cpp @@ -55,7 +55,7 @@ void AutoStory_Segment_24::run_segment( checkpoint_55(env, context, options.notif_status_update, stats); checkpoint_56(env, context, options.notif_status_update, stats); - // checkpoint_57(env, context, options.notif_status_update, stats); + checkpoint_57(env, context, options.notif_status_update, stats); context.wait_for_all_requests(); env.console.log("End Segment " + name(), COLOR_GREEN); @@ -215,7 +215,8 @@ void checkpoint_57( ){ checkpoint_reattempt_loop(env, context, notif_status_update, stats, [&](size_t attempt_number){ - + // fly back to East Province (Area Three) Watchtower + move_cursor_towards_flypoint_and_go_there(env.program_info(), env.console, context, {ZoomChange::KEEP_ZOOM, 0, 0, 0}, FlyPoint::FAST_TRAVEL); }); diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_24.h b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_24.h index 148dc778dc..2a8721455a 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_24.h +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_24.h @@ -28,7 +28,7 @@ class AutoStory_Segment_24 : public AutoStory_Segment{ // start: At East Province (Area Three) Watchtower. -// end: +// end: Beat Orthworm phase 1 void checkpoint_55( SingleSwitchProgramEnvironment& env, ProControllerContext& context, @@ -36,8 +36,8 @@ void checkpoint_55( AutoStoryStats& stats ); -// start: -// end: +// start: Beat Orthworm phase 1 +// end: Beat Orthworm phase 2 void checkpoint_56( SingleSwitchProgramEnvironment& env, ProControllerContext& context, @@ -45,7 +45,7 @@ void checkpoint_56( AutoStoryStats& stats ); -// start: +// start: Beat Orthworm phase 2 // end: void checkpoint_57( SingleSwitchProgramEnvironment& env, From 3759e9a9dca779ed238b0c082cbaa08514d7634c Mon Sep 17 00:00:00 2001 From: jw098 Date: Thu, 25 Sep 2025 17:02:47 -0700 Subject: [PATCH 06/10] implement move_cursor_to_position_offset_from_flypoint --- .../Programs/PokemonSV_WorldNavigation.cpp | 150 +++++++++++++++--- .../Programs/PokemonSV_WorldNavigation.h | 9 ++ 2 files changed, 133 insertions(+), 26 deletions(-) diff --git a/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.cpp b/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.cpp index 40007be95c..68a852cf74 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.cpp @@ -33,8 +33,8 @@ #include #include #include -// using std::cout; -// using std::endl; +using std::cout; +using std::endl; namespace PokemonAutomation{ namespace NintendoSwitch{ @@ -222,6 +222,123 @@ void leave_picnic(const ProgramInfo& info, VideoStream& stream, ProControllerCon context.wait_for(std::chrono::seconds(3)); } +std::string get_flypoint_string(FlyPoint fly_point){ + std::string fly_point_string; + if (fly_point == FlyPoint::POKECENTER){ + fly_point_string = "Pokecenter"; + }else if(fly_point == FlyPoint::FAST_TRAVEL){ + fly_point_string = "Fast Travel"; + } + + return fly_point_string; +} + +const std::vector get_flypoint_locations(const ProgramInfo& info, VideoStream& stream, ProControllerContext& context, FlyPoint fly_point){ + std::vector found_locations; + MapPokeCenterIconWatcher pokecenter_watcher(COLOR_RED, stream.overlay(), MAP_READABLE_AREA); + FastTravelWatcher fast_travel_watcher(COLOR_RED, stream.overlay(), MAP_READABLE_AREA); + int ret = -1; + if (fly_point == FlyPoint::POKECENTER){ + ret = wait_until(stream, context, std::chrono::seconds(2), {pokecenter_watcher}); + if (ret == 0){ + found_locations = pokecenter_watcher.found_locations(); + } + }else if(fly_point == FlyPoint::FAST_TRAVEL){ + ret = wait_until(stream, context, std::chrono::seconds(2), {fast_travel_watcher}); + if (ret == 0){ + found_locations = fast_travel_watcher.found_locations(); + } + } + + return found_locations; +} + +void print_flypoint_location(const ProgramInfo& info, VideoStream& stream, ProControllerContext& context, FlyPoint fly_point){ + std::string fly_point_string = get_flypoint_string(fly_point); + + const std::vector found_locations = get_flypoint_locations(info, stream, context, fly_point); + if (found_locations.empty()){ + stream.log("No visible " + fly_point_string + " found on map"); + return; + } + + for(const auto& box: found_locations){ + std::ostringstream os; + os << "Found " + fly_point_string + " at box: x=" << box.x << ", y=" << box.y << ", width=" << box.width << ", height=" << box.height; + stream.log(os.str()); + + } +} + +void move_cursor_to_position_offset_from_flypoint(const ProgramInfo& info, VideoStream& stream, ProControllerContext& context, FlyPoint fly_point, ExpectedMarkerPosition marker_offset){ + // loop through flypoint locations. find the point that is closest to marker_offset, by distance x_diff^2 + y_diff^2 + // based on the closest point, move cursor based on x_diff and y_diff. do this again until x_diff/y_diff are within certain margins + std::string fly_point_string = get_flypoint_string(fly_point); + size_t MAX_ATTEMPTS = 20; + for (size_t i = 0; i < MAX_ATTEMPTS; i++){ + const std::vector found_locations = get_flypoint_locations(info, stream, context, fly_point); + + const double expected_x = marker_offset.x; + const double expected_y = marker_offset.y; + double closest_icon_x = 0.0; + double closest_icon_y = 0.0; + double closest_dist2 = DBL_MAX; // distance^2 in pixels + + for(const auto& box: found_locations){ + const double found_x = box.x; + const double found_y = box.y; + const double x_diff = (found_x - expected_x) * 1920; + const double y_diff = (found_y - expected_y) * 1080; + const double dist2 = x_diff * x_diff + y_diff * y_diff; + + + if (dist2 < closest_dist2){ + closest_dist2 = dist2; + closest_icon_x = found_x; + closest_icon_y = found_y; + } + } + stream.log("Found closest " + fly_point_string + " icon on map: (" + std::to_string(closest_icon_x) + ", " + std::to_string(closest_icon_y) + ")."); + + + // Convert the vector from ExpectedMarkerPosition to the FlyPoint icon into a left joystick movement + const double dif_x = (closest_icon_x - expected_x) * 1920; + const double dif_y = (closest_icon_y - expected_y) * 1080; + const double magnitude = std::max(std::sqrt(closest_dist2), 1.0); + double push_x = dif_x * 64 / magnitude; + double push_y = dif_y * 64 / magnitude; + + double scale = 0.29; + if (closest_dist2 < 1000){ // if we're already very close to the target, reduce push velocity and push duration + scale = 0.1; + push_x *= 0.25; + push_y *= 0.25; + } + + if (closest_dist2 < 5){ // if we're very very close to the target, reduce push velocity and push duration even further + push_x *= 0.5; + push_y *= 0.5; + } + + cout << "sqrt(closest_dist2): " << std::sqrt(closest_dist2) << endl; + // cout << "push_x " << push_x << endl; + // cout << "dif_x "<< dif_x << endl; + // cout << "magnitude " << magnitude << endl; + + if (std::sqrt(closest_dist2) < 0.5){ + // return when we're close enough to the target + break; + } + + const uint8_t move_x = uint8_t(std::max(std::min(int(round(push_x + 128) + 0.5), 255), 0)); + const uint8_t move_y = uint8_t(std::max(std::min(int(round(push_y + 128) + 0.5), 255), 0)); + + const uint16_t push_time = std::max(uint16_t(magnitude * scale + 0.5), uint16_t(3)); + pbf_move_left_joystick(context, move_x, move_y, push_time, 30); + context.wait_for_all_requests(); + } + +} // While in the current map zoom level, detect pokecenter icons and move the map cursor there. // Return true if succeed. Return false if no visible pokcenter on map @@ -241,35 +358,16 @@ bool detect_closest_flypoint_and_move_map_cursor_there( double max_dist = DBL_MAX; const double center_x = 0.5 * screen_width, center_y = 0.5 * screen_height; { - int ret = -1; - std::string fly_point_string; - MapPokeCenterIconWatcher pokecenter_watcher(COLOR_RED, stream.overlay(), MAP_READABLE_AREA); - FastTravelWatcher fast_travel_watcher(COLOR_RED, stream.overlay(), MAP_READABLE_AREA); - const std::vector* found_locations = nullptr; - if (fly_point == FlyPoint::POKECENTER){ - fly_point_string = "Pokecenter"; - ret = wait_until(stream, context, std::chrono::seconds(2), {pokecenter_watcher}); - if (ret == 0){ - found_locations = &pokecenter_watcher.found_locations(); - } - }else if(fly_point == FlyPoint::FAST_TRAVEL){ - fly_point_string = "Fast Travel"; - ret = wait_until(stream, context, std::chrono::seconds(2), {fast_travel_watcher}); - if (ret == 0){ - found_locations = &fast_travel_watcher.found_locations(); - } - } - if (ret != 0){ + std::string fly_point_string = get_flypoint_string(fly_point); + const std::vector found_locations = get_flypoint_locations(info, stream, context, fly_point); + if (found_locations.empty()){ stream.log("No visible " + fly_point_string + " found on map"); stream.overlay().add_log("No whole " + fly_point_string + " icon"); return false; } - - if (found_locations == nullptr){ - throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "detect_closest_flypoint_and_move_map_cursor_there: Fly points have been found, but found_locations remains a nullptr."); - } + // Find the detected PokeCenter icon closest to the screen center (where player character is on the map). - for(const auto& box: *found_locations){ + for(const auto& box: found_locations){ const double loc_x = (box.x + box.width/2) * screen_width; const double loc_y = (box.y + box.height/2) * screen_height; const double x_diff = loc_x - center_x, y_diff = loc_y - center_y; diff --git a/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.h b/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.h index 50e11f91a5..0c2da29f76 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.h +++ b/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.h @@ -35,6 +35,10 @@ enum class FlyPoint{ POKECENTER, FAST_TRAVEL, }; +struct ExpectedMarkerPosition{ + double x; + double y; +}; enum class BattleStopCondition{ STOP_OVERWORLD, @@ -69,6 +73,11 @@ void picnic_from_overworld(const ProgramInfo& info, VideoStream& stream, ProCont // While in picnic, stop picnic and back to overworld. void leave_picnic(const ProgramInfo& info, VideoStream& stream, ProControllerContext& context); +void print_flypoint_location(const ProgramInfo& info, VideoStream& stream, ProControllerContext& context, FlyPoint fly_point); + +// with the map open, move the cursor to a specific position offset from the flypoint, as per marker_offset +void move_cursor_to_position_offset_from_flypoint(const ProgramInfo& info, VideoStream& stream, ProControllerContext& context, FlyPoint fly_point, ExpectedMarkerPosition marker_offset); + // While in the current map zoom level, detect pokecenter icons and move the map cursor there. // Return true if succeed. Return false if no visible pokcenter on map bool detect_closest_flypoint_and_move_map_cursor_there( From bfe245617c4c770d69693aca3c2033913ea62dad Mon Sep 17 00:00:00 2001 From: jw098 Date: Thu, 25 Sep 2025 17:19:33 -0700 Subject: [PATCH 07/10] add more test code for autostory --- .../AutoStory/PokemonSV_AutoStory.cpp | 54 ++++++++++++++++++- .../Programs/AutoStory/PokemonSV_AutoStory.h | 6 +++ .../Programs/PokemonSV_WorldNavigation.cpp | 2 +- 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp index 0783ea754b..f53f5914e3 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp @@ -415,13 +415,49 @@ AutoStory::AutoStory() "direction in radians", LockMode::UNLOCK_WHILE_RUNNING, 0 - ) + ) + , FLYPOINT_TYPE( + "Flypoint type:
" + "For print_flypoint_location() and move_cursor_to_position_offset_from_flypoint()", + { + {FlyPoint::POKECENTER, "pokecenter", "Pokecenter"}, + {FlyPoint::FAST_TRAVEL, "fast-travel", "Fast Travel"}, + }, + LockMode::UNLOCK_WHILE_RUNNING, + FlyPoint::POKECENTER + ) + , TEST_FLYPOINT_LOCATIONS( + "TEST: print_flypoint_location():", + LockMode::UNLOCK_WHILE_RUNNING, + false + ) + , TEST_MOVE_CURSOR_OFFSET_FROM_FLYPOINT( + "TEST: move_cursor_to_position_offset_from_flypoint():", + LockMode::UNLOCK_WHILE_RUNNING, + false + ) + , X_OFFSET( + "X offset from flypoint", + LockMode::UNLOCK_WHILE_RUNNING, + 0 + ) + , Y_OFFSET( + "Y offset from flypoint", + LockMode::UNLOCK_WHILE_RUNNING, + 0 + ) { if (PreloadSettings::instance().DEVELOPER_MODE){ PA_ADD_OPTION(m_advanced_options); PA_ADD_OPTION(CHANGE_SETTINGS); + PA_ADD_OPTION(FLYPOINT_TYPE); + PA_ADD_OPTION(TEST_FLYPOINT_LOCATIONS); + PA_ADD_OPTION(TEST_MOVE_CURSOR_OFFSET_FROM_FLYPOINT); + PA_ADD_OPTION(X_OFFSET); + PA_ADD_OPTION(Y_OFFSET); + PA_ADD_OPTION(TEST_CURRENT_DIRECTION); PA_ADD_OPTION(TEST_CHANGE_DIRECTION); PA_ADD_OPTION(DIR_RADIANS); @@ -768,6 +804,19 @@ void AutoStory::run_autostory(SingleSwitchProgramEnvironment& env, ProController } void AutoStory::test_code(SingleSwitchProgramEnvironment& env, ProControllerContext& context){ + + if (TEST_FLYPOINT_LOCATIONS){ + print_flypoint_location(env.program_info(), env.console, context, FLYPOINT_TYPE); + // print_flypoint_location(env.program_info(), env.console, context, FlyPoint::FAST_TRAVEL); + return; + } + + if (TEST_MOVE_CURSOR_OFFSET_FROM_FLYPOINT){ + move_cursor_to_position_offset_from_flypoint(env.program_info(), env.console, context, FLYPOINT_TYPE, {X_OFFSET, Y_OFFSET}); + + return; + } + if (TEST_CURRENT_DIRECTION){ DirectionDetector direction; // direction.change_direction(env.program_info(), env.console, context, DIR_RADIANS); @@ -817,6 +866,9 @@ void AutoStory::test_code(SingleSwitchProgramEnvironment& env, ProControllerCont DirectionDetector direction; + // detect_closest_flypoint_and_move_map_cursor_there(env.program_info(), env.console, context, FlyPoint::POKECENTER, 0.29); + // print_flypoint_location(env.program_info(), env.console, context, FlyPoint::FAST_TRAVEL); + return; } diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.h b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.h index 636dfe3a05..d4bb4cac38 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.h +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.h @@ -126,6 +126,12 @@ class AutoStory : public SingleSwitchProgramInstance, public ConfigOption::Liste BooleanCheckBoxOption TEST_CURRENT_DIRECTION; BooleanCheckBoxOption TEST_CHANGE_DIRECTION; FloatingPointOption DIR_RADIANS; + + EnumDropdownOption FLYPOINT_TYPE; + BooleanCheckBoxOption TEST_FLYPOINT_LOCATIONS; + BooleanCheckBoxOption TEST_MOVE_CURSOR_OFFSET_FROM_FLYPOINT; + FloatingPointOption X_OFFSET; + FloatingPointOption Y_OFFSET; }; const std::vector>& ALL_AUTO_STORY_SEGMENT_LIST(); diff --git a/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.cpp b/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.cpp index 68a852cf74..21180dc05f 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.cpp @@ -274,7 +274,7 @@ void move_cursor_to_position_offset_from_flypoint(const ProgramInfo& info, Video // loop through flypoint locations. find the point that is closest to marker_offset, by distance x_diff^2 + y_diff^2 // based on the closest point, move cursor based on x_diff and y_diff. do this again until x_diff/y_diff are within certain margins std::string fly_point_string = get_flypoint_string(fly_point); - size_t MAX_ATTEMPTS = 20; + size_t MAX_ATTEMPTS = 30; for (size_t i = 0; i < MAX_ATTEMPTS; i++){ const std::vector found_locations = get_flypoint_locations(info, stream, context, fly_point); From 0989052b870855acd4839d0680f8bea23abd9f86 Mon Sep 17 00:00:00 2001 From: jw098 Date: Thu, 25 Sep 2025 21:28:58 -0700 Subject: [PATCH 08/10] checkpoint 57: At East Province (Area Three) Pokecenter. --- .../AutoStory/PokemonSV_AutoStory.cpp | 2 - .../AutoStory/PokemonSV_AutoStoryTools.h | 14 --- .../PokemonSV_AutoStory_Segment_24.cpp | 106 +++++++++++++++++- .../PokemonSV_AutoStory_Segment_24.h | 2 +- .../Programs/PokemonSV_WorldNavigation.cpp | 69 ++++++++++++ .../Programs/PokemonSV_WorldNavigation.h | 17 +++ 6 files changed, 192 insertions(+), 18 deletions(-) diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp index f53f5914e3..1dd9f3d719 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory.cpp @@ -866,8 +866,6 @@ void AutoStory::test_code(SingleSwitchProgramEnvironment& env, ProControllerCont DirectionDetector direction; - // detect_closest_flypoint_and_move_map_cursor_there(env.program_info(), env.console, context, FlyPoint::POKECENTER, 0.29); - // print_flypoint_location(env.program_info(), env.console, context, FlyPoint::FAST_TRAVEL); return; diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h index 1f7d403068..8f2cf6f047 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStoryTools.h @@ -245,20 +245,6 @@ void change_settings(SingleSwitchProgramEnvironment& env, ProControllerContext& void checkpoint_save(SingleSwitchProgramEnvironment& env, ProControllerContext& context, EventNotificationOption& notif_status_update, AutoStoryStats& stats); -enum class ZoomChange{ - ZOOM_IN, - ZOOM_IN_TWICE, - ZOOM_OUT, - ZOOM_OUT_TWICE, - KEEP_ZOOM, -}; - -struct MoveCursor{ - ZoomChange zoom_change; - uint8_t move_x; - uint8_t move_y; - uint16_t move_duration; -}; // place a marker on the map, not relative to the current player position, but based on a fixed landmark, such as a pokecenter // How this works: diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_24.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_24.cpp index dca10d2545..1ed85e0518 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_24.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_24.cpp @@ -37,7 +37,7 @@ std::string AutoStory_Segment_24::start_text() const{ } std::string AutoStory_Segment_24::end_text() const{ - return "End: Beat Orthworm Titan. At East Province (Area Three) Watchtower."; + return "End: Beat Orthworm Titan. At East Province (Area Three) Pokecenter."; } void AutoStory_Segment_24::run_segment( @@ -218,6 +218,110 @@ void checkpoint_57( // fly back to East Province (Area Three) Watchtower move_cursor_towards_flypoint_and_go_there(env.program_info(), env.console, context, {ZoomChange::KEEP_ZOOM, 0, 0, 0}, FlyPoint::FAST_TRAVEL); + // marker 1 + place_marker_offset_from_flypoint(env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 0, 0, 0}, + FlyPoint::POKECENTER, + {0.769792, 0.725926} + ); + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 20, 10, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 255, 128, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 2 + place_marker_offset_from_flypoint(env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 0, 0, 0}, + FlyPoint::POKECENTER, + {0.280208, 0.447222} + ); + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 30, 10, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 255, 128, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 3 + place_marker_offset_from_flypoint(env.program_info(), env.console, context, + {ZoomChange::ZOOM_IN, 0, 128, 60}, + FlyPoint::POKECENTER, + {0.354167, 0.375} + ); + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 40, 10, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 255, 128, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 4 + place_marker_offset_from_flypoint(env.program_info(), env.console, context, + {ZoomChange::ZOOM_IN, 0, 128, 50}, + FlyPoint::POKECENTER, + {0.497917, 0.274074} + ); + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 30, 10, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 128, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 5. set marker to pokecenter + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::ZOOM_IN, 0, 0, 0}, + {ZoomChange::KEEP_ZOOM, 0, 0, 0} + ); + + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 20, 10, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 255, 0, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 6. set marker past pokecenter + handle_unexpected_battles(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_NEW_MARKER, 128, 0, 30); + }); + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_TIME, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 15, 12, 12, false); // can't wrap in handle_when_stationary_in_overworld(), since we expect to be stationary when walking into the pokecenter + + + fly_to_overlapping_flypoint(env.program_info(), env.console, context); + + }); } diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_24.h b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_24.h index 2a8721455a..7c811513e3 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_24.h +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_24.h @@ -46,7 +46,7 @@ void checkpoint_56( ); // start: Beat Orthworm phase 2 -// end: +// end: At East Province (Area Three) Pokecenter. void checkpoint_57( SingleSwitchProgramEnvironment& env, ProControllerContext& context, diff --git a/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.cpp b/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.cpp index 21180dc05f..d117cc53a8 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.cpp @@ -234,6 +234,7 @@ std::string get_flypoint_string(FlyPoint fly_point){ } const std::vector get_flypoint_locations(const ProgramInfo& info, VideoStream& stream, ProControllerContext& context, FlyPoint fly_point){ + context.wait_for_all_requests(); std::vector found_locations; MapPokeCenterIconWatcher pokecenter_watcher(COLOR_RED, stream.overlay(), MAP_READABLE_AREA); FastTravelWatcher fast_travel_watcher(COLOR_RED, stream.overlay(), MAP_READABLE_AREA); @@ -270,6 +271,74 @@ void print_flypoint_location(const ProgramInfo& info, VideoStream& stream, ProCo } } + + +void place_marker_offset_from_flypoint( + const ProgramInfo& info, + VideoStream& stream, + ProControllerContext& context, + MoveCursor move_cursor_near_flypoint, + FlyPoint fly_point, + ExpectedMarkerPosition marker_offset +){ + + stream.log("place_marker_offset_from_flypoint()"); + WallClock start = current_time(); + + while (true){ + if (current_time() - start > std::chrono::minutes(5)){ + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "place_marker_offset_from_flypoint(): Failed to place down marker after 5 minutes.", + stream + ); + } + + try { + open_map_from_overworld(info, stream, context, false); + + // move cursor near landmark (pokecenter) + switch(move_cursor_near_flypoint.zoom_change){ + case ZoomChange::ZOOM_IN: + pbf_press_button(context, BUTTON_ZR, 20, 105); + break; + case ZoomChange::ZOOM_IN_TWICE: + pbf_press_button(context, BUTTON_ZR, 20, 105); + pbf_press_button(context, BUTTON_ZR, 20, 105); + break; + case ZoomChange::ZOOM_OUT: + pbf_press_button(context, BUTTON_ZL, 20, 105); + break; + case ZoomChange::ZOOM_OUT_TWICE: + pbf_press_button(context, BUTTON_ZL, 20, 105); + pbf_press_button(context, BUTTON_ZL, 20, 105); + break; + case ZoomChange::KEEP_ZOOM: + break; + } + uint8_t move_x1 = move_cursor_near_flypoint.move_x; + uint8_t move_y1 = move_cursor_near_flypoint.move_y; + uint16_t move_duration1 = move_cursor_near_flypoint.move_duration; + pbf_move_left_joystick(context, move_x1, move_y1, move_duration1, 1 * TICKS_PER_SECOND); + + move_cursor_to_position_offset_from_flypoint(info, stream, context, fly_point, {marker_offset.x, marker_offset.y}); + + // place down marker + pbf_press_button(context, BUTTON_A, 20, 105); + pbf_press_button(context, BUTTON_A, 20, 105); + leave_phone_to_overworld(info, stream, context); + + return; + + }catch (UnexpectedBattleException&){ + run_wild_battle_press_A(stream, context, BattleStopCondition::STOP_OVERWORLD); + }catch (OperationFailedException&){ + // reset to overworld if failed to center on the pokecenter, and re-try + leave_phone_to_overworld(info, stream, context); + } + } +} + void move_cursor_to_position_offset_from_flypoint(const ProgramInfo& info, VideoStream& stream, ProControllerContext& context, FlyPoint fly_point, ExpectedMarkerPosition marker_offset){ // loop through flypoint locations. find the point that is closest to marker_offset, by distance x_diff^2 + y_diff^2 // based on the closest point, move cursor based on x_diff and y_diff. do this again until x_diff/y_diff are within certain margins diff --git a/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.h b/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.h index 0c2da29f76..71e5ae2153 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.h +++ b/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.h @@ -59,6 +59,21 @@ enum class CallbackEnum{ MOVE_SELECT, }; +enum class ZoomChange{ + ZOOM_IN, + ZOOM_IN_TWICE, + ZOOM_OUT, + ZOOM_OUT_TWICE, + KEEP_ZOOM, +}; + +struct MoveCursor{ + ZoomChange zoom_change; + uint8_t move_x; + uint8_t move_y; + uint16_t move_duration; +}; + // From map, press A to fly to a travel spot. // check_fly_menuitem == true: will detect if the "Fly" menuitem is available. Return false if no "Fly" menuitem (the game // will be on the map menu opened state). Return true if the flight is successful (the game will be at the overworld). @@ -75,6 +90,8 @@ void leave_picnic(const ProgramInfo& info, VideoStream& stream, ProControllerCon void print_flypoint_location(const ProgramInfo& info, VideoStream& stream, ProControllerContext& context, FlyPoint fly_point); +void place_marker_offset_from_flypoint(const ProgramInfo& info, VideoStream& stream, ProControllerContext& context, MoveCursor move_cursor_near_flypoint, FlyPoint fly_point, ExpectedMarkerPosition marker_offset); + // with the map open, move the cursor to a specific position offset from the flypoint, as per marker_offset void move_cursor_to_position_offset_from_flypoint(const ProgramInfo& info, VideoStream& stream, ProControllerContext& context, FlyPoint fly_point, ExpectedMarkerPosition marker_offset); From 2f2e9170288307cae085aacc738d7e57435adc62 Mon Sep 17 00:00:00 2001 From: jw098 Date: Sun, 28 Sep 2025 18:16:49 -0700 Subject: [PATCH 09/10] update checkpoint 54: Levincia to East Province (Area Three) Watchtower. --- .../PokemonSV_AutoStory_Segment_23.cpp | 287 ++++++++++++++++-- .../Programs/PokemonSV_WorldNavigation.cpp | 2 +- 2 files changed, 267 insertions(+), 22 deletions(-) diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_23.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_23.cpp index f755aa3134..c050765553 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_23.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_23.cpp @@ -82,7 +82,7 @@ void checkpoint_54_switch1(SingleSwitchProgramEnvironment& env, ProControllerCon } ); - // marker 2 + // marker 2. x=0.411979, y=0.730556 realign_player_from_landmark( env.program_info(), env.console, context, {ZoomChange::KEEP_ZOOM, 0, 0, 0}, @@ -101,7 +101,7 @@ void checkpoint_54_switch1(SingleSwitchProgramEnvironment& env, ProControllerCon } ); - // marker 3 + // marker 3. x=0.444792, y=0.640741. zoom out realign_player_from_landmark( env.program_info(), env.console, context, {ZoomChange::KEEP_ZOOM, 0, 0, 0}, @@ -120,7 +120,7 @@ void checkpoint_54_switch1(SingleSwitchProgramEnvironment& env, ProControllerCon } ); - // marker 4 + // marker 4. realign_player_from_landmark( env.program_info(), env.console, context, {ZoomChange::KEEP_ZOOM, 128, 255, 50}, @@ -138,12 +138,12 @@ void checkpoint_54_switch1(SingleSwitchProgramEnvironment& env, ProControllerCon } ); - // marker 5 + // marker 5. : x=0.499479, y=0.64537, zoom out realign_player_from_landmark( env.program_info(), env.console, context, {ZoomChange::KEEP_ZOOM, 128, 255, 50}, {ZoomChange::ZOOM_IN, 135, 0, 107} - ); + ); handle_when_stationary_in_overworld(env.program_info(), env.console, context, [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ overworld_navigation(env.program_info(), env.console, context, @@ -618,26 +618,271 @@ void checkpoint_54( EventNotificationOption& notif_status_update, AutoStoryStats& stats ){ - ConsoleType console_type = env.console.state().console_type(); checkpoint_reattempt_loop(env, context, notif_status_update, stats, [&](size_t attempt_number){ - - if (console_type == ConsoleType::Unknown){ - env.console.log("Unknown Switch type. Try to detect."); - console_type = detect_console_type_from_in_game(env.console, context); - } + DirectionDetector direction; + direction.change_direction(env.program_info(), env.console, context, 1.341); + pbf_move_left_joystick(context, 128, 0, 450, 100); + + // marker 1 + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_NEW_MARKER, 160, 0, 35); + + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 24, 8, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 2. x=0.411979, y=0.730556 + place_marker_offset_from_flypoint(env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 0, 0, 0}, + FlyPoint::POKECENTER, + {0.411979, 0.730556} + ); + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 40, 10, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 3. x=0.444792, y=0.640741. zoom out + place_marker_offset_from_flypoint(env.program_info(), env.console, context, + {ZoomChange::ZOOM_OUT, 0, 0, 0}, + FlyPoint::POKECENTER, + {0.444792, 0.640741} + ); + + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 24, 8, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 4. blind marker placement + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 128, 255, 50}, + {ZoomChange::ZOOM_IN, 150, 0, 112} + ); + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 20, 10, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 5. blind marker placement + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 128, 255, 50}, + {ZoomChange::ZOOM_IN, 135, 0, 107} + ); + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 16, 8, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 6. blind marker placement + realign_player_from_landmark( + env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 128, 255, 50}, + {ZoomChange::ZOOM_IN, 120, 0, 95} + ); + + + // walk forward until dialog + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_DIALOG, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 16, 8, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 255, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + mash_button_till_overworld(env.console, context, BUTTON_A); + + // resume marker 6 + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 16, 8, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 255, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + + // marker 7. x=0.505729, y=0.675926 + place_marker_offset_from_flypoint(env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 128, 255, 30}, + FlyPoint::POKECENTER, + {0.505729, 0.675926} + ); + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 20, 10, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 255, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 8. x=0.591146, y=0.575926, + place_marker_offset_from_flypoint(env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 0, 0, 0}, + FlyPoint::POKECENTER, + {0.591146, 0.575926} + ); + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 30, 10, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 9. at crossroads. x=0.723958, y=0.55463 + place_marker_offset_from_flypoint(env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 0, 0, 0}, + FlyPoint::POKECENTER, + {0.723958, 0.55463} + ); + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 40, 10, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 10. x=0.752604, y=0.643519 + place_marker_offset_from_flypoint(env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 0, 0, 0}, + FlyPoint::POKECENTER, + {0.752604, 0.643519} + ); + + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 20, 10, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 0, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // // marker 11 + // realign_player_from_landmark( + // env.program_info(), env.console, context, + // {ZoomChange::KEEP_ZOOM, 255, 128, 50}, + // {ZoomChange::ZOOM_IN, 0, 85, 135} + // ); + + // handle_when_stationary_in_overworld(env.program_info(), env.console, context, + // [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + // overworld_navigation(env.program_info(), env.console, context, + // NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + // 128, 0, 24, 8, false); + // }, + // [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + // pbf_move_left_joystick(context, 255, 255, 40, 50); + // realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + // } + // ); + + // marker 12. x=0.752083, y=0.702778 + place_marker_offset_from_flypoint(env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 0, 0, 0}, + FlyPoint::POKECENTER, + {0.752083, 0.702778} + ); + + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 16, 8, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 255, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + // marker 13. x=0.685417, y=0.748148 + place_marker_offset_from_flypoint(env.program_info(), env.console, context, + {ZoomChange::KEEP_ZOOM, 0, 0, 0}, + FlyPoint::POKECENTER, + {0.685417, 0.748148} + ); + + handle_when_stationary_in_overworld(env.program_info(), env.console, context, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + overworld_navigation(env.program_info(), env.console, context, + NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, + 128, 0, 16, 8, false); + }, + [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ + pbf_move_left_joystick(context, 255, 255, 40, 50); + realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); + } + ); + + fly_to_overlapping_flypoint(env.program_info(), env.console, context); - if (is_switch1(console_type)){ - checkpoint_54_switch1(env, context); - }else if (is_switch2(console_type)){ - checkpoint_54_switch2(env, context); - }else{ - throw UserSetupError( - env.console, - "Please select a valid Switch console type." - ); - } }); diff --git a/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.cpp b/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.cpp index d117cc53a8..884a651d1d 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_WorldNavigation.cpp @@ -343,7 +343,7 @@ void move_cursor_to_position_offset_from_flypoint(const ProgramInfo& info, Video // loop through flypoint locations. find the point that is closest to marker_offset, by distance x_diff^2 + y_diff^2 // based on the closest point, move cursor based on x_diff and y_diff. do this again until x_diff/y_diff are within certain margins std::string fly_point_string = get_flypoint_string(fly_point); - size_t MAX_ATTEMPTS = 30; + size_t MAX_ATTEMPTS = 20; for (size_t i = 0; i < MAX_ATTEMPTS; i++){ const std::vector found_locations = get_flypoint_locations(info, stream, context, fly_point); From 8caef210f11cfbf4ec2ce5e87187e56d65ae5fbe Mon Sep 17 00:00:00 2001 From: jw098 Date: Sun, 28 Sep 2025 20:51:09 -0700 Subject: [PATCH 10/10] more checkpoint 54 updates --- .../PokemonSV_AutoStory_Segment_23.cpp | 573 +----------------- 1 file changed, 3 insertions(+), 570 deletions(-) diff --git a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_23.cpp b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_23.cpp index c050765553..f240bec483 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_23.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/AutoStory/PokemonSV_AutoStory_Segment_23.cpp @@ -62,555 +62,6 @@ void AutoStory_Segment_23::run_segment( } -void checkpoint_54_switch1(SingleSwitchProgramEnvironment& env, ProControllerContext& context){ - DirectionDetector direction; - direction.change_direction(env.program_info(), env.console, context, 1.341); - pbf_move_left_joystick(context, 128, 0, 450, 100); - - // marker 1 - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_NEW_MARKER, 160, 0, 35); - - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 24, 8, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 0, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 2. x=0.411979, y=0.730556 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 0, 0, 0}, - {ZoomChange::ZOOM_IN, 200, 0, 80} - ); - - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 40, 10, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 0, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 3. x=0.444792, y=0.640741. zoom out - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 0, 0, 0}, - {ZoomChange::ZOOM_IN, 190, 0, 115} - ); - - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 24, 8, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 0, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 4. - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 128, 255, 50}, - {ZoomChange::ZOOM_IN, 150, 0, 112} - ); - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 20, 10, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 0, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 5. : x=0.499479, y=0.64537, zoom out - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 128, 255, 50}, - {ZoomChange::ZOOM_IN, 135, 0, 107} - ); - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 16, 8, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 0, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 6 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 128, 255, 50}, - {ZoomChange::ZOOM_IN, 120, 0, 95} - ); - - // walk forward until dialog - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_DIALOG, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 16, 8, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 255, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - mash_button_till_overworld(env.console, context, BUTTON_A); - - // resume marker 6 - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 16, 8, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 255, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 7 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 128, 255, 50}, - {ZoomChange::ZOOM_IN, 110, 0, 55} - ); - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 20, 10, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 255, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 8 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 0, 0, 0}, - {ZoomChange::ZOOM_IN, 0, 50, 60} - ); - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 30, 10, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 0, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 9. at crossroads - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 0, 0, 0}, - {ZoomChange::ZOOM_IN, 0, 110, 115} - ); - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 40, 10, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 0, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 10 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 0, 0, 0}, - {ZoomChange::ZOOM_IN, 0, 80, 125} - ); - - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 10, 10, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 0, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 11 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 255, 128, 50}, - {ZoomChange::ZOOM_IN, 0, 85, 135} - ); - - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 24, 8, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 255, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 12 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 255, 128, 50}, - {ZoomChange::ZOOM_IN, 0, 70, 140} - ); - - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 24, 8, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 255, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 13 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 255, 128, 50}, - {ZoomChange::ZOOM_IN, 0, 45, 130} - ); - - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 20, 10, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 255, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - fly_to_overlapping_flypoint(env.program_info(), env.console, context); - -} - -void checkpoint_54_switch2(SingleSwitchProgramEnvironment& env, ProControllerContext& context){ - - DirectionDetector direction; - direction.change_direction(env.program_info(), env.console, context, 1.341); - pbf_move_left_joystick(context, 128, 0, 450, 100); - - // marker 1 - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_NEW_MARKER, 160, 0, 35); - - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 24, 8, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 0, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 2 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 0, 0, 0}, - {ZoomChange::ZOOM_IN, 200, 0, 80} - ); - - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 40, 10, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 0, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 3 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 0, 0, 0}, - {ZoomChange::ZOOM_IN, 190, 0, 115} - ); - - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 24, 8, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 0, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 4 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 128, 255, 50}, - {ZoomChange::ZOOM_IN, 150, 0, 112} - ); - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 20, 10, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 0, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 5 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 128, 255, 50}, - {ZoomChange::ZOOM_IN, 135, 0, 107} - ); - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 16, 8, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 0, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 6 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 128, 255, 40}, - {ZoomChange::ZOOM_IN, 120, 0, 95} - ); - - // walk forward until dialog - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_DIALOG, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 16, 8, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 255, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - mash_button_till_overworld(env.console, context, BUTTON_A); - - // resume marker 6 - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 32, 8, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 255, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 7 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 128, 255, 50}, - {ZoomChange::ZOOM_IN, 110, 0, 55} - ); - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 20, 10, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 255, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 8 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 0, 0, 0}, - {ZoomChange::ZOOM_IN, 0, 50, 60} - ); - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 30, 10, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 0, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 9 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 0, 0, 0}, - {ZoomChange::ZOOM_IN, 0, 85, 100} - ); - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 40, 10, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 0, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 10. at crossroads - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 0, 0, 0}, - {ZoomChange::ZOOM_IN, 0, 110, 123} - ); - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 40, 10, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 0, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 11 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 0, 0, 0}, - {ZoomChange::ZOOM_IN, 0, 80, 125} - ); - - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 10, 10, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 0, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - , 6, 5, 5 - ); - - // marker 12 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 255, 128, 50}, - {ZoomChange::ZOOM_IN, 0, 85, 148} - ); - - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 24, 8, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 255, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 13 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 255, 128, 50}, - {ZoomChange::ZOOM_IN, 0, 70, 155} - ); - - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 24, 8, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 255, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - // marker 14 - realign_player_from_landmark( - env.program_info(), env.console, context, - {ZoomChange::KEEP_ZOOM, 255, 128, 50}, - {ZoomChange::ZOOM_IN, 0, 45, 137} - ); - - handle_when_stationary_in_overworld(env.program_info(), env.console, context, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - overworld_navigation(env.program_info(), env.console, context, - NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - 128, 0, 20, 10, false); - }, - [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - pbf_move_left_joystick(context, 255, 255, 40, 50); - realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - } - ); - - fly_to_overlapping_flypoint(env.program_info(), env.console, context); - - - -} void checkpoint_54( SingleSwitchProgramEnvironment& env, @@ -824,26 +275,8 @@ void checkpoint_54( } ); - // // marker 11 - // realign_player_from_landmark( - // env.program_info(), env.console, context, - // {ZoomChange::KEEP_ZOOM, 255, 128, 50}, - // {ZoomChange::ZOOM_IN, 0, 85, 135} - // ); - - // handle_when_stationary_in_overworld(env.program_info(), env.console, context, - // [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - // overworld_navigation(env.program_info(), env.console, context, - // NavigationStopCondition::STOP_MARKER, NavigationMovementMode::DIRECTIONAL_ONLY, - // 128, 0, 24, 8, false); - // }, - // [&](const ProgramInfo& info, VideoStream& stream, ProControllerContext& context){ - // pbf_move_left_joystick(context, 255, 255, 40, 50); - // realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER); - // } - // ); - - // marker 12. x=0.752083, y=0.702778 + + // marker 11. x=0.752083, y=0.702778 place_marker_offset_from_flypoint(env.program_info(), env.console, context, {ZoomChange::KEEP_ZOOM, 0, 0, 0}, FlyPoint::POKECENTER, @@ -862,7 +295,7 @@ void checkpoint_54( } ); - // marker 13. x=0.685417, y=0.748148 + // marker 12. x=0.685417, y=0.748148 place_marker_offset_from_flypoint(env.program_info(), env.console, context, {ZoomChange::KEEP_ZOOM, 0, 0, 0}, FlyPoint::POKECENTER,