Skip to main content

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}