77#include " CommonFramework/ProgramStats/StatsTracking.h"
88#include " CommonTools/Async/InferenceRoutines.h"
99#include " CommonFramework/Exceptions/OperationFailedException.h"
10+ #include " CommonFramework/Notifications/ProgramNotifications.h"
11+ #include " CommonFramework/VideoPipeline/VideoFeed.h"
1012#include " NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h"
1113#include " Pokemon/Pokemon_Strings.h"
14+ #include " Pokemon/Pokemon_Notification.h"
15+ #include " PokemonLZA/Inference/Boxes/PokemonLZA_BoxDetection.h"
16+ #include " PokemonLZA/Inference/Boxes/PokemonLZA_BoxInfoDetector.h"
1217#include " PokemonLZA/Inference/PokemonLZA_ButtonDetector.h"
1318#include " PokemonLZA/Inference/PokemonLZA_SelectionArrowDetector.h"
1419#include " PokemonLZA/Inference/PokemonLZA_DialogDetector.h"
20+ #include " PokemonLZA/Programs/PokemonLZA_GameEntry.h"
1521#include " PokemonLZA/Programs/PokemonLZA_MenuNavigation.h"
16- #include " PokemonLZA/Inference/Boxes/PokemonLZA_BoxDetection.h"
17- #include " PokemonLZA/Inference/Boxes/PokemonLZA_BoxInfoDetector.h"
22+ #include " NintendoSwitch/Programs/NintendoSwitch_GameEntry.h"
1823#include " PokemonLZA_AutoFossil.h"
1924
2025#include < sstream>
@@ -54,13 +59,19 @@ class AutoFossil_Descriptor::Stats : public StatsTracker{
5459public:
5560 Stats ()
5661 : fossils(m_stats[" Fossils" ])
62+ , alphas(m_stats[" Alphas" ])
63+ , shinies(m_stats[" Shinies" ])
5764 , errors(m_stats[" Errors" ])
5865 {
5966 m_display_order.emplace_back (" Fossils" );
67+ m_display_order.emplace_back (" Alphas" );
68+ m_display_order.emplace_back (" Shinies" );
6069 m_display_order.emplace_back (" Errors" , HIDDEN_IF_ZERO);
6170 }
6271
6372 std::atomic<uint64_t >& fossils;
73+ std::atomic<uint64_t >& alphas;
74+ std::atomic<uint64_t >& shinies;
6475 std::atomic<uint64_t >& errors;
6576};
6677
@@ -69,26 +80,60 @@ std::unique_ptr<StatsTracker> AutoFossil_Descriptor::make_stats() const{
6980}
7081
7182
72- AutoFossil::AutoFossil (){}
83+ AutoFossil::AutoFossil ()
84+ : NUM_BOXES(" <b>Boxes of Fossils to Revive:</b>" ,
85+ LockMode::LOCK_WHILE_RUNNING,
86+ 1 , 1 , 32
87+ )
88+ , FOUND_SHINY_OR_ALPHA(
89+ " Found Shiny or Alpha" ,
90+ true , true ,
91+ ImageAttachmentMode::JPG,
92+ {" Notifs" , " Showcase" }
93+ )
94+ , NOTIFICATION_STATUS(" Status Update" , true , false , std::chrono::seconds(3600 ))
95+ , NOTIFICATIONS({
96+ &NOTIFICATION_STATUS,
97+ &FOUND_SHINY_OR_ALPHA,
98+ &NOTIFICATION_PROGRAM_FINISH,
99+ &NOTIFICATION_ERROR_RECOVERABLE,
100+ &NOTIFICATION_ERROR_FATAL,
101+ })
102+ {
103+ PA_ADD_OPTION (STOP_ON);
104+ PA_ADD_OPTION (NUM_BOXES);
105+ PA_ADD_OPTION (NOTIFICATIONS);
106+ }
73107
74108
75109void AutoFossil::program (SingleSwitchProgramEnvironment& env, ProControllerContext& context){
76- check_fossils_in_box (env, context, 1 );
77- return ;
78-
79- // AutoFossil_Descriptor::Stats& stats = env.current_stats<AutoFossil_Descriptor::Stats>();
80- overworld_to_box_system (env.console , context);
81- return ;
110+ while (true ){
111+ size_t num_fossils_to_revive = size_t (NUM_BOXES) * 30 ;
112+ for (size_t i = 0 ; i < num_fossils_to_revive; i++){
113+ revive_one_fossil (env, context);
114+ std::ostringstream os;
115+ os << " Got Fossil " << i + 1 << " /" << num_fossils_to_revive;
116+ std::string log_str = os.str ();
117+ env.log (log_str);
118+ env.console .overlay ().add_log (log_str);
119+ }
82120
83- // Example loop structure
84- size_t num_fossils_to_revive = 3 ;
85- for (size_t i = 0 ; i < num_fossils_to_revive; i++){
86- revive_one_fossil (env, context);
87- std::ostringstream os;
88- os << " Got Fossil " << i + 1 << " /" << num_fossils_to_revive;
89- std::string log_str = os.str ();
90- env.log (log_str);
91- env.console .overlay ().add_log (log_str);
121+ overworld_to_box_system (env.console , context);
122+ for (uint8_t i = 0 ; i < NUM_BOXES; i++){
123+ bool found_match = check_fossils_in_one_box (env, context);
124+ if (found_match){
125+ return ;
126+ }
127+ if (i != NUM_BOXES - 1 ){
128+ // go to next page
129+ pbf_press_button (context, BUTTON_R, 200ms, 200ms);
130+ }
131+ }
132+ // checked all boxes, no match
133+ go_home (env.console , context);
134+ reset_game_from_home (env, env.console , context);
135+
136+ send_program_status_notification (env, NOTIFICATION_STATUS);
92137 }
93138}
94139
@@ -168,20 +213,59 @@ void AutoFossil::revive_one_fossil(SingleSwitchProgramEnvironment& env, ProContr
168213}
169214
170215// start at box system, check fossils one by one
171- void AutoFossil::check_fossils_in_box (SingleSwitchProgramEnvironment& env, ProControllerContext& context, size_t num_boxes){
216+ bool AutoFossil::check_fossils_in_one_box (SingleSwitchProgramEnvironment& env, ProControllerContext& context){
217+ AutoFossil_Descriptor::Stats& stats = env.current_stats <AutoFossil_Descriptor::Stats>();
218+
172219 uint8_t box_row = 1 , box_col = 0 ;
173220 bool next_cell_right = true ;
174221 BoxDetector box_detector (COLOR_RED, &env.console .overlay ());
175222 BoxPageInfoWatcher info_watcher (&env.console .overlay ());
176223 for (size_t i = 0 ; i < 30 ; i++){
224+ env.console .overlay ().add_log (" To cell: (" + std::to_string (box_row) + " , " + std::to_string (box_col) + " )" );
225+ box_detector.move_cursor (env.program_info (), env.console , context, box_row, box_col);
226+
177227 info_watcher.reset_state ();
178228 wait_until (env.console , context, WallClock::max (), {info_watcher});
179229
180230 std::ostringstream os;
181- os << i + 1 << " /" << (num_boxes *30 ) << " : " << info_watcher.info_str ();
231+ os << i + 1 << " /" << int (NUM_BOXES) *30 << " : " << info_watcher.info_str ();
182232 std::string log_str = os.str ();
183233 env.log (log_str);
184234 env.console .overlay ().add_log (log_str);
235+ if (info_watcher.is_alpha ()){
236+ stats.alphas ++;
237+ env.update_stats ();
238+ }
239+ if (info_watcher.is_shiny ()){
240+ stats.shinies ++;
241+ env.update_stats ();
242+ }
243+
244+ bool is_match = false ;
245+ switch (STOP_ON){
246+ case PokemonLA::StopOn::Shiny:
247+ is_match = info_watcher.is_shiny ();
248+ break ;
249+ case PokemonLA::StopOn::Alpha:
250+ is_match = info_watcher.is_alpha ();
251+ break ;
252+ case PokemonLA::StopOn::ShinyOrAlpha:
253+ is_match = info_watcher.is_shiny () || info_watcher.is_alpha ();
254+ break ;
255+ case PokemonLA::StopOn::ShinyAndAlpha:
256+ is_match = info_watcher.is_shiny () && info_watcher.is_alpha ();
257+ break ;
258+ }
259+ if (is_match){
260+ send_program_notification (
261+ env, FOUND_SHINY_OR_ALPHA,
262+ Pokemon::COLOR_STAR_SHINY,
263+ " Found " + info_watcher.info_str () + " !" ,
264+ {}, " " ,
265+ env.console .video ().snapshot (), true
266+ );
267+ return true ;
268+ }
185269
186270 if (next_cell_right){
187271 if (box_col == 5 ){
@@ -198,11 +282,8 @@ void AutoFossil::check_fossils_in_box(SingleSwitchProgramEnvironment& env, ProCo
198282 box_col--;
199283 }
200284 }
201- if (i != 29 ){
202- env.console .overlay ().add_log (" Next cell: (" + std::to_string (box_row) + " , " + std::to_string (box_col) + " )" );
203- box_detector.move_cursor (env.program_info (), env.console , context, box_row, box_col);
204- }
205285 }
286+ return false ;
206287}
207288
208289}
0 commit comments