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.