quakeball-rust/rust/src/soldier_mesh.rs

85 lines
2.2 KiB
Rust

use godot::{
classes::{AnimationTree, Skeleton3D},
prelude::*,
};
use crate::weapon::{BallWeapon, Raygun, Weapon};
#[derive(GodotClass)]
#[class(base=Node3D, init)]
pub struct SoldierMesh {
#[export]
hand_attachment: Option<Gd<Node3D>>,
#[export]
animation_tree: Option<Gd<AnimationTree>>,
#[export]
skeleton: Option<Gd<Skeleton3D>>,
#[export]
raygun: Option<Gd<PackedScene>>,
#[export]
ball: Option<Gd<PackedScene>>,
#[export]
look_at: Option<Gd<Node3D>>,
pub current_weapon: Option<DynGd<Node3D, dyn Weapon>>,
base: Base<Node3D>,
}
#[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<DynGd<Node3D, dyn Weapon>> {
if let Some(raygun) = &self.raygun {
let node = raygun.instantiate_as::<Raygun>();
self.spawn_weapon(node.into_dyn().upcast())
} else {
None
}
}
pub fn spawn_ball(&mut self) -> Option<DynGd<Node3D, dyn Weapon>> {
if let Some(ball) = &self.ball {
let node = ball.instantiate_as::<BallWeapon>();
self.spawn_weapon(node.into_dyn().upcast())
} else {
None
}
}
fn spawn_weapon(
&mut self,
node: DynGd<Node3D, dyn Weapon>,
) -> Option<DynGd<Node3D, dyn Weapon>> {
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<DynGd<Node3D, dyn Weapon>> {
self.current_weapon.clone()
}
}