diff --git a/SerialPrograms/CMakeLists.txt b/SerialPrograms/CMakeLists.txt index a7f928870..3935a551f 100644 --- a/SerialPrograms/CMakeLists.txt +++ b/SerialPrograms/CMakeLists.txt @@ -1378,6 +1378,10 @@ file(GLOB MAIN_SOURCES Source/PokemonSV/Options/PokemonSV_SandwichIngredientsTable.h Source/PokemonSV/Options/PokemonSV_SandwichMakerOption.cpp Source/PokemonSV/Options/PokemonSV_SandwichMakerOption.h + Source/PokemonSV/Options/PokemonSV_SinglesAIOption.cpp + Source/PokemonSV/Options/PokemonSV_SinglesAIOption.h + Source/PokemonSV/Options/PokemonSV_SinglesMoveTable.cpp + Source/PokemonSV/Options/PokemonSV_SinglesMoveTable.h Source/PokemonSV/Options/PokemonSV_TeraAIOption.cpp Source/PokemonSV/Options/PokemonSV_TeraAIOption.h Source/PokemonSV/Options/PokemonSV_TeraCatchOnWinOption.cpp @@ -1394,6 +1398,12 @@ file(GLOB MAIN_SOURCES Source/PokemonSV/PokemonSV_Panels.h Source/PokemonSV/PokemonSV_Settings.cpp Source/PokemonSV/PokemonSV_Settings.h + Source/PokemonSV/Programs/Battles/PokemonSV_BasicCatcher.cpp + Source/PokemonSV/Programs/Battles/PokemonSV_BasicCatcher.h + Source/PokemonSV/Programs/Battles/PokemonSV_Battles.cpp + Source/PokemonSV/Programs/Battles/PokemonSV_Battles.h + Source/PokemonSV/Programs/Battles/PokemonSV_SinglesBattler.cpp + Source/PokemonSV/Programs/Battles/PokemonSV_SinglesBattler.h Source/PokemonSV/Programs/Boxes/PokemonSV_BoxAttach.cpp Source/PokemonSV/Programs/Boxes/PokemonSV_BoxAttach.h Source/PokemonSV/Programs/Boxes/PokemonSV_BoxRelease.cpp @@ -1426,6 +1436,8 @@ file(GLOB MAIN_SOURCES Source/PokemonSV/Programs/Farming/PokemonSV_LPFarmer.h Source/PokemonSV/Programs/Farming/PokemonSV_TournamentFarmer.cpp Source/PokemonSV/Programs/Farming/PokemonSV_TournamentFarmer.h + Source/PokemonSV/Programs/Farming/PokemonSV_TournamentFarmer2.cpp + Source/PokemonSV/Programs/Farming/PokemonSV_TournamentFarmer2.h Source/PokemonSV/Programs/FastCodeEntry/PokemonSV_ClipboardFastCodeEntry.cpp Source/PokemonSV/Programs/FastCodeEntry/PokemonSV_ClipboardFastCodeEntry.h Source/PokemonSV/Programs/FastCodeEntry/PokemonSV_CodeEntry.cpp @@ -1454,10 +1466,6 @@ file(GLOB MAIN_SOURCES Source/PokemonSV/Programs/Glitches/PokemonSV_RideCloner-1.0.1.h Source/PokemonSV/Programs/PokemonSV_AreaZero.cpp Source/PokemonSV/Programs/PokemonSV_AreaZero.h - Source/PokemonSV/Programs/PokemonSV_BasicCatcher.cpp - Source/PokemonSV/Programs/PokemonSV_BasicCatcher.h - Source/PokemonSV/Programs/PokemonSV_Battles.cpp - Source/PokemonSV/Programs/PokemonSV_Battles.h Source/PokemonSV/Programs/PokemonSV_ConnectToInternet.cpp Source/PokemonSV/Programs/PokemonSV_ConnectToInternet.h Source/PokemonSV/Programs/PokemonSV_GameEntry.cpp diff --git a/SerialPrograms/SerialPrograms.pro b/SerialPrograms/SerialPrograms.pro index 0abbdb874..30012cfd3 100644 --- a/SerialPrograms/SerialPrograms.pro +++ b/SerialPrograms/SerialPrograms.pro @@ -688,6 +688,8 @@ SOURCES += \ Source/PokemonSV/Options/PokemonSV_SandwichIngredientsOption.cpp \ Source/PokemonSV/Options/PokemonSV_SandwichIngredientsTable.cpp \ Source/PokemonSV/Options/PokemonSV_SandwichMakerOption.cpp \ + Source/PokemonSV/Options/PokemonSV_SinglesAIOption.cpp \ + Source/PokemonSV/Options/PokemonSV_SinglesMoveTable.cpp \ Source/PokemonSV/Options/PokemonSV_TeraAIOption.cpp \ Source/PokemonSV/Options/PokemonSV_TeraCatchOnWinOption.cpp \ Source/PokemonSV/Options/PokemonSV_TeraMoveTable.cpp \ @@ -696,6 +698,9 @@ SOURCES += \ Source/PokemonSV/Options/PokemonSV_TournamentPrizeTable.cpp \ Source/PokemonSV/PokemonSV_Panels.cpp \ Source/PokemonSV/PokemonSV_Settings.cpp \ + Source/PokemonSV/Programs/Battles/PokemonSV_BasicCatcher.cpp \ + Source/PokemonSV/Programs/Battles/PokemonSV_Battles.cpp \ + Source/PokemonSV/Programs/Battles/PokemonSV_SinglesBattler.cpp \ Source/PokemonSV/Programs/Boxes/PokemonSV_BoxAttach.cpp \ Source/PokemonSV/Programs/Boxes/PokemonSV_BoxRelease.cpp \ Source/PokemonSV/Programs/Boxes/PokemonSV_BoxRoutines.cpp \ @@ -712,6 +717,7 @@ SOURCES += \ Source/PokemonSV/Programs/Farming/PokemonSV_GimmighoulRoamingFarmer.cpp \ Source/PokemonSV/Programs/Farming/PokemonSV_LPFarmer.cpp \ Source/PokemonSV/Programs/Farming/PokemonSV_TournamentFarmer.cpp \ + Source/PokemonSV/Programs/Farming/PokemonSV_TournamentFarmer2.cpp \ Source/PokemonSV/Programs/FastCodeEntry/PokemonSV_ClipboardFastCodeEntry.cpp \ Source/PokemonSV/Programs/FastCodeEntry/PokemonSV_CodeEntry.cpp \ Source/PokemonSV/Programs/FastCodeEntry/PokemonSV_FastCodeEntry.cpp \ @@ -726,8 +732,6 @@ SOURCES += \ Source/PokemonSV/Programs/Glitches/PokemonSV_CloneItems-1.0.1.cpp \ Source/PokemonSV/Programs/Glitches/PokemonSV_RideCloner-1.0.1.cpp \ Source/PokemonSV/Programs/PokemonSV_AreaZero.cpp \ - Source/PokemonSV/Programs/PokemonSV_BasicCatcher.cpp \ - Source/PokemonSV/Programs/PokemonSV_Battles.cpp \ Source/PokemonSV/Programs/PokemonSV_ConnectToInternet.cpp \ Source/PokemonSV/Programs/PokemonSV_GameEntry.cpp \ Source/PokemonSV/Programs/PokemonSV_Navigation.cpp \ @@ -1741,6 +1745,8 @@ HEADERS += \ Source/PokemonSV/Options/PokemonSV_SandwichIngredientsOption.h \ Source/PokemonSV/Options/PokemonSV_SandwichIngredientsTable.h \ Source/PokemonSV/Options/PokemonSV_SandwichMakerOption.h \ + Source/PokemonSV/Options/PokemonSV_SinglesAIOption.h \ + Source/PokemonSV/Options/PokemonSV_SinglesMoveTable.h \ Source/PokemonSV/Options/PokemonSV_TeraAIOption.h \ Source/PokemonSV/Options/PokemonSV_TeraCatchOnWinOption.h \ Source/PokemonSV/Options/PokemonSV_TeraMoveTable.h \ @@ -1749,6 +1755,9 @@ HEADERS += \ Source/PokemonSV/Options/PokemonSV_TournamentPrizeTable.h \ Source/PokemonSV/PokemonSV_Panels.h \ Source/PokemonSV/PokemonSV_Settings.h \ + Source/PokemonSV/Programs/Battles/PokemonSV_BasicCatcher.h \ + Source/PokemonSV/Programs/Battles/PokemonSV_Battles.h \ + Source/PokemonSV/Programs/Battles/PokemonSV_SinglesBattler.h \ Source/PokemonSV/Programs/Boxes/PokemonSV_BoxAttach.h \ Source/PokemonSV/Programs/Boxes/PokemonSV_BoxRelease.h \ Source/PokemonSV/Programs/Boxes/PokemonSV_BoxRoutines.h \ @@ -1765,6 +1774,7 @@ HEADERS += \ Source/PokemonSV/Programs/Farming/PokemonSV_GimmighoulRoamingFarmer.h \ Source/PokemonSV/Programs/Farming/PokemonSV_LPFarmer.h \ Source/PokemonSV/Programs/Farming/PokemonSV_TournamentFarmer.h \ + Source/PokemonSV/Programs/Farming/PokemonSV_TournamentFarmer2.h \ Source/PokemonSV/Programs/FastCodeEntry/PokemonSV_ClipboardFastCodeEntry.h \ Source/PokemonSV/Programs/FastCodeEntry/PokemonSV_CodeEntry.h \ Source/PokemonSV/Programs/FastCodeEntry/PokemonSV_FastCodeEntry.h \ @@ -1779,8 +1789,6 @@ HEADERS += \ Source/PokemonSV/Programs/Glitches/PokemonSV_CloneItems-1.0.1.h \ Source/PokemonSV/Programs/Glitches/PokemonSV_RideCloner-1.0.1.h \ Source/PokemonSV/Programs/PokemonSV_AreaZero.h \ - Source/PokemonSV/Programs/PokemonSV_BasicCatcher.h \ - Source/PokemonSV/Programs/PokemonSV_Battles.h \ Source/PokemonSV/Programs/PokemonSV_ConnectToInternet.h \ Source/PokemonSV/Programs/PokemonSV_GameEntry.h \ Source/PokemonSV/Programs/PokemonSV_Navigation.h \ diff --git a/SerialPrograms/Source/CommonFramework/Globals.cpp b/SerialPrograms/Source/CommonFramework/Globals.cpp index 5cb8fada1..eaf950e4d 100644 --- a/SerialPrograms/Source/CommonFramework/Globals.cpp +++ b/SerialPrograms/Source/CommonFramework/Globals.cpp @@ -24,8 +24,8 @@ namespace PokemonAutomation{ const bool IS_BETA_VERSION = true; const int PROGRAM_VERSION_MAJOR = 0; -const int PROGRAM_VERSION_MINOR = 44; -const int PROGRAM_VERSION_PATCH = 2; +const int PROGRAM_VERSION_MINOR = 45; +const int PROGRAM_VERSION_PATCH = 1; const std::string PROGRAM_VERSION_BASE = "v" + std::to_string(PROGRAM_VERSION_MAJOR) + diff --git a/SerialPrograms/Source/NintendoSwitch/DevPrograms/TestProgramSwitch.cpp b/SerialPrograms/Source/NintendoSwitch/DevPrograms/TestProgramSwitch.cpp index 28b9975dd..4a620b181 100644 --- a/SerialPrograms/Source/NintendoSwitch/DevPrograms/TestProgramSwitch.cpp +++ b/SerialPrograms/Source/NintendoSwitch/DevPrograms/TestProgramSwitch.cpp @@ -60,7 +60,7 @@ #include "PokemonLA/Programs/PokemonLA_GameEntry.h" #include "PokemonSV/Programs/PokemonSV_GameEntry.h" #include "PokemonSV/Programs/PokemonSV_Navigation.h" -#include "PokemonSV/Programs/PokemonSV_BasicCatcher.h" +#include "PokemonSV/Programs/Battles/PokemonSV_BasicCatcher.h" #include "PokemonSwSh/Inference/PokemonSwSh_YCommDetector.h" #include "PokemonSV/Inference/Tera/PokemonSV_TeraCardDetector.h" #include "PokemonSV/Inference/PokemonSV_PokemonSummaryReader.h" @@ -92,7 +92,7 @@ #include "PokemonSV/Programs/ShinyHunting/PokemonSV_AreaZeroPlatform.h" #include "PokemonSV/Inference/PokemonSV_SweatBubbleDetector.h" #include "PokemonSV/Programs/PokemonSV_AreaZero.h" -#include "PokemonSV/Programs/PokemonSV_Battles.h" +#include "PokemonSV/Programs/Battles/PokemonSV_Battles.h" #include "PokemonSV/Programs/PokemonSV_SaveGame.h" #include "PokemonSV/Inference/Battles/PokemonSV_NormalBattleMenus.h" #include "PokemonSV/Inference/Battles/PokemonSV_TeraBattleMenus.h" @@ -113,6 +113,7 @@ #include "NintendoSwitch/Programs/NintendoSwitch_GameEntry.h" #include "PokemonSwSh/Inference/PokemonSwSh_ReceivePokemonDetector.h" #include "PokemonSV/Inference/PokemonSV_PokemonSummaryReader.h" +#include "PokemonSV/Programs/Battles/PokemonSV_SinglesBattler.h" @@ -195,6 +196,7 @@ TestProgram::TestProgram() PA_ADD_OPTION(STATIC_TEXT); PA_ADD_OPTION(SELECT); PA_ADD_OPTION(PLAYER_LIST); + PA_ADD_OPTION(battle_AI); PA_ADD_OPTION(NOTIFICATIONS); BUTTON0.add_listener(*this); BUTTON1.add_listener(*this); @@ -228,8 +230,8 @@ void TestProgram::program(MultiSwitchProgramEnvironment& env, CancellableScope& using namespace Pokemon; // using namespace PokemonSwSh; // using namespace PokemonBDSP; - using namespace PokemonLA; -// using namespace PokemonSV; +// using namespace PokemonLA; + using namespace PokemonSV; [[maybe_unused]] Logger& logger = env.logger(); [[maybe_unused]] ConsoleHandle& console = env.consoles[0]; @@ -240,12 +242,31 @@ void TestProgram::program(MultiSwitchProgramEnvironment& env, CancellableScope& VideoOverlaySet overlays(overlay); +// SinglesAIOption battle_AI; + run_singles_battle(env, console, context, battle_AI, false); + + +#if 0 + run_pokemon( + console, context, + { + {SinglesMoveType::Move1, false}, + {SinglesMoveType::Move2, false}, + {SinglesMoveType::Move4, true}, + {SinglesMoveType::Run, false}, + } + ); +#endif + + + +#if 0 auto snapshot = console.video().snapshot(); PokemonSummaryDetector detector; detector.make_overlays(overlays); cout << detector.detect(snapshot) << endl; - +#endif #if 0 diff --git a/SerialPrograms/Source/NintendoSwitch/DevPrograms/TestProgramSwitch.h b/SerialPrograms/Source/NintendoSwitch/DevPrograms/TestProgramSwitch.h index 788294ef1..e276270a6 100644 --- a/SerialPrograms/Source/NintendoSwitch/DevPrograms/TestProgramSwitch.h +++ b/SerialPrograms/Source/NintendoSwitch/DevPrograms/TestProgramSwitch.h @@ -20,6 +20,7 @@ #include "PokemonSwSh/Options/EncounterFilter/PokemonSwSh_EncounterFilterOption.h" #include "PokemonSV/Options/PokemonSV_PlayerList.h" #include "CommonFramework/Tools/StatsTracking.h" +#include "PokemonSV/Options/PokemonSV_SinglesAIOption.h" namespace PokemonAutomation{ namespace NintendoSwitch{ @@ -70,6 +71,8 @@ class TestProgram : public MultiSwitchProgramInstance, public ButtonListener{ PokemonSV::PlayerListTable PLAYER_LIST; + PokemonSV::SinglesAIOption battle_AI; + EventNotificationOption NOTIFICATION_TEST; EventNotificationsOption NOTIFICATIONS; }; diff --git a/SerialPrograms/Source/PokemonSV/Inference/Battles/PokemonSV_NormalBattleMenus.cpp b/SerialPrograms/Source/PokemonSV/Inference/Battles/PokemonSV_NormalBattleMenus.cpp index 0f27ff54f..13b29f1f4 100644 --- a/SerialPrograms/Source/PokemonSV/Inference/Battles/PokemonSV_NormalBattleMenus.cpp +++ b/SerialPrograms/Source/PokemonSV/Inference/Battles/PokemonSV_NormalBattleMenus.cpp @@ -66,7 +66,11 @@ bool NormalBattleMenuDetector::move_to_slot(ConsoleHandle& console, BotBaseConte int8_t current_slot = detect_slot(screen); if (current_slot < 0 || current_slot > 3){ console.log("NormalBattleMenuDetector::move_to_slot(): Unable to detect slot.", COLOR_RED); - return false; + context.wait_for(std::chrono::milliseconds(500)); + continue; +// static int c = 0; +// screen->save("bad-" + std::to_string(c++) + ".png"); // REMOVE +// return false; } if (attempts > 10){ console.log("NormalBattleMenuDetector::move_to_slot(): Failed to move slot after 10 attempts.", COLOR_RED); @@ -75,8 +79,11 @@ bool NormalBattleMenuDetector::move_to_slot(ConsoleHandle& console, BotBaseConte uint8_t diff = (4 + slot - (uint8_t)current_slot) % 4; switch (diff){ - case 0: + case 0:{ +// static int c = 0; +// screen->save("good-" + std::to_string(c++) + ".png"); // REMOVE return true; + } case 1: pbf_press_dpad(context, DPAD_DOWN, 20, 30); continue; diff --git a/SerialPrograms/Source/PokemonSV/Options/PokemonSV_SinglesAIOption.cpp b/SerialPrograms/Source/PokemonSV/Options/PokemonSV_SinglesAIOption.cpp new file mode 100644 index 000000000..b07ba5f67 --- /dev/null +++ b/SerialPrograms/Source/PokemonSV/Options/PokemonSV_SinglesAIOption.cpp @@ -0,0 +1,55 @@ +/* Singles AI Option + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#include "Common/Cpp/Containers/FixedLimitVector.tpp" +#include "Pokemon/Pokemon_Strings.h" +#include "PokemonSV_SinglesAIOption.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonSV{ + +using namespace Pokemon; + + + +SinglesAIOption::SinglesAIOption() + : GroupOption( + "Battle AI", + LockMode::UNLOCK_WHILE_RUNNING, + false, true + ) + , description( + "Move Tables: Run these sequence of moves for the corresponding " + STRING_POKEMON + " in your party. " + "When the end of the table is reached, the last entry will be repeated " + "until the battle is won or the " + STRING_POKEMON +" faints. " + "If your " + STRING_POKEMON + " faints, the program will switch to the " + "next available " + STRING_POKEMON + " and run its table. " + "Changes to these tables take effect the next the " + STRING_POKEMON + " is sent out." + ) + , MOVE_TABLES(6) +{ + MOVE_TABLES.emplace_back("1st " + STRING_POKEMON + " Move Table:"); + MOVE_TABLES.emplace_back("2nd " + STRING_POKEMON + " Move Table:"); + MOVE_TABLES.emplace_back("3rd " + STRING_POKEMON + " Move Table:"); + MOVE_TABLES.emplace_back("4th " + STRING_POKEMON + " Move Table:"); + MOVE_TABLES.emplace_back("5th " + STRING_POKEMON + " Move Table:"); + MOVE_TABLES.emplace_back("6th " + STRING_POKEMON + " Move Table:"); + + PA_ADD_STATIC(description); + size_t c = 0; + for (SinglesMoveTable& table : MOVE_TABLES){ + add_option(table, "MOVE_TABLE" + std::to_string(++c)); + } +} + + + + + +} +} +} diff --git a/SerialPrograms/Source/PokemonSV/Options/PokemonSV_SinglesAIOption.h b/SerialPrograms/Source/PokemonSV/Options/PokemonSV_SinglesAIOption.h new file mode 100644 index 000000000..b9e0b499c --- /dev/null +++ b/SerialPrograms/Source/PokemonSV/Options/PokemonSV_SinglesAIOption.h @@ -0,0 +1,38 @@ +/* Singles AI Option + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#ifndef PokemonAutomation_PokemonSV_SinglesAIOption_H +#define PokemonAutomation_PokemonSV_SinglesAIOption_H + +#include "Common/Cpp/Containers/FixedLimitVector.h" +#include "Common/Cpp/Options/StaticTextOption.h" +//#include "Common/Cpp/Options/BooleanCheckBoxOption.h" +#include "Common/Cpp/Options/GroupOption.h" +#include "PokemonSV_SinglesMoveTable.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonSV{ + + + +class SinglesAIOption : public GroupOption{ +public: + SinglesAIOption(); + +public: + StaticTextOption description; + FixedLimitVector MOVE_TABLES; + +}; + + + + +} +} +} +#endif diff --git a/SerialPrograms/Source/PokemonSV/Options/PokemonSV_SinglesMoveTable.cpp b/SerialPrograms/Source/PokemonSV/Options/PokemonSV_SinglesMoveTable.cpp new file mode 100644 index 000000000..0981dce99 --- /dev/null +++ b/SerialPrograms/Source/PokemonSV/Options/PokemonSV_SinglesMoveTable.cpp @@ -0,0 +1,119 @@ +/* Single Battle Move Table + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#include "PokemonSV_SinglesMoveTable.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonSV{ + + +const EnumDatabase& singles_move_enum_database(){ + static EnumDatabase database{ + {SinglesMoveType::Move1, "move1", "Move 1"}, + {SinglesMoveType::Move2, "move2", "Move 2"}, + {SinglesMoveType::Move3, "move3", "Move 3"}, + {SinglesMoveType::Move4, "move4", "Move 4"}, + {SinglesMoveType::Run, "run", "Run"}, + }; + return database; +} + +std::string SinglesMoveEntry::to_str() const{ + switch (type){ + case SinglesMoveType::Move1: + case SinglesMoveType::Move2: + case SinglesMoveType::Move3: + case SinglesMoveType::Move4:{ + int slot = (int)type - (int)SinglesMoveType::Move1; + std::string str = "Move " + std::to_string(slot + 1); + if (terastallize){ + str += " (terastallize)"; + } + str += "."; + return str; + } + case SinglesMoveType::Run: + return "Run Away"; + } + return "(Invalid Move)"; +} + + + +SinglesMoveTableRow::~SinglesMoveTableRow(){ + type.remove_listener(*this); +} +SinglesMoveTableRow::SinglesMoveTableRow() + : type(singles_move_enum_database(), LockMode::UNLOCK_WHILE_RUNNING, SinglesMoveType::Move1) + , terastallize(LockMode::UNLOCK_WHILE_RUNNING, false) + , notes(false, LockMode::UNLOCK_WHILE_RUNNING, "", "(e.g. Screech, Belly Drum)") +{ + PA_ADD_OPTION(type); + PA_ADD_OPTION(terastallize); + PA_ADD_OPTION(notes); + + SinglesMoveTableRow::value_changed(); + type.add_listener(*this); +} +std::unique_ptr SinglesMoveTableRow::clone() const{ + std::unique_ptr ret(new SinglesMoveTableRow()); + ret->type.set(type); + ret->terastallize = (bool)terastallize; + ret->notes.set(notes); + return ret; +} +SinglesMoveEntry SinglesMoveTableRow::snapshot() const{ + return SinglesMoveEntry{type, terastallize}; +} +void SinglesMoveTableRow::value_changed(){ + +} + + + + + +SinglesMoveTable::SinglesMoveTable(std::string label) + : EditableTableOption_t( + std::move(label), +#if 0 + "Move Table:
" + "Run this sequence of moves. When the end of the table is reached, " + "the last entry will be repeated until the battle is won or your " + Pokemon::STRING_POKEMON +" faints." + "Changes to this table take effect on the next battle.", +#endif + LockMode::UNLOCK_WHILE_RUNNING, + make_defaults() + ) +{} + +std::vector SinglesMoveTable::snapshot(){ + return EditableTableOption_t::snapshot(); +} +std::vector SinglesMoveTable::make_header() const{ + return { + "Move", + "Terastallize", + "Notes", + }; +} +std::vector> SinglesMoveTable::make_defaults(){ + std::vector> ret; + ret.emplace_back(new SinglesMoveTableRow()); + return ret; +} + + + + + + + + +} +} +} diff --git a/SerialPrograms/Source/PokemonSV/Options/PokemonSV_SinglesMoveTable.h b/SerialPrograms/Source/PokemonSV/Options/PokemonSV_SinglesMoveTable.h new file mode 100644 index 000000000..c4033b66d --- /dev/null +++ b/SerialPrograms/Source/PokemonSV/Options/PokemonSV_SinglesMoveTable.h @@ -0,0 +1,73 @@ +/* Singles Move Table + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#ifndef PokemonAutomation_PokemonSV_SinglesMoveTable_H +#define PokemonAutomation_PokemonSV_SinglesMoveTable_H + +#include "Common/Cpp/Options/BooleanCheckBoxOption.h" +#include "Common/Cpp/Options/StringOption.h" +#include "Common/Cpp/Options/EnumDropdownOption.h" +#include "Common/Cpp/Options/EditableTableOption.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonSV{ + + +enum class SinglesMoveType{ + Move1, + Move2, + Move3, + Move4, + Run, +}; +const EnumDatabase& singles_move_enum_database(); + + +struct SinglesMoveEntry{ + SinglesMoveType type; + bool terastallize; + + std::string to_str() const; +}; + + +class SinglesMoveTableRow : public EditableTableRow, public ConfigOption::Listener{ +public: + ~SinglesMoveTableRow(); + SinglesMoveTableRow(); + virtual std::unique_ptr clone() const override; + + SinglesMoveEntry snapshot() const; + +private: + virtual void value_changed() override; + +private: + EnumDropdownCell type; + BooleanCheckBoxCell terastallize; + StringCell notes; +}; + + +class SinglesMoveTable : public EditableTableOption_t{ +public: + SinglesMoveTable(std::string label); + + std::vector snapshot(); + + virtual std::vector make_header() const; + + static std::vector> make_defaults(); + +}; + + + +} +} +} +#endif diff --git a/SerialPrograms/Source/PokemonSV/Options/PokemonSV_TeraAIOption.cpp b/SerialPrograms/Source/PokemonSV/Options/PokemonSV_TeraAIOption.cpp index 95c675ceb..1fcbdc7e0 100644 --- a/SerialPrograms/Source/PokemonSV/Options/PokemonSV_TeraAIOption.cpp +++ b/SerialPrograms/Source/PokemonSV/Options/PokemonSV_TeraAIOption.cpp @@ -1,4 +1,4 @@ -/* Battle AI Option +/* Tera AI Option * * From: https://github.com/PokemonAutomation/Arduino-Source * diff --git a/SerialPrograms/Source/PokemonSV/PokemonSV_Panels.cpp b/SerialPrograms/Source/PokemonSV/PokemonSV_Panels.cpp index 72e550fd9..f51647084 100644 --- a/SerialPrograms/Source/PokemonSV/PokemonSV_Panels.cpp +++ b/SerialPrograms/Source/PokemonSV/PokemonSV_Panels.cpp @@ -28,6 +28,7 @@ #include "Programs/Farming/PokemonSV_AuctionFarmer.h" #include "Programs/Farming/PokemonSV_ESPTraining.h" #include "Programs/Farming/PokemonSV_TournamentFarmer.h" +#include "Programs/Farming/PokemonSV_TournamentFarmer2.h" #include "Programs/Farming/PokemonSV_FlyingTrialFarmer.h" #include "Programs/Eggs/PokemonSV_EggFetcher.h" @@ -98,6 +99,9 @@ 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()); + if (PreloadSettings::instance().DEVELOPER_MODE){ + ret.emplace_back(make_single_switch_program()); + } ret.emplace_back(make_single_switch_program()); ret.emplace_back("---- Eggs ----"); diff --git a/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_BasicCatcher.cpp b/SerialPrograms/Source/PokemonSV/Programs/Battles/PokemonSV_BasicCatcher.cpp similarity index 100% rename from SerialPrograms/Source/PokemonSV/Programs/PokemonSV_BasicCatcher.cpp rename to SerialPrograms/Source/PokemonSV/Programs/Battles/PokemonSV_BasicCatcher.cpp diff --git a/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_BasicCatcher.h b/SerialPrograms/Source/PokemonSV/Programs/Battles/PokemonSV_BasicCatcher.h similarity index 100% rename from SerialPrograms/Source/PokemonSV/Programs/PokemonSV_BasicCatcher.h rename to SerialPrograms/Source/PokemonSV/Programs/Battles/PokemonSV_BasicCatcher.h diff --git a/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_Battles.cpp b/SerialPrograms/Source/PokemonSV/Programs/Battles/PokemonSV_Battles.cpp similarity index 100% rename from SerialPrograms/Source/PokemonSV/Programs/PokemonSV_Battles.cpp rename to SerialPrograms/Source/PokemonSV/Programs/Battles/PokemonSV_Battles.cpp diff --git a/SerialPrograms/Source/PokemonSV/Programs/PokemonSV_Battles.h b/SerialPrograms/Source/PokemonSV/Programs/Battles/PokemonSV_Battles.h similarity index 100% rename from SerialPrograms/Source/PokemonSV/Programs/PokemonSV_Battles.h rename to SerialPrograms/Source/PokemonSV/Programs/Battles/PokemonSV_Battles.h diff --git a/SerialPrograms/Source/PokemonSV/Programs/Battles/PokemonSV_SinglesBattler.cpp b/SerialPrograms/Source/PokemonSV/Programs/Battles/PokemonSV_SinglesBattler.cpp new file mode 100644 index 000000000..563983d3a --- /dev/null +++ b/SerialPrograms/Source/PokemonSV/Programs/Battles/PokemonSV_SinglesBattler.cpp @@ -0,0 +1,330 @@ +/* Singles Battler + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#include "CommonFramework/Exceptions/OperationFailedException.h" +#include "CommonFramework/InferenceInfra/InferenceRoutines.h" +#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" +#include "Pokemon/Pokemon_Strings.h" +#include "PokemonSV/Inference/Dialogs/PokemonSV_DialogDetector.h" +#include "PokemonSV/Inference/Overworld/PokemonSV_OverworldDetector.h" +#include "PokemonSV/Inference/Battles/PokemonSV_NormalBattleMenus.h" +#include "PokemonSV_SinglesBattler.h" + +//#include +//using std::cout; +//using std::endl; + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonSV{ + +using namespace Pokemon; + + +// Run a single move for a single turn. +// Returns true if move is successfully selected. +bool run_move_select( + ConsoleHandle& console, BotBaseContext& context, + MoveSelectWatcher& move_select_menu, + SinglesMoveEntry& move, size_t consecutive_move_select +){ + uint8_t index = 0; + switch (move.type){ + case SinglesMoveType::Move1: + index = 0; + break; + case SinglesMoveType::Move2: + index = 1; + break; + case SinglesMoveType::Move3: + index = 2; + break; + case SinglesMoveType::Move4: + index = 3; + break; + default: + pbf_press_button(context, BUTTON_B, 20, 10); + return false; + } + + // If we end up here consecutively too many times, the move is + // probably disabled. Select a different move. + if (consecutive_move_select > 3){ + console.log("Failed to select a move 3 times. Choosing a different move.", COLOR_RED); +// pbf_press_dpad(context, DPAD_DOWN, 20, 40); + index++; + if (index >= 4){ + index = 0; + } + move.type = (SinglesMoveType)((uint8_t)SinglesMoveType::Move1 + index); + } + + do{ + if (!move.terastallize){ + console.log("Skipping Terastallization. Reason: Not requested."); + break; + } + if (consecutive_move_select > 1){ + console.log("Skipping Terastallization. Reason: Previously failed move select."); + break; + } + + console.log("Attempting to Terastallize..."); + pbf_press_button(context, BUTTON_R, 20, 1 * TICKS_PER_SECOND); + }while (false); + + context.wait_for_all_requests(); + + if (move_select_menu.move_to_slot(console, context, index)){ + pbf_press_button(context, BUTTON_A, 20, 10); + } + return true; +} + + +bool run_battle_menu( + ConsoleHandle& console, BotBaseContext& context, + NormalBattleMenuWatcher& battle_menu, + const SinglesMoveEntry& move +){ + console.log("Current Move Selection: " + move.to_str()); + switch (move.type){ + case SinglesMoveType::Move1: + case SinglesMoveType::Move2: + case SinglesMoveType::Move3: + case SinglesMoveType::Move4: + if (battle_menu.move_to_slot(console, context, 0)){ + pbf_press_button(context, BUTTON_A, 20, 10); + return true; + }else{ + console.log("Unable to move to battle slot.", COLOR_RED); + pbf_mash_button(context, BUTTON_B, 125); + return false; + } + case SinglesMoveType::Run: + if (battle_menu.move_to_slot(console, context, 3)){ + pbf_press_button(context, BUTTON_A, 20, 10); + return true; + }else{ + console.log("Unable to move to run option.", COLOR_RED); + pbf_mash_button(context, BUTTON_B, 125); + return false; + } + } + throw OperationFailedException( + ErrorReport::SEND_ERROR_REPORT, + console, + "Invalid SinglesMoveType: " + std::to_string((int)move.type) + ); +} + + +// Run a battle using the current Pokemon. Returns false if it fainted. +bool run_pokemon( + ConsoleHandle& console, BotBaseContext& context, + const std::vector& move_table, + bool trainer_battle, bool& terastallized +){ + console.log("Starting singles battle routine for one " + STRING_POKEMON + "..."); + + size_t turn = 0; + SinglesMoveEntry current_move{SinglesMoveType::Move1, false}; + if (!move_table.empty()){ + current_move = move_table[0]; + } + + size_t consecutive_timeouts = 0; + size_t consecutive_move_select = 0; +// bool battle_menu_seen = false; + bool next_turn_on_battle_menu = false; + while (true){ + + NormalBattleMenuWatcher battle_menu(COLOR_RED); + MoveSelectWatcher move_select_menu(COLOR_YELLOW); + GradientArrowWatcher next_pokemon(COLOR_BLUE, GradientArrowType::RIGHT, {0.50, 0.51, 0.30, 0.10}); + SwapMenuWatcher swap_menu(COLOR_BLUE); + AdvanceDialogWatcher dialog(COLOR_CYAN); + OverworldWatcher overworld(COLOR_GREEN); + context.wait_for_all_requests(); + int ret = run_until( + console, context, + [](BotBaseContext& context){ + for (size_t c = 0; c < 4; c++){ + pbf_wait(context, 30 * TICKS_PER_SECOND); + pbf_press_button(context, BUTTON_B, 20, 0); + } + }, + { + battle_menu, + move_select_menu, + next_pokemon, + swap_menu, + dialog, + overworld, + } + ); + if (ret >= 0){ + consecutive_timeouts = 0; + } + context.wait_for(std::chrono::milliseconds(100)); + switch (ret){ + case 0:{ + console.log("Detected battle menu."); + consecutive_move_select = 0; +// battle_menu_seen = true; + + // If we enter here, we advance to the next turn. + if (next_turn_on_battle_menu){ + console.log("Detected battle menu. Turn: " + std::to_string(turn)); + turn++; + // Reset the move to the table entry in case we were forced to + // change moves due to move being unselectable. + if (move_table.empty()){ + current_move = SinglesMoveEntry{SinglesMoveType::Move1, false}; + }else if (turn < move_table.size()){ + current_move = move_table[turn]; + }else{ + current_move = move_table.back(); + } +// next_turn_on_battle_menu = false; + } + + if (terastallized){ + console.log("Already used terastallization. Cannot use again.", COLOR_ORANGE); + current_move.terastallize = false; + } + next_turn_on_battle_menu = run_battle_menu(console, context, battle_menu, current_move); + if (current_move.terastallize){ + terastallized = true; + } + continue; + } + case 1:{ + console.log("Detected move select. Turn: " + std::to_string(turn)); + consecutive_move_select++; + run_move_select( + console, context, + move_select_menu, + current_move, + consecutive_move_select + ); + continue; + } + case 2: + if (trainer_battle){ + console.log("Detected switch prompt...", COLOR_BLUE); + pbf_press_button(context, BUTTON_B, 20, 10); + }else{ + console.log("Detected own " + STRING_POKEMON + " fainted...", COLOR_ORANGE); + pbf_press_button(context, BUTTON_A, 20, 10); + } + continue; + case 3: + console.log("Detected switch " + STRING_POKEMON + " menu...", COLOR_ORANGE); + return false; + case 4: + console.log("Detected advance dialog!", COLOR_ORANGE); + return true; + case 5: + console.log("Detected overworld!", COLOR_ORANGE); + return true; + default: + consecutive_timeouts++; + if (consecutive_timeouts == 3){ + throw OperationFailedException( + ErrorReport::SEND_ERROR_REPORT, console, + "No state detected after 6 minutes.", + true + ); + } + console.log("Unable to detect any state for 2 minutes. Mashing B...", COLOR_RED); + pbf_mash_button(context, BUTTON_B, 250); + } + + + } + + + +} + + + + + + + +bool run_singles_battle( + ProgramEnvironment& env, + ConsoleHandle& console, BotBaseContext& context, + SinglesAIOption& battle_AI, + bool trainer_battle +){ + console.log("Starting singles battle routine..."); + + bool terastallized = false; + size_t faint_counter = 0; + while (true){ + bool win = run_pokemon( + console, context, + battle_AI.MOVE_TABLES[std::min(faint_counter, 5)].snapshot(), + trainer_battle, terastallized + ); + + if (win){ + return true; + } + + // Find something to send out. + faint_counter++; + + NormalBattleMenuWatcher battle_menu(COLOR_RED); + AdvanceDialogWatcher dialog(COLOR_CYAN); + SwapMenuWatcher swap_menu(COLOR_BLUE); + while (true){ + context.wait_for_all_requests(); + int ret = wait_until( + console, context, + std::chrono::seconds(120), + {battle_menu, dialog, swap_menu} + ); + context.wait_for(std::chrono::milliseconds(100)); + switch (ret){ + case 0: + console.log("Detected battle menu. Calling battle routine..."); + break; + case 1: + console.log("Detected advance dialog. Battle has been expectedly won already.", COLOR_RED); + return true; + case 2: + console.log("Attempting to send in next " + STRING_POKEMON + "..."); + pbf_press_dpad(context, DPAD_DOWN, 20, 105); + pbf_press_button(context, BUTTON_A, 20, 105); + pbf_press_button(context, BUTTON_A, 20, 105); + pbf_mash_button(context, BUTTON_B, 250); + pbf_wait(context, 50); + continue; + default: + throw OperationFailedException( + ErrorReport::SEND_ERROR_REPORT, + console, "Unable to send in a " + STRING_POKEMON + ".", + true + ); + } + break; + } + } +} + + + + + + + +} +} +} diff --git a/SerialPrograms/Source/PokemonSV/Programs/Battles/PokemonSV_SinglesBattler.h b/SerialPrograms/Source/PokemonSV/Programs/Battles/PokemonSV_SinglesBattler.h new file mode 100644 index 000000000..81c72b6f8 --- /dev/null +++ b/SerialPrograms/Source/PokemonSV/Programs/Battles/PokemonSV_SinglesBattler.h @@ -0,0 +1,46 @@ +/* Singles Battler + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#ifndef PokemonAutomation_PokemonSV_SinglesBattler_H +#define PokemonAutomation_PokemonSV_SinglesBattler_H + +#include "ClientSource/Connection/BotBase.h" +#include "CommonFramework/Tools/ConsoleHandle.h" +#include "CommonFramework/Tools/ProgramEnvironment.h" +#include "PokemonSV/Options/PokemonSV_SinglesMoveTable.h" +#include "PokemonSV/Options/PokemonSV_SinglesAIOption.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonSV{ + + +//enum RunPokemonResult{ +// OWN_FAINTED, +// OVERWORLD, +//}; + +bool run_pokemon( + ConsoleHandle& console, BotBaseContext& context, + const std::vector& move_table, + bool trainer_battle, bool& terastallized +); + + +// Run a singles battle until it is over (for whatever reason). +bool run_singles_battle( + ProgramEnvironment& env, + ConsoleHandle& console, BotBaseContext& context, + SinglesAIOption& battle_AI, + bool trainer_battle +); + + + +} +} +} +#endif diff --git a/SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_FlyingTrialFarmer.cpp b/SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_FlyingTrialFarmer.cpp index 554185f29..b8baf50ac 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_FlyingTrialFarmer.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_FlyingTrialFarmer.cpp @@ -89,7 +89,9 @@ FlyingTrialFarmer::FlyingTrialFarmer() LockMode::UNLOCK_WHILE_RUNNING, false ) + , NOTIFICATION_STATUS_UPDATE("Status Update", true, false, std::chrono::seconds(3600)) , NOTIFICATIONS({ + &NOTIFICATION_STATUS_UPDATE, &NOTIFICATION_PROGRAM_FINISH, &NOTIFICATION_ERROR_FATAL, }) @@ -248,6 +250,7 @@ void FlyingTrialFarmer::program(SingleSwitchProgramEnvironment& env, BotBaseCont } env.update_stats(); + send_program_status_notification(env, NOTIFICATION_STATUS_UPDATE); } send_program_finished_notification(env, NOTIFICATION_PROGRAM_FINISH); diff --git a/SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_FlyingTrialFarmer.h b/SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_FlyingTrialFarmer.h index 8f11484f5..ab24393aa 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_FlyingTrialFarmer.h +++ b/SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_FlyingTrialFarmer.h @@ -47,6 +47,7 @@ class FlyingTrialFarmer : public SingleSwitchProgramInstance{ EnumDropdownOption FLIGHT_PATH; BooleanCheckBoxOption INVERT_CONTROLS_WHILE_FLYING; + EventNotificationOption NOTIFICATION_STATUS_UPDATE; EventNotificationsOption NOTIFICATIONS; bool run_rewards(SingleSwitchProgramEnvironment& env, BotBaseContext& context); diff --git a/SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_TournamentFarmer.cpp b/SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_TournamentFarmer.cpp index e3a415d2b..e43967d88 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_TournamentFarmer.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_TournamentFarmer.cpp @@ -4,7 +4,7 @@ * */ -#include "CommonFramework/GlobalSettingsPanel.h" +//#include "CommonFramework/GlobalSettingsPanel.h" #include "CommonFramework/Exceptions/OperationFailedException.h" #include "CommonFramework/ImageTools/ImageFilter.h" #include "CommonFramework/Notifications/ProgramNotifications.h" diff --git a/SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_TournamentFarmer2.cpp b/SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_TournamentFarmer2.cpp new file mode 100644 index 000000000..fe734b062 --- /dev/null +++ b/SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_TournamentFarmer2.cpp @@ -0,0 +1,314 @@ +/* Tournament Farmer 2 + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#include "CommonFramework/Exceptions/OperationFailedException.h" +#include "CommonFramework/Logging/Logger.h" +#include "CommonFramework/Notifications/ProgramNotifications.h" +#include "CommonFramework/InferenceInfra/InferenceRoutines.h" +#include "CommonFramework/Tools/StatsTracking.h" +#include "CommonFramework/Tools/VideoResolutionCheck.h" +#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" +#include "Pokemon/Pokemon_Strings.h" +#include "PokemonSV/Inference/Dialogs/PokemonSV_DialogDetector.h" +#include "PokemonSV/Inference/Overworld/PokemonSV_OverworldDetector.h" +#include "PokemonSV/Inference/Battles/PokemonSV_NormalBattleMenus.h" +#include "PokemonSV/Programs/PokemonSV_SaveGame.h" +#include "PokemonSV/Programs/Battles/PokemonSV_SinglesBattler.h" +#include "PokemonSV_TournamentFarmer2.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonSV{ + +using namespace Pokemon; + +TournamentFarmer2_Descriptor::TournamentFarmer2_Descriptor() + : SingleSwitchProgramDescriptor( + "PokemonSV:TournamentFarmer2", + STRING_POKEMON + " SV", "Tournament Farmer 2", + "ComputerControl/blob/master/Wiki/Programs/PokemonSV/TournamentFarmer2.md", + "Farm the Academy Ace Tournament for money and prizes. (version 2)", + FeedbackType::REQUIRED, + AllowCommandsWhenRunning::DISABLE_COMMANDS, + PABotBaseLevel::PABOTBASE_12KB + ) +{} + +struct TournamentFarmer2_Descriptor::Stats : public StatsTracker{ + Stats() + : tournaments(m_stats["Tournaments"]) + , battles(m_stats["Battles Fought"]) + , wins(m_stats["Wins"]) + , losses(m_stats["Losses"]) +// , money(m_stats["Money Made"]) +// , matches(m_stats["Items Matched"]) + , errors(m_stats["Errors"]) + { + m_display_order.emplace_back("Tournaments"); + m_display_order.emplace_back("Battles Fought"); + m_display_order.emplace_back("Wins"); + m_display_order.emplace_back("Losses"); +// m_display_order.emplace_back("Money Made"); +// m_display_order.emplace_back("Items Matched"); + m_display_order.emplace_back("Errors", HIDDEN_IF_ZERO); + } + std::atomic& tournaments; + std::atomic& battles; + std::atomic& wins; + std::atomic& losses; +// std::atomic& money; +// std::atomic& matches; + std::atomic& errors; +}; +std::unique_ptr TournamentFarmer2_Descriptor::make_stats() const{ + return std::unique_ptr(new Stats()); +} + + +TournamentFarmer2::StopButton::StopButton() + : ButtonOption( + "Stop after Current Tournament:", + "Stop after current Tournament", + 0, 16 + ) +{} +void TournamentFarmer2::StopButton::set_idle(){ + this->set_enabled(false); + this->set_text("Stop after current Tournament"); +} +void TournamentFarmer2::StopButton::set_ready(){ + this->set_enabled(true); + this->set_text("Stop after current Tournament"); +} +void TournamentFarmer2::StopButton::set_pressed(){ + this->set_enabled(false); + this->set_text("Program will stop after current tournament..."); +} + + +TournamentFarmer2::~TournamentFarmer2(){ + STOP_AFTER_CURRENT.remove_listener(*this); +} +TournamentFarmer2::TournamentFarmer2() + : NUM_ROUNDS( + "Number of Tournaments to run:", + LockMode::UNLOCK_WHILE_RUNNING, + 100, 0 + ) + , SAVE_NUM_ROUNDS( + "Save every this many tournaments:
Zero disables saving. Will save win or lose.", + LockMode::UNLOCK_WHILE_RUNNING, + 1, 0 + ) + , GO_HOME_WHEN_DONE(false) + , NOTIFICATION_STATUS_UPDATE("Status Update", true, false, std::chrono::seconds(3600)) + , NOTIFICATIONS({ + &NOTIFICATION_STATUS_UPDATE, + &NOTIFICATION_PROGRAM_FINISH, + &NOTIFICATION_ERROR_FATAL, + }) + , m_stop_after_current(false) +{ + PA_ADD_OPTION(STOP_AFTER_CURRENT); + PA_ADD_OPTION(NUM_ROUNDS); + PA_ADD_OPTION(SAVE_NUM_ROUNDS); + PA_ADD_OPTION(BATTLE_AI); + PA_ADD_OPTION(GO_HOME_WHEN_DONE); + PA_ADD_OPTION(NOTIFICATIONS); + + STOP_AFTER_CURRENT.set_idle(); + STOP_AFTER_CURRENT.add_listener(*this); +} + +void TournamentFarmer2::on_press(){ + global_logger_tagged().log("Stop after current requested..."); + m_stop_after_current.store(true, std::memory_order_relaxed); + STOP_AFTER_CURRENT.set_pressed(); +} + + + +class TournamentFarmer2::ResetOnExit{ +public: + ResetOnExit(StopButton& button) + : m_button(button) + {} + ~ResetOnExit(){ + m_button.set_idle(); + } + +private: + StopButton& m_button; +}; + + +void TournamentFarmer2::program(SingleSwitchProgramEnvironment& env, BotBaseContext& context) { + assert_16_9_720p_min(env.logger(), env.console); + TournamentFarmer2_Descriptor::Stats& stats = env.current_stats(); + + m_stop_after_current.store(false, std::memory_order_relaxed); + STOP_AFTER_CURRENT.set_ready(); + ResetOnExit reset_button_on_exit(STOP_AFTER_CURRENT); + + + for (uint32_t c = 0; c < NUM_ROUNDS; c++){ + if (m_stop_after_current.load(std::memory_order_relaxed)){ + break; + } + + env.log("Tournament loop started."); + send_program_status_notification(env, NOTIFICATION_STATUS_UPDATE); + + // Initiate dialog then mash until first battle starts + { + AdvanceDialogWatcher advance_detector(COLOR_YELLOW); + pbf_press_button(context, BUTTON_A, 10, 50); + pbf_press_button(context, BUTTON_A, 10, 50); + int ret = wait_until(env.console, context, Milliseconds(7000), { advance_detector }); + if (ret == 0) { + env.log("Dialog detected."); + } + else { + env.log("Dialog not detected."); + } + pbf_mash_button(context, BUTTON_A, 400); + context.wait_for_all_requests(); + } + { + NormalBattleMenuWatcher battle_menu(COLOR_YELLOW); + int ret = run_until( + env.console, context, + [](BotBaseContext& context){ + pbf_mash_button(context, BUTTON_B, 10000); //it takes a while to load and start + }, + {battle_menu} + ); + if (ret != 0){ + stats.errors++; + env.update_stats(); + throw OperationFailedException( + ErrorReport::SEND_ERROR_REPORT, env.console, + "Failed to detect battle start!", + true + ); + } + } + context.wait_for_all_requests(); + + stats.tournaments++; + + bool battle_lost = false; + for (uint16_t battles = 0; battles < 4; battles++){ + NormalBattleMenuWatcher battle_menu(COLOR_YELLOW); // Next battle started + OverworldWatcher overworld(COLOR_CYAN); // Previous battle was lost + int ret = run_until( + env.console, context, + [](BotBaseContext& context) { + pbf_mash_button(context, BUTTON_B, 120 * TICKS_PER_SECOND); + }, + {battle_menu, overworld} + ); + context.wait_for_all_requests(); + + switch (ret){ + case 0: + env.log("Detected battle menu."); + run_singles_battle(env, env.console, context, BATTLE_AI, true); + stats.battles++; + env.update_stats(); + break; + case 1: + env.log("Detected overworld."); + battle_lost = true; + stats.losses++; + env.update_stats(); + break; + default: + env.log("Failed to detect battle menu or dialog prompt!"); + stats.errors++; + env.update_stats(); + throw OperationFailedException( + ErrorReport::SEND_ERROR_REPORT, env.console, + "Failed to detect battle menu or dialog prompt!", + true + ); + } + + // If this is the last battle in the tournament check for overworld in case player lost + if (battles == 3){ + env.log("Final battle of the tournament complete, checking for overworld/loss."); + + // Clear dialog, mash B + pbf_mash_button(context, BUTTON_B, 400); + context.wait_for_all_requests(); + + ret = wait_until( + env.console, context, + std::chrono::seconds(3), + {overworld} + ); + switch (ret){ + case 0: + env.log("Final battle of the tournament lost."); + battle_lost = true; + stats.losses++; + env.update_stats(); + break; + default: + env.log("Final battle of the tournament won."); + break; + } + } + + + } + + // Tournament won + if (!battle_lost){ + stats.wins++; + OverworldWatcher overworld(COLOR_CYAN); + int ret = run_until( + env.console, context, + [](BotBaseContext& context) { + pbf_mash_button(context, BUTTON_B, 120 * TICKS_PER_SECOND); + }, + {overworld} + ); + if (ret < 0){ + throw OperationFailedException( + ErrorReport::SEND_ERROR_REPORT, env.console, + "Failed to return to overworld afer 2 minutes.", + true + ); + } + } + + env.log("Tournament loop complete."); + + //Save the game if option is set + uint16_t num_rounds_temp = SAVE_NUM_ROUNDS; + if (num_rounds_temp != 0 && ((c + 1) % num_rounds_temp) == 0){ + env.log("Saving game."); + save_game_from_overworld(env.program_info(), env.console, context); + } + + } + + send_program_finished_notification(env, NOTIFICATION_PROGRAM_FINISH); + GO_HOME_WHEN_DONE.run_end_of_program(context); +} + + + + + + + + + +} +} +} diff --git a/SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_TournamentFarmer2.h b/SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_TournamentFarmer2.h new file mode 100644 index 000000000..f49c7ccd4 --- /dev/null +++ b/SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_TournamentFarmer2.h @@ -0,0 +1,66 @@ +/* Tournament Farmer 2 + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#ifndef PokemonAutomation_PokemonSwSh_TournamentFarmer2_H +#define PokemonAutomation_PokemonSwSh_TournamentFarmer2_H + +//#include "Common/Cpp/Options/BooleanCheckBoxOption.h" +#include "Common/Cpp/Options/SimpleIntegerOption.h" +#include "Common/Cpp/Options/ButtonOption.h" +//#include "CommonFramework/Options/LanguageOCROption.h" +#include "CommonFramework/Notifications/EventNotificationsTable.h" +#include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h" +#include "NintendoSwitch/Options/NintendoSwitch_GoHomeWhenDoneOption.h" +//#include "PokemonSV/Options/PokemonSV_TournamentPrizeTable.h" +#include "PokemonSV/Options/PokemonSV_SinglesAIOption.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonSV{ + + +class TournamentFarmer2_Descriptor : public SingleSwitchProgramDescriptor{ +public: + TournamentFarmer2_Descriptor(); + struct Stats; + virtual std::unique_ptr make_stats() const override; +}; + +class TournamentFarmer2 : public SingleSwitchProgramInstance, public ButtonListener{ +public: + ~TournamentFarmer2(); + TournamentFarmer2(); + virtual void program(SingleSwitchProgramEnvironment& env, BotBaseContext& context) override; + virtual void on_press() override; + +private: + class StopButton : public ButtonOption{ + public: + StopButton(); + void set_idle(); + void set_ready(); + void set_pressed(); + }; + class ResetOnExit; + + StopButton STOP_AFTER_CURRENT; + SimpleIntegerOption NUM_ROUNDS; + SimpleIntegerOption SAVE_NUM_ROUNDS; + SinglesAIOption BATTLE_AI; + GoHomeWhenDoneOption GO_HOME_WHEN_DONE; + EventNotificationOption NOTIFICATION_STATUS_UPDATE; + EventNotificationsOption NOTIFICATIONS; + + std::atomic m_stop_after_current; +}; + +} +} +} +#endif + + + diff --git a/SerialPrograms/Source/PokemonSV/Programs/General/PokemonSV_AutonomousBallThrower.cpp b/SerialPrograms/Source/PokemonSV/Programs/General/PokemonSV_AutonomousBallThrower.cpp index c10da97a0..dcd676084 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/General/PokemonSV_AutonomousBallThrower.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/General/PokemonSV_AutonomousBallThrower.cpp @@ -4,17 +4,12 @@ * */ -#include "CommonFramework/Exceptions/FatalProgramException.h" -#include "CommonFramework/Notifications/ProgramNotifications.h" -#include "CommonFramework/InferenceInfra/InferenceRoutines.h" #include "CommonFramework/Tools/StatsTracking.h" #include "CommonFramework/Tools/VideoResolutionCheck.h" #include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" #include "Pokemon/Inference/Pokemon_NameReader.h" #include "Pokemon/Pokemon_Strings.h" -#include "PokemonSV/Inference/Battles/PokemonSV_BattleBallReader.h" -#include "PokemonSV/Inference/Battles/PokemonSV_NormalBattleMenus.h" -#include "PokemonSV/Programs/PokemonSV_BasicCatcher.h" +#include "PokemonSV/Programs/Battles/PokemonSV_BasicCatcher.h" #include "PokemonSV_AutonomousBallThrower.h" namespace PokemonAutomation{ diff --git a/SerialPrograms/Source/PokemonSV/Programs/General/PokemonSV_StatsReset.cpp b/SerialPrograms/Source/PokemonSV/Programs/General/PokemonSV_StatsReset.cpp index f8544efe5..0f0a7fd48 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/General/PokemonSV_StatsReset.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/General/PokemonSV_StatsReset.cpp @@ -21,7 +21,7 @@ #include "PokemonSV/Inference/Overworld/PokemonSV_OverworldDetector.h" #include "PokemonSV/Programs/PokemonSV_GameEntry.h" #include "PokemonSV/Programs/PokemonSV_Navigation.h" -#include "PokemonSV/Programs/PokemonSV_BasicCatcher.h" +#include "PokemonSV/Programs/Battles/PokemonSV_BasicCatcher.h" #include "PokemonSV/Programs/Boxes/PokemonSV_BoxRoutines.h" #include "PokemonSV_StatsReset.h" diff --git a/SerialPrograms/Source/PokemonSV/Programs/General/PokemonSV_StatsResetBloodmoon.cpp b/SerialPrograms/Source/PokemonSV/Programs/General/PokemonSV_StatsResetBloodmoon.cpp index 00cc0ae9b..d00934a50 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/General/PokemonSV_StatsResetBloodmoon.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/General/PokemonSV_StatsResetBloodmoon.cpp @@ -4,10 +4,10 @@ * */ -#include "CommonFramework/GlobalSettingsPanel.h" #include "CommonFramework/Exceptions/OperationFailedException.h" #include "CommonFramework/Options/LanguageOCROption.h" #include "CommonFramework/Notifications/ProgramNotifications.h" +#include "CommonFramework/VideoPipeline/VideoFeed.h" #include "CommonFramework/InferenceInfra/InferenceRoutines.h" #include "CommonFramework/Tools/StatsTracking.h" #include "CommonFramework/Tools/VideoResolutionCheck.h" @@ -20,13 +20,10 @@ #include "PokemonSV/Inference/Battles/PokemonSV_NormalBattleMenus.h" #include "PokemonSV/Inference/Battles/PokemonSV_TeraBattleMenus.h" #include "PokemonSV/Inference/Boxes/PokemonSV_StatsResetChecker.h" -#include "PokemonSV/Inference/Boxes/PokemonSV_BoxDetection.h" #include "PokemonSV/Inference/Boxes/PokemonSV_IvJudgeReader.h" //#include "PokemonSV/Inference/Overworld/PokemonSV_OverworldDetector.h" #include "PokemonSV/Programs/PokemonSV_GameEntry.h" -#include "PokemonSV/Programs/PokemonSV_Navigation.h" -#include "PokemonSV/Programs/PokemonSV_BasicCatcher.h" -#include "PokemonSV/Programs/Boxes/PokemonSV_BoxRoutines.h" +#include "PokemonSV/Programs/Battles/PokemonSV_BasicCatcher.h" #include "PokemonSV_StatsResetBloodmoon.h" namespace PokemonAutomation{ diff --git a/SerialPrograms/Source/PokemonSV/Programs/Glitches/PokemonSV_RideCloner-1.0.1.cpp b/SerialPrograms/Source/PokemonSV/Programs/Glitches/PokemonSV_RideCloner-1.0.1.cpp index 7c4717d0c..215e043b7 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/Glitches/PokemonSV_RideCloner-1.0.1.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/Glitches/PokemonSV_RideCloner-1.0.1.cpp @@ -28,7 +28,7 @@ #include "PokemonSV/Inference/Overworld/PokemonSV_OverworldDetector.h" #include "PokemonSV/Programs/PokemonSV_SaveGame.h" #include "PokemonSV/Programs/PokemonSV_Navigation.h" -#include "PokemonSV/Programs/PokemonSV_BasicCatcher.h" +#include "PokemonSV/Programs/Battles/PokemonSV_BasicCatcher.h" #include "PokemonSV/Programs/TeraRaids/PokemonSV_TeraRoutines.h" #include "PokemonSV/Programs/TeraRaids/PokemonSV_TeraBattler.h" #include "PokemonSV_RideCloner-1.0.1.h" diff --git a/SerialPrograms/Source/PokemonSV/Programs/ShinyHunting/PokemonSV_LetsGoTools.cpp b/SerialPrograms/Source/PokemonSV/Programs/ShinyHunting/PokemonSV_LetsGoTools.cpp index db7c281fe..23b22a617 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/ShinyHunting/PokemonSV_LetsGoTools.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/ShinyHunting/PokemonSV_LetsGoTools.cpp @@ -17,8 +17,8 @@ #include "PokemonSV/Options/PokemonSV_EncounterBotCommon.h" #include "PokemonSV/Inference/PokemonSV_SweatBubbleDetector.h" //#include "PokemonSV/Inference/Overworld/PokemonSV_OverworldDetector.h" -#include "PokemonSV/Programs/PokemonSV_Battles.h" -#include "PokemonSV/Programs/PokemonSV_BasicCatcher.h" +#include "PokemonSV/Programs/Battles/PokemonSV_Battles.h" +#include "PokemonSV/Programs/Battles/PokemonSV_BasicCatcher.h" #include "PokemonSV_LetsGoTools.h" //#include diff --git a/SerialPrograms/Source/PokemonSV/Programs/ShinyHunting/PokemonSV_ShinyHunt-AreaZeroPlatform.cpp b/SerialPrograms/Source/PokemonSV/Programs/ShinyHunting/PokemonSV_ShinyHunt-AreaZeroPlatform.cpp index 9a9853dbe..8782839e4 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/ShinyHunting/PokemonSV_ShinyHunt-AreaZeroPlatform.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/ShinyHunting/PokemonSV_ShinyHunt-AreaZeroPlatform.cpp @@ -25,8 +25,8 @@ #include "PokemonSV/Programs/PokemonSV_Navigation.h" #include "PokemonSV/Programs/PokemonSV_GameEntry.h" #include "PokemonSV/Programs/PokemonSV_SaveGame.h" -#include "PokemonSV/Programs/PokemonSV_Battles.h" #include "PokemonSV/Programs/PokemonSV_AreaZero.h" +#include "PokemonSV/Programs/Battles/PokemonSV_Battles.h" #include "PokemonSV/Programs/Sandwiches/PokemonSV_SandwichRoutines.h" #include "PokemonSV_LetsGoTools.h" #include "PokemonSV_ShinyHunt-AreaZeroPlatform.h" diff --git a/SerialPrograms/Source/PokemonSV/Programs/ShinyHunting/PokemonSV_ShinyHunt-Scatterbug.cpp b/SerialPrograms/Source/PokemonSV/Programs/ShinyHunting/PokemonSV_ShinyHunt-Scatterbug.cpp index de8f527ba..3f41883b0 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/ShinyHunting/PokemonSV_ShinyHunt-Scatterbug.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/ShinyHunting/PokemonSV_ShinyHunt-Scatterbug.cpp @@ -10,22 +10,18 @@ #include "CommonFramework/GlobalSettingsPanel.h" #include "CommonFramework/Exceptions/ProgramFinishedException.h" #include "CommonFramework/Exceptions/OperationFailedException.h" -#include "CommonFramework/Exceptions/FatalProgramException.h" -#include "CommonFramework/Notifications/ProgramNotifications.h" #include "CommonFramework/InferenceInfra/InferenceRoutines.h" #include "CommonFramework/Tools/StatsTracking.h" #include "CommonFramework/Tools/VideoResolutionCheck.h" #include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" #include "Pokemon/Pokemon_Strings.h" -#include "PokemonSV/PokemonSV_Settings.h" #include "PokemonSV/Inference/Overworld/PokemonSV_LetsGoHpReader.h" #include "PokemonSV/Inference/Boxes/PokemonSV_IvJudgeReader.h" #include "PokemonSV/Inference/Battles/PokemonSV_EncounterWatcher.h" -#include "PokemonSV/Programs/PokemonSV_AreaZero.h" -#include "PokemonSV/Programs/PokemonSV_Battles.h" #include "PokemonSV/Programs/PokemonSV_GameEntry.h" #include "PokemonSV/Programs/PokemonSV_Navigation.h" #include "PokemonSV/Programs/PokemonSV_SaveGame.h" +#include "PokemonSV/Programs/Battles/PokemonSV_Battles.h" #include "PokemonSV/Programs/Sandwiches/PokemonSV_SandwichRoutines.h" #include "PokemonSV_LetsGoTools.h" #include "PokemonSV_ShinyHunt-Scatterbug.h" diff --git a/SerialPrograms/Source/PokemonSV/Programs/TeraRaids/PokemonSV_TeraBattler.cpp b/SerialPrograms/Source/PokemonSV/Programs/TeraRaids/PokemonSV_TeraBattler.cpp index baf9f022c..3feafa3d7 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/TeraRaids/PokemonSV_TeraBattler.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/TeraRaids/PokemonSV_TeraBattler.cpp @@ -33,11 +33,10 @@ enum class BattleMenuResult{ }; BattleMenuResult run_battle_menu( ConsoleHandle& console, BotBaseContext& context, - const std::vector& move_table, TeraBattleMenuDetector& battle_menu, TeraCatchWatcher& catch_menu, OverworldWatcher& overworld, - TeraMoveEntry& move + const TeraMoveEntry& move ){ console.log("Current Move Selection: " + move.to_str()); switch (move.type){ @@ -272,7 +271,6 @@ bool run_tera_battle( console.log("Current Move Selection: " + current_move.to_str()); BattleMenuResult battle_menu_result = run_battle_menu( console, context, - move_table, battle_menu, catch_menu, overworld, diff --git a/SerialPrograms/Source/PokemonSV/Programs/TeraRaids/PokemonSV_TeraBattler.h b/SerialPrograms/Source/PokemonSV/Programs/TeraRaids/PokemonSV_TeraBattler.h index 8c9fa3b5b..e98b2955b 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/TeraRaids/PokemonSV_TeraBattler.h +++ b/SerialPrograms/Source/PokemonSV/Programs/TeraRaids/PokemonSV_TeraBattler.h @@ -8,7 +8,6 @@ #define PokemonAutomation_PokemonSV_TeraBattler_H #include "ClientSource/Connection/BotBase.h" -#include "CommonFramework/Notifications/EventNotificationOption.h" #include "CommonFramework/Tools/ConsoleHandle.h" #include "CommonFramework/Tools/ProgramEnvironment.h" #include "PokemonSV/Options/PokemonSV_TeraAIOption.h" diff --git a/SerialPrograms/Source/PokemonSV/Programs/TeraRaids/PokemonSV_TeraRoutines.cpp b/SerialPrograms/Source/PokemonSV/Programs/TeraRaids/PokemonSV_TeraRoutines.cpp index 15985ce45..6dbf2d692 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/TeraRaids/PokemonSV_TeraRoutines.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/TeraRaids/PokemonSV_TeraRoutines.cpp @@ -14,7 +14,6 @@ #include "CommonFramework/Tools/ProgramEnvironment.h" #include "CommonFramework/Tools/ErrorDumper.h" #include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" -#include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h" #include "Pokemon/Pokemon_Strings.h" #include "Pokemon/Pokemon_Notification.h" #include "PokemonSV/Inference/Dialogs/PokemonSV_DialogDetector.h" @@ -28,7 +27,7 @@ #include "PokemonSV/Inference/Tera/PokemonSV_TeraRaidSearchDetector.h" #include "PokemonSV/Inference/Tera/PokemonSV_TeraRewardsReader.h" #include "PokemonSV/Programs/PokemonSV_ConnectToInternet.h" -#include "PokemonSV/Programs/PokemonSV_BasicCatcher.h" +#include "PokemonSV/Programs/Battles/PokemonSV_BasicCatcher.h" #include "PokemonSV_TeraRoutines.h" namespace PokemonAutomation{