diff options
-rw-r--r-- | apworld/client/assets/goal.png | bin | 0 -> 215 bytes | |||
-rw-r--r-- | apworld/client/client.gd | 4 | ||||
-rw-r--r-- | apworld/client/gamedata.gd | 5 | ||||
-rw-r--r-- | apworld/client/manager.gd | 16 | ||||
-rw-r--r-- | apworld/client/player.gd | 22 | ||||
-rw-r--r-- | apworld/client/textclient.gd | 15 | ||||
-rw-r--r-- | apworld/context.py | 23 | ||||
-rw-r--r-- | apworld/locations.py | 1 | ||||
-rw-r--r-- | apworld/player_logic.py | 9 | ||||
-rw-r--r-- | apworld/regions.py | 3 | ||||
-rw-r--r-- | apworld/tracker.py | 6 | ||||
-rw-r--r-- | data/maps/daedalus/doors.txtpb | 1 |
12 files changed, 77 insertions, 28 deletions
diff --git a/apworld/client/assets/goal.png b/apworld/client/assets/goal.png new file mode 100644 index 0000000..bd1650d --- /dev/null +++ b/apworld/client/assets/goal.png | |||
Binary files differ | |||
diff --git a/apworld/client/client.gd b/apworld/client/client.gd index a23e85a..62d7fd8 100644 --- a/apworld/client/client.gd +++ b/apworld/client/client.gd | |||
@@ -24,6 +24,7 @@ var _received_items = {} | |||
24 | var _slot_data = {} | 24 | var _slot_data = {} |
25 | var _accessible_locations = [] | 25 | var _accessible_locations = [] |
26 | var _accessible_worldports = [] | 26 | var _accessible_worldports = [] |
27 | var _goal_accessible = false | ||
27 | 28 | ||
28 | signal could_not_connect | 29 | signal could_not_connect |
29 | signal connect_status | 30 | signal connect_status |
@@ -61,6 +62,7 @@ func _reset_state(): | |||
61 | _checked_worldports = [] | 62 | _checked_worldports = [] |
62 | _accessible_locations = [] | 63 | _accessible_locations = [] |
63 | _accessible_worldports = [] | 64 | _accessible_worldports = [] |
65 | _goal_accessible = false | ||
64 | 66 | ||
65 | 67 | ||
66 | func disconnect_from_ap(): | 68 | func disconnect_from_ap(): |
@@ -174,6 +176,8 @@ func _on_web_socket_server_message_received(_peer_id: int, packet: String) -> vo | |||
174 | for port_id in message["worldports"]: | 176 | for port_id in message["worldports"]: |
175 | _accessible_worldports.append(int(port_id)) | 177 | _accessible_worldports.append(int(port_id)) |
176 | 178 | ||
179 | _goal_accessible = bool(message.get("goal", false)) | ||
180 | |||
177 | accessible_locations_updated.emit() | 181 | accessible_locations_updated.emit() |
178 | 182 | ||
179 | elif cmd == "UpdateKeyboard": | 183 | elif cmd == "UpdateKeyboard": |
diff --git a/apworld/client/gamedata.gd b/apworld/client/gamedata.gd index 1424721..334d42a 100644 --- a/apworld/client/gamedata.gd +++ b/apworld/client/gamedata.gd | |||
@@ -14,6 +14,7 @@ var letter_id_by_ap_id = {} | |||
14 | var symbol_item_ids = [] | 14 | var symbol_item_ids = [] |
15 | var anti_trap_ids = {} | 15 | var anti_trap_ids = {} |
16 | var location_name_by_id = {} | 16 | var location_name_by_id = {} |
17 | var ending_display_name_by_name = {} | ||
17 | 18 | ||
18 | var kSYMBOL_ITEMS | 19 | var kSYMBOL_ITEMS |
19 | 20 | ||
@@ -103,7 +104,9 @@ func load(data_bytes): | |||
103 | location_name_by_id[mastery.get_ap_id()] = _get_mastery_location_name(mastery) | 104 | location_name_by_id[mastery.get_ap_id()] = _get_mastery_location_name(mastery) |
104 | 105 | ||
105 | for ending in objects.get_endings(): | 106 | for ending in objects.get_endings(): |
106 | location_name_by_id[ending.get_ap_id()] = _get_ending_location_name(ending) | 107 | var location_name = _get_ending_location_name(ending) |
108 | location_name_by_id[ending.get_ap_id()] = location_name | ||
109 | ending_display_name_by_name[ending.get_name()] = location_name | ||
107 | 110 | ||
108 | for keyholder in objects.get_keyholders(): | 111 | for keyholder in objects.get_keyholders(): |
109 | if keyholder.has_key(): | 112 | if keyholder.has_key(): |
diff --git a/apworld/client/manager.gd b/apworld/client/manager.gd index 5b731d2..b4fef1c 100644 --- a/apworld/client/manager.gd +++ b/apworld/client/manager.gd | |||
@@ -45,6 +45,22 @@ const kCYAN_DOOR_BEHAVIOR_H2 = 0 | |||
45 | const kCYAN_DOOR_BEHAVIOR_DOUBLE_LETTER = 1 | 45 | const kCYAN_DOOR_BEHAVIOR_DOUBLE_LETTER = 1 |
46 | const kCYAN_DOOR_BEHAVIOR_ITEM = 2 | 46 | const kCYAN_DOOR_BEHAVIOR_ITEM = 2 |
47 | 47 | ||
48 | const kEndingNameByVictoryValue = { | ||
49 | 0: "GRAY", | ||
50 | 1: "PURPLE", | ||
51 | 2: "MINT", | ||
52 | 3: "BLACK", | ||
53 | 4: "BLUE", | ||
54 | 5: "CYAN", | ||
55 | 6: "RED", | ||
56 | 7: "PLUM", | ||
57 | 8: "ORANGE", | ||
58 | 9: "GOLD", | ||
59 | 10: "YELLOW", | ||
60 | 11: "GREEN", | ||
61 | 12: "WHITE", | ||
62 | } | ||
63 | |||
48 | var apworld_version = [0, 0] | 64 | var apworld_version = [0, 0] |
49 | var cyan_door_behavior = kCYAN_DOOR_BEHAVIOR_H2 | 65 | var cyan_door_behavior = kCYAN_DOOR_BEHAVIOR_H2 |
50 | var daedalus_roof_access = false | 66 | var daedalus_roof_access = false |
diff --git a/apworld/client/player.gd b/apworld/client/player.gd index 366c3b0..5417a48 100644 --- a/apworld/client/player.gd +++ b/apworld/client/player.gd | |||
@@ -1,21 +1,5 @@ | |||
1 | extends "res://scripts/nodes/player.gd" | 1 | extends "res://scripts/nodes/player.gd" |
2 | 2 | ||
3 | const kEndingNameByVictoryValue = { | ||
4 | 0: "GRAY", | ||
5 | 1: "PURPLE", | ||
6 | 2: "MINT", | ||
7 | 3: "BLACK", | ||
8 | 4: "BLUE", | ||
9 | 5: "CYAN", | ||
10 | 6: "RED", | ||
11 | 7: "PLUM", | ||
12 | 8: "ORANGE", | ||
13 | 9: "GOLD", | ||
14 | 10: "YELLOW", | ||
15 | 11: "GREEN", | ||
16 | 12: "WHITE", | ||
17 | } | ||
18 | |||
19 | signal evaluate_solvability | 3 | signal evaluate_solvability |
20 | 4 | ||
21 | var compass | 5 | var compass |
@@ -138,7 +122,7 @@ func _ready(): | |||
138 | 122 | ||
139 | get_parent().add_child.call_deferred(locationListener) | 123 | get_parent().add_child.call_deferred(locationListener) |
140 | 124 | ||
141 | if kEndingNameByVictoryValue.get(ap.victory_condition, null) == ending.get_name(): | 125 | if ap.kEndingNameByVictoryValue.get(ap.victory_condition, null) == ending.get_name(): |
142 | var victoryListener = ap.SCRIPT_victoryListener.new() | 126 | var victoryListener = ap.SCRIPT_victoryListener.new() |
143 | victoryListener.name = "victoryListener" | 127 | victoryListener.name = "victoryListener" |
144 | victoryListener.senders.append(NodePath("/root/scene/" + ending.get_path())) | 128 | victoryListener.senders.append(NodePath("/root/scene/" + ending.get_path())) |
@@ -216,9 +200,9 @@ func _ready(): | |||
216 | 200 | ||
217 | var sign2 = sign_prefab.instantiate() | 201 | var sign2 = sign_prefab.instantiate() |
218 | sign2.position = Vector3(-7, 4, -15.01) | 202 | sign2.position = Vector3(-7, 4, -15.01) |
219 | sign2.text = "%s ending" % kEndingNameByVictoryValue.get(ap.victory_condition, "?") | 203 | sign2.text = "%s ending" % ap.kEndingNameByVictoryValue.get(ap.victory_condition, "?") |
220 | 204 | ||
221 | var sign2_color = kEndingNameByVictoryValue.get(ap.victory_condition, "coral").to_lower() | 205 | var sign2_color = ap.kEndingNameByVictoryValue.get(ap.victory_condition, "coral").to_lower() |
222 | if sign2_color == "white": | 206 | if sign2_color == "white": |
223 | sign2_color = "silver" | 207 | sign2_color = "silver" |
224 | 208 | ||
diff --git a/apworld/client/textclient.gd b/apworld/client/textclient.gd index 0c4e675..530eddb 100644 --- a/apworld/client/textclient.gd +++ b/apworld/client/textclient.gd | |||
@@ -10,6 +10,7 @@ var is_open = false | |||
10 | var locations_overlay | 10 | var locations_overlay |
11 | var location_texture | 11 | var location_texture |
12 | var worldport_texture | 12 | var worldport_texture |
13 | var goal_texture | ||
13 | 14 | ||
14 | var worldports_tab | 15 | var worldports_tab |
15 | var worldports_tree | 16 | var worldports_tree |
@@ -116,6 +117,10 @@ func _ready(): | |||
116 | worldport_image.load_png_from_buffer(runtime.read_path("assets/worldport.png")) | 117 | worldport_image.load_png_from_buffer(runtime.read_path("assets/worldport.png")) |
117 | worldport_texture = ImageTexture.create_from_image(worldport_image) | 118 | worldport_texture = ImageTexture.create_from_image(worldport_image) |
118 | 119 | ||
120 | var goal_image = Image.new() | ||
121 | goal_image.load_png_from_buffer(runtime.read_path("assets/goal.png")) | ||
122 | goal_texture = ImageTexture.create_from_image(goal_image) | ||
123 | |||
119 | 124 | ||
120 | func _input(event): | 125 | func _input(event): |
121 | if global.loaded and event is InputEventKey and event.pressed: | 126 | if global.loaded and event is InputEventKey and event.pressed: |
@@ -179,6 +184,7 @@ func update_locations(): | |||
179 | 184 | ||
180 | const kLocation = 0 | 185 | const kLocation = 0 |
181 | const kWorldport = 1 | 186 | const kWorldport = 1 |
187 | const kGoal = 2 | ||
182 | 188 | ||
183 | var location_names = [] | 189 | var location_names = [] |
184 | var type_by_name = {} | 190 | var type_by_name = {} |
@@ -196,6 +202,13 @@ func update_locations(): | |||
196 | 202 | ||
197 | location_names.sort() | 203 | location_names.sort() |
198 | 204 | ||
205 | if ap.client._goal_accessible: | ||
206 | var location_name = gamedata.ending_display_name_by_name[ap.kEndingNameByVictoryValue[ | ||
207 | ap.victory_condition | ||
208 | ]] | ||
209 | location_names.push_front(location_name) | ||
210 | type_by_name[location_name] = kGoal | ||
211 | |||
199 | var count = 0 | 212 | var count = 0 |
200 | for location_name in location_names: | 213 | for location_name in location_names: |
201 | tracker_label.append_text("[p]%s[/p]" % location_name) | 214 | tracker_label.append_text("[p]%s[/p]" % location_name) |
@@ -207,6 +220,8 @@ func update_locations(): | |||
207 | locations_overlay.add_image(location_texture) | 220 | locations_overlay.add_image(location_texture) |
208 | elif type_by_name[location_name] == kWorldport: | 221 | elif type_by_name[location_name] == kWorldport: |
209 | locations_overlay.add_image(worldport_texture) | 222 | locations_overlay.add_image(worldport_texture) |
223 | elif type_by_name[location_name] == kGoal: | ||
224 | locations_overlay.add_image(goal_texture) | ||
210 | locations_overlay.pop() | 225 | locations_overlay.pop() |
211 | count += 1 | 226 | count += 1 |
212 | 227 | ||
diff --git a/apworld/context.py b/apworld/context.py index 4b78517..0e1a125 100644 --- a/apworld/context.py +++ b/apworld/context.py | |||
@@ -10,7 +10,7 @@ import Utils | |||
10 | import settings | 10 | import settings |
11 | from BaseClasses import ItemClassification | 11 | from BaseClasses import ItemClassification |
12 | from CommonClient import CommonContext, server_loop, gui_enabled, logger, get_base_parser, handle_url_arg | 12 | from CommonClient import CommonContext, server_loop, gui_enabled, logger, get_base_parser, handle_url_arg |
13 | from NetUtils import Endpoint, decode, encode | 13 | from NetUtils import Endpoint, decode, encode, ClientStatus |
14 | from Utils import async_start | 14 | from Utils import async_start |
15 | from . import Lingo2World | 15 | from . import Lingo2World |
16 | from .tracker import Tracker | 16 | from .tracker import Tracker |
@@ -36,6 +36,7 @@ class Lingo2Manager: | |||
36 | 36 | ||
37 | keyboard: dict[str, int] | 37 | keyboard: dict[str, int] |
38 | worldports: set[int] | 38 | worldports: set[int] |
39 | goaled: bool | ||
39 | 40 | ||
40 | def __init__(self, game_ctx: "Lingo2GameContext", client_ctx: "Lingo2ClientContext"): | 41 | def __init__(self, game_ctx: "Lingo2GameContext", client_ctx: "Lingo2ClientContext"): |
41 | self.game_ctx = game_ctx | 42 | self.game_ctx = game_ctx |
@@ -53,6 +54,7 @@ class Lingo2Manager: | |||
53 | self.keyboard[k] = 0 | 54 | self.keyboard[k] = 0 |
54 | 55 | ||
55 | self.worldports = set() | 56 | self.worldports = set() |
57 | self.goaled = False | ||
56 | 58 | ||
57 | def update_keyboard(self, new_keyboard: dict[str, int]) -> dict[str, int]: | 59 | def update_keyboard(self, new_keyboard: dict[str, int]) -> dict[str, int]: |
58 | ret: dict[str, int] = {} | 60 | ret: dict[str, int] = {} |
@@ -177,6 +179,9 @@ class Lingo2GameContext: | |||
177 | if len(self.manager.tracker.accessible_worldports) > 0: | 179 | if len(self.manager.tracker.accessible_worldports) > 0: |
178 | msg["worldports"] = list(self.manager.tracker.accessible_worldports) | 180 | msg["worldports"] = list(self.manager.tracker.accessible_worldports) |
179 | 181 | ||
182 | if self.manager.tracker.goal_accessible and not self.manager.goaled: | ||
183 | msg["goal"] = True | ||
184 | |||
180 | async_start(self.send_msgs([msg]), name="accessible locations") | 185 | async_start(self.send_msgs([msg]), name="accessible locations") |
181 | 186 | ||
182 | def send_update_locations(self, locations): | 187 | def send_update_locations(self, locations): |
@@ -226,6 +231,7 @@ class Lingo2ClientContext(CommonContext): | |||
226 | items_handling = 0b111 | 231 | items_handling = 0b111 |
227 | 232 | ||
228 | slot_data: dict[str, Any] | None | 233 | slot_data: dict[str, Any] | None |
234 | victory_data_storage_key: str | ||
229 | 235 | ||
230 | def __init__(self, server_address: str | None = None, password: str | None = None): | 236 | def __init__(self, server_address: str | None = None, password: str | None = None): |
231 | super().__init__(server_address, password) | 237 | super().__init__(server_address, password) |
@@ -253,7 +259,10 @@ class Lingo2ClientContext(CommonContext): | |||
253 | self.manager.tracker.set_checked_locations(self.checked_locations) | 259 | self.manager.tracker.set_checked_locations(self.checked_locations) |
254 | self.manager.game_ctx.send_accessible_locations() | 260 | self.manager.game_ctx.send_accessible_locations() |
255 | 261 | ||
256 | self.set_notify(self.get_datastorage_key("keyboard1"), self.get_datastorage_key("keyboard2")) | 262 | self.victory_data_storage_key = f"_read_client_status_{self.team}_{self.slot}" |
263 | |||
264 | self.set_notify(self.get_datastorage_key("keyboard1"), self.get_datastorage_key("keyboard2"), | ||
265 | self.victory_data_storage_key) | ||
257 | msg_batch = [{ | 266 | msg_batch = [{ |
258 | "cmd": "Set", | 267 | "cmd": "Set", |
259 | "key": self.get_datastorage_key("keyboard1"), | 268 | "key": self.get_datastorage_key("keyboard1"), |
@@ -360,6 +369,9 @@ class Lingo2ClientContext(CommonContext): | |||
360 | }) | 369 | }) |
361 | 370 | ||
362 | self.manager.game_ctx.send_location_info(locations) | 371 | self.manager.game_ctx.send_location_info(locations) |
372 | elif cmd == "Received": | ||
373 | if args["key"] == self.victory_data_storage_key: | ||
374 | self.handle_status_update(args["value"]) | ||
363 | elif cmd == "SetReply": | 375 | elif cmd == "SetReply": |
364 | if args["key"] == self.get_datastorage_key("keyboard1"): | 376 | if args["key"] == self.get_datastorage_key("keyboard1"): |
365 | self.handle_keyboard_update(1, args) | 377 | self.handle_keyboard_update(1, args) |
@@ -369,6 +381,8 @@ class Lingo2ClientContext(CommonContext): | |||
369 | updates = self.manager.update_worldports(set(args["value"])) | 381 | updates = self.manager.update_worldports(set(args["value"])) |
370 | if len(updates) > 0: | 382 | if len(updates) > 0: |
371 | self.manager.game_ctx.send_update_worldports(updates) | 383 | self.manager.game_ctx.send_update_worldports(updates) |
384 | elif args["key"] == self.victory_data_storage_key: | ||
385 | self.handle_status_update(args["value"]) | ||
372 | 386 | ||
373 | def get_datastorage_key(self, name: str): | 387 | def get_datastorage_key(self, name: str): |
374 | return f"Lingo2_{self.slot}_{name}" | 388 | return f"Lingo2_{self.slot}_{name}" |
@@ -445,6 +459,11 @@ class Lingo2ClientContext(CommonContext): | |||
445 | }] | 459 | }] |
446 | }]) | 460 | }]) |
447 | 461 | ||
462 | def handle_status_update(self, value: int): | ||
463 | self.manager.goaled = (value == ClientStatus.CLIENT_GOAL) | ||
464 | self.manager.tracker.refresh_state() | ||
465 | self.manager.game_ctx.send_accessible_locations() | ||
466 | |||
448 | 467 | ||
449 | async def pipe_loop(manager: Lingo2Manager): | 468 | async def pipe_loop(manager: Lingo2Manager): |
450 | while not manager.client_ctx.exit_event.is_set(): | 469 | while not manager.client_ctx.exit_event.is_set(): |
diff --git a/apworld/locations.py b/apworld/locations.py index a502931..3d619dc 100644 --- a/apworld/locations.py +++ b/apworld/locations.py | |||
@@ -5,3 +5,4 @@ class Lingo2Location(Location): | |||
5 | game: str = "Lingo 2" | 5 | game: str = "Lingo 2" |
6 | 6 | ||
7 | port_id: int | 7 | port_id: int |
8 | goal: bool | ||
diff --git a/apworld/player_logic.py b/apworld/player_logic.py index 8f2bd59..5be066d 100644 --- a/apworld/player_logic.py +++ b/apworld/player_logic.py | |||
@@ -316,12 +316,9 @@ class Lingo2PlayerLogic: | |||
316 | AccessRequirements())) | 316 | AccessRequirements())) |
317 | 317 | ||
318 | for ending in world.static_logic.objects.endings: | 318 | for ending in world.static_logic.objects.endings: |
319 | # Don't ever create a location for White Ending. Don't even make an event for it if it's not the victory | 319 | # Don't create a location for your selected ending, and never create a location for White Ending. |
320 | # condition, since it is necessarily going to be in the postgame. | 320 | if world.options.victory_condition.current_key.removesuffix("_ending").upper() != ending.name\ |
321 | if ending.name == "WHITE": | 321 | and ending.name != "WHITE": |
322 | if self.world.options.victory_condition != VictoryCondition.option_white_ending: | ||
323 | continue | ||
324 | else: | ||
325 | self.locations_by_room.setdefault(ending.room_id, []).append(PlayerLocation(ending.ap_id, | 322 | self.locations_by_room.setdefault(ending.room_id, []).append(PlayerLocation(ending.ap_id, |
326 | AccessRequirements())) | 323 | AccessRequirements())) |
327 | 324 | ||
diff --git a/apworld/regions.py b/apworld/regions.py index 9f44682..64302f6 100644 --- a/apworld/regions.py +++ b/apworld/regions.py | |||
@@ -28,6 +28,9 @@ def create_locations(room, new_region: Region, world: "Lingo2World", regions: di | |||
28 | 28 | ||
29 | for event_name, item_name in world.player_logic.event_loc_item_by_room.get(room.id, {}).items(): | 29 | for event_name, item_name in world.player_logic.event_loc_item_by_room.get(room.id, {}).items(): |
30 | new_location = Lingo2Location(world.player, event_name, None, new_region) | 30 | new_location = Lingo2Location(world.player, event_name, None, new_region) |
31 | if world.for_tracker and item_name == "Victory": | ||
32 | new_location.goal = True | ||
33 | |||
31 | event_item = Lingo2Item(item_name, ItemClassification.progression, None, world.player) | 34 | event_item = Lingo2Item(item_name, ItemClassification.progression, None, world.player) |
32 | new_location.place_locked_item(event_item) | 35 | new_location.place_locked_item(event_item) |
33 | new_region.locations.append(new_location) | 36 | new_region.locations.append(new_location) |
diff --git a/apworld/tracker.py b/apworld/tracker.py index cf2dbe1..7239b65 100644 --- a/apworld/tracker.py +++ b/apworld/tracker.py | |||
@@ -22,6 +22,7 @@ class Tracker: | |||
22 | checked_locations: set[int] | 22 | checked_locations: set[int] |
23 | accessible_locations: set[int] | 23 | accessible_locations: set[int] |
24 | accessible_worldports: set[int] | 24 | accessible_worldports: set[int] |
25 | goal_accessible: bool | ||
25 | 26 | ||
26 | state: CollectionState | 27 | state: CollectionState |
27 | 28 | ||
@@ -31,6 +32,7 @@ class Tracker: | |||
31 | self.checked_locations = set() | 32 | self.checked_locations = set() |
32 | self.accessible_locations = set() | 33 | self.accessible_locations = set() |
33 | self.accessible_worldports = set() | 34 | self.accessible_worldports = set() |
35 | self.goal_accessible = False | ||
34 | 36 | ||
35 | def setup_slot(self, slot_data): | 37 | def setup_slot(self, slot_data): |
36 | Lingo2World.for_tracker = True | 38 | Lingo2World.for_tracker = True |
@@ -94,6 +96,7 @@ class Tracker: | |||
94 | 96 | ||
95 | self.accessible_locations = set() | 97 | self.accessible_locations = set() |
96 | self.accessible_worldports = set() | 98 | self.accessible_worldports = set() |
99 | self.goal_accessible = False | ||
97 | 100 | ||
98 | for region in self.state.reachable_regions[PLAYER_NUM]: | 101 | for region in self.state.reachable_regions[PLAYER_NUM]: |
99 | for location in region.locations: | 102 | for location in region.locations: |
@@ -104,3 +107,6 @@ class Tracker: | |||
104 | elif hasattr(location, "port_id"): | 107 | elif hasattr(location, "port_id"): |
105 | if location.port_id not in self.manager.worldports: | 108 | if location.port_id not in self.manager.worldports: |
106 | self.accessible_worldports.add(location.port_id) | 109 | self.accessible_worldports.add(location.port_id) |
110 | elif hasattr(location, "goal") and location.goal: | ||
111 | if not self.manager.goaled: | ||
112 | self.goal_accessible = True | ||
diff --git a/data/maps/daedalus/doors.txtpb b/data/maps/daedalus/doors.txtpb index 95a3537..6097e57 100644 --- a/data/maps/daedalus/doors.txtpb +++ b/data/maps/daedalus/doors.txtpb | |||
@@ -1579,6 +1579,7 @@ doors { | |||
1579 | panels { room: "Salt Room" name: "SEASONING" } | 1579 | panels { room: "Salt Room" name: "SEASONING" } |
1580 | panels { room: "Pepper Room" name: "SEASONING" } | 1580 | panels { room: "Pepper Room" name: "SEASONING" } |
1581 | location_room: "Pepper Room" | 1581 | location_room: "Pepper Room" |
1582 | location_name: "Seasonings" | ||
1582 | } | 1583 | } |
1583 | doors { | 1584 | doors { |
1584 | name: "Bow Side" | 1585 | name: "Bow Side" |