azalea_entity/
data.rs

1//! Define some types needed for entity metadata.
2
3// TODO: this is here because of a bug in enum_as_inner. remove when it's fixed
4#![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    // we can't identify what the index is for here because we don't know the
28    // entity type
29    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// Note: This enum is partially generated and parsed by
60// codegen/lib/code/entity.py
61#[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    /// If this is air, that means it's absent,
79    OptionalBlockState(azalea_block::BlockState),
80    Particle(Particle),
81    Particles(Vec<Particle>),
82    VillagerData(VillagerData),
83    // 0 for absent; 1 + actual value otherwise. Used for entity IDs.
84    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// mojang just calls this ArmadilloState but i added "Kind" since otherwise it
116// collides with a name in metadata.rs
117#[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/// A set of x, y, and z rotations. This is used for armor stands.
145#[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}