From 17fd447c5c62dda985749ae31802ad3da4369beb Mon Sep 17 00:00:00 2001 From: kichithewolf Date: Sun, 14 Dec 2025 14:50:24 -0500 Subject: [PATCH 01/10] hyperspace reward names --- .../PokemonLZA_HyperspaceRewardNames.cpp | 109 ++++++++++++++++++ .../PokemonLZA_HyperspaceRewardNames.h | 39 +++++++ SerialPrograms/SourceFiles.cmake | 2 + 3 files changed, 150 insertions(+) create mode 100644 SerialPrograms/Source/PokemonLZA/Resources/PokemonLZA_HyperspaceRewardNames.cpp create mode 100644 SerialPrograms/Source/PokemonLZA/Resources/PokemonLZA_HyperspaceRewardNames.h diff --git a/SerialPrograms/Source/PokemonLZA/Resources/PokemonLZA_HyperspaceRewardNames.cpp b/SerialPrograms/Source/PokemonLZA/Resources/PokemonLZA_HyperspaceRewardNames.cpp new file mode 100644 index 000000000..6279ce7a8 --- /dev/null +++ b/SerialPrograms/Source/PokemonLZA/Resources/PokemonLZA_HyperspaceRewardNames.cpp @@ -0,0 +1,109 @@ +/* Hyperspace Reward Names + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#include +#include "Common/Cpp/Json/JsonValue.h" +#include "Common/Cpp/Json/JsonArray.h" +#include "Common/Cpp/Json/JsonObject.h" +#include "CommonFramework/Globals.h" +#include "PokemonLZA_HyperspaceRewardNames.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonLZA{ + + +struct HyperspaceRewardNamesDatabase{ + HyperspaceRewardNamesDatabase(); + + static const HyperspaceRewardNamesDatabase& instance(){ + static HyperspaceRewardNamesDatabase database; + return database; + } + + static const std::string NULL_SLUG; + std::vector ordered_list; + std::map database; + std::map reverse_lookup; +}; +const std::string HyperspaceRewardNamesDatabase::NULL_SLUG; + +HyperspaceRewardNamesDatabase::HyperspaceRewardNamesDatabase() +{ + // Load a list of tournament prize slugs in the desired order: + // ["potion", "fresh-water", ... ] + std::string path_slugs = RESOURCE_PATH() + "PokemonSV/AAT/TournamentPrizeList.json"; //TODO: Get reward list + JsonValue json_slugs = load_json_file(path_slugs); + JsonArray& slugs = json_slugs.to_array_throw(path_slugs); + + // Load a map of tournament prize slugs to item names in all languages, e.g.: + // { + // "potion": { + // "eng": "Potion", + // "deu": "Trank", + // ... + // }, + // .... + // } + std::string path_disp = RESOURCE_PATH() + "PokemonSV/AAT/TournamentPrizeNameDisplay.json"; //TODO: Get reward list + JsonValue json_disp = load_json_file(path_disp); + JsonObject& item_disp = json_disp.to_object_throw(path_disp); + + for (auto& item : slugs){ + std::string& slug = item.to_string_throw(path_slugs); + + JsonObject& auction_item_name_dict = item_disp.get_object_throw(slug, path_disp); + std::string& display_name = auction_item_name_dict.get_string_throw("eng", path_disp); + + ordered_list.push_back(slug); + database[std::move(slug)].m_display_name = std::move(display_name); + } + + for (const auto& item : database){ + reverse_lookup[item.second.m_display_name] = item.first; + } +} + +const HyperspaceRewardNames& get_hyperspace_reward_name(const std::string& slug){ + const std::map& database = HyperspaceRewardNamesDatabase::instance().database; + auto iter = database.find(slug); + if (iter == database.end()){ + throw InternalProgramError( + nullptr, PA_CURRENT_FUNCTION, + "Hyperspace reward slug not found in database: " + slug + ); + } + return iter->second; +} +const std::string& parse_hyperspace_reward_name(const std::string& display_name){ + const std::map& database = HyperspaceRewardNamesDatabase::instance().reverse_lookup; + auto iter = database.find(display_name); + if (iter == database.end()){ + throw InternalProgramError( + nullptr, PA_CURRENT_FUNCTION, + "Hyperspace reward name not found in database: " + display_name + ); + } + return iter->second; +} +const std::string& parse_hyperspace_reward_name_nothrow(const std::string& display_name){ + const std::map& database = HyperspaceRewardNamesDatabase::instance().reverse_lookup; + auto iter = database.find(display_name); + if (iter == database.end()){ + return HyperspaceRewardNamesDatabase::NULL_SLUG; + } + return iter->second; +} + + +const std::vector& HYPERSPACE_REWARD_SLUGS(){ + return HyperspaceRewardNamesDatabase::instance().ordered_list; +} + + +} +} +} diff --git a/SerialPrograms/Source/PokemonLZA/Resources/PokemonLZA_HyperspaceRewardNames.h b/SerialPrograms/Source/PokemonLZA/Resources/PokemonLZA_HyperspaceRewardNames.h new file mode 100644 index 000000000..107f44c94 --- /dev/null +++ b/SerialPrograms/Source/PokemonLZA/Resources/PokemonLZA_HyperspaceRewardNames.h @@ -0,0 +1,39 @@ +/* Hyperspace Reward Names + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#ifndef PokemonAutomation_PokemonLZA_HyperspaceRewardNames_H +#define PokemonAutomation_PokemonLZA_HyperspaceRewardNames_H + +#include +#include + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonLZA{ + + +class HyperspaceRewardNames{ +public: + const std::string& display_name() const { return m_display_name; } + +private: + friend struct HyperspaceRewardNamesDatabase; + + std::string m_display_name; +}; + + +const HyperspaceRewardNames& get_hyperspace_reward_name(const std::string& slug); +const std::string& parse_hyperspace_reward_name(const std::string& display_name); +const std::string& parse_hyperspace_reward_name_nothrow(const std::string& display_name); + +const std::vector& HYPERSPACE_REWARD_SLUGS(); + + +} +} +} +#endif diff --git a/SerialPrograms/SourceFiles.cmake b/SerialPrograms/SourceFiles.cmake index 5c92733bd..4ee6bafab 100644 --- a/SerialPrograms/SourceFiles.cmake +++ b/SerialPrograms/SourceFiles.cmake @@ -1686,6 +1686,8 @@ file(GLOB LIBRARY_SOURCES Source/PokemonLZA/Programs/Trading/PokemonLZA_SelfBoxTrade.h Source/PokemonLZA/Programs/Trading/PokemonLZA_TradeRoutines.cpp Source/PokemonLZA/Programs/Trading/PokemonLZA_TradeRoutines.h + Source/PokemonLZA/Resources/PokemonLZA_HyperspaceRewardNames.cpp + Source/PokemonLZA/Resources/PokemonLZA_HyperspaceRewardNames.h Source/PokemonRSE/Inference/Dialogs/PokemonRSE_DialogDetector.cpp Source/PokemonRSE/Inference/Dialogs/PokemonRSE_DialogDetector.h Source/PokemonRSE/Inference/PokemonRSE_ShinyNumberDetector.cpp From 324da2215a07d79a465815740e996e296c7cde27 Mon Sep 17 00:00:00 2001 From: kichithewolf Date: Sun, 14 Dec 2025 14:55:58 -0500 Subject: [PATCH 02/10] hyperspace reward option --- .../PokemonLZA_HyperspaceRewardOption.cpp | 42 +++++++++++++++++++ .../PokemonLZA_HyperspaceRewardOption.h | 24 +++++++++++ SerialPrograms/SourceFiles.cmake | 2 + 3 files changed, 68 insertions(+) create mode 100644 SerialPrograms/Source/PokemonLZA/Options/PokemonLZA_HyperspaceRewardOption.cpp create mode 100644 SerialPrograms/Source/PokemonLZA/Options/PokemonLZA_HyperspaceRewardOption.h diff --git a/SerialPrograms/Source/PokemonLZA/Options/PokemonLZA_HyperspaceRewardOption.cpp b/SerialPrograms/Source/PokemonLZA/Options/PokemonLZA_HyperspaceRewardOption.cpp new file mode 100644 index 000000000..79c33f84a --- /dev/null +++ b/SerialPrograms/Source/PokemonLZA/Options/PokemonLZA_HyperspaceRewardOption.cpp @@ -0,0 +1,42 @@ +/* Hyperspace Reward Option + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#include "CommonFramework/Logging/Logger.h" +#include "PokemonLZA/Resources/PokemonLZA_HyperspaceRewardNames.h" +#include "PokemonLZA_HyperspaceRewardOption.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonLZA{ + +StringSelectDatabase make_hyperspace_reward_database(){ + StringSelectDatabase ret; + for (const auto& slug : HYPERSPACE_REWARD_SLUGS()){ + const HyperspaceRewardNames& data = get_hyperspace_reward_name(slug); + ret.add_entry(StringSelectEntry(slug, data.display_name())); + } + return ret; +} +const StringSelectDatabase& HYPERSPACE_REWARD_DATABASE(){ + static StringSelectDatabase database = make_hyperspace_reward_database(); + return database; +} + + +HyperspaceRewardCell::HyperspaceRewardCell( + const std::string& default_slug +) + : StringSelectCell( + HYPERSPACE_REWARD_DATABASE(), + LockMode::LOCK_WHILE_RUNNING, + default_slug + ) +{} + + +} +} +} diff --git a/SerialPrograms/Source/PokemonLZA/Options/PokemonLZA_HyperspaceRewardOption.h b/SerialPrograms/Source/PokemonLZA/Options/PokemonLZA_HyperspaceRewardOption.h new file mode 100644 index 000000000..5fa7ff5bd --- /dev/null +++ b/SerialPrograms/Source/PokemonLZA/Options/PokemonLZA_HyperspaceRewardOption.h @@ -0,0 +1,24 @@ +/* Hyperspace Reward Option + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#ifndef PokemonAutomation_PokemonLZA_HyperspaceRewardOption_H +#define PokemonAutomation_PokemonLZA_HyperspaceRewardOption_H + +#include "CommonTools/Options/StringSelectOption.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonLZA{ + +class HyperspaceRewardCell : public StringSelectCell{ +public: + HyperspaceRewardCell(const std::string& default_slug); +}; + +} +} +} +#endif diff --git a/SerialPrograms/SourceFiles.cmake b/SerialPrograms/SourceFiles.cmake index 4ee6bafab..813bf6d92 100644 --- a/SerialPrograms/SourceFiles.cmake +++ b/SerialPrograms/SourceFiles.cmake @@ -1619,6 +1619,8 @@ file(GLOB LIBRARY_SOURCES Source/PokemonLZA/InferenceTraining/PokemonLZA_GenerateLocationNameOCR.h Source/PokemonLZA/Options/PokemonLZA_BattleAIOption.cpp Source/PokemonLZA/Options/PokemonLZA_BattleAIOption.h + Source/PokemonLZA/Options/PokemonLZA_HyperspaceRewardOption.cpp + Source/PokemonLZA/Options/PokemonLZA_HyperspaceRewardOption.h Source/PokemonLZA/Options/PokemonLZA_ShinyDetectedAction.cpp Source/PokemonLZA/Options/PokemonLZA_ShinyDetectedAction.h Source/PokemonLZA/PokemonLZA_Panels.cpp From 84ae461989fa2b91b03485455a2c160cd2f54d31 Mon Sep 17 00:00:00 2001 From: kichithewolf Date: Sun, 14 Dec 2025 14:59:40 -0500 Subject: [PATCH 03/10] hyperspace reward table --- .../PokemonLZA_HyperspaceRewardTable.cpp | 73 +++++++++++++++++++ .../PokemonLZA_HyperspaceRewardTable.h | 51 +++++++++++++ SerialPrograms/SourceFiles.cmake | 2 + 3 files changed, 126 insertions(+) create mode 100644 SerialPrograms/Source/PokemonLZA/Options/PokemonLZA_HyperspaceRewardTable.cpp create mode 100644 SerialPrograms/Source/PokemonLZA/Options/PokemonLZA_HyperspaceRewardTable.h diff --git a/SerialPrograms/Source/PokemonLZA/Options/PokemonLZA_HyperspaceRewardTable.cpp b/SerialPrograms/Source/PokemonLZA/Options/PokemonLZA_HyperspaceRewardTable.cpp new file mode 100644 index 000000000..3f7999ac3 --- /dev/null +++ b/SerialPrograms/Source/PokemonLZA/Options/PokemonLZA_HyperspaceRewardTable.cpp @@ -0,0 +1,73 @@ +/* Hyperspace Reward Table + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#include "PokemonLZA/Resources/PokemonLZA_HyperspaceRewardNames.h" +#include "PokemonLZA_HyperspaceRewardTable.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonLZA{ + +HyperspaceRewardRow::HyperspaceRewardRow(EditableTableOption& parent_table) + : EditableTableRow(parent_table) + , item("beast-ball") +{ + PA_ADD_OPTION(item); +} +std::unique_ptr HyperspaceRewardRow::clone() const{ + std::unique_ptr ret(new HyperspaceRewardRow(parent())); + ret->item.set_by_index(item.index()); + return ret; +} + +HyperspaceRewardTable::HyperspaceRewardTable(std::string label) + : EditableTableOption_t( + std::move(label), + LockMode::LOCK_WHILE_RUNNING, + make_defaults() + ) +{} + +bool HyperspaceRewardTable::find_item(const std::string& item_slug) const{ + std::vector> table = copy_snapshot(); + for (const std::unique_ptr& row : table){ + if (row->item.slug() == item_slug){ + return true; + } + } + return false; +} + +std::vector HyperspaceRewardTable::selected_items() const{ + std::vector> table = copy_snapshot(); + std::vector slugs; + for (const std::unique_ptr& row : table){ + slugs.emplace_back(row->item.slug()); + } + return slugs; +} + + +std::vector HyperspaceRewardTable::make_header() const{ + return std::vector{ + "Item", + }; +} + +std::vector> HyperspaceRewardTable::make_defaults(){ + std::vector> ret; + ret.emplace_back(std::make_unique(*this)); + return ret; +} + + + + + + +} +} +} diff --git a/SerialPrograms/Source/PokemonLZA/Options/PokemonLZA_HyperspaceRewardTable.h b/SerialPrograms/Source/PokemonLZA/Options/PokemonLZA_HyperspaceRewardTable.h new file mode 100644 index 000000000..72e4ba7f6 --- /dev/null +++ b/SerialPrograms/Source/PokemonLZA/Options/PokemonLZA_HyperspaceRewardTable.h @@ -0,0 +1,51 @@ +/* Hyperspace Reward Table + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#ifndef PokemonAutomation_PokemonLZA_HyperspaceRewardTable_H +#define PokemonAutomation_PokemonLZA_HyperspaceRewardTable_H + +#include "Common/Cpp/Options/EditableTableOption.h" +#include "PokemonLZA_HyperspaceRewardOption.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonLZA{ + + + +class HyperspaceRewardRow : public EditableTableRow{ +public: + HyperspaceRewardRow(EditableTableOption& parent_table); + virtual std::unique_ptr clone() const override; + +public: + HyperspaceRewardCell item; +}; + + + +class HyperspaceRewardTable : public EditableTableOption_t{ +public: + HyperspaceRewardTable(std::string label); + + + // Whether item_slug is among the selected items. + bool find_item(const std::string& item_slug) const; + std::vector selected_items() const; + + virtual std::vector make_header() const override; + + std::vector> make_defaults(); +}; + + + + + +} +} +} +#endif diff --git a/SerialPrograms/SourceFiles.cmake b/SerialPrograms/SourceFiles.cmake index 813bf6d92..11f379b9a 100644 --- a/SerialPrograms/SourceFiles.cmake +++ b/SerialPrograms/SourceFiles.cmake @@ -1621,6 +1621,8 @@ file(GLOB LIBRARY_SOURCES Source/PokemonLZA/Options/PokemonLZA_BattleAIOption.h Source/PokemonLZA/Options/PokemonLZA_HyperspaceRewardOption.cpp Source/PokemonLZA/Options/PokemonLZA_HyperspaceRewardOption.h + Source/PokemonLZA/Options/PokemonLZA_HyperspaceRewardTable.cpp + Source/PokemonLZA/Options/PokemonLZA_HyperspaceRewardTable.h Source/PokemonLZA/Options/PokemonLZA_ShinyDetectedAction.cpp Source/PokemonLZA/Options/PokemonLZA_ShinyDetectedAction.h Source/PokemonLZA/PokemonLZA_Panels.cpp From 7ab48233f68f139559cc55d9ed7457ea10a7f540 Mon Sep 17 00:00:00 2001 From: kichithewolf Date: Sun, 14 Dec 2025 15:21:16 -0500 Subject: [PATCH 04/10] hyperspace reward name reader --- .../PokemonLZA_HyperspaceRewardNameReader.cpp | 39 +++++++++++++++++++ .../PokemonLZA_HyperspaceRewardNameReader.h | 38 ++++++++++++++++++ SerialPrograms/SourceFiles.cmake | 4 ++ 3 files changed, 81 insertions(+) create mode 100644 SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_HyperspaceRewardNameReader.cpp create mode 100644 SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_HyperspaceRewardNameReader.h diff --git a/SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_HyperspaceRewardNameReader.cpp b/SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_HyperspaceRewardNameReader.cpp new file mode 100644 index 000000000..8208a51c3 --- /dev/null +++ b/SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_HyperspaceRewardNameReader.cpp @@ -0,0 +1,39 @@ +/* Hyperspace Reward Name Reader + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#include "CommonTools/OCR/OCR_RawOCR.h" +#include "PokemonLZA_HyperspaceRewardNameReader.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonLZA{ + +HyperspaceRewardNameReader& HyperspaceRewardNameReader::instance(){ + static HyperspaceRewardNameReader reader; + return reader; +} + + +HyperspaceRewardNameReader::HyperspaceRewardNameReader() + : SmallDictionaryMatcher("PokemonSV/AAT/TournamentPrizeNameOCR.json") //TODO: Get actual reward list +{} + +OCR::StringMatchResult HyperspaceRewardNameReader::read_substring( + Logger& logger, + Language language, + const ImageViewRGB32& image, + const std::vector& text_color_ranges, + double min_text_ratio, double max_text_ratio +) const{ + return match_substring_from_image_multifiltered( + &logger, language, image, text_color_ranges, + MAX_LOG10P, MAX_LOG10P_SPREAD, min_text_ratio, max_text_ratio + ); +} + +} +} +} diff --git a/SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_HyperspaceRewardNameReader.h b/SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_HyperspaceRewardNameReader.h new file mode 100644 index 000000000..53a8041e1 --- /dev/null +++ b/SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_HyperspaceRewardNameReader.h @@ -0,0 +1,38 @@ +/* Hyperspace Reward Name Reader + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#ifndef PokemonAutomation_PokemonLZA_HyperspaceRewardNameReader_H +#define PokemonAutomation_PokemonLZA_HyperspaceRewardNameReader_H + +#include "CommonTools/OCR/OCR_SmallDictionaryMatcher.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonLZA{ + +class HyperspaceRewardNameReader : public OCR::SmallDictionaryMatcher{ +public: + static constexpr double MAX_LOG10P = -1.40; + static constexpr double MAX_LOG10P_SPREAD = 0.50; + +public: + HyperspaceRewardNameReader(); + + static HyperspaceRewardNameReader& instance(); + + OCR::StringMatchResult read_substring( + Logger& logger, + Language language, + const ImageViewRGB32& image, + const std::vector& text_color_ranges, + double min_text_ratio = 0.01, double max_text_ratio = 0.50 + ) const; + +}; +} +} +} +#endif diff --git a/SerialPrograms/SourceFiles.cmake b/SerialPrograms/SourceFiles.cmake index 11f379b9a..8962a430f 100644 --- a/SerialPrograms/SourceFiles.cmake +++ b/SerialPrograms/SourceFiles.cmake @@ -1607,6 +1607,8 @@ file(GLOB LIBRARY_SOURCES Source/PokemonLZA/Inference/PokemonLZA_DayNightChangeDetector.h Source/PokemonLZA/Inference/PokemonLZA_DialogDetector.cpp Source/PokemonLZA/Inference/PokemonLZA_DialogDetector.h + Source/PokemonLZA/Inference/PokemonLZA_HyperspaceRewardNameReader.cpp + Source/PokemonLZA/Inference/PokemonLZA_HyperspaceRewardNameReader.h Source/PokemonLZA/Inference/PokemonLZA_MainMenuDetector.cpp Source/PokemonLZA/Inference/PokemonLZA_MainMenuDetector.h Source/PokemonLZA/Inference/PokemonLZA_OverworldPartySelectionDetector.cpp @@ -1631,6 +1633,8 @@ file(GLOB LIBRARY_SOURCES Source/PokemonLZA/PokemonLZA_Settings.h Source/PokemonLZA/Programs/Farming/PokemonLZA_FriendshipFarmer.cpp Source/PokemonLZA/Programs/Farming/PokemonLZA_FriendshipFarmer.h + Source/PokemonLZA/Programs/Farming/PokemonLZA_HyperspaceRewardReset.cpp + Source/PokemonLZA/Programs/Farming/PokemonLZA_HyperspaceRewardReset.h Source/PokemonLZA/Programs/Farming/PokemonLZA_InPlaceCatcher.cpp Source/PokemonLZA/Programs/Farming/PokemonLZA_InPlaceCatcher.h Source/PokemonLZA/Programs/Farming/PokemonLZA_JacintheInfiniteFarmer.cpp From 8c0a158d7755b682a8b2b14e9fb078c46df62119 Mon Sep 17 00:00:00 2001 From: kichithewolf Date: Sun, 14 Dec 2025 16:14:55 -0500 Subject: [PATCH 05/10] hyperspace reward reset --- .../Source/PokemonLZA/PokemonLZA_Panels.cpp | 2 + .../PokemonLZA_HyperspaceRewardReset.cpp | 233 ++++++++++++++++++ .../PokemonLZA_HyperspaceRewardReset.h | 54 ++++ 3 files changed, 289 insertions(+) create mode 100644 SerialPrograms/Source/PokemonLZA/Programs/Farming/PokemonLZA_HyperspaceRewardReset.cpp create mode 100644 SerialPrograms/Source/PokemonLZA/Programs/Farming/PokemonLZA_HyperspaceRewardReset.h diff --git a/SerialPrograms/Source/PokemonLZA/PokemonLZA_Panels.cpp b/SerialPrograms/Source/PokemonLZA/PokemonLZA_Panels.cpp index ab648cf64..003762059 100644 --- a/SerialPrograms/Source/PokemonLZA/PokemonLZA_Panels.cpp +++ b/SerialPrograms/Source/PokemonLZA/PokemonLZA_Panels.cpp @@ -24,6 +24,7 @@ #include "Programs/Farming/PokemonLZA_JacintheInfiniteFarmer.h" #include "Programs/Farming/PokemonLZA_FriendshipFarmer.h" #include "Programs/Farming/PokemonLZA_InPlaceCatcher.h" +#include "Programs/Farming/PokemonLZA_HyperspaceRewardReset.h" // Shiny Hunting #include "Programs/ShinyHunting/PokemonLZA_AutoFossil.h" @@ -77,6 +78,7 @@ std::vector PanelListFactory::make_panels() const{ ret.emplace_back(make_single_switch_program()); ret.emplace_back(make_single_switch_program()); ret.emplace_back(make_single_switch_program()); + ret.emplace_back(make_single_switch_program()); if (IS_BETA_VERSION){ } diff --git a/SerialPrograms/Source/PokemonLZA/Programs/Farming/PokemonLZA_HyperspaceRewardReset.cpp b/SerialPrograms/Source/PokemonLZA/Programs/Farming/PokemonLZA_HyperspaceRewardReset.cpp new file mode 100644 index 000000000..fd70a32e4 --- /dev/null +++ b/SerialPrograms/Source/PokemonLZA/Programs/Farming/PokemonLZA_HyperspaceRewardReset.cpp @@ -0,0 +1,233 @@ +/* Hyperspace Reward Reset + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#include "CommonFramework/Logging/Logger.h" +#include "CommonFramework/Exceptions/OperationFailedException.h" +#include "CommonFramework/Notifications/ProgramNotifications.h" +#include "CommonFramework/ProgramStats/StatsTracking.h" +#include "CommonFramework/VideoPipeline/VideoFeed.h" +#include "CommonTools/Images/ImageFilter.h" +#include "CommonTools/Async/InferenceRoutines.h" +#include "CommonTools/VisualDetectors/BlackScreenDetector.h" +#include "CommonTools/StartupChecks/VideoResolutionCheck.h" +#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" +#include "NintendoSwitch/Programs/NintendoSwitch_GameEntry.h" +#include "Pokemon/Pokemon_Strings.h" +#include "PokemonLZA/Programs/PokemonLZA_GameEntry.h" +#include "PokemonLZA/Inference/PokemonLZA_ButtonDetector.h" +#include "PokemonLZA/Inference/PokemonLZA_DialogDetector.h" +#include "PokemonLZA/Inference/PokemonLZA_HyperspaceRewardNameReader.h" +#include "PokemonLZA/Resources/PokemonLZA_HyperspaceRewardNames.h" +#include "PokemonLZA_HyperspaceRewardReset.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonLZA{ + +using namespace Pokemon; + +HyperspaceRewardReset_Descriptor::HyperspaceRewardReset_Descriptor() + : SingleSwitchProgramDescriptor( + "PokemonLZA:HyperspaceRewardReset", + STRING_POKEMON + " LZA", "Hyperspace Reward Reset", + "Programs/PokemonLZA/HyperspaceRewardReset.html", + "Reset in front of a Hyperspace Battle Zone trainer to receive a specific reward.", + ProgramControllerClass::StandardController_NoRestrictions, + FeedbackType::REQUIRED, + AllowCommandsWhenRunning::DISABLE_COMMANDS + ) +{} + +struct HyperspaceRewardReset_Descriptor::Stats : public StatsTracker{ + Stats() + : matches(m_stats["Items matched"]) + , resets(m_stats["Resets"]) + , errors(m_stats["Errors"]) + { + m_display_order.emplace_back("Items matched"); + m_display_order.emplace_back("Resets"); + m_display_order.emplace_back("Errors", HIDDEN_IF_ZERO); + } + std::atomic& matches; + std::atomic& resets; + std::atomic& errors; +}; +std::unique_ptr HyperspaceRewardReset_Descriptor::make_stats() const{ + return std::unique_ptr(new Stats()); +} + +HyperspaceRewardReset::HyperspaceRewardReset() + : LANGUAGE( + "Game Language:
The language is needed to read the rewards.", + HyperspaceRewardNameReader::instance().languages(), + LockMode::LOCK_WHILE_RUNNING, + true + ) + , TARGET_ITEMS("Items:") + , GO_HOME_WHEN_DONE(true) + , NOTIFICATION_REWARD_MATCH("Matching Reward", true, false, ImageAttachmentMode::JPG, { "Notifs" }) + , NOTIFICATION_STATUS_UPDATE("Status Update", true, false, std::chrono::seconds(3600)) + , NOTIFICATIONS({ + &NOTIFICATION_REWARD_MATCH, + &NOTIFICATION_STATUS_UPDATE, + &NOTIFICATION_PROGRAM_FINISH, + &NOTIFICATION_ERROR_FATAL, + }) +{ + PA_ADD_OPTION(LANGUAGE); + PA_ADD_OPTION(TARGET_ITEMS); + PA_ADD_OPTION(GO_HOME_WHEN_DONE); + PA_ADD_OPTION(NOTIFICATIONS); +} + +void HyperspaceRewardReset::talk_to_trainer(SingleSwitchProgramEnvironment& env, ProControllerContext& context){ + HyperspaceRewardReset_Descriptor::Stats& stats = env.current_stats(); + context.wait_for_all_requests(); + + env.log("Looking for A button."); + ButtonWatcher buttonA_watcher( + COLOR_WHITE, + ButtonType::ButtonA, + {0.1, 0.1, 0.8, 0.8}, + &env.console.overlay() + ); + int ret = wait_until( + env.console, context, + 10s, + { + buttonA_watcher, + } + ); + if (ret == 0) { + env.log("Detected A button."); + pbf_press_button(context, BUTTON_A, 80ms, 40ms); + } + else { + stats.errors++; + env.update_stats(); + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "talk_to_trainer(): Failed to detect A button.", + env.console + ); + } + context.wait_for_all_requests(); + + BlueDialogWatcher blue_dialog_watcher(COLOR_BLUE, &env.console.overlay()); + env.log("Pressing A until item received dialog."); + //First dialog box varies by trainer (hologram, regular, etc.) + int ret_blue = run_until( + env.console, context, + [](ProControllerContext& context){ + for (int i = 0; i < 20; i++) { + pbf_press_button(context, BUTTON_A, 80ms, 100ms); + pbf_wait(context, 1000ms); + context.wait_for_all_requests(); + } + }, + { blue_dialog_watcher } + ); + if (ret_blue != 0){ + stats.errors++; + env.update_stats(); + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "talk_to_trainer(): Failed to detect blue item received dialog after 20 A presses.", + env.console + ); + } + context.wait_for_all_requests(); +} + +//Check reward and notify if it matches filters +bool HyperspaceRewardReset::check_reward(SingleSwitchProgramEnvironment& env, ProControllerContext& context){ + HyperspaceRewardReset_Descriptor::Stats& stats = env.current_stats(); + + VideoSnapshot screen = env.console.video().snapshot(); + ImageFloatBox dialog_box(0.248, 0.792, 0.483, 0.147); + ImageViewRGB32 dialog_image = extract_box_reference(screen, dialog_box); + + /* + bool replace_color_within_range = false; + ImageRGB32 dialog_filtered = filter_rgb32_range( + extract_box_reference(screen, dialog_box), + combine_rgb(50, 135, 162), combine_rgb(167, 244, 255), Color(0), replace_color_within_range + ); + dialog_filtered.save("./dialog_image.png"); + */ + + const double LOG10P_THRESHOLD = -1.5; + OCR::StringMatchResult result = PokemonLZA::HyperspaceRewardNameReader::instance().read_substring( + env.console, LANGUAGE, dialog_image, + OCR::BLUE_TEXT_FILTERS() + ); + result.clear_beyond_log10p(LOG10P_THRESHOLD); + if (result.results.empty()){ + env.log("No matching reward name found in dialog box."); + send_program_status_notification(env, NOTIFICATION_STATUS_UPDATE); + } + for (const auto& r : result.results){ + env.console.log("Found reward: " + r.second.token); + if (TARGET_ITEMS.find_item(r.second.token)){ + env.log("Reward matched"); + + stats.matches++; + env.update_stats(); + + send_program_notification( + env, NOTIFICATION_REWARD_MATCH, + COLOR_GREEN, "Reward matched", + { + { "Item:", get_hyperspace_reward_name(r.second.token).display_name() }, + } + , "", screen); + return true; + break; + } + } + return false; +} + +void HyperspaceRewardReset::program(SingleSwitchProgramEnvironment& env, ProControllerContext& context){ + assert_16_9_720p_min(env.logger(), env.console); + HyperspaceRewardReset_Descriptor::Stats& stats = env.current_stats(); + + /* + * In a Hyperspace Battle Zone: + * Win a battle with a trainer that gives a prize. + * Save the game and reset. Do not talk to the trainer. + * (Reset is required because trainer position will move.) + * Re-enter the game and then save again, this time in front of the trainer. + * Start the program. + * + * Make sure you won't be spotted by another trainer. + */ + + bool item_found = false; + while (!item_found){ + send_program_status_notification(env, NOTIFICATION_STATUS_UPDATE); + + talk_to_trainer(env, context); + item_found = check_reward(env, context); + + if (item_found) { + break; + } + + go_home(env.console, context); + reset_game_from_home(env, env.console, context); + stats.resets++; + env.update_stats(); + } + + send_program_finished_notification(env, NOTIFICATION_PROGRAM_FINISH); + GO_HOME_WHEN_DONE.run_end_of_program(context); +} + +} +} +} + diff --git a/SerialPrograms/Source/PokemonLZA/Programs/Farming/PokemonLZA_HyperspaceRewardReset.h b/SerialPrograms/Source/PokemonLZA/Programs/Farming/PokemonLZA_HyperspaceRewardReset.h new file mode 100644 index 000000000..4c157c41b --- /dev/null +++ b/SerialPrograms/Source/PokemonLZA/Programs/Farming/PokemonLZA_HyperspaceRewardReset.h @@ -0,0 +1,54 @@ +/* Hyperspace Reward Reset + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#ifndef PokemonAutomation_PokemonLZA_HyperspaceRewardReset_H +#define PokemonAutomation_PokemonLZA_HyperspaceRewardReset_H + +#include "Common/Cpp/Options/BooleanCheckBoxOption.h" +#include "Common/Cpp/Options/SimpleIntegerOption.h" +#include "Common/Cpp/Options/ButtonOption.h" +#include "CommonFramework/Notifications/EventNotificationsTable.h" +#include "CommonTools/Options/LanguageOCROption.h" +#include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h" +#include "NintendoSwitch/Options/NintendoSwitch_GoHomeWhenDoneOption.h" +#include "PokemonLZA/Options/PokemonLZA_HyperspacerewardTable.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonLZA{ + +class HyperspaceRewardReset_Descriptor : public SingleSwitchProgramDescriptor{ +public: + HyperspaceRewardReset_Descriptor(); + struct Stats; + virtual std::unique_ptr make_stats() const override; +}; + +class HyperspaceRewardReset : public SingleSwitchProgramInstance{ +public: + HyperspaceRewardReset(); + virtual void program(SingleSwitchProgramEnvironment& env, ProControllerContext& context) override; + +private: + OCR::LanguageOCROption LANGUAGE; + HyperspaceRewardTable TARGET_ITEMS; + GoHomeWhenDoneOption GO_HOME_WHEN_DONE; + + EventNotificationOption NOTIFICATION_REWARD_MATCH; + EventNotificationOption NOTIFICATION_STATUS_UPDATE; + EventNotificationsOption NOTIFICATIONS; + + void talk_to_trainer(SingleSwitchProgramEnvironment& env, ProControllerContext& context); + bool check_reward(SingleSwitchProgramEnvironment& env, ProControllerContext& context); +}; + +} +} +} +#endif + + + From f43b847c8cdf7b72bc15930ac202b959b17fc516 Mon Sep 17 00:00:00 2001 From: kichithewolf Date: Sun, 14 Dec 2025 16:40:51 -0500 Subject: [PATCH 06/10] hyperspace battle reward list --- .../Inference/PokemonLZA_HyperspaceRewardNameReader.cpp | 2 +- SerialPrograms/Source/PokemonLZA/PokemonLZA_Panels.cpp | 2 +- .../PokemonLZA/Resources/PokemonLZA_HyperspaceRewardNames.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_HyperspaceRewardNameReader.cpp b/SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_HyperspaceRewardNameReader.cpp index 8208a51c3..eeba02352 100644 --- a/SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_HyperspaceRewardNameReader.cpp +++ b/SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_HyperspaceRewardNameReader.cpp @@ -18,7 +18,7 @@ HyperspaceRewardNameReader& HyperspaceRewardNameReader::instance(){ HyperspaceRewardNameReader::HyperspaceRewardNameReader() - : SmallDictionaryMatcher("PokemonSV/AAT/TournamentPrizeNameOCR.json") //TODO: Get actual reward list + : SmallDictionaryMatcher("PokemonLZA/HyperBattle/HyperspaceRewardNameOCR.json") {} OCR::StringMatchResult HyperspaceRewardNameReader::read_substring( diff --git a/SerialPrograms/Source/PokemonLZA/PokemonLZA_Panels.cpp b/SerialPrograms/Source/PokemonLZA/PokemonLZA_Panels.cpp index 003762059..e9fac21df 100644 --- a/SerialPrograms/Source/PokemonLZA/PokemonLZA_Panels.cpp +++ b/SerialPrograms/Source/PokemonLZA/PokemonLZA_Panels.cpp @@ -78,8 +78,8 @@ std::vector PanelListFactory::make_panels() const{ ret.emplace_back(make_single_switch_program()); ret.emplace_back(make_single_switch_program()); ret.emplace_back(make_single_switch_program()); - ret.emplace_back(make_single_switch_program()); if (IS_BETA_VERSION){ + ret.emplace_back(make_single_switch_program()); } ret.emplace_back("---- Shiny Hunting ----"); diff --git a/SerialPrograms/Source/PokemonLZA/Resources/PokemonLZA_HyperspaceRewardNames.cpp b/SerialPrograms/Source/PokemonLZA/Resources/PokemonLZA_HyperspaceRewardNames.cpp index 6279ce7a8..d7d13e9f6 100644 --- a/SerialPrograms/Source/PokemonLZA/Resources/PokemonLZA_HyperspaceRewardNames.cpp +++ b/SerialPrograms/Source/PokemonLZA/Resources/PokemonLZA_HyperspaceRewardNames.cpp @@ -35,7 +35,7 @@ HyperspaceRewardNamesDatabase::HyperspaceRewardNamesDatabase() { // Load a list of tournament prize slugs in the desired order: // ["potion", "fresh-water", ... ] - std::string path_slugs = RESOURCE_PATH() + "PokemonSV/AAT/TournamentPrizeList.json"; //TODO: Get reward list + std::string path_slugs = RESOURCE_PATH() + "PokemonLZA/HyperBattle/HyperspaceRewardList.json"; JsonValue json_slugs = load_json_file(path_slugs); JsonArray& slugs = json_slugs.to_array_throw(path_slugs); @@ -48,7 +48,7 @@ HyperspaceRewardNamesDatabase::HyperspaceRewardNamesDatabase() // }, // .... // } - std::string path_disp = RESOURCE_PATH() + "PokemonSV/AAT/TournamentPrizeNameDisplay.json"; //TODO: Get reward list + std::string path_disp = RESOURCE_PATH() + "PokemonLZA/HyperBattle/HyperspaceRewardNameDisplay.json"; //TODO: Get reward list JsonValue json_disp = load_json_file(path_disp); JsonObject& item_disp = json_disp.to_object_throw(path_disp); From 436a3ab5290af4dc3fa2c12e1b09b338f3bd92e5 Mon Sep 17 00:00:00 2001 From: kichithewolf Date: Sun, 14 Dec 2025 16:55:16 -0500 Subject: [PATCH 07/10] switch default item in table --- .../PokemonLZA/Options/PokemonLZA_HyperspaceRewardTable.cpp | 2 +- .../PokemonLZA/Resources/PokemonLZA_HyperspaceRewardNames.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/SerialPrograms/Source/PokemonLZA/Options/PokemonLZA_HyperspaceRewardTable.cpp b/SerialPrograms/Source/PokemonLZA/Options/PokemonLZA_HyperspaceRewardTable.cpp index 3f7999ac3..90c17e343 100644 --- a/SerialPrograms/Source/PokemonLZA/Options/PokemonLZA_HyperspaceRewardTable.cpp +++ b/SerialPrograms/Source/PokemonLZA/Options/PokemonLZA_HyperspaceRewardTable.cpp @@ -13,7 +13,7 @@ namespace PokemonLZA{ HyperspaceRewardRow::HyperspaceRewardRow(EditableTableOption& parent_table) : EditableTableRow(parent_table) - , item("beast-ball") + , item("bottle-cap") { PA_ADD_OPTION(item); } diff --git a/SerialPrograms/Source/PokemonLZA/Resources/PokemonLZA_HyperspaceRewardNames.cpp b/SerialPrograms/Source/PokemonLZA/Resources/PokemonLZA_HyperspaceRewardNames.cpp index d7d13e9f6..a63fbec8d 100644 --- a/SerialPrograms/Source/PokemonLZA/Resources/PokemonLZA_HyperspaceRewardNames.cpp +++ b/SerialPrograms/Source/PokemonLZA/Resources/PokemonLZA_HyperspaceRewardNames.cpp @@ -48,7 +48,7 @@ HyperspaceRewardNamesDatabase::HyperspaceRewardNamesDatabase() // }, // .... // } - std::string path_disp = RESOURCE_PATH() + "PokemonLZA/HyperBattle/HyperspaceRewardNameDisplay.json"; //TODO: Get reward list + std::string path_disp = RESOURCE_PATH() + "PokemonLZA/HyperBattle/HyperspaceRewardNameDisplay.json"; JsonValue json_disp = load_json_file(path_disp); JsonObject& item_disp = json_disp.to_object_throw(path_disp); From 15cc283530c919bc2f320d56a5db738382ea4d03 Mon Sep 17 00:00:00 2001 From: kichithewolf Date: Sun, 14 Dec 2025 17:14:27 -0500 Subject: [PATCH 08/10] fix --- .../Programs/Farming/PokemonLZA_HyperspaceRewardReset.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SerialPrograms/Source/PokemonLZA/Programs/Farming/PokemonLZA_HyperspaceRewardReset.h b/SerialPrograms/Source/PokemonLZA/Programs/Farming/PokemonLZA_HyperspaceRewardReset.h index 4c157c41b..861d2220a 100644 --- a/SerialPrograms/Source/PokemonLZA/Programs/Farming/PokemonLZA_HyperspaceRewardReset.h +++ b/SerialPrograms/Source/PokemonLZA/Programs/Farming/PokemonLZA_HyperspaceRewardReset.h @@ -14,7 +14,7 @@ #include "CommonTools/Options/LanguageOCROption.h" #include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h" #include "NintendoSwitch/Options/NintendoSwitch_GoHomeWhenDoneOption.h" -#include "PokemonLZA/Options/PokemonLZA_HyperspacerewardTable.h" +#include "PokemonLZA/Options/PokemonLZA_HyperspaceRewardTable.h" namespace PokemonAutomation{ namespace NintendoSwitch{ From a21d1e26e157b10418ba32e066facfcfddad094e Mon Sep 17 00:00:00 2001 From: kichithewolf Date: Sun, 14 Dec 2025 22:09:43 -0500 Subject: [PATCH 09/10] light blue dialog and blue arrow --- .../Inference/PokemonLZA_DialogDetector.cpp | 84 +++++++++++++++++++ .../Inference/PokemonLZA_DialogDetector.h | 31 +++++++ 2 files changed, 115 insertions(+) diff --git a/SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_DialogDetector.cpp b/SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_DialogDetector.cpp index 3acc9d7e8..6b948a8d2 100644 --- a/SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_DialogDetector.cpp +++ b/SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_DialogDetector.cpp @@ -105,6 +105,26 @@ class DialogTealArrowMatcher : public ImageMatch::WaterfillTemplateMatcher{ } }; +class DialogBlueArrowMatcher : public ImageMatch::WaterfillTemplateMatcher{ +public: + DialogBlueArrowMatcher() + : WaterfillTemplateMatcher( + "PokemonLZA/DialogBox/DialogBoxBlueArrow-Template.png", + Color(0xff005460), Color(0xff6BBEC9), 50 + ) + { + m_aspect_ratio_lower = 0.9; + m_aspect_ratio_upper = 1.1; + m_area_ratio_lower = 0.8; + m_area_ratio_upper = 1.1; + } + + static const ImageMatch::WaterfillTemplateMatcher& instance() { + static DialogBlueArrowMatcher matcher; + return matcher; + } +}; + namespace { @@ -143,6 +163,33 @@ bool detect_white_arrow(const ImageViewRGB32& screen, PokemonAutomation::ImageFl return found; } +bool detect_blue_arrow(const ImageViewRGB32& screen, PokemonAutomation::ImageFloatBox& found_box){ + double screen_rel_size = (screen.height() / 1080.0); + double screen_rel_size_2 = screen_rel_size * screen_rel_size; + + double min_area_1080p = 150.0; + double rmsd_threshold = 120.0; + size_t min_area = size_t(screen_rel_size_2 * min_area_1080p); + + const std::vector> FILTERS = { + {0x005460, 0xff7FC0C9}, + }; + + bool found = match_template_by_waterfill( + screen.size(), + extract_box_reference(screen, DIALOG_ARROW_BOX), + DialogBlueArrowMatcher::instance(), + FILTERS, + {min_area, SIZE_MAX}, + rmsd_threshold, + [&](Kernels::Waterfill::WaterfillObject& object) -> bool { + found_box = translate_to_parent(screen, DIALOG_ARROW_BOX, object); + return true; + } + ); + return found; +} + } // end anonymous namespace @@ -486,6 +533,43 @@ bool TransparentBattleDialogDetector::detect(const ImageViewRGB32& screen){ } +LightBlueDialogDetector::LightBlueDialogDetector(Color color, VideoOverlay* overlay) + : m_color(color) + , m_overlay(overlay) + , m_corner(0.765093, 0.933594, 0.006586, 0.013672) +{} +void LightBlueDialogDetector::make_overlays(VideoOverlaySet& items) const{ + items.add(m_color, m_corner); + items.add(m_color, DIALOG_ARROW_BOX); +} +bool LightBlueDialogDetector::detect(const ImageViewRGB32& screen){ + do{ + if (is_solid( + extract_box_reference(screen, m_corner), + {0.108317, 0.462282, 0.429400}, + 0.25 + )){ + break; + } + m_last_detected_box_scope.reset(); +// cout << "not solid" << endl; + return false; + }while (false); + + const bool found = detect_blue_arrow(screen, m_last_detected_box); + + if (m_overlay){ + if (found){ + m_last_detected_box_scope.emplace(*m_overlay, m_last_detected_box, COLOR_GREEN); + }else{ + m_last_detected_box_scope.reset(); + } + } + + return found; +} + + } } diff --git a/SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_DialogDetector.h b/SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_DialogDetector.h index 762fed850..d10f622bc 100644 --- a/SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_DialogDetector.h +++ b/SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_DialogDetector.h @@ -206,6 +206,37 @@ class TransparentBattleDialogWatcher : public DetectorToFinder m_last_detected_box_scope; +}; +class LightBlueDialogWatcher : public DetectorToFinder{ +public: + LightBlueDialogWatcher( + Color color = COLOR_RED, + VideoOverlay* overlay = nullptr, + std::chrono::milliseconds hold_duration = std::chrono::milliseconds(250) + ) + : DetectorToFinder("BlueDialogWatcher", hold_duration, color, overlay) + {} +}; + } } From 13bd2891f142aa91b8d7e543b7ed28509d08b5fb Mon Sep 17 00:00:00 2001 From: kichithewolf Date: Sun, 14 Dec 2025 22:10:53 -0500 Subject: [PATCH 10/10] use new light blue dialog detection --- .../PokemonLZA_HyperspaceRewardReset.cpp | 102 +++++++++--------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/SerialPrograms/Source/PokemonLZA/Programs/Farming/PokemonLZA_HyperspaceRewardReset.cpp b/SerialPrograms/Source/PokemonLZA/Programs/Farming/PokemonLZA_HyperspaceRewardReset.cpp index fd70a32e4..043583add 100644 --- a/SerialPrograms/Source/PokemonLZA/Programs/Farming/PokemonLZA_HyperspaceRewardReset.cpp +++ b/SerialPrograms/Source/PokemonLZA/Programs/Farming/PokemonLZA_HyperspaceRewardReset.cpp @@ -85,61 +85,61 @@ HyperspaceRewardReset::HyperspaceRewardReset() void HyperspaceRewardReset::talk_to_trainer(SingleSwitchProgramEnvironment& env, ProControllerContext& context){ HyperspaceRewardReset_Descriptor::Stats& stats = env.current_stats(); - context.wait_for_all_requests(); - - env.log("Looking for A button."); - ButtonWatcher buttonA_watcher( - COLOR_WHITE, - ButtonType::ButtonA, - {0.1, 0.1, 0.8, 0.8}, - &env.console.overlay() - ); - int ret = wait_until( - env.console, context, - 10s, - { - buttonA_watcher, - } - ); - if (ret == 0) { - env.log("Detected A button."); - pbf_press_button(context, BUTTON_A, 80ms, 40ms); - } - else { - stats.errors++; - env.update_stats(); - OperationFailedException::fire( - ErrorReport::SEND_ERROR_REPORT, - "talk_to_trainer(): Failed to detect A button.", - env.console + + bool exit = false; + while (!exit){ + context.wait_for_all_requests(); + + ButtonWatcher buttonA_watcher( + COLOR_WHITE, + ButtonType::ButtonA, + {0.1, 0.1, 0.8, 0.8}, + &env.console.overlay() ); - } - context.wait_for_all_requests(); - - BlueDialogWatcher blue_dialog_watcher(COLOR_BLUE, &env.console.overlay()); - env.log("Pressing A until item received dialog."); - //First dialog box varies by trainer (hologram, regular, etc.) - int ret_blue = run_until( - env.console, context, - [](ProControllerContext& context){ - for (int i = 0; i < 20; i++) { - pbf_press_button(context, BUTTON_A, 80ms, 100ms); - pbf_wait(context, 1000ms); - context.wait_for_all_requests(); + //First dialog box varies by trainer (hologram, regular, etc.) + BlueDialogWatcher blue_dialog_watcher(COLOR_BLUE, &env.console.overlay()); //Item received (not the big box) + FlatWhiteDialogWatcher white_dialog_watcher(COLOR_WHITE, &env.console.overlay()); //Non-hologram + LightBlueDialogWatcher light_blue_dialog_watcher(COLOR_WHITE, &env.console.overlay()); //hologram + + int ret = wait_until( + env.console, context, + 10s, + { + buttonA_watcher, + blue_dialog_watcher, + white_dialog_watcher, + light_blue_dialog_watcher, } - }, - { blue_dialog_watcher } - ); - if (ret_blue != 0){ - stats.errors++; - env.update_stats(); - OperationFailedException::fire( - ErrorReport::SEND_ERROR_REPORT, - "talk_to_trainer(): Failed to detect blue item received dialog after 20 A presses.", - env.console ); + context.wait_for(100ms); + + switch (ret){ + case 0: + env.log("Detected A button."); + pbf_press_button(context, BUTTON_A, 80ms, 40ms); + continue; + case 1: + env.log("Detected item received dialog."); + exit = true; + break; + case 2: + env.log("Detected white dialog."); + pbf_press_button(context, BUTTON_A, 80ms, 40ms); + continue; + case 3: + env.log("Detected light blue dialog."); + pbf_press_button(context, BUTTON_A, 80ms, 40ms); + continue; + default: + stats.errors++; + env.update_stats(); + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "talk_to_trainer(): Failed to detect blue item received dialog.", + env.console + ); + } } - context.wait_for_all_requests(); } //Check reward and notify if it matches filters