about summary refs log tree commit diff stats
path: root/Archipelago
diff options
context:
space:
mode:
Diffstat (limited to 'Archipelago')
-rw-r--r--Archipelago/client.gd54
-rw-r--r--Archipelago/effects.gd66
-rw-r--r--Archipelago/load.gd1
-rw-r--r--Archipelago/multiplayer.gd55
-rw-r--r--Archipelago/textclient.gd16
5 files changed, 175 insertions, 17 deletions
diff --git a/Archipelago/client.gd b/Archipelago/client.gd index 5f8be4e..8cddb83 100644 --- a/Archipelago/client.gd +++ b/Archipelago/client.gd
@@ -19,7 +19,7 @@ var enable_multiplayer = false
19var track_player = false 19var track_player = false
20var connection_history = [] 20var connection_history = []
21 21
22const my_version = "panels-beta6" 22const my_version = "4.2.1"
23const ap_version = {"major": 0, "minor": 5, "build": 0, "class": "Version"} 23const ap_version = {"major": 0, "minor": 5, "build": 0, "class": "Version"}
24const color_items = [ 24const color_items = [
25 "White", "Black", "Red", "Blue", "Green", "Brown", "Gray", "Orange", "Purple", "Yellow" 25 "White", "Black", "Red", "Blue", "Green", "Brown", "Gray", "Orange", "Purple", "Yellow"
@@ -114,6 +114,7 @@ var _pilgrimage_allows_roof_access = false
114var _pilgrimage_allows_paintings = false 114var _pilgrimage_allows_paintings = false
115var _sunwarp_shuffle = false 115var _sunwarp_shuffle = false
116var _sunwarp_mapping = [] 116var _sunwarp_mapping = []
117var _speed_boost_mode = false
117var _slot_seed = 0 118var _slot_seed = 0
118 119
119var _map_loaded = false 120var _map_loaded = false
@@ -127,8 +128,11 @@ var _puzzle_skips = 0
127var _cached_slowness = 0 128var _cached_slowness = 0
128var _cached_iceland = 0 129var _cached_iceland = 0
129var _cached_atbash = 0 130var _cached_atbash = 0
131var _cached_speed_boosts = 0
130var _geronimo_skip = false 132var _geronimo_skip = false
131var _checked_paintings = [] 133var _checked_paintings = []
134var _hints_key = ""
135var _hinted_locations = []
132 136
133signal could_not_connect 137signal could_not_connect
134signal connect_status 138signal connect_status
@@ -346,6 +350,10 @@ func _on_data():
346 _sunwarp_shuffle = false 350 _sunwarp_shuffle = false
347 if _slot_data.has("sunwarp_permutation"): 351 if _slot_data.has("sunwarp_permutation"):
348 _sunwarp_mapping = _slot_data["sunwarp_permutation"] 352 _sunwarp_mapping = _slot_data["sunwarp_permutation"]
353 if _slot_data.has("speed_boost_mode"):
354 _speed_boost_mode = _slot_data["speed_boost_mode"]
355 else:
356 _speed_boost_mode = false
349 357
350 if ( 358 if (
351 _location_classification_bit != kCLASSIFICATION_LOCAL_INSANITY 359 _location_classification_bit != kCLASSIFICATION_LOCAL_INSANITY
@@ -364,6 +372,7 @@ func _on_data():
364 _cached_slowness = 0 372 _cached_slowness = 0
365 _cached_iceland = 0 373 _cached_iceland = 0
366 _cached_atbash = 0 374 _cached_atbash = 0
375 _cached_speed_boosts = 0
367 _geronimo_skip = false 376 _geronimo_skip = false
368 377
369 _localdata_file = "user://archipelago_data/%s_%d" % [_seed, _slot] 378 _localdata_file = "user://archipelago_data/%s_%d" % [_seed, _slot]
@@ -395,6 +404,9 @@ func _on_data():
395 if localdata.size() > 5: 404 if localdata.size() > 5:
396 _geronimo_skip = localdata[5] 405 _geronimo_skip = localdata[5]
397 406
407 if localdata.size() > 6:
408 _cached_speed_boosts = localdata[6]
409
398 requestSync() 410 requestSync()
399 411
400 sendMessage( 412 sendMessage(
@@ -409,6 +421,11 @@ func _on_data():
409 ] 421 ]
410 ) 422 )
411 423
424 _hints_key = "_read_hints_%d_%d" % [_team, _slot]
425 sendMessage(
426 [{"cmd": "SetNotify", "keys": [_hints_key]}, {"cmd": "Get", "keys": [_hints_key]}]
427 )
428
412 emit_signal("client_connected") 429 emit_signal("client_connected")
413 430
414 elif cmd == "ConnectionRefused": 431 elif cmd == "ConnectionRefused":
@@ -506,9 +523,12 @@ func _on_data():
506 ) 523 )
507 else: 524 else:
508 if message["receiving"] != _slot: 525 if message["receiving"] != _slot:
509 messages.showMessage( 526 var sentMsg = (
510 "Sent [color=%s]%s[/color] to %s" % [item_color, item_name, player_name] 527 "Sent [color=%s]%s[/color] to %s" % [item_color, item_name, player_name]
511 ) 528 )
529 if _hinted_locations.has(message["item"]["location"]):
530 sentMsg += " ([color=#fafad2]Hinted![/color])"
531 messages.showMessage(sentMsg)
512 532
513 elif cmd == "Bounced": 533 elif cmd == "Bounced":
514 if ( 534 if (
@@ -529,8 +549,15 @@ func _on_data():
529 get_tree().get_root().get_node("Spatial/player/pause_menu")._reload() 549 get_tree().get_root().get_node("Spatial/player/pause_menu")._reload()
530 550
531 elif cmd == "SetReply": 551 elif cmd == "SetReply":
532 if message.has("key") and message["key"] == ("Lingo_%d_Paintings" % _slot): 552 if message.has("key"):
533 _checked_paintings = message["value"] 553 if message["key"] == ("Lingo_%d_Paintings" % _slot):
554 _checked_paintings = message["value"]
555 elif message["key"] == _hints_key:
556 parseHints(message["value"])
557
558 elif cmd == "Retrieved":
559 if message.has("keys") and message["keys"].has(_hints_key):
560 parseHints(message["keys"][_hints_key])
534 561
535 562
536func _process(_delta): 563func _process(_delta):
@@ -584,7 +611,8 @@ func saveLocaldata():
584 effects_node.slowness_remaining, 611 effects_node.slowness_remaining,
585 effects_node.iceland_remaining, 612 effects_node.iceland_remaining,
586 effects_node.atbash_remaining, 613 effects_node.atbash_remaining,
587 _geronimo_skip 614 _geronimo_skip,
615 effects_node.speed_boosts_remaining,
588 ] 616 ]
589 file.store_var(data, true) 617 file.store_var(data, true)
590 file.close() 618 file.close()
@@ -831,12 +859,14 @@ func processItem(item, index, from, flags):
831 ) 859 )
832 860
833 var effects_node = get_tree().get_root().get_node("Spatial/AP_Effects") 861 var effects_node = get_tree().get_root().get_node("Spatial/AP_Effects")
834 if item_name == "Slowness Trap": 862 if item_name == "Slowness Trap" and !_speed_boost_mode:
835 effects_node.trigger_slowness_trap() 863 effects_node.trigger_slowness_trap()
836 if item_name == "Iceland Trap": 864 if item_name == "Iceland Trap":
837 effects_node.trigger_iceland_trap() 865 effects_node.trigger_iceland_trap()
838 if item_name == "Atbash Trap": 866 if item_name == "Atbash Trap":
839 effects_node.trigger_atbash_trap() 867 effects_node.trigger_atbash_trap()
868 if item_name == "Speed Boost" and _speed_boost_mode:
869 effects_node.trigger_speed_boost()
840 if item_name == "Puzzle Skip": 870 if item_name == "Puzzle Skip":
841 _puzzle_skips += 1 871 _puzzle_skips += 1
842 872
@@ -887,6 +917,14 @@ func checkPainting(painting_id):
887 setValue("Paintings", [painting_id], "add") 917 setValue("Paintings", [painting_id], "add")
888 918
889 919
920func parseHints(hints):
921 _hinted_locations.clear()
922
923 for hint in hints:
924 if hint["finding_player"] == int(_slot):
925 _hinted_locations.append(hint["location"])
926
927
890func colorForItemType(flags): 928func colorForItemType(flags):
891 var int_flags = int(flags) 929 var int_flags = int(flags)
892 if int_flags & 1: # progression 930 if int_flags & 1: # progression
@@ -936,6 +974,10 @@ func parse_printjson(message):
936 textclient_node.parse_printjson("".join(parts)) 974 textclient_node.parse_printjson("".join(parts))
937 975
938 976
977func get_player_name():
978 return _player_name_by_slot[_slot]
979
980
939func compareVersion(lhs, rhs): 981func compareVersion(lhs, rhs):
940 if lhs["major"] == rhs["major"]: 982 if lhs["major"] == rhs["major"]:
941 if lhs["minor"] == rhs["minor"]: 983 if lhs["minor"] == rhs["minor"]:
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
5var slowness_remaining = 0 5var slowness_remaining = 0
6var iceland_remaining = 0 6var iceland_remaining = 0
7var atbash_remaining = 0 7var atbash_remaining = 0
8var speed_boosts_remaining = 0
8var queued_iceland = 0 9var queued_iceland = 0
9var skip_available = false 10var skip_available = false
10var puzzle_focused = false 11var 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
67func trigger_slowness_trap(length = 30): 80func 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
95func 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
82func trigger_iceland_trap(length = 60): 110func 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
101func trigger_atbash_trap(): 129func 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
229func _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
201func _tick_iceland(): 245func _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/load.gd b/Archipelago/load.gd index ce7bba5..4811b47 100644 --- a/Archipelago/load.gd +++ b/Archipelago/load.gd
@@ -674,6 +674,7 @@ func _load():
674 # Create the multiplayer node, if needed. 674 # Create the multiplayer node, if needed.
675 if apclient.enable_multiplayer: 675 if apclient.enable_multiplayer:
676 var multiplayer_node = apclient.SCRIPT_multiplayer.new() 676 var multiplayer_node = apclient.SCRIPT_multiplayer.new()
677 multiplayer_node.name = "Multiplayer"
677 multiplayer_node.ghost_mode = true 678 multiplayer_node.ghost_mode = true
678 add_child(multiplayer_node) 679 add_child(multiplayer_node)
679 680
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 @@
1extends "res://scripts/multiplayer.gd" 1extends "res://scripts/multiplayer.gd"
2 2
3var queued_messages = []
4var queued_messages_mutex = Mutex.new()
5
3 6
4func _request_lobby_list(): 7func _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
49func say(text):
50 queued_messages_mutex.lock()
51 queued_messages.append(text)
52 queued_messages_mutex.unlock()
53
54
55func _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.
89func _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
97func _send_hi(_discard):
98 pass
diff --git a/Archipelago/textclient.gd b/Archipelago/textclient.gd index 7bddf38..3abd9e0 100644 --- a/Archipelago/textclient.gd +++ b/Archipelago/textclient.gd
@@ -25,6 +25,7 @@ func _ready():
25 label.margin_top = 80 25 label.margin_top = 80
26 label.margin_bottom = 720 26 label.margin_bottom = 720
27 label.scroll_following = true 27 label.scroll_following = true
28 label.selection_enabled = true
28 panel.add_child(label) 29 panel.add_child(label)
29 30
30 var dynamic_font = DynamicFont.new() 31 var dynamic_font = DynamicFont.new()
@@ -51,7 +52,7 @@ func _ready():
51 52
52func _input(event): 53func _input(event):
53 if event is InputEventKey and event.pressed: 54 if event is InputEventKey and event.pressed:
54 if event.scancode == KEY_TAB: 55 if event.scancode == KEY_TAB and !Input.is_key_pressed(KEY_SHIFT):
55 if !get_tree().paused: 56 if !get_tree().paused:
56 is_open = true 57 is_open = true
57 get_tree().paused = true 58 get_tree().paused = true
@@ -84,5 +85,16 @@ func parse_printjson(text):
84 85
85func text_entered(text): 86func text_entered(text):
86 var apclient = global.get_node("Archipelago") 87 var apclient = global.get_node("Archipelago")
87 apclient.say(text.trim_suffix("\n")) 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)
88 entry.text = "" 100 entry.text = ""