diff --git a/BaseClasses.py b/BaseClasses.py index 4074108b..ec3fa9ce 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -1022,9 +1022,6 @@ class Entrance: connected_region: Optional[Region] = None randomization_group: int randomization_type: EntranceType - # LttP specific, TODO: should make a LttPEntrance - addresses = None - target = None def __init__(self, player: int, name: str = "", parent: Optional[Region] = None, randomization_group: int = 0, randomization_type: EntranceType = EntranceType.ONE_WAY) -> None: @@ -1043,10 +1040,8 @@ class Entrance: return False - def connect(self, region: Region, addresses: Any = None, target: Any = None) -> None: + def connect(self, region: Region) -> None: self.connected_region = region - self.target = target - self.addresses = addresses region.entrances.append(self) def is_valid_source_transition(self, er_state: "ERPlacementState") -> bool: diff --git a/worlds/alttp/OverworldGlitchRules.py b/worlds/alttp/OverworldGlitchRules.py index 2da76234..1a1c0152 100644 --- a/worlds/alttp/OverworldGlitchRules.py +++ b/worlds/alttp/OverworldGlitchRules.py @@ -2,8 +2,6 @@ Helper functions to deliver entrance/exit/region sets to OWG rules. """ -from BaseClasses import Entrance - from .StateHelpers import can_lift_heavy_rocks, can_boots_clip_lw, can_boots_clip_dw, can_get_glitched_speed_dw @@ -279,18 +277,14 @@ def create_no_logic_connections(player, world, connections): for entrance, parent_region, target_region, *rule_override in connections: parent = world.get_region(parent_region, player) target = world.get_region(target_region, player) - connection = Entrance(player, entrance, parent) - parent.exits.append(connection) - connection.connect(target) + parent.connect(target, entrance) def create_owg_connections(player, world, connections): for entrance, parent_region, target_region, *rule_override in connections: parent = world.get_region(parent_region, player) target = world.get_region(target_region, player) - connection = Entrance(player, entrance, parent) - parent.exits.append(connection) - connection.connect(target) + parent.connect(target, entrance) def set_owg_connection_rules(player, world, connections, default_rule): diff --git a/worlds/alttp/Regions.py b/worlds/alttp/Regions.py index f3dbbdc0..c2af7956 100644 --- a/worlds/alttp/Regions.py +++ b/worlds/alttp/Regions.py @@ -1,11 +1,11 @@ import collections import typing -from BaseClasses import Entrance, MultiWorld -from .SubClasses import LTTPRegion, LTTPRegionType +from BaseClasses import MultiWorld +from .SubClasses import LTTPEntrance, LTTPRegion, LTTPRegionType -def is_main_entrance(entrance: Entrance) -> bool: +def is_main_entrance(entrance: LTTPEntrance) -> bool: return entrance.parent_region.type in {LTTPRegionType.DarkWorld, LTTPRegionType.LightWorld} if entrance.parent_region.type else True @@ -410,7 +410,7 @@ def _create_region(world: MultiWorld, player: int, name: str, type: LTTPRegionTy ret = LTTPRegion(name, type, hint, player, world) if exits: for exit in exits: - ret.exits.append(Entrance(player, exit, ret)) + ret.create_exit(exit) if locations: for location in locations: if location in key_drop_data: diff --git a/worlds/alttp/Rules.py b/worlds/alttp/Rules.py index 47992947..3f508112 100644 --- a/worlds/alttp/Rules.py +++ b/worlds/alttp/Rules.py @@ -3,7 +3,7 @@ import logging from typing import Iterator, Set from Options import ItemsAccessibility -from BaseClasses import Entrance, MultiWorld +from BaseClasses import MultiWorld from worlds.generic.Rules import (add_item_rule, add_rule, forbid_item, item_name_in_location_names, location_item_name, set_rule, allow_self_locking_items) @@ -1071,9 +1071,8 @@ def swordless_rules(world, player): def add_connection(parent_name, target_name, entrance_name, world, player): parent = world.get_region(parent_name, player) target = world.get_region(target_name, player) - connection = Entrance(player, entrance_name, parent) - parent.exits.append(connection) - connection.connect(target) + parent.connect(target, entrance_name) + def standard_rules(world, player): @@ -1108,6 +1107,7 @@ def standard_rules(world, player): set_rule(world.get_location('Hyrule Castle - Zelda\'s Chest', player), lambda state: state.has('Big Key (Hyrule Castle)', player)) + def toss_junk_item(world, player): items = ['Rupees (20)', 'Bombs (3)', 'Arrows (10)', 'Rupees (5)', 'Rupee (1)', 'Bombs (10)', 'Single Arrow', 'Rupees (50)', 'Rupees (100)', 'Single Bomb', 'Bee', 'Bee Trap', diff --git a/worlds/alttp/SubClasses.py b/worlds/alttp/SubClasses.py index 328e28da..a3b1d778 100644 --- a/worlds/alttp/SubClasses.py +++ b/worlds/alttp/SubClasses.py @@ -2,11 +2,10 @@ from typing import Optional, TYPE_CHECKING from enum import IntEnum -from BaseClasses import Location, Item, ItemClassification, Region, MultiWorld +from BaseClasses import Entrance, Location, Item, ItemClassification, Region, MultiWorld if TYPE_CHECKING: from .Dungeons import Dungeon - from .Regions import LTTPRegion class ALttPLocation(Location): @@ -77,6 +76,19 @@ class ALttPItem(Item): return self.type +Addresses = int | list[int] | tuple[int, int, int, int, int, int, int, int, int, int, int, int, int] + + +class LTTPEntrance(Entrance): + addresses: Addresses | None = None + target: int | None = None + + def connect(self, region: Region, addresses: Addresses | None = None, target: int | None = None) -> None: + super().connect(region) + self.addresses = addresses + self.target = target + + class LTTPRegionType(IntEnum): LightWorld = 1 DarkWorld = 2 @@ -90,6 +102,7 @@ class LTTPRegionType(IntEnum): class LTTPRegion(Region): + entrance_type = LTTPEntrance type: LTTPRegionType # will be set after making connections. diff --git a/worlds/alttp/UnderworldGlitchRules.py b/worlds/alttp/UnderworldGlitchRules.py index 50397dea..2b18f67e 100644 --- a/worlds/alttp/UnderworldGlitchRules.py +++ b/worlds/alttp/UnderworldGlitchRules.py @@ -1,6 +1,6 @@ -from BaseClasses import Entrance from worlds.generic.Rules import set_rule, add_rule from .StateHelpers import can_bomb_clip, has_sword, has_beam_sword, has_fire_source, can_melt_things, has_misery_mire_medallion +from .SubClasses import LTTPEntrance # We actually need the logic to properly "mark" these regions as Light or Dark world. @@ -9,17 +9,15 @@ def underworld_glitch_connections(world, player): specrock = world.get_region('Spectacle Rock Cave (Bottom)', player) mire = world.get_region('Misery Mire (West)', player) - kikiskip = Entrance(player, 'Kiki Skip', specrock) - mire_to_hera = Entrance(player, 'Mire to Hera Clip', mire) - mire_to_swamp = Entrance(player, 'Hera to Swamp Clip', mire) - specrock.exits.append(kikiskip) - mire.exits.extend([mire_to_hera, mire_to_swamp]) + kikiskip = specrock.create_exit('Kiki Skip') + mire_to_hera = mire.create_exit('Mire to Hera Clip') + mire_to_swamp = mire.create_exit('Hera to Swamp Clip') if world.worlds[player].fix_fake_world: kikiskip.connect(world.get_entrance('Palace of Darkness Exit', player).connected_region) mire_to_hera.connect(world.get_entrance('Tower of Hera Exit', player).connected_region) mire_to_swamp.connect(world.get_entrance('Swamp Palace Exit', player).connected_region) - else: + else: kikiskip.connect(world.get_region('Palace of Darkness (Entrance)', player)) mire_to_hera.connect(world.get_region('Tower of Hera (Bottom)', player)) mire_to_swamp.connect(world.get_region('Swamp Palace (Entrance)', player)) @@ -37,7 +35,7 @@ def fake_pearl_state(state, player): # Sets the rules on where we can actually go using this clip. # Behavior differs based on what type of ER shuffle we're playing. -def dungeon_reentry_rules(world, player, clip: Entrance, dungeon_region: str, dungeon_exit: str): +def dungeon_reentry_rules(world, player, clip: LTTPEntrance, dungeon_region: str, dungeon_exit: str): fix_dungeon_exits = world.worlds[player].fix_palaceofdarkness_exit fix_fake_worlds = world.worlds[player].fix_fake_world diff --git a/worlds/pokemon_rb/regions.py b/worlds/pokemon_rb/regions.py index 84c9b257..5aa62435 100644 --- a/worlds/pokemon_rb/regions.py +++ b/worlds/pokemon_rb/regions.py @@ -2640,9 +2640,13 @@ class PokemonRBWarp(Entrance): self.warp_id = warp_id self.address = address self.flags = flags + self.addresses = None + self.target = None def connect(self, entrance): - super().connect(entrance.parent_region, None, target=entrance.warp_id) + super().connect(entrance.parent_region) + self.addresses = None + self.target = entrance.warp_id def access_rule(self, state): if self.connected_region is None: