From 3f53502a5907ed1982d28a392c54331f0c1c2c42 Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Thu, 25 Sep 2025 12:09:50 -0400 Subject: Move the client into the apworld Only works on source right now, not as an apworld. --- client/Archipelago/animationListener.gd | 38 -- client/Archipelago/client.gd | 417 ----------------- client/Archipelago/collectable.gd | 16 - client/Archipelago/compass.gd | 66 --- client/Archipelago/compass_overlay.gd | 17 - client/Archipelago/door.gd | 46 -- client/Archipelago/gamedata.gd | 159 ------- client/Archipelago/keyHolder.gd | 38 -- client/Archipelago/keyHolderChecker.gd | 24 - client/Archipelago/keyHolderResetterListener.gd | 8 - client/Archipelago/keyboard.gd | 199 --------- client/Archipelago/locationListener.gd | 20 - client/Archipelago/manager.gd | 571 ------------------------ client/Archipelago/messages.gd | 74 --- client/Archipelago/minimap.gd | 175 -------- client/Archipelago/painting.gd | 38 -- client/Archipelago/panel.gd | 101 ----- client/Archipelago/pauseMenu.gd | 44 -- client/Archipelago/player.gd | 369 --------------- client/Archipelago/rainbowText.gd | 10 - client/Archipelago/saver.gd | 23 - client/Archipelago/settings_buttons.gd | 24 - client/Archipelago/settings_screen.gd | 261 ----------- client/Archipelago/teleport.gd | 38 -- client/Archipelago/teleportListener.gd | 49 -- client/Archipelago/textclient.gd | 95 ---- client/Archipelago/vendor/LICENSE | 21 - client/Archipelago/vendor/uuid.gd | 195 -------- client/Archipelago/victoryListener.gd | 20 - client/Archipelago/visibilityListener.gd | 38 -- client/Archipelago/worldport.gd | 53 --- client/Archipelago/worldportListener.gd | 8 - 32 files changed, 3255 deletions(-) delete mode 100644 client/Archipelago/animationListener.gd delete mode 100644 client/Archipelago/client.gd delete mode 100644 client/Archipelago/collectable.gd delete mode 100644 client/Archipelago/compass.gd delete mode 100644 client/Archipelago/compass_overlay.gd delete mode 100644 client/Archipelago/door.gd delete mode 100644 client/Archipelago/gamedata.gd delete mode 100644 client/Archipelago/keyHolder.gd delete mode 100644 client/Archipelago/keyHolderChecker.gd delete mode 100644 client/Archipelago/keyHolderResetterListener.gd delete mode 100644 client/Archipelago/keyboard.gd delete mode 100644 client/Archipelago/locationListener.gd delete mode 100644 client/Archipelago/manager.gd delete mode 100644 client/Archipelago/messages.gd delete mode 100644 client/Archipelago/minimap.gd delete mode 100644 client/Archipelago/painting.gd delete mode 100644 client/Archipelago/panel.gd delete mode 100644 client/Archipelago/pauseMenu.gd delete mode 100644 client/Archipelago/player.gd delete mode 100644 client/Archipelago/rainbowText.gd delete mode 100644 client/Archipelago/saver.gd delete mode 100644 client/Archipelago/settings_buttons.gd delete mode 100644 client/Archipelago/settings_screen.gd delete mode 100644 client/Archipelago/teleport.gd delete mode 100644 client/Archipelago/teleportListener.gd delete mode 100644 client/Archipelago/textclient.gd delete mode 100644 client/Archipelago/vendor/LICENSE delete mode 100644 client/Archipelago/vendor/uuid.gd delete mode 100644 client/Archipelago/victoryListener.gd delete mode 100644 client/Archipelago/visibilityListener.gd delete mode 100644 client/Archipelago/worldport.gd delete mode 100644 client/Archipelago/worldportListener.gd (limited to 'client') diff --git a/client/Archipelago/animationListener.gd b/client/Archipelago/animationListener.gd deleted file mode 100644 index c3b26db..0000000 --- a/client/Archipelago/animationListener.gd +++ /dev/null @@ -1,38 +0,0 @@ -extends "res://scripts/nodes/listeners/animationListener.gd" - -var item_id -var item_amount - - -func _ready(): - var node_path = String( - get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names() - ) - - var gamedata = global.get_node("Gamedata") - var door_id = gamedata.get_door_for_map_node_path(global.map, node_path) - if door_id != null: - var ap = global.get_node("Archipelago") - var item_lock = ap.get_item_id_for_door(door_id) - - if item_lock != null: - item_id = item_lock[0] - item_amount = item_lock[1] - - self.senders = [] - self.senderGroup = [] - self.nested = false - self.complete_at = 0 - self.max_length = 0 - self.excludeSenders = [] - - call_deferred("_readier") - - super._ready() - - -func _readier(): - var ap = global.get_node("Archipelago") - - if ap.client.getItemAmount(item_id) >= item_amount: - handleTriggered() diff --git a/client/Archipelago/client.gd b/client/Archipelago/client.gd deleted file mode 100644 index 843647d..0000000 --- a/client/Archipelago/client.gd +++ /dev/null @@ -1,417 +0,0 @@ -extends Node - -const ap_version = {"major": 0, "minor": 6, "build": 3, "class": "Version"} - -var SCRIPT_uuid - -var _ws = WebSocketPeer.new() -var _should_process = false -var _initiated_disconnect = false -var _try_wss = false -var _has_connected = false - -var _datapackages = {} -var _pending_packages = [] -var _item_id_to_name = {} # All games -var _location_id_to_name = {} # All games -var _item_name_to_id = {} # Lingo 2 only -var _location_name_to_id = {} # Lingo 2 only - -var _remote_version = {"major": 0, "minor": 0, "build": 0} -var _gen_version = {"major": 0, "minor": 0, "build": 0} - -var ap_server = "" -var ap_user = "" -var ap_pass = "" - -var _authenticated = false -var _seed = "" -var _team = 0 -var _slot = 0 -var _players = [] -var _player_name_by_slot = {} -var _game_by_player = {} -var _checked_locations = [] -var _received_indexes = [] -var _received_items = {} -var _slot_data = {} - -signal could_not_connect -signal connect_status -signal client_connected(slot_data) -signal item_received(item_id, index, player, flags, amount) -signal message_received(message) -signal location_scout_received(item_id, location_id, player, flags) - - -func _init(): - set_process_mode(Node.PROCESS_MODE_ALWAYS) - - _ws.inbound_buffer_size = 8388608 - - global._print("Instantiated APClient") - - # Read AP datapackages from file, if there are any - if FileAccess.file_exists("user://ap_datapackages"): - var file = FileAccess.open("user://ap_datapackages", FileAccess.READ) - var data = file.get_var(true) - file.close() - - if typeof(data) != TYPE_DICTIONARY: - global._print("AP datapackages file is corrupted") - data = {} - - _datapackages = data - - processDatapackages() - - -func _ready(): - pass - #_ws.connect("connection_closed", _closed) - #_ws.connect("connection_failed", _closed) - #_ws.connect("server_disconnected", _closed) - #_ws.connect("connection_error", _errored) - #_ws.connect("connection_established", _connected) - - -func _reset_state(): - _should_process = false - _authenticated = false - _try_wss = false - _has_connected = false - _received_items = {} - _received_indexes = [] - - -func _errored(): - if _try_wss: - global._print("Could not connect to AP with ws://, now trying wss://") - connectToServer(ap_server, ap_user, ap_pass) - else: - global._print("AP connection failed") - _reset_state() - - emit_signal( - "could_not_connect", - "Could not connect to Archipelago. Check that your server and port are correct. See the error log for more information." - ) - - -func _closed(_was_clean = true): - global._print("Connection closed") - _reset_state() - - if not _initiated_disconnect: - emit_signal("could_not_connect", "Disconnected from Archipelago") - - _initiated_disconnect = false - - -func _connected(_proto = ""): - global._print("Connected!") - _try_wss = false - - -func disconnect_from_ap(): - _initiated_disconnect = true - _ws.close() - - -func _process(_delta): - if _should_process: - _ws.poll() - - var state = _ws.get_ready_state() - if state == WebSocketPeer.STATE_OPEN: - if not _has_connected: - _has_connected = true - - _connected() - - while _ws.get_available_packet_count(): - var packet = _ws.get_packet() - global._print("Got data from server: " + packet.get_string_from_utf8()) - var json = JSON.new() - var jserror = json.parse(packet.get_string_from_utf8()) - if jserror != OK: - global._print("Error parsing packet from AP: " + jserror.error_string) - return - - for message in json.data: - var cmd = message["cmd"] - global._print("Received command: " + cmd) - - if cmd == "RoomInfo": - _seed = message["seed_name"] - _remote_version = message["version"] - _gen_version = message["generator_version"] - - var needed_games = [] - for game in message["datapackage_checksums"].keys(): - if ( - !_datapackages.has(game) - or ( - _datapackages[game]["checksum"] - != message["datapackage_checksums"][game] - ) - ): - needed_games.append(game) - - if !needed_games.is_empty(): - _pending_packages = needed_games - var cur_needed = _pending_packages.pop_front() - requestDatapackages([cur_needed]) - else: - connectToRoom() - - elif cmd == "DataPackage": - for game in message["data"]["games"].keys(): - _datapackages[game] = message["data"]["games"][game] - saveDatapackages() - - if !_pending_packages.is_empty(): - var cur_needed = _pending_packages.pop_front() - requestDatapackages([cur_needed]) - else: - processDatapackages() - connectToRoom() - - elif cmd == "Connected": - _authenticated = true - _team = message["team"] - _slot = message["slot"] - _players = message["players"] - _checked_locations = message["checked_locations"] - _slot_data = message["slot_data"] - - for player in _players: - _player_name_by_slot[player["slot"]] = player["alias"] - _game_by_player[player["slot"]] = message["slot_info"][str( - player["slot"] - )]["game"] - - emit_signal("client_connected", _slot_data) - - elif cmd == "ConnectionRefused": - var error_message = "" - for error in message["errors"]: - var submsg = "" - if error == "InvalidSlot": - submsg = "Invalid player name." - elif error == "InvalidGame": - submsg = "The specified player is not playing Lingo." - elif error == "IncompatibleVersion": - submsg = ( - "The Archipelago server is not the correct version for this client. Expected v%d.%d.%d. Found v%d.%d.%d." - % [ - ap_version["major"], - ap_version["minor"], - ap_version["build"], - _remote_version["major"], - _remote_version["minor"], - _remote_version["build"] - ] - ) - elif error == "InvalidPassword": - submsg = "Incorrect password." - elif error == "InvalidItemsHandling": - submsg = "Invalid item handling flag. This is a bug with the client." - - if submsg != "": - if error_message != "": - error_message += " " - error_message += submsg - - if error_message == "": - error_message = "Unknown error." - - _initiated_disconnect = true - _ws.close() - - emit_signal("could_not_connect", error_message) - global._print("Connection to AP refused") - global._print(message) - - elif cmd == "ReceivedItems": - var i = 0 - for item in message["items"]: - var index = int(message["index"] + i) - i += 1 - - if _received_indexes.has(index): - # Do not re-process items. - continue - - _received_indexes.append(index) - - var item_id = int(item["item"]) - _received_items[item_id] = _received_items.get(item_id, 0) + 1 - - emit_signal( - "item_received", - item_id, - index, - int(item["player"]), - int(item["flags"]), - _received_items[item_id] - ) - - elif cmd == "PrintJSON": - emit_signal("message_received", message) - - elif cmd == "LocationInfo": - for loc in message["locations"]: - emit_signal( - "location_scout_received", - int(loc["item"]), - int(loc["location"]), - int(loc["player"]), - int(loc["flags"]) - ) - - elif state == WebSocketPeer.STATE_CLOSED: - if _has_connected: - _closed() - else: - _errored() - - -func saveDatapackages(): - # Save the AP datapackages to disk. - var file = FileAccess.open("user://ap_datapackages", FileAccess.WRITE) - file.store_var(_datapackages, true) - file.close() - - -func connectToServer(server, un, pw): - ap_server = server - ap_user = un - ap_pass = pw - - _initiated_disconnect = false - - var url = "" - if ap_server.begins_with("ws://") or ap_server.begins_with("wss://"): - url = ap_server - _try_wss = false - elif _try_wss: - url = "wss://" + ap_server - _try_wss = false - else: - url = "ws://" + ap_server - _try_wss = true - - var err = _ws.connect_to_url(url) - if err != OK: - emit_signal( - "could_not_connect", - ( - "Could not connect to Archipelago. Check that your server and port are correct. See the error log for more information. Error code: %d." - % err - ) - ) - global._print("Could not connect to AP: %d" % err) - return - _should_process = true - - emit_signal("connect_status", "Connecting...") - - -func sendMessage(msg): - var payload = JSON.stringify(msg) - _ws.send_text(payload) - - -func requestDatapackages(games): - emit_signal("connect_status", "Downloading %s data package..." % games[0]) - - sendMessage([{"cmd": "GetDataPackage", "games": games}]) - - -func processDatapackages(): - _item_id_to_name = {} - _location_id_to_name = {} - for game in _datapackages.keys(): - var package = _datapackages[game] - - _item_id_to_name[game] = {} - for item_name in package["item_name_to_id"].keys(): - _item_id_to_name[game][int(package["item_name_to_id"][item_name])] = item_name - - _location_id_to_name[game] = {} - for location_name in package["location_name_to_id"].keys(): - _location_id_to_name[game][int(package["location_name_to_id"][location_name])] = location_name - - if _datapackages.has("Lingo 2"): - _item_name_to_id = _datapackages["Lingo 2"]["item_name_to_id"] - _location_name_to_id = _datapackages["Lingo 2"]["location_name_to_id"] - - -func connectToRoom(): - emit_signal("connect_status", "Authenticating...") - - sendMessage( - [ - { - "cmd": "Connect", - "password": ap_pass, - "game": "Lingo 2", - "name": ap_user, - "uuid": SCRIPT_uuid.v4(), - "version": ap_version, - "items_handling": 0b111, # always receive our items - "tags": [], - "slot_data": true - } - ] - ) - - -func sendConnectUpdate(tags): - sendMessage([{"cmd": "ConnectUpdate", "tags": tags}]) - - -func requestSync(): - sendMessage([{"cmd": "Sync"}]) - - -func sendLocation(loc_id): - sendMessage([{"cmd": "LocationChecks", "locations": [loc_id]}]) - - -func sendLocations(loc_ids): - sendMessage([{"cmd": "LocationChecks", "locations": loc_ids}]) - - -func setValue(key, value, operation = "replace"): - sendMessage( - [ - { - "cmd": "Set", - "key": "Lingo2_%d_%s" % [_slot, key], - "want_reply": false, - "operations": [{"operation": operation, "value": value}] - } - ] - ) - - -func say(textdata): - sendMessage([{"cmd": "Say", "text": textdata}]) - - -func completedGoal(): - sendMessage([{"cmd": "StatusUpdate", "status": 30}]) # CLIENT_GOAL - - -func scoutLocations(loc_ids): - sendMessage([{"cmd": "LocationScouts", "locations": loc_ids}]) - - -func hasItem(item_id): - return _received_items.has(item_id) - - -func getItemAmount(item_id): - return _received_items.get(item_id, 0) diff --git a/client/Archipelago/collectable.gd b/client/Archipelago/collectable.gd deleted file mode 100644 index 4a17a2a..0000000 --- a/client/Archipelago/collectable.gd +++ /dev/null @@ -1,16 +0,0 @@ -extends "res://scripts/nodes/collectable.gd" - - -func pickedUp(): - if unlock_type == "key": - var ap = global.get_node("Archipelago") - if ap.get_letter_behavior(unlock_key, level == 2) == ap.kLETTER_BEHAVIOR_VANILLA: - ap.keyboard.collect_local_letter(unlock_key, level) - else: - ap.keyboard.update_unlocks() - - super.pickedUp() - - -func setScoutedText(text): - get_node("MeshInstance3D").mesh.text = text.replace(" ", "\n") diff --git a/client/Archipelago/compass.gd b/client/Archipelago/compass.gd deleted file mode 100644 index c90475a..0000000 --- a/client/Archipelago/compass.gd +++ /dev/null @@ -1,66 +0,0 @@ -extends Node2D - -const RADIUS = 48 - -var _font - - -func _ready(): - _font = load("res://assets/fonts/Lingo2.ttf") - - -func _draw(): - draw_circle(Vector2.ZERO, RADIUS, Color(1.0, 1.0, 1.0, 0.8), true) - draw_circle(Vector2.ZERO, RADIUS, Color.BLACK, false) - draw_string( - _font, - Vector2(-4, -RADIUS * 3.0 / 4.0), - "N", - HorizontalAlignment.HORIZONTAL_ALIGNMENT_LEFT, - -1, - 16, - Color.BLACK - ) - draw_set_transform(Vector2.ZERO, PI / 2) - draw_string( - _font, - Vector2(-4, -RADIUS * 3.0 / 4.0), - "E", - HorizontalAlignment.HORIZONTAL_ALIGNMENT_LEFT, - -1, - 16, - Color.BLACK - ) - draw_set_transform(Vector2.ZERO, PI) - draw_string( - _font, - Vector2(-4, -RADIUS * 3.0 / 4.0), - "S", - HorizontalAlignment.HORIZONTAL_ALIGNMENT_LEFT, - -1, - 16, - Color.BLACK - ) - draw_set_transform(Vector2.ZERO, PI * 3.0 / 2.0) - draw_string( - _font, - Vector2(-4, -RADIUS * 3.0 / 4.0), - "W", - HorizontalAlignment.HORIZONTAL_ALIGNMENT_LEFT, - -1, - 16, - Color.BLACK - ) - draw_set_transform(Vector2.ZERO) - draw_colored_polygon( - PackedVector2Array( - [Vector2(0, -RADIUS * 5.0 / 8.0), Vector2(-RADIUS / 6.0, 0), Vector2(RADIUS / 6.0, 0)] - ), - Color.RED - ) - draw_colored_polygon( - PackedVector2Array( - [Vector2(0, RADIUS * 5.0 / 8.0), Vector2(-RADIUS / 6.0, 0), Vector2(RADIUS / 6.0, 0)] - ), - Color.GRAY - ) diff --git a/client/Archipelago/compass_overlay.gd b/client/Archipelago/compass_overlay.gd deleted file mode 100644 index 56e81ff..0000000 --- a/client/Archipelago/compass_overlay.gd +++ /dev/null @@ -1,17 +0,0 @@ -extends CanvasLayer - -var SCRIPT_compass - -var compass - - -func _ready(): - compass = SCRIPT_compass.new() - compass.position = Vector2(1840, 80) - add_child(compass) - - visible = false - - -func update_rotation(ry): - compass.rotation = ry diff --git a/client/Archipelago/door.gd b/client/Archipelago/door.gd deleted file mode 100644 index 49f5728..0000000 --- a/client/Archipelago/door.gd +++ /dev/null @@ -1,46 +0,0 @@ -extends "res://scripts/nodes/door.gd" - -var item_id -var item_amount - - -func _ready(): - var node_path = String( - get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names() - ) - - var gamedata = global.get_node("Gamedata") - var door_id = gamedata.get_door_for_map_node_path(global.map, node_path) - if door_id != null: - var ap = global.get_node("Archipelago") - var item_lock = ap.get_item_id_for_door(door_id) - - if item_lock != null: - item_id = item_lock[0] - item_amount = item_lock[1] - - self.senders = [] - self.senderGroup = [] - self.nested = false - self.complete_at = 0 - self.max_length = 0 - self.excludeSenders = [] - - call_deferred("_readier") - - if global.map == "the_sun_temple": - if name == "spe_EndPlatform" or name == "spe_entry_2": - senders = [NodePath("/root/scene/Panels/EndCheck_dog")] - - if global.map == "the_parthenon": - if name == "spe_entry_1": - senders = [NodePath("/root/scene/Panels/EndCheck_dog")] - - super._ready() - - -func _readier(): - var ap = global.get_node("Archipelago") - - if ap.client.getItemAmount(item_id) >= item_amount: - handleTriggered() diff --git a/client/Archipelago/gamedata.gd b/client/Archipelago/gamedata.gd deleted file mode 100644 index 9eeec3b..0000000 --- a/client/Archipelago/gamedata.gd +++ /dev/null @@ -1,159 +0,0 @@ -extends Node - -var SCRIPT_proto - -var objects -var door_id_by_map_node_path = {} -var painting_id_by_map_node_path = {} -var panel_id_by_map_node_path = {} -var port_id_by_map_node_path = {} -var door_id_by_ap_id = {} -var map_id_by_name = {} -var progressive_id_by_ap_id = {} -var letter_id_by_ap_id = {} -var symbol_item_ids = [] -var anti_trap_ids = {} - -var kSYMBOL_ITEMS - - -func _init(proto_script): - SCRIPT_proto = proto_script - - kSYMBOL_ITEMS = { - SCRIPT_proto.PuzzleSymbol.SUN: "Sun Symbol", - SCRIPT_proto.PuzzleSymbol.SPARKLES: "Sparkles Symbol", - SCRIPT_proto.PuzzleSymbol.ZERO: "Zero Symbol", - SCRIPT_proto.PuzzleSymbol.EXAMPLE: "Example Symbol", - SCRIPT_proto.PuzzleSymbol.BOXES: "Boxes Symbol", - SCRIPT_proto.PuzzleSymbol.PLANET: "Planet Symbol", - SCRIPT_proto.PuzzleSymbol.PYRAMID: "Pyramid Symbol", - SCRIPT_proto.PuzzleSymbol.CROSS: "Cross Symbol", - SCRIPT_proto.PuzzleSymbol.SWEET: "Sweet Symbol", - SCRIPT_proto.PuzzleSymbol.GENDER: "Gender Symbol", - SCRIPT_proto.PuzzleSymbol.AGE: "Age Symbol", - SCRIPT_proto.PuzzleSymbol.SOUND: "Sound Symbol", - SCRIPT_proto.PuzzleSymbol.ANAGRAM: "Anagram Symbol", - SCRIPT_proto.PuzzleSymbol.JOB: "Job Symbol", - SCRIPT_proto.PuzzleSymbol.STARS: "Stars Symbol", - SCRIPT_proto.PuzzleSymbol.NULL: "Null Symbol", - SCRIPT_proto.PuzzleSymbol.EVAL: "Eval Symbol", - SCRIPT_proto.PuzzleSymbol.LINGO: "Lingo Symbol", - SCRIPT_proto.PuzzleSymbol.QUESTION: "Question Symbol", - } - - -func load(data_bytes): - objects = SCRIPT_proto.AllObjects.new() - - var result_code = objects.from_bytes(data_bytes) - if result_code != SCRIPT_proto.PB_ERR.NO_ERRORS: - print("Could not load generated data: %d" % result_code) - return - - for map in objects.get_maps(): - map_id_by_name[map.get_name()] = map.get_id() - - for door in objects.get_doors(): - var map = objects.get_maps()[door.get_map_id()] - - if not map.get_name() in door_id_by_map_node_path: - door_id_by_map_node_path[map.get_name()] = {} - - var map_data = door_id_by_map_node_path[map.get_name()] - for receiver in door.get_receivers(): - map_data[receiver] = door.get_id() - - for painting_id in door.get_move_paintings(): - var painting = objects.get_paintings()[painting_id] - map_data[painting.get_path()] = door.get_id() - - if door.has_ap_id(): - door_id_by_ap_id[door.get_ap_id()] = door.get_id() - - for painting in objects.get_paintings(): - var room = objects.get_rooms()[painting.get_room_id()] - var map = objects.get_maps()[room.get_map_id()] - - if not map.get_name() in painting_id_by_map_node_path: - painting_id_by_map_node_path[map.get_name()] = {} - - var _map_data = painting_id_by_map_node_path[map.get_name()] - - for port in objects.get_ports(): - var room = objects.get_rooms()[port.get_room_id()] - var map = objects.get_maps()[room.get_map_id()] - - if not map.get_name() in port_id_by_map_node_path: - port_id_by_map_node_path[map.get_name()] = {} - - var map_data = port_id_by_map_node_path[map.get_name()] - map_data[port.get_path()] = port.get_id() - - for progressive in objects.get_progressives(): - progressive_id_by_ap_id[progressive.get_ap_id()] = progressive.get_id() - - for letter in objects.get_letters(): - letter_id_by_ap_id[letter.get_ap_id()] = letter.get_id() - - for panel in objects.get_panels(): - var room = objects.get_rooms()[panel.get_room_id()] - var map = objects.get_maps()[room.get_map_id()] - - if not map.get_name() in panel_id_by_map_node_path: - panel_id_by_map_node_path[map.get_name()] = {} - - var map_data = panel_id_by_map_node_path[map.get_name()] - map_data[panel.get_path()] = panel.get_id() - - for symbol_name in kSYMBOL_ITEMS.values(): - symbol_item_ids.append(objects.get_special_ids()[symbol_name]) - - for special_name in objects.get_special_ids().keys(): - if special_name.begins_with("Anti "): - anti_trap_ids[objects.get_special_ids()[special_name]] = ( - special_name.substr(5).to_lower() - ) - - -func get_door_for_map_node_path(map_name, node_path): - if not door_id_by_map_node_path.has(map_name): - return null - - var map_data = door_id_by_map_node_path[map_name] - return map_data.get(node_path, null) - - -func get_panel_for_map_node_path(map_name, node_path): - if not panel_id_by_map_node_path.has(map_name): - return null - - var map_data = panel_id_by_map_node_path[map_name] - return map_data.get(node_path, null) - - -func get_port_for_map_node_path(map_name, node_path): - if not port_id_by_map_node_path.has(map_name): - return null - - var map_data = port_id_by_map_node_path[map_name] - return map_data.get(node_path, null) - - -func get_door_ap_id(door_id): - var door = objects.get_doors()[door_id] - if door.has_ap_id(): - return door.get_ap_id() - else: - return null - - -func get_door_receivers(door_id): - var door = objects.get_doors()[door_id] - return door.get_receivers() - - -func get_door_map_name(door_id): - var door = objects.get_doors()[door_id] - var map = objects.get_maps()[door.get_map_id()] - return map.get_name() diff --git a/client/Archipelago/keyHolder.gd b/client/Archipelago/keyHolder.gd deleted file mode 100644 index 3c037ff..0000000 --- a/client/Archipelago/keyHolder.gd +++ /dev/null @@ -1,38 +0,0 @@ -extends "res://scripts/nodes/keyHolder.gd" - - -func setFromAp(key, level): - if level > 0: - has_key = true - is_complete = "%s%d" % [key, level] - held_key = key - held_level = level - get_node("Hinge/Letter").mesh.text = held_key - get_node("Hinge/Letter2").mesh.text = held_key - setMaterial() - emit_signal("trigger") - else: - has_key = false - held_key = "" - held_level = 0 - setMaterial() - get_node("Hinge/Letter").mesh.text = "-" - get_node("Hinge/Letter2").mesh.text = "-" - is_complete = "" - emit_signal("untrigger") - - -func addKey(key): - var node_path = String( - get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names() - ) - var ap = global.get_node("Archipelago") - ap.keyboard.put_in_keyholder(key, global.map, node_path) - - -func removeKey(): - var node_path = String( - get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names() - ) - var ap = global.get_node("Archipelago") - ap.keyboard.remove_from_keyholder(held_key, global.map, node_path) diff --git a/client/Archipelago/keyHolderChecker.gd b/client/Archipelago/keyHolderChecker.gd deleted file mode 100644 index a75a9e4..0000000 --- a/client/Archipelago/keyHolderChecker.gd +++ /dev/null @@ -1,24 +0,0 @@ -extends "res://scripts/nodes/listeners/keyHolderChecker.gd" - - -func check(): - var ap = global.get_node("Archipelago") - var matches = [] - for map in ap.keyboard.keyholder_state.keys(): - var nodes = ap.keyboard.keyholder_state[map] - for node in nodes.keys(): - matches.append([nodes[node], 1, map, "/root/scene/%s" % node]) - - var count = 0 - for key_match in matches: - var active = ( - key_match[2] + String(key_match[3]).replace("/root/scene/Components/KeyHolders/", ".") - ) - if map[active] == key_match[0]: - emit_signal("trigger_letter", key_match[0], true) - count += 1 - else: - emit_signal("trigger_letter", key_match[0], false) - - if count > 25: - emit_signal("trigger") diff --git a/client/Archipelago/keyHolderResetterListener.gd b/client/Archipelago/keyHolderResetterListener.gd deleted file mode 100644 index d5300f3..0000000 --- a/client/Archipelago/keyHolderResetterListener.gd +++ /dev/null @@ -1,8 +0,0 @@ -extends "res://scripts/nodes/listeners/keyHolderResetterListener.gd" - - -func reset(): - var ap = global.get_node("Archipelago") - var was_removed = ap.keyboard.reset_keyholders() - if was_removed: - sfxPlayer.sfx_play("pickup") diff --git a/client/Archipelago/keyboard.gd b/client/Archipelago/keyboard.gd deleted file mode 100644 index 450566d..0000000 --- a/client/Archipelago/keyboard.gd +++ /dev/null @@ -1,199 +0,0 @@ -extends Node - -const kALL_LETTERS = "abcdefghjiklmnopqrstuvwxyz" - -var letters_saved = {} -var letters_in_keyholders = [] -var letters_blocked = [] -var letters_dynamic = {} -var keyholder_state = {} - -var filename = "" - - -func _init(): - reset() - - -func reset(): - letters_saved.clear() - letters_in_keyholders.clear() - letters_blocked.clear() - letters_dynamic.clear() - keyholder_state.clear() - - -func load_seed(): - var ap = global.get_node("Archipelago") - - reset() - - filename = "user://archipelago_keys/%s_%d" % [ap.client._seed, ap.client._slot] - - if FileAccess.file_exists(filename): - var ap_file = FileAccess.open(filename, FileAccess.READ) - var localdata = [] - if ap_file != null: - localdata = ap_file.get_var(true) - ap_file.close() - - if typeof(localdata) != TYPE_ARRAY: - print("AP keyboard file is corrupted") - localdata = [] - - if localdata.size() > 0: - letters_saved = localdata[0] - if localdata.size() > 1: - letters_in_keyholders = localdata[1] - if localdata.size() > 2: - keyholder_state = localdata[2] - - for k in kALL_LETTERS: - var level = 0 - - if ap.get_letter_behavior(k, false) == ap.kLETTER_BEHAVIOR_UNLOCKED: - level += 1 - if ap.get_letter_behavior(k, true) == ap.kLETTER_BEHAVIOR_UNLOCKED: - level += 1 - - letters_dynamic[k] = level - - update_unlocks() - - -func save(): - var dir = DirAccess.open("user://") - var folder = "archipelago_keys" - if not dir.dir_exists(folder): - dir.make_dir(folder) - - var file = FileAccess.open(filename, FileAccess.WRITE) - - var data = [ - letters_saved, - letters_in_keyholders, - keyholder_state, - ] - file.store_var(data, true) - file.close() - - -func update_unlocks(): - unlocks.resetKeys() - - var has_doubles = false - - for k in kALL_LETTERS: - var level = 0 - - if not letters_in_keyholders.has(k): - level = letters_saved.get(k, 0) + letters_dynamic.get(k, 0) - - if level >= 2: - level = 2 - has_doubles = true - - if letters_blocked.has(k): - level = 0 - - unlocks.unlockKey(k, level) - - if has_doubles and unlocks.data["double_letters"] != "unlocked": - var ap = global.get_node("Archipelago") - if ap.cyan_door_behavior == ap.kCYAN_DOOR_BEHAVIOR_DOUBLE_LETTER: - unlocks.setData("double_letters", "unlocked") - - -func collect_local_letter(key, level): - if level < 0 or level > 2 or level < letters_saved.get(key, 0): - return - - letters_saved[key] = level - - if letters_blocked.has(key): - letters_blocked.erase(key) - - update_unlocks() - save() - - -func collect_remote_letter(key, level): - if level < 0 or level > 2 or level < letters_dynamic.get(key, 0): - return - - letters_dynamic[key] = level - - if letters_blocked.has(key): - letters_blocked.erase(key) - - update_unlocks() - save() - - -func put_in_keyholder(key, map, kh_path): - if not keyholder_state.has(map): - keyholder_state[map] = {} - - keyholder_state[map][kh_path] = key - letters_in_keyholders.append(key) - - get_tree().get_root().get_node("scene").get_node(kh_path).setFromAp( - key, min(letters_saved.get(key, 0) + letters_dynamic.get(key, 0), 2) - ) - - update_unlocks() - save() - - -func remove_from_keyholder(key, map, kh_path): - if not keyholder_state.has(map): - # This... shouldn't happen. - keyholder_state[map] = {} - - keyholder_state[map].erase(kh_path) - letters_in_keyholders.erase(key) - - get_tree().get_root().get_node("scene").get_node(kh_path).setFromAp(key, 0) - - update_unlocks() - save() - - -func block_letter(key): - if not letters_blocked.has(key): - letters_blocked.append(key) - - update_unlocks() - - -func load_keyholders(map): - if keyholder_state.has(map): - var khs = keyholder_state[map] - - for path in khs.keys(): - var key = khs[path] - get_tree().get_root().get_node("scene").get_node(path).setFromAp( - key, min(letters_saved.get(key, 0) + letters_dynamic.get(key, 0), 2) - ) - - -func reset_keyholders(): - if letters_in_keyholders.is_empty() and letters_blocked.is_empty(): - return false - - var cleared_anything = not letters_in_keyholders.is_empty() or not letters_blocked.is_empty() - - if keyholder_state.has(global.map): - for path in keyholder_state[global.map]: - get_tree().get_root().get_node("scene").get_node(path).setFromAp( - keyholder_state[global.map][path], 0 - ) - - keyholder_state.clear() - letters_in_keyholders.clear() - letters_blocked.clear() - - update_unlocks() - save() - - return cleared_anything diff --git a/client/Archipelago/locationListener.gd b/client/Archipelago/locationListener.gd deleted file mode 100644 index 71792ed..0000000 --- a/client/Archipelago/locationListener.gd +++ /dev/null @@ -1,20 +0,0 @@ -extends Receiver - -var location_id - - -func _ready(): - super._ready() - - -func handleTriggered(): - triggered += 1 - if triggered >= total: - var ap = global.get_node("Archipelago") - ap.send_location(location_id) - - -func handleUntriggered(): - triggered -= 1 - if triggered < total: - pass diff --git a/client/Archipelago/manager.gd b/client/Archipelago/manager.gd deleted file mode 100644 index b170c77..0000000 --- a/client/Archipelago/manager.gd +++ /dev/null @@ -1,571 +0,0 @@ -extends Node - -const MOD_VERSION = 7 - -var SCRIPT_client -var SCRIPT_keyboard -var SCRIPT_locationListener -var SCRIPT_minimap -var SCRIPT_uuid -var SCRIPT_victoryListener - -var ap_server = "" -var ap_user = "" -var ap_pass = "" -var connection_history = [] -var show_compass = false - -var client -var keyboard - -var _localdata_file = "" -var _last_new_item = -1 -var _batch_locations = false -var _held_locations = [] -var _held_location_scouts = [] -var _location_scouts = {} -var _item_locks = {} -var _inverse_item_locks = {} -var _held_letters = {} -var _letters_setup = false - -const kSHUFFLE_LETTERS_VANILLA = 0 -const kSHUFFLE_LETTERS_UNLOCKED = 1 -const kSHUFFLE_LETTERS_PROGRESSIVE = 2 -const kSHUFFLE_LETTERS_VANILLA_CYAN = 3 -const kSHUFFLE_LETTERS_ITEM_CYAN = 4 - -const kLETTER_BEHAVIOR_VANILLA = 0 -const kLETTER_BEHAVIOR_ITEM = 1 -const kLETTER_BEHAVIOR_UNLOCKED = 2 - -const kCYAN_DOOR_BEHAVIOR_H2 = 0 -const kCYAN_DOOR_BEHAVIOR_DOUBLE_LETTER = 1 -const kCYAN_DOOR_BEHAVIOR_ITEM = 2 - -var apworld_version = [0, 0] -var cyan_door_behavior = kCYAN_DOOR_BEHAVIOR_H2 -var daedalus_roof_access = false -var keyholder_sanity = false -var port_pairings = {} -var shuffle_control_center_colors = false -var shuffle_doors = false -var shuffle_gallery_paintings = false -var shuffle_letters = kSHUFFLE_LETTERS_VANILLA -var shuffle_symbols = false -var shuffle_worldports = false -var strict_cyan_ending = false -var strict_purple_ending = false -var victory_condition = -1 - -signal could_not_connect -signal connect_status -signal ap_connected - - -func _init(): - # Read AP settings from file, if there are any - if FileAccess.file_exists("user://ap_settings"): - var file = FileAccess.open("user://ap_settings", FileAccess.READ) - var data = file.get_var(true) - file.close() - - if typeof(data) != TYPE_ARRAY: - global._print("AP settings file is corrupted") - data = [] - - if data.size() > 0: - ap_server = data[0] - - if data.size() > 1: - ap_user = data[1] - - if data.size() > 2: - ap_pass = data[2] - - if data.size() > 3: - connection_history = data[3] - - if data.size() > 4: - show_compass = data[4] - - -func _ready(): - client = SCRIPT_client.new() - client.SCRIPT_uuid = SCRIPT_uuid - - client.connect("item_received", _process_item) - client.connect("message_received", _process_message) - client.connect("location_scout_received", _process_location_scout) - client.connect("could_not_connect", _client_could_not_connect) - client.connect("connect_status", _client_connect_status) - client.connect("client_connected", _client_connected) - - add_child(client) - - keyboard = SCRIPT_keyboard.new() - add_child(keyboard) - - -func saveSettings(): - # Save the AP settings to disk. - var path = "user://ap_settings" - var file = FileAccess.open(path, FileAccess.WRITE) - - var data = [ - ap_server, - ap_user, - ap_pass, - connection_history, - show_compass, - ] - file.store_var(data, true) - file.close() - - -func saveLocaldata(): - # Save the MW/slot specific settings to disk. - var dir = DirAccess.open("user://") - var folder = "archipelago_data" - if not dir.dir_exists(folder): - dir.make_dir(folder) - - var file = FileAccess.open(_localdata_file, FileAccess.WRITE) - - var data = [ - _last_new_item, - ] - file.store_var(data, true) - file.close() - - -func connectToServer(): - _last_new_item = -1 - _batch_locations = false - _held_locations = [] - _held_location_scouts = [] - _location_scouts = {} - _letters_setup = false - _held_letters = {} - - client.connectToServer(ap_server, ap_user, ap_pass) - - -func getSaveFileName(): - return "zzAP_%s_%d" % [client._seed, client._slot] - - -func disconnect_from_ap(): - client.disconnect_from_ap() - - -func get_item_id_for_door(door_id): - return _item_locks.get(door_id, null) - - -func _process_item(item, index, from, flags, amount): - var item_name = "Unknown" - if client._item_id_to_name["Lingo 2"].has(item): - item_name = client._item_id_to_name["Lingo 2"][item] - - var gamedata = global.get_node("Gamedata") - - var prog_id = null - if _inverse_item_locks.has(item): - for lock in _inverse_item_locks.get(item): - if lock[1] != amount: - continue - - if gamedata.progressive_id_by_ap_id.has(item): - prog_id = lock[0] - - if gamedata.get_door_map_name(lock[0]) != global.map: - continue - - var receivers = gamedata.get_door_receivers(lock[0]) - var scene = get_tree().get_root().get_node_or_null("scene") - if scene != null: - for receiver in receivers: - var rnode = scene.get_node_or_null(receiver) - if rnode != null: - rnode.handleTriggered() - - var letter_id = gamedata.letter_id_by_ap_id.get(item, null) - if letter_id != null: - var letter = gamedata.objects.get_letters()[letter_id] - if not letter.has_level2() or not letter.get_level2(): - _process_key_item(letter.get_key(), amount) - - if gamedata.symbol_item_ids.has(item): - var player = get_tree().get_root().get_node_or_null("scene/player") - if player != null: - player.emit_signal("evaluate_solvability") - - # Show a message about the item if it's new. - if index != null and index > _last_new_item: - _last_new_item = index - saveLocaldata() - - var player_name = "Unknown" - if client._player_name_by_slot.has(float(from)): - player_name = client._player_name_by_slot[float(from)] - - var full_item_name = item_name - if prog_id != null: - var door = gamedata.objects.get_doors()[prog_id] - full_item_name = "%s (%s)" % [item_name, door.get_name()] - - var message - if from == client._slot: - message = "Found %s" % wrapInItemColorTags(full_item_name, flags) - else: - message = ( - "Received %s from %s" % [wrapInItemColorTags(full_item_name, flags), player_name] - ) - - if gamedata.anti_trap_ids.has(item): - keyboard.block_letter(gamedata.anti_trap_ids[item]) - - global._print(message) - - global.get_node("Messages").showMessage(message) - - -func _process_message(message): - parse_printjson_for_textclient(message) - - if ( - !message.has("receiving") - or !message.has("item") - or message["item"]["player"] != client._slot - ): - return - - var item_name = "Unknown" - var item_player_game = client._game_by_player[message["receiving"]] - if client._item_id_to_name[item_player_game].has(int(message["item"]["item"])): - item_name = client._item_id_to_name[item_player_game][int(message["item"]["item"])] - - var location_name = "Unknown" - var location_player_game = client._game_by_player[message["item"]["player"]] - if client._location_id_to_name[location_player_game].has(int(message["item"]["location"])): - location_name = (client._location_id_to_name[location_player_game][int( - message["item"]["location"] - )]) - - var player_name = "Unknown" - if client._player_name_by_slot.has(message["receiving"]): - player_name = client._player_name_by_slot[message["receiving"]] - - var item_color = colorForItemType(message["item"]["flags"]) - - if message["type"] == "Hint": - var is_for = "" - if message["receiving"] != client._slot: - is_for = " for %s" % player_name - if !message.has("found") || !message["found"]: - global.get_node("Messages").showMessage( - ( - "Hint: %s%s is on %s" - % [ - wrapInItemColorTags(item_name, message["item"]["flags"]), - is_for, - location_name - ] - ) - ) - else: - if message["receiving"] != client._slot: - var sentMsg = ( - "Sent %s to %s" - % [wrapInItemColorTags(item_name, message["item"]["flags"]), player_name] - ) - #if _hinted_locations.has(message["item"]["location"]): - # sentMsg += " ([color=#fafad2]Hinted![/color])" - global.get_node("Messages").showMessage(sentMsg) - - -func parse_printjson_for_textclient(message): - var parts = [] - for message_part in message["data"]: - if !message_part.has("type") and message_part.has("text"): - parts.append(message_part["text"]) - elif message_part["type"] == "player_id": - if int(message_part["text"]) == client._slot: - parts.append( - "[color=#ee00ee]%s[/color]" % client._player_name_by_slot[client._slot] - ) - else: - var from = float(message_part["text"]) - parts.append("[color=#fafad2]%s[/color]" % client._player_name_by_slot[from]) - elif message_part["type"] == "item_id": - var item_name = "Unknown" - var item_player_game = client._game_by_player[message_part["player"]] - if client._item_id_to_name[item_player_game].has(int(message_part["text"])): - item_name = client._item_id_to_name[item_player_game][int(message_part["text"])] - - parts.append(wrapInItemColorTags(item_name, message_part["flags"])) - elif message_part["type"] == "location_id": - var location_name = "Unknown" - var location_player_game = client._game_by_player[message_part["player"]] - if client._location_id_to_name[location_player_game].has(int(message_part["text"])): - location_name = client._location_id_to_name[location_player_game][int( - message_part["text"] - )] - - parts.append("[color=#00ff7f]%s[/color]" % location_name) - elif message_part.has("text"): - parts.append(message_part["text"]) - - var textclient_node = global.get_node("Textclient") - if textclient_node != null: - textclient_node.parse_printjson("".join(parts)) - - -func _process_location_scout(item_id, location_id, player, flags): - _location_scouts[location_id] = {"item": item_id, "player": player, "flags": flags} - - if player == client._slot and flags & 4 != 0: - # This is a trap for us, so let's not display it. - return - - var gamedata = global.get_node("Gamedata") - var map_id = gamedata.map_id_by_name.get(global.map) - - var item_name = "Unknown" - var item_player_game = client._game_by_player[float(player)] - if client._item_id_to_name[item_player_game].has(item_id): - item_name = client._item_id_to_name[item_player_game][item_id] - - var letter_id = gamedata.letter_id_by_ap_id.get(location_id, null) - if letter_id != null: - var letter = gamedata.objects.get_letters()[letter_id] - var room = gamedata.objects.get_rooms()[letter.get_room_id()] - if room.get_map_id() == map_id: - var collectable = get_tree().get_root().get_node("scene").get_node_or_null( - letter.get_path() - ) - if collectable != null: - collectable.setScoutedText(item_name) - - -func _client_could_not_connect(message): - emit_signal("could_not_connect", message) - - -func _client_connect_status(message): - emit_signal("connect_status", message) - - -func _client_connected(slot_data): - var gamedata = global.get_node("Gamedata") - - _localdata_file = "user://archipelago_data/%s_%d" % [client._seed, client._slot] - _last_new_item = -1 - - if FileAccess.file_exists(_localdata_file): - var ap_file = FileAccess.open(_localdata_file, FileAccess.READ) - var localdata = [] - if ap_file != null: - localdata = ap_file.get_var(true) - ap_file.close() - - if typeof(localdata) != TYPE_ARRAY: - print("AP localdata file is corrupted") - localdata = [] - - if localdata.size() > 0: - _last_new_item = localdata[0] - - # Read slot data. - cyan_door_behavior = int(slot_data.get("cyan_door_behavior", 0)) - daedalus_roof_access = bool(slot_data.get("daedalus_roof_access", false)) - keyholder_sanity = bool(slot_data.get("keyholder_sanity", false)) - shuffle_control_center_colors = bool(slot_data.get("shuffle_control_center_colors", false)) - shuffle_doors = bool(slot_data.get("shuffle_doors", false)) - shuffle_gallery_paintings = bool(slot_data.get("shuffle_gallery_paintings", false)) - shuffle_letters = int(slot_data.get("shuffle_letters", 0)) - shuffle_symbols = bool(slot_data.get("shuffle_symbols", false)) - shuffle_worldports = bool(slot_data.get("shuffle_worldports", false)) - strict_cyan_ending = bool(slot_data.get("strict_cyan_ending", false)) - strict_purple_ending = bool(slot_data.get("strict_purple_ending", false)) - victory_condition = int(slot_data.get("victory_condition", 0)) - - if slot_data.has("version"): - apworld_version = [int(slot_data["version"][0]), int(slot_data["version"][1])] - - port_pairings.clear() - if slot_data.has("port_pairings"): - var raw_pp = slot_data.get("port_pairings") - - for p1 in raw_pp.keys(): - port_pairings[int(p1)] = int(raw_pp[p1]) - - # Set up item locks. - _item_locks = {} - - if shuffle_doors: - for door in gamedata.objects.get_doors(): - if ( - door.get_type() == gamedata.SCRIPT_proto.DoorType.STANDARD - or door.get_type() == gamedata.SCRIPT_proto.DoorType.ITEM_ONLY - ): - _item_locks[door.get_id()] = [door.get_ap_id(), 1] - - for progressive in gamedata.objects.get_progressives(): - for i in range(0, progressive.get_doors().size()): - var door = gamedata.objects.get_doors()[progressive.get_doors()[i]] - _item_locks[door.get_id()] = [progressive.get_ap_id(), i + 1] - - for door_group in gamedata.objects.get_door_groups(): - if door_group.get_type() == gamedata.SCRIPT_proto.DoorGroupType.CONNECTOR: - if shuffle_worldports: - continue - elif door_group.get_type() != gamedata.SCRIPT_proto.DoorGroupType.SHUFFLE_GROUP: - continue - - for door in door_group.get_doors(): - _item_locks[door] = [door_group.get_ap_id(), 1] - - if shuffle_control_center_colors: - for door in gamedata.objects.get_doors(): - if door.get_type() == gamedata.SCRIPT_proto.DoorType.CONTROL_CENTER_COLOR: - _item_locks[door.get_id()] = [door.get_ap_id(), 1] - - for door_group in gamedata.objects.get_door_groups(): - if ( - door_group.get_type() == gamedata.SCRIPT_proto.DoorGroupType.COLOR_CONNECTOR - and not shuffle_worldports - ): - for door in door_group.get_doors(): - _item_locks[door] = [door_group.get_ap_id(), 1] - - if shuffle_gallery_paintings: - for door in gamedata.objects.get_doors(): - if door.get_type() == gamedata.SCRIPT_proto.DoorType.GALLERY_PAINTING: - _item_locks[door.get_id()] = [door.get_ap_id(), 1] - - if cyan_door_behavior == kCYAN_DOOR_BEHAVIOR_ITEM: - for door_group in gamedata.objects.get_door_groups(): - if door_group.get_type() == gamedata.SCRIPT_proto.DoorGroupType.CYAN_DOORS: - for door in door_group.get_doors(): - if not _item_locks.has(door): - _item_locks[door] = [door_group.get_ap_id(), 1] - - # Create a reverse item locks map for processing items. - _inverse_item_locks = {} - - for door_id in _item_locks.keys(): - var lock = _item_locks.get(door_id) - - if not _inverse_item_locks.has(lock[0]): - _inverse_item_locks[lock[0]] = [] - - _inverse_item_locks[lock[0]].append([door_id, lock[1]]) - - emit_signal("ap_connected") - - -func start_batching_locations(): - _batch_locations = true - - -func send_location(loc_id): - if _batch_locations: - _held_locations.append(loc_id) - else: - client.sendLocation(loc_id) - - -func scout_location(loc_id): - if _location_scouts.has(loc_id): - return _location_scouts.get(loc_id) - - if _batch_locations: - _held_location_scouts.append(loc_id) - else: - client.scoutLocation(loc_id) - - return null - - -func stop_batching_locations(): - _batch_locations = false - - if not _held_locations.is_empty(): - client.sendLocations(_held_locations) - _held_locations.clear() - - if not _held_location_scouts.is_empty(): - client.scoutLocations(_held_location_scouts) - _held_location_scouts.clear() - - -func colorForItemType(flags): - var int_flags = int(flags) - if int_flags & 1: # progression - if int_flags & 2: # proguseful - return "#f0d200" - else: - return "#bc51e0" - elif int_flags & 2: # useful - return "#2b67ff" - elif int_flags & 4: # trap - return "#d63a22" - else: # filler - return "#14de9e" - - -func wrapInItemColorTags(text, flags): - var int_flags = int(flags) - if int_flags & 1 and int_flags & 2: # proguseful - return "[rainbow]%s[/rainbow]" % text - else: - return "[color=%s]%s[/color]" % [colorForItemType(flags), text] - - -func get_letter_behavior(key, level2): - if shuffle_letters == kSHUFFLE_LETTERS_UNLOCKED: - return kLETTER_BEHAVIOR_UNLOCKED - - if [kSHUFFLE_LETTERS_VANILLA_CYAN, kSHUFFLE_LETTERS_ITEM_CYAN].has(shuffle_letters): - if level2: - if shuffle_letters == kSHUFFLE_LETTERS_VANILLA_CYAN: - return kLETTER_BEHAVIOR_VANILLA - else: - return kLETTER_BEHAVIOR_ITEM - else: - return kLETTER_BEHAVIOR_UNLOCKED - - if not level2 and ["h", "i", "n", "t"].has(key): - # This differs from the equivalent function in the apworld. Logically it is - # the same as UNLOCKED since they are in the starting room, but VANILLA - # means the player still has to actually pick up the letters. - return kLETTER_BEHAVIOR_VANILLA - - if shuffle_letters == kSHUFFLE_LETTERS_PROGRESSIVE: - return kLETTER_BEHAVIOR_ITEM - - return kLETTER_BEHAVIOR_VANILLA - - -func setup_keys(): - keyboard.load_seed() - - _letters_setup = true - - for k in _held_letters.keys(): - _process_key_item(k, _held_letters[k]) - - _held_letters.clear() - - -func _process_key_item(key, level): - if not _letters_setup: - _held_letters[key] = max(_held_letters.get(key, 0), level) - return - - if shuffle_letters == kSHUFFLE_LETTERS_ITEM_CYAN: - level += 1 - - keyboard.collect_remote_letter(key, level) diff --git a/client/Archipelago/messages.gd b/client/Archipelago/messages.gd deleted file mode 100644 index ab4f071..0000000 --- a/client/Archipelago/messages.gd +++ /dev/null @@ -1,74 +0,0 @@ -extends CanvasLayer - -var SCRIPT_rainbowText - -var _message_queue = [] -var _font -var _container -var _ordered_labels = [] - - -func _ready(): - _container = VBoxContainer.new() - _container.set_name("Container") - _container.anchor_bottom = 1 - _container.offset_left = 20.0 - _container.offset_right = 1920.0 - _container.offset_top = 0.0 - _container.offset_bottom = -20.0 - _container.alignment = BoxContainer.ALIGNMENT_END - _container.mouse_filter = Control.MOUSE_FILTER_IGNORE - self.add_child(_container) - - _font = load("res://assets/fonts/Lingo2.ttf") - - -func _add_message(text): - var new_label = RichTextLabel.new() - new_label.install_effect(SCRIPT_rainbowText.new()) - new_label.push_font(_font) - new_label.push_font_size(36) - new_label.push_outline_color(Color(0, 0, 0, 1)) - new_label.push_outline_size(2) - new_label.append_text(text) - new_label.fit_content = true - - _container.add_child(new_label) - _ordered_labels.push_back(new_label) - - -func showMessage(text): - if _ordered_labels.size() >= 9: - _message_queue.append(text) - return - - _add_message(text) - - if _ordered_labels.size() > 1: - return - - var timeout = 10.0 - while !_ordered_labels.is_empty(): - await get_tree().create_timer(timeout).timeout - - if !_ordered_labels.is_empty(): - var to_remove = _ordered_labels.pop_front() - var to_tween = get_tree().create_tween().bind_node(to_remove) - to_tween.tween_property(to_remove, "modulate:a", 0.0, 0.5) - to_tween.tween_callback(to_remove.queue_free) - - if !_message_queue.is_empty(): - var next_msg = _message_queue.pop_front() - _add_message(next_msg) - - if timeout > 4: - timeout -= 3 - - -func clear(): - _message_queue.clear() - - for message_label in _ordered_labels: - message_label.queue_free() - - _ordered_labels.clear() diff --git a/client/Archipelago/minimap.gd b/client/Archipelago/minimap.gd deleted file mode 100644 index 5640716..0000000 --- a/client/Archipelago/minimap.gd +++ /dev/null @@ -1,175 +0,0 @@ -extends CanvasLayer - -var player -var drawer -var sprite -var label - -var cell_left -var cell_top -var cell_right -var cell_bottom -var cell_width -var cell_height -var center_x_min -var center_x_max -var center_y_min -var center_y_max - - -func _ready(): - player = get_tree().get_root().get_node("scene/player") - - var svc = PanelContainer.new() - svc.anchor_left = 1.0 - svc.anchor_top = 1.0 - svc.anchor_right = 1.0 - svc.anchor_bottom = 1.0 - svc.offset_left = -320.0 - svc.offset_top = -320.0 - svc.offset_right = -64.0 - svc.offset_bottom = -64.0 - svc.clip_contents = true - add_child(svc) - - var background_color = Color.WHITE - - var world_env = get_tree().get_root().get_node("scene/WorldEnvironment") - if world_env != null and world_env.environment != null: - if world_env.environment.background_mode == Environment.BG_COLOR: - background_color = world_env.environment.background_color - elif ( - world_env.environment.background_mode == Environment.BG_SKY - and world_env.environment.sky != null - and world_env.environment.sky.sky_material != null - ): - var sky = world_env.environment.sky.sky_material - if sky is PhysicalSkyMaterial: - background_color = sky.ground_color - elif sky is ProceduralSkyMaterial: - background_color = sky.sky_top_color - - var stylebox = StyleBoxFlat.new() - stylebox.bg_color = Color(background_color, 0.6) - svc.add_theme_stylebox_override("panel", stylebox) - - drawer = Node2D.new() - svc.add_child(drawer) - - var gridmap = get_tree().get_root().get_node("scene/GridMap") - if gridmap == null: - visible = false - return - - cell_left = 0 - cell_top = 0 - cell_right = 0 - cell_bottom = 0 - - for pos in gridmap.get_used_cells(): - if pos.x < cell_left: - cell_left = pos.x - if pos.x > cell_right: - cell_right = pos.x - if pos.z < cell_top: - cell_top = pos.z - if pos.z > cell_bottom: - cell_bottom = pos.z - - cell_width = cell_right - cell_left + 1 - cell_height = cell_bottom - cell_top + 1 - - var rendered = _renderMap(gridmap) - - var image_texture = ImageTexture.create_from_image(rendered) - sprite = Sprite2D.new() - sprite.texture = image_texture - sprite.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST - sprite.scale = Vector2(2, 2) - sprite.centered = false - drawer.add_child(sprite) - - label = Label.new() - label.theme = preload("res://assets/themes/baseUI.tres") - label.add_theme_font_size_override("font_size", 32) - label.text = "@" - drawer.add_child(label) - - #var local_tl = gridmap.map_to_local(Vector3i(cell_left, 0, cell_top)) - #var global_tl = gridmap.to_global(local_tl) - #var local_br = gridmap.map_to_local(Vector3i(cell_right, 0, cell_bottom)) - #var global_br = gridmap.to_global(local_br) - - center_x_min = 0 - center_x_max = cell_width - 128 - center_y_min = 0 - center_y_max = cell_height - 128 - - if center_x_max < center_x_min: - center_x_min = (center_x_min + center_x_max) / 2 - center_x_max = center_x_min - - if center_y_max < center_y_min: - center_y_min = (center_y_min + center_y_max) / 2 - center_y_max = center_y_min - - -func _process(_delta): - if visible == false: - return - - drawer.position.x = clamp(player.position.x - cell_left - 64, center_x_min, center_x_max) * -2 - drawer.position.y = clamp(player.position.z - cell_top - 64, center_y_min, center_y_max) * -2 - - label.position.x = (player.position.x - cell_left) * 2 - 16 - label.position.y = (player.position.z - cell_top) * 2 - 16 - - -func _renderMap(gridmap): - var heights = {} - - var rendered = Image.create_empty(cell_width, cell_height, false, Image.FORMAT_RGBA8) - rendered.fill(Color.TRANSPARENT) - - var meshes_node = get_tree().get_root().get_node("scene/Meshes") - if meshes_node != null: - _renderMeshNode(gridmap, meshes_node, rendered) - - for pos in gridmap.get_used_cells(): - var in_plane = Vector2i(pos.x, pos.z) - - if in_plane in heights and heights[in_plane] > pos.y: - continue - - heights[in_plane] = pos.y - - var cell_item = gridmap.get_cell_item(pos) - var mesh = gridmap.mesh_library.get_item_mesh(cell_item) - var material = mesh.surface_get_material(0) - var color = material.albedo_color - - rendered.set_pixel(pos.x - cell_left, pos.z - cell_top, color) - - return rendered - - -func _renderMeshNode(gridmap, mesh, rendered): - if mesh is MeshInstance3D: - var local_tl = gridmap.map_to_local(Vector3i(cell_left, 0, cell_top)) - var global_tl = gridmap.to_global(local_tl) - var mesh_material = mesh.get_surface_override_material(0) - if mesh_material != null: - var mesh_color = mesh_material.albedo_color - - for y in range( - max(mesh.position.z - mesh.scale.z / 2 - global_tl.z, 0), - min(mesh.position.z + mesh.scale.z / 2 - global_tl.z, cell_height) - ): - for x in range( - max(mesh.position.x - mesh.scale.x / 2 - global_tl.x, 0), - min(mesh.position.x + mesh.scale.x / 2 - global_tl.x, cell_width) - ): - rendered.set_pixel(x, y, mesh_color) - - for child in mesh.get_children(): - _renderMeshNode(gridmap, child, rendered) diff --git a/client/Archipelago/painting.gd b/client/Archipelago/painting.gd deleted file mode 100644 index 276d4eb..0000000 --- a/client/Archipelago/painting.gd +++ /dev/null @@ -1,38 +0,0 @@ -extends "res://scripts/nodes/painting.gd" - -var item_id -var item_amount - - -func _ready(): - var node_path = String( - get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names() - ) - - var gamedata = global.get_node("Gamedata") - var door_id = gamedata.get_door_for_map_node_path(global.map, node_path) - if door_id != null: - var ap = global.get_node("Archipelago") - var item_lock = ap.get_item_id_for_door(door_id) - - if item_lock != null: - item_id = item_lock[0] - item_amount = item_lock[1] - - self.senders = [] - self.senderGroup = [] - self.nested = false - self.complete_at = 0 - self.max_length = 0 - self.excludeSenders = [] - - call_deferred("_readier") - - super._ready() - - -func _readier(): - var ap = global.get_node("Archipelago") - - if ap.client.getItemAmount(item_id) >= item_amount: - handleTriggered() diff --git a/client/Archipelago/panel.gd b/client/Archipelago/panel.gd deleted file mode 100644 index fdaaf0e..0000000 --- a/client/Archipelago/panel.gd +++ /dev/null @@ -1,101 +0,0 @@ -extends "res://scripts/nodes/panel.gd" - -var panel_logic = null -var symbol_solvable = true - -var black = load("res://assets/materials/black.material") - - -func _ready(): - super._ready() - - var node_path = String( - get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names() - ) - - var gamedata = global.get_node("Gamedata") - var panel_id = gamedata.get_panel_for_map_node_path(global.map, node_path) - if panel_id != null: - var ap = global.get_node("Archipelago") - if ap.shuffle_symbols: - if global.map == "the_entry" and node_path == "Panels/Entry/front_1": - clue = "i" - symbol = "" - - setField("clue", clue) - setField("symbol", symbol) - - panel_logic = gamedata.objects.get_panels()[panel_id] - checkSymbolSolvable() - - if not symbol_solvable: - get_tree().get_root().get_node("scene/player").connect( - "evaluate_solvability", evaluateSolvability - ) - - -func checkSymbolSolvable(): - var old_solvable = symbol_solvable - symbol_solvable = true - - if panel_logic == null: - # There's no logic for this panel. - return - - var ap = global.get_node("Archipelago") - if not ap.shuffle_symbols: - # Symbols aren't item-locked. - return - - var gamedata = global.get_node("Gamedata") - for symbol in panel_logic.get_symbols(): - var item_name = gamedata.kSYMBOL_ITEMS.get(symbol) - var item_id = gamedata.objects.get_special_ids()[item_name] - if ap.client.getItemAmount(item_id) < 1: - symbol_solvable = false - break - - if symbol_solvable != old_solvable: - if symbol_solvable: - setField("clue", clue) - setField("symbol", symbol) - setField("answer", answer) - else: - quad_mesh.surface_set_material(0, black) - get_node("Hinge/clue").text = "missing" - get_node("Hinge/answer").text = "symbols" - - -func checkSolvable(key): - checkSymbolSolvable() - if not symbol_solvable: - return false - - return super.checkSolvable(key) - - -func evaluateSolvability(): - checkSolvable("") - - -func passedInput(key, skip_focus_check = false): - if not symbol_solvable: - return - - super.passedInput(key, skip_focus_check) - - -func focus(): - if not symbol_solvable: - has_focus = false - return - - super.focus() - - -func unfocus(): - if not symbol_solvable: - has_focus = false - return - - super.unfocus() diff --git a/client/Archipelago/pauseMenu.gd b/client/Archipelago/pauseMenu.gd deleted file mode 100644 index cd1813c..0000000 --- a/client/Archipelago/pauseMenu.gd +++ /dev/null @@ -1,44 +0,0 @@ -extends "res://scripts/ui/pauseMenu.gd" - -var compass_button - - -func _ready(): - var ap_panel = Panel.new() - ap_panel.name = "Archipelago" - get_node("menu/settings/settingsInner/TabContainer").add_child(ap_panel) - - var ap = global.get_node("Archipelago") - - compass_button = CheckBox.new() - compass_button.text = "show compass" - compass_button.button_pressed = ap.show_compass - compass_button.position = Vector2(65, 100) - compass_button.theme = preload("res://assets/themes/baseUI.tres") - compass_button.add_theme_font_size_override("font_size", 60) - compass_button.pressed.connect(_toggle_compass) - ap_panel.add_child(compass_button) - - super._ready() - - -func _pause_game(): - global.get_node("Textclient").dismiss() - super._pause_game() - - -func _main_menu(): - global.loaded = false - global.get_node("Archipelago").disconnect_from_ap() - global.get_node("Messages").clear() - global.get_node("Compass").visible = false - super._main_menu() - - -func _toggle_compass(): - var ap = global.get_node("Archipelago") - ap.show_compass = compass_button.button_pressed - ap.saveSettings() - - var compass = global.get_node("Compass") - compass.visible = compass_button.button_pressed diff --git a/client/Archipelago/player.gd b/client/Archipelago/player.gd deleted file mode 100644 index e58f1bc..0000000 --- a/client/Archipelago/player.gd +++ /dev/null @@ -1,369 +0,0 @@ -extends "res://scripts/nodes/player.gd" - -const kEndingNameByVictoryValue = { - 0: "GRAY", - 1: "PURPLE", - 2: "MINT", - 3: "BLACK", - 4: "BLUE", - 5: "CYAN", - 6: "RED", - 7: "PLUM", - 8: "ORANGE", - 9: "GOLD", - 10: "YELLOW", - 11: "GREEN", - 12: "WHITE", -} - -signal evaluate_solvability - -var compass - - -func _ready(): - var khl_script = load("res://scripts/nodes/keyHolderListener.gd") - - var pause_menu = get_node("pause_menu") - pause_menu.layer = 3 - - var ap = global.get_node("Archipelago") - var gamedata = global.get_node("Gamedata") - - compass = global.get_node("Compass") - compass.visible = ap.show_compass - - ap.start_batching_locations() - - # Set up door locations. - var map_id = gamedata.map_id_by_name.get(global.map) - for door in gamedata.objects.get_doors(): - if door.get_map_id() != map_id: - continue - - if not door.has_ap_id(): - continue - - if ( - door.get_type() == gamedata.SCRIPT_proto.DoorType.ITEM_ONLY - or door.get_type() == gamedata.SCRIPT_proto.DoorType.GALLERY_PAINTING - ): - continue - - var locationListener = ap.SCRIPT_locationListener.new() - locationListener.location_id = door.get_ap_id() - locationListener.name = "locationListener_%d" % door.get_ap_id() - - for panel_ref in door.get_panels(): - var panel_data = gamedata.objects.get_panels()[panel_ref.get_panel()] - var panel_path = panel_data.get_path() - - if panel_ref.has_answer(): - for proxy in panel_data.get_proxies(): - if proxy.get_answer() == panel_ref.get_answer(): - panel_path = proxy.get_path() - break - - locationListener.senders.append(NodePath("/root/scene/" + panel_path)) - - for keyholder_ref in door.get_keyholders(): - var keyholder_data = gamedata.objects.get_keyholders()[keyholder_ref.get_keyholder()] - - var khl = khl_script.new() - khl.name = ( - "location_%d_keyholder_%d" % [door.get_ap_id(), keyholder_ref.get_keyholder()] - ) - khl.answer = keyholder_ref.get_key() - khl.senders.append(NodePath("/root/scene/" + keyholder_data.get_path())) - get_parent().add_child.call_deferred(khl) - - locationListener.senders.append(NodePath("../" + khl.name)) - - for sender in door.get_senders(): - locationListener.senders.append(NodePath("/root/scene/" + sender)) - - if door.has_complete_at(): - locationListener.complete_at = door.get_complete_at() - - get_parent().add_child.call_deferred(locationListener) - - # Set up letter locations. - for letter in gamedata.objects.get_letters(): - var room = gamedata.objects.get_rooms()[letter.get_room_id()] - if room.get_map_id() != map_id: - continue - - var locationListener = ap.SCRIPT_locationListener.new() - locationListener.location_id = letter.get_ap_id() - locationListener.name = "locationListener_%d" % letter.get_ap_id() - locationListener.senders.append(NodePath("/root/scene/" + letter.get_path())) - - get_parent().add_child.call_deferred(locationListener) - - if ( - ap.get_letter_behavior(letter.get_key(), letter.has_level2() and letter.get_level2()) - != ap.kLETTER_BEHAVIOR_VANILLA - ): - var scout = ap.scout_location(letter.get_ap_id()) - if ( - scout != null - and not (scout["player"] == ap.client._slot and scout["flags"] & 4 != 0) - ): - var item_name = "Unknown" - var item_player_game = ap.client._game_by_player[float(scout["player"])] - if ap.client._item_id_to_name[item_player_game].has(scout["item"]): - item_name = ap.client._item_id_to_name[item_player_game][scout["item"]] - - var collectable = get_tree().get_root().get_node("scene").get_node_or_null( - letter.get_path() - ) - if collectable != null: - collectable.setScoutedText.call_deferred(item_name) - - # Set up mastery locations. - for mastery in gamedata.objects.get_masteries(): - var room = gamedata.objects.get_rooms()[mastery.get_room_id()] - if room.get_map_id() != map_id: - continue - - var locationListener = ap.SCRIPT_locationListener.new() - locationListener.location_id = mastery.get_ap_id() - locationListener.name = "locationListener_%d" % mastery.get_ap_id() - locationListener.senders.append(NodePath("/root/scene/" + mastery.get_path())) - - get_parent().add_child.call_deferred(locationListener) - - # Set up ending locations. - for ending in gamedata.objects.get_endings(): - var room = gamedata.objects.get_rooms()[ending.get_room_id()] - if room.get_map_id() != map_id: - continue - - var locationListener = ap.SCRIPT_locationListener.new() - locationListener.location_id = ending.get_ap_id() - locationListener.name = "locationListener_%d" % ending.get_ap_id() - locationListener.senders.append(NodePath("/root/scene/" + ending.get_path())) - - get_parent().add_child.call_deferred(locationListener) - - if kEndingNameByVictoryValue.get(ap.victory_condition, null) == ending.get_name(): - var victoryListener = ap.SCRIPT_victoryListener.new() - victoryListener.name = "victoryListener" - victoryListener.senders.append(NodePath("/root/scene/" + ending.get_path())) - - get_parent().add_child.call_deferred(victoryListener) - - # Set up keyholder locations, in keyholder sanity. - if ap.keyholder_sanity: - for keyholder in gamedata.objects.get_keyholders(): - if not keyholder.has_key(): - continue - - var room = gamedata.objects.get_rooms()[keyholder.get_room_id()] - if room.get_map_id() != map_id: - continue - - var locationListener = ap.SCRIPT_locationListener.new() - locationListener.location_id = keyholder.get_ap_id() - locationListener.name = "locationListener_%d" % keyholder.get_ap_id() - - var khl = khl_script.new() - khl.name = "location_%d_keyholder" % keyholder.get_ap_id() - khl.answer = keyholder.get_key() - khl.senders.append(NodePath("/root/scene/" + keyholder.get_path())) - get_parent().add_child.call_deferred(khl) - - locationListener.senders.append(NodePath("../" + khl.name)) - - get_parent().add_child.call_deferred(locationListener) - - # Block off roof access in Daedalus. - if global.map == "daedalus" and 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" % kEndingNameByVictoryValue.get(ap.victory_condition, "?") - - var sign2_color = 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 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() - - var minimap = ap.SCRIPT_minimap.new() - minimap.name = "Minimap" - get_parent().add_child.call_deferred(minimap) - - super._ready() - - await get_tree().process_frame - await get_tree().process_frame - - 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 _process(_dt): - compass.update_rotation(global_rotation.y) diff --git a/client/Archipelago/rainbowText.gd b/client/Archipelago/rainbowText.gd deleted file mode 100644 index 9a4c1d0..0000000 --- a/client/Archipelago/rainbowText.gd +++ /dev/null @@ -1,10 +0,0 @@ -extends RichTextEffect - -var bbcode = "rainbow" - - -func _process_custom_fx(char_fx: CharFXTransform): - char_fx.color = Color.from_hsv( - char_fx.elapsed_time - floor(char_fx.elapsed_time), 1.0, 1.0, 1.0 - ) - return true diff --git a/client/Archipelago/saver.gd b/client/Archipelago/saver.gd deleted file mode 100644 index 44bc179..0000000 --- a/client/Archipelago/saver.gd +++ /dev/null @@ -1,23 +0,0 @@ -extends "res://scripts/nodes/saver.gd" - - -func levelLoaded(): - if type == "keyholders": - var ap = global.get_node("Archipelago") - ap.keyboard.load_keyholders.call_deferred(global.map) - else: - reload.call_deferred() - - -func reload(): - # Just rewriting this whole thing so I can remove Chris's safeguard. - var file = FileAccess.open(path + type + ".save", FileAccess.READ) - if file: - var data = file.get_var(true) - file.close() - for datum in data: - var saveable = get_node_or_null(datum[0]) - if saveable != null: - saveable.is_complete = datum[1] - if saveable.is_complete: - saveable.loadData(saveable.is_complete) diff --git a/client/Archipelago/settings_buttons.gd b/client/Archipelago/settings_buttons.gd deleted file mode 100644 index 9e61cb0..0000000 --- a/client/Archipelago/settings_buttons.gd +++ /dev/null @@ -1,24 +0,0 @@ -extends Button - - -func _ready(): - pass - - -func _connect_pressed(): - self.disabled = true - - var ap = global.get_node("Archipelago") - ap.ap_server = self.get_parent().get_node("server_box").text - ap.ap_user = self.get_parent().get_node("player_box").text - ap.ap_pass = self.get_parent().get_node("password_box").text - ap.saveSettings() - - ap.connectToServer() - - -func _back_pressed(): - var ap = global.get_node("Archipelago") - ap.disconnect_from_ap() - - get_tree().change_scene_to_file("res://objects/scenes/menus/main_menu.tscn") diff --git a/client/Archipelago/settings_screen.gd b/client/Archipelago/settings_screen.gd deleted file mode 100644 index d5aa747..0000000 --- a/client/Archipelago/settings_screen.gd +++ /dev/null @@ -1,261 +0,0 @@ -extends Node2D - - -func _ready(): - # Some helpful logging. - if Steam.isSubscribed(): - global._print("Provisioning successful! Build ID: %d" % Steam.getAppBuildId()) - else: - global._print("Provisioning failed.") - - # Undo the load screen removing our cursor - get_tree().get_root().set_disable_input(false) - Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) - - # Increase the WebSocket input buffer size so that we can download large - # data packages. - ProjectSettings.set_setting("network/limits/websocket_client/max_in_buffer_kb", 8192) - - switcher.layer = 4 - - # Create the global AP manager, if it doesn't already exist. - if not global.has_node("Archipelago"): - var ap_script = ResourceLoader.load("user://maps/Archipelago/manager.gd") - var ap_instance = ap_script.new() - ap_instance.name = "Archipelago" - - ap_instance.SCRIPT_client = load("user://maps/Archipelago/client.gd") - ap_instance.SCRIPT_keyboard = load("user://maps/Archipelago/keyboard.gd") - ap_instance.SCRIPT_locationListener = load("user://maps/Archipelago/locationListener.gd") - ap_instance.SCRIPT_minimap = load("user://maps/Archipelago/minimap.gd") - ap_instance.SCRIPT_uuid = load("user://maps/Archipelago/vendor/uuid.gd") - ap_instance.SCRIPT_victoryListener = load("user://maps/Archipelago/victoryListener.gd") - - global.add_child(ap_instance) - - # Let's also inject any scripts we need to inject now. - installScriptExtension(ResourceLoader.load("user://maps/Archipelago/animationListener.gd")) - installScriptExtension(ResourceLoader.load("user://maps/Archipelago/collectable.gd")) - installScriptExtension(ResourceLoader.load("user://maps/Archipelago/door.gd")) - installScriptExtension(ResourceLoader.load("user://maps/Archipelago/keyHolder.gd")) - installScriptExtension(ResourceLoader.load("user://maps/Archipelago/keyHolderChecker.gd")) - installScriptExtension( - ResourceLoader.load("user://maps/Archipelago/keyHolderResetterListener.gd") - ) - installScriptExtension(ResourceLoader.load("user://maps/Archipelago/painting.gd")) - installScriptExtension(ResourceLoader.load("user://maps/Archipelago/panel.gd")) - installScriptExtension(ResourceLoader.load("user://maps/Archipelago/pauseMenu.gd")) - installScriptExtension(ResourceLoader.load("user://maps/Archipelago/player.gd")) - installScriptExtension(ResourceLoader.load("user://maps/Archipelago/saver.gd")) - installScriptExtension(ResourceLoader.load("user://maps/Archipelago/teleport.gd")) - installScriptExtension(ResourceLoader.load("user://maps/Archipelago/teleportListener.gd")) - installScriptExtension(ResourceLoader.load("user://maps/Archipelago/visibilityListener.gd")) - installScriptExtension(ResourceLoader.load("user://maps/Archipelago/worldport.gd")) - installScriptExtension(ResourceLoader.load("user://maps/Archipelago/worldportListener.gd")) - - var proto_script = load("user://maps/Archipelago/generated/proto.gd") - var gamedata_script = load("user://maps/Archipelago/gamedata.gd") - var gamedata_instance = gamedata_script.new(proto_script) - gamedata_instance.load( - FileAccess.get_file_as_bytes("user://maps/Archipelago/generated/data.binpb") - ) - gamedata_instance.name = "Gamedata" - global.add_child(gamedata_instance) - - var messages_script = load("user://maps/Archipelago/messages.gd") - var messages_instance = messages_script.new() - messages_instance.name = "Messages" - messages_instance.SCRIPT_rainbowText = load("user://maps/Archipelago/rainbowText.gd") - global.add_child(messages_instance) - - var textclient_script = load("user://maps/Archipelago/textclient.gd") - var textclient_instance = textclient_script.new() - textclient_instance.name = "Textclient" - global.add_child(textclient_instance) - - var compass_overlay_script = load("user://maps/Archipelago/compass_overlay.gd") - var compass_overlay_instance = compass_overlay_script.new() - compass_overlay_instance.name = "Compass" - compass_overlay_instance.SCRIPT_compass = load("user://maps/Archipelago/compass.gd") - global.add_child(compass_overlay_instance) - - var ap = global.get_node("Archipelago") - var gamedata = global.get_node("Gamedata") - ap.connect("ap_connected", connectionSuccessful) - ap.connect("could_not_connect", connectionUnsuccessful) - ap.connect("connect_status", connectionStatus) - - # Populate textboxes with AP settings. - $Panel/server_box.text = ap.ap_server - $Panel/player_box.text = ap.ap_user - $Panel/password_box.text = ap.ap_pass - - var history_box = $Panel/connection_history - if ap.connection_history.is_empty(): - history_box.disabled = true - else: - history_box.disabled = false - - var i = 0 - for details in ap.connection_history: - history_box.get_popup().add_item("%s (%s)" % [details[1], details[0]], i) - i += 1 - - history_box.get_popup().connect("id_pressed", historySelected) - - # Show client version. - $Panel/title.text = "ARCHIPELAGO (%d.%d)" % [gamedata.objects.get_version(), ap.MOD_VERSION] - - # Increase font size in text boxes. - $Panel/server_box.add_theme_font_size_override("font_size", 36) - $Panel/player_box.add_theme_font_size_override("font_size", 36) - $Panel/password_box.add_theme_font_size_override("font_size", 36) - - # Set up version mismatch dialog. - $Panel/VersionMismatch.connect("confirmed", startGame) - $Panel/VersionMismatch.get_cancel_button().pressed.connect(versionMismatchDeclined) - - -# Adapted from https://gitlab.com/Delta-V-Modding/Mods/-/blob/main/game/ModLoader.gd -func installScriptExtension(childScript: Resource): - # Force Godot to compile the script now. - # We need to do this here to ensure that the inheritance chain is - # properly set up, and multiple mods can chain-extend the same - # class multiple times. - # This is also needed to make Godot instantiate the extended class - # when creating singletons. - # The actual instance is thrown away. - childScript.new() - - var parentScript = childScript.get_base_script() - var parentScriptPath = parentScript.resource_path - global._print("ModLoader: Installing script extension over %s" % parentScriptPath) - childScript.take_over_path(parentScriptPath) - - -func connectionStatus(message): - var popup = self.get_node("Panel/AcceptDialog") - popup.title = "Connecting to Archipelago" - popup.dialog_text = message - popup.exclusive = true - popup.get_ok_button().visible = false - popup.popup_centered() - - -func connectionSuccessful(): - var ap = global.get_node("Archipelago") - var gamedata = global.get_node("Gamedata") - - # Check for major version mismatch. - if ap.apworld_version[0] != gamedata.objects.get_version(): - $Panel/AcceptDialog.exclusive = false - - var popup = self.get_node("Panel/VersionMismatch") - popup.title = "Version Mismatch!" - popup.dialog_text = ( - "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." - % [ - ap.apworld_version[0], - ap.apworld_version[1], - gamedata.objects.get_version(), - ap.MOD_VERSION - ] - ) - popup.exclusive = true - popup.popup_centered() - - return - - startGame() - - -func startGame(): - var ap = global.get_node("Archipelago") - - # Save connection details - var connection_details = [ap.ap_server, ap.ap_user, ap.ap_pass] - if ap.connection_history.has(connection_details): - ap.connection_history.erase(connection_details) - ap.connection_history.push_front(connection_details) - if ap.connection_history.size() > 10: - ap.connection_history.resize(10) - ap.saveSettings() - - # Switch to the_entry - Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) - global.user = ap.getSaveFileName() - global.universe = "lingo" - global.map = "the_entry" - - unlocks.resetCollectables() - unlocks.resetData() - - ap.setup_keys() - - unlocks.loadCollectables() - unlocks.loadData() - unlocks.unlockKey("capslock", 1) - - if ap.shuffle_worldports: - settings.worldport_fades = "default" - else: - settings.worldport_fades = "never" - - clearResourceCache("res://objects/meshes/gridDoor.tscn") - clearResourceCache("res://objects/nodes/collectable.tscn") - clearResourceCache("res://objects/nodes/door.tscn") - clearResourceCache("res://objects/nodes/keyHolder.tscn") - clearResourceCache("res://objects/nodes/listeners/animationListener.tscn") - clearResourceCache("res://objects/nodes/listeners/keyHolderChecker.tscn") - clearResourceCache("res://objects/nodes/listeners/keyHolderResetterListener.tscn") - clearResourceCache("res://objects/nodes/listeners/teleportListener.tscn") - clearResourceCache("res://objects/nodes/listeners/visibilityListener.tscn") - clearResourceCache("res://objects/nodes/listeners/worldportListener.tscn") - clearResourceCache("res://objects/nodes/panel.tscn") - clearResourceCache("res://objects/nodes/player.tscn") - clearResourceCache("res://objects/nodes/saver.tscn") - clearResourceCache("res://objects/nodes/teleport.tscn") - clearResourceCache("res://objects/nodes/worldport.tscn") - clearResourceCache("res://objects/scenes/menus/pause_menu.tscn") - - var paintings_dir = DirAccess.open("res://objects/meshes/paintings") - if paintings_dir: - paintings_dir.list_dir_begin() - var file_name = paintings_dir.get_next() - while file_name != "": - if not paintings_dir.current_is_dir() and file_name.ends_with(".tscn"): - clearResourceCache("res://objects/meshes/paintings/" + file_name) - file_name = paintings_dir.get_next() - - switcher.switch_map.call_deferred("res://objects/scenes/the_entry.tscn") - - -func connectionUnsuccessful(error_message): - $Panel/connect_button.disabled = false - - var popup = $Panel/AcceptDialog - popup.title = "Could not connect to Archipelago" - popup.dialog_text = error_message - popup.exclusive = true - popup.get_ok_button().visible = true - popup.popup_centered() - - $Panel/connect_button.disabled = false - - -func versionMismatchDeclined(): - $Panel/AcceptDialog.hide() - $Panel/connect_button.disabled = false - - -func historySelected(index): - var ap = global.get_node("Archipelago") - var details = ap.connection_history[index] - - $Panel/server_box.text = details[0] - $Panel/player_box.text = details[1] - $Panel/password_box.text = details[2] - - -func clearResourceCache(path): - ResourceLoader.load(path, "", ResourceLoader.CACHE_MODE_REPLACE) diff --git a/client/Archipelago/teleport.gd b/client/Archipelago/teleport.gd deleted file mode 100644 index 428d50b..0000000 --- a/client/Archipelago/teleport.gd +++ /dev/null @@ -1,38 +0,0 @@ -extends "res://scripts/nodes/teleport.gd" - -var item_id -var item_amount - - -func _ready(): - var node_path = String( - get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names() - ) - - var gamedata = global.get_node("Gamedata") - var door_id = gamedata.get_door_for_map_node_path(global.map, node_path) - if door_id != null: - var ap = global.get_node("Archipelago") - var item_lock = ap.get_item_id_for_door(door_id) - - if item_lock != null: - item_id = item_lock[0] - item_amount = item_lock[1] - - self.senders = [] - self.senderGroup = [] - self.nested = false - self.complete_at = 0 - self.max_length = 0 - self.excludeSenders = [] - - call_deferred("_readier") - - super._ready() - - -func _readier(): - var ap = global.get_node("Archipelago") - - if ap.client.getItemAmount(item_id) >= item_amount: - handleTriggered() diff --git a/client/Archipelago/teleportListener.gd b/client/Archipelago/teleportListener.gd deleted file mode 100644 index 6f363af..0000000 --- a/client/Archipelago/teleportListener.gd +++ /dev/null @@ -1,49 +0,0 @@ -extends "res://scripts/nodes/listeners/teleportListener.gd" - -var item_id -var item_amount - - -func _ready(): - var node_path = String( - get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names() - ) - - if ( - global.map == "daedalus" - and ( - node_path == "Components/Triggers/teleportListenerConnections" - or node_path == "Components/Triggers/teleportListenerConnections2" - ) - ): - # Effectively disable these. - teleport_point = target_path.position - return - - var gamedata = global.get_node("Gamedata") - var door_id = gamedata.get_door_for_map_node_path(global.map, node_path) - if door_id != null: - var ap = global.get_node("Archipelago") - var item_lock = ap.get_item_id_for_door(door_id) - - if item_lock != null: - item_id = item_lock[0] - item_amount = item_lock[1] - - self.senders = [] - self.senderGroup = [] - self.nested = false - self.complete_at = 0 - self.max_length = 0 - self.excludeSenders = [] - - call_deferred("_readier") - - super._ready() - - -func _readier(): - var ap = global.get_node("Archipelago") - - if ap.client.getItemAmount(item_id) >= item_amount: - handleTriggered() diff --git a/client/Archipelago/textclient.gd b/client/Archipelago/textclient.gd deleted file mode 100644 index 26831b4..0000000 --- a/client/Archipelago/textclient.gd +++ /dev/null @@ -1,95 +0,0 @@ -extends CanvasLayer - -var panel -var label -var entry -var is_open = false - - -func _ready(): - process_mode = ProcessMode.PROCESS_MODE_ALWAYS - layer = 2 - - panel = Panel.new() - panel.set_name("Panel") - panel.offset_left = 100 - panel.offset_right = 1820 - panel.offset_top = 100 - panel.offset_bottom = 980 - panel.visible = false - add_child(panel) - - label = RichTextLabel.new() - label.set_name("Label") - label.offset_left = 80 - label.offset_right = 1640 - label.offset_top = 80 - label.offset_bottom = 720 - label.scroll_following = true - label.selection_enabled = true - panel.add_child(label) - - label.push_font(load("res://assets/fonts/Lingo2.ttf")) - label.push_font_size(36) - - var entry_style = StyleBoxFlat.new() - entry_style.bg_color = Color(0.9, 0.9, 0.9, 1) - - entry = LineEdit.new() - entry.set_name("Entry") - entry.offset_left = 80 - entry.offset_right = 1640 - entry.offset_top = 760 - entry.offset_bottom = 840 - entry.add_theme_font_override("font", load("res://assets/fonts/Lingo2.ttf")) - entry.add_theme_font_size_override("font_size", 36) - entry.add_theme_color_override("font_color", Color(0, 0, 0, 1)) - entry.add_theme_color_override("cursor_color", Color(0, 0, 0, 1)) - entry.add_theme_stylebox_override("focus", entry_style) - panel.add_child(entry) - entry.connect("text_submitted", text_entered) - - -func _input(event): - if global.loaded and event is InputEventKey and event.pressed: - if event.keycode == KEY_TAB and !Input.is_key_pressed(KEY_SHIFT): - if !get_tree().paused: - is_open = true - get_tree().paused = true - Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) - panel.visible = true - entry.grab_focus() - get_viewport().set_input_as_handled() - else: - dismiss() - elif event.keycode == KEY_ESCAPE: - if is_open: - dismiss() - get_viewport().set_input_as_handled() - - -func dismiss(): - if is_open: - get_tree().paused = false - Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) - panel.visible = false - is_open = false - - -func parse_printjson(text): - label.append_text("[p]" + text + "[/p]") - - -func text_entered(text): - var ap = global.get_node("Archipelago") - var cmd = text.trim_suffix("\n") - entry.text = "" - if OS.is_debug_build(): - if cmd.begins_with("/tp_map "): - var new_map = cmd.substr(8) - global.map = new_map - global.sets_entry_point = false - switcher.switch_map("res://objects/scenes/%s.tscn" % new_map) - return - - ap.client.say(cmd) diff --git a/client/Archipelago/vendor/LICENSE b/client/Archipelago/vendor/LICENSE deleted file mode 100644 index 115ba15..0000000 --- a/client/Archipelago/vendor/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Xavier Sellier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/client/Archipelago/vendor/uuid.gd b/client/Archipelago/vendor/uuid.gd deleted file mode 100644 index b63fa04..0000000 --- a/client/Archipelago/vendor/uuid.gd +++ /dev/null @@ -1,195 +0,0 @@ -# Note: The code might not be as pretty it could be, since it's written -# in a way that maximizes performance. Methods are inlined and loops are avoided. -extends Node - -const BYTE_MASK: int = 0b11111111 - - -static func uuidbin(): - randomize() - # 16 random bytes with the bytes on index 6 and 8 modified - return [ - randi() & BYTE_MASK, - randi() & BYTE_MASK, - randi() & BYTE_MASK, - randi() & BYTE_MASK, - randi() & BYTE_MASK, - randi() & BYTE_MASK, - ((randi() & BYTE_MASK) & 0x0f) | 0x40, - randi() & BYTE_MASK, - ((randi() & BYTE_MASK) & 0x3f) | 0x80, - randi() & BYTE_MASK, - randi() & BYTE_MASK, - randi() & BYTE_MASK, - randi() & BYTE_MASK, - randi() & BYTE_MASK, - randi() & BYTE_MASK, - randi() & BYTE_MASK, - ] - - -static func uuidbinrng(rng: RandomNumberGenerator): - rng.randomize() - return [ - rng.randi() & BYTE_MASK, - rng.randi() & BYTE_MASK, - rng.randi() & BYTE_MASK, - rng.randi() & BYTE_MASK, - rng.randi() & BYTE_MASK, - rng.randi() & BYTE_MASK, - ((rng.randi() & BYTE_MASK) & 0x0f) | 0x40, - rng.randi() & BYTE_MASK, - ((rng.randi() & BYTE_MASK) & 0x3f) | 0x80, - rng.randi() & BYTE_MASK, - rng.randi() & BYTE_MASK, - rng.randi() & BYTE_MASK, - rng.randi() & BYTE_MASK, - rng.randi() & BYTE_MASK, - rng.randi() & BYTE_MASK, - rng.randi() & BYTE_MASK, - ] - - -static func v4(): - # 16 random bytes with the bytes on index 6 and 8 modified - var b = uuidbin() - - return ( - "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x" - % [ - # low - b[0], - b[1], - b[2], - b[3], - # mid - b[4], - b[5], - # hi - b[6], - b[7], - # clock - b[8], - b[9], - # clock - b[10], - b[11], - b[12], - b[13], - b[14], - b[15] - ] - ) - - -static func v4_rng(rng: RandomNumberGenerator): - # 16 random bytes with the bytes on index 6 and 8 modified - var b = uuidbinrng(rng) - - return ( - "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x" - % [ - # low - b[0], - b[1], - b[2], - b[3], - # mid - b[4], - b[5], - # hi - b[6], - b[7], - # clock - b[8], - b[9], - # clock - b[10], - b[11], - b[12], - b[13], - b[14], - b[15] - ] - ) - - -var _uuid: Array - - -func _init(rng := RandomNumberGenerator.new()) -> void: - _uuid = uuidbinrng(rng) - - -func as_array() -> Array: - return _uuid.duplicate() - - -func as_dict(big_endian := true) -> Dictionary: - if big_endian: - return { - "low": (_uuid[0] << 24) + (_uuid[1] << 16) + (_uuid[2] << 8) + _uuid[3], - "mid": (_uuid[4] << 8) + _uuid[5], - "hi": (_uuid[6] << 8) + _uuid[7], - "clock": (_uuid[8] << 8) + _uuid[9], - "node": - ( - (_uuid[10] << 40) - + (_uuid[11] << 32) - + (_uuid[12] << 24) - + (_uuid[13] << 16) - + (_uuid[14] << 8) - + _uuid[15] - ) - } - else: - return { - "low": _uuid[0] + (_uuid[1] << 8) + (_uuid[2] << 16) + (_uuid[3] << 24), - "mid": _uuid[4] + (_uuid[5] << 8), - "hi": _uuid[6] + (_uuid[7] << 8), - "clock": _uuid[8] + (_uuid[9] << 8), - "node": - ( - _uuid[10] - + (_uuid[11] << 8) - + (_uuid[12] << 16) - + (_uuid[13] << 24) - + (_uuid[14] << 32) - + (_uuid[15] << 40) - ) - } - - -func as_string() -> String: - return ( - "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x" - % [ - # low - _uuid[0], - _uuid[1], - _uuid[2], - _uuid[3], - # mid - _uuid[4], - _uuid[5], - # hi - _uuid[6], - _uuid[7], - # clock - _uuid[8], - _uuid[9], - # node - _uuid[10], - _uuid[11], - _uuid[12], - _uuid[13], - _uuid[14], - _uuid[15] - ] - ) - - -func is_equal(other) -> bool: - # Godot Engine compares Array recursively - # There's no need for custom comparison here. - return _uuid == other._uuid diff --git a/client/Archipelago/victoryListener.gd b/client/Archipelago/victoryListener.gd deleted file mode 100644 index e9089d7..0000000 --- a/client/Archipelago/victoryListener.gd +++ /dev/null @@ -1,20 +0,0 @@ -extends Receiver - - -func _ready(): - super._ready() - - -func handleTriggered(): - triggered += 1 - if triggered >= total: - var ap = global.get_node("Archipelago") - ap.client.completedGoal() - - global.get_node("Messages").showMessage("You have completed your goal!") - - -func handleUntriggered(): - triggered -= 1 - if triggered < total: - pass diff --git a/client/Archipelago/visibilityListener.gd b/client/Archipelago/visibilityListener.gd deleted file mode 100644 index 5ea17a0..0000000 --- a/client/Archipelago/visibilityListener.gd +++ /dev/null @@ -1,38 +0,0 @@ -extends "res://scripts/nodes/listeners/visibilityListener.gd" - -var item_id -var item_amount - - -func _ready(): - var node_path = String( - get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names() - ) - - var gamedata = global.get_node("Gamedata") - var door_id = gamedata.get_door_for_map_node_path(global.map, node_path) - if door_id != null: - var ap = global.get_node("Archipelago") - var item_lock = ap.get_item_id_for_door(door_id) - - if item_lock != null: - item_id = item_lock[0] - item_amount = item_lock[1] - - self.senders = [] - self.senderGroup = [] - self.nested = false - self.complete_at = 0 - self.max_length = 0 - self.excludeSenders = [] - - call_deferred("_readier") - - super._ready() - - -func _readier(): - var ap = global.get_node("Archipelago") - - if ap.client.getItemAmount(item_id) >= item_amount: - handleTriggered() diff --git a/client/Archipelago/worldport.gd b/client/Archipelago/worldport.gd deleted file mode 100644 index cdca248..0000000 --- a/client/Archipelago/worldport.gd +++ /dev/null @@ -1,53 +0,0 @@ -extends "res://scripts/nodes/worldport.gd" - -var absolute_rotation = false -var target_rotation = 0 - - -func _ready(): - var node_path = String( - get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names() - ) - - var ap = global.get_node("Archipelago") - - if ap.shuffle_worldports: - var gamedata = global.get_node("Gamedata") - var port_id = gamedata.get_port_for_map_node_path(global.map, node_path) - if port_id != null: - if port_id in ap.port_pairings: - var target_port = gamedata.objects.get_ports()[ap.port_pairings[port_id]] - var target_room = gamedata.objects.get_rooms()[target_port.get_room_id()] - var target_map = gamedata.objects.get_maps()[target_room.get_map_id()] - - exit = target_map.get_name() - entry_point.x = target_port.get_destination().get_x() - entry_point.y = target_port.get_destination().get_y() - entry_point.z = target_port.get_destination().get_z() - absolute_rotation = true - target_rotation = target_port.get_rotation() - sets_entry_point = true - invisible = false - fades = true - - if global.map == "icarus" and exit == "daedalus": - if not ap.daedalus_roof_access: - entry_point = Vector3(58, 10, 0) - - super._ready() - - -func bodyEntered(body): - if body.is_in_group("player"): - if absolute_rotation: - entry_rotate.y = target_rotation - body.rotation_degrees.y - - super.bodyEntered(body) - - -func changeScene(): - var player = get_tree().get_root().get_node("scene/player") - if player != null: - player.playable = false - - super.changeScene() diff --git a/client/Archipelago/worldportListener.gd b/client/Archipelago/worldportListener.gd deleted file mode 100644 index 5c2faff..0000000 --- a/client/Archipelago/worldportListener.gd +++ /dev/null @@ -1,8 +0,0 @@ -extends "res://scripts/nodes/listeners/worldportListener.gd" - - -func handleTriggered(): - if exit == "menus/credits": - return - - super.handleTriggered() -- cgit 1.4.1