From 060a04700d8a1edf974a7da084b11eb0152e5814 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Fri, 30 Sep 2022 04:58:19 +0200 Subject: [PATCH] Core: allow generic access to indirect_connections (#1056) --- BaseClasses.py | 14 ++++++++++---- test/minor_glitches/TestMinor.py | 6 ++---- test/owg/TestVanillaOWG.py | 6 ++---- test/vanilla/TestVanilla.py | 6 ++---- worlds/alttp/__init__.py | 8 ++++++-- 5 files changed, 22 insertions(+), 18 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 634c2a83..c5e7640b 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -51,8 +51,10 @@ class MultiWorld(): non_local_items: Dict[int, Options.NonLocalItems] progression_balancing: Dict[int, Options.ProgressionBalancing] completion_condition: Dict[int, Callable[[CollectionState], bool]] + indirect_connections: Dict[Region, Set[Entrance]] exclude_locations: Dict[int, Options.ExcludeLocations] + class AttributeProxy(): def __init__(self, rule): self.rule = rule @@ -89,6 +91,7 @@ class MultiWorld(): self.customitemarray = [] self.shuffle_ganon = True self.spoiler = Spoiler(self) + self.indirect_connections = {} self.fix_trock_doors = self.AttributeProxy( lambda player: self.shuffle[player] != 'vanilla' or self.mode[player] == 'inverted') self.fix_skullwoods_exit = self.AttributeProxy( @@ -406,6 +409,11 @@ class MultiWorld(): def clear_entrance_cache(self): self._cached_entrances = None + def register_indirect_condition(self, region: Region, entrance: Entrance): + """Report that access to this Region can result in unlocking this Entrance, + state.can_reach(Region) in the Entrance's traversal condition, as opposed to pure transition logic.""" + self.indirect_connections.setdefault(region, set()).add(entrance) + def get_locations(self) -> List[Location]: if self._cached_locations is None: self._cached_locations = [location for region in self.regions for location in region.locations] @@ -610,7 +618,6 @@ class CollectionState(): self.collect(item, True) def update_reachable_regions(self, player: int): - from worlds.alttp.EntranceShuffle import indirect_connections self.stale[player] = False rrp = self.reachable_regions[player] bc = self.blocked_connections[player] @@ -618,7 +625,7 @@ class CollectionState(): start = self.world.get_region('Menu', player) # init on first call - this can't be done on construction since the regions don't exist yet - if not start in rrp: + if start not in rrp: rrp.add(start) bc.update(start.exits) queue.extend(start.exits) @@ -638,8 +645,7 @@ class CollectionState(): self.path[new_region] = (new_region.name, self.path.get(connection, None)) # Retry connections if the new region can unblock them - if new_region.name in indirect_connections: - new_entrance = self.world.get_entrance(indirect_connections[new_region.name], player) + for new_entrance in self.world.indirect_connections.get(new_region, set()): if new_entrance in bc and new_entrance not in queue: queue.append(new_entrance) diff --git a/test/minor_glitches/TestMinor.py b/test/minor_glitches/TestMinor.py index 81c09cfb..41cb1316 100644 --- a/test/minor_glitches/TestMinor.py +++ b/test/minor_glitches/TestMinor.py @@ -23,10 +23,8 @@ class TestMinor(TestBase): self.world.set_default_common_options() self.world.logic[1] = "minorglitches" self.world.difficulty_requirements[1] = difficulties['normal'] - create_regions(self.world, 1) - create_dungeons(self.world, 1) - create_shops(self.world, 1) - link_entrances(self.world, 1) + self.world.worlds[1].er_seed = 0 + self.world.worlds[1].create_regions() self.world.worlds[1].create_items() self.world.required_medallions[1] = ['Ether', 'Quake'] self.world.itempool.extend(get_dungeon_item_pool(self.world)) diff --git a/test/owg/TestVanillaOWG.py b/test/owg/TestVanillaOWG.py index e5489117..a4367fb5 100644 --- a/test/owg/TestVanillaOWG.py +++ b/test/owg/TestVanillaOWG.py @@ -24,10 +24,8 @@ class TestVanillaOWG(TestBase): self.world.set_default_common_options() self.world.difficulty_requirements[1] = difficulties['normal'] self.world.logic[1] = "owglitches" - create_regions(self.world, 1) - create_dungeons(self.world, 1) - create_shops(self.world, 1) - link_entrances(self.world, 1) + self.world.worlds[1].er_seed = 0 + self.world.worlds[1].create_regions() self.world.worlds[1].create_items() self.world.required_medallions[1] = ['Ether', 'Quake'] self.world.itempool.extend(get_dungeon_item_pool(self.world)) diff --git a/test/vanilla/TestVanilla.py b/test/vanilla/TestVanilla.py index e5ee7340..c9fa3f76 100644 --- a/test/vanilla/TestVanilla.py +++ b/test/vanilla/TestVanilla.py @@ -22,10 +22,8 @@ class TestVanilla(TestBase): self.world.set_default_common_options() self.world.logic[1] = "noglitches" self.world.difficulty_requirements[1] = difficulties['normal'] - create_regions(self.world, 1) - create_dungeons(self.world, 1) - create_shops(self.world, 1) - link_entrances(self.world, 1) + self.world.worlds[1].er_seed = 0 + self.world.worlds[1].create_regions() self.world.worlds[1].create_items() self.world.required_medallions[1] = ['Ether', 'Quake'] self.world.itempool.extend(get_dungeon_item_pool(self.world)) diff --git a/worlds/alttp/__init__.py b/worlds/alttp/__init__.py index bbdd9411..88d2c2f2 100644 --- a/worlds/alttp/__init__.py +++ b/worlds/alttp/__init__.py @@ -7,7 +7,7 @@ import typing import Utils from BaseClasses import Item, CollectionState, Tutorial from .Dungeons import create_dungeons -from .EntranceShuffle import link_entrances, link_inverted_entrances, plando_connect +from .EntranceShuffle import link_entrances, link_inverted_entrances, plando_connect, indirect_connections from .InvertedRegions import create_inverted_regions, mark_dark_world_regions from .ItemPool import generate_itempool, difficulties from .Items import item_init_table, item_name_groups, item_table, GetBeemizerItem @@ -19,7 +19,7 @@ from .Rom import LocalRom, patch_rom, patch_race_rom, check_enemizer, patch_enem from .Rules import set_rules from .Shops import create_shops, ShopSlotFill from .SubClasses import ALttPItem -from ..AutoWorld import World, WebWorld, LogicMixin +from worlds.AutoWorld import World, WebWorld, LogicMixin lttp_logger = logging.getLogger("A Link to the Past") @@ -223,6 +223,10 @@ class ALTTPWorld(World): world.random = old_random plando_connect(world, player) + for region_name, entrance_name in indirect_connections.items(): + world.register_indirect_condition(self.world.get_region(region_name, player), + self.world.get_entrance(entrance_name, player)) + def collect_item(self, state: CollectionState, item: Item, remove=False): item_name = item.name if item_name.startswith('Progressive '):