use bevy::prelude::*;
use super::Target;
use crate::game::GameTimeDelta;
pub struct TargettedTool {
pub cone: f32,
pub range: f32,
pub armed: bool,
pub firing: bool
}
pub struct Cooldown {
pub remaining: f32,
pub duration: f32,
}
impl Cooldown {
pub fn reset(&mut self) {
self.remaining = self.duration;
}
pub fn is_ready(&self) -> bool { self.remaining <= 0.0 }
pub fn new(duration: f32) -> Self {
Cooldown { remaining: duration, duration }
}
}
pub fn update_cooldowns(
dt: Res<GameTimeDelta>,
mut query: Query<&mut Cooldown>
) {
for mut cooldown in query.iter_mut() {
cooldown.remaining -= dt.0;
}
}
pub fn fire_targetted_tools(
mut query: Query<(
&mut Cooldown,
&mut TargettedTool,
&Target,
&GlobalTransform
)>,
pos_query: Query<&GlobalTransform>
) {
for (mut cooldown, mut tool, target, transform) in query.iter_mut() {
if target.0.is_none() {
continue;
}
if !tool.armed {
continue;
}
if !cooldown.is_ready() {
continue;
}
match pos_query.get_component::<GlobalTransform>(target.0.expect("target is None")) {
Err(_) => { continue },
Ok(target_transform) => {
let delta = target_transform.translation - transform.translation;
if delta.length_squared() > tool.range * tool.range {
continue;
}
let projection = delta.normalize().dot(transform.local_y().normalize());
if projection < (tool.cone / 2.0).cos() {
continue;
}
tool.firing = true;
cooldown.reset();
}
}
}
}
#[derive(PartialEq, Clone, Hash, Debug, Eq, SystemLabel)]
pub enum ToolSystems {
FireTargettedTools,
UpdateCooldowns
}