about summary refs log tree commit diff stats
path: root/apworld/player_logic.py
diff options
context:
space:
mode:
Diffstat (limited to 'apworld/player_logic.py')
-rw-r--r--apworld/player_logic.py55
1 files changed, 49 insertions, 6 deletions
diff --git a/apworld/player_logic.py b/apworld/player_logic.py index 5271ed1..0cf0473 100644 --- a/apworld/player_logic.py +++ b/apworld/player_logic.py
@@ -202,6 +202,8 @@ class LetterBehavior(IntEnum):
202class Lingo2PlayerLogic: 202class Lingo2PlayerLogic:
203 world: "Lingo2World" 203 world: "Lingo2World"
204 204
205 shuffled_maps: set[int]
206
205 locations_by_room: dict[int, list[PlayerLocation]] 207 locations_by_room: dict[int, list[PlayerLocation]]
206 event_loc_item_by_room: dict[int, dict[str, str]] 208 event_loc_item_by_room: dict[int, dict[str, str]]
207 209
@@ -227,9 +229,24 @@ class Lingo2PlayerLogic:
227 self.real_items = list() 229 self.real_items = list()
228 self.double_letter_amount = dict() 230 self.double_letter_amount = dict()
229 231
232 def should_shuffle_map(game_map) -> bool:
233 if game_map.type == data_pb2.MapType.NORMAL_MAP:
234 return True
235 elif game_map.type == data_pb2.MapType.ICARUS:
236 return bool(world.options.enable_icarus)
237
238 return False
239
240 self.shuffled_maps = set(game_map.id for game_map in world.static_logic.objects.maps
241 if should_shuffle_map(game_map))
242
230 if self.world.options.shuffle_doors: 243 if self.world.options.shuffle_doors:
231 for progressive in world.static_logic.objects.progressives: 244 for progressive in world.static_logic.objects.progressives:
232 for i in range(0, len(progressive.doors)): 245 for i in range(0, len(progressive.doors)):
246 door = world.static_logic.objects.doors[progressive.doors[i]]
247 if door.map_id not in self.shuffled_maps:
248 continue
249
233 self.item_by_door[progressive.doors[i]] = (progressive.name, i + 1) 250 self.item_by_door[progressive.doors[i]] = (progressive.name, i + 1)
234 self.real_items.append(progressive.name) 251 self.real_items.append(progressive.name)
235 252
@@ -246,14 +263,21 @@ class Lingo2PlayerLogic:
246 else: 263 else:
247 continue 264 continue
248 265
249 for door in door_group.doors: 266 shuffleable_doors = [door_id for door_id in door_group.doors
250 self.item_by_door[door] = (door_group.name, 1) 267 if world.static_logic.objects.doors[door_id].map_id in self.shuffled_maps]
251 268
252 self.real_items.append(door_group.name) 269 if len(shuffleable_doors) > 0:
270 for door in shuffleable_doors:
271 self.item_by_door[door] = (door_group.name, 1)
272
273 self.real_items.append(door_group.name)
253 274
254 # We iterate through the doors in two parts because it is essential that we determine which doors are shuffled 275 # We iterate through the doors in two parts because it is essential that we determine which doors are shuffled
255 # before we calculate any access requirements. 276 # before we calculate any access requirements.
256 for door in world.static_logic.objects.doors: 277 for door in world.static_logic.objects.doors:
278 if door.map_id not in self.shuffled_maps:
279 continue
280
257 if door.type in [data_pb2.DoorType.EVENT, data_pb2.DoorType.LOCATION_ONLY, data_pb2.DoorType.GRAVESTONE]: 281 if door.type in [data_pb2.DoorType.EVENT, data_pb2.DoorType.LOCATION_ONLY, data_pb2.DoorType.GRAVESTONE]:
258 continue 282 continue
259 283
@@ -282,18 +306,28 @@ class Lingo2PlayerLogic:
282 if door_group.type != data_pb2.DoorGroupType.CYAN_DOORS: 306 if door_group.type != data_pb2.DoorGroupType.CYAN_DOORS:
283 continue 307 continue
284 308
285 for door in door_group.doors: 309 shuffleable_doors = [door_id for door_id in door_group.doors
286 if not door in self.item_by_door: 310 if world.static_logic.objects.doors[door_id].map_id in self.shuffled_maps
311 and door_id not in self.item_by_door]
312
313 if len(shuffleable_doors) > 0:
314 for door in shuffleable_doors:
287 self.item_by_door[door] = (door_group.name, 1) 315 self.item_by_door[door] = (door_group.name, 1)
288 316
289 self.real_items.append(door_group.name) 317 self.real_items.append(door_group.name)
290 318
291 for door in world.static_logic.objects.doors: 319 for door in world.static_logic.objects.doors:
320 if door.map_id not in self.shuffled_maps:
321 continue
322
292 if door.type in [data_pb2.DoorType.STANDARD, data_pb2.DoorType.LOCATION_ONLY, data_pb2.DoorType.GRAVESTONE]: 323 if door.type in [data_pb2.DoorType.STANDARD, data_pb2.DoorType.LOCATION_ONLY, data_pb2.DoorType.GRAVESTONE]:
293 self.locations_by_room.setdefault(door.room_id, []).append(PlayerLocation(door.ap_id, 324 self.locations_by_room.setdefault(door.room_id, []).append(PlayerLocation(door.ap_id,
294 self.get_door_reqs(door.id))) 325 self.get_door_reqs(door.id)))
295 326
296 for letter in world.static_logic.objects.letters: 327 for letter in world.static_logic.objects.letters:
328 if world.static_logic.get_room_object_map_id(letter) not in self.shuffled_maps:
329 continue
330
297 self.locations_by_room.setdefault(letter.room_id, []).append(PlayerLocation(letter.ap_id, 331 self.locations_by_room.setdefault(letter.room_id, []).append(PlayerLocation(letter.ap_id,
298 AccessRequirements())) 332 AccessRequirements()))
299 behavior = self.get_letter_behavior(letter.key, letter.level2) 333 behavior = self.get_letter_behavior(letter.key, letter.level2)
@@ -313,10 +347,16 @@ class Lingo2PlayerLogic:
313 self.double_letter_amount[letter.key.upper()] = self.double_letter_amount.get(letter.key.upper(), 0) + 1 347 self.double_letter_amount[letter.key.upper()] = self.double_letter_amount.get(letter.key.upper(), 0) + 1
314 348
315 for mastery in world.static_logic.objects.masteries: 349 for mastery in world.static_logic.objects.masteries:
350 if world.static_logic.get_room_object_map_id(mastery) not in self.shuffled_maps:
351 continue
352
316 self.locations_by_room.setdefault(mastery.room_id, []).append(PlayerLocation(mastery.ap_id, 353 self.locations_by_room.setdefault(mastery.room_id, []).append(PlayerLocation(mastery.ap_id,
317 AccessRequirements())) 354 AccessRequirements()))
318 355
319 for ending in world.static_logic.objects.endings: 356 for ending in world.static_logic.objects.endings:
357 if world.static_logic.get_room_object_map_id(ending) not in self.shuffled_maps:
358 continue
359
320 # Don't create a location for your selected ending, and never create a location for White Ending. 360 # Don't create a location for your selected ending, and never create a location for White Ending.
321 if world.options.victory_condition.current_key.removesuffix("_ending").upper() != ending.name\ 361 if world.options.victory_condition.current_key.removesuffix("_ending").upper() != ending.name\
322 and ending.name != "WHITE": 362 and ending.name != "WHITE":
@@ -335,6 +375,9 @@ class Lingo2PlayerLogic:
335 if self.world.options.keyholder_sanity: 375 if self.world.options.keyholder_sanity:
336 for keyholder in world.static_logic.objects.keyholders: 376 for keyholder in world.static_logic.objects.keyholders:
337 if keyholder.HasField("key"): 377 if keyholder.HasField("key"):
378 if world.static_logic.get_room_object_map_id(keyholder) not in self.shuffled_maps:
379 continue
380
338 reqs = AccessRequirements() 381 reqs = AccessRequirements()
339 382
340 if self.get_letter_behavior(keyholder.key, False) != LetterBehavior.UNLOCKED: 383 if self.get_letter_behavior(keyholder.key, False) != LetterBehavior.UNLOCKED: