diff --git a/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.cpp b/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.cpp index 5c9090613..e88754a54 100644 --- a/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.cpp +++ b/SerialPrograms/Source/PokemonFRLG/PokemonFRLG_Navigation.cpp @@ -412,63 +412,83 @@ BattleResult spam_first_move(ConsoleHandle& console, ProControllerContext& conte } void flee_battle(ConsoleHandle& console, ProControllerContext& context){ + uint16_t errors = 0; + BattleMenuWatcher battle_menu(COLOR_RED); - context.wait_for_all_requests(); - int ret = run_until( - console, context, - [](ProControllerContext& context) { - pbf_wait(context, 1000ms); - pbf_mash_button(context, BUTTON_B, 9000ms); - }, - { battle_menu } - ); - if (ret < 0){ - OperationFailedException::fire( - ErrorReport::SEND_ERROR_REPORT, - "flee_battle(): Unable to detect battle menu.", - console + AdvanceBattleDialogWatcher ran_away(COLOR_YELLOW); + BlackScreenOverWatcher battle_over(COLOR_RED); + + while (true) + { + if (errors > 5){ + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "flee_battle(): Failed to flee battle after 5 attempts.", + console + ); + } + + context.wait_for_all_requests(); + int ret = run_until( + console, context, + [](ProControllerContext& context) { + pbf_wait(context, 1000ms); + pbf_mash_button(context, BUTTON_B, 9000ms); + }, + { battle_menu } ); - } + if (ret < 0) { + errors++; + console.log("flee_battle(): Failed to detect battle menu. Attempt " + std::to_string(errors) + "/5", COLOR_RED); + continue; + } - console.log("Navigate to Run."); - pbf_press_dpad(context, DPAD_RIGHT, 160ms, 160ms); - pbf_press_dpad(context, DPAD_DOWN, 160ms, 160ms); - pbf_press_button(context, BUTTON_A, 160ms, 320ms); + console.log("Navigate to Run."); + pbf_press_dpad(context, DPAD_RIGHT, 160ms, 160ms); + pbf_press_dpad(context, DPAD_DOWN, 160ms, 160ms); + pbf_press_button(context, BUTTON_A, 160ms, 320ms); - AdvanceBattleDialogWatcher ran_away(COLOR_YELLOW); - int ret2 = wait_until( - console, context, - std::chrono::seconds(5), - {{ran_away}} - ); - if (ret2 == 0){ - console.log("Running away..."); - }else{ - OperationFailedException::fire( - ErrorReport::SEND_ERROR_REPORT, - "flee_battle(): Unable to navigate to flee button.", - console + int ret2 = wait_until( + console, context, + std::chrono::seconds(5), + { {ran_away} } ); - } - BlackScreenOverWatcher battle_over(COLOR_RED); - int ret3 = run_until( - console, context, - [](ProControllerContext& context){ - pbf_press_button(context, BUTTON_A, 320ms, 640ms); - pbf_wait(context, 5000ms); + if (ret2 == 0) { + console.log("Running away..."); + } + else { + // Even though we failed to detect the "ran away" dialog, we might have still successfully fled. + // Attempt the next detections as a possible recovery. + console.log("flee_battle(): Failed to detect flee dialog.", COLOR_RED); + } + + int ret3 = run_until( + console, context, + [](ProControllerContext& context) { + pbf_press_button(context, BUTTON_A, 320ms, 640ms); + pbf_wait(context, 5000ms); + context.wait_for_all_requests(); + }, + { battle_over, battle_menu } + ); + if (ret3 == 0) { + console.log("Successfully fled the battle."); + return; + } + else if (ret3 == 1){ + errors++; + console.log("flee_battle(): Detected battle menu after attempting to flee. Attempt " + std::to_string(errors) + "/5", COLOR_RED); + continue; + } + else { + console.log("flee_battle(): failed to detect transition to overworld. Attempting to open start menu to verify successful flee..", COLOR_RED); + + open_start_menu(console, context); + close_start_menu(console, context); context.wait_for_all_requests(); - }, - { battle_over } - ); - if (ret3 == 0){ - console.log("Successfully fled the battle."); - }else{ - console.log("flee_battle(): failed to detect transition to overworld. Attempting to open start menu to verify successful flee.."); - - open_start_menu(console, context); - close_start_menu(console, context); - context.wait_for_all_requests(); + return; + } } }