forked from unfa/liblast
Improved players disconnecting from the game. Implemented network ping measurnment and FPS display.
This commit is contained in:
parent
26643f2696
commit
cec82c7738
6 changed files with 147 additions and 38 deletions
|
@ -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()
|
||||
|
||||
|
|
|
@ -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"]
|
||||
|
|
27
Game/Assets/HUD/Performance.gd
Normal file
27
Game/Assets/HUD/Performance.gd
Normal 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"
|
|
@ -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):
|
||||
|
|
45
Game/Main.gd
45
Game/Main.gd
|
@ -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")
|
||||
|
|
|
@ -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"]
|
||||
|
|
Loading…
Reference in a new issue