about summary refs log tree commit diff stats
path: root/apworld/locations.py
blob: fc7ef26de60b2fb7e30ff91b9272114473e6ba8f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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):
    game: str = "Lingo 2"

    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