diff --git a/SerialPrograms/Source/PokemonBDSP/Programs/Farming/PokemonBDSP_MoneyFarmerRoute210.cpp b/SerialPrograms/Source/PokemonBDSP/Programs/Farming/PokemonBDSP_MoneyFarmerRoute210.cpp index 75488fcdb..02aafae7a 100644 --- a/SerialPrograms/Source/PokemonBDSP/Programs/Farming/PokemonBDSP_MoneyFarmerRoute210.cpp +++ b/SerialPrograms/Source/PokemonBDSP/Programs/Farming/PokemonBDSP_MoneyFarmerRoute210.cpp @@ -19,6 +19,10 @@ #include "PokemonBDSP/Inference/Battles/PokemonBDSP_EndBattleDetector.h" #include "PokemonBDSP_MoneyFarmerRoute210.h" +#include "CommonFramework/ImageTools/ImageBoxes.h" +#include +#include + namespace PokemonAutomation{ namespace NintendoSwitch{ namespace PokemonBDSP{ @@ -269,6 +273,60 @@ bool MoneyFarmerRoute210::battle(SingleSwitchProgramEnvironment& env, ProControl ); } +void MoneyFarmerRoute210::move_to_trainer(SingleSwitchProgramEnvironment& env, ProControllerContext& context, const std::vector& bubbles + ){ + + const ImagePixelBox* closest = nullptr; + double best_dist_sq = std::numeric_limits::max(); + + // Calculate the distance between the character and the closest box + for (const auto& box : bubbles) { + double dx = box.min_x - 540.0; + double dy = box.min_y - 163.0; + double dist_sq = dx*dx + dy*dy; + + if (dist_sq < best_dist_sq) { + best_dist_sq = dist_sq; + closest = &box; + } + } + + if (!closest) return; + + if (closest->min_x < 350) { + // The trainer who wants to battle is to the far-left, behind the other trainer + pbf_press_dpad(context, DPAD_UP, 400ms, 0ms); + pbf_press_dpad(context, DPAD_LEFT, 500ms, 0ms); + pbf_mash_button(context, BUTTON_A, 1000ms); + context.wait_for_all_requests(); + pbf_press_dpad(context, DPAD_DOWN, 400ms, 0ms); + pbf_mash_button(context, BUTTON_A, 1000ms); + context.wait_for_all_requests(); + } else if (closest->min_x < 450) { + // The trainer who wants to battle is on the character's left + if (closest->min_y < 110) { + // The trainer who wants to battle is one step above us + pbf_press_dpad(context, DPAD_UP, 400ms, 0ms); + pbf_press_dpad(context, DPAD_LEFT, 400ms, 0ms); + context.wait_for_all_requests(); + } else { + // The trainer who wants to battle is on our left, right next to us + pbf_press_dpad(context, DPAD_LEFT, 400ms, 0ms); + } + } else if (closest->min_x < 560) { + // The trainer who wants to battle is right above us + pbf_press_dpad(context, DPAD_UP, 400ms, 0ms); + } else { + // The trainer who wants to battle is above us, one step to our right + pbf_press_dpad(context, DPAD_RIGHT, 400ms, 0ms); + pbf_press_dpad(context, DPAD_UP, 400ms, 0ms); + context.wait_for_all_requests(); + } + + pbf_mash_button(context, BUTTON_A, 1000ms); + context.wait_for_all_requests(); +} + void MoneyFarmerRoute210::check_pickup_items( ProControllerContext& context, const bool pickup_slots[6] ){ @@ -312,6 +370,7 @@ void MoneyFarmerRoute210::check_pickup_items( // Exit the screen pbf_mash_button(context, BUTTON_B, 2000ms); + } void MoneyFarmerRoute210::heal_at_center_and_return( @@ -499,10 +558,14 @@ void MoneyFarmerRoute210::program(SingleSwitchProgramEnvironment& env, ProContro stats.m_react++; } for (const ImagePixelBox& box : bubbles){ - env.log("Reaction at: " + std::to_string(box.min_x), COLOR_BLUE); + env.log("Reaction at X: " + std::to_string(box.min_x) + "Y: " + std::to_string(box.min_y), COLOR_BLUE); + } + if (!bubbles.empty()) { + move_to_trainer(env, context, bubbles); } if (this->battle(env, context, pp0, pp1)){ + env.update_stats(); return; } pickup_counter++; diff --git a/SerialPrograms/Source/PokemonBDSP/Programs/Farming/PokemonBDSP_MoneyFarmerRoute210.h b/SerialPrograms/Source/PokemonBDSP/Programs/Farming/PokemonBDSP_MoneyFarmerRoute210.h index 5fc4b0a3a..54b3ed968 100644 --- a/SerialPrograms/Source/PokemonBDSP/Programs/Farming/PokemonBDSP_MoneyFarmerRoute210.h +++ b/SerialPrograms/Source/PokemonBDSP/Programs/Farming/PokemonBDSP_MoneyFarmerRoute210.h @@ -15,6 +15,9 @@ #include "PokemonBDSP/Options/PokemonBDSP_ShortcutDirection.h" #include "PokemonBDSP/Options/PokemonBDSP_LearnMove.h" +#include "CommonFramework/ImageTools/ImageBoxes.h" +#include + namespace PokemonAutomation{ namespace NintendoSwitch{ namespace PokemonBDSP{ @@ -44,6 +47,11 @@ class MoneyFarmerRoute210 : public SingleSwitchProgramInstance{ ); // From the bottom row of the Ace Trainer pair, heal Pokemon and return. // Return true if VS Seeker needs charging. + void move_to_trainer( + SingleSwitchProgramEnvironment& env, + ProControllerContext& context, + const std::vector& bubbles + ); bool heal_after_battle_and_return( SingleSwitchProgramEnvironment& env, VideoStream& stream, ProControllerContext& context,