Improved players disconnecting from the game. Implemented network ping measurnment and FPS display.

This commit is contained in:
unfa 2021-10-24 20:17:19 +02:00
parent 26643f2696
commit cec82c7738
6 changed files with 147 additions and 38 deletions

View file

@ -5,10 +5,15 @@ var impact_player = preload("res://Assets/Effects/ImpactBlood.tscn")
var max_health = 100
var health = max_health:
set(value):
main.player_list.players[self.get_multiplayer_authority()].health = value
main.push_local_player_info()
if not dead:
if main.player_list.players.has(self.get_multiplayer_authority()):
main.player_list.players[self.get_multiplayer_authority()].health = value
main.push_local_player_info()
get:
return main.player_list.players[self.get_multiplayer_authority()].health
if not dead:
return main.player_list.players[self.get_multiplayer_authority()].health
else:
return 0
@export var mouse_sensitivity := 0.15
@ -380,41 +385,45 @@ func _process(delta):
crosshair.show()
@rpc(any_peer, call_local, reliable) func die(killer_pid: int):
if killer_pid == -1: # we're disconnecting from the game
#main.chat.chat_notification("Player [/i][b][color=" + main.player_list.players[self.get_multiplayer_authority()].color.to_html() + "]" + main.player_list.players[self.get_multiplayer_authority()].name + "[/color][/b][i] left the game.")
pass
else:
var gibs = gibs_vfx.instantiate()
get_tree().root.add_child(gibs)
gibs.global_transform = self.global_transform
var decal = blood_decal.instantiate()
get_tree().root.add_child(decal)
decal.global_transform = self.global_transform
if is_multiplayer_authority(): # don't touch these on puppets
hud.pain = 3
crosshair.hide()
#main.chat.rpc(&'chat_notification', "Player [/i][b][color=" + main.player_list.players[self.get_multiplayer_authority()].color.to_html() + "]" + main.player_list.players[self.get_multiplayer_authority()].name + "[/color][/b][i] was killed by " + main.player_list.players[killer_pid].name )
main.chat.chat_notification("Player [/i][b][color=" + main.player_list.players[self.get_multiplayer_authority()].color.to_html() + "]" + main.player_list.players[self.get_multiplayer_authority()].name + "[/color][/b][i] was killed by " + main.player_list.players[killer_pid].name )
revenge_pid = killer_pid
$Head/Camera.position.y = -1 # lower the head to the ground, let the player see their gibs
$Head/Camera.rotation.x = 0 # reset the tilt so the camera looks forward
$Head/Camera.rotation.z = -20
jetpack_active = false
view_zoom_target = 1.0
view_zoom = 1
dead = true
var gibs = gibs_vfx.instantiate()
get_tree().root.add_child(gibs)
gibs.global_transform = self.global_transform
var decal = blood_decal.instantiate()
get_tree().root.add_child(decal)
decal.global_transform = self.global_transform
main.destroy_player(self.get_multiplayer_authority())
self.hide()
$Body.disabled = true
#if get_tree().get_rpc_sender_id() != get_multiplayer_authority():
# print ("Death requested by a non-master. Ignoring")
# return
#main.rpc(&'destroy_player', self.get_multiplayer_authority())
main.destroy_player(self.get_multiplayer_authority())
self.hide()
$Body.disabled = true
if is_multiplayer_authority(): # don't touch these on puppets
hud.pain = 3
crosshair.hide()
#main.chat.rpc(&'chat_notification', "Player [/i][b][color=" + main.player_list.players[self.get_multiplayer_authority()].color.to_html() + "]" + main.player_list.players[self.get_multiplayer_authority()].name + "[/color][/b][i] was killed by " + main.player_list.players[killer_pid].name )
main.chat.chat_notification("Player [/i][b][color=" + main.player_list.players[self.get_multiplayer_authority()].color.to_html() + "]" + main.player_list.players[self.get_multiplayer_authority()].name + "[/color][/b][i] was killed by " + main.player_list.players[killer_pid].name )
revenge_pid = killer_pid
$Head/Camera.position.y = -1 # lower the head to the ground, let the player see their gibs
$Head/Camera.rotation.x = 0 # reset the tilt so the camera looks forward
$Head/Camera.rotation.z = -20
jetpack_active = false
view_zoom_target = 1.0
view_zoom = 1
#queue_free()

