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
|
||||
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:
|
||||
var attacker_id = 0
|
||||
var weapon_name = "Killed"
|
||||
@@ -454,6 +461,10 @@ func rpc_play_explosion(pos: Vector3, radius: float) -> void:
|
||||
@rpc("any_peer", "call_local", "reliable")
|
||||
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 impulse.length_squared() > 0.01:
|
||||
apply_impulse(impulse)
|
||||
|
||||
# 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)
|
||||
|
||||
@@ -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:
|
||||
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"):
|
||||
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:
|
||||
if not _damage_layer: return
|
||||
@@ -953,8 +973,8 @@ func die(impulse: Vector3 = Vector3.ZERO) -> void:
|
||||
death_screen.visible = true
|
||||
set_process_input(true)
|
||||
|
||||
func _apply_ragdoll_velocity(ragdoll: Node3D, l_vel: Vector3, imp: Vector3) -> void:
|
||||
if is_instance_valid(ragdoll):
|
||||
func _apply_ragdoll_velocity(ragdoll, l_vel: Vector3, imp: Vector3) -> void:
|
||||
if is_instance_valid(ragdoll) and ragdoll.has_method("apply_initial_velocities"):
|
||||
ragdoll.apply_initial_velocities(l_vel, imp)
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
|
||||
@@ -146,12 +146,11 @@ func _apply_impulse() -> void:
|
||||
var push_dir = camera.global_transform.basis.z.normalized()
|
||||
|
||||
# Apply impulse to player velocity
|
||||
player.velocity += push_dir * impulse_strength
|
||||
|
||||
# Small hack to ensure we aren't considered on floor if we shoot down
|
||||
if push_dir.y > 0:
|
||||
# Just slightly lift the player to break floor contact immediately
|
||||
player.position.y += 0.05
|
||||
var final_force = push_dir * impulse_strength
|
||||
if multiplayer.has_multiplayer_peer() and multiplayer.multiplayer_peer is not OfflineMultiplayerPeer:
|
||||
player.server_apply_impulse.rpc_id(1, final_force)
|
||||
else:
|
||||
player.apply_impulse(final_force)
|
||||
|
||||
func _play_muzzle_flash() -> void:
|
||||
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
|
||||
dir = (dir + Vector3(0, 0.5, 0)).normalized()
|
||||
|
||||
# Apply knockback if it has apply_impulse
|
||||
if col.has_method("apply_impulse"):
|
||||
# Apply knockback if it has server_apply_impulse (for rocket jumping)
|
||||
if col.has_method("server_apply_impulse") and col == owner_player:
|
||||
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 == 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
|
||||
elif owner_player and owner_player.multiplayer.is_server():
|
||||
elif owner_player:
|
||||
col.take_damage(final_damage, target_pos, owner_player, dir * final_knockback)
|
||||
|
||||
# Broadcast Visual Explosion Effect to other peers
|
||||
|
||||
Reference in New Issue
Block a user