Skip to content

Commit 7ebdeaa

Browse files
authored
Add BerryBuyer; Shift Dialog Detection to avoid Japanese Furigana (#785)
* Add BerryBuyer; Shift Dialog Detection to avoid Japanese Furigana * Intentionally don't leave the purchase menu to not get attacked * Shift dialog detection to the bottom instead
1 parent c6d4b8f commit 7ebdeaa

File tree

6 files changed

+252
-4
lines changed

6 files changed

+252
-4
lines changed

SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_DialogDetector.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -211,15 +211,15 @@ bool NormalDialogDetector::process_frame(const ImageViewRGB32& frame, WallClock
211211
FlatWhiteDialogDetector::FlatWhiteDialogDetector(Color color, VideoOverlay* overlay)
212212
: m_color(color)
213213
, m_overlay(overlay)
214-
, m_top(0.267838, 0.785156, 0.467618, 0.019531)
214+
, m_bottom(0.265, 0.930, 0.465, 0.020)
215215
, m_arrow_box(0.727, 0.868, 0.037, 0.086)
216216
{}
217217
void FlatWhiteDialogDetector::make_overlays(VideoOverlaySet& items) const{
218-
items.add(m_color, m_top);
218+
items.add(m_color, m_bottom);
219219
items.add(m_color, m_arrow_box);
220220
}
221221
bool FlatWhiteDialogDetector::detect(const ImageViewRGB32& screen){
222-
if (!is_white(extract_box_reference(screen, m_top), 500.0, 20.0)){
222+
if (!is_white(extract_box_reference(screen, m_bottom), 500.0, 20.0)){
223223
m_last_detected_box.reset();
224224
return false;
225225
}

SerialPrograms/Source/PokemonLZA/Inference/PokemonLZA_DialogDetector.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class FlatWhiteDialogDetector : public StaticScreenDetector{
6262

6363
const Color m_color;
6464
VideoOverlay* m_overlay;
65-
const ImageFloatBox m_top;
65+
const ImageFloatBox m_bottom;
6666
const ImageFloatBox m_arrow_box;
6767

6868
ImageFloatBox m_last_detected;

SerialPrograms/Source/PokemonLZA/PokemonLZA_Panels.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
// General
1414
#include "Programs/PokemonLZA_ClothingBuyer.h"
15+
#include "Programs/PokemonLZA_BerryBuyer.h"
1516

1617
// Farming
1718
#include "Programs/Farming/PokemonLZA_RestaurantFarmer.h"
@@ -47,6 +48,7 @@ std::vector<PanelEntry> PanelListFactory::make_panels() const{
4748

4849
ret.emplace_back("---- General ----");
4950
ret.emplace_back(make_single_switch_program<ClothingBuyer_Descriptor, ClothingBuyer>());
51+
ret.emplace_back(make_single_switch_program<BerryBuyer_Descriptor, BerryBuyer>());
5052

5153
ret.emplace_back("---- Farming ----");
5254
ret.emplace_back(make_single_switch_program<RestaurantFarmer_Descriptor, RestaurantFarmer>());
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
/* Berry Buyer
2+
*
3+
* From: https://github.com/PokemonAutomation/
4+
*
5+
*/
6+
7+
#include "CommonFramework/Exceptions/OperationFailedException.h"
8+
#include "CommonFramework/Notifications/ProgramNotifications.h"
9+
#include "CommonFramework/ProgramStats/StatsTracking.h"
10+
#include "CommonTools/Async/InferenceRoutines.h"
11+
#include "CommonTools/StartupChecks/VideoResolutionCheck.h"
12+
#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h"
13+
#include "Pokemon/Pokemon_Strings.h"
14+
#include "PokemonLZA/Inference/PokemonLZA_ButtonDetector.h"
15+
#include "PokemonLZA/Inference/PokemonLZA_SelectionArrowDetector.h"
16+
#include "PokemonLZA/Inference/PokemonLZA_DialogDetector.h"
17+
#include "PokemonLZA_BerryBuyer.h"
18+
19+
namespace PokemonAutomation{
20+
namespace NintendoSwitch{
21+
namespace PokemonLZA{
22+
23+
using namespace Pokemon;
24+
25+
BerryBuyer_Descriptor::BerryBuyer_Descriptor()
26+
: SingleSwitchProgramDescriptor(
27+
"PokemonLZA:BerryBuyer",
28+
STRING_POKEMON + " LZA", "Berry Buyer",
29+
"Programs/PokemonLZA/BerryBuyer.html",
30+
"Buy EV reducing berries from stall.",
31+
ProgramControllerClass::StandardController_NoRestrictions,
32+
FeedbackType::REQUIRED,
33+
AllowCommandsWhenRunning::DISABLE_COMMANDS
34+
)
35+
{}
36+
37+
class BerryBuyer_Descriptor::Stats : public StatsTracker{
38+
public:
39+
Stats()
40+
: purchases(m_stats["Purchases"])
41+
, errors(m_stats["Errors"])
42+
{
43+
m_display_order.emplace_back("Purchases");
44+
m_display_order.emplace_back("Errors", HIDDEN_IF_ZERO);
45+
}
46+
47+
std::atomic<uint64_t>& purchases;
48+
std::atomic<uint64_t>& errors;
49+
};
50+
std::unique_ptr<StatsTracker> BerryBuyer_Descriptor::make_stats() const{
51+
return std::unique_ptr<StatsTracker>(new Stats());
52+
}
53+
54+
55+
BerryBuyer::BerryBuyer()
56+
: BERRY_TYPE(
57+
"<b>Berry to Purchase:",
58+
{
59+
{BerryType::POMEG, "pomeg", "Pomeg (HP)"},
60+
{BerryType::KELPSY, "kelpsy", "Kelpsy (Attack)"},
61+
{BerryType::QUALOT, "qualot", "Qualot (Defence)"},
62+
{BerryType::HONDEW, "hondew", "Hondew (Special Attack)"},
63+
{BerryType::GREPA, "grepa", "Grepa (Special Defence)"},
64+
{BerryType::TAMATO, "tamato", "Tamato (Speed)"},
65+
},
66+
LockMode::LOCK_WHILE_RUNNING,
67+
BerryType::POMEG
68+
)
69+
, NUM_PURCHASE(
70+
"<b>Number to Purchase:</b><br>The number of berries you want to purchase.",
71+
LockMode::LOCK_WHILE_RUNNING,
72+
100, 1, 999
73+
)
74+
, GO_HOME_WHEN_DONE(false)
75+
, NOTIFICATION_STATUS_UPDATE("Status Update", true, false, std::chrono::seconds(3600))
76+
, NOTIFICATIONS({
77+
&NOTIFICATION_STATUS_UPDATE,
78+
&NOTIFICATION_PROGRAM_FINISH,
79+
&NOTIFICATION_ERROR_FATAL,
80+
})
81+
{
82+
PA_ADD_OPTION(BERRY_TYPE);
83+
PA_ADD_OPTION(NUM_PURCHASE);
84+
PA_ADD_OPTION(GO_HOME_WHEN_DONE);
85+
PA_ADD_OPTION(NOTIFICATIONS);
86+
}
87+
88+
void BerryBuyer::program(SingleSwitchProgramEnvironment& env, ProControllerContext& context){
89+
BerryBuyer_Descriptor::Stats& stats = env.current_stats<BerryBuyer_Descriptor::Stats>();
90+
assert_16_9_720p_min(env.logger(), env.console);
91+
while (true) {
92+
context.wait_for_all_requests();
93+
94+
ButtonWatcher buttonA(
95+
COLOR_RED,
96+
ButtonType::ButtonA,
97+
{0.1, 0.1, 0.8, 0.8},
98+
&env.console.overlay()
99+
);
100+
SelectionArrowWatcher select(
101+
COLOR_YELLOW, &env.console.overlay(),
102+
SelectionArrowType::RIGHT,
103+
{0.715, 0.235, 0.045, 0.080}
104+
);
105+
SelectionArrowWatcher confirm(
106+
COLOR_YELLOW, &env.console.overlay(),
107+
SelectionArrowType::RIGHT,
108+
{0.715, 0.600, 0.045, 0.080}
109+
);
110+
FlatWhiteDialogWatcher dialog(COLOR_RED, &env.console.overlay());
111+
112+
int ret = wait_until(
113+
env.console, context,
114+
30000ms,
115+
{
116+
buttonA,
117+
select,
118+
confirm,
119+
dialog,
120+
}
121+
);
122+
context.wait_for(100ms);
123+
124+
switch (ret){
125+
case 0:
126+
env.log("Detected A button.");
127+
pbf_press_button(context, BUTTON_A, 160ms, 80ms);
128+
continue;
129+
130+
case 1:
131+
env.log("Detected berry selection screen.");
132+
switch(BERRY_TYPE){
133+
case BerryType::HONDEW:
134+
pbf_press_dpad(context, DPAD_DOWN, 160ms, 80ms);
135+
case BerryType::QUALOT:
136+
pbf_press_dpad(context, DPAD_DOWN, 160ms, 80ms);
137+
case BerryType::KELPSY:
138+
pbf_press_dpad(context, DPAD_DOWN, 160ms, 80ms);
139+
case BerryType::POMEG:
140+
break;
141+
case BerryType::GREPA:
142+
pbf_press_dpad(context, DPAD_UP, 160ms, 80ms);
143+
case BerryType::TAMATO:
144+
pbf_press_dpad(context, DPAD_UP, 160ms, 80ms);
145+
pbf_press_dpad(context, DPAD_UP, 160ms, 80ms);
146+
break;
147+
}
148+
pbf_press_button(context, BUTTON_A, 160ms, 80ms);
149+
continue;
150+
151+
case 2:
152+
env.log("Detected purchase confirm screen.");
153+
pbf_press_button(context, BUTTON_A, 160ms, 80ms);
154+
stats.purchases++;
155+
env.update_stats();
156+
157+
if (stats.purchases == NUM_PURCHASE) {
158+
// pbf_mash_button(context, BUTTON_B, 5000ms);
159+
// intentionally don't leave the purchase menu to not get attacked
160+
GO_HOME_WHEN_DONE.run_end_of_program(context);
161+
send_program_finished_notification(env, NOTIFICATION_PROGRAM_FINISH);
162+
return;
163+
}
164+
165+
continue;
166+
167+
case 3:
168+
env.log("Detected white dialog.");
169+
pbf_press_button(context, BUTTON_A, 160ms, 80ms);
170+
continue;
171+
172+
default:
173+
stats.errors++;
174+
env.update_stats();
175+
OperationFailedException::fire(
176+
ErrorReport::SEND_ERROR_REPORT,
177+
"No recognized state after 30 seconds.",
178+
env.console
179+
);
180+
}
181+
}
182+
}
183+
184+
185+
}
186+
}
187+
}
188+
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/* Berry Buyer
2+
*
3+
* From: https://github.com/PokemonAutomation/
4+
*
5+
*/
6+
7+
#ifndef PokemonAutomation_PokemonLZA_BerryBuyer_H
8+
#define PokemonAutomation_PokemonLZA_BerryBuyer_H
9+
10+
#include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h"
11+
#include "CommonFramework/Notifications/EventNotificationsTable.h"
12+
#include "NintendoSwitch/Options/NintendoSwitch_GoHomeWhenDoneOption.h"
13+
#include "Common/Cpp/Options/SimpleIntegerOption.h"
14+
15+
namespace PokemonAutomation{
16+
namespace NintendoSwitch{
17+
namespace PokemonLZA{
18+
19+
class BerryBuyer_Descriptor : public SingleSwitchProgramDescriptor{
20+
public:
21+
BerryBuyer_Descriptor();
22+
23+
class Stats;
24+
virtual std::unique_ptr<StatsTracker> make_stats() const override;
25+
};
26+
27+
class BerryBuyer : public SingleSwitchProgramInstance{
28+
public:
29+
BerryBuyer();
30+
31+
virtual void program(SingleSwitchProgramEnvironment& env, ProControllerContext& context) override;
32+
33+
private:
34+
enum class BerryType{
35+
POMEG,
36+
KELPSY,
37+
QUALOT,
38+
HONDEW,
39+
GREPA,
40+
TAMATO,
41+
};
42+
EnumDropdownOption<BerryType> BERRY_TYPE;
43+
SimpleIntegerOption<uint16_t> NUM_PURCHASE;
44+
GoHomeWhenDoneOption GO_HOME_WHEN_DONE;
45+
EventNotificationOption NOTIFICATION_STATUS_UPDATE;
46+
EventNotificationsOption NOTIFICATIONS;
47+
};
48+
49+
50+
51+
52+
53+
}
54+
}
55+
}
56+
#endif

SerialPrograms/SourceFiles.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1569,6 +1569,8 @@ file(GLOB LIBRARY_SOURCES
15691569
Source/PokemonLZA/Programs/Farming/PokemonLZA_RestaurantFarmer.h
15701570
Source/PokemonLZA/Programs/PokemonLZA_BasicNavigation.cpp
15711571
Source/PokemonLZA/Programs/PokemonLZA_BasicNavigation.h
1572+
Source/PokemonLZA/Programs/PokemonLZA_BerryBuyer.cpp
1573+
Source/PokemonLZA/Programs/PokemonLZA_BerryBuyer.h
15721574
Source/PokemonLZA/Programs/PokemonLZA_ClothingBuyer.cpp
15731575
Source/PokemonLZA/Programs/PokemonLZA_ClothingBuyer.h
15741576
Source/PokemonLZA/Programs/PokemonLZA_GameEntry.cpp

0 commit comments

Comments
 (0)