From 25fe3e5ae64bd503a5af20b58ec84301c2e139a8 Mon Sep 17 00:00:00 2001 From: Sofia Date: Tue, 21 Jul 2026 02:35:35 +0300 Subject: [PATCH] Use DamageSource instead of player_id always --- rust/src/game_manager.rs | 50 ++++++++++++------------ rust/src/killbox.rs | 9 ++++- rust/src/net/network_manager.rs | 6 +-- rust/src/player.rs | 69 +++++++++++++++++++++++++-------- rust/src/weapon.rs | 10 ++++- 5 files changed, 95 insertions(+), 49 deletions(-) diff --git a/rust/src/game_manager.rs b/rust/src/game_manager.rs index d4cca40..151c87a 100644 --- a/rust/src/game_manager.rs +++ b/rust/src/game_manager.rs @@ -14,7 +14,7 @@ use crate::{ }, util::NetVector3, }, - player::{IPlayer, LocalPlayer, NetPlayerTransform, RemotePlayer}, + player::{DamageSource, IPlayer, LocalPlayer, NetPlayerTransform, RemotePlayer}, }; pub const GAME_MANAGER_GLOBAL: &str = "GameManagerGlobal"; @@ -320,30 +320,32 @@ impl Game { if let Some(character) = &mut character { if let Ok(mut local_player) = character.clone().try_cast::() { - local_player - .bind_mut() - .signals() - .on_die() - .connect_other(self, move |s, spid| s.on_death(spid, id)); + local_player.bind_mut().signals().on_die().connect_other( + self, + move |s, signal, spid| { + s.on_death(DamageSource::from_signal(signal, spid), id) + }, + ); local_player .bind_mut() .signals() .on_take_damage() - .connect_other(self, move |s, spid, damage| { - s.on_take_damage(spid, id, damage) + .connect_other(self, move |s, signal, spid, damage| { + s.on_take_damage(DamageSource::from_signal(signal, spid), id, damage) }); } else if let Ok(mut remote_player) = character.clone().try_cast::() { - remote_player - .bind_mut() - .signals() - .on_die() - .connect_other(self, move |s, spid| s.on_death(spid, id)); + remote_player.bind_mut().signals().on_die().connect_other( + self, + move |s, signal, spid| { + s.on_death(DamageSource::from_signal(signal, spid), id) + }, + ); remote_player .bind_mut() .signals() .on_take_damage() - .connect_other(self, move |s, spid, damage| { - s.on_take_damage(spid, id, damage) + .connect_other(self, move |s, signal, spid, damage| { + s.on_take_damage(DamageSource::from_signal(signal, spid), id, damage) }); } } @@ -438,39 +440,37 @@ impl Game { } // Handle taking damage, from server to client - pub fn handle_take_damage(&mut self, source_player_id: u16, player_id: u16, damage: i32) { + pub fn handle_take_damage(&mut self, source: DamageSource, player_id: u16, damage: i32) { if let Some(player) = self.find_player_mut(player_id) { if let Some(character) = &mut player.character { - character - .dyn_bind_mut() - .take_damage(source_player_id, damage, false); + character.dyn_bind_mut().take_damage(source, damage, false); } } } // Handle dying, from server to client - pub fn handle_kill(&mut self, source_player_id: u16, player_id: u16) { + pub fn handle_kill(&mut self, source: DamageSource, player_id: u16) { if let Some(player) = self.find_player_mut(player_id) { if let Some(character) = &mut player.character { - character.dyn_bind_mut().kill(source_player_id); + character.dyn_bind_mut().kill(source); } } } // Called whenever a player takes damage on the server-side - pub fn on_take_damage(&mut self, source_player_id: u16, target_player_id: u16, damage: i32) { + pub fn on_take_damage(&mut self, source: DamageSource, target_player_id: u16, damage: i32) { if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer { if let PeerKind::Server(peer, _) = peer { - peer.broadcast_reliable(TakeDamage(source_player_id, target_player_id, damage)); + peer.broadcast_reliable(TakeDamage(source, target_player_id, damage)); } } } // Called whenever a player dies on the server-side - pub fn on_death(&mut self, source_player_id: u16, target_player_id: u16) { + pub fn on_death(&mut self, source: DamageSource, target_player_id: u16) { if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer { if let PeerKind::Server(peer, _) = peer { - peer.broadcast_reliable(Kill(source_player_id, target_player_id)); + peer.broadcast_reliable(Kill(source, target_player_id)); } } } diff --git a/rust/src/killbox.rs b/rust/src/killbox.rs index 721dbd7..1a54e1e 100644 --- a/rust/src/killbox.rs +++ b/rust/src/killbox.rs @@ -3,7 +3,10 @@ use godot::{ prelude::*, }; -use crate::{net::network_manager::NetworkManager, player::IPlayer}; +use crate::{ + net::network_manager::NetworkManager, + player::{DamageSource, IPlayer}, +}; #[derive(GodotClass)] #[class(base=Area3D, init)] @@ -25,7 +28,9 @@ impl Killbox { pub fn kill(&mut self, node: Gd) { if let Ok(mut player) = node.try_dynify::() { if NetworkManager::singleton().bind().is_host() { - player.dyn_bind_mut().take_damage(0, 1000, true); + player + .dyn_bind_mut() + .take_damage(DamageSource::Killbox, 1000, true); } } } diff --git a/rust/src/net/network_manager.rs b/rust/src/net/network_manager.rs index 8eb4e0a..517e8a9 100644 --- a/rust/src/net/network_manager.rs +++ b/rust/src/net/network_manager.rs @@ -11,7 +11,7 @@ use teanet::{Peer, PeerConfig}; use crate::{ game_manager::{Game, GameManager, NetPlayer}, net::{net_stats::Stats, util::NetVector3}, - player::NetPlayerTransform, + player::{DamageSource, NetPlayerTransform}, ui::cli::{CliColor, CommandLinePanel}, }; @@ -572,8 +572,8 @@ pub enum Package { SelfSync(SyncPackage), Jump(u16), Shoot(u16, NetVector3, NetPlayerTransform, f32), - TakeDamage(u16, u16, i32), - Kill(u16, u16), + TakeDamage(DamageSource, u16, i32), + Kill(DamageSource, u16), } #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/rust/src/player.rs b/rust/src/player.rs index f872cf3..c16aff9 100644 --- a/rust/src/player.rs +++ b/rust/src/player.rs @@ -45,9 +45,9 @@ pub trait IPlayer { fn get_transform(&self) -> NetPlayerTransform; fn jump(&mut self); fn try_shoot(&mut self, to: Vector3, deal_damage: bool) -> bool; - fn take_damage(&mut self, source_player: u16, damage: i32, kill: bool); + fn take_damage(&mut self, source_player: DamageSource, damage: i32, kill: bool); fn is_dead(&self) -> bool; - fn kill(&mut self, source_player: u16); + fn kill(&mut self, source_player: DamageSource); fn dead_for(&self) -> f64; } @@ -196,11 +196,12 @@ impl IPlayer for LocalPlayer { } } - fn take_damage(&mut self, source_player: u16, damage: i32, kill: bool) { - self.run_deferred(move |s| s.signals().on_take_damage().emit(source_player, damage)); + fn take_damage(&mut self, source: DamageSource, damage: i32, kill: bool) { + let (signal, player) = source.into_signal(); + self.run_deferred(move |s| s.signals().on_take_damage().emit(signal, player, damage)); self.health -= damage; if kill && self.health <= 0 { - self.kill(source_player); + self.kill(source); } } @@ -212,8 +213,9 @@ impl IPlayer for LocalPlayer { self.dead_for } - fn kill(&mut self, source_player: u16) { - self.run_deferred(move |s| s.signals().on_die().emit(source_player)); + fn kill(&mut self, source: DamageSource) { + let (signal, player) = source.into_signal(); + self.run_deferred(move |s| s.signals().on_die().emit(signal, player)); if let Some(mut mesh) = self.soldier_mesh.take() { mesh.queue_free(); } @@ -227,7 +229,9 @@ impl IPlayer for LocalPlayer { splorch.set_emitting(true); } self.is_dead = true; - self.killer_id = Some(source_player); + if let DamageSource::Player(player_id) = source { + self.killer_id = Some(player_id); + } } } @@ -395,9 +399,9 @@ impl ICharacterBody3D for LocalPlayer { #[godot_api] impl LocalPlayer { #[signal] - pub fn on_die(source_player: u16); + pub fn on_die(source: DamageSourceSignal, player: u16); #[signal] - pub fn on_take_damage(source_player: u16, damage: i32); + pub fn on_take_damage(source: DamageSourceSignal, source_player: u16, damage: i32); fn set_lock(&mut self, locked: bool) { self.locked = locked; @@ -515,11 +519,12 @@ impl IPlayer for RemotePlayer { } } - fn take_damage(&mut self, source_player: u16, damage: i32, kill: bool) { - self.run_deferred(move |s| s.signals().on_take_damage().emit(source_player, damage)); + fn take_damage(&mut self, source: DamageSource, damage: i32, kill: bool) { + let (signal, player) = source.into_signal(); + self.run_deferred(move |s| s.signals().on_take_damage().emit(signal, player, damage)); self.health -= damage; if kill && self.health <= 0 { - self.kill(source_player); + self.kill(source); } } @@ -531,8 +536,9 @@ impl IPlayer for RemotePlayer { self.dead_for } - fn kill(&mut self, source_player: u16) { - self.run_deferred(move |s| s.signals().on_die().emit(source_player)); + fn kill(&mut self, source: DamageSource) { + let (signal, player) = source.into_signal(); + self.run_deferred(move |s| s.signals().on_die().emit(signal, player)); if let Some(mut mesh) = self.soldier_mesh.take() { mesh.queue_free(); } @@ -578,7 +584,36 @@ impl ICharacterBody3D for RemotePlayer { #[godot_api] impl RemotePlayer { #[signal] - pub fn on_die(source_player: u16); + pub fn on_die(source: DamageSourceSignal, player: u16); #[signal] - pub fn on_take_damage(source_player: u16, damage: i32); + pub fn on_take_damage(source: DamageSourceSignal, source_player: u16, damage: i32); +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum DamageSource { + Player(u16), + Killbox, +} + +impl DamageSource { + pub fn into_signal(&self) -> (DamageSourceSignal, u16) { + match self { + DamageSource::Player(id) => (DamageSourceSignal::Player, *id), + DamageSource::Killbox => (DamageSourceSignal::Killbox, 0), + } + } + + pub fn from_signal(signal: DamageSourceSignal, player: u16) -> DamageSource { + match signal { + DamageSourceSignal::Player => DamageSource::Player(player), + DamageSourceSignal::Killbox => DamageSource::Killbox, + } + } +} + +#[derive(Debug, GodotConvert, Clone)] +#[godot(via = u8)] +pub enum DamageSourceSignal { + Player, + Killbox, } diff --git a/rust/src/weapon.rs b/rust/src/weapon.rs index 6e23f4b..06793a0 100644 --- a/rust/src/weapon.rs +++ b/rust/src/weapon.rs @@ -1,6 +1,10 @@ use godot::{classes::AudioStreamPlayer3D, prelude::*}; -use crate::{game_manager::Game, net::util::cast_ray, player::IPlayer}; +use crate::{ + game_manager::Game, + net::util::cast_ray, + player::{DamageSource, IPlayer}, +}; pub trait Weapon { fn shoot(&mut self, player_rid: Rid, player_id: u16, to: Vector3, deal_damage: bool); @@ -57,7 +61,9 @@ impl Weapon for Raygun { if deal_damage && let Some(target) = target { if let Ok(mut player) = target.collider.try_dynify::() { - player.dyn_bind_mut().take_damage(player_id, 100, true); + player + .dyn_bind_mut() + .take_damage(DamageSource::Player(player_id), 100, true); } } }