diff options
Diffstat (limited to 'client/Archipelago')
| -rw-r--r-- | client/Archipelago/client.gd | 6 | ||||
| -rw-r--r-- | client/Archipelago/compass.gd | 66 | ||||
| -rw-r--r-- | client/Archipelago/compass_overlay.gd | 17 | ||||
| -rw-r--r-- | client/Archipelago/door.gd | 8 | ||||
| -rw-r--r-- | client/Archipelago/gamedata.gd | 7 | ||||
| -rw-r--r-- | client/Archipelago/keyboard.gd | 25 | ||||
| -rw-r--r-- | client/Archipelago/manager.gd | 36 | ||||
| -rw-r--r-- | client/Archipelago/messages.gd | 18 | ||||
| -rw-r--r-- | client/Archipelago/pauseMenu.gd | 32 | ||||
| -rw-r--r-- | client/Archipelago/player.gd | 148 | ||||
| -rw-r--r-- | client/Archipelago/saver.gd | 14 | ||||
| -rw-r--r-- | client/Archipelago/settings_screen.gd | 48 | ||||
| -rw-r--r-- | client/Archipelago/teleport.gd | 38 | ||||
| -rw-r--r-- | client/Archipelago/teleportListener.gd | 11 | ||||
| -rw-r--r-- | client/Archipelago/worldport.gd | 10 | ||||
| -rw-r--r-- | client/Archipelago/worldportListener.gd | 4 |
16 files changed, 472 insertions, 16 deletions
| diff --git a/client/Archipelago/client.gd b/client/Archipelago/client.gd index 2e080fd..843647d 100644 --- a/client/Archipelago/client.gd +++ b/client/Archipelago/client.gd | |||
| @@ -47,6 +47,8 @@ signal location_scout_received(item_id, location_id, player, flags) | |||
| 47 | func _init(): | 47 | func _init(): |
| 48 | set_process_mode(Node.PROCESS_MODE_ALWAYS) | 48 | set_process_mode(Node.PROCESS_MODE_ALWAYS) |
| 49 | 49 | ||
| 50 | _ws.inbound_buffer_size = 8388608 | ||
| 51 | |||
| 50 | global._print("Instantiated APClient") | 52 | global._print("Instantiated APClient") |
| 51 | 53 | ||
| 52 | # Read AP datapackages from file, if there are any | 54 | # Read AP datapackages from file, if there are any |
| @@ -225,7 +227,7 @@ func _process(_delta): | |||
| 225 | error_message = "Unknown error." | 227 | error_message = "Unknown error." |
| 226 | 228 | ||
| 227 | _initiated_disconnect = true | 229 | _initiated_disconnect = true |
| 228 | _ws.disconnect_from_host() | 230 | _ws.close() |
| 229 | 231 | ||
| 230 | emit_signal("could_not_connect", error_message) | 232 | emit_signal("could_not_connect", error_message) |
| 231 | global._print("Connection to AP refused") | 233 | global._print("Connection to AP refused") |
| @@ -309,7 +311,7 @@ func connectToServer(server, un, pw): | |||
| 309 | % err | 311 | % err |
| 310 | ) | 312 | ) |
| 311 | ) | 313 | ) |
| 312 | global._print("Could not connect to AP: " + err) | 314 | global._print("Could not connect to AP: %d" % err) |
| 313 | return | 315 | return |
| 314 | _should_process = true | 316 | _should_process = true |
| 315 | 317 | ||
| diff --git a/client/Archipelago/compass.gd b/client/Archipelago/compass.gd new file mode 100644 index 0000000..c90475a --- /dev/null +++ b/client/Archipelago/compass.gd | |||
| @@ -0,0 +1,66 @@ | |||
| 1 | extends Node2D | ||
| 2 | |||
| 3 | const RADIUS = 48 | ||
| 4 | |||
| 5 | var _font | ||
| 6 | |||
| 7 | |||
| 8 | func _ready(): | ||
| 9 | _font = load("res://assets/fonts/Lingo2.ttf") | ||
| 10 | |||
| 11 | |||
| 12 | func _draw(): | ||
| 13 | draw_circle(Vector2.ZERO, RADIUS, Color(1.0, 1.0, 1.0, 0.8), true) | ||
| 14 | draw_circle(Vector2.ZERO, RADIUS, Color.BLACK, false) | ||
| 15 | draw_string( | ||
| 16 | _font, | ||
| 17 | Vector2(-4, -RADIUS * 3.0 / 4.0), | ||
| 18 | "N", | ||
| 19 | HorizontalAlignment.HORIZONTAL_ALIGNMENT_LEFT, | ||
| 20 | -1, | ||
| 21 | 16, | ||
| 22 | Color.BLACK | ||
| 23 | ) | ||
| 24 | draw_set_transform(Vector2.ZERO, PI / 2) | ||
| 25 | draw_string( | ||
| 26 | _font, | ||
| 27 | Vector2(-4, -RADIUS * 3.0 / 4.0), | ||
| 28 | "E", | ||
| 29 | HorizontalAlignment.HORIZONTAL_ALIGNMENT_LEFT, | ||
| 30 | -1, | ||
| 31 | 16, | ||
| 32 | Color.BLACK | ||
| 33 | ) | ||
| 34 | draw_set_transform(Vector2.ZERO, PI) | ||
| 35 | draw_string( | ||
| 36 | _font, | ||
| 37 | Vector2(-4, -RADIUS * 3.0 / 4.0), | ||
| 38 | "S", | ||
| 39 | HorizontalAlignment.HORIZONTAL_ALIGNMENT_LEFT, | ||
| 40 | -1, | ||
| 41 | 16, | ||
| 42 | Color.BLACK | ||
| 43 | ) | ||
| 44 | draw_set_transform(Vector2.ZERO, PI * 3.0 / 2.0) | ||
| 45 | draw_string( | ||
| 46 | _font, | ||
| 47 | Vector2(-4, -RADIUS * 3.0 / 4.0), | ||
| 48 | "W", | ||
| 49 | HorizontalAlignment.HORIZONTAL_ALIGNMENT_LEFT, | ||
| 50 | -1, | ||
| 51 | 16, | ||
| 52 | Color.BLACK | ||
| 53 | ) | ||
| 54 | draw_set_transform(Vector2.ZERO) | ||
| 55 | draw_colored_polygon( | ||
| 56 | PackedVector2Array( | ||
| 57 | [Vector2(0, -RADIUS * 5.0 / 8.0), Vector2(-RADIUS / 6.0, 0), Vector2(RADIUS / 6.0, 0)] | ||
| 58 | ), | ||
| 59 | Color.RED | ||
| 60 | ) | ||
| 61 | draw_colored_polygon( | ||
| 62 | PackedVector2Array( | ||
| 63 | [Vector2(0, RADIUS * 5.0 / 8.0), Vector2(-RADIUS / 6.0, 0), Vector2(RADIUS / 6.0, 0)] | ||
| 64 | ), | ||
| 65 | Color.GRAY | ||
| 66 | ) | ||
| diff --git a/client/Archipelago/compass_overlay.gd b/client/Archipelago/compass_overlay.gd new file mode 100644 index 0000000..56e81ff --- /dev/null +++ b/client/Archipelago/compass_overlay.gd | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | extends CanvasLayer | ||
| 2 | |||
| 3 | var SCRIPT_compass | ||
| 4 | |||
| 5 | var compass | ||
| 6 | |||
| 7 | |||
| 8 | func _ready(): | ||
| 9 | compass = SCRIPT_compass.new() | ||
| 10 | compass.position = Vector2(1840, 80) | ||
| 11 | add_child(compass) | ||
| 12 | |||
| 13 | visible = false | ||
| 14 | |||
| 15 | |||
| 16 | func update_rotation(ry): | ||
| 17 | compass.rotation = ry | ||
| diff --git a/client/Archipelago/door.gd b/client/Archipelago/door.gd index fead818..49f5728 100644 --- a/client/Archipelago/door.gd +++ b/client/Archipelago/door.gd | |||
| @@ -28,6 +28,14 @@ func _ready(): | |||
| 28 | 28 | ||
| 29 | call_deferred("_readier") | 29 | call_deferred("_readier") |
| 30 | 30 | ||
| 31 | if global.map == "the_sun_temple": | ||
| 32 | if name == "spe_EndPlatform" or name == "spe_entry_2": | ||
| 33 | senders = [NodePath("/root/scene/Panels/EndCheck_dog")] | ||
| 34 | |||
| 35 | if global.map == "the_parthenon": | ||
| 36 | if name == "spe_entry_1": | ||
| 37 | senders = [NodePath("/root/scene/Panels/EndCheck_dog")] | ||
| 38 | |||
| 31 | super._ready() | 39 | super._ready() |
| 32 | 40 | ||
| 33 | 41 | ||
| diff --git a/client/Archipelago/gamedata.gd b/client/Archipelago/gamedata.gd index d8d16ed..41d966a 100644 --- a/client/Archipelago/gamedata.gd +++ b/client/Archipelago/gamedata.gd | |||
| @@ -11,6 +11,7 @@ var map_id_by_name = {} | |||
| 11 | var progressive_id_by_ap_id = {} | 11 | var progressive_id_by_ap_id = {} |
| 12 | var letter_id_by_ap_id = {} | 12 | var letter_id_by_ap_id = {} |
| 13 | var symbol_item_ids = [] | 13 | var symbol_item_ids = [] |
| 14 | var anti_trap_ids = {} | ||
| 14 | 15 | ||
| 15 | var kSYMBOL_ITEMS | 16 | var kSYMBOL_ITEMS |
| 16 | 17 | ||
| @@ -97,6 +98,12 @@ func load(data_bytes): | |||
| 97 | for symbol_name in kSYMBOL_ITEMS.values(): | 98 | for symbol_name in kSYMBOL_ITEMS.values(): |
| 98 | symbol_item_ids.append(objects.get_special_ids()[symbol_name]) | 99 | symbol_item_ids.append(objects.get_special_ids()[symbol_name]) |
| 99 | 100 | ||
| 101 | for special_name in objects.get_special_ids().keys(): | ||
| 102 | if special_name.begins_with("Anti "): | ||
| 103 | anti_trap_ids[objects.get_special_ids()[special_name]] = ( | ||
| 104 | special_name.substr(5).to_lower() | ||
| 105 | ) | ||
| 106 | |||
| 100 | 107 | ||
| 101 | func get_door_for_map_node_path(map_name, node_path): | 108 | func get_door_for_map_node_path(map_name, node_path): |
| 102 | if not door_id_by_map_node_path.has(map_name): | 109 | if not door_id_by_map_node_path.has(map_name): |
| diff --git a/client/Archipelago/keyboard.gd b/client/Archipelago/keyboard.gd index 600a047..450566d 100644 --- a/client/Archipelago/keyboard.gd +++ b/client/Archipelago/keyboard.gd | |||
| @@ -4,6 +4,7 @@ const kALL_LETTERS = "abcdefghjiklmnopqrstuvwxyz" | |||
| 4 | 4 | ||
| 5 | var letters_saved = {} | 5 | var letters_saved = {} |
| 6 | var letters_in_keyholders = [] | 6 | var letters_in_keyholders = [] |
| 7 | var letters_blocked = [] | ||
| 7 | var letters_dynamic = {} | 8 | var letters_dynamic = {} |
| 8 | var keyholder_state = {} | 9 | var keyholder_state = {} |
| 9 | 10 | ||
| @@ -17,6 +18,7 @@ func _init(): | |||
| 17 | func reset(): | 18 | func reset(): |
| 18 | letters_saved.clear() | 19 | letters_saved.clear() |
| 19 | letters_in_keyholders.clear() | 20 | letters_in_keyholders.clear() |
| 21 | letters_blocked.clear() | ||
| 20 | letters_dynamic.clear() | 22 | letters_dynamic.clear() |
| 21 | keyholder_state.clear() | 23 | keyholder_state.clear() |
| 22 | 24 | ||
| @@ -91,6 +93,9 @@ func update_unlocks(): | |||
| 91 | level = 2 | 93 | level = 2 |
| 92 | has_doubles = true | 94 | has_doubles = true |
| 93 | 95 | ||
| 96 | if letters_blocked.has(k): | ||
| 97 | level = 0 | ||
| 98 | |||
| 94 | unlocks.unlockKey(k, level) | 99 | unlocks.unlockKey(k, level) |
| 95 | 100 | ||
| 96 | if has_doubles and unlocks.data["double_letters"] != "unlocked": | 101 | if has_doubles and unlocks.data["double_letters"] != "unlocked": |
| @@ -105,6 +110,9 @@ func collect_local_letter(key, level): | |||
| 105 | 110 | ||
| 106 | letters_saved[key] = level | 111 | letters_saved[key] = level |
| 107 | 112 | ||
| 113 | if letters_blocked.has(key): | ||
| 114 | letters_blocked.erase(key) | ||
| 115 | |||
| 108 | update_unlocks() | 116 | update_unlocks() |
| 109 | save() | 117 | save() |
| 110 | 118 | ||
| @@ -115,6 +123,9 @@ func collect_remote_letter(key, level): | |||
| 115 | 123 | ||
| 116 | letters_dynamic[key] = level | 124 | letters_dynamic[key] = level |
| 117 | 125 | ||
| 126 | if letters_blocked.has(key): | ||
| 127 | letters_blocked.erase(key) | ||
| 128 | |||
| 118 | update_unlocks() | 129 | update_unlocks() |
| 119 | save() | 130 | save() |
| 120 | 131 | ||
| @@ -148,6 +159,13 @@ func remove_from_keyholder(key, map, kh_path): | |||
| 148 | save() | 159 | save() |
| 149 | 160 | ||
| 150 | 161 | ||
| 162 | func block_letter(key): | ||
| 163 | if not letters_blocked.has(key): | ||
| 164 | letters_blocked.append(key) | ||
| 165 | |||
| 166 | update_unlocks() | ||
| 167 | |||
| 168 | |||
| 151 | func load_keyholders(map): | 169 | func load_keyholders(map): |
| 152 | if keyholder_state.has(map): | 170 | if keyholder_state.has(map): |
| 153 | var khs = keyholder_state[map] | 171 | var khs = keyholder_state[map] |
| @@ -160,9 +178,11 @@ func load_keyholders(map): | |||
| 160 | 178 | ||
| 161 | 179 | ||
| 162 | func reset_keyholders(): | 180 | func reset_keyholders(): |
| 163 | if letters_in_keyholders.is_empty(): | 181 | if letters_in_keyholders.is_empty() and letters_blocked.is_empty(): |
| 164 | return false | 182 | return false |
| 165 | 183 | ||
| 184 | var cleared_anything = not letters_in_keyholders.is_empty() or not letters_blocked.is_empty() | ||
| 185 | |||
| 166 | if keyholder_state.has(global.map): | 186 | if keyholder_state.has(global.map): |
| 167 | for path in keyholder_state[global.map]: | 187 | for path in keyholder_state[global.map]: |
| 168 | get_tree().get_root().get_node("scene").get_node(path).setFromAp( | 188 | get_tree().get_root().get_node("scene").get_node(path).setFromAp( |
| @@ -171,8 +191,9 @@ func reset_keyholders(): | |||
| 171 | 191 | ||
| 172 | keyholder_state.clear() | 192 | keyholder_state.clear() |
| 173 | letters_in_keyholders.clear() | 193 | letters_in_keyholders.clear() |
| 194 | letters_blocked.clear() | ||
| 174 | 195 | ||
| 175 | update_unlocks() | 196 | update_unlocks() |
| 176 | save() | 197 | save() |
| 177 | 198 | ||
| 178 | return true | 199 | return cleared_anything |
| diff --git a/client/Archipelago/manager.gd b/client/Archipelago/manager.gd index 6eea2bd..218870c 100644 --- a/client/Archipelago/manager.gd +++ b/client/Archipelago/manager.gd | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | extends Node | 1 | extends Node |
| 2 | 2 | ||
| 3 | const MOD_VERSION = 0 | 3 | const MOD_VERSION = 7 |
| 4 | 4 | ||
| 5 | var SCRIPT_client | 5 | var SCRIPT_client |
| 6 | var SCRIPT_keyboard | 6 | var SCRIPT_keyboard |
| @@ -12,6 +12,7 @@ var ap_server = "" | |||
| 12 | var ap_user = "" | 12 | var ap_user = "" |
| 13 | var ap_pass = "" | 13 | var ap_pass = "" |
| 14 | var connection_history = [] | 14 | var connection_history = [] |
| 15 | var show_compass = false | ||
| 15 | 16 | ||
| 16 | var client | 17 | var client |
| 17 | var keyboard | 18 | var keyboard |
| @@ -41,13 +42,17 @@ const kCYAN_DOOR_BEHAVIOR_H2 = 0 | |||
| 41 | const kCYAN_DOOR_BEHAVIOR_DOUBLE_LETTER = 1 | 42 | const kCYAN_DOOR_BEHAVIOR_DOUBLE_LETTER = 1 |
| 42 | const kCYAN_DOOR_BEHAVIOR_ITEM = 2 | 43 | const kCYAN_DOOR_BEHAVIOR_ITEM = 2 |
| 43 | 44 | ||
| 45 | var apworld_version = [0, 0] | ||
| 44 | var cyan_door_behavior = kCYAN_DOOR_BEHAVIOR_H2 | 46 | var cyan_door_behavior = kCYAN_DOOR_BEHAVIOR_H2 |
| 45 | var daedalus_roof_access = false | 47 | var daedalus_roof_access = false |
| 46 | var keyholder_sanity = false | 48 | var keyholder_sanity = false |
| 47 | var shuffle_control_center_colors = false | 49 | var shuffle_control_center_colors = false |
| 48 | var shuffle_doors = false | 50 | var shuffle_doors = false |
| 51 | var shuffle_gallery_paintings = false | ||
| 49 | var shuffle_letters = kSHUFFLE_LETTERS_VANILLA | 52 | var shuffle_letters = kSHUFFLE_LETTERS_VANILLA |
| 50 | var shuffle_symbols = false | 53 | var shuffle_symbols = false |
| 54 | var strict_cyan_ending = false | ||
| 55 | var strict_purple_ending = false | ||
| 51 | var victory_condition = -1 | 56 | var victory_condition = -1 |
| 52 | 57 | ||
| 53 | signal could_not_connect | 58 | signal could_not_connect |
| @@ -78,6 +83,9 @@ func _init(): | |||
| 78 | if data.size() > 3: | 83 | if data.size() > 3: |
| 79 | connection_history = data[3] | 84 | connection_history = data[3] |
| 80 | 85 | ||
| 86 | if data.size() > 4: | ||
| 87 | show_compass = data[4] | ||
| 88 | |||
| 81 | 89 | ||
| 82 | func _ready(): | 90 | func _ready(): |
| 83 | client = SCRIPT_client.new() | 91 | client = SCRIPT_client.new() |
| @@ -106,6 +114,7 @@ func saveSettings(): | |||
| 106 | ap_user, | 114 | ap_user, |
| 107 | ap_pass, | 115 | ap_pass, |
| 108 | connection_history, | 116 | connection_history, |
| 117 | show_compass, | ||
| 109 | ] | 118 | ] |
| 110 | file.store_var(data, true) | 119 | file.store_var(data, true) |
| 111 | file.close() | 120 | file.close() |
| @@ -213,6 +222,9 @@ func _process_item(item, index, from, flags, amount): | |||
| 213 | "Received [color=%s]%s[/color] from %s" % [item_color, full_item_name, player_name] | 222 | "Received [color=%s]%s[/color] from %s" % [item_color, full_item_name, player_name] |
| 214 | ) | 223 | ) |
| 215 | 224 | ||
| 225 | if gamedata.anti_trap_ids.has(item): | ||
| 226 | keyboard.block_letter(gamedata.anti_trap_ids[item]) | ||
| 227 | |||
| 216 | global._print(message) | 228 | global._print(message) |
| 217 | 229 | ||
| 218 | global.get_node("Messages").showMessage(message) | 230 | global.get_node("Messages").showMessage(message) |
| @@ -307,6 +319,10 @@ func parse_printjson_for_textclient(message): | |||
| 307 | func _process_location_scout(item_id, location_id, player, flags): | 319 | func _process_location_scout(item_id, location_id, player, flags): |
| 308 | _location_scouts[location_id] = {"item": item_id, "player": player, "flags": flags} | 320 | _location_scouts[location_id] = {"item": item_id, "player": player, "flags": flags} |
| 309 | 321 | ||
| 322 | if player == client._slot and flags & 4 != 0: | ||
| 323 | # This is a trap for us, so let's not display it. | ||
| 324 | return | ||
| 325 | |||
| 310 | var gamedata = global.get_node("Gamedata") | 326 | var gamedata = global.get_node("Gamedata") |
| 311 | var map_id = gamedata.map_id_by_name.get(global.map) | 327 | var map_id = gamedata.map_id_by_name.get(global.map) |
| 312 | 328 | ||
| @@ -327,8 +343,8 @@ func _process_location_scout(item_id, location_id, player, flags): | |||
| 327 | collectable.setScoutedText(item_name) | 343 | collectable.setScoutedText(item_name) |
| 328 | 344 | ||
| 329 | 345 | ||
| 330 | func _client_could_not_connect(): | 346 | func _client_could_not_connect(message): |
| 331 | emit_signal("could_not_connect") | 347 | emit_signal("could_not_connect", message) |
| 332 | 348 | ||
| 333 | 349 | ||
| 334 | func _client_connect_status(message): | 350 | func _client_connect_status(message): |
| @@ -361,10 +377,16 @@ func _client_connected(slot_data): | |||
| 361 | keyholder_sanity = bool(slot_data.get("keyholder_sanity", false)) | 377 | keyholder_sanity = bool(slot_data.get("keyholder_sanity", false)) |
| 362 | shuffle_control_center_colors = bool(slot_data.get("shuffle_control_center_colors", false)) | 378 | shuffle_control_center_colors = bool(slot_data.get("shuffle_control_center_colors", false)) |
| 363 | shuffle_doors = bool(slot_data.get("shuffle_doors", false)) | 379 | shuffle_doors = bool(slot_data.get("shuffle_doors", false)) |
| 380 | shuffle_gallery_paintings = bool(slot_data.get("shuffle_gallery_paintings", false)) | ||
| 364 | shuffle_letters = int(slot_data.get("shuffle_letters", 0)) | 381 | shuffle_letters = int(slot_data.get("shuffle_letters", 0)) |
| 365 | shuffle_symbols = bool(slot_data.get("shuffle_symbols", false)) | 382 | shuffle_symbols = bool(slot_data.get("shuffle_symbols", false)) |
| 383 | strict_cyan_ending = bool(slot_data.get("strict_cyan_ending", false)) | ||
| 384 | strict_purple_ending = bool(slot_data.get("strict_purple_ending", false)) | ||
| 366 | victory_condition = int(slot_data.get("victory_condition", 0)) | 385 | victory_condition = int(slot_data.get("victory_condition", 0)) |
| 367 | 386 | ||
| 387 | if slot_data.has("version"): | ||
| 388 | apworld_version = [int(slot_data["version"][0]), int(slot_data["version"][1])] | ||
| 389 | |||
| 368 | # Set up item locks. | 390 | # Set up item locks. |
| 369 | _item_locks = {} | 391 | _item_locks = {} |
| 370 | 392 | ||
| @@ -399,6 +421,11 @@ func _client_connected(slot_data): | |||
| 399 | for door in door_group.get_doors(): | 421 | for door in door_group.get_doors(): |
| 400 | _item_locks[door] = [door_group.get_ap_id(), 1] | 422 | _item_locks[door] = [door_group.get_ap_id(), 1] |
| 401 | 423 | ||
| 424 | if shuffle_gallery_paintings: | ||
| 425 | for door in gamedata.objects.get_doors(): | ||
| 426 | if door.get_type() == gamedata.SCRIPT_proto.DoorType.GALLERY_PAINTING: | ||
| 427 | _item_locks[door.get_id()] = [door.get_ap_id(), 1] | ||
| 428 | |||
| 402 | if cyan_door_behavior == kCYAN_DOOR_BEHAVIOR_ITEM: | 429 | if cyan_door_behavior == kCYAN_DOOR_BEHAVIOR_ITEM: |
| 403 | for door_group in gamedata.objects.get_door_groups(): | 430 | for door_group in gamedata.objects.get_door_groups(): |
| 404 | if door_group.get_type() == gamedata.SCRIPT_proto.DoorGroupType.CYAN_DOORS: | 431 | if door_group.get_type() == gamedata.SCRIPT_proto.DoorGroupType.CYAN_DOORS: |
| @@ -511,4 +538,7 @@ func _process_key_item(key, level): | |||
| 511 | _held_letters[key] = max(_held_letters.get(key, 0), level) | 538 | _held_letters[key] = max(_held_letters.get(key, 0), level) |
| 512 | return | 539 | return |
| 513 | 540 | ||
| 541 | if shuffle_letters == kSHUFFLE_LETTERS_ITEM_CYAN: | ||
| 542 | level += 1 | ||
| 543 | |||
| 514 | keyboard.collect_remote_letter(key, level) | 544 | keyboard.collect_remote_letter(key, level) |
| diff --git a/client/Archipelago/messages.gd b/client/Archipelago/messages.gd index 52f38b9..82fdbc4 100644 --- a/client/Archipelago/messages.gd +++ b/client/Archipelago/messages.gd | |||
| @@ -48,10 +48,11 @@ func showMessage(text): | |||
| 48 | while !_ordered_labels.is_empty(): | 48 | while !_ordered_labels.is_empty(): |
| 49 | await get_tree().create_timer(timeout).timeout | 49 | await get_tree().create_timer(timeout).timeout |
| 50 | 50 | ||
| 51 | var to_remove = _ordered_labels.pop_front() | 51 | if !_ordered_labels.is_empty(): |
| 52 | var to_tween = get_tree().create_tween().bind_node(to_remove) | 52 | var to_remove = _ordered_labels.pop_front() |
| 53 | to_tween.tween_property(to_remove, "modulate:a", 0.0, 0.5) | 53 | var to_tween = get_tree().create_tween().bind_node(to_remove) |
| 54 | to_tween.tween_callback(to_remove.queue_free) | 54 | to_tween.tween_property(to_remove, "modulate:a", 0.0, 0.5) |
| 55 | to_tween.tween_callback(to_remove.queue_free) | ||
| 55 | 56 | ||
| 56 | if !_message_queue.is_empty(): | 57 | if !_message_queue.is_empty(): |
| 57 | var next_msg = _message_queue.pop_front() | 58 | var next_msg = _message_queue.pop_front() |
| @@ -59,3 +60,12 @@ func showMessage(text): | |||
| 59 | 60 | ||
| 60 | if timeout > 4: | 61 | if timeout > 4: |
| 61 | timeout -= 3 | 62 | timeout -= 3 |
| 63 | |||
| 64 | |||
| 65 | func clear(): | ||
| 66 | _message_queue.clear() | ||
| 67 | |||
| 68 | for message_label in _ordered_labels: | ||
| 69 | message_label.queue_free() | ||
| 70 | |||
| 71 | _ordered_labels.clear() | ||
| diff --git a/client/Archipelago/pauseMenu.gd b/client/Archipelago/pauseMenu.gd index 5da114a..cd1813c 100644 --- a/client/Archipelago/pauseMenu.gd +++ b/client/Archipelago/pauseMenu.gd | |||
| @@ -1,5 +1,26 @@ | |||
| 1 | extends "res://scripts/ui/pauseMenu.gd" | 1 | extends "res://scripts/ui/pauseMenu.gd" |
| 2 | 2 | ||
| 3 | var compass_button | ||
| 4 | |||
| 5 | |||
| 6 | func _ready(): | ||
| 7 | var ap_panel = Panel.new() | ||
| 8 | ap_panel.name = "Archipelago" | ||
| 9 | get_node("menu/settings/settingsInner/TabContainer").add_child(ap_panel) | ||
| 10 | |||
| 11 | var ap = global.get_node("Archipelago") | ||
| 12 | |||
| 13 | compass_button = CheckBox.new() | ||
| 14 | compass_button.text = "show compass" | ||
| 15 | compass_button.button_pressed = ap.show_compass | ||
| 16 | compass_button.position = Vector2(65, 100) | ||
| 17 | compass_button.theme = preload("res://assets/themes/baseUI.tres") | ||
| 18 | compass_button.add_theme_font_size_override("font_size", 60) | ||
| 19 | compass_button.pressed.connect(_toggle_compass) | ||
| 20 | ap_panel.add_child(compass_button) | ||
| 21 | |||
| 22 | super._ready() | ||
| 23 | |||
| 3 | 24 | ||
| 4 | func _pause_game(): | 25 | func _pause_game(): |
| 5 | global.get_node("Textclient").dismiss() | 26 | global.get_node("Textclient").dismiss() |
| @@ -9,4 +30,15 @@ func _pause_game(): | |||
| 9 | func _main_menu(): | 30 | func _main_menu(): |
| 10 | global.loaded = false | 31 | global.loaded = false |
| 11 | global.get_node("Archipelago").disconnect_from_ap() | 32 | global.get_node("Archipelago").disconnect_from_ap() |
| 33 | global.get_node("Messages").clear() | ||
| 34 | global.get_node("Compass").visible = false | ||
| 12 | super._main_menu() | 35 | super._main_menu() |
| 36 | |||
| 37 | |||
| 38 | func _toggle_compass(): | ||
| 39 | var ap = global.get_node("Archipelago") | ||
| 40 | ap.show_compass = compass_button.button_pressed | ||
| 41 | ap.saveSettings() | ||
| 42 | |||
| 43 | var compass = global.get_node("Compass") | ||
| 44 | compass.visible = compass_button.button_pressed | ||
| diff --git a/client/Archipelago/player.gd b/client/Archipelago/player.gd index 4b995bc..538830f 100644 --- a/client/Archipelago/player.gd +++ b/client/Archipelago/player.gd | |||
| @@ -18,6 +18,8 @@ const kEndingNameByVictoryValue = { | |||
| 18 | 18 | ||
| 19 | signal evaluate_solvability | 19 | signal evaluate_solvability |
| 20 | 20 | ||
| 21 | var compass | ||
| 22 | |||
| 21 | 23 | ||
| 22 | func _ready(): | 24 | func _ready(): |
| 23 | var khl_script = load("res://scripts/nodes/keyHolderListener.gd") | 25 | var khl_script = load("res://scripts/nodes/keyHolderListener.gd") |
| @@ -25,6 +27,9 @@ func _ready(): | |||
| 25 | var ap = global.get_node("Archipelago") | 27 | var ap = global.get_node("Archipelago") |
| 26 | var gamedata = global.get_node("Gamedata") | 28 | var gamedata = global.get_node("Gamedata") |
| 27 | 29 | ||
| 30 | compass = global.get_node("Compass") | ||
| 31 | compass.visible = ap.show_compass | ||
| 32 | |||
| 28 | ap.start_batching_locations() | 33 | ap.start_batching_locations() |
| 29 | 34 | ||
| 30 | # Set up door locations. | 35 | # Set up door locations. |
| @@ -36,7 +41,10 @@ func _ready(): | |||
| 36 | if not door.has_ap_id(): | 41 | if not door.has_ap_id(): |
| 37 | continue | 42 | continue |
| 38 | 43 | ||
| 39 | if door.get_type() == gamedata.SCRIPT_proto.DoorType.ITEM_ONLY: | 44 | if ( |
| 45 | door.get_type() == gamedata.SCRIPT_proto.DoorType.ITEM_ONLY | ||
| 46 | or door.get_type() == gamedata.SCRIPT_proto.DoorType.GALLERY_PAINTING | ||
| 47 | ): | ||
| 40 | continue | 48 | continue |
| 41 | 49 | ||
| 42 | var locationListener = ap.SCRIPT_locationListener.new() | 50 | var locationListener = ap.SCRIPT_locationListener.new() |
| @@ -68,6 +76,12 @@ func _ready(): | |||
| 68 | 76 | ||
| 69 | locationListener.senders.append(NodePath("../" + khl.name)) | 77 | locationListener.senders.append(NodePath("../" + khl.name)) |
| 70 | 78 | ||
| 79 | for sender in door.get_senders(): | ||
| 80 | locationListener.senders.append(NodePath("/root/scene/" + sender)) | ||
| 81 | |||
| 82 | if door.has_complete_at(): | ||
| 83 | locationListener.complete_at = door.get_complete_at() | ||
| 84 | |||
| 71 | get_parent().add_child.call_deferred(locationListener) | 85 | get_parent().add_child.call_deferred(locationListener) |
| 72 | 86 | ||
| 73 | # Set up letter locations. | 87 | # Set up letter locations. |
| @@ -88,7 +102,10 @@ func _ready(): | |||
| 88 | != ap.kLETTER_BEHAVIOR_VANILLA | 102 | != ap.kLETTER_BEHAVIOR_VANILLA |
| 89 | ): | 103 | ): |
| 90 | var scout = ap.scout_location(letter.get_ap_id()) | 104 | var scout = ap.scout_location(letter.get_ap_id()) |
| 91 | if scout != null: | 105 | if ( |
| 106 | scout != null | ||
| 107 | and not (scout["player"] == ap.client._slot and scout["flags"] & 4 != 0) | ||
| 108 | ): | ||
| 92 | var item_name = "Unknown" | 109 | var item_name = "Unknown" |
| 93 | var item_player_game = ap.client._game_by_player[float(scout["player"])] | 110 | var item_player_game = ap.client._game_by_player[float(scout["player"])] |
| 94 | if ap.client._item_id_to_name[item_player_game].has(scout["item"]): | 111 | if ap.client._item_id_to_name[item_player_game].has(scout["item"]): |
| @@ -190,11 +207,132 @@ func _ready(): | |||
| 190 | warp_enter.rotation_degrees.y = 90 | 207 | warp_enter.rotation_degrees.y = 90 |
| 191 | get_parent().add_child.call_deferred(warp_enter) | 208 | get_parent().add_child.call_deferred(warp_enter) |
| 192 | 209 | ||
| 193 | # Remove door behind X1. | ||
| 194 | if global.map == "the_entry": | 210 | if global.map == "the_entry": |
| 211 | # Remove door behind X1. | ||
| 195 | var door_node = get_tree().get_root().get_node("/root/scene/Components/Doors/exit_1") | 212 | var door_node = get_tree().get_root().get_node("/root/scene/Components/Doors/exit_1") |
| 196 | door_node.handleTriggered() | 213 | door_node.handleTriggered() |
| 197 | 214 | ||
| 215 | # Display win condition. | ||
| 216 | var sign_prefab = preload("res://objects/nodes/sign.tscn") | ||
| 217 | var sign1 = sign_prefab.instantiate() | ||
| 218 | sign1.position = Vector3(-7, 5, -15.01) | ||
| 219 | sign1.text = "victory" | ||
| 220 | get_parent().add_child.call_deferred(sign1) | ||
| 221 | |||
| 222 | var sign2 = sign_prefab.instantiate() | ||
| 223 | sign2.position = Vector3(-7, 4, -15.01) | ||
| 224 | sign2.text = "%s ending" % kEndingNameByVictoryValue.get(ap.victory_condition, "?") | ||
| 225 | |||
| 226 | var sign2_color = kEndingNameByVictoryValue.get(ap.victory_condition, "coral").to_lower() | ||
| 227 | if sign2_color == "white": | ||
| 228 | sign2_color = "silver" | ||
| 229 | |||
| 230 | sign2.material = load("res://assets/materials/%s.material" % sign2_color) | ||
| 231 | get_parent().add_child.call_deferred(sign2) | ||
| 232 | |||
| 233 | # Add the strict purple ending validation. | ||
| 234 | if global.map == "the_sun_temple" and ap.strict_purple_ending: | ||
| 235 | var panel_prefab = preload("res://objects/nodes/panel.tscn") | ||
| 236 | var tpl_prefab = preload("res://objects/nodes/listeners/teleportListener.tscn") | ||
| 237 | var reverse_prefab = preload("res://objects/nodes/listeners/reversingListener.tscn") | ||
| 238 | |||
| 239 | var previous_panel = null | ||
| 240 | var next_y = -100 | ||
| 241 | var words = ["quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog"] | ||
| 242 | for word in words: | ||
| 243 | var panel = panel_prefab.instantiate() | ||
| 244 | panel.position = Vector3(0, next_y, 0) | ||
| 245 | next_y -= 10 | ||
| 246 | panel.clue = word | ||
| 247 | panel.symbol = "" | ||
| 248 | panel.answer = word | ||
| 249 | panel.name = "EndCheck_%s" % word | ||
| 250 | |||
| 251 | var tpl = tpl_prefab.instantiate() | ||
| 252 | tpl.teleport_point = Vector3(0, 1, 0) | ||
| 253 | tpl.teleport_rotate = Vector3(-45, 180, 0) | ||
| 254 | tpl.target_path = panel | ||
| 255 | tpl.name = "Teleport" | ||
| 256 | |||
| 257 | if previous_panel == null: | ||
| 258 | tpl.senders.append(NodePath("/root/scene/Panels/End/panel_24")) | ||
| 259 | else: | ||
| 260 | tpl.senders.append(NodePath("../../%s" % previous_panel.name)) | ||
| 261 | |||
| 262 | var reversing = reverse_prefab.instantiate() | ||
| 263 | reversing.senders.append(NodePath("..")) | ||
| 264 | reversing.name = "Reversing" | ||
| 265 | tpl.senders.append(NodePath("../Reversing")) | ||
| 266 | |||
| 267 | panel.add_child.call_deferred(tpl) | ||
| 268 | panel.add_child.call_deferred(reversing) | ||
| 269 | get_parent().get_node("Panels").add_child.call_deferred(panel) | ||
| 270 | |||
| 271 | previous_panel = panel | ||
| 272 | |||
| 273 | # Duplicate the doors that usually wait on EQUINOX. We can't set the senders | ||
| 274 | # here for some reason so we actually set them in the door ready function. | ||
| 275 | var endplat = get_node("/root/scene/Components/Doors/EndPlatform") | ||
| 276 | var endplat2 = endplat.duplicate() | ||
| 277 | endplat2.name = "spe_EndPlatform" | ||
| 278 | endplat.get_parent().add_child.call_deferred(endplat2) | ||
| 279 | endplat.queue_free() | ||
| 280 | |||
| 281 | var entry2 = get_node("/root/scene/Components/Doors/entry_2") | ||
| 282 | var entry22 = entry2.duplicate() | ||
| 283 | entry22.name = "spe_entry_2" | ||
| 284 | entry2.get_parent().add_child.call_deferred(entry22) | ||
| 285 | entry2.queue_free() | ||
| 286 | |||
| 287 | # Add the strict cyan ending validation. | ||
| 288 | if global.map == "the_parthenon" and ap.strict_cyan_ending: | ||
| 289 | var panel_prefab = preload("res://objects/nodes/panel.tscn") | ||
| 290 | var tpl_prefab = preload("res://objects/nodes/listeners/teleportListener.tscn") | ||
| 291 | var reverse_prefab = preload("res://objects/nodes/listeners/reversingListener.tscn") | ||
| 292 | |||
| 293 | var previous_panel = null | ||
| 294 | var next_y = -100 | ||
| 295 | var words = ["quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog"] | ||
| 296 | for word in words: | ||
| 297 | var panel = panel_prefab.instantiate() | ||
| 298 | panel.position = Vector3(0, next_y, 0) | ||
| 299 | next_y -= 10 | ||
| 300 | panel.clue = word | ||
| 301 | panel.symbol = "." | ||
| 302 | panel.answer = "%s%s" % [word, word] | ||
| 303 | panel.name = "EndCheck_%s" % word | ||
| 304 | |||
| 305 | var tpl = tpl_prefab.instantiate() | ||
| 306 | tpl.teleport_point = Vector3(0, 1, -11) | ||
| 307 | tpl.teleport_rotate = Vector3(-45, 0, 0) | ||
| 308 | tpl.target_path = panel | ||
| 309 | tpl.name = "Teleport" | ||
| 310 | |||
| 311 | if previous_panel == null: | ||
| 312 | tpl.senderGroup.append(NodePath("/root/scene/Panels/Rulers")) | ||
| 313 | else: | ||
| 314 | tpl.senders.append(NodePath("../../%s" % previous_panel.name)) | ||
| 315 | |||
| 316 | var reversing = reverse_prefab.instantiate() | ||
| 317 | reversing.senders.append(NodePath("..")) | ||
| 318 | reversing.name = "Reversing" | ||
| 319 | tpl.senders.append(NodePath("../Reversing")) | ||
| 320 | |||
| 321 | panel.add_child.call_deferred(tpl) | ||
| 322 | panel.add_child.call_deferred(reversing) | ||
| 323 | get_parent().get_node("Panels").add_child.call_deferred(panel) | ||
| 324 | |||
| 325 | previous_panel = panel | ||
| 326 | |||
| 327 | # Duplicate the door that usually waits on the rulers. We can't set the | ||
| 328 | # senders here for some reason so we actually set them in the door ready | ||
| 329 | # function. | ||
| 330 | var entry1 = get_node("/root/scene/Components/Doors/entry_1") | ||
| 331 | var entry12 = entry1.duplicate() | ||
| 332 | entry12.name = "spe_entry_1" | ||
| 333 | entry1.get_parent().add_child.call_deferred(entry12) | ||
| 334 | entry1.queue_free() | ||
| 335 | |||
| 198 | super._ready() | 336 | super._ready() |
| 199 | 337 | ||
| 200 | await get_tree().process_frame | 338 | await get_tree().process_frame |
| @@ -218,3 +356,7 @@ func _set_up_invis_wall(x, y, z, sx, sy, sz): | |||
| 218 | newwall.visibility_range_fade_mode = RenderingServer.VISIBILITY_RANGE_FADE_SELF | 356 | newwall.visibility_range_fade_mode = RenderingServer.VISIBILITY_RANGE_FADE_SELF |
| 219 | newwall.skeleton = ".." | 357 | newwall.skeleton = ".." |
| 220 | get_parent().add_child.call_deferred(newwall) | 358 | get_parent().add_child.call_deferred(newwall) |
| 359 | |||
| 360 | |||
| 361 | func _process(_dt): | ||
| 362 | compass.update_rotation(global_rotation.y) | ||
| diff --git a/client/Archipelago/saver.gd b/client/Archipelago/saver.gd index 0fba9e7..44bc179 100644 --- a/client/Archipelago/saver.gd +++ b/client/Archipelago/saver.gd | |||
| @@ -7,3 +7,17 @@ func levelLoaded(): | |||
| 7 | ap.keyboard.load_keyholders.call_deferred(global.map) | 7 | ap.keyboard.load_keyholders.call_deferred(global.map) |
| 8 | else: | 8 | else: |
| 9 | reload.call_deferred() | 9 | reload.call_deferred() |
| 10 | |||
| 11 | |||
| 12 | func reload(): | ||
| 13 | # Just rewriting this whole thing so I can remove Chris's safeguard. | ||
| 14 | var file = FileAccess.open(path + type + ".save", FileAccess.READ) | ||
| 15 | if file: | ||
| 16 | var data = file.get_var(true) | ||
| 17 | file.close() | ||
| 18 | for datum in data: | ||
| 19 | var saveable = get_node_or_null(datum[0]) | ||
| 20 | if saveable != null: | ||
| 21 | saveable.is_complete = datum[1] | ||
| 22 | if saveable.is_complete: | ||
| 23 | saveable.loadData(saveable.is_complete) | ||
| diff --git a/client/Archipelago/settings_screen.gd b/client/Archipelago/settings_screen.gd index ff6f9df..b7bfacf 100644 --- a/client/Archipelago/settings_screen.gd +++ b/client/Archipelago/settings_screen.gd | |||
| @@ -44,8 +44,10 @@ func _ready(): | |||
| 44 | installScriptExtension(ResourceLoader.load("user://maps/Archipelago/pauseMenu.gd")) | 44 | installScriptExtension(ResourceLoader.load("user://maps/Archipelago/pauseMenu.gd")) |
| 45 | installScriptExtension(ResourceLoader.load("user://maps/Archipelago/player.gd")) | 45 | installScriptExtension(ResourceLoader.load("user://maps/Archipelago/player.gd")) |
| 46 | installScriptExtension(ResourceLoader.load("user://maps/Archipelago/saver.gd")) | 46 | installScriptExtension(ResourceLoader.load("user://maps/Archipelago/saver.gd")) |
| 47 | installScriptExtension(ResourceLoader.load("user://maps/Archipelago/teleport.gd")) | ||
| 47 | installScriptExtension(ResourceLoader.load("user://maps/Archipelago/teleportListener.gd")) | 48 | installScriptExtension(ResourceLoader.load("user://maps/Archipelago/teleportListener.gd")) |
| 48 | installScriptExtension(ResourceLoader.load("user://maps/Archipelago/visibilityListener.gd")) | 49 | installScriptExtension(ResourceLoader.load("user://maps/Archipelago/visibilityListener.gd")) |
| 50 | installScriptExtension(ResourceLoader.load("user://maps/Archipelago/worldport.gd")) | ||
| 49 | installScriptExtension(ResourceLoader.load("user://maps/Archipelago/worldportListener.gd")) | 51 | installScriptExtension(ResourceLoader.load("user://maps/Archipelago/worldportListener.gd")) |
| 50 | 52 | ||
| 51 | var proto_script = load("user://maps/Archipelago/generated/proto.gd") | 53 | var proto_script = load("user://maps/Archipelago/generated/proto.gd") |
| @@ -67,6 +69,12 @@ func _ready(): | |||
| 67 | textclient_instance.name = "Textclient" | 69 | textclient_instance.name = "Textclient" |
| 68 | global.add_child(textclient_instance) | 70 | global.add_child(textclient_instance) |
| 69 | 71 | ||
| 72 | var compass_overlay_script = load("user://maps/Archipelago/compass_overlay.gd") | ||
| 73 | var compass_overlay_instance = compass_overlay_script.new() | ||
| 74 | compass_overlay_instance.name = "Compass" | ||
| 75 | compass_overlay_instance.SCRIPT_compass = load("user://maps/Archipelago/compass.gd") | ||
| 76 | global.add_child(compass_overlay_instance) | ||
| 77 | |||
| 70 | var ap = global.get_node("Archipelago") | 78 | var ap = global.get_node("Archipelago") |
| 71 | var gamedata = global.get_node("Gamedata") | 79 | var gamedata = global.get_node("Gamedata") |
| 72 | ap.connect("ap_connected", connectionSuccessful) | 80 | ap.connect("ap_connected", connectionSuccessful) |
| @@ -99,6 +107,10 @@ func _ready(): | |||
| 99 | $Panel/player_box.add_theme_font_size_override("font_size", 36) | 107 | $Panel/player_box.add_theme_font_size_override("font_size", 36) |
| 100 | $Panel/password_box.add_theme_font_size_override("font_size", 36) | 108 | $Panel/password_box.add_theme_font_size_override("font_size", 36) |
| 101 | 109 | ||
| 110 | # Set up version mismatch dialog. | ||
| 111 | $Panel/VersionMismatch.connect("confirmed", startGame) | ||
| 112 | $Panel/VersionMismatch.get_cancel_button().pressed.connect(versionMismatchDeclined) | ||
| 113 | |||
| 102 | 114 | ||
| 103 | # Adapted from https://gitlab.com/Delta-V-Modding/Mods/-/blob/main/game/ModLoader.gd | 115 | # Adapted from https://gitlab.com/Delta-V-Modding/Mods/-/blob/main/game/ModLoader.gd |
| 104 | func installScriptExtension(childScript: Resource): | 116 | func installScriptExtension(childScript: Resource): |
| @@ -128,6 +140,33 @@ func connectionStatus(message): | |||
| 128 | 140 | ||
| 129 | func connectionSuccessful(): | 141 | func connectionSuccessful(): |
| 130 | var ap = global.get_node("Archipelago") | 142 | var ap = global.get_node("Archipelago") |
| 143 | var gamedata = global.get_node("Gamedata") | ||
| 144 | |||
| 145 | # Check for major version mismatch. | ||
| 146 | if ap.apworld_version[0] != gamedata.objects.get_version(): | ||
| 147 | $Panel/AcceptDialog.exclusive = false | ||
| 148 | |||
| 149 | var popup = self.get_node("Panel/VersionMismatch") | ||
| 150 | popup.title = "Version Mismatch!" | ||
| 151 | popup.dialog_text = ( | ||
| 152 | "This slot was generated using v%d.%d of the Lingo 2 apworld,\nwhich has a different major version than this client (v%d.%d).\nIt is highly recommended to play using the correct version of the client.\nYou may experience bugs or logic issues if you continue." | ||
| 153 | % [ | ||
| 154 | ap.apworld_version[0], | ||
| 155 | ap.apworld_version[1], | ||
| 156 | gamedata.objects.get_version(), | ||
| 157 | ap.MOD_VERSION | ||
| 158 | ] | ||
| 159 | ) | ||
| 160 | popup.exclusive = true | ||
| 161 | popup.popup_centered() | ||
| 162 | |||
| 163 | return | ||
| 164 | |||
| 165 | startGame() | ||
| 166 | |||
| 167 | |||
| 168 | func startGame(): | ||
| 169 | var ap = global.get_node("Archipelago") | ||
| 131 | 170 | ||
| 132 | # Save connection details | 171 | # Save connection details |
| 133 | var connection_details = [ap.ap_server, ap.ap_user, ap.ap_pass] | 172 | var connection_details = [ap.ap_server, ap.ap_user, ap.ap_pass] |
| @@ -166,6 +205,8 @@ func connectionSuccessful(): | |||
| 166 | clearResourceCache("res://objects/nodes/panel.tscn") | 205 | clearResourceCache("res://objects/nodes/panel.tscn") |
| 167 | clearResourceCache("res://objects/nodes/player.tscn") | 206 | clearResourceCache("res://objects/nodes/player.tscn") |
| 168 | clearResourceCache("res://objects/nodes/saver.tscn") | 207 | clearResourceCache("res://objects/nodes/saver.tscn") |
| 208 | clearResourceCache("res://objects/nodes/teleport.tscn") | ||
| 209 | clearResourceCache("res://objects/nodes/worldport.tscn") | ||
| 169 | clearResourceCache("res://objects/scenes/menus/pause_menu.tscn") | 210 | clearResourceCache("res://objects/scenes/menus/pause_menu.tscn") |
| 170 | 211 | ||
| 171 | var paintings_dir = DirAccess.open("res://objects/meshes/paintings") | 212 | var paintings_dir = DirAccess.open("res://objects/meshes/paintings") |
| @@ -190,6 +231,13 @@ func connectionUnsuccessful(error_message): | |||
| 190 | popup.get_ok_button().visible = true | 231 | popup.get_ok_button().visible = true |
| 191 | popup.popup_centered() | 232 | popup.popup_centered() |
| 192 | 233 | ||
| 234 | $Panel/connect_button.disabled = false | ||
| 235 | |||
| 236 | |||
| 237 | func versionMismatchDeclined(): | ||
| 238 | $Panel/AcceptDialog.hide() | ||
| 239 | $Panel/connect_button.disabled = false | ||
| 240 | |||
| 193 | 241 | ||
| 194 | func historySelected(index): | 242 | func historySelected(index): |
| 195 | var ap = global.get_node("Archipelago") | 243 | var ap = global.get_node("Archipelago") |
| diff --git a/client/Archipelago/teleport.gd b/client/Archipelago/teleport.gd new file mode 100644 index 0000000..428d50b --- /dev/null +++ b/client/Archipelago/teleport.gd | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | extends "res://scripts/nodes/teleport.gd" | ||
| 2 | |||
| 3 | var item_id | ||
| 4 | var item_amount | ||
| 5 | |||
| 6 | |||
| 7 | func _ready(): | ||
| 8 | var node_path = String( | ||
| 9 | get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names() | ||
| 10 | ) | ||
| 11 | |||
| 12 | var gamedata = global.get_node("Gamedata") | ||
| 13 | var door_id = gamedata.get_door_for_map_node_path(global.map, node_path) | ||
| 14 | if door_id != null: | ||
| 15 | var ap = global.get_node("Archipelago") | ||
| 16 | var item_lock = ap.get_item_id_for_door(door_id) | ||
| 17 | |||
| 18 | if item_lock != null: | ||
| 19 | item_id = item_lock[0] | ||
| 20 | item_amount = item_lock[1] | ||
| 21 | |||
| 22 | self.senders = [] | ||
| 23 | self.senderGroup = [] | ||
| 24 | self.nested = false | ||
| 25 | self.complete_at = 0 | ||
| 26 | self.max_length = 0 | ||
| 27 | self.excludeSenders = [] | ||
| 28 | |||
| 29 | call_deferred("_readier") | ||
| 30 | |||
| 31 | super._ready() | ||
| 32 | |||
| 33 | |||
| 34 | func _readier(): | ||
| 35 | var ap = global.get_node("Archipelago") | ||
| 36 | |||
| 37 | if ap.client.getItemAmount(item_id) >= item_amount: | ||
| 38 | handleTriggered() | ||
| diff --git a/client/Archipelago/teleportListener.gd b/client/Archipelago/teleportListener.gd index 4a7deec..6f363af 100644 --- a/client/Archipelago/teleportListener.gd +++ b/client/Archipelago/teleportListener.gd | |||
| @@ -9,6 +9,17 @@ func _ready(): | |||
| 9 | get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names() | 9 | get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names() |
| 10 | ) | 10 | ) |
| 11 | 11 | ||
| 12 | if ( | ||
| 13 | global.map == "daedalus" | ||
| 14 | and ( | ||
| 15 | node_path == "Components/Triggers/teleportListenerConnections" | ||
| 16 | or node_path == "Components/Triggers/teleportListenerConnections2" | ||
| 17 | ) | ||
| 18 | ): | ||
| 19 | # Effectively disable these. | ||
| 20 | teleport_point = target_path.position | ||
| 21 | return | ||
| 22 | |||
| 12 | var gamedata = global.get_node("Gamedata") | 23 | var gamedata = global.get_node("Gamedata") |
| 13 | var door_id = gamedata.get_door_for_map_node_path(global.map, node_path) | 24 | var door_id = gamedata.get_door_for_map_node_path(global.map, node_path) |
| 14 | if door_id != null: | 25 | if door_id != null: |
| diff --git a/client/Archipelago/worldport.gd b/client/Archipelago/worldport.gd new file mode 100644 index 0000000..d0fb6c9 --- /dev/null +++ b/client/Archipelago/worldport.gd | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | extends "res://scripts/nodes/worldport.gd" | ||
| 2 | |||
| 3 | |||
| 4 | func _ready(): | ||
| 5 | if global.map == "icarus" and exit == "daedalus": | ||
| 6 | var ap = global.get_node("Archipelago") | ||
| 7 | if not ap.daedalus_roof_access: | ||
| 8 | entry_point = Vector3(58, 10, 0) | ||
| 9 | |||
| 10 | super._ready() | ||
| diff --git a/client/Archipelago/worldportListener.gd b/client/Archipelago/worldportListener.gd index c31c825..5c2faff 100644 --- a/client/Archipelago/worldportListener.gd +++ b/client/Archipelago/worldportListener.gd | |||
| @@ -1,8 +1,8 @@ | |||
| 1 | extends "res://scripts/nodes/listeners/worldportListener.gd" | 1 | extends "res://scripts/nodes/listeners/worldportListener.gd" |
| 2 | 2 | ||
| 3 | 3 | ||
| 4 | func changeScene(): | 4 | func handleTriggered(): |
| 5 | if exit == "menus/credits": | 5 | if exit == "menus/credits": |
| 6 | return | 6 | return |
| 7 | 7 | ||
| 8 | super.changeScene() | 8 | super.handleTriggered() |
