Skip to content

Commit 39a84d5

Browse files
committed
Claim Mystery Gifts via Internet
1 parent 56199c6 commit 39a84d5

File tree

1 file changed

+102
-84
lines changed

1 file changed

+102
-84
lines changed

SerialPrograms/Source/PokemonSV/Programs/Farming/PokemonSV_ClaimMysteryGift.cpp

Lines changed: 102 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77
#include "CommonTools/Async/InferenceRoutines.h"
8+
#include "CommonTools/VisualDetectors/BlackScreenDetector.h"
89
#include "CommonFramework/Exceptions/OperationFailedException.h"
910
#include "CommonFramework/GlobalSettingsPanel.h"
1011
#include "CommonFramework/Notifications/ProgramNotifications.h"
@@ -74,20 +75,20 @@ ClaimMysteryGift::ClaimMysteryGift()
7475
{
7576
{StartingPoint::NEW_GAME, "new-game", "New Game: Start after you have selected your username and character appearance"},
7677
{StartingPoint::IN_MYSTERY_GIFT_CODE_WINDOW, "in-mystery-gift-code-window", "Start in Mystery Gift code window, with cursor on the “1” key."},
77-
{StartingPoint::DONE_TUTORIAL, "done-tutorial", "Start in game. Tutorial must be completed. All menus closed. Disconnected from internet. You need to be outside, where you can use Pokeportal."},
78+
// {StartingPoint::DONE_TUTORIAL, "done-tutorial", "Start in game. Tutorial must be completed. All menus closed. Disconnected from internet. You need to be outside, where you can use Pokeportal."},
7879
},
7980
LockMode::LOCK_WHILE_RUNNING,
8081
StartingPoint::NEW_GAME
8182
)
8283
, OBTAINING_METHOD(
8384
"<b>Method for obtaining mystery gift:",
8485
{
85-
// {ObtainingMethod::VIA_INTERNET_ALL, "via-internet-all", "Via Internet: Get all mystery gifts from the \"Get via Internet\" screen (except for the Mythical Pecha Berry)."},
86+
{ObtainingMethod::VIA_INTERNET_ALL, "via-internet-all", "Via Internet: Get all mystery gifts from the \"Get via Internet\" screen."},
8687
{ObtainingMethod::VIA_INTERNET_NONE, "via-internet-one", "Via Internet: Go to the Mystery Gift \"Get via Internet\" screen. Don't claim anything."},
8788
{ObtainingMethod::VIA_CODE, "via-code", "Via Code: Get the mystery gift based on the code entered below."},
8889
},
8990
LockMode::LOCK_WHILE_RUNNING,
90-
ObtainingMethod::VIA_INTERNET_NONE
91+
ObtainingMethod::VIA_INTERNET_ALL
9192
)
9293
, MYSTERY_GIFT_NOTE{
9394
"Ensure you are logged into a Nintendo account. This account does NOT need to have a subscription to Nintendo Switch Online."
@@ -198,77 +199,95 @@ void ClaimMysteryGift::enter_mystery_gift_via_internet_window(SingleSwitchProgra
198199
}
199200

200201

201-
// void ClaimMysteryGift::claim_internet_mystery_gift(SingleSwitchProgramEnvironment& env, ProControllerContext& context){
202-
// env.log("Claim Mystery Gifts via Internet.");
203-
// context.wait_for_all_requests();
204-
// ImageFloatBox box{0.256326, 0.099804, 0.044004, 0.616438};
205-
// GradientArrowWatcher arrow(COLOR_RED, GradientArrowType::RIGHT, box);
206-
// int ret = wait_until(
207-
// env.console, context,
208-
// Milliseconds(10 * 1000),
209-
// { arrow }
210-
// );
211-
// if (ret == 0){
212-
// env.console.log("Gradient arrow detected.");
213-
// }else{
214-
// OperationFailedException::fire(
215-
// ErrorReport::SEND_ERROR_REPORT,
216-
// "Failed to detect gradient arrow. We might not be in the Mystery Gift via Internet screen.",
217-
// env.console
218-
// );
219-
// }
220-
221-
// std::vector<double> y_position_seen;
222-
// // determine how many mystery gifts are available to claim
223-
// while(true){
224-
// context.wait_for_all_requests();
225-
// ImageFloatBox result_box;
226-
// arrow.detect(result_box, console.video().snapshot());
227-
// double current_y_pos = result_box.y;
228-
// bool seen = false;
229-
// for (double y_pos : y_position_seen){
230-
// // if difference is less than 0.02, then it's the same
231-
// if (std::abs(current_y_pos - y_pos) < 0.02){
232-
// seen = true;
233-
// break;
234-
// }
235-
// }
236-
// if (!seen){
237-
// y_position_seen.emplace_back(current_y_pos);
238-
// }else{
239-
// pbf_press_dpad(context, DPAD_DOWN, 160ms, 320ms);
240-
// }
241-
// }
242-
243-
// while(true){
244-
// context.wait_for_all_requests();
245-
// ImageFloatBox result_box;
246-
// arrow.detect(result_box, console.video().snapshot());
247-
// double y_pos = result_box.y;
248-
249-
// pbf_press_dpad(context, DPAD_DOWN, 160ms, 320ms);
250-
// // collect the mystery gift. Press A until you see the Gradient arrow again.
251-
// ret = run_until<ProControllerContext>(
252-
// env.console, context,
253-
// [&](ProControllerContext& context){
254-
// for (size_t i = 0; i < 40; i++){
255-
// pbf_press_button(context, BUTTON_A, 160ms, 1000ms);
256-
// }
257-
// },
258-
// arrow
259-
// );
260-
// if (ret < 0){
261-
// OperationFailedException::fire(
262-
// ErrorReport::SEND_ERROR_REPORT,
263-
// "Failed to detect gradient arrow. We might not be in the Mystery Gift via Internet screen.",
264-
// env.console
265-
// );
266-
// }
267-
268-
// }
269202

203+
void ClaimMysteryGift::claim_internet_mystery_gift(SingleSwitchProgramEnvironment& env, ProControllerContext& context){
204+
env.log("Claim Mystery Gifts via Internet.");
205+
context.wait_for_all_requests();
206+
ImageFloatBox box{0.256326, 0.099804, 0.044004, 0.616438};
207+
GradientArrowWatcher arrow(COLOR_RED, GradientArrowType::RIGHT, box);
208+
int ret = wait_until(
209+
env.console, context,
210+
Milliseconds(10 * 1000),
211+
{ arrow }
212+
);
213+
if (ret == 0){
214+
env.console.log("Gradient arrow detected.");
215+
}else{
216+
OperationFailedException::fire(
217+
ErrorReport::SEND_ERROR_REPORT,
218+
"Failed to detect gradient arrow. We might not be in the Mystery Gift via Internet screen.",
219+
env.console
220+
);
221+
}
270222

271-
// }
223+
// std::vector<double> y_position_seen;
224+
// double previous = -1;
225+
size_t max_attempts = 30;
226+
for (size_t i = 0; i < max_attempts; i++){
227+
context.wait_for_all_requests();
228+
// ImageFloatBox result_box;
229+
// arrow.detect(result_box, env.console.video().snapshot());
230+
// double current_y_pos = result_box.y;
231+
// if (current_y_pos < previous - 0.02){
232+
// env.console.log("We have looped back around. Stop.");
233+
// break;
234+
// }
235+
236+
// bool seen_before = false;
237+
// // check if we have seen this position before
238+
// for (double y_pos : y_position_seen){
239+
// // if difference is less than 0.02, then it's the same
240+
// env.console.log("current_y_pos: " + std::to_string(current_y_pos) + " y_pos: " + std::to_string(y_pos));
241+
// if (std::abs(current_y_pos - y_pos) < 0.02){
242+
// seen_before = true;
243+
// break;
244+
// }
245+
// }
246+
// if (seen_before){
247+
// env.console.log("We have seen this selection before, go down.");
248+
// previous = current_y_pos;
249+
// pbf_press_dpad(context, DPAD_DOWN, 160ms, 320ms);
250+
// continue;
251+
// }
252+
// env.console.log("We have NOT seen this selection before. Try to collect the Mystery Gift.");
253+
// y_position_seen.emplace_back(current_y_pos);
254+
255+
pbf_press_button(context, BUTTON_A, 30ms, 30ms);
256+
pbf_press_button(context, BUTTON_A, 160ms, 160ms); // second button press in case first one drops
257+
context.wait_for_all_requests();
258+
259+
BlackScreenWatcher detector(COLOR_RED, {0.286199, 0.221328, 0.453620, 0.205231});
260+
ret = wait_until(
261+
env.console, context,
262+
Milliseconds(1 * 1000),
263+
{detector}
264+
);
265+
if (ret == 0){
266+
env.console.log("Already received gift. Assume we have run out of mystery gifts to collect.", COLOR_ORANGE);
267+
break;
268+
}
269+
270+
// if Black screen not detected, it's likely an unclaimed gift.
271+
// collect the mystery gift. Press A until you see the Gradient arrow again.
272+
ret = run_until<ProControllerContext>(
273+
env.console, context,
274+
[&](ProControllerContext& context){
275+
for (size_t i = 0; i < 60; i++){
276+
pbf_press_button(context, BUTTON_A, 160ms, 1000ms);
277+
}
278+
},
279+
{arrow}
280+
);
281+
if (ret < 0){
282+
OperationFailedException::fire(
283+
ErrorReport::SEND_ERROR_REPORT,
284+
"Failed to detect gradient arrow. We might not be in the Mystery Gift via Internet screen.",
285+
env.console
286+
);
287+
}
288+
289+
}
290+
}
272291

273292
void ClaimMysteryGift::enter_mystery_gift_code_window(SingleSwitchProgramEnvironment& env, ProControllerContext& context, int menu_index){
274293
env.console.log("Save game, then try to enter the mystery gift window.", COLOR_YELLOW);
@@ -368,7 +387,6 @@ void ClaimMysteryGift::program(SingleSwitchProgramEnvironment& env, ProControlle
368387
// Connect controller
369388
pbf_press_button(context, BUTTON_L, 20, 20);
370389

371-
// env.console.log("Start Segment " + ALL_AUTO_STORY_SEGMENT_LIST()[get_start_segment_index()]->name(), COLOR_ORANGE);
372390

373391
if (STARTING_POINT == StartingPoint::NEW_GAME){
374392
run_autostory_until_pokeportal_unlocked(env, context);
@@ -377,8 +395,8 @@ void ClaimMysteryGift::program(SingleSwitchProgramEnvironment& env, ProControlle
377395
enter_mystery_gift_code_window(env, context, 2);
378396
enter_mystery_gift_code(env, context);
379397
}else if(OBTAINING_METHOD == ObtainingMethod::VIA_INTERNET_ALL){
380-
// enter_mystery_gift_via_internet_window(env, context, 2);
381-
// claim_internet_mystery_gift(env, context);
398+
enter_mystery_gift_via_internet_window(env, context, 2);
399+
claim_internet_mystery_gift(env, context);
382400

383401
}else if(OBTAINING_METHOD == ObtainingMethod::VIA_INTERNET_NONE){
384402
enter_mystery_gift_via_internet_window(env, context, 2);
@@ -389,18 +407,18 @@ void ClaimMysteryGift::program(SingleSwitchProgramEnvironment& env, ProControlle
389407
// only claim the mystery gift via code. not via internet
390408
enter_mystery_gift_code(env, context);
391409

392-
}else if (STARTING_POINT == StartingPoint::DONE_TUTORIAL){
410+
// }else if (STARTING_POINT == StartingPoint::DONE_TUTORIAL){
393411

394-
if (OBTAINING_METHOD == ObtainingMethod::VIA_CODE){
395-
enter_mystery_gift_code_window(env, context, 3);
396-
enter_mystery_gift_code(env, context);
397-
}else if(OBTAINING_METHOD == ObtainingMethod::VIA_INTERNET_ALL){
398-
// enter_mystery_gift_via_internet_window(env, context, 3);
412+
// if (OBTAINING_METHOD == ObtainingMethod::VIA_CODE){
413+
// enter_mystery_gift_code_window(env, context, 3);
414+
// enter_mystery_gift_code(env, context);
415+
// }else if(OBTAINING_METHOD == ObtainingMethod::VIA_INTERNET_ALL){
416+
// // enter_mystery_gift_via_internet_window(env, context, 3);
399417

400-
}else if(OBTAINING_METHOD == ObtainingMethod::VIA_INTERNET_NONE){
401-
enter_mystery_gift_via_internet_window(env, context, 3);
418+
// }else if(OBTAINING_METHOD == ObtainingMethod::VIA_INTERNET_NONE){
419+
// enter_mystery_gift_via_internet_window(env, context, 3);
402420

403-
}
421+
// }
404422
}else{
405423
throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "Unknown STARTING_POINT.");
406424
}

0 commit comments

Comments
 (0)