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.gd77
-rw-r--r--apworld/client/gamedata.gd132
-rw-r--r--apworld/client/keyboard.gd36
-rw-r--r--apworld/client/main.gd1
-rw-r--r--apworld/client/manager.gd33
-rw-r--r--apworld/client/pauseMenu.gd40
-rw-r--r--apworld/client/player.gd1
-rw-r--r--apworld/client/textclient.gd128
-rw-r--r--apworld/client/worldport.gd10
9 files changed, 414 insertions, 44 deletions
diff --git a/apworld/client/client.gd b/apworld/client/client.gd index 67edf29..a23e85a 100644 --- a/apworld/client/client.gd +++ b/apworld/client/client.gd
@@ -18,9 +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 = {}
25var _accessible_locations = []
26var _accessible_worldports = []
24 27
25signal could_not_connect 28signal could_not_connect
26signal connect_status 29signal connect_status
@@ -30,6 +33,10 @@ signal location_scout_received(location_id, item_name, player_name, flags, for_s
30signal text_message_received(message) 33signal text_message_received(message)
31signal item_sent_notification(message) 34signal item_sent_notification(message)
32signal hint_received(message) 35signal hint_received(message)
36signal accessible_locations_updated
37signal checked_locations_updated
38signal checked_worldports_updated
39signal keyboard_update_received
33 40
34 41
35func _init(): 42func _init():
@@ -51,6 +58,9 @@ func _reset_state():
51 _should_process = false 58 _should_process = false
52 _received_items = {} 59 _received_items = {}
53 _received_indexes = [] 60 _received_indexes = []
61 _checked_worldports = []
62 _accessible_locations = []
63 _accessible_worldports = []
54 64
55 65
56func disconnect_from_ap(): 66func disconnect_from_ap():
@@ -92,15 +102,34 @@ func _on_web_socket_server_message_received(_peer_id: int, packet: String) -> vo
92 _gen_version = message["generator_version"] 102 _gen_version = message["generator_version"]
93 _team = message["team"] 103 _team = message["team"]
94 _slot = message["slot"] 104 _slot = message["slot"]
95 _checked_locations = message["checked_locations"]
96 _slot_data = message["slot_data"] 105 _slot_data = message["slot_data"]
97 106
107 _checked_locations = []
108 for location in message["checked_locations"]:
109 _checked_locations.append(int(message["checked_locations"]))
110
98 client_connected.emit(_slot_data) 111 client_connected.emit(_slot_data)
99 112
100 elif cmd == "ConnectionRefused": 113 elif cmd == "ConnectionRefused":
101 could_not_connect.emit(message["text"]) 114 could_not_connect.emit(message["text"])
102 global._print("Connection to AP refused") 115 global._print("Connection to AP refused")
103 116
117 elif cmd == "UpdateLocations":
118 for location in message["locations"]:
119 var lint = int(location)
120 if not _checked_locations.has(lint):
121 _checked_locations.append(lint)
122
123 checked_locations_updated.emit()
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
104 elif cmd == "ItemReceived": 133 elif cmd == "ItemReceived":
105 for item in message["items"]: 134 for item in message["items"]:
106 var index = int(item["index"]) 135 var index = int(item["index"])
@@ -134,6 +163,26 @@ func _on_web_socket_server_message_received(_peer_id: int, packet: String) -> vo
134 int(loc["for_self"]) 163 int(loc["for_self"])
135 ) 164 )
136 165
166 elif cmd == "AccessibleLocations":
167 _accessible_locations.clear()
168 _accessible_worldports.clear()
169
170 for loc in message["locations"]:
171 _accessible_locations.append(int(loc))
172
173 if "worldports" in message:
174 for port_id in message["worldports"]:
175 _accessible_worldports.append(int(port_id))
176
177 accessible_locations_updated.emit()
178
179 elif cmd == "UpdateKeyboard":
180 var updates = {}
181 for k in message["updates"]:
182 updates[k] = int(message["updates"][k])
183
184 keyboard_update_received.emit(updates)
185
137 186
138func connectToServer(server, un, pw): 187func connectToServer(server, un, pw):
139 sendMessage([{"cmd": "Connect", "server": server, "player": un, "password": pw}]) 188 sendMessage([{"cmd": "Connect", "server": server, "player": un, "password": pw}])
@@ -179,19 +228,6 @@ func sendLocations(loc_ids):
179 sendMessage([{"cmd": "LocationChecks", "locations": loc_ids}]) 228 sendMessage([{"cmd": "LocationChecks", "locations": loc_ids}])
180 229
181 230
182func setValue(key, value, operation = "replace"):
183 sendMessage(
184 [
185 {
186 "cmd": "Set",
187 "key": "Lingo2_%d_%s" % [_slot, key],
188 "want_reply": false,
189 "operations": [{"operation": operation, "value": value}]
190 }
191 ]
192 )
193
194
195func say(textdata): 231func say(textdata):
196 sendMessage([{"cmd": "Say", "text": textdata}]) 232 sendMessage([{"cmd": "Say", "text": textdata}])
197 233
@@ -204,6 +240,19 @@ func scoutLocations(loc_ids):
204 sendMessage([{"cmd": "LocationScouts", "locations": loc_ids}]) 240 sendMessage([{"cmd": "LocationScouts", "locations": loc_ids}])
205 241
206 242
243func updateKeyboard(updates):
244 sendMessage([{"cmd": "UpdateKeyboard", "keyboard": updates}])
245
246
247func checkWorldport(port_id):
248 if not _checked_worldports.has(port_id):
249 sendMessage([{"cmd": "CheckWorldport", "port_id": port_id}])
250
251
252func sendQuit():
253 sendMessage([{"cmd": "Quit"}])
254
255
207func hasItem(item_id): 256func hasItem(item_id):
208 return _received_items.has(item_id) 257 return _received_items.has(item_id)
209 258
diff --git a/apworld/client/gamedata.gd b/apworld/client/gamedata.gd index 9eeec3b..e44fa17 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()]
@@ -148,12 +161,123 @@ func get_door_ap_id(door_id):
148 return null 161 return null
149 162
150 163
164func get_door_map_name(door_id):
165 var door = objects.get_doors()[door_id]
166 var room = objects.get_rooms()[door.get_room_id()]
167 var map = objects.get_maps()[room.get_map_id()]
168 return map.get_name()
169
170
151func get_door_receivers(door_id): 171func get_door_receivers(door_id):
152 var door = objects.get_doors()[door_id] 172 var door = objects.get_doors()[door_id]
153 return door.get_receivers() 173 return door.get_receivers()
154 174
155 175
156func get_door_map_name(door_id): 176func get_worldport_display_name(port_id):
157 var door = objects.get_doors()[door_id] 177 var port = objects.get_ports()[port_id]
158 var map = objects.get_maps()[door.get_map_id()] 178 return "%s - %s (Worldport)" % [_get_room_object_map_name(port), port.get_name()]
159 return map.get_name() 179
180
181func _get_map_object_map_name(obj):
182 return objects.get_maps()[obj.get_map_id()].get_display_name()
183
184
185func _get_room_object_map_name(obj):
186 return _get_map_object_map_name(objects.get_rooms()[obj.get_room_id()])
187
188
189func _get_room_object_location_prefix(obj):
190 var room = objects.get_rooms()[obj.get_room_id()]
191 var game_map = objects.get_maps()[room.get_map_id()]
192
193 if room.has_panel_display_name():
194 return "%s (%s)" % [game_map.get_display_name(), room.get_panel_display_name()]
195 else:
196 return game_map.get_display_name()
197
198
199func _get_door_location_name(door):
200 var map_part = _get_room_object_location_prefix(door)
201
202 if door.has_location_name():
203 return "%s - %s" % [map_part, door.get_location_name()]
204
205 var generated_location_name = _get_generated_door_location_name(door)
206 if generated_location_name != null:
207 return generated_location_name
208
209 return "%s - %s" % [map_part, door.get_name()]
210
211
212func _get_generated_door_location_name(door):
213 if door.get_type() != SCRIPT_proto.DoorType.STANDARD:
214 return null
215
216 if door.get_keyholders().size() > 0 or door.get_endings().size() > 0 or door.has_complete_at():
217 return null
218
219 if door.get_panels().size() > 4:
220 return null
221
222 var map_areas = []
223 for panel_id in door.get_panels():
224 var panel = objects.get_panels()[panel_id.get_panel()]
225 var panel_room = objects.get_rooms()[panel.get_room_id()]
226 # It's okay if panel_display_name is not present because then it's coalesced with other unnamed areas.
227 if not map_areas.has(panel_room.get_panel_display_name()):
228 map_areas.append(panel_room.get_panel_display_name())
229
230 if map_areas.size() > 1:
231 return null
232
233 var game_map = objects.get_maps()[door.get_map_id()]
234 var map_area = map_areas[0]
235 var map_part
236 if map_area == "":
237 map_part = game_map.get_display_name()
238 else:
239 map_part = "%s (%s)" % [game_map.get_display_name(), map_area]
240
241 var panel_names = []
242 for panel_id in door.get_panels():
243 var panel_data = objects.get_panels()[panel_id.get_panel()]
244 var panel_name
245 if panel_data.has_display_name():
246 panel_name = panel_data.get_display_name()
247 else:
248 panel_name = panel_data.get_name()
249
250 var location_part
251 if panel_id.has_answer():
252 location_part = "%s/%s" % [panel_name, panel_id.get_answer().to_upper()]
253 else:
254 location_part = panel_name
255
256 panel_names.append(location_part)
257
258 panel_names.sort()
259
260 return map_part + " - " + ", ".join(panel_names)
261
262
263func _get_letter_location_name(letter):
264 var letter_level = 2 if letter.get_level2() else 1
265 var letter_name = "%s%d" % [letter.get_key().to_upper(), letter_level]
266 return "%s - %s" % [_get_room_object_map_name(letter), letter_name]
267
268
269func _get_mastery_location_name(mastery):
270 return "%s - Mastery" % _get_room_object_map_name(mastery)
271
272
273func _get_ending_location_name(ending):
274 return (
275 "%s - %s Ending" % [_get_room_object_map_name(ending), ending.get_name().to_pascal_case()]
276 )
277
278
279func _get_keyholder_location_name(keyholder):
280 return (
281 "%s - %s Keyholder"
282 % [_get_room_object_location_prefix(keyholder), keyholder.get_key().to_upper()]
283 )
diff --git a/apworld/client/keyboard.gd b/apworld/client/keyboard.gd index 450566d..a59c4d0 100644 --- a/apworld/client/keyboard.gd +++ b/apworld/client/keyboard.gd
@@ -48,6 +48,9 @@ func load_seed():
48 if localdata.size() > 2: 48 if localdata.size() > 2:
49 keyholder_state = localdata[2] 49 keyholder_state = localdata[2]
50 50
51 if not letters_saved.is_empty():
52 ap.client.updateKeyboard(letters_saved)
53
51 for k in kALL_LETTERS: 54 for k in kALL_LETTERS:
52 var level = 0 55 var level = 0
53 56
@@ -105,10 +108,20 @@ func update_unlocks():
105 108
106 109
107func collect_local_letter(key, level): 110func collect_local_letter(key, level):
108 if level < 0 or level > 2 or level < letters_saved.get(key, 0): 111 var ap = global.get_node("Archipelago")
112 var true_level = 0
113
114 if ap.get_letter_behavior(key, false) == ap.kLETTER_BEHAVIOR_VANILLA:
115 true_level += 1
116 if level == 2 and ap.get_letter_behavior(key, true) == ap.kLETTER_BEHAVIOR_VANILLA:
117 true_level += 1
118
119 if true_level < letters_saved.get(key, 0):
109 return 120 return
110 121
111 letters_saved[key] = level 122 letters_saved[key] = true_level
123
124 ap.client.updateKeyboard({key: true_level})
112 125
113 if letters_blocked.has(key): 126 if letters_blocked.has(key):
114 letters_blocked.erase(key) 127 letters_blocked.erase(key)
@@ -197,3 +210,22 @@ func reset_keyholders():
197 save() 210 save()
198 211
199 return cleared_anything 212 return cleared_anything
213
214
215func remote_keyboard_updated(updates):
216 var reverse = {}
217 var should_update = false
218
219 for k in updates:
220 if not letters_saved.has(k) or updates[k] > letters_saved[k]:
221 letters_saved[k] = updates[k]
222 should_update = true
223 elif updates[k] < letters_saved[k]:
224 reverse[k] = letters_saved[k]
225
226 if should_update:
227 update_unlocks()
228
229 if not reverse.is_empty():
230 var ap = global.get_node("Archipelago")
231 ap.client.updateKeyboard(reverse)
diff --git a/apworld/client/main.gd b/apworld/client/main.gd index 9d66358..8425d8c 100644 --- a/apworld/client/main.gd +++ b/apworld/client/main.gd
@@ -137,6 +137,7 @@ func _connect_pressed():
137func _back_pressed(): 137func _back_pressed():
138 var ap = global.get_node("Archipelago") 138 var ap = global.get_node("Archipelago")
139 ap.disconnect_from_ap() 139 ap.disconnect_from_ap()
140 ap.client.sendQuit()
140 141
141 get_tree().quit() 142 get_tree().quit()
142 143
diff --git a/apworld/client/manager.gd b/apworld/client/manager.gd index 955d470..3facfba 100644 --- a/apworld/client/manager.gd +++ b/apworld/client/manager.gd
@@ -14,6 +14,8 @@ var ap_user = ""
14var ap_pass = "" 14var ap_pass = ""
15var connection_history = [] 15var connection_history = []
16var show_compass = false 16var show_compass = false
17var show_locations = false
18var show_minimap = false
17 19
18var client 20var client
19var keyboard 21var keyboard
@@ -89,6 +91,12 @@ func _init():
89 if data.size() > 4: 91 if data.size() > 4:
90 show_compass = data[4] 92 show_compass = data[4]
91 93
94 if data.size() > 5:
95 show_locations = data[5]
96
97 if data.size() > 6:
98 show_minimap = data[6]
99
92 100
93func _ready(): 101func _ready():
94 client = SCRIPT_client.new() 102 client = SCRIPT_client.new()
@@ -99,6 +107,9 @@ func _ready():
99 client.text_message_received.connect(_process_text_message) 107 client.text_message_received.connect(_process_text_message)
100 client.item_sent_notification.connect(_process_item_sent_notification) 108 client.item_sent_notification.connect(_process_item_sent_notification)
101 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)
111 client.checked_locations_updated.connect(_on_checked_locations_updated)
112 client.checked_worldports_updated.connect(_on_checked_worldports_updated)
102 113
103 client.could_not_connect.connect(_client_could_not_connect) 114 client.could_not_connect.connect(_client_could_not_connect)
104 client.connect_status.connect(_client_connect_status) 115 client.connect_status.connect(_client_connect_status)
@@ -108,6 +119,7 @@ func _ready():
108 119
109 keyboard = SCRIPT_keyboard.new() 120 keyboard = SCRIPT_keyboard.new()
110 add_child(keyboard) 121 add_child(keyboard)
122 client.keyboard_update_received.connect(keyboard.remote_keyboard_updated)
111 123
112 124
113func saveSettings(): 125func saveSettings():
@@ -121,6 +133,8 @@ func saveSettings():
121 ap_pass, 133 ap_pass,
122 connection_history, 134 connection_history,
123 show_compass, 135 show_compass,
136 show_locations,
137 show_minimap,
124 ] 138 ]
125 file.store_var(data, true) 139 file.store_var(data, true)
126 file.close() 140 file.close()
@@ -182,6 +196,7 @@ func _process_item(item, amount):
182 if gamedata.get_door_map_name(lock[0]) != global.map: 196 if gamedata.get_door_map_name(lock[0]) != global.map:
183 continue 197 continue
184 198
199 # TODO: fix doors opening from door groups
185 var receivers = gamedata.get_door_receivers(lock[0]) 200 var receivers = gamedata.get_door_receivers(lock[0])
186 var scene = get_tree().get_root().get_node_or_null("scene") 201 var scene = get_tree().get_root().get_node_or_null("scene")
187 if scene != null: 202 if scene != null:
@@ -302,6 +317,24 @@ func _process_location_scout(location_id, item_name, player_name, flags, for_sel
302 collectable.setScoutedText(item_name) 317 collectable.setScoutedText(item_name)
303 318
304 319
320func _on_accessible_locations_updated():
321 var textclient_node = global.get_node("Textclient")
322 if textclient_node != null:
323 textclient_node.update_locations()
324
325
326func _on_checked_locations_updated():
327 var textclient_node = global.get_node("Textclient")
328 if textclient_node != null:
329 textclient_node.update_locations()
330
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
337
305func _client_could_not_connect(message): 338func _client_could_not_connect(message):
306 could_not_connect.emit(message) 339 could_not_connect.emit(message)
307 340
diff --git a/apworld/client/pauseMenu.gd b/apworld/client/pauseMenu.gd index 8bc12c6..72b45e8 100644 --- a/apworld/client/pauseMenu.gd +++ b/apworld/client/pauseMenu.gd
@@ -1,6 +1,8 @@
1extends "res://scripts/ui/pauseMenu.gd" 1extends "res://scripts/ui/pauseMenu.gd"
2 2
3var compass_button 3var compass_button
4var locations_button
5var minimap_button
4 6
5 7
6func _ready(): 8func _ready():
@@ -19,6 +21,24 @@ func _ready():
19 compass_button.pressed.connect(_toggle_compass) 21 compass_button.pressed.connect(_toggle_compass)
20 ap_panel.add_child(compass_button) 22 ap_panel.add_child(compass_button)
21 23
24 locations_button = CheckBox.new()
25 locations_button.text = "show locations overlay"
26 locations_button.button_pressed = ap.show_locations
27 locations_button.position = Vector2(65, 200)
28 locations_button.theme = preload("res://assets/themes/baseUI.tres")
29 locations_button.add_theme_font_size_override("font_size", 60)
30 locations_button.pressed.connect(_toggle_locations)
31 ap_panel.add_child(locations_button)
32
33 minimap_button = CheckBox.new()
34 minimap_button.text = "show minimap"
35 minimap_button.button_pressed = ap.show_minimap
36 minimap_button.position = Vector2(65, 300)
37 minimap_button.theme = preload("res://assets/themes/baseUI.tres")
38 minimap_button.add_theme_font_size_override("font_size", 60)
39 minimap_button.pressed.connect(_toggle_minimap)
40 ap_panel.add_child(minimap_button)
41
22 super._ready() 42 super._ready()
23 43
24 44
@@ -32,6 +52,7 @@ func _main_menu():
32 global.get_node("Archipelago").disconnect_from_ap() 52 global.get_node("Archipelago").disconnect_from_ap()
33 global.get_node("Messages").clear() 53 global.get_node("Messages").clear()
34 global.get_node("Compass").visible = false 54 global.get_node("Compass").visible = false
55 global.get_node("Textclient").reset()
35 56
36 autosplitter.reset() 57 autosplitter.reset()
37 _unpause_game() 58 _unpause_game()
@@ -49,3 +70,22 @@ func _toggle_compass():
49 70
50 var compass = global.get_node("Compass") 71 var compass = global.get_node("Compass")
51 compass.visible = compass_button.button_pressed 72 compass.visible = compass_button.button_pressed
73
74
75func _toggle_locations():
76 var ap = global.get_node("Archipelago")
77 ap.show_locations = locations_button.button_pressed
78 ap.saveSettings()
79
80 var textclient = global.get_node("Textclient")
81 textclient.update_locations_visibility()
82
83
84func _toggle_minimap():
85 var ap = global.get_node("Archipelago")
86 ap.show_minimap = minimap_button.button_pressed
87 ap.saveSettings()
88
89 var minimap = get_tree().get_root().get_node("scene/Minimap")
90 if minimap != null:
91 minimap.visible = ap.show_minimap
diff --git a/apworld/client/player.gd b/apworld/client/player.gd index fb88880..366c3b0 100644 --- a/apworld/client/player.gd +++ b/apworld/client/player.gd
@@ -330,6 +330,7 @@ func _ready():
330 330
331 var minimap = ap.SCRIPT_minimap.new() 331 var minimap = ap.SCRIPT_minimap.new()
332 minimap.name = "Minimap" 332 minimap.name = "Minimap"
333 minimap.visible = ap.show_minimap
333 get_parent().add_child.call_deferred(minimap) 334 get_parent().add_child.call_deferred(minimap)
334 335
335 super._ready() 336 super._ready()
diff --git a/apworld/client/textclient.gd b/apworld/client/textclient.gd index 9841063..af155fb 100644 --- a/apworld/client/textclient.gd +++ b/apworld/client/textclient.gd
@@ -1,35 +1,57 @@
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
10var locations_overlay
11
8 12
9func _ready(): 13func _ready():
10 process_mode = ProcessMode.PROCESS_MODE_ALWAYS 14 process_mode = ProcessMode.PROCESS_MODE_ALWAYS
11 layer = 2 15 layer = 2
12 16
13 panel = Panel.new() 17 locations_overlay = RichTextLabel.new()
14 panel.set_name("Panel") 18 locations_overlay.name = "LocationsOverlay"
15 panel.offset_left = 100 19 locations_overlay.offset_top = 220
16 panel.offset_right = 1820 20 locations_overlay.offset_bottom = 720
17 panel.offset_top = 100 21 locations_overlay.offset_left = 20
18 panel.offset_bottom = 980 22 locations_overlay.anchor_right = 1.0
19 panel.visible = false 23 locations_overlay.offset_right = -20
20 add_child(panel) 24 locations_overlay.scroll_active = false
25 locations_overlay.mouse_filter = Control.MOUSE_FILTER_IGNORE
26 add_child(locations_overlay)
27 update_locations_visibility()
28
29 tabs = TabContainer.new()
30 tabs.name = "Tabs"
31 tabs.offset_left = 100
32 tabs.offset_right = 1820
33 tabs.offset_top = 100
34 tabs.offset_bottom = 980
35 tabs.visible = false
36 tabs.theme = preload("res://assets/themes/baseUI.tres")
37 tabs.add_theme_font_size_override("font_size", 36)
38 add_child(tabs)
39
40 panel = MarginContainer.new()
41 panel.name = "Text Client"
42 panel.add_theme_constant_override("margin_top", 60)
43 panel.add_theme_constant_override("margin_left", 60)
44 panel.add_theme_constant_override("margin_right", 60)
45 panel.add_theme_constant_override("margin_bottom", 60)
46 tabs.add_child(panel)
21 47
22 label = RichTextLabel.new() 48 label = RichTextLabel.new()
23 label.set_name("Label") 49 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 50 label.scroll_following = true
29 label.selection_enabled = true 51 label.selection_enabled = true
30 panel.add_child(label) 52 label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
31 53 label.size_flags_vertical = Control.SIZE_EXPAND_FILL
32 label.push_font(load("res://assets/fonts/Lingo2.ttf")) 54 label.push_font(preload("res://assets/fonts/Lingo2.ttf"))
33 label.push_font_size(36) 55 label.push_font_size(36)
34 56
35 var entry_style = StyleBoxFlat.new() 57 var entry_style = StyleBoxFlat.new()
@@ -37,18 +59,30 @@ func _ready():
37 59
38 entry = LineEdit.new() 60 entry = LineEdit.new()
39 entry.set_name("Entry") 61 entry.set_name("Entry")
40 entry.offset_left = 80 62 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) 63 entry.add_theme_font_size_override("font_size", 36)
46 entry.add_theme_color_override("font_color", Color(0, 0, 0, 1)) 64 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)) 65 entry.add_theme_color_override("cursor_color", Color(0, 0, 0, 1))
48 entry.add_theme_stylebox_override("focus", entry_style) 66 entry.add_theme_stylebox_override("focus", entry_style)
49 panel.add_child(entry)
50 entry.text_submitted.connect(text_entered) 67 entry.text_submitted.connect(text_entered)
51 68
69 var tc_arranger = VBoxContainer.new()
70 tc_arranger.add_child(label)
71 tc_arranger.add_child(entry)
72 tc_arranger.add_theme_constant_override("separation", 40)
73 panel.add_child(tc_arranger)
74
75 var tracker_margins = MarginContainer.new()
76 tracker_margins.name = "Locations"
77 tracker_margins.add_theme_constant_override("margin_top", 60)
78 tracker_margins.add_theme_constant_override("margin_left", 60)
79 tracker_margins.add_theme_constant_override("margin_right", 60)
80 tracker_margins.add_theme_constant_override("margin_bottom", 60)
81 tabs.add_child(tracker_margins)
82
83 tracker_label = RichTextLabel.new()
84 tracker_margins.add_child(tracker_label)
85
52 86
53func _input(event): 87func _input(event):
54 if global.loaded and event is InputEventKey and event.pressed: 88 if global.loaded and event is InputEventKey and event.pressed:
@@ -57,7 +91,7 @@ func _input(event):
57 is_open = true 91 is_open = true
58 get_tree().paused = true 92 get_tree().paused = true
59 Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) 93 Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
60 panel.visible = true 94 tabs.visible = true
61 entry.grab_focus() 95 entry.grab_focus()
62 get_viewport().set_input_as_handled() 96 get_viewport().set_input_as_handled()
63 else: 97 else:
@@ -72,7 +106,7 @@ func dismiss():
72 if is_open: 106 if is_open:
73 get_tree().paused = false 107 get_tree().paused = false
74 Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) 108 Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
75 panel.visible = false 109 tabs.visible = false
76 is_open = false 110 is_open = false
77 111
78 112
@@ -93,3 +127,51 @@ func text_entered(text):
93 return 127 return
94 128
95 ap.client.say(cmd) 129 ap.client.say(cmd)
130
131
132func update_locations():
133 var ap = global.get_node("Archipelago")
134 var gamedata = global.get_node("Gamedata")
135
136 tracker_label.clear()
137 tracker_label.push_font(preload("res://assets/fonts/Lingo2.ttf"))
138 tracker_label.push_font_size(24)
139
140 locations_overlay.clear()
141 locations_overlay.push_font(preload("res://assets/fonts/Lingo2.ttf"))
142 locations_overlay.push_font_size(24)
143 locations_overlay.push_color(Color(0.9, 0.9, 0.9, 1))
144 locations_overlay.push_outline_color(Color(0, 0, 0, 1))
145 locations_overlay.push_outline_size(2)
146
147 var location_names = []
148 for location_id in ap.client._accessible_locations:
149 if not ap.client._checked_locations.has(location_id):
150 var location_name = gamedata.location_name_by_id.get(location_id, "(Unknown)")
151 location_names.append(location_name)
152
153 for port_id in ap.client._accessible_worldports:
154 if not ap.client._checked_worldports.has(port_id):
155 var port_name = gamedata.get_worldport_display_name(port_id)
156 location_names.append(port_name)
157
158 location_names.sort()
159
160 var count = 0
161 for location_name in location_names:
162 tracker_label.append_text("[p]%s[/p]" % location_name)
163 if count < 18:
164 locations_overlay.append_text("[p align=right]%s[/p]" % location_name)
165 count += 1
166
167 if count > 18:
168 locations_overlay.append_text("[p align=right][lb]...[rb][/p]")
169
170
171func update_locations_visibility():
172 var ap = global.get_node("Archipelago")
173 locations_overlay.visible = ap.show_locations
174
175
176func reset():
177 locations_overlay.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