diff --git a/Game/Assets/Characters/Player.gd b/Game/Assets/Characters/Player.gd index 6945a75..893195a 100644 --- a/Game/Assets/Characters/Player.gd +++ b/Game/Assets/Characters/Player.gd @@ -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) diff --git a/Game/Assets/Weapons/Weapon.gd b/Game/Assets/Weapons/Weapon.gd index 59e4023..6fa11a9 100644 --- a/Game/Assets/Weapons/Weapon.gd +++ b/Game/Assets/Weapons/Weapon.gd @@ -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()) diff --git a/Game/Main.gd b/Game/Main.gd index 7fa1949..76b14e2 100644 --- a/Game/Main.gd +++ b/Game/Main.gd @@ -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