mcproto_types/teleport_flags.rs
1//! Minecraft protocol teleport flags.
2
3use mcproto_codec::error::{CodecError, CodecKind};
4
5use crate::{TypeCodec, basic::Int};
6
7bitflags::bitflags! {
8 /// Specifies how teleportation is applied to position, rotation, and velocity.
9 ///
10 /// Teleport flags are represented on the wire as a four-byte [`Int`]. For
11 /// each of the lower eight bits, a set bit makes the corresponding value
12 /// relative and an unset bit makes it absolute. Bit `0x0100` additionally
13 /// rotates velocity by the teleport's change in rotation before applying
14 /// the velocity change.
15 ///
16 /// Unknown bits are retained when decoding so values from newer protocol
17 /// versions can be decoded and re-encoded without losing information.
18 ///
19 /// # Examples
20 ///
21 /// ```
22 /// use mcproto_types::{TeleportFlags, TypeCodec};
23 ///
24 /// let flags = TeleportFlags::RELATIVE_X
25 /// | TeleportFlags::RELATIVE_YAW
26 /// | TeleportFlags::ROTATE_VELOCITY;
27 /// let mut encoded = Vec::new();
28 /// flags.encode(&mut encoded)?;
29 /// assert_eq!(encoded, [0x00, 0x00, 0x01, 0x09]);
30 ///
31 /// let mut input = encoded.as_slice();
32 /// assert_eq!(TeleportFlags::decode(&mut input)?, flags);
33 /// assert!(input.is_empty());
34 /// # Ok::<(), mcproto_codec::error::CodecError>(())
35 /// ```
36 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
37 pub struct TeleportFlags: u32 {
38 /// Apply the X position relatively.
39 const RELATIVE_X = 0x0001;
40 /// Apply the Y position relatively.
41 const RELATIVE_Y = 0x0002;
42 /// Apply the Z position relatively.
43 const RELATIVE_Z = 0x0004;
44 /// Apply yaw relatively.
45 const RELATIVE_YAW = 0x0008;
46 /// Apply pitch relatively.
47 const RELATIVE_PITCH = 0x0010;
48 /// Apply X velocity relatively.
49 const RELATIVE_VELOCITY_X = 0x0020;
50 /// Apply Y velocity relatively.
51 const RELATIVE_VELOCITY_Y = 0x0040;
52 /// Apply Z velocity relatively.
53 const RELATIVE_VELOCITY_Z = 0x0080;
54 /// Rotate velocity by the change in rotation before applying its change.
55 const ROTATE_VELOCITY = 0x0100;
56 }
57}
58
59impl TypeCodec for TeleportFlags {
60 fn encode(&self, writer: &mut impl std::io::Write) -> Result<(), CodecError> {
61 Int(self.bits() as i32)
62 .encode(writer)
63 .map_err(|error| error.with_context(CodecKind::TeleportFlags))
64 }
65
66 fn decode(reader: &mut impl std::io::Read) -> Result<Self, CodecError> {
67 let bits = Int::decode(reader)
68 .map_err(|error| error.with_context(CodecKind::TeleportFlags))?
69 .0 as u32;
70 Ok(Self::from_bits_retain(bits))
71 }
72}