diff --git a/SerialPrograms/Source/PokemonSV/Options/PokemonSV_BBQOption.cpp b/SerialPrograms/Source/PokemonSV/Options/PokemonSV_BBQOption.cpp index 5e6385b103..ec4e72739b 100644 --- a/SerialPrograms/Source/PokemonSV/Options/PokemonSV_BBQOption.cpp +++ b/SerialPrograms/Source/PokemonSV/Options/PokemonSV_BBQOption.cpp @@ -12,6 +12,127 @@ namespace PokemonAutomation{ namespace NintendoSwitch{ namespace PokemonSV{ +//Does not include multiplayer quests +const EnumDropdownDatabase& BBQuests_database(){ + static EnumDropdownDatabase database{ + {BBQuests::auto_10, "auto-10", "Defeat 10 wild Pokemon using Auto Battle!"}, + {BBQuests::make_tm, "make-tm", "Make yourself a TM!"}, + //{BBQuests::pickup_10, "pickup-10", "Pick up items on the ground 10 times!"}, + {BBQuests::sneak_up, "sneak-up", "Successfully sneak up on 1 Pokemon and surprise them with a battle!"}, + {BBQuests::photo_fly, "photo-fly", "Take a photo of a wild Pokemon in flight!"}, + {BBQuests::photo_swim, "photo-swim", "Take a photo of a wild Pokemon that is swimming!"}, + {BBQuests::photo_canyon, "photo-canyon", "Take a photo of a wild Pokemon in the Canyon Biome!"}, + {BBQuests::photo_coastal, "photo-coastal", "Take a photo of a wild Pokemon in the Coastal Biome!"}, + {BBQuests::photo_polar, "photo-polar", "Take a photo of a wild Pokemon in the Polar Biome!"}, + {BBQuests::photo_savanna, "photo-savanna", "Take a photo of a wild Pokemon in the Savanna Biome!"}, + {BBQuests::tera_self_defeat,"tera-self-defeat", "Terastallize your Pokemon to defeat a wild Pokemon!"}, + {BBQuests::travel_500, "travel-500", "Travel over 500 yards!"}, + {BBQuests::catch_any, "catch-any", "Catch 1 Pokemon!"}, + {BBQuests::catch_normal, "catch-normal", "Catch 1 Normal-type Pokemon!"}, + {BBQuests::catch_fighting, "catch-fighting", "Catch 1 Fighting-type Pokemon!"}, + {BBQuests::catch_flying, "catch-flying", "Catch 1 Flying-type Pokemon!"}, + {BBQuests::catch_poison, "catch-poison", "Catch 1 Poison-type Pokemon!"}, + {BBQuests::catch_ground, "catch-ground", "Catch 1 Ground-type Pokemon!"}, + {BBQuests::catch_rock, "catch-rock", "Catch 1 Rock-type Pokemon!"}, + {BBQuests::catch_bug, "catch-bug", "Catch 1 Bug-type Pokemon!"}, + {BBQuests::catch_ghost, "catch-ghost", "Catch 1 Ghost-type Pokemon!"}, + {BBQuests::catch_steel, "catch-steel", "Catch 1 Steel-type Pokemon!"}, + {BBQuests::catch_fire, "catch-fire", "Catch 1 Fire-type Pokemon!"}, + {BBQuests::catch_water, "catch-water", "Catch 1 Water-type Pokemon!"}, + {BBQuests::catch_grass, "catch-grass", "Catch 1 Grass-type Pokemon!"}, + {BBQuests::catch_electric, "catch-electric", "Catch 1 Electric-type Pokemon!"}, + {BBQuests::catch_psychic, "catch-psychic", "Catch 1 Psychic-type Pokemon!"}, + {BBQuests::catch_ice, "catch-ice", "Catch 1 Ice-type Pokemon!"}, + {BBQuests::catch_dragon, "catch-dragon", "Catch 1 Dragon-type Pokemon!"}, + {BBQuests::catch_dark, "catch-dark", "Catch 1 Dark-type Pokemon!"}, + {BBQuests::catch_fairy, "catch-fairy", "Catch 1 Fairy-type Pokemon!"}, + {BBQuests::wash_pokemon, "wash-pokemon", "Give your Pokemon a nice washing!"}, + {BBQuests::wild_tera, "wild-tera", "Battle a wild Tera Pokemon!"}, + {BBQuests::auto_30, "auto-30", "Defeat 30 wild Pokemon using Auto Battle!"}, + {BBQuests::tera_raid, "tera-raid", "Claim victory in a Tera Raid Battle!"}, + {BBQuests::sandwich_three, "sandwich-three", "Make a sandwich that uses at least 3 ingredients!"}, + {BBQuests::bitter_sandwich, "bitter-sandwich", "Make a bitter sandwich!"}, + {BBQuests::sweet_sandwich, "sweet-sandwich", "Make a sweet sandwich!"}, + {BBQuests::salty_sandwich, "salty-sandwich", "Make a salty sandwich!"}, + {BBQuests::sour_sandwich, "sour-sandwich", "Make a sour sandwich!"}, + {BBQuests::spicy_sandwich, "spicy-sandwich", "Make a spicy sandwich!"}, + //{BBQuests::hatch_egg, "hatch-egg", "Hatch a Pokemon Egg!"}, + {BBQuests::photo_normal, "photo-normal", "Take a photo of a wild Normal-type Pokemon!"}, + {BBQuests::photo_fighting, "photo-fighting", "Take a photo of a wild Fighting-type Pokemon!"}, + {BBQuests::photo_flying, "photo-flying", "Take a photo of a wild Flying-type Pokemon!"}, + {BBQuests::photo_poison, "photo-poison", "Take a photo of a wild Poison-type Pokemon!"}, + {BBQuests::photo_ground, "photo-ground", "Take a photo of a wild Ground-type Pokemon!"}, + {BBQuests::photo_rock, "photo-rock", "Take a photo of a wild Rock-type Pokemon!"}, + {BBQuests::photo_bug, "photo-bug", "Take a photo of a wild Bug-type Pokemon!"}, + {BBQuests::photo_ghost, "photo-ghost", "Take a photo of a wild Ghost-type Pokemon!"}, + {BBQuests::photo_steel, "photo-steel", "Take a photo of a wild Steel-type Pokemon!"}, + {BBQuests::photo_fire, "photo-fire", "Take a photo of a wild Fire-type Pokemon!"}, + {BBQuests::photo_water, "photo-water", "Take a photo of a wild Water-type Pokemon!"}, + {BBQuests::photo_grass, "photo-grass", "Take a photo of a wild Grass-type Pokemon!"}, + {BBQuests::photo_electric, "photo-electric", "Take a photo of a wild Electric-type Pokemon!"}, + {BBQuests::photo_psychic, "photo-psychic", "Take a photo of a wild Psychic-type Pokemon!"}, + {BBQuests::photo_ice, "photo-ice", "Take a photo of a wild Ice-type Pokemon!"}, + {BBQuests::photo_dragon, "photo-dragon", "Take a photo of a wild Dragon-type Pokemon!"}, + {BBQuests::photo_dark, "photo-dark", "Take a photo of a wild Dark-type Pokemon!"}, + {BBQuests::photo_fairy, "photo-fairy", "Take a photo of a wild Fairy-type Pokemon!"}, + }; + return database; +} + +const EnumDropdownDatabase& BBQAction_database(){ + static EnumDropdownDatabase database{ + {BBQAction::run, "run", "Run Quest"}, + {BBQAction::skip, "skip", "Skip"}, + {BBQAction::reroll, "reroll", "Reroll"}, + }; + return database; +} + +BBQuestTableRow::BBQuestTableRow(EditableTableOption& parent_table) + : EditableTableRow(parent_table) + , quest(BBQuests_database(), LockMode::UNLOCK_WHILE_RUNNING, BBQuests::auto_10) + , action(BBQAction_database(), LockMode::UNLOCK_WHILE_RUNNING, BBQAction::skip) +{ + PA_ADD_OPTION(quest); + PA_ADD_OPTION(action); +} +std::unique_ptr BBQuestTableRow::clone() const{ + std::unique_ptr ret(new BBQuestTableRow(parent())); + ret->quest.set(quest); + ret->action.set(action); + return ret; +} + +BBQuestTable::BBQuestTable() + : EditableTableOption_t( + "Quest Exclusions:
" + "Warning: Skipping Bonus quests will block the bonus slot.
" + "Exclude the quests in the table. If you want to skip a quest, select it below. " + "(Quests can be explicitly included, but this is not necessary.) " + "Do not exclude too many quests, as rerolling costs BP. " + "The program will automatically reroll all quests if none are possible, but will not handle being out of BP. " + "Does not include egg hatching or pickup quests, as eggs are handled in other options and pickup is not possible. ", + //"Duplicates of the same quest", + //duplicates will work in table order. might lead to weird behavior like rerolling and then marking a quest as complete. + //won't break the program though. + LockMode::LOCK_WHILE_RUNNING, + make_defaults() + ) +{} + +std::vector BBQuestTable::make_header() const{ + return { + "Quest", + "Action", + }; +} +std::vector> BBQuestTable::make_defaults(){ + std::vector> ret; + ret.emplace_back(new BBQuestTableRow(*this)); + return ret; +} + + BBQOption::BBQOption(OCR::LanguageOCROption* language_option) : GroupOption("Blueberry Quests", LockMode::UNLOCK_WHILE_RUNNING) , m_language_owner(language_option == nullptr @@ -81,6 +202,7 @@ BBQOption::BBQOption(OCR::LanguageOCROption* language_option) } PA_ADD_OPTION(NUM_QUESTS); PA_ADD_OPTION(SAVE_NUM_QUESTS); + PA_ADD_OPTION(QUEST_EXCLUSIONS); PA_ADD_OPTION(INVERTED_FLIGHT); PA_ADD_OPTION(QUICKBALL); PA_ADD_OPTION(BALL_SELECT); diff --git a/SerialPrograms/Source/PokemonSV/Options/PokemonSV_BBQOption.h b/SerialPrograms/Source/PokemonSV/Options/PokemonSV_BBQOption.h index 3fd0be699d..a4034f10c3 100644 --- a/SerialPrograms/Source/PokemonSV/Options/PokemonSV_BBQOption.h +++ b/SerialPrograms/Source/PokemonSV/Options/PokemonSV_BBQOption.h @@ -9,6 +9,7 @@ #include "Common/Cpp/Options/GroupOption.h" #include "Common/Cpp/Options/EnumDropdownOption.h" +#include "Common/Cpp/Options/EditableTableOption.h" #include "Common/Cpp/Options/SimpleIntegerOption.h" #include "Common/Cpp/Options/BooleanCheckBoxOption.h" #include "CommonTools/Options/LanguageOCROption.h" @@ -20,6 +21,47 @@ namespace PokemonAutomation{ namespace NintendoSwitch{ namespace PokemonSV{ +enum class BBQuests{ + auto_10, make_tm, pickup_10, sneak_up, photo_fly, photo_swim, photo_canyon, photo_coastal, photo_polar, photo_savanna, tera_self_defeat, + travel_500, catch_any, catch_normal, catch_fighting, catch_flying, catch_poison, catch_ground, catch_rock, catch_bug, catch_ghost, catch_steel, + catch_fire, catch_water, catch_grass, catch_electric, catch_psychic, catch_ice, catch_dragon, catch_dark, catch_fairy, + wash_pokemon, wild_tera, auto_30, tera_raid, sandwich_three, bitter_sandwich, sweet_sandwich, salty_sandwich, sour_sandwich, spicy_sandwich, hatch_egg, + photo_normal, photo_fighting, photo_flying, photo_poison, photo_ground, photo_rock, photo_bug, photo_ghost, photo_steel, photo_fire, photo_water, + photo_grass, photo_electric, photo_psychic, photo_ice, photo_dragon, photo_dark, photo_fairy, + ditto_central, ditto_canyon, ditto_coastal, ditto_polar, ditto_savanna, group_canyon, group_coastal, group_polar, group_savanna, group_eyewear, group_nonuniform, + group_masks, sandwich_four, catch_hint, catch_hint2, + UnableToDetect +}; + +enum class BBQAction{ + run, + skip, + reroll +}; + +//Quest exclusion table +const EnumDropdownDatabase& BBQuests_database(); + +class BBQuestTableRow : public EditableTableRow{ +public: + BBQuestTableRow(EditableTableOption& parent_table); + virtual std::unique_ptr clone() const override; + +public: + EnumDropdownCell quest; + EnumDropdownCell action; +}; + +class BBQuestTable : public EditableTableOption_t{ +public: + BBQuestTable(); + + virtual std::vector make_header() const; + std::vector> make_defaults(); +}; + + +//BBQ Options class BBQOption : public GroupOption{ public: @@ -48,6 +90,8 @@ class BBQOption : public GroupOption{ SimpleIntegerOption NUM_QUESTS; SimpleIntegerOption SAVE_NUM_QUESTS; + BBQuestTable QUEST_EXCLUSIONS; + BooleanCheckBoxOption INVERTED_FLIGHT; //For catching pokemon quests diff --git a/SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_BlueberryQuests.cpp b/SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_BlueberryQuests.cpp index 623df7812e..c7039c9fc0 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_BlueberryQuests.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_BlueberryQuests.cpp @@ -228,6 +228,9 @@ std::vector process_quest_list( uint8_t& eggs_hatched ){ std::vector quests_to_do; + bool rerolled = false; + std::vector> exclusions_table = BBQ_OPTIONS.QUEST_EXCLUSIONS.copy_snapshot(); + int questpos = 0; stream.log("Processing quests."); //Put all do-able quests into a different list @@ -267,6 +270,7 @@ std::vector process_quest_list( pbf_wait(context, 100); context.wait_for_all_requests(); + rerolled = true; press_Bs_to_back_to_overworld(info, stream, context); break; @@ -284,26 +288,97 @@ std::vector process_quest_list( ); break; } - }else{ - stream.log("Quest possible"); - quests_to_do.push_back(n); + } + else{ + bool quest_in_table = false; + for(const std::unique_ptr& row : exclusions_table){ + if(n == row->quest) { + stream.log("Quest found in inclusions/exclusions table."); + quest_in_table = true; + + WhiteButtonWatcher rp2(COLOR_BLUE, WhiteButton::ButtonB, {0.484, 0.117, 0.022, 0.037}); + int result2; + switch (row->action) { + case BBQAction::run: + stream.log("Run selected. Adding quest to list."); + quests_to_do.push_back(n); + break; + case BBQAction::reroll: + stream.log("Reroll selected. Rerolling quest. New quest will be run in the next batch of quests."); + result2 = run_until( + stream, context, + [&](ProControllerContext& context){ + for (int i = 0; i < 6; i++){ + pbf_press_dpad(context, DPAD_RIGHT, 50, 20); + pbf_wait(context, 200); + context.wait_for_all_requests(); + } + }, + {{ rp2 }} + ); + if (result2 == 0){ + stream.log("Found quest panel."); + } + context.wait_for_all_requests(); + + //Move cursor down to quest + for (int i = 0; i < questpos; i++) { + pbf_press_dpad(context, DPAD_DOWN, 20, 20); + pbf_wait(context, 100); + context.wait_for_all_requests(); + } + + //Reroll + pbf_press_button(context, BUTTON_A, 20, 50); + pbf_press_button(context, BUTTON_A, 20, 50); + pbf_wait(context, 100); + context.wait_for_all_requests(); + + //Prevent error/rerolling again at the end (allows program to read the rerolled quests) + rerolled = true; + + press_Bs_to_back_to_overworld(info, stream, context); + break; + case BBQAction::skip: + stream.log("Skip selected. Skipping quest."); + break; + } + } + } + if(!quest_in_table){ + stream.log("Quest not in inclusion/exclusions table. Adding to list."); + quests_to_do.push_back(n); + } } } + questpos++; } - - /* - Old logic that assumes most quests are not possible. Written when first starting on the program. - Should not be necessary anymore. Keeping around in case anyone wants to try making a multiplayer version. //Check that quests_to_do is not empty (after completing all quests on the list, be sure to erase it. //Lag might be a problem in multi - look into making slots like menu-left navigation - if (quests_to_do.size() == 0){ - console.log("No possible quests! Rerolling all quests."); + if (!rerolled && quests_to_do.size() == 0){ + stream.log("No possible quests! Rerolling all quests."); - //Open quest panel - see above - //Reroll all. + //Open quest panel and reroll all quests. //This does not handle out of BP. - for (int i = 0; i < quest_list.size(); i++){ + WhiteButtonWatcher panel(COLOR_BLUE, WhiteButton::ButtonB, {0.484, 0.117, 0.022, 0.037}); + int result = run_until( + stream, context, + [&](ProControllerContext& context){ + for (int i = 0; i < 6; i++){ + pbf_press_dpad(context, DPAD_RIGHT, 50, 20); + pbf_wait(context, 200); + context.wait_for_all_requests(); + } + }, + {{ panel }} + ); + if (result == 0){ + stream.log("Found quest panel."); + } + context.wait_for_all_requests(); + + for (string::size_type i = 0; i < quest_list.size(); i++){ pbf_press_button(context, BUTTON_A, 20, 50); pbf_press_button(context, BUTTON_A, 20, 50); //Yes. pbf_wait(context, 100); @@ -313,16 +388,17 @@ std::vector process_quest_list( context.wait_for_all_requests(); } //Close quest panel - mash b - }*/ - - if (quests_to_do.size() == 0){ + press_Bs_to_back_to_overworld(info, stream, context); + } + /* + if (!rerolled && quests_to_do.size() == 0){ OperationFailedException::fire( ErrorReport::SEND_ERROR_REPORT, "No possible quests! Check language selection.", stream ); } - + */ return quests_to_do; } diff --git a/SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_BlueberryQuests.h b/SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_BlueberryQuests.h index d24212a4bb..cac60c37d0 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_BlueberryQuests.h +++ b/SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_BlueberryQuests.h @@ -17,18 +17,6 @@ namespace PokemonAutomation{ namespace NintendoSwitch{ namespace PokemonSV{ -enum class BBQuests{ - auto_10, make_tm, pickup_10, sneak_up, photo_fly, photo_swim, photo_canyon, photo_coastal, photo_polar, photo_savanna, tera_self_defeat, - travel_500, catch_any, catch_normal, catch_fighting, catch_flying, catch_poison, catch_ground, catch_rock, catch_bug, catch_ghost, catch_steel, - catch_fire, catch_water, catch_grass, catch_electric, catch_psychic, catch_ice, catch_dragon, catch_dark, catch_fairy, - wash_pokemon, wild_tera, auto_30, tera_raid, sandwich_three, bitter_sandwich, sweet_sandwich, salty_sandwich, sour_sandwich, spicy_sandwich, hatch_egg, - photo_normal, photo_fighting, photo_flying, photo_poison, photo_ground, photo_rock, photo_bug, photo_ghost, photo_steel, photo_fire, photo_water, - photo_grass, photo_electric, photo_psychic, photo_ice, photo_dragon, photo_dark, photo_fairy, - ditto_central, ditto_canyon, ditto_coastal, ditto_polar, ditto_savanna, group_canyon, group_coastal, group_polar, group_savanna, group_eyewear, group_nonuniform, - group_masks, sandwich_four, catch_hint, catch_hint2, - UnableToDetect -}; - BBQuests BBQuests_string_to_enum(const std::string& token); enum class CameraAngle{