-
Notifications
You must be signed in to change notification settings - Fork 106
Expand file tree
/
Copy pathPokemonSwSh_MaxLair_BossFinder.cpp
More file actions
224 lines (184 loc) · 7.1 KB
/
PokemonSwSh_MaxLair_BossFinder.cpp
File metadata and controls
224 lines (184 loc) · 7.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
/* Max Lair (Boss Finder)
*
* From: https://github.com/PokemonAutomation/
*
*/
#include "Common/Compiler.h"
#include "Common/Cpp/Exceptions.h"
#include "CommonFramework/Notifications/ProgramNotifications.h"
#include "CommonTools/StartupChecks/VideoResolutionCheck.h"
#include "NintendoSwitch/NintendoSwitch_Settings.h"
#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h"
#include "Pokemon/Pokemon_Strings.h"
#include "PokemonSwSh/Programs/PokemonSwSh_GameEntry.h"
#include "Program/PokemonSwSh_MaxLair_Run_Adventure.h"
#include "PokemonSwSh_MaxLair_BossFinder.h"
namespace PokemonAutomation{
namespace NintendoSwitch{
namespace PokemonSwSh{
using namespace MaxLairInternal;
MaxLairBossFinder_Descriptor::MaxLairBossFinder_Descriptor()
: MultiSwitchProgramDescriptor(
"PokemonSwSh:MaxLair-BossFinder",
STRING_POKEMON + " SwSh", "Max Lair - Boss Finder",
"Programs/PokemonSwSh/MaxLair-BossFinder.html",
"Auto Max Lair 2.0 - Run adventures until you find the boss you want. Once you find your boss, switch to the other programs to shiny hunt it.",
ProgramControllerClass::StandardController_NoRestrictions,
FeedbackType::REQUIRED,
AllowCommandsWhenRunning::DISABLE_COMMANDS,
1, 4, 1
)
{}
std::unique_ptr<StatsTracker> MaxLairBossFinder_Descriptor::make_stats() const{
return std::unique_ptr<StatsTracker>(new Stats());
}
class MaxLairBossFinder_ConsoleOptions : public ConsoleSpecificOptions{
public:
MaxLairBossFinder_ConsoleOptions(std::string label, const LanguageSet& languages, bool host)
: ConsoleSpecificOptions(std::move(label), languages, host)
, normal_ball(
"<b>Normal Ball:</b> Ball for catching non-boss " + STRING_POKEMON + ".",
LockMode::LOCK_WHILE_RUNNING,
"poke-ball"
)
{
PA_ADD_OPTION(normal_ball);
}
PokemonBallSelectOption normal_ball;
};
class MaxLairBossFinder_ConsoleFactory : public ConsoleSpecificOptionsFactory{
public:
virtual std::unique_ptr<ConsoleSpecificOptions> make(
std::string label,
const LanguageSet& languages,
bool host
) const override{
return std::unique_ptr<ConsoleSpecificOptions>(new MaxLairBossFinder_ConsoleOptions(std::move(label), languages, host));
}
};
MaxLairBossFinder::MaxLairBossFinder()
: MultiSwitchProgramInstance({"Notifs", "LiveHost"})
, GO_HOME_WHEN_DONE(false)
, CONSOLES(MaxLairBossFinder_ConsoleFactory())
, NOTIFICATION_STATUS("Status Update", true, false)
, NOTIFICATION_SHINY("Shiny Catch", true, true, ImageAttachmentMode::JPG, {"Notifs", "Showcase"})
, NOTIFICATIONS({
&HOSTING.NOTIFICATIONS.NOTIFICATION,
&NOTIFICATION_STATUS,
&NOTIFICATION_SHINY,
&NOTIFICATION_PROGRAM_FINISH,
&NOTIFICATION_ERROR_FATAL,
})
{
PA_ADD_OPTION(START_LOCATION);
PA_ADD_OPTION(GO_HOME_WHEN_DONE);
PA_ADD_OPTION(CONSOLES);
PA_ADD_OPTION(BOSS_LIST);
PA_ADD_OPTION(HOSTING);
PA_ADD_OPTION(TOUCH_DATE_INTERVAL);
PA_ADD_OPTION(NOTIFICATIONS);
}
std::string MaxLairBossFinder::check_validity() const{
std::string error = MultiSwitchProgramInstance::check_validity();
if (!error.empty()){
return error;
}
size_t active_consoles = CONSOLES.active_consoles();
error = CONSOLES.HOST.check_validity(active_consoles);
if (!error.empty()){
return error;
}
error = HOSTING.check_validity(active_consoles);
if (!error.empty()){
return error;
}
return std::string();
}
void MaxLairBossFinder::update_active_consoles(size_t switch_count){
CONSOLES.set_active_consoles(switch_count);
}
class EndBattleDecider_BossFinder : public EndBattleDecider{
public:
EndBattleDecider_BossFinder(const Consoles& consoles, const BossActionTable& boss_list)
: m_consoles(consoles)
, m_boss_list(boss_list)
{}
virtual const std::string& normal_ball(
size_t console_index
) const override{
return console(console_index).normal_ball.slug();
}
virtual const std::string& boss_ball(
size_t console_index, const std::string& boss_slug
) const override{
return get_filter(boss_slug).ball.slug();
}
virtual CaughtScreenAction end_adventure_action(
size_t console_index, const std::string& boss_slug,
const PathStats& path_stats,
bool any_shiny, bool boss_is_shiny
) const override{
if (boss_slug.empty()){
return CaughtScreenAction::TAKE_NON_BOSS_SHINY_AND_CONTINUE;
}
switch (get_filter(boss_slug).action){
case BossAction::CATCH_AND_STOP_PROGRAM:
return CaughtScreenAction::STOP_PROGRAM;
case BossAction::CATCH_AND_STOP_IF_SHINY:
return boss_is_shiny
? CaughtScreenAction::STOP_PROGRAM
: CaughtScreenAction::TAKE_NON_BOSS_SHINY_AND_CONTINUE;
}
throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "Invalid enum.");
}
virtual bool is_in_save_list(const std::string& boss_slug) const override {
return get_filter(boss_slug).save_on_the_go;
}
private:
const BossActionRow& get_filter(const std::string& boss_slug) const{
for (const StaticTableRow* row : m_boss_list.table()){
const BossActionRow& filter = static_cast<const BossActionRow&>(*row);
if (boss_slug == filter.slug()){
return filter;
}
}
throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "Unrecognized boss slug: " + boss_slug);
}
private:
const MaxLairBossFinder_ConsoleOptions& console(size_t index) const{
return static_cast<const MaxLairBossFinder_ConsoleOptions&>(m_consoles[index]);
}
const Consoles& m_consoles;
const BossActionTable& m_boss_list;
};
void MaxLairBossFinder::program(MultiSwitchProgramEnvironment& env, CancellableScope& scope){
size_t host_index = CONSOLES.HOST.current_value();
if (host_index >= env.consoles.size()){
throw UserSetupError(env.logger(), "Invalid Host Switch");
}
env.run_in_parallel(scope, [&](ConsoleHandle& console, ProControllerContext& context){
assert_16_9_720p_min(console, console);
if (START_LOCATION.start_in_grip_menu()){
grip_menu_connect_go_home(context);
resume_game_no_interact(console, context, ConsoleSettings::instance().TOLERATE_SYSTEM_UPDATE_MENU_FAST);
}else{
pbf_press_button(context, BUTTON_B, 40ms, 40ms);
}
});
EndBattleDecider_BossFinder decider(CONSOLES, BOSS_LIST);
loop_adventures(
env, scope, CONSOLES,
host_index, 0,
decider,
GO_HOME_WHEN_DONE,
HOSTING,
TOUCH_DATE_INTERVAL,
NOTIFICATION_STATUS,
NOTIFICATION_SHINY
);
env.update_stats();
send_program_finished_notification(env, NOTIFICATION_PROGRAM_FINISH);
}
}
}
}