From a0ce60c238ada432a63c2e2306fa3a5363f66dd9 Mon Sep 17 00:00:00 2001 From: Sofia Date: Mon, 27 Jul 2026 22:54:00 +0300 Subject: [PATCH] Allow activating telegrenade in-flight --- rust/src/game_manager.rs | 26 +++++++++++++++++++++++++- rust/src/net/network_manager.rs | 1 + rust/src/net/protocol.rs | 9 +++++++++ rust/src/player/local_player.rs | 22 ++++++++++++++++++++-- rust/src/player/mod.rs | 9 ++++++--- rust/src/player/remote_player.rs | 4 ++-- 6 files changed, 63 insertions(+), 8 deletions(-) diff --git a/rust/src/game_manager.rs b/rust/src/game_manager.rs index 44222d1..b6641e7 100644 --- a/rust/src/game_manager.rs +++ b/rust/src/game_manager.rs @@ -14,7 +14,9 @@ use crate::{ net::{ network_manager::{ BallSync, NetworkManager, - Package::{self, Kill, SelfSync, SetTeam, SpawnPlayer, TakeDamage}, + Package::{ + self, Kill, SelfSync, SetTeam, SpawnPlayer, TakeDamage, TelegrenadeTeleport, + }, PeerKind, SyncPackage, TelegrenadeSync, }, util::NetVector3, @@ -1301,6 +1303,7 @@ impl Game { } } + // Handle telegrenade activate from server to client pub fn handle_telegrenade_teleport(&mut self, player_id: u16, to: NetVector3) { if let Some(player) = self.find_player_mut(player_id) && let Some(character) = &mut player.character @@ -1308,6 +1311,27 @@ impl Game { character.dyn_bind_mut().telegrenade_teleport(to.into()); } } + + // Handle telegrenade activation from client to server + pub fn handle_telegrenade_activate(&mut self, player_id: u16) { + if let Some(player) = self.find_player_mut(player_id) + && let Some(character) = &mut player.character + { + let pos = if let Some(telegrenade) = character.dyn_bind().get_telegrenade() { + telegrenade.get_global_position() + } else { + Vector3::ZERO + }; + character.dyn_bind_mut().telegrenade_teleport(pos); + self.run_deferred(move |_| { + if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer + && let PeerKind::Server(peer, _) = peer + { + peer.broadcast_reliable(TelegrenadeTeleport(player_id, pos.into())); + } + }); + } + } } #[derive(Clone, Debug)] diff --git a/rust/src/net/network_manager.rs b/rust/src/net/network_manager.rs index fb005c0..aa14db0 100644 --- a/rust/src/net/network_manager.rs +++ b/rust/src/net/network_manager.rs @@ -317,6 +317,7 @@ pub enum Package { Pickup(u8, u16), ThrowTelegrenade(u16, NetVector3), TelegrenadeTeleport(u16, NetVector3), + TelegrenadeActivate, // End-of-Game packages FinishGame, diff --git a/rust/src/net/protocol.rs b/rust/src/net/protocol.rs index c437854..24841bd 100644 --- a/rust/src/net/protocol.rs +++ b/rust/src/net/protocol.rs @@ -464,6 +464,15 @@ impl NetworkManager { } } } + Package::TelegrenadeActivate => { + if let Some(game) = &mut Game::singleton() { + let player = + game.bind().find_player_by_addr(&conn.address).cloned(); + if let Some(player) = player { + game.bind_mut().handle_telegrenade_activate(player.id()); + } + } + } _ => {} }, }, diff --git a/rust/src/player/local_player.rs b/rust/src/player/local_player.rs index 4de0ccc..cc24896 100644 --- a/rust/src/player/local_player.rs +++ b/rust/src/player/local_player.rs @@ -341,8 +341,8 @@ impl IPlayer for LocalPlayer { self.telegrenade.clone() } - fn telegrenade_teleport(&mut self, to: Vector3) { - self.telegrenade_teleport_common(to); + fn telegrenade_teleport(&mut self, to: Vector3) -> bool { + self.telegrenade_teleport_common(to) } fn as_gd(&self) -> DynGd { @@ -500,6 +500,24 @@ impl ICharacterBody3D for LocalPlayer { fn input(&mut self, event: Gd) { if self.locked { if event.is_action_pressed("throw_telegrenade") { + if let Some(telegrenade) = &mut self.telegrenade { + if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer { + match peer { + PeerKind::Client(peer, socket_addr) => { + peer.send_reliable(socket_addr, Package::TelegrenadeActivate); + } + PeerKind::Server(peer, _) => { + let position = telegrenade.get_global_position(); + self.telegrenade_teleport(position); + peer.broadcast_reliable(Package::TelegrenadeTeleport( + self.player_id.unwrap_or(0), + position.into(), + )); + } + } + } + } + if let Some(pos) = self.raycast_from_camera() { if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer { match peer { diff --git a/rust/src/player/mod.rs b/rust/src/player/mod.rs index 938205b..b6ea8bf 100644 --- a/rust/src/player/mod.rs +++ b/rust/src/player/mod.rs @@ -70,7 +70,7 @@ pub trait IPlayer { fn try_throw_telegrenade(&mut self, to: Vector3) -> bool; fn set_telegrenade(&mut self, telegrenade: Option>); fn get_telegrenade(&self) -> Option>; - fn telegrenade_teleport(&mut self, to: Vector3); + fn telegrenade_teleport(&mut self, to: Vector3) -> bool; fn as_gd(&self) -> DynGd; } @@ -83,7 +83,7 @@ pub trait PlayerCommon { fn try_shoot_common(&mut self, to: Vector3, deal_damage: bool) -> bool; fn try_punch_common(&mut self, to: Vector3, deal_damage: bool) -> bool; fn throw_telegrenade_common(&mut self, to: Vector3) -> bool; - fn telegrenade_teleport_common(&mut self, to: Vector3); + fn telegrenade_teleport_common(&mut self, to: Vector3) -> bool; } impl PlayerCommon for T { @@ -293,12 +293,15 @@ impl PlayerCommon for T { true } - fn telegrenade_teleport_common(&mut self, to: Vector3) { + fn telegrenade_teleport_common(&mut self, to: Vector3) -> bool { if let Some(mut telegrenade) = self.get_telegrenade() { telegrenade.queue_free(); + } else { + return false; } self.set_telegrenade(None); self.base_mut().set_global_position(to); + true } } diff --git a/rust/src/player/remote_player.rs b/rust/src/player/remote_player.rs index dbac0f1..53fd124 100644 --- a/rust/src/player/remote_player.rs +++ b/rust/src/player/remote_player.rs @@ -281,8 +281,8 @@ impl IPlayer for RemotePlayer { self.telegrenade.clone() } - fn telegrenade_teleport(&mut self, to: Vector3) { - self.telegrenade_teleport_common(to); + fn telegrenade_teleport(&mut self, to: Vector3) -> bool { + self.telegrenade_teleport_common(to) } fn as_gd(&self) -> DynGd {