diff options
Diffstat (limited to 'Archipelago/client.gd')
-rw-r--r-- | Archipelago/client.gd | 171 |
1 files changed, 154 insertions, 17 deletions
diff --git a/Archipelago/client.gd b/Archipelago/client.gd index 78058ca..390b14d 100644 --- a/Archipelago/client.gd +++ b/Archipelago/client.gd | |||
@@ -9,6 +9,7 @@ var SCRIPT_mypainting | |||
9 | var SCRIPT_notifier | 9 | var SCRIPT_notifier |
10 | var SCRIPT_panel | 10 | var SCRIPT_panel |
11 | var SCRIPT_pilgrimage_terminator | 11 | var SCRIPT_pilgrimage_terminator |
12 | var SCRIPT_textclient | ||
12 | var SCRIPT_uuid | 13 | var SCRIPT_uuid |
13 | 14 | ||
14 | var ap_server = "" | 15 | var ap_server = "" |
@@ -19,12 +20,12 @@ var enable_multiplayer = false | |||
19 | var track_player = false | 20 | var track_player = false |
20 | var connection_history = [] | 21 | var connection_history = [] |
21 | 22 | ||
22 | const my_version = "4.0.2" | 23 | const my_version = "5.0.1" |
23 | const ap_version = {"major": 0, "minor": 5, "build": 0, "class": "Version"} | 24 | const ap_version = {"major": 0, "minor": 5, "build": 1, "class": "Version"} |
24 | const color_items = [ | 25 | const color_items = [ |
25 | "White", "Black", "Red", "Blue", "Green", "Brown", "Gray", "Orange", "Purple", "Yellow" | 26 | "White", "Black", "Red", "Blue", "Green", "Brown", "Gray", "Orange", "Purple", "Yellow" |
26 | ] | 27 | ] |
27 | const progressive_items = { | 28 | const door_progressive_items = { |
28 | "Progressive Orange Tower": | 29 | "Progressive Orange Tower": |
29 | ["Second Floor", "Third Floor", "Fourth Floor", "Fifth Floor", "Sixth Floor", "Seventh Floor"], | 30 | ["Second Floor", "Third Floor", "Fourth Floor", "Fifth Floor", "Sixth Floor", "Seventh Floor"], |
30 | "Progressive Art Gallery": | 31 | "Progressive Art Gallery": |
@@ -36,6 +37,15 @@ const progressive_items = { | |||
36 | "Progressive Pilgrimage": | 37 | "Progressive Pilgrimage": |
37 | ["1 Sunwarp", "2 Sunwarp", "3 Sunwarp", "4 Sunwarp", "5 Sunwarp", "6 Sunwarp"] | 38 | ["1 Sunwarp", "2 Sunwarp", "3 Sunwarp", "4 Sunwarp", "5 Sunwarp", "6 Sunwarp"] |
38 | } | 39 | } |
40 | const panel_progressive_items = { | ||
41 | "Progressive Hallway Room": ["First Door", "Second Door", "Third Door", "Fourth Door"], | ||
42 | "Progressive Colorful": | ||
43 | ["White", "Black", "Red", "Yellow", "Blue", "Purple", "Orange", "Green", "Brown", "Gray"], | ||
44 | "Progressive Number Hunt": | ||
45 | ["Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Zero"], | ||
46 | "Progressive Symmetry Room": ["Near Far", "Warts Straw", "Leaf Feel"], | ||
47 | "Progressive Suits Area": ["Words Sword", "Lost", "Amen Name"] | ||
48 | } | ||
39 | 49 | ||
40 | const kTHE_END = 0 | 50 | const kTHE_END = 0 |
41 | const kTHE_MASTER = 1 | 51 | const kTHE_MASTER = 1 |
@@ -91,6 +101,7 @@ var _localdata_file = "" | |||
91 | var _death_link = false | 101 | var _death_link = false |
92 | var _victory_condition = 0 # THE END, THE MASTER, LEVEL 2 | 102 | var _victory_condition = 0 # THE END, THE MASTER, LEVEL 2 |
93 | var _door_shuffle = false | 103 | var _door_shuffle = false |
104 | var _panel_door_shuffle = false | ||
94 | var _color_shuffle = false | 105 | var _color_shuffle = false |
95 | var _panel_shuffle = 0 # none, rearrange | 106 | var _panel_shuffle = 0 # none, rearrange |
96 | var _painting_shuffle = false | 107 | var _painting_shuffle = false |
@@ -105,6 +116,7 @@ var _pilgrimage_allows_roof_access = false | |||
105 | var _pilgrimage_allows_paintings = false | 116 | var _pilgrimage_allows_paintings = false |
106 | var _sunwarp_shuffle = false | 117 | var _sunwarp_shuffle = false |
107 | var _sunwarp_mapping = [] | 118 | var _sunwarp_mapping = [] |
119 | var _speed_boost_mode = false | ||
108 | var _slot_seed = 0 | 120 | var _slot_seed = 0 |
109 | 121 | ||
110 | var _map_loaded = false | 122 | var _map_loaded = false |
@@ -118,8 +130,11 @@ var _puzzle_skips = 0 | |||
118 | var _cached_slowness = 0 | 130 | var _cached_slowness = 0 |
119 | var _cached_iceland = 0 | 131 | var _cached_iceland = 0 |
120 | var _cached_atbash = 0 | 132 | var _cached_atbash = 0 |
133 | var _cached_speed_boosts = 0 | ||
121 | var _geronimo_skip = false | 134 | var _geronimo_skip = false |
122 | var _checked_paintings = [] | 135 | var _checked_paintings = [] |
136 | var _hints_key = "" | ||
137 | var _hinted_locations = [] | ||
123 | 138 | ||
124 | signal could_not_connect | 139 | signal could_not_connect |
125 | signal connect_status | 140 | signal connect_status |
@@ -277,9 +292,15 @@ func _on_data(): | |||
277 | _color_shuffle = _slot_data["shuffle_colors"] | 292 | _color_shuffle = _slot_data["shuffle_colors"] |
278 | 293 | ||
279 | if _slot_data.has("shuffle_doors"): | 294 | if _slot_data.has("shuffle_doors"): |
280 | _door_shuffle = (_slot_data["shuffle_doors"] > 0) | 295 | if _slot_data.has("group_doors"): |
296 | _door_shuffle = (_slot_data["shuffle_doors"] == 2) | ||
297 | _panel_door_shuffle = (_slot_data["shuffle_doors"] == 1) | ||
298 | else: | ||
299 | _door_shuffle = (_slot_data["shuffle_doors"] > 0) | ||
300 | _panel_door_shuffle = false | ||
281 | else: | 301 | else: |
282 | _door_shuffle = false | 302 | _door_shuffle = false |
303 | _panel_door_shuffle = false | ||
283 | 304 | ||
284 | if _slot_data.has("shuffle_paintings"): | 305 | if _slot_data.has("shuffle_paintings"): |
285 | _painting_shuffle = _slot_data["shuffle_paintings"] | 306 | _painting_shuffle = _slot_data["shuffle_paintings"] |
@@ -331,6 +352,10 @@ func _on_data(): | |||
331 | _sunwarp_shuffle = false | 352 | _sunwarp_shuffle = false |
332 | if _slot_data.has("sunwarp_permutation"): | 353 | if _slot_data.has("sunwarp_permutation"): |
333 | _sunwarp_mapping = _slot_data["sunwarp_permutation"] | 354 | _sunwarp_mapping = _slot_data["sunwarp_permutation"] |
355 | if _slot_data.has("speed_boost_mode"): | ||
356 | _speed_boost_mode = _slot_data["speed_boost_mode"] | ||
357 | else: | ||
358 | _speed_boost_mode = false | ||
334 | 359 | ||
335 | if ( | 360 | if ( |
336 | _location_classification_bit != kCLASSIFICATION_LOCAL_INSANITY | 361 | _location_classification_bit != kCLASSIFICATION_LOCAL_INSANITY |
@@ -349,6 +374,7 @@ func _on_data(): | |||
349 | _cached_slowness = 0 | 374 | _cached_slowness = 0 |
350 | _cached_iceland = 0 | 375 | _cached_iceland = 0 |
351 | _cached_atbash = 0 | 376 | _cached_atbash = 0 |
377 | _cached_speed_boosts = 0 | ||
352 | _geronimo_skip = false | 378 | _geronimo_skip = false |
353 | 379 | ||
354 | _localdata_file = "user://archipelago_data/%s_%d" % [_seed, _slot] | 380 | _localdata_file = "user://archipelago_data/%s_%d" % [_seed, _slot] |
@@ -380,6 +406,9 @@ func _on_data(): | |||
380 | if localdata.size() > 5: | 406 | if localdata.size() > 5: |
381 | _geronimo_skip = localdata[5] | 407 | _geronimo_skip = localdata[5] |
382 | 408 | ||
409 | if localdata.size() > 6: | ||
410 | _cached_speed_boosts = localdata[6] | ||
411 | |||
383 | requestSync() | 412 | requestSync() |
384 | 413 | ||
385 | sendMessage( | 414 | sendMessage( |
@@ -394,6 +423,11 @@ func _on_data(): | |||
394 | ] | 423 | ] |
395 | ) | 424 | ) |
396 | 425 | ||
426 | _hints_key = "_read_hints_%d_%d" % [_team, _slot] | ||
427 | sendMessage( | ||
428 | [{"cmd": "SetNotify", "keys": [_hints_key]}, {"cmd": "Get", "keys": [_hints_key]}] | ||
429 | ) | ||
430 | |||
397 | emit_signal("client_connected") | 431 | emit_signal("client_connected") |
398 | 432 | ||
399 | elif cmd == "ConnectionRefused": | 433 | elif cmd == "ConnectionRefused": |
@@ -453,6 +487,8 @@ func _on_data(): | |||
453 | i += 1 | 487 | i += 1 |
454 | 488 | ||
455 | elif cmd == "PrintJSON": | 489 | elif cmd == "PrintJSON": |
490 | parse_printjson(message) | ||
491 | |||
456 | if ( | 492 | if ( |
457 | !message.has("receiving") | 493 | !message.has("receiving") |
458 | or !message.has("item") | 494 | or !message.has("item") |
@@ -489,9 +525,12 @@ func _on_data(): | |||
489 | ) | 525 | ) |
490 | else: | 526 | else: |
491 | if message["receiving"] != _slot: | 527 | if message["receiving"] != _slot: |
492 | messages.showMessage( | 528 | var sentMsg = ( |
493 | "Sent [color=%s]%s[/color] to %s" % [item_color, item_name, player_name] | 529 | "Sent [color=%s]%s[/color] to %s" % [item_color, item_name, player_name] |
494 | ) | 530 | ) |
531 | if _hinted_locations.has(message["item"]["location"]): | ||
532 | sentMsg += " ([color=#fafad2]Hinted![/color])" | ||
533 | messages.showMessage(sentMsg) | ||
495 | 534 | ||
496 | elif cmd == "Bounced": | 535 | elif cmd == "Bounced": |
497 | if ( | 536 | if ( |
@@ -512,8 +551,15 @@ func _on_data(): | |||
512 | get_tree().get_root().get_node("Spatial/player/pause_menu")._reload() | 551 | get_tree().get_root().get_node("Spatial/player/pause_menu")._reload() |
513 | 552 | ||
514 | elif cmd == "SetReply": | 553 | elif cmd == "SetReply": |
515 | if message.has("key") and message["key"] == ("Lingo_%d_Paintings" % _slot): | 554 | if message.has("key"): |
516 | _checked_paintings = message["value"] | 555 | if message["key"] == ("Lingo_%d_Paintings" % _slot): |
556 | _checked_paintings = message["value"] | ||
557 | elif message["key"] == _hints_key: | ||
558 | parseHints(message["value"]) | ||
559 | |||
560 | elif cmd == "Retrieved": | ||
561 | if message.has("keys") and message["keys"].has(_hints_key): | ||
562 | parseHints(message["keys"][_hints_key]) | ||
517 | 563 | ||
518 | 564 | ||
519 | func _process(_delta): | 565 | func _process(_delta): |
@@ -567,7 +613,8 @@ func saveLocaldata(): | |||
567 | effects_node.slowness_remaining, | 613 | effects_node.slowness_remaining, |
568 | effects_node.iceland_remaining, | 614 | effects_node.iceland_remaining, |
569 | effects_node.atbash_remaining, | 615 | effects_node.atbash_remaining, |
570 | _geronimo_skip | 616 | _geronimo_skip, |
617 | effects_node.speed_boosts_remaining, | ||
571 | ] | 618 | ] |
572 | file.store_var(data, true) | 619 | file.store_var(data, true) |
573 | file.close() | 620 | file.close() |
@@ -686,6 +733,10 @@ func setValue(key, value, operation = "replace"): | |||
686 | ) | 733 | ) |
687 | 734 | ||
688 | 735 | ||
736 | func say(textdata): | ||
737 | sendMessage([{"cmd": "Say", "text": textdata}]) | ||
738 | |||
739 | |||
689 | func completedGoal(): | 740 | func completedGoal(): |
690 | sendMessage([{"cmd": "StatusUpdate", "status": 30}]) # CLIENT_GOAL | 741 | sendMessage([{"cmd": "StatusUpdate", "status": 30}]) # CLIENT_GOAL |
691 | 742 | ||
@@ -729,6 +780,18 @@ func processItem(item, index, from, flags): | |||
729 | for door_id in gamedata.door_ids_by_item_id[int(item)]: | 780 | for door_id in gamedata.door_ids_by_item_id[int(item)]: |
730 | doorsNode.get_node(door_id).openDoor() | 781 | doorsNode.get_node(door_id).openDoor() |
731 | 782 | ||
783 | if gamedata.panel_ids_by_item_id.has(int(item)): | ||
784 | var panel_ids = gamedata.panel_ids_by_item_id[int(item)] | ||
785 | if wasGeneratedOnVersion(0, 5, 1): | ||
786 | var extradata = get_node("Extradata") | ||
787 | if extradata.panels_mode_051_panel_fixes.has(int(item)): | ||
788 | panel_ids = extradata.panels_mode_051_panel_fixes[int(item)] | ||
789 | |||
790 | var panelsNode = get_tree().get_root().get_node("Spatial/Panels") | ||
791 | for panel_id in panel_ids: | ||
792 | panelsNode.get_node(panel_id).get_node("AP_Panel").locked = false | ||
793 | emit_signal("evaluate_solvability") | ||
794 | |||
732 | if gamedata.painting_ids_by_item_id.has(int(item)): | 795 | if gamedata.painting_ids_by_item_id.has(int(item)): |
733 | var real_parent_node = get_tree().get_root().get_node("Spatial/Decorations/Paintings") | 796 | var real_parent_node = get_tree().get_root().get_node("Spatial/Decorations/Paintings") |
734 | var fake_parent_node = get_tree().get_root().get_node_or_null("Spatial/AP_Paintings") | 797 | var fake_parent_node = get_tree().get_root().get_node_or_null("Spatial/AP_Paintings") |
@@ -749,15 +812,34 @@ func processItem(item, index, from, flags): | |||
749 | warpsNode.get_node(warp_id).unlock_warp() | 812 | warpsNode.get_node(warp_id).unlock_warp() |
750 | 813 | ||
751 | # Handle progressive items. | 814 | # Handle progressive items. |
752 | if int(item) in gamedata.items_by_progressive_id.keys(): | 815 | var is_progressive_door = int(item) in gamedata.door_items_by_progressive_id |
816 | var is_progressive_panel = int(item) in gamedata.panel_items_by_progressive_id | ||
817 | var progitems = null | ||
818 | var prognames = null | ||
819 | |||
820 | if is_progressive_door and is_progressive_panel: | ||
821 | if _door_shuffle: | ||
822 | progitems = gamedata.door_items_by_progressive_id[int(item)] | ||
823 | prognames = door_progressive_items | ||
824 | else: | ||
825 | progitems = gamedata.panel_items_by_progressive_id[int(item)] | ||
826 | prognames = panel_progressive_items | ||
827 | elif is_progressive_door: | ||
828 | progitems = gamedata.door_items_by_progressive_id[int(item)] | ||
829 | prognames = door_progressive_items | ||
830 | elif is_progressive_panel: | ||
831 | progitems = gamedata.panel_items_by_progressive_id[int(item)] | ||
832 | prognames = panel_progressive_items | ||
833 | |||
834 | if progitems != null: | ||
753 | if not int(item) in _progressive_progress: | 835 | if not int(item) in _progressive_progress: |
754 | _progressive_progress[int(item)] = 0 | 836 | _progressive_progress[int(item)] = 0 |
755 | 837 | ||
756 | if _progressive_progress[int(item)] < gamedata.items_by_progressive_id[int(item)].size(): | 838 | if _progressive_progress[int(item)] < progitems.size(): |
757 | var subitems = gamedata.items_by_progressive_id[int(item)] | 839 | var subitem_id = progitems[_progressive_progress[int(item)]] |
758 | var subitem_id = subitems[_progressive_progress[int(item)]] | ||
759 | global._print("Subitem: %d" % subitem_id) | 840 | global._print("Subitem: %d" % subitem_id) |
760 | processItem(subitem_id, null, null, null) | 841 | processItem(subitem_id, null, null, null) |
842 | item_name += " (%s)" % prognames[item_name][_progressive_progress[int(item)]] | ||
761 | _progressive_progress[int(item)] += 1 | 843 | _progressive_progress[int(item)] += 1 |
762 | 844 | ||
763 | if _color_shuffle and color_items.has(_item_id_to_name["Lingo"][item]): | 845 | if _color_shuffle and color_items.has(_item_id_to_name["Lingo"][item]): |
@@ -771,10 +853,6 @@ func processItem(item, index, from, flags): | |||
771 | _last_new_item = index | 853 | _last_new_item = index |
772 | saveLocaldata() | 854 | saveLocaldata() |
773 | 855 | ||
774 | if item_name in progressive_items: | ||
775 | var subitem = progressive_items[item_name][_progressive_progress[int(item)] - 1] | ||
776 | item_name += " (%s)" % subitem | ||
777 | |||
778 | var player_name = "Unknown" | 856 | var player_name = "Unknown" |
779 | if _player_name_by_slot.has(from): | 857 | if _player_name_by_slot.has(from): |
780 | player_name = _player_name_by_slot[from] | 858 | player_name = _player_name_by_slot[from] |
@@ -789,12 +867,14 @@ func processItem(item, index, from, flags): | |||
789 | ) | 867 | ) |
790 | 868 | ||
791 | var effects_node = get_tree().get_root().get_node("Spatial/AP_Effects") | 869 | var effects_node = get_tree().get_root().get_node("Spatial/AP_Effects") |
792 | if item_name == "Slowness Trap": | 870 | if item_name == "Slowness Trap" and !_speed_boost_mode: |
793 | effects_node.trigger_slowness_trap() | 871 | effects_node.trigger_slowness_trap() |
794 | if item_name == "Iceland Trap": | 872 | if item_name == "Iceland Trap": |
795 | effects_node.trigger_iceland_trap() | 873 | effects_node.trigger_iceland_trap() |
796 | if item_name == "Atbash Trap": | 874 | if item_name == "Atbash Trap": |
797 | effects_node.trigger_atbash_trap() | 875 | effects_node.trigger_atbash_trap() |
876 | if item_name == "Speed Boost" and _speed_boost_mode: | ||
877 | effects_node.trigger_speed_boost() | ||
798 | if item_name == "Puzzle Skip": | 878 | if item_name == "Puzzle Skip": |
799 | _puzzle_skips += 1 | 879 | _puzzle_skips += 1 |
800 | 880 | ||
@@ -845,6 +925,14 @@ func checkPainting(painting_id): | |||
845 | setValue("Paintings", [painting_id], "add") | 925 | setValue("Paintings", [painting_id], "add") |
846 | 926 | ||
847 | 927 | ||
928 | func parseHints(hints): | ||
929 | _hinted_locations.clear() | ||
930 | |||
931 | for hint in hints: | ||
932 | if hint["finding_player"] == int(_slot): | ||
933 | _hinted_locations.append(hint["location"]) | ||
934 | |||
935 | |||
848 | func colorForItemType(flags): | 936 | func colorForItemType(flags): |
849 | var int_flags = int(flags) | 937 | var int_flags = int(flags) |
850 | if int_flags & 1: # progression | 938 | if int_flags & 1: # progression |
@@ -857,6 +945,47 @@ func colorForItemType(flags): | |||
857 | return "#14de9e" | 945 | return "#14de9e" |
858 | 946 | ||
859 | 947 | ||
948 | func parse_printjson(message): | ||
949 | var parts = [] | ||
950 | for message_part in message["data"]: | ||
951 | if !message_part.has("type") and message_part.has("text"): | ||
952 | parts.append(message_part["text"]) | ||
953 | elif message_part["type"] == "player_id": | ||
954 | if int(message_part["text"]) == _slot: | ||
955 | parts.append("[color=#ee00ee]%s[/color]" % _player_name_by_slot[_slot]) | ||
956 | else: | ||
957 | var from = float(message_part["text"]) | ||
958 | parts.append("[color=#fafad2]%s[/color]" % _player_name_by_slot[from]) | ||
959 | elif message_part["type"] == "item_id": | ||
960 | var item_name = "Unknown" | ||
961 | var item_player_game = _game_by_player[message_part["player"]] | ||
962 | if _item_id_to_name[item_player_game].has(float(message_part["text"])): | ||
963 | item_name = _item_id_to_name[item_player_game][float(message_part["text"])] | ||
964 | |||
965 | parts.append( | ||
966 | "[color=%s]%s[/color]" % [colorForItemType(message_part["flags"]), item_name] | ||
967 | ) | ||
968 | elif message_part["type"] == "location_id": | ||
969 | var location_name = "Unknown" | ||
970 | var location_player_game = _game_by_player[message_part["player"]] | ||
971 | if _location_id_to_name[location_player_game].has(float(message_part["text"])): | ||
972 | location_name = _location_id_to_name[location_player_game][float( | ||
973 | message_part["text"] | ||
974 | )] | ||
975 | |||
976 | parts.append("[color=#00ff7f]%s[/color]" % location_name) | ||
977 | elif message_part.has("text"): | ||
978 | parts.append(message_part["text"]) | ||
979 | |||
980 | var textclient_node = get_tree().get_root().get_node_or_null("Spatial/AP_TextClient") | ||
981 | if textclient_node != null: | ||
982 | textclient_node.parse_printjson("".join(parts)) | ||
983 | |||
984 | |||
985 | func get_player_name(): | ||
986 | return _player_name_by_slot[_slot] | ||
987 | |||
988 | |||
860 | func compareVersion(lhs, rhs): | 989 | func compareVersion(lhs, rhs): |
861 | if lhs["major"] == rhs["major"]: | 990 | if lhs["major"] == rhs["major"]: |
862 | if lhs["minor"] == rhs["minor"]: | 991 | if lhs["minor"] == rhs["minor"]: |
@@ -869,3 +998,11 @@ func compareVersion(lhs, rhs): | |||
869 | 998 | ||
870 | func wasGeneratedBeforeVersion(major, minor, build): | 999 | func wasGeneratedBeforeVersion(major, minor, build): |
871 | return compareVersion(_gen_version, {"major": major, "minor": minor, "build": build}) | 1000 | return compareVersion(_gen_version, {"major": major, "minor": minor, "build": build}) |
1001 | |||
1002 | |||
1003 | func wasGeneratedOnVersion(major, minor, build): | ||
1004 | return ( | ||
1005 | _gen_version["major"] == major | ||
1006 | and _gen_version["minor"] == minor | ||
1007 | and _gen_version["build"] == build | ||
1008 | ) | ||