summary refs log tree commit diff stats
path: root/client/Archipelago/manager.gd
diff options
context:
space:
mode:
Diffstat (limited to 'client/Archipelago/manager.gd')
-rw-r--r--client/Archipelago/manager.gd147
1 files changed, 122 insertions, 25 deletions
diff --git a/client/Archipelago/manager.gd b/client/Archipelago/manager.gd index 07d28a4..cd0654f 100644 --- a/client/Archipelago/manager.gd +++ b/client/Archipelago/manager.gd
@@ -20,7 +20,10 @@ var _localdata_file = ""
20var _last_new_item = -1 20var _last_new_item = -1
21var _batch_locations = false 21var _batch_locations = false
22var _held_locations = [] 22var _held_locations = []
23var _held_location_scouts = []
24var _location_scouts = {}
23var _item_locks = {} 25var _item_locks = {}
26var _inverse_item_locks = {}
24var _held_letters = {} 27var _held_letters = {}
25var _letters_setup = false 28var _letters_setup = false
26 29
@@ -34,8 +37,14 @@ const kLETTER_BEHAVIOR_VANILLA = 0
34const kLETTER_BEHAVIOR_ITEM = 1 37const kLETTER_BEHAVIOR_ITEM = 1
35const kLETTER_BEHAVIOR_UNLOCKED = 2 38const kLETTER_BEHAVIOR_UNLOCKED = 2
36 39
40const kCYAN_DOOR_BEHAVIOR_H2 = 0
41const kCYAN_DOOR_BEHAVIOR_DOUBLE_LETTER = 1
42const kCYAN_DOOR_BEHAVIOR_ITEM = 2
43
44var cyan_door_behavior = kCYAN_DOOR_BEHAVIOR_H2
37var daedalus_roof_access = false 45var daedalus_roof_access = false
38var keyholder_sanity = false 46var keyholder_sanity = false
47var shuffle_control_center_colors = false
39var shuffle_doors = false 48var shuffle_doors = false
40var shuffle_letters = kSHUFFLE_LETTERS_VANILLA 49var shuffle_letters = kSHUFFLE_LETTERS_VANILLA
41var victory_condition = -1 50var victory_condition = -1
@@ -75,6 +84,7 @@ func _ready():
75 84
76 client.connect("item_received", _process_item) 85 client.connect("item_received", _process_item)
77 client.connect("message_received", _process_message) 86 client.connect("message_received", _process_message)
87 client.connect("location_scout_received", _process_location_scout)
78 client.connect("could_not_connect", _client_could_not_connect) 88 client.connect("could_not_connect", _client_could_not_connect)
79 client.connect("connect_status", _client_connect_status) 89 client.connect("connect_status", _client_connect_status)
80 client.connect("client_connected", _client_connected) 90 client.connect("client_connected", _client_connected)
@@ -118,6 +128,10 @@ func saveLocaldata():
118 128
119func connectToServer(): 129func connectToServer():
120 _last_new_item = -1 130 _last_new_item = -1
131 _batch_locations = false
132 _held_locations = []
133 _held_location_scouts = []
134 _location_scouts = {}
121 _letters_setup = false 135 _letters_setup = false
122 _held_letters = {} 136 _held_letters = {}
123 137
@@ -142,28 +156,32 @@ func _process_item(item, index, from, flags, amount):
142 item_name = client._item_id_to_name["Lingo 2"][item] 156 item_name = client._item_id_to_name["Lingo 2"][item]
143 157
144 var gamedata = global.get_node("Gamedata") 158 var gamedata = global.get_node("Gamedata")
145 var door_id = gamedata.door_id_by_ap_id.get(item, null)
146 var prog_id = null
147 159
148 if door_id == null: 160 var prog_id = null
149 prog_id = gamedata.progressive_id_by_ap_id.get(item, null) 161 if _inverse_item_locks.has(item):
150 if prog_id != null: 162 for lock in _inverse_item_locks.get(item):
151 var progressive = gamedata.objects.get_progressives()[prog_id] 163 if lock[1] != amount:
152 if progressive.get_doors().size() >= amount: 164 continue
153 door_id = progressive.get_doors()[amount - 1] 165
154 166 if gamedata.progressive_id_by_ap_id.has(item):
155 if door_id != null and gamedata.get_door_map_name(door_id) == global.map: 167 prog_id = lock[0]
156 var receivers = gamedata.get_door_receivers(door_id) 168
157 var scene = get_tree().get_root().get_node_or_null("scene") 169 if gamedata.get_door_map_name(lock[0]) != global.map:
158 if scene != null: 170 continue
159 for receiver in receivers: 171
160 var rnode = scene.get_node_or_null(receiver) 172 var receivers = gamedata.get_door_receivers(lock[0])
161 if rnode != null: 173 var scene = get_tree().get_root().get_node_or_null("scene")
162 rnode.handleTriggered() 174 if scene != null:
163 175 for receiver in receivers:
164 var letter_key = gamedata.letter_key_by_ap_id.get(item, null) 176 var rnode = scene.get_node_or_null(receiver)
165 if letter_key != null: 177 if rnode != null:
166 _process_key_item(letter_key, amount) 178 rnode.handleTriggered()
179
180 var letter_id = gamedata.letter_id_by_ap_id.get(item, null)
181 if letter_id != null:
182 var letter = gamedata.objects.get_letters()[letter_id]
183 if not letter.has_level2() or not letter.get_level2():
184 _process_key_item(letter.get_key(), amount)
167 185
168 # Show a message about the item if it's new. 186 # Show a message about the item if it's new.
169 if index != null and index > _last_new_item: 187 if index != null and index > _last_new_item:
@@ -177,8 +195,8 @@ func _process_item(item, index, from, flags, amount):
177 var item_color = colorForItemType(flags) 195 var item_color = colorForItemType(flags)
178 196
179 var full_item_name = item_name 197 var full_item_name = item_name
180 if prog_id != null and door_id != null: 198 if prog_id != null:
181 var door = gamedata.objects.get_doors()[door_id] 199 var door = gamedata.objects.get_doors()[prog_id]
182 full_item_name = "%s (%s)" % [item_name, door.get_name()] 200 full_item_name = "%s (%s)" % [item_name, door.get_name()]
183 201
184 var message 202 var message
@@ -280,6 +298,29 @@ func parse_printjson_for_textclient(message):
280 textclient_node.parse_printjson("".join(parts)) 298 textclient_node.parse_printjson("".join(parts))
281 299
282 300
301func _process_location_scout(item_id, location_id, player, flags):
302 _location_scouts[location_id] = {"item": item_id, "player": player, "flags": flags}
303
304 var gamedata = global.get_node("Gamedata")
305 var map_id = gamedata.map_id_by_name.get(global.map)
306
307 var item_name = "Unknown"
308 var item_player_game = client._game_by_player[float(player)]
309 if client._item_id_to_name[item_player_game].has(item_id):
310 item_name = client._item_id_to_name[item_player_game][item_id]
311
312 var letter_id = gamedata.letter_id_by_ap_id.get(location_id, null)
313 if letter_id != null:
314 var letter = gamedata.objects.get_letters()[letter_id]
315 var room = gamedata.objects.get_rooms()[letter.get_room_id()]
316 if room.get_map_id() == map_id:
317 var collectable = get_tree().get_root().get_node("scene").get_node_or_null(
318 letter.get_path()
319 )
320 if collectable != null:
321 collectable.setScoutedText(item_name)
322
323
283func _client_could_not_connect(): 324func _client_could_not_connect():
284 emit_signal("could_not_connect") 325 emit_signal("could_not_connect")
285 326
@@ -309,8 +350,10 @@ func _client_connected(slot_data):
309 _last_new_item = localdata[0] 350 _last_new_item = localdata[0]
310 351
311 # Read slot data. 352 # Read slot data.
353 cyan_door_behavior = int(slot_data.get("cyan_door_behavior", 0))
312 daedalus_roof_access = bool(slot_data.get("daedalus_roof_access", false)) 354 daedalus_roof_access = bool(slot_data.get("daedalus_roof_access", false))
313 keyholder_sanity = bool(slot_data.get("keyholder_sanity", false)) 355 keyholder_sanity = bool(slot_data.get("keyholder_sanity", false))
356 shuffle_control_center_colors = bool(slot_data.get("shuffle_control_center_colors", false))
314 shuffle_doors = bool(slot_data.get("shuffle_doors", false)) 357 shuffle_doors = bool(slot_data.get("shuffle_doors", false))
315 shuffle_letters = int(slot_data.get("shuffle_letters", 0)) 358 shuffle_letters = int(slot_data.get("shuffle_letters", 0))
316 victory_condition = int(slot_data.get("victory_condition", 0)) 359 victory_condition = int(slot_data.get("victory_condition", 0))
@@ -331,6 +374,42 @@ func _client_connected(slot_data):
331 var door = gamedata.objects.get_doors()[progressive.get_doors()[i]] 374 var door = gamedata.objects.get_doors()[progressive.get_doors()[i]]
332 _item_locks[door.get_id()] = [progressive.get_ap_id(), i + 1] 375 _item_locks[door.get_id()] = [progressive.get_ap_id(), i + 1]
333 376
377 for door_group in gamedata.objects.get_door_groups():
378 if (
379 door_group.get_type() == gamedata.SCRIPT_proto.DoorGroupType.CONNECTOR
380 or door_group.get_type() == gamedata.SCRIPT_proto.DoorGroupType.SHUFFLE_GROUP
381 ):
382 for door in door_group.get_doors():
383 _item_locks[door] = [door_group.get_ap_id(), 1]
384
385 if shuffle_control_center_colors:
386 for door in gamedata.objects.get_doors():
387 if door.get_type() == gamedata.SCRIPT_proto.DoorType.CONTROL_CENTER_COLOR:
388 _item_locks[door.get_id()] = [door.get_ap_id(), 1]
389
390 for door_group in gamedata.objects.get_door_groups():
391 if door_group.get_type() == gamedata.SCRIPT_proto.DoorGroupType.COLOR_CONNECTOR:
392 for door in door_group.get_doors():
393 _item_locks[door] = [door_group.get_ap_id(), 1]
394
395 if cyan_door_behavior == kCYAN_DOOR_BEHAVIOR_ITEM:
396 for door_group in gamedata.objects.get_door_groups():
397 if door_group.get_type() == gamedata.SCRIPT_proto.DoorGroupType.CYAN_DOORS:
398 for door in door_group.get_doors():
399 if not _item_locks.has(door):
400 _item_locks[door] = [door_group.get_ap_id(), 1]
401
402 # Create a reverse item locks map for processing items.
403 _inverse_item_locks = {}
404
405 for door_id in _item_locks.keys():
406 var lock = _item_locks.get(door_id)
407
408 if not _inverse_item_locks.has(lock[0]):
409 _inverse_item_locks[lock[0]] = []
410
411 _inverse_item_locks[lock[0]].append([door_id, lock[1]])
412
334 emit_signal("ap_connected") 413 emit_signal("ap_connected")
335 414
336 415
@@ -345,10 +424,28 @@ func send_location(loc_id):
345 client.sendLocation(loc_id) 424 client.sendLocation(loc_id)
346 425
347 426
427func scout_location(loc_id):
428 if _location_scouts.has(loc_id):
429 return _location_scouts.get(loc_id)
430
431 if _batch_locations:
432 _held_location_scouts.append(loc_id)
433 else:
434 client.scoutLocation(loc_id)
435
436 return null
437
438
348func stop_batching_locations(): 439func stop_batching_locations():
349 _batch_locations = false 440 _batch_locations = false
350 client.sendLocations(_held_locations) 441
351 _held_locations.clear() 442 if not _held_locations.is_empty():
443 client.sendLocations(_held_locations)
444 _held_locations.clear()
445
446 if not _held_location_scouts.is_empty():
447 client.scoutLocations(_held_location_scouts)
448 _held_location_scouts.clear()
352 449
353 450
354func colorForItemType(flags): 451func colorForItemType(flags):