diff options
Diffstat (limited to 'Archipelago/client.gd')
-rw-r--r-- | Archipelago/client.gd | 107 |
1 files changed, 82 insertions, 25 deletions
diff --git a/Archipelago/client.gd b/Archipelago/client.gd index 0f1c651..325418f 100644 --- a/Archipelago/client.gd +++ b/Archipelago/client.gd | |||
@@ -18,8 +18,8 @@ var enable_multiplayer = false | |||
18 | var track_player = false | 18 | var track_player = false |
19 | var connection_history = [] | 19 | var connection_history = [] |
20 | 20 | ||
21 | const my_version = "3.0.1" | 21 | const my_version = "4.0.2" |
22 | const ap_version = {"major": 0, "minor": 4, "build": 6, "class": "Version"} | 22 | const ap_version = {"major": 0, "minor": 5, "build": 0, "class": "Version"} |
23 | const color_items = [ | 23 | const color_items = [ |
24 | "White", "Black", "Red", "Blue", "Green", "Brown", "Gray", "Orange", "Purple", "Yellow" | 24 | "White", "Black", "Red", "Blue", "Green", "Brown", "Gray", "Orange", "Purple", "Yellow" |
25 | ] | 25 | ] |
@@ -56,6 +56,7 @@ const kREARRANGE_PANELS = 1 | |||
56 | const kCLASSIFICATION_LOCAL_NORMAL = 1 | 56 | const kCLASSIFICATION_LOCAL_NORMAL = 1 |
57 | const kCLASSIFICATION_LOCAL_REDUCED = 2 | 57 | const kCLASSIFICATION_LOCAL_REDUCED = 2 |
58 | const kCLASSIFICATION_LOCAL_INSANITY = 4 | 58 | const kCLASSIFICATION_LOCAL_INSANITY = 4 |
59 | const kCLASSIFICATION_LOCAL_SMALL_SPHERE_ONE = 8 | ||
59 | 60 | ||
60 | const kCLASSIFICATION_REMOTE_NORMAL = 0 | 61 | const kCLASSIFICATION_REMOTE_NORMAL = 0 |
61 | const kCLASSIFICATION_REMOTE_REDUCED = 1 | 62 | const kCLASSIFICATION_REMOTE_REDUCED = 1 |
@@ -89,6 +90,7 @@ var _team = 0 | |||
89 | var _slot = 0 | 90 | var _slot = 0 |
90 | var _players = [] | 91 | var _players = [] |
91 | var _player_name_by_slot = {} | 92 | var _player_name_by_slot = {} |
93 | var _game_by_player = {} | ||
92 | var _checked_locations = [] | 94 | var _checked_locations = [] |
93 | var _slot_data = {} | 95 | var _slot_data = {} |
94 | var _paintings_mapping = {} | 96 | var _paintings_mapping = {} |
@@ -125,6 +127,7 @@ var _cached_slowness = 0 | |||
125 | var _cached_iceland = 0 | 127 | var _cached_iceland = 0 |
126 | var _cached_atbash = 0 | 128 | var _cached_atbash = 0 |
127 | var _geronimo_skip = false | 129 | var _geronimo_skip = false |
130 | var _checked_paintings = [] | ||
128 | 131 | ||
129 | signal could_not_connect | 132 | signal could_not_connect |
130 | signal connect_status | 133 | signal connect_status |
@@ -142,6 +145,10 @@ func _init(): | |||
142 | var data = file.get_var(true) | 145 | var data = file.get_var(true) |
143 | file.close() | 146 | file.close() |
144 | 147 | ||
148 | if typeof(data) != TYPE_ARRAY: | ||
149 | global._print("AP settings file is corrupted") | ||
150 | data = [] | ||
151 | |||
145 | if data.size() > 0: | 152 | if data.size() > 0: |
146 | ap_server = data[0] | 153 | ap_server = data[0] |
147 | if data.size() > 1: | 154 | if data.size() > 1: |
@@ -266,6 +273,7 @@ func _on_data(): | |||
266 | 273 | ||
267 | for player in _players: | 274 | for player in _players: |
268 | _player_name_by_slot[player["slot"]] = player["alias"] | 275 | _player_name_by_slot[player["slot"]] = player["alias"] |
276 | _game_by_player[player["slot"]] = message["slot_info"][str(player["slot"])]["game"] | ||
269 | 277 | ||
270 | _death_link = _slot_data.has("death_link") and _slot_data["death_link"] | 278 | _death_link = _slot_data.has("death_link") and _slot_data["death_link"] |
271 | if _death_link: | 279 | if _death_link: |
@@ -275,6 +283,7 @@ func _on_data(): | |||
275 | _victory_condition = _slot_data["victory_condition"] | 283 | _victory_condition = _slot_data["victory_condition"] |
276 | if _slot_data.has("shuffle_colors"): | 284 | if _slot_data.has("shuffle_colors"): |
277 | _color_shuffle = _slot_data["shuffle_colors"] | 285 | _color_shuffle = _slot_data["shuffle_colors"] |
286 | |||
278 | if _slot_data.has("shuffle_doors"): | 287 | if _slot_data.has("shuffle_doors"): |
279 | if _slot_data.has("group_doors"): | 288 | if _slot_data.has("group_doors"): |
280 | _door_shuffle = (_slot_data["shuffle_doors"] == 2) | 289 | _door_shuffle = (_slot_data["shuffle_doors"] == 2) |
@@ -282,6 +291,10 @@ func _on_data(): | |||
282 | else: | 291 | else: |
283 | _door_shuffle = (_slot_data["shuffle_doors"] > 0) | 292 | _door_shuffle = (_slot_data["shuffle_doors"] > 0) |
284 | _panel_door_shuffle = false | 293 | _panel_door_shuffle = false |
294 | else: | ||
295 | _door_shuffle = false | ||
296 | _panel_door_shuffle = false | ||
297 | |||
285 | if _slot_data.has("shuffle_paintings"): | 298 | if _slot_data.has("shuffle_paintings"): |
286 | _painting_shuffle = _slot_data["shuffle_paintings"] | 299 | _painting_shuffle = _slot_data["shuffle_paintings"] |
287 | if _slot_data.has("shuffle_panels"): | 300 | if _slot_data.has("shuffle_panels"): |
@@ -298,6 +311,7 @@ func _on_data(): | |||
298 | _mastery_achievements = _slot_data["mastery_achievements"] | 311 | _mastery_achievements = _slot_data["mastery_achievements"] |
299 | if _slot_data.has("level_2_requirement"): | 312 | if _slot_data.has("level_2_requirement"): |
300 | _level_2_requirement = _slot_data["level_2_requirement"] | 313 | _level_2_requirement = _slot_data["level_2_requirement"] |
314 | |||
301 | if _slot_data.has("location_checks"): | 315 | if _slot_data.has("location_checks"): |
302 | if _slot_data["location_checks"] == kCLASSIFICATION_REMOTE_NORMAL: | 316 | if _slot_data["location_checks"] == kCLASSIFICATION_REMOTE_NORMAL: |
303 | _location_classification_bit = kCLASSIFICATION_LOCAL_NORMAL | 317 | _location_classification_bit = kCLASSIFICATION_LOCAL_NORMAL |
@@ -305,8 +319,13 @@ func _on_data(): | |||
305 | _location_classification_bit = kCLASSIFICATION_LOCAL_REDUCED | 319 | _location_classification_bit = kCLASSIFICATION_LOCAL_REDUCED |
306 | elif _slot_data["location_checks"] == kCLASSIFICATION_REMOTE_INSANITY: | 320 | elif _slot_data["location_checks"] == kCLASSIFICATION_REMOTE_INSANITY: |
307 | _location_classification_bit = kCLASSIFICATION_LOCAL_INSANITY | 321 | _location_classification_bit = kCLASSIFICATION_LOCAL_INSANITY |
322 | else: | ||
323 | _location_classification_bit = kCLASSIFICATION_LOCAL_NORMAL | ||
324 | |||
308 | if _slot_data.has("early_color_hallways"): | 325 | if _slot_data.has("early_color_hallways"): |
309 | _early_color_hallways = _slot_data["early_color_hallways"] | 326 | _early_color_hallways = _slot_data["early_color_hallways"] |
327 | else: | ||
328 | _early_color_hallways = false | ||
310 | if _slot_data.has("enable_pilgrimage"): | 329 | if _slot_data.has("enable_pilgrimage"): |
311 | _pilgrimage_enabled = _slot_data["enable_pilgrimage"] | 330 | _pilgrimage_enabled = _slot_data["enable_pilgrimage"] |
312 | else: | 331 | else: |
@@ -327,12 +346,24 @@ func _on_data(): | |||
327 | if _slot_data.has("sunwarp_permutation"): | 346 | if _slot_data.has("sunwarp_permutation"): |
328 | _sunwarp_mapping = _slot_data["sunwarp_permutation"] | 347 | _sunwarp_mapping = _slot_data["sunwarp_permutation"] |
329 | 348 | ||
349 | if ( | ||
350 | _location_classification_bit != kCLASSIFICATION_LOCAL_INSANITY | ||
351 | and _door_shuffle | ||
352 | and not _early_color_hallways | ||
353 | ): | ||
354 | _location_classification_bit += kCLASSIFICATION_LOCAL_SMALL_SPHERE_ONE | ||
355 | |||
330 | if track_player: | 356 | if track_player: |
331 | setValue("PlayerPos", {"x": 0, "z": 0}) | 357 | setValue("PlayerPos", {"x": 0, "z": 0}) |
332 | else: | 358 | else: |
333 | setValue("PlayerPos", null) | 359 | setValue("PlayerPos", null) |
334 | 360 | ||
335 | _puzzle_skips = 0 | 361 | _puzzle_skips = 0 |
362 | _last_new_item = -1 | ||
363 | _cached_slowness = 0 | ||
364 | _cached_iceland = 0 | ||
365 | _cached_atbash = 0 | ||
366 | _geronimo_skip = false | ||
336 | 367 | ||
337 | _localdata_file = "user://archipelago_data/%s_%d" % [_seed, _slot] | 368 | _localdata_file = "user://archipelago_data/%s_%d" % [_seed, _slot] |
338 | var ap_file = File.new() | 369 | var ap_file = File.new() |
@@ -341,36 +372,42 @@ func _on_data(): | |||
341 | var localdata = ap_file.get_var(true) | 372 | var localdata = ap_file.get_var(true) |
342 | ap_file.close() | 373 | ap_file.close() |
343 | 374 | ||
375 | if typeof(localdata) != TYPE_ARRAY: | ||
376 | global._print("AP localdata file is corrupted") | ||
377 | localdata = [] | ||
378 | |||
344 | if localdata.size() > 0: | 379 | if localdata.size() > 0: |
345 | _last_new_item = localdata[0] | 380 | _last_new_item = localdata[0] |
346 | else: | ||
347 | _last_new_item = -1 | ||
348 | 381 | ||
349 | if localdata.size() > 1: | 382 | if localdata.size() > 1: |
350 | _puzzle_skips = localdata[1] | 383 | _puzzle_skips = localdata[1] |
351 | 384 | ||
352 | if localdata.size() > 2: | 385 | if localdata.size() > 2: |
353 | _cached_slowness = localdata[2] | 386 | _cached_slowness = localdata[2] |
354 | else: | ||
355 | _cached_slowness = 0 | ||
356 | 387 | ||
357 | if localdata.size() > 3: | 388 | if localdata.size() > 3: |
358 | _cached_iceland = localdata[3] | 389 | _cached_iceland = localdata[3] |
359 | else: | ||
360 | _cached_iceland = 0 | ||
361 | 390 | ||
362 | if localdata.size() > 4: | 391 | if localdata.size() > 4: |
363 | _cached_atbash = localdata[4] | 392 | _cached_atbash = localdata[4] |
364 | else: | ||
365 | _cached_atbash = 0 | ||
366 | 393 | ||
367 | if localdata.size() > 5: | 394 | if localdata.size() > 5: |
368 | _geronimo_skip = localdata[5] | 395 | _geronimo_skip = localdata[5] |
369 | else: | ||
370 | _geronimo_skip = false | ||
371 | 396 | ||
372 | requestSync() | 397 | requestSync() |
373 | 398 | ||
399 | sendMessage( | ||
400 | [ | ||
401 | { | ||
402 | "cmd": "Set", | ||
403 | "key": "Lingo_%d_Paintings" % [_slot], | ||
404 | "default": [], | ||
405 | "want_reply": true, | ||
406 | "operations": [{"operation": "default", "value": []}] | ||
407 | } | ||
408 | ] | ||
409 | ) | ||
410 | |||
374 | emit_signal("client_connected") | 411 | emit_signal("client_connected") |
375 | 412 | ||
376 | elif cmd == "ConnectionRefused": | 413 | elif cmd == "ConnectionRefused": |
@@ -438,12 +475,14 @@ func _on_data(): | |||
438 | continue | 475 | continue |
439 | 476 | ||
440 | var item_name = "Unknown" | 477 | var item_name = "Unknown" |
441 | if _item_id_to_name.has(message["item"]["item"]): | 478 | var item_player_game = _game_by_player[message["receiving"]] |
442 | item_name = _item_id_to_name[message["item"]["item"]] | 479 | if _item_id_to_name[item_player_game].has(message["item"]["item"]): |
480 | item_name = _item_id_to_name[item_player_game][message["item"]["item"]] | ||
443 | 481 | ||
444 | var location_name = "Unknown" | 482 | var location_name = "Unknown" |
445 | if _location_id_to_name.has(message["item"]["location"]): | 483 | var location_player_game = _game_by_player[message["item"]["player"]] |
446 | location_name = _location_id_to_name[message["item"]["location"]] | 484 | if _location_id_to_name[location_player_game].has(message["item"]["location"]): |
485 | location_name = _location_id_to_name[location_player_game][message["item"]["location"]] | ||
447 | 486 | ||
448 | var player_name = "Unknown" | 487 | var player_name = "Unknown" |
449 | if _player_name_by_slot.has(message["receiving"]): | 488 | if _player_name_by_slot.has(message["receiving"]): |
@@ -486,6 +525,10 @@ func _on_data(): | |||
486 | # Return the player home. | 525 | # Return the player home. |
487 | get_tree().get_root().get_node("Spatial/player/pause_menu")._reload() | 526 | get_tree().get_root().get_node("Spatial/player/pause_menu")._reload() |
488 | 527 | ||
528 | elif cmd == "SetReply": | ||
529 | if message.has("key") and message["key"] == ("Lingo_%d_Paintings" % _slot): | ||
530 | _checked_paintings = message["value"] | ||
531 | |||
489 | 532 | ||
490 | func _process(_delta): | 533 | func _process(_delta): |
491 | if _should_process: | 534 | if _should_process: |
@@ -593,12 +636,16 @@ func requestDatapackages(games): | |||
593 | func processDatapackages(): | 636 | func processDatapackages(): |
594 | _item_id_to_name = {} | 637 | _item_id_to_name = {} |
595 | _location_id_to_name = {} | 638 | _location_id_to_name = {} |
596 | for package in _datapackages.values(): | 639 | for game in _datapackages.keys(): |
640 | var package = _datapackages[game] | ||
641 | |||
642 | _item_id_to_name[game] = {} | ||
597 | for name in package["item_name_to_id"].keys(): | 643 | for name in package["item_name_to_id"].keys(): |
598 | _item_id_to_name[package["item_name_to_id"][name]] = name | 644 | _item_id_to_name[game][package["item_name_to_id"][name]] = name |
599 | 645 | ||
646 | _location_id_to_name[game] = {} | ||
600 | for name in package["location_name_to_id"].keys(): | 647 | for name in package["location_name_to_id"].keys(): |
601 | _location_id_to_name[package["location_name_to_id"][name]] = name | 648 | _location_id_to_name[game][package["location_name_to_id"][name]] = name |
602 | 649 | ||
603 | if _datapackages.has("Lingo"): | 650 | if _datapackages.has("Lingo"): |
604 | _item_name_to_id = _datapackages["Lingo"]["item_name_to_id"] | 651 | _item_name_to_id = _datapackages["Lingo"]["item_name_to_id"] |
@@ -640,13 +687,14 @@ func sendLocation(loc_id): | |||
640 | _held_locations.append(loc_id) | 687 | _held_locations.append(loc_id) |
641 | 688 | ||
642 | 689 | ||
643 | func setValue(key, value): | 690 | func setValue(key, value, operation = "replace"): |
644 | sendMessage( | 691 | sendMessage( |
645 | [ | 692 | [ |
646 | { | 693 | { |
647 | "cmd": "Set", | 694 | "cmd": "Set", |
648 | "key": "Lingo_%d_%s" % [_slot, key], | 695 | "key": "Lingo_%d_%s" % [_slot, key], |
649 | "operations": [{"operation": "replace", "value": value}] | 696 | "want_reply": false, |
697 | "operations": [{"operation": operation, "value": value}] | ||
650 | } | 698 | } |
651 | ] | 699 | ] |
652 | ) | 700 | ) |
@@ -687,8 +735,8 @@ func processItem(item, index, from, flags): | |||
687 | 735 | ||
688 | var gamedata = $Gamedata | 736 | var gamedata = $Gamedata |
689 | var item_name = "Unknown" | 737 | var item_name = "Unknown" |
690 | if _item_id_to_name.has(item): | 738 | if _item_id_to_name["Lingo"].has(item): |
691 | item_name = _item_id_to_name[item] | 739 | item_name = _item_id_to_name["Lingo"][item] |
692 | 740 | ||
693 | if gamedata.door_ids_by_item_id.has(int(item)): | 741 | if gamedata.door_ids_by_item_id.has(int(item)): |
694 | var doorsNode = get_tree().get_root().get_node("Spatial/Doors") | 742 | var doorsNode = get_tree().get_root().get_node("Spatial/Doors") |
@@ -751,8 +799,8 @@ func processItem(item, index, from, flags): | |||
751 | item_name += " (%s)" % prognames[item_name][_progressive_progress[int(item)]] | 799 | item_name += " (%s)" % prognames[item_name][_progressive_progress[int(item)]] |
752 | _progressive_progress[int(item)] += 1 | 800 | _progressive_progress[int(item)] += 1 |
753 | 801 | ||
754 | if _color_shuffle and color_items.has(_item_id_to_name[item]): | 802 | if _color_shuffle and color_items.has(_item_id_to_name["Lingo"][item]): |
755 | var lcol = _item_id_to_name[item].to_lower() | 803 | var lcol = _item_id_to_name["Lingo"][item].to_lower() |
756 | if not _has_colors.has(lcol): | 804 | if not _has_colors.has(lcol): |
757 | _has_colors.append(lcol) | 805 | _has_colors.append(lcol) |
758 | emit_signal("evaluate_solvability") | 806 | emit_signal("evaluate_solvability") |
@@ -823,6 +871,15 @@ func geronimo(): | |||
823 | saveLocaldata() | 871 | saveLocaldata() |
824 | 872 | ||
825 | 873 | ||
874 | func checkPainting(painting_id): | ||
875 | if _checked_paintings.has(painting_id): | ||
876 | return | ||
877 | |||
878 | _checked_paintings.append(painting_id) | ||
879 | |||
880 | setValue("Paintings", [painting_id], "add") | ||
881 | |||
882 | |||
826 | func colorForItemType(flags): | 883 | func colorForItemType(flags): |
827 | var int_flags = int(flags) | 884 | var int_flags = int(flags) |
828 | if int_flags & 1: # progression | 885 | if int_flags & 1: # progression |