Skip to main content

azalea_physics/
client_movement.rs

1use azalea_core::position::Vec2;
2use bevy_ecs::component::Component;
3
4/// Component for entities that can move and sprint.
5///
6/// Usually only present for [`LocalEntity`]s.
7///
8/// [`LocalEntity`]: azalea_entity::LocalEntity
9#[derive(Clone, Component, Default)]
10pub struct ClientMovementState {
11    /// Minecraft only sends a movement packet either after 20 ticks or if the
12    /// player moved enough. This is that tick counter.
13    pub position_remainder: u32,
14    pub was_sprinting: bool,
15    // Whether we're going to try to start sprinting this tick. Equivalent to
16    // holding down ctrl for a tick.
17    pub trying_to_sprint: bool,
18
19    /// Whether our player is currently trying to sneak.
20    ///
21    /// This is distinct from
22    /// [`AbstractEntityShiftKeyDown`](azalea_entity::metadata::AbstractEntityShiftKeyDown),
23    /// which is a metadata value that is controlled by the server and affects
24    /// how the nametags of other entities are displayed.
25    ///
26    /// To check whether we're actually sneaking, you can check the
27    /// [`Crouching`](azalea_entity::Crouching) or [`Pose`](azalea_entity::Pose)
28    /// components.
29    pub trying_to_crouch: bool,
30
31    pub move_direction: WalkDirection,
32    pub move_vector: Vec2,
33}
34
35/// A direction that a player can walk in, including none.
36///
37/// Superset of [`SprintDirection`].
38///
39/// This can be freely converted to and from [`DirectionStates`].
40#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
41pub enum WalkDirection {
42    #[default]
43    None,
44    Forward,
45    Backward,
46    Left,
47    Right,
48    ForwardRight,
49    ForwardLeft,
50    BackwardRight,
51    BackwardLeft,
52}
53impl WalkDirection {
54    /// Returns true if the direction is forward, forward-right, or
55    /// forward-left.
56    pub fn forward(self) -> bool {
57        DirectionStates::from(self).forward
58    }
59    /// Returns true if the direction is backward, backward-right, or
60    /// backward-left.
61    pub fn backward(self) -> bool {
62        DirectionStates::from(self).backward
63    }
64    /// Returns true if the direction is left, forward-left, or backward-left.
65    pub fn left(self) -> bool {
66        DirectionStates::from(self).left
67    }
68    /// Returns true if the direction is right, forward-right, or
69    /// backward-right.
70    pub fn right(self) -> bool {
71        DirectionStates::from(self).right
72    }
73
74    pub fn set_forward(&mut self, value: bool) {
75        let mut d = DirectionStates::from(*self);
76        d.forward = value;
77        *self = d.into();
78    }
79    pub fn set_backward(&mut self, value: bool) {
80        let mut d = DirectionStates::from(*self);
81        d.backward = value;
82        *self = d.into();
83    }
84    pub fn set_left(&mut self, value: bool) {
85        let mut d = DirectionStates::from(*self);
86        d.left = value;
87        *self = d.into();
88    }
89    pub fn set_right(&mut self, value: bool) {
90        let mut d = DirectionStates::from(*self);
91        d.right = value;
92        *self = d.into();
93    }
94}
95/// A struct containing fields for each direction.
96///
97/// This can be freely converted to and from a [`WalkDirection`], and may
98/// simplify certain movement direction checks.
99#[derive(Default)]
100pub struct DirectionStates {
101    pub forward: bool,
102    pub backward: bool,
103    pub left: bool,
104    pub right: bool,
105}
106impl From<WalkDirection> for DirectionStates {
107    fn from(d: WalkDirection) -> Self {
108        let mut s = Self::default();
109        match d {
110            WalkDirection::None => {}
111            WalkDirection::Forward => s.forward = true,
112            WalkDirection::Backward => s.backward = true,
113            WalkDirection::Left => s.left = true,
114            WalkDirection::Right => s.right = true,
115            WalkDirection::ForwardRight => {
116                s.forward = true;
117                s.right = true
118            }
119            WalkDirection::ForwardLeft => {
120                s.forward = true;
121                s.left = true
122            }
123            WalkDirection::BackwardRight => {
124                s.backward = true;
125                s.right = true
126            }
127            WalkDirection::BackwardLeft => {
128                s.forward = true;
129                s.left = true
130            }
131        };
132        s
133    }
134}
135impl From<DirectionStates> for WalkDirection {
136    fn from(d: DirectionStates) -> Self {
137        let left = d.left && !d.right;
138        let right = d.right && !d.left;
139
140        if d.forward && !d.backward {
141            if right {
142                return Self::ForwardRight;
143            } else if left {
144                return Self::ForwardLeft;
145            }
146            return Self::Forward;
147        } else if d.backward && !d.forward {
148            if right {
149                return Self::BackwardRight;
150            } else if left {
151                return Self::BackwardLeft;
152            }
153            return Self::Backward;
154        }
155        if right {
156            return Self::Right;
157        } else if left {
158            return Self::Left;
159        }
160        Self::None
161    }
162}
163
164/// The directions that a player can sprint in. It's a subset of
165/// [`WalkDirection`].
166#[derive(Clone, Copy, Debug)]
167pub enum SprintDirection {
168    Forward,
169    ForwardRight,
170    ForwardLeft,
171}
172
173impl From<SprintDirection> for WalkDirection {
174    fn from(d: SprintDirection) -> Self {
175        match d {
176            SprintDirection::Forward => WalkDirection::Forward,
177            SprintDirection::ForwardRight => WalkDirection::ForwardRight,
178            SprintDirection::ForwardLeft => WalkDirection::ForwardLeft,
179        }
180    }
181}