From 179f10e4494dfe082334f5d800fc03e9346b5b47 Mon Sep 17 00:00:00 2001 From: Sofia Date: Tue, 21 Jul 2026 21:54:09 +0300 Subject: [PATCH] Make sure that ball cannot be picked up by the same player instantly --- rust/src/ball.rs | 14 ++++++++++++++ rust/src/game_manager.rs | 13 ++++++++----- rust/src/map.rs | 7 ++++++- rust/src/net/network_manager.rs | 6 +++--- rust/src/player.rs | 11 +++++++---- 5 files changed, 38 insertions(+), 13 deletions(-) diff --git a/rust/src/ball.rs b/rust/src/ball.rs index 8778a70..ac14a8e 100644 --- a/rust/src/ball.rs +++ b/rust/src/ball.rs @@ -8,6 +8,10 @@ use crate::player::{IPlayer, NetTransform}; #[derive(GodotClass)] #[class(base=RigidBody3D, init)] pub struct Ball { + pub dropper: Option, + + alive_for: f64, + base: Base, } @@ -19,6 +23,10 @@ impl IRigidBody3D for Ball { .body_entered() .connect_other(self, |s, body| s.on_collision(body)); } + + fn process(&mut self, delta: f64) { + self.alive_for += delta; + } } #[godot_api] @@ -37,6 +45,12 @@ impl Ball { if let Ok(player) = node.try_dynify::() && let Some(player_id) = player.dyn_bind().get_player_id() { + if let Some(dropper_id) = self.dropper + && dropper_id == player_id + && self.alive_for < 1.0 + { + return; + } self.run_deferred(move |s| s.signals().on_ball_pickup().emit(player_id)); } } diff --git a/rust/src/game_manager.rs b/rust/src/game_manager.rs index ed29f04..49d498c 100644 --- a/rust/src/game_manager.rs +++ b/rust/src/game_manager.rs @@ -303,27 +303,30 @@ impl Game { for player in s.players.clone() { s.spawn_player_server(player.id); } - s.spawn_ball(None); + s.spawn_ball(None, None); }); } } } - pub fn spawn_ball(&mut self, transform: Option) { + pub fn spawn_ball(&mut self, transform: Option, player_id: Option) { if let Some(map) = &mut self.current_map { - let ball = map.bind_mut().spawn_ball(transform); + let ball = map.bind_mut().spawn_ball(transform, player_id); if let Some(ball) = &ball { self.world_ball = Some(ball.clone()); ball.signals() .on_ball_pickup() .connect_other(self, |s, player_id| s.handle_ball_pickup(player_id)); } - self.run_deferred(|_| { + self.run_deferred(move |_| { if let Some(ball) = ball && let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer && let PeerKind::Server(peer, _) = peer { - peer.broadcast_reliable(Package::SpawnBall(ball.bind().get_transform())); + peer.broadcast_reliable(Package::SpawnBall( + ball.bind().get_transform(), + player_id, + )); } }); } diff --git a/rust/src/map.rs b/rust/src/map.rs index 060240b..017a6da 100644 --- a/rust/src/map.rs +++ b/rust/src/map.rs @@ -90,11 +90,16 @@ impl Map { } } - pub fn spawn_ball(&mut self, transform: Option) -> Option> { + pub fn spawn_ball( + &mut self, + transform: Option, + player_id: Option, + ) -> Option> { if let Some(ball_spawner) = self.ball_spawner.clone() && let Some(ball_prefab) = &self.ball { let mut ball = ball_prefab.instantiate_as::(); + ball.bind_mut().dropper = player_id; self.base_mut().add_child(&ball); if let Some(transform) = transform { ball.set_global_position(transform.location.into()); diff --git a/rust/src/net/network_manager.rs b/rust/src/net/network_manager.rs index d528d4c..768239e 100644 --- a/rust/src/net/network_manager.rs +++ b/rust/src/net/network_manager.rs @@ -258,9 +258,9 @@ impl INode for NetworkManager { .handle_kill(source_player_id, target_player_id); } } - Package::SpawnBall(transform) => { + Package::SpawnBall(transform, player_id) => { if let Some(game) = &mut Game::singleton() { - game.bind_mut().spawn_ball(Some(transform)); + game.bind_mut().spawn_ball(Some(transform), player_id); } } Package::DespawnBall => { @@ -594,7 +594,7 @@ pub enum Package { Shoot(u16, NetVector3, NetTransform, f32), TakeDamage(DamageSource, u16, i32), Kill(DamageSource, u16), - SpawnBall(NetTransform), + SpawnBall(NetTransform, Option), DespawnBall, SwapWeapon(u16, WeaponType), } diff --git a/rust/src/player.rs b/rust/src/player.rs index 118474f..e0c733f 100644 --- a/rust/src/player.rs +++ b/rust/src/player.rs @@ -98,10 +98,13 @@ impl PlayerMovement for T { )); if let Some(mut game) = Game::singleton() { if let Some(ball_origin) = &s.get_ball_origin() { - game.bind_mut().spawn_ball(Some(NetTransform { - location: ball_origin.get_global_position().into(), - rotation: ball_origin.get_global_rotation().into(), - })); + game.bind_mut().spawn_ball( + Some(NetTransform { + location: ball_origin.get_global_position().into(), + rotation: ball_origin.get_global_rotation().into(), + }), + s.get_player_id(), + ); } } }