From c5a564bfc9bcf422d04c9016f56d65260b007c67 Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Sat, 13 Dec 2025 07:10:05 -0500 Subject: Refactor AccessRequirements --- apworld/locations.py | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) (limited to 'apworld/locations.py') diff --git a/apworld/locations.py b/apworld/locations.py index 3d619dc..fc7ef26 100644 --- a/apworld/locations.py +++ b/apworld/locations.py @@ -1,4 +1,20 @@ -from BaseClasses import Location +from typing import TYPE_CHECKING + +from BaseClasses import Location, Region, CollectionState, Entrance +from .rules import AccessRequirements + +if TYPE_CHECKING: + from . import Lingo2World + + +def get_required_regions(reqs: AccessRequirements, world: "Lingo2World", + regions: dict[str, Region] | None) -> list[Region]: + # Replace required rooms with regions for the top level requirement, which saves looking up the regions during rule + # checking. + if regions is not None: + return [regions[room_name] for room_name in reqs.rooms] + else: + return [world.multiworld.get_region(room_name, world.player) for room_name in reqs.rooms] class Lingo2Location(Location): @@ -6,3 +22,63 @@ class Lingo2Location(Location): port_id: int goal: bool + reqs: AccessRequirements | None + world: "Lingo2World" + required_regions: list[Region] + + @classmethod + def non_event_location(cls, world: "Lingo2World", code: int, region: Region): + result = cls(world.player, world.static_logic.location_id_to_name[code], code, region) + result.reqs = None + result.world = world + result.required_regions = [] + + return result + + @classmethod + def event_location(cls, world: "Lingo2World", name: str, region: Region): + result = cls(world.player, name, None, region) + result.reqs = None + result.world = world + result.required_regions = [] + + return result + + def set_access_rule(self, reqs: AccessRequirements, regions: dict[str, Region] | None): + self.reqs = reqs + self.required_regions = get_required_regions(reqs, self.world, regions) + + def access_rule(self, state: CollectionState) -> bool: + if self.reqs is not None and not self.reqs.check_access(state, self.world): + return False + + if not all(state.can_reach(region) for region in self.required_regions): + return False + + return True + + +class Lingo2Entrance(Entrance): + reqs: AccessRequirements | None + world: "Lingo2World" + required_regions: list[Region] + + def __init__(self, world: "Lingo2World", description: str, region: Region): + super().__init__(world.player, description, region) + + self.reqs = None + self.world = world + self.required_regions = [] + + def set_access_rule(self, reqs: AccessRequirements, regions: dict[str, Region] | None): + self.reqs = reqs + self.required_regions = get_required_regions(reqs, self.world, regions) + + def access_rule(self, state: CollectionState) -> bool: + if self.reqs is not None and not self.reqs.check_access(state, self.world): + return False + + if not all(state.can_reach(region) for region in self.required_regions): + return False + + return True -- cgit 1.4.1