83 lines
3.0 KiB
GDScript3
83 lines
3.0 KiB
GDScript3
|
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
|