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    /// Inverts the walk direction.
96    ///
97    /// ```
98    /// assert_eq!(WalkDirection::Forward.opposite(), WalkDirection::Backward);
99    /// assert_eq!(
100    ///     WalkDirection::BackwardRight.opposite(),
101    ///     WalkDirection::ForwardLeft
102    /// );
103    /// assert_eq!(WalkDirection::None.opposite(), WalkDirection::None);
104    /// ```
105    pub fn opposite(self) -> Self {
106        match self {
107            Self::None => Self::None,
108            Self::Forward => Self::Backward,
109            Self::Backward => Self::Forward,
110            Self::Left => Self::Right,
111            Self::Right => Self::Left,
112            Self::ForwardRight => Self::BackwardLeft,
113            Self::ForwardLeft => Self::BackwardRight,
114            Self::BackwardRight => Self::ForwardLeft,
115            Self::BackwardLeft => Self::ForwardRight,
116        }
117    }
118}
119/// A struct containing fields for each direction.
120///
121/// This can be freely converted to and from a [`WalkDirection`], and may
122/// simplify certain movement direction checks.
123#[derive(Default)]
124pub struct DirectionStates {
125    pub forward: bool,
126    pub backward: bool,
127    pub left: bool,
128    pub right: bool,
129}
130impl From<WalkDirection> for DirectionStates {
131    fn from(d: WalkDirection) -> Self {
132        let mut s = Self::default();
133        match d {
134            WalkDirection::None => {}
135            WalkDirection::Forward => s.forward = true,
136            WalkDirection::Backward => s.backward = true,
137            WalkDirection::Left => s.left = true,
138            WalkDirection::Right => s.right = true,
139            WalkDirection::ForwardRight => {
140                s.forward = true;
141                s.right = true
142            }
143            WalkDirection::ForwardLeft => {
144                s.forward = true;
145                s.left = true
146            }
147            WalkDirection::BackwardRight => {
148                s.backward = true;
149                s.right = true
150            }
151            WalkDirection::BackwardLeft => {
152                s.forward = true;
153                s.left = true
154            }
155        };
156        s
157    }
158}
159impl From<DirectionStates> for WalkDirection {
160    fn from(d: DirectionStates) -> Self {
161        let left = d.left && !d.right;
162        let right = d.right && !d.left;
163
164        if d.forward && !d.backward {
165            if right {
166                return Self::ForwardRight;
167            } else if left {
168                return Self::ForwardLeft;
169            }
170            return Self::Forward;
171        } else if d.backward && !d.forward {
172            if right {
173                return Self::BackwardRight;
174            } else if left {
175                return Self::BackwardLeft;
176            }
177            return Self::Backward;
178        }
179        if right {
180            return Self::Right;
181        } else if left {
182            return Self::Left;
183        }
184        Self::None
185    }
186}
187
188/// The directions that a player can sprint in. It's a subset of
189/// [`WalkDirection`].
190#[derive(Clone, Copy, Debug)]
191pub enum SprintDirection {
192    Forward,
193    ForwardRight,
194    ForwardLeft,
195}
196
197impl From<SprintDirection> for WalkDirection {
198    fn from(d: SprintDirection) -> Self {
199        match d {
200            SprintDirection::Forward => WalkDirection::Forward,
201            SprintDirection::ForwardRight => WalkDirection::ForwardRight,
202            SprintDirection::ForwardLeft => WalkDirection::ForwardLeft,
203        }
204    }
205}