1use std::io::{self, Cursor, Write};
4
5use azalea_buf::{AzBuf, AzaleaRead, AzaleaReadVar, AzaleaWrite, AzaleaWriteVar, BufReadError};
6use azalea_chat::FormattedText;
7use azalea_core::{
8 direction::Direction,
9 position::{BlockPos, GlobalPos, Vec3f32},
10};
11use azalea_inventory::{ItemStack, components};
12use bevy_ecs::component::Component;
13use derive_more::Deref;
14use enum_as_inner::EnumAsInner;
15use uuid::Uuid;
16
17use crate::particle::Particle;
18
19#[derive(Clone, Debug, Deref, PartialEq)]
20pub struct EntityMetadataItems(pub Vec<EntityDataItem>);
21
22#[derive(Clone, Debug, PartialEq)]
23pub struct EntityDataItem {
24 pub index: u8,
27 pub value: EntityDataValue,
28}
29
30impl AzaleaRead for EntityMetadataItems {
31 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
32 let mut metadata = Vec::new();
33 loop {
34 let id = u8::azalea_read(buf)?;
35 if id == 0xff {
36 break;
37 }
38 let value = EntityDataValue::azalea_read(buf)?;
39 metadata.push(EntityDataItem { index: id, value });
40 }
41 Ok(EntityMetadataItems(metadata))
42 }
43}
44
45impl AzaleaWrite for EntityMetadataItems {
46 fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
47 for item in &self.0 {
48 item.index.azalea_write(buf)?;
49 item.value.azalea_write(buf)?;
50 }
51 0xffu8.azalea_write(buf)?;
52 Ok(())
53 }
54}
55
56#[derive(Clone, Debug, EnumAsInner, AzBuf, PartialEq)]
59pub enum EntityDataValue {
60 Byte(u8),
61 Int(#[var] i32),
62 Long(#[var] i64),
63 Float(f32),
64 String(String),
65 FormattedText(FormattedText),
66 OptionalFormattedText(Option<FormattedText>),
67 ItemStack(ItemStack),
68 Boolean(bool),
69 Rotations(Rotations),
70 BlockPos(BlockPos),
71 OptionalBlockPos(Option<BlockPos>),
72 Direction(Direction),
73 OptionalLivingEntityReference(Option<Uuid>),
74 BlockState(azalea_block::BlockState),
75 OptionalBlockState(azalea_block::BlockState),
77 Particle(Particle),
78 Particles(Vec<Particle>),
79 VillagerData(VillagerData),
80 OptionalUnsignedInt(OptionalUnsignedInt),
82 Pose(Pose),
83 CatVariant(azalea_registry::CatVariant),
84 ChickenVariant(azalea_registry::ChickenVariant),
85 CowVariant(azalea_registry::CowVariant),
86 WolfVariant(azalea_registry::WolfVariant),
87 WolfSoundVariant(azalea_registry::WolfSoundVariant),
88 FrogVariant(azalea_registry::FrogVariant),
89 PigVariant(azalea_registry::PigVariant),
90 OptionalGlobalPos(Option<GlobalPos>),
91 PaintingVariant(azalea_registry::PaintingVariant),
92 SnifferState(SnifferStateKind),
93 ArmadilloState(ArmadilloStateKind),
94 CopperGolemState(CopperGolemStateKind),
95 WeatheringCopperState(WeatheringCopperStateKind),
96 Vector3(Vec3f32),
97 Quaternion(Quaternion),
98 ResolvableProfile(components::Profile),
99}
100
101#[derive(Clone, Debug, PartialEq)]
102pub struct OptionalUnsignedInt(pub Option<u32>);
103
104#[derive(Clone, Debug, AzBuf, PartialEq)]
105pub struct Quaternion {
106 pub x: f32,
107 pub y: f32,
108 pub z: f32,
109 pub w: f32,
110}
111
112#[derive(Clone, Debug, Copy, Default, AzBuf, PartialEq)]
115pub enum ArmadilloStateKind {
116 #[default]
117 Idle,
118 Rolling,
119 Scared,
120}
121
122impl AzaleaRead for OptionalUnsignedInt {
123 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
124 let val = u32::azalea_read_var(buf)?;
125 Ok(OptionalUnsignedInt(if val == 0 {
126 None
127 } else {
128 Some(val - 1)
129 }))
130 }
131}
132impl AzaleaWrite for OptionalUnsignedInt {
133 fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
134 match self.0 {
135 Some(val) => (val + 1).azalea_write_var(buf),
136 None => 0u32.azalea_write_var(buf),
137 }
138 }
139}
140
141#[derive(Clone, Debug, AzBuf, Default, PartialEq)]
143pub struct Rotations {
144 pub x: f32,
145 pub y: f32,
146 pub z: f32,
147}
148
149#[derive(Clone, Debug, Copy, AzBuf, Default, Component, Eq, PartialEq)]
150pub enum Pose {
151 #[default]
152 Standing = 0,
153 FallFlying,
154 Sleeping,
155 Swimming,
156 SpinAttack,
157 Crouching,
158 LongJumping,
159 Dying,
160 Croaking,
161 UsingTongue,
162 Sitting,
163 Roaring,
164 Sniffing,
165 Emerging,
166 Digging,
167 Sliding,
168 Shooting,
169 Inhaling,
170}
171
172#[derive(Debug, Clone, AzBuf, PartialEq)]
173pub struct VillagerData {
174 pub kind: azalea_registry::VillagerKind,
175 pub profession: azalea_registry::VillagerProfession,
176 #[var]
177 pub level: u32,
178}
179
180#[derive(Debug, Copy, Clone, AzBuf, Default, PartialEq)]
181pub enum SnifferStateKind {
182 #[default]
183 Idling,
184 FeelingHappy,
185 Scenting,
186 Sniffing,
187 Searching,
188 Digging,
189 Rising,
190}
191
192#[derive(Debug, Copy, Clone, AzBuf, Default, PartialEq)]
193pub enum CopperGolemStateKind {
194 #[default]
195 Idle,
196 GettingItem,
197 GettingNoItem,
198 DroppingItem,
199 DroppingNoItem,
200}
201#[derive(Debug, Copy, Clone, AzBuf, Default, PartialEq)]
202pub enum WeatheringCopperStateKind {
203 #[default]
204 Unaffected,
205 Exposed,
206 Weathered,
207 Oxidized,
208}