Spawn ball at ball origin

This commit is contained in:
Sofia 2026-07-21 21:47:49 +03:00
parent a5e1a945a8
commit b93cb1eb39
3 changed files with 50 additions and 43 deletions

View File

@ -8,7 +8,7 @@ glow_enabled = true
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_oh8vq"]
[node name="player" type="LocalPlayer" unique_id=863055906 node_paths=PackedStringArray("camera", "soldier_mesh", "collider", "splorch", "dead_cam_target", "respawn_label")]
[node name="player" type="LocalPlayer" unique_id=863055906 node_paths=PackedStringArray("camera", "soldier_mesh", "collider", "splorch", "dead_cam_target", "respawn_label", "ball_origin")]
look_sensitivity = 1.5
camera = NodePath("camera_3d")
move_speed = 5.0
@ -17,6 +17,7 @@ collider = NodePath("collision_shape_3d2")
splorch = NodePath("splorch")
dead_cam_target = NodePath("dead_camera_target")
respawn_label = NodePath("respawn_label")
ball_origin = NodePath("camera_3d")
health = 100
collision_mask = 4

View File

@ -30,3 +30,6 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.7611488, 0)
[node name="spectate_camera" type="Camera3D" parent="spectate_root" unique_id=1408688016]
transform = Transform3D(1, 0, 0, 0, 0.89379096, 0.44848388, 0, -0.44848388, 0.89379096, 0, 0.6601318, 1.0407685)
[node name="ball_origin" type="Node3D" parent="." unique_id=1445680156]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.8724979, -0.2644562)

View File

@ -52,10 +52,12 @@ pub trait IPlayer {
fn swap_weapon(&mut self, weapon: WeaponType);
fn get_weapon(&self) -> Option<DynGd<Node3D, dyn Weapon>>;
fn drop_ball(&mut self, with_velocity: bool) -> bool;
fn get_ball_origin(&self) -> Option<Gd<Node3D>>;
}
pub trait PlayerMovement {
fn player_update(&mut self, delta: f64);
fn drop_ball_common(&mut self, with_velocity: bool) -> bool;
}
impl<T: IPlayer + ICharacterBody3D + WithBaseField> PlayerMovement for T {
@ -80,6 +82,35 @@ impl<T: IPlayer + ICharacterBody3D + WithBaseField> PlayerMovement for T {
self.base_mut().move_and_slide();
}
}
fn drop_ball_common(&mut self, with_velocity: bool) -> bool {
if let Some(weapon) = self.get_weapon()
&& let Ok(_) = weapon.try_cast::<BallWeapon>()
{
self.run_deferred(|s| {
if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer
&& let PeerKind::Server(peer, _) = peer
{
s.swap_weapon(WeaponType::Raygun);
peer.broadcast_reliable(Package::SwapWeapon(
s.get_player_id().unwrap_or(0),
WeaponType::Raygun,
));
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(),
}));
}
}
}
});
true
} else {
false
}
}
}
#[derive(GodotClass)]
@ -102,6 +133,8 @@ pub struct LocalPlayer {
#[export]
respawn_label: Option<Gd<Label>>,
#[export]
ball_origin: Option<Gd<Node3D>>,
#[export]
health: i32,
pub player_id: Option<u16>,
@ -253,27 +286,11 @@ impl IPlayer for LocalPlayer {
}
fn drop_ball(&mut self, with_velocity: bool) -> bool {
if let Some(weapon) = self.get_weapon()
&& let Ok(_) = weapon.try_cast::<BallWeapon>()
{
self.run_deferred(|s| {
if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer
&& let PeerKind::Server(peer, _) = peer
{
s.swap_weapon(WeaponType::Raygun);
peer.broadcast_reliable(Package::SwapWeapon(
s.player_id.unwrap_or(0),
WeaponType::Raygun,
));
if let Some(mut game) = Game::singleton() {
game.bind_mut().spawn_ball(None);
}
}
});
true
} else {
false
}
self.drop_ball_common(with_velocity)
}
fn get_ball_origin(&self) -> Option<Gd<Node3D>> {
self.ball_origin.clone()
}
}
@ -468,6 +485,8 @@ pub struct RemotePlayer {
health: i32,
#[export]
spectator_camera: Option<Gd<Camera3D>>,
#[export]
ball_origin: Option<Gd<Node3D>>,
pub player_id: Option<u16>,
@ -612,27 +631,11 @@ impl IPlayer for RemotePlayer {
}
fn drop_ball(&mut self, with_velocity: bool) -> bool {
if let Some(weapon) = self.get_weapon()
&& let Ok(_) = weapon.try_cast::<BallWeapon>()
{
self.run_deferred(|s| {
if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer
&& let PeerKind::Server(peer, _) = peer
{
s.swap_weapon(WeaponType::Raygun);
peer.broadcast_reliable(Package::SwapWeapon(
s.player_id.unwrap_or(0),
WeaponType::Raygun,
));
if let Some(mut game) = Game::singleton() {
game.bind_mut().spawn_ball(None);
}
}
});
true
} else {
false
}
self.drop_ball_common(with_velocity)
}
fn get_ball_origin(&self) -> Option<Gd<Node3D>> {
self.ball_origin.clone()
}
}