use godot::{ classes::{AnimationTree, Skeleton3D}, prelude::*, }; use crate::player::{ player_hand_remover::PlayerHandRemover, weapon::{BallWeapon, Raygun, Shotgun, Weapon}, }; #[derive(GodotClass)] #[class(base=Node3D, init)] pub struct SoldierMesh { #[export] hand_attachment: Option>, #[export] animation_tree: Option>, #[export] skeleton: Option>, #[export] pub raygun: Option>, #[export] pub shotgun: Option>, #[export] pub ball: Option>, #[export] look_at: Option>, #[export] pub hand_remover: Option>, pub current_weapon: Option>, base: Base, } #[godot_api] impl INode3D for SoldierMesh { fn ready(&mut self) {} } impl SoldierMesh { pub fn update_movement(&mut self, movement: Vector2) { if let Some(tree) = &mut self.animation_tree { tree.set("parameters/Movement/blend_position", &movement.to_variant()); } } pub fn update_y_look(&mut self, rotation: f32) { if let Some(node) = &mut self.look_at { node.set_rotation(Vector3::RIGHT * -rotation); } } pub fn spawn_raygun(&mut self) -> Option> { if let Some(raygun) = &self.raygun { let node = raygun.instantiate_as::(); self.spawn_weapon(node.into_dyn().upcast()) } else { None } } pub fn spawn_shotgun(&mut self) -> Option> { if let Some(shotgun) = &self.shotgun { let node = shotgun.instantiate_as::(); self.spawn_weapon(node.into_dyn().upcast()) } else { None } } pub fn spawn_ball(&mut self) -> Option> { if let Some(ball) = &self.ball { let node = ball.instantiate_as::(); self.spawn_weapon(node.into_dyn().upcast()) } else { None } } fn spawn_weapon( &mut self, node: DynGd, ) -> Option> { if let Some(mut weapon) = self.current_weapon.take() { weapon.queue_free(); } if let Some(hand) = &mut self.hand_attachment { hand.add_child(&node); self.current_weapon = Some(node.clone()); Some(node) } else { None } } pub fn get_weapon(&self) -> Option> { self.current_weapon.clone() } pub fn take_weapon(&self) -> Option<&DynGd> { self.current_weapon.as_ref().take() } }