use godot::{ classes::{IRigidBody3D, RigidBody3D}, prelude::*, }; use crate::player::{IPlayer, NetTransform}; #[derive(GodotClass)] #[class(base=RigidBody3D, init)] pub struct Ball { pub dropper: Option, alive_for: f64, base: Base, } #[godot_api] impl IRigidBody3D for Ball { fn ready(&mut self) { self.base() .signals() .body_entered() .connect_other(self, |s, body| s.on_collision(body)); } fn process(&mut self, delta: f64) { self.alive_for += delta; } } #[godot_api] impl Ball { #[signal] pub fn on_ball_pickup(player_id: u16); pub fn get_transform(&self) -> NetTransform { NetTransform { location: self.base().get_global_position().into(), rotation: self.base().get_global_rotation().into(), } } fn on_collision(&mut self, node: Gd) { 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)); } } }