From 452289b3b6247bb512b9353e0f2c6a9b7090be55 Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Tue, 4 Nov 2025 14:56:04 -0500 Subject: Split map-specific initialization into separate files --- apworld/client/apworld_runtime.gd | 5 + apworld/client/manager.gd | 14 + apworld/client/maps/control_center.gd | 85 +++++ apworld/client/maps/daedalus.gd | 85 +++++ apworld/client/maps/icarus.gd | 38 ++ apworld/client/maps/the_advanced.gd | 36 ++ apworld/client/maps/the_charismatic.gd | 26 ++ apworld/client/maps/the_crystalline.gd | 34 ++ apworld/client/maps/the_entry.gd | 156 ++++++++ apworld/client/maps/the_fuzzy.gd | 25 ++ apworld/client/maps/the_parthenon.gd | 51 +++ apworld/client/maps/the_plaza.gd | 4 + apworld/client/maps/the_stellar.gd | 30 ++ apworld/client/maps/the_sun_temple.gd | 56 +++ apworld/client/maps/the_unyielding.gd | 5 + apworld/client/player.gd | 636 +-------------------------------- apworld/client/source_runtime.gd | 4 + 17 files changed, 658 insertions(+), 632 deletions(-) create mode 100644 apworld/client/maps/control_center.gd create mode 100644 apworld/client/maps/daedalus.gd create mode 100644 apworld/client/maps/icarus.gd create mode 100644 apworld/client/maps/the_advanced.gd create mode 100644 apworld/client/maps/the_charismatic.gd create mode 100644 apworld/client/maps/the_crystalline.gd create mode 100644 apworld/client/maps/the_entry.gd create mode 100644 apworld/client/maps/the_fuzzy.gd create mode 100644 apworld/client/maps/the_parthenon.gd create mode 100644 apworld/client/maps/the_plaza.gd create mode 100644 apworld/client/maps/the_stellar.gd create mode 100644 apworld/client/maps/the_sun_temple.gd create mode 100644 apworld/client/maps/the_unyielding.gd (limited to 'apworld') diff --git a/apworld/client/apworld_runtime.gd b/apworld/client/apworld_runtime.gd index faf8e0c..03568bf 100644 --- a/apworld/client/apworld_runtime.gd +++ b/apworld/client/apworld_runtime.gd @@ -15,6 +15,11 @@ func _get_true_path(path): return "lingo2/client/%s" % path +func path_exists(path): + var true_path = _get_true_path(path) + return apworld_reader.file_exists(true_path) + + func load_script(path): var true_path = _get_true_path(path) diff --git a/apworld/client/manager.gd b/apworld/client/manager.gd index 830ebb8..8c981f9 100644 --- a/apworld/client/manager.gd +++ b/apworld/client/manager.gd @@ -30,6 +30,7 @@ var _held_letters = {} var _letters_setup = false var _already_connected = false var _ignored_locations = [] +var _map_scripts = {} const kSHUFFLE_LETTERS_VANILLA = 0 const kSHUFFLE_LETTERS_UNLOCKED = 1 @@ -701,3 +702,16 @@ func toggle_ignored_location(loc_id): client.removeIgnoredLocation(loc_id) else: client.addIgnoredLocation(loc_id) + + +func get_map_script(map_name): + if !_map_scripts.has(map_name): + var runtime = global.get_node("Runtime") + var script_path = "maps/%s.gd" % map_name + if runtime.path_exists(script_path): + var script = runtime.load_script(script_path) + _map_scripts[map_name] = script.new() + else: + _map_scripts[map_name] = null + + return _map_scripts[map_name] diff --git a/apworld/client/maps/control_center.gd b/apworld/client/maps/control_center.gd new file mode 100644 index 0000000..de9ae4b --- /dev/null +++ b/apworld/client/maps/control_center.gd @@ -0,0 +1,85 @@ +func on_map_load(root): + var ap = global.get_node("Archipelago") + + # Remove the door blocking the trophy case. + root.get_node("/root/scene/Components/Doors/entry_18").queue_free() + + # Set up mastery listeners for extra maps. + _set_up_mastery_listener(root, "advanced") + _set_up_mastery_listener(root, "charismatic") + _set_up_mastery_listener(root, "crystalline") + _set_up_mastery_listener(root, "fuzzy") + _set_up_mastery_listener(root, "icarus") + _set_up_mastery_listener(root, "stellar") + + if ap.endings_requirement != 12 or ap.masteries_requirement != 0: + # Set up listeners for the potential White Ending requirements. + var merging_prefab = preload("res://objects/nodes/listeners/mergingListener.tscn") + + var old_door = root.get_node("/root/scene/Components/Doors/entry_19") + var new_door = old_door.duplicate() + new_door.name = "entry_19_new" + new_door.senders.clear() + new_door.senderGroup.clear() + new_door.excludeSenders.clear() + + if ap.endings_requirement == 12: + new_door.senderGroup.append(NodePath("/root/scene/Meshes/Trophies/Listeners")) + elif ap.endings_requirement > 0: + if ap.masteries_requirement == 0: + new_door.senderGroup.append(NodePath("/root/scene/Meshes/Trophies/Listeners")) + new_door.complete_at = ap.endings_requirement + else: + var endings_merge = merging_prefab.instantiate() + endings_merge.name = "EndingsMerge" + endings_merge.senderGroup.append(NodePath("/root/scene/Meshes/Trophies/Listeners")) + endings_merge.complete_at = ap.endings_requirement + root.get_node("/root/scene/Components").add_child.call_deferred(endings_merge) + new_door.senders.append(NodePath("/root/scene/Components/EndingsMerge")) + + var max_masteries = 13 + ap.enable_gift_maps.size() + if ap.enable_icarus: + max_masteries += 1 + + if ap.masteries_requirement == max_masteries: + new_door.senderGroup.append(NodePath("/root/scene/Meshes/Trophies/MasteryListeners")) + new_door.excludeSenders.append( + NodePath("/root/scene/Meshes/Trophies/MasteryListeners/unlockReaderListenerWhite") + ) + elif ap.masteries_requirement > 0: + if ap.endings_requirement == 0: + new_door.senderGroup.append( + NodePath("/root/scene/Meshes/Trophies/MasteryListeners") + ) + new_door.excludeSenders.append( + NodePath( + "/root/scene/Meshes/Trophies/MasteryListeners/unlockReaderListenerWhite" + ) + ) + new_door.complete_at = ap.masteries_requirement + else: + var masteries_merge = merging_prefab.instantiate() + masteries_merge.name = "MasteriesMerge" + masteries_merge.senderGroup.append( + NodePath("/root/scene/Meshes/Trophies/MasteryListeners") + ) + masteries_merge.excludeSenders.append( + NodePath( + "/root/scene/Meshes/Trophies/MasteryListeners/unlockReaderListenerWhite" + ) + ) + masteries_merge.complete_at = ap.masteries_requirement + root.get_node("/root/scene/Components").add_child.call_deferred(masteries_merge) + new_door.senders.append(NodePath("/root/scene/Components/MasteriesMerge")) + + old_door.queue_free() + root.get_node("/root/scene/Components/Doors").add_child.call_deferred(new_door) + + +func _set_up_mastery_listener(root, name): + var prefab = preload("res://objects/nodes/listeners/unlockReaderListener.tscn") + var url = prefab.instantiate() + url.name = "unlockReaderListenerMastery_%s" % name + url.key = "%s_mastery" % name + url.value = "unlocked" + root.get_node("/root/scene/Meshes/Trophies/MasteryListeners").add_child.call_deferred(url) diff --git a/apworld/client/maps/daedalus.gd b/apworld/client/maps/daedalus.gd new file mode 100644 index 0000000..5fcf7a5 --- /dev/null +++ b/apworld/client/maps/daedalus.gd @@ -0,0 +1,85 @@ +func on_map_load(root): + var ap = global.get_node("Archipelago") + + # Teleport the direction panels when the stairs are there. + var tpl_prefab = preload("res://objects/nodes/listeners/teleportListener.tscn") + + var dir1 = root.get_node("/root/scene/Panels/Castle Entrance/castle_direction_1") + var dir1_tpl = tpl_prefab.instantiate() + dir1_tpl.target_path = dir1 + dir1_tpl.teleport_point = Vector3(59.5, 8, -6.5) + dir1_tpl.teleport_rotate = Vector3(-45, 0, 0) + dir1_tpl.senders.append(NodePath("/root/scene/Panels/Castle Entrance/castle_south")) + dir1_tpl.senders.append(NodePath("/root/scene/Panels/Castle Entrance/castle_north")) + dir1_tpl.senders.append(NodePath("/root/scene/Panels/Castle Entrance/castle_west")) + dir1.add_child.call_deferred(dir1_tpl) + + var dir2 = root.get_node("/root/scene/Panels/Castle Entrance/castle_direction_2") + var dir2_tpl = tpl_prefab.instantiate() + dir2_tpl.target_path = dir2 + dir2_tpl.teleport_point = Vector3(59.5, 8, 6.5) + dir2_tpl.teleport_rotate = Vector3(-45, -180, 0) + dir2_tpl.senders.append(NodePath("/root/scene/Panels/Castle Entrance/castle_south")) + dir2_tpl.senders.append(NodePath("/root/scene/Panels/Castle Entrance/castle_north")) + dir2_tpl.senders.append(NodePath("/root/scene/Panels/Castle Entrance/castle_west")) + dir2.add_child.call_deferred(dir2_tpl) + + var dir3 = root.get_node("/root/scene/Panels/Castle Entrance/castle_direction_3") + var dir3_tpl = tpl_prefab.instantiate() + dir3_tpl.target_path = dir3 + dir3_tpl.teleport_point = Vector3(54, 8, 0) + dir3_tpl.teleport_rotate = Vector3(-45, 90, 0) + dir3_tpl.senders.append(NodePath("/root/scene/Panels/Castle Entrance/castle_south")) + dir3_tpl.senders.append(NodePath("/root/scene/Panels/Castle Entrance/castle_north")) + dir3_tpl.senders.append(NodePath("/root/scene/Panels/Castle Entrance/castle_west")) + dir3.add_child.call_deferred(dir3_tpl) + + # Block off roof access in Daedalus. + if not ap.daedalus_roof_access: + _set_up_invis_wall(root, 75.5, 11, -24.5, 1, 10, 49) + _set_up_invis_wall(root, 51.5, 11, -17, 16, 10, 1) + _set_up_invis_wall(root, 46, 10, -9.5, 1, 10, 10) + _set_up_invis_wall(root, 67.5, 11, 17, 16, 10, 1) + _set_up_invis_wall(root, 50.5, 11, 14, 10, 10, 1) + _set_up_invis_wall(root, 39, 10, 18.5, 1, 10, 22) + _set_up_invis_wall(root, 20, 15, 18.5, 1, 10, 16) + _set_up_invis_wall(root, 11.5, 15, 3, 32, 10, 1) + _set_up_invis_wall(root, 11.5, 16, -20, 14, 20, 1) + _set_up_invis_wall(root, 14, 16, -26.5, 1, 20, 4) + _set_up_invis_wall(root, 28.5, 20.5, -26.5, 1, 15, 25) + _set_up_invis_wall(root, 40.5, 20.5, -11, 30, 15, 1) + _set_up_invis_wall(root, 50.5, 15, 5.5, 7, 10, 1) + _set_up_invis_wall(root, 83.5, 33.5, 5.5, 1, 7, 11) + _set_up_invis_wall(root, 83.5, 33.5, -5.5, 1, 7, 11) + + var warp_exit_prefab = preload("res://objects/nodes/exit.tscn") + var warp_exit = warp_exit_prefab.instantiate() + warp_exit.name = "roof_access_blocker_warp_exit" + warp_exit.position = Vector3(58, 10, 0) + warp_exit.rotation_degrees.y = 90 + root.get_node("/root/scene").add_child.call_deferred(warp_exit) + + var warp_enter_prefab = preload("res://objects/nodes/teleportAuto.tscn") + var warp_enter = warp_enter_prefab.instantiate() + warp_enter.target = warp_exit + warp_enter.position = Vector3(76.5, 30, 1) + warp_enter.scale = Vector3(4, 1.5, 1) + warp_enter.rotation_degrees.y = 90 + root.get_node("/root/scene").add_child.call_deferred(warp_enter) + + +func _set_up_invis_wall(root, x, y, z, sx, sy, sz): + var prefab = preload("res://objects/nodes/block.tscn") + var newwall = prefab.instantiate() + newwall.position.x = x + newwall.position.y = y + newwall.position.z = z + newwall.scale.x = sz + newwall.scale.y = sy + newwall.scale.z = sx + newwall.set_surface_override_material(0, preload("res://assets/materials/blackMatte.material")) + newwall.visibility_range_end = 3 + newwall.visibility_range_end_margin = 1 + newwall.visibility_range_fade_mode = RenderingServer.VISIBILITY_RANGE_FADE_SELF + newwall.skeleton = ".." + root.get_node("/root/scene").add_child.call_deferred(newwall) diff --git a/apworld/client/maps/icarus.gd b/apworld/client/maps/icarus.gd new file mode 100644 index 0000000..ad00741 --- /dev/null +++ b/apworld/client/maps/icarus.gd @@ -0,0 +1,38 @@ +func on_map_load(root): + var ap = global.get_node("Archipelago") + + # Add the mastery to Icarus. + if ap.enable_icarus: + var collectable_prefab = preload("res://objects/nodes/collectable.tscn") + var saver_prefab = preload("res://objects/nodes/saver.tscn") + var tpl_prefab = preload("res://objects/nodes/listeners/teleportListener.tscn") + var usl_prefab = preload("res://objects/nodes/listeners/unlockSetterListener.tscn") + + var mastery = collectable_prefab.instantiate() + mastery.name = "collectable" + mastery.position = Vector3(0, -2000, 0) + mastery.unlock_type = "smiley" + mastery.material_override = load("res://assets/materials/gold.material") + root.get_node("/root/scene/Components/Collectables").add_child.call_deferred(mastery) + + var tpl = tpl_prefab.instantiate() + tpl.teleport_point = Vector3(56.25, 0, -5.5) + tpl.teleport_rotate = Vector3(0, 0, 0) + tpl.target_path = mastery + tpl.name = "Teleport" + tpl.senderGroup.append(NodePath("/root/scene/Panels")) + tpl.nested = true + mastery.add_child.call_deferred(tpl) + + var usl = usl_prefab.instantiate() + usl.name = "unlockSetterListenerMastery" + usl.key = "icarus_mastery" + usl.value = "unlocked" + usl.senders.append(NodePath("/root/scene/Components/Collectables/collectable")) + root.get_node("/root/scene/Components").add_child.call_deferred(usl) + + var saver = saver_prefab.instantiate() + saver.name = "saver_collectables" + saver.type = "collectables" + saver.senderGroup.append(NodePath("/root/scene/Components/Collectables")) + root.get_node("/root/scene").add_child.call_deferred(saver) diff --git a/apworld/client/maps/the_advanced.gd b/apworld/client/maps/the_advanced.gd new file mode 100644 index 0000000..b41549c --- /dev/null +++ b/apworld/client/maps/the_advanced.gd @@ -0,0 +1,36 @@ +func on_map_load(root): + # Add the mastery to The Advanced. + var collectable_prefab = preload("res://objects/nodes/collectable.tscn") + var saver_prefab = preload("res://objects/nodes/saver.tscn") + var tpl_prefab = preload("res://objects/nodes/listeners/teleportListener.tscn") + var usl_prefab = preload("res://objects/nodes/listeners/unlockSetterListener.tscn") + + var mastery = collectable_prefab.instantiate() + mastery.name = "collectable" + mastery.position = Vector3(0, -200, -5) + mastery.unlock_type = "smiley" + mastery.material_override = load("res://assets/materials/gold.material") + root.get_node("/root/scene/Components/Collectables").add_child.call_deferred(mastery) + + var tpl = tpl_prefab.instantiate() + tpl.teleport_point = Vector3(0, 2, -5) + tpl.teleport_rotate = Vector3(0, 0, 0) + tpl.target_path = mastery + tpl.name = "Teleport" + tpl.senders.append(NodePath("/root/scene/Panels/Room_1/panel_29")) + tpl.senders.append(NodePath("/root/scene/Panels/Room_1/panel_30")) + tpl.senders.append(NodePath("/root/scene/Panels/Room_1/panel_31")) + mastery.add_child.call_deferred(tpl) + + var usl = usl_prefab.instantiate() + usl.name = "unlockSetterListenerMastery" + usl.key = "advanced_mastery" + usl.value = "unlocked" + usl.senders.append(NodePath("/root/scene/Components/Collectables/collectable")) + root.get_node("/root/scene/Components").add_child.call_deferred(usl) + + var saver = saver_prefab.instantiate() + saver.name = "saver_collectables" + saver.type = "collectables" + saver.senderGroup.append(NodePath("/root/scene/Components/Collectables")) + root.get_node("/root/scene").add_child.call_deferred(saver) diff --git a/apworld/client/maps/the_charismatic.gd b/apworld/client/maps/the_charismatic.gd new file mode 100644 index 0000000..734001d --- /dev/null +++ b/apworld/client/maps/the_charismatic.gd @@ -0,0 +1,26 @@ +func on_map_load(root): + # Add the mastery to The Charismatic. + var collectable_prefab = preload("res://objects/nodes/collectable.tscn") + var saver_prefab = preload("res://objects/nodes/saver.tscn") + var usl_prefab = preload("res://objects/nodes/listeners/unlockSetterListener.tscn") + + var mastery = collectable_prefab.instantiate() + mastery.name = "collectable" + mastery.position = Vector3(-17, 2, -29) + mastery.rotation_degrees = Vector3(0, 45, 0) + mastery.unlock_type = "smiley" + mastery.material_override = load("res://assets/materials/gold.material") + root.get_node("/root/scene/Components/Collectables").add_child.call_deferred(mastery) + + var usl = usl_prefab.instantiate() + usl.name = "unlockSetterListenerMastery" + usl.key = "charismatic_mastery" + usl.value = "unlocked" + usl.senders.append(NodePath("/root/scene/Components/Collectables/collectable")) + root.get_node("/root/scene/Components").add_child.call_deferred(usl) + + var saver = saver_prefab.instantiate() + saver.name = "saver_collectables" + saver.type = "collectables" + saver.senderGroup.append(NodePath("/root/scene/Components/Collectables")) + root.get_node("/root/scene").add_child.call_deferred(saver) diff --git a/apworld/client/maps/the_crystalline.gd b/apworld/client/maps/the_crystalline.gd new file mode 100644 index 0000000..7d43e78 --- /dev/null +++ b/apworld/client/maps/the_crystalline.gd @@ -0,0 +1,34 @@ +func on_map_load(root): + # Add the mastery to The Crystalline. + var collectable_prefab = preload("res://objects/nodes/collectable.tscn") + var saver_prefab = preload("res://objects/nodes/saver.tscn") + var tpl_prefab = preload("res://objects/nodes/listeners/teleportListener.tscn") + var usl_prefab = preload("res://objects/nodes/listeners/unlockSetterListener.tscn") + + var mastery = collectable_prefab.instantiate() + mastery.name = "collectable" + mastery.position = Vector3(0, 13, 37) + mastery.unlock_type = "smiley" + mastery.material_override = load("res://assets/materials/gold.material") + root.get_node("/root/scene/Components/Collectables").add_child.call_deferred(mastery) + + var tpl = tpl_prefab.instantiate() + tpl.teleport_point = Vector3(0, 11.5, -20) + tpl.teleport_rotate = Vector3(0, 0, 180) + tpl.target_path = mastery + tpl.name = "Teleport" + tpl.senders.append(NodePath("/root/scene/Panels/Room_1/panel_3")) + mastery.add_child.call_deferred(tpl) + + var usl = usl_prefab.instantiate() + usl.name = "unlockSetterListenerMastery" + usl.key = "crystalline_mastery" + usl.value = "unlocked" + usl.senders.append(NodePath("/root/scene/Components/Collectables/collectable")) + root.get_node("/root/scene/Components").add_child.call_deferred(usl) + + var saver = saver_prefab.instantiate() + saver.name = "saver_collectables" + saver.type = "collectables" + saver.senderGroup.append(NodePath("/root/scene/Components/Collectables")) + root.get_node("/root/scene").add_child.call_deferred(saver) diff --git a/apworld/client/maps/the_entry.gd b/apworld/client/maps/the_entry.gd new file mode 100644 index 0000000..3608bb3 --- /dev/null +++ b/apworld/client/maps/the_entry.gd @@ -0,0 +1,156 @@ +func on_map_load(root): + var ap = global.get_node("Archipelago") + + # Remove door behind X1. + var door_node = root.get_node("/root/scene/Components/Doors/exit_1") + door_node.handleTriggered() + + # Display win condition. + var sign_prefab = preload("res://objects/nodes/sign.tscn") + var sign1 = sign_prefab.instantiate() + sign1.position = Vector3(-7, 5, -15.01) + sign1.text = "victory" + root.get_node("/root/scene").add_child.call_deferred(sign1) + + var sign2 = sign_prefab.instantiate() + sign2.position = Vector3(-7, 4, -15.01) + sign2.text = "%s ending" % ap.kEndingNameByVictoryValue.get(ap.victory_condition, "?") + + var sign2_color = ap.kEndingNameByVictoryValue.get(ap.victory_condition, "coral").to_lower() + if sign2_color == "white": + sign2_color = "silver" + + sign2.material = load("res://assets/materials/%s.material" % sign2_color) + root.get_node("/root/scene").add_child.call_deferred(sign2) + + # Add the gift map entry panel if needed. + if not ap.enable_gift_maps.is_empty(): + var panel_prefab = preload("res://objects/nodes/panel.tscn") + var tpl_prefab = preload("res://objects/nodes/listeners/teleportListener.tscn") + var wpl_prefab = preload("res://objects/nodes/listeners/worldportListener.tscn") + + var giftmap_parent = Node.new() + giftmap_parent.name = "GiftMapEntrance" + root.get_node("/root/scene/Components").add_child.call_deferred(giftmap_parent) + + var symbolless_player = "" + for i in range(ap.client.ap_user.length()): + if "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".contains( + ap.client.ap_user[i] + ): + symbolless_player = symbolless_player + ap.client.ap_user[i].to_lower() + + var giftmap_panel = panel_prefab.instantiate() + giftmap_panel.name = "Panel" + giftmap_panel.position = Vector3(33.5, -190, 5.5) + giftmap_panel.rotation_degrees = Vector3(-45, 0, 0) + giftmap_panel.clue = "player" + giftmap_panel.answer = symbolless_player + + if ap.enable_gift_maps.has("The Advanced"): + var icely_panel = panel_prefab.instantiate() + icely_panel.name = "IcelyPanel" + icely_panel.answer = "icely" + icely_panel.position = Vector3(33.5, -200, 5.5) + giftmap_panel.proxies.append(NodePath("../IcelyPanel")) + giftmap_parent.add_child.call_deferred(icely_panel) + + var icely_wpl = wpl_prefab.instantiate() + icely_wpl.name = "IcelyWpl" + icely_wpl.exit = "the_advanced" + icely_wpl.senders.append(NodePath("../IcelyPanel")) + giftmap_parent.add_child.call_deferred(icely_wpl) + + if ap.enable_gift_maps.has("The Charismatic"): + var souvey_panel = panel_prefab.instantiate() + souvey_panel.name = "SouveyPanel" + souvey_panel.answer = "souvey" + souvey_panel.position = Vector3(33.5, -210, 5.5) + giftmap_panel.proxies.append(NodePath("../SouveyPanel")) + giftmap_parent.add_child.call_deferred(souvey_panel) + + var souvey_wpl = wpl_prefab.instantiate() + souvey_wpl.name = "SouveyWpl" + souvey_wpl.exit = "the_charismatic" + souvey_wpl.senders.append(NodePath("../SouveyPanel")) + giftmap_parent.add_child.call_deferred(souvey_wpl) + + if ap.enable_gift_maps.has("The Crystalline"): + var q_panel = panel_prefab.instantiate() + q_panel.name = "QPanel" + q_panel.answer = "q" + q_panel.position = Vector3(33.5, -220, 5.5) + giftmap_panel.proxies.append(NodePath("../QPanel")) + giftmap_parent.add_child.call_deferred(q_panel) + + var q_wpl = wpl_prefab.instantiate() + q_wpl.name = "QWpl" + q_wpl.exit = "the_crystalline" + q_wpl.senders.append(NodePath("../QPanel")) + giftmap_parent.add_child.call_deferred(q_wpl) + + if ap.enable_gift_maps.has("The Fuzzy"): + var gongus_panel = panel_prefab.instantiate() + gongus_panel.name = "GongusPanel" + gongus_panel.answer = "gongus" + gongus_panel.position = Vector3(33.5, -260, 5.5) + giftmap_panel.proxies.append(NodePath("../GongusPanel")) + giftmap_parent.add_child.call_deferred(gongus_panel) + + var kiwi_panel = panel_prefab.instantiate() + kiwi_panel.name = "KiwiPanel" + kiwi_panel.answer = "kiwi" + kiwi_panel.position = Vector3(33.5, -270, 5.5) + giftmap_panel.proxies.append(NodePath("../KiwiPanel")) + giftmap_parent.add_child.call_deferred(kiwi_panel) + + var fuzzy_wpl = wpl_prefab.instantiate() + fuzzy_wpl.name = "FuzzyWpl" + fuzzy_wpl.exit = "the_fuzzy" + fuzzy_wpl.senders.append(NodePath("../GongusPanel")) + fuzzy_wpl.senders.append(NodePath("../KiwiPanel")) + fuzzy_wpl.complete_at = 1 + giftmap_parent.add_child.call_deferred(fuzzy_wpl) + + if ap.enable_gift_maps.has("The Stellar"): + var hatkirby_panel = panel_prefab.instantiate() + hatkirby_panel.name = "HatkirbyPanel" + hatkirby_panel.answer = "hatkirby" + hatkirby_panel.position = Vector3(33.5, -230, 5.5) + giftmap_panel.proxies.append(NodePath("../HatkirbyPanel")) + giftmap_parent.add_child.call_deferred(hatkirby_panel) + + var kirby_panel = panel_prefab.instantiate() + kirby_panel.name = "KirbyPanel" + kirby_panel.answer = "kirby" + kirby_panel.position = Vector3(33.5, -240, 5.5) + giftmap_panel.proxies.append(NodePath("../KirbyPanel")) + giftmap_parent.add_child.call_deferred(kirby_panel) + + var star_panel = panel_prefab.instantiate() + star_panel.name = "StarPanel" + star_panel.answer = "star" + star_panel.position = Vector3(33.5, -250, 5.5) + giftmap_panel.proxies.append(NodePath("../StarPanel")) + giftmap_parent.add_child.call_deferred(star_panel) + + var stellar_wpl = wpl_prefab.instantiate() + stellar_wpl.name = "StellarWpl" + stellar_wpl.exit = "the_stellar" + stellar_wpl.senders.append(NodePath("../HatkirbyPanel")) + stellar_wpl.senders.append(NodePath("../KirbyPanel")) + stellar_wpl.senders.append(NodePath("../StarPanel")) + stellar_wpl.complete_at = 1 + giftmap_parent.add_child.call_deferred(stellar_wpl) + + giftmap_parent.add_child.call_deferred(giftmap_panel) + + var giftmap_tpl = tpl_prefab.instantiate() + giftmap_tpl.name = "PanelTeleporter" + giftmap_tpl.teleport_point = Vector3(33.5, 1, 5.5) + giftmap_tpl.teleport_rotate = Vector3(-45, 0, 0) + giftmap_tpl.target_path = giftmap_panel + giftmap_tpl.senders.append( + NodePath("/root/scene/Components/Listeners/unlockReaderListenerDoubles") + ) + giftmap_parent.add_child.call_deferred(giftmap_tpl) diff --git a/apworld/client/maps/the_fuzzy.gd b/apworld/client/maps/the_fuzzy.gd new file mode 100644 index 0000000..269dcee --- /dev/null +++ b/apworld/client/maps/the_fuzzy.gd @@ -0,0 +1,25 @@ +func on_map_load(root): + # Add the mastery to The Fuzzy. + var collectable_prefab = preload("res://objects/nodes/collectable.tscn") + var saver_prefab = preload("res://objects/nodes/saver.tscn") + var usl_prefab = preload("res://objects/nodes/listeners/unlockSetterListener.tscn") + + var mastery = collectable_prefab.instantiate() + mastery.name = "collectable" + mastery.position = Vector3(0, 2, -20) + mastery.unlock_type = "smiley" + mastery.material_override = load("res://assets/materials/gold.material") + root.get_node("/root/scene/Components/Collectables").add_child.call_deferred(mastery) + + var usl = usl_prefab.instantiate() + usl.name = "unlockSetterListenerMastery" + usl.key = "fuzzy_mastery" + usl.value = "unlocked" + usl.senders.append(NodePath("/root/scene/Components/Collectables/collectable")) + root.get_node("/root/scene/Components").add_child.call_deferred(usl) + + var saver = saver_prefab.instantiate() + saver.name = "saver_collectables" + saver.type = "collectables" + saver.senderGroup.append(NodePath("/root/scene/Components/Collectables")) + root.get_node("/root/scene").add_child.call_deferred(saver) diff --git a/apworld/client/maps/the_parthenon.gd b/apworld/client/maps/the_parthenon.gd new file mode 100644 index 0000000..96510da --- /dev/null +++ b/apworld/client/maps/the_parthenon.gd @@ -0,0 +1,51 @@ +func on_map_load(root): + var ap = global.get_node("Archipelago") + + # Add the strict cyan ending validation. + if ap.strict_cyan_ending: + var panel_prefab = preload("res://objects/nodes/panel.tscn") + var tpl_prefab = preload("res://objects/nodes/listeners/teleportListener.tscn") + var reverse_prefab = preload("res://objects/nodes/listeners/reversingListener.tscn") + + var previous_panel = null + var next_y = -100 + var words = ["quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog"] + for word in words: + var panel = panel_prefab.instantiate() + panel.position = Vector3(0, next_y, 0) + next_y -= 10 + panel.clue = word + panel.symbol = "." + panel.answer = "%s%s" % [word, word] + panel.name = "EndCheck_%s" % word + + var tpl = tpl_prefab.instantiate() + tpl.teleport_point = Vector3(0, 1, -11) + tpl.teleport_rotate = Vector3(-45, 0, 0) + tpl.target_path = panel + tpl.name = "Teleport" + + if previous_panel == null: + tpl.senderGroup.append(NodePath("/root/scene/Panels/Rulers")) + else: + tpl.senders.append(NodePath("../../%s" % previous_panel.name)) + + var reversing = reverse_prefab.instantiate() + reversing.senders.append(NodePath("..")) + reversing.name = "Reversing" + tpl.senders.append(NodePath("../Reversing")) + + panel.add_child.call_deferred(tpl) + panel.add_child.call_deferred(reversing) + root.get_node("/root/scene/Panels").add_child.call_deferred(panel) + + previous_panel = panel + + # Duplicate the door that usually waits on the rulers. We can't set the + # senders here for some reason so we actually set them in the door ready + # function. + var entry1 = root.get_node("/root/scene/Components/Doors/entry_1") + var entry12 = entry1.duplicate() + entry12.name = "spe_entry_1" + entry1.get_parent().add_child.call_deferred(entry12) + entry1.queue_free() diff --git a/apworld/client/maps/the_plaza.gd b/apworld/client/maps/the_plaza.gd new file mode 100644 index 0000000..13e002d --- /dev/null +++ b/apworld/client/maps/the_plaza.gd @@ -0,0 +1,4 @@ +func on_map_load(root): + # Move the Plaza RTE trigger outside of the turtle. + var rte_trigger = root.get_node("/root/scene/Components/Warps/triggerArea") + rte_trigger.position.z = 0 diff --git a/apworld/client/maps/the_stellar.gd b/apworld/client/maps/the_stellar.gd new file mode 100644 index 0000000..d633535 --- /dev/null +++ b/apworld/client/maps/the_stellar.gd @@ -0,0 +1,30 @@ +func on_map_load(root): + # Add the mastery to The Stellar. + var collectable_prefab = preload("res://objects/nodes/collectable.tscn") + var saver_prefab = preload("res://objects/nodes/saver.tscn") + var usl_prefab = preload("res://objects/nodes/listeners/unlockSetterListener.tscn") + + var collectables = Node.new() + collectables.name = "Collectables" + + var mastery = collectable_prefab.instantiate() + mastery.name = "collectable" + mastery.position = Vector3(2, 2, -31) + mastery.rotation_degrees = Vector3(0, 90, 0) + mastery.unlock_type = "smiley" + mastery.material_override = load("res://assets/materials/gold.material") + collectables.add_child.call_deferred(mastery) + root.get_node("/root/scene/Components").add_child.call_deferred(collectables) + + var usl = usl_prefab.instantiate() + usl.name = "unlockSetterListenerMastery" + usl.key = "stellar_mastery" + usl.value = "unlocked" + usl.senders.append(NodePath("/root/scene/Components/Collectables/collectable")) + root.get_node("/root/scene/Components").add_child.call_deferred(usl) + + var saver = saver_prefab.instantiate() + saver.name = "saver_collectables" + saver.type = "collectables" + saver.senderGroup.append(NodePath("/root/scene/Components/Collectables")) + root.get_node("/root/scene").add_child.call_deferred(saver) diff --git a/apworld/client/maps/the_sun_temple.gd b/apworld/client/maps/the_sun_temple.gd new file mode 100644 index 0000000..9804bf8 --- /dev/null +++ b/apworld/client/maps/the_sun_temple.gd @@ -0,0 +1,56 @@ +func on_map_load(root): + var ap = global.get_node("Archipelago") + + # Add the strict purple ending validation. + if ap.strict_purple_ending: + var panel_prefab = preload("res://objects/nodes/panel.tscn") + var tpl_prefab = preload("res://objects/nodes/listeners/teleportListener.tscn") + var reverse_prefab = preload("res://objects/nodes/listeners/reversingListener.tscn") + + var previous_panel = null + var next_y = -100 + var words = ["quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog"] + for word in words: + var panel = panel_prefab.instantiate() + panel.position = Vector3(0, next_y, 0) + next_y -= 10 + panel.clue = word + panel.symbol = "" + panel.answer = word + panel.name = "EndCheck_%s" % word + + var tpl = tpl_prefab.instantiate() + tpl.teleport_point = Vector3(0, 1, 0) + tpl.teleport_rotate = Vector3(-45, 180, 0) + tpl.target_path = panel + tpl.name = "Teleport" + + if previous_panel == null: + tpl.senders.append(NodePath("/root/scene/Panels/End/panel_24")) + else: + tpl.senders.append(NodePath("../../%s" % previous_panel.name)) + + var reversing = reverse_prefab.instantiate() + reversing.senders.append(NodePath("..")) + reversing.name = "Reversing" + tpl.senders.append(NodePath("../Reversing")) + + panel.add_child.call_deferred(tpl) + panel.add_child.call_deferred(reversing) + root.get_node("/root/scene/Panels").add_child.call_deferred(panel) + + previous_panel = panel + + # Duplicate the doors that usually wait on EQUINOX. We can't set the senders + # here for some reason so we actually set them in the door ready function. + var endplat = root.get_node("/root/scene/Components/Doors/EndPlatform") + var endplat2 = endplat.duplicate() + endplat2.name = "spe_EndPlatform" + endplat.get_parent().add_child.call_deferred(endplat2) + endplat.queue_free() + + var entry2 = root.get_node("/root/scene/Components/Doors/entry_2") + var entry22 = entry2.duplicate() + entry22.name = "spe_entry_2" + entry2.get_parent().add_child.call_deferred(entry22) + entry2.queue_free() diff --git a/apworld/client/maps/the_unyielding.gd b/apworld/client/maps/the_unyielding.gd new file mode 100644 index 0000000..a2f8eee --- /dev/null +++ b/apworld/client/maps/the_unyielding.gd @@ -0,0 +1,5 @@ +func on_map_load(root): + # Shrink the painting trigger in The Unyielding. + var trigger_area = root.get_node("/root/scene/Components/PaintingUnlocker/triggerArea") + trigger_area.position = Vector3(0, 0, -6) + trigger_area.scale = Vector3(6, 1, 6) diff --git a/apworld/client/player.gd b/apworld/client/player.gd index 65bf54e..5fac9fd 100644 --- a/apworld/client/player.gd +++ b/apworld/client/player.gd @@ -19,612 +19,10 @@ func _ready(): ap.start_batching_locations() - if global.map == "control_center": - get_node("/root/scene/Components/Doors/entry_18").queue_free() - - _set_up_mastery_listener("advanced") - _set_up_mastery_listener("charismatic") - _set_up_mastery_listener("crystalline") - _set_up_mastery_listener("fuzzy") - _set_up_mastery_listener("icarus") - _set_up_mastery_listener("stellar") - - if ap.endings_requirement != 12 or ap.masteries_requirement != 0: - # Set up listeners for the potential White Ending requirements. - var merging_prefab = preload("res://objects/nodes/listeners/mergingListener.tscn") - - var old_door = get_node("/root/scene/Components/Doors/entry_19") - var new_door = old_door.duplicate() - new_door.name = "entry_19_new" - new_door.senders.clear() - new_door.senderGroup.clear() - new_door.excludeSenders.clear() - - if ap.endings_requirement == 12: - new_door.senderGroup.append(NodePath("/root/scene/Meshes/Trophies/Listeners")) - elif ap.endings_requirement > 0: - if ap.masteries_requirement == 0: - new_door.senderGroup.append(NodePath("/root/scene/Meshes/Trophies/Listeners")) - new_door.complete_at = ap.endings_requirement - else: - var endings_merge = merging_prefab.instantiate() - endings_merge.name = "EndingsMerge" - endings_merge.senderGroup.append( - NodePath("/root/scene/Meshes/Trophies/Listeners") - ) - endings_merge.complete_at = ap.endings_requirement - get_node("/root/scene/Components").add_child.call_deferred(endings_merge) - new_door.senders.append(NodePath("/root/scene/Components/EndingsMerge")) - - var max_masteries = 13 + ap.enable_gift_maps.size() - if ap.enable_icarus: - max_masteries += 1 - - if ap.masteries_requirement == max_masteries: - new_door.senderGroup.append( - NodePath("/root/scene/Meshes/Trophies/MasteryListeners") - ) - new_door.excludeSenders.append( - NodePath( - "/root/scene/Meshes/Trophies/MasteryListeners/unlockReaderListenerWhite" - ) - ) - elif ap.masteries_requirement > 0: - if ap.endings_requirement == 0: - new_door.senderGroup.append( - NodePath("/root/scene/Meshes/Trophies/MasteryListeners") - ) - new_door.excludeSenders.append( - NodePath( - "/root/scene/Meshes/Trophies/MasteryListeners/unlockReaderListenerWhite" - ) - ) - new_door.complete_at = ap.masteries_requirement - else: - var masteries_merge = merging_prefab.instantiate() - masteries_merge.name = "MasteriesMerge" - masteries_merge.senderGroup.append( - NodePath("/root/scene/Meshes/Trophies/MasteryListeners") - ) - masteries_merge.excludeSenders.append( - NodePath( - "/root/scene/Meshes/Trophies/MasteryListeners/unlockReaderListenerWhite" - ) - ) - masteries_merge.complete_at = ap.masteries_requirement - get_node("/root/scene/Components").add_child.call_deferred(masteries_merge) - new_door.senders.append(NodePath("/root/scene/Components/MasteriesMerge")) - - old_door.queue_free() - get_node("/root/scene/Components/Doors").add_child.call_deferred(new_door) - - if global.map == "daedalus": - # Teleport the direction panels when the stairs are there. - var tpl_prefab = preload("res://objects/nodes/listeners/teleportListener.tscn") - - var dir1 = get_node("/root/scene/Panels/Castle Entrance/castle_direction_1") - var dir1_tpl = tpl_prefab.instantiate() - dir1_tpl.target_path = dir1 - dir1_tpl.teleport_point = Vector3(59.5, 8, -6.5) - dir1_tpl.teleport_rotate = Vector3(-45, 0, 0) - dir1_tpl.senders.append(NodePath("/root/scene/Panels/Castle Entrance/castle_south")) - dir1_tpl.senders.append(NodePath("/root/scene/Panels/Castle Entrance/castle_north")) - dir1_tpl.senders.append(NodePath("/root/scene/Panels/Castle Entrance/castle_west")) - dir1.add_child.call_deferred(dir1_tpl) - - var dir2 = get_node("/root/scene/Panels/Castle Entrance/castle_direction_2") - var dir2_tpl = tpl_prefab.instantiate() - dir2_tpl.target_path = dir2 - dir2_tpl.teleport_point = Vector3(59.5, 8, 6.5) - dir2_tpl.teleport_rotate = Vector3(-45, -180, 0) - dir2_tpl.senders.append(NodePath("/root/scene/Panels/Castle Entrance/castle_south")) - dir2_tpl.senders.append(NodePath("/root/scene/Panels/Castle Entrance/castle_north")) - dir2_tpl.senders.append(NodePath("/root/scene/Panels/Castle Entrance/castle_west")) - dir2.add_child.call_deferred(dir2_tpl) - - var dir3 = get_node("/root/scene/Panels/Castle Entrance/castle_direction_3") - var dir3_tpl = tpl_prefab.instantiate() - dir3_tpl.target_path = dir3 - dir3_tpl.teleport_point = Vector3(54, 8, 0) - dir3_tpl.teleport_rotate = Vector3(-45, 90, 0) - dir3_tpl.senders.append(NodePath("/root/scene/Panels/Castle Entrance/castle_south")) - dir3_tpl.senders.append(NodePath("/root/scene/Panels/Castle Entrance/castle_north")) - dir3_tpl.senders.append(NodePath("/root/scene/Panels/Castle Entrance/castle_west")) - dir3.add_child.call_deferred(dir3_tpl) - - # Block off roof access in Daedalus. - if not ap.daedalus_roof_access: - _set_up_invis_wall(75.5, 11, -24.5, 1, 10, 49) - _set_up_invis_wall(51.5, 11, -17, 16, 10, 1) - _set_up_invis_wall(46, 10, -9.5, 1, 10, 10) - _set_up_invis_wall(67.5, 11, 17, 16, 10, 1) - _set_up_invis_wall(50.5, 11, 14, 10, 10, 1) - _set_up_invis_wall(39, 10, 18.5, 1, 10, 22) - _set_up_invis_wall(20, 15, 18.5, 1, 10, 16) - _set_up_invis_wall(11.5, 15, 3, 32, 10, 1) - _set_up_invis_wall(11.5, 16, -20, 14, 20, 1) - _set_up_invis_wall(14, 16, -26.5, 1, 20, 4) - _set_up_invis_wall(28.5, 20.5, -26.5, 1, 15, 25) - _set_up_invis_wall(40.5, 20.5, -11, 30, 15, 1) - _set_up_invis_wall(50.5, 15, 5.5, 7, 10, 1) - _set_up_invis_wall(83.5, 33.5, 5.5, 1, 7, 11) - _set_up_invis_wall(83.5, 33.5, -5.5, 1, 7, 11) - - var warp_exit_prefab = preload("res://objects/nodes/exit.tscn") - var warp_exit = warp_exit_prefab.instantiate() - warp_exit.name = "roof_access_blocker_warp_exit" - warp_exit.position = Vector3(58, 10, 0) - warp_exit.rotation_degrees.y = 90 - get_parent().add_child.call_deferred(warp_exit) - - var warp_enter_prefab = preload("res://objects/nodes/teleportAuto.tscn") - var warp_enter = warp_enter_prefab.instantiate() - warp_enter.target = warp_exit - warp_enter.position = Vector3(76.5, 30, 1) - warp_enter.scale = Vector3(4, 1.5, 1) - warp_enter.rotation_degrees.y = 90 - get_parent().add_child.call_deferred(warp_enter) - - if global.map == "the_entry": - # Remove door behind X1. - var door_node = get_tree().get_root().get_node("/root/scene/Components/Doors/exit_1") - door_node.handleTriggered() - - # Display win condition. - var sign_prefab = preload("res://objects/nodes/sign.tscn") - var sign1 = sign_prefab.instantiate() - sign1.position = Vector3(-7, 5, -15.01) - sign1.text = "victory" - get_parent().add_child.call_deferred(sign1) - - var sign2 = sign_prefab.instantiate() - sign2.position = Vector3(-7, 4, -15.01) - sign2.text = "%s ending" % ap.kEndingNameByVictoryValue.get(ap.victory_condition, "?") - - var sign2_color = ap.kEndingNameByVictoryValue.get(ap.victory_condition, "coral").to_lower() - if sign2_color == "white": - sign2_color = "silver" - - sign2.material = load("res://assets/materials/%s.material" % sign2_color) - get_parent().add_child.call_deferred(sign2) - - # Add the gift map entry panel if needed. - if not ap.enable_gift_maps.is_empty(): - var panel_prefab = preload("res://objects/nodes/panel.tscn") - var tpl_prefab = preload("res://objects/nodes/listeners/teleportListener.tscn") - var wpl_prefab = preload("res://objects/nodes/listeners/worldportListener.tscn") - - var giftmap_parent = Node.new() - giftmap_parent.name = "GiftMapEntrance" - get_node("/root/scene/Components").add_child.call_deferred(giftmap_parent) - - var symbolless_player = "" - for i in range(ap.client.ap_user.length()): - if "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".contains( - ap.client.ap_user[i] - ): - symbolless_player = symbolless_player + ap.client.ap_user[i].to_lower() - - var giftmap_panel = panel_prefab.instantiate() - giftmap_panel.name = "Panel" - giftmap_panel.position = Vector3(33.5, -190, 5.5) - giftmap_panel.rotation_degrees = Vector3(-45, 0, 0) - giftmap_panel.clue = "player" - giftmap_panel.answer = symbolless_player - - if ap.enable_gift_maps.has("The Advanced"): - var icely_panel = panel_prefab.instantiate() - icely_panel.name = "IcelyPanel" - icely_panel.answer = "icely" - icely_panel.position = Vector3(33.5, -200, 5.5) - giftmap_panel.proxies.append(NodePath("../IcelyPanel")) - giftmap_parent.add_child.call_deferred(icely_panel) - - var icely_wpl = wpl_prefab.instantiate() - icely_wpl.name = "IcelyWpl" - icely_wpl.exit = "the_advanced" - icely_wpl.senders.append(NodePath("../IcelyPanel")) - giftmap_parent.add_child.call_deferred(icely_wpl) - - if ap.enable_gift_maps.has("The Charismatic"): - var souvey_panel = panel_prefab.instantiate() - souvey_panel.name = "SouveyPanel" - souvey_panel.answer = "souvey" - souvey_panel.position = Vector3(33.5, -210, 5.5) - giftmap_panel.proxies.append(NodePath("../SouveyPanel")) - giftmap_parent.add_child.call_deferred(souvey_panel) - - var souvey_wpl = wpl_prefab.instantiate() - souvey_wpl.name = "SouveyWpl" - souvey_wpl.exit = "the_charismatic" - souvey_wpl.senders.append(NodePath("../SouveyPanel")) - giftmap_parent.add_child.call_deferred(souvey_wpl) - - if ap.enable_gift_maps.has("The Crystalline"): - var q_panel = panel_prefab.instantiate() - q_panel.name = "QPanel" - q_panel.answer = "q" - q_panel.position = Vector3(33.5, -220, 5.5) - giftmap_panel.proxies.append(NodePath("../QPanel")) - giftmap_parent.add_child.call_deferred(q_panel) - - var q_wpl = wpl_prefab.instantiate() - q_wpl.name = "QWpl" - q_wpl.exit = "the_crystalline" - q_wpl.senders.append(NodePath("../QPanel")) - giftmap_parent.add_child.call_deferred(q_wpl) - - if ap.enable_gift_maps.has("The Fuzzy"): - var gongus_panel = panel_prefab.instantiate() - gongus_panel.name = "GongusPanel" - gongus_panel.answer = "gongus" - gongus_panel.position = Vector3(33.5, -260, 5.5) - giftmap_panel.proxies.append(NodePath("../GongusPanel")) - giftmap_parent.add_child.call_deferred(gongus_panel) - - var kiwi_panel = panel_prefab.instantiate() - kiwi_panel.name = "KiwiPanel" - kiwi_panel.answer = "kiwi" - kiwi_panel.position = Vector3(33.5, -270, 5.5) - giftmap_panel.proxies.append(NodePath("../KiwiPanel")) - giftmap_parent.add_child.call_deferred(kiwi_panel) - - var fuzzy_wpl = wpl_prefab.instantiate() - fuzzy_wpl.name = "FuzzyWpl" - fuzzy_wpl.exit = "the_fuzzy" - fuzzy_wpl.senders.append(NodePath("../GongusPanel")) - fuzzy_wpl.senders.append(NodePath("../KiwiPanel")) - fuzzy_wpl.complete_at = 1 - giftmap_parent.add_child.call_deferred(fuzzy_wpl) - - if ap.enable_gift_maps.has("The Stellar"): - var hatkirby_panel = panel_prefab.instantiate() - hatkirby_panel.name = "HatkirbyPanel" - hatkirby_panel.answer = "hatkirby" - hatkirby_panel.position = Vector3(33.5, -230, 5.5) - giftmap_panel.proxies.append(NodePath("../HatkirbyPanel")) - giftmap_parent.add_child.call_deferred(hatkirby_panel) - - var kirby_panel = panel_prefab.instantiate() - kirby_panel.name = "KirbyPanel" - kirby_panel.answer = "kirby" - kirby_panel.position = Vector3(33.5, -240, 5.5) - giftmap_panel.proxies.append(NodePath("../KirbyPanel")) - giftmap_parent.add_child.call_deferred(kirby_panel) - - var star_panel = panel_prefab.instantiate() - star_panel.name = "StarPanel" - star_panel.answer = "star" - star_panel.position = Vector3(33.5, -250, 5.5) - giftmap_panel.proxies.append(NodePath("../StarPanel")) - giftmap_parent.add_child.call_deferred(star_panel) - - var stellar_wpl = wpl_prefab.instantiate() - stellar_wpl.name = "StellarWpl" - stellar_wpl.exit = "the_stellar" - stellar_wpl.senders.append(NodePath("../HatkirbyPanel")) - stellar_wpl.senders.append(NodePath("../KirbyPanel")) - stellar_wpl.senders.append(NodePath("../StarPanel")) - stellar_wpl.complete_at = 1 - giftmap_parent.add_child.call_deferred(stellar_wpl) - - giftmap_parent.add_child.call_deferred(giftmap_panel) - - var giftmap_tpl = tpl_prefab.instantiate() - giftmap_tpl.name = "PanelTeleporter" - giftmap_tpl.teleport_point = Vector3(33.5, 1, 5.5) - giftmap_tpl.teleport_rotate = Vector3(-45, 0, 0) - giftmap_tpl.target_path = giftmap_panel - giftmap_tpl.senders.append( - NodePath("/root/scene/Components/Listeners/unlockReaderListenerDoubles") - ) - giftmap_parent.add_child.call_deferred(giftmap_tpl) - - # Add the strict purple ending validation. - if global.map == "the_sun_temple" and ap.strict_purple_ending: - var panel_prefab = preload("res://objects/nodes/panel.tscn") - var tpl_prefab = preload("res://objects/nodes/listeners/teleportListener.tscn") - var reverse_prefab = preload("res://objects/nodes/listeners/reversingListener.tscn") - - var previous_panel = null - var next_y = -100 - var words = ["quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog"] - for word in words: - var panel = panel_prefab.instantiate() - panel.position = Vector3(0, next_y, 0) - next_y -= 10 - panel.clue = word - panel.symbol = "" - panel.answer = word - panel.name = "EndCheck_%s" % word - - var tpl = tpl_prefab.instantiate() - tpl.teleport_point = Vector3(0, 1, 0) - tpl.teleport_rotate = Vector3(-45, 180, 0) - tpl.target_path = panel - tpl.name = "Teleport" - - if previous_panel == null: - tpl.senders.append(NodePath("/root/scene/Panels/End/panel_24")) - else: - tpl.senders.append(NodePath("../../%s" % previous_panel.name)) - - var reversing = reverse_prefab.instantiate() - reversing.senders.append(NodePath("..")) - reversing.name = "Reversing" - tpl.senders.append(NodePath("../Reversing")) - - panel.add_child.call_deferred(tpl) - panel.add_child.call_deferred(reversing) - get_parent().get_node("Panels").add_child.call_deferred(panel) - - previous_panel = panel - - # Duplicate the doors that usually wait on EQUINOX. We can't set the senders - # here for some reason so we actually set them in the door ready function. - var endplat = get_node("/root/scene/Components/Doors/EndPlatform") - var endplat2 = endplat.duplicate() - endplat2.name = "spe_EndPlatform" - endplat.get_parent().add_child.call_deferred(endplat2) - endplat.queue_free() - - var entry2 = get_node("/root/scene/Components/Doors/entry_2") - var entry22 = entry2.duplicate() - entry22.name = "spe_entry_2" - entry2.get_parent().add_child.call_deferred(entry22) - entry2.queue_free() - - # Add the strict cyan ending validation. - if global.map == "the_parthenon" and ap.strict_cyan_ending: - var panel_prefab = preload("res://objects/nodes/panel.tscn") - var tpl_prefab = preload("res://objects/nodes/listeners/teleportListener.tscn") - var reverse_prefab = preload("res://objects/nodes/listeners/reversingListener.tscn") - - var previous_panel = null - var next_y = -100 - var words = ["quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog"] - for word in words: - var panel = panel_prefab.instantiate() - panel.position = Vector3(0, next_y, 0) - next_y -= 10 - panel.clue = word - panel.symbol = "." - panel.answer = "%s%s" % [word, word] - panel.name = "EndCheck_%s" % word - - var tpl = tpl_prefab.instantiate() - tpl.teleport_point = Vector3(0, 1, -11) - tpl.teleport_rotate = Vector3(-45, 0, 0) - tpl.target_path = panel - tpl.name = "Teleport" - - if previous_panel == null: - tpl.senderGroup.append(NodePath("/root/scene/Panels/Rulers")) - else: - tpl.senders.append(NodePath("../../%s" % previous_panel.name)) - - var reversing = reverse_prefab.instantiate() - reversing.senders.append(NodePath("..")) - reversing.name = "Reversing" - tpl.senders.append(NodePath("../Reversing")) - - panel.add_child.call_deferred(tpl) - panel.add_child.call_deferred(reversing) - get_parent().get_node("Panels").add_child.call_deferred(panel) - - previous_panel = panel - - # Duplicate the door that usually waits on the rulers. We can't set the - # senders here for some reason so we actually set them in the door ready - # function. - var entry1 = get_node("/root/scene/Components/Doors/entry_1") - var entry12 = entry1.duplicate() - entry12.name = "spe_entry_1" - entry1.get_parent().add_child.call_deferred(entry12) - entry1.queue_free() - - # Move the Plaza RTE trigger outside of the turtle. - if global.map == "the_plaza": - var rte_trigger = get_node("/root/scene/Components/Warps/triggerArea") - rte_trigger.position.z = 0 - - # Add the mastery to Icarus. - if global.map == "icarus" and ap.enable_icarus: - var collectable_prefab = preload("res://objects/nodes/collectable.tscn") - var saver_prefab = preload("res://objects/nodes/saver.tscn") - var tpl_prefab = preload("res://objects/nodes/listeners/teleportListener.tscn") - var usl_prefab = preload("res://objects/nodes/listeners/unlockSetterListener.tscn") - - var mastery = collectable_prefab.instantiate() - mastery.name = "collectable" - mastery.position = Vector3(0, -2000, 0) - mastery.unlock_type = "smiley" - mastery.material_override = load("res://assets/materials/gold.material") - get_node("/root/scene/Components/Collectables").add_child.call_deferred(mastery) - - var tpl = tpl_prefab.instantiate() - tpl.teleport_point = Vector3(56.25, 0, -5.5) - tpl.teleport_rotate = Vector3(0, 0, 0) - tpl.target_path = mastery - tpl.name = "Teleport" - tpl.senderGroup.append(NodePath("/root/scene/Panels")) - tpl.nested = true - mastery.add_child.call_deferred(tpl) - - var usl = usl_prefab.instantiate() - usl.name = "unlockSetterListenerMastery" - usl.key = "icarus_mastery" - usl.value = "unlocked" - usl.senders.append(NodePath("/root/scene/Components/Collectables/collectable")) - get_node("/root/scene/Components").add_child.call_deferred(usl) - - var saver = saver_prefab.instantiate() - saver.name = "saver_collectables" - saver.type = "collectables" - saver.senderGroup.append(NodePath("/root/scene/Components/Collectables")) - get_node("/root/scene").add_child.call_deferred(saver) - - # Add the mastery to The Advanced. - if global.map == "the_advanced": - var collectable_prefab = preload("res://objects/nodes/collectable.tscn") - var saver_prefab = preload("res://objects/nodes/saver.tscn") - var tpl_prefab = preload("res://objects/nodes/listeners/teleportListener.tscn") - var usl_prefab = preload("res://objects/nodes/listeners/unlockSetterListener.tscn") - - var mastery = collectable_prefab.instantiate() - mastery.name = "collectable" - mastery.position = Vector3(0, -200, -5) - mastery.unlock_type = "smiley" - mastery.material_override = load("res://assets/materials/gold.material") - get_node("/root/scene/Components/Collectables").add_child.call_deferred(mastery) - - var tpl = tpl_prefab.instantiate() - tpl.teleport_point = Vector3(0, 2, -5) - tpl.teleport_rotate = Vector3(0, 0, 0) - tpl.target_path = mastery - tpl.name = "Teleport" - tpl.senders.append(NodePath("/root/scene/Panels/Room_1/panel_29")) - tpl.senders.append(NodePath("/root/scene/Panels/Room_1/panel_30")) - tpl.senders.append(NodePath("/root/scene/Panels/Room_1/panel_31")) - mastery.add_child.call_deferred(tpl) - - var usl = usl_prefab.instantiate() - usl.name = "unlockSetterListenerMastery" - usl.key = "advanced_mastery" - usl.value = "unlocked" - usl.senders.append(NodePath("/root/scene/Components/Collectables/collectable")) - get_node("/root/scene/Components").add_child.call_deferred(usl) - - var saver = saver_prefab.instantiate() - saver.name = "saver_collectables" - saver.type = "collectables" - saver.senderGroup.append(NodePath("/root/scene/Components/Collectables")) - get_node("/root/scene").add_child.call_deferred(saver) - - # Add the mastery to The Charismatic. - if global.map == "the_charismatic": - var collectable_prefab = preload("res://objects/nodes/collectable.tscn") - var saver_prefab = preload("res://objects/nodes/saver.tscn") - var usl_prefab = preload("res://objects/nodes/listeners/unlockSetterListener.tscn") - - var mastery = collectable_prefab.instantiate() - mastery.name = "collectable" - mastery.position = Vector3(-17, 2, -29) - mastery.rotation_degrees = Vector3(0, 45, 0) - mastery.unlock_type = "smiley" - mastery.material_override = load("res://assets/materials/gold.material") - get_node("/root/scene/Components/Collectables").add_child.call_deferred(mastery) - - var usl = usl_prefab.instantiate() - usl.name = "unlockSetterListenerMastery" - usl.key = "charismatic_mastery" - usl.value = "unlocked" - usl.senders.append(NodePath("/root/scene/Components/Collectables/collectable")) - get_node("/root/scene/Components").add_child.call_deferred(usl) - - var saver = saver_prefab.instantiate() - saver.name = "saver_collectables" - saver.type = "collectables" - saver.senderGroup.append(NodePath("/root/scene/Components/Collectables")) - get_node("/root/scene").add_child.call_deferred(saver) - - # Add the mastery to The Crystalline. - if global.map == "the_crystalline": - var collectable_prefab = preload("res://objects/nodes/collectable.tscn") - var saver_prefab = preload("res://objects/nodes/saver.tscn") - var tpl_prefab = preload("res://objects/nodes/listeners/teleportListener.tscn") - var usl_prefab = preload("res://objects/nodes/listeners/unlockSetterListener.tscn") - - var mastery = collectable_prefab.instantiate() - mastery.name = "collectable" - mastery.position = Vector3(0, 13, 37) - mastery.unlock_type = "smiley" - mastery.material_override = load("res://assets/materials/gold.material") - get_node("/root/scene/Components/Collectables").add_child.call_deferred(mastery) - - var tpl = tpl_prefab.instantiate() - tpl.teleport_point = Vector3(0, 11.5, -20) - tpl.teleport_rotate = Vector3(0, 0, 180) - tpl.target_path = mastery - tpl.name = "Teleport" - tpl.senders.append(NodePath("/root/scene/Panels/Room_1/panel_3")) - mastery.add_child.call_deferred(tpl) - - var usl = usl_prefab.instantiate() - usl.name = "unlockSetterListenerMastery" - usl.key = "crystalline_mastery" - usl.value = "unlocked" - usl.senders.append(NodePath("/root/scene/Components/Collectables/collectable")) - get_node("/root/scene/Components").add_child.call_deferred(usl) - - var saver = saver_prefab.instantiate() - saver.name = "saver_collectables" - saver.type = "collectables" - saver.senderGroup.append(NodePath("/root/scene/Components/Collectables")) - get_node("/root/scene").add_child.call_deferred(saver) - - # Add the mastery to The Fuzzy. - if global.map == "the_fuzzy": - var collectable_prefab = preload("res://objects/nodes/collectable.tscn") - var saver_prefab = preload("res://objects/nodes/saver.tscn") - var usl_prefab = preload("res://objects/nodes/listeners/unlockSetterListener.tscn") - - var mastery = collectable_prefab.instantiate() - mastery.name = "collectable" - mastery.position = Vector3(0, 2, -20) - mastery.unlock_type = "smiley" - mastery.material_override = load("res://assets/materials/gold.material") - get_node("/root/scene/Components/Collectables").add_child.call_deferred(mastery) - - var usl = usl_prefab.instantiate() - usl.name = "unlockSetterListenerMastery" - usl.key = "fuzzy_mastery" - usl.value = "unlocked" - usl.senders.append(NodePath("/root/scene/Components/Collectables/collectable")) - get_node("/root/scene/Components").add_child.call_deferred(usl) - - var saver = saver_prefab.instantiate() - saver.name = "saver_collectables" - saver.type = "collectables" - saver.senderGroup.append(NodePath("/root/scene/Components/Collectables")) - get_node("/root/scene").add_child.call_deferred(saver) - - # Add the mastery to The Stellar. - if global.map == "the_stellar": - var collectable_prefab = preload("res://objects/nodes/collectable.tscn") - var saver_prefab = preload("res://objects/nodes/saver.tscn") - var usl_prefab = preload("res://objects/nodes/listeners/unlockSetterListener.tscn") - - var collectables = Node.new() - collectables.name = "Collectables" - - var mastery = collectable_prefab.instantiate() - mastery.name = "collectable" - mastery.position = Vector3(2, 2, -31) - mastery.rotation_degrees = Vector3(0, 90, 0) - mastery.unlock_type = "smiley" - mastery.material_override = load("res://assets/materials/gold.material") - collectables.add_child.call_deferred(mastery) - get_node("/root/scene/Components").add_child.call_deferred(collectables) - - var usl = usl_prefab.instantiate() - usl.name = "unlockSetterListenerMastery" - usl.key = "stellar_mastery" - usl.value = "unlocked" - usl.senders.append(NodePath("/root/scene/Components/Collectables/collectable")) - get_node("/root/scene/Components").add_child.call_deferred(usl) - - var saver = saver_prefab.instantiate() - saver.name = "saver_collectables" - saver.type = "collectables" - saver.senderGroup.append(NodePath("/root/scene/Components/Collectables")) - get_node("/root/scene").add_child.call_deferred(saver) - - # Shrink the painting trigger in The Unyielding. - if global.map == "the_unyielding": - var trigger_area = get_node("/root/scene/Components/PaintingUnlocker/triggerArea") - trigger_area.position = Vector3(0, 0, -6) - trigger_area.scale = Vector3(6, 1, 6) + # Run map-specific initialization. + var map_script = ap.get_map_script(global.map) + if map_script != null: + map_script.on_map_load(get_tree().get_root()) ap.update_job_well_done_sign() @@ -779,31 +177,5 @@ func _ready(): ap.stop_batching_locations() -func _set_up_invis_wall(x, y, z, sx, sy, sz): - var prefab = preload("res://objects/nodes/block.tscn") - var newwall = prefab.instantiate() - newwall.position.x = x - newwall.position.y = y - newwall.position.z = z - newwall.scale.x = sz - newwall.scale.y = sy - newwall.scale.z = sx - newwall.set_surface_override_material(0, preload("res://assets/materials/blackMatte.material")) - newwall.visibility_range_end = 3 - newwall.visibility_range_end_margin = 1 - newwall.visibility_range_fade_mode = RenderingServer.VISIBILITY_RANGE_FADE_SELF - newwall.skeleton = ".." - get_parent().add_child.call_deferred(newwall) - - -func _set_up_mastery_listener(name): - var prefab = preload("res://objects/nodes/listeners/unlockReaderListener.tscn") - var url = prefab.instantiate() - url.name = "unlockReaderListenerMastery_%s" % name - url.key = "%s_mastery" % name - url.value = "unlocked" - get_node("/root/scene/Meshes/Trophies/MasteryListeners").add_child.call_deferred(url) - - func _process(_dt): compass.update_rotation(global_rotation.y) diff --git a/apworld/client/source_runtime.gd b/apworld/client/source_runtime.gd index 35428ea..146587a 100644 --- a/apworld/client/source_runtime.gd +++ b/apworld/client/source_runtime.gd @@ -7,6 +7,10 @@ func _init(path): source_path = path +func path_exists(path): + return FileAccess.file_exists("%s/%s" % [source_path, path]) + + func load_script(path): return ResourceLoader.load("%s/%s" % [source_path, path]) -- cgit 1.4.1