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;
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)]
20pub struct EntityMetadataItems(pub Vec<EntityDataItem>);
21
22#[derive(Clone, Debug)]
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)]
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 CompoundTag(simdnbt::owned::NbtCompound),
78 Particle(Particle),
79 Particles(Vec<Particle>),
80 VillagerData(VillagerData),
81 OptionalUnsignedInt(OptionalUnsignedInt),
83 Pose(Pose),
84 CatVariant(azalea_registry::CatVariant),
85 ChickenVariant(azalea_registry::ChickenVariant),
86 CowVariant(azalea_registry::CowVariant),
87 WolfVariant(azalea_registry::WolfVariant),
88 WolfSoundVariant(azalea_registry::WolfSoundVariant),
89 FrogVariant(azalea_registry::FrogVariant),
90 PigVariant(azalea_registry::PigVariant),
91 OptionalGlobalPos(Option<GlobalPos>),
92 PaintingVariant(azalea_registry::PaintingVariant),
93 SnifferState(SnifferStateKind),
94 ArmadilloState(ArmadilloStateKind),
95 Vector3(Vec3f32),
96 Quaternion(Quaternion),
97}
98
99#[derive(Clone, Debug)]
100pub struct OptionalUnsignedInt(pub Option<u32>);
101
102#[derive(Clone, Debug, AzBuf)]
103pub struct Quaternion {
104 pub x: f32,
105 pub y: f32,
106 pub z: f32,
107 pub w: f32,
108}
109
110#[derive(Clone, Debug, Copy, Default, AzBuf)]
113pub enum ArmadilloStateKind {
114 #[default]
115 Idle,
116 Rolling,
117 Scared,
118}
119
120impl AzaleaRead for OptionalUnsignedInt {
121 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
122 let val = u32::azalea_read_var(buf)?;
123 Ok(OptionalUnsignedInt(if val == 0 {
124 None
125 } else {
126 Some(val - 1)
127 }))
128 }
129}
130impl AzaleaWrite for OptionalUnsignedInt {
131 fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
132 match self.0 {
133 Some(val) => (val + 1).azalea_write_var(buf),
134 None => 0u32.azalea_write_var(buf),
135 }
136 }
137}
138
139#[derive(Clone, Debug, AzBuf, Default)]
141pub struct Rotations {
142 pub x: f32,
143 pub y: f32,
144 pub z: f32,
145}
146
147#[derive(Clone, Debug, Copy, AzBuf, Default, Component, Eq, PartialEq)]
148pub enum Pose {
149 #[default]
150 Standing = 0,
151 FallFlying,
152 Sleeping,
153 Swimming,
154 SpinAttack,
155 Crouching,
156 LongJumping,
157 Dying,
158 Croaking,
159 UsingTongue,
160 Sitting,
161 Roaring,
162 Sniffing,
163 Emerging,
164 Digging,
165 Sliding,
166 Shooting,
167 Inhaling,
168}
169
170#[derive(Debug, Clone, AzBuf)]
171pub struct VillagerData {
172 pub kind: azalea_registry::VillagerKind,
173 pub profession: azalea_registry::VillagerProfession,
174 #[var]
175 pub level: u32,
176}
177
178#[derive(Debug, Copy, Clone, AzBuf, Default)]
179pub enum SnifferStateKind {
180 #[default]
181 Idling,
182 FeelingHappy,
183 Scenting,
184 Sniffing,
185 Searching,
186 Digging,
187 Rising,
188}