Skip to content

Commit

Permalink
update autostory segments and DialogArrowDetector (#514)
Browse files Browse the repository at this point in the history
  • Loading branch information
jw098 authored Dec 1, 2024
1 parent 5a063bd commit acdb930
Show file tree
Hide file tree
Showing 16 changed files with 232 additions and 150 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
#include "CommonFramework/ImageMatch/ExactImageMatcher.h"
#include "PokemonSV_DialogArrowDetector.h"

// #include <iostream>
// using std::cout;
// using std::endl;
#include <iostream>
using std::cout;
using std::endl;

namespace PokemonAutomation{
namespace NintendoSwitch{
Expand Down Expand Up @@ -188,19 +188,24 @@ void DialogArrowWatcher::make_overlays(VideoOverlaySet& items) const{
// - every time the arrow is above top_line, increment m_num_oscillation_above_top_line.
// - likewise for m_num_oscillation_below_bottom_line
// - we alternate between looking for the arrow being above top_line vs below bottom_line
// - reset counts whenever the dialog arrow is not detected
// - reset counts whenever the dialog arrow has not been detected for 10 frames consecutively
bool DialogArrowWatcher::process_frame(const ImageViewRGB32& frame, WallClock timestamp){
std::pair<double, double> arrow_location = m_detector.locate_dialog_arrow(frame);
double y_location = arrow_location.second;
// cout << std::to_string(y_location) << endl;

if (y_location < 0){ // dialog arrow not detected
// reset oscillation counts
m_num_oscillation_above_top_line = 0;
m_num_oscillation_below_bottom_line = 0;
return false;
m_num_no_detection++;
if (m_num_no_detection > 10){
// reset oscillation counts
m_num_oscillation_above_top_line = 0;
m_num_oscillation_below_bottom_line = 0;
}
return false;
}else{
m_num_no_detection = 0;
}

if (m_num_oscillation_above_top_line >= 5 && m_num_oscillation_below_bottom_line >= 5){
// we have had 5 oscillations above and below the top and bottom line respectively
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class DialogArrowWatcher : public VisualInferenceCallback{
double m_bottom_line;
uint16_t m_num_oscillation_above_top_line;
uint16_t m_num_oscillation_below_bottom_line;
uint16_t m_num_no_detection;
// FixedLimitVector<OverlayBoxScope> m_arrows;

};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ void DirectionDetector::change_direction(
}
is_minimap_definitely_unlocked = true;

if (abs_diff < 0.01){
if (abs_diff < 0.0105){
// return when we're close enough to the target
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -489,8 +489,8 @@ void overworld_navigation(
context.wait_for_all_requests();
try {
realign_player(info, console, context, PlayerRealignMode::REALIGN_OLD_MARKER);
if (!confirm_marker_present(info, console, context)){
// if marker not present, don't keep walking forward.
if (stop_condition == NavigationStopCondition::STOP_MARKER && !confirm_marker_present(info, console, context)){
// if marker not present when using marker based navigation, don't keep walking forward.
return;
}

Expand Down Expand Up @@ -632,7 +632,7 @@ void change_settings(SingleSwitchProgramEnvironment& env, BotBaseContext& contex
{MenuOptionItemEnum::GIVE_NICKNAMES, {MenuOptionToggleEnum::OFF}},
{MenuOptionItemEnum::VERTICAL_CAMERA_CONTROLS, {MenuOptionToggleEnum::REGULAR, MenuOptionToggleEnum::NORMAL}},
{MenuOptionItemEnum::HORIZONTAL_CAMERA_CONTROLS, {MenuOptionToggleEnum::REGULAR, MenuOptionToggleEnum::NORMAL}},
{MenuOptionItemEnum::CAMERA_SUPPORT, {MenuOptionToggleEnum::ON}},
{MenuOptionItemEnum::CAMERA_SUPPORT, {MenuOptionToggleEnum::OFF}},
{MenuOptionItemEnum::CAMERA_INTERPOLATION, {MenuOptionToggleEnum::NORMAL, MenuOptionToggleEnum::AVERAGE}},
{MenuOptionItemEnum::CAMERA_DISTANCE, {MenuOptionToggleEnum::CLOSE}},
{MenuOptionItemEnum::AUTOSAVE, {MenuOptionToggleEnum::OFF}},
Expand All @@ -650,7 +650,7 @@ void change_settings(SingleSwitchProgramEnvironment& env, BotBaseContext& contex
config_option(context, 1); // Give Nicknames: Off
config_option(context, 0); // Vertical Camera Controls: Regular
config_option(context, 0); // Horiztontal Camera Controls: Regular
config_option(context, 0); // Camera Support: On
config_option(context, 1); // Camera Support: Off
config_option(context, 0); // Camera Interpolation: Normal
config_option(context, 0); // Camera Distance: Close
config_option(context, 1); // Autosave: Off
Expand Down Expand Up @@ -853,7 +853,7 @@ void press_A_until_dialog(const ProgramInfo& info, ConsoleHandle& console, BotBa
}
}

bool check_ride_active(const ProgramInfo& info, ConsoleHandle& console, BotBaseContext& context){
bool is_ride_active(const ProgramInfo& info, ConsoleHandle& console, BotBaseContext& context){
while (true){
try {
// open main menu
Expand All @@ -879,14 +879,22 @@ bool check_ride_active(const ProgramInfo& info, ConsoleHandle& console, BotBaseC
}

void get_on_ride(const ProgramInfo& info, ConsoleHandle& console, BotBaseContext& context){
get_on_or_off_ride(info, console, context, true);
}

void get_off_ride(const ProgramInfo& info, ConsoleHandle& console, BotBaseContext& context){
get_on_or_off_ride(info, console, context, false);
}

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

WallClock start = current_time();
while (!check_ride_active(info, console, context)){
while (get_on != is_ride_active(info, console, context)){
if (current_time() - start > std::chrono::minutes(3)){
throw OperationFailedException(
ErrorReport::SEND_ERROR_REPORT, console,
"get_on_ride(): Failed to get on ride after 3 minutes.",
"get_on_or_off_ride(): Failed to get on/off ride after 3 minutes.",
true
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,10 +230,15 @@ void wait_for_overworld(

void press_A_until_dialog(const ProgramInfo& info, ConsoleHandle& console, BotBaseContext& context, uint16_t seconds_between_button_presses);

bool check_ride_active(const ProgramInfo& info, ConsoleHandle& console, BotBaseContext& context);
// return true if ride is active. i.e. if you are on your ride
bool is_ride_active(const ProgramInfo& info, ConsoleHandle& console, BotBaseContext& context);

void get_on_ride(const ProgramInfo& info, ConsoleHandle& console, BotBaseContext& context);

void get_off_ride(const ProgramInfo& info, ConsoleHandle& console, BotBaseContext& context);

void get_on_or_off_ride(const ProgramInfo& info, ConsoleHandle& console, BotBaseContext& context, bool get_on);


// change the settings prior to Autostory
// Assumes that `current_segment` represents where we currently are in the story.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "PokemonSV/Programs/PokemonSV_GameEntry.h"
#include "PokemonSV/Programs/PokemonSV_SaveGame.h"
#include "PokemonSV/Inference/PokemonSV_TutorialDetector.h"
#include "PokemonSV/Inference/Overworld/PokemonSV_DirectionDetector.h"
#include "PokemonSV_AutoStoryTools.h"
#include "PokemonSV_AutoStory_Segment_01.h"

Expand Down Expand Up @@ -83,14 +84,14 @@ AutoStoryStats& stats = env.current_stats<AutoStoryStats>();
stats.m_checkpoint++;
env.update_stats();
send_program_status_notification(env, notif_status_update, "Saved at checkpoint.");
first_attempt = false;
}

context.wait_for_all_requests();
// set settings
enter_menu_from_overworld(env.program_info(), env.console, context, 0, MenuSide::RIGHT, false);
change_settings(env, context, language, first_attempt);
pbf_mash_button(context, BUTTON_B, 2 * TICKS_PER_SECOND);
context.wait_for_all_requests();

break;
}catch(...){
Expand All @@ -114,7 +115,7 @@ void checkpoint_02(
bool first_attempt = true;
while (true){
try{
if(!first_attempt){
if(first_attempt){
save_game_tutorial(env.program_info(), env.console, context);
stats.m_checkpoint++;
env.update_stats();
Expand Down Expand Up @@ -179,14 +180,8 @@ void checkpoint_02(
env.console.log("clear_dialog: Talk with Clavell outside. Receive Rotom phone. Stop when detect overworld.");
clear_dialog(env.console, context, ClearDialogMode::STOP_OVERWORLD, 60, {CallbackEnum::OVERWORLD, CallbackEnum::WHITE_A_BUTTON});

context.wait_for_all_requests();
env.console.log("Bump into power of science NPC");
// console.overlay().add_log("Bump into power of science NPC", COLOR_WHITE);
pbf_move_left_joystick(context, 128, 0, 33 * TICKS_PER_SECOND, 20);

context.wait_for_all_requests();
env.console.log("Clear map tutorial");
// console.overlay().add_log("Clear map tutorial", COLOR_WHITE);
open_map_from_overworld(env.program_info(), env.console, context, true);
leave_phone_to_overworld(env.program_info(), env.console, context);

Expand Down Expand Up @@ -218,11 +213,13 @@ void checkpoint_03(
}

context.wait_for_all_requests();

pbf_move_left_joystick(context, 255, 0, 1 * TICKS_PER_SECOND, 20);
realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_NEW_MARKER, 255, 156, 1 * TICKS_PER_SECOND);
env.console.log("overworld_navigation(): Go to Nemona's house.");
overworld_navigation(env.program_info(), env.console, context, NavigationStopCondition::STOP_DIALOG, NavigationMovementMode::DIRECTIONAL_ONLY, 128, 0);
DirectionDetector direction;
direction.change_direction(env.program_info(), env.console, context, 4.62);
pbf_move_left_joystick(context, 128, 0, 3600, 50);
pbf_move_left_joystick(context, 0, 128, 30, 50);

direction.change_direction(env.program_info(), env.console, context, 4.62);
walk_forward_until_dialog(env.program_info(), env.console, context, NavigationMovementMode::DIRECTIONAL_ONLY, 20);

context.wait_for_all_requests();
env.console.log("Entered Nemona's house");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "PokemonSV/Programs/PokemonSV_GameEntry.h"
#include "PokemonSV/Programs/PokemonSV_SaveGame.h"
#include "PokemonSV/Inference/PokemonSV_TutorialDetector.h"
#include "PokemonSV/Inference/Overworld/PokemonSV_DirectionDetector.h"
#include "PokemonSV_AutoStoryTools.h"
#include "PokemonSV_AutoStory_Segment_02.h"

Expand Down Expand Up @@ -80,27 +81,21 @@ void checkpoint_04(
}
context.wait_for_all_requests();

realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_NEW_MARKER, 220, 245, 50);
pbf_move_left_joystick(context, 128, 0, 4 * TICKS_PER_SECOND, 1 * TICKS_PER_SECOND);
realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_NEW_MARKER, 255, 128, 50);
pbf_move_left_joystick(context, 128, 0, 4 * TICKS_PER_SECOND, 1 * TICKS_PER_SECOND);
realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_NEW_MARKER, 255, 60, 50);
pbf_move_left_joystick(context, 128, 0, 4 * TICKS_PER_SECOND, 2 * TICKS_PER_SECOND);
env.console.log("overworld_navigation: Go to Nemona at the beach.");
overworld_navigation(env.program_info(), env.console, context, NavigationStopCondition::STOP_DIALOG, NavigationMovementMode::DIRECTIONAL_SPAM_A, 128, 0, 8);

context.wait_for_all_requests();
env.console.overlay().add_log("Found Nemona", COLOR_WHITE);
DirectionDetector direction;
direction.change_direction(env.program_info(), env.console, context, 3.72);
pbf_move_left_joystick(context, 128, 0, 400, 50);
direction.change_direction(env.program_info(), env.console, context, 4.55);
pbf_move_left_joystick(context, 128, 0, 600, 50);
direction.change_direction(env.program_info(), env.console, context, 5.27);
walk_forward_until_dialog(env.program_info(), env.console, context, NavigationMovementMode::DIRECTIONAL_SPAM_A, 20);

context.wait_for_all_requests();
env.console.log("Starting battle...");
env.console.overlay().add_log("Starting battle...", COLOR_WHITE);
// TODO: Battle start prompt detection
// can lose this battle, and story will continue
mash_button_till_overworld(env.console, context);
context.wait_for_all_requests();
env.console.log("Finished battle.");
env.console.overlay().add_log("Finished battle.", COLOR_WHITE);

break;
}catch(...){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#include "PokemonSwSh/Inference/PokemonSwSh_IvJudgeReader.h"
#include "PokemonSV/Programs/PokemonSV_GameEntry.h"
#include "PokemonSV/Programs/PokemonSV_SaveGame.h"
#include "PokemonSV/Inference/PokemonSV_TutorialDetector.h"
#include "PokemonSV/Inference/Overworld/PokemonSV_DirectionDetector.h"
#include "PokemonSV_AutoStoryTools.h"
#include "PokemonSV_AutoStory_Segment_03.h"

Expand Down Expand Up @@ -82,11 +82,11 @@ void checkpoint_05(
}
context.wait_for_all_requests();

realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_NEW_MARKER, 40, 160, 60);
pbf_move_left_joystick(context, 128, 0, 7 * TICKS_PER_SECOND, 20);
realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_NEW_MARKER, 40, 84, 60);
env.console.log("overworld_navigation: Go to mom at the gate.");
overworld_navigation(env.program_info(), env.console, context, NavigationStopCondition::STOP_DIALOG, NavigationMovementMode::DIRECTIONAL_ONLY, 128, 0, 20);
DirectionDetector direction;
direction.change_direction(env.program_info(), env.console, context, 1.92);
pbf_move_left_joystick(context, 128, 0, 7 * TICKS_PER_SECOND, 50);
direction.change_direction(env.program_info(), env.console, context, 1.13);
walk_forward_until_dialog(env.program_info(), env.console, context, NavigationMovementMode::DIRECTIONAL_ONLY, 20);

context.wait_for_all_requests();
env.console.log("Get mom's sandwich");
Expand Down Expand Up @@ -123,7 +123,7 @@ void checkpoint_06(
pbf_move_left_joystick(context, 128, 0, 6 * TICKS_PER_SECOND, 20);
realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_NEW_MARKER, 110, 10, 60);
env.console.log("overworld_navigation: Go to Nemona.");
overworld_navigation(env.program_info(), env.console, context, NavigationStopCondition::STOP_DIALOG, NavigationMovementMode::DIRECTIONAL_ONLY, 128, 0, 20);
overworld_navigation(env.program_info(), env.console, context, NavigationStopCondition::STOP_DIALOG, NavigationMovementMode::DIRECTIONAL_ONLY, 128, 0, 20, 20, true, true);

context.wait_for_all_requests();
env.console.log("clear_dialog: Talk with Nemona to start catch tutorial. Stop when detect battle.");
Expand Down Expand Up @@ -171,11 +171,25 @@ void checkpoint_07(
env.console.log("Move to cliff");
env.console.overlay().add_log("Move to cliff", COLOR_WHITE);

realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_NEW_MARKER, 240, 60, 80);
realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_NEW_MARKER, 255, 70, 100);
env.console.log("overworld_navigation: Go to cliff.");
overworld_navigation(env.program_info(), env.console, context, NavigationStopCondition::STOP_DIALOG, NavigationMovementMode::DIRECTIONAL_ONLY, 116, 0, 72, 24, true, true);
overworld_navigation(env.program_info(), env.console, context,
NavigationStopCondition::STOP_TIME, NavigationMovementMode::DIRECTIONAL_ONLY,
135, 0, 24, 12, true, true);

realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_NEW_MARKER, 128, 0, 80);
handle_when_stationary_in_overworld(env.program_info(), env.console, context,
[&](const ProgramInfo& info, ConsoleHandle& console, BotBaseContext& context){
overworld_navigation(env.program_info(), env.console, context,
NavigationStopCondition::STOP_DIALOG, NavigationMovementMode::DIRECTIONAL_ONLY,
128, 0, 24, 12, true, true);
},
[&](const ProgramInfo& info, ConsoleHandle& console, BotBaseContext& context){
pbf_move_left_joystick(context, 0, 128, 40, 50);
realign_player(env.program_info(), env.console, context, PlayerRealignMode::REALIGN_OLD_MARKER);
}
);

env.console.log("clear_dialog: Talk to Nemona at the cliff. Stop when detect overworld.");
clear_dialog(env.console, context, ClearDialogMode::STOP_OVERWORLD, 60, {CallbackEnum::OVERWORLD});

context.wait_for_all_requests();
Expand Down
Loading

0 comments on commit acdb930

Please sign in to comment.