azalea_inventory/
components.rs

1use core::f64;
2use std::{any::Any, collections::HashMap, io::Cursor};
3
4use azalea_buf::{AzBuf, AzaleaRead, AzaleaWrite, BufReadError};
5use azalea_chat::FormattedText;
6use azalea_core::{
7    filterable::Filterable, position::GlobalPos, resource_location::ResourceLocation,
8    sound::CustomSound,
9};
10use azalea_registry::{
11    self as registry, Attribute, Block, ConsumeEffectKind, DamageKind, DataComponentKind,
12    Enchantment, EntityKind, Holder, HolderSet, Item, MobEffect, Potion, SoundEvent, TrimMaterial,
13    TrimPattern,
14};
15use simdnbt::owned::{Nbt, NbtCompound};
16use tracing::trace;
17use uuid::Uuid;
18
19use crate::{ItemStack, item::consume_effect::ConsumeEffect};
20
21pub trait DataComponent: Send + Sync + Any {
22    const KIND: DataComponentKind;
23}
24
25pub trait EncodableDataComponent: Send + Sync + Any {
26    fn encode(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error>;
27    // using the Clone trait makes it not be object-safe, so we have our own clone
28    // function instead
29    fn clone(&self) -> Box<dyn EncodableDataComponent>;
30    // same deal here
31    fn eq(&self, other: Box<dyn EncodableDataComponent>) -> bool;
32}
33
34impl<T> EncodableDataComponent for T
35where
36    T: DataComponent + Clone + AzaleaWrite + AzaleaRead + PartialEq,
37{
38    fn encode(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
39        self.azalea_write(buf)
40    }
41    fn clone(&self) -> Box<dyn EncodableDataComponent> {
42        let cloned = self.clone();
43        Box::new(cloned)
44    }
45    fn eq(&self, other: Box<dyn EncodableDataComponent>) -> bool {
46        let other_any: Box<dyn Any> = other;
47        match other_any.downcast_ref::<T>() {
48            Some(other) => self == other,
49            _ => false,
50        }
51    }
52}
53
54pub fn from_kind(
55    kind: registry::DataComponentKind,
56    buf: &mut Cursor<&[u8]>,
57) -> Result<Box<dyn EncodableDataComponent>, BufReadError> {
58    // if this is causing a compile-time error, look at DataComponents.java in the
59    // decompiled vanilla code to see how to implement new components
60
61    trace!("Reading data component {kind}");
62
63    // note that this match statement is updated by genitemcomponents.py
64    Ok(match kind {
65        DataComponentKind::CustomData => Box::new(CustomData::azalea_read(buf)?),
66        DataComponentKind::MaxStackSize => Box::new(MaxStackSize::azalea_read(buf)?),
67        DataComponentKind::MaxDamage => Box::new(MaxDamage::azalea_read(buf)?),
68        DataComponentKind::Damage => Box::new(Damage::azalea_read(buf)?),
69        DataComponentKind::Unbreakable => Box::new(Unbreakable::azalea_read(buf)?),
70        DataComponentKind::CustomName => Box::new(CustomName::azalea_read(buf)?),
71        DataComponentKind::ItemName => Box::new(ItemName::azalea_read(buf)?),
72        DataComponentKind::Lore => Box::new(Lore::azalea_read(buf)?),
73        DataComponentKind::Rarity => Box::new(Rarity::azalea_read(buf)?),
74        DataComponentKind::Enchantments => Box::new(Enchantments::azalea_read(buf)?),
75        DataComponentKind::CanPlaceOn => Box::new(CanPlaceOn::azalea_read(buf)?),
76        DataComponentKind::CanBreak => Box::new(CanBreak::azalea_read(buf)?),
77        DataComponentKind::AttributeModifiers => Box::new(AttributeModifiers::azalea_read(buf)?),
78        DataComponentKind::CustomModelData => Box::new(CustomModelData::azalea_read(buf)?),
79        DataComponentKind::RepairCost => Box::new(RepairCost::azalea_read(buf)?),
80        DataComponentKind::CreativeSlotLock => Box::new(CreativeSlotLock::azalea_read(buf)?),
81        DataComponentKind::EnchantmentGlintOverride => {
82            Box::new(EnchantmentGlintOverride::azalea_read(buf)?)
83        }
84        DataComponentKind::IntangibleProjectile => {
85            Box::new(IntangibleProjectile::azalea_read(buf)?)
86        }
87        DataComponentKind::Food => Box::new(Food::azalea_read(buf)?),
88        DataComponentKind::Tool => Box::new(Tool::azalea_read(buf)?),
89        DataComponentKind::StoredEnchantments => Box::new(StoredEnchantments::azalea_read(buf)?),
90        DataComponentKind::DyedColor => Box::new(DyedColor::azalea_read(buf)?),
91        DataComponentKind::MapColor => Box::new(MapColor::azalea_read(buf)?),
92        DataComponentKind::MapId => Box::new(MapId::azalea_read(buf)?),
93        DataComponentKind::MapDecorations => Box::new(MapDecorations::azalea_read(buf)?),
94        DataComponentKind::MapPostProcessing => Box::new(MapPostProcessing::azalea_read(buf)?),
95        DataComponentKind::ChargedProjectiles => Box::new(ChargedProjectiles::azalea_read(buf)?),
96        DataComponentKind::BundleContents => Box::new(BundleContents::azalea_read(buf)?),
97        DataComponentKind::PotionContents => Box::new(PotionContents::azalea_read(buf)?),
98        DataComponentKind::SuspiciousStewEffects => {
99            Box::new(SuspiciousStewEffects::azalea_read(buf)?)
100        }
101        DataComponentKind::WritableBookContent => Box::new(WritableBookContent::azalea_read(buf)?),
102        DataComponentKind::WrittenBookContent => Box::new(WrittenBookContent::azalea_read(buf)?),
103        DataComponentKind::Trim => Box::new(Trim::azalea_read(buf)?),
104        DataComponentKind::DebugStickState => Box::new(DebugStickState::azalea_read(buf)?),
105        DataComponentKind::EntityData => Box::new(EntityData::azalea_read(buf)?),
106        DataComponentKind::BucketEntityData => Box::new(BucketEntityData::azalea_read(buf)?),
107        DataComponentKind::BlockEntityData => Box::new(BlockEntityData::azalea_read(buf)?),
108        DataComponentKind::Instrument => Box::new(Instrument::azalea_read(buf)?),
109        DataComponentKind::OminousBottleAmplifier => {
110            Box::new(OminousBottleAmplifier::azalea_read(buf)?)
111        }
112        DataComponentKind::Recipes => Box::new(Recipes::azalea_read(buf)?),
113        DataComponentKind::LodestoneTracker => Box::new(LodestoneTracker::azalea_read(buf)?),
114        DataComponentKind::FireworkExplosion => Box::new(FireworkExplosion::azalea_read(buf)?),
115        DataComponentKind::Fireworks => Box::new(Fireworks::azalea_read(buf)?),
116        DataComponentKind::Profile => Box::new(Profile::azalea_read(buf)?),
117        DataComponentKind::NoteBlockSound => Box::new(NoteBlockSound::azalea_read(buf)?),
118        DataComponentKind::BannerPatterns => Box::new(BannerPatterns::azalea_read(buf)?),
119        DataComponentKind::BaseColor => Box::new(BaseColor::azalea_read(buf)?),
120        DataComponentKind::PotDecorations => Box::new(PotDecorations::azalea_read(buf)?),
121        DataComponentKind::Container => Box::new(Container::azalea_read(buf)?),
122        DataComponentKind::BlockState => Box::new(BlockState::azalea_read(buf)?),
123        DataComponentKind::Bees => Box::new(Bees::azalea_read(buf)?),
124        DataComponentKind::Lock => Box::new(Lock::azalea_read(buf)?),
125        DataComponentKind::ContainerLoot => Box::new(ContainerLoot::azalea_read(buf)?),
126        DataComponentKind::JukeboxPlayable => Box::new(JukeboxPlayable::azalea_read(buf)?),
127        DataComponentKind::Consumable => Box::new(Consumable::azalea_read(buf)?),
128        DataComponentKind::UseRemainder => Box::new(UseRemainder::azalea_read(buf)?),
129        DataComponentKind::UseCooldown => Box::new(UseCooldown::azalea_read(buf)?),
130        DataComponentKind::Enchantable => Box::new(Enchantable::azalea_read(buf)?),
131        DataComponentKind::Repairable => Box::new(Repairable::azalea_read(buf)?),
132        DataComponentKind::ItemModel => Box::new(ItemModel::azalea_read(buf)?),
133        DataComponentKind::DamageResistant => Box::new(DamageResistant::azalea_read(buf)?),
134        DataComponentKind::Equippable => Box::new(Equippable::azalea_read(buf)?),
135        DataComponentKind::Glider => Box::new(Glider::azalea_read(buf)?),
136        DataComponentKind::TooltipStyle => Box::new(TooltipStyle::azalea_read(buf)?),
137        DataComponentKind::DeathProtection => Box::new(DeathProtection::azalea_read(buf)?),
138        DataComponentKind::Weapon => Box::new(Weapon::azalea_read(buf)?),
139        DataComponentKind::PotionDurationScale => Box::new(PotionDurationScale::azalea_read(buf)?),
140        DataComponentKind::VillagerVariant => Box::new(VillagerVariant::azalea_read(buf)?),
141        DataComponentKind::WolfVariant => Box::new(WolfVariant::azalea_read(buf)?),
142        DataComponentKind::WolfCollar => Box::new(WolfCollar::azalea_read(buf)?),
143        DataComponentKind::FoxVariant => Box::new(FoxVariant::azalea_read(buf)?),
144        DataComponentKind::SalmonSize => Box::new(SalmonSize::azalea_read(buf)?),
145        DataComponentKind::ParrotVariant => Box::new(ParrotVariant::azalea_read(buf)?),
146        DataComponentKind::TropicalFishPattern => Box::new(TropicalFishPattern::azalea_read(buf)?),
147        DataComponentKind::TropicalFishBaseColor => {
148            Box::new(TropicalFishBaseColor::azalea_read(buf)?)
149        }
150        DataComponentKind::TropicalFishPatternColor => {
151            Box::new(TropicalFishPatternColor::azalea_read(buf)?)
152        }
153        DataComponentKind::MooshroomVariant => Box::new(MooshroomVariant::azalea_read(buf)?),
154        DataComponentKind::RabbitVariant => Box::new(RabbitVariant::azalea_read(buf)?),
155        DataComponentKind::PigVariant => Box::new(PigVariant::azalea_read(buf)?),
156        DataComponentKind::FrogVariant => Box::new(FrogVariant::azalea_read(buf)?),
157        DataComponentKind::HorseVariant => Box::new(HorseVariant::azalea_read(buf)?),
158        DataComponentKind::PaintingVariant => Box::new(PaintingVariant::azalea_read(buf)?),
159        DataComponentKind::LlamaVariant => Box::new(LlamaVariant::azalea_read(buf)?),
160        DataComponentKind::AxolotlVariant => Box::new(AxolotlVariant::azalea_read(buf)?),
161        DataComponentKind::CatVariant => Box::new(CatVariant::azalea_read(buf)?),
162        DataComponentKind::CatCollar => Box::new(CatCollar::azalea_read(buf)?),
163        DataComponentKind::SheepColor => Box::new(SheepColor::azalea_read(buf)?),
164        DataComponentKind::ShulkerColor => Box::new(ShulkerColor::azalea_read(buf)?),
165        DataComponentKind::TooltipDisplay => Box::new(TooltipDisplay::azalea_read(buf)?),
166        DataComponentKind::BlocksAttacks => Box::new(BlocksAttacks::azalea_read(buf)?),
167        DataComponentKind::ProvidesTrimMaterial => {
168            Box::new(ProvidesTrimMaterial::azalea_read(buf)?)
169        }
170        DataComponentKind::ProvidesBannerPatterns => {
171            Box::new(ProvidesBannerPatterns::azalea_read(buf)?)
172        }
173        DataComponentKind::BreakSound => Box::new(BreakSound::azalea_read(buf)?),
174        DataComponentKind::WolfSoundVariant => Box::new(WolfSoundVariant::azalea_read(buf)?),
175        DataComponentKind::CowVariant => Box::new(CowVariant::azalea_read(buf)?),
176        DataComponentKind::ChickenVariant => Box::new(ChickenVariant::azalea_read(buf)?),
177    })
178}
179
180#[derive(Clone, PartialEq, AzBuf)]
181pub struct CustomData {
182    pub nbt: Nbt,
183}
184impl DataComponent for CustomData {
185    const KIND: DataComponentKind = DataComponentKind::CustomData;
186}
187
188#[derive(Clone, PartialEq, AzBuf)]
189pub struct MaxStackSize {
190    #[var]
191    pub count: i32,
192}
193impl DataComponent for MaxStackSize {
194    const KIND: DataComponentKind = DataComponentKind::MaxStackSize;
195}
196
197#[derive(Clone, PartialEq, AzBuf)]
198pub struct MaxDamage {
199    #[var]
200    pub amount: i32,
201}
202impl DataComponent for MaxDamage {
203    const KIND: DataComponentKind = DataComponentKind::MaxDamage;
204}
205
206#[derive(Clone, PartialEq, AzBuf)]
207pub struct Damage {
208    #[var]
209    pub amount: i32,
210}
211
212impl DataComponent for Damage {
213    const KIND: DataComponentKind = DataComponentKind::Damage;
214}
215
216#[derive(Clone, PartialEq, Default, AzBuf)]
217pub struct Unbreakable;
218impl DataComponent for Unbreakable {
219    const KIND: DataComponentKind = DataComponentKind::Unbreakable;
220}
221
222#[derive(Clone, PartialEq, AzBuf)]
223pub struct CustomName {
224    pub name: FormattedText,
225}
226impl DataComponent for CustomName {
227    const KIND: DataComponentKind = DataComponentKind::CustomName;
228}
229
230#[derive(Clone, PartialEq, AzBuf)]
231pub struct ItemName {
232    pub name: FormattedText,
233}
234impl DataComponent for ItemName {
235    const KIND: DataComponentKind = DataComponentKind::ItemName;
236}
237
238#[derive(Clone, PartialEq, AzBuf)]
239pub struct Lore {
240    pub lines: Vec<FormattedText>,
241    // vanilla also has styled_lines here but it doesn't appear to be used for the protocol
242}
243impl DataComponent for Lore {
244    const KIND: DataComponentKind = DataComponentKind::Lore;
245}
246
247#[derive(Clone, PartialEq, Copy, AzBuf)]
248pub enum Rarity {
249    Common,
250    Uncommon,
251    Rare,
252    Epic,
253}
254impl DataComponent for Rarity {
255    const KIND: DataComponentKind = DataComponentKind::Rarity;
256}
257
258#[derive(Clone, PartialEq, AzBuf)]
259pub struct Enchantments {
260    #[var]
261    pub levels: HashMap<Enchantment, u32>,
262}
263impl DataComponent for Enchantments {
264    const KIND: DataComponentKind = DataComponentKind::Enchantments;
265}
266
267#[derive(Clone, PartialEq, AzBuf)]
268pub enum BlockStateValueMatcher {
269    Exact {
270        value: String,
271    },
272    Range {
273        min: Option<String>,
274        max: Option<String>,
275    },
276}
277
278#[derive(Clone, PartialEq, AzBuf)]
279pub struct BlockStatePropertyMatcher {
280    pub name: String,
281    pub value_matcher: BlockStateValueMatcher,
282}
283
284#[derive(Clone, PartialEq, AzBuf)]
285pub struct BlockPredicate {
286    pub blocks: Option<HolderSet<Block, ResourceLocation>>,
287    pub properties: Option<Vec<BlockStatePropertyMatcher>>,
288    pub nbt: Option<NbtCompound>,
289}
290
291#[derive(Clone, PartialEq, AzBuf)]
292pub struct AdventureModePredicate {
293    pub predicates: Vec<BlockPredicate>,
294}
295
296#[derive(Clone, PartialEq, AzBuf)]
297pub struct CanPlaceOn {
298    pub predicate: AdventureModePredicate,
299}
300impl DataComponent for CanPlaceOn {
301    const KIND: DataComponentKind = DataComponentKind::CanPlaceOn;
302}
303
304#[derive(Clone, PartialEq, AzBuf)]
305pub struct CanBreak {
306    pub predicate: AdventureModePredicate,
307}
308impl DataComponent for CanBreak {
309    const KIND: DataComponentKind = DataComponentKind::CanBreak;
310}
311
312#[derive(Clone, Copy, PartialEq, AzBuf)]
313pub enum EquipmentSlotGroup {
314    Any,
315    Mainhand,
316    Offhand,
317    Hand,
318    Feet,
319    Legs,
320    Chest,
321    Head,
322    Armor,
323    Body,
324}
325
326#[derive(Clone, Copy, PartialEq, AzBuf)]
327pub enum AttributeModifierOperation {
328    Addition,
329    MultiplyBase,
330    MultiplyTotal,
331}
332
333// this is duplicated in azalea-entity, BUT the one there has a different
334// protocol format (and we can't use it anyways because it would cause a
335// circular dependency)
336#[derive(Clone, PartialEq, AzBuf)]
337pub struct AttributeModifier {
338    pub id: ResourceLocation,
339    pub amount: f64,
340    pub operation: AttributeModifierOperation,
341}
342
343#[derive(Clone, PartialEq, AzBuf)]
344pub struct AttributeModifiersEntry {
345    pub attribute: Attribute,
346    pub modifier: AttributeModifier,
347    pub slot: EquipmentSlotGroup,
348}
349
350#[derive(Clone, PartialEq, AzBuf)]
351pub struct AttributeModifiers {
352    pub modifiers: Vec<AttributeModifiersEntry>,
353}
354impl DataComponent for AttributeModifiers {
355    const KIND: DataComponentKind = DataComponentKind::AttributeModifiers;
356}
357
358#[derive(Clone, PartialEq, AzBuf)]
359pub struct CustomModelData {
360    pub floats: Vec<f32>,
361    pub flags: Vec<bool>,
362    pub strings: Vec<String>,
363    pub colors: Vec<i32>,
364}
365impl DataComponent for CustomModelData {
366    const KIND: DataComponentKind = DataComponentKind::CustomModelData;
367}
368
369#[derive(Clone, PartialEq, AzBuf)]
370pub struct RepairCost {
371    #[var]
372    pub cost: u32,
373}
374impl DataComponent for RepairCost {
375    const KIND: DataComponentKind = DataComponentKind::RepairCost;
376}
377
378#[derive(Clone, PartialEq, AzBuf)]
379pub struct CreativeSlotLock;
380impl DataComponent for CreativeSlotLock {
381    const KIND: DataComponentKind = DataComponentKind::CreativeSlotLock;
382}
383
384#[derive(Clone, PartialEq, AzBuf)]
385pub struct EnchantmentGlintOverride {
386    pub show_glint: bool,
387}
388impl DataComponent for EnchantmentGlintOverride {
389    const KIND: DataComponentKind = DataComponentKind::EnchantmentGlintOverride;
390}
391
392#[derive(Clone, PartialEq, AzBuf)]
393pub struct IntangibleProjectile;
394impl DataComponent for IntangibleProjectile {
395    const KIND: DataComponentKind = DataComponentKind::IntangibleProjectile;
396}
397
398#[derive(Clone, PartialEq, AzBuf)]
399pub struct MobEffectDetails {
400    #[var]
401    pub amplifier: i32,
402    #[var]
403    pub duration: i32,
404    pub ambient: bool,
405    pub show_particles: bool,
406    pub show_icon: bool,
407    pub hidden_effect: Option<Box<MobEffectDetails>>,
408}
409
410#[derive(Clone, PartialEq, AzBuf)]
411pub struct MobEffectInstance {
412    pub effect: MobEffect,
413    pub details: MobEffectDetails,
414}
415
416#[derive(Clone, PartialEq, AzBuf)]
417pub struct PossibleEffect {
418    pub effect: MobEffectInstance,
419    pub probability: f32,
420}
421
422#[derive(Clone, PartialEq, AzBuf)]
423pub struct Food {
424    #[var]
425    pub nutrition: i32,
426    pub saturation: f32,
427    pub can_always_eat: bool,
428    pub eat_seconds: f32,
429    pub effects: Vec<PossibleEffect>,
430}
431impl DataComponent for Food {
432    const KIND: DataComponentKind = DataComponentKind::Food;
433}
434
435#[derive(Clone, PartialEq, AzBuf)]
436pub struct ToolRule {
437    pub blocks: HolderSet<Block, ResourceLocation>,
438    pub speed: Option<f32>,
439    pub correct_for_drops: Option<bool>,
440}
441
442#[derive(Clone, PartialEq, AzBuf)]
443pub struct Tool {
444    pub rules: Vec<ToolRule>,
445    pub default_mining_speed: f32,
446    #[var]
447    pub damage_per_block: i32,
448}
449impl DataComponent for Tool {
450    const KIND: DataComponentKind = DataComponentKind::Tool;
451}
452
453#[derive(Clone, PartialEq, AzBuf)]
454pub struct StoredEnchantments {
455    #[var]
456    pub enchantments: HashMap<Enchantment, i32>,
457}
458impl DataComponent for StoredEnchantments {
459    const KIND: DataComponentKind = DataComponentKind::StoredEnchantments;
460}
461
462#[derive(Clone, PartialEq, AzBuf)]
463pub struct DyedColor {
464    pub rgb: i32,
465}
466impl DataComponent for DyedColor {
467    const KIND: DataComponentKind = DataComponentKind::DyedColor;
468}
469
470#[derive(Clone, PartialEq, AzBuf)]
471pub struct MapColor {
472    pub color: i32,
473}
474impl DataComponent for MapColor {
475    const KIND: DataComponentKind = DataComponentKind::MapColor;
476}
477
478#[derive(Clone, PartialEq, AzBuf)]
479pub struct MapId {
480    #[var]
481    pub id: i32,
482}
483impl DataComponent for MapId {
484    const KIND: DataComponentKind = DataComponentKind::MapId;
485}
486
487#[derive(Clone, PartialEq, AzBuf)]
488pub struct MapDecorations {
489    pub decorations: NbtCompound,
490}
491impl DataComponent for MapDecorations {
492    const KIND: DataComponentKind = DataComponentKind::MapDecorations;
493}
494
495#[derive(Clone, Copy, PartialEq, AzBuf)]
496pub enum MapPostProcessing {
497    Lock,
498    Scale,
499}
500impl DataComponent for MapPostProcessing {
501    const KIND: DataComponentKind = DataComponentKind::MapPostProcessing;
502}
503
504#[derive(Clone, PartialEq, AzBuf)]
505pub struct ChargedProjectiles {
506    pub items: Vec<ItemStack>,
507}
508impl DataComponent for ChargedProjectiles {
509    const KIND: DataComponentKind = DataComponentKind::ChargedProjectiles;
510}
511
512#[derive(Clone, PartialEq, AzBuf)]
513pub struct BundleContents {
514    pub items: Vec<ItemStack>,
515}
516impl DataComponent for BundleContents {
517    const KIND: DataComponentKind = DataComponentKind::BundleContents;
518}
519
520#[derive(Clone, PartialEq, AzBuf)]
521pub struct PotionContents {
522    pub potion: Option<Potion>,
523    pub custom_color: Option<i32>,
524    pub custom_effects: Vec<MobEffectInstance>,
525    pub custom_name: Option<String>,
526}
527impl DataComponent for PotionContents {
528    const KIND: DataComponentKind = DataComponentKind::PotionContents;
529}
530
531#[derive(Clone, PartialEq, AzBuf)]
532pub struct SuspiciousStewEffect {
533    pub effect: MobEffect,
534    #[var]
535    pub duration: i32,
536}
537
538#[derive(Clone, PartialEq, AzBuf)]
539pub struct SuspiciousStewEffects {
540    pub effects: Vec<SuspiciousStewEffect>,
541}
542impl DataComponent for SuspiciousStewEffects {
543    const KIND: DataComponentKind = DataComponentKind::SuspiciousStewEffects;
544}
545
546#[derive(Clone, PartialEq, AzBuf)]
547pub struct WritableBookContent {
548    pub pages: Vec<String>,
549}
550impl DataComponent for WritableBookContent {
551    const KIND: DataComponentKind = DataComponentKind::WritableBookContent;
552}
553
554#[derive(Clone, PartialEq, AzBuf)]
555pub struct WrittenBookContent {
556    #[limit(32)]
557    pub title: Filterable<String>,
558    pub author: String,
559    #[var]
560    pub generation: i32,
561    pub pages: Vec<Filterable<FormattedText>>,
562    pub resolved: bool,
563}
564
565impl DataComponent for WrittenBookContent {
566    const KIND: DataComponentKind = DataComponentKind::WrittenBookContent;
567}
568
569#[derive(Clone, PartialEq, AzBuf)]
570pub struct Trim {
571    pub material: TrimMaterial,
572    pub pattern: TrimPattern,
573}
574impl DataComponent for Trim {
575    const KIND: DataComponentKind = DataComponentKind::Trim;
576}
577
578#[derive(Clone, PartialEq, AzBuf)]
579pub struct DebugStickState {
580    pub properties: NbtCompound,
581}
582impl DataComponent for DebugStickState {
583    const KIND: DataComponentKind = DataComponentKind::DebugStickState;
584}
585
586#[derive(Clone, PartialEq, AzBuf)]
587pub struct EntityData {
588    pub entity: NbtCompound,
589}
590impl DataComponent for EntityData {
591    const KIND: DataComponentKind = DataComponentKind::EntityData;
592}
593
594#[derive(Clone, PartialEq, AzBuf)]
595pub struct BucketEntityData {
596    pub entity: NbtCompound,
597}
598impl DataComponent for BucketEntityData {
599    const KIND: DataComponentKind = DataComponentKind::BucketEntityData;
600}
601
602#[derive(Clone, PartialEq, AzBuf)]
603pub struct BlockEntityData {
604    pub entity: NbtCompound,
605}
606impl DataComponent for BlockEntityData {
607    const KIND: DataComponentKind = DataComponentKind::BlockEntityData;
608}
609
610#[derive(Clone, PartialEq, Debug, AzBuf)]
611pub enum Instrument {
612    Registry(registry::Instrument),
613    Holder(Holder<registry::Instrument, InstrumentData>),
614}
615impl DataComponent for Instrument {
616    const KIND: DataComponentKind = DataComponentKind::Instrument;
617}
618
619#[derive(Clone, PartialEq, Debug, AzBuf)]
620pub struct InstrumentData {
621    pub sound_event: Holder<SoundEvent, azalea_core::sound::CustomSound>,
622    pub use_duration: f32,
623    pub range: f32,
624    pub description: FormattedText,
625}
626
627#[derive(Clone, PartialEq, AzBuf)]
628pub struct OminousBottleAmplifier {
629    #[var]
630    pub amplifier: i32,
631}
632impl DataComponent for OminousBottleAmplifier {
633    const KIND: DataComponentKind = DataComponentKind::OminousBottleAmplifier;
634}
635
636#[derive(Clone, PartialEq, AzBuf)]
637pub struct Recipes {
638    pub recipes: Vec<ResourceLocation>,
639}
640impl DataComponent for Recipes {
641    const KIND: DataComponentKind = DataComponentKind::Recipes;
642}
643
644#[derive(Clone, PartialEq, AzBuf)]
645pub struct LodestoneTracker {
646    pub target: Option<GlobalPos>,
647    pub tracked: bool,
648}
649impl DataComponent for LodestoneTracker {
650    const KIND: DataComponentKind = DataComponentKind::LodestoneTracker;
651}
652
653#[derive(Clone, Copy, PartialEq, AzBuf)]
654pub enum FireworkExplosionShape {
655    SmallBall,
656    LargeBall,
657    Star,
658    Creeper,
659    Burst,
660}
661
662#[derive(Clone, PartialEq, AzBuf)]
663pub struct FireworkExplosion {
664    pub shape: FireworkExplosionShape,
665    pub colors: Vec<i32>,
666    pub fade_colors: Vec<i32>,
667    pub has_trail: bool,
668    pub has_twinkle: bool,
669}
670impl DataComponent for FireworkExplosion {
671    const KIND: DataComponentKind = DataComponentKind::FireworkExplosion;
672}
673
674#[derive(Clone, PartialEq, AzBuf)]
675pub struct Fireworks {
676    #[var]
677    pub flight_duration: i32,
678    pub explosions: Vec<FireworkExplosion>,
679}
680impl DataComponent for Fireworks {
681    const KIND: DataComponentKind = DataComponentKind::Fireworks;
682}
683
684#[derive(Clone, PartialEq, AzBuf)]
685pub struct GameProfileProperty {
686    pub name: String,
687    pub value: String,
688    pub signature: Option<String>,
689}
690
691#[derive(Clone, PartialEq, AzBuf)]
692pub struct Profile {
693    pub name: Option<String>,
694    pub id: Option<Uuid>,
695    pub properties: Vec<GameProfileProperty>,
696}
697impl DataComponent for Profile {
698    const KIND: DataComponentKind = DataComponentKind::Profile;
699}
700
701#[derive(Clone, PartialEq, AzBuf)]
702pub struct NoteBlockSound {
703    pub sound: ResourceLocation,
704}
705impl DataComponent for NoteBlockSound {
706    const KIND: DataComponentKind = DataComponentKind::NoteBlockSound;
707}
708
709#[derive(Clone, PartialEq, AzBuf)]
710pub struct BannerPattern {
711    #[var]
712    pub pattern: i32,
713    #[var]
714    pub color: i32,
715}
716
717#[derive(Clone, PartialEq, AzBuf)]
718pub struct BannerPatterns {
719    pub patterns: Vec<BannerPattern>,
720}
721impl DataComponent for BannerPatterns {
722    const KIND: DataComponentKind = DataComponentKind::BannerPatterns;
723}
724
725#[derive(Clone, Copy, PartialEq, AzBuf)]
726pub enum DyeColor {
727    White,
728    Orange,
729    Magenta,
730    LightBlue,
731    Yellow,
732    Lime,
733    Pink,
734    Gray,
735    LightGray,
736    Cyan,
737    Purple,
738    Blue,
739    Brown,
740    Green,
741    Red,
742    Black,
743}
744
745#[derive(Clone, PartialEq, AzBuf)]
746pub struct BaseColor {
747    pub color: DyeColor,
748}
749impl DataComponent for BaseColor {
750    const KIND: DataComponentKind = DataComponentKind::BaseColor;
751}
752
753#[derive(Clone, PartialEq, AzBuf)]
754pub struct PotDecorations {
755    pub items: Vec<Item>,
756}
757impl DataComponent for PotDecorations {
758    const KIND: DataComponentKind = DataComponentKind::PotDecorations;
759}
760
761#[derive(Clone, PartialEq, AzBuf)]
762pub struct Container {
763    pub items: Vec<ItemStack>,
764}
765impl DataComponent for Container {
766    const KIND: DataComponentKind = DataComponentKind::Container;
767}
768
769#[derive(Clone, PartialEq, AzBuf)]
770pub struct BlockState {
771    pub properties: HashMap<String, String>,
772}
773impl DataComponent for BlockState {
774    const KIND: DataComponentKind = DataComponentKind::BlockState;
775}
776
777#[derive(Clone, PartialEq, AzBuf)]
778pub struct BeehiveOccupant {
779    pub entity_data: NbtCompound,
780    #[var]
781    pub ticks_in_hive: i32,
782    #[var]
783    pub min_ticks_in_hive: i32,
784}
785
786#[derive(Clone, PartialEq, AzBuf)]
787pub struct Bees {
788    pub occupants: Vec<BeehiveOccupant>,
789}
790impl DataComponent for Bees {
791    const KIND: DataComponentKind = DataComponentKind::Bees;
792}
793
794#[derive(Clone, PartialEq, AzBuf)]
795pub struct Lock {
796    pub key: String,
797}
798impl DataComponent for Lock {
799    const KIND: DataComponentKind = DataComponentKind::Lock;
800}
801
802#[derive(Clone, PartialEq, AzBuf)]
803pub struct ContainerLoot {
804    pub loot: NbtCompound,
805}
806impl DataComponent for ContainerLoot {
807    const KIND: DataComponentKind = DataComponentKind::ContainerLoot;
808}
809
810#[derive(Clone, PartialEq, AzBuf)]
811pub enum JukeboxPlayable {
812    Referenced(ResourceLocation),
813    Direct(Holder<registry::JukeboxSong, JukeboxSongData>),
814}
815impl DataComponent for JukeboxPlayable {
816    const KIND: DataComponentKind = DataComponentKind::JukeboxPlayable;
817}
818#[derive(Clone, PartialEq, AzBuf)]
819pub struct JukeboxSongData {
820    pub sound_event: Holder<SoundEvent, CustomSound>,
821    pub description: FormattedText,
822    pub length_in_seconds: f32,
823    #[var]
824    pub comparator_output: i32,
825}
826
827#[derive(Clone, PartialEq, AzBuf)]
828pub struct Consumable {
829    pub consume_seconds: f32,
830    pub animation: ItemUseAnimation,
831    pub sound: azalea_registry::Holder<SoundEvent, CustomSound>,
832    pub has_consume_particles: bool,
833    pub on_consume_effects: Vec<ConsumeEffect>,
834}
835impl DataComponent for Consumable {
836    const KIND: DataComponentKind = DataComponentKind::Consumable;
837}
838
839#[derive(Clone, Copy, PartialEq, AzBuf)]
840pub enum ItemUseAnimation {
841    None,
842    Eat,
843    Drink,
844    Block,
845    Bow,
846    Spear,
847    Crossbow,
848    Spyglass,
849    TootHorn,
850    Brush,
851}
852
853#[derive(Clone, PartialEq, AzBuf)]
854pub struct UseRemainder {
855    pub convert_into: ItemStack,
856}
857impl DataComponent for UseRemainder {
858    const KIND: DataComponentKind = DataComponentKind::UseRemainder;
859}
860
861#[derive(Clone, PartialEq, AzBuf)]
862pub struct UseCooldown {
863    pub seconds: f32,
864    pub cooldown_group: Option<ResourceLocation>,
865}
866impl DataComponent for UseCooldown {
867    const KIND: DataComponentKind = DataComponentKind::UseCooldown;
868}
869
870#[derive(Clone, PartialEq, AzBuf)]
871pub struct Enchantable {
872    #[var]
873    pub value: u32,
874}
875impl DataComponent for Enchantable {
876    const KIND: DataComponentKind = DataComponentKind::Enchantable;
877}
878
879#[derive(Clone, PartialEq, AzBuf)]
880pub struct Repairable {
881    pub items: HolderSet<Item, ResourceLocation>,
882}
883impl DataComponent for Repairable {
884    const KIND: DataComponentKind = DataComponentKind::Repairable;
885}
886
887#[derive(Clone, PartialEq, AzBuf)]
888pub struct ItemModel {
889    pub resource_location: ResourceLocation,
890}
891impl DataComponent for ItemModel {
892    const KIND: DataComponentKind = DataComponentKind::ItemModel;
893}
894
895#[derive(Clone, PartialEq, AzBuf)]
896pub struct DamageResistant {
897    // in the vanilla code this is
898    // ```
899    // StreamCodec.composite(
900    //   TagKey.streamCodec(Registries.DAMAGE_TYPE), DamageResistant::types, DamageResistant::new
901    // );
902    // ```
903    // i'm not entirely sure if this is meant to be a vec or something, i just made it a
904    // resourcelocation for now
905    pub types: ResourceLocation,
906}
907impl DataComponent for DamageResistant {
908    const KIND: DataComponentKind = DataComponentKind::DamageResistant;
909}
910
911#[derive(Clone, PartialEq, AzBuf)]
912pub struct Equippable {
913    pub slot: EquipmentSlot,
914    pub equip_sound: SoundEvent,
915    pub asset_id: Option<ResourceLocation>,
916    pub camera_overlay: Option<ResourceLocation>,
917    pub allowed_entities: Option<HolderSet<EntityKind, ResourceLocation>>,
918    pub dispensable: bool,
919    pub swappable: bool,
920    pub damage_on_hurt: bool,
921}
922impl DataComponent for Equippable {
923    const KIND: DataComponentKind = DataComponentKind::Equippable;
924}
925
926#[derive(Clone, Copy, Debug, PartialEq, AzBuf)]
927pub enum EquipmentSlot {
928    Mainhand,
929    Offhand,
930    Hand,
931    Feet,
932    Legs,
933    Chest,
934    Head,
935    Armor,
936    Body,
937}
938
939#[derive(Clone, PartialEq, AzBuf)]
940pub struct Glider;
941impl DataComponent for Glider {
942    const KIND: DataComponentKind = DataComponentKind::Glider;
943}
944
945#[derive(Clone, PartialEq, AzBuf)]
946pub struct TooltipStyle {
947    pub resource_location: ResourceLocation,
948}
949impl DataComponent for TooltipStyle {
950    const KIND: DataComponentKind = DataComponentKind::TooltipStyle;
951}
952
953#[derive(Clone, PartialEq, AzBuf)]
954pub struct DeathProtection {
955    pub death_effects: Vec<ConsumeEffectKind>,
956}
957impl DataComponent for DeathProtection {
958    const KIND: DataComponentKind = DataComponentKind::DeathProtection;
959}
960
961#[derive(Clone, PartialEq, AzBuf)]
962pub struct Weapon {
963    #[var]
964    pub damage_per_attack: i32,
965    pub can_disable_blocking: bool,
966}
967impl DataComponent for Weapon {
968    const KIND: DataComponentKind = DataComponentKind::Weapon;
969}
970
971#[derive(Clone, PartialEq, AzBuf)]
972pub struct PotionDurationScale {
973    pub value: f32,
974}
975impl DataComponent for PotionDurationScale {
976    const KIND: DataComponentKind = DataComponentKind::PotionDurationScale;
977}
978
979#[derive(Clone, PartialEq, AzBuf)]
980pub struct VillagerVariant {
981    pub variant: registry::VillagerKind,
982}
983impl DataComponent for VillagerVariant {
984    const KIND: DataComponentKind = DataComponentKind::VillagerVariant;
985}
986
987#[derive(Clone, PartialEq, AzBuf)]
988pub struct WolfVariant {
989    pub variant: registry::WolfVariant,
990}
991impl DataComponent for WolfVariant {
992    const KIND: DataComponentKind = DataComponentKind::WolfVariant;
993}
994
995#[derive(Clone, PartialEq, AzBuf)]
996pub struct WolfCollar {
997    pub color: DyeColor,
998}
999impl DataComponent for WolfCollar {
1000    const KIND: DataComponentKind = DataComponentKind::WolfCollar;
1001}
1002
1003#[derive(Clone, PartialEq, AzBuf)]
1004pub struct FoxVariant {
1005    pub variant: registry::FoxVariant,
1006}
1007impl DataComponent for FoxVariant {
1008    const KIND: DataComponentKind = DataComponentKind::FoxVariant;
1009}
1010
1011#[derive(Clone, Copy, PartialEq, AzBuf)]
1012pub enum SalmonSize {
1013    Small,
1014    Medium,
1015    Large,
1016}
1017impl DataComponent for SalmonSize {
1018    const KIND: DataComponentKind = DataComponentKind::SalmonSize;
1019}
1020
1021#[derive(Clone, PartialEq, AzBuf)]
1022pub struct ParrotVariant {
1023    pub variant: registry::ParrotVariant,
1024}
1025impl DataComponent for ParrotVariant {
1026    const KIND: DataComponentKind = DataComponentKind::ParrotVariant;
1027}
1028
1029#[derive(Clone, Copy, PartialEq, AzBuf)]
1030pub enum TropicalFishPattern {
1031    Kob,
1032    Sunstreak,
1033    Snooper,
1034    Dasher,
1035    Brinely,
1036    Spotty,
1037    Flopper,
1038    Stripey,
1039    Glitter,
1040    Blockfish,
1041    Betty,
1042    Clayfish,
1043}
1044impl DataComponent for TropicalFishPattern {
1045    const KIND: DataComponentKind = DataComponentKind::TropicalFishPattern;
1046}
1047
1048#[derive(Clone, PartialEq, AzBuf)]
1049pub struct TropicalFishBaseColor {
1050    pub color: DyeColor,
1051}
1052impl DataComponent for TropicalFishBaseColor {
1053    const KIND: DataComponentKind = DataComponentKind::TropicalFishBaseColor;
1054}
1055
1056#[derive(Clone, PartialEq, AzBuf)]
1057pub struct TropicalFishPatternColor {
1058    pub color: DyeColor,
1059}
1060impl DataComponent for TropicalFishPatternColor {
1061    const KIND: DataComponentKind = DataComponentKind::TropicalFishPatternColor;
1062}
1063
1064#[derive(Clone, PartialEq, AzBuf)]
1065pub struct MooshroomVariant {
1066    pub variant: registry::MooshroomVariant,
1067}
1068impl DataComponent for MooshroomVariant {
1069    const KIND: DataComponentKind = DataComponentKind::MooshroomVariant;
1070}
1071
1072#[derive(Clone, PartialEq, AzBuf)]
1073pub struct RabbitVariant {
1074    pub variant: registry::RabbitVariant,
1075}
1076impl DataComponent for RabbitVariant {
1077    const KIND: DataComponentKind = DataComponentKind::RabbitVariant;
1078}
1079
1080#[derive(Clone, PartialEq, AzBuf)]
1081pub struct PigVariant {
1082    pub variant: registry::PigVariant,
1083}
1084impl DataComponent for PigVariant {
1085    const KIND: DataComponentKind = DataComponentKind::PigVariant;
1086}
1087
1088#[derive(Clone, PartialEq, AzBuf)]
1089pub struct FrogVariant {
1090    pub variant: registry::FrogVariant,
1091}
1092impl DataComponent for FrogVariant {
1093    const KIND: DataComponentKind = DataComponentKind::FrogVariant;
1094}
1095
1096#[derive(Clone, PartialEq, AzBuf)]
1097pub struct HorseVariant {
1098    pub variant: registry::HorseVariant,
1099}
1100impl DataComponent for HorseVariant {
1101    const KIND: DataComponentKind = DataComponentKind::HorseVariant;
1102}
1103
1104#[derive(Clone, PartialEq, AzBuf)]
1105pub struct PaintingVariant {
1106    pub variant: Holder<registry::PaintingVariant, PaintingVariantData>,
1107}
1108impl DataComponent for PaintingVariant {
1109    const KIND: DataComponentKind = DataComponentKind::PaintingVariant;
1110}
1111#[derive(Clone, PartialEq, AzBuf)]
1112pub struct PaintingVariantData {
1113    #[var]
1114    pub width: i32,
1115    #[var]
1116    pub height: i32,
1117    pub asset_id: ResourceLocation,
1118    pub title: Option<FormattedText>,
1119    pub author: Option<FormattedText>,
1120}
1121
1122#[derive(Clone, PartialEq, AzBuf)]
1123pub struct LlamaVariant {
1124    pub variant: registry::LlamaVariant,
1125}
1126impl DataComponent for LlamaVariant {
1127    const KIND: DataComponentKind = DataComponentKind::LlamaVariant;
1128}
1129
1130#[derive(Clone, PartialEq, AzBuf)]
1131pub struct AxolotlVariant {
1132    pub variant: registry::AxolotlVariant,
1133}
1134impl DataComponent for AxolotlVariant {
1135    const KIND: DataComponentKind = DataComponentKind::AxolotlVariant;
1136}
1137
1138#[derive(Clone, PartialEq, AzBuf)]
1139pub struct CatVariant {
1140    pub variant: registry::CatVariant,
1141}
1142impl DataComponent for CatVariant {
1143    const KIND: DataComponentKind = DataComponentKind::CatVariant;
1144}
1145
1146#[derive(Clone, PartialEq, AzBuf)]
1147pub struct CatCollar {
1148    pub color: DyeColor,
1149}
1150impl DataComponent for CatCollar {
1151    const KIND: DataComponentKind = DataComponentKind::CatCollar;
1152}
1153
1154#[derive(Clone, PartialEq, AzBuf)]
1155pub struct SheepColor {
1156    pub color: DyeColor,
1157}
1158impl DataComponent for SheepColor {
1159    const KIND: DataComponentKind = DataComponentKind::SheepColor;
1160}
1161
1162#[derive(Clone, PartialEq, AzBuf)]
1163pub struct ShulkerColor {
1164    pub color: DyeColor,
1165}
1166impl DataComponent for ShulkerColor {
1167    const KIND: DataComponentKind = DataComponentKind::ShulkerColor;
1168}
1169
1170#[derive(Clone, PartialEq, AzBuf)]
1171pub struct TooltipDisplay {
1172    pub hide_tooltip: bool,
1173    pub hidden_components: Vec<DataComponentKind>,
1174}
1175impl DataComponent for TooltipDisplay {
1176    const KIND: DataComponentKind = DataComponentKind::TooltipDisplay;
1177}
1178
1179#[derive(Clone, PartialEq, AzBuf)]
1180pub struct BlocksAttacks {
1181    pub block_delay_seconds: f32,
1182    pub disable_cooldown_scale: f32,
1183    pub damage_reductions: Vec<DamageReduction>,
1184    pub item_damage: ItemDamageFunction,
1185    pub bypassed_by: Option<ResourceLocation>,
1186    pub block_sound: Option<azalea_registry::Holder<SoundEvent, CustomSound>>,
1187    pub disable_sound: Option<azalea_registry::Holder<SoundEvent, CustomSound>>,
1188}
1189impl DataComponent for BlocksAttacks {
1190    const KIND: DataComponentKind = DataComponentKind::BlocksAttacks;
1191}
1192
1193#[derive(Clone, PartialEq, AzBuf)]
1194pub struct DamageReduction {
1195    pub horizontal_blocking_angle: f32,
1196    pub kind: Option<HolderSet<DamageKind, ResourceLocation>>,
1197    pub base: f32,
1198    pub factor: f32,
1199}
1200#[derive(Clone, PartialEq, AzBuf)]
1201pub struct ItemDamageFunction {
1202    pub threshold: f32,
1203    pub base: f32,
1204    pub factor: f32,
1205}
1206
1207#[derive(Clone, PartialEq, AzBuf)]
1208pub enum ProvidesTrimMaterial {
1209    Referenced(ResourceLocation),
1210    Direct(Holder<TrimMaterial, DirectTrimMaterial>),
1211}
1212impl DataComponent for ProvidesTrimMaterial {
1213    const KIND: DataComponentKind = DataComponentKind::ProvidesTrimMaterial;
1214}
1215
1216#[derive(Clone, PartialEq, AzBuf)]
1217pub struct DirectTrimMaterial {
1218    pub assets: MaterialAssetGroup,
1219    pub description: FormattedText,
1220}
1221#[derive(Clone, PartialEq, AzBuf)]
1222pub struct MaterialAssetGroup {
1223    pub base: AssetInfo,
1224    pub overrides: Vec<(ResourceLocation, AssetInfo)>,
1225}
1226
1227#[derive(Clone, PartialEq, AzBuf)]
1228pub struct AssetInfo {
1229    pub suffix: String,
1230}
1231
1232#[derive(Clone, PartialEq, AzBuf)]
1233pub struct ProvidesBannerPatterns {
1234    pub key: ResourceLocation,
1235}
1236impl DataComponent for ProvidesBannerPatterns {
1237    const KIND: DataComponentKind = DataComponentKind::ProvidesBannerPatterns;
1238}
1239
1240#[derive(Clone, PartialEq, AzBuf)]
1241pub struct BreakSound {
1242    pub sound: azalea_registry::Holder<SoundEvent, CustomSound>,
1243}
1244impl DataComponent for BreakSound {
1245    const KIND: DataComponentKind = DataComponentKind::BreakSound;
1246}
1247
1248#[derive(Clone, PartialEq, AzBuf)]
1249pub struct WolfSoundVariant {
1250    pub variant: azalea_registry::WolfSoundVariant,
1251}
1252impl DataComponent for WolfSoundVariant {
1253    const KIND: DataComponentKind = DataComponentKind::WolfSoundVariant;
1254}
1255
1256#[derive(Clone, PartialEq, AzBuf)]
1257pub struct CowVariant {
1258    pub variant: azalea_registry::CowVariant,
1259}
1260impl DataComponent for CowVariant {
1261    const KIND: DataComponentKind = DataComponentKind::CowVariant;
1262}
1263
1264#[derive(Clone, PartialEq, AzBuf)]
1265pub enum ChickenVariant {
1266    Referenced(ResourceLocation),
1267    Direct(ChickenVariantData),
1268}
1269impl DataComponent for ChickenVariant {
1270    const KIND: DataComponentKind = DataComponentKind::ChickenVariant;
1271}
1272#[derive(Clone, PartialEq, AzBuf)]
1273pub struct ChickenVariantData {
1274    pub registry: azalea_registry::ChickenVariant,
1275}