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