Finish killing

This commit is contained in:
Sofia 2026-07-20 22:00:00 +03:00
parent a2cf76701f
commit 18f298bf10
4 changed files with 84 additions and 14 deletions

View File

@ -9,7 +9,7 @@ use crate::{
net::{ net::{
network_manager::{ network_manager::{
NetworkManager, NetworkManager,
Package::{self, SelfSync}, Package::{self, Kill, SelfSync, TakeDamage},
PeerKind, SyncPackage, PeerKind, SyncPackage,
}, },
util::NetVector3, util::NetVector3,
@ -289,14 +289,28 @@ impl Game {
.signals() .signals()
.on_die() .on_die()
.connect_other(s, move |s| s.on_death(player_id)); .connect_other(s, move |s| s.on_death(player_id));
} else if let Ok(mut local_player) = local_player
.bind_mut()
.signals()
.on_take_damage()
.connect_other(s, move |s, damage| {
s.on_take_damage(player_id, damage)
});
} else if let Ok(mut remote_player) =
character.clone().try_cast::<RemotePlayer>() character.clone().try_cast::<RemotePlayer>()
{ {
local_player remote_player
.bind_mut() .bind_mut()
.signals() .signals()
.on_die() .on_die()
.connect_other(s, move |s| s.on_death(player_id)); .connect_other(s, move |s| s.on_death(player_id));
remote_player
.bind_mut()
.signals()
.on_take_damage()
.connect_other(s, move |s, damage| {
s.on_take_damage(player_id, damage)
});
} }
} }
@ -310,7 +324,8 @@ impl Game {
} }
} }
pub fn spawn_player(&mut self, id: u16, transform: NetPlayerTransform) { // Method called on the client-side whenever a player has spawned
pub fn spawn_player_client(&mut self, id: u16, transform: NetPlayerTransform) {
if let Some(map) = &mut self.current_map { if let Some(map) = &mut self.current_map {
if let Some(player) = self.players.iter_mut().find(|p| p.id == id) { if let Some(player) = self.players.iter_mut().find(|p| p.id == id) {
let character = map.bind_mut().spawn_player( let character = map.bind_mut().spawn_player(
@ -323,6 +338,7 @@ impl Game {
} }
} }
// Handle a sync package from the server
pub fn handle_sync(&mut self, sync_data: HashMap<u16, SyncPackage>) { pub fn handle_sync(&mut self, sync_data: HashMap<u16, SyncPackage>) {
for ( for (
player_id, player_id,
@ -353,6 +369,7 @@ impl Game {
} }
} }
// Handle a jump, either from the server or from a client
pub fn handle_jump(&mut self, player_id: u16) { pub fn handle_jump(&mut self, player_id: u16) {
if player_id != self.self_id.unwrap_or(0) { if player_id != self.self_id.unwrap_or(0) {
if let Some(player) = self.find_player_mut(player_id) { if let Some(player) = self.find_player_mut(player_id) {
@ -361,6 +378,7 @@ impl Game {
} }
} }
// Handle shooting, either from the server of from a client
pub fn handle_shoot( pub fn handle_shoot(
&mut self, &mut self,
player_id: u16, player_id: u16,
@ -381,8 +399,42 @@ impl Game {
} }
} }
// Handle taking damage, from server to client
pub fn handle_take_damage(&mut self, 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(damage, false);
}
}
}
// Handle dying, from server to client
pub fn handle_kill(&mut self, player_id: u16) {
godot_print!("Got kill!");
if let Some(player) = self.find_player_mut(player_id) {
if let Some(character) = &mut player.character {
character.dyn_bind_mut().kill();
}
}
}
// Called whenever a player takes damage on the server-side
pub fn on_take_damage(&mut self, 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(player_id, damage));
}
}
}
// Called whenever a player dies on the server-side
pub fn on_death(&mut self, player_id: u16) { pub fn on_death(&mut self, player_id: u16) {
godot_print!("Player {} has died!", player_id); if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer {
if let PeerKind::Server(peer, _) = peer {
godot_print!("Sent kill!");
peer.broadcast_reliable(Kill(player_id));
}
}
} }
} }

View File

@ -214,7 +214,7 @@ impl INode for NetworkManager {
} }
Package::SpawnPlayer(id, transform) => { Package::SpawnPlayer(id, transform) => {
if let Some(game) = &mut Game::singleton() { if let Some(game) = &mut Game::singleton() {
game.bind_mut().spawn_player(id, transform); game.bind_mut().spawn_player_client(id, transform);
} }
} }
Package::Sync(sync_data) => { Package::Sync(sync_data) => {
@ -238,6 +238,16 @@ impl INode for NetworkManager {
); );
} }
} }
Package::TakeDamage(player_id, damage) => {
if let Some(game) = &mut Game::singleton() {
game.bind_mut().handle_take_damage(player_id, damage);
}
}
Package::Kill(player_id) => {
if let Some(game) = &mut Game::singleton() {
game.bind_mut().handle_kill(player_id);
}
}
_ => {} _ => {}
}, },
} }
@ -541,6 +551,8 @@ pub enum Package {
SelfSync(SyncPackage), SelfSync(SyncPackage),
Jump(u16), Jump(u16),
Shoot(u16, NetVector3, NetPlayerTransform, f32), Shoot(u16, NetVector3, NetPlayerTransform, f32),
TakeDamage(u16, i32),
Kill(u16),
} }
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]

