From be47474bbe7df8c1dc2eede0078c04cb9f8b90d8 Mon Sep 17 00:00:00 2001 From: Dalton-V Date: Tue, 23 Jun 2026 21:19:13 -0500 Subject: [PATCH 1/5] FRLG Add Empty Party Slot Detector --- .../PokemonFRLG_PartyEmptySlotDetector.cpp | 55 +++++++++++++++++++ .../PokemonFRLG_PartyEmptySlotDetector.h | 50 +++++++++++++++++ SerialPrograms/cmake/SourceFiles.cmake | 2 + 3 files changed, 107 insertions(+) create mode 100644 SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.cpp create mode 100644 SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.h diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.cpp b/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.cpp new file mode 100644 index 0000000000..6f79634a97 --- /dev/null +++ b/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.cpp @@ -0,0 +1,55 @@ +/* Party Empty Slot Detector + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#include "Common/Cpp/Exceptions.h" +#include "CommonTools/Images/SolidColorTest.h" +#include "PokemonFRLG_PartyEmptySlotDetector.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonFRLG{ + +ImageFloatBox PartyEmptySlotDetector::box_for_slot(PartySlot slot){ + switch (slot){ + case PartySlot::ONE: + throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "Invalid FRLG Party Empty Slot. Slot 1 should always be occupied."); + case PartySlot::TWO: + return ImageFloatBox(0.432, 0.150, 0.025, 0.050); + case PartySlot::THREE: + return ImageFloatBox(0.432, 0.3, 0.025, 0.050); + case PartySlot::FOUR: + return ImageFloatBox(0.432, 0.45, 0.025, 0.050); + case PartySlot::FIVE: + return ImageFloatBox(0.432, 0.6, 0.025, 0.050); + case PartySlot::SIX: + return ImageFloatBox(0.432, 0.725, 0.025, 0.050); + default: + break; + } + throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "Invalid FRLG Party Empty Slot."); +} + +PartyEmptySlotDetector::PartyEmptySlotDetector( + Color color, + VideoOverlay* overlay, + PartySlot slot +) + : m_color(color) + , m_overlay(overlay) + , m_box(box_for_slot(slot)) +{} +void PartyEmptySlotDetector::make_overlays(VideoOverlaySet& items) const{ + const BoxOption& GAME_BOX = GameSettings::instance().GAME_BOX; + items.add(m_color, GAME_BOX.inner_to_outer(m_box)); +} +bool PartyEmptySlotDetector::detect(const ImageViewRGB32& screen){ + const BoxOption& GAME_BOX = GameSettings::instance().GAME_BOX; + ImageViewRGB32 game_screen = extract_box_reference(screen, GAME_BOX); + const auto stats = image_stats(extract_box_reference(game_screen, m_box)); + return stats.stddev.sum() < 20.0; +} +} +} \ No newline at end of file diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.h b/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.h new file mode 100644 index 0000000000..e523d101a6 --- /dev/null +++ b/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.h @@ -0,0 +1,50 @@ +/* Party Empty Slot Detector + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#ifndef PokemonAutomation_PokemonFRLG_PartyEmptySlotDetector_H +#define PokemonAutomation_PokemonFRLG_PartyEmptySlotDetector_H + +#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h" +#include "CommonTools/VisualDetector.h" +#include "PokemonFRLG_PartyMenuDetector.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonFRLG{ + +class PartyEmptySlotDetector : public StaticScreenDetector{ +public: + PartyEmptySlotDetector( + Color color, + VideoOverlay* overlay, + PartySlot slot + ); + static ImageFloatBox box_for_slot(PartySlot slot); + virtual void make_overlays(VideoOverlaySet& items) const override; + // This is not const so that detectors can save/cache state. + virtual bool detect(const ImageViewRGB32& screen) override; + +private: + Color m_color; + VideoOverlay* m_overlay; + ImageFloatBox m_box; +}; +class PartyEmptySlotWatcher : public DetectorToFinder{ +public: + PartyEmptySlotWatcher( + Color color, + VideoOverlay* overlay, + PartySlot slot, + std::chrono::milliseconds hold_duration = std::chrono::milliseconds(250) + ) + : DetectorToFinder("PartyEmptySlotWatcher", hold_duration, color, overlay, slot) + {} +}; + +} +} +} +#endif \ No newline at end of file diff --git a/SerialPrograms/cmake/SourceFiles.cmake b/SerialPrograms/cmake/SourceFiles.cmake index 2924fe9269..0311f25332 100644 --- a/SerialPrograms/cmake/SourceFiles.cmake +++ b/SerialPrograms/cmake/SourceFiles.cmake @@ -1472,6 +1472,8 @@ file(GLOB LIBRARY_SOURCES Source/PokemonFRLG/Inference/Menus/PokemonFRLG_BagDetector.h Source/PokemonFRLG/Inference/Menus/PokemonFRLG_LoadMenuDetector.cpp Source/PokemonFRLG/Inference/Menus/PokemonFRLG_LoadMenuDetector.h + Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.cpp + Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.h Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyHeldItemDetector.cpp Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyHeldItemDetector.h Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyMenuDetector.cpp From 2c8cccfc7be9fa88f310399cb597bada905d93c9 Mon Sep 17 00:00:00 2001 From: Dalton-V Date: Tue, 23 Jun 2026 21:33:05 -0500 Subject: [PATCH 2/5] Condense party slot enums --- .../PokemonFRLG_PartyEmptySlotDetector.cpp | 2 ++ .../PokemonFRLG_PartyEmptySlotDetector.h | 3 ++- .../PokemonFRLG_PartyHeldItemDetector.cpp | 16 +++++------ .../Menus/PokemonFRLG_PartyHeldItemDetector.h | 18 ++++--------- .../Menus/PokemonFRLG_PartyMenuDetector.h | 11 +------- .../Inference/Menus/PokemonFRLG_PartySlot.h | 27 +++++++++++++++++++ .../Farming/PokemonFRLG_ItemDuplication.cpp | 2 +- SerialPrograms/cmake/SourceFiles.cmake | 1 + 8 files changed, 47 insertions(+), 33 deletions(-) create mode 100644 SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartySlot.h diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.cpp b/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.cpp index 6f79634a97..5a9cbc57c3 100644 --- a/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.cpp @@ -6,6 +6,7 @@ #include "Common/Cpp/Exceptions.h" #include "CommonTools/Images/SolidColorTest.h" +#include "PokemonFRLG/PokemonFRLG_Settings.h" #include "PokemonFRLG_PartyEmptySlotDetector.h" namespace PokemonAutomation{ @@ -52,4 +53,5 @@ bool PartyEmptySlotDetector::detect(const ImageViewRGB32& screen){ return stats.stddev.sum() < 20.0; } } +} } \ No newline at end of file diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.h b/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.h index e523d101a6..acec6f462e 100644 --- a/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.h +++ b/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.h @@ -7,9 +7,10 @@ #ifndef PokemonAutomation_PokemonFRLG_PartyEmptySlotDetector_H #define PokemonAutomation_PokemonFRLG_PartyEmptySlotDetector_H +#include #include "CommonFramework/VideoPipeline/VideoOverlayScopes.h" #include "CommonTools/VisualDetector.h" -#include "PokemonFRLG_PartyMenuDetector.h" +#include "PokemonFRLG_PartySlot.h" namespace PokemonAutomation{ namespace NintendoSwitch{ diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyHeldItemDetector.cpp b/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyHeldItemDetector.cpp index 7f944b0f74..957b6c2d5b 100644 --- a/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyHeldItemDetector.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyHeldItemDetector.cpp @@ -37,19 +37,19 @@ class PartyHeldItemMatcher : public ImageMatch::WaterfillTemplateMatcher{ } }; -ImageFloatBox PartyHeldItemDetector::box_for_slot(PartyHeldItemSlot slot){ +ImageFloatBox PartyHeldItemDetector::box_for_slot(PartySlot slot){ switch (slot){ - case PartyHeldItemSlot::SLOT_1: + case PartySlot::ONE: return ImageFloatBox(0.069, 0.285, 0.025, 0.050); - case PartyHeldItemSlot::SLOT_2: + case PartySlot::TWO: return ImageFloatBox(0.432, 0.150, 0.025, 0.050); - case PartyHeldItemSlot::SLOT_3: + case PartySlot::THREE: return ImageFloatBox(0.432, 0.3, 0.025, 0.050); - case PartyHeldItemSlot::SLOT_4: + case PartySlot::FOUR: return ImageFloatBox(0.432, 0.45, 0.025, 0.050); - case PartyHeldItemSlot::SLOT_5: + case PartySlot::FIVE: return ImageFloatBox(0.432, 0.6, 0.025, 0.050); - case PartyHeldItemSlot::SLOT_6: + case PartySlot::SIX: return ImageFloatBox(0.432, 0.725, 0.025, 0.050); default: break; @@ -60,7 +60,7 @@ ImageFloatBox PartyHeldItemDetector::box_for_slot(PartyHeldItemSlot slot){ PartyHeldItemDetector::PartyHeldItemDetector( Color color, VideoOverlay* overlay, - PartyHeldItemSlot slot + PartySlot slot ) : m_color(color) , m_overlay(overlay) diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyHeldItemDetector.h b/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyHeldItemDetector.h index 7dae06b1c5..6113a8f5d4 100644 --- a/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyHeldItemDetector.h +++ b/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyHeldItemDetector.h @@ -7,23 +7,15 @@ #ifndef PokemonAutomation_PokemonFRLG_PartyHeldItemDetector_H #define PokemonAutomation_PokemonFRLG_PartyHeldItemDetector_H +#include #include "CommonFramework/VideoPipeline/VideoOverlayScopes.h" #include "CommonTools/VisualDetector.h" +#include "PokemonFRLG_PartySlot.h" namespace PokemonAutomation{ namespace NintendoSwitch{ namespace PokemonFRLG{ - -enum class PartyHeldItemSlot{ - SLOT_1, - SLOT_2, - SLOT_3, - SLOT_4, - SLOT_5, - SLOT_6 -}; - class PartyHeldItemDetector : public StaticScreenDetector{ public: PartyHeldItemDetector( @@ -34,10 +26,10 @@ class PartyHeldItemDetector : public StaticScreenDetector{ PartyHeldItemDetector( Color color, VideoOverlay* overlay, - PartyHeldItemSlot slot + PartySlot slot ); - static ImageFloatBox box_for_slot(PartyHeldItemSlot slot); + static ImageFloatBox box_for_slot(PartySlot slot); const ImageFloatBox& last_detected() const { return m_last_detected; } @@ -69,7 +61,7 @@ class PartyHeldItemWatcher : public DetectorToFinder{ PartyHeldItemWatcher( Color color, VideoOverlay* overlay, - PartyHeldItemSlot slot, + PartySlot slot, std::chrono::milliseconds hold_duration = std::chrono::milliseconds(250) ) : DetectorToFinder("PartyHeldItemWatcher", hold_duration, color, overlay, box_for_slot(slot)) diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyMenuDetector.h b/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyMenuDetector.h index 61dfb64d33..ee17121f4a 100644 --- a/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyMenuDetector.h +++ b/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyMenuDetector.h @@ -14,6 +14,7 @@ #include "CommonTools/VisualDetector.h" #include "CommonTools/InferenceCallbacks/VisualInferenceCallback.h" #include "PokemonFRLG/PokemonFRLG_Settings.h" +#include "PokemonFRLG_PartySlot.h" namespace PokemonAutomation{ class CancellableScope; @@ -21,16 +22,6 @@ namespace PokemonAutomation{ namespace NintendoSwitch{ namespace PokemonFRLG{ -enum class PartySlot{ - ONE, - TWO, - THREE, - FOUR, - FIVE, - SIX - //CXL -}; - // The Party menu has a white box on the bottom // The background around the edges is dark teal/navy class PartyMenuDetector : public StaticScreenDetector{ diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartySlot.h b/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartySlot.h new file mode 100644 index 0000000000..1cd50e2400 --- /dev/null +++ b/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartySlot.h @@ -0,0 +1,27 @@ +/* Party Slot + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#ifndef PokemonAutomation_PokemonFRLG_PartySlot_H +#define PokemonAutomation_PokemonFRLG_PartySlot_H + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonFRLG{ + +enum class PartySlot{ + ONE, + TWO, + THREE, + FOUR, + FIVE, + SIX + //CXL +}; + +} +} +} +#endif diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/Farming/PokemonFRLG_ItemDuplication.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/Farming/PokemonFRLG_ItemDuplication.cpp index 14d3a6f42f..970c423420 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/Farming/PokemonFRLG_ItemDuplication.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Programs/Farming/PokemonFRLG_ItemDuplication.cpp @@ -86,7 +86,7 @@ void ItemDuplication::program(SingleSwitchProgramEnvironment& env, ProController ImageFloatBox mail_arrow_box{ 0.3670769231, 0.06373076639, 0.028, 0.077 }; ImageFloatBox mail_confirmation_arrow_box{ 0.7289230769, 0.4604230588, 0.029, 0.076 }; SelectionArrowWatcher mail_selection_arrow(COLOR_BLUE, &env.console.overlay(), mail_arrow_box); - PartyHeldItemWatcher farfetchd_held_item(COLOR_BLUE, &env.console.overlay(), PartyHeldItemSlot::SLOT_1); + PartyHeldItemWatcher farfetchd_held_item(COLOR_BLUE, &env.console.overlay(), PartySlot::ONE); AdvanceWhiteDialogWatcher item_description(COLOR_BLUE); SelectionArrowWatcher confirmation_arrow(COLOR_BLUE, &env.console.overlay(), SelectionArrowPositionConfirmationMenu::YES); SelectionArrowWatcher mail_confirmation_arrow(COLOR_BLUE, &env.console.overlay(), mail_confirmation_arrow_box); diff --git a/SerialPrograms/cmake/SourceFiles.cmake b/SerialPrograms/cmake/SourceFiles.cmake index 0311f25332..95e9cc92d5 100644 --- a/SerialPrograms/cmake/SourceFiles.cmake +++ b/SerialPrograms/cmake/SourceFiles.cmake @@ -1478,6 +1478,7 @@ file(GLOB LIBRARY_SOURCES Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyHeldItemDetector.h Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyMenuDetector.cpp Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyMenuDetector.h + Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartySlot.h Source/PokemonFRLG/Inference/Menus/PokemonFRLG_TrainerCardDetector.cpp Source/PokemonFRLG/Inference/Menus/PokemonFRLG_TrainerCardDetector.h Source/PokemonFRLG/Inference/Menus/PokemonFRLG_DexRegistrationDetector.cpp From ccf8410905d71a3521b1278af8ad5cafc0bd5e3f Mon Sep 17 00:00:00 2001 From: Dalton-V Date: Tue, 23 Jun 2026 22:09:18 -0500 Subject: [PATCH 3/5] Add helper method for finding last occupied party slot --- .../PokemonFRLG_PartyEmptySlotDetector.cpp | 2 -- .../PokemonFRLG_PartyEmptySlotDetector.h | 13 ----------- .../PokemonFRLG/PokemonFRLG_Navigation.cpp | 22 +++++++++++++++++++ .../PokemonFRLG/PokemonFRLG_Navigation.h | 4 ++++ 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.cpp b/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.cpp index 5a9cbc57c3..a2f98f749b 100644 --- a/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.cpp @@ -35,11 +35,9 @@ ImageFloatBox PartyEmptySlotDetector::box_for_slot(PartySlot slot){ PartyEmptySlotDetector::PartyEmptySlotDetector( Color color, - VideoOverlay* overlay, PartySlot slot ) : m_color(color) - , m_overlay(overlay) , m_box(box_for_slot(slot)) {} void PartyEmptySlotDetector::make_overlays(VideoOverlaySet& items) const{ diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.h b/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.h index acec6f462e..765801d94b 100644 --- a/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.h +++ b/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.h @@ -20,7 +20,6 @@ class PartyEmptySlotDetector : public StaticScreenDetector{ public: PartyEmptySlotDetector( Color color, - VideoOverlay* overlay, PartySlot slot ); static ImageFloatBox box_for_slot(PartySlot slot); @@ -30,20 +29,8 @@ class PartyEmptySlotDetector : public StaticScreenDetector{ private: Color m_color; - VideoOverlay* m_overlay; ImageFloatBox m_box; }; -class PartyEmptySlotWatcher : public DetectorToFinder{ -public: - PartyEmptySlotWatcher( - Color color, - VideoOverlay* overlay, - PartySlot slot, - std::chrono::milliseconds hold_duration = std::chrono::milliseconds(250) - ) - : DetectorToFinder("PartyEmptySlotWatcher", hold_duration, color, overlay, slot) - {} -}; } } diff --git a/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.cpp b/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.cpp index ff017e0744..44043f982e 100644 --- a/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.cpp +++ b/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.cpp @@ -6,6 +6,7 @@ * */ +#include #include "CommonFramework/Exceptions/OperationFailedException.h" #include "CommonFramework/VideoPipeline/VideoFeed.h" #include "CommonTools/Random.h" @@ -33,6 +34,7 @@ #include "PokemonFRLG/Inference/PokemonFRLG_BattlePokemonDetector.h" #include "PokemonFRLG/Programs/PokemonFRLG_StartMenuNavigation.h" #include "PokemonFRLG_Navigation.h" +#include "Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.h" namespace PokemonAutomation{ namespace NintendoSwitch{ @@ -755,6 +757,26 @@ void open_party_menu_from_overworld(ConsoleHandle& console, ProControllerContext } } +PartySlot detect_last_occupied_party_slot(ConsoleHandle& console){ + const auto snapshot = console.video().snapshot(); + constexpr std::array slots{ + PartySlot::SIX, + PartySlot::FIVE, + PartySlot::FOUR, + PartySlot::THREE, + PartySlot::TWO, + }; + + for (PartySlot slot : slots){ + PartyEmptySlotDetector empty_slot_detector(COLOR_RED, slot); + if (!empty_slot_detector.detect(snapshot)){ + return slot; + } + } + + return PartySlot::ONE; +} + void open_bag_from_overworld(ConsoleHandle& console, ProControllerContext& context, StartMenuContext menu_context){ uint16_t errors = 0; bool start_menu_is_open = false; diff --git a/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.h b/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.h index b5a3ac3177..959b5ae19f 100644 --- a/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.h +++ b/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.h @@ -11,6 +11,7 @@ #include "CommonFramework/Tools/VideoStream.h" #include "NintendoSwitch/Controllers/Procon/NintendoSwitch_ProController.h" +#include "Inference/Menus/PokemonFRLG_PartySlot.h" namespace PokemonAutomation{ namespace NintendoSwitch{ @@ -80,6 +81,9 @@ enum class StartMenuContext { }; void open_party_menu_from_overworld(ConsoleHandle& console, ProControllerContext& context, StartMenuContext menu_context = StartMenuContext::STANDARD); +// Starting from the party menu, detect the last occupied party slot +PartySlot detect_last_occupied_party_slot(ConsoleHandle& console); + // Starting from the start menu, a sub-screen of the start menu, or the overworld, navigate to the bag void open_bag_from_overworld(ConsoleHandle& console, ProControllerContext& context, StartMenuContext menu_context = StartMenuContext::STANDARD); From 3e1880e7ca762403da02872e8e220184fbe832cc Mon Sep 17 00:00:00 2001 From: Dalton-V Date: Tue, 23 Jun 2026 22:45:21 -0500 Subject: [PATCH 4/5] Update boxes --- .../Menus/PokemonFRLG_PartyEmptySlotDetector.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.cpp b/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.cpp index a2f98f749b..4b9e2f191d 100644 --- a/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.cpp @@ -18,15 +18,15 @@ ImageFloatBox PartyEmptySlotDetector::box_for_slot(PartySlot slot){ case PartySlot::ONE: throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "Invalid FRLG Party Empty Slot. Slot 1 should always be occupied."); case PartySlot::TWO: - return ImageFloatBox(0.432, 0.150, 0.025, 0.050); + return ImageFloatBox(0.709, 0.078, 0.01, 0.018); case PartySlot::THREE: - return ImageFloatBox(0.432, 0.3, 0.025, 0.050); + return ImageFloatBox(0.709, 0.228, 0.01, 0.018); case PartySlot::FOUR: - return ImageFloatBox(0.432, 0.45, 0.025, 0.050); + return ImageFloatBox(0.709, 0.378, 0.01, 0.018); case PartySlot::FIVE: - return ImageFloatBox(0.432, 0.6, 0.025, 0.050); + return ImageFloatBox(0.709, 0.527, 0.01, 0.018); case PartySlot::SIX: - return ImageFloatBox(0.432, 0.725, 0.025, 0.050); + return ImageFloatBox(0.709, 0.677, 0.01, 0.018); default: break; } @@ -48,7 +48,7 @@ bool PartyEmptySlotDetector::detect(const ImageViewRGB32& screen){ const BoxOption& GAME_BOX = GameSettings::instance().GAME_BOX; ImageViewRGB32 game_screen = extract_box_reference(screen, GAME_BOX); const auto stats = image_stats(extract_box_reference(game_screen, m_box)); - return stats.stddev.sum() < 20.0; + return stats.stddev.sum() > 20.0; } } } From b151f81d63e46bf876092496507eee6df0ddb4fb Mon Sep 17 00:00:00 2001 From: Dalton-V Date: Tue, 23 Jun 2026 22:52:36 -0500 Subject: [PATCH 5/5] cleanup --- SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.cpp | 4 ++-- SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.cpp b/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.cpp index 44043f982e..4282fb9efe 100644 --- a/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.cpp +++ b/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.cpp @@ -25,16 +25,16 @@ #include "PokemonFRLG/Inference/Dialogs/PokemonFRLG_BattleDialogs.h" #include "PokemonFRLG/Inference/Dialogs/PokemonFRLG_PartyDialogs.h" #include "PokemonFRLG/Inference/Sounds/PokemonFRLG_ShinySoundDetector.h" +#include "PokemonFRLG/Inference/Menus/PokemonFRLG_BagDetector.h" #include "PokemonFRLG/Inference/Menus/PokemonFRLG_StartMenuDetector.h" #include "PokemonFRLG/Inference/Menus/PokemonFRLG_LoadMenuDetector.h" #include "PokemonFRLG/Inference/Menus/PokemonFRLG_SummaryDetector.h" +#include "PokemonFRLG/Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.h" #include "PokemonFRLG/Inference/Menus/PokemonFRLG_PartyMenuDetector.h" -#include "PokemonFRLG/Inference/Menus/PokemonFRLG_BagDetector.h" #include "PokemonFRLG/Inference/Map/PokemonFRLG_MapDetector.h" #include "PokemonFRLG/Inference/PokemonFRLG_BattlePokemonDetector.h" #include "PokemonFRLG/Programs/PokemonFRLG_StartMenuNavigation.h" #include "PokemonFRLG_Navigation.h" -#include "Inference/Menus/PokemonFRLG_PartyEmptySlotDetector.h" namespace PokemonAutomation{ namespace NintendoSwitch{ diff --git a/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.h b/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.h index 959b5ae19f..fbeedc9479 100644 --- a/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.h +++ b/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.h @@ -11,7 +11,7 @@ #include "CommonFramework/Tools/VideoStream.h" #include "NintendoSwitch/Controllers/Procon/NintendoSwitch_ProController.h" -#include "Inference/Menus/PokemonFRLG_PartySlot.h" +#include "PokemonFRLG/Inference/Menus/PokemonFRLG_PartySlot.h" namespace PokemonAutomation{ namespace NintendoSwitch{