From b559422450758d4360eea552f5305d1c20ba61a6 Mon Sep 17 00:00:00 2001 From: Scipio Wright Date: Fri, 9 Aug 2024 20:59:03 -0400 Subject: [PATCH] Make seed groups in decoupled with overlapping but not fully overlapped plando connections interact nicely without messing with what the entrances look like in the spoiler log --- worlds/tunic/__init__.py | 15 ++++++++------- worlds/tunic/er_scripts.py | 17 ++++++++++++++--- worlds/tunic/options.py | 2 +- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/worlds/tunic/__init__.py b/worlds/tunic/__init__.py index 96361a9489..8280806a7f 100644 --- a/worlds/tunic/__init__.py +++ b/worlds/tunic/__init__.py @@ -57,7 +57,7 @@ class SeedGroup(TypedDict): laurels_at_10_fairies: bool # laurels location value entrance_layout: int # entrance layout value has_decoupled_enabled: bool # for checking that players don't have conflicting options - plando: TunicPlandoConnections # consolidated plando connections for the seed group + plando: List[PlandoConnection] # consolidated plando connections for the seed group class TunicWorld(World): @@ -90,7 +90,7 @@ class TunicWorld(World): self.er_regions = tunic_er_regions.copy() if self.options.plando_connections: for index, cxn in enumerate(self.options.plando_connections): - # flip any that are pointing to exit to point to entrance so I don't have to deal with it + # flip any that are pointing to exit to point to entrance so that I don't have to deal with it if self.options.decoupled and cxn.direction == "exit": replacement = PlandoConnection(entrance=cxn.exit, exit=cxn.entrance, direction="entrance", percentage=cxn.percentage) self.options.plando_connections.value.remove(cxn) @@ -155,11 +155,12 @@ class TunicWorld(World): laurels_at_10_fairies=tunic.options.laurels_location == LaurelsLocation.option_10_fairies, entrance_layout=tunic.options.entrance_layout.value, has_decoupled_enabled=bool(tunic.options.decoupled), - plando=tunic.options.plando_connections) + plando=tunic.options.plando_connections.value.copy()) continue # I feel that syncing this one is worse than erroring out if bool(tunic.options.decoupled) != cls.seed_groups[group]["has_decoupled_enabled"]: - raise OptionError(f"TUNIC: All players in the seed group {group} must have Decoupled either enabled or disabled.") + raise OptionError(f"TUNIC: All players in the seed group {group} must " + f"have Decoupled either enabled or disabled.") # off is more restrictive if not tunic.options.laurels_zips: cls.seed_groups[group]["laurels_zips"] = False @@ -197,8 +198,8 @@ class TunicWorld(World): new_cxn = False # if the group's was one-way and the player's was two-way, we replace the group's now if player_cxn.direction == "both" and group_cxn.direction == "entrance": - cls.seed_groups[group]["plando"].value.remove(group_cxn) - cls.seed_groups[group]["plando"].value.insert(index, player_cxn) + cls.seed_groups[group]["plando"].remove(group_cxn) + cls.seed_groups[group]["plando"].insert(index, player_cxn) break is_mismatched = ( player_cxn.entrance == group_cxn.entrance and player_cxn.exit != group_cxn.exit @@ -217,7 +218,7 @@ class TunicWorld(World): f"{tunic.multiworld.get_player_name(tunic.player)}'s plando " f"connection {player_cxn.entrance} {player_dir} {player_cxn.exit}") if new_cxn: - cls.seed_groups[group]["plando"].value.append(player_cxn) + cls.seed_groups[group]["plando"].append(player_cxn) def create_item(self, name: str, classification: ItemClassification = None) -> TunicItem: item_data = item_table[name] diff --git a/worlds/tunic/er_scripts.py b/worlds/tunic/er_scripts.py index e36aeda0b1..04caaf6dc6 100644 --- a/worlds/tunic/er_scripts.py +++ b/worlds/tunic/er_scripts.py @@ -352,9 +352,22 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal two_plus2 = two_plus if plando_connections: + if decoupled: + modified_plando_connections = plando_connections.copy() + for index, cxn in enumerate(modified_plando_connections): + # it's much easier if we split both-direction portals into two one-ways in decoupled + if cxn.direction == "both": + replacement1 = PlandoConnection(cxn.entrance, cxn.exit, "entrance") + replacement2 = PlandoConnection(cxn.exit, cxn.entrance, "entrance") + modified_plando_connections.remove(cxn) + modified_plando_connections.insert(index, replacement1) + modified_plando_connections.append(replacement2) + else: + modified_plando_connections = plando_connections + connected_shop_portal1s: Set[int] = set() connected_shop_portal2s: Set[int] = set() - for connection in plando_connections: + for connection in modified_plando_connections: p_entrance = connection.entrance p_exit = connection.exit # if you plando secret gathering place, need to know that during portal pairing @@ -457,8 +470,6 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal if decoupled: # we turn any plando that uses "exit" to use "entrance" instead traversal_reqs.setdefault(portal1.region, dict())[get_portal_outlet_region(portal2, world)] = [] - if connection.direction == "both": - traversal_reqs.setdefault(portal2.region, dict())[get_portal_outlet_region(portal1, world)] = [] # outside decoupled, we want to use what we were doing before decoupled got added else: # update the traversal chart to say you can get from portal1's region to portal2's and vice versa diff --git a/worlds/tunic/options.py b/worlds/tunic/options.py index 5203b00958..275df7078c 100644 --- a/worlds/tunic/options.py +++ b/worlds/tunic/options.py @@ -337,7 +337,7 @@ tunic_option_groups = [ EntranceRando, EntranceLayout, Decoupled, - PlandoConnections, + TunicPlandoConnections, ]), ]