@@ -68,7 +68,7 @@ MaterialFarmerOptions::MaterialFarmerOptions(
6868 , RUN_TIME_IN_MINUTES(
6969 " <b>Run Duration:</b><br>Run the material farmer for this many minutes." ,
7070 LockMode::UNLOCK_WHILE_RUNNING,
71- 70
71+ 32
7272 )
7373// , SAVE_GAME_BEFORE_SANDWICH(
7474// "<b>Save Game before each round:</b>",
@@ -165,7 +165,14 @@ void MaterialFarmerOptions::value_changed(void* object){
165165
166166}
167167
168-
168+ // return new start time, so that minutes remaining is rounded up to a multiple of 32
169+ WallClock new_start_time_after_reset (WallClock old_start_time, uint16_t run_time_in_minutes){
170+ auto farming_time_remaining = minutes_remaining (old_start_time, std::chrono::minutes (run_time_in_minutes));
171+ // round up the time to multiple of 32 (30 minutes per sandwich, plus 2 minutes for sandwich making)
172+ size_t desired_minutes_remaining = ((farming_time_remaining.count ()/32 )+1 )*32 ;
173+ WallClock new_start_time = current_time () + std::chrono::minutes (desired_minutes_remaining) - std::chrono::minutes (run_time_in_minutes);
174+ return new_start_time;
175+ }
169176
170177
171178void run_material_farmer (
@@ -184,88 +191,128 @@ void run_material_farmer(
184191 WallClock last_sandwich_time = WallClock::min ();
185192 LetsGoHpWatcher hp_watcher (COLOR_RED);
186193
194+ // ensure we save before running the material farmer.
195+ // but no need to save if already saving prior to each sandwich
196+ if (!(options.SANDWICH_OPTIONS .enabled () && options.SANDWICH_OPTIONS .SAVE_GAME_BEFORE_SANDWICH )){
197+ save_game_from_overworld (env.program_info (), console, context);
198+ }
199+
187200 /*
188201 - Use Let's Go along the path. Fly back to pokecenter when it reaches the end of the path.
189202 - Keeping repeating this for RUN_TIME_IN_MINUTES minutes
190203 */
204+ size_t consecutive_failures = 0 ;
205+ size_t max_consecutive_failures = 15 ;
191206 while (true ){
192- // check time left on material farming
193- auto farming_time_remaining = minutes_remaining (start_time, std::chrono::minutes (options.RUN_TIME_IN_MINUTES ));
194- console.log (
195- " Time left in Material Farming: " +
196- std::to_string (farming_time_remaining.count ()) + " min" ,
197- COLOR_PURPLE
198- );
199- if (farming_time_remaining < std::chrono::minutes (0 )){
200- console.log (" Time's up. Stop the Material farming program." , COLOR_RED);
201- break ;
202- }
203-
204- // Check time left on sandwich
205- if (options.SANDWICH_OPTIONS .enabled ()){
206- auto sandwich_time_remaining = minutes_remaining (last_sandwich_time, std::chrono::minutes (options.TIME_PER_SANDWICH ));
207+ try {
208+ while (true ){
209+ // check time left on material farming
210+ auto farming_time_remaining = minutes_remaining (start_time, std::chrono::minutes (options.RUN_TIME_IN_MINUTES ));
207211 console.log (
208- " Time left on sandwich : " +
209- std::to_string (sandwich_time_remaining .count ()) + " min" ,
212+ " Time left in Material Farming : " +
213+ std::to_string (farming_time_remaining .count ()) + " min" ,
210214 COLOR_PURPLE
211- );
212- if (sandwich_time_remaining < std::chrono::minutes (0 )){
213- console.log (" Sandwich not active. Make a sandwich." );
214- last_sandwich_time = make_sandwich_material_farm (env, console, context, options, stats);
215- console.overlay ().add_log (" Sandwich made." );
216-
217- // Log time remaining in Material farming
218- farming_time_remaining = minutes_remaining (start_time, std::chrono::minutes (options.RUN_TIME_IN_MINUTES ));
219- console.log (
220- " Time left in Material Farming: " +
221- std::to_string (farming_time_remaining.count ()) + " min" ,
222- COLOR_PURPLE
223- );
224- // Log time remaining on Sandwich
225- sandwich_time_remaining = minutes_remaining (last_sandwich_time, std::chrono::minutes (options.TIME_PER_SANDWICH ));
215+ );
216+ if (farming_time_remaining < std::chrono::minutes (0 )){
217+ console.log (" Time's up. Stop the Material farming program." , COLOR_RED);
218+ return ;
219+ }
220+
221+ // Check time left on sandwich
222+ if (options.SANDWICH_OPTIONS .enabled ()){
223+ auto sandwich_time_remaining = minutes_remaining (last_sandwich_time, std::chrono::minutes (options.TIME_PER_SANDWICH ));
226224 console.log (
227225 " Time left on sandwich: " +
228226 std::to_string (sandwich_time_remaining.count ()) + " min" ,
229227 COLOR_PURPLE
230- );
228+ );
229+ if (sandwich_time_remaining < std::chrono::minutes (0 )){
230+ console.log (" Sandwich not active. Make a sandwich." );
231+ last_sandwich_time = make_sandwich_material_farm (env, console, context, options, stats);
232+ console.overlay ().add_log (" Sandwich made." );
233+
234+ // Log time remaining in Material farming
235+ farming_time_remaining = minutes_remaining (start_time, std::chrono::minutes (options.RUN_TIME_IN_MINUTES ));
236+ console.log (
237+ " Time left in Material Farming: " +
238+ std::to_string (farming_time_remaining.count ()) + " min" ,
239+ COLOR_PURPLE
240+ );
241+ // Log time remaining on Sandwich
242+ sandwich_time_remaining = minutes_remaining (last_sandwich_time, std::chrono::minutes (options.TIME_PER_SANDWICH ));
243+ console.log (
244+ " Time left on sandwich: " +
245+ std::to_string (sandwich_time_remaining.count ()) + " min" ,
246+ COLOR_PURPLE
247+ );
248+ }
231249 }
250+
251+ // heal before starting Let's go
252+ console.log (" Heal before starting Let's go" , COLOR_PURPLE);
253+ console.log (" Heal threshold: " + tostr_default (options.AUTO_HEAL_PERCENT ), COLOR_PURPLE);
254+ check_hp (env, console, context, options, hp_watcher, stats);
255+
256+ /*
257+ - Starts from pokemon center.
258+ - Flies to start position. Runs a Let's Go iteration.
259+ - Then returns to pokemon center, regardless of whether
260+ it completes the action or gets caught in a battle
261+ */
262+ run_from_battles_and_back_to_pokecenter (env, console, context, stats,
263+ [&](ProgramEnvironment& env, ConsoleHandle& console, BotBaseContext& context){
264+ // Move to starting position for Let's Go hunting path
265+ console.log (" Move to starting position for Let's Go hunting path." , COLOR_PURPLE);
266+ move_to_start_position_for_letsgo1 (console, context);
267+
268+ // run let's go while updating the HP watcher
269+ console.log (" Starting Let's Go hunting path." , COLOR_PURPLE);
270+ run_until (
271+ console, context,
272+ [&](BotBaseContext& context){
273+ run_lets_go_iteration (console, context, encounter_tracker, options.NUM_FORWARD_MOVES_PER_LETS_GO_ITERATION );
274+ },
275+ {hp_watcher}
276+ );
277+ }
278+ );
279+
280+ context.wait_for_all_requests ();
232281 }
282+ }catch (OperationFailedException& e){
283+ stats.m_errors ++;
284+ env.update_stats ();
285+ e.send_notification (env, options.NOTIFICATION_ERROR_RECOVERABLE );
233286
234- // heal before starting Let's go
235- console.log (" Heal before starting Let's go" , COLOR_PURPLE);
236- console.log (" Heal threshold: " + tostr_default (options.AUTO_HEAL_PERCENT ), COLOR_PURPLE);
237- check_hp (env, console, context, options, hp_watcher, stats);
238-
239- /*
240- - Starts from pokemon center.
241- - Flies to start position. Runs a Let's Go iteration.
242- - Then returns to pokemon center, regardless of whether
243- it completes the action or gets caught in a battle
244- */
245- run_from_battles_and_back_to_pokecenter (env, console, context, stats,
246- [&](ProgramEnvironment& env, ConsoleHandle& console, BotBaseContext& context){
247- // Move to starting position for Let's Go hunting path
248- console.log (" Move to starting position for Let's Go hunting path." , COLOR_PURPLE);
249- move_to_start_position_for_letsgo1 (console, context);
250-
251- // run let's go while updating the HP watcher
252- console.log (" Starting Let's Go hunting path." , COLOR_PURPLE);
253- run_until (
254- console, context,
255- [&](BotBaseContext& context){
256- run_lets_go_iteration (console, context, encounter_tracker, options.NUM_FORWARD_MOVES_PER_LETS_GO_ITERATION );
257- },
258- {hp_watcher}
259- );
260- }
261- );
262-
263- context.wait_for_all_requests ();
264- }
287+ // save screenshot after operation failed,
288+ // dump_snapshot(console);
289+
290+ if (options.SAVE_DEBUG_VIDEO ){
291+ // Take a video to give more context for debugging
292+ pbf_press_button (context, BUTTON_CAPTURE, 2 * TICKS_PER_SECOND, 2 * TICKS_PER_SECOND);
293+ context.wait_for_all_requests ();
294+ }
265295
296+ consecutive_failures++;
297+ if (consecutive_failures >= max_consecutive_failures){
298+ throw e;
299+ }
300+
301+ env.log (" Reset game to handle recoverable error." );
302+ reset_game (env.program_info (), console, context);
303+ stats.m_game_resets ++;
304+ env.update_stats ();
266305
306+ // update start time, so that minutes remaining is rounded up to a multiple of 32
307+ start_time = new_start_time_after_reset (start_time, options.RUN_TIME_IN_MINUTES );
308+ // also update last sandwich time
309+ last_sandwich_time = WallClock::min ();
310+ }
311+ }
267312}
268313
314+
315+
269316void check_hp (
270317 ProgramEnvironment& env,
271318 ConsoleHandle& console,
@@ -290,69 +337,20 @@ void check_hp(
290337
291338
292339
293- // start at North Province (Area 3) Pokecenter. make sandwich then go back to Pokecenter to reset position
294- // return the time that the sandwich was made
340+ // make sandwich then go back to Pokecenter to reset position
341+ // if gets caught up in a battle, try again.
295342WallClock make_sandwich_material_farm (
296343 ProgramEnvironment& env,
297344 ConsoleHandle& console,
298345 BotBaseContext& context,
299346 MaterialFarmerOptions& options,
300347 MaterialFarmerStats& stats
301348){
349+
302350 if (options.SANDWICH_OPTIONS .SAVE_GAME_BEFORE_SANDWICH ){
303351 save_game_from_overworld (env.program_info (), console, context);
304352 }
305353
306- WallClock last_sandwich_time;
307- size_t consecutive_failures = 0 ;
308- size_t max_consecutive_failures = 10 ;
309- while (true ){
310- try {
311- last_sandwich_time = try_make_sandwich_material_farm (env, console, context, options, stats);
312- break ;
313- }catch (OperationFailedException& e){
314- stats.m_errors ++;
315- env.update_stats ();
316- e.send_notification (env, options.NOTIFICATION_ERROR_RECOVERABLE );
317-
318- // save screenshot after operation failed,
319- dump_snapshot (console);
320-
321- if (options.SAVE_DEBUG_VIDEO ){
322- // Take a video to give more context for debugging
323- pbf_press_button (context, BUTTON_CAPTURE, 2 * TICKS_PER_SECOND, 2 * TICKS_PER_SECOND);
324- context.wait_for_all_requests ();
325- }
326-
327- consecutive_failures++;
328- if (consecutive_failures >= max_consecutive_failures){
329- throw OperationFailedException (
330- ErrorReport::SEND_ERROR_REPORT, console,
331- " Failed to make sandwich " + std::to_string (max_consecutive_failures) + " times in a row." ,
332- true
333- );
334- }
335-
336- env.log (" Failed to make sandwich. Reset game to handle recoverable error." );
337- reset_game (env.program_info (), console, context);
338- stats.m_game_resets ++;
339- env.update_stats ();
340- }
341- }
342-
343- return last_sandwich_time;
344- }
345-
346-
347- // make sandwich then go back to Pokecenter to reset position
348- // if gets caught up in a battle, try again.
349- WallClock try_make_sandwich_material_farm (
350- ProgramEnvironment& env,
351- ConsoleHandle& console,
352- BotBaseContext& context,
353- MaterialFarmerOptions& options,
354- MaterialFarmerStats& stats
355- ){
356354 WallClock last_sandwich_time = WallClock::min ();
357355 while (last_sandwich_time == WallClock::min ()){
358356 run_from_battles_and_back_to_pokecenter (env, console, context, stats,
@@ -373,7 +371,7 @@ WallClock try_make_sandwich_material_farm(
373371
374372 // make sandwich
375373 picnic_from_overworld (env.program_info (), console, context);
376- pbf_move_left_joystick (context, 128 , 0 , 30 , 40 );
374+ pbf_move_left_joystick (context, 128 , 0 , 100 , 40 ); // walk forward to picnic table
377375 enter_sandwich_recipe_list (env.program_info (), console, context);
378376 make_sandwich_option (env, console, context, options.SANDWICH_OPTIONS );
379377 last_sandwich_time = current_time ();
@@ -468,7 +466,9 @@ void move_to_start_position_for_letsgo1(
468466 pbf_move_left_joystick (context, 128 , 0 , 300 , 10 );
469467
470468 // look right, towards the start position
471- pbf_move_right_joystick (context, 255 , 128 , 130 , 10 );
469+ DirectionDetector direction;
470+ direction.change_direction (console, context, 5.76 );
471+ // pbf_move_right_joystick(context, 255, 128, 130, 10);
472472 pbf_move_left_joystick (context, 128 , 0 , 10 , 10 );
473473
474474 // get on ride
@@ -498,7 +498,8 @@ void move_to_start_position_for_letsgo1(
498498 pbf_press_button (context, BUTTON_B, 50 , 10 );
499499
500500 // look right
501- pbf_move_right_joystick (context, 255 , 128 , 20 , 10 );
501+ // pbf_move_right_joystick(context, 255, 128, 20, 10);
502+ direction.change_direction (console, context, 5.46 );
502503
503504 // move forward slightly
504505 pbf_move_left_joystick (context, 128 , 0 , 50 , 10 );
0 commit comments