From 639e6f9a6c089fb5d3a2f17043b08cfe2dd3fb15 Mon Sep 17 00:00:00 2001 From: espeon65536 Date: Sat, 20 Nov 2021 15:36:57 -0600 Subject: [PATCH] OoT: plando entrances --- Generate.py | 4 +-- worlds/oot/EntranceShuffle.py | 47 ++++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/Generate.py b/Generate.py index 99631165..c209b35e 100644 --- a/Generate.py +++ b/Generate.py @@ -493,7 +493,7 @@ def roll_settings(weights: dict, plando_options: typing.Set[str] = frozenset(("b handle_option(ret, game_weights, option_key, option) if "items" in plando_options: ret.plando_items = roll_item_plando(world_type, game_weights) - if ret.game == "Minecraft": + if ret.game == "Minecraft" or ret.game == "Ocarina of Time": # bad hardcoded behavior to make this work for now ret.plando_connections = [] if "connections" in plando_options: @@ -503,7 +503,7 @@ def roll_settings(weights: dict, plando_options: typing.Set[str] = frozenset(("b ret.plando_connections.append(PlandoConnection( get_choice("entrance", placement), get_choice("exit", placement), - get_choice("direction", placement, "both") + get_choice("direction", placement) )) elif ret.game == "A Link to the Past": roll_alttp_settings(ret, game_weights, plando_options) diff --git a/worlds/oot/EntranceShuffle.py b/worlds/oot/EntranceShuffle.py index e66193bf..d781cb56 100644 --- a/worlds/oot/EntranceShuffle.py +++ b/worlds/oot/EntranceShuffle.py @@ -443,7 +443,52 @@ def shuffle_random_entrances(ootworld): if item_tuple[1] == player: none_state.prog_items[item_tuple] = 0 - # Plando entrances? + # Plando entrances + if world.plando_connections[player]: + rollbacks = [] + all_targets = {**one_way_target_entrance_pools, **target_entrance_pools} + for conn in world.plando_connections[player]: + try: + entrance = ootworld.get_entrance(conn.entrance) + exit = ootworld.get_entrance(conn.exit) + if entrance is None: + raise EntranceShuffleError(f"Could not find entrance to plando: {conn.entrance}") + if exit is None: + raise EntranceShuffleError(f"Could not find entrance to plando: {conn.exit}") + target_region = exit.name.split(' -> ')[1] + target_parent = exit.parent_region.name + pool_type = entrance.type + matched_targets_to_region = list(filter(lambda target: target.connected_region and target.connected_region.name == target_region, + all_targets[pool_type])) + target = next(filter(lambda target: target.replaces.parent_region.name == target_parent, matched_targets_to_region)) + + replace_entrance(ootworld, entrance, target, rollbacks, locations_to_ensure_reachable, all_state, none_state) + if conn.direction == 'both' and entrance.reverse and ootworld.decouple_entrances: + replace_entrance(ootworld, entrance.reverse, target.reverse, rollbacks, locations_to_ensure_reachable, all_state, none_state) + except EntranceShuffleError as e: + raise RuntimeError(f"Failed to plando OoT entrances. Reason: {e}") + except StopIteration: + raise RuntimeError(f"Could not find entrance to plando: {conn.entrance} => {conn.exit}") + finally: + for (entrance, target) in rollbacks: + confirm_replacement(entrance, target) + + # Check placed one way entrances and trim. + # The placed entrances are already pointing at their new regions. + placed_entrances = [entrance for entrance in chain.from_iterable(one_way_entrance_pools.values()) + if entrance.replaces is not None] + replaced_entrances = [entrance.replaces for entrance in placed_entrances] + # Remove replaced entrances so we don't place two in one target. + for remaining_target in chain.from_iterable(one_way_target_entrance_pools.values()): + if remaining_target.replaces and remaining_target.replaces in replaced_entrances: + delete_target_entrance(remaining_target) + # Remove priority targets if any placed entrances point at their region(s). + for key, (regions, _) in priority_entrance_table.items(): + if key in one_way_priorities: + for entrance in placed_entrances: + if entrance.connected_region and entrance.connected_region.name in regions: + del one_way_priorities[key] + break # Place priority entrances shuffle_one_way_priority_entrances(ootworld, one_way_priorities, one_way_entrance_pools, one_way_target_entrance_pools, locations_to_ensure_reachable, all_state, none_state, retry_count=2)