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/client.gd25
-rw-r--r--apworld/client/gamedata.gd120
-rw-r--r--apworld/client/manager.gd14
-rw-r--r--apworld/client/textclient.gd86
4 files changed, 217 insertions, 28 deletions
diff --git a/apworld/client/client.gd b/apworld/client/client.gd index 67edf29..05b2b6c 100644 --- a/apworld/client/client.gd +++ b/apworld/client/client.gd
@@ -21,6 +21,7 @@ var _checked_locations = []
21var _received_indexes = [] 21var _received_indexes = []
22var _received_items = {} 22var _received_items = {}
23var _slot_data = {} 23var _slot_data = {}
24var _accessible_locations = []
24 25
25signal could_not_connect 26signal could_not_connect
26signal connect_status 27signal connect_status
@@ -30,6 +31,8 @@ signal location_scout_received(location_id, item_name, player_name, flags, for_s
30signal text_message_received(message) 31signal text_message_received(message)
31signal item_sent_notification(message) 32signal item_sent_notification(message)
32signal hint_received(message) 33signal hint_received(message)
34signal accessible_locations_updated
35signal checked_locations_updated
33 36
34 37
35func _init(): 38func _init():
@@ -51,6 +54,7 @@ func _reset_state():
51 _should_process = false 54 _should_process = false
52 _received_items = {} 55 _received_items = {}
53 _received_indexes = [] 56 _received_indexes = []
57 _accessible_locations = []
54 58
55 59
56func disconnect_from_ap(): 60func disconnect_from_ap():
@@ -92,15 +96,26 @@ func _on_web_socket_server_message_received(_peer_id: int, packet: String) -> vo
92 _gen_version = message["generator_version"] 96 _gen_version = message["generator_version"]
93 _team = message["team"] 97 _team = message["team"]
94 _slot = message["slot"] 98 _slot = message["slot"]
95 _checked_locations = message["checked_locations"]
96 _slot_data = message["slot_data"] 99 _slot_data = message["slot_data"]
97 100
101 _checked_locations = []
102 for location in message["checked_locations"]:
103 _checked_locations.append(int(message["checked_locations"]))
104
98 client_connected.emit(_slot_data) 105 client_connected.emit(_slot_data)
99 106
100 elif cmd == "ConnectionRefused": 107 elif cmd == "ConnectionRefused":
101 could_not_connect.emit(message["text"]) 108 could_not_connect.emit(message["text"])
102 global._print("Connection to AP refused") 109 global._print("Connection to AP refused")
103 110
111 elif cmd == "UpdateLocations":
112 for location in message["locations"]:
113 var lint = int(location)
114 if not _checked_locations.has(lint):
115 _checked_locations.append(lint)
116
117 checked_locations_updated.emit()
118
104 elif cmd == "ItemReceived": 119 elif cmd == "ItemReceived":
105 for item in message["items"]: 120 for item in message["items"]:
106 var index = int(item["index"]) 121 var index = int(item["index"])
@@ -134,6 +149,14 @@ func _on_web_socket_server_message_received(_peer_id: int, packet: String) -> vo
134 int(loc["for_self"]) 149 int(loc["for_self"])
135 ) 150 )
136 151
152 elif cmd == "AccessibleLocations":
153 _accessible_locations.clear()
154
155 for loc in message["locations"]:
156 _accessible_locations.append(int(loc))
157
158 accessible_locations_updated.emit()
159
137 160
138func connectToServer(server, un, pw): 161func connectToServer(server, un, pw):
139 sendMessage([{"cmd": "Connect", "server": server, "player": un, "password": pw}]) 162 sendMessage([{"cmd": "Connect", "server": server, "player": un, "password": pw}])
diff --git a/apworld/client/gamedata.gd b/apworld/client/gamedata.gd index 9eeec3b..39e0583 100644 --- a/apworld/client/gamedata.gd +++ b/apworld/client/gamedata.gd
@@ -13,6 +13,7 @@ var progressive_id_by_ap_id = {}
13var letter_id_by_ap_id = {} 13var letter_id_by_ap_id = {}
14var symbol_item_ids = [] 14var symbol_item_ids = []
15var anti_trap_ids = {} 15var anti_trap_ids = {}
16var location_name_by_id = {}
16 17
17var kSYMBOL_ITEMS 18var kSYMBOL_ITEMS
18 19
@@ -70,6 +71,7 @@ func load(data_bytes):
70 71
71 if door.has_ap_id(): 72 if door.has_ap_id():
72 door_id_by_ap_id[door.get_ap_id()] = door.get_id() 73 door_id_by_ap_id[door.get_ap_id()] = door.get_id()
74 location_name_by_id[door.get_ap_id()] = _get_door_location_name(door)
73 75
74 for painting in objects.get_paintings(): 76 for painting in objects.get_paintings():
75 var room = objects.get_rooms()[painting.get_room_id()] 77 var room = objects.get_rooms()[painting.get_room_id()]
@@ -95,6 +97,17 @@ func load(data_bytes):
95 97
96 for letter in objects.get_letters(): 98 for letter in objects.get_letters():
97 letter_id_by_ap_id[letter.get_ap_id()] = letter.get_id() 99 letter_id_by_ap_id[letter.get_ap_id()] = letter.get_id()
100 location_name_by_id[letter.get_ap_id()] = _get_letter_location_name(letter)
101
102 for mastery in objects.get_masteries():
103 location_name_by_id[mastery.get_ap_id()] = _get_mastery_location_name(mastery)
104
105 for ending in objects.get_endings():
106 location_name_by_id[ending.get_ap_id()] = _get_ending_location_name(ending)
107
108 for keyholder in objects.get_keyholders():
109 if keyholder.has_key():
110 location_name_by_id[keyholder.get_ap_id()] = _get_keyholder_location_name(keyholder)
98 111
99 for panel in objects.get_panels(): 112 for panel in objects.get_panels():
100 var room = objects.get_rooms()[panel.get_room_id()] 113 var room = objects.get_rooms()[panel.get_room_id()]
@@ -153,7 +166,106 @@ func get_door_receivers(door_id):
153 return door.get_receivers() 166 return door.get_receivers()
154 167
155 168
156func get_door_map_name(door_id): 169func _get_map_object_map_name(obj):
157 var door = objects.get_doors()[door_id] 170 return objects.get_maps()[obj.get_map_id()].get_display_name()
158 var map = objects.get_maps()[door.get_map_id()] 171
159 return map.get_name() 172
173func _get_room_object_map_name(obj):
174 return _get_map_object_map_name(objects.get_rooms()[obj.get_room_id()])
175
176
177func _get_room_object_location_prefix(obj):
178 var room = objects.get_rooms()[obj.get_room_id()]
179 var game_map = objects.get_maps()[room.get_map_id()]
180
181 if room.has_panel_display_name():
182 return "%s (%s)" % [game_map.get_display_name(), room.get_panel_display_name()]
183 else:
184 return game_map.get_display_name()
185
186
187func _get_door_location_name(door):
188 var map_part = _get_room_object_location_prefix(door)
189
190 if door.has_location_name():
191 return "%s - %s" % [map_part, door.get_location_name()]
192
193 var generated_location_name = _get_generated_door_location_name(door)
194 if generated_location_name != null:
195 return generated_location_name
196
197 return "%s - %s" % [map_part, door.get_name()]
198
199
200func _get_generated_door_location_name(door):
201 if door.get_type() != SCRIPT_proto.DoorType.STANDARD:
202 return null
203
204 if door.get_keyholders().size() > 0 or door.get_endings().size() > 0 or door.has_complete_at():
205 return null
206
207 if door.get_panels().size() > 4:
208 return null
209
210 var map_areas = []
211 for panel_id in door.get_panels():
212 var panel = objects.get_panels()[panel_id.get_panel()]
213 var panel_room = objects.get_rooms()[panel.get_room_id()]
214 # It's okay if panel_display_name is not present because then it's coalesced with other unnamed areas.
215 if not map_areas.has(panel_room.get_panel_display_name()):
216 map_areas.append(panel_room.get_panel_display_name())
217
218 if map_areas.size() > 1:
219 return null
220
221 var game_map = objects.get_maps()[door.get_map_id()]
222 var map_area = map_areas[0]
223 var map_part
224 if map_area == "":
225 map_part = game_map.get_display_name()
226 else:
227 map_part = "%s (%s)" % [game_map.get_display_name(), map_area]
228
229 var panel_names = []
230 for panel_id in door.get_panels():
231 var panel_data = objects.get_panels()[panel_id.get_panel()]
232 var panel_name
233 if panel_data.has_display_name():
234 panel_name = panel_data.get_display_name()
235 else:
236 panel_name = panel_data.get_name()
237
238 var location_part
239 if panel_id.has_answer():
240 location_part = "%s/%s" % [panel_name, panel_id.get_answer().to_upper()]
241 else:
242 location_part = panel_name
243
244 panel_names.append(location_part)
245
246 panel_names.sort()
247
248 return map_part + " - " + ", ".join(panel_names)
249
250
251func _get_letter_location_name(letter):
252 var letter_level = 2 if letter.get_level2() else 1
253 var letter_name = "%s%d" % [letter.get_key().to_upper(), letter_level]
254 return "%s - %s" % [_get_room_object_map_name(letter), letter_name]
255
256
257func _get_mastery_location_name(mastery):
258 return "%s - Mastery" % _get_room_object_map_name(mastery)
259
260
261func _get_ending_location_name(ending):
262 return (
263 "%s - %s Ending" % [_get_room_object_map_name(ending), ending.get_name().to_pascal_case()]
264 )
265
266
267func _get_keyholder_location_name(keyholder):
268 return (
269 "%s - %s Keyholder"
270 % [_get_room_object_location_prefix(keyholder), keyholder.get_key().to_upper()]
271 )
diff --git a/apworld/client/manager.gd b/apworld/client/manager.gd index 955d470..7f4a8a6 100644 --- a/apworld/client/manager.gd +++ b/apworld/client/manager.gd
@@ -99,6 +99,8 @@ func _ready():
99 client.text_message_received.connect(_process_text_message) 99 client.text_message_received.connect(_process_text_message)
100 client.item_sent_notification.connect(_process_item_sent_notification) 100 client.item_sent_notification.connect(_process_item_sent_notification)
101 client.hint_received.connect(_process_hint_received) 101 client.hint_received.connect(_process_hint_received)
102 client.accessible_locations_updated.connect(_on_accessible_locations_updated)
103 client.checked_locations_updated.connect(_on_checked_locations_updated)
102 104
103 client.could_not_connect.connect(_client_could_not_connect) 105 client.could_not_connect.connect(_client_could_not_connect)
104 client.connect_status.connect(_client_connect_status) 106 client.connect_status.connect(_client_connect_status)
@@ -302,6 +304,18 @@ func _process_location_scout(location_id, item_name, player_name, flags, for_sel
302 collectable.setScoutedText(item_name) 304 collectable.setScoutedText(item_name)
303 305
304 306
307func _on_accessible_locations_updated():
308 var textclient_node = global.get_node("Textclient")
309 if textclient_node != null:
310 textclient_node.update_locations()
311
312
313func _on_checked_locations_updated():
314 var textclient_node = global.get_node("Textclient")
315 if textclient_node != null:
316 textclient_node.update_locations()
317
318
305func _client_could_not_connect(message): 319func _client_could_not_connect(message):
306 could_not_connect.emit(message) 320 could_not_connect.emit(message)
307 321
diff --git a/apworld/client/textclient.gd b/apworld/client/textclient.gd index 9841063..e345489 100644 --- a/apworld/client/textclient.gd +++ b/apworld/client/textclient.gd
@@ -1,8 +1,10 @@
1extends CanvasLayer 1extends CanvasLayer
2 2
3var tabs
3var panel 4var panel
4var label 5var label
5var entry 6var entry
7var tracker_label
6var is_open = false 8var is_open = false
7 9
8 10
@@ -10,26 +12,32 @@ func _ready():
10 process_mode = ProcessMode.PROCESS_MODE_ALWAYS 12 process_mode = ProcessMode.PROCESS_MODE_ALWAYS
11 layer = 2 13 layer = 2
12 14
13 panel = Panel.new() 15 tabs = TabContainer.new()
14 panel.set_name("Panel") 16 tabs.name = "Tabs"
15 panel.offset_left = 100 17 tabs.offset_left = 100
16 panel.offset_right = 1820 18 tabs.offset_right = 1820
17 panel.offset_top = 100 19 tabs.offset_top = 100
18 panel.offset_bottom = 980 20 tabs.offset_bottom = 980
19 panel.visible = false 21 tabs.visible = false
20 add_child(panel) 22 tabs.theme = preload("res://assets/themes/baseUI.tres")
23 tabs.add_theme_font_size_override("font_size", 36)
24 add_child(tabs)
25
26 panel = MarginContainer.new()
27 panel.name = "Text Client"
28 panel.add_theme_constant_override("margin_top", 60)
29 panel.add_theme_constant_override("margin_left", 60)
30 panel.add_theme_constant_override("margin_right", 60)
31 panel.add_theme_constant_override("margin_bottom", 60)
32 tabs.add_child(panel)
21 33
22 label = RichTextLabel.new() 34 label = RichTextLabel.new()
23 label.set_name("Label") 35 label.set_name("Label")
24 label.offset_left = 80
25 label.offset_right = 1640
26 label.offset_top = 80
27 label.offset_bottom = 720
28 label.scroll_following = true 36 label.scroll_following = true
29 label.selection_enabled = true 37 label.selection_enabled = true
30 panel.add_child(label) 38 label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
31 39 label.size_flags_vertical = Control.SIZE_EXPAND_FILL
32 label.push_font(load("res://assets/fonts/Lingo2.ttf")) 40 label.push_font(preload("res://assets/fonts/Lingo2.ttf"))
33 label.push_font_size(36) 41 label.push_font_size(36)
34 42
35 var entry_style = StyleBoxFlat.new() 43 var entry_style = StyleBoxFlat.new()
@@ -37,18 +45,30 @@ func _ready():
37 45
38 entry = LineEdit.new() 46 entry = LineEdit.new()
39 entry.set_name("Entry") 47 entry.set_name("Entry")
40 entry.offset_left = 80 48 entry.add_theme_font_override("font", preload("res://assets/fonts/Lingo2.ttf"))
41 entry.offset_right = 1640
42 entry.offset_top = 760
43 entry.offset_bottom = 840
44 entry.add_theme_font_override("font", load("res://assets/fonts/Lingo2.ttf"))
45 entry.add_theme_font_size_override("font_size", 36) 49 entry.add_theme_font_size_override("font_size", 36)
46 entry.add_theme_color_override("font_color", Color(0, 0, 0, 1)) 50 entry.add_theme_color_override("font_color", Color(0, 0, 0, 1))
47 entry.add_theme_color_override("cursor_color", Color(0, 0, 0, 1)) 51 entry.add_theme_color_override("cursor_color", Color(0, 0, 0, 1))
48 entry.add_theme_stylebox_override("focus", entry_style) 52 entry.add_theme_stylebox_override("focus", entry_style)
49 panel.add_child(entry)
50 entry.text_submitted.connect(text_entered) 53 entry.text_submitted.connect(text_entered)
51 54
55 var tc_arranger = VBoxContainer.new()
56 tc_arranger.add_child(label)
57 tc_arranger.add_child(entry)
58 tc_arranger.add_theme_constant_override("separation", 40)
59 panel.add_child(tc_arranger)
60
61 var tracker_margins = MarginContainer.new()
62 tracker_margins.name = "Locations"
63 tracker_margins.add_theme_constant_override("margin_top", 60)
64 tracker_margins.add_theme_constant_override("margin_left", 60)
65 tracker_margins.add_theme_constant_override("margin_right", 60)
66 tracker_margins.add_theme_constant_override("margin_bottom", 60)
67 tabs.add_child(tracker_margins)
68
69 tracker_label = RichTextLabel.new()
70 tracker_margins.add_child(tracker_label)
71
52 72
53func _input(event): 73func _input(event):
54 if global.loaded and event is InputEventKey and event.pressed: 74 if global.loaded and event is InputEventKey and event.pressed:
@@ -57,7 +77,7 @@ func _input(event):
57 is_open = true 77 is_open = true
58 get_tree().paused = true 78 get_tree().paused = true
59 Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) 79 Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
60 panel.visible = true 80 tabs.visible = true
61 entry.grab_focus() 81 entry.grab_focus()
62 get_viewport().set_input_as_handled() 82 get_viewport().set_input_as_handled()
63 else: 83 else:
@@ -72,7 +92,7 @@ func dismiss():
72 if is_open: 92 if is_open:
73 get_tree().paused = false 93 get_tree().paused = false
74 Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) 94 Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
75 panel.visible = false 95 tabs.visible = false
76 is_open = false 96 is_open = false
77 97
78 98
@@ -93,3 +113,23 @@ func text_entered(text):
93 return 113 return
94 114
95 ap.client.say(cmd) 115 ap.client.say(cmd)
116
117
118func update_locations():
119 var ap = global.get_node("Archipelago")
120 var gamedata = global.get_node("Gamedata")
121
122 tracker_label.clear()
123 tracker_label.push_font(preload("res://assets/fonts/Lingo2.ttf"))
124 tracker_label.push_font_size(24)
125
126 var location_names = []
127 for location_id in ap.client._accessible_locations:
128 if not ap.client._checked_locations.has(location_id):
129 var location_name = gamedata.location_name_by_id.get(location_id, "(Unknown)")
130 location_names.append(location_name)
131
132 location_names.sort()
133
134 for location_name in location_names:
135 tracker_label.append_text("[p]%s[/p]" % location_name)