From d94198a5efd47ab1b5ca5b04bd4bcf72405edbea Mon Sep 17 00:00:00 2001 From: theAstrogoth Date: Sun, 26 Apr 2026 04:04:58 -0500 Subject: [PATCH] add bag, party menu dialog detectors --- .../Dialogs/PokemonFRLG_PartyDialogs.cpp | 122 ++++++++++++++++++ .../Dialogs/PokemonFRLG_PartyDialogs.h | 99 ++++++++++++++ .../Menus/PokemonFRLG_BagDetector.cpp | 61 +++++++++ .../Inference/Menus/PokemonFRLG_BagDetector.h | 50 +++++++ .../Menus/PokemonFRLG_PartyMenuDetector.cpp | 25 ---- .../Menus/PokemonFRLG_PartyMenuDetector.h | 20 --- .../PokemonFRLG_PartyLevelUpReader.cpp | 94 ++++++++++++++ .../PokemonFRLG_PartyLevelUpReader.h | 53 ++++++++ .../PokemonFRLG/PokemonFRLG_Navigation.cpp | 1 + .../Farming/PokemonFRLG_EvTrainer.cpp | 1 + .../Farming/PokemonFRLG_PickupFarmer.cpp | 1 + SerialPrograms/cmake/SourceFiles.cmake | 6 + 12 files changed, 488 insertions(+), 45 deletions(-) create mode 100644 SerialPrograms/Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_PartyDialogs.cpp create mode 100644 SerialPrograms/Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_PartyDialogs.h create mode 100644 SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_BagDetector.cpp create mode 100644 SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_BagDetector.h create mode 100644 SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_PartyLevelUpReader.cpp create mode 100644 SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_PartyLevelUpReader.h diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_PartyDialogs.cpp b/SerialPrograms/Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_PartyDialogs.cpp new file mode 100644 index 0000000000..4cdfb3b203 --- /dev/null +++ b/SerialPrograms/Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_PartyDialogs.cpp @@ -0,0 +1,122 @@ +/* Party Dialog Detectors + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#include "CommonTools/Images/SolidColorTest.h" +#include "CommonTools/Images/ImageFilter.h" +#include "PokemonFRLG/PokemonFRLG_Settings.h" +#include "PokemonFRLG_PartyDialogs.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonFRLG{ + + +PartySelectionDetector::PartySelectionDetector(Color color) + : m_dialog_right_box(0.955, 0.648, 0.010, 0.303) + , m_page_background_box(0.028, 0.500, 0.010, 0.250) +{} +void PartySelectionDetector::make_overlays(VideoOverlaySet& items) const{ + const BoxOption& GAME_BOX = GameSettings::instance().GAME_BOX; + items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_dialog_right_box)); + items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_page_background_box)); +} +bool PartySelectionDetector::detect(const ImageViewRGB32& screen){ + ImageViewRGB32 game_screen = extract_box_reference(screen, GameSettings::instance().GAME_BOX); + + //Dialog is white + ImageViewRGB32 dialog_right_image = extract_box_reference(game_screen, m_dialog_right_box); + + //Menu background is teal + ImageViewRGB32 menu_background_image = extract_box_reference(game_screen, m_page_background_box); + + if (is_white(dialog_right_image) + && is_solid(menu_background_image, { 0.020, 0.424, 0.412 }, 0.25, 20) //5, 108, 105 teal + ){ + return true; + } + return false; +} + + +PartyLevelUpDetector::PartyLevelUpDetector(Color color, PartyLevelUpDialog dialog_type) + : dialog_type(dialog_type) + , m_border_top_box(0.619231, 0.023038, 0.362179, 0.001923) // gray (120, 115, 140) + , m_border_right_box(0.982692, 0.025923, 0.001923, 0.597115) + , m_dialog_top_box(0.626282, 0.042492, 0.341026, 0.006175) // white + , m_dialog_right_box(0.967949, 0.050923, 0.003846, 0.550962) + , m_plus_box(0.862663, 0.051852, 0.034267, 0.553560) +{} +void PartyLevelUpDetector::make_overlays(VideoOverlaySet& items) const{ + const BoxOption& GAME_BOX = GameSettings::instance().GAME_BOX; + items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_border_top_box)); + items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_border_right_box)); + items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_dialog_top_box)); + items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_dialog_right_box)); +} +bool PartyLevelUpDetector::detect(const ImageViewRGB32& screen){ + ImageViewRGB32 game_screen = extract_box_reference(screen, GameSettings::instance().GAME_BOX); + + ImageViewRGB32 border_top_image = extract_box_reference(game_screen, m_border_top_box); + ImageViewRGB32 border_right_image = extract_box_reference(game_screen, m_border_right_box); + + ImageViewRGB32 dialog_top_image = extract_box_reference(game_screen, m_dialog_top_box); + ImageViewRGB32 dialog_right_image = extract_box_reference(game_screen, m_dialog_right_box); + + //Plus box is not solid white on the first screen, but is white on the second one + ImageViewRGB32 plus_image = extract_box_reference(game_screen, m_plus_box); + bool good_plus_image = ( + dialog_type == PartyLevelUpDialog::either + || (dialog_type == PartyLevelUpDialog::plus && !is_white(plus_image)) + || (dialog_type == PartyLevelUpDialog::stats && is_white(plus_image)) + ); + + if (is_solid(border_top_image, { 0.320, 0.307, 0.373 }, 0.25, 20) + && is_solid(border_right_image, { 0.320, 0.307, 0.373 }, 0.25, 20) + && is_white(dialog_top_image) + && is_white(dialog_right_image) + && good_plus_image + ){ + return true; + } + return false; +} + +PartyMoveLearnDetector::PartyMoveLearnDetector(Color color) + : m_border_top_box(0.685096, 0.422836, 0.229327, 0.002163) // gray (120, 115, 140) + , m_border_right_box(0.916346, 0.426442, 0.001442, 0.245913) + , m_dialog_top_box(0.699038, 0.445913, 0.200000, 0.006490) // white + , m_dialog_right_box(0.899519, 0.454567, 0.004327, 0.194712) +{} +void PartyMoveLearnDetector::make_overlays(VideoOverlaySet& items) const{ + const BoxOption& GAME_BOX = GameSettings::instance().GAME_BOX; + items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_border_top_box)); + items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_border_right_box)); + items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_dialog_top_box)); + items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_dialog_right_box)); +} +bool PartyMoveLearnDetector::detect(const ImageViewRGB32& screen){ + ImageViewRGB32 game_screen = extract_box_reference(screen, GameSettings::instance().GAME_BOX); + + ImageViewRGB32 border_top_image = extract_box_reference(game_screen, m_border_top_box); + ImageViewRGB32 border_right_image = extract_box_reference(game_screen, m_border_right_box); + + ImageViewRGB32 dialog_top_image = extract_box_reference(game_screen, m_dialog_top_box); + ImageViewRGB32 dialog_right_image = extract_box_reference(game_screen, m_dialog_right_box); + + if (is_solid(border_top_image, { 0.320, 0.307, 0.373 }, 0.25, 20) + && is_solid(border_right_image, { 0.320, 0.307, 0.373 }, 0.25, 20) + && is_white(dialog_top_image) + && is_white(dialog_right_image) + ){ + return true; + } + return false; +} + + +} +} +} diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_PartyDialogs.h b/SerialPrograms/Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_PartyDialogs.h new file mode 100644 index 0000000000..4d6e711112 --- /dev/null +++ b/SerialPrograms/Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_PartyDialogs.h @@ -0,0 +1,99 @@ +/* Party Dialog Detectors + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#ifndef PokemonAutomation_PokemonFRLG_PartyDialogs_H +#define PokemonAutomation_PokemonFRLG_PartyDialogs_H + +#include +#include "Common/Cpp/Color.h" +#include "CommonFramework/ImageTools/ImageBoxes.h" +#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h" +#include "CommonTools/VisualDetector.h" +#include "CommonTools/InferenceCallbacks/VisualInferenceCallback.h" + +namespace PokemonAutomation{ + class CancellableScope; + class VideoFeed; +namespace NintendoSwitch{ +namespace PokemonFRLG{ + + +// The Party menu has a white box in the bottom right corner when a Pokemon is selected +// The background around the edges is dark teal/navy +class PartySelectionDetector : public StaticScreenDetector{ +public: + PartySelectionDetector(Color color); + + virtual void make_overlays(VideoOverlaySet& items) const override; + virtual bool detect(const ImageViewRGB32& screen) override; + +private: + ImageFloatBox m_dialog_right_box; + ImageFloatBox m_page_background_box; +}; +class PartySelectionWatcher : public DetectorToFinder{ +public: + PartySelectionWatcher(Color color) + : DetectorToFinder("PartySelectionWatcher", std::chrono::milliseconds(250), color) + {} +}; + +enum class PartyLevelUpDialog{ + plus, + stats, + either +}; + +class PartyLevelUpDetector : public StaticScreenDetector{ +public: + PartyLevelUpDetector(Color color, PartyLevelUpDialog dialog_type); + + virtual void make_overlays(VideoOverlaySet& items) const override; + virtual bool detect(const ImageViewRGB32& screen) override; + +private: + PartyLevelUpDialog dialog_type; + ImageFloatBox m_border_top_box; + ImageFloatBox m_border_right_box; + ImageFloatBox m_dialog_top_box; + ImageFloatBox m_dialog_right_box; + ImageFloatBox m_plus_box; +}; +class PartyLevelUpWatcher : public DetectorToFinder{ +public: + PartyLevelUpWatcher(Color color, PartyLevelUpDialog dialog_type) + : DetectorToFinder("BattleLevelUpWatcher", std::chrono::milliseconds(250), color, dialog_type) + {} +}; + + +class PartyMoveLearnDetector : public StaticScreenDetector{ +public: + PartyMoveLearnDetector(Color color); + + virtual void make_overlays(VideoOverlaySet& items) const override; + virtual bool detect(const ImageViewRGB32& screen) override; + +private: + ImageFloatBox m_border_top_box; + ImageFloatBox m_border_right_box; + ImageFloatBox m_dialog_top_box; + ImageFloatBox m_dialog_right_box; +}; +class PartyMoveLearnWatcher : public DetectorToFinder{ +public: + PartyMoveLearnWatcher(Color color) + : DetectorToFinder("PartyMoveLearnWatcher", std::chrono::milliseconds(250), color) + {} +}; + + + +} +} +} + +#endif diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_BagDetector.cpp b/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_BagDetector.cpp new file mode 100644 index 0000000000..750e72d2f3 --- /dev/null +++ b/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_BagDetector.cpp @@ -0,0 +1,61 @@ +/* Bag Detector + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#include "Common/Cpp/Exceptions.h" +#include "CommonFramework/ImageTools/ImageBoxes.h" +#include "CommonFramework/ImageTypes/ImageRGB32.h" +#include "CommonFramework/ImageTools/ImageStats.h" +#include "CommonFramework/ImageTypes/ImageViewRGB32.h" +#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h" +#include "CommonTools/Images/SolidColorTest.h" +#include "CommonTools/Images/ImageFilter.h" +#include "CommonTools/Images/WaterfillUtilities.h" +#include "PokemonFRLG_BagDetector.h" + + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonFRLG{ + + +BagDetector::BagDetector(Color color) + : m_bag_shadow_box(0.130769, 0.594471, 0.070192, 0.015865) + , m_pocket_underline_box(0.043269, 0.137259, 0.279808, 0.005769) + , m_menu_top_box(0.029808, 0.029086, 0.947115, 0.003606) + , m_menu_right_box(0.977404, 0.034134, 0.005288, 0.597837) +{} +void BagDetector::make_overlays(VideoOverlaySet& items) const{ + const BoxOption& GAME_BOX = GameSettings::instance().GAME_BOX; + items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_bag_shadow_box)); // Gray RGB(159, 159, 159) + items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_pocket_underline_box)); // Orange RGB(255, 152, 50) + items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_menu_top_box)); // Yellow RGB(255, 225, 93) + items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_menu_right_box)); // Yellow + +} +bool BagDetector::detect(const ImageViewRGB32& screen){ + ImageViewRGB32 game_screen = extract_box_reference(screen, GameSettings::instance().GAME_BOX); + + ImageViewRGB32 bag_shadow_image = extract_box_reference(game_screen, m_bag_shadow_box); + ImageViewRGB32 pocket_underline_image = extract_box_reference(game_screen, m_pocket_underline_box); + ImageViewRGB32 menu_top_image = extract_box_reference(game_screen, m_menu_top_box); + ImageViewRGB32 menu_right_image = extract_box_reference(game_screen, m_menu_right_box); + + + if ( is_solid(bag_shadow_image, { 0.333, 0.333, 0.333 }, 0.25, 20) + && is_solid(pocket_underline_image, { 0.558, 0.333, 0.109 }, 0.25, 20) + && is_solid(menu_top_image, { 0.445, 0.393, 0.162 }, 0.25, 20) + && is_solid(menu_right_image, { 0.445, 0.393, 0.162 }, 0.25, 20) + ){ + return true; + } + return false; +} + + + +} +} +} diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_BagDetector.h b/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_BagDetector.h new file mode 100644 index 0000000000..03b855da49 --- /dev/null +++ b/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_BagDetector.h @@ -0,0 +1,50 @@ +/* Bag Detector + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#ifndef PokemonAutomation_PokemonFRLG_BagDetector_H +#define PokemonAutomation_PokemonFRLG_BagDetector_H + +#include +#include "Common/Cpp/Color.h" +#include "CommonFramework/ImageTools/ImageBoxes.h" +#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h" +#include "CommonTools/VisualDetector.h" +#include "CommonTools/InferenceCallbacks/VisualInferenceCallback.h" +#include "PokemonFRLG/PokemonFRLG_Settings.h" + +namespace PokemonAutomation{ + class CancellableScope; + class VideoFeed; +namespace NintendoSwitch{ +namespace PokemonFRLG{ + +class BagDetector : public StaticScreenDetector{ +public: + BagDetector(Color color); + + virtual void make_overlays(VideoOverlaySet& items) const override; + virtual bool detect(const ImageViewRGB32& screen) override; + +private: + ImageFloatBox m_bag_shadow_box; + ImageFloatBox m_pocket_underline_box; + ImageFloatBox m_menu_top_box; + ImageFloatBox m_menu_right_box; +}; +class BagWatcher : public DetectorToFinder{ +public: + BagWatcher(Color color) + : DetectorToFinder("BagWatcher", std::chrono::milliseconds(250), color) + {} +}; + + + +} +} +} + +#endif diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyMenuDetector.cpp b/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyMenuDetector.cpp index 7ea3981ccf..593cc85a81 100644 --- a/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyMenuDetector.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyMenuDetector.cpp @@ -47,31 +47,6 @@ bool PartyMenuDetector::detect(const ImageViewRGB32& screen){ return false; } -PartySelectionDetector::PartySelectionDetector(Color color) - : m_dialog_right_box(0.955, 0.648, 0.010, 0.303) - , m_page_background_box(0.028, 0.500, 0.010, 0.250) -{} -void PartySelectionDetector::make_overlays(VideoOverlaySet& items) const{ - const BoxOption& GAME_BOX = GameSettings::instance().GAME_BOX; - items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_dialog_right_box)); - items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_page_background_box)); -} -bool PartySelectionDetector::detect(const ImageViewRGB32& screen){ - ImageViewRGB32 game_screen = extract_box_reference(screen, GameSettings::instance().GAME_BOX); - - //Dialog is white - ImageViewRGB32 dialog_right_image = extract_box_reference(game_screen, m_dialog_right_box); - - //Menu background is teal - ImageViewRGB32 menu_background_image = extract_box_reference(game_screen, m_page_background_box); - - if (is_white(dialog_right_image) - && is_solid(menu_background_image, { 0.020, 0.424, 0.412 }, 0.25, 20) //5, 108, 105 teal - ){ - return true; - } - return false; -} ImageFloatBox PartySlotDetector::party_slot_boxes(PartySlot position){ switch (position){ diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyMenuDetector.h b/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyMenuDetector.h index 74ab616a60..61dfb64d33 100644 --- a/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyMenuDetector.h +++ b/SerialPrograms/Source/PokemonFRLG/Inference/Menus/PokemonFRLG_PartyMenuDetector.h @@ -51,26 +51,6 @@ class PartyMenuWatcher : public DetectorToFinder{ {} }; -// The Party menu has a white box in the bottom right corner when a Pokemon is selected -// The background around the edges is dark teal/navy -class PartySelectionDetector : public StaticScreenDetector{ -public: - PartySelectionDetector(Color color); - - virtual void make_overlays(VideoOverlaySet& items) const override; - virtual bool detect(const ImageViewRGB32& screen) override; - -private: - ImageFloatBox m_dialog_right_box; - ImageFloatBox m_page_background_box; -}; -class PartySelectionWatcher : public DetectorToFinder{ -public: - PartySelectionWatcher(Color color) - : DetectorToFinder("PartySelectionWatcher", std::chrono::milliseconds(250), color) - {} -}; - class PartySlotDetector : public StaticScreenDetector{ public: diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_PartyLevelUpReader.cpp b/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_PartyLevelUpReader.cpp new file mode 100644 index 0000000000..ab2c887752 --- /dev/null +++ b/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_PartyLevelUpReader.cpp @@ -0,0 +1,94 @@ +/* Party Level Up Reader + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#include +#include "Common/Cpp/Color.h" +#include "Common/Cpp/Exceptions.h" +#include "CommonFramework/GlobalSettingsPanel.h" +#include "CommonFramework/ImageTypes/ImageViewRGB32.h" +#include "CommonFramework/Tools/GlobalThreadPools.h" +#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h" +#include "CommonTools/Images/ImageFilter.h" +#include "CommonTools/Images/ImageManip.h" +#include "CommonTools/OCR/OCR_NumberReader.h" +#include "CommonTools/OCR/OCR_Routines.h" +#include "Pokemon/Pokemon_StatsCalculation.h" +#include "Pokemon/Inference/Pokemon_NameReader.h" +#include "Pokemon/Inference/Pokemon_NatureReader.h" +#include "PokemonFRLG/PokemonFRLG_Settings.h" +#include "PokemonFRLG_DigitReader.h" +#include "PokemonFRLG_PartyLevelUpReader.h" + + +namespace PokemonAutomation { +namespace NintendoSwitch { +namespace PokemonFRLG { + + +PartyLevelUpReader::PartyLevelUpReader(Color color) + : m_color(color) + , m_box_hp(0.904069, 0.051852, 0.068535, 0.079387) + , m_box_attack(0.904069, 0.145052, 0.068535, 0.079387) + , m_box_defense(0.904069, 0.238252, 0.068535, 0.079387) + , m_box_sp_attack(0.904069, 0.331452, 0.068535, 0.079387) + , m_box_sp_defense(0.904069, 0.424652, 0.068535, 0.079387) + , m_box_speed(0.904069, 0.517852, 0.068535, 0.0793879) +{} + +void PartyLevelUpReader::make_overlays(VideoOverlaySet &items) const { + const BoxOption &GAME_BOX = GameSettings::instance().GAME_BOX; + items.add(m_color, GAME_BOX.inner_to_outer(m_box_hp)); + items.add(m_color, GAME_BOX.inner_to_outer(m_box_attack)); + items.add(m_color, GAME_BOX.inner_to_outer(m_box_defense)); + items.add(m_color, GAME_BOX.inner_to_outer(m_box_sp_attack)); + items.add(m_color, GAME_BOX.inner_to_outer(m_box_sp_defense)); + items.add(m_color, GAME_BOX.inner_to_outer(m_box_speed)); +} + +StatReads PartyLevelUpReader::read_stats(Logger &logger, const ImageViewRGB32& frame) const{ + ImageViewRGB32 game_screen = + extract_box_reference(frame, GameSettings::instance().GAME_BOX); + + auto read_stat = [&](const ImageFloatBox &box, const std::string &name){ + ImageViewRGB32 stat_region = extract_box_reference(game_screen, box); + + if (!GlobalSettings::instance().USE_PADDLE_OCR){ + // Tesseract-free path: waterfill segmentation + template matching + // against the PokemonFRLG/Digits/0-9.png templates. + return read_digits_waterfill_template(logger, stat_region); + } + + // PaddleOCR path (original): preprocess then per-digit waterfill OCR. + // Dark text [0..190] -> black. Threshold at 190 captures the + // blurred gap pixels between segments, making bridges thicker. + // Not higher than 190 to avoid capturing yellow bg edge noise. + ImageRGB32 ocr_ready = preprocess_for_ocr( + stat_region, name, 7, 2, true, + combine_rgb(0, 0, 0), combine_rgb(190, 190, 190) + ); + + // Waterfill isolates each digit -> per-char SINGLE_CHAR OCR. + return OCR::read_number_waterfill( + logger, ocr_ready, 0xff000000, + 0xff808080 + ); + }; + + StatReads stats; + stats.hp = uint16_t(read_stat(m_box_hp, "hp")); + stats.attack = uint16_t(read_stat(m_box_attack, "attack")); + stats.defense = uint16_t(read_stat(m_box_defense, "defense")); + stats.spatk = uint16_t(read_stat(m_box_sp_attack, "spatk")); + stats.spdef = uint16_t(read_stat(m_box_sp_defense, "spdef")); + stats.speed = uint16_t(read_stat(m_box_speed, "speed")); + return stats; +} + + +} // namespace PokemonFRLG +} // namespace NintendoSwitch +} // namespace PokemonAutomation + diff --git a/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_PartyLevelUpReader.h b/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_PartyLevelUpReader.h new file mode 100644 index 0000000000..a9edfd344d --- /dev/null +++ b/SerialPrograms/Source/PokemonFRLG/Inference/PokemonFRLG_PartyLevelUpReader.h @@ -0,0 +1,53 @@ +/* Party Level Up Reader + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#ifndef PokemonAutomation_PokemonFRLG_PartyLevelUpReader_H +#define PokemonAutomation_PokemonFRLG_PartyLevelUpReader_H + +#include +#include +#include "Common/Cpp/Color.h" +#include "CommonFramework/ImageTools/ImageBoxes.h" +#include "CommonFramework/Language.h" +#include "Pokemon/Pokemon_StatsCalculation.h" + + +namespace PokemonAutomation{ + +class Logger; +class ImageViewRGB32; +class VideoOverlaySet; + +namespace NintendoSwitch{ +namespace PokemonFRLG{ + +using namespace Pokemon; + + +class PartyLevelUpReader { +public: + PartyLevelUpReader(Color color = COLOR_RED); + + void make_overlays(VideoOverlaySet &items) const; + + StatReads read_stats(Logger &logger, const ImageViewRGB32& frame) const; + +private: + Color m_color; + ImageFloatBox m_box_hp; + ImageFloatBox m_box_attack; + ImageFloatBox m_box_defense; + ImageFloatBox m_box_sp_attack; + ImageFloatBox m_box_sp_defense; + ImageFloatBox m_box_speed; + +}; + +} // namespace PokemonFRLG +} // namespace NintendoSwitch +} // namespace PokemonAutomation +#endif + diff --git a/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.cpp b/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.cpp index d8d9f24d3a..29fe872e2d 100644 --- a/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.cpp +++ b/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.cpp @@ -20,6 +20,7 @@ #include "PokemonFRLG/PokemonFRLG_Settings.h" #include "PokemonFRLG/Inference/Dialogs/PokemonFRLG_DialogDetector.h" #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_StartMenuDetector.h" #include "PokemonFRLG/Inference/Menus/PokemonFRLG_LoadMenuDetector.h" diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/Farming/PokemonFRLG_EvTrainer.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/Farming/PokemonFRLG_EvTrainer.cpp index 7092392528..a3212a04cb 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/Farming/PokemonFRLG_EvTrainer.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Programs/Farming/PokemonFRLG_EvTrainer.cpp @@ -19,6 +19,7 @@ #include "NintendoSwitch/Commands/NintendoSwitch_Commands_Superscalar.h" #include "PokemonFRLG/Inference/Dialogs/PokemonFRLG_DialogDetector.h" #include "PokemonFRLG/Inference/Dialogs/PokemonFRLG_BattleDialogs.h" +#include "PokemonFRLG/Inference/Dialogs/PokemonFRLG_PartyDialogs.h" #include "PokemonFRLG/Inference/Menus/PokemonFRLG_PartyMenuDetector.h" #include "PokemonFRLG/Programs/PokemonFRLG_StartMenuNavigation.h" #include "Pokemon/Inference/Pokemon_NameReader.h" diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/Farming/PokemonFRLG_PickupFarmer.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/Farming/PokemonFRLG_PickupFarmer.cpp index 75ed895b7f..9f93faa7d7 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/Farming/PokemonFRLG_PickupFarmer.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Programs/Farming/PokemonFRLG_PickupFarmer.cpp @@ -15,6 +15,7 @@ #include "Pokemon/Pokemon_Strings.h" #include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" #include "PokemonFRLG/Inference/Dialogs/PokemonFRLG_BattleDialogs.h" +#include "PokemonFRLG/Inference/Dialogs/PokemonFRLG_PartyDialogs.h" #include "PokemonFRLG/Inference/Menus/PokemonFRLG_PartyMenuDetector.h" #include "PokemonFRLG/Programs/PokemonFRLG_StartMenuNavigation.h" #include "PokemonFRLG/PokemonFRLG_Navigation.h" diff --git a/SerialPrograms/cmake/SourceFiles.cmake b/SerialPrograms/cmake/SourceFiles.cmake index ce2cc9b5b7..db3d5241ec 100644 --- a/SerialPrograms/cmake/SourceFiles.cmake +++ b/SerialPrograms/cmake/SourceFiles.cmake @@ -1448,6 +1448,8 @@ file(GLOB LIBRARY_SOURCES Source/PokemonBDSP/Resources/PokemonBDSP_NameDatabase.h Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_BattleDialogs.cpp Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_BattleDialogs.h + Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_PartyDialogs.cpp + Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_PartyDialogs.h Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_DialogDetector.cpp Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_DialogDetector.h Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_PrizeSelectDetector.cpp @@ -1458,6 +1460,8 @@ file(GLOB LIBRARY_SOURCES Source/PokemonFRLG/Inference/Menus/PokemonFRLG_StartMenuDetector.h Source/PokemonFRLG/Inference/Menus/PokemonFRLG_SummaryDetector.cpp Source/PokemonFRLG/Inference/Menus/PokemonFRLG_SummaryDetector.h + Source/PokemonFRLG/Inference/Menus/PokemonFRLG_BagDetector.cpp + 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_PartyHeldItemDetector.cpp @@ -1480,6 +1484,8 @@ file(GLOB LIBRARY_SOURCES Source/PokemonFRLG/Inference/PokemonFRLG_StatsReader.h Source/PokemonFRLG/Inference/PokemonFRLG_BattleLevelUpReader.cpp Source/PokemonFRLG/Inference/PokemonFRLG_BattleLevelUpReader.h + Source/PokemonFRLG/Inference/PokemonFRLG_PartyLevelUpReader.cpp + Source/PokemonFRLG/Inference/PokemonFRLG_PartyLevelUpReader.h Source/PokemonFRLG/Inference/PokemonFRLG_TrainerIdReader.cpp Source/PokemonFRLG/Inference/PokemonFRLG_TrainerIdReader.h Source/PokemonFRLG/Inference/PokemonFRLG_BattlePokemonDetector.cpp