diff options
Diffstat (limited to 'apworld/locations.py')
| -rw-r--r-- | apworld/locations.py | 78 |
1 files changed, 77 insertions, 1 deletions
| 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 @@ | |||
| 1 | from BaseClasses import Location | 1 | from typing import TYPE_CHECKING |
| 2 | |||
| 3 | from BaseClasses import Location, Region, CollectionState, Entrance | ||
| 4 | from .rules import AccessRequirements | ||
| 5 | |||
| 6 | if TYPE_CHECKING: | ||
| 7 | from . import Lingo2World | ||
| 8 | |||
| 9 | |||
| 10 | def get_required_regions(reqs: AccessRequirements, world: "Lingo2World", | ||
| 11 | regions: dict[str, Region] | None) -> list[Region]: | ||
| 12 | # Replace required rooms with regions for the top level requirement, which saves looking up the regions during rule | ||
| 13 | # checking. | ||
| 14 | if regions is not None: | ||
| 15 | return [regions[room_name] for room_name in reqs.rooms] | ||
| 16 | else: | ||
| 17 | return [world.multiworld.get_region(room_name, world.player) for room_name in reqs.rooms] | ||
| 2 | 18 | ||
| 3 | 19 | ||
| 4 | class Lingo2Location(Location): | 20 | class Lingo2Location(Location): |
| @@ -6,3 +22,63 @@ class Lingo2Location(Location): | |||
| 6 | 22 | ||
| 7 | port_id: int | 23 | port_id: int |
| 8 | goal: bool | 24 | goal: bool |
| 25 | reqs: AccessRequirements | None | ||
| 26 | world: "Lingo2World" | ||
| 27 | required_regions: list[Region] | ||
| 28 | |||
| 29 | @classmethod | ||
| 30 | def non_event_location(cls, world: "Lingo2World", code: int, region: Region): | ||
| 31 | result = cls(world.player, world.static_logic.location_id_to_name[code], code, region) | ||
| 32 | result.reqs = None | ||
| 33 | result.world = world | ||
| 34 | result.required_regions = [] | ||
| 35 | |||
| 36 | return result | ||
| 37 | |||
| 38 | @classmethod | ||
| 39 | def event_location(cls, world: "Lingo2World", name: str, region: Region): | ||
| 40 | result = cls(world.player, name, None, region) | ||
| 41 | result.reqs = None | ||
| 42 | result.world = world | ||
| 43 | result.required_regions = [] | ||
| 44 | |||
| 45 | return result | ||
| 46 | |||
| 47 | def set_access_rule(self, reqs: AccessRequirements, regions: dict[str, Region] | None): | ||
| 48 | self.reqs = reqs | ||
| 49 | self.required_regions = get_required_regions(reqs, self.world, regions) | ||
| 50 | |||
| 51 | def access_rule(self, state: CollectionState) -> bool: | ||
| 52 | if self.reqs is not None and not self.reqs.check_access(state, self.world): | ||
| 53 | return False | ||
| 54 | |||
| 55 | if not all(state.can_reach(region) for region in self.required_regions): | ||
| 56 | return False | ||
| 57 | |||
| 58 | return True | ||
| 59 | |||
| 60 | |||
| 61 | class Lingo2Entrance(Entrance): | ||
| 62 | reqs: AccessRequirements | None | ||
| 63 | world: "Lingo2World" | ||
| 64 | required_regions: list[Region] | ||
| 65 | |||
| 66 | def __init__(self, world: "Lingo2World", description: str, region: Region): | ||
| 67 | super().__init__(world.player, description, region) | ||
| 68 | |||
| 69 | self.reqs = None | ||
| 70 | self.world = world | ||
| 71 | self.required_regions = [] | ||
| 72 | |||
| 73 | def set_access_rule(self, reqs: AccessRequirements, regions: dict[str, Region] | None): | ||
| 74 | self.reqs = reqs | ||
| 75 | self.required_regions = get_required_regions(reqs, self.world, regions) | ||
| 76 | |||
| 77 | def access_rule(self, state: CollectionState) -> bool: | ||
| 78 | if self.reqs is not None and not self.reqs.check_access(state, self.world): | ||
| 79 | return False | ||
| 80 | |||
| 81 | if not all(state.can_reach(region) for region in self.required_regions): | ||
| 82 | return False | ||
| 83 | |||
| 84 | return True | ||
