diff options
Diffstat (limited to 'client/Archipelago/manager.gd')
-rw-r--r-- | client/Archipelago/manager.gd | 147 |
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 = "" | |||
20 | var _last_new_item = -1 | 20 | var _last_new_item = -1 |
21 | var _batch_locations = false | 21 | var _batch_locations = false |
22 | var _held_locations = [] | 22 | var _held_locations = [] |
23 | var _held_location_scouts = [] | ||
24 | var _location_scouts = {} | ||
23 | var _item_locks = {} | 25 | var _item_locks = {} |
26 | var _inverse_item_locks = {} | ||
24 | var _held_letters = {} | 27 | var _held_letters = {} |
25 | var _letters_setup = false | 28 | var _letters_setup = false |
26 | 29 | ||
@@ -34,8 +37,14 @@ const kLETTER_BEHAVIOR_VANILLA = 0 | |||
34 | const kLETTER_BEHAVIOR_ITEM = 1 | 37 | const kLETTER_BEHAVIOR_ITEM = 1 |
35 | const kLETTER_BEHAVIOR_UNLOCKED = 2 | 38 | const kLETTER_BEHAVIOR_UNLOCKED = 2 |
36 | 39 | ||
40 | const kCYAN_DOOR_BEHAVIOR_H2 = 0 | ||
41 | const kCYAN_DOOR_BEHAVIOR_DOUBLE_LETTER = 1 | ||
42 | const kCYAN_DOOR_BEHAVIOR_ITEM = 2 | ||
43 | |||
44 | var cyan_door_behavior = kCYAN_DOOR_BEHAVIOR_H2 | ||
37 | var daedalus_roof_access = false | 45 | var daedalus_roof_access = false |
38 | var keyholder_sanity = false | 46 | var keyholder_sanity = false |
47 | var shuffle_control_center_colors = false | ||
39 | var shuffle_doors = false | 48 | var shuffle_doors = false |
40 | var shuffle_letters = kSHUFFLE_LETTERS_VANILLA | 49 | var shuffle_letters = kSHUFFLE_LETTERS_VANILLA |
41 | var victory_condition = -1 | 50 | var 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 | ||
119 | func connectToServer(): | 129 | func 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 | ||
301 | func _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 | |||
283 | func _client_could_not_connect(): | 324 | func _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 | ||
427 | func 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 | |||
348 | func stop_batching_locations(): | 439 | func 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 | ||
354 | func colorForItemType(flags): | 451 | func colorForItemType(flags): |