Skip to content

Commit 899bf79

Browse files
authored
emerald mew hunt (#539)
* emerald mew hunt (no timings yet) * mew timings
1 parent 106631d commit 899bf79

File tree

5 files changed

+296
-0
lines changed

5 files changed

+296
-0
lines changed

SerialPrograms/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1349,6 +1349,8 @@ file(GLOB MAIN_SOURCES
13491349
Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_LegendaryHunt-Emerald.h
13501350
Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_ShinyHunt-Deoxys.cpp
13511351
Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_ShinyHunt-Deoxys.h
1352+
Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_ShinyHunt-Mew.cpp
1353+
Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_ShinyHunt-Mew.h
13521354
Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_StarterReset.cpp
13531355
Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_StarterReset.h
13541356
Source/PokemonRSE/Programs/TestPrograms/PokemonRSE_SoundListener.cpp

SerialPrograms/SerialPrograms.pro

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,7 @@ SOURCES += \
666666
Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_AudioStarterReset.cpp \
667667
Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_LegendaryHunt-Emerald.cpp \
668668
Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_ShinyHunt-Deoxys.cpp \
669+
Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_ShinyHunt-Mew.cpp \
669670
Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_StarterReset.cpp \
670671
Source/PokemonRSE/Programs/TestPrograms/PokemonRSE_SoundListener.cpp \
671672
Source/PokemonSV/Inference/Battles/PokemonSV_BattleBallReader.cpp \
@@ -1832,6 +1833,7 @@ HEADERS += \
18321833
Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_AudioStarterReset.h \
18331834
Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_LegendaryHunt-Emerald.h \
18341835
Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_ShinyHunt-Deoxys.h \
1836+
Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_ShinyHunt-Mew.h \
18351837
Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_StarterReset.h \
18361838
Source/PokemonRSE/Programs/TestPrograms/PokemonRSE_SoundListener.h \
18371839
Source/PokemonSV/Inference/Battles/PokemonSV_BattleBallReader.h \

SerialPrograms/Source/PokemonRSE/PokemonRSE_Panels.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "Programs/ShinyHunting/PokemonRSE_AudioStarterReset.h"
1414
#include "Programs/ShinyHunting/PokemonRSE_LegendaryHunt-Emerald.h"
1515
#include "Programs/ShinyHunting/PokemonRSE_ShinyHunt-Deoxys.h"
16+
#include "Programs/ShinyHunting/PokemonRSE_ShinyHunt-Mew.h"
1617

1718
#include "Programs/ShinyHunting/PokemonRSE_StarterReset.h"
1819
#include "Programs/TestPrograms/PokemonRSE_SoundListener.h"
@@ -41,6 +42,7 @@ std::vector<PanelEntry> PanelListFactory::make_panels() const{
4142
ret.emplace_back("---- Shiny Hunting (Emerald) ----");
4243
ret.emplace_back(make_single_switch_program<LegendaryHuntEmerald_Descriptor, LegendaryHuntEmerald>());
4344
ret.emplace_back(make_single_switch_program<ShinyHuntDeoxys_Descriptor, ShinyHuntDeoxys>());
45+
ret.emplace_back(make_single_switch_program<ShinyHuntMew_Descriptor, ShinyHuntMew>());
4446

4547

4648
if (PreloadSettings::instance().DEVELOPER_MODE){
Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
/* E Shiny Mew
2+
*
3+
* From: https://github.com/PokemonAutomation/Arduino-Source
4+
*
5+
*/
6+
7+
#include "Common/Cpp/PrettyPrint.h"
8+
#include "CommonFramework/Exceptions/OperationFailedException.h"
9+
#include "CommonTools/Async/InferenceRoutines.h"
10+
#include "CommonTools/VisualDetectors/BlackScreenDetector.h"
11+
#include "CommonFramework/Notifications/ProgramNotifications.h"
12+
#include "CommonFramework/ProgramStats/StatsTracking.h"
13+
#include "CommonFramework/VideoPipeline/VideoFeed.h"
14+
#include "Pokemon/Pokemon_Strings.h"
15+
#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h"
16+
#include "NintendoSwitch/Commands/NintendoSwitch_Commands_Superscalar.h"
17+
#include "PokemonRSE/Inference/Dialogs/PokemonRSE_DialogDetector.h"
18+
#include "PokemonRSE/PokemonRSE_Navigation.h"
19+
#include "PokemonRSE_ShinyHunt-Mew.h"
20+
21+
namespace PokemonAutomation{
22+
namespace NintendoSwitch{
23+
namespace PokemonRSE{
24+
25+
ShinyHuntMew_Descriptor::ShinyHuntMew_Descriptor()
26+
: SingleSwitchProgramDescriptor(
27+
"PokemonRSE:ShinyHuntMew",
28+
Pokemon::STRING_POKEMON + " RSE", "Shiny Hunt - Mew",
29+
"ComputerControl/blob/master/Wiki/Programs/PokemonRSE/ShinyHuntMew.md",
30+
"Use the Run Away method to shiny hunt Mew in Emerald.",
31+
FeedbackType::VIDEO_AUDIO,
32+
AllowCommandsWhenRunning::DISABLE_COMMANDS,
33+
{SerialPABotBase::OLD_NINTENDO_SWITCH_DEFAULT_REQUIREMENTS}
34+
)
35+
{}
36+
37+
struct ShinyHuntMew_Descriptor::Stats : public StatsTracker{
38+
Stats()
39+
: resets(m_stats["Resets"])
40+
, shinies(m_stats["Shinies"])
41+
{
42+
m_display_order.emplace_back("Resets");
43+
m_display_order.emplace_back("Shinies");
44+
}
45+
std::atomic<uint64_t>& resets;
46+
std::atomic<uint64_t>& shinies;
47+
};
48+
std::unique_ptr<StatsTracker> ShinyHuntMew_Descriptor::make_stats() const{
49+
return std::unique_ptr<StatsTracker>(new Stats());
50+
}
51+
52+
ShinyHuntMew::ShinyHuntMew()
53+
: NOTIFICATION_SHINY(
54+
"Shiny Found",
55+
true, true, ImageAttachmentMode::JPG,
56+
{"Notifs", "Showcase"}
57+
)
58+
, NOTIFICATION_STATUS_UPDATE("Status Update", true, false, std::chrono::seconds(3600))
59+
, NOTIFICATIONS({
60+
&NOTIFICATION_SHINY,
61+
&NOTIFICATION_STATUS_UPDATE,
62+
&NOTIFICATION_PROGRAM_FINISH,
63+
})
64+
, m_advanced_options(
65+
"<font size=4><b>Advanced Options:</b> You should not need to touch anything below here.</font>"
66+
)
67+
, MEW_WAIT_TIME(
68+
"<b>Mew wait time:</b><br>Wait this long after entering for Mew to hide in the grass.",
69+
LockMode::LOCK_WHILE_RUNNING,
70+
"2000 ms"
71+
)
72+
, DOOR_TO_GRASS_TIME(
73+
"<b>Door to grass time:</b><br>Time it takes to run from the door to the edge of the tall grass. Three steps up.",
74+
LockMode::LOCK_WHILE_RUNNING,
75+
"400 ms"
76+
)
77+
, RIGHT_GRASS_1_TIME(
78+
"<b>First Right time:</b><br>Time it takes to turn right and take three steps. This follows the edge of the grass.",
79+
LockMode::LOCK_WHILE_RUNNING,
80+
"450 ms"
81+
)
82+
, UP_GRASS_1_TIME(
83+
"<b>Move Up time::</b><br>Time it takes turn up and take one step.",
84+
LockMode::LOCK_WHILE_RUNNING,
85+
"200 ms"
86+
)
87+
, RIGHT_GRASS_2_TIME(
88+
"<b>Second Right time:</b><br>Time it takes to turn right and take two steps.",
89+
LockMode::LOCK_WHILE_RUNNING,
90+
"260 ms"
91+
)
92+
, FACE_UP_TIME(
93+
"<b>Face Up time:</b><br>Time it takes to tap the up button and face up, without taking a step.",
94+
LockMode::LOCK_WHILE_RUNNING,
95+
"150 ms"
96+
)
97+
{
98+
PA_ADD_OPTION(NOTIFICATIONS);
99+
PA_ADD_STATIC(m_advanced_options);
100+
PA_ADD_OPTION(MEW_WAIT_TIME);
101+
PA_ADD_OPTION(DOOR_TO_GRASS_TIME);
102+
PA_ADD_OPTION(RIGHT_GRASS_1_TIME);
103+
PA_ADD_OPTION(UP_GRASS_1_TIME);
104+
PA_ADD_OPTION(RIGHT_GRASS_2_TIME);
105+
PA_ADD_OPTION(FACE_UP_TIME);
106+
}
107+
108+
void ShinyHuntMew::enter_mew(SingleSwitchProgramEnvironment& env, ProControllerContext& context) {
109+
BlackScreenOverWatcher enter_area(COLOR_RED, {0.282, 0.064, 0.448, 0.871});
110+
int ret = run_until<ProControllerContext>(
111+
env.console, context,
112+
[](ProControllerContext& context){
113+
pbf_press_dpad(context, DPAD_UP, 250, 20);
114+
pbf_wait(context, 300);
115+
},
116+
{enter_area}
117+
);
118+
context.wait_for_all_requests();
119+
if (ret != 0){
120+
env.log("Failed to enter area.", COLOR_RED);
121+
OperationFailedException::fire(
122+
ErrorReport::SEND_ERROR_REPORT,
123+
"Failed to enter area.",
124+
env.console
125+
);
126+
}
127+
else {
128+
env.log("Entered area.");
129+
}
130+
131+
//Wait for Mew ! animation to finish
132+
pbf_wait(context, MEW_WAIT_TIME);
133+
context.wait_for_all_requests();
134+
135+
//DO NOT pause while running!
136+
//Run up toward the extra tall grass - 3 steps
137+
ssf_press_button(context, BUTTON_B, 0ms, DOOR_TO_GRASS_TIME);
138+
pbf_press_dpad(context, DPAD_UP, DOOR_TO_GRASS_TIME, 0ms);
139+
140+
//Turn right, take 3 steps
141+
ssf_press_button(context, BUTTON_B, 0ms, RIGHT_GRASS_1_TIME);
142+
pbf_press_dpad(context, DPAD_RIGHT, RIGHT_GRASS_1_TIME, 0ms);
143+
144+
//Turn up, take 1 step
145+
ssf_press_button(context, BUTTON_B, 0ms, UP_GRASS_1_TIME);
146+
pbf_press_dpad(context, DPAD_UP, UP_GRASS_1_TIME, 0ms);
147+
148+
//Turn right, take 2 steps
149+
ssf_press_button(context, BUTTON_B, 0ms, RIGHT_GRASS_2_TIME);
150+
pbf_press_dpad(context, DPAD_RIGHT, RIGHT_GRASS_2_TIME, 0ms);
151+
152+
//Turn up. Start battle.
153+
pbf_press_dpad(context, DPAD_UP, FACE_UP_TIME, 0ms);
154+
155+
context.wait_for_all_requests();
156+
}
157+
158+
void ShinyHuntMew::exit_mew(SingleSwitchProgramEnvironment& env, ProControllerContext& context) {
159+
ssf_press_button(context, BUTTON_B, 0, 50);
160+
pbf_press_dpad(context, DPAD_DOWN, 50, 20);
161+
162+
ssf_press_button(context, BUTTON_B, 0, 90);
163+
pbf_press_dpad(context, DPAD_LEFT, 90, 20);
164+
165+
ssf_press_button(context, BUTTON_B, 0, 100);
166+
pbf_press_dpad(context, DPAD_DOWN, 100, 20);
167+
168+
BlackScreenOverWatcher exit_area(COLOR_RED, {0.282, 0.064, 0.448, 0.871});
169+
int ret = run_until<ProControllerContext>(
170+
env.console, context,
171+
[](ProControllerContext& context){
172+
pbf_press_dpad(context, DPAD_DOWN, 250, 20);
173+
pbf_wait(context, 300);
174+
},
175+
{exit_area}
176+
);
177+
context.wait_for_all_requests();
178+
if (ret != 0){
179+
env.log("Failed to exit area.", COLOR_RED);
180+
OperationFailedException::fire(
181+
ErrorReport::SEND_ERROR_REPORT,
182+
"Failed to exit area.",
183+
env.console
184+
);
185+
}
186+
else {
187+
env.log("Exited area.");
188+
}
189+
}
190+
191+
void ShinyHuntMew::program(SingleSwitchProgramEnvironment& env, ProControllerContext& context){
192+
ShinyHuntMew_Descriptor::Stats& stats = env.current_stats<ShinyHuntMew_Descriptor::Stats>();
193+
194+
/*
195+
* Requires more precision to ensure a Mew encounter every time.
196+
* Movement is very configurable due to this.
197+
* Enter on the left side, run up and hug the grass to the edge just after the flower on the right
198+
* This but without the bike:
199+
* https://old.reddit.com/r/ShinyPokemon/comments/1c773oi/gen3_discuss_is_this_the_fastest_way_to_encounter/
200+
*/
201+
202+
while (true) {
203+
enter_mew(env, context);
204+
205+
bool legendary_shiny = handle_encounter(env.console, context, true);
206+
if (legendary_shiny) {
207+
stats.shinies++;
208+
env.update_stats();
209+
send_program_notification(env, NOTIFICATION_SHINY, COLOR_YELLOW, "Shiny found!", {}, "", env.console.video().snapshot(), true);
210+
break;
211+
}
212+
env.log("No shiny found.");
213+
flee_battle(env.console, context);
214+
215+
//Close dialog
216+
pbf_mash_button(context, BUTTON_B, 250);
217+
context.wait_for_all_requests();
218+
219+
exit_mew(env, context);
220+
221+
stats.resets++;
222+
env.update_stats();
223+
}
224+
225+
send_program_finished_notification(env, NOTIFICATION_PROGRAM_FINISH);
226+
}
227+
228+
}
229+
}
230+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/* E Shiny Mew
2+
*
3+
* From: https://github.com/PokemonAutomation/Arduino-Source
4+
*
5+
*/
6+
7+
#ifndef PokemonAutomation_PokemonRSE_ShinyHuntMew_H
8+
#define PokemonAutomation_PokemonRSE_ShinyHuntMew_H
9+
10+
#include "Common/Cpp/Options/StaticTextOption.h"
11+
#include "Common/Cpp/Options/TimeDurationOption.h"
12+
#include "CommonFramework/Notifications/EventNotificationsTable.h"
13+
#include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h"
14+
15+
namespace PokemonAutomation{
16+
namespace NintendoSwitch{
17+
namespace PokemonRSE{
18+
19+
class ShinyHuntMew_Descriptor : public SingleSwitchProgramDescriptor{
20+
public:
21+
ShinyHuntMew_Descriptor();
22+
struct Stats;
23+
virtual std::unique_ptr<StatsTracker> make_stats() const override;
24+
};
25+
26+
class ShinyHuntMew : public SingleSwitchProgramInstance{
27+
public:
28+
ShinyHuntMew();
29+
virtual void program(SingleSwitchProgramEnvironment& env, ProControllerContext& context) override;
30+
31+
virtual void start_program_border_check(
32+
CancellableScope& scope,
33+
VideoStream& stream,
34+
FeedbackType feedback_type
35+
) override{}
36+
37+
private:
38+
EventNotificationOption NOTIFICATION_SHINY;
39+
EventNotificationOption NOTIFICATION_STATUS_UPDATE;
40+
EventNotificationsOption NOTIFICATIONS;
41+
42+
SectionDividerOption m_advanced_options;
43+
44+
MillisecondsOption MEW_WAIT_TIME;
45+
MillisecondsOption DOOR_TO_GRASS_TIME;
46+
MillisecondsOption RIGHT_GRASS_1_TIME;
47+
MillisecondsOption UP_GRASS_1_TIME;
48+
MillisecondsOption RIGHT_GRASS_2_TIME;
49+
MillisecondsOption FACE_UP_TIME;
50+
51+
void enter_mew(SingleSwitchProgramEnvironment& env, ProControllerContext& context);
52+
void exit_mew(SingleSwitchProgramEnvironment& env, ProControllerContext& context);
53+
54+
};
55+
56+
}
57+
}
58+
}
59+
#endif
60+

0 commit comments

Comments
 (0)