diff --git a/worlds/tunic/__init__.py b/worlds/tunic/__init__.py index 9ef5800955aa..624208da3a0b 100644 --- a/worlds/tunic/__init__.py +++ b/worlds/tunic/__init__.py @@ -8,7 +8,7 @@ from .regions import tunic_regions from .er_scripts import create_er_regions from .er_data import portal_mapping -from .options import TunicOptions, EntranceRando, tunic_option_groups, tunic_option_presets +from .options import TunicOptions, EntranceRando, tunic_option_groups, tunic_option_presets, TunicPlandoConnections from worlds.AutoWorld import WebWorld, World from Options import PlandoConnection from decimal import Decimal, ROUND_HALF_UP @@ -43,7 +43,7 @@ class SeedGroup(TypedDict): logic_rules: int # logic rules value laurels_at_10_fairies: bool # laurels location value fixed_shop: bool # fixed shop value - plando: List[PlandoConnection] # consolidated list of plando connections for the seed group + plando: TunicPlandoConnections # consolidated of plando connections for the seed group class TunicWorld(World): @@ -96,13 +96,15 @@ def generate_early(self) -> None: self.options.hexagon_quest.value = passthrough["hexagon_quest"] self.options.entrance_rando.value = passthrough["entrance_rando"] self.options.shuffle_ladders.value = passthrough["shuffle_ladders"] + self.options.fixed_shop.value = self.options.fixed_shop.option_false + self.options.laurels_location.value = self.options.laurels_location.option_anywhere @classmethod def stage_generate_early(cls, multiworld: MultiWorld) -> None: tunic_worlds: Tuple[TunicWorld] = multiworld.get_game_worlds("TUNIC") for tunic in tunic_worlds: # if it's one of the options, then it isn't a custom seed group - if tunic.options.entrance_rando.value in EntranceRando.options: + if tunic.options.entrance_rando.value in EntranceRando.options.values(): continue group = tunic.options.entrance_rando.value # if this is the first world in the group, set the rules equal to its rules @@ -147,7 +149,7 @@ def stage_generate_early(cls, multiworld: MultiWorld) -> None: f"{tunic.multiworld.get_player_name(tunic.player)}'s plando " f"connection {cxn.entrance} <-> {cxn.exit}") if new_cxn: - cls.seed_groups[group]["plando"].append(cxn) + cls.seed_groups[group]["plando"].value.append(cxn) def create_item(self, name: str) -> TunicItem: item_data = item_table[name] diff --git a/worlds/tunic/er_scripts.py b/worlds/tunic/er_scripts.py index 7e022c9f3a0d..9d25137ba469 100644 --- a/worlds/tunic/er_scripts.py +++ b/worlds/tunic/er_scripts.py @@ -140,7 +140,7 @@ def pair_portals(world: "TunicWorld") -> Dict[Portal, Portal]: waterfall_plando = False # if it's not one of the EntranceRando options, it's a custom seed - if world.options.entrance_rando.value not in EntranceRando.options: + if world.options.entrance_rando.value not in EntranceRando.options.values(): seed_group = world.seed_groups[world.options.entrance_rando.value] logic_rules = seed_group["logic_rules"] fixed_shop = seed_group["fixed_shop"] @@ -162,6 +162,11 @@ def pair_portals(world: "TunicWorld") -> Dict[Portal, Portal]: portal_map.remove(portal) break + # If using Universal Tracker, restore portal_map. Could be cleaner, but it does not matter for UT even a little bit + if hasattr(world.multiworld, "re_gen_passthrough"): + if "TUNIC" in world.multiworld.re_gen_passthrough: + portal_map = portal_mapping.copy() + # create separate lists for dead ends and non-dead ends for portal in portal_map: dead_end_status = tunic_er_regions[portal.region].dead_end @@ -193,7 +198,7 @@ def pair_portals(world: "TunicWorld") -> Dict[Portal, Portal]: connected_regions.add(start_region) connected_regions = update_reachable_regions(connected_regions, traversal_reqs, has_laurels, logic_rules) - if world.options.entrance_rando.value in EntranceRando.options: + if world.options.entrance_rando.value in EntranceRando.options.values(): plando_connections = world.options.plando_connections.value else: plando_connections = world.seed_groups[world.options.entrance_rando.value]["plando"] @@ -255,7 +260,7 @@ def pair_portals(world: "TunicWorld") -> Dict[Portal, Portal]: else: # if not both, they're both dead ends if not portal2: - if world.options.entrance_rando.value not in EntranceRando.options: + if world.options.entrance_rando.value not in EntranceRando.options.values(): raise Exception(f"Tunic ER seed group {world.options.entrance_rando.value} paired a dead " "end to a dead end in their plando connections.") else: @@ -302,21 +307,21 @@ def pair_portals(world: "TunicWorld") -> Dict[Portal, Portal]: traversal_reqs.setdefault(portal1.region, dict())[portal2.region] = [] traversal_reqs.setdefault(portal2.region, dict())[portal1.region] = [] - if portal1.region == "Zig Skip Exit" or portal2.region == "Zig Skip Exit": - if portal1_dead_end or portal2_dead_end or \ - portal1.region == "Secret Gathering Place" or portal2.region == "Secret Gathering Place": - if world.options.entrance_rando.value not in EntranceRando.options: - raise Exception(f"Tunic ER seed group {world.options.entrance_rando.value} paired a dead " - "end to a dead end in their plando connections.") - else: - raise Exception(f"{player_name} paired a dead end to a dead end in their " - "plando connections.") + if (portal1.region == "Zig Skip Exit" and (portal2_dead_end or portal2.region == "Secret Gathering Place") + or portal2.region == "Zig Skip Exit" and (portal1_dead_end or portal1.region == "Secret Gathering Place")): + if world.options.entrance_rando.value not in EntranceRando.options.values(): + raise Exception(f"Tunic ER seed group {world.options.entrance_rando.value} paired a dead " + "end to a dead end in their plando connections.") + else: + raise Exception(f"{player_name} paired a dead end to a dead end in their " + "plando connections.") - if portal1.region == "Secret Gathering Place" or portal2.region == "Secret Gathering Place": + if (portal1.region == "Secret Gathering Place" and (portal2_dead_end or portal2.region == "Zig Skip Exit") + or portal2.region == "Secret Gathering Place" and (portal1_dead_end or portal1.region == "Zig Skip Exit")): # need to make sure you didn't pair this to a dead end or zig skip if portal1_dead_end or portal2_dead_end or \ portal1.region == "Zig Skip Exit" or portal2.region == "Zig Skip Exit": - if world.options.entrance_rando.value not in EntranceRando.options: + if world.options.entrance_rando.value not in EntranceRando.options.values(): raise Exception(f"Tunic ER seed group {world.options.entrance_rando.value} paired a dead " "end to a dead end in their plando connections.") else: diff --git a/worlds/tunic/options.py b/worlds/tunic/options.py index b3b6b3b96fb0..ff9872ab4807 100644 --- a/worlds/tunic/options.py +++ b/worlds/tunic/options.py @@ -173,7 +173,7 @@ class ShuffleLadders(Toggle): display_name = "Shuffle Ladders" -class TUNICPlandoConnections(PlandoConnections): +class TunicPlandoConnections(PlandoConnections): entrances = {*(portal.name for portal in portal_mapping), "Shop", "Shop Portal"} exits = {*(portal.name for portal in portal_mapping), "Shop", "Shop Portal"} @@ -198,7 +198,7 @@ class TunicOptions(PerGameCommonOptions): lanternless: Lanternless maskless: Maskless laurels_location: LaurelsLocation - plando_connections: TUNICPlandoConnections + plando_connections: TunicPlandoConnections tunic_option_groups = [