Skip to content

Commit 974dc33

Browse files
author
Gin
committed
writing ThreeSegmentDudunsparceFinder
1 parent f6d29e4 commit 974dc33

File tree

5 files changed

+115
-11
lines changed

5 files changed

+115
-11
lines changed

SerialPrograms/Source/PokemonSV/Programs/Eggs/PokemonSV_EggHatcher.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,20 +120,20 @@ void EggHatcher::hatch_one_box(SingleSwitchProgramEnvironment& env, ProControlle
120120
if (num_non_egg_pokemon == 0){
121121
// nothing in this column
122122
env.log("Nothing in column " + std::to_string(column_index+1) + ".");
123-
env.console.overlay().add_log("Empty column", COLOR_WHITE);
123+
env.console.overlay().add_log("Empty column");
124124
continue;
125125
}
126126

127127
// we have only non-egg pokemon in the column
128128
// Move them back
129129
env.log("Only non-egg pokemon in column, move them back.");
130-
env.console.overlay().add_log("No egg in column", COLOR_WHITE);
130+
env.console.overlay().add_log("No egg in column");
131131
unload_one_column_from_party(env, env.console, context, NOTIFICATION_ERROR_RECOVERABLE, column_index, HAS_CLONE_RIDE_POKEMON);
132132
continue;
133133
}
134134

135135
env.log("Loaded " + std::to_string(num_eggs) + " eggs to party.");
136-
env.console.overlay().add_log("Load " + std::to_string(num_eggs) + " eggs", COLOR_WHITE);
136+
env.console.overlay().add_log("Load " + std::to_string(num_eggs) + " eggs");
137137
leave_box_system_to_overworld(env.program_info(), env.console, context);
138138

