steel_utils/types/
gameplay.rs1use std::io::{self, Cursor, Write};
2
3use bitflags::bitflags;
4use serde::{Deserialize, Serialize};
5
6use crate::{
7 codec::VarInt,
8 serial::{ReadFrom, WriteTo},
9};
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
13#[expect(missing_docs, reason = "variant names are self-explanatory")]
14pub enum GameType {
15 Survival = 0,
16 Creative = 1,
17 Adventure = 2,
18 Spectator = 3,
19}
20
21impl GameType {
22 #[must_use]
24 pub const fn name(self) -> &'static str {
25 match self {
26 GameType::Survival => "survival",
27 GameType::Creative => "creative",
28 GameType::Adventure => "adventure",
29 GameType::Spectator => "spectator",
30 }
31 }
32}
33
34impl ReadFrom for GameType {
35 fn read(data: &mut Cursor<&[u8]>) -> io::Result<Self> {
36 let value = VarInt::read(data)?.0;
37 match value {
38 0 => Ok(GameType::Survival),
39 1 => Ok(GameType::Creative),
40 2 => Ok(GameType::Adventure),
41 3 => Ok(GameType::Spectator),
42 _ => Err(io::Error::new(
43 io::ErrorKind::InvalidData,
44 "Invalid GameType",
45 )),
46 }
47 }
48}
49
50impl From<GameType> for i8 {
51 fn from(value: GameType) -> Self {
52 value as i8
53 }
54}
55
56impl From<GameType> for i32 {
57 fn from(value: GameType) -> Self {
58 value as i32
59 }
60}
61
62impl From<GameType> for f32 {
63 fn from(value: GameType) -> Self {
64 f32::from(value as i8)
65 }
66}
67
68impl From<i8> for GameType {
69 fn from(value: i8) -> Self {
70 match value {
71 1 => GameType::Creative,
72 2 => GameType::Adventure,
73 3 => GameType::Spectator,
74 _ => GameType::Survival,
75 }
76 }
77}
78
79impl From<i32> for GameType {
80 fn from(value: i32) -> Self {
81 match value {
82 1 => GameType::Creative,
83 2 => GameType::Adventure,
84 3 => GameType::Spectator,
85 _ => GameType::Survival,
86 }
87 }
88}
89
90impl From<f32> for GameType {
91 fn from(value: f32) -> Self {
92 match value {
93 1. => GameType::Creative,
94 2. => GameType::Adventure,
95 3. => GameType::Spectator,
96 _ => GameType::Survival,
97 }
98 }
99}
100
101#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
106#[repr(u8)]
107pub enum Difficulty {
108 Peaceful = 0,
110 Easy = 1,
112 #[default]
114 Normal = 2,
115 Hard = 3,
117}
118
119#[expect(clippy::match_same_arms, reason = "cause it looks better")]
120impl From<u8> for Difficulty {
121 fn from(value: u8) -> Self {
122 match value {
123 0 => Difficulty::Peaceful,
124 1 => Difficulty::Easy,
125 2 => Difficulty::Normal,
126 3 => Difficulty::Hard,
127 _ => Difficulty::Normal,
128 }
129 }
130}
131
132impl From<Difficulty> for u8 {
133 fn from(value: Difficulty) -> Self {
134 value as u8
135 }
136}
137
138impl ReadFrom for Difficulty {
139 fn read(data: &mut Cursor<&[u8]>) -> io::Result<Self> {
140 let value = <u8 as ReadFrom>::read(data)?;
141 match value {
142 0 => Ok(Difficulty::Peaceful),
143 1 => Ok(Difficulty::Easy),
144 2 => Ok(Difficulty::Normal),
145 3 => Ok(Difficulty::Hard),
146 _ => Err(io::Error::new(
147 io::ErrorKind::InvalidData,
148 format!("Invalid Difficulty: {value}"),
149 )),
150 }
151 }
152}
153
154impl WriteTo for Difficulty {
155 fn write(&self, writer: &mut impl Write) -> io::Result<()> {
156 (*self as u8).write(writer)
157 }
158}
159
160impl Serialize for Difficulty {
161 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
162 where
163 S: serde::Serializer,
164 {
165 serializer.serialize_u8(*self as u8)
166 }
167}
168
169impl<'de> Deserialize<'de> for Difficulty {
170 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
171 where
172 D: serde::Deserializer<'de>,
173 {
174 let id = u8::deserialize(deserializer)?;
175 Ok(Self::from(id))
176 }
177}
178
179#[derive(Debug, Clone, Copy, PartialEq, Eq)]
181pub enum InteractionHand {
182 MainHand,
184 OffHand,
186}
187
188impl ReadFrom for InteractionHand {
189 fn read(data: &mut Cursor<&[u8]>) -> io::Result<Self> {
190 let id = VarInt::read(data)?.0;
191 match id {
192 0 => Ok(InteractionHand::MainHand),
193 1 => Ok(InteractionHand::OffHand),
194 _ => Err(io::Error::other("Invalid InteractionHand id")),
195 }
196 }
197}
198
199#[derive(Clone, Copy, Debug, PartialEq, Eq)]
201pub struct UpdateFlags(u16);
202
203bitflags! {
204 impl UpdateFlags: u16 {
205 const UPDATE_NEIGHBORS = 1;
206 const UPDATE_CLIENTS = 1 << 1;
207 const UPDATE_INVISIBLE = 1 << 2;
208 const UPDATE_IMMEDIATE = 1 << 3;
209 const UPDATE_KNOWN_SHAPE = 1 << 4;
210 const UPDATE_SUPPRESS_DROPS = 1 << 5;
211 const UPDATE_MOVE_BY_PISTON = 1 << 6;
212 const UPDATE_SKIP_SHAPE_UPDATE_ON_WIRE = 1 << 7;
213 const UPDATE_SKIP_BLOCK_ENTITY_SIDEEFFECTS = 1 << 8;
214 const UPDATE_SKIP_ON_PLACE = 1 << 9;
215
216 const UPDATE_NONE = Self::UPDATE_INVISIBLE.bits() | Self::UPDATE_SKIP_BLOCK_ENTITY_SIDEEFFECTS.bits();
217 const UPDATE_ALL = Self::UPDATE_NEIGHBORS.bits() | Self::UPDATE_CLIENTS.bits();
218 const UPDATE_ALL_IMMEDIATE = Self::UPDATE_ALL.bits() | Self::UPDATE_IMMEDIATE.bits();
219 }
220}