diff --git a/SerialPrograms/CMakeLists.txt b/SerialPrograms/CMakeLists.txt index c13285cb3..fcecc7028 100644 --- a/SerialPrograms/CMakeLists.txt +++ b/SerialPrograms/CMakeLists.txt @@ -1359,6 +1359,8 @@ file(GLOB MAIN_SOURCES Source/PokemonSV/Options/PokemonSV_TeraAIOption.h Source/PokemonSV/Options/PokemonSV_TeraMoveTable.cpp Source/PokemonSV/Options/PokemonSV_TeraMoveTable.h + Source/PokemonSV/Options/PokemonSV_TeraRollFilter.cpp + Source/PokemonSV/Options/PokemonSV_TeraRollFilter.h Source/PokemonSV/Options/PokemonSV_TournamentPrizeSelectOption.cpp Source/PokemonSV/Options/PokemonSV_TournamentPrizeSelectOption.h Source/PokemonSV/Options/PokemonSV_TournamentPrizeTable.cpp diff --git a/SerialPrograms/SerialPrograms.pro b/SerialPrograms/SerialPrograms.pro index dbd5099a2..e9b84cec0 100644 --- a/SerialPrograms/SerialPrograms.pro +++ b/SerialPrograms/SerialPrograms.pro @@ -677,6 +677,7 @@ SOURCES += \ Source/PokemonSV/Options/PokemonSV_SandwichMakerOption.cpp \ Source/PokemonSV/Options/PokemonSV_TeraAIOption.cpp \ Source/PokemonSV/Options/PokemonSV_TeraMoveTable.cpp \ + Source/PokemonSV/Options/PokemonSV_TeraRollFilter.cpp \ Source/PokemonSV/Options/PokemonSV_TournamentPrizeSelectOption.cpp \ Source/PokemonSV/Options/PokemonSV_TournamentPrizeTable.cpp \ Source/PokemonSV/PokemonSV_Panels.cpp \ @@ -701,6 +702,7 @@ SOURCES += \ Source/PokemonSV/Programs/General/PokemonSV_MassRelease.cpp \ Source/PokemonSV/Programs/General/PokemonSV_SizeChecker.cpp \ Source/PokemonSV/Programs/General/PokemonSV_StatsReset.cpp \ + Source/PokemonSV/Programs/General/PokemonSV_StatsResetBloodmoon.cpp \ Source/PokemonSV/Programs/General/PokemonSV_TournamentFarmer.cpp \ Source/PokemonSV/Programs/Glitches/PokemonSV_CloneItems-1.0.1.cpp \ Source/PokemonSV/Programs/Glitches/PokemonSV_RideCloner-1.0.1.cpp \ @@ -1714,6 +1716,7 @@ HEADERS += \ Source/PokemonSV/Options/PokemonSV_SandwichMakerOption.h \ Source/PokemonSV/Options/PokemonSV_TeraAIOption.h \ Source/PokemonSV/Options/PokemonSV_TeraMoveTable.h \ + Source/PokemonSV/Options/PokemonSV_TeraRollFilter.h \ Source/PokemonSV/Options/PokemonSV_TournamentPrizeSelectOption.h \ Source/PokemonSV/Options/PokemonSV_TournamentPrizeTable.h \ Source/PokemonSV/PokemonSV_Panels.h \ @@ -1738,6 +1741,7 @@ HEADERS += \ Source/PokemonSV/Programs/General/PokemonSV_MassRelease.h \ Source/PokemonSV/Programs/General/PokemonSV_SizeChecker.h \ Source/PokemonSV/Programs/General/PokemonSV_StatsReset.h \ + Source/PokemonSV/Programs/General/PokemonSV_StatsResetBloodmoon.h \ Source/PokemonSV/Programs/General/PokemonSV_TournamentFarmer.h \ Source/PokemonSV/Programs/Glitches/PokemonSV_CloneItems-1.0.1.h \ Source/PokemonSV/Programs/Glitches/PokemonSV_RideCloner-1.0.1.h \ diff --git a/SerialPrograms/Source/CommonFramework/Globals.cpp b/SerialPrograms/Source/CommonFramework/Globals.cpp index 37841ac53..59670c11c 100644 --- a/SerialPrograms/Source/CommonFramework/Globals.cpp +++ b/SerialPrograms/Source/CommonFramework/Globals.cpp @@ -23,7 +23,7 @@ namespace PokemonAutomation{ const bool IS_BETA_VERSION = true; const int PROGRAM_VERSION_MAJOR = 0; const int PROGRAM_VERSION_MINOR = 39; -const int PROGRAM_VERSION_PATCH = 3; +const int PROGRAM_VERSION_PATCH = 5; const std::string PROGRAM_VERSION_BASE = "v" + std::to_string(PROGRAM_VERSION_MAJOR) + diff --git a/SerialPrograms/Source/PokemonSV/Inference/Tera/PokemonSV_TeraCardDetector.cpp b/SerialPrograms/Source/PokemonSV/Inference/Tera/PokemonSV_TeraCardDetector.cpp index 20f1418cb..30001104d 100644 --- a/SerialPrograms/Source/PokemonSV/Inference/Tera/PokemonSV_TeraCardDetector.cpp +++ b/SerialPrograms/Source/PokemonSV/Inference/Tera/PokemonSV_TeraCardDetector.cpp @@ -8,9 +8,9 @@ #include #include #include "Common/Cpp/PrettyPrint.h" -#include "Common/Qt/StringToolsQt.h" //#include "Kernels/Waterfill/Kernels_Waterfill.h" #include "Kernels/Waterfill/Kernels_Waterfill_Session.h" +#include "CommonFramework/GlobalSettingsPanel.h" #include "CommonFramework/ImageTypes/ImageRGB32.h" #include "CommonFramework/ImageTypes/BinaryImage.h" #include "CommonFramework/ImageTools/SolidColorTest.h" @@ -20,7 +20,8 @@ //#include "CommonFramework/ImageTools/ImageFilter.h" #include "CommonFramework/OCR/OCR_RawOCR.h" //#include "CommonFramework/OCR/OCR_NumberReader.h" -//#include "CommonFramework/Tools/ErrorDumper.h" +#include "CommonFramework/Tools/DebugDumper.h" +#include "CommonFramework/Tools/ErrorDumper.h" //#include "CommonFramework/OCR/OCR_Routines.h" #include "PokemonSV/Inference/Dialogs/PokemonSV_GradientArrowDetector.h" #include "PokemonSV_TeraCodeReader.h" @@ -47,6 +48,8 @@ TeraCardReader::TeraCardReader(Color color) , m_label(CARD_LABEL_BOX()) , m_cursor(0.135, 0.25, 0.05, 0.25) , m_stars(0.500, 0.555, 0.310, 0.070) + , m_tera_type(color) + , m_silhouette(color) {} void TeraCardReader::make_overlays(VideoOverlaySet& items) const{ items.add(m_color, m_top); @@ -55,6 +58,8 @@ void TeraCardReader::make_overlays(VideoOverlaySet& items) const{ items.add(m_color, m_label); items.add(m_color, m_cursor); items.add(m_color, m_stars); + m_tera_type.make_overlays(items); + m_silhouette.make_overlays(items); } const ImageFloatBox& TeraCardReader::CARD_LABEL_BOX(){ @@ -143,6 +148,40 @@ size_t TeraCardReader::stars(const ImageViewRGB32& screen) const{ return 0; } +std::string TeraCardReader::tera_type( + Logger& logger, const ProgramInfo& info, const ImageViewRGB32& screen +) const{ + ImageMatch::ImageMatchResult type = m_tera_type.read(screen); + type.log(logger, 100); + std::string best_type; + if (!type.results.empty()){ + best_type = type.results.begin()->second; + } + if (best_type.empty()){ + dump_image(logger, info, "ReadTypeFailed", screen); + }else if (PreloadSettings::debug().IMAGE_TEMPLATE_MATCHING){ + dump_debug_image(logger, "PokemonSV/TeraRoller/" + best_type, "", screen); + } + + return best_type; +} +std::string TeraCardReader::pokemon_slug( + Logger& logger, const ProgramInfo& info, const ImageViewRGB32& screen +) const{ + ImageMatch::ImageMatchResult silhouette = m_silhouette.read(screen); + silhouette.log(logger, 100); + std::string best_silhouette; + if (!silhouette.results.empty()){ + best_silhouette = silhouette.results.begin()->second; + } + if (silhouette.results.empty()){ + dump_image(logger, info, "ReadSilhouetteFailed", screen); + }else if (PreloadSettings::debug().IMAGE_TEMPLATE_MATCHING){ + dump_debug_image(logger, "PokemonSV/TeraRoller/" + best_silhouette, "", screen); + } + + return best_silhouette; +} diff --git a/SerialPrograms/Source/PokemonSV/Inference/Tera/PokemonSV_TeraCardDetector.h b/SerialPrograms/Source/PokemonSV/Inference/Tera/PokemonSV_TeraCardDetector.h index f8da8bfbe..d10a990cb 100644 --- a/SerialPrograms/Source/PokemonSV/Inference/Tera/PokemonSV_TeraCardDetector.h +++ b/SerialPrograms/Source/PokemonSV/Inference/Tera/PokemonSV_TeraCardDetector.h @@ -13,8 +13,10 @@ #include "Common/Cpp/AbstractLogger.h" #include "CommonFramework/ImageTools/ImageBoxes.h" #include "CommonFramework/Inference/VisualDetector.h" -#include "CommonFramework/InferenceInfra/VisualInferenceCallback.h" +//#include "CommonFramework/InferenceInfra/VisualInferenceCallback.h" #include "PokemonSV/Options/PokemonSV_PlayerList.h" +#include "PokemonSV_TeraTypeReader.h" +#include "PokemonSV_TeraSilhouetteReader.h" namespace PokemonAutomation{ class AsyncDispatcher; @@ -35,6 +37,12 @@ class TeraCardReader : public StaticScreenDetector{ virtual bool detect(const ImageViewRGB32& screen) const override; size_t stars(const ImageViewRGB32& screen) const; + std::string tera_type( + Logger& logger, const ProgramInfo& info, const ImageViewRGB32& screen + ) const; + std::string pokemon_slug( + Logger& logger, const ProgramInfo& info, const ImageViewRGB32& screen + ) const; static const ImageFloatBox& CARD_LABEL_BOX(); static bool is_card_label(const ImageViewRGB32& screen); @@ -46,7 +54,10 @@ class TeraCardReader : public StaticScreenDetector{ ImageFloatBox m_bottom_right; ImageFloatBox m_label; ImageFloatBox m_cursor; + ImageFloatBox m_stars; + TeraTypeReader m_tera_type; + TeraSilhouetteReader m_silhouette; }; class TeraCardWatcher : public DetectorToFinder{ public: diff --git a/SerialPrograms/Source/PokemonSV/Options/PokemonSV_TeraMoveTable.h b/SerialPrograms/Source/PokemonSV/Options/PokemonSV_TeraMoveTable.h index 88d926a08..25e72cde7 100644 --- a/SerialPrograms/Source/PokemonSV/Options/PokemonSV_TeraMoveTable.h +++ b/SerialPrograms/Source/PokemonSV/Options/PokemonSV_TeraMoveTable.h @@ -7,9 +7,6 @@ #ifndef PokemonAutomation_PokemonSV_TeraMoveTable_H #define PokemonAutomation_PokemonSV_TeraMoveTable_H -//#include "Common/Cpp/Options/GroupOption.h" -//#include "Common/Cpp/Options/StaticTextOption.h" -//#include "Common/Cpp/Options/BooleanCheckBoxOption.h" #include "Common/Cpp/Options/SimpleIntegerOption.h" #include "Common/Cpp/Options/StringOption.h" #include "Common/Cpp/Options/EnumDropdownOption.h" diff --git a/SerialPrograms/Source/PokemonSV/Options/PokemonSV_TeraRollFilter.cpp b/SerialPrograms/Source/PokemonSV/Options/PokemonSV_TeraRollFilter.cpp new file mode 100644 index 000000000..93e55da14 --- /dev/null +++ b/SerialPrograms/Source/PokemonSV/Options/PokemonSV_TeraRollFilter.cpp @@ -0,0 +1,171 @@ +/* Tera Roll Filter + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#include "Common/Cpp/Exceptions.h" +#include "ClientSource/Connection/BotBase.h" +#include "CommonFramework/VideoPipeline/VideoFeed.h" +#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h" +#include "CommonFramework/Tools/ConsoleHandle.h" +//#include "CommonFramework/Tools/DebugDumper.h" +#include "CommonFramework/Tools/ErrorDumper.h" +#include "Pokemon/Pokemon_Strings.h" +#include "PokemonSV/Inference/Tera/PokemonSV_TeraCardDetector.h" +#include "PokemonSV/Programs/TeraRaids/PokemonSV_TeraRoutines.h" +#include "PokemonSV_TeraRollFilter.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonSV{ + + +TeraRollFilter::TeraRollFilter() + : GroupOption("Opponent Filter", LockWhileRunning::UNLOCKED) + , EVENT_CHECK_MODE( + "Event Tera Raid Action:
Choose how the program interacts with event/non-event raids." + "
Check only non-event can be further sped up if you exclude 6 star from your filters.", + { + {EventCheckMode::CHECK_ALL, "check_all", "Check everything. Don't filter by event."}, + {EventCheckMode::CHECK_ONLY_EVENT, "check_event", "Check only event raids."}, + {EventCheckMode::CHECK_ONLY_NONEVENT, "check_nonevent", "Check only non-event raids."}, + }, + LockWhileRunning::UNLOCKED, + EventCheckMode::CHECK_ALL + ) + , MIN_STARS( + "Min Stars:
Skip raids with less than this many stars.", + LockWhileRunning::UNLOCKED, + 1, 1, 7 + ) + , MAX_STARS( + "Max Stars:
Skip raids with more than this many stars.", + LockWhileRunning::UNLOCKED, + 4, 1, 7 + ) +{ + PA_ADD_OPTION(EVENT_CHECK_MODE); + PA_ADD_OPTION(MIN_STARS); + PA_ADD_OPTION(MAX_STARS); +} + +void TeraRollFilter::start_program_check(Logger& logger) const{ + if (MIN_STARS > MAX_STARS){ + throw UserSetupError(logger, "Error in the settings, \"Min Stars\" is bigger than \"Max Stars\"."); + } +} + +TeraRollFilter::FilterResult TeraRollFilter::run_filter( + const ProgramInfo& info, ConsoleHandle& console, BotBaseContext& context, + std::string* pokemon_slug, size_t* stars +){ + if (pokemon_slug != nullptr){ + pokemon_slug->clear(); + } + if (stars != nullptr){ + *stars = 0; + } + + uint8_t min_stars = MIN_STARS; + uint8_t max_stars = MAX_STARS; + EventCheckMode event_check_mode = EVENT_CHECK_MODE; + + bool sparkling_raid = false; + + switch (event_check_mode){ + case EventCheckMode::CHECK_ALL: + break; + case EventCheckMode::CHECK_ONLY_EVENT: + // this makes sure that we only check sparkling raids + // and that includes event & 6 star raids + // a later star check will be performed to exclude 6 star raids + if (!is_sparkling_raid(console, context)){ + console.log("No sparkling raid detected, skipping...", COLOR_ORANGE); + return FilterResult::NO_RAID; + } + break; + case EventCheckMode::CHECK_ONLY_NONEVENT: + if (is_sparkling_raid(console, context)){ + // if the user excluded 6 star raids, skip sparkling raids + if (min_stars > 6 || max_stars < 6){ + console.log("Sparkling raid detected, skipping...", COLOR_ORANGE); + return FilterResult::FAILED; + } + // if the user included 6 star raids, defer skip decision + sparkling_raid = true; + } + break; + } + + if (!open_raid(console, context)){ + return FilterResult::NO_RAID; + } + context.wait_for(std::chrono::milliseconds(500)); + + VideoSnapshot screen = console.video().snapshot(); + TeraCardReader reader(COLOR_RED); + size_t read_stars = reader.stars(screen); + if (stars != nullptr){ + *stars = read_stars; + } + if (read_stars == 0){ + dump_image(console, info, "ReadStarsFailed", *screen.frame); + } + + switch (event_check_mode){ + case EventCheckMode::CHECK_ALL: + break; + case EventCheckMode::CHECK_ONLY_EVENT: + // only sparkling raids at this point + // skip 6 star raids + if (read_stars == 6){ + console.log("Detected non-event 6 star raid, skipping...", COLOR_ORANGE); + close_raid(info, console, context); + return FilterResult::NO_RAID; + } + break; + case EventCheckMode::CHECK_ONLY_NONEVENT: + // skip sparkling raids unless 6 stars + if (sparkling_raid && read_stars != 6){ + console.log("Detected event raid, skipping...", COLOR_ORANGE); + close_raid(info, console, context); + return FilterResult::NO_RAID; + } + break; + } + context.wait_for_all_requests(); + + + VideoOverlaySet overlay_set(console); + + std::string silhouette = reader.pokemon_slug(console, info, screen); + if (silhouette.empty()){ + silhouette = "unknown " + Pokemon::STRING_POKEMON; + } + + std::string tera_type = reader.tera_type(console, info, screen); + if (tera_type.empty()){ + tera_type = "unknown tera type"; + } + + std::string log = "Detected a " + std::to_string(read_stars) + "* " + tera_type + " " + silhouette; + console.overlay().add_log(log, COLOR_GREEN); + console.log(log); + + if (read_stars < min_stars || read_stars > max_stars){ + close_raid(info, console, context); + return FilterResult::FAILED; + } + + // TODO: Add species filter + + return FilterResult::PASSED; +} + + + + +} +} +} diff --git a/SerialPrograms/Source/PokemonSV/Options/PokemonSV_TeraRollFilter.h b/SerialPrograms/Source/PokemonSV/Options/PokemonSV_TeraRollFilter.h new file mode 100644 index 000000000..30440c5f4 --- /dev/null +++ b/SerialPrograms/Source/PokemonSV/Options/PokemonSV_TeraRollFilter.h @@ -0,0 +1,57 @@ +/* Tera Roll Filter + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#ifndef PokemonAutomation_PokemonSV_TeraRollFilter_H +#define PokemonAutomation_PokemonSV_TeraRollFilter_H + +#include "Common/Cpp/Options/GroupOption.h" +#include "Common/Cpp/Options/SimpleIntegerOption.h" +#include "Common/Cpp/Options/EnumDropdownOption.h" + +namespace PokemonAutomation{ + class Logger; + class ConsoleHandle; + class BotBaseContext; + struct ProgramInfo; +namespace NintendoSwitch{ +namespace PokemonSV{ + + + +class TeraRollFilter : public GroupOption{ +public: + TeraRollFilter(); + + void start_program_check(Logger& logger) const; + + enum class FilterResult{ + NO_RAID, + FAILED, + PASSED, + }; + + FilterResult run_filter( + const ProgramInfo& info, ConsoleHandle& console, BotBaseContext& context, + std::string* pokemon_slug = nullptr, size_t* stars = nullptr + ); + + enum class EventCheckMode{ + CHECK_ALL, + CHECK_ONLY_EVENT, + CHECK_ONLY_NONEVENT, + }; + EnumDropdownOption EVENT_CHECK_MODE; + + SimpleIntegerOption MIN_STARS; + SimpleIntegerOption MAX_STARS; +}; + + + +} +} +} +#endif diff --git a/SerialPrograms/Source/PokemonSV/Programs/TeraRaids/PokemonSV_TeraRoller.cpp b/SerialPrograms/Source/PokemonSV/Programs/TeraRaids/PokemonSV_TeraRoller.cpp index 905f035a7..bdeca452c 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/TeraRaids/PokemonSV_TeraRoller.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/TeraRaids/PokemonSV_TeraRoller.cpp @@ -9,14 +9,14 @@ #include #include "Common/Cpp/Exceptions.h" #include "CommonFramework/Exceptions/ProgramFinishedException.h" -#include "CommonFramework/GlobalSettingsPanel.h" +//#include "CommonFramework/GlobalSettingsPanel.h" #include "CommonFramework/InferenceInfra/InferenceRoutines.h" #include "CommonFramework/Inference/VisualDetector.h" #include "CommonFramework/Notifications/ProgramNotifications.h" #include "CommonFramework/VideoPipeline/VideoFeed.h" #include "CommonFramework/VideoPipeline/VideoOverlay.h" -#include "CommonFramework/Tools/DebugDumper.h" -#include "CommonFramework/Tools/ErrorDumper.h" +//#include "CommonFramework/Tools/DebugDumper.h" +//#include "CommonFramework/Tools/ErrorDumper.h" #include "CommonFramework/Tools/StatsTracking.h" #include "CommonFramework/Tools/VideoResolutionCheck.h" #include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" @@ -25,8 +25,9 @@ #include "PokemonSV/PokemonSV_Settings.h" #include "PokemonSV/Inference/Boxes/PokemonSV_BoxShinyDetector.h" #include "PokemonSV/Inference/Tera/PokemonSV_TeraCardDetector.h" -#include "PokemonSV/Inference/Tera/PokemonSV_TeraSilhouetteReader.h" -#include "PokemonSV/Inference/Tera/PokemonSV_TeraTypeReader.h" +//#include "PokemonSV/Inference/Tera/PokemonSV_TeraSilhouetteReader.h" +//#include "PokemonSV/Inference/Tera/PokemonSV_TeraTypeReader.h" +#include "PokemonSV/Programs/PokemonSV_GameEntry.h" #include "PokemonSV/Programs/PokemonSV_SaveGame.h" #include "PokemonSV/Programs/PokemonSV_Navigation.h" #include "PokemonSV/Programs/TeraRaids/PokemonSV_TeraRoutines.h" @@ -57,18 +58,21 @@ TeraRoller_Descriptor::TeraRoller_Descriptor() struct TeraRoller_Descriptor::Stats : public StatsTracker{ Stats() : m_skips(m_stats["Date Skips"]) + , m_resets(m_stats["Resets"]) , m_raids(m_stats["Raids"]) , m_skipped(m_stats["Skipped"]) , m_errors(m_stats["Errors"]) , m_shinies(m_stats["Shinies"]) { m_display_order.emplace_back("Date Skips"); + m_display_order.emplace_back("Resets"); m_display_order.emplace_back("Raids"); m_display_order.emplace_back("Skipped"); m_display_order.emplace_back("Errors", true); m_display_order.emplace_back("Shinies", true); } std::atomic& m_skips; + std::atomic& m_resets; std::atomic& m_raids; std::atomic& m_skipped; std::atomic& m_errors; @@ -80,32 +84,6 @@ std::unique_ptr TeraRoller_Descriptor::make_stats() const{ -TeraRollerOpponentFilter::TeraRollerOpponentFilter() - : GroupOption("Opponent Filter", LockWhileRunning::UNLOCKED) - , MIN_STARS( - "Min Stars:
Skip raids with less than this many stars.", - LockWhileRunning::UNLOCKED, - 1, 1, 7 - ) - , MAX_STARS( - "Max Stars:
Skip raids with more than this many stars.", - LockWhileRunning::UNLOCKED, - 4, 1, 7 - ) -{ - PA_ADD_OPTION(MIN_STARS); - PA_ADD_OPTION(MAX_STARS); -} - -bool TeraRollerOpponentFilter::should_battle(size_t stars, const std::string& pokemon) const{ - if (stars < MIN_STARS || stars > MAX_STARS){ - return false; - } - - // TODO: Add species filter - - return true; -} TeraRoller::TeraRoller() @@ -114,16 +92,10 @@ TeraRoller::TeraRoller() LockWhileRunning::UNLOCKED, false ) - , EVENT_CHECK_MODE( - "Event Tera Raid Action:
Choose how the program interacts with event/non-event raids." - "
Check only non-event can be further sped up if you exclude 6 star from your filters.", - { - {EventCheckMode::CHECK_ALL, "check_all", "Ongoing event, check all raids / No ongoing event"}, - {EventCheckMode::CHECK_ONLY_EVENT, "check_event", "Ongoing event, check only event raids"}, - {EventCheckMode::CHECK_ONLY_NONEVENT, "check_nonevent", "Ongoing event, check only non-event raids"}, - }, - LockWhileRunning::LOCKED, - EventCheckMode::CHECK_ALL + , PERIODIC_RESET( + "Periodic Game Reset:
Reset the game after this many skips. This clears up the framerate bug.", + LockWhileRunning::UNLOCKED, + 20 ) , NOTIFICATION_STATUS_UPDATE("Status Update", true, false, std::chrono::seconds(3600)) , NOTIFICATION_SHINY( @@ -140,9 +112,9 @@ TeraRoller::TeraRoller() &NOTIFICATION_ERROR_FATAL, }) { - PA_ADD_OPTION(CHECK_ONLY_FIRST); - PA_ADD_OPTION(EVENT_CHECK_MODE); PA_ADD_OPTION(FILTER); + PA_ADD_OPTION(CHECK_ONLY_FIRST); + PA_ADD_OPTION(PERIODIC_RESET); PA_ADD_OPTION(NOTIFICATIONS); } @@ -152,6 +124,7 @@ void TeraRoller::program(SingleSwitchProgramEnvironment& env, BotBaseContext& co TeraRoller_Descriptor::Stats& stats = env.current_stats(); + FILTER.start_program_check(env.console); if (FILTER.MIN_STARS > FILTER.MAX_STARS){ throw UserSetupError(env.console, "Error in the settings, \"Min Stars\" is bigger than \"Max Stars\"."); } @@ -160,6 +133,7 @@ void TeraRoller::program(SingleSwitchProgramEnvironment& env, BotBaseContext& co pbf_press_button(context, BUTTON_L, 10, 10); bool first = true; + uint32_t skip_counter = 0; while (true){ env.update_stats(); @@ -170,119 +144,39 @@ void TeraRoller::program(SingleSwitchProgramEnvironment& env, BotBaseContext& co pbf_wait(context, GameSettings::instance().RAID_SPAWN_DELAY); context.wait_for_all_requests(); stats.m_skips++; + skip_counter++; + env.update_stats(); } first = false; - bool sparkling_raid = false; - - switch (EVENT_CHECK_MODE){ - case EventCheckMode::CHECK_ALL: - break; - case EventCheckMode::CHECK_ONLY_EVENT: - // this makes sure that we only check sparkling raids - // and that includes event & 6 star raids - // a later star check will be performed to exclude 6 star raids - if (!is_sparkling_raid(env, context)){ - env.log("No sparkling raid detected, skipping...", COLOR_ORANGE); - continue; - } - break; - case EventCheckMode::CHECK_ONLY_NONEVENT: - if (is_sparkling_raid(env, context)){ - // if the user excluded 6 star raids, skip sparkling raids - if (FILTER.MIN_STARS > 6 || FILTER.MAX_STARS < 6){ - env.log("Sparkling raid detected, skipping...", COLOR_ORANGE); - continue; - } - // if the user included 6 star raids, defer skip decision - sparkling_raid = true; - } - break; + uint8_t reset_period = PERIODIC_RESET; + if (reset_period != 0 && skip_counter >= reset_period){ + env.log("Resetting game to clear framerate."); + save_game_from_overworld(env.program_info(), env.console, context); + reset_game(env.program_info(), env.console, context); + skip_counter = 0; + stats.m_resets++; } - if (open_raid(env.console, context)){ + TeraRollFilter::FilterResult result = FILTER.run_filter(env.program_info(), env.console, context); + switch (result){ + case TeraRollFilter::FilterResult::NO_RAID: + continue; + case TeraRollFilter::FilterResult::FAILED: stats.m_raids++; - }else{ + stats.m_skipped++; continue; - } - context.wait_for(std::chrono::milliseconds(500)); - - VideoSnapshot screen = env.console.video().snapshot(); - TeraCardReader reader(COLOR_RED); - size_t stars = reader.stars(screen); - if (stars == 0){ - dump_image(env.logger(), env.program_info(), "ReadStarsFailed", *screen.frame); - } - - switch (EVENT_CHECK_MODE){ - case EventCheckMode::CHECK_ALL: - break; - case EventCheckMode::CHECK_ONLY_EVENT: - // only sparkling raids at this point - // skip 6 star raids - if (stars == 6){ - env.log("Detected non-event 6 star raid, skipping...", COLOR_ORANGE); - stats.m_skipped++; - close_raid(env.program_info(), env.console, context); - continue; - } - break; - case EventCheckMode::CHECK_ONLY_NONEVENT: - // skip sparkling raids unless 6 stars - if (sparkling_raid && stars != 6){ - env.log("Detected event raid, skipping...", COLOR_ORANGE); - stats.m_skipped++; - close_raid(env.program_info(), env.console, context); - continue; - } + case TeraRollFilter::FilterResult::PASSED: + stats.m_raids++; break; } - context.wait_for_all_requests(); - - VideoOverlaySet overlay_set(env.console); - - TeraSilhouetteReader silhouette_reader; - silhouette_reader.make_overlays(overlay_set); - ImageMatch::ImageMatchResult silhouette = silhouette_reader.read(screen); - silhouette.log(env.logger(), 100); - std::string best_silhouette = silhouette.results.empty() ? "UnknownSilhouette" : silhouette.results.begin()->second; - if (silhouette.results.empty()){ - dump_image(env.logger(), env.program_info(), "ReadSilhouetteFailed", *screen.frame); - } - else if (PreloadSettings::debug().IMAGE_TEMPLATE_MATCHING){ - dump_debug_image(env.logger(), "PokemonSV/TeraRoller/" + best_silhouette, "", screen); - } - - TeraTypeReader type_reader; - type_reader.make_overlays(overlay_set); - ImageMatch::ImageMatchResult type = type_reader.read(screen); - type.log(env.logger(), 100); - std::string best_type = type.results.empty() ? "UnknownType" : type.results.begin()->second; - if (type.results.empty()){ - dump_image(env.logger(), env.program_info(), "ReadTypeFailed", *screen.frame); - } - else if (PreloadSettings::debug().IMAGE_TEMPLATE_MATCHING){ - dump_debug_image(env.logger(), "PokemonSV/TeraRoller/" + best_type, "", screen); - } - { - std::string log = "Detected a " + std::to_string(stars) + "* " + best_type + " " + best_silhouette; - env.console.overlay().add_log(log, COLOR_GREEN); - env.log(log); - } - - if (!FILTER.should_battle(stars, best_silhouette)) { - env.log("Skipping raid...", COLOR_ORANGE); - stats.m_skipped++; - close_raid(env.program_info(), env.console, context); - continue; - } // Enter tera raid battle alone pbf_press_dpad(context, DPAD_DOWN, 10, 10); pbf_mash_button(context, BUTTON_A, 250); context.wait_for_all_requests(); - overlay_set.clear(); +// overlay_set.clear(); env.console.log("Entering tera raid..."); env.console.overlay().add_log("Entering tera raid...", COLOR_WHITE); @@ -297,7 +191,7 @@ void TeraRoller::program(SingleSwitchProgramEnvironment& env, BotBaseContext& co // Since encountering the same species within 5 encounters is possible, // loop through all 5 candidates of recently battled pokemon for shinies - for(int i = 0; i < 5; i++){ + for (int i = 0; i < 5; i++){ BoxShinyWatcher shiny_detector(COLOR_YELLOW, {0.187, 0.196, 0.028, 0.046}); context.wait_for_all_requests(); @@ -312,7 +206,7 @@ void TeraRoller::program(SingleSwitchProgramEnvironment& env, BotBaseContext& co env.console.overlay().add_log("Shiny!", COLOR_GREEN); stats.m_shinies += 1; - pbf_wait(context, 500); // Wait enough time for the Pokémon sprite to load + pbf_wait(context, 500); // Wait enough time for the Pokemon sprite to load context.wait_for_all_requests(); send_encounter_notification( env, diff --git a/SerialPrograms/Source/PokemonSV/Programs/TeraRaids/PokemonSV_TeraRoller.h b/SerialPrograms/Source/PokemonSV/Programs/TeraRaids/PokemonSV_TeraRoller.h index c6a7dba73..2f6a9fa08 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/TeraRaids/PokemonSV_TeraRoller.h +++ b/SerialPrograms/Source/PokemonSV/Programs/TeraRaids/PokemonSV_TeraRoller.h @@ -11,14 +11,13 @@ #include "Common/Cpp/Options/SimpleIntegerOption.h" #include "CommonFramework/Notifications/EventNotificationsTable.h" #include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h" +#include "PokemonSV/Options/PokemonSV_TeraRollFilter.h" namespace PokemonAutomation{ struct VideoSnapshot; namespace NintendoSwitch{ namespace PokemonSV{ -class TeraRoller; - class TeraRoller_Descriptor : public SingleSwitchProgramDescriptor{ public: @@ -32,34 +31,16 @@ class TeraRoller_Descriptor : public SingleSwitchProgramDescriptor{ -class TeraRollerOpponentFilter : public GroupOption{ -public: - TeraRollerOpponentFilter(); - - bool should_battle(size_t stars, const std::string& pokemon) const; - - SimpleIntegerOption MIN_STARS; - SimpleIntegerOption MAX_STARS; - -}; - - - class TeraRoller : public SingleSwitchProgramInstance{ public: TeraRoller(); virtual void program(SingleSwitchProgramEnvironment& env, BotBaseContext& context) override; private: + TeraRollFilter FILTER; + BooleanCheckBoxOption CHECK_ONLY_FIRST; - TeraRollerOpponentFilter FILTER; - - enum class EventCheckMode{ - CHECK_ALL, - CHECK_ONLY_EVENT, - CHECK_ONLY_NONEVENT, - }; - EnumDropdownOption EVENT_CHECK_MODE; + SimpleIntegerOption PERIODIC_RESET; // Notifications EventNotificationOption NOTIFICATION_STATUS_UPDATE; diff --git a/SerialPrograms/Source/PokemonSV/Programs/TeraRaids/PokemonSV_TeraRoutines.cpp b/SerialPrograms/Source/PokemonSV/Programs/TeraRaids/PokemonSV_TeraRoutines.cpp index 66f7f494c..673102c8c 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/TeraRaids/PokemonSV_TeraRoutines.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/TeraRaids/PokemonSV_TeraRoutines.cpp @@ -698,21 +698,21 @@ void run_from_tera_battle(const ProgramInfo& info, ConsoleHandle& console, BotBa } -bool is_sparkling_raid(SingleSwitchProgramEnvironment& env, BotBaseContext& context){ +bool is_sparkling_raid(ConsoleHandle& console, BotBaseContext& context){ OverworldWatcher static_map(COLOR_CYAN, true); context.wait_for_all_requests(); int ret = wait_until( - env.console, context, + console, context, std::chrono::seconds(2), {static_map} ); if (ret == 0){ - env.console.log("Did not detect sparkling raid", COLOR_ORANGE); + console.log("Did not detect sparkling raid", COLOR_ORANGE); return false; } - env.console.log("Detected sparkling raid", COLOR_ORANGE); + console.log("Detected sparkling raid", COLOR_ORANGE); return true; } diff --git a/SerialPrograms/Source/PokemonSV/Programs/TeraRaids/PokemonSV_TeraRoutines.h b/SerialPrograms/Source/PokemonSV/Programs/TeraRaids/PokemonSV_TeraRoutines.h index 811975368..435b4fd19 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/TeraRaids/PokemonSV_TeraRoutines.h +++ b/SerialPrograms/Source/PokemonSV/Programs/TeraRaids/PokemonSV_TeraRoutines.h @@ -11,7 +11,7 @@ #include #include #include "CommonFramework/Language.h" -#include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h" +//#include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h" //#include "CommonFramework/Tools/StatsTracking.h" namespace PokemonAutomation{ @@ -117,7 +117,7 @@ TeraResult run_tera_summary( // Run away from tera battle. void run_from_tera_battle(const ProgramInfo& info, ConsoleHandle& console, BotBaseContext& context); -bool is_sparkling_raid(SingleSwitchProgramEnvironment& env, BotBaseContext& context); +bool is_sparkling_raid(ConsoleHandle& console, BotBaseContext& context); }