diff options
| author | Star Rauchenberger <fefferburbia@gmail.com> | 2024-12-09 12:50:37 -0500 |
|---|---|---|
| committer | Star Rauchenberger <fefferburbia@gmail.com> | 2024-12-09 12:50:37 -0500 |
| commit | 880e4b5069c4dfbf1ed532fc117697cde83b5566 (patch) | |
| tree | 233bcbd82ff1ea8b2237232d430c665168ba009f /Archipelago | |
| parent | f834267a75c873d143e1f7f56f73faaa5e15cf2f (diff) | |
| parent | 45fa76505dd00bdd6665bae476277371fb1252a2 (diff) | |
| download | lingo-archipelago-880e4b5069c4dfbf1ed532fc117697cde83b5566.tar.gz lingo-archipelago-880e4b5069c4dfbf1ed532fc117697cde83b5566.tar.bz2 lingo-archipelago-880e4b5069c4dfbf1ed532fc117697cde83b5566.zip | |
Merge branch 'main' into experimental-panels
Diffstat (limited to 'Archipelago')
| -rw-r--r-- | Archipelago/client.gd | 171 | ||||
| -rw-r--r-- | Archipelago/effects.gd | 66 | ||||
| -rw-r--r-- | Archipelago/extradata.gd | 84 | ||||
| -rw-r--r-- | Archipelago/load.gd | 23 | ||||
| -rw-r--r-- | Archipelago/multiplayer.gd | 55 | ||||
| -rw-r--r-- | Archipelago/panel.gd | 11 | ||||
| -rw-r--r-- | Archipelago/pause_menu.gd | 5 | ||||
| -rw-r--r-- | Archipelago/settings_screen.gd | 1 | ||||
| -rw-r--r-- | Archipelago/textclient.gd | 100 |
9 files changed, 489 insertions, 27 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 | ) | ||
| diff --git a/Archipelago/effects.gd b/Archipelago/effects.gd index 1e2e311..341a783 100644 --- a/Archipelago/effects.gd +++ b/Archipelago/effects.gd | |||
| @@ -5,6 +5,7 @@ var effect_running = false | |||
| 5 | var slowness_remaining = 0 | 5 | var slowness_remaining = 0 |
| 6 | var iceland_remaining = 0 | 6 | var iceland_remaining = 0 |
| 7 | var atbash_remaining = 0 | 7 | var atbash_remaining = 0 |
| 8 | var speed_boosts_remaining = 0 | ||
| 8 | var queued_iceland = 0 | 9 | var queued_iceland = 0 |
| 9 | var skip_available = false | 10 | var skip_available = false |
| 10 | var puzzle_focused = false | 11 | var puzzle_focused = false |
| @@ -48,6 +49,12 @@ func _ready(): | |||
| 48 | add_child(slowness_timer) | 49 | add_child(slowness_timer) |
| 49 | slowness_timer.connect("timeout", self, "_tick_slowness") | 50 | slowness_timer.connect("timeout", self, "_tick_slowness") |
| 50 | 51 | ||
| 52 | var speed_boost_timer = Timer.new() | ||
| 53 | speed_boost_timer.name = "SpeedBoostTimer" | ||
| 54 | speed_boost_timer.wait_time = 1.0 | ||
| 55 | add_child(speed_boost_timer) | ||
| 56 | speed_boost_timer.connect("timeout", self, "_tick_speed_boost") | ||
| 57 | |||
| 51 | var iceland_timer = Timer.new() | 58 | var iceland_timer = Timer.new() |
| 52 | iceland_timer.name = "IcelandTimer" | 59 | iceland_timer.name = "IcelandTimer" |
| 53 | iceland_timer.wait_time = 1.0 | 60 | iceland_timer.wait_time = 1.0 |
| @@ -63,6 +70,12 @@ func activate(): | |||
| 63 | 70 | ||
| 64 | queued_iceland = 0 | 71 | queued_iceland = 0 |
| 65 | 72 | ||
| 73 | var apclient = global.get_node("Archipelago") | ||
| 74 | if apclient._speed_boost_mode: | ||
| 75 | var player = get_tree().get_root().get_node("Spatial/player") | ||
| 76 | player.walk_speed = orig_walk / 2.0 | ||
| 77 | player.run_speed = orig_run / 2.0 | ||
| 78 | |||
| 66 | 79 | ||
| 67 | func trigger_slowness_trap(length = 30): | 80 | func trigger_slowness_trap(length = 30): |
| 68 | if slowness_remaining == 0: | 81 | if slowness_remaining == 0: |
| @@ -79,6 +92,21 @@ func trigger_slowness_trap(length = 30): | |||
| 79 | apclient.saveLocaldata() | 92 | apclient.saveLocaldata() |
| 80 | 93 | ||
| 81 | 94 | ||
| 95 | func trigger_speed_boost(length = 20): | ||
| 96 | if speed_boosts_remaining == 0: | ||
| 97 | var player = get_tree().get_root().get_node("Spatial/player") | ||
| 98 | player.walk_speed = orig_walk | ||
| 99 | player.run_speed = orig_run | ||
| 100 | |||
| 101 | $SpeedBoostTimer.start() | ||
| 102 | |||
| 103 | speed_boosts_remaining += length | ||
| 104 | text_dirty = true | ||
| 105 | |||
| 106 | var apclient = global.get_node("Archipelago") | ||
| 107 | apclient.saveLocaldata() | ||
| 108 | |||
| 109 | |||
| 82 | func trigger_iceland_trap(length = 60): | 110 | func trigger_iceland_trap(length = 60): |
| 83 | if not activated: | 111 | if not activated: |
| 84 | queued_iceland += length | 112 | queued_iceland += length |
| @@ -99,7 +127,7 @@ func trigger_iceland_trap(length = 60): | |||
| 99 | 127 | ||
| 100 | 128 | ||
| 101 | func trigger_atbash_trap(): | 129 | func trigger_atbash_trap(): |
| 102 | var newly_atbash = (atbash_remaining == 0) | 130 | var newly_atbash = atbash_remaining == 0 |
| 103 | atbash_remaining += 1 | 131 | atbash_remaining += 1 |
| 104 | 132 | ||
| 105 | if newly_atbash: | 133 | if newly_atbash: |
| @@ -121,7 +149,7 @@ func deactivate_atbash_trap(): | |||
| 121 | apclient.evaluateSolvability() | 149 | apclient.evaluateSolvability() |
| 122 | 150 | ||
| 123 | text_dirty = true | 151 | text_dirty = true |
| 124 | 152 | ||
| 125 | var apclient = global.get_node("Archipelago") | 153 | var apclient = global.get_node("Archipelago") |
| 126 | apclient.saveLocaldata() | 154 | apclient.saveLocaldata() |
| 127 | 155 | ||
| @@ -192,23 +220,37 @@ func _tick_slowness(): | |||
| 192 | player.run_speed = orig_run | 220 | player.run_speed = orig_run |
| 193 | 221 | ||
| 194 | $SlownessTimer.stop() | 222 | $SlownessTimer.stop() |
| 195 | 223 | ||
| 196 | if slowness_remaining % 5 == 0: | 224 | if slowness_remaining % 5 == 0: |
| 197 | var apclient = global.get_node("Archipelago") | 225 | var apclient = global.get_node("Archipelago") |
| 198 | apclient.saveLocaldata() | 226 | apclient.saveLocaldata() |
| 199 | 227 | ||
| 200 | 228 | ||
| 229 | func _tick_speed_boost(): | ||
| 230 | speed_boosts_remaining -= 1 | ||
| 231 | text_dirty = true | ||
| 232 | |||
| 233 | if speed_boosts_remaining == 0: | ||
| 234 | var player = get_tree().get_root().get_node("Spatial/player") | ||
| 235 | player.walk_speed = orig_walk / 2.0 | ||
| 236 | player.run_speed = orig_run / 2.0 | ||
| 237 | |||
| 238 | $SpeedBoostTimer.stop() | ||
| 239 | |||
| 240 | if speed_boosts_remaining % 5 == 0: | ||
| 241 | var apclient = global.get_node("Archipelago") | ||
| 242 | apclient.saveLocaldata() | ||
| 243 | |||
| 244 | |||
| 201 | func _tick_iceland(): | 245 | func _tick_iceland(): |
| 202 | iceland_remaining -= 1 | 246 | iceland_remaining -= 1 |
| 203 | text_dirty = true | 247 | text_dirty = true |
| 204 | 248 | ||
| 205 | if iceland_remaining == 0: | 249 | if iceland_remaining == 0: |
| 206 | get_tree().get_root().get_node("Spatial/player/pivot/camera").set_environment( | 250 | get_tree().get_root().get_node("Spatial/player/pivot/camera").set_environment(orig_env) |
| 207 | orig_env | ||
| 208 | ) | ||
| 209 | 251 | ||
| 210 | $IcelandTimer.stop() | 252 | $IcelandTimer.stop() |
| 211 | 253 | ||
| 212 | if iceland_remaining % 5 == 0: | 254 | if iceland_remaining % 5 == 0: |
| 213 | var apclient = global.get_node("Archipelago") | 255 | var apclient = global.get_node("Archipelago") |
| 214 | apclient.saveLocaldata() | 256 | apclient.saveLocaldata() |
| @@ -220,9 +262,11 @@ func _process(_delta): | |||
| 220 | if wallcast.is_colliding(): | 262 | if wallcast.is_colliding(): |
| 221 | var player = get_tree().get_root().get_node("Spatial/player") | 263 | var player = get_tree().get_root().get_node("Spatial/player") |
| 222 | var puzzlecast = player.get_node("pivot/camera/RayCast_sight") | 264 | var puzzlecast = player.get_node("pivot/camera/RayCast_sight") |
| 223 | var distance = puzzlecast.get_collision_point().distance_to(wallcast.get_collision_point()) | 265 | var distance = puzzlecast.get_collision_point().distance_to( |
| 266 | wallcast.get_collision_point() | ||
| 267 | ) | ||
| 224 | should_nbw = (distance < 0.05) | 268 | should_nbw = (distance < 0.05) |
| 225 | 269 | ||
| 226 | if should_nbw != not_behind_wall: | 270 | if should_nbw != not_behind_wall: |
| 227 | not_behind_wall = should_nbw | 271 | not_behind_wall = should_nbw |
| 228 | text_dirty = true | 272 | text_dirty = true |
| @@ -239,6 +283,10 @@ func _process(_delta): | |||
| 239 | if not text.empty(): | 283 | if not text.empty(): |
| 240 | text += "\n" | 284 | text += "\n" |
| 241 | text += "Slowness: %d seconds" % slowness_remaining | 285 | text += "Slowness: %d seconds" % slowness_remaining |
| 286 | if speed_boosts_remaining > 0: | ||
| 287 | if not text.empty(): | ||
| 288 | text += "\n" | ||
| 289 | text += "Speed Boost: %d seconds" % speed_boosts_remaining | ||
| 242 | if iceland_remaining > 0: | 290 | if iceland_remaining > 0: |
| 243 | if not text.empty(): | 291 | if not text.empty(): |
| 244 | text += "\n" | 292 | text += "\n" |
| diff --git a/Archipelago/extradata.gd b/Archipelago/extradata.gd index 89c41d2..2e26eb2 100644 --- a/Archipelago/extradata.gd +++ b/Archipelago/extradata.gd | |||
| @@ -93,3 +93,87 @@ var proxies = { | |||
| 93 | "Open Areas/Panel_rise_horizon": ["Open Areas/Panel_son_horizon"], | 93 | "Open Areas/Panel_rise_horizon": ["Open Areas/Panel_son_horizon"], |
| 94 | "Open Areas/Panel_son_sunrise": ["Open Areas/Panel_rise_sunrise"] | 94 | "Open Areas/Panel_son_sunrise": ["Open Areas/Panel_rise_sunrise"] |
| 95 | } | 95 | } |
| 96 | |||
| 97 | var panels_mode_051_panel_fixes = { | ||
| 98 | 444647: | ||
| 99 | [ | ||
| 100 | "Backside Room/Panel_three_three", | ||
| 101 | "Backside Room/Panel_three_three_2", | ||
| 102 | "Backside Room/Panel_three_three_3", | ||
| 103 | "Backside Room/Panel_four_four_3", | ||
| 104 | "Backside Room/Panel_four_four_2", | ||
| 105 | "Backside Room/Panel_four_four_4" | ||
| 106 | ], | ||
| 107 | 444648: | ||
| 108 | [ | ||
| 109 | "Backside Room/Panel_four_four", | ||
| 110 | "Backside Room/Panel_five_five_5", | ||
| 111 | "Backside Room/Panel_five_five_4" | ||
| 112 | ], | ||
| 113 | 444649: | ||
| 114 | [ | ||
| 115 | "Backside Room/Panel_five_five", | ||
| 116 | "Backside Room/Panel_five_five_3", | ||
| 117 | "Backside Room/Panel_five_five_2", | ||
| 118 | "Backside Room/Panel_six_six_4" | ||
| 119 | ], | ||
| 120 | 444650: | ||
| 121 | [ | ||
| 122 | "Backside Room/Panel_six_six", | ||
| 123 | "Backside Room/Panel_six_six_3", | ||
| 124 | "Backside Room/Panel_six_six_2", | ||
| 125 | "Backside Room/Panel_six_six_5", | ||
| 126 | "Backside Room/Panel_six_six_6", | ||
| 127 | "Backside Room/Panel_seven_seven_5", | ||
| 128 | "Backside Room/Panel_seven_seven_6" | ||
| 129 | ], | ||
| 130 | 444651: | ||
| 131 | [ | ||
| 132 | "Backside Room/Panel_seven_seven", | ||
| 133 | "Backside Room/Panel_seven_seven_2", | ||
| 134 | "Backside Room/Panel_seven_seven_7", | ||
| 135 | "Backside Room/Panel_seven_seven_3", | ||
| 136 | "Backside Room/Panel_seven_seven_4", | ||
| 137 | "Backside Room/Panel_eight_eight_8", | ||
| 138 | "Backside Room/Panel_eight_eight_5", | ||
| 139 | "Backside Room/Panel_eight_eight_3", | ||
| 140 | "Backside Room/Panel_eight_eight_7" | ||
| 141 | ], | ||
| 142 | 444652: | ||
| 143 | [ | ||
| 144 | "Backside Room/Panel_eight_eight", | ||
| 145 | "Backside Room/Panel_eight_eight_2", | ||
| 146 | "Backside Room/Panel_eight_eight_4", | ||
| 147 | "Backside Room/Panel_eight_eight_6", | ||
| 148 | "Backside Room/Panel_nine_nine_3", | ||
| 149 | "Backside Room/Panel_nine_nine_8", | ||
| 150 | "Backside Room/Panel_nine_nine_4", | ||
| 151 | "Backside Room/Panel_nine_nine_5", | ||
| 152 | "Backside Room/Panel_nine_nine_2" | ||
| 153 | ], | ||
| 154 | 444653: | ||
| 155 | [ | ||
| 156 | "Backside Room/Panel_nine_nine", | ||
| 157 | "Backside Room/Panel_nine_nine_6", | ||
| 158 | "Backside Room/Panel_nine_nine_8", | ||
| 159 | "Backside Room/Panel_nine_nine_9", | ||
| 160 | "Backside Room/Panel_nine_nine_7" | ||
| 161 | ] | ||
| 162 | } | ||
| 163 | |||
| 164 | var panels_mode_051_door_fixes = { | ||
| 165 | "Door_four_hider": ["Door_four_hider_3", "Door_four_hider_4", "Door_four_hider_2"], | ||
| 166 | "Door_five_hider": ["Door_five_hider_4", "Door_five_hider_5"], | ||
| 167 | "Door_six_hider": ["Door_six_hider_4"], | ||
| 168 | "Door_seven_hider": ["Door_seven_hider_6", "Door_seven_hider_5"], | ||
| 169 | "Door_eight_hider": | ||
| 170 | ["Door_eight_hider_7", "Door_eight_hider_8", "Door_eight_hider_3", "Door_eight_hider_5"], | ||
| 171 | "Door_nine_hider": | ||
| 172 | [ | ||
| 173 | "Door_nine_hider_3", | ||
| 174 | "Door_nine_hider_8", | ||
| 175 | "Door_nine_hider_4", | ||
| 176 | "Door_nine_hider_5", | ||
| 177 | "Door_nine_hider_2" | ||
| 178 | ] | ||
| 179 | } | ||
| diff --git a/Archipelago/load.gd b/Archipelago/load.gd index be209c3..8559b10 100644 --- a/Archipelago/load.gd +++ b/Archipelago/load.gd | |||
| @@ -554,6 +554,20 @@ func _load(): | |||
| 554 | proxynode.exact_proxy = true | 554 | proxynode.exact_proxy = true |
| 555 | proxynode.request_ready() | 555 | proxynode.request_ready() |
| 556 | oldparent.add_child(proxynode) | 556 | oldparent.add_child(proxynode) |
| 557 | |||
| 558 | # If the world was generated on 0.5.1, apply the hotfix for the number hunt doors. | ||
| 559 | if apclient._panel_door_shuffle && apclient.wasGeneratedOnVersion(0, 5, 1): | ||
| 560 | var number_hunt_parent = get_node("Doors/Count Up Room Area Doors") | ||
| 561 | var extradata_051_fix = apclient.get_node("Extradata").panels_mode_051_door_fixes | ||
| 562 | for template_door_path in extradata_051_fix: | ||
| 563 | var template_door = number_hunt_parent.get_node(template_door_path) | ||
| 564 | var impacted_doors = extradata_051_fix[template_door_path] | ||
| 565 | for impacted_door_path in impacted_doors: | ||
| 566 | var impacted_door = number_hunt_parent.get_node(impacted_door_path) | ||
| 567 | var copied_door = impacted_door.duplicate() | ||
| 568 | copied_door.panels = template_door.panels | ||
| 569 | number_hunt_parent.add_child(copied_door) | ||
| 570 | impacted_door.queue_free() | ||
| 557 | 571 | ||
| 558 | # Attach a script to every panel so that we can do things like conditionally | 572 | # Attach a script to every panel so that we can do things like conditionally |
| 559 | # disable them. | 573 | # disable them. |
| @@ -567,6 +581,8 @@ func _load(): | |||
| 567 | var script_instance = panel_script.new() | 581 | var script_instance = panel_script.new() |
| 568 | script_instance.name = "AP_Panel" | 582 | script_instance.name = "AP_Panel" |
| 569 | script_instance.data = panel | 583 | script_instance.data = panel |
| 584 | if apclient._panel_door_shuffle and gamedata.mentioned_panels.has(panel["id"]): | ||
| 585 | script_instance.locked = true | ||
| 570 | panel_node.add_child(script_instance) | 586 | panel_node.add_child(script_instance) |
| 571 | apclient.connect("evaluate_solvability", script_instance, "evaluate_solvability") | 587 | apclient.connect("evaluate_solvability", script_instance, "evaluate_solvability") |
| 572 | 588 | ||
| @@ -666,9 +682,16 @@ func _load(): | |||
| 666 | effects.set_name("AP_Effects") | 682 | effects.set_name("AP_Effects") |
| 667 | self.add_child(effects) | 683 | self.add_child(effects) |
| 668 | 684 | ||
| 685 | # Create the textclient node. | ||
| 686 | var textclient_script = apclient.SCRIPT_textclient | ||
| 687 | var textclient = textclient_script.new() | ||
| 688 | textclient.set_name("AP_TextClient") | ||
| 689 | self.add_child(textclient) | ||
| 690 | |||
| 669 | # Create the multiplayer node, if needed. | 691 | # Create the multiplayer node, if needed. |
| 670 | if apclient.enable_multiplayer: | 692 | if apclient.enable_multiplayer: |
| 671 | var multiplayer_node = apclient.SCRIPT_multiplayer.new() | 693 | var multiplayer_node = apclient.SCRIPT_multiplayer.new() |
| 694 | multiplayer_node.name = "Multiplayer" | ||
| 672 | multiplayer_node.ghost_mode = true | 695 | multiplayer_node.ghost_mode = true |
| 673 | add_child(multiplayer_node) | 696 | add_child(multiplayer_node) |
| 674 | 697 | ||
| diff --git a/Archipelago/multiplayer.gd b/Archipelago/multiplayer.gd index 0bc2241..c2d9875 100644 --- a/Archipelago/multiplayer.gd +++ b/Archipelago/multiplayer.gd | |||
| @@ -1,5 +1,8 @@ | |||
| 1 | extends "res://scripts/multiplayer.gd" | 1 | extends "res://scripts/multiplayer.gd" |
| 2 | 2 | ||
| 3 | var queued_messages = [] | ||
| 4 | var queued_messages_mutex = Mutex.new() | ||
| 5 | |||
| 3 | 6 | ||
| 4 | func _request_lobby_list(): | 7 | func _request_lobby_list(): |
| 5 | var apclient = global.get_node("Archipelago") | 8 | var apclient = global.get_node("Archipelago") |
| @@ -41,3 +44,55 @@ func _update_lobby_members(): | |||
| 41 | if member_id != player_steam_id and member_id in active_lobby_members: | 44 | if member_id != player_steam_id and member_id in active_lobby_members: |
| 42 | var slot_name = Steam.getLobbyMemberData(active_lobby_id, member_id, "slot_name") | 45 | var slot_name = Steam.getLobbyMemberData(active_lobby_id, member_id, "slot_name") |
| 43 | active_lobby_members[member_id].steam_name = slot_name | 46 | active_lobby_members[member_id].steam_name = slot_name |
| 47 | |||
| 48 | |||
| 49 | func say(text): | ||
| 50 | queued_messages_mutex.lock() | ||
| 51 | queued_messages.append(text) | ||
| 52 | queued_messages_mutex.unlock() | ||
| 53 | |||
| 54 | |||
| 55 | func _physics_process(_delta): | ||
| 56 | if queued_messages_mutex.try_lock() == OK: | ||
| 57 | if queued_messages.empty(): | ||
| 58 | queued_messages_mutex.unlock() | ||
| 59 | else: | ||
| 60 | var messages = queued_messages.duplicate() | ||
| 61 | queued_messages = [] | ||
| 62 | queued_messages_mutex.unlock() | ||
| 63 | |||
| 64 | var player = get_tree().get_root().get_node("Spatial/player") | ||
| 65 | var space_state = get_tree().get_root().get_world().direct_space_state | ||
| 66 | var nearby_members = [] | ||
| 67 | for member_id in active_lobby_members.keys(): | ||
| 68 | var other_member = active_lobby_members[member_id] | ||
| 69 | var ray = space_state.intersect_ray( | ||
| 70 | player.global_translation, other_member.global_translation, [player], 0b0101 | ||
| 71 | ) | ||
| 72 | if !("collider" in ray) or ray["collider"] == other_member: | ||
| 73 | # Visible! | ||
| 74 | nearby_members.append(member_id) | ||
| 75 | |||
| 76 | var apclient = global.get_node("Archipelago") | ||
| 77 | var player_name = apclient.get_player_name() | ||
| 78 | for member_id in nearby_members: | ||
| 79 | for msg in messages: | ||
| 80 | _send_p2p_packet( | ||
| 81 | {"solves": [{"say": msg, "from": player_name}]}, | ||
| 82 | member_id, | ||
| 83 | Steam.P2P_SEND_RELIABLE, | ||
| 84 | true | ||
| 85 | ) | ||
| 86 | |||
| 87 | |||
| 88 | # I'm completely hijacking this callback, since we're in ghost mode and it won't be called normally. | ||
| 89 | func _receive_solve(data): | ||
| 90 | if "say" in data: | ||
| 91 | get_tree().get_root().get_node("Spatial/AP_TextClient").parse_printjson( | ||
| 92 | "[LOCAL] [color=#fafad2]%s[/color]: %s" % [data["from"], data["say"]] | ||
| 93 | ) | ||
| 94 | messages.showMessage("[color=#fafad2]%s[/color]: %s" % [data["from"], data["say"]]) | ||
| 95 | |||
| 96 | |||
| 97 | func _send_hi(_discard): | ||
| 98 | pass | ||
| diff --git a/Archipelago/panel.gd b/Archipelago/panel.gd index fc5963a..ce632c5 100644 --- a/Archipelago/panel.gd +++ b/Archipelago/panel.gd | |||
| @@ -5,6 +5,7 @@ var orig_text = "" | |||
| 5 | var atbash_text = "" | 5 | var atbash_text = "" |
| 6 | var orig_color = Color(0, 0, 0, 0) | 6 | var orig_color = Color(0, 0, 0, 0) |
| 7 | var solvable = true | 7 | var solvable = true |
| 8 | var locked = false | ||
| 8 | 9 | ||
| 9 | const kAtbashPre = "abcdefghijklmnopqrstuvwxyz1234567890+-" | 10 | const kAtbashPre = "abcdefghijklmnopqrstuvwxyz1234567890+-" |
| 10 | const kAtbashPost = "zyxwvutsrqponmlkjihgfedcba0987654321-+" | 11 | const kAtbashPost = "zyxwvutsrqponmlkjihgfedcba0987654321-+" |
| @@ -39,7 +40,9 @@ func evaluate_solvability(): | |||
| 39 | solvable = true | 40 | solvable = true |
| 40 | var missing = [] | 41 | var missing = [] |
| 41 | 42 | ||
| 42 | if apclient._color_shuffle: | 43 | if locked: |
| 44 | solvable = false | ||
| 45 | elif apclient._color_shuffle: | ||
| 43 | for color in data["color"]: | 46 | for color in data["color"]: |
| 44 | if not apclient._has_colors.has(color): | 47 | if not apclient._has_colors.has(color): |
| 45 | missing.append(color) | 48 | missing.append(color) |
| @@ -52,6 +55,12 @@ func evaluate_solvability(): | |||
| 52 | self.get_parent().get_node("Viewport/GUI/Panel/Label").text = orig_text | 55 | self.get_parent().get_node("Viewport/GUI/Panel/Label").text = orig_text |
| 53 | self.get_parent().get_node("Viewport/GUI/Panel/TextEdit").editable = true | 56 | self.get_parent().get_node("Viewport/GUI/Panel/TextEdit").editable = true |
| 54 | self.get_parent().get_node("Quad").get_surface_material(0).albedo_color = orig_color | 57 | self.get_parent().get_node("Quad").get_surface_material(0).albedo_color = orig_color |
| 58 | elif locked: | ||
| 59 | self.get_parent().get_node("Viewport/GUI/Panel/Label").text = "Locked" | ||
| 60 | self.get_parent().get_node("Viewport/GUI/Panel/TextEdit").editable = false | ||
| 61 | self.get_parent().get_node("Quad").get_surface_material(0).albedo_color = Color( | ||
| 62 | 0.2, 0.7, 0.7 | ||
| 63 | ) | ||
| 55 | else: | 64 | else: |
| 56 | var missing_text = "Missing: " | 65 | var missing_text = "Missing: " |
| 57 | for thing in missing: | 66 | for thing in missing: |
| diff --git a/Archipelago/pause_menu.gd b/Archipelago/pause_menu.gd index 40994d9..62ba6c3 100644 --- a/Archipelago/pause_menu.gd +++ b/Archipelago/pause_menu.gd | |||
| @@ -6,3 +6,8 @@ func _main_menu(): | |||
| 6 | apclient.disconnect_from_ap() | 6 | apclient.disconnect_from_ap() |
| 7 | 7 | ||
| 8 | ._main_menu() | 8 | ._main_menu() |
| 9 | |||
| 10 | |||
| 11 | func _pause_game(): | ||
| 12 | get_tree().get_root().get_node("Spatial/AP_TextClient").dismiss() | ||
| 13 | ._pause_game() | ||
| diff --git a/Archipelago/settings_screen.gd b/Archipelago/settings_screen.gd index 956d966..ec3b5f1 100644 --- a/Archipelago/settings_screen.gd +++ b/Archipelago/settings_screen.gd | |||
| @@ -38,6 +38,7 @@ func _ready(): | |||
| 38 | apclient_instance.SCRIPT_panel = load("user://maps/Archipelago/panel.gd") | 38 | apclient_instance.SCRIPT_panel = load("user://maps/Archipelago/panel.gd") |
| 39 | var pilg_term = load("user://maps/Archipelago/pilgrimage_terminator.gd") | 39 | var pilg_term = load("user://maps/Archipelago/pilgrimage_terminator.gd") |
| 40 | apclient_instance.SCRIPT_pilgrimage_terminator = pilg_term | 40 | apclient_instance.SCRIPT_pilgrimage_terminator = pilg_term |
| 41 | apclient_instance.SCRIPT_textclient = load("user://maps/Archipelago/textclient.gd") | ||
| 41 | apclient_instance.SCRIPT_uuid = load("user://maps/Archipelago/vendor/uuid.gd") | 42 | apclient_instance.SCRIPT_uuid = load("user://maps/Archipelago/vendor/uuid.gd") |
| 42 | 43 | ||
| 43 | var apdata = ResourceLoader.load("user://maps/Archipelago/gamedata.gd") | 44 | var apdata = ResourceLoader.load("user://maps/Archipelago/gamedata.gd") |
| diff --git a/Archipelago/textclient.gd b/Archipelago/textclient.gd new file mode 100644 index 0000000..3abd9e0 --- /dev/null +++ b/Archipelago/textclient.gd | |||
| @@ -0,0 +1,100 @@ | |||
| 1 | extends Node | ||
| 2 | |||
| 3 | var panel | ||
| 4 | var label | ||
| 5 | var entry | ||
| 6 | var is_open = false | ||
| 7 | |||
| 8 | |||
| 9 | func _ready(): | ||
| 10 | pause_mode = PAUSE_MODE_PROCESS | ||
| 11 | |||
| 12 | panel = Panel.new() | ||
| 13 | panel.set_name("Panel") | ||
| 14 | panel.margin_left = 100 | ||
| 15 | panel.margin_right = 1820 | ||
| 16 | panel.margin_top = 100 | ||
| 17 | panel.margin_bottom = 980 | ||
| 18 | panel.visible = false | ||
| 19 | add_child(panel) | ||
| 20 | |||
| 21 | label = RichTextLabel.new() | ||
| 22 | label.set_name("Label") | ||
| 23 | label.margin_left = 80 | ||
| 24 | label.margin_right = 1640 | ||
| 25 | label.margin_top = 80 | ||
| 26 | label.margin_bottom = 720 | ||
| 27 | label.scroll_following = true | ||
| 28 | label.selection_enabled = true | ||
| 29 | panel.add_child(label) | ||
| 30 | |||
| 31 | var dynamic_font = DynamicFont.new() | ||
| 32 | dynamic_font.font_data = load("res://fonts/Lingo.ttf") | ||
| 33 | dynamic_font.size = 36 | ||
| 34 | label.push_font(dynamic_font) | ||
| 35 | |||
| 36 | var entry_style = StyleBoxFlat.new() | ||
| 37 | entry_style.bg_color = Color(0.9, 0.9, 0.9, 1) | ||
| 38 | |||
| 39 | entry = LineEdit.new() | ||
| 40 | entry.set_name("Entry") | ||
| 41 | entry.margin_left = 80 | ||
| 42 | entry.margin_right = 1640 | ||
| 43 | entry.margin_top = 760 | ||
| 44 | entry.margin_bottom = 840 | ||
| 45 | entry.add_font_override("font", dynamic_font) | ||
| 46 | entry.add_color_override("font_color", Color(0, 0, 0, 1)) | ||
| 47 | entry.add_color_override("cursor_color", Color(0, 0, 0, 1)) | ||
| 48 | entry.add_stylebox_override("focus", entry_style) | ||
| 49 | panel.add_child(entry) | ||
| 50 | entry.connect("text_entered", self, "text_entered") | ||
| 51 | |||
| 52 | |||
| 53 | func _input(event): | ||
| 54 | if event is InputEventKey and event.pressed: | ||
| 55 | if event.scancode == KEY_TAB and !Input.is_key_pressed(KEY_SHIFT): | ||
| 56 | if !get_tree().paused: | ||
| 57 | is_open = true | ||
| 58 | get_tree().paused = true | ||
| 59 | Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) | ||
| 60 | panel.visible = true | ||
| 61 | entry.grab_focus() | ||
| 62 | get_tree().set_input_as_handled() | ||
| 63 | else: | ||
| 64 | dismiss() | ||
| 65 | elif event.scancode == KEY_ESCAPE: | ||
| 66 | if is_open: | ||
| 67 | dismiss() | ||
| 68 | get_tree().set_input_as_handled() | ||
| 69 | |||
| 70 | |||
| 71 | func dismiss(): | ||
| 72 | if is_open: | ||
| 73 | get_tree().paused = false | ||
| 74 | Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) | ||
| 75 | panel.visible = false | ||
| 76 | is_open = false | ||
| 77 | |||
| 78 | |||
| 79 | func parse_printjson(text): | ||
| 80 | if !label.text.empty(): | ||
| 81 | label.append_bbcode("\n") | ||
| 82 | |||
| 83 | label.append_bbcode(text) | ||
| 84 | |||
| 85 | |||
| 86 | func text_entered(text): | ||
| 87 | var apclient = global.get_node("Archipelago") | ||
| 88 | var cmd = text.trim_suffix("\n") | ||
| 89 | if cmd.begins_with("/say "): | ||
| 90 | if apclient.enable_multiplayer: | ||
| 91 | var msg = cmd.trim_prefix("/say ") | ||
| 92 | parse_printjson( | ||
| 93 | "[LOCAL] [color=#ee00ee]%s[/color]: %s" % [apclient.get_player_name(), msg] | ||
| 94 | ) | ||
| 95 | get_tree().get_root().get_node("Spatial/Multiplayer").say(msg) | ||
| 96 | else: | ||
| 97 | parse_printjson("Multiplayer must be enabled to use /say") | ||
| 98 | else: | ||
| 99 | apclient.say(cmd) | ||
| 100 | entry.text = "" | ||
