Skip to content

Commit 3525a1f

Browse files
committed
Add WattTraderFarmer.
1 parent 0694e02 commit 3525a1f

File tree

5 files changed

+248
-0
lines changed

5 files changed

+248
-0
lines changed

SerialPrograms/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2079,6 +2079,8 @@ file(GLOB MAIN_SOURCES
20792079
Source/PokemonSwSh/Programs/DateSpamFarmers/PokemonSwSh_DateSpam-StowOnSideFarmer.h
20802080
Source/PokemonSwSh/Programs/DateSpamFarmers/PokemonSwSh_DateSpam-WattFarmer.cpp
20812081
Source/PokemonSwSh/Programs/DateSpamFarmers/PokemonSwSh_DateSpam-WattFarmer.h
2082+
Source/PokemonSwSh/Programs/DateSpamFarmers/PokemonSwSh_DateSpam-WattTraderFarmer.cpp
2083+
Source/PokemonSwSh/Programs/DateSpamFarmers/PokemonSwSh_DateSpam-WattTraderFarmer.h
20822084
Source/PokemonSwSh/Programs/DenHunting/PokemonSwSh_BeamReset.cpp
20832085
Source/PokemonSwSh/Programs/DenHunting/PokemonSwSh_BeamReset.h
20842086
Source/PokemonSwSh/Programs/DenHunting/PokemonSwSh_DaySkipperEU.cpp

SerialPrograms/Source/NintendoSwitch/Framework/UI/NintendoSwitch_SwitchSystemWidget.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ SwitchSystemWidget::~SwitchSystemWidget(){
3636
delete m_audio_display;
3737
delete m_audio_widget;
3838
delete m_video_display;
39+
delete m_video_selector;
3940
delete m_controller;
4041
}
4142

SerialPrograms/Source/PokemonSwSh/PokemonSwSh_Panels.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "Programs/DateSpamFarmers/PokemonSwSh_DateSpam-StowOnSideFarmer.h"
2929
#include "Programs/DateSpamFarmers/PokemonSwSh_DateSpam-DailyHighlightFarmer.h"
3030
#include "Programs/DateSpamFarmers/PokemonSwSh_DateSpam-PokeJobsFarmer.h"
31+
#include "Programs/DateSpamFarmers/PokemonSwSh_DateSpam-WattTraderFarmer.h"
3132

3233
#include "Programs/DenHunting/PokemonSwSh_BeamReset.h"
3334
#include "Programs/DenHunting/PokemonSwSh_PurpleBeamFinder.h"
@@ -127,6 +128,9 @@ std::vector<PanelEntry> PanelListFactory::make_panels() const{
127128
ret.emplace_back(make_single_switch_program<StowOnSideFarmer_Descriptor, StowOnSideFarmer>());
128129
ret.emplace_back(make_single_switch_program<DailyHighlightFarmer_Descriptor, DailyHighlightFarmer>());
129130
ret.emplace_back(make_single_switch_program<PokeJobsFarmer_Descriptor, PokeJobsFarmer>());
131+
if (PreloadSettings::instance().DEVELOPER_MODE){
132+
ret.emplace_back(make_single_switch_program<WattTraderFarmer_Descriptor, WattTraderFarmer>());
133+
}
130134

131135
ret.emplace_back("---- Den Hunting ----");
132136
ret.emplace_back(make_single_switch_program<PurpleBeamFinder_Descriptor, PurpleBeamFinder>());
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
/* Watt Trader Farmer
2+
*
3+
* From: https://github.com/PokemonAutomation/
4+
*
5+
*/
6+
7+
#include "CommonFramework/ProgramStats/StatsTracking.h"
8+
#include "CommonFramework/VideoPipeline/VideoFeed.h"
9+
#include "CommonTools/Images/SolidColorTest.h"
10+
#include "CommonTools/Async/InferenceRoutines.h"
11+
#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h"
12+
#include "NintendoSwitch/Commands/NintendoSwitch_Commands_Superscalar.h"
13+
#include "Pokemon/Pokemon_Strings.h"
14+
#include "PokemonSwSh/PokemonSwSh_Settings.h"
15+
#include "PokemonSwSh/Commands/PokemonSwSh_Commands_DateSpam.h"
16+
#include "PokemonSwSh/Inference/PokemonSwSh_DialogTriangleDetector.h"
17+
#include "PokemonSwSh/Inference/PokemonSwSh_SelectionArrowFinder.h"
18+
#include "PokemonSwSh_DateSpam-WattTraderFarmer.h"
19+
20+
namespace PokemonAutomation{
21+
namespace NintendoSwitch{
22+
namespace PokemonSwSh{
23+
24+
using namespace Pokemon;
25+
26+
27+
WattTraderFarmer_Descriptor::WattTraderFarmer_Descriptor()
28+
: SingleSwitchProgramDescriptor(
29+
"PokemonSwSh:WattTraderFarmer",
30+
STRING_POKEMON + " SwSh", "Date Spam - Watt Trader Farmer",
31+
"",
32+
"Buy as much stuff from a watt trader as possible - day skipping as needed to reroll items.",
33+
FeedbackType::REQUIRED,
34+
AllowCommandsWhenRunning::DISABLE_COMMANDS,
35+
{ControllerFeature::NintendoSwitch_ProController},
36+
FasterIfTickPrecise::MUCH_FASTER
37+
)
38+
{}
39+
40+
class WattTraderFarmer_Descriptor::Stats : public StatsTracker{
41+
public:
42+
Stats()
43+
: day_skips(m_stats["Day Skips"])
44+
, items_probed(m_stats["Items Probed"])
45+
, failed(m_stats["Failed"])
46+
, success(m_stats["Success"])
47+
, errors(m_stats["Errors"])
48+
{
49+
m_display_order.insert(m_display_order.begin() + 0, Stat("Day Skips"));
50+
m_display_order.insert(m_display_order.begin() + 1, Stat("Items Probed"));
51+
m_display_order.insert(m_display_order.begin() + 2, Stat("Failed"));
52+
m_display_order.insert(m_display_order.begin() + 3, Stat("Success"));
53+
m_display_order.insert(m_display_order.begin() + 4, Stat("Errors"));
54+
}
55+
56+
public:
57+
std::atomic<uint64_t>& day_skips;
58+
std::atomic<uint64_t>& items_probed;
59+
std::atomic<uint64_t>& failed;
60+
std::atomic<uint64_t>& success;
61+
std::atomic<uint64_t>& errors;
62+
};
63+
std::unique_ptr<StatsTracker> WattTraderFarmer_Descriptor::make_stats() const{
64+
return std::unique_ptr<StatsTracker>(new Stats());
65+
}
66+
67+
68+
69+
WattTraderFarmer::WattTraderFarmer(){
70+
71+
}
72+
73+
74+
75+
class BuyCursorDetector : public SelectionArrowFinder{
76+
public:
77+
BuyCursorDetector(VideoOverlay& overlay)
78+
: SelectionArrowFinder(overlay, ImageFloatBox(0.448775, 0.087129, 0.062361, 0.596040))
79+
{}
80+
};
81+
class BuyQuantityDetector : public VisualInferenceCallback{
82+
public:
83+
BuyQuantityDetector()
84+
: VisualInferenceCallback("BuyQuantityDetector")
85+
, m_box(0.814031, 0.681188, 0.170379, 0.045545)
86+
{}
87+
virtual void make_overlays(VideoOverlaySet& items) const override{
88+
items.add(COLOR_GREEN, m_box);
89+
}
90+
virtual bool process_frame(const VideoSnapshot& frame) override{
91+
ImageStats stats = image_stats(extract_box_reference(frame, m_box));
92+
return is_solid(stats, {0.62963, 0.37037, 0.});
93+
}
94+
95+
private:
96+
ImageFloatBox m_box;
97+
};
98+
99+
100+
101+
void WattTraderFarmer::buy_one(SingleSwitchProgramEnvironment& env, ProControllerContext& context){
102+
WattTraderFarmer_Descriptor::Stats& stats = env.current_stats<WattTraderFarmer_Descriptor::Stats>();
103+
104+
bool purchased = false;
105+
while (true){
106+
DialogTriangleDetector dialog(env.logger(), env.console, true);
107+
BuyCursorDetector item_select(env.console);
108+
BuyQuantityDetector quantity;
109+
context.wait_for_all_requests();
110+
int ret = wait_until(
111+
env.console, context,
112+
std::chrono::seconds(10),
113+
{
114+
dialog,
115+
item_select,
116+
quantity,
117+
}
118+
);
119+
context.wait_for(200ms);
120+
switch (ret){
121+
case 0:
122+
env.log("Detected dialog...", COLOR_BLUE);
123+
if (!purchased){
124+
stats.failed++;
125+
env.update_stats();
126+
}
127+
pbf_press_button(context, BUTTON_B, 200ms, 800ms);
128+
return;
129+
case 1:
130+
env.log("Detected item select...", COLOR_BLUE);
131+
if (purchased){
132+
return;
133+
}
134+
pbf_press_button(context, BUTTON_A, 200ms, 800ms);
135+
continue;
136+
case 2:
137+
env.log("Detected quantity select...", COLOR_BLUE);
138+
stats.success++;
139+
env.update_stats();
140+
pbf_press_dpad(context, DPAD_DOWN, 200ms, 800ms);
141+
pbf_press_button(context, BUTTON_A, 200ms, 800ms);
142+
pbf_press_button(context, BUTTON_A, 200ms, 800ms);
143+
purchased = true;
144+
continue;
145+
default:
146+
env.log("No recognized state after 5 seconds.", COLOR_RED);
147+
stats.errors++;
148+
env.update_stats();
149+
pbf_mash_button(context, BUTTON_B, 5000ms);
150+
pbf_press_button(context, BUTTON_A, 200ms, 800ms);
151+
pbf_press_button(context, BUTTON_A, 200ms, 800ms);
152+
continue;
153+
}
154+
}
155+
}
156+
157+
158+
159+
void WattTraderFarmer::program(SingleSwitchProgramEnvironment& env, ProControllerContext& context){
160+
WattTraderFarmer_Descriptor::Stats& stats = env.current_stats<WattTraderFarmer_Descriptor::Stats>();
161+
162+
uint8_t year = MAX_YEAR;
163+
while (true){
164+
pbf_press_button(context, BUTTON_A, 200ms, 800ms);
165+
pbf_press_button(context, BUTTON_A, 200ms, 800ms);
166+
167+
for (size_t c = 0; c < 7; c++){
168+
buy_one(env, context);
169+
stats.items_probed++;
170+
env.update_stats();
171+
pbf_press_dpad(context, DPAD_DOWN, 200ms, 200ms);
172+
}
173+
174+
pbf_mash_button(context, BUTTON_B, 5000ms);
175+
176+
// Tap HOME and quickly spam B. The B spamming ensures that we don't
177+
// accidentally update the system if the system update window pops up.
178+
ssf_press_button(context, BUTTON_HOME, 120ms, 160ms);
179+
pbf_mash_button(context, BUTTON_B, GameSettings::instance().GAME_TO_HOME_DELAY_FAST0.get() - 120ms);
180+
181+
home_roll_date_enter_game_autorollback(env.console, context, year);
182+
pbf_mash_button(context, BUTTON_B, 90);
183+
stats.day_skips++;
184+
env.update_stats();
185+
}
186+
}
187+
188+
189+
190+
191+
192+
}
193+
}
194+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/* Watt Trader Farmer
2+
*
3+
* From: https://github.com/PokemonAutomation/
4+
*
5+
*/
6+
7+
#ifndef PokemonAutomation_PokemonSwSh_WattTraderFarmer_H
8+
#define PokemonAutomation_PokemonSwSh_WattTraderFarmer_H
9+
10+
#include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h"
11+
12+
namespace PokemonAutomation{
13+
namespace NintendoSwitch{
14+
namespace PokemonSwSh{
15+
16+
17+
class WattTraderFarmer_Descriptor : public SingleSwitchProgramDescriptor{
18+
public:
19+
WattTraderFarmer_Descriptor();
20+
21+
class Stats;
22+
virtual std::unique_ptr<StatsTracker> make_stats() const override;
23+
};
24+
25+
26+
27+
class WattTraderFarmer : public SingleSwitchProgramInstance{
28+
public:
29+
WattTraderFarmer();
30+
31+
virtual void program(SingleSwitchProgramEnvironment& env, ProControllerContext& context) override;
32+
33+
private:
34+
void buy_one(SingleSwitchProgramEnvironment& env, ProControllerContext& context);
35+
36+
37+
};
38+
39+
40+
41+
}
42+
}
43+
}
44+
#endif
45+
46+
47+

0 commit comments

Comments
 (0)