Skip to main content

steel_protocol/packets/game/
s_move_player.rs

1use glam::DVec3;
2use steel_macros::{ReadFrom, ServerPacket};
3
4const fn unpack_on_ground(packed_byte: u8) -> bool {
5    packed_byte & 0b0000_0001 != 0
6}
7
8const fn unpack_horizontal_collision(packed_byte: u8) -> bool {
9    packed_byte & 0b0000_0010 != 0
10}
11
12/// Constructed packet by the server to more easily be able to handle movement.
13#[derive(Clone, Debug)]
14pub struct SMovePlayer {
15    pub position: DVec3,
16    pub y_rot: f32,
17    pub x_rot: f32,
18    pub on_ground: bool,
19    pub horizontal_collision: bool,
20    pub has_pos: bool,
21    pub has_rot: bool,
22}
23
24impl SMovePlayer {
25    #[must_use]
26    pub const fn get_x(&self, fallback: f64) -> f64 {
27        if self.has_pos {
28            self.position.x
29        } else {
30            fallback
31        }
32    }
33
34    #[must_use]
35    pub const fn get_y(&self, fallback: f64) -> f64 {
36        if self.has_pos {
37            self.position.y
38        } else {
39            fallback
40        }
41    }
42
43    #[must_use]
44    pub const fn get_z(&self, fallback: f64) -> f64 {
45        if self.has_pos {
46            self.position.z
47        } else {
48            fallback
49        }
50    }
51
52    #[must_use]
53    pub const fn get_x_rot(&self, fallback: f32) -> f32 {
54        if self.has_rot { self.x_rot } else { fallback }
55    }
56
57    #[must_use]
58    pub const fn get_y_rot(&self, fallback: f32) -> f32 {
59        if self.has_rot { self.y_rot } else { fallback }
60    }
61}
62
63#[derive(ReadFrom, Clone, Debug, ServerPacket)]
64pub struct SMovePlayerPos {
65    pub pos: DVec3,
66    pub packed_byte: u8,
67}
68
69impl From<SMovePlayerPos> for SMovePlayer {
70    fn from(value: SMovePlayerPos) -> Self {
71        Self {
72            position: value.pos,
73            has_pos: true,
74            has_rot: false,
75            x_rot: 0.0,
76            y_rot: 0.0,
77            on_ground: unpack_on_ground(value.packed_byte),
78            horizontal_collision: unpack_horizontal_collision(value.packed_byte),
79        }
80    }
81}
82
83#[derive(ReadFrom, Clone, Debug, ServerPacket)]
84pub struct SMovePlayerPosRot {
85    pub pos: DVec3,
86    pub y_rot: f32,
87    pub x_rot: f32,
88    pub packed_byte: u8,
89}
90
91impl From<SMovePlayerPosRot> for SMovePlayer {
92    fn from(value: SMovePlayerPosRot) -> Self {
93        Self {
94            position: value.pos,
95            has_pos: true,
96            has_rot: true,
97            x_rot: value.x_rot,
98            y_rot: value.y_rot,
99            on_ground: unpack_on_ground(value.packed_byte),
100            horizontal_collision: unpack_horizontal_collision(value.packed_byte),
101        }
102    }
103}
104
105#[derive(ReadFrom, Clone, Debug, ServerPacket)]
106pub struct SMovePlayerRot {
107    pub y_rot: f32,
108    pub x_rot: f32,
109    pub packed_byte: u8,
110}
111
112impl From<SMovePlayerRot> for SMovePlayer {
113    fn from(value: SMovePlayerRot) -> Self {
114        Self {
115            position: DVec3::ZERO,
116            has_pos: false,
117            has_rot: true,
118            x_rot: value.x_rot,
119            y_rot: value.y_rot,
120            on_ground: unpack_on_ground(value.packed_byte),
121            horizontal_collision: unpack_horizontal_collision(value.packed_byte),
122        }
123    }
124}
125
126/// Status-only movement packet (no position or rotation, just `on_ground` flag).
127///
128/// Sent by the client when they haven't moved but want to update their ground status.
129#[derive(ReadFrom, Clone, Debug, ServerPacket)]
130pub struct SMovePlayerStatusOnly {
131    pub packed_byte: u8,
132}
133
134impl From<SMovePlayerStatusOnly> for SMovePlayer {
135    fn from(value: SMovePlayerStatusOnly) -> Self {
136        Self {
137            position: DVec3::ZERO,
138            has_pos: false,
139            has_rot: false,
140            x_rot: 0.0,
141            y_rot: 0.0,
142            on_ground: unpack_on_ground(value.packed_byte),
143            horizontal_collision: unpack_horizontal_collision(value.packed_byte),
144        }
145    }
146}