View file

@ -1,4 +1,4 @@
[gd_scene load_steps=23 format=3 uid="uid://bff5uslrxesjx"]
[gd_scene load_steps=24 format=3 uid="uid://bff5uslrxesjx"]
[ext_resource type="Texture2D" uid="uid://blnjjtjifk22i" path="res://Assets/HUD/Vignette.png" id="1"]
[ext_resource type="Script" path="res://Assets/HUD/HUD.gd" id="1_wc430"]
@ -16,6 +16,7 @@
[ext_resource type="AudioStream" uid="uid://d36o2duyrij57" path="res://Assets/SFX/UI_Message.wav" id="9_ubwxw"]
[ext_resource type="Texture2D" uid="uid://dvt25wji1pdyl" path="res://Assets/HUD/BarOver.svg" id="10_5i332"]
[ext_resource type="Texture2D" uid="uid://0j6rxd7ncmu1" path="res://Assets/HUD/BarProgress.svg" id="11_tlgqu"]
[ext_resource type="Script" path="res://Assets/HUD/Performance.gd" id="17_getmp"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_dxk5q"]
resource_local_to_scene = true
@ -459,4 +460,21 @@ stretch_margin_right = 16
stretch_margin_bottom = 16
script = null
[node name="Performance" type="Label" parent="."]
material = ExtResource( "4_f6eam" )
anchor_top = 1.0
anchor_bottom = 1.0
offset_left = 4.0
offset_top = -106.0
offset_right = 202.0
offset_bottom = -2.0
text = "FPS:
PING:"
valign = 2
structured_text_bidi_override_options = []
script = ExtResource( "17_getmp" )
__meta__ = {
"_edit_use_anchors_": false
}
[connection signal="text_submitted" from="Chat/VBoxContainer/Typing/Editor" to="Chat" method="_on_Editor_text_submitted"]

View file

@ -0,0 +1,27 @@
extends Label
# Declare member variables here. Examples:
# var a = 2
# var b = "text"
@onready var main = get_tree().root.get_node("Main")
# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
if not get_tree().multiplayer.has_multiplayer_peer():
text = "Offline"
elif get_tree().multiplayer.is_server():
text = "Hosting"
else:
if main.ping_time >= 0:
text = "Ping: " + str(round(main.ping_time * 1000)) + " ms"
else:
text = "Ping unknown"
text += "\nFPS: " + str(Engine.get_frames_per_second())
text += "\nLiblast 0.1.1 pre-alpha"

View file

@ -50,6 +50,18 @@ func apply_settings():
# These functions are for applying settings changes
func quit_game():
var main = get_tree().get_root().get_node("Main")
var pid = main.get_multiplayer_authority()
var player_node = main.get_node("Players").get_node(str(pid))
#main.get_node("HUD/Chat").rpc(&'chat_notification', "Player " + str(pid) +" left the game.")
#player_node.rpc(&'die', -1)
#main.rpc(&'disconnect_player', pid) # tell everyone we're leaving
#main.multiplayer = null
get_tree().multiplayer.multiplayer_peer = null
get_tree().quit()
func toggle_fullscreen(is_fullscreen):

View file

@ -10,6 +10,11 @@ const NET_SERVER = "localhost"
var peer = ENetMultiplayerPeer.new()
var ping_time = -1
var ping_sent = 0
var ping_recieved = 0
var ping_token = 0
var role = MultiplayerRole.NONE:
set(new_role):
role = new_role
@ -22,6 +27,23 @@ var player_scene = preload("res://Assets/Characters/Player.tscn")
@onready var chat = hud.get_node("Chat")
var local_player: Node = null
@rpc(call_remote, any_peer, unreliable) func ping(token:int = -1):
if get_tree().multiplayer.is_server(): # we are the sever - reply to pinging client
# for i in range(0, 100):
# print(i)
rpc_id(get_tree().multiplayer.get_remote_sender_id(), &'ping', token)
else:
if get_tree().multiplayer.get_remote_sender_id() == 1: #recieve answer from server
if token == ping_token: # if the token is correct
ping_recieved = uptime
ping_time = ping_recieved - ping_sent
#else:
# ping_time = -1
elif token == -1: # send ping
ping_sent = uptime
ping_token = randi()
rpc_id(1, &'ping', ping_token)
class PlayerInfo:
var name: String
var team: int
@ -133,7 +155,10 @@ class PlayerList:
players[pid] = info
func get(pid: int) -> PlayerInfo:
return players[pid]
if players.has(pid):
return players[pid]
else:
return PlayerInfo.new()
@onready var player_list = PlayerList.new()
@ -184,7 +209,7 @@ func _input(_event) -> void:
@rpc(any_peer, call_local, reliable) func game_over(winner):
if local_player:
local_player.rpc(&'set_dead', true)
local_player.die(-1)
hud.game_over(winner)
spawn_queue.clear()
@ -244,6 +269,9 @@ func update_hud():
@rpc(any_peer, reliable) func player_list_update(info, pid = get_tree().get_rpc_sender_id(), erase:=false):
if erase:
player_list.erase(pid)
spawn_queue.erase(pid)
get_node("Players").get_node(str(pid)).die(-1)
return
var new_info = PlayerInfo.new()
new_info.deserialize(info)
@ -268,6 +296,7 @@ func update_hud():
func push_local_player_info(): #
var pid = get_tree().multiplayer.get_unique_id()
assert(pid >= 1, "Another server must be running. PID is 0, that means Enet did not initialize.")
rpc(&'player_list_update', player_list.get(pid).serialize(), pid)
@rpc(call_local, any_peer, reliable) func destroy_player(pid: int):
@ -290,7 +319,9 @@ func push_local_player_info(): #
if destroy_free_player_crash_workaround:
pass
#print("Setting player ", pid, " as DEAD")
#player_node.set_dead(true)
if not player_node.dead: # disconnected, not killed
player_node.die(-1)
return # skip the rest - don't add to respawn queue
else: # regular method follows
player_node.name = str(player_node.name) + "_dead" # avoids name collision when instancing another player scene
@ -298,7 +329,8 @@ func push_local_player_info(): #
player_node.queue_free()
print("after free")
# respawn queue applies ot both implementations of death
spawn_queue[pid] = uptime + respawn_delay
if player_list.players.has(pid): # don't respawn players that are not there, lol
spawn_queue[pid] = uptime + respawn_delay
if pid == get_tree().multiplayer.get_unique_id():
update_hud()
@ -443,7 +475,7 @@ func _player_connected(pid) -> void:
# if role in [MultiplayerRole.SERVER, MultiplayerRole.DEDICATED_SERVER]:
# rpc_id(id, "player_list_update", player_list)
func _player_disconnected(pid) -> void:
@rpc(call_remote, any_peer, reliable) func disconnect_player(pid):
print("player disconnected, id: ", pid)
spawn_queue.erase(pid)
if get_tree().multiplayer.is_server():
@ -451,6 +483,9 @@ func _player_disconnected(pid) -> void:
player_list.erase(pid)
rpc(&'player_list_update', null, pid, true)
rpc(&'destroy_player', pid)
func _player_disconnected(pid) -> void:
disconnect_player(pid)
func _connected_ok() -> void:
print("connected to server")

View file

@ -241,6 +241,9 @@ offset_top = 49.0
custom_effects = []
structured_text_bidi_override_options = []
[node name="Performance" parent="HUD" index="8"]
structured_text_bidi_override_options = []
[node name="GUI" parent="." instance=ExtResource( "2" )]
[node name="Players" type="Node3D" parent="."]
@ -336,11 +339,16 @@ stream = ExtResource( "5_ilayd" )
bus = &"Announcer"
script = ExtResource( "6_gcsgr" )
[node name="PingTimer" type="Timer" parent="."]
autostart = true
script = null
[connection signal="toggled" from="NetworkTesting/CheckButton" to="." method="_on_CheckButton_toggled"]
[connection signal="pressed" from="NetworkTesting/Host" to="." method="_on_Host_pressed"]
[connection signal="pressed" from="NetworkTesting/Connect" to="." method="_on_Connect_pressed"]
[connection signal="text_submitted" from="NetworkTesting/TextEdit" to="." method="_on_TextEdit_text_submitted"]
[connection signal="color_changed" from="NetworkTesting/ColorPickerButton" to="." method="_on_ColorPickerButton_color_changed"]
[connection signal="pressed" from="NetworkTesting/Button" to="." method="_on_Button_pressed"]
[connection signal="timeout" from="PingTimer" to="." method="ping"]
[editable path="HUD"]