diff options
author | Star Rauchenberger <fefferburbia@gmail.com> | 2025-09-02 14:09:35 -0400 |
---|---|---|
committer | Star Rauchenberger <fefferburbia@gmail.com> | 2025-09-02 14:09:35 -0400 |
commit | 7f82beb120e222ace6c258fc3982b5988f9ae070 (patch) | |
tree | 6a9fdf65badf1ed5e7d26b9a07bf0b0e840ca10e | |
parent | 7f5f14ddb5a67e1ccfdc7aa3d68d829473d0b745 (diff) | |
download | lingo2-archipelago-7f82beb120e222ace6c258fc3982b5988f9ae070.tar.gz lingo2-archipelago-7f82beb120e222ace6c258fc3982b5988f9ae070.tar.bz2 lingo2-archipelago-7f82beb120e222ace6c258fc3982b5988f9ae070.zip |
Added keyholder sanity
33 files changed, 183 insertions, 8 deletions
diff --git a/apworld/__init__.py b/apworld/__init__.py index 4e5777a..1f1e6fe 100644 --- a/apworld/__init__.py +++ b/apworld/__init__.py | |||
@@ -65,7 +65,9 @@ class Lingo2World(World): | |||
65 | 65 | ||
66 | def fill_slot_data(self): | 66 | def fill_slot_data(self): |
67 | slot_options = [ | 67 | slot_options = [ |
68 | "victory_condition", "shuffle_doors", | 68 | "keyholder_sanity", |
69 | "shuffle_doors", | ||
70 | "victory_condition", | ||
69 | ] | 71 | ] |
70 | 72 | ||
71 | slot_data = { | 73 | slot_data = { |
diff --git a/apworld/options.py b/apworld/options.py index d984beb..dacbc46 100644 --- a/apworld/options.py +++ b/apworld/options.py | |||
@@ -8,6 +8,15 @@ class ShuffleDoors(Toggle): | |||
8 | display_name = "Shuffle Doors" | 8 | display_name = "Shuffle Doors" |
9 | 9 | ||
10 | 10 | ||
11 | class KeyholderSanity(Toggle): | ||
12 | """ | ||
13 | If enabled, 26 locations will be created for placing each key into its respective Green Ending keyholder. | ||
14 | |||
15 | NOTE: This does not apply to the two disappearing keyholders in The Congruent, as they are not part of Green Ending. | ||
16 | """ | ||
17 | display_name = "Keyholder Sanity" | ||
18 | |||
19 | |||
11 | class VictoryCondition(Choice): | 20 | class VictoryCondition(Choice): |
12 | """Victory condition.""" | 21 | """Victory condition.""" |
13 | display_name = "Victory Condition" | 22 | display_name = "Victory Condition" |
@@ -29,4 +38,5 @@ class VictoryCondition(Choice): | |||
29 | @dataclass | 38 | @dataclass |
30 | class Lingo2Options(PerGameCommonOptions): | 39 | class Lingo2Options(PerGameCommonOptions): |
31 | shuffle_doors: ShuffleDoors | 40 | shuffle_doors: ShuffleDoors |
41 | keyholder_sanity: KeyholderSanity | ||
32 | victory_condition: VictoryCondition | 42 | victory_condition: VictoryCondition |
diff --git a/apworld/player_logic.py b/apworld/player_logic.py index e08f644..dc1bdf0 100644 --- a/apworld/player_logic.py +++ b/apworld/player_logic.py | |||
@@ -166,6 +166,15 @@ class Lingo2PlayerLogic: | |||
166 | 166 | ||
167 | self.event_loc_item_by_room.setdefault(ending.room_id, {})[event_name] = item_name | 167 | self.event_loc_item_by_room.setdefault(ending.room_id, {})[event_name] = item_name |
168 | 168 | ||
169 | if self.world.options.keyholder_sanity: | ||
170 | for keyholder in world.static_logic.objects.keyholders: | ||
171 | if keyholder.HasField("key"): | ||
172 | reqs = AccessRequirements() | ||
173 | reqs.letters[keyholder.key.upper()] = 1 | ||
174 | |||
175 | self.locations_by_room.setdefault(keyholder.room_id, []).append(PlayerLocation(keyholder.ap_id, | ||
176 | reqs)) | ||
177 | |||
169 | def get_panel_reqs(self, panel_id: int, answer: str | None) -> AccessRequirements: | 178 | def get_panel_reqs(self, panel_id: int, answer: str | None) -> AccessRequirements: |
170 | if answer is None: | 179 | if answer is None: |
171 | if panel_id not in self.panel_reqs: | 180 | if panel_id not in self.panel_reqs: |
diff --git a/apworld/static_logic.py b/apworld/static_logic.py index 0613474..a945bc0 100644 --- a/apworld/static_logic.py +++ b/apworld/static_logic.py | |||
@@ -44,6 +44,11 @@ class Lingo2StaticLogic: | |||
44 | for progressive in self.objects.progressives: | 44 | for progressive in self.objects.progressives: |
45 | self.item_id_to_name[progressive.ap_id] = progressive.name | 45 | self.item_id_to_name[progressive.ap_id] = progressive.name |
46 | 46 | ||
47 | for keyholder in self.objects.keyholders: | ||
48 | if keyholder.HasField("key"): | ||
49 | location_name = f"{self.get_room_object_location_prefix(keyholder)} - {keyholder.key.upper()} Keyholder" | ||
50 | self.location_id_to_name[keyholder.ap_id] = location_name | ||
51 | |||
47 | self.item_id_to_name[self.objects.special_ids["Nothing"]] = "Nothing" | 52 | self.item_id_to_name[self.objects.special_ids["Nothing"]] = "Nothing" |
48 | 53 | ||
49 | self.item_name_to_id = {name: ap_id for ap_id, name in self.item_id_to_name.items()} | 54 | self.item_name_to_id = {name: ap_id for ap_id, name in self.item_id_to_name.items()} |
@@ -57,13 +62,7 @@ class Lingo2StaticLogic: | |||
57 | return self.get_door_item_name(door_id) | 62 | return self.get_door_item_name(door_id) |
58 | 63 | ||
59 | def get_door_location_name(self, door: data_pb2.Door) -> str: | 64 | def get_door_location_name(self, door: data_pb2.Door) -> str: |
60 | game_map = self.objects.maps[door.map_id] | 65 | map_part = self.get_room_object_location_prefix(door) |
61 | room = self.objects.rooms[door.room_id] | ||
62 | |||
63 | if room.HasField("panel_display_name"): | ||
64 | map_part = f"{game_map.display_name} ({room.panel_display_name})" | ||
65 | else: | ||
66 | map_part = game_map.display_name | ||
67 | 66 | ||
68 | if door.HasField("location_name"): | 67 | if door.HasField("location_name"): |
69 | return f"{map_part} - {door.location_name}" | 68 | return f"{map_part} - {door.location_name}" |
@@ -129,3 +128,12 @@ class Lingo2StaticLogic: | |||
129 | 128 | ||
130 | def get_room_object_map_name(self, obj) -> str: | 129 | def get_room_object_map_name(self, obj) -> str: |
131 | return self.get_map_object_map_name(self.objects.rooms[obj.room_id]) | 130 | return self.get_map_object_map_name(self.objects.rooms[obj.room_id]) |
131 | |||
132 | def get_room_object_location_prefix(self, obj) -> str: | ||
133 | room = self.objects.rooms[obj.room_id] | ||
134 | game_map = self.objects.maps[room.map_id] | ||
135 | |||
136 | if room.HasField("panel_display_name"): | ||
137 | return f"{game_map.display_name} ({room.panel_display_name})" | ||
138 | else: | ||
139 | return game_map.display_name | ||
diff --git a/data/ids.yaml b/data/ids.yaml index 3aff6ea..b66d6a9 100644 --- a/data/ids.yaml +++ b/data/ids.yaml | |||
@@ -20,6 +20,11 @@ maps: | |||
20 | panels: | 20 | panels: |
21 | COLOR: 2726 | 21 | COLOR: 2726 |
22 | Letters: 2727 | 22 | Letters: 2727 |
23 | keyholders: | ||
24 | 1: 2760 | ||
25 | 2: 2761 | ||
26 | 3: 2762 | ||
27 | 4: 2763 | ||
23 | Partial Entrance: | 28 | Partial Entrance: |
24 | panels: | 29 | panels: |
25 | PARTIAL: 2729 | 30 | PARTIAL: 2729 |
@@ -155,6 +160,9 @@ maps: | |||
155 | Brown Smiley: | 160 | Brown Smiley: |
156 | panels: | 161 | panels: |
157 | OTHERS: 1667 | 162 | OTHERS: 1667 |
163 | C Keyholder: | ||
164 | keyholders: | ||
165 | C: 2755 | ||
158 | Castle: | 166 | Castle: |
159 | panels: | 167 | panels: |
160 | FIVE (Blue): 1673 | 168 | FIVE (Blue): 1673 |
@@ -265,6 +273,9 @@ maps: | |||
265 | SUMMER: 1754 | 273 | SUMMER: 1754 |
266 | WORD: 1753 | 274 | WORD: 1753 |
267 | WORDWORD: 1761 | 275 | WORDWORD: 1761 |
276 | D Keyholder: | ||
277 | keyholders: | ||
278 | D: 2759 | ||
268 | Dark Light Exit: | 279 | Dark Light Exit: |
269 | panels: | 280 | panels: |
270 | GASKET: 1763 | 281 | GASKET: 1763 |
@@ -287,6 +298,9 @@ maps: | |||
287 | Eye Painting: | 298 | Eye Painting: |
288 | panels: | 299 | panels: |
289 | REVILED: 1777 | 300 | REVILED: 1777 |
301 | F Keyholder: | ||
302 | keyholders: | ||
303 | F: 2756 | ||
290 | F2 Room: | 304 | F2 Room: |
291 | panels: | 305 | panels: |
292 | CAST: 1782 | 306 | CAST: 1782 |
@@ -480,6 +494,8 @@ maps: | |||
480 | panels: | 494 | panels: |
481 | GOING: 1934 | 495 | GOING: 1934 |
482 | TURN: 1935 | 496 | TURN: 1935 |
497 | keyholders: | ||
498 | G: 2757 | ||
483 | Nursery: | 499 | Nursery: |
484 | panels: | 500 | panels: |
485 | "?": 1937 | 501 | "?": 1937 |
@@ -547,6 +563,8 @@ maps: | |||
547 | WALLS: 1986 | 563 | WALLS: 1986 |
548 | WHISPER: 1978 | 564 | WHISPER: 1978 |
549 | WING: 1979 | 565 | WING: 1979 |
566 | keyholders: | ||
567 | H: 2758 | ||
550 | Outside Magic Room: | 568 | Outside Magic Room: |
551 | panels: | 569 | panels: |
552 | WIZARD: 1988 | 570 | WIZARD: 1988 |
@@ -1160,6 +1178,9 @@ maps: | |||
1160 | SWAY: 24 | 1178 | SWAY: 24 |
1161 | TERROR: 20 | 1179 | TERROR: 20 |
1162 | TURN: 22 | 1180 | TURN: 22 |
1181 | Keyholder Room: | ||
1182 | keyholders: | ||
1183 | A: 2773 | ||
1163 | Synonyms Room: | 1184 | Synonyms Room: |
1164 | panels: | 1185 | panels: |
1165 | ADORE: 26 | 1186 | ADORE: 26 |
@@ -1452,6 +1473,9 @@ maps: | |||
1452 | panels: | 1473 | panels: |
1453 | CIVIL: 216 | 1474 | CIVIL: 216 |
1454 | CRABS: 217 | 1475 | CRABS: 217 |
1476 | T Keyholder: | ||
1477 | keyholders: | ||
1478 | T: 2754 | ||
1455 | doors: | 1479 | doors: |
1456 | C Keyholder Blocker: 176 | 1480 | C Keyholder Blocker: 176 |
1457 | C2 Door: 177 | 1481 | C2 Door: 177 |
@@ -1760,6 +1784,8 @@ maps: | |||
1760 | X Plus: | 1784 | X Plus: |
1761 | panels: | 1785 | panels: |
1762 | ROSE: 405 | 1786 | ROSE: 405 |
1787 | keyholders: | ||
1788 | M: 2766 | ||
1763 | X Plus Middle Leg: | 1789 | X Plus Middle Leg: |
1764 | panels: | 1790 | panels: |
1765 | COLONY: 403 | 1791 | COLONY: 403 |
@@ -1789,6 +1815,9 @@ maps: | |||
1789 | Daedalus Extension: | 1815 | Daedalus Extension: |
1790 | panels: | 1816 | panels: |
1791 | WHERE: 433 | 1817 | WHERE: 433 |
1818 | Main Area: | ||
1819 | keyholders: | ||
1820 | P: 2765 | ||
1792 | doors: | 1821 | doors: |
1793 | Ancient Painting: 428 | 1822 | Ancient Painting: 428 |
1794 | Between Painting: 414 | 1823 | Between Painting: 414 |
@@ -1973,6 +2002,8 @@ maps: | |||
1973 | LAUGH FINISHED: 573 | 2002 | LAUGH FINISHED: 573 |
1974 | PLANTS: 570 | 2003 | PLANTS: 570 |
1975 | WEATHER: 568 | 2004 | WEATHER: 568 |
2005 | keyholders: | ||
2006 | X: 2770 | ||
1976 | Outside Jail: | 2007 | Outside Jail: |
1977 | panels: | 2008 | panels: |
1978 | GUT: 575 | 2009 | GUT: 575 |
@@ -2120,6 +2151,8 @@ maps: | |||
2120 | WAS: 631 | 2151 | WAS: 631 |
2121 | WINGS: 662 | 2152 | WINGS: 662 |
2122 | YELL: 636 | 2153 | YELL: 636 |
2154 | keyholders: | ||
2155 | B: 2769 | ||
2123 | Mastery Room: | 2156 | Mastery Room: |
2124 | masteries: | 2157 | masteries: |
2125 | MASTERY: 666 | 2158 | MASTERY: 666 |
@@ -2186,6 +2219,8 @@ maps: | |||
2186 | FLASHBACK: 705 | 2219 | FLASHBACK: 705 |
2187 | PUSH: 703 | 2220 | PUSH: 703 |
2188 | PUSHBACK: 702 | 2221 | PUSHBACK: 702 |
2222 | keyholders: | ||
2223 | J: 2772 | ||
2189 | doors: | 2224 | doors: |
2190 | Side Door: 687 | 2225 | Side Door: 687 |
2191 | the_keen: | 2226 | the_keen: |
@@ -2297,6 +2332,8 @@ maps: | |||
2297 | NAY: 774 | 2332 | NAY: 774 |
2298 | NIGH: 781 | 2333 | NIGH: 781 |
2299 | TORE: 787 | 2334 | TORE: 787 |
2335 | keyholders: | ||
2336 | S: 2767 | ||
2300 | doors: | 2337 | doors: |
2301 | Left Room Puzzles: 763 | 2338 | Left Room Puzzles: 763 |
2302 | Main Room Door: 2750 | 2339 | Main Room Door: 2750 |
@@ -2404,6 +2441,9 @@ maps: | |||
2404 | CLEOPATRA: 859 | 2441 | CLEOPATRA: 859 |
2405 | NAPOLEON: 860 | 2442 | NAPOLEON: 860 |
2406 | XERXES: 857 | 2443 | XERXES: 857 |
2444 | U Keyholder: | ||
2445 | keyholders: | ||
2446 | U: 2777 | ||
2407 | doors: | 2447 | doors: |
2408 | K2 Door: 852 | 2448 | K2 Door: 852 |
2409 | the_partial: | 2449 | the_partial: |
@@ -2427,6 +2467,8 @@ maps: | |||
2427 | TON: 878 | 2467 | TON: 878 |
2428 | TURN: 875 | 2468 | TURN: 875 |
2429 | UP: 870 | 2469 | UP: 870 |
2470 | keyholders: | ||
2471 | L: 2771 | ||
2430 | Reverse Side: | 2472 | Reverse Side: |
2431 | panels: | 2473 | panels: |
2432 | BRO: 884 | 2474 | BRO: 884 |
@@ -2545,6 +2587,9 @@ maps: | |||
2545 | Turtle Entrance: 891 | 2587 | Turtle Entrance: 891 |
2546 | the_quiet: | 2588 | the_quiet: |
2547 | rooms: | 2589 | rooms: |
2590 | Keyholder Room: | ||
2591 | keyholders: | ||
2592 | Q: 2778 | ||
2548 | Main Area: | 2593 | Main Area: |
2549 | panels: | 2594 | panels: |
2550 | BEE: 979 | 2595 | BEE: 979 |
@@ -2791,6 +2836,8 @@ maps: | |||
2791 | STIM: 1148 | 2836 | STIM: 1148 |
2792 | STONE: 1142 | 2837 | STONE: 1142 |
2793 | TADPOLES: 1159 | 2838 | TADPOLES: 1159 |
2839 | keyholders: | ||
2840 | N: 2779 | ||
2794 | doors: | 2841 | doors: |
2795 | Books Puzzles: 1136 | 2842 | Books Puzzles: 1136 |
2796 | Games Puzzles: 1137 | 2843 | Games Puzzles: 1137 |
@@ -3145,6 +3192,8 @@ maps: | |||
3145 | SWINE (Brown): 2446 | 3192 | SWINE (Brown): 2446 |
3146 | WIFE (Black): 2440 | 3193 | WIFE (Black): 2440 |
3147 | WIFE (Brown): 2447 | 3194 | WIFE (Brown): 2447 |
3195 | keyholders: | ||
3196 | Y: 2764 | ||
3148 | doors: | 3197 | doors: |
3149 | Black Side Panels: 2427 | 3198 | Black Side Panels: 2427 |
3150 | Brown Side Panels: 2428 | 3199 | Brown Side Panels: 2428 |
@@ -3157,6 +3206,9 @@ maps: | |||
3157 | Control Center Entrance: | 3206 | Control Center Entrance: |
3158 | panels: | 3207 | panels: |
3159 | ZERO: 2455 | 3208 | ZERO: 2455 |
3209 | Main Area: | ||
3210 | keyholders: | ||
3211 | K: 2768 | ||
3160 | Mastery: | 3212 | Mastery: |
3161 | masteries: | 3213 | masteries: |
3162 | MASTERY: 2456 | 3214 | MASTERY: 2456 |
@@ -3361,6 +3413,8 @@ maps: | |||
3361 | WAYS: 2621 | 3413 | WAYS: 2621 |
3362 | WHILE: 2613 | 3414 | WHILE: 2613 |
3363 | ZOO: 2615 | 3415 | ZOO: 2615 |
3416 | keyholders: | ||
3417 | I: 2775 | ||
3364 | Middle Room: | 3418 | Middle Room: |
3365 | panels: | 3419 | panels: |
3366 | FELLOW: 2624 | 3420 | FELLOW: 2624 |
@@ -3408,6 +3462,12 @@ maps: | |||
3408 | UNINTERESTED: 2650 | 3462 | UNINTERESTED: 2650 |
3409 | UNIRONIC: 2656 | 3463 | UNIRONIC: 2656 |
3410 | UNLUCKY: 2654 | 3464 | UNLUCKY: 2654 |
3465 | V Keyholder: | ||
3466 | keyholders: | ||
3467 | V: 2776 | ||
3468 | W Keyholder: | ||
3469 | keyholders: | ||
3470 | W: 2774 | ||
3411 | doors: | 3471 | doors: |
3412 | Cog Rhino Hug Rug: 2586 | 3472 | Cog Rhino Hug Rug: 2586 |
3413 | Control Center Orange Door: 2582 | 3473 | Control Center Orange Door: 2582 |
diff --git a/data/maps/control_center/rooms/Main Area.txtpb b/data/maps/control_center/rooms/Main Area.txtpb index 44b0f79..bf81e26 100644 --- a/data/maps/control_center/rooms/Main Area.txtpb +++ b/data/maps/control_center/rooms/Main Area.txtpb | |||
@@ -30,18 +30,22 @@ panels { | |||
30 | keyholders { | 30 | keyholders { |
31 | name: "1" | 31 | name: "1" |
32 | path: "Components/KeyHolders/keyHolder" | 32 | path: "Components/KeyHolders/keyHolder" |
33 | key: "z" | ||
33 | } | 34 | } |
34 | keyholders { | 35 | keyholders { |
35 | name: "2" | 36 | name: "2" |
36 | path: "Components/KeyHolders/keyHolder2" | 37 | path: "Components/KeyHolders/keyHolder2" |
38 | key: "e" | ||
37 | } | 39 | } |
38 | keyholders { | 40 | keyholders { |
39 | name: "3" | 41 | name: "3" |
40 | path: "Components/KeyHolders/keyHolder3" | 42 | path: "Components/KeyHolders/keyHolder3" |
43 | key: "r" | ||
41 | } | 44 | } |
42 | keyholders { | 45 | keyholders { |
43 | name: "4" | 46 | name: "4" |
44 | path: "Components/KeyHolders/keyHolder4" | 47 | path: "Components/KeyHolders/keyHolder4" |
48 | key: "o" | ||
45 | } | 49 | } |
46 | ports { | 50 | ports { |
47 | name: "RIGHT" | 51 | name: "RIGHT" |
diff --git a/data/maps/daedalus/rooms/C Keyholder.txtpb b/data/maps/daedalus/rooms/C Keyholder.txtpb index cc8548c..ef10a90 100644 --- a/data/maps/daedalus/rooms/C Keyholder.txtpb +++ b/data/maps/daedalus/rooms/C Keyholder.txtpb | |||
@@ -3,4 +3,5 @@ panel_display_name: "North Area" | |||
3 | keyholders { | 3 | keyholders { |
4 | name: "C" | 4 | name: "C" |
5 | path: "Components/KeyHolders/keyHolderC" | 5 | path: "Components/KeyHolders/keyHolderC" |
6 | key: "c" | ||
6 | } | 7 | } |
diff --git a/data/maps/daedalus/rooms/D Keyholder.txtpb b/data/maps/daedalus/rooms/D Keyholder.txtpb index 2521ab2..a5852be 100644 --- a/data/maps/daedalus/rooms/D Keyholder.txtpb +++ b/data/maps/daedalus/rooms/D Keyholder.txtpb | |||
@@ -3,4 +3,5 @@ panel_display_name: "Plum Room" | |||
3 | keyholders { | 3 | keyholders { |
4 | name: "D" | 4 | name: "D" |
5 | path: "Components/KeyHolders/keyHolderD" | 5 | path: "Components/KeyHolders/keyHolderD" |
6 | key: "d" | ||
6 | } | 7 | } |
diff --git a/data/maps/daedalus/rooms/F Keyholder.txtpb b/data/maps/daedalus/rooms/F Keyholder.txtpb index 662f76d..b424c6a 100644 --- a/data/maps/daedalus/rooms/F Keyholder.txtpb +++ b/data/maps/daedalus/rooms/F Keyholder.txtpb | |||
@@ -3,4 +3,5 @@ panel_display_name: "West Area" | |||
3 | keyholders { | 3 | keyholders { |
4 | name: "F" | 4 | name: "F" |
5 | path: "Components/KeyHolders/keyHolderF" | 5 | path: "Components/KeyHolders/keyHolderF" |
6 | key: "f" | ||
6 | } | 7 | } |
diff --git a/data/maps/daedalus/rooms/Number Paintings Area.txtpb b/data/maps/daedalus/rooms/Number Paintings Area.txtpb index 15c8875..c89bfcf 100644 --- a/data/maps/daedalus/rooms/Number Paintings Area.txtpb +++ b/data/maps/daedalus/rooms/Number Paintings Area.txtpb | |||
@@ -17,6 +17,7 @@ panels { | |||
17 | keyholders { | 17 | keyholders { |
18 | name: "G" | 18 | name: "G" |
19 | path: "Components/KeyHolders/keyHolderG" | 19 | path: "Components/KeyHolders/keyHolderG" |
20 | key: "g" | ||
20 | } | 21 | } |
21 | paintings { | 22 | paintings { |
22 | name: "WON" | 23 | name: "WON" |
diff --git a/data/maps/daedalus/rooms/Outside House.txtpb b/data/maps/daedalus/rooms/Outside House.txtpb index fd3f5f0..fed9dda 100644 --- a/data/maps/daedalus/rooms/Outside House.txtpb +++ b/data/maps/daedalus/rooms/Outside House.txtpb | |||
@@ -75,6 +75,7 @@ panels { | |||
75 | keyholders { | 75 | keyholders { |
76 | name: "H" | 76 | name: "H" |
77 | path: "Components/KeyHolders/keyHolderH" | 77 | path: "Components/KeyHolders/keyHolderH" |
78 | key: "h" | ||
78 | } | 79 | } |
79 | paintings { | 80 | paintings { |
80 | name: "CASTLE2" | 81 | name: "CASTLE2" |
diff --git a/data/maps/four_rooms/rooms/Keyholder Room.txtpb b/data/maps/four_rooms/rooms/Keyholder Room.txtpb index e7c7fa6..13c3dce 100644 --- a/data/maps/four_rooms/rooms/Keyholder Room.txtpb +++ b/data/maps/four_rooms/rooms/Keyholder Room.txtpb | |||
@@ -2,4 +2,5 @@ name: "Keyholder Room" | |||
2 | keyholders { | 2 | keyholders { |
3 | name: "A" | 3 | name: "A" |
4 | path: "Components/KeyHolders/keyHolderA" | 4 | path: "Components/KeyHolders/keyHolderA" |
5 | key: "a" | ||
5 | } | 6 | } |
diff --git a/data/maps/the_congruent/rooms/T Keyholder.txtpb b/data/maps/the_congruent/rooms/T Keyholder.txtpb index 360b030..143ea53 100644 --- a/data/maps/the_congruent/rooms/T Keyholder.txtpb +++ b/data/maps/the_congruent/rooms/T Keyholder.txtpb | |||
@@ -2,4 +2,5 @@ name: "T Keyholder" | |||
2 | keyholders { | 2 | keyholders { |
3 | name: "T" | 3 | name: "T" |
4 | path: "Components/KeyHolders/keyHolderT" | 4 | path: "Components/KeyHolders/keyHolderT" |
5 | key: "t" | ||
5 | } | 6 | } |
diff --git a/data/maps/the_extravagant/rooms/X Plus.txtpb b/data/maps/the_extravagant/rooms/X Plus.txtpb index 89b6da7..a1c4b9d 100644 --- a/data/maps/the_extravagant/rooms/X Plus.txtpb +++ b/data/maps/the_extravagant/rooms/X Plus.txtpb | |||
@@ -23,4 +23,5 @@ paintings { | |||
23 | keyholders { | 23 | keyholders { |
24 | name: "M" | 24 | name: "M" |
25 | path: "Components/KeyHolders/keyHolderM" | 25 | path: "Components/KeyHolders/keyHolderM" |
26 | key: "m" | ||
26 | } | 27 | } |
diff --git a/data/maps/the_gallery/rooms/Main Area.txtpb b/data/maps/the_gallery/rooms/Main Area.txtpb index 5ba6b25..bc1606d 100644 --- a/data/maps/the_gallery/rooms/Main Area.txtpb +++ b/data/maps/the_gallery/rooms/Main Area.txtpb | |||
@@ -2,6 +2,7 @@ name: "Main Area" | |||
2 | keyholders { | 2 | keyholders { |
3 | name: "P" | 3 | name: "P" |
4 | path: "Components/KeyHolders/keyHolderP" | 4 | path: "Components/KeyHolders/keyHolderP" |
5 | key: "p" | ||
5 | } | 6 | } |
6 | paintings { | 7 | paintings { |
7 | name: "OWL" | 8 | name: "OWL" |
diff --git a/data/maps/the_great/rooms/North Landscape.txtpb b/data/maps/the_great/rooms/North Landscape.txtpb index f0fde77..fb11c42 100644 --- a/data/maps/the_great/rooms/North Landscape.txtpb +++ b/data/maps/the_great/rooms/North Landscape.txtpb | |||
@@ -52,6 +52,7 @@ panels { | |||
52 | keyholders { | 52 | keyholders { |
53 | name: "X" | 53 | name: "X" |
54 | path: "Components/KeyHolders/keyHolderX" | 54 | path: "Components/KeyHolders/keyHolderX" |
55 | key: "x" | ||
55 | } | 56 | } |
56 | ports { | 57 | ports { |
57 | name: "INVISIBLE" | 58 | name: "INVISIBLE" |
diff --git a/data/maps/the_hive/rooms/Main Area.txtpb b/data/maps/the_hive/rooms/Main Area.txtpb index 0f73682..013390a 100644 --- a/data/maps/the_hive/rooms/Main Area.txtpb +++ b/data/maps/the_hive/rooms/Main Area.txtpb | |||
@@ -268,6 +268,7 @@ panels { | |||
268 | keyholders { | 268 | keyholders { |
269 | name: "B" | 269 | name: "B" |
270 | path: "Components/KeyHolders/keyHolderB" | 270 | path: "Components/KeyHolders/keyHolderB" |
271 | key: "b" | ||
271 | } | 272 | } |
272 | ports { | 273 | ports { |
273 | name: "DAED1" | 274 | name: "DAED1" |
diff --git a/data/maps/the_jubilant/rooms/Side Area.txtpb b/data/maps/the_jubilant/rooms/Side Area.txtpb index e924762..807f044 100644 --- a/data/maps/the_jubilant/rooms/Side Area.txtpb +++ b/data/maps/the_jubilant/rooms/Side Area.txtpb | |||
@@ -38,4 +38,5 @@ panels { | |||
38 | keyholders { | 38 | keyholders { |
39 | name: "J" | 39 | name: "J" |
40 | path: "Components/KeyHolders/keyHolderJ" | 40 | path: "Components/KeyHolders/keyHolderJ" |
41 | key: "j" | ||
41 | } | 42 | } |
diff --git a/data/maps/the_nuanced/rooms/Main Room.txtpb b/data/maps/the_nuanced/rooms/Main Room.txtpb index 8da3b5f..da89bd8 100644 --- a/data/maps/the_nuanced/rooms/Main Room.txtpb +++ b/data/maps/the_nuanced/rooms/Main Room.txtpb | |||
@@ -112,4 +112,5 @@ ports { | |||
112 | keyholders { | 112 | keyholders { |
113 | name: "S" | 113 | name: "S" |
114 | path: "Components/KeyHolders/keyHolderS" | 114 | path: "Components/KeyHolders/keyHolderS" |
115 | key: "s" | ||
115 | } | 116 | } |
diff --git a/data/maps/the_parthenon/rooms/U Keyholder.txtpb b/data/maps/the_parthenon/rooms/U Keyholder.txtpb index 8248df8..0a5c31b 100644 --- a/data/maps/the_parthenon/rooms/U Keyholder.txtpb +++ b/data/maps/the_parthenon/rooms/U Keyholder.txtpb | |||
@@ -2,4 +2,5 @@ name: "U Keyholder" | |||
2 | keyholders { | 2 | keyholders { |
3 | name: "U" | 3 | name: "U" |
4 | path: "Components/KeyHolders/keyHolderU" | 4 | path: "Components/KeyHolders/keyHolderU" |
5 | key: "u" | ||
5 | } | 6 | } |
diff --git a/data/maps/the_partial/rooms/Obverse Side.txtpb b/data/maps/the_partial/rooms/Obverse Side.txtpb index 75cd9bb..c0ce04b 100644 --- a/data/maps/the_partial/rooms/Obverse Side.txtpb +++ b/data/maps/the_partial/rooms/Obverse Side.txtpb | |||
@@ -106,6 +106,7 @@ keyholders { | |||
106 | # This is one of the ones that's misnamed within the game. | 106 | # This is one of the ones that's misnamed within the game. |
107 | name: "L" | 107 | name: "L" |
108 | path: "Components/KeyHolders/keyHolderI" | 108 | path: "Components/KeyHolders/keyHolderI" |
109 | key: "l" | ||
109 | } | 110 | } |
110 | paintings { | 111 | paintings { |
111 | name: "F" | 112 | name: "F" |
diff --git a/data/maps/the_quiet/rooms/Keyholder Room.txtpb b/data/maps/the_quiet/rooms/Keyholder Room.txtpb index d0f2677..d3cab73 100644 --- a/data/maps/the_quiet/rooms/Keyholder Room.txtpb +++ b/data/maps/the_quiet/rooms/Keyholder Room.txtpb | |||
@@ -2,4 +2,5 @@ name: "Keyholder Room" | |||
2 | keyholders { | 2 | keyholders { |
3 | name: "Q" | 3 | name: "Q" |
4 | path: "Components/KeyHolders/keyHolderQ" | 4 | path: "Components/KeyHolders/keyHolderQ" |
5 | key: "q" | ||
5 | } | 6 | } |
diff --git a/data/maps/the_shop/rooms/Main Area.txtpb b/data/maps/the_shop/rooms/Main Area.txtpb index d45e0f0..db93fe1 100644 --- a/data/maps/the_shop/rooms/Main Area.txtpb +++ b/data/maps/the_shop/rooms/Main Area.txtpb | |||
@@ -160,4 +160,5 @@ ports { | |||
160 | keyholders { | 160 | keyholders { |
161 | name: "N" | 161 | name: "N" |
162 | path: "Components/KeyHolders/keyHolderN" | 162 | path: "Components/KeyHolders/keyHolderN" |
163 | key: "n" | ||
163 | } | 164 | } |
diff --git a/data/maps/the_talented/rooms/Main Area.txtpb b/data/maps/the_talented/rooms/Main Area.txtpb index cc3e222..f99be48 100644 --- a/data/maps/the_talented/rooms/Main Area.txtpb +++ b/data/maps/the_talented/rooms/Main Area.txtpb | |||
@@ -107,6 +107,7 @@ panels { | |||
107 | keyholders { | 107 | keyholders { |
108 | name: "Y" | 108 | name: "Y" |
109 | path: "Components/KeyHolders/keyHolderY" | 109 | path: "Components/KeyHolders/keyHolderY" |
110 | key: "y" | ||
110 | } | 111 | } |
111 | ports { | 112 | ports { |
112 | name: "GREAT" | 113 | name: "GREAT" |
diff --git a/data/maps/the_tenacious/rooms/Main Area.txtpb b/data/maps/the_tenacious/rooms/Main Area.txtpb index 8190827..18356e7 100644 --- a/data/maps/the_tenacious/rooms/Main Area.txtpb +++ b/data/maps/the_tenacious/rooms/Main Area.txtpb | |||
@@ -2,4 +2,5 @@ name: "Main Area" | |||
2 | keyholders { | 2 | keyholders { |
3 | name: "K" | 3 | name: "K" |
4 | path: "Components/KeyHolders/keyHolderK" | 4 | path: "Components/KeyHolders/keyHolderK" |
5 | key: "k" | ||
5 | } | 6 | } |
diff --git a/data/maps/the_unkempt/rooms/Main Area.txtpb b/data/maps/the_unkempt/rooms/Main Area.txtpb index ed3ce21..b5d29c4 100644 --- a/data/maps/the_unkempt/rooms/Main Area.txtpb +++ b/data/maps/the_unkempt/rooms/Main Area.txtpb | |||
@@ -212,6 +212,7 @@ panels { | |||
212 | keyholders { | 212 | keyholders { |
213 | name: "I" | 213 | name: "I" |
214 | path: "Components/KeyHolders/keyHolderL" | 214 | path: "Components/KeyHolders/keyHolderL" |
215 | key: "i" | ||
215 | } | 216 | } |
216 | ports { | 217 | ports { |
217 | name: "GREAT" | 218 | name: "GREAT" |
diff --git a/data/maps/the_unkempt/rooms/V Keyholder.txtpb b/data/maps/the_unkempt/rooms/V Keyholder.txtpb index 0906b2e..8a4941d 100644 --- a/data/maps/the_unkempt/rooms/V Keyholder.txtpb +++ b/data/maps/the_unkempt/rooms/V Keyholder.txtpb | |||
@@ -2,4 +2,5 @@ name: "V Keyholder" | |||
2 | keyholders { | 2 | keyholders { |
3 | name: "V" | 3 | name: "V" |
4 | path: "Components/KeyHolders/keyHolderV" | 4 | path: "Components/KeyHolders/keyHolderV" |
5 | key: "v" | ||
5 | } | 6 | } |
diff --git a/data/maps/the_unkempt/rooms/W Keyholder.txtpb b/data/maps/the_unkempt/rooms/W Keyholder.txtpb index ae367b2..e16f997 100644 --- a/data/maps/the_unkempt/rooms/W Keyholder.txtpb +++ b/data/maps/the_unkempt/rooms/W Keyholder.txtpb | |||
@@ -2,4 +2,5 @@ name: "W Keyholder" | |||
2 | keyholders { | 2 | keyholders { |
3 | name: "W" | 3 | name: "W" |
4 | path: "Components/KeyHolders/keyHolderW" | 4 | path: "Components/KeyHolders/keyHolderW" |
5 | key: "w" | ||
5 | } | 6 | } |
diff --git a/proto/data.proto b/proto/data.proto index b627e83..9cdf5fd 100644 --- a/proto/data.proto +++ b/proto/data.proto | |||
@@ -162,10 +162,12 @@ message Port { | |||
162 | 162 | ||
163 | message KeyholderData { | 163 | message KeyholderData { |
164 | optional uint64 id = 1; | 164 | optional uint64 id = 1; |
165 | optional uint64 ap_id = 6; | ||
165 | optional uint64 room_id = 2; | 166 | optional uint64 room_id = 2; |
166 | 167 | ||
167 | optional string name = 3; | 168 | optional string name = 3; |
168 | optional string path = 4; | 169 | optional string path = 4; |
170 | optional string key = 5; | ||
169 | } | 171 | } |
170 | 172 | ||
171 | message Letter { | 173 | message Letter { |
diff --git a/proto/human.proto b/proto/human.proto index 8d882da..e0378cc 100644 --- a/proto/human.proto +++ b/proto/human.proto | |||
@@ -142,6 +142,13 @@ message HumanPort { | |||
142 | message HumanKeyholder { | 142 | message HumanKeyholder { |
143 | optional string name = 1; | 143 | optional string name = 1; |
144 | optional string path = 2; | 144 | optional string path = 2; |
145 | |||
146 | // If this is set, the keyholder will become a location when keyholder shuffle | ||
147 | // is enabled. This value specifies the key that is required to clear the | ||
148 | // location. It should be the same as the key needed for Green Ending. The | ||
149 | // only cases when this shouldn't be set is the two disappearing keyholders in | ||
150 | // The Congruent. | ||
151 | optional string key = 3; | ||
145 | } | 152 | } |
146 | 153 | ||
147 | message HumanLetter { | 154 | message HumanLetter { |
@@ -196,6 +203,7 @@ message IdMappings { | |||
196 | message RoomIds { | 203 | message RoomIds { |
197 | map<string, uint64> panels = 1; | 204 | map<string, uint64> panels = 1; |
198 | map<string, uint64> masteries = 2; | 205 | map<string, uint64> masteries = 2; |
206 | map<string, uint64> keyholders = 3; | ||
199 | } | 207 | } |
200 | 208 | ||
201 | message MapIds { | 209 | message MapIds { |
diff --git a/tools/assign_ids/main.cpp b/tools/assign_ids/main.cpp index 3a2f347..6eb41e3 100644 --- a/tools/assign_ids/main.cpp +++ b/tools/assign_ids/main.cpp | |||
@@ -183,6 +183,29 @@ class AssignIds { | |||
183 | endings[h_ending.name()] = next_id_++; | 183 | endings[h_ending.name()] = next_id_++; |
184 | } | 184 | } |
185 | } | 185 | } |
186 | |||
187 | for (const HumanKeyholder& h_keyholder : h_room.keyholders()) { | ||
188 | if (!h_keyholder.has_key()) { | ||
189 | continue; | ||
190 | } | ||
191 | |||
192 | if (!id_mappings_.maps().contains(current_map_name) || | ||
193 | !id_mappings_.maps() | ||
194 | .at(current_map_name) | ||
195 | .rooms() | ||
196 | .contains(h_room.name()) || | ||
197 | !id_mappings_.maps() | ||
198 | .at(current_map_name) | ||
199 | .rooms() | ||
200 | .at(h_room.name()) | ||
201 | .keyholders() | ||
202 | .contains(h_keyholder.name())) { | ||
203 | auto& maps = *id_mappings_.mutable_maps(); | ||
204 | auto& rooms = *maps[current_map_name].mutable_rooms(); | ||
205 | auto& keyholders = *rooms[h_room.name()].mutable_keyholders(); | ||
206 | keyholders[h_keyholder.name()] = next_id_++; | ||
207 | } | ||
208 | } | ||
186 | } | 209 | } |
187 | 210 | ||
188 | void ProcessProgressivesFile(std::filesystem::path path) { | 211 | void ProcessProgressivesFile(std::filesystem::path path) { |
diff --git a/tools/datapacker/main.cpp b/tools/datapacker/main.cpp index 5ed82cc..d7e0b69 100644 --- a/tools/datapacker/main.cpp +++ b/tools/datapacker/main.cpp | |||
@@ -293,6 +293,10 @@ class DataPacker { | |||
293 | 293 | ||
294 | keyholder.set_path(h_keyholder.path()); | 294 | keyholder.set_path(h_keyholder.path()); |
295 | 295 | ||
296 | if (h_keyholder.has_key()) { | ||
297 | keyholder.set_key(h_keyholder.key()); | ||
298 | } | ||
299 | |||
296 | return keyholder_id; | 300 | return keyholder_id; |
297 | } | 301 | } |
298 | 302 | ||
@@ -592,6 +596,14 @@ class DataPacker { | |||
592 | .mutable_masteries(mastery_id) | 596 | .mutable_masteries(mastery_id) |
593 | ->set_ap_id(ap_id); | 597 | ->set_ap_id(ap_id); |
594 | } | 598 | } |
599 | |||
600 | for (const auto& [keyholder_name, ap_id] : room.keyholders()) { | ||
601 | uint64_t keyholder_id = container_.FindOrAddKeyholder( | ||
602 | map_name, room_name, keyholder_name, std::nullopt, std::nullopt); | ||
603 | container_.all_objects() | ||
604 | .mutable_keyholders(keyholder_id) | ||
605 | ->set_ap_id(ap_id); | ||
606 | } | ||
595 | } | 607 | } |
596 | } | 608 | } |
597 | 609 | ||
diff --git a/tools/util/ids_yaml_format.cpp b/tools/util/ids_yaml_format.cpp index ae62073..67c21d6 100644 --- a/tools/util/ids_yaml_format.cpp +++ b/tools/util/ids_yaml_format.cpp | |||
@@ -56,6 +56,14 @@ IdMappings ReadIdsFromYaml(const std::string& filename) { | |||
56 | mastery_it.second.as<uint64_t>(); | 56 | mastery_it.second.as<uint64_t>(); |
57 | } | 57 | } |
58 | } | 58 | } |
59 | |||
60 | if (room_it.second["keyholders"]) { | ||
61 | for (const auto& keyholder_it : room_it.second["keyholders"]) { | ||
62 | (*room_ids.mutable_keyholders())[keyholder_it.first | ||
63 | .as<std::string>()] = | ||
64 | keyholder_it.second.as<uint64_t>(); | ||
65 | } | ||
66 | } | ||
59 | } | 67 | } |
60 | } | 68 | } |
61 | 69 | ||
@@ -124,6 +132,13 @@ void WriteIdsAsYaml(const IdMappings& ids, const std::string& filename) { | |||
124 | mastery_id; | 132 | mastery_id; |
125 | }); | 133 | }); |
126 | 134 | ||
135 | OperateOnSortedMap(room_ids.keyholders(), | ||
136 | [&room_node](const std::string& keyholder_name, | ||
137 | uint64_t keyholder_id) { | ||
138 | room_node["keyholders"][keyholder_name] = | ||
139 | keyholder_id; | ||
140 | }); | ||
141 | |||
127 | map_node["rooms"][room_name] = std::move(room_node); | 142 | map_node["rooms"][room_name] = std::move(room_node); |
128 | }); | 143 | }); |
129 | 144 | ||