about summary refs log tree commit diff stats
path: root/apworld/client/textclient.gd
diff options
context:
space:
mode:
Diffstat (limited to 'apworld/client/textclient.gd')
-rw-r--r--apworld/client/textclient.gd258
1 files changed, 228 insertions, 30 deletions
diff --git a/apworld/client/textclient.gd b/apworld/client/textclient.gd index 530eddb..ce28a3a 100644 --- a/apworld/client/textclient.gd +++ b/apworld/client/textclient.gd
@@ -4,7 +4,6 @@ var tabs
4var panel 4var panel
5var label 5var label
6var entry 6var entry
7var tracker_label
8var is_open = false 7var is_open = false
9 8
10var locations_overlay 9var locations_overlay
@@ -12,11 +11,23 @@ var location_texture
12var worldport_texture 11var worldport_texture
13var goal_texture 12var goal_texture
14 13
14var tracker_tree
15var tracker_loc_tree_item_by_id = {}
16var tracker_port_tree_item_by_id = {}
17var tracker_goal_tree_item = null
18var tracker_object_by_index = {}
19var tracker_object_by_ignored_index = {}
20var tracker_ignored_group = null
21
15var worldports_tab 22var worldports_tab
16var worldports_tree 23var worldports_tree
17var port_tree_item_by_map = {} 24var port_tree_item_by_map = {}
18var port_tree_item_by_map_port = {} 25var port_tree_item_by_map_port = {}
19 26
27const kLocation = 0
28const kWorldport = 1
29const kGoal = 2
30
20 31
21func _ready(): 32func _ready():
22 process_mode = ProcessMode.PROCESS_MODE_ALWAYS 33 process_mode = ProcessMode.PROCESS_MODE_ALWAYS
@@ -61,7 +72,7 @@ func _ready():
61 label.size_flags_horizontal = Control.SIZE_EXPAND_FILL 72 label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
62 label.size_flags_vertical = Control.SIZE_EXPAND_FILL 73 label.size_flags_vertical = Control.SIZE_EXPAND_FILL
63 label.push_font(preload("res://assets/fonts/Lingo2.ttf")) 74 label.push_font(preload("res://assets/fonts/Lingo2.ttf"))
64 label.push_font_size(36) 75 label.push_font_size(30)
65 76
66 var entry_style = StyleBoxFlat.new() 77 var entry_style = StyleBoxFlat.new()
67 entry_style.bg_color = Color(0.9, 0.9, 0.9, 1) 78 entry_style.bg_color = Color(0.9, 0.9, 0.9, 1)
@@ -89,8 +100,20 @@ func _ready():
89 tracker_margins.add_theme_constant_override("margin_bottom", 60) 100 tracker_margins.add_theme_constant_override("margin_bottom", 60)
90 tabs.add_child(tracker_margins) 101 tabs.add_child(tracker_margins)
91 102
92 tracker_label = RichTextLabel.new() 103 tracker_tree = Tree.new()
93 tracker_margins.add_child(tracker_label) 104 tracker_tree.columns = 4
105 tracker_tree.hide_root = true
106 tracker_tree.add_theme_font_size_override("font_size", 24)
107 tracker_tree.add_theme_color_override("font_color", Color(0.8, 0.8, 0.8, 1))
108 tracker_tree.add_theme_constant_override("v_separation", 1)
109 tracker_tree.item_edited.connect(_on_tracker_button_clicked)
110 tracker_tree.set_column_expand(0, false)
111 tracker_tree.set_column_expand(1, true)
112 tracker_tree.set_column_expand(2, false)
113 tracker_tree.set_column_expand(3, false)
114 tracker_tree.set_column_custom_minimum_width(2, 200)
115 tracker_tree.set_column_custom_minimum_width(3, 200)
116 tracker_margins.add_child(tracker_tree)
94 117
95 worldports_tab = MarginContainer.new() 118 worldports_tab = MarginContainer.new()
96 worldports_tab.name = "Worldports" 119 worldports_tab.name = "Worldports"
@@ -167,14 +190,10 @@ func text_entered(text):
167 ap.client.say(cmd) 190 ap.client.say(cmd)
168 191
169 192
170func update_locations(): 193func update_locations(reset_locations = true):
171 var ap = global.get_node("Archipelago") 194 var ap = global.get_node("Archipelago")
172 var gamedata = global.get_node("Gamedata") 195 var gamedata = global.get_node("Gamedata")
173 196
174 tracker_label.clear()
175 tracker_label.push_font(preload("res://assets/fonts/Lingo2.ttf"))
176 tracker_label.push_font_size(24)
177
178 locations_overlay.clear() 197 locations_overlay.clear()
179 locations_overlay.push_font(preload("res://assets/fonts/Lingo2.ttf")) 198 locations_overlay.push_font(preload("res://assets/fonts/Lingo2.ttf"))
180 locations_overlay.push_font_size(24) 199 locations_overlay.push_font_size(24)
@@ -182,58 +201,226 @@ func update_locations():
182 locations_overlay.push_outline_color(Color(0, 0, 0, 1)) 201 locations_overlay.push_outline_color(Color(0, 0, 0, 1))
183 locations_overlay.push_outline_size(2) 202 locations_overlay.push_outline_size(2)
184 203
185 const kLocation = 0 204 var locations = []
186 const kWorldport = 1
187 const kGoal = 2
188
189 var location_names = []
190 var type_by_name = {}
191 for location_id in ap.client._accessible_locations: 205 for location_id in ap.client._accessible_locations:
192 if not ap.client._checked_locations.has(location_id): 206 if not ap.client._checked_locations.has(location_id):
193 var location_name = gamedata.location_name_by_id.get(location_id, "(Unknown)") 207 var location_name = gamedata.location_name_by_id.get(location_id, "(Unknown)")
194 location_names.append(location_name) 208 (
195 type_by_name[location_name] = kLocation 209 locations
210 . append(
211 {
212 "name": location_name,
213 "type": kLocation,
214 "id": location_id,
215 "ignored": ap._ignored_locations.has(location_id),
216 "hint": ap.client._hinted_locations.has(location_id),
217 }
218 )
219 )
196 220
197 for port_id in ap.client._accessible_worldports: 221 for port_id in ap.client._accessible_worldports:
198 if not ap.client._checked_worldports.has(port_id): 222 if not ap.client._checked_worldports.has(port_id):
199 var port_name = gamedata.get_worldport_display_name(port_id) 223 var port_name = gamedata.get_worldport_display_name(port_id)
200 location_names.append(port_name) 224 (
201 type_by_name[port_name] = kWorldport 225 locations
202 226 . append(
203 location_names.sort() 227 {
228 "name": port_name,
229 "type": kWorldport,
230 "id": port_id,
231 "ignored": false,
232 "hint": false,
233 }
234 )
235 )
236
237 locations.sort_custom(_cmp_tracker_objects)
204 238
205 if ap.client._goal_accessible: 239 if ap.client._goal_accessible:
206 var location_name = gamedata.ending_display_name_by_name[ap.kEndingNameByVictoryValue[ 240 var location_name = gamedata.ending_display_name_by_name[ap.kEndingNameByVictoryValue[
207 ap.victory_condition 241 ap.victory_condition
208 ]] 242 ]]
209 location_names.push_front(location_name) 243 (
210 type_by_name[location_name] = kGoal 244 locations
245 . push_front(
246 {
247 "name": location_name,
248 "type": kGoal,
249 "ignored": false,
250 "hint": false,
251 }
252 )
253 )
211 254
212 var count = 0 255 var count = 0
213 for location_name in location_names: 256 for location in locations:
214 tracker_label.append_text("[p]%s[/p]" % location_name) 257 if count < 18 and not location["ignored"]:
215 if count < 18:
216 locations_overlay.push_paragraph(HORIZONTAL_ALIGNMENT_RIGHT) 258 locations_overlay.push_paragraph(HORIZONTAL_ALIGNMENT_RIGHT)
217 locations_overlay.append_text(location_name) 259 if location["hint"]:
260 locations_overlay.push_color(Color("#fafad2"))
261 locations_overlay.append_text(location["name"])
218 locations_overlay.append_text(" ") 262 locations_overlay.append_text(" ")
219 if type_by_name[location_name] == kLocation: 263 if location["type"] == kLocation:
220 locations_overlay.add_image(location_texture) 264 locations_overlay.add_image(location_texture)
221 elif type_by_name[location_name] == kWorldport: 265 elif location["type"] == kWorldport:
222 locations_overlay.add_image(worldport_texture) 266 locations_overlay.add_image(worldport_texture)
223 elif type_by_name[location_name] == kGoal: 267 elif location["type"] == kGoal:
224 locations_overlay.add_image(goal_texture) 268 locations_overlay.add_image(goal_texture)
269 if location["hint"]:
270 locations_overlay.pop()
225 locations_overlay.pop() 271 locations_overlay.pop()
226 count += 1 272 count += 1
227 273
228 if count > 18: 274 if count > 18:
229 locations_overlay.append_text("[p align=right][lb]...[rb][/p]") 275 locations_overlay.append_text("[p align=right][lb]...[rb][/p]")
230 276
277 if reset_locations:
278 reset_tracker_tab()
279
280 var root_ti = tracker_tree.create_item(null)
281
282 for location in locations:
283 var loc_row
284
285 if location["ignored"]:
286 if tracker_ignored_group == null:
287 tracker_ignored_group = root_ti.create_child()
288 tracker_ignored_group.set_text(1, "Ignored Locations")
289 tracker_ignored_group.set_selectable(0, false)
290 tracker_ignored_group.set_selectable(1, false)
291 tracker_ignored_group.set_selectable(2, false)
292 tracker_ignored_group.set_selectable(3, false)
293
294 loc_row = tracker_ignored_group.create_child()
295 else:
296 loc_row = root_ti.create_child()
297
298 loc_row.set_cell_mode(0, TreeItem.CELL_MODE_ICON)
299 loc_row.set_selectable(0, false)
300 loc_row.set_text(1, location["name"])
301 loc_row.set_selectable(1, false)
302 if location["hint"]:
303 loc_row.set_custom_color(1, Color("#fafad2"))
304 loc_row.set_cell_mode(2, TreeItem.CELL_MODE_CUSTOM)
305 loc_row.set_text(2, "Show Path")
306 loc_row.set_custom_as_button(2, true)
307 loc_row.set_editable(2, true)
308 loc_row.set_selectable(2, false)
309 loc_row.set_text_alignment(2, HORIZONTAL_ALIGNMENT_CENTER)
310 loc_row.set_selectable(3, false)
311 if location["type"] == kLocation:
312 loc_row.set_cell_mode(3, TreeItem.CELL_MODE_CUSTOM)
313 if location["ignored"]:
314 loc_row.set_text(3, "Unignore")
315 else:
316 loc_row.set_text(3, "Ignore")
317 loc_row.set_custom_as_button(3, true)
318 loc_row.set_editable(3, true)
319 loc_row.set_text_alignment(3, HORIZONTAL_ALIGNMENT_CENTER)
320
321 if location["type"] == kLocation:
322 loc_row.set_icon(0, location_texture)
323 tracker_loc_tree_item_by_id[location["id"]] = loc_row
324 elif location["type"] == kWorldport:
325 loc_row.set_icon(0, worldport_texture)
326 tracker_port_tree_item_by_id[location["id"]] = loc_row
327 elif location["type"] == kGoal:
328 loc_row.set_icon(0, goal_texture)
329 tracker_goal_tree_item = loc_row
330
331 if location["ignored"]:
332 tracker_object_by_ignored_index[loc_row.get_index()] = location
333 else:
334 tracker_object_by_index[loc_row.get_index()] = location
335 else:
336 for loc_row in tracker_tree.get_root().get_children():
337 loc_row.visible = false
338
339 for location_id in tracker_loc_tree_item_by_id.keys():
340 if (
341 ap.client._accessible_locations.has(location_id)
342 and not ap.client._checked_locations.has(location_id)
343 ):
344 tracker_loc_tree_item_by_id[location_id].visible = true
345
346 for port_id in tracker_port_tree_item_by_id.keys():
347 if (
348 ap.client._accessible_worldports.has(port_id)
349 and not ap.client._checked_worldports.has(port_id)
350 ):
351 tracker_port_tree_item_by_id[port_id].visible = true
352
353 if tracker_goal_tree_item != null and ap.client._goal_accessible:
354 tracker_goal_tree_item.visible = true
355
356 if tracker_ignored_group != null:
357 tracker_ignored_group.visible = true
358
359
360func _cmp_tracker_objects(a, b) -> bool:
361 if a["ignored"] != b["ignored"]:
362 return !a["ignored"]
363 elif a["hint"] != b["hint"]:
364 return a["hint"]
365 else:
366 return a["name"] < b["name"]
367
231 368
232func update_locations_visibility(): 369func update_locations_visibility():
233 var ap = global.get_node("Archipelago") 370 var ap = global.get_node("Archipelago")
234 locations_overlay.visible = ap.show_locations 371 locations_overlay.visible = ap.show_locations
235 372
236 373
374func _on_tracker_button_clicked():
375 var ap = global.get_node("Archipelago")
376
377 var edited_item = tracker_tree.get_edited()
378 var edited_index = edited_item.get_index()
379
380 if edited_item.get_parent() == tracker_tree.get_root():
381 if tracker_object_by_index.has(edited_index):
382 var tracker_object = tracker_object_by_index[edited_index]
383 if tracker_tree.get_edited_column() == 2:
384 var type_str = ""
385 if tracker_object["type"] == kLocation:
386 type_str = "location"
387 elif tracker_object["type"] == kWorldport:
388 type_str = "worldport"
389 elif tracker_object["type"] == kGoal:
390 type_str = "goal"
391 ap.client.getLogicalPath(type_str, tracker_object.get("id", null))
392 elif tracker_tree.get_edited_column() == 3:
393 ap.toggle_ignored_location(tracker_object["id"])
394 elif edited_item.get_parent() == tracker_ignored_group:
395 # This is the ignored locations group.
396 if (
397 tracker_object_by_ignored_index.has(edited_index)
398 and tracker_tree.get_edited_column() == 3
399 ):
400 var tracker_object = tracker_object_by_ignored_index[edited_index]
401 ap.toggle_ignored_location(tracker_object["id"])
402
403
404func display_logical_path(object_type, object_id, paths):
405 var ap = global.get_node("Archipelago")
406 var gamedata = global.get_node("Gamedata")
407
408 var location_name = "(Unknown)"
409 if object_type == "location" and object_id != null:
410 location_name = gamedata.location_name_by_id.get(object_id, "(Unknown)")
411 elif object_type == "worldport" and object_id != null:
412 location_name = gamedata.get_worldport_display_name(object_id)
413 elif object_type == "goal":
414 location_name = gamedata.ending_display_name_by_name[ap.kEndingNameByVictoryValue[
415 ap.victory_condition
416 ]]
417
418 label.append_text("[p]Path to %s:[/p]" % location_name)
419 label.append_text("[ol]" + "\n".join(paths) + "[/ol]")
420
421 panel.visible = true
422
423
237func setup_worldports(): 424func setup_worldports():
238 tabs.set_tab_hidden(2, false) 425 tabs.set_tab_hidden(2, false)
239 426
@@ -308,3 +495,14 @@ func reset():
308 port_tree_item_by_map.clear() 495 port_tree_item_by_map.clear()
309 port_tree_item_by_map_port.clear() 496 port_tree_item_by_map_port.clear()
310 worldports_tree.clear() 497 worldports_tree.clear()
498 reset_tracker_tab()
499
500
501func reset_tracker_tab():
502 tracker_loc_tree_item_by_id.clear()
503 tracker_port_tree_item_by_id.clear()
504 tracker_goal_tree_item = null
505 tracker_object_by_index.clear()
506 tracker_object_by_ignored_index.clear()
507 tracker_ignored_group = null
508 tracker_tree.clear()