View File

@ -45,7 +45,7 @@ pub trait IPlayer {
fn get_transform(&self) -> NetPlayerTransform; fn get_transform(&self) -> NetPlayerTransform;
fn jump(&mut self); fn jump(&mut self);
fn try_shoot(&mut self, to: Vector3, deal_damage: bool) -> bool; fn try_shoot(&mut self, to: Vector3, deal_damage: bool) -> bool;
fn take_damage(&mut self, damage: i32); fn take_damage(&mut self, damage: i32, kill: bool);
fn is_dead(&self) -> bool; fn is_dead(&self) -> bool;
fn kill(&mut self); fn kill(&mut self);
} }
@ -183,9 +183,10 @@ impl IPlayer for LocalPlayer {
} }
} }
fn take_damage(&mut self, damage: i32) { fn take_damage(&mut self, damage: i32, kill: bool) {
self.run_deferred(move |s| s.signals().on_take_damage().emit(damage));
self.health -= damage; self.health -= damage;
if self.health <= 0 { if kill && self.health <= 0 {
self.kill(); self.kill();
} }
} }
@ -195,7 +196,7 @@ impl IPlayer for LocalPlayer {
} }
fn kill(&mut self) { fn kill(&mut self) {
self.signals().on_die().emit(); self.run_deferred(move |s| s.signals().on_die().emit());
if let Some(mut mesh) = self.soldier_mesh.take() { if let Some(mut mesh) = self.soldier_mesh.take() {
mesh.queue_free(); mesh.queue_free();
} }
@ -328,6 +329,8 @@ impl ICharacterBody3D for LocalPlayer {
impl LocalPlayer { impl LocalPlayer {
#[signal] #[signal]
pub fn on_die(); pub fn on_die();
#[signal]
pub fn on_take_damage(damage: i32);
fn set_lock(&mut self, locked: bool) { fn set_lock(&mut self, locked: bool) {
self.locked = locked; self.locked = locked;
@ -440,9 +443,10 @@ impl IPlayer for RemotePlayer {
} }
} }
fn take_damage(&mut self, damage: i32) { fn take_damage(&mut self, damage: i32, kill: bool) {
self.run_deferred(move |s| s.signals().on_take_damage().emit(damage));
self.health -= damage; self.health -= damage;
if self.health <= 0 { if kill && self.health <= 0 {
self.kill(); self.kill();
} }
} }
@ -452,7 +456,7 @@ impl IPlayer for RemotePlayer {
} }
fn kill(&mut self) { fn kill(&mut self) {
self.signals().on_die().emit(); self.run_deferred(move |s| s.signals().on_die().emit());
if let Some(mut mesh) = self.soldier_mesh.take() { if let Some(mut mesh) = self.soldier_mesh.take() {
mesh.queue_free(); mesh.queue_free();
} }
@ -495,4 +499,6 @@ impl ICharacterBody3D for RemotePlayer {
impl RemotePlayer { impl RemotePlayer {
#[signal] #[signal]
pub fn on_die(); pub fn on_die();
#[signal]
pub fn on_take_damage(damage: i32);
} }

View File

@ -56,7 +56,7 @@ impl Weapon for Raygun {
if deal_damage && let Some(target) = target { if deal_damage && let Some(target) = target {
if let Ok(mut player) = target.collider.try_dynify::<dyn IPlayer>() { if let Ok(mut player) = target.collider.try_dynify::<dyn IPlayer>() {
player.dyn_bind_mut().take_damage(100); player.dyn_bind_mut().take_damage(100, true);
} }
} }
} }