summary refs log tree commit diff stats
path: root/apworld
diff options
context:
space:
mode:
Diffstat (limited to 'apworld')
-rw-r--r--apworld/player_logic.py27
-rw-r--r--apworld/rules.py3
-rw-r--r--apworld/static_logic.py3
3 files changed, 30 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
24class AccessRequirements: 24class 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:
diff --git a/apworld/rules.py b/apworld/rules.py index 4a84acf..5e20de5 100644 --- a/apworld/rules.py +++ b/apworld/rules.py
@@ -12,6 +12,9 @@ def lingo2_can_satisfy_requirements(state: CollectionState, reqs: AccessRequirem
12 if not all(state.has(item, world.player) for item in reqs.items): 12 if not all(state.has(item, world.player) for item in reqs.items):
13 return False 13 return False
14 14
15 if not all(state.has(item, world.player, amount) for item, amount in reqs.progressives.items()):
16 return False
17
15 if not all(state.can_reach_region(region_name, world.player) for region_name in reqs.rooms): 18 if not all(state.can_reach_region(region_name, world.player) for region_name in reqs.rooms):
16 return False 19 return False
17 20
diff --git a/apworld/static_logic.py b/apworld/static_logic.py index ff1f17d..0613474 100644 --- a/apworld/static_logic.py +++ b/apworld/static_logic.py
@@ -41,6 +41,9 @@ class Lingo2StaticLogic:
41 location_name = f"{self.get_room_object_map_name(ending)} - {ending.name.title()} Ending" 41 location_name = f"{self.get_room_object_map_name(ending)} - {ending.name.title()} Ending"
42 self.location_id_to_name[ending.ap_id] = location_name 42 self.location_id_to_name[ending.ap_id] = location_name
43 43
44 for progressive in self.objects.progressives:
45 self.item_id_to_name[progressive.ap_id] = progressive.name
46
44 self.item_id_to_name[self.objects.special_ids["Nothing"]] = "Nothing" 47 self.item_id_to_name[self.objects.special_ids["Nothing"]] = "Nothing"
45 48
46 self.item_name_to_id = {name: ap_id for ap_id, name in self.item_id_to_name.items()} 49 self.item_name_to_id = {name: ap_id for ap_id, name in self.item_id_to_name.items()}