amb-crawl/lobby.gd

83 lines
3.0 KiB
GDScript

extends Control
signal game_start
var pname=""
var players={}
var PLAYER_SCENE=load("res://player.tscn")
func _ready():
multiplayer.peer_connected.connect(add_player)
multiplayer.peer_disconnected.connect(remove_player)
func start(id,given_name):
push_warning(id) # Helps identify windows for print() output, but push_warning is more convenient anyway.
pname=given_name # Why can't I have push_notice/push_debug?
add_player(id)
show()
# ESSENTIAL TENETS:
# The multiplayer authority of spawning basically always resides with 1.
# Whether this is tied to the authority of the spawner or its target node, I don't know, but it doesn't really matter.
# THEREFORE, any local data you want to pick up has to be fetched after RPC handoff.
# In addition: Any properties set on an object in the frame it's created probably won't sync or persist
# use call_deferred or await get_tree().process_frame to fix this.
func add_player(pid):
players[pid]={}
var a
if multiplayer.get_unique_id()==1:
a=PLAYER_SCENE.instantiate()
a.name=str(pid)
$fuck_layouts/player_list.add_child(a)
else:
a=$fuck_layouts/player_list.find_child(str(pid),false,false)
while a==null:
await get_tree().process_frame
a=$fuck_layouts/player_list.find_child(str(pid),false,false)
a.set_multiplayer_authority(pid)
a.get_node('PName').text=pname # This tries to force local name on every node but sync will fix it after
func remove_player(pid):
players.erase(pid)
# Kinda works? Sometimes posts errors from other clients but still behaves correctly so idk
$fuck_layouts/player_list.remove_child($fuck_layouts/player_list.get_node(str(pid)))
func _on_send_message_pressed(message=""):
var box=$fuck_layouts/menu_shiz/chats/shitpost/input
if message=="": message=box.text
rpc("receive_message",pname,message)
box.text=""
@rpc("any_peer","call_local")
func receive_message(pid,message):
var a=Label.new()
a.text=str(pid)+": "+message
var scroll=$fuck_layouts/menu_shiz/chats/elder
scroll.get_node('messages').add_child(a)
# I don't really understand this magic number but it works on my machine.
# The offset is actually 128px, but this means it should grab even if you only see ~3/4 of the last message
var bump=scroll.scroll_vertical+134>scroll.get_v_scroll_bar().max_value
await get_tree().process_frame # This seems to not work if the window doesn't have focus.
# Not going to bother figuring it out unless it's important for something else.
if bump: scroll.ensure_control_visible(a)
func _start_clicked():
var pid=0
for child in $fuck_layouts/player_list.get_children(true):
if child.name=='player_spawner': continue
pid=child.get_multiplayer_authority()
players[pid]['name']=child.get_node('PName').text
players[pid]['class']=child.get_node('PChar/Class').selected
if players.values().any(func(x):return x=={} or x['class']==-1):
receive_message('System','Not all players have finalised their options')
return
rpc("gamestart",players)
@rpc("any_peer","call_local")
func gamestart(players):
emit_signal('game_start',players)
hide()
func _idk_clicked():
pass