about summary refs log tree commit diff stats
path: root/apworld/client/player.gd
diff options
context:
space:
mode:
authorStar Rauchenberger <fefferburbia@gmail.com>2025-10-23 12:13:09 -0400
committerStar Rauchenberger <fefferburbia@gmail.com>2025-10-23 12:13:09 -0400
commit8cfee29fe6500e96c3b8669c12ac944716e9aae4 (patch)
treebf4723a1790d30155bb70fc710d416f008790b27 /apworld/client/player.gd
parent3cb2ced48dec3b9ea60e008b2a3598a322458adf (diff)
downloadlingo2-archipelago-8cfee29fe6500e96c3b8669c12ac944716e9aae4.tar.gz
lingo2-archipelago-8cfee29fe6500e96c3b8669c12ac944716e9aae4.tar.bz2
lingo2-archipelago-8cfee29fe6500e96c3b8669c12ac944716e9aae4.zip
Added "Enable Gift Maps" option
Only supports The Advanced so far. Also added the mastery to The Advanced. Location listeners are now created after any map edits are made since some locations may require custom nodes (like The Advanced's mastery).
Diffstat (limited to 'apworld/client/player.gd')
-rw-r--r--apworld/client/player.gd338
1 files changed, 203 insertions, 135 deletions
diff --git a/apworld/client/player.gd b/apworld/client/player.gd index 1330e24..43bf758 100644 --- a/apworld/client/player.gd +++ b/apworld/client/player.gd
@@ -19,141 +19,6 @@ func _ready():
19 19
20 ap.start_batching_locations() 20 ap.start_batching_locations()
21 21
22 # Set up door locations.
23 var map_id = gamedata.map_id_by_name.get(global.map)
24 for door in gamedata.objects.get_doors():
25 if door.get_map_id() != map_id:
26 continue
27
28 if not door.has_ap_id():
29 continue
30
31 if (
32 door.get_type() == gamedata.SCRIPT_proto.DoorType.ITEM_ONLY
33 or door.get_type() == gamedata.SCRIPT_proto.DoorType.GALLERY_PAINTING
34 or door.get_type() == gamedata.SCRIPT_proto.DoorType.CONTROL_CENTER_COLOR
35 ):
36 continue
37
38 var locationListener = ap.SCRIPT_locationListener.new()
39 locationListener.location_id = door.get_ap_id()
40 locationListener.name = "locationListener_%d" % door.get_ap_id()
41
42 for panel_ref in door.get_panels():
43 var panel_data = gamedata.objects.get_panels()[panel_ref.get_panel()]
44 var panel_path = panel_data.get_path()
45
46 if panel_ref.has_answer():
47 for proxy in panel_data.get_proxies():
48 if proxy.get_answer() == panel_ref.get_answer():
49 panel_path = proxy.get_path()
50 break
51
52 locationListener.senders.append(NodePath("/root/scene/" + panel_path))
53
54 for keyholder_ref in door.get_keyholders():
55 var keyholder_data = gamedata.objects.get_keyholders()[keyholder_ref.get_keyholder()]
56
57 var khl = khl_script.new()
58 khl.name = (
59 "location_%d_keyholder_%d" % [door.get_ap_id(), keyholder_ref.get_keyholder()]
60 )
61 khl.answer = keyholder_ref.get_key()
62 khl.senders.append(NodePath("/root/scene/" + keyholder_data.get_path()))
63 get_parent().add_child.call_deferred(khl)
64
65 locationListener.senders.append(NodePath("../" + khl.name))
66
67 for sender in door.get_senders():
68 locationListener.senders.append(NodePath("/root/scene/" + sender))
69
70 if door.has_complete_at():
71 locationListener.complete_at = door.get_complete_at()
72
73 get_parent().add_child.call_deferred(locationListener)
74
75 # Set up letter locations.
76 for letter in gamedata.objects.get_letters():
77 var room = gamedata.objects.get_rooms()[letter.get_room_id()]
78 if room.get_map_id() != map_id:
79 continue
80
81 var locationListener = ap.SCRIPT_locationListener.new()
82 locationListener.location_id = letter.get_ap_id()
83 locationListener.name = "locationListener_%d" % letter.get_ap_id()
84 locationListener.senders.append(NodePath("/root/scene/" + letter.get_path()))
85
86 get_parent().add_child.call_deferred(locationListener)
87
88 if (
89 ap.get_letter_behavior(letter.get_key(), letter.has_level2() and letter.get_level2())
90 != ap.kLETTER_BEHAVIOR_VANILLA
91 ):
92 var scout = ap.scout_location(letter.get_ap_id())
93 if scout != null and not (scout["for_self"] and scout["flags"] & 4 != 0):
94 var collectable = get_tree().get_root().get_node("scene").get_node_or_null(
95 letter.get_path()
96 )
97 if collectable != null:
98 collectable.setScoutedText.call_deferred(scout["item"])
99
100 # Set up mastery locations.
101 for mastery in gamedata.objects.get_masteries():
102 var room = gamedata.objects.get_rooms()[mastery.get_room_id()]
103 if room.get_map_id() != map_id:
104 continue
105
106 var locationListener = ap.SCRIPT_locationListener.new()
107 locationListener.location_id = mastery.get_ap_id()
108 locationListener.name = "locationListener_%d" % mastery.get_ap_id()
109 locationListener.senders.append(NodePath("/root/scene/" + mastery.get_path()))
110
111 get_parent().add_child.call_deferred(locationListener)
112
113 # Set up ending locations.
114 for ending in gamedata.objects.get_endings():
115 var room = gamedata.objects.get_rooms()[ending.get_room_id()]
116 if room.get_map_id() != map_id:
117 continue
118
119 var locationListener = ap.SCRIPT_locationListener.new()
120 locationListener.location_id = ending.get_ap_id()
121 locationListener.name = "locationListener_%d" % ending.get_ap_id()
122 locationListener.senders.append(NodePath("/root/scene/" + ending.get_path()))
123
124 get_parent().add_child.call_deferred(locationListener)
125
126 if ap.kEndingNameByVictoryValue.get(ap.victory_condition, null) == ending.get_name():
127 var victoryListener = ap.SCRIPT_victoryListener.new()
128 victoryListener.name = "victoryListener"
129 victoryListener.senders.append(NodePath("/root/scene/" + ending.get_path()))
130
131 get_parent().add_child.call_deferred(victoryListener)
132
133 # Set up keyholder locations, in keyholder sanity.
134 if ap.keyholder_sanity:
135 for keyholder in gamedata.objects.get_keyholders():
136 if not keyholder.has_key():
137 continue
138
139 var room = gamedata.objects.get_rooms()[keyholder.get_room_id()]
140 if room.get_map_id() != map_id:
141 continue
142
143 var locationListener = ap.SCRIPT_locationListener.new()
144 locationListener.location_id = keyholder.get_ap_id()
145 locationListener.name = "locationListener_%d" % keyholder.get_ap_id()
146
147 var khl = khl_script.new()
148 khl.name = "location_%d_keyholder" % keyholder.get_ap_id()
149 khl.answer = keyholder.get_key()
150 khl.senders.append(NodePath("/root/scene/" + keyholder.get_path()))
151 get_parent().add_child.call_deferred(khl)
152
153 locationListener.senders.append(NodePath("../" + khl.name))
154
155 get_parent().add_child.call_deferred(locationListener)
156
157 # Block off roof access in Daedalus. 22 # Block off roof access in Daedalus.
158 if global.map == "daedalus" and not ap.daedalus_roof_access: 23 if global.map == "daedalus" and not ap.daedalus_roof_access:
159 _set_up_invis_wall(75.5, 11, -24.5, 1, 10, 49) 24 _set_up_invis_wall(75.5, 11, -24.5, 1, 10, 49)
@@ -210,6 +75,45 @@ func _ready():
210 sign2.material = load("res://assets/materials/%s.material" % sign2_color) 75 sign2.material = load("res://assets/materials/%s.material" % sign2_color)
211 get_parent().add_child.call_deferred(sign2) 76 get_parent().add_child.call_deferred(sign2)
212 77
78 # Add the gift map entry panel if needed.
79 if not ap.enable_gift_maps.is_empty():
80 var panel_prefab = preload("res://objects/nodes/panel.tscn")
81 var wpl_prefab = preload("res://objects/nodes/listeners/worldportListener.tscn")
82
83 var giftmap_parent = Node.new()
84 giftmap_parent.name = "GiftMapEntrance"
85 get_node("/root/scene/Components").add_child.call_deferred(giftmap_parent)
86
87 var symbolless_player = ""
88 for i in range(ap.client.ap_user.length()):
89 if "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".contains(
90 ap.client.ap_user[i]
91 ):
92 symbolless_player = symbolless_player + ap.client.ap_user[i].to_lower()
93
94 var giftmap_panel = panel_prefab.instantiate()
95 giftmap_panel.name = "Panel"
96 giftmap_panel.position = Vector3(33.5, 1, 5.5)
97 giftmap_panel.rotation_degrees = Vector3(-45, 0, 0)
98 giftmap_panel.clue = "player"
99 giftmap_panel.answer = symbolless_player
100
101 if ap.enable_gift_maps.has("The Advanced"):
102 var icely_panel = panel_prefab.instantiate()
103 icely_panel.name = "IcelyPanel"
104 icely_panel.answer = "icely"
105 icely_panel.position = Vector3(33.5, -200, 5.5)
106 giftmap_panel.proxies.append(NodePath("../IcelyPanel"))
107 giftmap_parent.add_child.call_deferred(icely_panel)
108
109 var icely_wpl = wpl_prefab.instantiate()
110 icely_wpl.name = "IcelyWpl"
111 icely_wpl.exit = "the_advanced"
112 icely_wpl.senders.append(NodePath("../IcelyPanel"))
113 giftmap_parent.add_child.call_deferred(icely_wpl)
114
115 giftmap_parent.add_child.call_deferred(giftmap_panel)
116
213 # Add the strict purple ending validation. 117 # Add the strict purple ending validation.
214 if global.map == "the_sun_temple" and ap.strict_purple_ending: 118 if global.map == "the_sun_temple" and ap.strict_purple_ending:
215 var panel_prefab = preload("res://objects/nodes/panel.tscn") 119 var panel_prefab = preload("res://objects/nodes/panel.tscn")
@@ -318,8 +222,172 @@ func _ready():
318 var rte_trigger = get_node("/root/scene/Components/Warps/triggerArea") 222 var rte_trigger = get_node("/root/scene/Components/Warps/triggerArea")
319 rte_trigger.position.z = 0 223 rte_trigger.position.z = 0
320 224
225 # Add the mastery to The Advanced.
226 if global.map == "the_advanced":
227 var collectable_prefab = preload("res://objects/nodes/collectable.tscn")
228 var saver_prefab = preload("res://objects/nodes/saver.tscn")
229 var tpl_prefab = preload("res://objects/nodes/listeners/teleportListener.tscn")
230
231 var mastery = collectable_prefab.instantiate()
232 mastery.name = "collectable"
233 mastery.position = Vector3(0, -200, -5)
234 mastery.unlock_type = "smiley"
235 mastery.material_override = load("res://assets/materials/gold.material")
236 get_node("/root/scene/Components/Collectables").add_child.call_deferred(mastery)
237
238 var tpl = tpl_prefab.instantiate()
239 tpl.teleport_point = Vector3(0, 2, -5)
240 tpl.teleport_rotate = Vector3(0, 0, 0)
241 tpl.target_path = mastery
242 tpl.name = "Teleport"
243 tpl.senders.append(NodePath("/root/scene/Panels/Room_1/panel_29"))
244 tpl.senders.append(NodePath("/root/scene/Panels/Room_1/panel_30"))
245 tpl.senders.append(NodePath("/root/scene/Panels/Room_1/panel_31"))
246 mastery.add_child.call_deferred(tpl)
247
248 var saver = saver_prefab.instantiate()
249 saver.name = "saver_collectables"
250 saver.type = "collectables"
251 saver.senderGroup.append(NodePath("/root/scene/Components/Collectables"))
252 get_node("/root/scene").add_child.call_deferred(saver)
253
321 ap.update_job_well_done_sign() 254 ap.update_job_well_done_sign()
322 255
256 # Set up door locations.
257 var map_id = gamedata.map_id_by_name.get(global.map)
258 for door in gamedata.objects.get_doors():
259 if door.get_map_id() != map_id:
260 continue
261
262 if not door.has_ap_id():
263 continue
264
265 if (
266 door.get_type() == gamedata.SCRIPT_proto.DoorType.ITEM_ONLY
267 or door.get_type() == gamedata.SCRIPT_proto.DoorType.GALLERY_PAINTING
268 or door.get_type() == gamedata.SCRIPT_proto.DoorType.CONTROL_CENTER_COLOR
269 ):
270 continue
271
272 var locationListener = ap.SCRIPT_locationListener.new()
273 locationListener.location_id = door.get_ap_id()
274 locationListener.name = "locationListener_%d" % door.get_ap_id()
275
276 for panel_ref in door.get_panels():
277 var panel_data = gamedata.objects.get_panels()[panel_ref.get_panel()]
278 var panel_path = panel_data.get_path()
279
280 if panel_ref.has_answer():
281 for proxy in panel_data.get_proxies():
282 if proxy.get_answer() == panel_ref.get_answer():
283 panel_path = proxy.get_path()
284 break
285
286 locationListener.senders.append(NodePath("/root/scene/" + panel_path))
287
288 for keyholder_ref in door.get_keyholders():
289 var keyholder_data = gamedata.objects.get_keyholders()[keyholder_ref.get_keyholder()]
290
291 var khl = khl_script.new()
292 khl.name = (
293 "location_%d_keyholder_%d" % [door.get_ap_id(), keyholder_ref.get_keyholder()]
294 )
295 khl.answer = keyholder_ref.get_key()
296 khl.senders.append(NodePath("/root/scene/" + keyholder_data.get_path()))
297 get_parent().add_child.call_deferred(khl)
298
299 locationListener.senders.append(NodePath("../" + khl.name))
300
301 for sender in door.get_senders():
302 locationListener.senders.append(NodePath("/root/scene/" + sender))
303
304 if door.has_complete_at():
305 locationListener.complete_at = door.get_complete_at()
306
307 get_parent().add_child.call_deferred(locationListener)
308
309 # Set up letter locations.
310 for letter in gamedata.objects.get_letters():
311 var room = gamedata.objects.get_rooms()[letter.get_room_id()]
312 if room.get_map_id() != map_id:
313 continue
314
315 var locationListener = ap.SCRIPT_locationListener.new()
316 locationListener.location_id = letter.get_ap_id()
317 locationListener.name = "locationListener_%d" % letter.get_ap_id()
318 locationListener.senders.append(NodePath("/root/scene/" + letter.get_path()))
319
320 get_parent().add_child.call_deferred(locationListener)
321
322 if (
323 ap.get_letter_behavior(letter.get_key(), letter.has_level2() and letter.get_level2())
324 != ap.kLETTER_BEHAVIOR_VANILLA
325 ):
326 var scout = ap.scout_location(letter.get_ap_id())
327 if scout != null and not (scout["for_self"] and scout["flags"] & 4 != 0):
328 var collectable = get_tree().get_root().get_node("scene").get_node_or_null(
329 letter.get_path()
330 )
331 if collectable != null:
332 collectable.setScoutedText.call_deferred(scout["item"])
333
334 # Set up mastery locations.
335 for mastery in gamedata.objects.get_masteries():
336 var room = gamedata.objects.get_rooms()[mastery.get_room_id()]
337 if room.get_map_id() != map_id:
338 continue
339
340 var locationListener = ap.SCRIPT_locationListener.new()
341 locationListener.location_id = mastery.get_ap_id()
342 locationListener.name = "locationListener_%d" % mastery.get_ap_id()
343 locationListener.senders.append(NodePath("/root/scene/" + mastery.get_path()))
344
345 get_parent().add_child.call_deferred(locationListener)
346
347 # Set up ending locations.
348 for ending in gamedata.objects.get_endings():
349 var room = gamedata.objects.get_rooms()[ending.get_room_id()]
350 if room.get_map_id() != map_id:
351 continue
352
353 var locationListener = ap.SCRIPT_locationListener.new()
354 locationListener.location_id = ending.get_ap_id()
355 locationListener.name = "locationListener_%d" % ending.get_ap_id()
356 locationListener.senders.append(NodePath("/root/scene/" + ending.get_path()))
357
358 get_parent().add_child.call_deferred(locationListener)
359
360 if ap.kEndingNameByVictoryValue.get(ap.victory_condition, null) == ending.get_name():
361 var victoryListener = ap.SCRIPT_victoryListener.new()
362 victoryListener.name = "victoryListener"
363 victoryListener.senders.append(NodePath("/root/scene/" + ending.get_path()))
364
365 get_parent().add_child.call_deferred(victoryListener)
366
367 # Set up keyholder locations, in keyholder sanity.
368 if ap.keyholder_sanity:
369 for keyholder in gamedata.objects.get_keyholders():
370 if not keyholder.has_key():
371 continue
372
373 var room = gamedata.objects.get_rooms()[keyholder.get_room_id()]
374 if room.get_map_id() != map_id:
375 continue
376
377 var locationListener = ap.SCRIPT_locationListener.new()
378 locationListener.location_id = keyholder.get_ap_id()
379 locationListener.name = "locationListener_%d" % keyholder.get_ap_id()
380
381 var khl = khl_script.new()
382 khl.name = "location_%d_keyholder" % keyholder.get_ap_id()
383 khl.answer = keyholder.get_key()
384 khl.senders.append(NodePath("/root/scene/" + keyholder.get_path()))
385 get_parent().add_child.call_deferred(khl)
386
387 locationListener.senders.append(NodePath("../" + khl.name))
388
389 get_parent().add_child.call_deferred(locationListener)
390
323 var minimap = ap.SCRIPT_minimap.new() 391 var minimap = ap.SCRIPT_minimap.new()
324 minimap.name = "Minimap" 392 minimap.name = "Minimap"
325 minimap.visible = ap.show_minimap 393 minimap.visible = ap.show_minimap