diff options
-rw-r--r-- | README.md | 9 | ||||
-rw-r--r-- | apworld/client/gamedata.gd | 2 | ||||
-rw-r--r-- | apworld/client/manager.gd | 5 | ||||
-rw-r--r-- | apworld/client/textclient.gd | 94 | ||||
-rw-r--r-- | apworld/context.py | 6 | ||||
-rw-r--r-- | data/maps/the_great/doors.txtpb | 2 | ||||
-rw-r--r-- | data/maps/the_parthenon/rooms/Main Area.txtpb | 4 |
7 files changed, 115 insertions, 7 deletions
diff --git a/README.md b/README.md index 8b1a425..9af22a3 100644 --- a/README.md +++ b/README.md | |||
@@ -132,6 +132,15 @@ before leaving solve mode, as the keyholder will still be considered to be | |||
132 | "focused", even though it has moved. If you have already moved, though, there is | 132 | "focused", even though it has moved. If you have already moved, though, there is |
133 | another way to get your letters back: just use the Key Return in The Entry. | 133 | another way to get your letters back: just use the Key Return in The Entry. |
134 | 134 | ||
135 | ### Why is the tracker telling me to solve a panel that's currently red? | ||
136 | |||
137 | Red usually indicates that a panel cannot be solved because of missing letters. | ||
138 | However, that only applies to the puzzle's main answer. If a puzzle has | ||
139 | alternate answers, you may be expected to use one of those instead of the main | ||
140 | one. As long as you have all of the necessary letters, an alternate answer can | ||
141 | be typed into a red panel even though it does not show you typing. When you | ||
142 | finish typing the answer, the panel will solve as normal. | ||
143 | |||
135 | ## Running from source | 144 | ## Running from source |
136 | 145 | ||
137 | The randomizer is mostly written in Python and GDScript, which do not need to be | 146 | The randomizer is mostly written in Python and GDScript, which do not need to be |
diff --git a/apworld/client/gamedata.gd b/apworld/client/gamedata.gd index 8e909dd..1424721 100644 --- a/apworld/client/gamedata.gd +++ b/apworld/client/gamedata.gd | |||
@@ -175,7 +175,7 @@ func get_door_receivers(door_id): | |||
175 | 175 | ||
176 | func get_worldport_display_name(port_id): | 176 | func get_worldport_display_name(port_id): |
177 | var port = objects.get_ports()[port_id] | 177 | var port = objects.get_ports()[port_id] |
178 | return "%s - %s" % [_get_room_object_map_name(port), port.get_name()] | 178 | return "%s - %s" % [_get_room_object_map_name(port), port.get_display_name()] |
179 | 179 | ||
180 | 180 | ||
181 | func _get_map_object_map_name(obj): | 181 | func _get_map_object_map_name(obj): |
diff --git a/apworld/client/manager.gd b/apworld/client/manager.gd index 3facfba..5b731d2 100644 --- a/apworld/client/manager.gd +++ b/apworld/client/manager.gd | |||
@@ -333,6 +333,7 @@ func _on_checked_worldports_updated(): | |||
333 | var textclient_node = global.get_node("Textclient") | 333 | var textclient_node = global.get_node("Textclient") |
334 | if textclient_node != null: | 334 | if textclient_node != null: |
335 | textclient_node.update_locations() | 335 | textclient_node.update_locations() |
336 | textclient_node.update_worldports() | ||
336 | 337 | ||
337 | 338 | ||
338 | func _client_could_not_connect(message): | 339 | func _client_could_not_connect(message): |
@@ -449,6 +450,10 @@ func _client_connected(slot_data): | |||
449 | 450 | ||
450 | _inverse_item_locks[lock[0]].append([door_id, lock[1]]) | 451 | _inverse_item_locks[lock[0]].append([door_id, lock[1]]) |
451 | 452 | ||
453 | if shuffle_worldports: | ||
454 | var textclient = global.get_node("Textclient") | ||
455 | textclient.setup_worldports() | ||
456 | |||
452 | ap_connected.emit() | 457 | ap_connected.emit() |
453 | 458 | ||
454 | 459 | ||
diff --git a/apworld/client/textclient.gd b/apworld/client/textclient.gd index 1a0ce5c..0c4e675 100644 --- a/apworld/client/textclient.gd +++ b/apworld/client/textclient.gd | |||
@@ -8,10 +8,14 @@ var tracker_label | |||
8 | var is_open = false | 8 | var is_open = false |
9 | 9 | ||
10 | var locations_overlay | 10 | var locations_overlay |
11 | |||
12 | var location_texture | 11 | var location_texture |
13 | var worldport_texture | 12 | var worldport_texture |
14 | 13 | ||
14 | var worldports_tab | ||
15 | var worldports_tree | ||
16 | var port_tree_item_by_map = {} | ||
17 | var port_tree_item_by_map_port = {} | ||
18 | |||
15 | 19 | ||
16 | func _ready(): | 20 | func _ready(): |
17 | process_mode = ProcessMode.PROCESS_MODE_ALWAYS | 21 | process_mode = ProcessMode.PROCESS_MODE_ALWAYS |
@@ -87,6 +91,22 @@ func _ready(): | |||
87 | tracker_label = RichTextLabel.new() | 91 | tracker_label = RichTextLabel.new() |
88 | tracker_margins.add_child(tracker_label) | 92 | tracker_margins.add_child(tracker_label) |
89 | 93 | ||
94 | worldports_tab = MarginContainer.new() | ||
95 | worldports_tab.name = "Worldports" | ||
96 | worldports_tab.add_theme_constant_override("margin_top", 60) | ||
97 | worldports_tab.add_theme_constant_override("margin_left", 60) | ||
98 | worldports_tab.add_theme_constant_override("margin_right", 60) | ||
99 | worldports_tab.add_theme_constant_override("margin_bottom", 60) | ||
100 | tabs.add_child(worldports_tab) | ||
101 | tabs.set_tab_hidden(2, true) | ||
102 | |||
103 | worldports_tree = Tree.new() | ||
104 | worldports_tree.columns = 2 | ||
105 | worldports_tree.hide_root = true | ||
106 | worldports_tree.theme = preload("res://assets/themes/baseUI.tres") | ||
107 | worldports_tree.add_theme_font_size_override("font_size", 24) | ||
108 | worldports_tab.add_child(worldports_tree) | ||
109 | |||
90 | var runtime = global.get_node("Runtime") | 110 | var runtime = global.get_node("Runtime") |
91 | var location_image = Image.new() | 111 | var location_image = Image.new() |
92 | location_image.load_png_from_buffer(runtime.read_path("assets/location.png")) | 112 | location_image.load_png_from_buffer(runtime.read_path("assets/location.png")) |
@@ -199,5 +219,77 @@ func update_locations_visibility(): | |||
199 | locations_overlay.visible = ap.show_locations | 219 | locations_overlay.visible = ap.show_locations |
200 | 220 | ||
201 | 221 | ||
222 | func setup_worldports(): | ||
223 | tabs.set_tab_hidden(2, false) | ||
224 | |||
225 | var root_ti = worldports_tree.create_item(null) | ||
226 | |||
227 | var ports_by_map_id = {} | ||
228 | var display_names_by_map_id = {} | ||
229 | var display_names_by_port_id = {} | ||
230 | |||
231 | var ap = global.get_node("Archipelago") | ||
232 | var gamedata = global.get_node("Gamedata") | ||
233 | for fpid in ap.port_pairings: | ||
234 | var port = gamedata.objects.get_ports()[fpid] | ||
235 | var room = gamedata.objects.get_rooms()[port.get_room_id()] | ||
236 | |||
237 | if not ports_by_map_id.has(room.get_map_id()): | ||
238 | ports_by_map_id[room.get_map_id()] = [] | ||
239 | |||
240 | var map = gamedata.objects.get_maps()[room.get_map_id()] | ||
241 | display_names_by_map_id[map.get_id()] = map.get_display_name() | ||
242 | |||
243 | ports_by_map_id[room.get_map_id()].append(fpid) | ||
244 | display_names_by_port_id[fpid] = port.get_display_name() | ||
245 | |||
246 | var sorted_map_ids = ports_by_map_id.keys().duplicate() | ||
247 | sorted_map_ids.sort_custom( | ||
248 | func(a, b): return display_names_by_map_id[a] < display_names_by_map_id[b] | ||
249 | ) | ||
250 | |||
251 | for map_id in sorted_map_ids: | ||
252 | var map_ti = root_ti.create_child() | ||
253 | map_ti.set_text(0, display_names_by_map_id[map_id]) | ||
254 | map_ti.visible = false | ||
255 | map_ti.collapsed = true | ||
256 | port_tree_item_by_map[map_id] = map_ti | ||
257 | port_tree_item_by_map_port[map_id] = {} | ||
258 | |||
259 | var port_ids = ports_by_map_id[map_id] | ||
260 | port_ids.sort_custom( | ||
261 | func(a, b): return display_names_by_port_id[a] < display_names_by_port_id[b] | ||
262 | ) | ||
263 | |||
264 | for port_id in port_ids: | ||
265 | var port_ti = map_ti.create_child() | ||
266 | port_ti.set_text(0, display_names_by_port_id[port_id]) | ||
267 | port_ti.set_text(1, gamedata.get_worldport_display_name(ap.port_pairings[port_id])) | ||
268 | port_ti.visible = false | ||
269 | port_tree_item_by_map_port[map_id][port_id] = port_ti | ||
270 | |||
271 | update_worldports() | ||
272 | |||
273 | |||
274 | func update_worldports(): | ||
275 | var ap = global.get_node("Archipelago") | ||
276 | |||
277 | for map_id in port_tree_item_by_map_port.keys(): | ||
278 | var map_visible = false | ||
279 | |||
280 | for port_id in port_tree_item_by_map_port[map_id].keys(): | ||
281 | var ti = port_tree_item_by_map_port[map_id][port_id] | ||
282 | ti.visible = ap.client._checked_worldports.has(port_id) | ||
283 | |||
284 | if ti.visible: | ||
285 | map_visible = true | ||
286 | |||
287 | port_tree_item_by_map[map_id].visible = map_visible | ||
288 | |||
289 | |||
202 | func reset(): | 290 | func reset(): |
203 | locations_overlay.clear() | 291 | locations_overlay.clear() |
292 | tabs.set_tab_hidden(2, true) | ||
293 | port_tree_item_by_map.clear() | ||
294 | port_tree_item_by_map_port.clear() | ||
295 | worldports_tree.clear() | ||
diff --git a/apworld/context.py b/apworld/context.py index 4a85868..4b78517 100644 --- a/apworld/context.py +++ b/apworld/context.py | |||
@@ -280,8 +280,9 @@ class Lingo2ClientContext(CommonContext): | |||
280 | 280 | ||
281 | async_start(self.send_msgs(msg_batch), name="default keys") | 281 | async_start(self.send_msgs(msg_batch), name="default keys") |
282 | elif cmd == "RoomUpdate": | 282 | elif cmd == "RoomUpdate": |
283 | self.manager.tracker.set_checked_locations(self.checked_locations) | 283 | if "checked_locations" in args: |
284 | self.manager.game_ctx.send_update_locations(args["checked_locations"]) | 284 | self.manager.tracker.set_checked_locations(self.checked_locations) |
285 | self.manager.game_ctx.send_update_locations(args["checked_locations"]) | ||
285 | elif cmd == "ReceivedItems": | 286 | elif cmd == "ReceivedItems": |
286 | self.manager.tracker.set_collected_items(self.items_received) | 287 | self.manager.tracker.set_collected_items(self.items_received) |
287 | 288 | ||
@@ -495,6 +496,7 @@ async def process_game_cmd(manager: Lingo2Manager, args: dict): | |||
495 | updates = manager.update_worldports(worldports) | 496 | updates = manager.update_worldports(worldports) |
496 | if len(updates) > 0: | 497 | if len(updates) > 0: |
497 | async_start(manager.client_ctx.update_worldports(updates), name="client update worldports") | 498 | async_start(manager.client_ctx.update_worldports(updates), name="client update worldports") |
499 | manager.game_ctx.send_update_worldports(updates) | ||
498 | elif cmd == "Quit": | 500 | elif cmd == "Quit": |
499 | manager.client_ctx.exit_event.set() | 501 | manager.client_ctx.exit_event.set() |
500 | 502 | ||
diff --git a/data/maps/the_great/doors.txtpb b/data/maps/the_great/doors.txtpb index abbbc11..628715f 100644 --- a/data/maps/the_great/doors.txtpb +++ b/data/maps/the_great/doors.txtpb | |||
@@ -60,7 +60,7 @@ doors { | |||
60 | doors { | 60 | doors { |
61 | name: "Control Center Gray Door" | 61 | name: "Control Center Gray Door" |
62 | type: CONTROL_CENTER_COLOR | 62 | type: CONTROL_CENTER_COLOR |
63 | receivers: "Components/Doors/Gates/Gate" | 63 | receivers: "Components/Doors/Gates/Gate/animationListener" |
64 | control_center_color: "gray" | 64 | control_center_color: "gray" |
65 | } | 65 | } |
66 | doors { | 66 | doors { |
diff --git a/data/maps/the_parthenon/rooms/Main Area.txtpb b/data/maps/the_parthenon/rooms/Main Area.txtpb index 79f5e8f..2d989f8 100644 --- a/data/maps/the_parthenon/rooms/Main Area.txtpb +++ b/data/maps/the_parthenon/rooms/Main Area.txtpb | |||
@@ -55,14 +55,14 @@ panels { | |||
55 | } | 55 | } |
56 | ports { | 56 | ports { |
57 | name: "GALLERY" | 57 | name: "GALLERY" |
58 | display_name: "Building Worldport" | 58 | display_name: "Columns Worldport" |
59 | path: "Components/Warps/worldport" | 59 | path: "Components/Warps/worldport" |
60 | destination { x: 0 y: 0 z: 0 } | 60 | destination { x: 0 y: 0 z: 0 } |
61 | rotation: 0 | 61 | rotation: 0 |
62 | } | 62 | } |
63 | ports { | 63 | ports { |
64 | name: "ENTRY" | 64 | name: "ENTRY" |
65 | display_name: "Columns Worldport" | 65 | display_name: "Building Worldport" |
66 | path: "Components/Warps/worldport2" | 66 | path: "Components/Warps/worldport2" |
67 | destination { x: 0 y: 0 z: -21 } | 67 | destination { x: 0 y: 0 z: -21 } |
68 | rotation: 0 | 68 | rotation: 0 |