1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
use vek::Vec2;

pub struct KeyState {
    pub right: bool,
    pub left: bool,
    pub up: bool,
    pub down: bool,
    pub climb_up: bool,
    pub climb_down: bool,
    pub swim_up: bool,
    pub swim_down: bool,
    pub fly: bool,
    pub auto_walk: bool,
    pub speed_mul: f32,
    pub trade: bool,
    pub analog_matrix: Vec2<f32>,
}

impl Default for KeyState {
    fn default() -> Self {
        Self {
            right: false,
            left: false,
            up: false,
            down: false,
            climb_up: false,
            climb_down: false,
            swim_up: false,
            swim_down: false,
            fly: false,
            auto_walk: false,
            speed_mul: 1.0,
            trade: false,
            analog_matrix: Vec2::zero(),
        }
    }
}

impl KeyState {
    pub fn dir_vec(&self) -> Vec2<f32> {
        let dir = if self.analog_matrix == Vec2::zero() {
            Vec2::<f32>::new(
                if self.right { 1.0 } else { 0.0 } + if self.left { -1.0 } else { 0.0 },
                if self.up || self.auto_walk { 1.0 } else { 0.0 }
                    + if self.down { -1.0 } else { 0.0 },
            )
            .try_normalized()
            .unwrap_or_default()
        } else {
            self.analog_matrix
        } * self.speed_mul;

        if dir.magnitude_squared() <= 1.0 {
            dir
        } else {
            dir.normalized()
        }
    }

    pub fn climb(&self) -> Option<common::comp::Climb> {
        use common::comp::Climb;
        match (self.climb_up, self.climb_down) {
            (true, false) => Some(Climb::Up),
            (false, true) => Some(Climb::Down),
            (true, true) => Some(Climb::Hold),
            (false, false) => None,
        }
    }
}