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::{position::GlobalPos, resource_location::ResourceLocation};
7use azalea_registry::{
8    Attribute, Block, ConsumeEffectKind, DataComponentKind, Enchantment, EntityKind, HolderSet,
9    Item, MobEffect, Potion, SoundEvent, TrimMaterial, TrimPattern,
10};
11use simdnbt::owned::{Nbt, NbtCompound};
12use uuid::Uuid;
13
14use crate::ItemStack;
15
16pub trait DataComponent: Send + Sync + Any {
17    const KIND: DataComponentKind;
18}
19
20pub trait EncodableDataComponent: Send + Sync + Any {
21    fn encode(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error>;
22    // using the Clone trait makes it not be object-safe, so we have our own clone
23    // function instead
24    fn clone(&self) -> Box<dyn EncodableDataComponent>;
25    // same deal here
26    fn eq(&self, other: Box<dyn EncodableDataComponent>) -> bool;
27}
28
29impl<T> EncodableDataComponent for T
30where
31    T: DataComponent + Clone + AzaleaWrite + AzaleaRead + PartialEq,
32{
33    fn encode(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
34        self.azalea_write(buf)
35    }
36    fn clone(&self) -> Box<dyn EncodableDataComponent> {
37        let cloned = self.clone();
38        Box::new(cloned)
39    }
40    fn eq(&self, other: Box<dyn EncodableDataComponent>) -> bool {
41        let other_any: Box<dyn Any> = other;
42        if let Some(other) = other_any.downcast_ref::<T>() {
43            self == other
44        } else {
45            false
46        }
47    }
48}
49
50pub fn from_kind(
51    kind: azalea_registry::DataComponentKind,
52    buf: &mut Cursor<&[u8]>,
53) -> Result<Box<dyn EncodableDataComponent>, BufReadError> {
54    // if this is causing a compile-time error, look at DataComponents.java in the
55    // decompiled vanilla code to see how to implement new components
56
57    // note that this match statement is updated by genitemcomponents.py
58    Ok(match kind {
59        DataComponentKind::CustomData => Box::new(CustomData::azalea_read(buf)?),
60        DataComponentKind::MaxStackSize => Box::new(MaxStackSize::azalea_read(buf)?),
61        DataComponentKind::MaxDamage => Box::new(MaxDamage::azalea_read(buf)?),
62        DataComponentKind::Damage => Box::new(Damage::azalea_read(buf)?),
63        DataComponentKind::Unbreakable => Box::new(Unbreakable::azalea_read(buf)?),
64        DataComponentKind::CustomName => Box::new(CustomName::azalea_read(buf)?),
65        DataComponentKind::ItemName => Box::new(ItemName::azalea_read(buf)?),
66        DataComponentKind::Lore => Box::new(Lore::azalea_read(buf)?),
67        DataComponentKind::Rarity => Box::new(Rarity::azalea_read(buf)?),
68        DataComponentKind::Enchantments => Box::new(Enchantments::azalea_read(buf)?),
69        DataComponentKind::CanPlaceOn => Box::new(CanPlaceOn::azalea_read(buf)?),
70        DataComponentKind::CanBreak => Box::new(CanBreak::azalea_read(buf)?),
71        DataComponentKind::AttributeModifiers => Box::new(AttributeModifiers::azalea_read(buf)?),
72        DataComponentKind::CustomModelData => Box::new(CustomModelData::azalea_read(buf)?),
73        DataComponentKind::HideAdditionalTooltip => {
74            Box::new(HideAdditionalTooltip::azalea_read(buf)?)
75        }
76        DataComponentKind::HideTooltip => Box::new(HideTooltip::azalea_read(buf)?),
77        DataComponentKind::RepairCost => Box::new(RepairCost::azalea_read(buf)?),
78        DataComponentKind::CreativeSlotLock => Box::new(CreativeSlotLock::azalea_read(buf)?),
79        DataComponentKind::EnchantmentGlintOverride => {
80            Box::new(EnchantmentGlintOverride::azalea_read(buf)?)
81        }
82        DataComponentKind::IntangibleProjectile => {
83            Box::new(IntangibleProjectile::azalea_read(buf)?)
84        }
85        DataComponentKind::Food => Box::new(Food::azalea_read(buf)?),
86        DataComponentKind::Tool => Box::new(Tool::azalea_read(buf)?),
87        DataComponentKind::StoredEnchantments => Box::new(StoredEnchantments::azalea_read(buf)?),
88        DataComponentKind::DyedColor => Box::new(DyedColor::azalea_read(buf)?),
89        DataComponentKind::MapColor => Box::new(MapColor::azalea_read(buf)?),
90        DataComponentKind::MapId => Box::new(MapId::azalea_read(buf)?),
91        DataComponentKind::MapDecorations => Box::new(MapDecorations::azalea_read(buf)?),
92        DataComponentKind::MapPostProcessing => Box::new(MapPostProcessing::azalea_read(buf)?),
93        DataComponentKind::ChargedProjectiles => Box::new(ChargedProjectiles::azalea_read(buf)?),
94        DataComponentKind::BundleContents => Box::new(BundleContents::azalea_read(buf)?),
95        DataComponentKind::PotionContents => Box::new(PotionContents::azalea_read(buf)?),
96        DataComponentKind::SuspiciousStewEffects => {
97            Box::new(SuspiciousStewEffects::azalea_read(buf)?)
98        }
99        DataComponentKind::WritableBookContent => Box::new(WritableBookContent::azalea_read(buf)?),
100        DataComponentKind::WrittenBookContent => Box::new(WrittenBookContent::azalea_read(buf)?),
101        DataComponentKind::Trim => Box::new(Trim::azalea_read(buf)?),
102        DataComponentKind::DebugStickState => Box::new(DebugStickState::azalea_read(buf)?),
103        DataComponentKind::EntityData => Box::new(EntityData::azalea_read(buf)?),
104        DataComponentKind::BucketEntityData => Box::new(BucketEntityData::azalea_read(buf)?),
105        DataComponentKind::BlockEntityData => Box::new(BlockEntityData::azalea_read(buf)?),
106        DataComponentKind::Instrument => Box::new(Instrument::azalea_read(buf)?),
107        DataComponentKind::OminousBottleAmplifier => {
108            Box::new(OminousBottleAmplifier::azalea_read(buf)?)
109        }
110        DataComponentKind::Recipes => Box::new(Recipes::azalea_read(buf)?),
111        DataComponentKind::LodestoneTracker => Box::new(LodestoneTracker::azalea_read(buf)?),
112        DataComponentKind::FireworkExplosion => Box::new(FireworkExplosion::azalea_read(buf)?),
113        DataComponentKind::Fireworks => Box::new(Fireworks::azalea_read(buf)?),
114        DataComponentKind::Profile => Box::new(Profile::azalea_read(buf)?),
115        DataComponentKind::NoteBlockSound => Box::new(NoteBlockSound::azalea_read(buf)?),
116        DataComponentKind::BannerPatterns => Box::new(BannerPatterns::azalea_read(buf)?),
117        DataComponentKind::BaseColor => Box::new(BaseColor::azalea_read(buf)?),
118        DataComponentKind::PotDecorations => Box::new(PotDecorations::azalea_read(buf)?),
119        DataComponentKind::Container => Box::new(Container::azalea_read(buf)?),
120        DataComponentKind::BlockState => Box::new(BlockState::azalea_read(buf)?),
121        DataComponentKind::Bees => Box::new(Bees::azalea_read(buf)?),
122        DataComponentKind::Lock => Box::new(Lock::azalea_read(buf)?),
123        DataComponentKind::ContainerLoot => Box::new(ContainerLoot::azalea_read(buf)?),
124        DataComponentKind::JukeboxPlayable => Box::new(JukeboxPlayable::azalea_read(buf)?),
125        DataComponentKind::Consumable => Box::new(Consumable::azalea_read(buf)?),
126        DataComponentKind::UseRemainder => Box::new(UseRemainder::azalea_read(buf)?),
127        DataComponentKind::UseCooldown => Box::new(UseCooldown::azalea_read(buf)?),
128        DataComponentKind::Enchantable => Box::new(Enchantable::azalea_read(buf)?),
129        DataComponentKind::Repairable => Box::new(Repairable::azalea_read(buf)?),
130        DataComponentKind::ItemModel => Box::new(ItemModel::azalea_read(buf)?),
131        DataComponentKind::DamageResistant => Box::new(DamageResistant::azalea_read(buf)?),
132        DataComponentKind::Equippable => Box::new(Equippable::azalea_read(buf)?),
133        DataComponentKind::Glider => Box::new(Glider::azalea_read(buf)?),
134        DataComponentKind::TooltipStyle => Box::new(TooltipStyle::azalea_read(buf)?),
135        DataComponentKind::DeathProtection => Box::new(DeathProtection::azalea_read(buf)?),
136    })
137}
138
139#[derive(Clone, PartialEq, AzBuf)]
140pub struct CustomData {
141    pub nbt: Nbt,
142}
143impl DataComponent for CustomData {
144    const KIND: DataComponentKind = DataComponentKind::CustomData;
145}
146
147#[derive(Clone, PartialEq, AzBuf)]
148pub struct MaxStackSize {
149    #[var]
150    pub count: i32,
151}
152impl DataComponent for MaxStackSize {
153    const KIND: DataComponentKind = DataComponentKind::MaxStackSize;
154}
155
156#[derive(Clone, PartialEq, AzBuf)]
157pub struct MaxDamage {
158    #[var]
159    pub amount: i32,
160}
161impl DataComponent for MaxDamage {
162    const KIND: DataComponentKind = DataComponentKind::MaxDamage;
163}
164
165#[derive(Clone, PartialEq, AzBuf)]
166pub struct Damage {
167    #[var]
168    pub amount: i32,
169}
170
171impl DataComponent for Damage {
172    const KIND: DataComponentKind = DataComponentKind::Damage;
173}
174
175#[derive(Clone, PartialEq, AzBuf)]
176pub struct Unbreakable {
177    pub show_in_tooltip: bool,
178}
179impl DataComponent for Unbreakable {
180    const KIND: DataComponentKind = DataComponentKind::Unbreakable;
181}
182impl Default for Unbreakable {
183    fn default() -> Self {
184        Self {
185            show_in_tooltip: true,
186        }
187    }
188}
189
190#[derive(Clone, PartialEq, AzBuf)]
191pub struct CustomName {
192    pub name: FormattedText,
193}
194impl DataComponent for CustomName {
195    const KIND: DataComponentKind = DataComponentKind::CustomName;
196}
197
198#[derive(Clone, PartialEq, AzBuf)]
199pub struct ItemName {
200    pub name: FormattedText,
201}
202impl DataComponent for ItemName {
203    const KIND: DataComponentKind = DataComponentKind::ItemName;
204}
205
206#[derive(Clone, PartialEq, AzBuf)]
207pub struct Lore {
208    pub lines: Vec<FormattedText>,
209    // vanilla also has styled_lines here but it doesn't appear to be used for the protocol
210}
211impl DataComponent for Lore {
212    const KIND: DataComponentKind = DataComponentKind::Lore;
213}
214
215#[derive(Clone, PartialEq, Copy, AzBuf)]
216pub enum Rarity {
217    Common,
218    Uncommon,
219    Rare,
220    Epic,
221}
222impl DataComponent for Rarity {
223    const KIND: DataComponentKind = DataComponentKind::Rarity;
224}
225
226#[derive(Clone, PartialEq, AzBuf)]
227pub struct Enchantments {
228    #[var]
229    pub levels: HashMap<Enchantment, u32>,
230    pub show_in_tooltip: bool,
231}
232impl DataComponent for Enchantments {
233    const KIND: DataComponentKind = DataComponentKind::Enchantments;
234}
235
236#[derive(Clone, PartialEq, AzBuf)]
237pub enum BlockStateValueMatcher {
238    Exact {
239        value: String,
240    },
241    Range {
242        min: Option<String>,
243        max: Option<String>,
244    },
245}
246
247#[derive(Clone, PartialEq, AzBuf)]
248pub struct BlockStatePropertyMatcher {
249    pub name: String,
250    pub value_matcher: BlockStateValueMatcher,
251}
252
253#[derive(Clone, PartialEq, AzBuf)]
254pub struct BlockPredicate {
255    pub blocks: Option<HolderSet<Block, ResourceLocation>>,
256    pub properties: Option<Vec<BlockStatePropertyMatcher>>,
257    pub nbt: Option<NbtCompound>,
258}
259
260#[derive(Clone, PartialEq, AzBuf)]
261pub struct AdventureModePredicate {
262    pub predicates: Vec<BlockPredicate>,
263    pub show_in_tooltip: bool,
264}
265
266#[derive(Clone, PartialEq, AzBuf)]
267pub struct CanPlaceOn {
268    pub predicate: AdventureModePredicate,
269}
270impl DataComponent for CanPlaceOn {
271    const KIND: DataComponentKind = DataComponentKind::CanPlaceOn;
272}
273
274#[derive(Clone, PartialEq, AzBuf)]
275pub struct CanBreak {
276    pub predicate: AdventureModePredicate,
277}
278impl DataComponent for CanBreak {
279    const KIND: DataComponentKind = DataComponentKind::CanBreak;
280}
281
282#[derive(Clone, Copy, PartialEq, AzBuf)]
283pub enum EquipmentSlotGroup {
284    Any,
285    Mainhand,
286    Offhand,
287    Hand,
288    Feet,
289    Legs,
290    Chest,
291    Head,
292    Armor,
293    Body,
294}
295
296#[derive(Clone, Copy, PartialEq, AzBuf)]
297pub enum AttributeModifierOperation {
298    Addition,
299    MultiplyBase,
300    MultiplyTotal,
301}
302
303// this is duplicated in azalea-entity, BUT the one there has a different
304// protocol format (and we can't use it anyways because it would cause a
305// circular dependency)
306#[derive(Clone, PartialEq, AzBuf)]
307pub struct AttributeModifier {
308    pub id: ResourceLocation,
309    pub amount: f64,
310    pub operation: AttributeModifierOperation,
311}
312
313#[derive(Clone, PartialEq, AzBuf)]
314pub struct AttributeModifiersEntry {
315    pub attribute: Attribute,
316    pub modifier: AttributeModifier,
317    pub slot: EquipmentSlotGroup,
318}
319
320#[derive(Clone, PartialEq, AzBuf)]
321pub struct AttributeModifiers {
322    pub modifiers: Vec<AttributeModifiersEntry>,
323    pub show_in_tooltip: bool,
324}
325impl DataComponent for AttributeModifiers {
326    const KIND: DataComponentKind = DataComponentKind::AttributeModifiers;
327}
328
329#[derive(Clone, PartialEq, AzBuf)]
330pub struct CustomModelData {
331    #[var]
332    pub value: i32,
333}
334impl DataComponent for CustomModelData {
335    const KIND: DataComponentKind = DataComponentKind::CustomModelData;
336}
337
338#[derive(Clone, PartialEq, AzBuf)]
339pub struct HideAdditionalTooltip;
340impl DataComponent for HideAdditionalTooltip {
341    const KIND: DataComponentKind = DataComponentKind::HideAdditionalTooltip;
342}
343
344#[derive(Clone, PartialEq, AzBuf)]
345pub struct HideTooltip;
346impl DataComponent for HideTooltip {
347    const KIND: DataComponentKind = DataComponentKind::HideTooltip;
348}
349
350#[derive(Clone, PartialEq, AzBuf)]
351pub struct RepairCost {
352    #[var]
353    pub cost: u32,
354}
355impl DataComponent for RepairCost {
356    const KIND: DataComponentKind = DataComponentKind::RepairCost;
357}
358
359#[derive(Clone, PartialEq, AzBuf)]
360pub struct CreativeSlotLock;
361impl DataComponent for CreativeSlotLock {
362    const KIND: DataComponentKind = DataComponentKind::CreativeSlotLock;
363}
364
365#[derive(Clone, PartialEq, AzBuf)]
366pub struct EnchantmentGlintOverride {
367    pub show_glint: bool,
368}
369impl DataComponent for EnchantmentGlintOverride {
370    const KIND: DataComponentKind = DataComponentKind::EnchantmentGlintOverride;
371}
372
373#[derive(Clone, PartialEq, AzBuf)]
374pub struct IntangibleProjectile;
375impl DataComponent for IntangibleProjectile {
376    const KIND: DataComponentKind = DataComponentKind::IntangibleProjectile;
377}
378
379#[derive(Clone, PartialEq, AzBuf)]
380pub struct MobEffectDetails {
381    #[var]
382    pub amplifier: i32,
383    #[var]
384    pub duration: i32,
385    pub ambient: bool,
386    pub show_particles: bool,
387    pub show_icon: bool,
388    pub hidden_effect: Option<Box<MobEffectDetails>>,
389}
390
391#[derive(Clone, PartialEq, AzBuf)]
392pub struct MobEffectInstance {
393    pub effect: MobEffect,
394    pub details: MobEffectDetails,
395}
396
397#[derive(Clone, PartialEq, AzBuf)]
398pub struct PossibleEffect {
399    pub effect: MobEffectInstance,
400    pub probability: f32,
401}
402
403#[derive(Clone, PartialEq, AzBuf)]
404pub struct Food {
405    #[var]
406    pub nutrition: i32,
407    pub saturation: f32,
408    pub can_always_eat: bool,
409    pub eat_seconds: f32,
410    pub effects: Vec<PossibleEffect>,
411}
412impl DataComponent for Food {
413    const KIND: DataComponentKind = DataComponentKind::Food;
414}
415
416#[derive(Clone, PartialEq, AzBuf)]
417pub struct ToolRule {
418    pub blocks: HolderSet<Block, ResourceLocation>,
419    pub speed: Option<f32>,
420    pub correct_for_drops: Option<bool>,
421}
422
423#[derive(Clone, PartialEq, AzBuf)]
424pub struct Tool {
425    pub rules: Vec<ToolRule>,
426    pub default_mining_speed: f32,
427    #[var]
428    pub damage_per_block: i32,
429}
430impl DataComponent for Tool {
431    const KIND: DataComponentKind = DataComponentKind::Tool;
432}
433
434#[derive(Clone, PartialEq, AzBuf)]
435pub struct StoredEnchantments {
436    #[var]
437    pub enchantments: HashMap<Enchantment, i32>,
438    pub show_in_tooltip: bool,
439}
440impl DataComponent for StoredEnchantments {
441    const KIND: DataComponentKind = DataComponentKind::StoredEnchantments;
442}
443
444#[derive(Clone, PartialEq, AzBuf)]
445pub struct DyedColor {
446    pub rgb: i32,
447    pub show_in_tooltip: bool,
448}
449impl DataComponent for DyedColor {
450    const KIND: DataComponentKind = DataComponentKind::DyedColor;
451}
452
453#[derive(Clone, PartialEq, AzBuf)]
454pub struct MapColor {
455    pub color: i32,
456}
457impl DataComponent for MapColor {
458    const KIND: DataComponentKind = DataComponentKind::MapColor;
459}
460
461#[derive(Clone, PartialEq, AzBuf)]
462pub struct MapId {
463    #[var]
464    pub id: i32,
465}
466impl DataComponent for MapId {
467    const KIND: DataComponentKind = DataComponentKind::MapId;
468}
469
470#[derive(Clone, PartialEq, AzBuf)]
471pub struct MapDecorations {
472    pub decorations: NbtCompound,
473}
474impl DataComponent for MapDecorations {
475    const KIND: DataComponentKind = DataComponentKind::MapDecorations;
476}
477
478#[derive(Clone, Copy, PartialEq, AzBuf)]
479pub enum MapPostProcessing {
480    Lock,
481    Scale,
482}
483impl DataComponent for MapPostProcessing {
484    const KIND: DataComponentKind = DataComponentKind::MapPostProcessing;
485}
486
487#[derive(Clone, PartialEq, AzBuf)]
488pub struct ChargedProjectiles {
489    pub items: Vec<ItemStack>,
490}
491impl DataComponent for ChargedProjectiles {
492    const KIND: DataComponentKind = DataComponentKind::ChargedProjectiles;
493}
494
495#[derive(Clone, PartialEq, AzBuf)]
496pub struct BundleContents {
497    pub items: Vec<ItemStack>,
498}
499impl DataComponent for BundleContents {
500    const KIND: DataComponentKind = DataComponentKind::BundleContents;
501}
502
503#[derive(Clone, PartialEq, AzBuf)]
504pub struct PotionContents {
505    pub potion: Option<Potion>,
506    pub custom_color: Option<i32>,
507    pub custom_effects: Vec<MobEffectInstance>,
508}
509impl DataComponent for PotionContents {
510    const KIND: DataComponentKind = DataComponentKind::PotionContents;
511}
512
513#[derive(Clone, PartialEq, AzBuf)]
514pub struct SuspiciousStewEffect {
515    pub effect: MobEffect,
516    #[var]
517    pub duration: i32,
518}
519
520#[derive(Clone, PartialEq, AzBuf)]
521pub struct SuspiciousStewEffects {
522    pub effects: Vec<SuspiciousStewEffect>,
523}
524impl DataComponent for SuspiciousStewEffects {
525    const KIND: DataComponentKind = DataComponentKind::SuspiciousStewEffects;
526}
527
528#[derive(Clone, PartialEq, AzBuf)]
529pub struct WritableBookContent {
530    pub pages: Vec<String>,
531}
532impl DataComponent for WritableBookContent {
533    const KIND: DataComponentKind = DataComponentKind::WritableBookContent;
534}
535
536#[derive(Clone, PartialEq, AzBuf)]
537pub struct WrittenBookContent {
538    pub title: String,
539    pub author: String,
540    #[var]
541    pub generation: i32,
542    pub pages: Vec<FormattedText>,
543    pub resolved: bool,
544}
545impl DataComponent for WrittenBookContent {
546    const KIND: DataComponentKind = DataComponentKind::WrittenBookContent;
547}
548
549#[derive(Clone, PartialEq, AzBuf)]
550pub struct Trim {
551    pub material: TrimMaterial,
552    pub pattern: TrimPattern,
553    pub show_in_tooltip: bool,
554}
555impl DataComponent for Trim {
556    const KIND: DataComponentKind = DataComponentKind::Trim;
557}
558
559#[derive(Clone, PartialEq, AzBuf)]
560pub struct DebugStickState {
561    pub properties: NbtCompound,
562}
563impl DataComponent for DebugStickState {
564    const KIND: DataComponentKind = DataComponentKind::DebugStickState;
565}
566
567#[derive(Clone, PartialEq, AzBuf)]
568pub struct EntityData {
569    pub entity: NbtCompound,
570}
571impl DataComponent for EntityData {
572    const KIND: DataComponentKind = DataComponentKind::EntityData;
573}
574
575#[derive(Clone, PartialEq, AzBuf)]
576pub struct BucketEntityData {
577    pub entity: NbtCompound,
578}
579impl DataComponent for BucketEntityData {
580    const KIND: DataComponentKind = DataComponentKind::BucketEntityData;
581}
582
583#[derive(Clone, PartialEq, AzBuf)]
584pub struct BlockEntityData {
585    pub entity: NbtCompound,
586}
587impl DataComponent for BlockEntityData {
588    const KIND: DataComponentKind = DataComponentKind::BlockEntityData;
589}
590
591#[derive(Clone, PartialEq, AzBuf)]
592pub struct Instrument {
593    pub instrument: azalea_registry::Instrument,
594}
595impl DataComponent for Instrument {
596    const KIND: DataComponentKind = DataComponentKind::Instrument;
597}
598
599#[derive(Clone, PartialEq, AzBuf)]
600pub struct OminousBottleAmplifier {
601    #[var]
602    pub amplifier: i32,
603}
604impl DataComponent for OminousBottleAmplifier {
605    const KIND: DataComponentKind = DataComponentKind::OminousBottleAmplifier;
606}
607
608#[derive(Clone, PartialEq, AzBuf)]
609pub struct Recipes {
610    pub recipes: Vec<ResourceLocation>,
611}
612impl DataComponent for Recipes {
613    const KIND: DataComponentKind = DataComponentKind::Recipes;
614}
615
616#[derive(Clone, PartialEq, AzBuf)]
617pub struct LodestoneTracker {
618    pub target: Option<GlobalPos>,
619    pub tracked: bool,
620}
621impl DataComponent for LodestoneTracker {
622    const KIND: DataComponentKind = DataComponentKind::LodestoneTracker;
623}
624
625#[derive(Clone, Copy, PartialEq, AzBuf)]
626pub enum FireworkExplosionShape {
627    SmallBall,
628    LargeBall,
629    Star,
630    Creeper,
631    Burst,
632}
633
634#[derive(Clone, PartialEq, AzBuf)]
635pub struct FireworkExplosion {
636    pub shape: FireworkExplosionShape,
637    pub colors: Vec<i32>,
638    pub fade_colors: Vec<i32>,
639    pub has_trail: bool,
640    pub has_twinkle: bool,
641}
642impl DataComponent for FireworkExplosion {
643    const KIND: DataComponentKind = DataComponentKind::FireworkExplosion;
644}
645
646#[derive(Clone, PartialEq, AzBuf)]
647pub struct Fireworks {
648    #[var]
649    pub flight_duration: i32,
650    pub explosions: Vec<FireworkExplosion>,
651}
652impl DataComponent for Fireworks {
653    const KIND: DataComponentKind = DataComponentKind::Fireworks;
654}
655
656#[derive(Clone, PartialEq, AzBuf)]
657pub struct GameProfileProperty {
658    pub name: String,
659    pub value: String,
660    pub signature: Option<String>,
661}
662
663#[derive(Clone, PartialEq, AzBuf)]
664pub struct Profile {
665    pub name: Option<String>,
666    pub id: Option<Uuid>,
667    pub properties: Vec<GameProfileProperty>,
668}
669impl DataComponent for Profile {
670    const KIND: DataComponentKind = DataComponentKind::Profile;
671}
672
673#[derive(Clone, PartialEq, AzBuf)]
674pub struct NoteBlockSound {
675    pub sound: ResourceLocation,
676}
677impl DataComponent for NoteBlockSound {
678    const KIND: DataComponentKind = DataComponentKind::NoteBlockSound;
679}
680
681#[derive(Clone, PartialEq, AzBuf)]
682pub struct BannerPattern {
683    #[var]
684    pub pattern: i32,
685    #[var]
686    pub color: i32,
687}
688
689#[derive(Clone, PartialEq, AzBuf)]
690pub struct BannerPatterns {
691    pub patterns: Vec<BannerPattern>,
692}
693impl DataComponent for BannerPatterns {
694    const KIND: DataComponentKind = DataComponentKind::BannerPatterns;
695}
696
697#[derive(Clone, Copy, PartialEq, AzBuf)]
698pub enum DyeColor {
699    White,
700    Orange,
701    Magenta,
702    LightBlue,
703    Yellow,
704    Lime,
705    Pink,
706    Gray,
707    LightGray,
708    Cyan,
709    Purple,
710    Blue,
711    Brown,
712    Green,
713    Red,
714    Black,
715}
716
717#[derive(Clone, PartialEq, AzBuf)]
718pub struct BaseColor {
719    pub color: DyeColor,
720}
721impl DataComponent for BaseColor {
722    const KIND: DataComponentKind = DataComponentKind::BaseColor;
723}
724
725#[derive(Clone, PartialEq, AzBuf)]
726pub struct PotDecorations {
727    pub items: Vec<Item>,
728}
729impl DataComponent for PotDecorations {
730    const KIND: DataComponentKind = DataComponentKind::PotDecorations;
731}
732
733#[derive(Clone, PartialEq, AzBuf)]
734pub struct Container {
735    pub items: Vec<ItemStack>,
736}
737impl DataComponent for Container {
738    const KIND: DataComponentKind = DataComponentKind::Container;
739}
740
741#[derive(Clone, PartialEq, AzBuf)]
742pub struct BlockState {
743    pub properties: HashMap<String, String>,
744}
745impl DataComponent for BlockState {
746    const KIND: DataComponentKind = DataComponentKind::BlockState;
747}
748
749#[derive(Clone, PartialEq, AzBuf)]
750pub struct BeehiveOccupant {
751    pub entity_data: NbtCompound,
752    #[var]
753    pub ticks_in_hive: i32,
754    #[var]
755    pub min_ticks_in_hive: i32,
756}
757
758#[derive(Clone, PartialEq, AzBuf)]
759pub struct Bees {
760    pub occupants: Vec<BeehiveOccupant>,
761}
762impl DataComponent for Bees {
763    const KIND: DataComponentKind = DataComponentKind::Bees;
764}
765
766#[derive(Clone, PartialEq, AzBuf)]
767pub struct Lock {
768    pub key: String,
769}
770impl DataComponent for Lock {
771    const KIND: DataComponentKind = DataComponentKind::Lock;
772}
773
774#[derive(Clone, PartialEq, AzBuf)]
775pub struct ContainerLoot {
776    pub loot: NbtCompound,
777}
778impl DataComponent for ContainerLoot {
779    const KIND: DataComponentKind = DataComponentKind::ContainerLoot;
780}
781
782#[derive(Clone, PartialEq, AzBuf)]
783pub struct JukeboxPlayable {
784    pub song: azalea_registry::JukeboxSong,
785    pub show_in_tooltip: bool,
786}
787impl DataComponent for JukeboxPlayable {
788    const KIND: DataComponentKind = DataComponentKind::JukeboxPlayable;
789}
790
791#[derive(Clone, PartialEq, AzBuf)]
792pub struct Consumable {
793    pub consume_seconds: f32,
794    pub animation: ItemUseAnimation,
795    pub sound: SoundEvent,
796    pub has_consume_particles: bool,
797    pub on_consuime_effects: Vec<ConsumeEffectKind>,
798}
799impl DataComponent for Consumable {
800    const KIND: DataComponentKind = DataComponentKind::Consumable;
801}
802
803#[derive(Clone, Copy, PartialEq, AzBuf)]
804pub enum ItemUseAnimation {
805    None,
806    Eat,
807    Drink,
808    Block,
809    Bow,
810    Spear,
811    Crossbow,
812    Spyglass,
813    TootHorn,
814    Brush,
815}
816
817#[derive(Clone, PartialEq, AzBuf)]
818pub struct UseRemainder {
819    pub convert_into: ItemStack,
820}
821impl DataComponent for UseRemainder {
822    const KIND: DataComponentKind = DataComponentKind::UseRemainder;
823}
824
825#[derive(Clone, PartialEq, AzBuf)]
826pub struct UseCooldown {
827    pub seconds: f32,
828    pub cooldown_group: Option<ResourceLocation>,
829}
830impl DataComponent for UseCooldown {
831    const KIND: DataComponentKind = DataComponentKind::UseCooldown;
832}
833
834#[derive(Clone, PartialEq, AzBuf)]
835pub struct Enchantable {
836    #[var]
837    pub value: u32,
838}
839impl DataComponent for Enchantable {
840    const KIND: DataComponentKind = DataComponentKind::Enchantable;
841}
842
843#[derive(Clone, PartialEq, AzBuf)]
844pub struct Repairable {
845    pub items: HolderSet<Item, ResourceLocation>,
846}
847impl DataComponent for Repairable {
848    const KIND: DataComponentKind = DataComponentKind::Repairable;
849}
850
851#[derive(Clone, PartialEq, AzBuf)]
852pub struct ItemModel {
853    pub resource_location: ResourceLocation,
854}
855impl DataComponent for ItemModel {
856    const KIND: DataComponentKind = DataComponentKind::ItemModel;
857}
858
859#[derive(Clone, PartialEq, AzBuf)]
860pub struct DamageResistant {
861    // in the vanilla code this is
862    // ```
863    // StreamCodec.composite(
864    //   TagKey.streamCodec(Registries.DAMAGE_TYPE), DamageResistant::types, DamageResistant::new
865    // );
866    // ```
867    // i'm not entirely sure if this is meant to be a vec or something, i just made it a
868    // resourcelocation for now
869    pub types: ResourceLocation,
870}
871impl DataComponent for DamageResistant {
872    const KIND: DataComponentKind = DataComponentKind::DamageResistant;
873}
874
875#[derive(Clone, PartialEq, AzBuf)]
876pub struct Equippable {
877    pub slot: EquipmentSlot,
878    pub equip_sound: SoundEvent,
879    pub asset_id: Option<ResourceLocation>,
880    pub camera_overlay: Option<ResourceLocation>,
881    pub allowed_entities: Option<HolderSet<EntityKind, ResourceLocation>>,
882    pub dispensable: bool,
883    pub swappable: bool,
884    pub damage_on_hurt: bool,
885}
886impl DataComponent for Equippable {
887    const KIND: DataComponentKind = DataComponentKind::Equippable;
888}
889
890#[derive(Clone, Copy, Debug, PartialEq, AzBuf)]
891pub enum EquipmentSlot {
892    Mainhand,
893    Offhand,
894    Hand,
895    Feet,
896    Legs,
897    Chest,
898    Head,
899    Armor,
900    Body,
901}
902
903#[derive(Clone, PartialEq, AzBuf)]
904pub struct Glider;
905impl DataComponent for Glider {
906    const KIND: DataComponentKind = DataComponentKind::Glider;
907}
908
909#[derive(Clone, PartialEq, AzBuf)]
910pub struct TooltipStyle {
911    pub resource_location: ResourceLocation,
912}
913impl DataComponent for TooltipStyle {
914    const KIND: DataComponentKind = DataComponentKind::TooltipStyle;
915}
916
917#[derive(Clone, PartialEq, AzBuf)]
918pub struct DeathProtection {
919    pub death_effects: Vec<ConsumeEffectKind>,
920}
921impl DataComponent for DeathProtection {
922    const KIND: DataComponentKind = DataComponentKind::DeathProtection;
923}