about summary refs log tree commit diff stats
path: root/apworld/client
diff options
context:
space:
mode:
Diffstat (limited to 'apworld/client')
-rw-r--r--apworld/client/assets/location.pngbin0 -> 311 bytes
-rw-r--r--apworld/client/assets/worldport.pngbin0 -> 219 bytes
-rw-r--r--apworld/client/client.gd23
-rw-r--r--apworld/client/gamedata.gd5
-rw-r--r--apworld/client/manager.gd13
-rw-r--r--apworld/client/textclient.gd127
-rw-r--r--apworld/client/worldport.gd10
7 files changed, 175 insertions, 3 deletions
diff --git a/apworld/client/assets/location.png b/apworld/client/assets/location.png new file mode 100644 index 0000000..5304deb --- /dev/null +++ b/apworld/client/assets/location.png
Binary files differ
diff --git a/apworld/client/assets/worldport.png b/apworld/client/assets/worldport.png new file mode 100644 index 0000000..19dfdc3 --- /dev/null +++ b/apworld/client/assets/worldport.png
Binary files differ
diff --git a/apworld/client/client.gd b/apworld/client/client.gd index 3d4096f..a23e85a 100644 --- a/apworld/client/client.gd +++ b/apworld/client/client.gd
@@ -18,10 +18,12 @@ var _seed = ""
18var _team = 0 18var _team = 0
19var _slot = 0 19var _slot = 0
20var _checked_locations = [] 20var _checked_locations = []
21var _checked_worldports = []
21var _received_indexes = [] 22var _received_indexes = []
22var _received_items = {} 23var _received_items = {}
23var _slot_data = {} 24var _slot_data = {}
24var _accessible_locations = [] 25var _accessible_locations = []
26var _accessible_worldports = []
25 27
26signal could_not_connect 28signal could_not_connect
27signal connect_status 29signal connect_status
@@ -33,6 +35,7 @@ signal item_sent_notification(message)
33signal hint_received(message) 35signal hint_received(message)
34signal accessible_locations_updated 36signal accessible_locations_updated
35signal checked_locations_updated 37signal checked_locations_updated
38signal checked_worldports_updated
36signal keyboard_update_received 39signal keyboard_update_received
37 40
38 41
@@ -55,7 +58,9 @@ func _reset_state():
55 _should_process = false 58 _should_process = false
56 _received_items = {} 59 _received_items = {}
57 _received_indexes = [] 60 _received_indexes = []
61 _checked_worldports = []
58 _accessible_locations = [] 62 _accessible_locations = []
63 _accessible_worldports = []
59 64
60 65
61func disconnect_from_ap(): 66func disconnect_from_ap():
@@ -117,6 +122,14 @@ func _on_web_socket_server_message_received(_peer_id: int, packet: String) -> vo
117 122
118 checked_locations_updated.emit() 123 checked_locations_updated.emit()
119 124
125 elif cmd == "UpdateWorldports":
126 for port_id in message["worldports"]:
127 var lint = int(port_id)
128 if not _checked_worldports.has(lint):
129 _checked_worldports.append(lint)
130
131 checked_worldports_updated.emit()
132
120 elif cmd == "ItemReceived": 133 elif cmd == "ItemReceived":
121 for item in message["items"]: 134 for item in message["items"]:
122 var index = int(item["index"]) 135 var index = int(item["index"])
@@ -152,10 +165,15 @@ func _on_web_socket_server_message_received(_peer_id: int, packet: String) -> vo
152 165
153 elif cmd == "AccessibleLocations": 166 elif cmd == "AccessibleLocations":
154 _accessible_locations.clear() 167 _accessible_locations.clear()
168 _accessible_worldports.clear()
155 169
156 for loc in message["locations"]: 170 for loc in message["locations"]:
157 _accessible_locations.append(int(loc)) 171 _accessible_locations.append(int(loc))
158 172
173 if "worldports" in message:
174 for port_id in message["worldports"]:
175 _accessible_worldports.append(int(port_id))
176
159 accessible_locations_updated.emit() 177 accessible_locations_updated.emit()
160 178
161 elif cmd == "UpdateKeyboard": 179 elif cmd == "UpdateKeyboard":
@@ -226,6 +244,11 @@ func updateKeyboard(updates):
226 sendMessage([{"cmd": "UpdateKeyboard", "keyboard": updates}]) 244 sendMessage([{"cmd": "UpdateKeyboard", "keyboard": updates}])
227 245
228 246
247func checkWorldport(port_id):
248 if not _checked_worldports.has(port_id):
249 sendMessage([{"cmd": "CheckWorldport", "port_id": port_id}])
250
251
229func sendQuit(): 252func sendQuit():
230 sendMessage([{"cmd": "Quit"}]) 253 sendMessage([{"cmd": "Quit"}])
231 254
diff --git a/apworld/client/gamedata.gd b/apworld/client/gamedata.gd index 13ec568..1424721 100644 --- a/apworld/client/gamedata.gd +++ b/apworld/client/gamedata.gd
@@ -173,6 +173,11 @@ func get_door_receivers(door_id):
173 return door.get_receivers() 173 return door.get_receivers()
174 174
175 175
176func get_worldport_display_name(port_id):
177 var port = objects.get_ports()[port_id]
178 return "%s - %s" % [_get_room_object_map_name(port), port.get_display_name()]
179
180
176func _get_map_object_map_name(obj): 181func _get_map_object_map_name(obj):
177 return objects.get_maps()[obj.get_map_id()].get_display_name() 182 return objects.get_maps()[obj.get_map_id()].get_display_name()
178 183
diff --git a/apworld/client/manager.gd b/apworld/client/manager.gd index afa3ebe..5b731d2 100644 --- a/apworld/client/manager.gd +++ b/apworld/client/manager.gd
@@ -109,6 +109,7 @@ func _ready():
109 client.hint_received.connect(_process_hint_received) 109 client.hint_received.connect(_process_hint_received)
110 client.accessible_locations_updated.connect(_on_accessible_locations_updated) 110 client.accessible_locations_updated.connect(_on_accessible_locations_updated)
111 client.checked_locations_updated.connect(_on_checked_locations_updated) 111 client.checked_locations_updated.connect(_on_checked_locations_updated)
112 client.checked_worldports_updated.connect(_on_checked_worldports_updated)
112 113
113 client.could_not_connect.connect(_client_could_not_connect) 114 client.could_not_connect.connect(_client_could_not_connect)
114 client.connect_status.connect(_client_connect_status) 115 client.connect_status.connect(_client_connect_status)
@@ -195,6 +196,7 @@ func _process_item(item, amount):
195 if gamedata.get_door_map_name(lock[0]) != global.map: 196 if gamedata.get_door_map_name(lock[0]) != global.map:
196 continue 197 continue
197 198
199 # TODO: fix doors opening from door groups
198 var receivers = gamedata.get_door_receivers(lock[0]) 200 var receivers = gamedata.get_door_receivers(lock[0])
199 var scene = get_tree().get_root().get_node_or_null("scene") 201 var scene = get_tree().get_root().get_node_or_null("scene")
200 if scene != null: 202 if scene != null:
@@ -327,6 +329,13 @@ func _on_checked_locations_updated():
327 textclient_node.update_locations() 329 textclient_node.update_locations()
328 330
329 331
332func _on_checked_worldports_updated():
333 var textclient_node = global.get_node("Textclient")
334 if textclient_node != null:
335 textclient_node.update_locations()
336 textclient_node.update_worldports()
337
338
330func _client_could_not_connect(message): 339func _client_could_not_connect(message):
331 could_not_connect.emit(message) 340 could_not_connect.emit(message)
332 341
@@ -441,6 +450,10 @@ func _client_connected(slot_data):
441 450
442 _inverse_item_locks[lock[0]].append([door_id, lock[1]]) 451 _inverse_item_locks[lock[0]].append([door_id, lock[1]])
443 452
453 if shuffle_worldports:
454 var textclient = global.get_node("Textclient")
455 textclient.setup_worldports()
456
444 ap_connected.emit() 457 ap_connected.emit()
445 458
446 459
diff --git a/apworld/client/textclient.gd b/apworld/client/textclient.gd index 1b36c29..0c4e675 100644 --- a/apworld/client/textclient.gd +++ b/apworld/client/textclient.gd
@@ -8,6 +8,13 @@ var tracker_label
8var is_open = false 8var is_open = false
9 9
10var locations_overlay 10var locations_overlay
11var location_texture
12var worldport_texture
13
14var worldports_tab
15var worldports_tree
16var port_tree_item_by_map = {}
17var port_tree_item_by_map_port = {}
11 18
12 19
13func _ready(): 20func _ready():
@@ -20,9 +27,10 @@ func _ready():
20 locations_overlay.offset_bottom = 720 27 locations_overlay.offset_bottom = 720
21 locations_overlay.offset_left = 20 28 locations_overlay.offset_left = 20
22 locations_overlay.anchor_right = 1.0 29 locations_overlay.anchor_right = 1.0
23 locations_overlay.offset_right = -20 30 locations_overlay.offset_right = -10
24 locations_overlay.scroll_active = false 31 locations_overlay.scroll_active = false
25 locations_overlay.mouse_filter = Control.MOUSE_FILTER_IGNORE 32 locations_overlay.mouse_filter = Control.MOUSE_FILTER_IGNORE
33 locations_overlay.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
26 add_child(locations_overlay) 34 add_child(locations_overlay)
27 update_locations_visibility() 35 update_locations_visibility()
28 36
@@ -83,6 +91,31 @@ func _ready():
83 tracker_label = RichTextLabel.new() 91 tracker_label = RichTextLabel.new()
84 tracker_margins.add_child(tracker_label) 92 tracker_margins.add_child(tracker_label)
85 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
110 var runtime = global.get_node("Runtime")
111 var location_image = Image.new()
112 location_image.load_png_from_buffer(runtime.read_path("assets/location.png"))
113 location_texture = ImageTexture.create_from_image(location_image)
114
115 var worldport_image = Image.new()
116 worldport_image.load_png_from_buffer(runtime.read_path("assets/worldport.png"))
117 worldport_texture = ImageTexture.create_from_image(worldport_image)
118
86 119
87func _input(event): 120func _input(event):
88 if global.loaded and event is InputEventKey and event.pressed: 121 if global.loaded and event is InputEventKey and event.pressed:
@@ -144,11 +177,22 @@ func update_locations():
144 locations_overlay.push_outline_color(Color(0, 0, 0, 1)) 177 locations_overlay.push_outline_color(Color(0, 0, 0, 1))
145 locations_overlay.push_outline_size(2) 178 locations_overlay.push_outline_size(2)
146 179
180 const kLocation = 0
181 const kWorldport = 1
182
147 var location_names = [] 183 var location_names = []
184 var type_by_name = {}
148 for location_id in ap.client._accessible_locations: 185 for location_id in ap.client._accessible_locations:
149 if not ap.client._checked_locations.has(location_id): 186 if not ap.client._checked_locations.has(location_id):
150 var location_name = gamedata.location_name_by_id.get(location_id, "(Unknown)") 187 var location_name = gamedata.location_name_by_id.get(location_id, "(Unknown)")
151 location_names.append(location_name) 188 location_names.append(location_name)
189 type_by_name[location_name] = kLocation
190
191 for port_id in ap.client._accessible_worldports:
192 if not ap.client._checked_worldports.has(port_id):
193 var port_name = gamedata.get_worldport_display_name(port_id)
194 location_names.append(port_name)
195 type_by_name[port_name] = kWorldport
152 196
153 location_names.sort() 197 location_names.sort()
154 198
@@ -156,7 +200,14 @@ func update_locations():
156 for location_name in location_names: 200 for location_name in location_names:
157 tracker_label.append_text("[p]%s[/p]" % location_name) 201 tracker_label.append_text("[p]%s[/p]" % location_name)
158 if count < 18: 202 if count < 18:
159 locations_overlay.append_text("[p align=right]%s[/p]" % location_name) 203 locations_overlay.push_paragraph(HORIZONTAL_ALIGNMENT_RIGHT)
204 locations_overlay.append_text(location_name)
205 locations_overlay.append_text(" ")
206 if type_by_name[location_name] == kLocation:
207 locations_overlay.add_image(location_texture)
208 elif type_by_name[location_name] == kWorldport:
209 locations_overlay.add_image(worldport_texture)
210 locations_overlay.pop()
160 count += 1 211 count += 1
161 212
162 if count > 18: 213 if count > 18:
@@ -168,5 +219,77 @@ func update_locations_visibility():
168 locations_overlay.visible = ap.show_locations 219 locations_overlay.visible = ap.show_locations
169 220
170 221
222func 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
274func 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
171func reset(): 290func reset():
172 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/client/worldport.gd b/apworld/client/worldport.gd index cdca248..ed9891e 100644 --- a/apworld/client/worldport.gd +++ b/apworld/client/worldport.gd
@@ -3,6 +3,8 @@ extends "res://scripts/nodes/worldport.gd"
3var absolute_rotation = false 3var absolute_rotation = false
4var target_rotation = 0 4var target_rotation = 0
5 5
6var port_id = null
7
6 8
7func _ready(): 9func _ready():
8 var node_path = String( 10 var node_path = String(
@@ -13,7 +15,7 @@ func _ready():
13 15
14 if ap.shuffle_worldports: 16 if ap.shuffle_worldports:
15 var gamedata = global.get_node("Gamedata") 17 var gamedata = global.get_node("Gamedata")
16 var port_id = gamedata.get_port_for_map_node_path(global.map, node_path) 18 port_id = gamedata.get_port_for_map_node_path(global.map, node_path)
17 if port_id != null: 19 if port_id != null:
18 if port_id in ap.port_pairings: 20 if port_id in ap.port_pairings:
19 var target_port = gamedata.objects.get_ports()[ap.port_pairings[port_id]] 21 var target_port = gamedata.objects.get_ports()[ap.port_pairings[port_id]]
@@ -29,6 +31,8 @@ func _ready():
29 sets_entry_point = true 31 sets_entry_point = true
30 invisible = false 32 invisible = false
31 fades = true 33 fades = true
34 else:
35 port_id = null
32 36
33 if global.map == "icarus" and exit == "daedalus": 37 if global.map == "icarus" and exit == "daedalus":
34 if not ap.daedalus_roof_access: 38 if not ap.daedalus_roof_access:
@@ -39,6 +43,10 @@ func _ready():
39 43
40func bodyEntered(body): 44func bodyEntered(body):
41 if body.is_in_group("player"): 45 if body.is_in_group("player"):
46 if port_id != null:
47 var ap = global.get_node("Archipelago")
48 ap.client.checkWorldport(port_id)
49
42 if absolute_rotation: 50 if absolute_rotation:
43 entry_rotate.y = target_rotation - body.rotation_degrees.y 51 entry_rotate.y = target_rotation - body.rotation_degrees.y
44 52