Feat/10 adding multiplayer fundamentals #14
@@ -252,6 +252,13 @@ func apply_impulse(force: Vector3) -> void:
|
|||||||
# Tiny upward bump helps move_and_slide detach from the floor
|
# Tiny upward bump helps move_and_slide detach from the floor
|
||||||
global_position.y += 0.1
|
global_position.y += 0.1
|
||||||
|
|
||||||
|
@rpc("any_peer", "call_local", "reliable")
|
||||||
|
func server_apply_impulse(force: Vector3) -> void:
|
||||||
|
if not multiplayer.is_server(): return
|
||||||
|
var sender = multiplayer.get_remote_sender_id()
|
||||||
|
if sender != 1 and sender != str(name).to_int(): return
|
||||||
|
apply_impulse(force)
|
||||||
|
|
||||||
func take_damage(amount: float, _hit_pos: Vector3, _source: Node3D = null, impulse: Vector3 = Vector3.ZERO) -> void:
|
func take_damage(amount: float, _hit_pos: Vector3, _source: Node3D = null, impulse: Vector3 = Vector3.ZERO) -> void:
|
||||||
var attacker_id = 0
|
var attacker_id = 0
|
||||||
var weapon_name = "Killed"
|
var weapon_name = "Killed"
|
||||||
@@ -454,6 +461,10 @@ func rpc_play_explosion(pos: Vector3, radius: float) -> void:
|
|||||||
@rpc("any_peer", "call_local", "reliable")
|
@rpc("any_peer", "call_local", "reliable")
|
||||||
func server_take_damage(amount: float, hit_pos: Vector3, attacker_id: int, weapon_name: String, impulse: Vector3) -> void:
|
func server_take_damage(amount: float, hit_pos: Vector3, attacker_id: int, weapon_name: String, impulse: Vector3) -> void:
|
||||||
if not multiplayer.is_server(): return
|
if not multiplayer.is_server(): return
|
||||||
|
|
||||||
|
if impulse.length_squared() > 0.01:
|
||||||
|
apply_impulse(impulse)
|
||||||
|
|
||||||
# Broadcast damage event to all peers so the victim dies on all screens
|
# Broadcast damage event to all peers so the victim dies on all screens
|
||||||
rpc_take_damage.rpc(amount, hit_pos, attacker_id, weapon_name, impulse)
|
rpc_take_damage.rpc(amount, hit_pos, attacker_id, weapon_name, impulse)
|
||||||
|
|
||||||
@@ -507,8 +518,17 @@ func rpc_take_damage(amount: float, hit_pos: Vector3, attacker_id: int, weapon_n
|
|||||||
if aid != killer_id and now - recent_attackers[aid] <= 10.0:
|
if aid != killer_id and now - recent_attackers[aid] <= 10.0:
|
||||||
assist_ids.append(aid)
|
assist_ids.append(aid)
|
||||||
|
|
||||||
|
var real_victim_name = "Player " + str(name)
|
||||||
|
if "player_name" in self and self.player_name != "":
|
||||||
|
real_victim_name = self.player_name
|
||||||
|
elif str(name).to_int() == 1:
|
||||||
|
real_victim_name = "Host"
|
||||||
|
|
||||||
if nm.has_method("register_kill"):
|
if nm.has_method("register_kill"):
|
||||||
nm.register_kill.rpc(-1, killer_id, weapon_name, self.name, assist_ids)
|
var victim_id = str(name).to_int()
|
||||||
|
if victim_id == 0:
|
||||||
|
victim_id = 1 # Fallback to host if something is weird
|
||||||
|
nm.register_kill.rpc(victim_id, killer_id, weapon_name, real_victim_name, assist_ids)
|
||||||
|
|
||||||
func _show_damage_indicator(hit_pos: Vector3) -> void:
|
func _show_damage_indicator(hit_pos: Vector3) -> void:
|
||||||
if not _damage_layer: return
|
if not _damage_layer: return
|
||||||
@@ -953,8 +973,8 @@ func die(impulse: Vector3 = Vector3.ZERO) -> void:
|
|||||||
death_screen.visible = true
|
death_screen.visible = true
|
||||||
set_process_input(true)
|
set_process_input(true)
|
||||||
|
|
||||||
func _apply_ragdoll_velocity(ragdoll: Node3D, l_vel: Vector3, imp: Vector3) -> void:
|
func _apply_ragdoll_velocity(ragdoll, l_vel: Vector3, imp: Vector3) -> void:
|
||||||
if is_instance_valid(ragdoll):
|
if is_instance_valid(ragdoll) and ragdoll.has_method("apply_initial_velocities"):
|
||||||
ragdoll.apply_initial_velocities(l_vel, imp)
|
ragdoll.apply_initial_velocities(l_vel, imp)
|
||||||
|
|
||||||
func _input(event: InputEvent) -> void:
|
func _input(event: InputEvent) -> void:
|
||||||
|
|||||||
@@ -146,12 +146,11 @@ func _apply_impulse() -> void:
|
|||||||
var push_dir = camera.global_transform.basis.z.normalized()
|
var push_dir = camera.global_transform.basis.z.normalized()
|
||||||
|
|
||||||
# Apply impulse to player velocity
|
# Apply impulse to player velocity
|
||||||
player.velocity += push_dir * impulse_strength
|
var final_force = push_dir * impulse_strength
|
||||||
|
if multiplayer.has_multiplayer_peer() and multiplayer.multiplayer_peer is not OfflineMultiplayerPeer:
|
||||||
# Small hack to ensure we aren't considered on floor if we shoot down
|
player.server_apply_impulse.rpc_id(1, final_force)
|
||||||
if push_dir.y > 0:
|
else:
|
||||||
# Just slightly lift the player to break floor contact immediately
|
player.apply_impulse(final_force)
|
||||||
player.position.y += 0.05
|
|
||||||
|
|
||||||
func _play_muzzle_flash() -> void:
|
func _play_muzzle_flash() -> void:
|
||||||
if muzzle_flash:
|
if muzzle_flash:
|
||||||
|
|||||||
@@ -191,16 +191,19 @@ func _explode(pos: Vector3) -> void:
|
|||||||
# Add a tiny bit of upward bias to knockback so it lifts them
|
# Add a tiny bit of upward bias to knockback so it lifts them
|
||||||
dir = (dir + Vector3(0, 0.5, 0)).normalized()
|
dir = (dir + Vector3(0, 0.5, 0)).normalized()
|
||||||
|
|
||||||
# Apply knockback if it has apply_impulse
|
# Apply knockback if it has server_apply_impulse (for rocket jumping)
|
||||||
if col.has_method("apply_impulse"):
|
if col.has_method("server_apply_impulse") and col == owner_player:
|
||||||
col.apply_impulse(dir * final_knockback)
|
if multiplayer.has_multiplayer_peer() and multiplayer.multiplayer_peer is not OfflineMultiplayerPeer:
|
||||||
|
col.server_apply_impulse.rpc_id(1, dir * final_knockback)
|
||||||
|
else:
|
||||||
|
col.apply_impulse(dir * final_knockback)
|
||||||
|
|
||||||
# Apply damage
|
# Apply damage (and knockback for other players via take_damage)
|
||||||
if col.has_method("take_damage"):
|
if col.has_method("take_damage"):
|
||||||
if col == owner_player and not can_self_damage:
|
if col == owner_player and not can_self_damage:
|
||||||
# Skip self damage, but we still applied the knockback!
|
# Skip self damage (we already applied knockback above)
|
||||||
pass
|
pass
|
||||||
elif owner_player and owner_player.multiplayer.is_server():
|
elif owner_player:
|
||||||
col.take_damage(final_damage, target_pos, owner_player, dir * final_knockback)
|
col.take_damage(final_damage, target_pos, owner_player, dir * final_knockback)
|
||||||
|
|
||||||
# Broadcast Visual Explosion Effect to other peers
|
# Broadcast Visual Explosion Effect to other peers
|
||||||
|
|||||||
Reference in New Issue
Block a user