azalea_inventory/
components.rs

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