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
273292void 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