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"