Skip to main content

veloren_voxygen/ecs/
comp.rs

1use common::{comp::Ori, outcome::HealthChangeInfo};
2use specs::{Component, VecStorage};
3use vek::*;
4
5// Floats over entity that has had a health change, rising up over time until it
6// vanishes
7#[derive(Copy, Clone, Debug)]
8pub struct HpFloater {
9    pub timer: f32,
10    // Used for the "jumping" animation of the HpFloater whenever it changes it's value
11    pub jump_timer: f32,
12    pub info: HealthChangeInfo,
13    // Used for randomly offsetting
14    pub rand: f32,
15}
16#[derive(Clone, Debug, Default)]
17pub struct HpFloaterList {
18    // Order oldest to newest
19    pub floaters: Vec<HpFloater>,
20
21    // The time since you last damaged this entity
22    // Used to display nametags outside normal range if this time is below a certain value
23    pub time_since_last_dmg_by_me: Option<f32>,
24}
25impl Component for HpFloaterList {
26    type Storage = VecStorage<Self>;
27}
28
29// Used for smooth interpolation of visual elements that are tied to entity
30// position
31#[derive(Copy, Clone, Debug)]
32pub struct Interpolated {
33    pub pos: Vec3<f32>,
34    pub ori: Ori,
35}
36impl Component for Interpolated {
37    type Storage = VecStorage<Self>;
38}
39
40const MAX_FEET: usize = 8;
41
42/// Track footsteps over time by detecting flips in foot velocity.
43#[derive(Default)]
44pub struct Footsteps {
45    // What were the last known foot positions?
46    foot_state: [Option<[f32; 2]>; MAX_FEET],
47    // Did a step just occur?
48    stepped: [bool; MAX_FEET],
49}
50impl Component for Footsteps {
51    type Storage = VecStorage<Self>;
52}
53
54impl Footsteps {
55    pub fn update(&mut self, foot_z: &[f32]) {
56        self.stepped = [false; MAX_FEET];
57        for (i, foot_z) in foot_z.iter().take(MAX_FEET).enumerate() {
58            match &mut self.foot_state[i] {
59                Some([a, b]) => {
60                    // Position second differential flipped - footstep detected!
61                    if a > b && *b < *foot_z {
62                        self.stepped[i] = true;
63                    }
64                    *a = *b;
65                    *b = *foot_z;
66                },
67                foot_state @ None => *foot_state = Some([*foot_z; 2]),
68            }
69        }
70    }
71
72    pub fn is_stepping(&self, foot: usize) -> bool {
73        self.stepped.get(foot).copied().unwrap_or(false)
74    }
75
76    pub fn is_any_stepping(&self) -> bool { self.stepped.iter().any(|x| *x) }
77}