diff --git a/SerialPrograms/Source/PokemonSwSh/Programs/DateSpamFarmers/PokemonSwSh_DateSpam-WattFarmer.cpp b/SerialPrograms/Source/PokemonSwSh/Programs/DateSpamFarmers/PokemonSwSh_DateSpam-WattFarmer.cpp index 75f60f1713..a18fbbc7ed 100644 --- a/SerialPrograms/Source/PokemonSwSh/Programs/DateSpamFarmers/PokemonSwSh_DateSpam-WattFarmer.cpp +++ b/SerialPrograms/Source/PokemonSwSh/Programs/DateSpamFarmers/PokemonSwSh_DateSpam-WattFarmer.cpp @@ -9,10 +9,19 @@ #include "Controllers/ControllerTypes.h" #include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" #include "NintendoSwitch/Commands/NintendoSwitch_Commands_Superscalar.h" +#include "NintendoSwitch/Programs/DateSpam/NintendoSwitch_HomeToDateTime.h" +#include "NintendoSwitch/Programs/DateSpam/NintendoSwitch_RollDateForward1.h" +#include "NintendoSwitch/Programs/DateSpam/NintendoSwitch_RollDateBackwardN.h" +#include "NintendoSwitch/NintendoSwitch_Settings.h" +#include "NintendoSwitch/Programs/NintendoSwitch_GameEntry.h" #include "Pokemon/Pokemon_Strings.h" #include "PokemonSwSh/PokemonSwSh_Settings.h" #include "PokemonSwSh/Commands/PokemonSwSh_Commands_DateSpam.h" #include "PokemonSwSh_DateSpam-WattFarmer.h" +#include "PokemonSwSh/Programs/Hosting/PokemonSwSh_DenTools.h" +#include "PokemonSwSh/Programs/Hosting/PokemonSwSh_DenRoller.h" +#include "PokemonSwSh/Programs/PokemonSwSh_GameEntry.h" +#include "PokemonSwSh/Options/PokemonSwSh_Catchability.h" namespace PokemonAutomation{ namespace NintendoSwitch{ @@ -58,6 +67,12 @@ WattFarmer::WattFarmer() LockMode::LOCK_WHILE_RUNNING, 100 ) + , HAVE_NSO( + "I have Nintendo Switch Online
" + "If you don't have NSO, the program won't use the Y-Comm glitch", + LockMode::LOCK_WHILE_RUNNING, + true + ) , NOTIFICATIONS({ &NOTIFICATION_PROGRAM_FINISH, }) @@ -67,9 +82,11 @@ WattFarmer::WattFarmer() PA_ADD_OPTION(EXIT_DEN_WAIT); PA_ADD_OPTION(SKIPS); PA_ADD_OPTION(SAVE_ITERATIONS0); + PA_ADD_OPTION(HAVE_NSO); PA_ADD_OPTION(NOTIFICATIONS); } + void WattFarmer::program(SingleSwitchProgramEnvironment& env, ProControllerContext& context){ if (START_LOCATION.start_in_grip_menu()){ grip_menu_connect_go_home(context); @@ -78,37 +95,76 @@ void WattFarmer::program(SingleSwitchProgramEnvironment& env, ProControllerConte pbf_press_button(context, BUTTON_B, 40ms, 40ms); ssf_press_button(context, BUTTON_HOME, GameSettings::instance().GAME_TO_HOME_DELAY_FAST0, 160ms); } - + uint8_t year = MAX_YEAR; uint16_t save_count = 0; - for (uint32_t c = 0; c < SKIPS; c++){ - env.log("Fetch Attempts: " + tostr_u_commas(c)); - - home_roll_date_enter_game_autorollback(env.console, context, year); - if (context->performance_class() == ControllerPerformanceClass::SysbotBase){ - pbf_wait(context, 720ms); - }else{ - pbf_mash_button(context, BUTTON_B, 720ms); + + if (!HAVE_NSO) { + // First subdivide the number of skips into batches of 60 because the roll_den function only goes up to 60 + + for (uint32_t c = 0; c < SKIPS; c++){ + enter_den(context, 0ms, c >= 0, false); + enter_lobby(context, 0ms, false, Catchability::ALWAYS_CATCHABLE); + + // Skip forward. + ssf_press_button(context, BUTTON_HOME, GameSettings::instance().GAME_TO_HOME_DELAY_FAST0, 80ms); + home_to_date_time(env.console, context, true); + roll_date_forward_1(env.console, context, false); + + // Enter game + pbf_press_button(context, BUTTON_HOME, 80ms, 720ms); + PokemonAutomation::NintendoSwitch::resume_game_from_home(env.console, context); + + // Exit Raid + ssf_press_button(context, BUTTON_B, 960ms, 400ms); + ssf_press_button(context, BUTTON_A, GameSettings::instance().REENTER_DEN_DELAY0, 400ms); + + // Save after X skips + if (SAVE_ITERATIONS0 != 0){ + save_count++; + if (save_count >= SAVE_ITERATIONS0){ + save_count = 0; + pbf_mash_button(context, BUTTON_B, 2000ms); + pbf_press_button(context, BUTTON_X, 160ms, GameSettings::instance().OVERWORLD_TO_MENU_DELAY0); + pbf_press_button(context, BUTTON_R, 160ms, 2000ms); + pbf_press_button(context, BUTTON_ZL, 160ms, 3000ms); + } + } } + // Take the last Watts from the Den + ssf_mash_AZs(context, GameSettings::instance().COLLECT_WATTS_OFFLINE_DELAY0); + ssf_mash1_button(context, BUTTON_B, 960ms); + + } else { + for (uint32_t c = 0; c < SKIPS; c++){ + env.log("Fetch Attempts: " + tostr_u_commas(c)); + + home_roll_date_enter_game_autorollback(env.console, context, year); + if (context->performance_class() == ControllerPerformanceClass::SysbotBase){ + pbf_wait(context, 720ms); + }else{ + pbf_mash_button(context, BUTTON_B, 720ms); + } - ssf_press_button_ptv(context, BUTTON_A, 40ms); - pbf_mash_button(context, BUTTON_B, EXIT_DEN_WAIT); - - if (SAVE_ITERATIONS0 != 0){ - save_count++; - if (save_count >= SAVE_ITERATIONS0){ - save_count = 0; - pbf_mash_button(context, BUTTON_B, 2000ms); - pbf_press_button(context, BUTTON_X, 160ms, GameSettings::instance().OVERWORLD_TO_MENU_DELAY0); - pbf_press_button(context, BUTTON_R, 160ms, 2000ms); - pbf_press_button(context, BUTTON_ZL, 160ms, 3000ms); + ssf_press_button_ptv(context, BUTTON_A, 40ms); + pbf_mash_button(context, BUTTON_B, EXIT_DEN_WAIT); + + if (SAVE_ITERATIONS0 != 0){ + save_count++; + if (save_count >= SAVE_ITERATIONS0){ + save_count = 0; + pbf_mash_button(context, BUTTON_B, 2000ms); + pbf_press_button(context, BUTTON_X, 160ms, GameSettings::instance().OVERWORLD_TO_MENU_DELAY0); + pbf_press_button(context, BUTTON_R, 160ms, 2000ms); + pbf_press_button(context, BUTTON_ZL, 160ms, 3000ms); + } } - } - // Tap HOME and quickly spam B. The B spamming ensures that we don't - // accidentally update the system if the system update window pops up. - ssf_press_button(context, BUTTON_HOME, 120ms, 160ms); - pbf_mash_button(context, BUTTON_B, GameSettings::instance().GAME_TO_HOME_DELAY_FAST0.get() - 120ms); + // Tap HOME and quickly spam B. The B spamming ensures that we don't + // accidentally update the system if the system update window pops up. + ssf_press_button(context, BUTTON_HOME, 120ms, 160ms); + pbf_mash_button(context, BUTTON_B, GameSettings::instance().GAME_TO_HOME_DELAY_FAST0.get() - 120ms); + } } send_program_finished_notification(env, NOTIFICATION_PROGRAM_FINISH); diff --git a/SerialPrograms/Source/PokemonSwSh/Programs/DateSpamFarmers/PokemonSwSh_DateSpam-WattFarmer.h b/SerialPrograms/Source/PokemonSwSh/Programs/DateSpamFarmers/PokemonSwSh_DateSpam-WattFarmer.h index 6c31c6f2b4..0dbc8edd7f 100644 --- a/SerialPrograms/Source/PokemonSwSh/Programs/DateSpamFarmers/PokemonSwSh_DateSpam-WattFarmer.h +++ b/SerialPrograms/Source/PokemonSwSh/Programs/DateSpamFarmers/PokemonSwSh_DateSpam-WattFarmer.h @@ -39,6 +39,8 @@ class WattFarmer : public SingleSwitchProgramInstance{ SimpleIntegerOption SKIPS; SimpleIntegerOption SAVE_ITERATIONS0; + + BooleanCheckBoxOption HAVE_NSO; EventNotificationsOption NOTIFICATIONS; }; diff --git a/SerialPrograms/Source/PokemonSwSh/Programs/Hosting/PokemonSwSh_DenRoller.cpp b/SerialPrograms/Source/PokemonSwSh/Programs/Hosting/PokemonSwSh_DenRoller.cpp index 5d7e129ee0..dd4dfb4a94 100644 --- a/SerialPrograms/Source/PokemonSwSh/Programs/Hosting/PokemonSwSh_DenRoller.cpp +++ b/SerialPrograms/Source/PokemonSwSh/Programs/Hosting/PokemonSwSh_DenRoller.cpp @@ -70,7 +70,7 @@ DenRoller::DenRoller() "Automatically stop when this " + STRING_POKEMON + " is rolled. Video output is required." ) , VIEW_TIME0( - "View Time:
Wait this long before restting. This wait is skipped if the desired " + + "View Time:
Wait this long before resetting. This wait is skipped if the desired " + STRING_POKEMON + " is set since the program will be watching it for you.", LockMode::LOCK_WHILE_RUNNING, "5 s"