diff options
| author | Star Rauchenberger <fefferburbia@gmail.com> | 2023-04-13 18:09:30 -0400 |
|---|---|---|
| committer | Star Rauchenberger <fefferburbia@gmail.com> | 2023-04-13 18:09:30 -0400 |
| commit | 617e31fce21eb18d1ffccdc9c377d25535157351 (patch) | |
| tree | c1fbcee75a67062663a0fe1ff00f4be1db382be1 /Archipelago | |
| parent | 679bba3b46ea30a329c617b3cc47645d540a261f (diff) | |
| download | lingo-archipelago-617e31fce21eb18d1ffccdc9c377d25535157351.tar.gz lingo-archipelago-617e31fce21eb18d1ffccdc9c377d25535157351.tar.bz2 lingo-archipelago-617e31fce21eb18d1ffccdc9c377d25535157351.zip | |
It WORKS!
You can send checks and receive door items!
Diffstat (limited to 'Archipelago')
| -rw-r--r-- | Archipelago/client.gd | 70 | ||||
| -rw-r--r-- | Archipelago/doorControl.gd | 15 | ||||
| -rw-r--r-- | Archipelago/load.gd | 36 | ||||
| -rw-r--r-- | Archipelago/location.gd | 17 | ||||
| -rw-r--r-- | Archipelago/painting_eye.gd | 12 | ||||
| -rw-r--r-- | Archipelago/settings_screen.gd | 26 |
6 files changed, 176 insertions, 0 deletions
| diff --git a/Archipelago/client.gd b/Archipelago/client.gd index 74fe6e9..cbddf89 100644 --- a/Archipelago/client.gd +++ b/Archipelago/client.gd | |||
| @@ -16,12 +16,21 @@ var _location_name_to_id = {} | |||
| 16 | 16 | ||
| 17 | const uuid_util = preload("user://maps/Archipelago/vendor/uuid.gd") | 17 | const uuid_util = preload("user://maps/Archipelago/vendor/uuid.gd") |
| 18 | 18 | ||
| 19 | # TODO: caching per MW/slot, reset between connections | ||
| 19 | var _authenticated = false | 20 | var _authenticated = false |
| 20 | var _team = 0 | 21 | var _team = 0 |
| 21 | var _slot = 0 | 22 | var _slot = 0 |
| 22 | var _players = [] | 23 | var _players = [] |
| 23 | var _checked_locations = [] | 24 | var _checked_locations = [] |
| 24 | var _slot_data = {} | 25 | var _slot_data = {} |
| 26 | var _door_ids_by_item = {} | ||
| 27 | var _mentioned_doors = [] | ||
| 28 | var _painting_ids_by_item = {} | ||
| 29 | var _mentioned_paintings = [] | ||
| 30 | var _panel_ids_by_location = {} | ||
| 31 | |||
| 32 | var _map_loaded = false | ||
| 33 | var _held_items = [] | ||
| 25 | 34 | ||
| 26 | signal client_connected | 35 | signal client_connected |
| 27 | 36 | ||
| @@ -104,12 +113,36 @@ func _on_data(): | |||
| 104 | _checked_locations = message["checked_locations"] | 113 | _checked_locations = message["checked_locations"] |
| 105 | _slot_data = message["slot_data"] | 114 | _slot_data = message["slot_data"] |
| 106 | 115 | ||
| 116 | if _slot_data.has("door_ids_by_item_id"): | ||
| 117 | _door_ids_by_item = _slot_data["door_ids_by_item_id"] | ||
| 118 | |||
| 119 | _mentioned_doors = [] | ||
| 120 | for item in _door_ids_by_item.values(): | ||
| 121 | for door in item: | ||
| 122 | _mentioned_doors.append(door) | ||
| 123 | if _slot_data.has("painting_ids_by_item_id"): | ||
| 124 | _painting_ids_by_item = _slot_data["painting_ids_by_item_id"] | ||
| 125 | |||
| 126 | _mentioned_paintings = [] | ||
| 127 | for item in _painting_ids_by_item.values(): | ||
| 128 | for painting in item: | ||
| 129 | _mentioned_paintings.append(painting) | ||
| 130 | if _slot_data.has("panel_ids_by_location_id"): | ||
| 131 | _panel_ids_by_location = _slot_data["panel_ids_by_location_id"] | ||
| 132 | |||
| 107 | emit_signal("client_connected") | 133 | emit_signal("client_connected") |
| 108 | 134 | ||
| 109 | elif cmd == "ConnectionRefused": | 135 | elif cmd == "ConnectionRefused": |
| 110 | global._print("Connection to AP refused") | 136 | global._print("Connection to AP refused") |
| 111 | global._print(message) | 137 | global._print(message) |
| 112 | 138 | ||
| 139 | elif cmd == "ReceivedItems": | ||
| 140 | for item in message["items"]: | ||
| 141 | if _map_loaded: | ||
| 142 | processItem(item["item"]) | ||
| 143 | else: | ||
| 144 | _held_items.append(item["item"]) | ||
| 145 | |||
| 113 | 146 | ||
| 114 | func _process(_delta): | 147 | func _process(_delta): |
| 115 | if _should_process: | 148 | if _should_process: |
| @@ -170,3 +203,40 @@ func connectToRoom(): | |||
| 170 | } | 203 | } |
| 171 | ] | 204 | ] |
| 172 | ) | 205 | ) |
| 206 | |||
| 207 | |||
| 208 | func sendLocation(loc_id): | ||
| 209 | sendMessage([{"cmd": "LocationChecks", "locations": [loc_id]}]) | ||
| 210 | |||
| 211 | |||
| 212 | func mapFinishedLoading(): | ||
| 213 | if !_map_loaded: | ||
| 214 | _map_loaded = true | ||
| 215 | |||
| 216 | for item in _held_items: | ||
| 217 | processItem(item) | ||
| 218 | |||
| 219 | _held_items = [] | ||
| 220 | |||
| 221 | |||
| 222 | func processItem(item): | ||
| 223 | global._print(item) | ||
| 224 | |||
| 225 | var stringified = String(item) | ||
| 226 | if _door_ids_by_item.has(stringified): | ||
| 227 | var doorsNode = get_tree().get_root().get_node("Spatial/Doors") | ||
| 228 | for door_id in _door_ids_by_item[stringified]: | ||
| 229 | doorsNode.get_node(door_id).openDoor() | ||
| 230 | |||
| 231 | if _painting_ids_by_item.has(stringified): | ||
| 232 | var paintingsNode = get_tree().get_root().get_node("Spatial/Decorations/Paintings") | ||
| 233 | for painting_id in _painting_ids_by_item[stringified]: | ||
| 234 | paintingsNode.get_node(painting_id).movePainting() | ||
| 235 | |||
| 236 | |||
| 237 | func doorIsVanilla(door): | ||
| 238 | return !_mentioned_doors.has(door) | ||
| 239 | |||
| 240 | |||
| 241 | func paintingIsVanilla(painting): | ||
| 242 | return !_mentioned_paintings.has(painting) | ||
| diff --git a/Archipelago/doorControl.gd b/Archipelago/doorControl.gd new file mode 100644 index 0000000..011b0e0 --- /dev/null +++ b/Archipelago/doorControl.gd | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | extends "res://scripts/doorControl.gd" | ||
| 2 | |||
| 3 | |||
| 4 | func handle_correct(): | ||
| 5 | # TODO: Right now we are just assuming that door shuffle is on. | ||
| 6 | var apclient = global.get_node("Archipelago") | ||
| 7 | if apclient.doorIsVanilla(self.get_parent().name + "/" + self.name): | ||
| 8 | .handle_correct() | ||
| 9 | |||
| 10 | |||
| 11 | func openDoor(): | ||
| 12 | if !ran: | ||
| 13 | # Basically do the same thing that the base game does. | ||
| 14 | ran = true | ||
| 15 | $AnimationPlayer.play("Open") | ||
| diff --git a/Archipelago/load.gd b/Archipelago/load.gd new file mode 100644 index 0000000..b0ccafc --- /dev/null +++ b/Archipelago/load.gd | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | extends "res://scripts/load.gd" | ||
| 2 | |||
| 3 | |||
| 4 | func _load(): | ||
| 5 | global._print("Hooked Load Start") | ||
| 6 | |||
| 7 | var apclient = global.get_node("Archipelago") | ||
| 8 | |||
| 9 | # TODO: Override the YOU panel with the AP slot name | ||
| 10 | |||
| 11 | # This is the best time to create the location nodes, since the map is now | ||
| 12 | # loaded but the panels haven't been solved from the save file yet. | ||
| 13 | var panels_parent = self.get_node("Panels") | ||
| 14 | var location_script = ResourceLoader.load("user://maps/Archipelago/location.gd") | ||
| 15 | for location_name in apclient._location_name_to_id: | ||
| 16 | var location = location_script.new() | ||
| 17 | location.ap_name = location_name | ||
| 18 | location.ap_id = apclient._location_name_to_id[location_name] | ||
| 19 | location.name = "AP_location_" + location.ap_id | ||
| 20 | self.add_child(location) | ||
| 21 | |||
| 22 | var panels = apclient._panel_ids_by_location[String(location.ap_id)] | ||
| 23 | location.total = panels.size() | ||
| 24 | |||
| 25 | for panel in panels: | ||
| 26 | var that_panel = panels_parent.get_node(panel) | ||
| 27 | that_panel.get_node("Viewport/GUI/Panel/TextEdit").connect( | ||
| 28 | "answer_correct", location, "handle_correct" | ||
| 29 | ) | ||
| 30 | |||
| 31 | # Process any items received while the map was loading. | ||
| 32 | apclient.mapFinishedLoading() | ||
| 33 | |||
| 34 | # Proceed with the rest of the load. | ||
| 35 | global._print("Hooked Load End") | ||
| 36 | ._load() | ||
| diff --git a/Archipelago/location.gd b/Archipelago/location.gd new file mode 100644 index 0000000..b85b5c4 --- /dev/null +++ b/Archipelago/location.gd | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | extends Node | ||
| 2 | |||
| 3 | var ap_name = "" | ||
| 4 | var ap_id = 0 | ||
| 5 | var total = 0 | ||
| 6 | var solved = 0 | ||
| 7 | var ran = false | ||
| 8 | |||
| 9 | |||
| 10 | func handle_correct(): | ||
| 11 | solved += 1 | ||
| 12 | |||
| 13 | if solved >= total && !ran: | ||
| 14 | ran = true | ||
| 15 | |||
| 16 | var apclient = global.get_node("Archipelago") | ||
| 17 | apclient.sendLocation(ap_id) | ||
| diff --git a/Archipelago/painting_eye.gd b/Archipelago/painting_eye.gd new file mode 100644 index 0000000..86e0ce9 --- /dev/null +++ b/Archipelago/painting_eye.gd | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | extends "res://scripts/painting_eye.gd" | ||
| 2 | |||
| 3 | |||
| 4 | func _answer_correct(): | ||
| 5 | # TODO: Right now we are just assuming that door shuffle is on. | ||
| 6 | var apclient = global.get_node("Archipelago") | ||
| 7 | if apclient.paintingIsVanilla(self.name): | ||
| 8 | ._answer_correct() | ||
| 9 | |||
| 10 | |||
| 11 | func movePainting(): | ||
| 12 | ._answer_correct() | ||
| diff --git a/Archipelago/settings_screen.gd b/Archipelago/settings_screen.gd index 0854a8b..9624693 100644 --- a/Archipelago/settings_screen.gd +++ b/Archipelago/settings_screen.gd | |||
| @@ -13,6 +13,11 @@ func _ready(): | |||
| 13 | apclient_instance.name = "Archipelago" | 13 | apclient_instance.name = "Archipelago" |
| 14 | global.add_child(apclient_instance) | 14 | global.add_child(apclient_instance) |
| 15 | 15 | ||
| 16 | # Let's also inject any scripts we need to inject now. | ||
| 17 | installScriptExtension("user://maps/Archipelago/doorControl.gd") | ||
| 18 | installScriptExtension("user://maps/Archipelago/load.gd") | ||
| 19 | installScriptExtension("user://maps/Archipelago/painting_eye.gd") | ||
| 20 | |||
| 16 | global.get_node("Archipelago").connect("client_connected", self, "connectionSuccessful") | 21 | global.get_node("Archipelago").connect("client_connected", self, "connectionSuccessful") |
| 17 | 22 | ||
| 18 | # Populate textboxes with AP settings. | 23 | # Populate textboxes with AP settings. |
| @@ -21,6 +26,27 @@ func _ready(): | |||
| 21 | self.get_node("Panel/password_box").text = global.get_node("Archipelago").ap_pass | 26 | self.get_node("Panel/password_box").text = global.get_node("Archipelago").ap_pass |
| 22 | 27 | ||
| 23 | 28 | ||
| 29 | # Adapted from https://gitlab.com/Delta-V-Modding/Mods/-/blob/main/game/ModLoader.gd | ||
| 30 | func installScriptExtension(childScriptPath: String): | ||
| 31 | var childScript = ResourceLoader.load(childScriptPath) | ||
| 32 | |||
| 33 | # Force Godot to compile the script now. | ||
| 34 | # We need to do this here to ensure that the inheritance chain is | ||
| 35 | # properly set up, and multiple mods can chain-extend the same | ||
| 36 | # class multiple times. | ||
| 37 | # This is also needed to make Godot instantiate the extended class | ||
| 38 | # when creating singletons. | ||
| 39 | # The actual instance is thrown away. | ||
| 40 | childScript.new() | ||
| 41 | |||
| 42 | var parentScript = childScript.get_base_script() | ||
| 43 | var parentScriptPath = parentScript.resource_path | ||
| 44 | global._print( | ||
| 45 | "ModLoader: Installing script extension: %s <- %s" % [parentScriptPath, childScriptPath] | ||
| 46 | ) | ||
| 47 | childScript.take_over_path(parentScriptPath) | ||
| 48 | |||
| 49 | |||
| 24 | func connectionSuccessful(): | 50 | func connectionSuccessful(): |
| 25 | # Switch to LL1 | 51 | # Switch to LL1 |
| 26 | Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) | 52 | Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) |
