summary refs log tree commit diff stats
path: root/client/Archipelago
diff options
context:
space:
mode:
authorStar Rauchenberger <fefferburbia@gmail.com>2025-09-01 14:50:47 -0400
committerStar Rauchenberger <fefferburbia@gmail.com>2025-09-01 14:50:47 -0400
commit7f5f14ddb5a67e1ccfdc7aa3d68d829473d0b745 (patch)
tree3fa17e011d0b4b4824e8d887949bffa476eb8cb2 /client/Archipelago
parentffc3276b11308bdf0d42a07820aaaa44e3534b4e (diff)
downloadlingo2-archipelago-7f5f14ddb5a67e1ccfdc7aa3d68d829473d0b745.tar.gz
lingo2-archipelago-7f5f14ddb5a67e1ccfdc7aa3d68d829473d0b745.tar.bz2
lingo2-archipelago-7f5f14ddb5a67e1ccfdc7aa3d68d829473d0b745.zip
[Client] Handle progressive doors
Diffstat (limited to 'client/Archipelago')
-rw-r--r--client/Archipelago/animationListener.gd14
-rw-r--r--client/Archipelago/client.gd32
-rw-r--r--client/Archipelago/door.gd14
-rw-r--r--client/Archipelago/gamedata.gd4
-rw-r--r--client/Archipelago/manager.gd70
-rw-r--r--client/Archipelago/painting.gd14
-rw-r--r--client/Archipelago/teleportListener.gd14
7 files changed, 99 insertions, 63 deletions
diff --git a/client/Archipelago/animationListener.gd b/client/Archipelago/animationListener.gd index f1fb5fb..c3b26db 100644 --- a/client/Archipelago/animationListener.gd +++ b/client/Archipelago/animationListener.gd
@@ -1,6 +1,7 @@
1extends "res://scripts/nodes/listeners/animationListener.gd" 1extends "res://scripts/nodes/listeners/animationListener.gd"
2 2
3var item_id 3var item_id
4var item_amount
4 5
5 6
6func _ready(): 7func _ready():
@@ -8,17 +9,16 @@ func _ready():
8 get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names() 9 get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names()
9 ) 10 )
10 11
11 print("node: %s" % node_path)
12
13 var gamedata = global.get_node("Gamedata") 12 var gamedata = global.get_node("Gamedata")
14 var door_id = gamedata.get_door_for_map_node_path(global.map, node_path) 13 var door_id = gamedata.get_door_for_map_node_path(global.map, node_path)
15 if door_id != null: 14 if door_id != null:
16 print("door_id: %d" % door_id)
17
18 var ap = global.get_node("Archipelago") 15 var ap = global.get_node("Archipelago")
19 item_id = ap.get_item_id_for_door(door_id) 16 var item_lock = ap.get_item_id_for_door(door_id)
17
18 if item_lock != null:
19 item_id = item_lock[0]
20 item_amount = item_lock[1]
20 21
21 if item_id != null:
22 self.senders = [] 22 self.senders = []
23 self.senderGroup = [] 23 self.senderGroup = []
24 self.nested = false 24 self.nested = false
@@ -34,5 +34,5 @@ func _ready():
34func _readier(): 34func _readier():
35 var ap = global.get_node("Archipelago") 35 var ap = global.get_node("Archipelago")
36 36
37 if ap.has_item(item_id): 37 if ap.client.getItemAmount(item_id) >= item_amount:
38 handleTriggered() 38 handleTriggered()
diff --git a/client/Archipelago/client.gd b/client/Archipelago/client.gd index f0f36d7..52ce047 100644 --- a/client/Archipelago/client.gd +++ b/client/Archipelago/client.gd
@@ -32,13 +32,14 @@ var _players = []
32var _player_name_by_slot = {} 32var _player_name_by_slot = {}
33var _game_by_player = {} 33var _game_by_player = {}
34var _checked_locations = [] 34var _checked_locations = []
35var _received_items = [] 35var _received_indexes = []
36var _received_items = {}
36var _slot_data = {} 37var _slot_data = {}
37 38
38signal could_not_connect 39signal could_not_connect
39signal connect_status 40signal connect_status
40signal client_connected(slot_data) 41signal client_connected(slot_data)
41signal item_received(item_id, index, player, flags) 42signal item_received(item_id, index, player, flags, amount)
42signal message_received(message) 43signal message_received(message)
43 44
44 45
@@ -74,6 +75,8 @@ func _reset_state():
74 _authenticated = false 75 _authenticated = false
75 _try_wss = false 76 _try_wss = false
76 _has_connected = false 77 _has_connected = false
78 _received_items = {}
79 _received_indexes = []
77 80
78 81
79func _errored(): 82func _errored():
@@ -228,17 +231,26 @@ func _process(_delta):
228 elif cmd == "ReceivedItems": 231 elif cmd == "ReceivedItems":
229 var i = 0 232 var i = 0
230 for item in message["items"]: 233 for item in message["items"]:
231 if not _received_items.has(int(item["item"])): 234 var index = int(message["index"] + i)
232 _received_items.append(int(item["item"])) 235 i += 1
236
237 if _received_indexes.has(index):
238 # Do not re-process items.
239 continue
240
241 _received_indexes.append(index)
242
243 var item_id = int(item["item"])
244 _received_items[item_id] = _received_items.get(item_id, 0) + 1
233 245
234 emit_signal( 246 emit_signal(
235 "item_received", 247 "item_received",
236 int(item["item"]), 248 item_id,
237 int(message["index"]) + i, 249 index,
238 int(item["player"]), 250 int(item["player"]),
239 int(item["flags"]) 251 int(item["flags"]),
252 _received_items[item_id]
240 ) 253 )
241 i += 1
242 254
243 elif cmd == "PrintJSON": 255 elif cmd == "PrintJSON":
244 emit_signal("message_received", message) 256 emit_signal("message_received", message)
@@ -380,3 +392,7 @@ func completedGoal():
380 392
381func hasItem(item_id): 393func hasItem(item_id):
382 return _received_items.has(item_id) 394 return _received_items.has(item_id)
395
396
397func getItemAmount(item_id):
398 return _received_items.get(item_id, 0)
diff --git a/client/Archipelago/door.gd b/client/Archipelago/door.gd index 731eca4..fead818 100644 --- a/client/Archipelago/door.gd +++ b/client/Archipelago/door.gd
@@ -1,6 +1,7 @@
1extends "res://scripts/nodes/door.gd" 1extends "res://scripts/nodes/door.gd"
2 2
3var item_id 3var item_id
4var item_amount
4 5
5 6
6func _ready(): 7func _ready():
@@ -8,17 +9,16 @@ func _ready():
8 get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names() 9 get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names()
9 ) 10 )
10 11
11 print("node: %s" % node_path)
12
13 var gamedata = global.get_node("Gamedata") 12 var gamedata = global.get_node("Gamedata")
14 var door_id = gamedata.get_door_for_map_node_path(global.map, node_path) 13 var door_id = gamedata.get_door_for_map_node_path(global.map, node_path)
15 if door_id != null: 14 if door_id != null:
16 print("door_id: %d" % door_id)
17
18 var ap = global.get_node("Archipelago") 15 var ap = global.get_node("Archipelago")
19 item_id = ap.get_item_id_for_door(door_id) 16 var item_lock = ap.get_item_id_for_door(door_id)
17
18 if item_lock != null:
19 item_id = item_lock[0]
20 item_amount = item_lock[1]
20 21
21 if item_id != null:
22 self.senders = [] 22 self.senders = []
23 self.senderGroup = [] 23 self.senderGroup = []
24 self.nested = false 24 self.nested = false
@@ -34,5 +34,5 @@ func _ready():
34func _readier(): 34func _readier():
35 var ap = global.get_node("Archipelago") 35 var ap = global.get_node("Archipelago")
36 36
37 if ap.has_item(item_id): 37 if ap.client.getItemAmount(item_id) >= item_amount:
38 handleTriggered() 38 handleTriggered()
diff --git a/client/Archipelago/gamedata.gd b/client/Archipelago/gamedata.gd index 16368a9..669ad3d 100644 --- a/client/Archipelago/gamedata.gd +++ b/client/Archipelago/gamedata.gd
@@ -7,6 +7,7 @@ var door_id_by_map_node_path = {}
7var painting_id_by_map_node_path = {} 7var painting_id_by_map_node_path = {}
8var door_id_by_ap_id = {} 8var door_id_by_ap_id = {}
9var map_id_by_name = {} 9var map_id_by_name = {}
10var progressive_id_by_ap_id = {}
10 11
11 12
12func _init(proto_script): 13func _init(proto_script):
@@ -50,6 +51,9 @@ func load(data_bytes):
50 51
51 var _map_data = painting_id_by_map_node_path[map.get_name()] 52 var _map_data = painting_id_by_map_node_path[map.get_name()]
52 53
54 for progressive in objects.get_progressives():
55 progressive_id_by_ap_id[progressive.get_ap_id()] = progressive.get_id()
56
53 57
54func get_door_for_map_node_path(map_name, node_path): 58func get_door_for_map_node_path(map_name, node_path):
55 if not door_id_by_map_node_path.has(map_name): 59 if not door_id_by_map_node_path.has(map_name):
diff --git a/client/Archipelago/manager.gd b/client/Archipelago/manager.gd index 97c556a..0186a09 100644 --- a/client/Archipelago/manager.gd +++ b/client/Archipelago/manager.gd
@@ -15,12 +15,13 @@ var connection_history = []
15var client 15var client
16 16
17var _localdata_file = "" 17var _localdata_file = ""
18var _received_indexes = []
19var _last_new_item = -1 18var _last_new_item = -1
20var _batch_locations = false 19var _batch_locations = false
21var _held_locations = [] 20var _held_locations = []
21var _item_locks = {}
22 22
23var victory_condition = -1 23var victory_condition = -1
24var shuffle_doors = false
24 25
25signal could_not_connect 26signal could_not_connect
26signal connect_status 27signal connect_status
@@ -96,7 +97,6 @@ func saveLocaldata():
96 97
97 98
98func connectToServer(): 99func connectToServer():
99 _received_indexes = []
100 _last_new_item = -1 100 _last_new_item = -1
101 101
102 client.connectToServer(ap_server, ap_user, ap_pass) 102 client.connectToServer(ap_server, ap_user, ap_pass)
@@ -111,35 +111,25 @@ func disconnect_from_ap():
111 111
112 112
113func get_item_id_for_door(door_id): 113func get_item_id_for_door(door_id):
114 var gamedata = global.get_node("Gamedata") 114 return _item_locks.get(door_id, null)
115 var door = gamedata.objects.get_doors()[door_id]
116 if (
117 door.get_type() == gamedata.SCRIPT_proto.DoorType.EVENT
118 or door.get_type() == gamedata.SCRIPT_proto.DoorType.LOCATION_ONLY
119 or door.get_type() == gamedata.SCRIPT_proto.DoorType.CONTROL_CENTER_COLOR
120 ):
121 return null
122 return gamedata.get_door_ap_id(door_id)
123
124
125func has_item(item_id):
126 return client.hasItem(item_id)
127
128
129func _process_item(item, index, from, flags):
130 if index != null:
131 if _received_indexes.has(index):
132 # Do not re-process items.
133 return
134 115
135 _received_indexes.append(index)
136 116
117func _process_item(item, index, from, flags, amount):
137 var item_name = "Unknown" 118 var item_name = "Unknown"
138 if client._item_id_to_name["Lingo 2"].has(item): 119 if client._item_id_to_name["Lingo 2"].has(item):
139 item_name = client._item_id_to_name["Lingo 2"][item] 120 item_name = client._item_id_to_name["Lingo 2"][item]
140 121
141 var gamedata = global.get_node("Gamedata") 122 var gamedata = global.get_node("Gamedata")
142 var door_id = gamedata.door_id_by_ap_id.get(item, null) 123 var door_id = gamedata.door_id_by_ap_id.get(item, null)
124 var prog_id = null
125
126 if door_id == null:
127 prog_id = gamedata.progressive_id_by_ap_id.get(item, null)
128 if prog_id != null:
129 var progressive = gamedata.objects.get_progressives()[prog_id]
130 if progressive.get_doors().size() >= amount:
131 door_id = progressive.get_doors()[amount - 1]
132
143 if door_id != null and gamedata.get_door_map_name(door_id) == global.map: 133 if door_id != null and gamedata.get_door_map_name(door_id) == global.map:
144 var receivers = gamedata.get_door_receivers(door_id) 134 var receivers = gamedata.get_door_receivers(door_id)
145 var scene = get_tree().get_root().get_node_or_null("scene") 135 var scene = get_tree().get_root().get_node_or_null("scene")
@@ -165,11 +155,18 @@ func _process_item(item, index, from, flags):
165 155
166 var item_color = colorForItemType(flags) 156 var item_color = colorForItemType(flags)
167 157
158 var full_item_name = item_name
159 if prog_id != null and door_id != null:
160 var door = gamedata.objects.get_doors()[door_id]
161 full_item_name = "%s (%s)" % [item_name, door.get_name()]
162
168 var message 163 var message
169 if from == client._slot: 164 if from == client._slot:
170 message = "Found [color=%s]%s[/color]" % [item_color, item_name] 165 message = "Found [color=%s]%s[/color]" % [item_color, full_item_name]
171 else: 166 else:
172 message = "Received [color=%s]%s[/color] from %s" % [item_color, item_name, player_name] 167 message = (
168 "Received [color=%s]%s[/color] from %s" % [item_color, full_item_name, player_name]
169 )
173 170
174 global._print(message) 171 global._print(message)
175 172
@@ -271,6 +268,8 @@ func _client_connect_status(message):
271 268
272 269
273func _client_connected(slot_data): 270func _client_connected(slot_data):
271 var gamedata = global.get_node("Gamedata")
272
274 _localdata_file = "user://archipelago_data/%s_%d" % [client._seed, client._slot] 273 _localdata_file = "user://archipelago_data/%s_%d" % [client._seed, client._slot]
275 _last_new_item = -1 274 _last_new_item = -1
276 275
@@ -288,8 +287,25 @@ func _client_connected(slot_data):
288 if localdata.size() > 0: 287 if localdata.size() > 0:
289 _last_new_item = localdata[0] 288 _last_new_item = localdata[0]
290 289
291 if slot_data.has("victory_condition"): 290 # Read slot data.
292 victory_condition = int(slot_data["victory_condition"]) 291 victory_condition = int(slot_data.get("victory_condition", 0))
292 shuffle_doors = bool(slot_data.get("shuffle_doors", false))
293
294 # Set up item locks.
295 _item_locks = {}
296
297 if shuffle_doors:
298 for door in gamedata.objects.get_doors():
299 if (
300 door.get_type() == gamedata.SCRIPT_proto.DoorType.STANDARD
301 or door.get_type() == gamedata.SCRIPT_proto.DoorType.ITEM_ONLY
302 ):
303 _item_locks[door.get_id()] = [door.get_ap_id(), 1]
304
305 for progressive in gamedata.objects.get_progressives():
306 for i in range(0, progressive.get_doors().size()):
307 var door = gamedata.objects.get_doors()[progressive.get_doors()[i]]
308 _item_locks[door.get_id()] = [progressive.get_ap_id(), i + 1]
293 309
294 emit_signal("ap_connected") 310 emit_signal("ap_connected")
295 311
diff --git a/client/Archipelago/painting.gd b/client/Archipelago/painting.gd index 6b3de0b..276d4eb 100644 --- a/client/Archipelago/painting.gd +++ b/client/Archipelago/painting.gd
@@ -1,6 +1,7 @@
1extends "res://scripts/nodes/painting.gd" 1extends "res://scripts/nodes/painting.gd"
2 2
3var item_id 3var item_id
4var item_amount
4 5
5 6
6func _ready(): 7func _ready():
@@ -8,17 +9,16 @@ func _ready():
8 get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names() 9 get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names()
9 ) 10 )
10 11
11 print("node: %s" % node_path)
12
13 var gamedata = global.get_node("Gamedata") 12 var gamedata = global.get_node("Gamedata")
14 var door_id = gamedata.get_door_for_map_node_path(global.map, node_path) 13 var door_id = gamedata.get_door_for_map_node_path(global.map, node_path)
15 if door_id != null: 14 if door_id != null:
16 print("door_id: %d" % door_id)
17
18 var ap = global.get_node("Archipelago") 15 var ap = global.get_node("Archipelago")
19 item_id = ap.get_item_id_for_door(door_id) 16 var item_lock = ap.get_item_id_for_door(door_id)
17
18 if item_lock != null:
19 item_id = item_lock[0]
20 item_amount = item_lock[1]
20 21
21 if item_id != null:
22 self.senders = [] 22 self.senders = []
23 self.senderGroup = [] 23 self.senderGroup = []
24 self.nested = false 24 self.nested = false
@@ -34,5 +34,5 @@ func _ready():
34func _readier(): 34func _readier():
35 var ap = global.get_node("Archipelago") 35 var ap = global.get_node("Archipelago")
36 36
37 if ap.has_item(item_id): 37 if ap.client.getItemAmount(item_id) >= item_amount:
38 handleTriggered() 38 handleTriggered()
diff --git a/client/Archipelago/teleportListener.gd b/client/Archipelago/teleportListener.gd index 4bb08c9..4a7deec 100644 --- a/client/Archipelago/teleportListener.gd +++ b/client/Archipelago/teleportListener.gd
@@ -1,6 +1,7 @@
1extends "res://scripts/nodes/listeners/teleportListener.gd" 1extends "res://scripts/nodes/listeners/teleportListener.gd"
2 2
3var item_id 3var item_id
4var item_amount
4 5
5 6
6func _ready(): 7func _ready():
@@ -8,17 +9,16 @@ func _ready():
8 get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names() 9 get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names()
9 ) 10 )
10 11
11 print("node: %s" % node_path)
12
13 var gamedata = global.get_node("Gamedata") 12 var gamedata = global.get_node("Gamedata")
14 var door_id = gamedata.get_door_for_map_node_path(global.map, node_path) 13 var door_id = gamedata.get_door_for_map_node_path(global.map, node_path)
15 if door_id != null: 14 if door_id != null:
16 print("door_id: %d" % door_id)
17
18 var ap = global.get_node("Archipelago") 15 var ap = global.get_node("Archipelago")
19 item_id = ap.get_item_id_for_door(door_id) 16 var item_lock = ap.get_item_id_for_door(door_id)
17
18 if item_lock != null:
19 item_id = item_lock[0]
20 item_amount = item_lock[1]
20 21
21 if item_id != null:
22 self.senders = [] 22 self.senders = []
23 self.senderGroup = [] 23 self.senderGroup = []
24 self.nested = false 24 self.nested = false
@@ -34,5 +34,5 @@ func _ready():
34func _readier(): 34func _readier():
35 var ap = global.get_node("Archipelago") 35 var ap = global.get_node("Archipelago")
36 36
37 if ap.has_item(item_id): 37 if ap.client.getItemAmount(item_id) >= item_amount:
38 handleTriggered() 38 handleTriggered()