diff --git a/worlds/oot_soh/EntranceShuffle.py b/worlds/oot_soh/EntranceShuffle.py new file mode 100644 index 000000000000..1d4f170e7225 --- /dev/null +++ b/worlds/oot_soh/EntranceShuffle.py @@ -0,0 +1,249 @@ +from typing import TYPE_CHECKING, Callable +from BaseClasses import Location, Region, Entrance +from .Enums import SOHBossEntranceExitNames, SOHBossEntranceNames, SOHDungeonExitNames, SOHDungeonEntranceNames, Locations, SOHEntranceGroups, Regions, SOHBossWarpEntranceNames, SOHGrottoEntranceNames, SOHGrottoExitNames, SOHInteriorEntranceNames, SOHInteriorExitNames, SOHSpecialInteriorEntranceNames, SOHSpecialInteriorExitNames, SOHThievesHideoutEntranceNames, SOHOverworldEntranceNames +from .Locations import SohLocation +from entrance_rando import disconnect_entrance_for_randomization, randomize_entrances, bake_target_group_lookup, EntranceRandomizationError +from entrance_rando import ERPlacementState, Entrance +from .LogicHelpers import rule_wrapper +from worlds.generic.Rules import set_rule +from enum import StrEnum + +if TYPE_CHECKING: + from . import SohWorld + +# This is only needed for One Way entrances +entrance_matching = { + SOHBossEntranceNames.DEKU_TREE_BOSS_ENTRANCE: SOHBossEntranceExitNames.DEKU_TREE_BOSS_EXIT, + SOHBossEntranceNames.DODONGOS_CAVERN_BOSS_ENTRANCE: SOHBossEntranceExitNames.DODONGOS_CAVERN_BOSS_EXIT, + SOHBossEntranceNames.JABU_JABUS_BOSS_ENTRANCE: SOHBossEntranceExitNames.JABU_JABUS_BOSS_EXIT, + SOHBossEntranceNames.FOREST_TEMPLE_BOSS_ENTRANCE: SOHBossEntranceExitNames.FOREST_TEMPLE_BOSS_EXIT, + SOHBossEntranceNames.FIRE_TEMPLE_BOSS_ENTRANCE: SOHBossEntranceExitNames.FIRE_TEMPLE_BOSS_EXIT, + SOHBossEntranceNames.WATER_TEMPLE_BOSS_ENTRANCE: SOHBossEntranceExitNames.WATER_TEMPLE_BOSS_EXIT, + SOHBossEntranceNames.SHADOW_TEMPLE_BOSS_ENTRANCE: SOHBossEntranceExitNames.SHADOW_TEMPLE_BOSS_EXIT, + SOHBossEntranceNames.SPIRIT_TEMPLE_BOSS_ENTRANCE: SOHBossEntranceExitNames.SPIRIT_TEMPLE_BOSS_EXIT, + SOHOverworldEntranceNames.LAKE_HYLIA_RIVER_ENTRANCE: SOHOverworldEntranceNames.LAKE_HYLIA_RIVER_EXIT +} + + +default_group_lookup = { + SOHEntranceGroups.DUNGEON_ENTRANCE: [SOHEntranceGroups.DUNGEON_ENTRANCE], + SOHEntranceGroups.BOSS_ENTRANCE: [SOHEntranceGroups.BOSS_ENTRANCE], + SOHEntranceGroups.GROTTO: [SOHEntranceGroups.GROTTO], + SOHEntranceGroups.INTERIOR: [SOHEntranceGroups.INTERIOR], + SOHEntranceGroups.THIEVES_HIDEOUT_ENTRANCE: [SOHEntranceGroups.GERUDO_FORTRESS_ENTRANCE], + SOHEntranceGroups.GERUDO_FORTRESS_ENTRANCE: [SOHEntranceGroups.THIEVES_HIDEOUT_ENTRANCE], + SOHEntranceGroups.OVERWORLD: [SOHEntranceGroups.OVERWORLD] +} + + +mixed_group_lookup = {group: [all for all in (SOHEntranceGroups.OTHER, SOHEntranceGroups.BOSS_ENTRANCE, SOHEntranceGroups.DUNGEON_ENTRANCE, + SOHEntranceGroups.OVERWORLD, SOHEntranceGroups.INTERIOR, SOHEntranceGroups.GROTTO)] + for group in (SOHEntranceGroups.OTHER, SOHEntranceGroups.BOSS_ENTRANCE, SOHEntranceGroups.DUNGEON_ENTRANCE, + SOHEntranceGroups.OVERWORLD, SOHEntranceGroups.INTERIOR, SOHEntranceGroups.GROTTO)} + + +# This is allowing us to brute force the problem of GER failing. May be a necessary evil as it doesn't do swap or automatic retries itself. +OOT_SOH_GER_RETRIES_AMOUNT: int = 10 + +def get_target_groups(group: int) -> list[int]: + type = group & SOHEntranceGroups.TYPE_MASK + age = group & SOHEntranceGroups.AGE_MASK + + if(age == SOHEntranceGroups.ANY_AGE): + return [pair_type | ages for pair_type in default_group_lookup[type] for ages in (SOHEntranceGroups.ANY_AGE, SOHEntranceGroups.CHILD, SOHEntranceGroups.ADULT, SOHEntranceGroups.CHILD_ONLY, SOHEntranceGroups.ADULT_ONLY, SOHEntranceGroups.BOTH_AGE)] + + if(age == SOHEntranceGroups.BOTH_AGE): + return [pair_type | ages for pair_type in default_group_lookup[type] for ages in (SOHEntranceGroups.BOTH_AGE, SOHEntranceGroups.ADULT, SOHEntranceGroups.CHILD, SOHEntranceGroups.ANY_AGE)] + + if(age == SOHEntranceGroups.CHILD): + return [pair_type | ages for pair_type in default_group_lookup[type] for ages in (SOHEntranceGroups.CHILD, SOHEntranceGroups.CHILD_ONLY, SOHEntranceGroups.ADULT, SOHEntranceGroups.BOTH_AGE, SOHEntranceGroups.ANY_AGE)] + + if(age == SOHEntranceGroups.ADULT): + return [pair_type | ages for pair_type in default_group_lookup[type] for ages in (SOHEntranceGroups.ADULT, SOHEntranceGroups.ADULT_ONLY, SOHEntranceGroups.CHILD, SOHEntranceGroups.BOTH_AGE, SOHEntranceGroups.ANY_AGE)] + + if(age == SOHEntranceGroups.ADULT_ONLY): + return [pair_type | ages for pair_type in default_group_lookup[type] for ages in (SOHEntranceGroups.ADULT_ONLY, SOHEntranceGroups.ADULT, SOHEntranceGroups.ANY_AGE)] + + if(age == SOHEntranceGroups.CHILD_ONLY): + return [pair_type | ages for pair_type in default_group_lookup[type] for ages in (SOHEntranceGroups.CHILD_ONLY, SOHEntranceGroups.CHILD, SOHEntranceGroups.ANY_AGE)] + + return [pair_type | age for pair_type in default_group_lookup[type]] + +def get_target_groups_mixed_entrance_pools(group: int) -> list[int]: + type = group & SOHEntranceGroups.TYPE_MASK + age = group & SOHEntranceGroups.AGE_MASK + + if(age == SOHEntranceGroups.ANY_AGE): + return [pair_type | ages for pair_type in mixed_group_lookup[type] for ages in (SOHEntranceGroups.ANY_AGE, SOHEntranceGroups.CHILD, SOHEntranceGroups.ADULT, SOHEntranceGroups.CHILD_ONLY, SOHEntranceGroups.ADULT_ONLY, SOHEntranceGroups.BOTH_AGE)] + + if(age == SOHEntranceGroups.BOTH_AGE): + return [pair_type | ages for pair_type in mixed_group_lookup[type] for ages in (SOHEntranceGroups.BOTH_AGE, SOHEntranceGroups.ADULT, SOHEntranceGroups.CHILD, SOHEntranceGroups.ANY_AGE)] + + if(age == SOHEntranceGroups.CHILD): + return [pair_type | ages for pair_type in mixed_group_lookup[type] for ages in (SOHEntranceGroups.CHILD, SOHEntranceGroups.CHILD_ONLY, SOHEntranceGroups.ADULT, SOHEntranceGroups.BOTH_AGE, SOHEntranceGroups.ANY_AGE)] + + if(age == SOHEntranceGroups.ADULT): + return [pair_type | ages for pair_type in mixed_group_lookup[type] for ages in (SOHEntranceGroups.ADULT, SOHEntranceGroups.ADULT_ONLY, SOHEntranceGroups.CHILD, SOHEntranceGroups.BOTH_AGE, SOHEntranceGroups.ANY_AGE)] + + if(age == SOHEntranceGroups.ADULT_ONLY): + return [pair_type | ages for pair_type in mixed_group_lookup[type] for ages in (SOHEntranceGroups.ADULT_ONLY, SOHEntranceGroups.ADULT, SOHEntranceGroups.ANY_AGE)] + + if(age == SOHEntranceGroups.CHILD_ONLY): + return [pair_type | ages for pair_type in mixed_group_lookup[type] for ages in (SOHEntranceGroups.CHILD_ONLY, SOHEntranceGroups.CHILD, SOHEntranceGroups.ANY_AGE)] + + return [pair_type | age for pair_type in mixed_group_lookup[type]] + +def get_target_groups_age_restrictive(group: int) -> list[int]: + type = group & SOHEntranceGroups.TYPE_MASK + age = group & SOHEntranceGroups.AGE_MASK + + if(age == SOHEntranceGroups.CHILD): + return [pair_type | ages for pair_type in default_group_lookup[type] for ages in (SOHEntranceGroups.CHILD_ONLY, SOHEntranceGroups.CHILD)] + + if(age == SOHEntranceGroups.ADULT): + return [pair_type | ages for pair_type in default_group_lookup[type] for ages in (SOHEntranceGroups.ADULT_ONLY, SOHEntranceGroups.ADULT)] + + if(age == SOHEntranceGroups.ADULT_ONLY): + return [pair_type | ages for pair_type in default_group_lookup[type] for ages in (SOHEntranceGroups.ADULT, SOHEntranceGroups.ADULT_ONLY)] + + if(age == SOHEntranceGroups.CHILD_ONLY): + return [pair_type | ages for pair_type in default_group_lookup[type] for ages in (SOHEntranceGroups.CHILD, SOHEntranceGroups.CHILD_ONLY)] + + return [pair_type | age for pair_type in default_group_lookup[type]] + + +# Special Randomization for one ways like Owl Drop and Warp Songs +def randomize_soh_one_way_entrances(world: "SohWorld") -> None: + if world.options.shuffle_owl_drop_entrances or world.options.shuffle_warp_song_entrances or world.options.shuffle_overworld_spawns: + one_way_entrance_names = list() + one_way_entrance_exit_names = list() + # TODO This will need to be updated as we make more named entrances + all_named_entrances = list(SOHDungeonEntranceNames) + list(SOHDungeonExitNames) + list(SOHGrottoExitNames) + list(SOHGrottoEntranceNames) + list(SOHInteriorEntranceNames) + list(SOHInteriorExitNames) + list(SOHSpecialInteriorExitNames) + list(SOHSpecialInteriorEntranceNames) + list(SOHOverworldEntranceNames) + + if world.options.shuffle_owl_drop_entrances: + one_way_entrance_names += [Regions.LH_OWL_FLIGHT, Regions.DMT_OWL_FLIGHT] + + if world.options.shuffle_warp_song_entrances: + # SOH Seems to put these at random places, except for glitchless. They enforce Graveyard, Crater, and Colossus Warp pads be assigned when glitchless. + one_way_entrance_names +=[Regions.MINUET_OF_FOREST_WARP, Regions.BOLERO_OF_FIRE_WARP, Regions.SERENADE_OF_WATER_WARP, Regions.NOCTURNE_OF_SHADOW_WARP, Regions.REQUIEM_OF_SPIRIT_WARP, Regions.PRELUDE_OF_LIGHT_WARP] + one_way_entrance_exit_names += [Regions.DMC_CENTRAL_LOCAL, Regions.DESERT_COLOSSUS, Regions.GRAVEYARD_WARP_PAD_REGION] + + # Remove the existing exit + for name in one_way_entrance_names: + entrance = world.get_entrance(str(name)) + entrance.connected_region.entrances.remove(entrance) + entrance.connected_region = None + + # Get enough entrances to connect up + world.random.shuffle(all_named_entrances) + for entrance_name in all_named_entrances: + if len(one_way_entrance_names) == len(one_way_entrance_exit_names): + break + + if entrance_name not in one_way_entrance_exit_names: + one_way_entrance_exit_names.append(entrance_name) + + if len(one_way_entrance_names) > 0: + # Randomize the the entrance name list + world.random.shuffle(one_way_entrance_exit_names) + # For Owl Drop/ Song Warps + soh_one_way_entrance_connections(world, one_way_entrance_names, one_way_entrance_exit_names, all_named_entrances) + + # Handle Overworld Spawns separately + if world.options.shuffle_overworld_spawns: + one_way_entrance_names = [Regions.CHILD_SPAWN, Regions.ADULT_SPAWN] + + # Remove the existing exit + for name in one_way_entrance_names: + entrance = world.get_entrance(str(name)) + entrance.connected_region.entrances.remove(entrance) + entrance.connected_region = None + + # Remove special cases for child/adult spawns + # Problematic if they shuffle swim + if world.options.shuffle_swim: + all_named_entrances.remove(SOHDungeonEntranceNames.WATER_TEMPLE_DUNGEON_ENTRANCE) + all_named_entrances.remove(SOHDungeonExitNames.WATER_TEMPLE_DUNGEON_EXIT) + all_named_entrances.remove(SOHGrottoEntranceNames.ZD_STORMS_GROTTO_ENTRANCE) + all_named_entrances.remove(SOHGrottoExitNames.ZD_STORMS_GROTTO_EXIT) + + # Problematic because they have to brave lava to get out + all_named_entrances.remove(SOHGrottoEntranceNames.GC_GROTTO_ENTRANCE) + all_named_entrances.remove(SOHGrottoExitNames.GC_GROTTO_EXIT) + # Can't cross bridge with nothing or as child + all_named_entrances.remove(SOHDungeonEntranceNames.FIRE_TEMPLE_DUNGEON_ENTRANCE) + all_named_entrances.remove(SOHDungeonExitNames.FIRE_TEMPLE_DUNGEON_EXIT) + + world.random.shuffle(all_named_entrances) + + soh_one_way_entrance_connections(world, one_way_entrance_names, all_named_entrances, all_named_entrances) + + +def soh_one_way_entrance_connections(world: "SohWorld", entrance_names: list, exit_names: list, potential_entrance_names: list): + index: int = 0 + for entrance_name in entrance_names: + entrance = world.get_entrance(str(entrance_name)) + + if exit_names[index] in potential_entrance_names: + connected_region_name = world.get_entrance(str(exit_names[index])).parent_region.name + else: + connected_region_name = str(exit_names[index]) + + entrance.connected_region = world.get_region(connected_region_name) + entrance.connected_region.entrances.append(entrance) + + index += 1 + + +# Might need to return the ER Placement state at the end +def randomize_entrances_soh(world: "SohWorld", entrances_to_shuffle: set[SOHBossEntranceNames | SOHDungeonEntranceNames | SOHDungeonExitNames | SOHInteriorEntranceNames | SOHInteriorExitNames | SOHSpecialInteriorEntranceNames | SOHSpecialInteriorExitNames | SOHThievesHideoutEntranceNames], on_connect: Callable[[ERPlacementState, list[Entrance], list[Entrance]], bool | None] | None = None, coupled: bool = True, ageRestricted: bool = False) -> None: + for entranceEnum in entrances_to_shuffle: + disconnect_entrance_for_randomization(world.multiworld.get_entrance( + entranceEnum.value, world.player), one_way_target_name=entrance_matching[entranceEnum].value if entranceEnum in entrance_matching else None) + + if ageRestricted: + target_group_lookup = bake_target_group_lookup(world, get_target_groups_age_restrictive) + elif world.options.mixed_entrances_pools: + target_group_lookup = bake_target_group_lookup(world, get_target_groups_mixed_entrance_pools) + else: + target_group_lookup = bake_target_group_lookup(world, get_target_groups) + + + for i in range(OOT_SOH_GER_RETRIES_AMOUNT): + try: + er_state = randomize_entrances(world, coupled, target_group_lookup, False, on_connect=on_connect) + world.er_pairings += er_state.pairings + # print(world.er_pairings) + # print(f"Took {i} attempts to get GER working.") + break + except EntranceRandomizationError as error: + if i >= OOT_SOH_GER_RETRIES_AMOUNT - 1: + raise EntranceRandomizationError(f"OOT SOH: failed GER after {OOT_SOH_GER_RETRIES_AMOUNT} " + f"attempts. Final error here: \n\n{error}") + # need to disconnect all entrances that are supposed to be shuffled + for entranceEnum in entrances_to_shuffle: + _exit: Entrance = world.multiworld.get_entrance(entranceEnum.value, world.player) + if (_exit.randomization_group in target_group_lookup and _exit.parent_region and _exit.connected_region and _exit.name not in world.er_pairings): + disconnect_entrance_for_randomization(_exit, one_way_target_name=entrance_matching[entranceEnum].value if entranceEnum in entrance_matching else None) + + +# This should probably be double checked by someone who knows how to properly remove a location from a region and give it a new parent region +def on_connect_soh(er_state: ERPlacementState, placed_exits: list[Entrance], paired_entrances: list[Entrance]) -> bool: + # Force a rescan of all reachable regions + er_state.collection_state._soh_stale[er_state.world.player] = True + + # Sheik at colossus logic fix + if er_state.world.options.decouple_entrances and len(paired_entrances) >= 2 and paired_entrances[1].name == SOHDungeonEntranceNames.SPIRIT_TEMPLE_DUNGEON_ENTRNACE: + world: SohWorld = er_state.world + def locationRule(bundle): return True + + # print(f'Placed Exits: {placed_exits} | Paired Entrances: {paired_entrances}') + location: Location = world.get_location(Locations.SHEIK_AT_COLOSSUS) + location.parent_region.locations.remove(location) + + new_parent_region: Region = world.get_entrance(paired_entrances[0].name).parent_region + location.parent_region = new_parent_region + new_parent_region.add_locations({str(location.name): location.address}, SohLocation) + set_rule(world.get_location(location.name), rule_wrapper.wrap(new_parent_region, locationRule, world)) + + return False diff --git a/worlds/oot_soh/Enums.py b/worlds/oot_soh/Enums.py index cc927ee11b11..48d641b4b275 100644 --- a/worlds/oot_soh/Enums.py +++ b/worlds/oot_soh/Enums.py @@ -69,7 +69,7 @@ class Regions(StrEnum): GF_NEAR_GROTTO = "GF Near Grotto" GF_OUTSIDE_GTG = "GF Outside GTG" GF_TO_GTG = "GF to GTG" - GF_EXITING_GTG = "GF Exiting GTG" + # GF_EXITING_GTG = "GF Exiting GTG" GF_ABOVE_GTG = "GF Above GTG" GF_BOTTOM_OF_LOWER_VINES = "GF Bottom of Lower Vines" GF_TOP_OF_LOWER_VINES = "GF Top of Lower Vines" @@ -103,7 +103,7 @@ class Regions(StrEnum): WASTELAND_NEAR_COLOSSUS = "Wasteland Near Colossus" DESERT_COLOSSUS = "Desert Colossus" DESERT_COLOSSUS_OASIS = "Desert Colossus Oasis" - DESERT_COLOSSUS_OUTSIDE_TEMPLE = "Desert Colossus Outside Temple" + # DESERT_COLOSSUS_OUTSIDE_TEMPLE = "Desert Colossus Outside Temple" COLOSSUS_GREAT_FAIRY_FOUNTAIN = "Colossus Great Fairy Fountain" COLOSSUS_GROTTO = "Colossus Grotto" MARKET_ENTRANCE = "Market Entrance" @@ -124,7 +124,7 @@ class Regions(StrEnum): BEYOND_DOOR_OF_TIME = "Beyond Door of Time" MASTER_SWORD_PEDESTAL = "Master Sword Pedestal" CASTLE_GROUNDS = "Castle Grounds" - CASTLE_GROUNDS_FROM_GANONS_CASTLE = "Castle Grounds From Ganon's Castle" + # CASTLE_GROUNDS_FROM_GANONS_CASTLE = "Castle Grounds From Ganon's Castle" HYRULE_CASTLE_GROUNDS = "Hyrule Castle Grounds" HC_GARDEN_SONG_FROM_IMPA = "HC Garden Song From Impa" HC_GARDEN = "HC Garden" @@ -3846,7 +3846,368 @@ class Tricks(StrEnum): GANONS_CASTLE_BARRIER_SKIP_HOVER = "Ganons Castle Barrier Skip Hover" GANONS_CASTLE_GOLD_GAUNTLET_SKIP = "Ganons Castle Gold Gauntlet Skip" + +# Probabaly need more than these for other shuffles, but for now this works. +class SOHEntranceGroups(IntEnum): + # Entrance Type + OTHER = 0 + DUNGEON_ENTRANCE = 1 + BOSS_ENTRANCE = 2 + OVERWORLD = 3 + INTERIOR = 4 + THIEVES_HIDEOUT_ENTRANCE = 5 + GERUDO_FORTRESS_ENTRANCE = 6 + GROTTO = 7 + OWL_DROP = 8 + WARP_SONG = 9 + # Age Accessible + ANY_AGE = 1 << 4 + CHILD = 2 << 4 + ADULT = 3 << 4 + CHILD_ONLY = 4 << 4 + ADULT_ONLY = 5 << 4 + BOTH_AGE = 6 << 4 + # Bitmasks + TYPE_MASK = ANY_AGE - 1 + AGE_MASK = ~0 << 4 + + +class SOHDungeonExitNames(StrEnum): + DEKU_TREE_DUNGEON_EXIT = "Deku Tree Dungeon Exit" + DODONGOS_CAVERN_DUNGEON_EXIT = "Dodongos Cavern Dungeon Exit" + JABU_JABUS_DUNGEON_EXIT = "Jabu Jabus Dungeon Exit" + FOREST_TEMPLE_DUNGEON_EXIT = "Forest Temple Dungeon Exit" + FIRE_TEMPLE_DUNGEON_EXIT = "Fire Temple Dungeon Exit" + WATER_TEMPLE_DUNGEON_EXIT = "Water Temple Dungeon Exit" + SHADOW_TEMPLE_DUNGEON_EXIT = "Shadow Temple Dungeon Exit" + SPIRIT_TEMPLE_DUNGEON_EXIT = "Spirit Temple Dungeon Exit" + GANONS_CASTLE_DUNGEON_EXIT = "Ganons Castle Dungeon Exit" + BOTTOM_OF_THE_WELL_DUNGEON_EXIT = "Bottom of the Well Dungeon Exit" + ICE_CAVERN_DUNGEON_EXIT = "Ice Cavern Dungeon Exit" + GERUDO_TRAINING_GROUND_DUNGEON_EXIT = "Gerudo Training Ground Dungeon Exit" + + +class SOHDungeonEntranceNames(StrEnum): + DEKU_TREE_DUNGEON_ENTRANCE = "Deku Tree Dungeon Entrance" + DODONGOS_CAVERN_DUNGEON_ENTRANCE = "Dodongos Cavern Dungeon Entrance" + JABU_JABUS_DUNGEON_ENTRANCE = "Jabu Jabus Dungeon Entrance" + FOREST_TEMPLE_DUNGEON_ENTRANCE = "Forest Temple Dungeon Entrance" + FIRE_TEMPLE_DUNGEON_ENTRANCE = "Fire Temple Dungeon Entrance" + WATER_TEMPLE_DUNGEON_ENTRANCE = "Water Temple Dungeon Entrance" + SHADOW_TEMPLE_DUNGEON_ENTRANCE = "Shadow Temple Dungeon Entrance" + SPIRIT_TEMPLE_DUNGEON_ENTRNACE = "Spirit Temple Dungeon Entrance" + GANONS_CASTLE_DUNGEON_ENTRANCE = "Ganons Castle Dungeon Entrance" + BOTTOM_OF_THE_WELL_DUNGEON_ENTRANCE = "Bottom of the Well Dungeon Entrance" + ICE_CAVERN_DUNGEON_ENTRANCE = "Ice Cavern Dungeon Entrance" + GERUDO_TRAINING_GROUND_DUNGEON_ENTRANCE = "Gerudo Training Ground Dungeon Entrance" + + +class SOHBossEntranceNames(StrEnum): + DEKU_TREE_BOSS_ENTRANCE = "Deku Tree Dungeon Boss Entrance" + DODONGOS_CAVERN_BOSS_ENTRANCE = "Dodongos Cavern Dungeon Boss Entrance" + JABU_JABUS_BOSS_ENTRANCE = "Jabu Jabus Dungeon Boss Entrance" + FOREST_TEMPLE_BOSS_ENTRANCE = "Forest Temple Dungeon Boss Entrance" + FIRE_TEMPLE_BOSS_ENTRANCE = "Fire Temple Dungeon Boss Entrance" + WATER_TEMPLE_BOSS_ENTRANCE = "Water Temple Dungeon Boss Entrance" + SHADOW_TEMPLE_BOSS_ENTRANCE = "Shadow Temple Dungeon Boss Entrance" + SPIRIT_TEMPLE_BOSS_ENTRANCE = "Spirit Temple Dungeon Boss Entrance" + + +class SOHBossEntranceExitNames(StrEnum): + DEKU_TREE_BOSS_EXIT = "Deku Tree Dungeon Boss Exit" + DODONGOS_CAVERN_BOSS_EXIT = "Dodongos Cavern Dungeon Boss Exit" + JABU_JABUS_BOSS_EXIT = "Jabu Jabus Dungeon Boss Exit" + FOREST_TEMPLE_BOSS_EXIT = "Forest Temple Dungeon Boss Exit" + FIRE_TEMPLE_BOSS_EXIT = "Fire Temple Dungeon Boss Exit" + WATER_TEMPLE_BOSS_EXIT = "Water Temple Dungeon Boss Exit" + SHADOW_TEMPLE_BOSS_EXIT = "Shadow Temple Dungeon Boss Exit" + SPIRIT_TEMPLE_BOSS_EXIT = "Spirit Temple Dungeon Boss Exit" + +class SOHBossWarpEntranceNames(StrEnum): + DEKU_TREE_BOSS_WARP_ENTRANCE = "Deku Tree Dungeon Boss Warp Entrance" + DODONGOS_CAVERN_BOSS_WARP_ENTRANCE = "Dodongos Cavern Dungeon Boss Warp Entrance" + JABU_JABUS_BOSS_WARP_ENTRANCE = "Jabu Jabus Dungeon Boss Warp Entrance" + FOREST_TEMPLE_BOSS_WARP_ENTRANCE = "Forest Temple Dungeon Boss Warp Entrance" + FIRE_TEMPLE_BOSS_WARP_ENTRANCE = "Fire Temple Dungeon Boss Warp Entrance" + WATER_TEMPLE_BOSS_WARP_ENTRANCE = "Water Temple Dungeon Boss Warp Entrance" + SHADOW_TEMPLE_BOSS_WARP_ENTRANCE = "Shadow Temple Dungeon Boss Warp Entrance" + SPIRIT_TEMPLE_BOSS_WARP_ENTRANCE = "Spirit Temple Dungeon Boss Warp Entrance" + + +class SOHBossWarpExitNames(StrEnum): + DEKU_TREE_BOSS_WARP_EXIT = "Deku Tree Dungeon Boss Warp Exit" + DODONGOS_CAVERN_BOSS_WARP_EXIT = "Dodongos Cavern Dungeon Boss Warp Exit" + JABU_JABUS_BOSS_WARP_EXIT = "Jabu Jabus Dungeon Boss Warp Exit" + FOREST_TEMPLE_BOSS_WARP_EXIT = "Forest Temple Dungeon Boss Warp Exit" + FIRE_TEMPLE_BOSS_WARP_EXIT = "Fire Temple Dungeon Boss Warp Exit" + WATER_TEMPLE_BOSS_WARP_EXIT = "Water Temple Dungeon Boss Warp Exit" + SHADOW_TEMPLE_BOSS_WARP_EXIT = "Shadow Temple Dungeon Boss Warp Exit" + SPIRIT_TEMPLE_BOSS_WARP_EXIT = "Spirit Temple Dungeon Boss Warp Exit" + + +class SOHGrottoEntranceNames(StrEnum): + COLOSSUS_GROTTO_ENTRANCE = "Colossus Grotto Entrance" + LH_GROTTO_ENTRANCE = "LH Grotto Entrance" + ZR_OPEN_GROTTO_ENTRANCE = "ZR Open Grotto Entrance" + ZR_FAIRY_GROTTO_ENTRANCE = "ZR Fairy Grotto Entrance" + ZR_STORMS_GROTTO_ENTRANCE = "ZR Storms Grotto Entrance" + DMC_HAMMER_GROTTO_ENTRANCE = "DMC Hammer Grotto Entrance" + DMC_UPPER_GROTTO_ENTRANCE = "DMC Upper Grotto Entrance" + GC_GROTTO_ENTRANCE = "GC Grotto Entrance" + DMT_STORMS_GROTTO_ENTRANCE = "DMT Storms Grotto Entrance" + DMT_COW_GROTTO_ENTRANCE = "DMT Cow Grotto Entrance" + KAK_OPEN_GROTTO_ENTRANCE = "Kak Open Grotto Entrance" + KAK_REDEAD_GROTTO_ENTRANCE = "Kak Redead Grotto Entrance" + HC_STORMS_GROTTO_ENTRANCE = "HC Storms Grotto Entrance" + HF_TEKTITE_GROTTO_ENTRANCE = "HF Tektitie Grotto Entrance" + HF_NEAR_KAK_GROTTO_ENTRANCE = "HF Near Kak Grotto Entrance" + HF_FAIRY_GROTTO_ENTRANCE = "HF Fairy Grotto Entrance" + HF_NEAR_MARKET_GROTTO_ENTRANCE = "HF Near Market Grotto Entrance" + HF_COW_GROTTO_ENTRANCE = "HF Cow Grotto Entrance" + HF_INSIDE_FENCE_GROTTO_ENTRANCE = "HF Inside Fence Grotto Entrance" + HF_OPEN_GROTTO_ENTRANCE = "HF Open Grotto Entrance" + HF_SOUTHEAST_GROTTO_ENTRANCE = "HF Southeast Grotto Entrance" + LLR_GROTTO_ENTRANCE = "LLR Grotto Entrance" + SFM_WOLFOS_GROTTO_ENTRANCE = "SFM Wolfos Grotto Entrance" + SFM_STORMS_GROTTO_ENTRANCE = "SFM Storms Grotto Entrance" + SFM_FAIRY_GROTTO_ENTRANCE = "SFM Fairy Grotto Entrance" + LW_SCRUBS_GROTTO_ENTRANCE = "LW Scrubs Grotto Entrance" + LW_NEAR_SHORTCUTS_GROTTO_ENTRANCE = "LW Near Shortcuts Grotto Entrance" + KF_STORMS_GROTTO_ENTRANCE = "KF Storms Grotto Entrance" + ZD_STORMS_GROTTO_ENTRANCE = "ZD Storms Grotto Entrance" + GF_STORMS_GROTTO_ENTRANCE = "GF Storms Grotto Entrance" + GV_STORMS_GROTTO_ENTRANCE = "GV Storms Grotto Entrance" + GV_OCTOROK_GROTTO_ENTRANCE = "GV Oktorok Grotto Entrance" + DEKU_THEATER_ENTRANCE = "Deku Theater Entrance" + #Graves + GRAVEYARD_SHEILD_GRAVE_ENTRANCE = "Graveyard Shield Grave Entrance" + GRAVEYARD_COMPOSERS_GRAVE_ENTRANCE = "Graveyard Composers Grave Entrance" + GRAVEYARD_HEART_PIECE_GRAVE_ENTRANCE = "Graveyard Heart Piece Grave Entrance" + GRAVEYARD_DAMPES_GRAVE_ENTRANCE = "Graveyard Dampes Grave Entrance" + + +class SOHGrottoExitNames(StrEnum): + COLOSSUS_GROTTO_EXIT = "Colossus Grotto Exit" + LH_GROTTO_EXIT = "LH Grotto Exit" + ZR_OPEN_GROTTO_EXIT = "ZR Open Grotto Exit" + ZR_FAIRY_GROTTO_EXIT = "ZR Fairy Grotto Exit" + ZR_STORMS_GROTTO_EXIT = "ZR Storms Grotto Exit" + DMC_HAMMER_GROTTO_EXIT = "DMC Hammer Grotto Exit" + DMC_UPPER_GROTTO_EXIT = "DMC Upper Grotto Exit" + GC_GROTTO_EXIT = "GC Grotto Exit" + DMT_STORMS_GROTTO_EXIT = "DMT Storms Grotto Exit" + DMT_COW_GROTTO_EXIT = "DMT Cow Grotto Exit" + KAK_OPEN_GROTTO_EXIT = "Kak Open Grotto Exit" + KAK_REDEAD_GROTTO_EXIT = "Kak Redead Grotto Exit" + HC_STORMS_GROTTO_EXIT = "HC Storms Grotto Exit" + HF_TEKTITE_GROTTO_EXIT = "HF Tektitie Grotto Exit" + HF_NEAR_KAK_GROTTO_EXIT = "HF Near Kak Grotto Exit" + HF_FAIRY_GROTTO_EXIT = "HF Fairy Grotto Exit" + HF_NEAR_MARKET_GROTTO_EXIT = "HF Near Market Grotto Exit" + HF_COW_GROTTO_EXIT = "HF Cow Grotto Exit" + HF_INSIDE_FENCE_GROTTO_EXIT = "HF Inside Fence Grotto Exit" + HF_OPEN_GROTTO_EXIT = "HF Open Grotto Exit" + HF_SOUTHEAST_GROTTO_EXIT = "HF Southeast Grotto Exit" + LLR_GROTTO_EXIT = "LLR Grotto Exit" + SFM_WOLFOS_GROTTO_EXIT = "SFM Wolfos Grotto Exit" + SFM_STORMS_GROTTO_EXIT = "SFM Storms Grotto Exit" + SFM_FAIRY_GROTTO_EXIT = "SFM Fairy Grotto Exit" + LW_SCRUBS_GROTTO_EXIT = "LW Scrubs Grotto Exit" + LW_NEAR_SHORTCUTS_GROTTO_EXIT = "LW Near Shortcuts Grotto Exit" + KF_STORMS_GROTTO_EXIT = "KF Storms Grotto Exit" + ZD_STORMS_GROTTO_EXIT = "ZD Storms Grotto Exit" + GF_STORMS_GROTTO_EXIT = "GF Storms Grotto Exit" + GV_STORMS_GROTTO_EXIT = "GV Storms Grotto Exit" + GV_OCTOROK_GROTTO_EXIT = "GV Oktorok Grotto Exit" + DEKU_THEATER_EXIT = "Deku Theater Exit" + #Graves + GRAVEYARD_SHEILD_GRAVE_EXIT = "Graveyard Shield Grave Exit" + GRAVEYARD_COMPOSERS_GRAVE_EXIT = "Graveyard Composers Grave Exit" + GRAVEYARD_HEART_PIECE_GRAVE_EXIT = "Graveyard Heart Piece Grave Exit" + GRAVEYARD_DAMPES_GRAVE_EXIT = "Graveyard Dampes Grave Exit" + + +class SOHInteriorEntranceNames(StrEnum): + KF_MIDOS_HOUSE_ENTRANCE = "KF Midos House Entrance" + KF_SARIAS_HOUSE_ENTRANCE = "KF Sarias House Entrance" + KF_TWINS_HOUSE_ENTRANCE = "KF Twins House Entrance" + KF_KNOW_IT_ALL_HOUSE_ENTRANCE = "KF Know It All House Entrance" + KF_KOKIRI_SHOP_ENTRANCE = "KF Kokiri Shop Entrance" + LH_LAB_ENTRANCE = "LH Lab Entrance" + LH_FISHING_POND_ENTRANCE = "LF Fishing Pond Entrance" + GV_CARPENTER_TENT_ENTRANCE = "GV Carpenter Tent Entrance" + MARKET_GUARD_HOUSE_ENTRANCE = "Market Guard House Entrance" + MARKET_MASK_SHOP_ENTRANCE = "Market Mask Shop Entrance" + MARKET_BOMBCHU_BOWLING_ENTRANCE = "Market Bombchu Bowling Entrance" + MARKET_POTION_SHOP_ENTRANCE = "Market Potion Shop Entrance" + MARKET_TREASURE_CHEST_GAME_ENTRANCE = "Market Treasure Chest Game Entrance" + MARKET_BOMBCHU_SHOP_ENTRANCE = "Market Bombchu Shop Entrance" + MARKET_MAN_IN_GREEN_HOUSE_ENTRANCE = "Market Man In Green House Entrance" + KAK_CARPENTER_BOSS_HOUSE_ENTRANCE = "Kak Carpenter Boss House Entrance" + KAK_HOUSE_OF_SKULLTULA_ENTRANCE = "Kak House Of Skulltula Entrance" + KAK_IMPAS_HOUSE_ENTRANCE = "Kak Impas House Entrance" + KAK_IMPAS_HOUSE_BACK_ENTRANCE = "Kak Impas House Back Entrance" + KAK_ODD_POTION_BUILDING_ENTRANCE = "Kak Odd Potion Building Entrance" + GRAVEYARD_DAMPES_HOUSE_ENTRANCE = "Graveyard Dampes House Entrance" + GC_SHOP_ENTRANCE = "GC Shop Entrance" + ZD_SHOP_ENTRANCE = "ZD Shop Entrance" + LLR_TALONS_HOUSE_ENTRANCE = "LLR Talons House Entrance" + LLR_STABLES_ENTRANCE = "LLR Stables Entrance" + LLR_TOWER_ENTRANCE = "LLR Tower Entrance" + MARKET_BAZAAR_ENTRANCE = "Market Bazaar Entrance" + MARKET_SHOOTING_GALLERY_ENTRANCE = "Market Shooing Gallery Entrance" + KAK_BAZAAR_ENTRANCE = "Kak Bazaar Entrance" + KAK_SHOOTING_GALLERY_ENTRANCE = "Kak Shooting Gallery Entrance" + COLOSSUS_GREAT_FAIRY_FOUNTAIN_ENTRANCE = "Colossus Great Fairy Fountain Entrance" + HC_GREAT_FAIRY_FOUNTAIN_ENTRANCE = "HC Great Fairy Fountain Entrance" + OGC_GREAT_FAIRY_FOUNTAIN_ENTRANCE = "OGC Great Fairy Fountain Entrance" + DMC_GREAT_FAIRY_FOUNTAIN_ENTRANCE = "DMC Great Fairy Fountain Entrance" + DMT_GREAT_FAIRY_FOUNTAIN_ENTRANCE = "DMT Great Fairy Fountain Entrance" + ZF_GREAT_FAIRY_FOUNTAIN_ENTRANCE = "ZF Great Fairy Fountain Entrance" + + +class SOHInteriorExitNames(StrEnum): + KF_MIDOS_HOUSE_EXIT = "KF Midos House Exit" + KF_SARIAS_HOUSE_EXIT = "KF Sarias House Exit" + KF_TWINS_HOUSE_EXIT = "KF Twins House Exit" + KF_KNOW_IT_ALL_HOUSE_EXIT = "KF Know It All House Exit" + KF_KOKIRI_SHOP_EXIT = "KF Kokiri Shop Exit" + LH_LAB_EXIT = "LH Lab Exit" + LH_FISHING_POND_EXIT = "LF Fishing Pond Exit" + GV_CARPENTER_TENT_EXIT = "GV Carpenter Tent Exit" + MARKET_GUARD_HOUSE_EXIT = "Market Guard House Exit" + MARKET_MASK_SHOP_EXIT = "Market Mask Shop Exit" + MARKET_BOMBCHU_BOWLING_EXIT = "Market Bombchu Bowling Exit" + MARKET_POTION_SHOP_EXIT = "Market Potion Shop Exit" + MARKET_TREASURE_CHEST_GAME_EXIT = "Market Treasure Chest Game Exit" + MARKET_BOMBCHU_SHOP_EXIT = "Market Bombchu Shop Exit" + MARKET_MAN_IN_GREEN_HOUSE_EXIT = "Market Man In Green House Exit" + KAK_CARPENTER_BOSS_HOUSE_EXIT = "Kak Carpenter Boss House Exit" + KAK_HOUSE_OF_SKULLTULA_EXIT = "Kak House Of Skulltula Exit" + KAK_IMPAS_HOUSE_EXIT = "Kak Impas House Exit" + KAK_IMPAS_HOUSE_BACK_EXIT = "Kak Impas House Back Exit" + KAK_ODD_POTION_BUILDING_EXIT = "Kak Odd Potion Building Exit" + GRAVEYARD_DAMPES_HOUSE_EXIT = "Graveyard Dampes House Exit" + GC_SHOP_EXIT = "GC Shop Exit" + ZD_SHOP_EXIT = "ZD Shop Exit" + LLR_TALONS_HOUSE_EXIT = "LLR Talons House Exit" + LLR_STABLES_EXIT = "LLR Stables Exit" + LLR_TOWER_EXIT = "LLR Tower Exit" + MARKET_BAZAAR_EXIT = "Market Bazaar Exit" + MARKET_SHOOTING_GALLERY_EXIT = "Market Shooing Gallery Exit" + KAK_BAZAAR_EXIT = "Kak Bazaar Exit" + KAK_SHOOTING_GALLERY_EXIT = "Kak Shooting Gallery Exit" + COLOSSUS_GREAT_FAIRY_FOUNTAIN_EXIT = "Colossus Great Fairy Fountain Exit" + HC_GREAT_FAIRY_FOUNTAIN_EXIT = "HC Great Fairy Fountain Exit" + OGC_GREAT_FAIRY_FOUNTAIN_EXIT = "OGC Great Fairy Fountain Exit" + DMC_GREAT_FAIRY_FOUNTAIN_EXIT = "DMC Great Fairy Fountain Exit" + DMT_GREAT_FAIRY_FOUNTAIN_EXIT = "DMT Great Fairy Fountain Exit" + ZF_GREAT_FAIRY_FOUNTAIN_EXIT = "ZF Great Fairy Fountain Exit" + + +class SOHSpecialInteriorEntranceNames(StrEnum): + KF_LINKS_HOUSE_ENTRANCE = "KF Links House Entrance" + TEMPLE_OF_TIME_ENTRANCE = "Temple Of Time Entrance" + KAK_WINDMILL_ENTRANCE = "Kak Windmill Entrance" + KAK_POTION_SHOP_FRONT_ENTRANCE = "Kak Potion Shop Front Entrance" + KAK_POTION_SHOP_BACK_ENTRANCE = "Kak Potion Shop Back Entrance" + + +class SOHSpecialInteriorExitNames(StrEnum): + KF_LINKS_HOUSE_EXIT = "KF Links House Exit" + TEMPLE_OF_TIME_EXIT = "Temple Of Time Exit" + KAK_WINDMILL_EXIT = "Kak Windmill Exit" + KAK_POTION_SHOP_FRONT_EXIT = "Kak Potion Shop Front Exit" + KAK_POTION_SHOP_BACK_EXIT = "Kak Potion Shop Back Exit" + + +class SOHOverworldEntranceNames(StrEnum): + LOST_WOODS_BRIDGE_EAST_EXIT = "Lost Woods Bridge East Exit" + KOKIRI_FOREST_LOWER_EXIT = "Kokiri Forest Lower Exit" + LOST_WOODS_SOUTH_EXIT = "Lost Woods South Exit" + KOKIRI_FOREST_UPPER_EXIT = "Kokiri Forest Upper Exit" + GORON_CITY_TUNNEL_SHORTCUT = "Goron City Tunnel Shortcut" + LOST_WOODS_TUNNEL_SHORTCUT = "Lost Woods Tunnel Shortcut" + ZORAS_RIVER_UNDERWATER_SHORTCUT = "Zoras River Underwater Shortcut" + LOST_WOODS_UNDERWATER_SHORTCUT = "Lost Woods Underwater Shortcut" + SACRED_FOREST_MEADOW_SOUTH_EXIT = "Sacred Forst Meadow South Exit" + LOST_WOODS_NORTH_EXIT = "Lost Woods North Exit" + HYRULE_FIELD_WOODED_EXIT = "Hyrule Field Wooded Exit" + LOST_WOODS_BRIDGE_WEST_EXIT = "Lost Woods Bridge West Exit" + LAKE_HYLIA_NORTH_EXIT = "Lake Hylia North Exit" + HYRULE_FIELD_FENCE_EXIT = "Hyrule Field Fence Exit" + GERUDO_VALLEY_EAST_EXIT = "Gerudo Valley East Exit" + HYRULE_FIELD_ROCKY_PATH = "Hyrule Field Rocky Path" + MARKET_ENTRANCE_NEAR_GUARD_EXIT = "Market Entrance Near Guard Exit" + HYRULE_FIELD_ON_BRIDGE_SPAWN = "Hyrule Field On Bridge Spawn" + KAKARIKO_VILLAGE_FRONT_GATE = "Kakariko Village Front Gate" + HYRULE_FIELD_STAIRS_EXIT = "Hyrule Field Stairs Exit" + ZORAS_RIVER_WEST_EXIT = "Zoras River West Exit" + HYRULE_FIELD_RIVER_EXIT = "Hyrule Field River Exit" + LON_LON_RANCH_ENTRANCE = "Lon Lon Ranch Entrance" + HYRULE_FIELD_CENTER_EXIT = "Hyrule Field Center Exit" + ZORAS_DOMAIN_UNDERWATER_SHORTCUT = "Zoras Domain Underwater Shortcut" + LAKE_HYLIA_UNDERWATER_SHORTCUT = "Lake Hylia Underwater Shortcut" + GERUDOS_FORTRESS_EAST_EXIT = "Gerudos Fortress East Exit" + GERUDO_VALLEY_WEST_EXIT = "Gerudo Valley West Exit" + HAUNTED_WASTELAND_EAST_EXIT = "Haunted Wasteland East Exit" + GERUDOS_FORTRESS_GATE_EXIT = "Gerudos Fortress Gate Exit" + DESERT_COLOSSUS_EAST_EXIT = "Desert Colossus East Exit" + HAUNTED_WASTELAND_WEST_EXIT = "Haunted Wasteland West Exit" + MARKET_SOUTH_EXIT = "Market South Exit" + MARKET_ENTRANCE_NORTH_EXIT = "Market Entrance North Exit" + CASTLE_GROUNDS_SOUTH_EXIT = "Castle Grounds South Exit" + MARKET_DAY_CASTLE_EXIT = "Market Day Castle Exit" + TEMPLE_OF_TIME_EXTERIOR_DAY_GOSSIP_STONE_EXIT = "Temple of Time Exterior Day Gossip Stone Exit" + MARKET_DAY_TEMPLE_EXIT = "Market Day Temple Exit" + GRAVEYARD_ENTRANCE = "Graveyard Entrance" + KAKARIKO_VILLAGE_SOUTHEAST_EXIT = "Kakariko Village Southeast Exit" + DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT = "Death Mountain Trail Bottom Exit" + KAKARIKO_VILLAGE_GUARD_GATE = "Kakariko Village Guard Gate" + GORON_CITY_UPPER_EXIT = "Goron City Upper Exit" + DEATH_MOUNTAIN_TRAIL_GC_EXIT = "Death Mountain Trail GC Exit" + DEATH_MOUNTAIN_CRATER_GC_EXIT = "Death Mountain Crater GC Exit" + GORON_CITY_DARUNIA_ROOM_EXIT = "Goron City Darunia Room Exit" + DEATH_MOUNTAIN_CRATER_UPPER_EXIT = "Death Mountain Crater Upper Exit" + DEATH_MOUNTAIN_TRAIL_SUMMIT_EXIT = "Death Mountain Trail Summit Exit" + ZORAS_DOMAIN_ENTRANCE = "Zoras Domain Entrance" + ZORAS_RIVER_WATERFALL_EXIT = "Zoras River Waterfall Exit" + ZORAS_FOUNTAIN_TUNNEL_EXIT = "Zoras Fountain Tunnel Exit" + ZORAS_DOMAIN_KING_ZORA_EXIT = "Zoras Domain King Zora Exit" + LAKE_HYLIA_RIVER_EXIT = "Lake Hylia River Exit" + LAKE_HYLIA_RIVER_ENTRANCE = "Lake Hylia River Entrance" + + +class SOHThievesHideoutEntranceNames(StrEnum): + THIEVES_HIDEOUT_0 = "Thieves Hideout 0" + GERUDOS_FORTRESS_1 = "Gerudos Fortress 1" + THIEVES_HIDEOUT_1 = "Thieves Hideout 1" + GERUDOS_FORTRESS_2 = "Gerudos Fortress 2" + THIEVES_HIDEOUT_2 = "Thieves Hideout 2" + GERUDOS_FORTRESS_3 = "Gerudos Fortress 3" + THIEVES_HIDEOUT_3 = "Thieves Hideout 3" + GERUDOS_FORTRESS_4 = "Gerudos Fortress 4" + THIEVES_HIDEOUT_4 = "Thieves Hideout 4" + GERUDOS_FORTRESS_5 = "Gerudos Fortress 5" + THIEVES_HIDEOUT_5 = "Thieves Hideout 5" + GERUDOS_FORTRESS_6 = "Gerudos Fortress 6" + THIEVES_HIDEOUT_6 = "Thieves Hideout 6" + GERUDOS_FORTRESS_7 = "Gerudos Fortress 7" + THIEVES_HIDEOUT_7 = "Thieves Hideout 7" + GERUDOS_FORTRESS_8 = "Gerudos Fortress 8" + THIEVES_HIDEOUT_8 = "Thieves Hideout 8" + GERUDOS_FORTRESS_9 = "Gerudos Fortress 9" + THIEVES_HIDEOUT_9 = "Thieves Hideout 9" + GERUDOS_FORTRESS_10 = "Gerudos Fortress 10" + THIEVES_HIDEOUT_10 = "Thieves Hideout 10" + GERUDOS_FORTRESS_11 = "Gerudos Fortress 11" + THIEVES_HIDEOUT_11 = "Thieves Hideout 11" + GERUDOS_FORTRESS_12 = "Gerudos Fortress 12" + THIEVES_HIDEOUT_12 = "Thieves Hideout 12" + GERUDOS_FORTRESS_13 = "Gerudos Fortress 13" + + class TokenCounts(IntEnum): DUNGEON = 44 OVERWORLD = 56 - TOTAL = DUNGEON + OVERWORLD \ No newline at end of file + TOTAL = DUNGEON + OVERWORLD diff --git a/worlds/oot_soh/LogicHelpers.py b/worlds/oot_soh/LogicHelpers.py index e3f5f4f57948..189dfd8ccf1a 100644 --- a/worlds/oot_soh/LogicHelpers.py +++ b/worlds/oot_soh/LogicHelpers.py @@ -2,7 +2,7 @@ from typing import TYPE_CHECKING, Callable from collections import Counter -from BaseClasses import CollectionState, ItemClassification as IC, MultiWorld +from BaseClasses import CollectionState, ItemClassification as IC, MultiWorld, EntranceType from .Locations import SohLocation from worlds.generic.Rules import set_rule from worlds.AutoWorld import LogicMixin @@ -47,14 +47,25 @@ def locationRule(bundle): return True def connect_regions(parent_region: Regions, world: "SohWorld", - child_regions: list[tuple[Regions, Callable[[tuple[CollectionState, Regions, "SohWorld"]], bool]]]) -> None: + child_regions: list[tuple[Regions, Callable[[tuple[CollectionState, Regions, "SohWorld"]], bool], SOHBossEntranceNames | SOHDungeonExitNames | SOHBossWarpEntranceNames | SOHGrottoEntranceNames | SOHGrottoExitNames, int, EntranceType]]) -> None: for region in child_regions: regionName = region[0] + entranceName = None def regionRule(bundle): return True if len(region) > 1: - regionRule = region[1] # type: ignore # noqa - world.get_region(parent_region).connect(world.get_region(regionName), - rule=rule_wrapper.wrap(parent_region, regionRule, world)) + regionRule = region[1] + if len(region) > 2: + entranceName = region[2].value + entrance = world.get_region(parent_region).connect(world.get_region( + regionName), entranceName, rule_wrapper.wrap(parent_region, regionRule, world)) + + if len(region) > 3: + entrance.randomization_group = region[3] + if len(region) > 4: + entrance.randomization_type = region[4] + else: + #Default to EntranceType.Two_Way + entrance.randomization_type = EntranceType.TWO_WAY def add_events(parent_region: Regions, world: "SohWorld", diff --git a/worlds/oot_soh/Options.py b/worlds/oot_soh/Options.py index 4226be638dbd..8b6da3a04ae9 100644 --- a/worlds/oot_soh/Options.py +++ b/worlds/oot_soh/Options.py @@ -888,6 +888,117 @@ class ShuffleTycoonWallet(Toggle): display_name = "Shuffle Tycoon Wallet" +class ShuffleDungeonBossEntrances(Choice): + """ + Shuffle the pool of dungeon boss entrances. This affects the boss rooms of all stone and medallion dungeons + Age Restricted - Shuffle the entrances of child and adult boss rooms separetly. + Full - Shuffle the entrances of all boss rooms together. Child may be expected to defeat Phantom Ganon and/or Bongo Bongo + """ + display_name = "Boss Entrances Shuffle" + option_off = 0 + option_age_restricted = 1 + option_full = 2 + default = 0 + + +class ShuffleOverworldEntrances(Toggle): + """ + Shuffle the pool of Overworld Entrances, which corresponds to almost all loading zones between overworld areas. + + Some Entrances are unshuffled to avoid issues: + - Hyrule Castle Courtyard and Garden Entrance + - Both Market and Back Alley Entrances + - Gerudo Valley to Lake Hylia (unless entrances are decoupled) + """ + display_name = "Shuffle Overworld Entrances" + + +class ShuffleDungeonEntrances(Choice): + """ + Shuffle the pool of dungeon entrances, including Bottom of the Well, Ice Cavern and Gerudo Training Ground. + Shuffling Ganon's Castle can be enabled separately. + Additionally, the entrances of Deku Tree, Fire Temple, Bottom of the Well and Gerudo Training Ground are + opened for both child and adult. + - Deku Tree will be open for adult after Mido has seen child Link with a sword and a shield. + - Bottom of the Well will be open for adult after playing Song of Storms to the Windmill guy as child. + - Gerudo Training Ground will be open for child after adult has paid to open the gate once. + """ + display_name = "Dungeon Entrances Shuffle" + option_off = 0 + option_on = 1 + option_on_plus_ganon = 2 + default = 0 + + +class ShuffleTheivesHideoutEntrances(Toggle): + """ + Shuffle the pool of entrances between Gerudo Fortress & Theives' Hideout + """ + display_name = "Shuffle Theives' Hideout Entrances" + + +class ShuffleGrottoEntrances(Toggle): + """ + Shuffle the pool of grotto entrances, including all graves, small Fairy fountains and Deku Theatre. + """ + display_name = "Grotto Entrances Shuffle" + + +class ShuffleOwlDropEntrances(Toggle): + """ + Randomized where Kaepora Gaebora (the Owl) drops you at when you talk to him at Lake Hylia or at the top of Death Mountain Trail. + """ + display_name = " Shuffle Owl Drop Entrances" + + +class ShuffleWarpSongEntrances(Toggle): + """ + Randomized where each of the 6 warp songs leads to. + """ + display_name = "Shuffle Warp Song Entrances" + + +class ShuffleInteriorEntrances(Choice): + """ + Shuffle the pool of interior entrances which contains most houses and all Great Fairies + All - An extended version of 'Simple' with some extra places: + - Windmill + - Link's House + - Temple of Time + - Kakariko Potion Shop + """ + display_name = "Shuffle Interior Entrances" + option_off = 0 + option_simple = 1 + option_all = 2 + default = 0 + + +class ShuffleOverworldSpawns(Toggle): + """ + Randomized where you start as Child or Adult when loading a save in the Overworld. This means you may not necessarily spawn inside Link's House or Temple of Time. + This stays consistent after saving and loading the game. + Keep in mind you man need to temporarily disable the "Remember Save Location" time saver to be able to use the spawn positions, especially if they are the only logical way to get to certain areas. + """ + display_name = "Shuffle Overworld Spawns" + +#currently doesn't work +class DecoupleEntrances(Toggle): + """ + Decouple entrances when shuffling them. This means that you are no longer guaranteed to end up back where you came from when you go back through an entrance. + This also adds the one way entrance from Gerudo Valley to Lake Hylia in the pool of overworld entrances when they are shuffled. + """ + display_name = "Decouple Entrances" + visibility = Visibility.none + + +class MixedEntrancePools(Toggle): + """ + Shuffle entrances into a mixed pool instead of separate ones. Has no effect on pools whose entrances aren't shuffled, and "Shuffle Boss Entrances" must be set to "Full" to include them. + """ + display_name = "Mixed Entrances Pools" + + @dataclass class SohOptions(PerGameCommonOptions): closed_forest: ClosedForest @@ -976,6 +1087,17 @@ class SohOptions(PerGameCommonOptions): shuffle_tycoon_wallet: ShuffleTycoonWallet tricks_in_logic: TricksInLogic enable_all_tricks: EnableAllTricks + shuffle_dungeon_entrances: ShuffleDungeonEntrances + shuffle_boss_entrances: ShuffleDungeonBossEntrances + shuffle_overworld_entrances: ShuffleOverworldEntrances + shuffle_theives_hideout_entrances: ShuffleTheivesHideoutEntrances + shuffle_grotto_entrances: ShuffleGrottoEntrances + shuffle_warp_song_entrances: ShuffleWarpSongEntrances + shuffle_owl_drop_entrances: ShuffleOwlDropEntrances + shuffle_overworld_spawns: ShuffleOverworldSpawns + shuffle_interior_entrances: ShuffleInteriorEntrances + decouple_entrances: DecoupleEntrances + mixed_entrances_pools: MixedEntrancePools soh_option_groups = [ @@ -1005,17 +1127,19 @@ class SohOptions(PerGameCommonOptions): TriforceHuntPiecesTotal, TriforceHuntPiecesRequiredPercentage, ]), - # OptionGroup("Shuffle Entrances", [ - # # Dungeon Entrances - # # Boss Entrances - # # Overworld Entrances - # # Interior Entrances - # # Grotto Entrances - # # Owl Drops - # # Warp Songs - # # Overworld Spawns - # # Decouple Entrances - # ]), + OptionGroup("Shuffle Entrances", [ + ShuffleDungeonEntrances, + ShuffleDungeonBossEntrances, + ShuffleOverworldEntrances, + ShuffleInteriorEntrances, + ShuffleTheivesHideoutEntrances, + ShuffleGrottoEntrances, + ShuffleWarpSongEntrances, + ShuffleOwlDropEntrances, + ShuffleOverworldSpawns, + DecoupleEntrances, + MixedEntrancePools + ]), OptionGroup("Shuffle Items", [ # Shuffle Songs -- idk if this or the other ones here will be an actual option here, delete if not ShuffleTokens, diff --git a/worlds/oot_soh/__init__.py b/worlds/oot_soh/__init__.py index 2a07c63a863d..860b97ababf4 100644 --- a/worlds/oot_soh/__init__.py +++ b/worlds/oot_soh/__init__.py @@ -3,7 +3,7 @@ from typing import Any, List, ClassVar -from BaseClasses import CollectionState, Item, Tutorial, ItemClassification +from BaseClasses import CollectionState, Item, Tutorial, ItemClassification, Entrance from worlds.AutoWorld import WebWorld, World from .Items import SohItem, item_data_table, item_table, item_name_groups, progressive_items from .Locations import location_table, location_name_groups, token_amounts @@ -19,6 +19,8 @@ from settings import Group, Bool from Options import OptionError from .LogicHelpers import wallet_capacities +from .EntranceShuffle import randomize_entrances_soh, on_connect_soh, randomize_soh_one_way_entrances +from .location_access.overworld.graveyard import connect_dampes_grave_windmill import logging logger = logging.getLogger("SOH_OOT") @@ -65,6 +67,7 @@ class SohWorld(World): item_name_to_id = item_table item_name_groups = item_name_groups location_name_groups = location_name_groups + er_pairings: List[tuple[str, str]] = [] # Universal Tracker stuff, does not do anything in normal gen glitches_item_name = Items.GLITCHED @@ -228,6 +231,91 @@ def set_rules(self) -> None: # Completion condition. self.multiworld.completion_condition[self.player] = lambda state: state.has( Events.GAME_COMPLETED.value, self.player) + + def connect_entrances(self): + # Do quircky one ways separate from the rest + randomize_soh_one_way_entrances(self) + + entrances_to_shuffle = set() + # Reverse decoupled option for randomize_entrances because it is asking if you wanted coupled + # Update this when it is figured out why decoupled doesn't work with the current groupings + coupled = True #(not self.options.decouple_entrances) + + if self.options.shuffle_theives_hideout_entrances: + # Make Temp Entrance to GF_ABOVE_JAIL to appease GER + temp_entrance: Entrance = self.get_region(Regions.ROOT.value).connect(self.get_region(Regions.GF_ABOVE_JAIL.value), "Temp GF_ABOVE_JAIL Entrance", None) + + for entranceName in SOHThievesHideoutEntranceNames: + entrances_to_shuffle.add(entranceName) + randomize_entrances_soh(self, entrances_to_shuffle) + entrances_to_shuffle.clear() + + # Clean up Temp Entrance + temp_entrance.connected_region.entrances.remove(temp_entrance) + temp_entrance.connected_region = None + + # Boss Entrances + if self.options.shuffle_boss_entrances: + for entranceName in SOHBossEntranceNames: + entrances_to_shuffle.add(entranceName) + + if self.options.shuffle_boss_entrances == "age_restricted": + randomize_entrances_soh(self, entrances_to_shuffle, ageRestricted=True) + entrances_to_shuffle.clear() + + # Overworld Entrances + if self.options.shuffle_overworld_entrances: + for entranceName in SOHOverworldEntranceNames: + if not self.options.decouple_entrances and sum(map(bool, [self.options.shuffle_grotto_entrances, self.options.shuffle_interior_entrances, self.options.shuffle_dungeon_entrances, True if self.options.shuffle_boss_entrances == "full" else False])) >= 1 and entranceName == SOHOverworldEntranceNames.LAKE_HYLIA_RIVER_ENTRANCE: + continue + + # ignore our one way exit here + if entranceName == SOHOverworldEntranceNames.LAKE_HYLIA_RIVER_EXIT: + continue + + entrances_to_shuffle.add(entranceName) + + # Grotto Entrances + if self.options.shuffle_grotto_entrances: + for entranceName in SOHGrottoExitNames: + entrances_to_shuffle.add(entranceName) + + for entranceName in SOHGrottoEntranceNames: + entrances_to_shuffle.add(entranceName) + + # Interior Entrances + if self.options.shuffle_interior_entrances: + if self.options.shuffle_interior_entrances == "all": + for entranceName in SOHSpecialInteriorExitNames: + entrances_to_shuffle.add(entranceName) + + for entranceName in SOHSpecialInteriorEntranceNames: + entrances_to_shuffle.add(entranceName) + + for entranceName in SOHInteriorExitNames: + entrances_to_shuffle.add(entranceName) + + for entranceName in SOHInteriorEntranceNames: + entrances_to_shuffle.add(entranceName) + + # Dungeon Entrances + if self.options.shuffle_dungeon_entrances: + for entranceName in SOHDungeonExitNames: + if entranceName != SOHDungeonExitNames.GANONS_CASTLE_DUNGEON_EXIT or self.options.shuffle_dungeon_entrances == 2: + entrances_to_shuffle.add(entranceName) + + for entranceName in SOHDungeonEntranceNames: + if entranceName != SOHDungeonEntranceNames.GANONS_CASTLE_DUNGEON_ENTRANCE or self.options.shuffle_dungeon_entrances == 2: + entrances_to_shuffle.add(entranceName) + + if len(entrances_to_shuffle) > 0: + randomize_entrances_soh( + self, entrances_to_shuffle, on_connect_soh, coupled) + + # Connect Dampes After randomization so GER doesn't get any funny ideas + connect_dampes_grave_windmill(self) + + return super().connect_entrances() def collect(self, state: CollectionState, item: Item) -> bool: changed = super().collect(state, item) @@ -275,11 +363,11 @@ def remove(self, state: CollectionState, item: Item) -> bool: return changed # For debugging purposes - # def generate_output(self, output_directory: str): - # from Utils import visualize_regions - # visualize_regions(self.get_region(self.origin_region_name), f"SOH-Player{self.player}.puml", - # show_entrance_names=True, - # regions_to_highlight=self.multiworld.get_all_state().reachable_regions[self.player]) + def generate_output(self, output_directory: str): + from Utils import visualize_regions + visualize_regions(self.get_region(self.origin_region_name), f"SOH-Player{self.player}.puml", + show_entrance_names=True, + regions_to_highlight=self.multiworld.get_all_state().reachable_regions[self.player]) def fill_slot_data(self) -> dict[str, Any]: return { @@ -366,4 +454,5 @@ def fill_slot_data(self) -> dict[str, Any]: "apworld_version": self.apworld_version, "enable_all_tricks": self.options.enable_all_tricks.value, "tricks_in_logic": self.options.tricks_in_logic.value + # Need to figure out how to get the randomized entrances to Ship } diff --git a/worlds/oot_soh/location_access/dungeons/bottom_of_the_well.py b/worlds/oot_soh/location_access/dungeons/bottom_of_the_well.py index b322bff9246f..e962936e4b39 100644 --- a/worlds/oot_soh/location_access/dungeons/bottom_of_the_well.py +++ b/worlds/oot_soh/location_access/dungeons/bottom_of_the_well.py @@ -26,7 +26,8 @@ def set_region_rules(world: "SohWorld") -> None: (Regions.BOTTOM_OF_THE_WELL_PERIMETER, lambda bundle: is_child( bundle) and can_pass_enemy(bundle, Enemies.BIG_SKULLTULA)), # [Regions.BOTTOM_OF_THE_WELL_MQ_PERIMETER, lambda bundle: is_child(bundle), - (Regions.KAK_WELL, lambda bundle: True) + (Regions.KAK_WELL, lambda bundle: True, SOHDungeonExitNames.BOTTOM_OF_THE_WELL_DUNGEON_EXIT, + SOHEntranceGroups.DUNGEON_ENTRANCE | SOHEntranceGroups.CHILD_ONLY, EntranceType.TWO_WAY) ]) # Bottom of the Well Perimeter diff --git a/worlds/oot_soh/location_access/dungeons/deku_tree.py b/worlds/oot_soh/location_access/dungeons/deku_tree.py index 27d533cd8606..ae3b4c916020 100644 --- a/worlds/oot_soh/location_access/dungeons/deku_tree.py +++ b/worlds/oot_soh/location_access/dungeons/deku_tree.py @@ -30,7 +30,8 @@ def set_region_rules(world: "SohWorld") -> None: # Connections connect_regions(Regions.DEKU_TREE_ENTRYWAY, world, [ (Regions.DEKU_TREE_LOBBY, lambda bundle: True), - (Regions.KF_OUTSIDE_DEKU_TREE, lambda bundle: True) + (Regions.KF_OUTSIDE_DEKU_TREE, lambda bundle: True, SOHDungeonExitNames.DEKU_TREE_DUNGEON_EXIT, + SOHEntranceGroups.DUNGEON_ENTRANCE | SOHEntranceGroups.CHILD, EntranceType.TWO_WAY) ]) # Deku Lobby @@ -277,7 +278,7 @@ def set_region_rules(world: "SohWorld") -> None: connect_regions(Regions.DEKU_TREE_OUTSIDE_BOSS_ROOM, world, [ (Regions.DEKU_TREE_BASEMENT_UPPER, lambda bundle: True), (Regions.DEKU_TREE_BOSS_ENTRYWAY, lambda bundle: (has_item(Items.BRONZE_SCALE, bundle) or can_use(Items.IRON_BOOTS, bundle)) - and can_reflect_nuts(bundle)) + and can_reflect_nuts(bundle), SOHBossEntranceNames.DEKU_TREE_BOSS_ENTRANCE, SOHEntranceGroups.BOSS_ENTRANCE | SOHEntranceGroups.CHILD, EntranceType.ONE_WAY) ]) # Skipping master quest for now @@ -328,5 +329,5 @@ def set_region_rules(world: "SohWorld") -> None: connect_regions(Regions.DEKU_TREE_BOSS_ROOM, world, [ (Regions.DEKU_TREE_BOSS_EXIT, lambda bundle: True), (Regions.KF_OUTSIDE_DEKU_TREE, lambda bundle: has_item( - Events.DEKU_TREE_COMPLETED, bundle)) + Events.DEKU_TREE_COMPLETED, bundle), SOHBossWarpEntranceNames.DEKU_TREE_BOSS_WARP_ENTRANCE, SOHEntranceGroups.OTHER, EntranceType.ONE_WAY) ]) diff --git a/worlds/oot_soh/location_access/dungeons/dodongos_cavern.py b/worlds/oot_soh/location_access/dungeons/dodongos_cavern.py index bf93b67b0714..58659bbeff36 100644 --- a/worlds/oot_soh/location_access/dungeons/dodongos_cavern.py +++ b/worlds/oot_soh/location_access/dungeons/dodongos_cavern.py @@ -26,9 +26,9 @@ def set_region_rules(world: "SohWorld") -> None: # Connections connect_regions(Regions.DODONGOS_CAVERN_ENTRYWAY, world, [ (Regions.DODONGOS_CAVERN_BEGINNING, lambda bundle: True), - (Regions.DEATH_MOUNTAIN_TRAIL, lambda bundle: True), + (Regions.DEATH_MOUNTAIN_TRAIL, lambda bundle: True, SOHDungeonExitNames.DODONGOS_CAVERN_DUNGEON_EXIT, + SOHEntranceGroups.DUNGEON_ENTRANCE | SOHEntranceGroups.ADULT, EntranceType.TWO_WAY), ]) - # Dodongos Cavern Beginning # Connections connect_regions(Regions.DODONGOS_CAVERN_BEGINNING, world, [ @@ -70,7 +70,7 @@ def set_region_rules(world: "SohWorld") -> None: lambda bundle: has_item(LocalEvents.DODONGOS_CAVERN_LIFT_PLATFORM, bundle)), (Regions.DODONGOS_CAVERN_BOSS_REGION, lambda bundle: has_item( LocalEvents.DODONGOS_CAVERN_EYES_LIT, bundle)), - (Regions.DODONGOS_CAVERN_BOSS_ENTRYWAY, lambda bundle: False), + # (Regions.DODONGOS_CAVERN_BOSS_ENTRYWAY, lambda bundle: False), ]) # Dodongos Cavern Lobby Switch @@ -402,7 +402,8 @@ def set_region_rules(world: "SohWorld") -> None: (Regions.DODONGOS_CAVERN_LOBBY, lambda bundle: True), (Regions.DODONGOS_CAVERN_BACK_ROOM, lambda bundle: can_break_mud_walls(bundle)), - (Regions.DODONGOS_CAVERN_BOSS_ENTRYWAY, lambda bundle: True), + (Regions.DODONGOS_CAVERN_BOSS_ENTRYWAY, lambda bundle: True, SOHBossEntranceNames.DODONGOS_CAVERN_BOSS_ENTRANCE, + SOHEntranceGroups.BOSS_ENTRANCE | SOHEntranceGroups.CHILD, EntranceType.ONE_WAY), ]) # Dodongos Cavern Back Room @@ -453,5 +454,5 @@ def set_region_rules(world: "SohWorld") -> None: connect_regions(Regions.DODONGOS_CAVERN_BOSS_ROOM, world, [ (Regions.DODONGOS_CAVERN_BOSS_EXIT, lambda bundle: True), (Regions.DEATH_MOUNTAIN_TRAIL, lambda bundle: has_item( - Events.DODONGOS_CAVERN_COMPLETED, bundle)), + Events.DODONGOS_CAVERN_COMPLETED, bundle), SOHBossWarpEntranceNames.DODONGOS_CAVERN_BOSS_WARP_ENTRANCE, SOHEntranceGroups.OTHER, EntranceType.ONE_WAY), ]) diff --git a/worlds/oot_soh/location_access/dungeons/fire_temple.py b/worlds/oot_soh/location_access/dungeons/fire_temple.py index bc3a5f927416..be0e5a571522 100644 --- a/worlds/oot_soh/location_access/dungeons/fire_temple.py +++ b/worlds/oot_soh/location_access/dungeons/fire_temple.py @@ -23,7 +23,8 @@ def set_region_rules(world: "SohWorld") -> None: # Connections connect_regions(Regions.FIRE_TEMPLE_ENTRYWAY, world, [ (Regions.FIRE_TEMPLE_FIRST_ROOM, lambda bundle: True), - (Regions.DMC_CENTRAL_LOCAL, lambda bundle: True) + (Regions.DMC_CENTRAL_LOCAL, lambda bundle: True, SOHDungeonExitNames.FIRE_TEMPLE_DUNGEON_EXIT, + SOHEntranceGroups.DUNGEON_ENTRANCE | SOHEntranceGroups.ADULT, EntranceType.TWO_WAY) ]) # Fire Temple First Room @@ -68,7 +69,7 @@ def set_region_rules(world: "SohWorld") -> None: (is_adult(bundle) and (can_do_trick(Tricks.FIRE_BOSS_DOOR_JUMP, bundle) or has_item(LocalEvents.FIRE_TEMPLE_FIRE_MAZE_UPPER_PLATFORM_HIT, bundle) or - can_use(Items.HOVER_BOOTS, bundle)))) + can_use(Items.HOVER_BOOTS, bundle))), SOHBossEntranceNames.FIRE_TEMPLE_BOSS_ENTRANCE, SOHEntranceGroups.BOSS_ENTRANCE | SOHEntranceGroups.ADULT_ONLY, EntranceType.ONE_WAY) ]) # Fire Temple Loop Enemies @@ -554,5 +555,5 @@ def set_region_rules(world: "SohWorld") -> None: connect_regions(Regions.FIRE_TEMPLE_BOSS_ROOM, world, [ (Regions.FIRE_TEMPLE_BOSS_ENTRYWAY, lambda bundle: False), (Regions.DMC_CENTRAL_LOCAL, lambda bundle: has_item( - Events.FIRE_TEMPLE_COMPLETED, bundle)) + Events.FIRE_TEMPLE_COMPLETED, bundle), SOHBossWarpEntranceNames.FIRE_TEMPLE_BOSS_WARP_ENTRANCE, SOHEntranceGroups.OTHER, EntranceType.ONE_WAY) ]) diff --git a/worlds/oot_soh/location_access/dungeons/forest_temple.py b/worlds/oot_soh/location_access/dungeons/forest_temple.py index 86a8548042c1..56dfa3ccb793 100644 --- a/worlds/oot_soh/location_access/dungeons/forest_temple.py +++ b/worlds/oot_soh/location_access/dungeons/forest_temple.py @@ -36,7 +36,8 @@ def set_region_rules(world: "SohWorld") -> None: connect_regions(Regions.FOREST_TEMPLE_ENTRYWAY, world, [ # Todo: Change this when we have IsVanilla vs. IsMQ (Regions.FOREST_TEMPLE_FIRST_ROOM, lambda bundle: True), - (Regions.SACRED_FOREST_MEADOW, lambda bundle: True) + (Regions.SACRED_FOREST_MEADOW, lambda bundle: True, SOHDungeonExitNames.FOREST_TEMPLE_DUNGEON_EXIT, + SOHEntranceGroups.DUNGEON_ENTRANCE | SOHEntranceGroups.ADULT, EntranceType.TWO_WAY) ]) # Forest Temple First Room @@ -510,7 +511,8 @@ def set_region_rules(world: "SohWorld") -> None: # Connections connect_regions(Regions.FOREST_TEMPLE_BOSS_REGION, world, [ (Regions.FOREST_TEMPLE_LOBBY, lambda bundle: True), - (Regions.FOREST_TEMPLE_BOSS_ENTRYWAY, lambda bundle: True) + (Regions.FOREST_TEMPLE_BOSS_ENTRYWAY, lambda bundle: True, SOHBossEntranceNames.FOREST_TEMPLE_BOSS_ENTRANCE, + SOHEntranceGroups.BOSS_ENTRANCE | SOHEntranceGroups.ADULT, EntranceType.ONE_WAY) ]) # Forest Temple Boss Entryway @@ -539,5 +541,5 @@ def set_region_rules(world: "SohWorld") -> None: connect_regions(Regions.FOREST_TEMPLE_BOSS_ROOM, world, [ (Regions.FOREST_TEMPLE_BOSS_ENTRYWAY, lambda bundle: False), (Regions.SACRED_FOREST_MEADOW, lambda bundle: has_item( - Events.FOREST_TEMPLE_COMPLETED, bundle)) + Events.FOREST_TEMPLE_COMPLETED, bundle), SOHBossWarpEntranceNames.FOREST_TEMPLE_BOSS_WARP_ENTRANCE, SOHEntranceGroups.OTHER, EntranceType.ONE_WAY) ]) diff --git a/worlds/oot_soh/location_access/dungeons/ganons_castle.py b/worlds/oot_soh/location_access/dungeons/ganons_castle.py index c96d9905a74c..c7e99516d5c9 100644 --- a/worlds/oot_soh/location_access/dungeons/ganons_castle.py +++ b/worlds/oot_soh/location_access/dungeons/ganons_castle.py @@ -32,7 +32,8 @@ def set_region_rules(world: "SohWorld") -> None: # Connections connect_regions(Regions.GANONS_CASTLE_ENTRYWAY, world, [ (Regions.GANONS_CASTLE_LOBBY, lambda bundle: True), - (Regions.CASTLE_GROUNDS_FROM_GANONS_CASTLE, lambda bundle: True) + (Regions.GANONS_CASTLE_LEDGE, lambda bundle: True, + SOHDungeonExitNames.GANONS_CASTLE_DUNGEON_EXIT, SOHEntranceGroups.DUNGEON_ENTRANCE | SOHEntranceGroups.ADULT, EntranceType.TWO_WAY) ]) # Ganon's Castle Lobby diff --git a/worlds/oot_soh/location_access/dungeons/gerudo_training_ground.py b/worlds/oot_soh/location_access/dungeons/gerudo_training_ground.py index 400913076c01..5e426135db73 100644 --- a/worlds/oot_soh/location_access/dungeons/gerudo_training_ground.py +++ b/worlds/oot_soh/location_access/dungeons/gerudo_training_ground.py @@ -9,7 +9,8 @@ def set_region_rules(world: "SohWorld") -> None: # Connections connect_regions(Regions.GERUDO_TRAINING_GROUND_ENTRYWAY, world, [ (Regions.GERUDO_TRAINING_GROUND_LOBBY, lambda bundle: True), - (Regions.GF_EXITING_GTG, lambda bundle: True), + (Regions.GF_TO_GTG, lambda bundle: True, SOHDungeonExitNames.GERUDO_TRAINING_GROUND_DUNGEON_EXIT, + SOHEntranceGroups.DUNGEON_ENTRANCE | SOHEntranceGroups.ADULT, EntranceType.TWO_WAY), ]) # Gerudo Training Ground Lobby diff --git a/worlds/oot_soh/location_access/dungeons/ice_cavern.py b/worlds/oot_soh/location_access/dungeons/ice_cavern.py index 9c85c02ccf4a..01ccf2dfb0ba 100644 --- a/worlds/oot_soh/location_access/dungeons/ice_cavern.py +++ b/worlds/oot_soh/location_access/dungeons/ice_cavern.py @@ -12,13 +12,12 @@ class EventLocations(StrEnum): def set_region_rules(world: "SohWorld") -> None: # Ice Cavern Entryway - # Locations - add_locations(Regions.ICE_CAVERN_ENTRYWAY, world, []) # Connections connect_regions(Regions.ICE_CAVERN_ENTRYWAY, world, [ (Regions.ICE_CAVERN_BEGINNING, lambda bundle: True), # Skipping MQ - (Regions.ZF_LEDGE, lambda bundle: True) + (Regions.ZF_LEDGE, lambda bundle: True, SOHDungeonExitNames.ICE_CAVERN_DUNGEON_EXIT, + SOHEntranceGroups.DUNGEON_ENTRANCE | SOHEntranceGroups.ADULT, EntranceType.TWO_WAY) ]) # Ice Cavern Beginning diff --git a/worlds/oot_soh/location_access/dungeons/jabujabus_belly.py b/worlds/oot_soh/location_access/dungeons/jabujabus_belly.py index fcc01392fe5d..09c4d54c9ec1 100644 --- a/worlds/oot_soh/location_access/dungeons/jabujabus_belly.py +++ b/worlds/oot_soh/location_access/dungeons/jabujabus_belly.py @@ -31,7 +31,8 @@ def set_region_rules(world: "SohWorld") -> None: connect_regions(Regions.JABU_JABUS_BELLY_ENTRYWAY, world, [ # TODO: Add vanilla/MQ check (Regions.JABU_JABUS_BELLY_BEGINNING, lambda bundle: True), - (Regions.ZORAS_FOUNTAIN, lambda bundle: True) + (Regions.ZORAS_FOUNTAIN, lambda bundle: True, SOHDungeonExitNames.JABU_JABUS_DUNGEON_EXIT, + SOHEntranceGroups.DUNGEON_ENTRANCE | SOHEntranceGroups.CHILD, EntranceType.TWO_WAY) ]) # Jabu Jabu's Belly Beginning @@ -245,7 +246,7 @@ def set_region_rules(world: "SohWorld") -> None: connect_regions(Regions.JABU_JABUS_BELLY_NEAR_BOSS_ROOM, world, [ (Regions.JABU_JABUS_BELLY_MAIN, lambda bundle: True), (Regions.JABU_JABUS_BELLY_BOSS_ENTRYWAY, lambda bundle: can_use(Items.BOOMERANG, bundle) or (can_do_trick(Tricks.JABU_NEAR_BOSS_RANGED, bundle) and can_use_any([Items.HOOKSHOT, Items.FAIRY_BOW, Items.FAIRY_SLINGSHOT], bundle)) or ( - can_do_trick(Tricks.JABU_NEAR_BOSS_EXPLOSIVES, bundle) and (can_use(Items.BOMBCHUS_5, bundle) or (can_use(Items.HOVER_BOOTS, bundle) and can_use(Items.BOMB_BAG, bundle))))) + can_do_trick(Tricks.JABU_NEAR_BOSS_EXPLOSIVES, bundle) and (can_use(Items.BOMBCHUS_5, bundle) or (can_use(Items.HOVER_BOOTS, bundle) and can_use(Items.BOMB_BAG, bundle)))), SOHBossEntranceNames.JABU_JABUS_BOSS_ENTRANCE, SOHEntranceGroups.BOSS_ENTRANCE | SOHEntranceGroups.CHILD_ONLY, EntranceType.ONE_WAY) ]) # Skipping master quest for now @@ -292,5 +293,5 @@ def set_region_rules(world: "SohWorld") -> None: connect_regions(Regions.JABU_JABUS_BELLY_BOSS_ROOM, world, [ # (Regions.JABU_JABUS_BELLY_BOSS_EXIT, lambda bundle: False), # readd for MQ stuff (Regions.ZORAS_FOUNTAIN, lambda bundle: has_item( - Events.JABU_JABUS_BELLY_COMPLETED, bundle)) + Events.JABU_JABUS_BELLY_COMPLETED, bundle), SOHBossWarpEntranceNames.JABU_JABUS_BOSS_WARP_ENTRANCE, SOHEntranceGroups.OTHER, EntranceType.ONE_WAY) ]) diff --git a/worlds/oot_soh/location_access/dungeons/shadow_temple.py b/worlds/oot_soh/location_access/dungeons/shadow_temple.py index f31a86e78ab8..c075ca9ae6e7 100644 --- a/worlds/oot_soh/location_access/dungeons/shadow_temple.py +++ b/worlds/oot_soh/location_access/dungeons/shadow_temple.py @@ -16,7 +16,8 @@ def set_region_rules(world: "SohWorld") -> None: connect_regions(Regions.SHADOW_TEMPLE_ENTRYWAY, world, [ (Regions.SHADOW_TEMPLE_BEGINNING, lambda bundle: (can_do_trick(Tricks.LENS_SHADOW, bundle) or can_use( Items.LENS_OF_TRUTH, bundle)) and (can_use(Items.HOVER_BOOTS, bundle) or can_use(Items.HOOKSHOT, bundle))), - (Regions.GRAVEYARD_WARP_PAD_REGION, lambda bundle: True) + (Regions.GRAVEYARD_WARP_PAD_REGION, lambda bundle: True, + SOHDungeonExitNames.SHADOW_TEMPLE_DUNGEON_EXIT, SOHEntranceGroups.DUNGEON_ENTRANCE | SOHEntranceGroups.ADULT_ONLY, EntranceType.TWO_WAY) ]) # Shadow Temple Beginning @@ -177,8 +178,8 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.SHADOW_TEMPLE_BEYOND_BOAT, world, [ - (Regions.SHADOW_TEMPLE_BOSS_ENTRYWAY, lambda bundle: (can_use(Items.FAIRY_BOW, bundle) or can_use(Items.DISTANT_SCARECROW, bundle) or (can_do_trick( - Tricks.SHADOW_STATUE, bundle) and can_use(Items.BOMBCHUS_5, bundle))) and small_keys(Items.SHADOW_TEMPLE_SMALL_KEY, 5, bundle) and can_use(Items.HOVER_BOOTS, bundle)), + (Regions.SHADOW_TEMPLE_BOSS_ENTRYWAY, lambda bundle: (can_use(Items.FAIRY_BOW, bundle) or can_use(Items.DISTANT_SCARECROW, bundle) or (can_do_trick(Tricks.SHADOW_STATUE, bundle) and can_use(Items.BOMBCHUS_5, bundle))) + and small_keys(Items.SHADOW_TEMPLE_SMALL_KEY, 5, bundle) and can_use(Items.HOVER_BOOTS, bundle), SOHBossEntranceNames.SHADOW_TEMPLE_BOSS_ENTRANCE, SOHEntranceGroups.BOSS_ENTRANCE | SOHEntranceGroups.ADULT, EntranceType.ONE_WAY), ]) # Shadow Temple Boss Entryway @@ -206,5 +207,5 @@ def set_region_rules(world: "SohWorld") -> None: connect_regions(Regions.SHADOW_TEMPLE_BOSS_ROOM, world, [ (Regions.SHADOW_TEMPLE_BOSS_ENTRYWAY, lambda bundle: False), (Regions.GRAVEYARD_WARP_PAD_REGION, lambda bundle: has_item( - Events.SHADOW_TEMPLE_COMPLETED, bundle)) + Events.SHADOW_TEMPLE_COMPLETED, bundle), SOHBossWarpEntranceNames.SHADOW_TEMPLE_BOSS_WARP_ENTRANCE, SOHEntranceGroups.OTHER, EntranceType.ONE_WAY) ]) diff --git a/worlds/oot_soh/location_access/dungeons/spirit_temple.py b/worlds/oot_soh/location_access/dungeons/spirit_temple.py index c03e244ee36d..2adcd28de205 100644 --- a/worlds/oot_soh/location_access/dungeons/spirit_temple.py +++ b/worlds/oot_soh/location_access/dungeons/spirit_temple.py @@ -14,7 +14,8 @@ def set_region_rules(world: "SohWorld") -> None: # Connections connect_regions(Regions.SPIRIT_TEMPLE_ENTRYWAY, world, [ (Regions.SPIRIT_TEMPLE_LOBBY, lambda bundle: True), - (Regions.DESERT_COLOSSUS_OUTSIDE_TEMPLE, lambda bundle: True) + (Regions.DESERT_COLOSSUS, lambda bundle: True, SOHDungeonExitNames.SPIRIT_TEMPLE_DUNGEON_EXIT, + SOHEntranceGroups.DUNGEON_ENTRANCE | SOHEntranceGroups.BOTH_AGE, EntranceType.TWO_WAY) ]) # Spirit Temple Lobby @@ -203,7 +204,8 @@ def set_region_rules(world: "SohWorld") -> None: # Connections connect_regions(Regions.SPIRIT_TEMPLE_INSIDE_STATUE_HEAD, world, [ (Regions.SPIRIT_TEMPLE_CENTRAL_CHAMBER, lambda bundle: True), - (Regions.SPIRIT_TEMPLE_BOSS_ENTRYWAY, lambda bundle: True) + (Regions.SPIRIT_TEMPLE_BOSS_ENTRYWAY, lambda bundle: True, SOHBossEntranceNames.SPIRIT_TEMPLE_BOSS_ENTRANCE, + SOHEntranceGroups.BOSS_ENTRANCE | SOHEntranceGroups.ADULT_ONLY, EntranceType.ONE_WAY) ]) # Spirit Temple Boss Entryway @@ -231,5 +233,5 @@ def set_region_rules(world: "SohWorld") -> None: connect_regions(Regions.SPIRIT_TEMPLE_BOSS_ROOM, world, [ (Regions.SPIRIT_TEMPLE_BOSS_ENTRYWAY, lambda bundle: False), (Regions.DESERT_COLOSSUS, lambda bundle: has_item( - Events.SPIRIT_TEMPLE_COMPLETED, bundle)) + Events.SPIRIT_TEMPLE_COMPLETED, bundle), SOHBossWarpEntranceNames.SPIRIT_TEMPLE_BOSS_WARP_ENTRANCE, SOHEntranceGroups.OTHER, EntranceType.ONE_WAY) ]) diff --git a/worlds/oot_soh/location_access/dungeons/water_temple.py b/worlds/oot_soh/location_access/dungeons/water_temple.py index aba8ea48f3d8..c91a3ad6983a 100644 --- a/worlds/oot_soh/location_access/dungeons/water_temple.py +++ b/worlds/oot_soh/location_access/dungeons/water_temple.py @@ -25,7 +25,8 @@ def set_region_rules(world: "SohWorld") -> None: connect_regions(Regions.WATER_TEMPLE_ENTRYWAY, world, [ (Regions.WATER_TEMPLE_LOBBY, lambda bundle: ( has_item(Items.BRONZE_SCALE, bundle))), - (Regions.LH_FROM_WATER_TEMPLE, lambda bundle: True) + (Regions.LH_FROM_WATER_TEMPLE, lambda bundle: True, SOHDungeonExitNames.WATER_TEMPLE_DUNGEON_EXIT, + SOHEntranceGroups.DUNGEON_ENTRANCE | SOHEntranceGroups.ADULT, EntranceType.TWO_WAY) ]) # Water Temple Lobby @@ -559,7 +560,8 @@ def set_region_rules(world: "SohWorld") -> None: # Connections connect_regions(Regions.WATER_TEMPLE_PRE_BOSS_ROOM, world, [ (Regions.WATER_TEMPLE_LOBBY, lambda bundle: True), - (Regions.WATER_TEMPLE_BOSS_ENTRYWAY, lambda bundle: True) + (Regions.WATER_TEMPLE_BOSS_ENTRYWAY, lambda bundle: True, SOHBossEntranceNames.WATER_TEMPLE_BOSS_ENTRANCE, + SOHEntranceGroups.BOSS_ENTRANCE | SOHEntranceGroups.ADULT_ONLY, EntranceType.ONE_WAY) ]) # Water Temple Boss Entryway @@ -587,5 +589,5 @@ def set_region_rules(world: "SohWorld") -> None: connect_regions(Regions.WATER_TEMPLE_BOSS_ROOM, world, [ (Regions.WATER_TEMPLE_BOSS_ENTRYWAY, lambda bundle: False), (Regions.LAKE_HYLIA, lambda bundle: has_item( - Events.WATER_TEMPLE_COMPLETED, bundle)) + Events.WATER_TEMPLE_COMPLETED, bundle), SOHBossWarpEntranceNames.WATER_TEMPLE_BOSS_WARP_ENTRANCE, SOHEntranceGroups.OTHER, EntranceType.ONE_WAY) ]) diff --git a/worlds/oot_soh/location_access/overworld/castle_grounds.py b/worlds/oot_soh/location_access/overworld/castle_grounds.py index ac8a82ab8a97..3e55a4e72f34 100644 --- a/worlds/oot_soh/location_access/overworld/castle_grounds.py +++ b/worlds/oot_soh/location_access/overworld/castle_grounds.py @@ -23,7 +23,7 @@ def set_region_rules(world: "SohWorld") -> None: # Castle Grounds # Connections connect_regions(Regions.CASTLE_GROUNDS, world, [ - (Regions.MARKET, lambda bundle: True), + (Regions.MARKET, lambda bundle: True, SOHOverworldEntranceNames.CASTLE_GROUNDS_SOUTH_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), (Regions.HYRULE_CASTLE_GROUNDS, lambda bundle: is_child(bundle)), (Regions.GANONS_CASTLE_GROUNDS, lambda bundle: is_adult(bundle)) ]) @@ -68,8 +68,8 @@ def set_region_rules(world: "SohWorld") -> None: # Connections connect_regions(Regions.HYRULE_CASTLE_GROUNDS, world, [ (Regions.CASTLE_GROUNDS, lambda bundle: True), - (Regions.HC_GREAT_FAIRY_FOUNTAIN, lambda bundle: blast_or_smash(bundle)), - (Regions.HC_STORMS_GROTTO, lambda bundle: can_open_storms_grotto(bundle)) + (Regions.HC_GREAT_FAIRY_FOUNTAIN, lambda bundle: blast_or_smash(bundle), SOHInteriorEntranceNames.HC_GREAT_FAIRY_FOUNTAIN_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.CHILD_ONLY), + (Regions.HC_STORMS_GROTTO, lambda bundle: can_open_storms_grotto(bundle), SOHGrottoEntranceNames.HC_STORMS_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.CHILD_ONLY) ]) if not world.options.skip_child_zelda: connect_regions(Regions.HYRULE_CASTLE_GROUNDS, world, [ @@ -103,13 +103,13 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.HC_GREAT_FAIRY_FOUNTAIN, world, [ - (Regions.CASTLE_GROUNDS, lambda bundle: True) + (Regions.CASTLE_GROUNDS, lambda bundle: True, SOHInteriorExitNames.HC_GREAT_FAIRY_FOUNTAIN_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE) ]) # Hyrule Castle Storms Grotto # Connections connect_regions(Regions.HC_STORMS_GROTTO, world, [ - (Regions.CASTLE_GROUNDS, lambda bundle: True), + (Regions.CASTLE_GROUNDS, lambda bundle: True, SOHGrottoExitNames.HC_STORMS_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), (Regions.HC_STORMS_GROTTO_BEHIND_WALLS, lambda bundle: can_break_mud_walls(bundle)), (Regions.HC_STORMS_SKULLTULA, lambda bundle: can_use( @@ -168,7 +168,7 @@ def set_region_rules(world: "SohWorld") -> None: connect_regions(Regions.GANONS_CASTLE_GROUNDS, world, [ (Regions.CASTLE_GROUNDS, lambda bundle: at_night(bundle)), (Regions.OGC_GREAT_FAIRY_FOUNTAIN, lambda bundle: can_use( - Items.GOLDEN_GAUNTLETS, bundle) and at_night(bundle)), + Items.GOLDEN_GAUNTLETS, bundle) and at_night(bundle), SOHInteriorEntranceNames.OGC_GREAT_FAIRY_FOUNTAIN_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ADULT_ONLY), (Regions.GANONS_CASTLE_LEDGE, lambda bundle: has_item( LocalEvents.HC_OGC_RAINBOW_BRIDGE_BUILT, bundle)) ]) @@ -181,20 +181,23 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.OGC_GREAT_FAIRY_FOUNTAIN, world, [ - (Regions.CASTLE_GROUNDS, lambda bundle: True) + (Regions.CASTLE_GROUNDS, lambda bundle: True, SOHInteriorExitNames.OGC_GREAT_FAIRY_FOUNTAIN_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE) ]) - # Castle Grounds from Ganon's Castle - # Connections - connect_regions(Regions.CASTLE_GROUNDS_FROM_GANONS_CASTLE, world, [ - (Regions.HYRULE_CASTLE_GROUNDS, lambda bundle: is_child(bundle)), - (Regions.GANONS_CASTLE_LEDGE, lambda bundle: is_adult(bundle)) - ]) + # Deviation from Ship, but makes ER easier + # # Castle Grounds from Ganon's Castle + # # Connections + # connect_regions(Regions.CASTLE_GROUNDS_FROM_GANONS_CASTLE, world, [ + # (Regions.HYRULE_CASTLE_GROUNDS, lambda bundle: is_child(bundle)), + # (Regions.GANONS_CASTLE_LEDGE, lambda bundle: is_adult(bundle)) + # ]) # Ganon's Castle Ledge # Connections connect_regions(Regions.GANONS_CASTLE_LEDGE, world, [ - (Regions.GANONS_CASTLE_GROUNDS, lambda bundle: has_item( - LocalEvents.HC_OGC_RAINBOW_BRIDGE_BUILT, bundle)), - (Regions.GANONS_CASTLE_ENTRYWAY, lambda bundle: is_adult(bundle)) + (Regions.GANONS_CASTLE_GROUNDS, lambda bundle: is_adult(bundle) + and has_item(LocalEvents.HC_OGC_RAINBOW_BRIDGE_BUILT, bundle)), + (Regions.HYRULE_CASTLE_GROUNDS, lambda bundle: is_child(bundle)), + (Regions.GANONS_CASTLE_ENTRYWAY, lambda bundle: is_adult(bundle), + SOHDungeonEntranceNames.GANONS_CASTLE_DUNGEON_ENTRANCE, SOHEntranceGroups.DUNGEON_ENTRANCE | SOHEntranceGroups.ADULT_ONLY, EntranceType.TWO_WAY) ]) diff --git a/worlds/oot_soh/location_access/overworld/death_mountain_crater.py b/worlds/oot_soh/location_access/overworld/death_mountain_crater.py index 40831fca872f..579ea22671d0 100644 --- a/worlds/oot_soh/location_access/overworld/death_mountain_crater.py +++ b/worlds/oot_soh/location_access/overworld/death_mountain_crater.py @@ -23,9 +23,9 @@ def set_region_rules(world: "SohWorld") -> None: # Connections connect_regions(Regions.DMC_UPPER_NEARBY, world, [ (Regions.DMC_UPPER_LOCAL, lambda bundle: fire_timer(bundle) >= 48), - (Regions.DEATH_MOUNTAIN_SUMMIT, lambda bundle: True), + (Regions.DEATH_MOUNTAIN_SUMMIT, lambda bundle: True, SOHOverworldEntranceNames.DEATH_MOUNTAIN_CRATER_UPPER_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), (Regions.DMC_UPPER_GROTTO, lambda bundle: blast_or_smash( - bundle) and (fire_timer(bundle) >= 8 or hearts(bundle) >= 3)), + bundle) and (fire_timer(bundle) >= 8 or hearts(bundle) >= 3), SOHGrottoEntranceNames.DMC_UPPER_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), ]) # Death Mountain Crater Upper Local @@ -52,9 +52,8 @@ def set_region_rules(world: "SohWorld") -> None: (Regions.DMC_UPPER_NEARBY, lambda bundle: True), (Regions.DMC_LADDER_REGION_NEARBY, lambda bundle: fire_timer( bundle) >= 16 or hearts(bundle) >= 3), - (Regions.DMC_CENTRAL_NEARBY, lambda bundle: is_adult(bundle) and can_use(Items.GORON_TUNIC, bundle) and can_use(Items.DISTANT_SCARECROW, bundle) and (effective_health( - # TODO Implement Dungeon Shuffle Option to replace False - bundle) > 2 or (can_use(Items.BOTTLE_WITH_FAIRY, bundle) and False or can_use(Items.NAYRUS_LOVE, bundle)))), + (Regions.DMC_CENTRAL_NEARBY, lambda bundle: is_adult(bundle) and can_use(Items.GORON_TUNIC, bundle) and can_use(Items.DISTANT_SCARECROW, bundle) and ( + effective_health(bundle) > 2 or (can_use(Items.BOTTLE_WITH_FAIRY, bundle) and world.options.shuffle_dungeon_entrances.value > 0) or can_use(Items.NAYRUS_LOVE, bundle))), (Regions.DMC_LOWER_NEARBY, lambda bundle: False), (Regions.DMC_DISTANT_PLATFORM, lambda bundle: (fire_timer( bundle) >= 48 or hearts(bundle) >= 2) or hearts(bundle) >= 3), @@ -84,11 +83,11 @@ def set_region_rules(world: "SohWorld") -> None: # Connections connect_regions(Regions.DMC_LOWER_NEARBY, world, [ (Regions.DMC_LOWER_LOCAL, lambda bundle: fire_timer(bundle) >= 48), - (Regions.GC_DARUNIAS_CHAMBER, lambda bundle: True), + (Regions.GC_DARUNIAS_CHAMBER, lambda bundle: True, SOHOverworldEntranceNames.DEATH_MOUNTAIN_TRAIL_GC_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), (Regions.DMC_GREAT_FAIRY_FOUNTAIN, - lambda bundle: can_use(Items.MEGATON_HAMMER, bundle)), + lambda bundle: can_use(Items.MEGATON_HAMMER, bundle), SOHInteriorEntranceNames.DMC_GREAT_FAIRY_FOUNTAIN_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ADULT_ONLY), (Regions.DMC_HAMMER_GROTTO, lambda bundle: is_adult( - bundle) and can_use(Items.MEGATON_HAMMER, bundle)) + bundle) and can_use(Items.MEGATON_HAMMER, bundle), SOHGrottoEntranceNames.DMC_HAMMER_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ADULT_ONLY) ]) # Death Mountain Crater Lower Local @@ -162,9 +161,8 @@ def set_region_rules(world: "SohWorld") -> None: bundle)) or can_use(Items.HOVER_BOOTS, bundle) or can_use(Items.HOOKSHOT, bundle)), (Regions.DMC_UPPER_NEARBY, lambda bundle: is_adult(bundle) and has_item(LocalEvents.DMC_BEAN_PLANTED, bundle)), - (Regions.FIRE_TEMPLE_ENTRYWAY, lambda bundle: (is_child(bundle) and hearts(bundle) >= 3 and False) or ( - # TODO Implement Dungeon Shuffle Option to replace False - is_adult(bundle) and fire_timer(bundle) >= 24)), + (Regions.FIRE_TEMPLE_ENTRYWAY, lambda bundle: (is_child(bundle) and hearts(bundle) >= 3 and world.options.shuffle_dungeon_entrances.value > 0) or ( + is_adult(bundle) and fire_timer(bundle) >= 24), SOHDungeonEntranceNames.FIRE_TEMPLE_DUNGEON_ENTRANCE, SOHEntranceGroups.DUNGEON_ENTRANCE | SOHEntranceGroups.ANY_AGE, EntranceType.TWO_WAY), (Regions.DMC_DISTANT_PLATFORM, lambda bundle: (fire_timer(bundle) >= 48 or hearts(bundle) >= 2) and can_use(Items.DISTANT_SCARECROW, bundle)), ]) @@ -177,7 +175,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.DMC_GREAT_FAIRY_FOUNTAIN, world, [ - (Regions.DMC_LOWER_LOCAL, lambda bundle: True) + (Regions.DMC_LOWER_LOCAL, lambda bundle: True, SOHInteriorExitNames.DMC_GREAT_FAIRY_FOUNTAIN_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE) ]) # Death Mountain Crater Upper Grotto @@ -204,14 +202,18 @@ def set_region_rules(world: "SohWorld") -> None: lambda bundle: can_break_lower_hives(bundle)), (Locations.DMC_UPPER_GROTTO_BEEHIVE_RIGHT, lambda bundle: can_break_lower_hives(bundle)), - (Locations.DMC_UPPER_GROTTO_GRASS1, lambda bundle: can_cut_shrubs(bundle)), - (Locations.DMC_UPPER_GROTTO_GRASS2, lambda bundle: can_cut_shrubs(bundle)), - (Locations.DMC_UPPER_GROTTO_GRASS3, lambda bundle: can_cut_shrubs(bundle)), - (Locations.DMC_UPPER_GROTTO_GRASS4, lambda bundle: can_cut_shrubs(bundle)) + (Locations.DMC_UPPER_GROTTO_GRASS1, + lambda bundle: can_cut_shrubs(bundle)), + (Locations.DMC_UPPER_GROTTO_GRASS2, + lambda bundle: can_cut_shrubs(bundle)), + (Locations.DMC_UPPER_GROTTO_GRASS3, + lambda bundle: can_cut_shrubs(bundle)), + (Locations.DMC_UPPER_GROTTO_GRASS4, + lambda bundle: can_cut_shrubs(bundle)) ]) # Connections connect_regions(Regions.DMC_UPPER_GROTTO, world, [ - (Regions.DMC_UPPER_LOCAL, lambda bundle: True) + (Regions.DMC_UPPER_LOCAL, lambda bundle: True, SOHGrottoExitNames.DMC_UPPER_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.CHILD) ]) # Death Mountain Crater Hammer Grotto @@ -228,19 +230,26 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.DMC_HAMMER_GROTTO, world, [ - (Regions.DMC_LOWER_LOCAL, lambda bundle: True) + (Regions.DMC_LOWER_LOCAL, lambda bundle: True, SOHGrottoExitNames.DMC_HAMMER_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE) ]) # Death Mountain Crater Distant Platform # Locations add_locations(Regions.DMC_DISTANT_PLATFORM, world, [ - (Locations.DMC_DISTANT_PLATFORM_RUPEE1, lambda bundle: is_adult(bundle)), - (Locations.DMC_DISTANT_PLATFORM_RUPEE2, lambda bundle: is_adult(bundle)), - (Locations.DMC_DISTANT_PLATFORM_RUPEE3, lambda bundle: is_adult(bundle)), - (Locations.DMC_DISTANT_PLATFORM_RUPEE4, lambda bundle: is_adult(bundle)), - (Locations.DMC_DISTANT_PLATFORM_RUPEE5, lambda bundle: is_adult(bundle)), - (Locations.DMC_DISTANT_PLATFORM_RUPEE6, lambda bundle: is_adult(bundle)), - (Locations.DMC_DISTANT_PLATFORM_RED_RUPEE, lambda bundle: is_adult(bundle)) + (Locations.DMC_DISTANT_PLATFORM_RUPEE1, + lambda bundle: is_adult(bundle)), + (Locations.DMC_DISTANT_PLATFORM_RUPEE2, + lambda bundle: is_adult(bundle)), + (Locations.DMC_DISTANT_PLATFORM_RUPEE3, + lambda bundle: is_adult(bundle)), + (Locations.DMC_DISTANT_PLATFORM_RUPEE4, + lambda bundle: is_adult(bundle)), + (Locations.DMC_DISTANT_PLATFORM_RUPEE5, + lambda bundle: is_adult(bundle)), + (Locations.DMC_DISTANT_PLATFORM_RUPEE6, + lambda bundle: is_adult(bundle)), + (Locations.DMC_DISTANT_PLATFORM_RED_RUPEE, + lambda bundle: is_adult(bundle)) ]) # Connections connect_regions(Regions.DMC_DISTANT_PLATFORM, world, [ diff --git a/worlds/oot_soh/location_access/overworld/death_mountain_trail.py b/worlds/oot_soh/location_access/overworld/death_mountain_trail.py index 2ad25937625f..6de0c7a5344b 100644 --- a/worlds/oot_soh/location_access/overworld/death_mountain_trail.py +++ b/worlds/oot_soh/location_access/overworld/death_mountain_trail.py @@ -62,13 +62,13 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.DEATH_MOUNTAIN_TRAIL, world, [ - (Regions.KAK_BEHIND_GATE, lambda bundle: True), - (Regions.GORON_CITY, lambda bundle: True), + (Regions.KAK_BEHIND_GATE, lambda bundle: True, SOHOverworldEntranceNames.DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), + (Regions.GORON_CITY, lambda bundle: True, SOHOverworldEntranceNames.DEATH_MOUNTAIN_CRATER_GC_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), (Regions.DEATH_MOUNTAIN_SUMMIT, lambda bundle: blast_or_smash(bundle) or (is_adult(bundle) and ((has_item(LocalEvents.DMT_BEAN_PLANTED, bundle) and has_item(Items.GORONS_BRACELET, bundle)) or (can_use(Items.HOVER_BOOTS, bundle) and can_do_trick(Tricks.DMT_CLIMB_HOVERS, bundle))))), - (Regions.DODONGOS_CAVERN_ENTRYWAY, lambda bundle: has_explosives( - bundle) or has_item(Items.GORONS_BRACELET, bundle) or is_adult(bundle)), - (Regions.DMT_STORMS_GROTTO, lambda bundle: can_open_storms_grotto(bundle)) + (Regions.DODONGOS_CAVERN_ENTRYWAY, lambda bundle: has_explosives(bundle) or has_item(Items.GORONS_BRACELET, bundle) or is_adult( + bundle), SOHDungeonEntranceNames.DODONGOS_CAVERN_DUNGEON_ENTRANCE, SOHEntranceGroups.DUNGEON_ENTRANCE | SOHEntranceGroups.ANY_AGE, EntranceType.TWO_WAY), + (Regions.DMT_STORMS_GROTTO, lambda bundle: can_open_storms_grotto(bundle), SOHGrottoEntranceNames.DMT_STORMS_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE) ]) # Death Mountain Summit @@ -96,16 +96,16 @@ def set_region_rules(world: "SohWorld") -> None: # Connections connect_regions(Regions.DEATH_MOUNTAIN_SUMMIT, world, [ (Regions.DEATH_MOUNTAIN_TRAIL, lambda bundle: True), - (Regions.DMC_UPPER_LOCAL, lambda bundle: True), + (Regions.DMC_UPPER_LOCAL, lambda bundle: True, SOHOverworldEntranceNames.DEATH_MOUNTAIN_TRAIL_SUMMIT_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), (Regions.DMT_OWL_FLIGHT, lambda bundle: is_child(bundle)), - (Regions.DMT_COW_GROTTO, lambda bundle: blast_or_smash(bundle)), - (Regions.DMT_GREAT_FAIRY_FOUNTAIN, lambda bundle: blast_or_smash(bundle)) + (Regions.DMT_COW_GROTTO, lambda bundle: blast_or_smash(bundle), SOHGrottoEntranceNames.DMT_COW_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), + (Regions.DMT_GREAT_FAIRY_FOUNTAIN, lambda bundle: blast_or_smash(bundle), SOHInteriorEntranceNames.DMT_GREAT_FAIRY_FOUNTAIN_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE) ]) # Death Mountain Trail Owl Flight # Connections connect_regions(Regions.DMT_OWL_FLIGHT, world, [ - (Regions.KAK_IMPAS_ROOFTOP, lambda bundle: True) + (Regions.KAK_IMPAS_ROOFTOP, lambda bundle: True, Regions.DMT_OWL_FLIGHT) ]) # Death Mountain Trail Cow Grotto @@ -133,7 +133,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.DMT_COW_GROTTO, world, [ - (Regions.DEATH_MOUNTAIN_SUMMIT, lambda bundle: True) + (Regions.DEATH_MOUNTAIN_SUMMIT, lambda bundle: True, SOHGrottoExitNames.DMT_COW_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE) ]) # Death Mountain Trail Storms Grotto @@ -167,7 +167,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.DMT_STORMS_GROTTO, world, [ - (Regions.DEATH_MOUNTAIN_TRAIL, lambda bundle: True) + (Regions.DEATH_MOUNTAIN_TRAIL, lambda bundle: True, SOHGrottoExitNames.DMT_STORMS_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.CHILD) ]) # Death Mountain Trail Great Fairy Fountain @@ -178,5 +178,5 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.DMT_GREAT_FAIRY_FOUNTAIN, world, [ - (Regions.DEATH_MOUNTAIN_SUMMIT, lambda bundle: True) + (Regions.DEATH_MOUNTAIN_SUMMIT, lambda bundle: True, SOHInteriorExitNames.DMT_GREAT_FAIRY_FOUNTAIN_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE) ]) diff --git a/worlds/oot_soh/location_access/overworld/desert_colossus.py b/worlds/oot_soh/location_access/overworld/desert_colossus.py index b09d2159f65f..76cfeff6b9dd 100644 --- a/worlds/oot_soh/location_access/overworld/desert_colossus.py +++ b/worlds/oot_soh/location_access/overworld/desert_colossus.py @@ -51,19 +51,20 @@ def set_region_rules(world: "SohWorld") -> None: (Locations.COLOSSUS_GOSSIP_STONE_FAIRY, lambda bundle: call_gossip_fairy(bundle)), (Locations.COLOSSUS_GOSSIP_STONE_BIG_FAIRY, - lambda bundle: can_use(Items.SONG_OF_STORMS, bundle)) - + lambda bundle: can_use(Items.SONG_OF_STORMS, bundle)), + (Locations.SHEIK_AT_COLOSSUS, lambda bundle: True) ]) # Connections connect_regions(Regions.DESERT_COLOSSUS, world, [ (Regions.DESERT_COLOSSUS_OASIS, lambda bundle: can_use(Items.SONG_OF_STORMS, bundle) and ( has_item(Items.BRONZE_SCALE, bundle) or can_use(Items.IRON_BOOTS, bundle))), (Regions.COLOSSUS_GREAT_FAIRY_FOUNTAIN, - lambda bundle: has_explosives(bundle)), - (Regions.SPIRIT_TEMPLE_ENTRYWAY, lambda bundle: True), - (Regions.WASTELAND_NEAR_COLOSSUS, lambda bundle: True), + lambda bundle: has_explosives(bundle), SOHInteriorEntranceNames.COLOSSUS_GREAT_FAIRY_FOUNTAIN_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE), + (Regions.SPIRIT_TEMPLE_ENTRYWAY, lambda bundle: True, SOHDungeonEntranceNames.SPIRIT_TEMPLE_DUNGEON_ENTRNACE, + SOHEntranceGroups.DUNGEON_ENTRANCE | SOHEntranceGroups.ANY_AGE, EntranceType.TWO_WAY), + (Regions.WASTELAND_NEAR_COLOSSUS, lambda bundle: True, SOHOverworldEntranceNames.DESERT_COLOSSUS_EAST_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.ANY_AGE), (Regions.COLOSSUS_GROTTO, lambda bundle: can_use( - Items.SILVER_GAUNTLETS, bundle)) + Items.SILVER_GAUNTLETS, bundle), SOHGrottoEntranceNames.COLOSSUS_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ADULT_ONLY) ]) # Desert Colossus Oasis @@ -89,15 +90,15 @@ def set_region_rules(world: "SohWorld") -> None: (Regions.DESERT_COLOSSUS, lambda bundle: True) ]) - # Desert Colossus Outside Temple - # Locations - add_locations(Regions.DESERT_COLOSSUS_OUTSIDE_TEMPLE, world, [ - (Locations.SHEIK_AT_COLOSSUS, lambda bundle: True) - ]) - # Connections - connect_regions(Regions.DESERT_COLOSSUS_OUTSIDE_TEMPLE, world, [ - (Regions.DESERT_COLOSSUS, lambda bundle: True) - ]) + # # Desert Colossus Outside Temple + # # Locations + # add_locations(Regions.DESERT_COLOSSUS_OUTSIDE_TEMPLE, world, [ + # (Locations.SHEIK_AT_COLOSSUS, lambda bundle: True) + # ]) + # # Connections + # connect_regions(Regions.DESERT_COLOSSUS_OUTSIDE_TEMPLE, world, [ + # (Regions.DESERT_COLOSSUS, lambda bundle: True) + # ]) # Desert Colossus Great Fairy Fountain # Locations @@ -107,7 +108,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.COLOSSUS_GREAT_FAIRY_FOUNTAIN, world, [ - (Regions.DESERT_COLOSSUS, lambda bundle: True) + (Regions.DESERT_COLOSSUS, lambda bundle: True, SOHInteriorExitNames.COLOSSUS_GREAT_FAIRY_FOUNTAIN_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE) ]) # Desert Colossus Great Fairy Fountain @@ -122,5 +123,5 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.COLOSSUS_GROTTO, world, [ - (Regions.DESERT_COLOSSUS, lambda bundle: True) + (Regions.DESERT_COLOSSUS, lambda bundle: True, SOHGrottoExitNames.COLOSSUS_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE) ]) diff --git a/worlds/oot_soh/location_access/overworld/gerudo_fortress.py b/worlds/oot_soh/location_access/overworld/gerudo_fortress.py index 3fd44aa5ccf9..9439bac3d074 100644 --- a/worlds/oot_soh/location_access/overworld/gerudo_fortress.py +++ b/worlds/oot_soh/location_access/overworld/gerudo_fortress.py @@ -33,8 +33,8 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.GERUDO_FORTRESS_OUTSKIRTS, world, [ - (Regions.GV_FORTRESS_SIDE, lambda bundle: True), - (Regions.THIEVES_HIDEOUT_1_TORCH_CELL, lambda bundle: True), + (Regions.GV_FORTRESS_SIDE, lambda bundle: True, SOHOverworldEntranceNames.GERUDOS_FORTRESS_EAST_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.ADULT), + (Regions.THIEVES_HIDEOUT_1_TORCH_CELL, lambda bundle: True, SOHThievesHideoutEntranceNames.THIEVES_HIDEOUT_0, int(SOHEntranceGroups.THIEVES_HIDEOUT_ENTRANCE)), (Regions.GF_OUTSIDE_GATE, lambda bundle: has_item( LocalEvents.GF_GATE_OPEN, bundle)), (Regions.GF_NEAR_GROTTO, lambda bundle: is_child(bundle) @@ -58,9 +58,9 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.GF_NEAR_GROTTO, world, [ - (Regions.THIEVES_HIDEOUT_1_TORCH_CELL, lambda bundle: True), - (Regions.THIEVES_HIDEOUT_STEEP_SLOPE_CELL, lambda bundle: True), - (Regions.THIEVES_HIDEOUT_KITCHEN_CORRIDOR, lambda bundle: True), + (Regions.THIEVES_HIDEOUT_1_TORCH_CELL, lambda bundle: True, SOHThievesHideoutEntranceNames.THIEVES_HIDEOUT_1, int(SOHEntranceGroups.THIEVES_HIDEOUT_ENTRANCE)), + (Regions.THIEVES_HIDEOUT_STEEP_SLOPE_CELL, lambda bundle: True, SOHThievesHideoutEntranceNames.THIEVES_HIDEOUT_4, int(SOHEntranceGroups.THIEVES_HIDEOUT_ENTRANCE)), + (Regions.THIEVES_HIDEOUT_KITCHEN_CORRIDOR, lambda bundle: True, SOHThievesHideoutEntranceNames.THIEVES_HIDEOUT_2, int(SOHEntranceGroups.THIEVES_HIDEOUT_ENTRANCE)), (Regions.GERUDO_FORTRESS_OUTSKIRTS, lambda bundle: True), (Regions.GF_JAIL_WINDOW, lambda bundle: can_use(Items.HOOKSHOT, bundle)), (Regions.GF_OUTSIDE_GTG, lambda bundle: is_child(bundle) @@ -68,7 +68,7 @@ def set_region_rules(world: "SohWorld") -> None: (Regions.GF_TOP_OF_UPPER_VINES, lambda bundle: can_use(Items.LONGSHOT, bundle)), (Regions.GF_STORMS_GROTTO, lambda bundle: is_adult( - bundle) and can_open_storms_grotto(bundle)), + bundle) and can_open_storms_grotto(bundle), SOHGrottoEntranceNames.GF_STORMS_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ADULT_ONLY), ]) # GF Outside GTG @@ -80,9 +80,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.GF_OUTSIDE_GTG, world, [ - # TODO: Check for entrance rando - (Regions.GF_TO_GTG, lambda bundle: has_item( - LocalEvents.GTG_GATE_OPEN, bundle) and is_adult(bundle)), + (Regions.GF_TO_GTG, lambda bundle: True), (Regions.GF_JAIL_WINDOW, lambda bundle: can_use(Items.HOOKSHOT, bundle)), (Regions.GERUDO_FORTRESS_OUTSKIRTS, lambda bundle: True), (Regions.GF_NEAR_GROTTO, lambda bundle: is_child(bundle) @@ -98,23 +96,29 @@ def set_region_rules(world: "SohWorld") -> None: # GF to GTG # Connections connect_regions(Regions.GF_TO_GTG, world, [ - (Regions.GERUDO_TRAINING_GROUND_ENTRYWAY, lambda bundle: True), - ]) - - # GF Exiting GTG - # Connections - connect_regions(Regions.GF_EXITING_GTG, world, [ + (Regions.GERUDO_TRAINING_GROUND_ENTRYWAY, lambda bundle: has_item(LocalEvents.GTG_GATE_OPEN, bundle) and (is_adult(bundle) or world.options.shuffle_dungeon_entrances > + 0), SOHDungeonEntranceNames.GERUDO_TRAINING_GROUND_DUNGEON_ENTRANCE, SOHEntranceGroups.DUNGEON_ENTRANCE | SOHEntranceGroups.ADULT_ONLY, EntranceType.TWO_WAY), (Regions.GF_OUTSIDE_GTG, lambda bundle: is_child(bundle) or has_item(Items.GERUDO_MEMBERSHIP_CARD, bundle)), (Regions.GF_JAIL_WINDOW, lambda bundle: can_use(Items.HOOKSHOT, bundle)), (Regions.GERUDO_FORTRESS_OUTSKIRTS, lambda bundle: True), ]) + # Deviation from Ship + # GF Exiting GTG + # Connections + # connect_regions(Regions.GF_EXITING_GTG, world, [ + # (Regions.GF_OUTSIDE_GTG, lambda bundle: is_child(bundle) + # or has_item(Items.GERUDO_MEMBERSHIP_CARD, bundle)), + # (Regions.GF_JAIL_WINDOW, lambda bundle: can_use(Items.HOOKSHOT, bundle)), + # (Regions.GERUDO_FORTRESS_OUTSKIRTS, lambda bundle: True), + # ]) + # GF Above GTG # Connections connect_regions(Regions.GF_ABOVE_GTG, world, [ - (Regions.THIEVES_HIDEOUT_DOUBLE_CELL, lambda bundle: True), - (Regions.THIEVES_HIDEOUT_KITCHEN_CORRIDOR, lambda bundle: True), + (Regions.THIEVES_HIDEOUT_DOUBLE_CELL, lambda bundle: True, SOHThievesHideoutEntranceNames.THIEVES_HIDEOUT_6, int(SOHEntranceGroups.THIEVES_HIDEOUT_ENTRANCE)), + (Regions.THIEVES_HIDEOUT_KITCHEN_CORRIDOR, lambda bundle: True, SOHThievesHideoutEntranceNames.THIEVES_HIDEOUT_3, int(SOHEntranceGroups.THIEVES_HIDEOUT_ENTRANCE)), (Regions.GF_JAIL_WINDOW, lambda bundle: can_use(Items.HOOKSHOT, bundle)), (Regions.GERUDO_FORTRESS_OUTSKIRTS, lambda bundle: True), (Regions.GF_NEAR_GROTTO, lambda bundle: True), @@ -127,7 +131,7 @@ def set_region_rules(world: "SohWorld") -> None: # GF Bottom of Lower Vines # Connections connect_regions(Regions.GF_BOTTOM_OF_LOWER_VINES, world, [ - (Regions.THIEVES_HIDEOUT_STEEP_SLOPE_CELL, lambda bundle: True), + (Regions.THIEVES_HIDEOUT_STEEP_SLOPE_CELL, lambda bundle: True, SOHThievesHideoutEntranceNames.THIEVES_HIDEOUT_5, int(SOHEntranceGroups.THIEVES_HIDEOUT_ENTRANCE)), (Regions.GF_NEAR_GROTTO, lambda bundle: True), (Regions.GF_TOP_OF_LOWER_VINES, lambda bundle: True), (Regions.GF_ABOVE_GTG, lambda bundle: True), @@ -138,8 +142,8 @@ def set_region_rules(world: "SohWorld") -> None: # GF Top of Lower Vines # Connections connect_regions(Regions.GF_TOP_OF_LOWER_VINES, world, [ - (Regions.THIEVES_HIDEOUT_KITCHEN_TOP, lambda bundle: True), - (Regions.THIEVES_HIDEOUT_DOUBLE_CELL, lambda bundle: True), + (Regions.THIEVES_HIDEOUT_KITCHEN_TOP, lambda bundle: True, SOHThievesHideoutEntranceNames.THIEVES_HIDEOUT_8, int(SOHEntranceGroups.THIEVES_HIDEOUT_ENTRANCE)), + (Regions.THIEVES_HIDEOUT_DOUBLE_CELL, lambda bundle: True, SOHThievesHideoutEntranceNames.THIEVES_HIDEOUT_7, int(SOHEntranceGroups.THIEVES_HIDEOUT_ENTRANCE)), (Regions.GF_ABOVE_GTG, lambda bundle: True), (Regions.GF_BOTTOM_OF_LOWER_VINES, lambda bundle: True), (Regions.GF_BOTTOM_OF_UPPER_VINES, lambda bundle: is_adult( @@ -149,7 +153,7 @@ def set_region_rules(world: "SohWorld") -> None: # GF Near GS # Connections connect_regions(Regions.GF_NEAR_GS, world, [ - (Regions.THIEVES_HIDEOUT_KITCHEN_TOP, lambda bundle: True), + (Regions.THIEVES_HIDEOUT_KITCHEN_TOP, lambda bundle: True, SOHThievesHideoutEntranceNames.THIEVES_HIDEOUT_9, int(SOHEntranceGroups.THIEVES_HIDEOUT_ENTRANCE)), (Regions.GF_BOTTOM_OF_LOWER_VINES, lambda bundle: True), (Regions.GF_TOP_OF_LOWER_VINES, lambda bundle: True), (Regions.GF_SLOPED_ROOF, lambda bundle: is_adult( @@ -239,7 +243,7 @@ def set_region_rules(world: "SohWorld") -> None: # GF Below GS # Connections connect_regions(Regions.GF_BELOW_GS, world, [ - (Regions.THIEVES_HIDEOUT_DEAD_END_CELL, lambda bundle: True), + (Regions.THIEVES_HIDEOUT_DEAD_END_CELL, lambda bundle: True, SOHThievesHideoutEntranceNames.THIEVES_HIDEOUT_12, int(SOHEntranceGroups.THIEVES_HIDEOUT_ENTRANCE)), (Regions.GF_BOTTOM_OF_LOWER_VINES, lambda bundle: True), (Regions.GF_GS_KILL_ZONE, lambda bundle: is_adult(bundle) and can_get_enemy_drop(bundle, Enemies.GOLD_SKULLTULA, @@ -250,7 +254,7 @@ def set_region_rules(world: "SohWorld") -> None: # GF Below Chest # Connections connect_regions(Regions.GF_BELOW_CHEST, world, [ - (Regions.THIEVES_HIDEOUT_BREAK_ROOM, lambda bundle: True), + (Regions.THIEVES_HIDEOUT_BREAK_ROOM, lambda bundle: True, SOHThievesHideoutEntranceNames.THIEVES_HIDEOUT_10, int(SOHEntranceGroups.THIEVES_HIDEOUT_ENTRANCE)), (Regions.GERUDO_FORTRESS_OUTSKIRTS, lambda bundle: True), ]) @@ -266,6 +270,7 @@ def set_region_rules(world: "SohWorld") -> None: (Regions.GF_NEAR_CHEST, lambda bundle: can_use(Items.LONGSHOT, bundle)), (Regions.GF_BELOW_CHEST, lambda bundle: take_damage(bundle)), (Regions.GF_JAIL_WINDOW, lambda bundle: can_use(Items.HOOKSHOT, bundle)), + (Regions.THIEVES_HIDEOUT_BREAK_ROOM_CORRIDOR, lambda bundle: True, SOHThievesHideoutEntranceNames.THIEVES_HIDEOUT_11, int(SOHEntranceGroups.THIEVES_HIDEOUT_ENTRANCE)) ]) # GF Jail Window @@ -330,7 +335,7 @@ def set_region_rules(world: "SohWorld") -> None: connect_regions(Regions.GF_OUTSIDE_GATE, world, [ (Regions.GERUDO_FORTRESS_OUTSKIRTS, lambda bundle: has_item( LocalEvents.GF_GATE_OPEN, bundle)), - (Regions.WASTELAND_NEAR_FORTRESS, lambda bundle: True), + (Regions.WASTELAND_NEAR_FORTRESS, lambda bundle: True, SOHOverworldEntranceNames.GERUDOS_FORTRESS_GATE_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), ]) # GF Storms Grotto @@ -352,5 +357,5 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.GF_STORMS_GROTTO, world, [ - (Regions.GF_NEAR_GROTTO, lambda bundle: True), + (Regions.GF_NEAR_GROTTO, lambda bundle: True, SOHGrottoExitNames.GF_STORMS_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), ]) diff --git a/worlds/oot_soh/location_access/overworld/gerudo_valley.py b/worlds/oot_soh/location_access/overworld/gerudo_valley.py index c0339b28c7aa..680b79736cfd 100644 --- a/worlds/oot_soh/location_access/overworld/gerudo_valley.py +++ b/worlds/oot_soh/location_access/overworld/gerudo_valley.py @@ -35,7 +35,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connection connect_regions(Regions.GERUDO_VALLEY, world, [ - (Regions.HYRULE_FIELD, lambda bundle: True), + (Regions.HYRULE_FIELD, lambda bundle: True, SOHOverworldEntranceNames.GERUDO_VALLEY_EAST_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), (Regions.GV_UPPER_STREAM, lambda bundle: is_child(bundle) or has_item(Items.BRONZE_SCALE, bundle) or take_damage(bundle)), (Regions.GV_CRATE_LEDGE, lambda bundle: is_child( @@ -91,7 +91,7 @@ def set_region_rules(world: "SohWorld") -> None: # GV Lower Stream # Connections connect_regions(Regions.GV_LOWER_STREAM, world, [ - (Regions.LAKE_HYLIA, lambda bundle: True) + (Regions.LAKE_HYLIA, lambda bundle: True, SOHOverworldEntranceNames.LAKE_HYLIA_RIVER_ENTRANCE, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.ANY_AGE, EntranceType.ONE_WAY) ]) # GV Grotto Ledge @@ -102,7 +102,7 @@ def set_region_rules(world: "SohWorld") -> None: (Regions.GV_LOWER_STREAM, lambda bundle: has_item(Items.BRONZE_SCALE, bundle) or can_use(Items.IRON_BOOTS, bundle)), (Regions.GV_OCTOROK_GROTTO, lambda bundle: can_use( - Items.SILVER_GAUNTLETS, bundle)), + Items.SILVER_GAUNTLETS, bundle), SOHGrottoEntranceNames.GV_OCTOROK_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ADULT_ONLY), (Regions.GV_CRATE_LEDGE, lambda bundle: can_use(Items.LONGSHOT, bundle)) ]) @@ -144,15 +144,15 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.GV_FORTRESS_SIDE, world, [ - (Regions.GERUDO_FORTRESS_OUTSKIRTS, lambda bundle: True), + (Regions.GERUDO_FORTRESS_OUTSKIRTS, lambda bundle: True, SOHOverworldEntranceNames.GERUDO_VALLEY_WEST_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), (Regions.GV_UPPER_STREAM, lambda bundle: True), (Regions.GERUDO_VALLEY, lambda bundle: is_child(bundle) or can_use(Items.EPONA, bundle) or can_use(Items.LONGSHOT, bundle) or world.options.fortress_carpenters.value == 2 or has_item( Events.RESCUED_ALL_CARPENTERS, bundle)), - (Regions.GV_CARPENTER_TENT, lambda bundle: is_adult(bundle)), + (Regions.GV_CARPENTER_TENT, lambda bundle: is_adult(bundle), SOHInteriorEntranceNames.GV_CARPENTER_TENT_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ADULT_ONLY), (Regions.GV_STORMS_GROTTO, lambda bundle: is_adult( - bundle) and can_open_storms_grotto(bundle)), + bundle) and can_open_storms_grotto(bundle), SOHGrottoEntranceNames.GV_STORMS_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ADULT_ONLY), (Regions.GV_CRATE_LEDGE, lambda bundle: can_do_trick(Tricks.DAMAGE_BOOST_SIMPLE, bundle) and has_explosives(bundle)), ]) @@ -160,7 +160,7 @@ def set_region_rules(world: "SohWorld") -> None: # GV Carpenter Tent # Connections connect_regions(Regions.GV_CARPENTER_TENT, world, [ - (Regions.GV_FORTRESS_SIDE, lambda bundle: True), + (Regions.GV_FORTRESS_SIDE, lambda bundle: True, SOHInteriorExitNames.GV_CARPENTER_TENT_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE), ]) # GV Octorok Grotto @@ -193,7 +193,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.GV_OCTOROK_GROTTO, world, [ - (Regions.GV_GROTTO_LEDGE, lambda bundle: True), + (Regions.GV_GROTTO_LEDGE, lambda bundle: True, SOHGrottoExitNames.GV_OCTOROK_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), ]) # GV Storms Grotto @@ -208,5 +208,5 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.GV_STORMS_GROTTO, world, [ - (Regions.GV_FORTRESS_SIDE, lambda bundle: True), + (Regions.GV_FORTRESS_SIDE, lambda bundle: True, SOHGrottoExitNames.GV_STORMS_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), ]) diff --git a/worlds/oot_soh/location_access/overworld/goron_city.py b/worlds/oot_soh/location_access/overworld/goron_city.py index 2f2f947b17fe..0ead4920ea02 100644 --- a/worlds/oot_soh/location_access/overworld/goron_city.py +++ b/worlds/oot_soh/location_access/overworld/goron_city.py @@ -76,13 +76,13 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.GORON_CITY, world, [ - (Regions.DEATH_MOUNTAIN_TRAIL, lambda bundle: True), + (Regions.DEATH_MOUNTAIN_TRAIL, lambda bundle: True, SOHOverworldEntranceNames.GORON_CITY_UPPER_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), (Regions.GC_MEDIGORON, lambda bundle: can_break_mud_walls( bundle) or has_item(Items.GORONS_BRACELET, bundle)), (Regions.GC_WOODS_WARP, lambda bundle: has_item( LocalEvents.GC_WOODS_WARP_OPEN, bundle)), (Regions.GC_SHOP, lambda bundle: (is_adult(bundle) and has_item(LocalEvents.GC_STOP_ROLLING_GORON_AS_ADULT, bundle)) or (is_child(bundle) and ( - blast_or_smash(bundle) or has_item(Items.GORONS_BRACELET, bundle) or has_item(LocalEvents.GC_CHILD_FIRE_LIT, bundle) or can_use(Items.FAIRY_BOW, bundle)))), + blast_or_smash(bundle) or has_item(Items.GORONS_BRACELET, bundle) or has_item(LocalEvents.GC_CHILD_FIRE_LIT, bundle) or can_use(Items.FAIRY_BOW, bundle))), SOHInteriorEntranceNames.GC_SHOP_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE), (Regions.GC_DARUNIAS_CHAMBER, lambda bundle: (is_adult(bundle) and has_item(LocalEvents.GC_STOP_ROLLING_GORON_AS_ADULT, bundle)) or (is_child(bundle) and has_item(LocalEvents.GC_DARUNIAS_DOOR_OPENED_AS_CHILD, bundle))), (Regions.GC_GROTTO_PLATFORM, lambda bundle: is_adult(bundle) and ((can_use(Items.SONG_OF_TIME, bundle) and ((effective_health(bundle) > 2) or can_use(Items.GORON_TUNIC, bundle) or can_use(Items.LONGSHOT, bundle) or can_use(Items.NAYRUS_LOVE, bundle))) or (effective_health( @@ -113,7 +113,7 @@ def set_region_rules(world: "SohWorld") -> None: connect_regions(Regions.GC_WOODS_WARP, world, [ (Regions.GORON_CITY, lambda bundle: has_item( LocalEvents.GC_WOODS_WARP_OPEN, bundle)), - (Regions.LOST_WOODS, lambda bundle: True) + (Regions.LOST_WOODS, lambda bundle: True, SOHOverworldEntranceNames.GORON_CITY_TUNNEL_SHORTCUT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE) ]) # Goron City Darunias Chamber @@ -133,13 +133,13 @@ def set_region_rules(world: "SohWorld") -> None: # Connections connect_regions(Regions.GC_DARUNIAS_CHAMBER, world, [ (Regions.GORON_CITY, lambda bundle: True), - (Regions.DMC_LOWER_LOCAL, lambda bundle: is_adult(bundle)) + (Regions.DMC_LOWER_LOCAL, lambda bundle: is_adult(bundle), SOHOverworldEntranceNames.GORON_CITY_DARUNIA_ROOM_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE) ]) # Goron City Grotto Platform # Connections connect_regions(Regions.GC_GROTTO_PLATFORM, world, [ - (Regions.GC_GROTTO, lambda bundle: True), + (Regions.GC_GROTTO, lambda bundle: True, SOHGrottoEntranceNames.GC_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ADULT_ONLY), (Regions.GORON_CITY, lambda bundle: effective_health(bundle) > 2 or can_use_any([Items.GORON_TUNIC, Items.NAYRUS_LOVE], bundle) or ( (is_child(bundle) or can_use(Items.SONG_OF_TIME, bundle)) and can_use(Items.LONGSHOT, bundle))) ]) @@ -158,7 +158,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.GC_SHOP, world, [ - (Regions.GORON_CITY, lambda bundle: True) + (Regions.GORON_CITY, lambda bundle: True, SOHInteriorExitNames.GC_SHOP_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE) ]) # Goron City Grotto @@ -174,5 +174,5 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.GC_GROTTO, world, [ - (Regions.GC_GROTTO_PLATFORM, lambda bundle: True) + (Regions.GC_GROTTO_PLATFORM, lambda bundle: True, SOHGrottoExitNames.GC_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE) ]) diff --git a/worlds/oot_soh/location_access/overworld/graveyard.py b/worlds/oot_soh/location_access/overworld/graveyard.py index 450c212c429f..476abfa766a2 100644 --- a/worlds/oot_soh/location_access/overworld/graveyard.py +++ b/worlds/oot_soh/location_access/overworld/graveyard.py @@ -70,15 +70,15 @@ def set_region_rules(world: "SohWorld") -> None: # Connections connect_regions(Regions.THE_GRAVEYARD, world, [ (Regions.GRAVEYARD_SHIELD_GRAVE, - lambda bundle: is_adult(bundle) or at_night(bundle)), + lambda bundle: is_adult(bundle) or at_night(bundle), SOHGrottoEntranceNames.GRAVEYARD_SHEILD_GRAVE_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ADULT_ONLY), (Regions.GRAVEYARD_COMPOSERS_GRAVE, - lambda bundle: can_use(Items.ZELDAS_LULLABY, bundle)), + lambda bundle: can_use(Items.ZELDAS_LULLABY, bundle), SOHGrottoEntranceNames.GRAVEYARD_COMPOSERS_GRAVE_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), (Regions.GRAVEYARD_HEART_PIECE_GRAVE, - lambda bundle: is_adult(bundle) or at_night(bundle)), - (Regions.GRAVEYARD_DAMPES_GRAVE, lambda bundle: is_adult(bundle)), + lambda bundle: is_adult(bundle) or at_night(bundle), SOHGrottoEntranceNames.GRAVEYARD_HEART_PIECE_GRAVE_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ADULT_ONLY), + (Regions.GRAVEYARD_DAMPES_GRAVE, lambda bundle: is_adult(bundle), SOHGrottoEntranceNames.GRAVEYARD_DAMPES_GRAVE_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ADULT_ONLY), (Regions.GRAVEYARD_DAMPES_HOUSE, lambda bundle: is_adult(bundle) - and can_open_overworld_door(Items.DAMPES_HUT_KEY, bundle)), - (Regions.KAKARIKO_VILLAGE, lambda bundle: True), + and can_open_overworld_door(Items.DAMPES_HUT_KEY, bundle), SOHInteriorEntranceNames.GRAVEYARD_DAMPES_HOUSE_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ADULT_ONLY), + (Regions.KAKARIKO_VILLAGE, lambda bundle: True, SOHOverworldEntranceNames.GRAVEYARD_ENTRANCE, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), (Regions.GRAVEYARD_WARP_PAD_REGION, lambda bundle: False) ]) @@ -89,7 +89,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.GRAVEYARD_SHIELD_GRAVE, world, [ - (Regions.THE_GRAVEYARD, lambda bundle: True), + (Regions.THE_GRAVEYARD, lambda bundle: True, SOHGrottoExitNames.GRAVEYARD_SHEILD_GRAVE_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), (Regions.GRAVEYARD_SHIELD_GRAVE_BACK, lambda bundle: can_break_mud_walls(bundle)) ]) @@ -119,7 +119,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.GRAVEYARD_HEART_PIECE_GRAVE, world, [ - (Regions.THE_GRAVEYARD, lambda bundle: True) + (Regions.THE_GRAVEYARD, lambda bundle: True, SOHGrottoExitNames.GRAVEYARD_HEART_PIECE_GRAVE_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE) ]) # The Graveyard Composers Grave @@ -134,7 +134,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.GRAVEYARD_COMPOSERS_GRAVE, world, [ - (Regions.THE_GRAVEYARD, lambda bundle: True) + (Regions.THE_GRAVEYARD, lambda bundle: True, SOHGrottoExitNames.GRAVEYARD_COMPOSERS_GRAVE_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE) ]) # The Graveyard Dampes Grave @@ -173,15 +173,16 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.GRAVEYARD_DAMPES_GRAVE, world, [ - (Regions.THE_GRAVEYARD, lambda bundle: True), - (Regions.KAK_WINDMILL, lambda bundle: (is_adult(bundle) and can_use( - Items.SONG_OF_TIME, bundle)) or (is_child(bundle) and can_ground_jump(bundle))) + (Regions.THE_GRAVEYARD, lambda bundle: True, SOHGrottoExitNames.GRAVEYARD_DAMPES_GRAVE_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ADULT), + # Doing this connection in __init__ connect_entrances for ER reasons + # (Regions.KAK_WINDMILL, lambda bundle: (is_adult(bundle) and can_use( + # Items.SONG_OF_TIME, bundle)) or (is_child(bundle) and can_ground_jump(bundle))) ]) # The Graveyard Dampes House # Connections connect_regions(Regions.GRAVEYARD_DAMPES_HOUSE, world, [ - (Regions.THE_GRAVEYARD, lambda bundle: True) + (Regions.THE_GRAVEYARD, lambda bundle: True, SOHInteriorExitNames.GRAVEYARD_DAMPES_HOUSE_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE) ]) # The Graveyard Warp Pad Region @@ -200,6 +201,11 @@ def set_region_rules(world: "SohWorld") -> None: # Connections connect_regions(Regions.GRAVEYARD_WARP_PAD_REGION, world, [ (Regions.THE_GRAVEYARD, lambda bundle: True), - (Regions.SHADOW_TEMPLE_ENTRYWAY, lambda bundle: can_use(Items.DINS_FIRE, bundle) or (can_do_trick( - Tricks.GY_SHADOW_FIRE_ARROWS, bundle) and is_adult(bundle) and can_use(Items.FIRE_ARROW, bundle))) + (Regions.SHADOW_TEMPLE_ENTRYWAY, lambda bundle: can_use(Items.DINS_FIRE, bundle) or (can_do_trick(Tricks.GY_SHADOW_FIRE_ARROWS, bundle) and is_adult( + bundle) and can_use(Items.FIRE_ARROW, bundle)), SOHDungeonEntranceNames.SHADOW_TEMPLE_DUNGEON_ENTRANCE, SOHEntranceGroups.DUNGEON_ENTRANCE | SOHEntranceGroups.ANY_AGE, EntranceType.TWO_WAY) ]) + +def connect_dampes_grave_windmill(world: "SohWorld"): + connect_regions(Regions.GRAVEYARD_DAMPES_GRAVE, world, [ + (Regions.KAK_WINDMILL, lambda bundle: (is_adult(bundle) and can_use(Items.SONG_OF_TIME, bundle)) or (is_child(bundle) and can_ground_jump(bundle))) + ]) \ No newline at end of file diff --git a/worlds/oot_soh/location_access/overworld/haunted_wasteland.py b/worlds/oot_soh/location_access/overworld/haunted_wasteland.py index a5e43c823dc9..95c02dbd596a 100644 --- a/worlds/oot_soh/location_access/overworld/haunted_wasteland.py +++ b/worlds/oot_soh/location_access/overworld/haunted_wasteland.py @@ -19,7 +19,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.WASTELAND_NEAR_FORTRESS, world, [ - (Regions.GF_OUTSIDE_GATE, lambda bundle: True), + (Regions.GF_OUTSIDE_GATE, lambda bundle: True, SOHOverworldEntranceNames.HAUNTED_WASTELAND_EAST_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), (Regions.HAUNTED_WASTELAND, lambda bundle: can_use_any( [Items.HOVER_BOOTS, Items.LONGSHOT], bundle) or can_do_trick(Tricks.HW_CROSSING, bundle)) ]) @@ -70,7 +70,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.WASTELAND_NEAR_COLOSSUS, world, [ - (Regions.DESERT_COLOSSUS, lambda bundle: True), + (Regions.DESERT_COLOSSUS, lambda bundle: True, SOHOverworldEntranceNames.HAUNTED_WASTELAND_WEST_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), (Regions.HAUNTED_WASTELAND, lambda bundle: can_do_trick( Tricks.HW_REVERSE, bundle)) ]) diff --git a/worlds/oot_soh/location_access/overworld/hyrule_field.py b/worlds/oot_soh/location_access/overworld/hyrule_field.py index 155e10ce9b8a..e76eefe4957d 100644 --- a/worlds/oot_soh/location_access/overworld/hyrule_field.py +++ b/worlds/oot_soh/location_access/overworld/hyrule_field.py @@ -173,23 +173,23 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.HYRULE_FIELD, world, [ - (Regions.LW_BRIDGE, lambda bundle: True), - (Regions.LAKE_HYLIA, lambda bundle: True), - (Regions.GERUDO_VALLEY, lambda bundle: True), - (Regions.MARKET_ENTRANCE, lambda bundle: True), - (Regions.KAKARIKO_VILLAGE, lambda bundle: True), - (Regions.ZR_FRONT, lambda bundle: True), - (Regions.LON_LON_RANCH, lambda bundle: True), - (Regions.HF_SOUTHEAST_GROTTO, lambda bundle: (blast_or_smash(bundle))), - (Regions.HF_OPEN_GROTTO, lambda bundle: True), + (Regions.LW_BRIDGE, lambda bundle: True, SOHOverworldEntranceNames.HYRULE_FIELD_WOODED_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), + (Regions.LAKE_HYLIA, lambda bundle: True, SOHOverworldEntranceNames.HYRULE_FIELD_FENCE_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), + (Regions.GERUDO_VALLEY, lambda bundle: True, SOHOverworldEntranceNames.HYRULE_FIELD_ROCKY_PATH, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), + (Regions.MARKET_ENTRANCE, lambda bundle: True, SOHOverworldEntranceNames.HYRULE_FIELD_ON_BRIDGE_SPAWN, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), + (Regions.KAKARIKO_VILLAGE, lambda bundle: True, SOHOverworldEntranceNames.HYRULE_FIELD_STAIRS_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), + (Regions.ZR_FRONT, lambda bundle: True, SOHOverworldEntranceNames.HYRULE_FIELD_RIVER_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), + (Regions.LON_LON_RANCH, lambda bundle: True, SOHOverworldEntranceNames.HYRULE_FIELD_CENTER_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), + (Regions.HF_SOUTHEAST_GROTTO, lambda bundle: (blast_or_smash(bundle)), SOHGrottoEntranceNames.HF_SOUTHEAST_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), + (Regions.HF_OPEN_GROTTO, lambda bundle: True, SOHGrottoEntranceNames.HF_OPEN_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), (Regions.HF_INSIDE_FENCE_GROTTO, lambda bundle: ( - can_open_bomb_grotto(bundle))), + can_open_bomb_grotto(bundle)), SOHGrottoEntranceNames.HF_INSIDE_FENCE_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), (Regions.HF_COW_GROTTO, lambda bundle: ((can_use(Items.MEGATON_HAMMER, - bundle) or is_child(bundle)) and can_open_bomb_grotto(bundle))), - (Regions.HF_NEAR_MARKET_GROTTO, lambda bundle: (blast_or_smash(bundle))), - (Regions.HF_FAIRY_GROTTO, lambda bundle: (blast_or_smash(bundle))), - (Regions.HF_NEAR_KAK_GROTTO, lambda bundle: (can_open_bomb_grotto(bundle))), - (Regions.HF_TEKTITE_GROTTO, lambda bundle: (can_open_bomb_grotto(bundle))), + bundle) or is_child(bundle)) and can_open_bomb_grotto(bundle)), SOHGrottoEntranceNames.HF_COW_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), + (Regions.HF_NEAR_MARKET_GROTTO, lambda bundle: (blast_or_smash(bundle)), SOHGrottoEntranceNames.HF_NEAR_MARKET_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), + (Regions.HF_FAIRY_GROTTO, lambda bundle: (blast_or_smash(bundle)), SOHGrottoEntranceNames.HF_FAIRY_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), + (Regions.HF_NEAR_KAK_GROTTO, lambda bundle: (can_open_bomb_grotto(bundle)), SOHGrottoEntranceNames.HF_NEAR_KAK_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), + (Regions.HF_TEKTITE_GROTTO, lambda bundle: (can_open_bomb_grotto(bundle)), SOHGrottoEntranceNames.HF_TEKTITE_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), ]) # HF Southeast Grotto @@ -227,7 +227,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.HF_SOUTHEAST_GROTTO, world, [ - (Regions.HYRULE_FIELD, lambda bundle: True) + (Regions.HYRULE_FIELD, lambda bundle: True, SOHGrottoExitNames.HF_SOUTHEAST_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.CHILD) ]) # HF Open Grotto @@ -261,7 +261,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.HF_OPEN_GROTTO, world, [ - (Regions.HYRULE_FIELD, lambda bundle: True) + (Regions.HYRULE_FIELD, lambda bundle: True, SOHGrottoExitNames.HF_OPEN_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.CHILD) ]) # HF Inside Fence Grotto @@ -275,13 +275,13 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.HF_INSIDE_FENCE_GROTTO, world, [ - (Regions.HYRULE_FIELD, lambda bundle: True) + (Regions.HYRULE_FIELD, lambda bundle: True, SOHGrottoExitNames.HF_INSIDE_FENCE_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE) ]) # HF Cow Grotto # Connections connect_regions(Regions.HF_COW_GROTTO, world, [ - (Regions.HYRULE_FIELD, lambda bundle: True), + (Regions.HYRULE_FIELD, lambda bundle: True, SOHGrottoExitNames.HF_COW_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), (Regions.HF_COW_GROTTO_BEHIND_WEBS, lambda bundle: (has_fire_source(bundle))) ]) @@ -350,7 +350,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.HF_NEAR_MARKET_GROTTO, world, [ - (Regions.HYRULE_FIELD, lambda bundle: True) + (Regions.HYRULE_FIELD, lambda bundle: True, SOHGrottoExitNames.HF_NEAR_MARKET_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.CHILD) ]) # HF Fairy Grotto @@ -372,7 +372,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.HF_FAIRY_GROTTO, world, [ - (Regions.HYRULE_FIELD, lambda bundle: True) + (Regions.HYRULE_FIELD, lambda bundle: True, SOHGrottoExitNames.HF_FAIRY_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE) ]) # HF Near Kak Grotto @@ -383,7 +383,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.HF_NEAR_KAK_GROTTO, world, [ - (Regions.HYRULE_FIELD, lambda bundle: True) + (Regions.HYRULE_FIELD, lambda bundle: True, SOHGrottoExitNames.HF_NEAR_KAK_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE) ]) # HF Tektite Grotto @@ -394,5 +394,5 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.HF_TEKTITE_GROTTO, world, [ - (Regions.HYRULE_FIELD, lambda bundle: True) + (Regions.HYRULE_FIELD, lambda bundle: True, SOHGrottoExitNames.HF_TEKTITE_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE) ]) diff --git a/worlds/oot_soh/location_access/overworld/kakariko.py b/worlds/oot_soh/location_access/overworld/kakariko.py index f087438fa503..34b4e4713edb 100644 --- a/worlds/oot_soh/location_access/overworld/kakariko.py +++ b/worlds/oot_soh/location_access/overworld/kakariko.py @@ -122,20 +122,20 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.KAKARIKO_VILLAGE, world, [ - (Regions.HYRULE_FIELD, lambda bundle: True), + (Regions.HYRULE_FIELD, lambda bundle: True, SOHOverworldEntranceNames.KAKARIKO_VILLAGE_FRONT_GATE, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), (Regions.KAK_CARPENTER_BOSS_HOUSE, - lambda bundle: can_open_overworld_door(Items.BOSS_HOUSE_KEY, bundle)), + lambda bundle: can_open_overworld_door(Items.BOSS_HOUSE_KEY, bundle), SOHInteriorEntranceNames.KAK_CARPENTER_BOSS_HOUSE_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE), (Regions.KAK_HOUSE_OF_SKULLTULA, lambda bundle: can_open_overworld_door( - Items.SKULLTULA_HOUSE_KEY, bundle)), + Items.SKULLTULA_HOUSE_KEY, bundle), SOHInteriorEntranceNames.KAK_HOUSE_OF_SKULLTULA_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE), (Regions.KAK_IMPAS_HOUSE, lambda bundle: can_open_overworld_door( - Items.IMPAS_HOUSE_KEY, bundle)), + Items.IMPAS_HOUSE_KEY, bundle), SOHInteriorEntranceNames.KAK_IMPAS_HOUSE_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE), (Regions.KAK_WINDMILL, lambda bundle: can_open_overworld_door( - Items.WINDMILL_KEY, bundle)), + Items.WINDMILL_KEY, bundle), SOHSpecialInteriorEntranceNames.KAK_WINDMILL_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE), (Regions.KAK_BAZAAR, - lambda bundle: is_adult(bundle) and at_day(bundle) and can_open_overworld_door(Items.KAK_BAZAAR_KEY, bundle)), + lambda bundle: is_adult(bundle) and at_day(bundle) and can_open_overworld_door(Items.KAK_BAZAAR_KEY, bundle), SOHInteriorEntranceNames.KAK_BAZAAR_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ADULT_ONLY), (Regions.KAK_SHOOTING_GALLERY, lambda bundle: is_adult(bundle) and at_day(bundle) and can_open_overworld_door(Items.KAK_SHOOTING_GALLERY_KEY, - bundle)), + bundle), SOHInteriorEntranceNames.KAK_SHOOTING_GALLERY_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ADULT_ONLY), (Regions.KAK_WELL, lambda bundle: is_adult(bundle) or has_item(Events.DRAIN_WELL, bundle) or can_use(Items.IRON_BOOTS, bundle) or ( @@ -143,8 +143,8 @@ def set_region_rules(world: "SohWorld") -> None: bundle) and has_item(Items.BRONZE_SCALE, bundle) and can_jump_slash(bundle))), (Regions.KAK_POTION_SHOP_FRONT, lambda bundle: (at_day(bundle) or is_child(bundle)) and can_open_overworld_door( - Items.KAK_POTION_SHOP_KEY, bundle)), - (Regions.KAK_REDEAD_GROTTO, lambda bundle: can_open_bomb_grotto(bundle)), + Items.KAK_POTION_SHOP_KEY, bundle), SOHSpecialInteriorEntranceNames.KAK_POTION_SHOP_FRONT_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE), + (Regions.KAK_REDEAD_GROTTO, lambda bundle: can_open_bomb_grotto(bundle), SOHGrottoEntranceNames.KAK_REDEAD_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), (Regions.KAK_IMPAS_LEDGE, lambda bundle: (is_child(bundle) and at_day(bundle)) or ( is_adult(bundle) and can_do_trick(Tricks.VISIBLE_COLLISION, bundle))), (Regions.KAK_WATCHTOWER, @@ -157,7 +157,7 @@ def set_region_rules(world: "SohWorld") -> None: (Regions.KAK_IMPAS_ROOFTOP, lambda bundle: can_use(Items.HOOKSHOT, bundle) or can_do_trick(Tricks.KAK_ROOFTOP_GS, bundle) and can_use( Items.HOVER_BOOTS, bundle)), - (Regions.THE_GRAVEYARD, lambda bundle: True), + (Regions.THE_GRAVEYARD, lambda bundle: True, SOHOverworldEntranceNames.KAKARIKO_VILLAGE_SOUTHEAST_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), (Regions.KAK_BEHIND_GATE, lambda bundle: is_adult(bundle) or has_item(Events.KAKARIKO_GATE_OPEN, bundle)), (Regions.KAK_BACKYARD, lambda bundle: is_adult(bundle) or at_day(bundle)), @@ -166,7 +166,7 @@ def set_region_rules(world: "SohWorld") -> None: # Kak Impas Ledge # Connections connect_regions(Regions.KAK_IMPAS_LEDGE, world, [ - (Regions.KAK_IMPAS_HOUSE_BACK, lambda bundle: True), + (Regions.KAK_IMPAS_HOUSE_BACK, lambda bundle: True, SOHInteriorEntranceNames.KAK_IMPAS_HOUSE_BACK_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ADULT_ONLY), (Regions.KAKARIKO_VILLAGE, lambda bundle: True), ]) @@ -218,12 +218,12 @@ def set_region_rules(world: "SohWorld") -> None: # Connections connect_regions(Regions.KAK_BACKYARD, world, [ (Regions.KAKARIKO_VILLAGE, lambda bundle: True), - (Regions.KAK_OPEN_GROTTO, lambda bundle: True), + (Regions.KAK_OPEN_GROTTO, lambda bundle: True, SOHGrottoEntranceNames.KAK_OPEN_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), (Regions.KAK_GRANNYS_POTION_SHOP, - lambda bundle: is_adult(bundle) and can_open_overworld_door(Items.GRANNYS_POTION_SHOP_KEY, bundle)), + lambda bundle: is_adult(bundle) and can_open_overworld_door(Items.GRANNYS_POTION_SHOP_KEY, bundle), SOHInteriorEntranceNames.KAK_ODD_POTION_BUILDING_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ADULT_ONLY), (Regions.KAK_POTION_SHOP_BACK, lambda bundle: is_adult(bundle) and at_day(bundle) and can_open_overworld_door(Items.KAK_POTION_SHOP_KEY, - bundle)), + bundle), SOHSpecialInteriorEntranceNames.KAK_POTION_SHOP_BACK_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ADULT_ONLY), ]) # Kak Carpenter Boss House @@ -235,7 +235,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.KAK_CARPENTER_BOSS_HOUSE, world, [ - (Regions.KAKARIKO_VILLAGE, lambda bundle: True), + (Regions.KAKARIKO_VILLAGE, lambda bundle: True, SOHInteriorExitNames.KAK_CARPENTER_BOSS_HOUSE_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ADULT), ]) # Kak House of Skulltula @@ -256,13 +256,13 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.KAK_HOUSE_OF_SKULLTULA, world, [ - (Regions.KAKARIKO_VILLAGE, lambda bundle: True), + (Regions.KAKARIKO_VILLAGE, lambda bundle: True, SOHInteriorExitNames.KAK_HOUSE_OF_SKULLTULA_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE), ]) # Kak Impas House # Connections connect_regions(Regions.KAK_IMPAS_HOUSE, world, [ - (Regions.KAKARIKO_VILLAGE, lambda bundle: True), + (Regions.KAKARIKO_VILLAGE, lambda bundle: True, SOHInteriorExitNames.KAK_IMPAS_HOUSE_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE), (Regions.KAK_COW_CAGE, lambda bundle: can_play_song(Items.EPONAS_SONG, bundle)) ]) @@ -273,7 +273,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.KAK_IMPAS_HOUSE_BACK, world, [ - (Regions.KAK_IMPAS_LEDGE, lambda bundle: True), + (Regions.KAK_IMPAS_LEDGE, lambda bundle: True, SOHInteriorExitNames.KAK_IMPAS_HOUSE_BACK_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE), (Regions.KAK_COW_CAGE, lambda bundle: can_play_song(Items.EPONAS_SONG, bundle)), ]) @@ -302,7 +302,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.KAK_WINDMILL, world, [ - (Regions.KAKARIKO_VILLAGE, lambda bundle: True), + (Regions.KAKARIKO_VILLAGE, lambda bundle: True, SOHSpecialInteriorExitNames.KAK_WINDMILL_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.BOTH_AGE), ]) # Kak Bazaar @@ -318,7 +318,7 @@ def set_region_rules(world: "SohWorld") -> None: (Locations.KAK_BAZAAR_ITEM8, lambda bundle: True), ]) connect_regions(Regions.KAK_BAZAAR, world, [ - (Regions.KAKARIKO_VILLAGE, lambda bundle: True), + (Regions.KAKARIKO_VILLAGE, lambda bundle: True, SOHInteriorExitNames.KAK_BAZAAR_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE), ]) # Kak Shooting Gallery @@ -329,7 +329,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.KAK_SHOOTING_GALLERY, world, [ - (Regions.KAKARIKO_VILLAGE, lambda bundle: True), + (Regions.KAKARIKO_VILLAGE, lambda bundle: True, SOHInteriorExitNames.KAK_SHOOTING_GALLERY_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ADULT_ONLY), ]) # Kak Potion Shop Front @@ -346,7 +346,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.KAK_POTION_SHOP_FRONT, world, [ - (Regions.KAKARIKO_VILLAGE, lambda bundle: True), + (Regions.KAKARIKO_VILLAGE, lambda bundle: True, SOHSpecialInteriorExitNames.KAK_POTION_SHOP_FRONT_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ADULT_ONLY), (Regions.KAK_POTION_SHOP_BACK, lambda bundle: is_adult(bundle)), ]) @@ -354,7 +354,7 @@ def set_region_rules(world: "SohWorld") -> None: # Connections connect_regions(Regions.KAK_POTION_SHOP_BACK, world, [ (Regions.KAK_POTION_SHOP_FRONT, lambda bundle: True), - (Regions.KAK_BACKYARD, lambda bundle: is_adult(bundle)), + (Regions.KAK_BACKYARD, lambda bundle: is_adult(bundle), SOHSpecialInteriorExitNames.KAK_POTION_SHOP_BACK_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ADULT_ONLY), ]) # Kak Granny's Potion Shop @@ -368,7 +368,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.KAK_GRANNYS_POTION_SHOP, world, [ - (Regions.KAK_BACKYARD, lambda bundle: True) + (Regions.KAK_BACKYARD, lambda bundle: True, SOHInteriorExitNames.KAK_ODD_POTION_BUILDING_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ADULT_ONLY) ]) # Kak Redead Grotto @@ -380,7 +380,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.KAK_REDEAD_GROTTO, world, [ - (Regions.KAKARIKO_VILLAGE, lambda bundle: True), + (Regions.KAKARIKO_VILLAGE, lambda bundle: True, SOHGrottoExitNames.KAK_REDEAD_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), ]) # Kak Open Grotto @@ -414,7 +414,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.KAK_OPEN_GROTTO, world, [ - (Regions.KAK_BACKYARD, lambda bundle: True), + (Regions.KAK_BACKYARD, lambda bundle: True, SOHGrottoExitNames.KAK_OPEN_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.CHILD), ]) # Kak Behind Gate @@ -423,16 +423,14 @@ def set_region_rules(world: "SohWorld") -> None: (Regions.KAKARIKO_VILLAGE, lambda bundle: is_adult(bundle) or has_item(Events.KAKARIKO_GATE_OPEN, bundle) or can_do_trick( Tricks.VISIBLE_COLLISION, bundle)), - (Regions.DEATH_MOUNTAIN, lambda bundle: True) + (Regions.DEATH_MOUNTAIN, lambda bundle: True, SOHOverworldEntranceNames.KAKARIKO_VILLAGE_GUARD_GATE, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE) ]) # Kak Well # Connections connect_regions(Regions.KAK_WELL, world, [ (Regions.KAKARIKO_VILLAGE, - lambda bundle: is_adult(bundle) or has_item(Items.BRONZE_SCALE, bundle) or has_item(Events.DRAIN_WELL, - bundle)), - # TODO: Add check for dungeon entrance randomization - (Regions.BOTTOM_OF_THE_WELL_ENTRYWAY, lambda bundle: is_child( - bundle) or has_item(Events.DRAIN_WELL, bundle)), + lambda bundle: is_adult(bundle) or has_item(Items.BRONZE_SCALE, bundle) or has_item(Events.DRAIN_WELL, bundle)), + (Regions.BOTTOM_OF_THE_WELL_ENTRYWAY, lambda bundle: is_child(bundle) or (has_item(Events.DRAIN_WELL, bundle) and world.options.shuffle_dungeon_entrances.value > + 0), SOHDungeonEntranceNames.BOTTOM_OF_THE_WELL_DUNGEON_ENTRANCE, SOHEntranceGroups.DUNGEON_ENTRANCE | SOHEntranceGroups.ANY_AGE, EntranceType.TWO_WAY) ]) diff --git a/worlds/oot_soh/location_access/overworld/kokiri_forest.py b/worlds/oot_soh/location_access/overworld/kokiri_forest.py index f697f40ef08e..cb2fdfb35c3f 100644 --- a/worlds/oot_soh/location_access/overworld/kokiri_forest.py +++ b/worlds/oot_soh/location_access/overworld/kokiri_forest.py @@ -167,22 +167,22 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.KOKIRI_FOREST, world, [ - (Regions.KF_LINKS_HOUSE, lambda bundle: True), - (Regions.KF_MIDOS_HOUSE, lambda bundle: True), - (Regions.KF_SARIAS_HOUSE, lambda bundle: True), - (Regions.KF_HOUSE_OF_TWINS, lambda bundle: True), - (Regions.KF_KNOW_IT_ALL_HOUSE, lambda bundle: True), - (Regions.KF_KOKIRI_SHOP, lambda bundle: True), + (Regions.KF_LINKS_HOUSE, lambda bundle: True, SOHSpecialInteriorEntranceNames.KF_LINKS_HOUSE_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE), + (Regions.KF_MIDOS_HOUSE, lambda bundle: True, SOHInteriorEntranceNames.KF_MIDOS_HOUSE_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE), + (Regions.KF_SARIAS_HOUSE, lambda bundle: True, SOHInteriorEntranceNames.KF_SARIAS_HOUSE_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE), + (Regions.KF_HOUSE_OF_TWINS, lambda bundle: True, SOHInteriorEntranceNames.KF_TWINS_HOUSE_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE), + (Regions.KF_KNOW_IT_ALL_HOUSE, lambda bundle: True, SOHInteriorEntranceNames.KF_KNOW_IT_ALL_HOUSE_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE), + (Regions.KF_KOKIRI_SHOP, lambda bundle: True, SOHInteriorEntranceNames.KF_KOKIRI_SHOP_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE), (Regions.KF_OUTSIDE_DEKU_TREE, lambda bundle: (is_adult(bundle) and (can_pass_enemy(bundle, Enemies.BIG_SKULLTULA) or has_item(Events.FOREST_TEMPLE_COMPLETED, bundle))) or (is_child(bundle) and has_item(LocalEvents.MIDO_SWORD_AND_SHIELD, bundle)) # Todo, maybe create a helper for handling settings or world.options.closed_forest.value == 2), - (Regions.LOST_WOODS, lambda bundle: True), + (Regions.LOST_WOODS, lambda bundle: True, SOHOverworldEntranceNames.KOKIRI_FOREST_UPPER_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), (Regions.LW_BRIDGE_FROM_FOREST, lambda bundle: world.options.closed_forest.value >= 1 or is_adult(bundle) or - has_item(Events.DEKU_TREE_COMPLETED, bundle)), - (Regions.KF_STORMS_GROTTO, lambda bundle: can_open_storms_grotto(bundle)) + has_item(Events.DEKU_TREE_COMPLETED, bundle), SOHOverworldEntranceNames.KOKIRI_FOREST_LOWER_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), + (Regions.KF_STORMS_GROTTO, lambda bundle: can_open_storms_grotto(bundle), SOHGrottoEntranceNames.KF_STORMS_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE) ]) # KF Outside Deku Tree @@ -211,10 +211,8 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.KF_OUTSIDE_DEKU_TREE, world, [ - (Regions.DEKU_TREE_ENTRYWAY, lambda bundle: (is_child(bundle)) - # Todo: Add dungeons shuffle rule when entrance shuffle is implementedd - and (world.options.closed_forest.value == 2 - or has_item(LocalEvents.MIDO_SWORD_AND_SHIELD, bundle))), + (Regions.DEKU_TREE_ENTRYWAY, lambda bundle: is_child(bundle) or (world.options.shuffle_dungeon_entrances.value > 0 and (world.options.closed_forest.value == 2 or has_item( + LocalEvents.MIDO_SWORD_AND_SHIELD, bundle))), SOHDungeonEntranceNames.DEKU_TREE_DUNGEON_ENTRANCE, SOHEntranceGroups.DUNGEON_ENTRANCE | SOHEntranceGroups.ANY_AGE, EntranceType.TWO_WAY), (Regions.KOKIRI_FOREST, lambda bundle: (is_adult(bundle) and (can_pass_enemy(bundle, Enemies.BIG_SKULLTULA) or has_item(Events.FOREST_TEMPLE_COMPLETED, bundle))) @@ -232,7 +230,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.KF_LINKS_HOUSE, world, [ - (Regions.KOKIRI_FOREST, lambda bundle: True) + (Regions.KOKIRI_FOREST, lambda bundle: True, SOHSpecialInteriorExitNames.KF_LINKS_HOUSE_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.BOTH_AGE) ]) # KF Mido's House @@ -245,7 +243,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.KF_MIDOS_HOUSE, world, [ - (Regions.KOKIRI_FOREST, lambda bundle: True) + (Regions.KOKIRI_FOREST, lambda bundle: True, SOHInteriorExitNames.KF_MIDOS_HOUSE_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE) ]) # KF Saria's House @@ -258,7 +256,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.KF_SARIAS_HOUSE, world, [ - (Regions.KOKIRI_FOREST, lambda bundle: True) + (Regions.KOKIRI_FOREST, lambda bundle: True, SOHInteriorExitNames.KF_SARIAS_HOUSE_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE) ]) # KF House of Twins @@ -270,7 +268,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.KF_HOUSE_OF_TWINS, world, [ - (Regions.KOKIRI_FOREST, lambda bundle: True) + (Regions.KOKIRI_FOREST, lambda bundle: True, SOHInteriorExitNames.KF_TWINS_HOUSE_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE) ]) # KF Know it All House @@ -282,7 +280,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.KF_KNOW_IT_ALL_HOUSE, world, [ - (Regions.KOKIRI_FOREST, lambda bundle: True) + (Regions.KOKIRI_FOREST, lambda bundle: True, SOHInteriorExitNames.KF_KNOW_IT_ALL_HOUSE_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE) ]) # KF Kokiri Shop @@ -299,7 +297,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.KF_KOKIRI_SHOP, world, [ - (Regions.KOKIRI_FOREST, lambda bundle: True) + (Regions.KOKIRI_FOREST, lambda bundle: True, SOHInteriorExitNames.KF_KOKIRI_SHOP_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE) ]) # KF Storms Grotto @@ -333,5 +331,5 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.KF_STORMS_GROTTO, world, [ - (Regions.KOKIRI_FOREST, lambda bundle: True) + (Regions.KOKIRI_FOREST, lambda bundle: True, SOHGrottoExitNames.KF_STORMS_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.CHILD) ]) diff --git a/worlds/oot_soh/location_access/overworld/lake_hylia.py b/worlds/oot_soh/location_access/overworld/lake_hylia.py index 6f8f1bcfd6f0..1370bcb80043 100644 --- a/worlds/oot_soh/location_access/overworld/lake_hylia.py +++ b/worlds/oot_soh/location_access/overworld/lake_hylia.py @@ -155,7 +155,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.LAKE_HYLIA, world, [ - (Regions.HYRULE_FIELD, lambda bundle: True), + (Regions.HYRULE_FIELD, lambda bundle: True, SOHOverworldEntranceNames.LAKE_HYLIA_NORTH_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), (Regions.LH_FROM_SHORTCUT, lambda bundle: True), (Regions.LH_OWL_FLIGHT, lambda bundle: is_child(bundle)), (Regions.LH_FISHING_ISLAND, lambda bundle: ((is_child(bundle) @@ -165,9 +165,9 @@ def set_region_rules(world: "SohWorld") -> None: and (can_use(Items.SCARECROW, bundle) or has_item(LocalEvents.LH_BEAN_PLANTED, bundle)))), (Regions.LH_LAB, lambda bundle: can_open_overworld_door( - Items.HYLIA_LAB_KEY, bundle)), + Items.HYLIA_LAB_KEY, bundle), SOHInteriorEntranceNames.LH_LAB_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE), (Regions.LH_FROM_WATER_TEMPLE, lambda bundle: True), - (Regions.LH_GROTTO, lambda bundle: True), + (Regions.LH_GROTTO, lambda bundle: True, SOHGrottoEntranceNames.LH_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), ]) # LH from Shortcut @@ -179,7 +179,7 @@ def set_region_rules(world: "SohWorld") -> None: can_use(Items.IRON_BOOTS, bundle)), (Regions.ZORAS_DOMAIN, lambda bundle: is_child(bundle) and (has_item(Items.SILVER_SCALE, bundle) or - can_use(Items.IRON_BOOTS, bundle))), + can_use(Items.IRON_BOOTS, bundle)), SOHOverworldEntranceNames.LAKE_HYLIA_UNDERWATER_SHORTCUT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.CHILD_ONLY), ]) # LH from Water Temple @@ -194,7 +194,7 @@ def set_region_rules(world: "SohWorld") -> None: has_item(Items.GOLDEN_SCALE, bundle))) or (is_adult(bundle) and can_use(Items.LONGSHOT, bundle) and - has_item(Items.GOLDEN_SCALE, bundle)))), + has_item(Items.GOLDEN_SCALE, bundle))), SOHDungeonEntranceNames.WATER_TEMPLE_DUNGEON_ENTRANCE, SOHEntranceGroups.DUNGEON_ENTRANCE | SOHEntranceGroups.ADULT_ONLY, EntranceType.TWO_WAY), ]) # LH Fishing Island @@ -202,13 +202,13 @@ def set_region_rules(world: "SohWorld") -> None: connect_regions(Regions.LH_FISHING_ISLAND, world, [ (Regions.LAKE_HYLIA, lambda bundle: has_item(Items.BRONZE_SCALE, bundle)), (Regions.LH_FISHING_HOLE, lambda bundle: can_open_overworld_door( - Items.FISHING_HOLE_KEY, bundle)), + Items.FISHING_HOLE_KEY, bundle), SOHInteriorEntranceNames.LH_FISHING_POND_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE), ]) # LH Owl Flight # Connections connect_regions(Regions.LH_OWL_FLIGHT, world, [ - (Regions.HYRULE_FIELD, lambda bundle: True), + (Regions.HYRULE_FIELD, lambda bundle: True, Regions.LH_OWL_FLIGHT), ]) # LH Lab @@ -234,7 +234,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.LH_LAB, world, [ - (Regions.LAKE_HYLIA, lambda bundle: True), + (Regions.LAKE_HYLIA, lambda bundle: True, SOHInteriorExitNames.LH_LAB_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ADULT), ]) # LH Fishing HOLE @@ -316,7 +316,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.LH_FISHING_HOLE, world, [ - (Regions.LH_FISHING_ISLAND, lambda bundle: True), + (Regions.LH_FISHING_ISLAND, lambda bundle: True, SOHInteriorExitNames.LH_FISHING_POND_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.BOTH_AGE), ]) # LH Grotto @@ -333,5 +333,5 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.LH_GROTTO, world, [ - (Regions.LAKE_HYLIA, lambda bundle: True) + (Regions.LAKE_HYLIA, lambda bundle: True, SOHGrottoExitNames.LH_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE) ]) diff --git a/worlds/oot_soh/location_access/overworld/lon_lon_ranch.py b/worlds/oot_soh/location_access/overworld/lon_lon_ranch.py index 9906fd9522e2..eb653de113d2 100644 --- a/worlds/oot_soh/location_access/overworld/lon_lon_ranch.py +++ b/worlds/oot_soh/location_access/overworld/lon_lon_ranch.py @@ -51,14 +51,14 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.LON_LON_RANCH, world, [ - (Regions.HYRULE_FIELD, lambda bundle: True), + (Regions.HYRULE_FIELD, lambda bundle: True, SOHOverworldEntranceNames.LON_LON_RANCH_ENTRANCE, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), (Regions.LLR_TALONS_HOUSE, lambda bundle: can_open_overworld_door( - Items.TALONS_HOUSE_KEY, bundle)), + Items.TALONS_HOUSE_KEY, bundle), SOHInteriorEntranceNames.LLR_TALONS_HOUSE_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE), (Regions.LLR_STABLES, lambda bundle: can_open_overworld_door( - Items.STABLES_KEY, bundle)), + Items.STABLES_KEY, bundle), SOHInteriorEntranceNames.LLR_STABLES_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE), (Regions.LLR_TOWER, lambda bundle: can_open_overworld_door( - Items.BACK_TOWER_KEY, bundle)), - (Regions.LLR_GROTTO, lambda bundle: is_child(bundle)), + Items.BACK_TOWER_KEY, bundle), SOHInteriorEntranceNames.LLR_TOWER_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE), + (Regions.LLR_GROTTO, lambda bundle: is_child(bundle), SOHGrottoEntranceNames.LLR_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.CHILD_ONLY), ]) # LLR Talons House @@ -72,7 +72,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.LLR_TALONS_HOUSE, world, [ - (Regions.LON_LON_RANCH, lambda bundle: True) + (Regions.LON_LON_RANCH, lambda bundle: True, SOHInteriorExitNames.LLR_TALONS_HOUSE_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.CHILD) ]) # LLR Stables @@ -85,7 +85,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.LLR_STABLES, world, [ - (Regions.LON_LON_RANCH, lambda bundle: True) + (Regions.LON_LON_RANCH, lambda bundle: True, SOHInteriorExitNames.LLR_STABLES_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE) ]) # LLR Tower @@ -99,7 +99,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.LLR_TOWER, world, [ - (Regions.LON_LON_RANCH, lambda bundle: True) + (Regions.LON_LON_RANCH, lambda bundle: True, SOHInteriorExitNames.LLR_TOWER_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.CHILD) ]) # LLR Grotto @@ -116,5 +116,5 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.LLR_GROTTO, world, [ - (Regions.LON_LON_RANCH, lambda bundle: True) + (Regions.LON_LON_RANCH, lambda bundle: True, SOHGrottoExitNames.LLR_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE) ]) diff --git a/worlds/oot_soh/location_access/overworld/lost_woods.py b/worlds/oot_soh/location_access/overworld/lost_woods.py index 42fb3e5ca92e..263e815ecc56 100644 --- a/worlds/oot_soh/location_access/overworld/lost_woods.py +++ b/worlds/oot_soh/location_access/overworld/lost_woods.py @@ -27,7 +27,7 @@ def set_region_rules(world: "SohWorld") -> None: # LW Forest Exit # Connections connect_regions(Regions.LW_FOREST_EXIT, world, [ - (Regions.KOKIRI_FOREST, lambda bundle: True), + (Regions.KOKIRI_FOREST, lambda bundle: True, SOHOverworldEntranceNames.LOST_WOODS_SOUTH_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), ]) # Lost Woods @@ -101,7 +101,7 @@ def set_region_rules(world: "SohWorld") -> None: # Connections connect_regions(Regions.LOST_WOODS, world, [ (Regions.LW_FOREST_EXIT, lambda bundle: True), - (Regions.GC_WOODS_WARP, lambda bundle: True), + (Regions.GC_WOODS_WARP, lambda bundle: True, SOHOverworldEntranceNames.LOST_WOODS_TUNNEL_SHORTCUT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), (Regions.LW_BRIDGE, lambda bundle: (is_adult(bundle) and ( has_item(LocalEvents.LW_BRIDGE_BEAN_PLANTED, bundle) or can_do_trick(Tricks.LW_BRIDGE, bundle))) or can_use(Items.HOVER_BOOTS, bundle) or can_use( @@ -109,11 +109,11 @@ def set_region_rules(world: "SohWorld") -> None: (Regions.ZR_FROM_SHORTCUT, lambda bundle: has_item(Items.SILVER_SCALE, bundle) or can_use(Items.IRON_BOOTS, bundle) or (can_do_trick( Tricks.LOST_WOOD_NAVI_DIVE, bundle) and is_child(bundle) and has_item(Items.BRONZE_SCALE, - bundle) and can_jump_slash(bundle))), + bundle) and can_jump_slash(bundle)), SOHOverworldEntranceNames.LOST_WOODS_UNDERWATER_SHORTCUT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), (Regions.LW_BEYOND_MIDO, lambda bundle: is_child(bundle) or can_use(Items.SARIAS_SONG, bundle) or can_do_trick(Tricks.LW_MIDO_BACKFLIP, bundle)), - (Regions.LW_NEAR_SHORTCUTS_GROTTO, lambda bundle: blast_or_smash(bundle)), + (Regions.LW_NEAR_SHORTCUTS_GROTTO, lambda bundle: blast_or_smash(bundle), SOHGrottoEntranceNames.LW_NEAR_SHORTCUTS_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), ]) # LW Beyond Mido @@ -160,9 +160,9 @@ def set_region_rules(world: "SohWorld") -> None: (Regions.LW_FOREST_EXIT, lambda bundle: True), (Regions.LOST_WOODS, lambda bundle: is_child( bundle) or can_use(Items.SARIAS_SONG, bundle)), - (Regions.SFM_ENTRYWAY, lambda bundle: True), - (Regions.DEKU_THEATER, lambda bundle: True), - (Regions.LW_SCRUBS_GROTTO, lambda bundle: blast_or_smash(bundle)), + (Regions.SFM_ENTRYWAY, lambda bundle: True, SOHOverworldEntranceNames.LOST_WOODS_NORTH_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), + (Regions.DEKU_THEATER, lambda bundle: True, SOHGrottoEntranceNames.DEKU_THEATER_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), + (Regions.LW_SCRUBS_GROTTO, lambda bundle: blast_or_smash(bundle), SOHGrottoEntranceNames.LW_SCRUBS_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), ]) # LW Near Shortcuts Grotto @@ -201,7 +201,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.LW_NEAR_SHORTCUTS_GROTTO, world, [ - (Regions.LOST_WOODS, lambda bundle: True), + (Regions.LOST_WOODS, lambda bundle: True, SOHGrottoExitNames.LW_NEAR_SHORTCUTS_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.CHILD), ]) # Deku Theater @@ -214,7 +214,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.DEKU_THEATER, world, [ - (Regions.LOST_WOODS, lambda bundle: True), + (Regions.LOST_WOODS, lambda bundle: True, SOHGrottoExitNames.DEKU_THEATER_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.CHILD_ONLY), ]) # LW Scrubs Grotto @@ -230,23 +230,27 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.LW_SCRUBS_GROTTO, world, [ - (Regions.LW_BEYOND_MIDO, lambda bundle: True), + (Regions.LW_BEYOND_MIDO, lambda bundle: True, SOHGrottoExitNames.LW_SCRUBS_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), ]) - # LW Bridge From Forest + # # LW Bridge From Forest + # # Location + # add_locations(Regions.LW_BRIDGE_FROM_FOREST, world, [ + # (Locations.LW_GIFT_FROM_SARIA, lambda bundle: True) + # ]) + # # Connections + # connect_regions(Regions.LW_BRIDGE_FROM_FOREST, world, [ + # (Regions.LW_BRIDGE, lambda bundle: True), + # ]) + + # LW Bridge # Location - add_locations(Regions.LW_BRIDGE_FROM_FOREST, world, [ + add_locations(Regions.LW_BRIDGE, world, [ (Locations.LW_GIFT_FROM_SARIA, lambda bundle: True) ]) # Connections - connect_regions(Regions.LW_BRIDGE_FROM_FOREST, world, [ - (Regions.LW_BRIDGE, lambda bundle: True), - ]) - - # LW Bridge - # Connections connect_regions(Regions.LW_BRIDGE, world, [ - (Regions.KOKIRI_FOREST, lambda bundle: True), - (Regions.HYRULE_FIELD, lambda bundle: True), + (Regions.KOKIRI_FOREST, lambda bundle: True, SOHOverworldEntranceNames.LOST_WOODS_BRIDGE_EAST_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), + (Regions.HYRULE_FIELD, lambda bundle: True, SOHOverworldEntranceNames.LOST_WOODS_BRIDGE_WEST_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), (Regions.LOST_WOODS, lambda bundle: can_use(Items.LONGSHOT, bundle)) ]) diff --git a/worlds/oot_soh/location_access/overworld/market.py b/worlds/oot_soh/location_access/overworld/market.py index 50dc336489a9..e91f601ffe52 100644 --- a/worlds/oot_soh/location_access/overworld/market.py +++ b/worlds/oot_soh/location_access/overworld/market.py @@ -19,10 +19,10 @@ def set_region_rules(world: "SohWorld") -> None: # Connections connect_regions(Regions.MARKET_ENTRANCE, world, [ (Regions.HYRULE_FIELD, lambda bundle: ( - is_adult(bundle) or at_day(bundle))), - (Regions.MARKET, lambda bundle: True), + is_adult(bundle) or at_day(bundle)), SOHOverworldEntranceNames.MARKET_ENTRANCE_NEAR_GUARD_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), + (Regions.MARKET, lambda bundle: True, SOHOverworldEntranceNames.MARKET_ENTRANCE_NORTH_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), (Regions.MARKET_GUARD_HOUSE, lambda bundle: can_open_overworld_door( - Items.GUARD_HOUSE_KEY, bundle)) + Items.GUARD_HOUSE_KEY, bundle), SOHInteriorEntranceNames.MARKET_GUARD_HOUSE_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE) ]) # Market @@ -55,21 +55,21 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.MARKET, world, [ - (Regions.MARKET_ENTRANCE, lambda bundle: True), - (Regions.TOT_ENTRANCE, lambda bundle: True), - (Regions.CASTLE_GROUNDS, lambda bundle: True), + (Regions.MARKET_ENTRANCE, lambda bundle: True, SOHOverworldEntranceNames.MARKET_SOUTH_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), + (Regions.TOT_ENTRANCE, lambda bundle: True, SOHOverworldEntranceNames.MARKET_DAY_TEMPLE_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), + (Regions.CASTLE_GROUNDS, lambda bundle: True, SOHOverworldEntranceNames.MARKET_DAY_CASTLE_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), (Regions.MARKET_BAZAAR, lambda bundle: (is_child(bundle) and at_day( - bundle) and can_open_overworld_door(Items.MARKET_BAZAAR_KEY, bundle))), + bundle) and can_open_overworld_door(Items.MARKET_BAZAAR_KEY, bundle)), SOHInteriorEntranceNames.MARKET_BAZAAR_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.CHILD_ONLY), (Regions.MARKET_MASK_SHOP, lambda bundle: (is_child(bundle) and at_day( - bundle) and can_open_overworld_door(Items.MASK_SHOP_KEY, bundle))), + bundle) and can_open_overworld_door(Items.MASK_SHOP_KEY, bundle)), SOHInteriorEntranceNames.MARKET_MASK_SHOP_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.CHILD_ONLY), (Regions.MARKET_SHOOTING_GALLERY, lambda bundle: (is_child(bundle) and at_day( - bundle) and can_open_overworld_door(Items.MARKET_SHOOTING_GALLERY_KEY, bundle))), + bundle) and can_open_overworld_door(Items.MARKET_SHOOTING_GALLERY_KEY, bundle)), SOHInteriorEntranceNames.MARKET_SHOOTING_GALLERY_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.CHILD_ONLY), (Regions.MARKET_BOMBCHU_BOWLING, lambda bundle: (is_child(bundle) - and can_open_overworld_door(Items.BOMBCHU_BOWLING_KEY, bundle))), + and can_open_overworld_door(Items.BOMBCHU_BOWLING_KEY, bundle)), SOHInteriorEntranceNames.MARKET_BOMBCHU_BOWLING_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.CHILD_ONLY), (Regions.MARKET_TREASURE_CHEST_GAME, lambda bundle: (is_child(bundle) and at_night( - bundle) and can_open_overworld_door(Items.TREASURE_CHEST_GAME_BUILDING_KEY, bundle))), + bundle) and can_open_overworld_door(Items.TREASURE_CHEST_GAME_BUILDING_KEY, bundle)), SOHInteriorEntranceNames.MARKET_TREASURE_CHEST_GAME_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.CHILD_ONLY), (Regions.MARKET_POTION_SHOP, lambda bundle: (is_child(bundle) and at_day( - bundle) and can_open_overworld_door(Items.MARKET_POTION_SHOP_KEY, bundle))), + bundle) and can_open_overworld_door(Items.MARKET_POTION_SHOP_KEY, bundle)), SOHInteriorEntranceNames.MARKET_POTION_SHOP_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.CHILD_ONLY), (Regions.MARKET_BACK_ALLEY, lambda bundle: is_child(bundle)) ]) @@ -78,11 +78,11 @@ def set_region_rules(world: "SohWorld") -> None: connect_regions(Regions.MARKET_BACK_ALLEY, world, [ (Regions.MARKET, lambda bundle: True), (Regions.MARKET_BOMBCHU_SHOP, lambda bundle: (at_night(bundle) - and can_open_overworld_door(Items.BOMBCHU_SHOP_KEY, bundle))), + and can_open_overworld_door(Items.BOMBCHU_SHOP_KEY, bundle)), SOHInteriorEntranceNames.MARKET_BOMBCHU_SHOP_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.CHILD_ONLY), (Regions.MARKET_DOG_LADY_HOUSE, lambda bundle: ( can_open_overworld_door(Items.RICHARDS_HOUSE_KEY, bundle))), (Regions.MARKET_MAN_IN_GREEN_HOUSE, lambda bundle: (at_night(bundle) - and can_open_overworld_door(Items.ALLEY_HOUSE_KEY, bundle))) + and can_open_overworld_door(Items.ALLEY_HOUSE_KEY, bundle)), SOHInteriorEntranceNames.MARKET_MAN_IN_GREEN_HOUSE_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.CHILD_ONLY) ]) # Market Guard House @@ -221,7 +221,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.MARKET_GUARD_HOUSE, world, [ - (Regions.MARKET_ENTRANCE, lambda bundle: True) + (Regions.MARKET_ENTRANCE, lambda bundle: True, SOHInteriorExitNames.MARKET_GUARD_HOUSE_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.BOTH_AGE) ]) # Market Bazaar @@ -238,7 +238,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.MARKET_BAZAAR, world, [ - (Regions.MARKET, lambda bundle: True) + (Regions.MARKET, lambda bundle: True, SOHInteriorExitNames.MARKET_BAZAAR_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE) ]) # Market Mask Shop @@ -257,7 +257,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.MARKET_MASK_SHOP, world, [ - (Regions.MARKET, lambda bundle: True) + (Regions.MARKET, lambda bundle: True, SOHInteriorExitNames.MARKET_MASK_SHOP_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE) ]) # Market Shooting Gallery @@ -268,7 +268,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.MARKET_SHOOTING_GALLERY, world, [ - (Regions.MARKET, lambda bundle: True) + (Regions.MARKET, lambda bundle: True, SOHInteriorExitNames.MARKET_SHOOTING_GALLERY_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.CHILD) ]) # Market Bombchu Bowling @@ -286,7 +286,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.MARKET_BOMBCHU_BOWLING, world, [ - (Regions.MARKET, lambda bundle: True) + (Regions.MARKET, lambda bundle: True, SOHInteriorExitNames.MARKET_BOMBCHU_BOWLING_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE) ]) # Market Potion Shop @@ -303,7 +303,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.MARKET_POTION_SHOP, world, [ - (Regions.MARKET, lambda bundle: True) + (Regions.MARKET, lambda bundle: True, SOHInteriorExitNames.MARKET_POTION_SHOP_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE) ]) # Market Treasure Chest Game @@ -314,7 +314,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.MARKET_TREASURE_CHEST_GAME, world, [ - (Regions.MARKET, lambda bundle: True) + (Regions.MARKET, lambda bundle: True, SOHInteriorExitNames.MARKET_TREASURE_CHEST_GAME_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE) ]) # Market Bombchu Shop @@ -331,7 +331,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.MARKET_BOMBCHU_SHOP, world, [ - (Regions.MARKET_BACK_ALLEY, lambda bundle: True) + (Regions.MARKET_BACK_ALLEY, lambda bundle: True, SOHInteriorExitNames.MARKET_BOMBCHU_SHOP_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE) ]) # Market Dog Lady House @@ -359,5 +359,5 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.MARKET_MAN_IN_GREEN_HOUSE, world, [ - (Regions.MARKET_BACK_ALLEY, lambda bundle: True) + (Regions.MARKET_BACK_ALLEY, lambda bundle: True, SOHInteriorExitNames.MARKET_MAN_IN_GREEN_HOUSE_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE) ]) diff --git a/worlds/oot_soh/location_access/overworld/sacred_forest_meadow.py b/worlds/oot_soh/location_access/overworld/sacred_forest_meadow.py index 24323b25390c..9f5791fa4a2f 100644 --- a/worlds/oot_soh/location_access/overworld/sacred_forest_meadow.py +++ b/worlds/oot_soh/location_access/overworld/sacred_forest_meadow.py @@ -13,10 +13,10 @@ def set_region_rules(world: "SohWorld") -> None: # SFM Entryway # Connections connect_regions(Regions.SFM_ENTRYWAY, world, [ - (Regions.LW_BEYOND_MIDO, lambda bundle: True), + (Regions.LW_BEYOND_MIDO, lambda bundle: True, SOHOverworldEntranceNames.SACRED_FOREST_MEADOW_SOUTH_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), (Regions.SACRED_FOREST_MEADOW, lambda bundle: is_adult( bundle) or can_kill_enemy(bundle, Enemies.WOLFOS)), - (Regions.SFM_WOLFOS_GROTTO, lambda bundle: can_open_bomb_grotto(bundle)), + (Regions.SFM_WOLFOS_GROTTO, lambda bundle: can_open_bomb_grotto(bundle), SOHGrottoEntranceNames.SFM_WOLFOS_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), ]) # Sacred Forest Meadow @@ -48,10 +48,10 @@ def set_region_rules(world: "SohWorld") -> None: # Connections connect_regions(Regions.SACRED_FOREST_MEADOW, world, [ (Regions.SFM_ENTRYWAY, lambda bundle: True), - (Regions.FOREST_TEMPLE_ENTRYWAY, - lambda bundle: can_use(Items.HOOKSHOT, bundle)), - (Regions.SFM_FAIRY_GROTTO, lambda bundle: True), - (Regions.SFM_STORMS_GROTTO, lambda bundle: can_open_storms_grotto(bundle)), + (Regions.FOREST_TEMPLE_ENTRYWAY, lambda bundle: can_use(Items.HOOKSHOT, bundle), + SOHDungeonEntranceNames.FOREST_TEMPLE_DUNGEON_ENTRANCE, SOHEntranceGroups.DUNGEON_ENTRANCE | SOHEntranceGroups.ADULT_ONLY, EntranceType.TWO_WAY), + (Regions.SFM_FAIRY_GROTTO, lambda bundle: True, SOHGrottoEntranceNames.SFM_FAIRY_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), + (Regions.SFM_STORMS_GROTTO, lambda bundle: can_open_storms_grotto(bundle), SOHGrottoEntranceNames.SFM_STORMS_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), ]) # SFM Fairy Grotto @@ -73,7 +73,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.SFM_FAIRY_GROTTO, world, [ - (Regions.SACRED_FOREST_MEADOW, lambda bundle: True), + (Regions.SACRED_FOREST_MEADOW, lambda bundle: True, SOHGrottoExitNames.SFM_FAIRY_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), ]) # SFM Wolfos Grotto @@ -84,7 +84,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.SFM_WOLFOS_GROTTO, world, [ - (Regions.SACRED_FOREST_MEADOW, lambda bundle: True), + (Regions.SACRED_FOREST_MEADOW, lambda bundle: True, SOHGrottoExitNames.SFM_WOLFOS_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), ]) # SFM Storms Grotto @@ -99,5 +99,5 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.SFM_STORMS_GROTTO, world, [ - (Regions.SACRED_FOREST_MEADOW, lambda bundle: True), + (Regions.SACRED_FOREST_MEADOW, lambda bundle: True, SOHGrottoExitNames.SFM_STORMS_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), ]) diff --git a/worlds/oot_soh/location_access/overworld/temple_of_time.py b/worlds/oot_soh/location_access/overworld/temple_of_time.py index c3eee32e28da..c3cd300d959f 100644 --- a/worlds/oot_soh/location_access/overworld/temple_of_time.py +++ b/worlds/oot_soh/location_access/overworld/temple_of_time.py @@ -37,8 +37,8 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.TOT_ENTRANCE, world, [ - (Regions.MARKET, lambda bundle: True), - (Regions.TEMPLE_OF_TIME, lambda bundle: True) + (Regions.MARKET, lambda bundle: True, SOHOverworldEntranceNames.TEMPLE_OF_TIME_EXTERIOR_DAY_GOSSIP_STONE_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), + (Regions.TEMPLE_OF_TIME, lambda bundle: True, SOHSpecialInteriorEntranceNames.TEMPLE_OF_TIME_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE) ]) # Temple of Time @@ -49,7 +49,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.TEMPLE_OF_TIME, world, [ - (Regions.TOT_ENTRANCE, lambda bundle: True), + (Regions.TOT_ENTRANCE, lambda bundle: True, SOHSpecialInteriorExitNames.TEMPLE_OF_TIME_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.BOTH_AGE), (Regions.BEYOND_DOOR_OF_TIME, lambda bundle: world.options.door_of_time == "open" or (can_use(Items.SONG_OF_TIME, bundle) and diff --git a/worlds/oot_soh/location_access/overworld/thieves_hideout.py b/worlds/oot_soh/location_access/overworld/thieves_hideout.py index b4ce44e58ce7..1660b0c6a44e 100644 --- a/worlds/oot_soh/location_access/overworld/thieves_hideout.py +++ b/worlds/oot_soh/location_access/overworld/thieves_hideout.py @@ -39,8 +39,8 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.THIEVES_HIDEOUT_1_TORCH_CELL, world, [ - (Regions.GERUDO_FORTRESS_OUTSKIRTS, lambda bundle: True), - (Regions.GF_NEAR_GROTTO, lambda bundle: True), + (Regions.GERUDO_FORTRESS_OUTSKIRTS, lambda bundle: True, SOHThievesHideoutEntranceNames.GERUDOS_FORTRESS_1, int(SOHEntranceGroups.GERUDO_FORTRESS_ENTRANCE)), + (Regions.GF_NEAR_GROTTO, lambda bundle: True, SOHThievesHideoutEntranceNames.GERUDOS_FORTRESS_2, int(SOHEntranceGroups.GERUDO_FORTRESS_ENTRANCE)), (Regions.THIEVES_HIDEOUT_RESCUE_CARPENTERS, lambda bundle: True) ]) @@ -72,8 +72,9 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.THIEVES_HIDEOUT_DOUBLE_CELL, world, [ - (Regions.GERUDO_FORTRESS_OUTSKIRTS, lambda bundle: True), - (Regions.GF_NEAR_GROTTO, lambda bundle: True), + (Regions.GERUDO_FORTRESS_OUTSKIRTS, lambda bundle: True, SOHThievesHideoutEntranceNames.GERUDOS_FORTRESS_7, int(SOHEntranceGroups.GERUDO_FORTRESS_ENTRANCE)), + (Regions.GF_ABOVE_GTG, lambda bundle: True), + (Regions.GF_TOP_OF_LOWER_VINES, lambda bundle: True, SOHThievesHideoutEntranceNames.GERUDOS_FORTRESS_8, int(SOHEntranceGroups.GERUDO_FORTRESS_ENTRANCE)), (Regions.THIEVES_HIDEOUT_RESCUE_CARPENTERS, lambda bundle: True) ]) @@ -92,7 +93,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.THIEVES_HIDEOUT_DEAD_END_CELL, world, [ - (Regions.GF_BELOW_GS, lambda bundle: True), + (Regions.GF_BELOW_GS, lambda bundle: True, SOHThievesHideoutEntranceNames.GERUDOS_FORTRESS_13, int(SOHEntranceGroups.GERUDO_FORTRESS_ENTRANCE)), (Regions.THIEVES_HIDEOUT_RESCUE_CARPENTERS, lambda bundle: True) ]) @@ -112,8 +113,8 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.THIEVES_HIDEOUT_STEEP_SLOPE_CELL, world, [ - (Regions.GF_ABOVE_GTG, lambda bundle: True), - (Regions.GF_TOP_OF_LOWER_VINES, lambda bundle: True), + (Regions.GF_ABOVE_GTG, lambda bundle: True, SOHThievesHideoutEntranceNames.GERUDOS_FORTRESS_5, int(SOHEntranceGroups.GERUDO_FORTRESS_ENTRANCE)), + (Regions.GF_TOP_OF_LOWER_VINES, lambda bundle: True, SOHThievesHideoutEntranceNames.GERUDOS_FORTRESS_6, int(SOHEntranceGroups.GERUDO_FORTRESS_ENTRANCE)), (Regions.THIEVES_HIDEOUT_RESCUE_CARPENTERS, lambda bundle: True) ]) @@ -153,8 +154,8 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.THIEVES_HIDEOUT_KITCHEN_CORRIDOR, world, [ - (Regions.GF_NEAR_GROTTO, lambda bundle: True), - (Regions.GF_ABOVE_GTG, lambda bundle: True), + (Regions.GF_NEAR_GROTTO, lambda bundle: True, SOHThievesHideoutEntranceNames.GERUDOS_FORTRESS_3, int(SOHEntranceGroups.GERUDO_FORTRESS_ENTRANCE)), + (Regions.GF_ABOVE_GTG, lambda bundle: True, SOHThievesHideoutEntranceNames.GERUDOS_FORTRESS_4, int(SOHEntranceGroups.GERUDO_FORTRESS_ENTRANCE)), (Regions.THIEVES_HIDEOUT_KITCHEN_BOTTOM, lambda bundle: can_pass_enemy(bundle, Enemies.GERUDO_GUARD)) ]) @@ -184,9 +185,9 @@ def set_region_rules(world: "SohWorld") -> None: (Regions.THIEVES_HIDEOUT_KITCHEN_POTS, lambda bundle: can_use(Items.BOOMERANG, bundle)), (Regions.GF_NEAR_GS, - lambda bundle: can_pass_enemy(bundle, Enemies.GERUDO_GUARD) or can_use(Items.HOVER_BOOTS, bundle)), + lambda bundle: can_pass_enemy(bundle, Enemies.GERUDO_GUARD) or can_use(Items.HOVER_BOOTS, bundle), SOHThievesHideoutEntranceNames.GERUDOS_FORTRESS_10, int(SOHEntranceGroups.GERUDO_FORTRESS_ENTRANCE)), (Regions.GF_TOP_OF_LOWER_VINES, - lambda bundle: can_pass_enemy(bundle, Enemies.GERUDO_GUARD) or can_use(Items.HOVER_BOOTS, bundle)) + lambda bundle: can_pass_enemy(bundle, Enemies.GERUDO_GUARD) or can_use(Items.HOVER_BOOTS, bundle), SOHThievesHideoutEntranceNames.GERUDOS_FORTRESS_9, int(SOHEntranceGroups.GERUDO_FORTRESS_ENTRANCE)) ]) # Thieves Hideout Kitchen Pots @@ -227,7 +228,7 @@ def set_region_rules(world: "SohWorld") -> None: # Connections connect_regions(Regions.THIEVES_HIDEOUT_BREAK_ROOM, world, [ (Regions.GF_BELOW_CHEST, lambda bundle: can_pass_enemy( - bundle, Enemies.GERUDO_GUARD)), + bundle, Enemies.GERUDO_GUARD), SOHThievesHideoutEntranceNames.GERUDOS_FORTRESS_11, int(SOHEntranceGroups.GERUDO_FORTRESS_ENTRANCE)), (Regions.THIEVES_HIDEOUT_BREAK_ROOM_CORRIDOR, lambda bundle: can_use(Items.HOOKSHOT, bundle)) ]) @@ -237,5 +238,5 @@ def set_region_rules(world: "SohWorld") -> None: connect_regions(Regions.THIEVES_HIDEOUT_BREAK_ROOM_CORRIDOR, world, [ (Regions.THIEVES_HIDEOUT_BREAK_ROOM, lambda bundle: can_use(Items.HOOKSHOT, bundle)), - (Regions.GF_ABOVE_JAIL, lambda bundle: True) + (Regions.GF_ABOVE_JAIL, lambda bundle: True, SOHThievesHideoutEntranceNames.GERUDOS_FORTRESS_12, int(SOHEntranceGroups.GERUDO_FORTRESS_ENTRANCE)) ]) diff --git a/worlds/oot_soh/location_access/overworld/zoras_domain.py b/worlds/oot_soh/location_access/overworld/zoras_domain.py index 71b8f6675080..168895c7f779 100644 --- a/worlds/oot_soh/location_access/overworld/zoras_domain.py +++ b/worlds/oot_soh/location_access/overworld/zoras_domain.py @@ -82,14 +82,14 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.ZORAS_DOMAIN, world, [ - (Regions.ZR_BEHIND_WATERFALL, lambda bundle: True), + (Regions.ZR_BEHIND_WATERFALL, lambda bundle: True, SOHOverworldEntranceNames.ZORAS_DOMAIN_ENTRANCE, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), (Regions.LH_FROM_SHORTCUT, lambda bundle: is_child(bundle) and ( - has_item(Items.SILVER_SCALE, bundle) or can_use(Items.IRON_BOOTS, bundle))), + has_item(Items.SILVER_SCALE, bundle) or can_use(Items.IRON_BOOTS, bundle)), SOHOverworldEntranceNames.ZORAS_DOMAIN_UNDERWATER_SHORTCUT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.CHILD_ONLY), (Regions.ZD_BEHIND_KING_ZORA, lambda bundle: has_item(Events.DELIVER_LETTER, bundle) or world.options.zoras_fountain.value == 2 or ( world.options.zoras_fountain.value == 1 and is_adult(bundle)) or ( can_do_trick(Tricks.ZD_KING_ZORA_SKIP, bundle) and is_adult(bundle))), - (Regions.ZD_SHOP, lambda bundle: is_child(bundle) or blue_fire(bundle)), + (Regions.ZD_SHOP, lambda bundle: is_child(bundle) or blue_fire(bundle), SOHInteriorEntranceNames.ZD_SHOP_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE), (Regions.ZORAS_DOMAIN_ISLAND, lambda bundle: True), ]) @@ -98,7 +98,7 @@ def set_region_rules(world: "SohWorld") -> None: connect_regions(Regions.ZORAS_DOMAIN_ISLAND, world, [ (Regions.ZORAS_DOMAIN, lambda bundle: is_adult( bundle) or has_item(Items.BRONZE_SCALE, bundle)), - (Regions.ZD_STORMS_GROTTO, lambda bundle: can_open_storms_grotto(bundle)), + (Regions.ZD_STORMS_GROTTO, lambda bundle: can_open_storms_grotto(bundle), SOHGrottoEntranceNames.ZD_STORMS_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), ]) # ZD Behind King Zora @@ -117,7 +117,7 @@ def set_region_rules(world: "SohWorld") -> None: (Regions.ZORAS_DOMAIN, lambda bundle: has_item(Events.DELIVER_LETTER, bundle) or world.options.zoras_fountain.value == 2 or ( world.options.zoras_fountain.value == 1 and is_adult(bundle))), - (Regions.ZORAS_FOUNTAIN, lambda bundle: True), + (Regions.ZORAS_FOUNTAIN, lambda bundle: True, SOHOverworldEntranceNames.ZORAS_DOMAIN_KING_ZORA_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), ]) # ZD Shop @@ -134,7 +134,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.ZD_SHOP, world, [ - (Regions.ZORAS_DOMAIN, lambda bundle: True), + (Regions.ZORAS_DOMAIN, lambda bundle: True, SOHInteriorExitNames.ZD_SHOP_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE), ]) # ZD Storms Grotto @@ -156,5 +156,5 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.ZD_STORMS_GROTTO, world, [ - (Regions.ZORAS_DOMAIN_ISLAND, lambda bundle: True), + (Regions.ZORAS_DOMAIN_ISLAND, lambda bundle: True, SOHGrottoExitNames.ZD_STORMS_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), ]) diff --git a/worlds/oot_soh/location_access/overworld/zoras_fountain.py b/worlds/oot_soh/location_access/overworld/zoras_fountain.py index 37834e7e44b4..b86492210e0c 100644 --- a/worlds/oot_soh/location_access/overworld/zoras_fountain.py +++ b/worlds/oot_soh/location_access/overworld/zoras_fountain.py @@ -45,17 +45,17 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.ZORAS_FOUNTAIN, world, [ - (Regions.ZD_BEHIND_KING_ZORA, lambda bundle: True), + (Regions.ZD_BEHIND_KING_ZORA, lambda bundle: True, SOHOverworldEntranceNames.ZORAS_FOUNTAIN_TUNNEL_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE), (Regions.ZF_ICEBERGS, lambda bundle: is_adult(bundle)), (Regions.ZF_LAKEBED, lambda bundle: can_use(Items.IRON_BOOTS, bundle)), (Regions.ZF_HIDDEN_CAVE, lambda bundle: can_use( Items.SILVER_GAUNTLETS, bundle) and blast_or_smash(bundle)), (Regions.ZF_ROCK, lambda bundle: is_adult( bundle) and can_use(Items.SCARECROW, bundle)), - (Regions.JABU_JABUS_BELLY_ENTRYWAY, - lambda bundle: is_child(bundle) and (can_use(Items.BOTTLE_WITH_FISH, bundle) or world.options.jabu_jabu.value == 1)), + (Regions.JABU_JABUS_BELLY_ENTRYWAY, lambda bundle: is_child(bundle) and (can_use(Items.BOTTLE_WITH_FISH, bundle) + or world.options.jabu_jabu.value == 1), SOHDungeonEntranceNames.JABU_JABUS_DUNGEON_ENTRANCE, SOHEntranceGroups.DUNGEON_ENTRANCE | SOHEntranceGroups.CHILD_ONLY, EntranceType.TWO_WAY), (Regions.ZF_GREAT_FAIRY_FOUNTAIN, lambda bundle: has_explosives(bundle) or (can_do_trick( - Tricks.ZF_GREAT_FAIRY_WITHOUT_EXPLOSIVES, bundle) and can_use(Items.MEGATON_HAMMER, bundle) and can_use(Items.SILVER_GAUNTLETS, bundle))) + Tricks.ZF_GREAT_FAIRY_WITHOUT_EXPLOSIVES, bundle) and can_use(Items.MEGATON_HAMMER, bundle) and can_use(Items.SILVER_GAUNTLETS, bundle)), SOHInteriorEntranceNames.ZF_GREAT_FAIRY_FOUNTAIN_ENTRANCE, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE) ]) # Zora's Fountains Icebergs @@ -124,7 +124,8 @@ def set_region_rules(world: "SohWorld") -> None: (Regions.ZORAS_FOUNTAIN, lambda bundle: has_item(Items.BRONZE_SCALE, bundle)), (Regions.ZF_ICEBERGS, lambda bundle: is_adult(bundle)), (Regions.ZF_LAKEBED, lambda bundle: can_use(Items.IRON_BOOTS, bundle)), - (Regions.ICE_CAVERN_ENTRYWAY, lambda bundle: True) + (Regions.ICE_CAVERN_ENTRYWAY, lambda bundle: True, SOHDungeonEntranceNames.ICE_CAVERN_DUNGEON_ENTRANCE, + SOHEntranceGroups.DUNGEON_ENTRANCE | SOHEntranceGroups.ADULT_ONLY, EntranceType.TWO_WAY) ]) # Zora's Fountain Hidden Cave @@ -169,5 +170,5 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.ZF_GREAT_FAIRY_FOUNTAIN, world, [ - (Regions.ZORAS_FOUNTAIN, lambda bundle: True) + (Regions.ZORAS_FOUNTAIN, lambda bundle: True, SOHInteriorExitNames.ZF_GREAT_FAIRY_FOUNTAIN_EXIT, SOHEntranceGroups.INTERIOR | SOHEntranceGroups.ANY_AGE) ]) diff --git a/worlds/oot_soh/location_access/overworld/zoras_river.py b/worlds/oot_soh/location_access/overworld/zoras_river.py index 57bf47c3435d..a750fb2e9075 100644 --- a/worlds/oot_soh/location_access/overworld/zoras_river.py +++ b/worlds/oot_soh/location_access/overworld/zoras_river.py @@ -53,7 +53,7 @@ def set_region_rules(world: "SohWorld") -> None: connect_regions(Regions.ZR_FRONT, world, [ (Regions.ZORA_RIVER, lambda bundle: is_adult( bundle) or blast_or_smash(bundle)), - (Regions.HYRULE_FIELD, lambda bundle: True) + (Regions.HYRULE_FIELD, lambda bundle: True, SOHOverworldEntranceNames.ZORAS_RIVER_WEST_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE) ]) # Zora River @@ -154,19 +154,19 @@ def set_region_rules(world: "SohWorld") -> None: # Connections connect_regions(Regions.ZORA_RIVER, world, [ (Regions.ZR_FRONT, lambda bundle: True), - (Regions.ZR_OPEN_GROTTO, lambda bundle: True), + (Regions.ZR_OPEN_GROTTO, lambda bundle: True, SOHGrottoEntranceNames.ZR_OPEN_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), # I am not sure that there's any scenario where blast or smash wouldn't apply to here, not sure why this needs here (which checks if the other age opened it, basically)? - (Regions.ZR_FAIRY_GROTTO, lambda bundle: blast_or_smash(bundle)), + (Regions.ZR_FAIRY_GROTTO, lambda bundle: blast_or_smash(bundle), SOHGrottoEntranceNames.ZR_FAIRY_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), (Regions.LOST_WOODS, lambda bundle: has_item( Items.SILVER_SCALE, bundle) or can_use(Items.IRON_BOOTS, bundle)), - (Regions.ZR_STORMS_GROTTO, lambda bundle: can_open_storms_grotto(bundle)), + (Regions.ZR_STORMS_GROTTO, lambda bundle: can_open_storms_grotto(bundle), SOHGrottoEntranceNames.ZR_STORMS_GROTTO_ENTRANCE, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE), (Regions.ZR_BEHIND_WATERFALL, lambda bundle: world.options.sleeping_waterfall.value == 1 or can_use(Items.ZELDAS_LULLABY, bundle) or (is_child(bundle) and can_do_trick(Tricks.ZR_CUCCO, bundle)) or (is_adult(bundle) and can_use(Items.HOVER_BOOTS, bundle) and - can_do_trick(Tricks.ZR_HOVERS, bundle))) + can_do_trick(Tricks.ZR_HOVERS, bundle)), SOHOverworldEntranceNames.ZORAS_RIVER_WATERFALL_EXIT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE) ]) # Events @@ -178,7 +178,7 @@ def set_region_rules(world: "SohWorld") -> None: has_item(Items.BOTTLE_WITH_FAIRY, bundle) or has_item(Items.BRONZE_SCALE, bundle)), (Regions.LOST_WOODS, lambda bundle: has_item(Items.SILVER_SCALE, bundle) or - can_use(Items.IRON_BOOTS, bundle)) + can_use(Items.IRON_BOOTS, bundle), SOHOverworldEntranceNames.ZORAS_RIVER_UNDERWATER_SHORTCUT, SOHEntranceGroups.OVERWORLD | SOHEntranceGroups.BOTH_AGE) ]) @@ -220,7 +220,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.ZR_OPEN_GROTTO, world, [ - (Regions.ZORA_RIVER, lambda bundle: True) + (Regions.ZORA_RIVER, lambda bundle: True, SOHGrottoExitNames.ZR_OPEN_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.CHILD) ]) # ZR Fairy Grotto @@ -237,7 +237,7 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.ZR_FAIRY_GROTTO, world, [ - (Regions.ZORA_RIVER, lambda bundle: True) + (Regions.ZORA_RIVER, lambda bundle: True, SOHGrottoExitNames.ZR_FAIRY_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE) ]) # ZR Storms Grotto @@ -253,5 +253,5 @@ def set_region_rules(world: "SohWorld") -> None: ]) # Connections connect_regions(Regions.ZR_STORMS_GROTTO, world, [ - (Regions.ZORA_RIVER, lambda bundle: True) + (Regions.ZORA_RIVER, lambda bundle: True, SOHGrottoExitNames.ZR_STORMS_GROTTO_EXIT, SOHEntranceGroups.GROTTO | SOHEntranceGroups.ANY_AGE) ]) diff --git a/worlds/oot_soh/location_access/root.py b/worlds/oot_soh/location_access/root.py index 67ef8069b80a..005f10e85af8 100644 --- a/worlds/oot_soh/location_access/root.py +++ b/worlds/oot_soh/location_access/root.py @@ -65,53 +65,53 @@ def set_region_rules(world: "SohWorld") -> None: # Child Spawn # Connections connect_regions(Regions.CHILD_SPAWN, world, [ - (Regions.KF_LINKS_HOUSE, lambda bundle: True) + (Regions.KF_LINKS_HOUSE, lambda bundle: True, Regions.CHILD_SPAWN) ]) # Adult Spawn # Connections connect_regions(Regions.ADULT_SPAWN, world, [ - (Regions.TEMPLE_OF_TIME, lambda bundle: True) + (Regions.TEMPLE_OF_TIME, lambda bundle: True, Regions.ADULT_SPAWN) ]) # Minuet of Forest Warp # Connections connect_regions(Regions.MINUET_OF_FOREST_WARP, world, [ (Regions.SACRED_FOREST_MEADOW, lambda bundle: can_use( - Items.MINUET_OF_FOREST, bundle)) + Items.MINUET_OF_FOREST, bundle), Regions.MINUET_OF_FOREST_WARP) ]) # Bolero of Fire Warp # Connections connect_regions(Regions.BOLERO_OF_FIRE_WARP, world, [ (Regions.DMC_CENTRAL_LOCAL, lambda bundle: can_use( - Items.BOLERO_OF_FIRE, bundle)) + Items.BOLERO_OF_FIRE, bundle), Regions.BOLERO_OF_FIRE_WARP) ]) # Serenade of Water Warp # Connections connect_regions(Regions.SERENADE_OF_WATER_WARP, world, [ (Regions.LAKE_HYLIA, lambda bundle: can_use( - Items.SERENADE_OF_WATER, bundle)) + Items.SERENADE_OF_WATER, bundle), Regions.SERENADE_OF_WATER_WARP) ]) # Requiem of Spirit Warp # Connections connect_regions(Regions.REQUIEM_OF_SPIRIT_WARP, world, [ (Regions.DESERT_COLOSSUS, lambda bundle: can_use( - Items.REQUIEM_OF_SPIRIT, bundle)) + Items.REQUIEM_OF_SPIRIT, bundle), Regions.REQUIEM_OF_SPIRIT_WARP) ]) # Nocturne of Shadow Warp # Connections connect_regions(Regions.NOCTURNE_OF_SHADOW_WARP, world, [ (Regions.GRAVEYARD_WARP_PAD_REGION, lambda bundle: can_use( - Items.NOCTURNE_OF_SHADOW, bundle)) + Items.NOCTURNE_OF_SHADOW, bundle), Regions.NOCTURNE_OF_SHADOW_WARP) ]) # Prelude of Light Warp # Connections connect_regions(Regions.PRELUDE_OF_LIGHT_WARP, world, [ (Regions.TEMPLE_OF_TIME, lambda bundle: can_use( - Items.PRELUDE_OF_LIGHT, bundle)) + Items.PRELUDE_OF_LIGHT, bundle), Regions.PRELUDE_OF_LIGHT_WARP) ])