139139
auto hatched_callback = [&](uint8_t){

SerialPrograms/Source/PokemonSV/Programs/PokemonSV_Navigation.cpp

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -999,10 +999,10 @@ void enter_menu_from_overworld(const ProgramInfo& info, VideoStream& stream, Pro
999999
bool success = false;
10001000

10011001
while (true){
1002-
if (current_time() - start > std::chrono::minutes(3)){
1002+
if (current_time() - start > std::chrono::minutes(1)){
10031003
OperationFailedException::fire(
10041004
ErrorReport::SEND_ERROR_REPORT,
1005-
"enter_menu_from_overworld(): Failed to enter specified menu after 3 minutes.",
1005+
"enter_menu_from_overworld(): Failed to enter specified menu after 1 minute.",
10061006
stream
10071007
);
10081008
}
@@ -1064,6 +1064,64 @@ void enter_menu_from_overworld(const ProgramInfo& info, VideoStream& stream, Pro
10641064
}
10651065
}
10661066

1067+
void enter_menu_from_box_system(const ProgramInfo& info, VideoStream& stream, ProControllerContext& context,
1068+
int menu_index,
1069+
MenuSide side
1070+
){
1071+
WallClock start = current_time();
1072+
bool success = false;
1073+
1074+
while (true){
1075+
if (current_time() - start > std::chrono::seconds(20)){
1076+
OperationFailedException::fire(
1077+
ErrorReport::SEND_ERROR_REPORT,
1078+
"enter_menu_from_box_system(): Failed to enter specified menu after 20 seconds.",
1079+
stream
1080+
);
1081+
}
1082+
1083+
MainMenuWatcher main_menu(COLOR_RED);
1084+
context.wait_for_all_requests();
1085+
1086+
int ret = run_until<ProControllerContext>(
1087+
stream, context,
1088+
[](ProControllerContext& context){
1089+
// repeatedly pressing B and waiting for three seconds
1090+
for (int i = 0; i < 10; i++){
1091+
pbf_press_button(context, BUTTON_B, 20, 3 * TICKS_PER_SECOND);
1092+
}
1093+
},
1094+
{main_menu}
1095+
);
1096+
context.wait_for(std::chrono::milliseconds(100));
1097+
1098+
const bool fast_mode = false;
1099+
switch (ret){
1100+
case 0:
1101+
stream.log("Detected main menu.");
1102+
if (menu_index == -1){
1103+
return;
1104+
}
1105+
success = main_menu.move_cursor(info, stream, context, side, menu_index, fast_mode);
1106+
if (success == false){
1107+
OperationFailedException::fire(
1108+
ErrorReport::SEND_ERROR_REPORT,
1109+
"enter_menu_from_overworld(): Cannot move menu cursor to specified menu.",
1110+
stream
1111+
);
1112+
}
1113+
pbf_press_button(context, BUTTON_A, 20, 105);
1114+
return;
1115+
default:
1116+
OperationFailedException::fire(
1117+
ErrorReport::SEND_ERROR_REPORT,
1118+
"enter_menu_from_overworld(): No recognized state after 30 seconds.",
1119+
stream
1120+
);
1121+
}
1122+
}
1123+
}
1124+
10671125
void press_button_until_gradient_arrow(
10681126
const ProgramInfo& info,
10691127
VideoStream& stream,

SerialPrograms/Source/PokemonSV/Programs/PokemonSV_Navigation.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ void set_time_to_12am_from_home(const ProgramInfo& info, VideoStream& stream, Pr
2626
void day_skip_from_overworld(VideoStream& stream, ProControllerContext& context);
2727

2828
// Press B to return to the overworld
29-
void press_Bs_to_back_to_overworld(const ProgramInfo& info, VideoStream& stream, ProControllerContext& context, uint16_t seconds_between_b_presses = 3);
29+
void press_Bs_to_back_to_overworld(const ProgramInfo& info, VideoStream& stream, ProControllerContext& context,
30+
uint16_t seconds_between_b_presses = 3);
3031

3132
// From overworld, open map. Will change map view from rotated to fixed if not already fixed.
3233
void open_map_from_overworld(
@@ -164,14 +165,21 @@ void fly_to_overlapping_flypoint(const ProgramInfo& info, VideoStream& stream, P
164165
// throw exception if there is a fly point/pokecenter that overlaps with the player on the map
165166
void confirm_no_overlapping_flypoint(const ProgramInfo& info, VideoStream& stream, ProControllerContext& context);
166167

167-
// enter menu and move the cursor the given side, and index. then press the A button
168+
// enter menu and move the cursor to the given side and index, then press the A button (without wait for A button to press)
168169
// if menu_index is -1, return once the menu is detected.
169170
void enter_menu_from_overworld(const ProgramInfo& info, VideoStream& stream, ProControllerContext& context,
170171
int menu_index,
171172
MenuSide side = MenuSide::RIGHT,
172173
bool has_minimap = true
173174
);
174175

176+
// enter menu and move the cursor to the given side and index, then press the A button (without wait for A button to press)
177+
// if menu_index is -1, return once the menu is detected.
178+
void enter_menu_from_box_system(const ProgramInfo& info, VideoStream& stream, ProControllerContext& context,
179+
int menu_index,
180+
MenuSide side = MenuSide::RIGHT
181+
);
182+
175183
// press given button until gradient arrow appears in given box_area_to_check.
176184
void press_button_until_gradient_arrow(
177185
const ProgramInfo& info,

SerialPrograms/Source/PokemonSV/Programs/PokemonSV_ThreeSegmentDudunsparceFinder.cpp

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,30 @@
44
*
55
*/
66

7+
#include "Common/Cpp/Exceptions.h"
8+
#include "CommonFramework/Exceptions/FatalProgramException.h"
79
#include "CommonFramework/Exceptions/OperationFailedException.h"
810
#include "CommonFramework/Notifications/ProgramNotifications.h"
911
#include "CommonFramework/ProgramStats/StatsTracking.h"
1012
#include "CommonTools/StartupChecks/VideoResolutionCheck.h"
1113
#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h"
14+
#include "Pokemon/Pokemon_Strings.h"
15+
#include "PokemonSV/Programs/Boxes/PokemonSV_BoxRoutines.h"
16+
#include "PokemonSV/Programs/PokemonSV_Navigation.h"
1217
#include "PokemonSV_ThreeSegmentDudunsparceFinder.h"
1318

1419
namespace PokemonAutomation{
1520
namespace NintendoSwitch{
1621
namespace PokemonSV{
1722

23+
using namespace Pokemon;
1824

1925
ThreeSegmentDudunsparceFinder_Descriptor::ThreeSegmentDudunsparceFinder_Descriptor()
2026
: SingleSwitchProgramDescriptor(
2127
"PokemonSV:ThreeSegmentDudunsparceFinder",
22-
"Game Name", "Three-Segment Dudunsparce Finder",
28+
STRING_POKEMON + " SV", "Three-Segment Dudunsparce Finder",
2329
"ComputerControl/blob/master/Wiki/Programs/PokemonSV/ThreeSegmentDudunsparceFinder.md",
24-
"<Description of this program>.",
30+
"Check whether a box of Dunsparce contain at least one that evolves into Three-Segment Dudunsparce.",
2531
FeedbackType::REQUIRED,
2632
AllowCommandsWhenRunning::DISABLE_COMMANDS,
2733
{ControllerFeature::NintendoSwitch_ProController},
@@ -47,6 +53,13 @@ std::unique_ptr<StatsTracker> ThreeSegmentDudunsparceFinder_Descriptor::make_sta
4753

4854
ThreeSegmentDudunsparceFinder::ThreeSegmentDudunsparceFinder()
4955
: GO_HOME_WHEN_DONE(false)
56+
, HAS_CLONE_RIDE_POKEMON(
57+
"<b>Cloned Ride Legendary 2nd in Party:</b><br>"
58+
"Ride legendary cannot be cloned after patch 1.0.1. To preserve the existing clone while hatching eggs, "
59+
"place it as second in party before starting the program.</b>"
60+
"The program will skip the first row of eggs in the box as a result.",
61+
LockMode::LOCK_WHILE_RUNNING,
62+
false)
5063
, NOTIFICATION_STATUS_UPDATE("Status Update", true, false, std::chrono::seconds(3600))
5164
, NOTIFICATIONS({
5265
&NOTIFICATION_STATUS_UPDATE,
@@ -56,9 +69,28 @@ ThreeSegmentDudunsparceFinder::ThreeSegmentDudunsparceFinder()
5669
})
5770
{
5871
PA_ADD_OPTION(GO_HOME_WHEN_DONE);
72+
PA_ADD_OPTION(HAS_CLONE_RIDE_POKEMON);
5973
PA_ADD_OPTION(NOTIFICATIONS);
6074
}
6175

76+
void ThreeSegmentDudunsparceFinder::check_one_column(SingleSwitchProgramEnvironment& env, ProControllerContext& context, int column_index){
77+
enter_box_system_from_overworld(env.program_info(), env.console, context);
78+
const uint8_t expected_empty_slots_in_party = HAS_CLONE_RIDE_POKEMON ? 4 : 5;
79+
if (check_empty_slots_in_party(env.program_info(), env.console, context) != expected_empty_slots_in_party){
80+
throw_and_log<FatalProgramException>(
81+
env.console, ErrorReport::SEND_ERROR_REPORT,
82+
"Your party should have " + std::to_string(expected_empty_slots_in_party) + " " + STRING_POKEMON + ".",
83+
env.console
84+
);
85+
}
86+
87+
load_one_column_to_party(env, env.console, context, NOTIFICATION_ERROR_FATAL, column_index, HAS_CLONE_RIDE_POKEMON);
88+
const int menu_index = 0;
89+
// go to bag from box system
90+
enter_menu_from_box_system(env.program_info(), env.console, context, menu_index, MenuSide::RIGHT);
91+
context.wait_for_all_requests();
92+
// BagWatcher bag_detector(BagWatcher::FinderType::PRESENT, COLOR_GREEN);
93+
}
6294

6395
void ThreeSegmentDudunsparceFinder::program(SingleSwitchProgramEnvironment& env, ProControllerContext& context){
6496
assert_16_9_720p_min(env.logger(), env.console);
@@ -69,7 +101,10 @@ void ThreeSegmentDudunsparceFinder::program(SingleSwitchProgramEnvironment& env,
69101
pbf_press_button(context, BUTTON_L, 10, 100);
70102

71103
try{
72-
104+
for(int i = 0; i < 6; i++){
105+
check_one_column(env, context, i);
106+
break; // XXX
107+
}
73108
} catch(OperationFailedException&){
74109
stats.m_errors++;
75110
env.update_stats();

SerialPrograms/Source/PokemonSV/Programs/PokemonSV_ThreeSegmentDudunsparceFinder.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#ifndef PokemonAutomation_PokemonSV_ThreeSegmentDudunsparceFinder_H
88
#define PokemonAutomation_PokemonSV_ThreeSegmentDudunsparceFinder_H
99

10+
#include "Common/Cpp/Options/BooleanCheckBoxOption.h"
1011
#include "CommonFramework/Notifications/EventNotificationsTable.h"
1112
#include "NintendoSwitch/Options/NintendoSwitch_GoHomeWhenDoneOption.h"
1213
#include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h"
@@ -33,11 +34,13 @@ class ThreeSegmentDudunsparceFinder : public SingleSwitchProgramInstance{
3334
virtual void program(SingleSwitchProgramEnvironment& env, ProControllerContext& context) override;
3435

3536
private:
37+
void check_one_column(SingleSwitchProgramEnvironment& env, ProControllerContext& context, int column_index);
3638

3739
private:
38-
3940
GoHomeWhenDoneOption GO_HOME_WHEN_DONE;
4041

42+
BooleanCheckBoxOption HAS_CLONE_RIDE_POKEMON;
43+
4144

4245
EventNotificationOption NOTIFICATION_STATUS_UPDATE;
4346
EventNotificationsOption NOTIFICATIONS;

0 commit comments

Comments
 (0)