diff --git a/worlds/tunic/__init__.py b/worlds/tunic/__init__.py index 29dbf150125c..40b5967d4173 100644 --- a/worlds/tunic/__init__.py +++ b/worlds/tunic/__init__.py @@ -90,6 +90,9 @@ class TunicWorld(World): item_link_locations: Dict[int, Dict[str, List[Tuple[int, str]]]] = {} player_item_link_locations: Dict[str, List[Location]] + using_ut: bool # so we can check if we're using UT only once + passthrough: Dict[str, Any] + def generate_early(self) -> None: if self.options.logic_rules >= LogicRules.option_no_major_glitches: self.options.laurels_zips.value = LaurelsZips.option_true @@ -113,23 +116,28 @@ def generate_early(self) -> None: # Universal tracker stuff, shouldn't do anything in standard gen if hasattr(self.multiworld, "re_gen_passthrough"): if "TUNIC" in self.multiworld.re_gen_passthrough: - passthrough = self.multiworld.re_gen_passthrough["TUNIC"] - self.options.start_with_sword.value = passthrough["start_with_sword"] - self.options.keys_behind_bosses.value = passthrough["keys_behind_bosses"] - self.options.sword_progression.value = passthrough["sword_progression"] - self.options.ability_shuffling.value = passthrough["ability_shuffling"] - self.options.laurels_zips.value = passthrough["laurels_zips"] - self.options.ice_grappling.value = passthrough["ice_grappling"] - self.options.ladder_storage.value = passthrough["ladder_storage"] - self.options.ladder_storage_without_items = passthrough["ladder_storage_without_items"] - self.options.lanternless.value = passthrough["lanternless"] - self.options.maskless.value = passthrough["maskless"] - 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.using_ut = True + self.passthrough = self.multiworld.re_gen_passthrough["TUNIC"] + self.options.start_with_sword.value = self.passthrough["start_with_sword"] + self.options.keys_behind_bosses.value = self.passthrough["keys_behind_bosses"] + self.options.sword_progression.value = self.passthrough["sword_progression"] + self.options.ability_shuffling.value = self.passthrough["ability_shuffling"] + self.options.laurels_zips.value = self.passthrough["laurels_zips"] + self.options.ice_grappling.value = self.passthrough["ice_grappling"] + self.options.ladder_storage.value = self.passthrough["ladder_storage"] + self.options.ladder_storage_without_items = self.passthrough["ladder_storage_without_items"] + self.options.lanternless.value = self.passthrough["lanternless"] + self.options.maskless.value = self.passthrough["maskless"] + self.options.hexagon_quest.value = self.passthrough["hexagon_quest"] + self.options.entrance_rando.value = self.passthrough["entrance_rando"] + self.options.shuffle_ladders.value = self.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 - self.options.combat_logic.value = passthrough["combat_logic"] + self.options.combat_logic.value = self.passthrough["combat_logic"] + else: + self.using_ut = False + else: + self.using_ut = False @classmethod def stage_generate_early(cls, multiworld: MultiWorld) -> None: @@ -329,12 +337,10 @@ def create_regions(self) -> None: self.ability_unlocks = randomize_ability_unlocks(self.random, self.options) # stuff for universal tracker support, can be ignored for standard gen - if hasattr(self.multiworld, "re_gen_passthrough"): - if "TUNIC" in self.multiworld.re_gen_passthrough: - passthrough = self.multiworld.re_gen_passthrough["TUNIC"] - self.ability_unlocks["Pages 24-25 (Prayer)"] = passthrough["Hexagon Quest Prayer"] - self.ability_unlocks["Pages 42-43 (Holy Cross)"] = passthrough["Hexagon Quest Holy Cross"] - self.ability_unlocks["Pages 52-53 (Icebolt)"] = passthrough["Hexagon Quest Icebolt"] + if self.using_ut: + self.ability_unlocks["Pages 24-25 (Prayer)"] = self.passthrough["Hexagon Quest Prayer"] + self.ability_unlocks["Pages 42-43 (Holy Cross)"] = self.passthrough["Hexagon Quest Holy Cross"] + self.ability_unlocks["Pages 52-53 (Icebolt)"] = self.passthrough["Hexagon Quest Icebolt"] # Ladders and Combat Logic uses ER rules with vanilla connections for easier maintenance if self.options.entrance_rando or self.options.shuffle_ladders or self.options.combat_logic: diff --git a/worlds/tunic/er_scripts.py b/worlds/tunic/er_scripts.py index aa5833b4db36..ed9fc0120ddc 100644 --- a/worlds/tunic/er_scripts.py +++ b/worlds/tunic/er_scripts.py @@ -177,7 +177,7 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal logic_tricks: Tuple[bool, int, int] = (laurels_zips, ice_grappling, ladder_storage) # marking that you don't immediately have laurels - if laurels_location == "10_fairies" and not hasattr(world.multiworld, "re_gen_passthrough"): + if laurels_location == "10_fairies" and not world.using_ut: has_laurels = False shop_count = 6 @@ -191,9 +191,8 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[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() + if world.using_ut: + portal_map = portal_mapping.copy() # create separate lists for dead ends and non-dead ends for portal in portal_map: @@ -232,25 +231,24 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal plando_connections = world.seed_groups[world.options.entrance_rando.value]["plando"] # universal tracker support stuff, don't need to care about region dependency - if hasattr(world.multiworld, "re_gen_passthrough"): - if "TUNIC" in world.multiworld.re_gen_passthrough: - plando_connections.clear() - # universal tracker stuff, won't do anything in normal gen - for portal1, portal2 in world.multiworld.re_gen_passthrough["TUNIC"]["Entrance Rando"].items(): - portal_name1 = "" - portal_name2 = "" - - for portal in portal_mapping: - if portal.scene_destination() == portal1: - portal_name1 = portal.name - # connected_regions.update(add_dependent_regions(portal.region, logic_rules)) - if portal.scene_destination() == portal2: - portal_name2 = portal.name - # connected_regions.update(add_dependent_regions(portal.region, logic_rules)) - # shops have special handling - if not portal_name2 and portal2 == "Shop, Previous Region_": - portal_name2 = "Shop Portal" - plando_connections.append(PlandoConnection(portal_name1, portal_name2, "both")) + if world.using_ut: + plando_connections.clear() + # universal tracker stuff, won't do anything in normal gen + for portal1, portal2 in world.passthrough["Entrance Rando"].items(): + portal_name1 = "" + portal_name2 = "" + + for portal in portal_mapping: + if portal.scene_destination() == portal1: + portal_name1 = portal.name + # connected_regions.update(add_dependent_regions(portal.region, logic_rules)) + if portal.scene_destination() == portal2: + portal_name2 = portal.name + # connected_regions.update(add_dependent_regions(portal.region, logic_rules)) + # shops have special handling + if not portal_name2 and portal2 == "Shop, Previous Region_": + portal_name2 = "Shop Portal" + plando_connections.append(PlandoConnection(portal_name1, portal_name2, "both")) non_dead_end_regions = set() for region_name, region_info in world.er_regions.items(): @@ -362,7 +360,7 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal # if we have plando connections, our connected regions may change somewhat connected_regions = update_reachable_regions(connected_regions, traversal_reqs, has_laurels, logic_tricks) - if fixed_shop and not hasattr(world.multiworld, "re_gen_passthrough"): + if fixed_shop and not world.using_ut: portal1 = None for portal in two_plus: if portal.scene_destination() == "Overworld Redux, Windmill_": @@ -392,7 +390,7 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal fail_count = 0 while len(connected_regions) < len(non_dead_end_regions): # if this is universal tracker, just break immediately and move on - if hasattr(world.multiworld, "re_gen_passthrough"): + if world.using_ut: break # if the connected regions length stays unchanged for too long, it's stuck in a loop # should, hopefully, only ever occur if someone plandos connections poorly @@ -445,9 +443,8 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal random_object.shuffle(two_plus) # for universal tracker, we want to skip shop gen - if hasattr(world.multiworld, "re_gen_passthrough"): - if "TUNIC" in world.multiworld.re_gen_passthrough: - shop_count = 0 + if world.using_ut: + shop_count = 0 for i in range(shop_count): portal1 = two_plus.pop() @@ -462,7 +459,7 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal # connect dead ends to random non-dead ends # none of the key events are in dead ends, so we don't need to do gate_before_switch while len(dead_ends) > 0: - if hasattr(world.multiworld, "re_gen_passthrough"): + if world.using_ut: break portal1 = two_plus.pop() portal2 = dead_ends.pop() @@ -470,7 +467,7 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal # then randomly connect the remaining portals to each other # every region is accessible, so gate_before_switch is not necessary while len(two_plus) > 1: - if hasattr(world.multiworld, "re_gen_passthrough"): + if world.using_ut: break portal1 = two_plus.pop() portal2 = two_plus.pop()