diff --git a/SerialPrograms/Source/PokemonSV/Programs/Eggs/PokemonSV_EggAutonomous.cpp b/SerialPrograms/Source/PokemonSV/Programs/Eggs/PokemonSV_EggAutonomous.cpp index 14b2799130..8ae5fe2919 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/Eggs/PokemonSV_EggAutonomous.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/Eggs/PokemonSV_EggAutonomous.cpp @@ -93,6 +93,15 @@ EggAutonomous::EggAutonomous() LockMode::LOCK_WHILE_RUNNING, true ) + , LOCATION( + "Location:
The location to hatch eggs.", + { + {EggAutoLocation::ZeroGate, "zero-gate", "Zero Gate"}, + {EggAutoLocation::NorthLighthouse, "north-lighthouse", "North Province (Area Three) Lighthouse"} + }, + LockMode::LOCK_WHILE_RUNNING, + EggAutoLocation::ZeroGate + ) , MAX_KEEPERS( "Max Keepers:
Stop the program after keeping this many " + STRING_POKEMON + ". " "The program will put them into a box neighboring the current box.", @@ -173,6 +182,7 @@ EggAutonomous::EggAutonomous() PA_ADD_OPTION(GO_HOME_WHEN_DONE); PA_ADD_OPTION(LANGUAGE); PA_ADD_OPTION(EGG_SANDWICH); + PA_ADD_OPTION(LOCATION); PA_ADD_OPTION(MAX_KEEPERS); PA_ADD_OPTION(AUTO_SAVING); PA_ADD_OPTION(KEEP_BOX_LOCATION); @@ -312,7 +322,12 @@ void EggAutonomous::program(SingleSwitchProgramEnvironment& env, ProControllerCo int EggAutonomous::fetch_eggs_full_routine(SingleSwitchProgramEnvironment& env, ProControllerContext& context){ auto& stats = env.current_stats(); - picnic_at_zero_gate(env.program_info(), env.console, context); + if (LOCATION == EggAutoLocation::ZeroGate) { + picnic_at_zero_gate(env.program_info(), env.console, context); + } else { + pbf_press_button(context, BUTTON_L, 50, 40); + picnic_from_overworld(env.program_info(), env.console, context); + } // Now we are at picnic. We are at one end of picnic table while the egg basket is at the other end bool can_make_sandwich = eat_egg_sandwich_at_picnic(env, env.console, context, EGG_SANDWICH.EGG_SANDWICH_TYPE, LANGUAGE); @@ -338,7 +353,13 @@ int EggAutonomous::fetch_eggs_full_routine(SingleSwitchProgramEnvironment& env, leave_picnic(env.program_info(), env.console, context); // Reset position to flying spot: - reset_position_to_flying_spot(env, context); + if (LOCATION == EggAutoLocation::ZeroGate) { + reset_position_to_flying_spot(env, context); + } else { + //Lighthouse: We haven't moved much so just fly. + open_map_from_overworld(env.program_info(), env.console, context); + fly_to_overworld_from_map(env.program_info(), env.console, context); + } return picnic_party_to_hatch_party(env, context); } @@ -436,8 +457,16 @@ void EggAutonomous::hatch_eggs_full_routine(SingleSwitchProgramEnvironment& env, stats.m_hatched++; env.update_stats(); }; - hatch_eggs_at_zero_gate(env.program_info(), env.console, context, (uint8_t)num_eggs_in_party, hatched_callback); - reset_position_to_flying_spot(env, context); + if (LOCATION == EggAutoLocation::ZeroGate) { + hatch_eggs_at_zero_gate(env.program_info(), env.console, context, (uint8_t)num_eggs_in_party, hatched_callback); + reset_position_to_flying_spot(env, context); + } else { + hatch_eggs_at_area_three_lighthouse(env.program_info(), env.console, context, (uint8_t)num_eggs_in_party, hatched_callback); + reset_position_to_flying_spot(env, context); + //Clear spawns - over time floette/vivillon drift over past the fence (usually aroudn the 3rd batch) + picnic_from_overworld(env.program_info(), env.console, context); + leave_picnic(env.program_info(), env.console, context); + } enter_box_system_from_overworld(env.program_info(), env.console, context); @@ -647,7 +676,12 @@ bool EggAutonomous::move_pokemon_to_keep(SingleSwitchProgramEnvironment& env, Pr void EggAutonomous::reset_position_to_flying_spot(SingleSwitchProgramEnvironment& env, ProControllerContext& context){ // Use map to fly back to the flying spot open_map_from_overworld(env.program_info(), env.console, context); - pbf_move_left_joystick(context, 128, 160, 20, 50); + if (LOCATION == EggAutoLocation::ZeroGate) { + pbf_move_left_joystick(context, 128, 160, 20, 50); + } else { //lighthouse + pbf_move_left_joystick(context, 130, 0, 150ms, 50ms); + pbf_press_button(context, BUTTON_ZL, 40, 100); + } fly_to_overworld_from_map(env.program_info(), env.console, context); } diff --git a/SerialPrograms/Source/PokemonSV/Programs/Eggs/PokemonSV_EggAutonomous.h b/SerialPrograms/Source/PokemonSV/Programs/Eggs/PokemonSV_EggAutonomous.h index d0c41e1eeb..69de407f5c 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/Eggs/PokemonSV_EggAutonomous.h +++ b/SerialPrograms/Source/PokemonSV/Programs/Eggs/PokemonSV_EggAutonomous.h @@ -76,6 +76,13 @@ class EggAutonomous : public SingleSwitchProgramInstance{ GoHomeWhenDoneOption GO_HOME_WHEN_DONE; OCR::LanguageOCROption LANGUAGE; + + enum class EggAutoLocation{ + ZeroGate, + NorthLighthouse, + }; + EnumDropdownOption LOCATION; + SimpleIntegerOption MAX_KEEPERS; enum class AutoSave{ diff --git a/SerialPrograms/Source/PokemonSV/Programs/Eggs/PokemonSV_EggRoutines.cpp b/SerialPrograms/Source/PokemonSV/Programs/Eggs/PokemonSV_EggRoutines.cpp index 8a9b958e7e..f65c59a122 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/Eggs/PokemonSV_EggRoutines.cpp +++ b/SerialPrograms/Source/PokemonSV/Programs/Eggs/PokemonSV_EggRoutines.cpp @@ -619,6 +619,70 @@ void hatch_eggs_at_zero_gate( } // end hatching each egg } +void hatch_eggs_at_area_three_lighthouse( + const ProgramInfo& info, + VideoStream& stream, ProControllerContext& context, + uint8_t num_eggs_in_party, + std::function egg_hatched_callback) +{ + bool got_off_ramp = false; + for(uint8_t egg_idx = 0; egg_idx < num_eggs_in_party; egg_idx++){ + stream.log("Hatching egg " + std::to_string(egg_idx+1) + "/" + std::to_string(num_eggs_in_party) + "."); + stream.overlay().add_log("Hatching egg " + std::to_string(egg_idx+1) + "/" + std::to_string(num_eggs_in_party), COLOR_BLUE); + + // Orient camera to look at same direction as player character + // This is needed because when save-load the game, the camera is reset + // to this location. + pbf_press_button(context, BUTTON_L, 50, 40); + + context.wait_for_all_requests(); + + if (got_off_ramp == false){ + AdvanceDialogWatcher dialog(COLOR_RED); + // first, navigate to a clear area in the team star base for circling motions + int ret = run_until( + stream, context, + [&](ProControllerContext& context){ + if (egg_idx == 0){ + //Run forward a bit + pbf_move_left_joystick(context, 128, 0, 150, 20); + //Face at an angle, to avoid the tent to the left + pbf_move_left_joystick(context, 0, 0, 50, 50); + //Get on your mount + pbf_press_button(context, BUTTON_L, 50, 40); + pbf_press_button(context, BUTTON_PLUS, 50, 100); + //Go in deep, spawns outside the fence like to come in otherwise + pbf_move_left_joystick(context, 128, 0, 750, 0); + pbf_move_left_joystick(context, 0, 0, 50, 50); + pbf_press_button(context, BUTTON_L, 50, 40); + pbf_move_left_joystick(context, 128, 0, 550, 0); + } + }, + {dialog} + ); + if (ret == 0){ + // egg hatching when going off ramp: + handle_egg_hatching(info, stream, context, num_eggs_in_party, egg_idx, egg_hatched_callback); + + stream.log("Reset location by flying back to lighthouse."); + // Use map to fly back to the flying spot + open_map_from_overworld(info, stream, context); + pbf_move_left_joystick(context, 200, 0, 20, 50); + fly_to_overworld_from_map(info, stream, context); + continue; + } + + got_off_ramp = true; + stream.log("Got off ramp"); + } + + // Circular motions: + do_egg_cycle_motion(info, stream, context); + + handle_egg_hatching(info, stream, context, num_eggs_in_party, egg_idx, egg_hatched_callback); + } // end hatching each egg +} + void hatch_eggs_anywhere( const ProgramInfo& info, VideoStream& stream, ProControllerContext& context, diff --git a/SerialPrograms/Source/PokemonSV/Programs/Eggs/PokemonSV_EggRoutines.h b/SerialPrograms/Source/PokemonSV/Programs/Eggs/PokemonSV_EggRoutines.h index 9727b78f2c..a4bef8f465 100644 --- a/SerialPrograms/Source/PokemonSV/Programs/Eggs/PokemonSV_EggRoutines.h +++ b/SerialPrograms/Source/PokemonSV/Programs/Eggs/PokemonSV_EggRoutines.h @@ -76,6 +76,18 @@ void hatch_eggs_at_zero_gate( std::function egg_hatched_callback = nullptr ); +// Start at North Province (Area Three) Lighthouse flying spot, go in circles in Ruchbah (fairy) Squad's base to hatch eggs. +// Switch 2 only, this is an alternate egg hatch spot as Zero Gate now has spawns in the way. +// Switch 1 is untested in this location but the area is extremely laggy. +// This is a minor modification to hatch_eggs_at_zero_gate +// `egg_hatched_callback` will be called after each egg hatched, with egg index (0-indexed) +void hatch_eggs_at_area_three_lighthouse( + const ProgramInfo& info, + VideoStream& stream, ProControllerContext& context, + uint8_t num_eggs_in_party, + std::function egg_hatched_callback = nullptr +); + // From overworld, go in circles to hatch eggs. // `egg_hatched_callback` will be called after each egg hatched, with egg index (0-indexed) // `already_on_ride`: whether the player character is on ride when starting the function.