Implemented death and respawning (no delay)

remotes/1705377932733043820/tmp_refs/heads/unbroken
unfa 2021-08-29 20:32:46 +02:00
parent f36e358ab8
commit bd2de8adb8
3 changed files with 48 additions and 17 deletions

View File

@ -146,11 +146,17 @@ func _process(delta):
func damage(hp: int):
var target = main.player_list.players[self.get_network_master()]
target.health -= hp
if target.health <= 0: # int(name) is the player instance node name signifying owner's PID
die()
#if target.health <= 0: # int(name) is the player instance node name signifying owner's PID
# die()
func die():
# if get_tree().get_rpc_sender_id() != get_network_master():
# print ("Death requested by a non-master. Ignoring")
# return
main.rpc(&'destroy_player', self.get_network_master())
main.chat.rpc(&'chat_notification', "Player " + main.player_list.players[self.get_network_master()].name + " is dead")
#queue_free()
func _physics_process(delta):
# rpc_unreliable(&'set_global_transform', global_transform)

View File

@ -18,7 +18,7 @@ var impact_player = preload("res://Assets/Effects/ImpactPlayer.tscn")
#enum Trigger {TRIGGER_PRIMARY, TRIGGER_SECONDARY}
@remotesync func shoot():
print("SHOOT from PID ", get_tree().get_network_unique_id(), " controlled by ", player.get_network_master())
#print("SHOOT from PID ", get_tree().get_network_unique_id(), " controlled by ", player.get_network_master())
var space_state = get_world_3d().direct_space_state
var from = camera.get_global_transform().origin
@ -32,8 +32,10 @@ var impact_player = preload("res://Assets/Effects/ImpactPlayer.tscn")
if ray: # did we hit anything?
if ray['collider'].has_method(&'damage'):
if get_tree().get_network_unique_id() == 1: # make sure this can only run on the server
print("SHOT HIT ", ray['collider'])
ray['collider'].damage(10) # apply damage
#print("SHOT HIT ", ray['collider'])
ray['collider'].damage(50) # apply damage
if main.player_list.get(ray['collider'].get_network_master()).health <= 0: # if he ded
ray['collider'].die()
# boardcast the new health value to all peers TODO: fix this
main.rpc(&'player_list_update', main.player_list.get(ray['collider'].get_network_master()).serialize(), ray['collider'].get_network_master())

View File

@ -181,31 +181,52 @@ func push_local_player_info(): #
else:
rpc(&'player_list_update', player_list.get(id).serialize(), 1)
func create_player(pid: int, is_local: bool) -> void:
@remotesync func destroy_player(pid: int):
var player_node = $Players.get_node(str(pid))
assert(player_node != null, "Attempting to delete a player node that does not exist")
player_node.name = str(player_node.name) + "_dead" # avoids name collision when instancing another player scene
player_node.queue_free()
#player.queue_free()
var is_local = true if pid == local_player.get_network_master() else false
create_player(pid, is_local, true)
func create_player(pid: int, is_local:= false, respawn:= false) -> void:
var new_player
new_player = player_scene.instantiate()
var spawnpoint = $Map/SpawnPoints.get_children()[randi() % len($Map/SpawnPoints.get_children())]
new_player.name = str(pid)
new_player.global_transform = spawnpoint.global_transform
new_player.set_network_master(pid)
$Players.add_child(new_player)
var new_info: PlayerInfo
if not respawn: # first spawn
new_info = PlayerInfo.new() # generate namee, color etc
else: # respawn
new_info = player_list.players[pid] # reuse previous name, color etc
new_info.health = 100 # give the respawned player full health
player_list.set(pid, new_info)
if get_tree().network_peer.get_unique_id() != 1: # if we're not the server - update the server
rpc_id(1, &'player_list_update', new_info.serialize()) # send local player info to the server
else: # if we're the server, update the clients
rpc(&'player_list_update', new_info.serialize(), pid)
if is_local:
local_player = new_player #$Players.get_node(str(id))
local_player.get_node("Head/Camera").current = true
var new_info = PlayerInfo.new()
player_list.set(pid, new_info)
if get_tree().network_peer.get_unique_id() != 1: #if we're not the server
rpc_id(1, &'player_list_update', new_info.serialize()) # send local player info to the server
$NetworkTesting/TextEdit.text = new_info.name
$NetworkTesting/ColorPickerButton.color = new_info.color
else: # make sure we use the right camera
elif local_player: # if there is a local player, make sure we keep using it's camera
new_player.get_node("Head/Camera").current = false
if local_player: #if there is a local player, use it's camera
local_player.get_node("Head/Camera").current = true
local_player.get_node("Head/Camera").current = true
func start_dedicated_server(): # start server without creating a local player
role = NetworkRole.DEDICATED_SERVER
@ -279,6 +300,8 @@ func _ready() -> void:
get_tree().connect("connection_failed", self._connected_fail)
get_tree().connect("server_disconnected", self._server_disconnected)
if OS.get_cmdline_args().has("dedicated_server"):
start_dedicated_server()
func _on_TextEdit_text_submitted(new_text):
player_list.players[get_tree().network_peer.get_unique_id()].name = new_text