Core: allow generic access to indirect_connections (#1056)

This commit is contained in:
Fabian Dill 2022-09-30 04:58:19 +02:00 committed by GitHub
parent 61e39f355d
commit 060a04700d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 22 additions and 18 deletions

View File

@ -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)

View File

@ -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))

View File

@ -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))

View File

@ -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))

View File

@ -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 '):