use godot::{ classes::{AnimationTree, MeshInstance3D, 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] mesh: Option>, #[export] pub raygun: Option>, #[export] pub shotgun: Option>, #[export] pub ball: Option>, #[export] look_at: Option>, #[export] pub hand_remover: Option>, #[export] pub bubble: 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, mut node: DynGd, ) -> Option> { let prev_cd = if let Some(mut weapon) = self.current_weapon.take() { let rem = weapon.dyn_bind().get_remaining_cd(); weapon.queue_free(); rem } else { 0. }; if let Some(hand) = &mut self.hand_attachment { node.dyn_bind_mut().set_remaining_cd(prev_cd); 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() } pub fn set_color(&mut self, color: Color) { if let Some(mesh) = &mut self.mesh && let Some(mut mat) = mesh.get_surface_override_material(0) { mat.set("albedo_color", &color.to_variant()); } } pub fn set_bubble_color(&mut self, color: Color) { if let Some(bubble) = &mut self.bubble && let Some(mut mat) = bubble.get_active_material(0) { mat.set("shader_parameter/BubbleColor", &color.to_variant()); } } }