Allow activating telegrenade in-flight

This commit is contained in:
Sofia 2026-07-27 22:54:00 +03:00
parent a6e6e66d28
commit a0ce60c238
6 changed files with 63 additions and 8 deletions

View File

@ -14,7 +14,9 @@ use crate::{
net::{ net::{
network_manager::{ network_manager::{
BallSync, NetworkManager, BallSync, NetworkManager,
Package::{self, Kill, SelfSync, SetTeam, SpawnPlayer, TakeDamage}, Package::{
self, Kill, SelfSync, SetTeam, SpawnPlayer, TakeDamage, TelegrenadeTeleport,
},
PeerKind, SyncPackage, TelegrenadeSync, PeerKind, SyncPackage, TelegrenadeSync,
}, },
util::NetVector3, 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) { pub fn handle_telegrenade_teleport(&mut self, player_id: u16, to: NetVector3) {
if let Some(player) = self.find_player_mut(player_id) if let Some(player) = self.find_player_mut(player_id)
&& let Some(character) = &mut player.character && let Some(character) = &mut player.character
@ -1308,6 +1311,27 @@ impl Game {
character.dyn_bind_mut().telegrenade_teleport(to.into()); 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)] #[derive(Clone, Debug)]

View File

@ -317,6 +317,7 @@ pub enum Package {
Pickup(u8, u16), Pickup(u8, u16),
ThrowTelegrenade(u16, NetVector3), ThrowTelegrenade(u16, NetVector3),
TelegrenadeTeleport(u16, NetVector3), TelegrenadeTeleport(u16, NetVector3),
TelegrenadeActivate,
// End-of-Game packages // End-of-Game packages
FinishGame, FinishGame,

View File

@ -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());
}
}
}
_ => {} _ => {}
}, },
}, },

View File

@ -341,8 +341,8 @@ impl IPlayer for LocalPlayer {
self.telegrenade.clone() self.telegrenade.clone()
} }
fn telegrenade_teleport(&mut self, to: Vector3) { fn telegrenade_teleport(&mut self, to: Vector3) -> bool {
self.telegrenade_teleport_common(to); self.telegrenade_teleport_common(to)
} }
fn as_gd(&self) -> DynGd<CharacterBody3D, dyn IPlayer> { fn as_gd(&self) -> DynGd<CharacterBody3D, dyn IPlayer> {
@ -500,6 +500,24 @@ impl ICharacterBody3D for LocalPlayer {
fn input(&mut self, event: Gd<InputEvent>) { fn input(&mut self, event: Gd<InputEvent>) {
if self.locked { if self.locked {
if event.is_action_pressed("throw_telegrenade") { 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(pos) = self.raycast_from_camera() {
if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer { if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer {
match peer { match peer {

View File

@ -70,7 +70,7 @@ pub trait IPlayer {
fn try_throw_telegrenade(&mut self, to: Vector3) -> bool; fn try_throw_telegrenade(&mut self, to: Vector3) -> bool;
fn set_telegrenade(&mut self, telegrenade: Option<Gd<Telegrenade>>); fn set_telegrenade(&mut self, telegrenade: Option<Gd<Telegrenade>>);
fn get_telegrenade(&self) -> Option<Gd<Telegrenade>>; fn get_telegrenade(&self) -> Option<Gd<Telegrenade>>;
fn telegrenade_teleport(&mut self, to: Vector3); fn telegrenade_teleport(&mut self, to: Vector3) -> bool;
fn as_gd(&self) -> DynGd<CharacterBody3D, dyn IPlayer>; fn as_gd(&self) -> DynGd<CharacterBody3D, dyn IPlayer>;
} }
@ -83,7 +83,7 @@ pub trait PlayerCommon {
fn try_shoot_common(&mut self, to: Vector3, deal_damage: bool) -> bool; 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 try_punch_common(&mut self, to: Vector3, deal_damage: bool) -> bool;
fn throw_telegrenade_common(&mut self, to: Vector3) -> 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<T: IPlayer + ICharacterBody3D + WithBaseField> PlayerCommon for T { impl<T: IPlayer + ICharacterBody3D + WithBaseField> PlayerCommon for T {
@ -293,12 +293,15 @@ impl<T: IPlayer + ICharacterBody3D + WithBaseField> PlayerCommon for T {
true 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() { if let Some(mut telegrenade) = self.get_telegrenade() {
telegrenade.queue_free(); telegrenade.queue_free();
} else {
return false;
} }
self.set_telegrenade(None); self.set_telegrenade(None);
self.base_mut().set_global_position(to); self.base_mut().set_global_position(to);
true
} }
} }

View File

@ -281,8 +281,8 @@ impl IPlayer for RemotePlayer {
self.telegrenade.clone() self.telegrenade.clone()
} }
fn telegrenade_teleport(&mut self, to: Vector3) { fn telegrenade_teleport(&mut self, to: Vector3) -> bool {
self.telegrenade_teleport_common(to); self.telegrenade_teleport_common(to)
} }
fn as_gd(&self) -> DynGd<CharacterBody3D, dyn IPlayer> { fn as_gd(&self) -> DynGd<CharacterBody3D, dyn IPlayer> {