diff options
Diffstat (limited to 'apworld/player_logic.py')
-rw-r--r-- | apworld/player_logic.py | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/apworld/player_logic.py b/apworld/player_logic.py index c6465f6..e08f644 100644 --- a/apworld/player_logic.py +++ b/apworld/player_logic.py | |||
@@ -23,6 +23,7 @@ def calculate_letter_histogram(solution: str) -> dict[str, int]: | |||
23 | 23 | ||
24 | class AccessRequirements: | 24 | class AccessRequirements: |
25 | items: set[str] | 25 | items: set[str] |
26 | progressives: dict[str, int] | ||
26 | rooms: set[str] | 27 | rooms: set[str] |
27 | symbols: set[str] | 28 | symbols: set[str] |
28 | letters: dict[str, int] | 29 | letters: dict[str, int] |
@@ -32,6 +33,7 @@ class AccessRequirements: | |||
32 | 33 | ||
33 | def __init__(self): | 34 | def __init__(self): |
34 | self.items = set() | 35 | self.items = set() |
36 | self.progressives = dict() | ||
35 | self.rooms = set() | 37 | self.rooms = set() |
36 | self.symbols = set() | 38 | self.symbols = set() |
37 | self.letters = dict() | 39 | self.letters = dict() |
@@ -47,6 +49,9 @@ class AccessRequirements: | |||
47 | for item in other.items: | 49 | for item in other.items: |
48 | self.items.add(item) | 50 | self.items.add(item) |
49 | 51 | ||
52 | for item, amount in other.progressives.items(): | ||
53 | self.progressives[item] = max(amount, self.progressives.get(item, 0)) | ||
54 | |||
50 | for room in other.rooms: | 55 | for room in other.rooms: |
51 | self.rooms.add(room) | 56 | self.rooms.add(room) |
52 | 57 | ||
@@ -63,6 +68,8 @@ class AccessRequirements: | |||
63 | parts = [] | 68 | parts = [] |
64 | if len(self.items) > 0: | 69 | if len(self.items) > 0: |
65 | parts.append(f"items={self.items}") | 70 | parts.append(f"items={self.items}") |
71 | if len(self.progressives) > 0: | ||
72 | parts.append(f"progressives={self.progressives}") | ||
66 | if len(self.rooms) > 0: | 73 | if len(self.rooms) > 0: |
67 | parts.append(f"rooms={self.rooms}") | 74 | parts.append(f"rooms={self.rooms}") |
68 | if len(self.symbols) > 0: | 75 | if len(self.symbols) > 0: |
@@ -85,7 +92,7 @@ class Lingo2PlayerLogic: | |||
85 | locations_by_room: dict[int, list[PlayerLocation]] | 92 | locations_by_room: dict[int, list[PlayerLocation]] |
86 | event_loc_item_by_room: dict[int, dict[str, str]] | 93 | event_loc_item_by_room: dict[int, dict[str, str]] |
87 | 94 | ||
88 | item_by_door: dict[int, str] | 95 | item_by_door: dict[int, tuple[str, int]] |
89 | 96 | ||
90 | panel_reqs: dict[int, AccessRequirements] | 97 | panel_reqs: dict[int, AccessRequirements] |
91 | proxy_reqs: dict[int, dict[str, AccessRequirements]] | 98 | proxy_reqs: dict[int, dict[str, AccessRequirements]] |
@@ -103,12 +110,21 @@ class Lingo2PlayerLogic: | |||
103 | self.door_reqs = dict() | 110 | self.door_reqs = dict() |
104 | self.real_items = list() | 111 | self.real_items = list() |
105 | 112 | ||
113 | if self.world.options.shuffle_doors: | ||
114 | for progressive in world.static_logic.objects.progressives: | ||
115 | for i in range(0, len(progressive.doors)): | ||
116 | self.item_by_door[progressive.doors[i]] = (progressive.name, i + 1) | ||
117 | self.real_items.append(progressive.name) | ||
118 | |||
106 | # We iterate through the doors in two parts because it is essential that we determine which doors are shuffled | 119 | # We iterate through the doors in two parts because it is essential that we determine which doors are shuffled |
107 | # before we calculate any access requirements. | 120 | # before we calculate any access requirements. |
108 | for door in world.static_logic.objects.doors: | 121 | for door in world.static_logic.objects.doors: |
109 | if door.type in [data_pb2.DoorType.STANDARD, data_pb2.DoorType.ITEM_ONLY] and self.world.options.shuffle_doors: | 122 | if door.type in [data_pb2.DoorType.STANDARD, data_pb2.DoorType.ITEM_ONLY] and self.world.options.shuffle_doors: |
123 | if door.id in self.item_by_door: | ||
124 | continue | ||
125 | |||
110 | door_item_name = self.world.static_logic.get_door_item_name(door) | 126 | door_item_name = self.world.static_logic.get_door_item_name(door) |
111 | self.item_by_door[door.id] = door_item_name | 127 | self.item_by_door[door.id] = (door_item_name, 1) |
112 | self.real_items.append(door_item_name) | 128 | self.real_items.append(door_item_name) |
113 | 129 | ||
114 | for door in world.static_logic.objects.doors: | 130 | for door in world.static_logic.objects.doors: |
@@ -261,7 +277,12 @@ class Lingo2PlayerLogic: | |||
261 | def get_door_open_reqs(self, door_id: int) -> AccessRequirements: | 277 | def get_door_open_reqs(self, door_id: int) -> AccessRequirements: |
262 | if door_id in self.item_by_door: | 278 | if door_id in self.item_by_door: |
263 | reqs = AccessRequirements() | 279 | reqs = AccessRequirements() |
264 | reqs.items.add(self.item_by_door.get(door_id)) | 280 | |
281 | item_name, amount = self.item_by_door.get(door_id) | ||
282 | if amount == 1: | ||
283 | reqs.items.add(item_name) | ||
284 | else: | ||
285 | reqs.progressives[item_name] = amount | ||
265 | 286 | ||
266 | return reqs | 287 | return reqs |
267 | else: | 288 | else: |