summary refs log tree commit diff stats
path: root/player_logic.py
diff options
context:
space:
mode:
authorStar Rauchenberger <fefferburbia@gmail.com>2024-07-24 08:34:51 -0400
committerGitHub <noreply@github.com>2024-07-24 14:34:51 +0200
commit1c142350c379d503de512953072f55a8737c30d2 (patch)
tree40b469c4be80a2f273706a66683e9074217a6045 /player_logic.py
parentcccdf6481571cd883c9519cde0a717b6f336fbda (diff)
downloadlingo-apworld-1c142350c379d503de512953072f55a8737c30d2.tar.gz
lingo-apworld-1c142350c379d503de512953072f55a8737c30d2.tar.bz2
lingo-apworld-1c142350c379d503de512953072f55a8737c30d2.zip
Lingo: Add option to prevent shuffling postgame (#3350)
* Lingo: Add option to prevent shuffling postgame

* Allow roof access on door shuffle

* Fix broken unit test

* Simplified THE END edge case

* Revert unnecessary change

* Review comments

* Fix mastery unit test

* Update generated.dat

* Added player's name to error message
Diffstat (limited to 'player_logic.py')
-rw-r--r--player_logic.py34
1 files changed, 21 insertions, 13 deletions
diff --git a/player_logic.py b/player_logic.py index 1621620..35080ac 100644 --- a/player_logic.py +++ b/player_logic.py
@@ -19,22 +19,25 @@ class AccessRequirements:
19 doors: Set[RoomAndDoor] 19 doors: Set[RoomAndDoor]
20 colors: Set[str] 20 colors: Set[str]
21 the_master: bool 21 the_master: bool
22 postgame: bool
22 23
23 def __init__(self): 24 def __init__(self):
24 self.rooms = set() 25 self.rooms = set()
25 self.doors = set() 26 self.doors = set()
26 self.colors = set() 27 self.colors = set()
27 self.the_master = False 28 self.the_master = False
29 self.postgame = False
28 30
29 def merge(self, other: "AccessRequirements"): 31 def merge(self, other: "AccessRequirements"):
30 self.rooms |= other.rooms 32 self.rooms |= other.rooms
31 self.doors |= other.doors 33 self.doors |= other.doors
32 self.colors |= other.colors 34 self.colors |= other.colors
33 self.the_master |= other.the_master 35 self.the_master |= other.the_master
36 self.postgame |= other.postgame
34 37
35 def __str__(self): 38 def __str__(self):
36 return f"AccessRequirements(rooms={self.rooms}, doors={self.doors}, colors={self.colors})," \ 39 return f"AccessRequirements(rooms={self.rooms}, doors={self.doors}, colors={self.colors}," \
37 f" the_master={self.the_master}" 40 f" the_master={self.the_master}, postgame={self.postgame})"
38 41
39 42
40class PlayerLocation(NamedTuple): 43class PlayerLocation(NamedTuple):
@@ -190,16 +193,6 @@ class LingoPlayerLogic:
190 if color_shuffle: 193 if color_shuffle:
191 self.real_items += [name for name, item in ALL_ITEM_TABLE.items() if item.type == ItemType.COLOR] 194 self.real_items += [name for name, item in ALL_ITEM_TABLE.items() if item.type == ItemType.COLOR]
192 195
193 # Create events for each achievement panel, so that we can determine when THE MASTER is accessible.
194 for room_name, room_data in PANELS_BY_ROOM.items():
195 for panel_name, panel_data in room_data.items():
196 if panel_data.achievement:
197 access_req = AccessRequirements()
198 access_req.merge(self.calculate_panel_requirements(room_name, panel_name, world))
199 access_req.rooms.add(room_name)
200
201 self.mastery_reqs.append(access_req)
202
203 # Handle the victory condition. Victory conditions other than the chosen one become regular checks, so we need 196 # Handle the victory condition. Victory conditions other than the chosen one become regular checks, so we need
204 # to prevent the actual victory condition from becoming a check. 197 # to prevent the actual victory condition from becoming a check.
205 self.mastery_location = "Orange Tower Seventh Floor - THE MASTER" 198 self.mastery_location = "Orange Tower Seventh Floor - THE MASTER"
@@ -207,7 +200,7 @@ class LingoPlayerLogic:
207 200
208 if victory_condition == VictoryCondition.option_the_end: 201 if victory_condition == VictoryCondition.option_the_end:
209 self.victory_condition = "Orange Tower Seventh Floor - THE END" 202 self.victory_condition = "Orange Tower Seventh Floor - THE END"
210 self.add_location("Orange Tower Seventh Floor", "The End (Solved)", None, [], world) 203 self.add_location("Ending Area", "The End (Solved)", None, [], world)
211 self.event_loc_to_item["The End (Solved)"] = "Victory" 204 self.event_loc_to_item["The End (Solved)"] = "Victory"
212 elif victory_condition == VictoryCondition.option_the_master: 205 elif victory_condition == VictoryCondition.option_the_master:
213 self.victory_condition = "Orange Tower Seventh Floor - THE MASTER" 206 self.victory_condition = "Orange Tower Seventh Floor - THE MASTER"
@@ -231,6 +224,16 @@ class LingoPlayerLogic:
231 [RoomAndPanel("Pilgrim Antechamber", "PILGRIM")], world) 224 [RoomAndPanel("Pilgrim Antechamber", "PILGRIM")], world)
232 self.event_loc_to_item["PILGRIM (Solved)"] = "Victory" 225 self.event_loc_to_item["PILGRIM (Solved)"] = "Victory"
233 226
227 # Create events for each achievement panel, so that we can determine when THE MASTER is accessible.
228 for room_name, room_data in PANELS_BY_ROOM.items():
229 for panel_name, panel_data in room_data.items():
230 if panel_data.achievement:
231 access_req = AccessRequirements()
232 access_req.merge(self.calculate_panel_requirements(room_name, panel_name, world))
233 access_req.rooms.add(room_name)
234
235 self.mastery_reqs.append(access_req)
236
234 # Create groups of counting panel access requirements for the LEVEL 2 check. 237 # Create groups of counting panel access requirements for the LEVEL 2 check.
235 self.create_panel_hunt_events(world) 238 self.create_panel_hunt_events(world)
236 239
@@ -470,6 +473,11 @@ class LingoPlayerLogic:
470 if panel == "THE MASTER": 473 if panel == "THE MASTER":
471 access_reqs.the_master = True 474 access_reqs.the_master = True
472 475
476 # Evil python magic (so sayeth NewSoupVi): this checks victory_condition against the panel's location name
477 # override if it exists, or the auto-generated location name if it's None.
478 if self.victory_condition == (panel_object.location_name or f"{room} - {panel}"):
479 access_reqs.postgame = True
480
473 self.panel_reqs[room][panel] = access_reqs 481 self.panel_reqs[room][panel] = access_reqs
474 482
475 return self.panel_reqs[room][panel] 483 return self.panel_reqs[room][panel]