diff options
| author | Star Rauchenberger <fefferburbia@gmail.com> | 2024-04-18 15:00:37 -0400 |
|---|---|---|
| committer | Star Rauchenberger <fefferburbia@gmail.com> | 2024-04-18 15:00:37 -0400 |
| commit | b882031250c7ad970852b8219deb99276f573833 (patch) | |
| tree | 67472145a454a87129627104e5813bca9c4e2ff5 | |
| parent | 6bb60c1b8b4edaf454685fb74b0952baf2ad714f (diff) | |
| parent | 6aad55fa66eb9caa668bb09289391e6b39eee7da (diff) | |
| download | lingo-archipelago-b882031250c7ad970852b8219deb99276f573833.tar.gz lingo-archipelago-b882031250c7ad970852b8219deb99276f573833.tar.bz2 lingo-archipelago-b882031250c7ad970852b8219deb99276f573833.zip | |
Merge branch 'main' into sunwarps
| -rw-r--r-- | Archipelago/client.gd | 58 | ||||
| -rw-r--r-- | Archipelago/load.gd | 70 | ||||
| -rw-r--r-- | Archipelago/player.gd | 28 | ||||
| -rw-r--r-- | Archipelago/settings_buttons.gd | 1 | ||||
| -rw-r--r-- | Archipelago/settings_screen.gd | 45 | ||||
| -rw-r--r-- | CHANGELOG.md | 54 | ||||
| -rw-r--r-- | archipelago.tscn | 31 | ||||
| -rw-r--r-- | util/generate_gamedata.rb | 6 |
8 files changed, 267 insertions, 26 deletions
| diff --git a/Archipelago/client.gd b/Archipelago/client.gd index d1f95c8..13a7635 100644 --- a/Archipelago/client.gd +++ b/Archipelago/client.gd | |||
| @@ -15,8 +15,10 @@ var ap_user = "" | |||
| 15 | var ap_pass = "" | 15 | var ap_pass = "" |
| 16 | var confusify_world = false | 16 | var confusify_world = false |
| 17 | var enable_multiplayer = false | 17 | var enable_multiplayer = false |
| 18 | var track_player = false | ||
| 19 | var connection_history = [] | ||
| 18 | 20 | ||
| 19 | const my_version = "sunwarps-beta2" | 21 | const my_version = "2.2.0" |
| 20 | const ap_version = {"major": 0, "minor": 4, "build": 5, "class": "Version"} | 22 | const ap_version = {"major": 0, "minor": 4, "build": 5, "class": "Version"} |
| 21 | const color_items = [ | 23 | const color_items = [ |
| 22 | "White", "Black", "Red", "Blue", "Green", "Brown", "Gray", "Orange", "Purple", "Yellow" | 24 | "White", "Black", "Red", "Blue", "Green", "Brown", "Gray", "Orange", "Purple", "Yellow" |
| @@ -110,6 +112,7 @@ var _item_name_to_id = {} # LINGO only | |||
| 110 | var _location_name_to_id = {} # LINGO only | 112 | var _location_name_to_id = {} # LINGO only |
| 111 | 113 | ||
| 112 | var _remote_version = {"major": 0, "minor": 0, "build": 0} | 114 | var _remote_version = {"major": 0, "minor": 0, "build": 0} |
| 115 | var _gen_version = {"major": 0, "minor": 0, "build": 0} | ||
| 113 | 116 | ||
| 114 | # TODO: caching per MW/slot, reset between connections | 117 | # TODO: caching per MW/slot, reset between connections |
| 115 | var _authenticated = false | 118 | var _authenticated = false |
| @@ -151,6 +154,7 @@ var _puzzle_skips = 0 | |||
| 151 | var _cached_slowness = 0 | 154 | var _cached_slowness = 0 |
| 152 | var _cached_iceland = 0 | 155 | var _cached_iceland = 0 |
| 153 | var _cached_atbash = 0 | 156 | var _cached_atbash = 0 |
| 157 | var _geronimo_skip = false | ||
| 154 | 158 | ||
| 155 | signal could_not_connect | 159 | signal could_not_connect |
| 156 | signal connect_status | 160 | signal connect_status |
| @@ -180,6 +184,10 @@ func _init(): | |||
| 180 | confusify_world = data[4] | 184 | confusify_world = data[4] |
| 181 | if data.size() > 5: | 185 | if data.size() > 5: |
| 182 | enable_multiplayer = data[5] | 186 | enable_multiplayer = data[5] |
| 187 | if data.size() > 6: | ||
| 188 | track_player = data[6] | ||
| 189 | if data.size() > 7: | ||
| 190 | connection_history = data[7] | ||
| 183 | 191 | ||
| 184 | processDatapackages() | 192 | processDatapackages() |
| 185 | 193 | ||
| @@ -249,6 +257,7 @@ func _on_data(): | |||
| 249 | if cmd == "RoomInfo": | 257 | if cmd == "RoomInfo": |
| 250 | _seed = message["seed_name"] | 258 | _seed = message["seed_name"] |
| 251 | _remote_version = message["version"] | 259 | _remote_version = message["version"] |
| 260 | _gen_version = message["generator_version"] | ||
| 252 | 261 | ||
| 253 | var needed_games = [] | 262 | var needed_games = [] |
| 254 | for game in message["datapackage_checksums"].keys(): | 263 | for game in message["datapackage_checksums"].keys(): |
| @@ -332,6 +341,11 @@ func _on_data(): | |||
| 332 | if _slot_data.has("sunwarp_permutation"): | 341 | if _slot_data.has("sunwarp_permutation"): |
| 333 | _sunwarp_mapping = _slot_data["sunwarp_permutation"] | 342 | _sunwarp_mapping = _slot_data["sunwarp_permutation"] |
| 334 | 343 | ||
| 344 | if track_player: | ||
| 345 | setValue("PlayerPos", {"x": 0, "z": 0}) | ||
| 346 | else: | ||
| 347 | setValue("PlayerPos", null) | ||
| 348 | |||
| 335 | _puzzle_skips = 0 | 349 | _puzzle_skips = 0 |
| 336 | 350 | ||
| 337 | _localdata_file = "user://archipelago_data/%s_%d" % [_seed, _slot] | 351 | _localdata_file = "user://archipelago_data/%s_%d" % [_seed, _slot] |
| @@ -364,6 +378,11 @@ func _on_data(): | |||
| 364 | else: | 378 | else: |
| 365 | _cached_atbash = 0 | 379 | _cached_atbash = 0 |
| 366 | 380 | ||
| 381 | if localdata.size() > 5: | ||
| 382 | _geronimo_skip = localdata[5] | ||
| 383 | else: | ||
| 384 | _geronimo_skip = false | ||
| 385 | |||
| 367 | requestSync() | 386 | requestSync() |
| 368 | 387 | ||
| 369 | emit_signal("client_connected") | 388 | emit_signal("client_connected") |
| @@ -499,7 +518,16 @@ func saveSettings(): | |||
| 499 | var file = File.new() | 518 | var file = File.new() |
| 500 | file.open("user://settings/archipelago", File.WRITE) | 519 | file.open("user://settings/archipelago", File.WRITE) |
| 501 | 520 | ||
| 502 | var data = [ap_server, ap_user, ap_pass, _datapackages, confusify_world, enable_multiplayer] | 521 | var data = [ |
| 522 | ap_server, | ||
| 523 | ap_user, | ||
| 524 | ap_pass, | ||
| 525 | _datapackages, | ||
| 526 | confusify_world, | ||
| 527 | enable_multiplayer, | ||
| 528 | track_player, | ||
| 529 | connection_history | ||
| 530 | ] | ||
| 503 | file.store_var(data, true) | 531 | file.store_var(data, true) |
| 504 | file.close() | 532 | file.close() |
| 505 | 533 | ||
| @@ -523,7 +551,8 @@ func saveLocaldata(): | |||
| 523 | _puzzle_skips, | 551 | _puzzle_skips, |
| 524 | effects_node.slowness_remaining, | 552 | effects_node.slowness_remaining, |
| 525 | effects_node.iceland_remaining, | 553 | effects_node.iceland_remaining, |
| 526 | effects_node.atbash_remaining | 554 | effects_node.atbash_remaining, |
| 555 | _geronimo_skip | ||
| 527 | ] | 556 | ] |
| 528 | file.store_var(data, true) | 557 | file.store_var(data, true) |
| 529 | file.close() | 558 | file.close() |
| @@ -777,6 +806,15 @@ func usePuzzleSkip(): | |||
| 777 | saveLocaldata() | 806 | saveLocaldata() |
| 778 | 807 | ||
| 779 | 808 | ||
| 809 | func geronimo(): | ||
| 810 | if !_geronimo_skip: | ||
| 811 | messages.showMessage("Geronimo! You found a puzzle skip.") | ||
| 812 | |||
| 813 | _puzzle_skips += 1 | ||
| 814 | _geronimo_skip = true | ||
| 815 | saveLocaldata() | ||
| 816 | |||
| 817 | |||
| 780 | func colorForItemType(flags): | 818 | func colorForItemType(flags): |
| 781 | var int_flags = int(flags) | 819 | var int_flags = int(flags) |
| 782 | if int_flags & 1: # progression | 820 | if int_flags & 1: # progression |
| @@ -787,3 +825,17 @@ func colorForItemType(flags): | |||
| 787 | return "#d63a22" | 825 | return "#d63a22" |
| 788 | else: # filler | 826 | else: # filler |
| 789 | return "#14de9e" | 827 | return "#14de9e" |
| 828 | |||
| 829 | |||
| 830 | func compareVersion(lhs, rhs): | ||
| 831 | if lhs["major"] == rhs["major"]: | ||
| 832 | if lhs["minor"] == rhs["minor"]: | ||
| 833 | return lhs["build"] < rhs["build"] | ||
| 834 | else: | ||
| 835 | return lhs["minor"] < rhs["minor"] | ||
| 836 | else: | ||
| 837 | return lhs["major"] < rhs["major"] | ||
| 838 | |||
| 839 | |||
| 840 | func wasGeneratedBeforeVersion(major, minor, build): | ||
| 841 | return compareVersion(_gen_version, {"major": major, "minor": minor, "build": build}) | ||
| diff --git a/Archipelago/load.gd b/Archipelago/load.gd index 673c762..0ed978a 100644 --- a/Archipelago/load.gd +++ b/Archipelago/load.gd | |||
| @@ -25,6 +25,11 @@ func _load(): | |||
| 25 | var apclient = global.get_node("Archipelago") | 25 | var apclient = global.get_node("Archipelago") |
| 26 | var panels_parent = self.get_node("Panels") | 26 | var panels_parent = self.get_node("Panels") |
| 27 | 27 | ||
| 28 | var date = Time.get_date_dict_from_system() | ||
| 29 | var april_fools = false | ||
| 30 | if date["month"] == 4 && date["day"] == 1: | ||
| 31 | april_fools = true | ||
| 32 | |||
| 28 | # Add a wall-blocked raycast to the player. | 33 | # Add a wall-blocked raycast to the player. |
| 29 | var wallcast = RayCast.new() | 34 | var wallcast = RayCast.new() |
| 30 | wallcast.name = "wallcast" | 35 | wallcast.name = "wallcast" |
| @@ -64,7 +69,7 @@ func _load(): | |||
| 64 | wanderer_entrance.rotation = Vector3(0, -PI / 2, 0) | 69 | wanderer_entrance.rotation = Vector3(0, -PI / 2, 0) |
| 65 | wanderer_entrance.scale = Vector3(1, 1.5, 1) | 70 | wanderer_entrance.scale = Vector3(1, 1.5, 1) |
| 66 | wanderer_entrance.set_script(door_script) | 71 | wanderer_entrance.set_script(door_script) |
| 67 | wanderer_entrance.panels.append("../../../Panels/Tower Room/Panel_wanderlust_1234567890") | 72 | wanderer_entrance.panels = ["../../../Panels/Tower Room/Panel_wanderlust_1234567890"] |
| 68 | get_node("Doors/Tower Room Area Doors").add_child(wanderer_entrance) | 73 | get_node("Doors/Tower Room Area Doors").add_child(wanderer_entrance) |
| 69 | 74 | ||
| 70 | var wanderer_achieve = get_node("Panels/Tower Room/Panel_1234567890_wanderlust") | 75 | var wanderer_achieve = get_node("Panels/Tower Room/Panel_1234567890_wanderlust") |
| @@ -91,18 +96,19 @@ func _load(): | |||
| 91 | 96 | ||
| 92 | wanderer_achieve.translation = Vector3(-51, -33, 35) # way under the map | 97 | wanderer_achieve.translation = Vector3(-51, -33, 35) # way under the map |
| 93 | 98 | ||
| 94 | # Turn THE COLORFUL into a cdp. | ||
| 95 | var real_colorful = panels_parent.get_node("Countdown Panels/Panel_colorful_colorful") | ||
| 96 | var cdp_auto_scene = load("res://nodes/panel_countdown_auto.tscn") | 99 | var cdp_auto_scene = load("res://nodes/panel_countdown_auto.tscn") |
| 97 | var colorful_cdp = cdp_auto_scene.instance() | 100 | if !apclient.wasGeneratedBeforeVersion(0, 4, 5): |
| 98 | colorful_cdp.name = "CountdownPanel_colorful" | 101 | # Turn THE COLORFUL into a cdp. |
| 99 | colorful_cdp.replace_with = "../../Panels/Countdown Panels/Panel_colorful_colorful" | 102 | var real_colorful = panels_parent.get_node("Countdown Panels/Panel_colorful_colorful") |
| 100 | colorful_cdp.panels = "../../Panels/Doorways Room" | 103 | var colorful_cdp = cdp_auto_scene.instance() |
| 101 | colorful_cdp.translation = real_colorful.translation | 104 | colorful_cdp.name = "CountdownPanel_colorful" |
| 102 | colorful_cdp.rotation = real_colorful.rotation | 105 | colorful_cdp.replace_with = "../../Panels/Countdown Panels/Panel_colorful_colorful" |
| 103 | get_node("CountdownPanels").add_child(colorful_cdp) | 106 | colorful_cdp.panels = "../../Panels/Doorways Room" |
| 104 | real_colorful.translation = Vector3(-51, -35, 35) # way under the map | 107 | colorful_cdp.translation = real_colorful.translation |
| 105 | get_node("Doors/Doorway Room Doors/Door_gray2").queue_free() | 108 | colorful_cdp.rotation = real_colorful.rotation |
| 109 | get_node("CountdownPanels").add_child(colorful_cdp) | ||
| 110 | real_colorful.translation = Vector3(-51, -35, 35) # way under the map | ||
| 111 | get_node("Doors/Doorway Room Doors/Door_gray2").queue_free() | ||
| 106 | 112 | ||
| 107 | # Set up The Master to be variable. | 113 | # Set up The Master to be variable. |
| 108 | var old_master_cdp = get_node("CountdownPanels/CountdownPanel_countdown_16") | 114 | var old_master_cdp = get_node("CountdownPanels/CountdownPanel_countdown_16") |
| @@ -420,6 +426,8 @@ func _load(): | |||
| 420 | if not classes.has(painting): | 426 | if not classes.has(painting): |
| 421 | var i = rng.randi_range(0, all_paintings.size() - 1) | 427 | var i = rng.randi_range(0, all_paintings.size() - 1) |
| 422 | var chosen = all_paintings[i] | 428 | var chosen = all_paintings[i] |
| 429 | if april_fools: | ||
| 430 | chosen = "bg_notnerb" | ||
| 423 | classes[painting] = chosen | 431 | classes[painting] = chosen |
| 424 | all_paintings.remove(i) | 432 | all_paintings.remove(i) |
| 425 | 433 | ||
| @@ -444,6 +452,9 @@ func _load(): | |||
| 444 | var j = rng.randi_range(0, all_paintings.size() - 1) | 452 | var j = rng.randi_range(0, all_paintings.size() - 1) |
| 445 | remaining.append(all_paintings[j]) | 453 | remaining.append(all_paintings[j]) |
| 446 | all_paintings.remove(j) | 454 | all_paintings.remove(j) |
| 455 | |||
| 456 | if april_fools: | ||
| 457 | remaining = ["bg_notnerb"] | ||
| 447 | 458 | ||
| 448 | for painting in gamedata.paintings.keys(): | 459 | for painting in gamedata.paintings.keys(): |
| 449 | if randomized.has(painting): | 460 | if randomized.has(painting): |
| @@ -451,6 +462,26 @@ func _load(): | |||
| 451 | 462 | ||
| 452 | var chosen_painting = remaining[rng.randi_range(0, remaining.size() - 1)] | 463 | var chosen_painting = remaining[rng.randi_range(0, remaining.size() - 1)] |
| 453 | instantiate_painting(painting, chosen_painting) | 464 | instantiate_painting(painting, chosen_painting) |
| 465 | |||
| 466 | # Replace the roof of The Artistic. | ||
| 467 | var artistic_paintings = [ | ||
| 468 | ["smile_painting_9", -49.5, 44.5], | ||
| 469 | ["cherry_painting3", -38.5, 44.5], | ||
| 470 | ["boxes_painting2", -38.5, 55.5], | ||
| 471 | ["panda_painting_3", -49.5, 55.5] | ||
| 472 | ] | ||
| 473 | for painting in artistic_paintings: | ||
| 474 | var painting_node = get_node("AP_Paintings").get_node(painting[0]).get_node("GridMap") | ||
| 475 | var small_mesh_library = painting_node.mesh_library | ||
| 476 | |||
| 477 | for x in range(0,10): | ||
| 478 | for y in range(0,10): | ||
| 479 | var cellitem = painting_node.get_cell_item(-5 + x, 1+y, 0) | ||
| 480 | var meshitem = small_mesh_library.get_item_name(cellitem) | ||
| 481 | if meshitem.begins_with("Tiny"): | ||
| 482 | meshitem = meshitem.substr(4) | ||
| 483 | set_gridmap_tile(painting[1]+9-y, 8.5, painting[2]+x, meshitem) | ||
| 484 | |||
| 454 | 485 | ||
| 455 | # We need to make some changes to the Art Gallery. The player should always | 486 | # We need to make some changes to the Art Gallery. The player should always |
| 456 | # have access to the backroom, but they shouldn't have access to ORDER until | 487 | # have access to the backroom, but they shouldn't have access to ORDER until |
| @@ -644,6 +675,17 @@ func _load(): | |||
| 644 | var multiplayer_node = apclient.SCRIPT_multiplayer.new() | 675 | var multiplayer_node = apclient.SCRIPT_multiplayer.new() |
| 645 | multiplayer_node.ghost_mode = true | 676 | multiplayer_node.ghost_mode = true |
| 646 | add_child(multiplayer_node) | 677 | add_child(multiplayer_node) |
| 678 | |||
| 679 | # Hook up Geronimo handler. | ||
| 680 | $player.connect("player_jumped", apclient, "geronimo") | ||
| 681 | |||
| 682 | if april_fools: | ||
| 683 | # Change the appearance of every painting. | ||
| 684 | var notnerb_painting = load("res://nodes/paintings/bg_notnerb.tscn").instance() | ||
| 685 | for child in $Decorations/Paintings.get_children(): | ||
| 686 | if child.get_node_or_null("GridMap") != null: | ||
| 687 | child.get_node("GridMap").queue_free() | ||
| 688 | child.add_child(notnerb_painting.get_node("GridMap").duplicate(true)) | ||
| 647 | 689 | ||
| 648 | # Hook up the scene to be able to handle connection failures. | 690 | # Hook up the scene to be able to handle connection failures. |
| 649 | apclient.connect("could_not_connect", self, "archipelago_disconnected") | 691 | apclient.connect("could_not_connect", self, "archipelago_disconnected") |
| @@ -727,8 +769,10 @@ func set_gridmap_tile(x, y, z, tile): | |||
| 727 | var gridmap = self.get_node("GridMap") | 769 | var gridmap = self.get_node("GridMap") |
| 728 | var mesh_library = gridmap.mesh_library | 770 | var mesh_library = gridmap.mesh_library |
| 729 | var mapvec = gridmap.world_to_map(gridmap.to_local(Vector3(x, y, z))) | 771 | var mapvec = gridmap.world_to_map(gridmap.to_local(Vector3(x, y, z))) |
| 772 | var cellitem = mesh_library.find_item_by_name(tile) | ||
| 730 | 773 | ||
| 731 | gridmap.set_cell_item(mapvec.x, mapvec.y, mapvec.z, mesh_library.find_item_by_name(tile)) | 774 | if cellitem != GridMap.INVALID_CELL_ITEM: |
| 775 | gridmap.set_cell_item(mapvec.x, mapvec.y, mapvec.z, cellitem) | ||
| 732 | 776 | ||
| 733 | 777 | ||
| 734 | func clear_gridmap_tile(x, y, z): | 778 | func clear_gridmap_tile(x, y, z): |
| diff --git a/Archipelago/player.gd b/Archipelago/player.gd index 87d9d0c..49d907d 100644 --- a/Archipelago/player.gd +++ b/Archipelago/player.gd | |||
| @@ -1,6 +1,34 @@ | |||
| 1 | extends "res://scripts/player.gd" | 1 | extends "res://scripts/player.gd" |
| 2 | 2 | ||
| 3 | 3 | ||
| 4 | var _oldpos = Vector3(0, -200, 0) | ||
| 5 | |||
| 6 | |||
| 7 | func _ready(): | ||
| 8 | _oldpos = translation | ||
| 9 | _oldpos.y = 0 | ||
| 10 | |||
| 11 | var apclient = global.get_node("Archipelago") | ||
| 12 | if apclient.track_player: | ||
| 13 | var tracking_timer = Timer.new() | ||
| 14 | tracking_timer.name = "TrackingTimer" | ||
| 15 | tracking_timer.wait_time = 5.0 | ||
| 16 | add_child(tracking_timer) | ||
| 17 | tracking_timer.connect("timeout", self, "_tick_tracking") | ||
| 18 | tracking_timer.start() | ||
| 19 | |||
| 20 | |||
| 21 | func _tick_tracking(): | ||
| 22 | var newpos = translation | ||
| 23 | newpos.y = 0 | ||
| 24 | |||
| 25 | if newpos != _oldpos && newpos.distance_to(_oldpos) > 10: | ||
| 26 | _oldpos = newpos | ||
| 27 | |||
| 28 | var apclient = global.get_node("Archipelago") | ||
| 29 | apclient.setValue("PlayerPos", {"x": int(_oldpos.x), "z": int(_oldpos.z)}) | ||
| 30 | |||
| 31 | |||
| 4 | func _solving(): | 32 | func _solving(): |
| 5 | ._solving() | 33 | ._solving() |
| 6 | 34 | ||
| diff --git a/Archipelago/settings_buttons.gd b/Archipelago/settings_buttons.gd index e9cff9d..9193b61 100644 --- a/Archipelago/settings_buttons.gd +++ b/Archipelago/settings_buttons.gd | |||
| @@ -14,6 +14,7 @@ func _connect_pressed(): | |||
| 14 | apclient.ap_pass = self.get_parent().get_node("password_box").text | 14 | apclient.ap_pass = self.get_parent().get_node("password_box").text |
| 15 | apclient.confusify_world = self.get_parent().get_node("confusing_box").pressed | 15 | apclient.confusify_world = self.get_parent().get_node("confusing_box").pressed |
| 16 | apclient.enable_multiplayer = self.get_parent().get_node("multiplayer_box").pressed | 16 | apclient.enable_multiplayer = self.get_parent().get_node("multiplayer_box").pressed |
| 17 | apclient.track_player = self.get_parent().get_node("position_box").pressed | ||
| 17 | apclient.saveSettings() | 18 | apclient.saveSettings() |
| 18 | 19 | ||
| 19 | apclient.connectToServer() | 20 | apclient.connectToServer() |
| diff --git a/Archipelago/settings_screen.gd b/Archipelago/settings_screen.gd index 1be32d9..bf2c78f 100644 --- a/Archipelago/settings_screen.gd +++ b/Archipelago/settings_screen.gd | |||
| @@ -2,6 +2,12 @@ extends Spatial | |||
| 2 | 2 | ||
| 3 | 3 | ||
| 4 | func _ready(): | 4 | func _ready(): |
| 5 | # Some helpful logging. | ||
| 6 | if Steam.isSubscribed(): | ||
| 7 | global._print("Provisioning successful! Build ID: %d" % Steam.getAppBuildId()) | ||
| 8 | else: | ||
| 9 | global._print("Provisioning failed.") | ||
| 10 | |||
| 5 | # Undo the load screen removing our cursor | 11 | # Undo the load screen removing our cursor |
| 6 | get_tree().get_root().set_disable_input(false) | 12 | get_tree().get_root().set_disable_input(false) |
| 7 | Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) | 13 | Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) |
| @@ -62,6 +68,20 @@ func _ready(): | |||
| 62 | self.get_node("Panel/password_box").text = apclient.ap_pass | 68 | self.get_node("Panel/password_box").text = apclient.ap_pass |
| 63 | self.get_node("Panel/confusing_box").pressed = apclient.confusify_world | 69 | self.get_node("Panel/confusing_box").pressed = apclient.confusify_world |
| 64 | self.get_node("Panel/multiplayer_box").pressed = apclient.enable_multiplayer | 70 | self.get_node("Panel/multiplayer_box").pressed = apclient.enable_multiplayer |
| 71 | self.get_node("Panel/position_box").pressed = apclient.track_player | ||
| 72 | |||
| 73 | var history_box = get_node("Panel/connection_history") | ||
| 74 | if apclient.connection_history.empty(): | ||
| 75 | history_box.disabled = true | ||
| 76 | else: | ||
| 77 | history_box.disabled = false | ||
| 78 | |||
| 79 | var i = 0 | ||
| 80 | for details in apclient.connection_history: | ||
| 81 | history_box.get_popup().add_item("%s (%s)" % [details[1], details[0]], i) | ||
| 82 | i += 1 | ||
| 83 | |||
| 84 | history_box.get_popup().connect("id_pressed", self, "historySelected") | ||
| 65 | 85 | ||
| 66 | # Show client version. | 86 | # Show client version. |
| 67 | self.get_node("Panel/title").text = "ARCHIPELAGO (%s)" % apclient.my_version | 87 | self.get_node("Panel/title").text = "ARCHIPELAGO (%s)" % apclient.my_version |
| @@ -105,10 +125,24 @@ func connectionStatus(message): | |||
| 105 | func connectionSuccessful(): | 125 | func connectionSuccessful(): |
| 106 | var apclient = global.get_node("Archipelago") | 126 | var apclient = global.get_node("Archipelago") |
| 107 | 127 | ||
| 128 | # Save connection details | ||
| 129 | var connection_details = [apclient.ap_server, apclient.ap_user, apclient.ap_pass] | ||
| 130 | if apclient.connection_history.has(connection_details): | ||
| 131 | apclient.connection_history.erase(connection_details) | ||
| 132 | apclient.connection_history.push_front(connection_details) | ||
| 133 | if apclient.connection_history.size() > 10: | ||
| 134 | apclient.connection_history.resize(10) | ||
| 135 | apclient.saveSettings() | ||
| 136 | |||
| 108 | # Switch to LL1 | 137 | # Switch to LL1 |
| 109 | Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) | 138 | Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) |
| 110 | global.map = "level1" | ||
| 111 | global.save_file = apclient.getSaveFileName() | 139 | global.save_file = apclient.getSaveFileName() |
| 140 | |||
| 141 | if Directory.new().file_exists("user://level1/%s.save" % global.save_file): | ||
| 142 | global.map = "level1" | ||
| 143 | else: | ||
| 144 | global.map = "level1_stable" | ||
| 145 | |||
| 112 | var _discard = get_tree().change_scene("res://scenes/load_screen.tscn") | 146 | var _discard = get_tree().change_scene("res://scenes/load_screen.tscn") |
| 113 | 147 | ||
| 114 | 148 | ||
| @@ -121,3 +155,12 @@ func connectionUnsuccessful(error_message): | |||
| 121 | popup.popup_exclusive = true | 155 | popup.popup_exclusive = true |
| 122 | popup.get_ok().visible = true | 156 | popup.get_ok().visible = true |
| 123 | popup.popup_centered() | 157 | popup.popup_centered() |
| 158 | |||
| 159 | |||
| 160 | func historySelected(index): | ||
| 161 | var apclient = global.get_node("Archipelago") | ||
| 162 | var details = apclient.connection_history[index] | ||
| 163 | |||
| 164 | self.get_node("Panel/server_box").text = details[0] | ||
| 165 | self.get_node("Panel/player_box").text = details[1] | ||
| 166 | self.get_node("Panel/password_box").text = details[2] | ||
| diff --git a/CHANGELOG.md b/CHANGELOG.md index 9915d06..d5fc54d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md | |||
| @@ -1,5 +1,59 @@ | |||
| 1 | # lingo-archipelago Releases | 1 | # lingo-archipelago Releases |
| 2 | 2 | ||
| 3 | ## v2.2.0 - 2024-04-17 | ||
| 4 | |||
| 5 | - The last ten connections are now saved in a list so that you can easily switch | ||
| 6 | between concurrent multiworlds. | ||
| 7 | - THE COLORFUL is no longer turned into a countdown panel if the multiworld was | ||
| 8 | generated before Archipelago 0.4.5. This should improve backwards | ||
| 9 | compatibility, but a v1.x.x version is still the most accurate way to play an | ||
| 10 | older multiworld. | ||
| 11 | |||
| 12 | Download: | ||
| 13 | [lingo-archipelago-v2.2.0.zip](https://files.fourisland.com/releases/lingo-archipelago/lingo-archipelago-v2.2.0.zip)<br/> | ||
| 14 | Source: [v2.2.0](https://code.fourisland.com/lingo-archipelago/tag/?h=v2.2.0) | ||
| 15 | |||
| 16 | ## v2.1.1 - 2024-04-11 | ||
| 17 | |||
| 18 | - Added some debug logging. | ||
| 19 | |||
| 20 | Download: | ||
| 21 | [lingo-archipelago-v2.1.1.zip](https://files.fourisland.com/releases/lingo-archipelago/lingo-archipelago-v2.1.1.zip)<br/> | ||
| 22 | Source: [v2.1.1](https://code.fourisland.com/lingo-archipelago/tag/?h=v2.1.1) | ||
| 23 | |||
| 24 | ## v2.1.0 - 2024-04-03 | ||
| 25 | |||
| 26 | - Added a checkbox that enables tracking the player's current position. This can | ||
| 27 | be displayed on the map in the tracker. (requires v0.8.0) | ||
| 28 | |||
| 29 | Download: | ||
| 30 | [lingo-archipelago-v2.1.0.zip](https://files.fourisland.com/releases/lingo-archipelago/lingo-archipelago-v2.1.0.zip)<br/> | ||
| 31 | Source: [v2.1.0](https://code.fourisland.com/lingo-archipelago/tag/?h=v2.1.0) | ||
| 32 | |||
| 33 | ## v2.0.0 - 2024-04-01 | ||
| 34 | |||
| 35 | - [Archipelago 0.4.5](https://github.com/ArchipelagoMW/Archipelago/releases/tag/0.4.5) | ||
| 36 | has been released! This update includes various small changes to the Lingo | ||
| 37 | world, most notably making The Colorful into a countdown achievement, and | ||
| 38 | making the doors in The Colorful optionally progressive. | ||
| 39 | - When painting shuffle is on, the roof of The Artistic now takes on the | ||
| 40 | appearance of the four paintings inside the room. | ||
| 41 | - Getting the "Geronimo!" bonus achievement now gives you a puzzle skip, once | ||
| 42 | per save file. | ||
| 43 | |||
| 44 | Download: | ||
| 45 | [lingo-archipelago-v2.0.0.zip](https://files.fourisland.com/releases/lingo-archipelago/lingo-archipelago-v2.0.0.zip)<br/> | ||
| 46 | Source: [v2.0.0](https://code.fourisland.com/lingo-archipelago/tag/?h=v2.0.0) | ||
| 47 | |||
| 48 | ## v1.2.1 - 2024-03-29 | ||
| 49 | |||
| 50 | - Fixed the entrance to The Wanderer not opening after disconnecting from | ||
| 51 | Archipelago and connecting again without closing the game. | ||
| 52 | |||
| 53 | Download: | ||
| 54 | [lingo-archipelago-v1.2.1.zip](https://files.fourisland.com/releases/lingo-archipelago/lingo-archipelago-v1.2.1.zip)<br/> | ||
| 55 | Source: [v1.2.1](https://code.fourisland.com/lingo-archipelago/tag/?h=v1.2.1) | ||
| 56 | |||
| 3 | ## v1.2.0 - 2024-02-04 | 57 | ## v1.2.0 - 2024-02-04 |
| 4 | 58 | ||
| 5 | - The "Press P to skip puzzle" message will no longer appear when the cursor is | 59 | - The "Press P to skip puzzle" message will no longer appear when the cursor is |
| diff --git a/archipelago.tscn b/archipelago.tscn index 917db4e..f063af9 100644 --- a/archipelago.tscn +++ b/archipelago.tscn | |||
| @@ -86,9 +86,9 @@ align = 2 | |||
| 86 | 86 | ||
| 87 | [node name="credit5" parent="Panel" instance=ExtResource( 1 )] | 87 | [node name="credit5" parent="Panel" instance=ExtResource( 1 )] |
| 88 | margin_left = 1239.0 | 88 | margin_left = 1239.0 |
| 89 | margin_top = 271.0 | 89 | margin_top = 422.0 |
| 90 | margin_right = 1829.0 | 90 | margin_right = 1829.0 |
| 91 | margin_bottom = 335.0 | 91 | margin_bottom = 486.0 |
| 92 | custom_fonts/font = ExtResource( 2 ) | 92 | custom_fonts/font = ExtResource( 2 ) |
| 93 | custom_styles/normal = SubResource( 1 ) | 93 | custom_styles/normal = SubResource( 1 ) |
| 94 | text = "OPTIONS" | 94 | text = "OPTIONS" |
| @@ -155,9 +155,9 @@ margin_bottom = 58.0 | |||
| 155 | 155 | ||
| 156 | [node name="confusing_box" type="CheckBox" parent="Panel"] | 156 | [node name="confusing_box" type="CheckBox" parent="Panel"] |
| 157 | margin_left = 1227.0 | 157 | margin_left = 1227.0 |
| 158 | margin_top = 351.0 | 158 | margin_top = 502.0 |
| 159 | margin_right = 1832.0 | 159 | margin_right = 1832.0 |
| 160 | margin_bottom = 439.0 | 160 | margin_bottom = 590.0 |
| 161 | custom_fonts/font = ExtResource( 6 ) | 161 | custom_fonts/font = ExtResource( 6 ) |
| 162 | custom_icons/checked = ExtResource( 8 ) | 162 | custom_icons/checked = ExtResource( 8 ) |
| 163 | custom_icons/unchecked = ExtResource( 7 ) | 163 | custom_icons/unchecked = ExtResource( 7 ) |
| @@ -165,13 +165,32 @@ text = "Make world more confusing" | |||
| 165 | 165 | ||
| 166 | [node name="multiplayer_box" type="CheckBox" parent="Panel"] | 166 | [node name="multiplayer_box" type="CheckBox" parent="Panel"] |
| 167 | margin_left = 1227.0 | 167 | margin_left = 1227.0 |
| 168 | margin_top = 461.0 | 168 | margin_top = 612.0 |
| 169 | margin_right = 1832.0 | 169 | margin_right = 1832.0 |
| 170 | margin_bottom = 549.0 | 170 | margin_bottom = 700.0 |
| 171 | custom_fonts/font = ExtResource( 6 ) | 171 | custom_fonts/font = ExtResource( 6 ) |
| 172 | custom_icons/checked = ExtResource( 8 ) | 172 | custom_icons/checked = ExtResource( 8 ) |
| 173 | custom_icons/unchecked = ExtResource( 7 ) | 173 | custom_icons/unchecked = ExtResource( 7 ) |
| 174 | text = "Show other players" | 174 | text = "Show other players" |
| 175 | 175 | ||
| 176 | [node name="position_box" type="CheckBox" parent="Panel"] | ||
| 177 | margin_left = 1227.0 | ||
| 178 | margin_top = 722.0 | ||
| 179 | margin_right = 1832.0 | ||
| 180 | margin_bottom = 810.0 | ||
| 181 | custom_fonts/font = ExtResource( 6 ) | ||
| 182 | custom_icons/checked = ExtResource( 8 ) | ||
| 183 | custom_icons/unchecked = ExtResource( 7 ) | ||
| 184 | text = "Send position to tracker" | ||
| 185 | |||
| 186 | [node name="connection_history" type="MenuButton" parent="Panel"] | ||
| 187 | margin_left = 1239.0 | ||
| 188 | margin_top = 276.0 | ||
| 189 | margin_right = 1829.0 | ||
| 190 | margin_bottom = 372.0 | ||
| 191 | custom_fonts/font = ExtResource( 6 ) | ||
| 192 | text = "connection history" | ||
| 193 | flat = false | ||
| 194 | |||
| 176 | [connection signal="pressed" from="Panel/connect_button" to="Panel/connect_button" method="_connect_pressed"] | 195 | [connection signal="pressed" from="Panel/connect_button" to="Panel/connect_button" method="_connect_pressed"] |
| 177 | [connection signal="pressed" from="Panel/quit_button" to="Panel/quit_button" method="_back_pressed"] | 196 | [connection signal="pressed" from="Panel/quit_button" to="Panel/quit_button" method="_back_pressed"] |
| diff --git a/util/generate_gamedata.rb b/util/generate_gamedata.rb index 7674277..6923bc5 100644 --- a/util/generate_gamedata.rb +++ b/util/generate_gamedata.rb | |||
| @@ -146,9 +146,9 @@ config.each do |room_name, room_data| | |||
| 146 | internal_door_ids = door["id"] | 146 | internal_door_ids = door["id"] |
| 147 | end | 147 | end |
| 148 | 148 | ||
| 149 | if door.include? "group" | 149 | if door.include? "door_group" |
| 150 | door_groups[door["group"]] ||= Set[] | 150 | door_groups[door["door_group"]] ||= Set[] |
| 151 | door_groups[door["group"]].merge(internal_door_ids) | 151 | door_groups[door["door_group"]].merge(internal_door_ids) |
| 152 | end | 152 | end |
| 153 | 153 | ||
| 154 | door_ids_by_item_id[item_id] = internal_door_ids | 154 | door_ids_by_item_id[item_id] = internal_door_ids |
