//! Jumper states use bevy::time::Stopwatch; use super::*; /// Entity awaits until [AiTarget] comes closer, then transits to [Approaching] #[derive(Component, Clone, Copy, PartialEq, Debug, Default, Reflect)] #[reflect(Component, Clone, PartialEq, Debug, Default)] pub struct Idle; impl Idle { /// Minimal distance required for next state in pixels pub const MIN_DISTANCE: f32 = meters(4.); } /// Approaches distance, required to jump, awaits for next [BpmTimer](crate::timer::BpmTimer) tick, then transits to [Attacking] /// If target distances from entity very far, transits to [Idle] #[derive(Component, Clone, Copy, PartialEq, Debug, Reflect, Default)] #[reflect(Component, Clone, PartialEq, Debug, Default)] pub struct Approaching; impl Approaching { /// Minimal distance in pixels, when entity should transit to [Attacking] pub const MIN_DISTANCE: f32 = meters(2.); /// Maximal distance in pixels, when entity should transit to [Attacking] pub const MAX_DISTANCE: f32 = meters(3.); /// Distance in pixels, when entity should transit to [Idle] pub const MAX_RANGE: f32 = meters(6.); /// Approaching speed, px/s pub const SPEED: f32 = meters(0.5); } /// Jumps at the [AiTarget] /// If target was reached and jumper was not hit, it deals damage /// Transits to [Approaching] when reaches the floor #[derive(Component, Clone, Debug, Reflect)] #[reflect(Component, Clone, Debug)] pub struct Attacking { /// May deal damage to [AiTarget] pub may_attack: bool, } impl Attacking { /// Constructs new [Attacking] state pub fn new() -> Self { Self { may_attack: true } } /// Damage applied to the [AiTarget] pub const DAMAGE: f32 = 20.; }