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