1mod profile;
2
3use core::f64;
4use std::{
5 any::Any,
6 collections::HashMap,
7 fmt::{self, Display},
8 io::{self, Cursor},
9 mem::ManuallyDrop,
10};
11
12use azalea_buf::{AzBuf, BufReadError};
13use azalea_chat::FormattedText;
14use azalea_core::{
15 attribute_modifier_operation::AttributeModifierOperation,
16 checksum::{Checksum, get_checksum},
17 codec_utils::*,
18 filterable::Filterable,
19 position::GlobalPos,
20 registry_holder::{RegistryHolder, dimension_type::DamageTypeElement},
21 sound::CustomSound,
22};
23use azalea_registry::{
24 Holder, HolderSet,
25 builtin::{
26 Attribute, BlockKind, DataComponentKind, EntityKind, ItemKind, MobEffect, Potion,
27 SoundEvent, VillagerKind,
28 },
29 data::{self, DamageKind, Enchantment, JukeboxSong, TrimMaterial, TrimPattern},
30 identifier::Identifier,
31};
32pub use profile::*;
33use serde::{Serialize, Serializer, ser::SerializeMap};
34use simdnbt::owned::{Nbt, NbtCompound};
35use tracing::trace;
36
37use crate::{ItemStack, item::consume_effect::ConsumeEffect};
38
39pub trait DataComponentTrait:
40 Send + Sync + Any + Clone + Serialize + Into<DataComponentUnion>
41{
42 const KIND: DataComponentKind;
43}
44
45pub trait EncodableDataComponent: Send + Sync + Any {
46 fn encode(&self, buf: &mut Vec<u8>) -> io::Result<()>;
47 fn crc_hash(&self, registries: &RegistryHolder) -> Checksum;
48 fn clone(&self) -> Box<dyn EncodableDataComponent>;
51 fn eq(&self, other: &dyn EncodableDataComponent) -> bool;
53}
54
55impl<T> EncodableDataComponent for T
56where
57 T: DataComponentTrait + Clone + AzBuf + PartialEq,
58{
59 fn encode(&self, buf: &mut Vec<u8>) -> io::Result<()> {
60 self.azalea_write(buf)
61 }
62 fn crc_hash(&self, registries: &RegistryHolder) -> Checksum {
63 get_checksum(self, registries).expect("serializing data components should always succeed")
64 }
65 fn clone(&self) -> Box<dyn EncodableDataComponent> {
66 let cloned = self.clone();
67 Box::new(cloned)
68 }
69 fn eq(&self, other: &dyn EncodableDataComponent) -> bool {
70 let other_any: &dyn Any = other;
71 match other_any.downcast_ref::<T>() {
72 Some(other) => self == other,
73 _ => false,
74 }
75 }
76}
77
78#[macro_export]
79macro_rules! define_data_components {
80 ( $( $x:ident ),* $(,)? ) => {
81 #[allow(non_snake_case)]
91 pub union DataComponentUnion {
92 $( $x: ManuallyDrop<$x>, )*
93 }
94 impl DataComponentUnion {
95 pub unsafe fn serialize_entry_as<S: SerializeMap>(
99 &self,
100 serializer: &mut S,
101 kind: DataComponentKind,
102 ) -> Result<(), S::Error> {
103 match kind {
104 $( DataComponentKind::$x => { unsafe { serializer.serialize_entry(&kind, &*self.$x) } }, )*
105 }
106 }
107 pub unsafe fn drop_as(&mut self, kind: DataComponentKind) {
111 match kind {
112 $( DataComponentKind::$x => { unsafe { ManuallyDrop::drop(&mut self.$x) } }, )*
113 }
114 }
115 pub unsafe fn as_kind(&self, kind: DataComponentKind) -> &dyn EncodableDataComponent {
119 match kind {
120 $( DataComponentKind::$x => { unsafe { &**(&self.$x as &ManuallyDrop<dyn EncodableDataComponent>) } }, )*
121 }
122 }
123 pub fn azalea_read_as(
124 kind: DataComponentKind,
125 buf: &mut Cursor<&[u8]>,
126 ) -> Result<Self, BufReadError> {
127 trace!("Reading data component {kind}");
128
129 Ok(match kind {
130 $( DataComponentKind::$x => {
131 let v = $x::azalea_read(buf)?;
132 Self { $x: ManuallyDrop::new(v) }
133 }, )*
134 })
135 }
136 pub unsafe fn azalea_write_as(
140 &self,
141 kind: DataComponentKind,
142 buf: &mut impl std::io::Write,
143 ) -> io::Result<()> {
144 let mut value = Vec::new();
145 match kind {
146 $( DataComponentKind::$x => unsafe { self.$x.encode(&mut value)? }, )*
147 };
148 buf.write_all(&value)?;
149
150 Ok(())
151 }
152 pub unsafe fn clone_as(
156 &self,
157 kind: DataComponentKind,
158 ) -> Self {
159 match kind {
160 $( DataComponentKind::$x => {
161 Self { $x: unsafe { self.$x.clone() } }
162 }, )*
163 }
164 }
165 pub unsafe fn eq_as(
169 &self,
170 other: &Self,
171 kind: DataComponentKind,
172 ) -> bool {
173 match kind {
174 $( DataComponentKind::$x => unsafe { self.$x.eq(&other.$x) }, )*
175 }
176 }
177 }
178 $(
179 impl From<$x> for DataComponentUnion {
180 fn from(value: $x) -> Self {
181 DataComponentUnion { $x: ManuallyDrop::new(value) }
182 }
183 }
184 )*
185
186 $(
187 impl DataComponentTrait for $x {
188 const KIND: DataComponentKind = DataComponentKind::$x;
189 }
190 )*
191 };
192}
193
194define_data_components!(
199 CustomData,
200 MaxStackSize,
201 MaxDamage,
202 Damage,
203 Unbreakable,
204 CustomName,
205 ItemName,
206 ItemModel,
207 Lore,
208 Rarity,
209 Enchantments,
210 CanPlaceOn,
211 CanBreak,
212 AttributeModifiers,
213 CustomModelData,
214 TooltipDisplay,
215 RepairCost,
216 CreativeSlotLock,
217 EnchantmentGlintOverride,
218 IntangibleProjectile,
219 Food,
220 Consumable,
221 UseRemainder,
222 UseCooldown,
223 DamageResistant,
224 Tool,
225 Weapon,
226 Enchantable,
227 Equippable,
228 Repairable,
229 Glider,
230 TooltipStyle,
231 DeathProtection,
232 BlocksAttacks,
233 StoredEnchantments,
234 DyedColor,
235 MapColor,
236 MapId,
237 MapDecorations,
238 MapPostProcessing,
239 ChargedProjectiles,
240 BundleContents,
241 PotionContents,
242 PotionDurationScale,
243 SuspiciousStewEffects,
244 WritableBookContent,
245 WrittenBookContent,
246 Trim,
247 DebugStickState,
248 EntityData,
249 BucketEntityData,
250 BlockEntityData,
251 Instrument,
252 ProvidesTrimMaterial,
253 OminousBottleAmplifier,
254 JukeboxPlayable,
255 ProvidesBannerPatterns,
256 Recipes,
257 LodestoneTracker,
258 FireworkExplosion,
259 Fireworks,
260 Profile,
261 NoteBlockSound,
262 BannerPatterns,
263 BaseColor,
264 PotDecorations,
265 Container,
266 BlockState,
267 Bees,
268 Lock,
269 ContainerLoot,
270 BreakSound,
271 VillagerVariant,
272 WolfVariant,
273 WolfSoundVariant,
274 WolfCollar,
275 FoxVariant,
276 SalmonSize,
277 ParrotVariant,
278 TropicalFishPattern,
279 TropicalFishBaseColor,
280 TropicalFishPatternColor,
281 MooshroomVariant,
282 RabbitVariant,
283 PigVariant,
284 CowVariant,
285 ChickenVariant,
286 FrogVariant,
287 HorseVariant,
288 PaintingVariant,
289 LlamaVariant,
290 AxolotlVariant,
291 CatVariant,
292 CatCollar,
293 SheepColor,
294 ShulkerColor,
295 UseEffects,
296 MinimumAttackCharge,
297 DamageType,
298 PiercingWeapon,
299 KineticWeapon,
300 SwingAnimation,
301 ZombieNautilusVariant,
302 AttackRange,
303);
304
305#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
306#[serde(transparent)]
307pub struct CustomData {
308 pub nbt: Nbt,
309}
310
311#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
312#[serde(transparent)]
313pub struct MaxStackSize {
314 #[var]
315 pub count: i32,
316}
317
318#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
319#[serde(transparent)]
320pub struct MaxDamage {
321 #[var]
322 pub amount: i32,
323}
324
325#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
326#[serde(transparent)]
327pub struct Damage {
328 #[var]
329 pub amount: i32,
330}
331
332#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
333pub struct Unbreakable;
334
335#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
336#[serde(transparent)]
337pub struct CustomName {
338 pub name: FormattedText,
339}
340
341#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
342#[serde(transparent)]
343pub struct ItemName {
344 pub name: FormattedText,
345}
346
347#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
348#[serde(transparent)]
349pub struct Lore {
350 pub lines: Vec<FormattedText>,
351 }
353
354#[derive(AzBuf, Clone, Copy, Debug, PartialEq, Serialize)]
355#[serde(rename_all = "snake_case")]
356pub enum Rarity {
357 Common,
358 Uncommon,
359 Rare,
360 Epic,
361}
362
363#[derive(AzBuf, Clone, Default, PartialEq, Serialize)]
364#[serde(transparent)]
365pub struct Enchantments {
366 #[var]
368 pub levels: HashMap<Enchantment, i32>,
369}
370
371#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
372pub enum BlockStateValueMatcher {
373 Exact {
374 value: String,
375 },
376 Range {
377 min: Option<String>,
378 max: Option<String>,
379 },
380}
381
382#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
383pub struct BlockStatePropertyMatcher {
384 pub name: String,
385 pub value_matcher: BlockStateValueMatcher,
386}
387
388#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
389pub struct BlockPredicate {
390 #[serde(skip_serializing_if = "is_default")]
391 pub blocks: Option<HolderSet<BlockKind, Identifier>>,
392 #[serde(skip_serializing_if = "is_default")]
393 pub properties: Option<Vec<BlockStatePropertyMatcher>>,
394 #[serde(skip_serializing_if = "is_default")]
395 pub nbt: Option<NbtCompound>,
396}
397
398#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
399#[serde(transparent)]
400pub struct AdventureModePredicate {
401 #[serde(serialize_with = "flatten_array")]
402 pub predicates: Vec<BlockPredicate>,
403}
404
405#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
406#[serde(transparent)]
407pub struct CanPlaceOn {
408 pub predicate: AdventureModePredicate,
409}
410
411#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
412#[serde(transparent)]
413pub struct CanBreak {
414 pub predicate: AdventureModePredicate,
415}
416
417#[derive(AzBuf, Clone, Copy, Debug, PartialEq, Serialize)]
418#[serde(rename_all = "snake_case")]
419pub enum EquipmentSlotGroup {
420 Any,
421 Mainhand,
422 Offhand,
423 Hand,
424 Feet,
425 Legs,
426 Chest,
427 Head,
428 Armor,
429 Body,
430}
431
432#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
436pub struct AttributeModifier {
437 pub id: Identifier,
438 pub amount: f64,
439 pub operation: AttributeModifierOperation,
440}
441
442#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
443pub struct AttributeModifiersEntry {
444 #[serde(rename = "type")]
445 pub kind: Attribute,
446 #[serde(flatten)]
447 pub modifier: AttributeModifier,
448 pub slot: EquipmentSlotGroup,
449 #[serde(skip_serializing_if = "is_default")]
450 pub display: AttributeModifierDisplay,
451}
452
453#[derive(AzBuf, Clone, Debug, Default, PartialEq, Serialize)]
454#[serde(transparent)]
455pub struct AttributeModifiers {
456 pub modifiers: Vec<AttributeModifiersEntry>,
457}
458
459#[derive(AzBuf, Clone, Debug, Default, PartialEq, Serialize)]
460#[serde(rename_all = "snake_case")]
461pub enum AttributeModifierDisplay {
462 #[default]
463 Default,
464 Hidden,
465 Override {
466 text: FormattedText,
467 },
468}
469
470#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
471pub struct CustomModelData {
472 #[serde(skip_serializing_if = "Vec::is_empty")]
473 pub floats: Vec<f32>,
474 #[serde(skip_serializing_if = "Vec::is_empty")]
475 pub flags: Vec<bool>,
476 #[serde(skip_serializing_if = "Vec::is_empty")]
477 pub strings: Vec<String>,
478 #[serde(skip_serializing_if = "Vec::is_empty")]
479 pub colors: Vec<i32>,
480}
481
482#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
483#[serde(transparent)]
484pub struct RepairCost {
485 #[var]
486 pub cost: u32,
487}
488
489#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
490pub struct CreativeSlotLock;
491
492#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
493#[serde(transparent)]
494pub struct EnchantmentGlintOverride {
495 pub show_glint: bool,
496}
497
498#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
499pub struct IntangibleProjectile;
500
501#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
502pub struct MobEffectDetails {
503 #[var]
504 #[serde(skip_serializing_if = "is_default")]
505 pub amplifier: i32,
506 #[var]
507 #[serde(skip_serializing_if = "is_default")]
508 pub duration: i32,
509 #[serde(skip_serializing_if = "is_default")]
510 pub ambient: bool,
511 #[serde(skip_serializing_if = "is_default")]
512 pub show_particles: bool,
513 pub show_icon: bool,
514 #[serde(skip_serializing_if = "is_default")]
515 pub hidden_effect: Option<Box<MobEffectDetails>>,
516}
517impl MobEffectDetails {
518 pub const fn new() -> Self {
519 MobEffectDetails {
520 amplifier: 0,
521 duration: 0,
522 ambient: false,
523 show_particles: true,
524 show_icon: true,
525 hidden_effect: None,
526 }
527 }
528}
529impl Default for MobEffectDetails {
530 fn default() -> Self {
531 Self::new()
532 }
533}
534
535#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
536pub struct MobEffectInstance {
537 pub id: MobEffect,
538 #[serde(flatten)]
539 pub details: MobEffectDetails,
540}
541
542#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
543pub struct PossibleEffect {
544 pub effect: MobEffectInstance,
545 pub probability: f32,
546}
547
548#[derive(AzBuf, Clone, Debug, Default, PartialEq, Serialize)]
549pub struct Food {
550 #[var]
551 pub nutrition: i32,
552 pub saturation: f32,
553 #[serde(skip_serializing_if = "is_default")]
554 pub can_always_eat: bool,
555}
556
557impl Food {
558 pub const fn new() -> Self {
559 Food {
560 nutrition: 0,
561 saturation: 0.,
562 can_always_eat: false,
563 }
564 }
565}
566
567#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
568pub struct ToolRule {
569 pub blocks: HolderSet<BlockKind, Identifier>,
570 #[serde(skip_serializing_if = "is_default")]
571 pub speed: Option<f32>,
572 #[serde(skip_serializing_if = "is_default")]
573 pub correct_for_drops: Option<bool>,
574}
575impl ToolRule {
576 pub const fn new() -> Self {
577 ToolRule {
578 blocks: HolderSet::Direct { contents: vec![] },
579 speed: None,
580 correct_for_drops: None,
581 }
582 }
583}
584impl Default for ToolRule {
585 fn default() -> Self {
586 Self::new()
587 }
588}
589
590#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
591pub struct Tool {
592 #[serde(serialize_with = "flatten_array")]
593 pub rules: Vec<ToolRule>,
594 #[serde(skip_serializing_if = "is_default")]
595 pub default_mining_speed: f32,
596 #[var]
597 #[serde(skip_serializing_if = "is_default")]
598 pub damage_per_block: i32,
599 #[serde(skip_serializing_if = "is_default")]
600 pub can_destroy_blocks_in_creative: bool,
601}
602
603impl Tool {
604 pub const fn new() -> Self {
605 Tool {
606 rules: vec![],
607 default_mining_speed: 1.,
608 damage_per_block: 1,
609 can_destroy_blocks_in_creative: true,
610 }
611 }
612}
613impl Default for Tool {
614 fn default() -> Self {
615 Self::new()
616 }
617}
618
619#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
620#[serde(transparent)]
621pub struct StoredEnchantments {
622 #[var]
623 pub enchantments: HashMap<Enchantment, i32>,
624}
625
626#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
627#[serde(transparent)]
628pub struct DyedColor {
629 pub rgb: i32,
630}
631
632#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
633#[serde(transparent)]
634pub struct MapColor {
635 pub color: i32,
636}
637
638#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
639#[serde(transparent)]
640pub struct MapId {
641 #[var]
642 pub id: i32,
643}
644
645#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
646#[serde(transparent)]
647pub struct MapDecorations {
648 pub decorations: NbtCompound,
649}
650
651#[derive(AzBuf, Clone, Copy, Debug, PartialEq, Serialize)]
652pub enum MapPostProcessing {
653 Lock,
654 Scale,
655}
656
657#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
658#[serde(transparent)]
659pub struct ChargedProjectiles {
660 pub items: Vec<ItemStack>,
661}
662
663#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
664#[serde(transparent)]
665pub struct BundleContents {
666 pub items: Vec<ItemStack>,
667}
668
669#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
670pub struct PotionContents {
671 #[serde(skip_serializing_if = "is_default")]
672 pub potion: Option<Potion>,
673 #[serde(skip_serializing_if = "is_default")]
674 pub custom_color: Option<i32>,
675 #[serde(skip_serializing_if = "is_default")]
676 pub custom_effects: Vec<MobEffectInstance>,
677 #[serde(skip_serializing_if = "is_default")]
678 pub custom_name: Option<String>,
679}
680
681impl PotionContents {
682 pub const fn new() -> Self {
683 PotionContents {
684 potion: None,
685 custom_color: None,
686 custom_effects: vec![],
687 custom_name: None,
688 }
689 }
690}
691impl Default for PotionContents {
692 fn default() -> Self {
693 Self::new()
694 }
695}
696
697#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
698pub struct SuspiciousStewEffect {
699 #[serde(rename = "id")]
700 pub effect: MobEffect,
701 #[var]
702 #[serde(skip_serializing_if = "is_default")]
703 pub duration: i32,
704}
705
706#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
707#[serde(transparent)]
708pub struct SuspiciousStewEffects {
709 pub effects: Vec<SuspiciousStewEffect>,
710}
711
712#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
713pub struct WritableBookContent {
714 pub pages: Vec<Filterable<String>>,
715}
716
717#[derive(AzBuf, Clone, PartialEq, Serialize)]
718pub struct WrittenBookContent {
719 #[limit(32)]
720 pub title: Filterable<String>,
721 pub author: String,
722 #[var]
723 #[serde(skip_serializing_if = "is_default")]
724 pub generation: i32,
725 #[serde(skip_serializing_if = "is_default")]
726 pub pages: Vec<Filterable<FormattedText>>,
727 #[serde(skip_serializing_if = "is_default")]
728 pub resolved: bool,
729}
730
731#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
732pub struct Trim {
733 pub material: TrimMaterial,
734 pub pattern: TrimPattern,
735}
736
737#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
738#[serde(transparent)]
739pub struct DebugStickState {
740 pub properties: NbtCompound,
741}
742
743#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
744pub struct EntityData {
745 #[serde(rename = "id")]
746 pub kind: EntityKind,
747 #[serde(flatten)]
748 pub data: NbtCompound,
749}
750
751#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
752#[serde(transparent)]
753pub struct BucketEntityData {
754 pub entity: NbtCompound,
755}
756
757#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
758pub struct BlockEntityData {
759 #[serde(rename = "id")]
760 pub kind: EntityKind,
761 #[serde(flatten)]
762 pub data: NbtCompound,
763}
764
765#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
766#[serde(untagged)]
767pub enum Instrument {
768 Registry(data::Instrument),
769 Holder(Holder<data::Instrument, InstrumentData>),
770}
771
772#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
773pub struct InstrumentData {
774 pub sound_event: Holder<SoundEvent, azalea_core::sound::CustomSound>,
775 pub use_duration: f32,
776 pub range: f32,
777 pub description: FormattedText,
778}
779
780#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
781#[serde(transparent)]
782pub struct OminousBottleAmplifier {
783 #[var]
784 pub amplifier: i32,
785}
786
787#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
788#[serde(transparent)]
789pub struct Recipes {
790 pub recipes: Vec<Identifier>,
791}
792
793#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
794pub struct LodestoneTracker {
795 #[serde(skip_serializing_if = "is_default")]
796 pub target: Option<GlobalPos>,
797 #[serde(skip_serializing_if = "is_true")]
798 pub tracked: bool,
799}
800
801#[derive(AzBuf, Clone, Copy, Debug, PartialEq, Serialize)]
802#[serde(rename_all = "snake_case")]
803pub enum FireworkExplosionShape {
804 SmallBall,
805 LargeBall,
806 Star,
807 Creeper,
808 Burst,
809}
810
811#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
812pub struct FireworkExplosion {
813 pub shape: FireworkExplosionShape,
814 #[serde(skip_serializing_if = "is_default")]
815 pub colors: Vec<i32>,
816 #[serde(skip_serializing_if = "is_default")]
817 pub fade_colors: Vec<i32>,
818 #[serde(skip_serializing_if = "is_default")]
819 pub has_trail: bool,
820 #[serde(skip_serializing_if = "is_default")]
821 pub has_twinkle: bool,
822}
823
824#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
825pub struct Fireworks {
826 #[var]
827 #[serde(skip_serializing_if = "is_default")]
828 pub flight_duration: i32,
829 #[limit(256)]
830 pub explosions: Vec<FireworkExplosion>,
831}
832
833impl Fireworks {
834 pub const fn new() -> Self {
835 Fireworks {
836 flight_duration: 0,
837 explosions: vec![],
838 }
839 }
840}
841impl Default for Fireworks {
842 fn default() -> Self {
843 Self::new()
844 }
845}
846
847#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
848#[serde(transparent)]
849pub struct NoteBlockSound {
850 pub sound: Identifier,
851}
852
853#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
854pub struct BannerPattern {
855 #[var]
856 pub pattern: i32,
857 #[var]
858 pub color: i32,
859}
860
861#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
862#[serde(transparent)]
863pub struct BannerPatterns {
864 pub patterns: Vec<BannerPattern>,
865}
866
867#[derive(AzBuf, Clone, Copy, Debug, PartialEq, Serialize)]
868#[serde(rename_all = "snake_case")]
869pub enum DyeColor {
870 White,
871 Orange,
872 Magenta,
873 LightBlue,
874 Yellow,
875 Lime,
876 Pink,
877 Gray,
878 LightGray,
879 Cyan,
880 Purple,
881 Blue,
882 Brown,
883 Green,
884 Red,
885 Black,
886}
887
888#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
889#[serde(transparent)]
890pub struct BaseColor {
891 pub color: DyeColor,
892}
893
894#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
895#[serde(transparent)]
896pub struct PotDecorations {
897 pub items: Vec<ItemKind>,
898}
899
900#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
901#[serde(transparent)]
902pub struct Container {
903 pub items: Vec<ItemStack>,
904}
905
906#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
907#[serde(transparent)]
908pub struct BlockState {
909 pub properties: HashMap<String, String>,
910}
911
912#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
913pub struct BeehiveOccupant {
914 #[serde(skip_serializing_if = "is_default")]
915 pub entity_data: NbtCompound,
916 #[var]
917 pub ticks_in_hive: i32,
918 #[var]
919 pub min_ticks_in_hive: i32,
920}
921
922#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
923#[serde(transparent)]
924pub struct Bees {
925 pub occupants: Vec<BeehiveOccupant>,
926}
927
928#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
929pub struct Lock {
930 pub key: String,
931}
932
933#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
934pub struct ContainerLoot {
935 pub loot_table: NbtCompound,
936}
937
938#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
939#[serde(untagged)]
940pub enum JukeboxPlayable {
941 Referenced(Identifier),
942 Direct(Holder<JukeboxSong, JukeboxSongData>),
943}
944
945#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
946pub struct JukeboxSongData {
947 pub sound_event: Holder<SoundEvent, CustomSound>,
948 pub description: FormattedText,
949 pub length_in_seconds: f32,
950 #[var]
951 pub comparator_output: i32,
952}
953
954#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
955pub struct Consumable {
956 #[serde(skip_serializing_if = "is_default")]
957 pub consume_seconds: f32,
958 #[serde(skip_serializing_if = "is_default")]
959 pub animation: ItemUseAnimation,
960 #[serde(skip_serializing_if = "is_default_eat_sound")]
961 pub sound: azalea_registry::Holder<SoundEvent, CustomSound>,
962 #[serde(skip_serializing_if = "is_default")]
963 pub has_consume_particles: bool,
964 #[serde(skip_serializing_if = "is_default")]
965 pub on_consume_effects: Vec<ConsumeEffect>,
966}
967fn is_default_eat_sound(sound: &azalea_registry::Holder<SoundEvent, CustomSound>) -> bool {
968 matches!(
969 sound,
970 azalea_registry::Holder::Reference(SoundEvent::EntityGenericEat)
971 )
972}
973
974impl Consumable {
975 pub const fn new() -> Self {
976 Self {
977 consume_seconds: 1.6,
978 animation: ItemUseAnimation::Eat,
979 sound: azalea_registry::Holder::Reference(SoundEvent::EntityGenericEat),
980 has_consume_particles: true,
981 on_consume_effects: Vec::new(),
982 }
983 }
984}
985impl Default for Consumable {
986 fn default() -> Self {
987 Self::new()
988 }
989}
990
991#[derive(AzBuf, Clone, Copy, Debug, Default, PartialEq, Serialize)]
992#[serde(rename_all = "snake_case")]
993pub enum ItemUseAnimation {
994 #[default]
995 None,
996 Eat,
997 Drink,
998 BlockKind,
999 Bow,
1000 Spear,
1001 Crossbow,
1002 Spyglass,
1003 TootHorn,
1004 Brush,
1005}
1006
1007#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1008#[serde(transparent)]
1009pub struct UseRemainder {
1010 pub convert_into: ItemStack,
1011}
1012
1013#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1014pub struct UseCooldown {
1015 pub seconds: f32,
1016 #[serde(skip_serializing_if = "is_default")]
1017 pub cooldown_group: Option<Identifier>,
1018}
1019
1020impl UseCooldown {
1021 pub const fn new() -> Self {
1022 Self {
1023 seconds: 0.,
1024 cooldown_group: None,
1025 }
1026 }
1027}
1028impl Default for UseCooldown {
1029 fn default() -> Self {
1030 Self::new()
1031 }
1032}
1033
1034#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1035pub struct Enchantable {
1036 #[var]
1037 pub value: u32,
1038}
1039
1040#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1041pub struct Repairable {
1042 pub items: HolderSet<ItemKind, Identifier>,
1043}
1044
1045#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1046#[serde(transparent)]
1047pub struct ItemModel {
1048 pub resource_location: Identifier,
1049}
1050
1051#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1052pub struct DamageResistant {
1053 pub types: Identifier,
1055}
1056
1057#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1058pub struct Equippable {
1059 pub slot: EquipmentSlot,
1060 #[serde(skip_serializing_if = "is_default_equip_sound")]
1061 pub equip_sound: SoundEvent,
1062 #[serde(skip_serializing_if = "is_default")]
1063 pub asset_id: Option<Identifier>,
1064 #[serde(skip_serializing_if = "is_default")]
1065 pub camera_overlay: Option<Identifier>,
1066 #[serde(skip_serializing_if = "is_default")]
1067 pub allowed_entities: Option<HolderSet<EntityKind, Identifier>>,
1068 #[serde(skip_serializing_if = "is_true")]
1069 pub dispensable: bool,
1070 #[serde(skip_serializing_if = "is_true")]
1071 pub swappable: bool,
1072 #[serde(skip_serializing_if = "is_true")]
1073 pub damage_on_hurt: bool,
1074 #[serde(skip_serializing_if = "is_default")]
1075 pub equip_on_interact: bool,
1076 #[serde(skip_serializing_if = "is_default")]
1077 pub can_be_sheared: bool,
1078 #[serde(skip_serializing_if = "is_default_shearing_sound")]
1079 pub shearing_sound: SoundEvent,
1080}
1081fn is_default_equip_sound(sound: &SoundEvent) -> bool {
1082 matches!(sound, SoundEvent::ItemArmorEquipGeneric)
1083}
1084fn is_default_shearing_sound(sound: &SoundEvent) -> bool {
1085 matches!(sound, SoundEvent::ItemShearsSnip)
1086}
1087
1088impl Equippable {
1089 pub const fn new() -> Self {
1090 Self {
1091 slot: EquipmentSlot::Body,
1092 equip_sound: SoundEvent::ItemArmorEquipGeneric,
1093 asset_id: None,
1094 camera_overlay: None,
1095 allowed_entities: None,
1096 dispensable: true,
1097 swappable: true,
1098 damage_on_hurt: true,
1099 equip_on_interact: false,
1100 can_be_sheared: false,
1101 shearing_sound: SoundEvent::ItemShearsSnip,
1102 }
1103 }
1104}
1105impl Default for Equippable {
1106 fn default() -> Self {
1107 Self::new()
1108 }
1109}
1110
1111#[derive(AzBuf, Clone, Copy, Debug, Eq, Hash, PartialEq, Serialize)]
1113#[serde(rename_all = "snake_case")]
1114pub enum EquipmentSlot {
1115 Mainhand,
1116 Offhand,
1117 Feet,
1118 Legs,
1119 Chest,
1120 Head,
1121 Body,
1123 Saddle,
1124}
1125impl EquipmentSlot {
1126 #[must_use]
1127 pub fn from_byte(byte: u8) -> Option<Self> {
1128 let value = match byte {
1129 0 => Self::Mainhand,
1130 1 => Self::Offhand,
1131 2 => Self::Feet,
1132 3 => Self::Legs,
1133 4 => Self::Chest,
1134 5 => Self::Head,
1135 _ => return None,
1136 };
1137 Some(value)
1138 }
1139 pub fn values() -> [Self; 8] {
1140 [
1141 Self::Mainhand,
1142 Self::Offhand,
1143 Self::Feet,
1144 Self::Legs,
1145 Self::Chest,
1146 Self::Head,
1147 Self::Body,
1148 Self::Saddle,
1149 ]
1150 }
1151 pub fn name(self) -> &'static str {
1153 match self {
1154 Self::Mainhand => "mainhand",
1155 Self::Offhand => "offhand",
1156 Self::Feet => "feet",
1157 Self::Legs => "legs",
1158 Self::Chest => "chest",
1159 Self::Head => "head",
1160 Self::Body => "body",
1161 Self::Saddle => "saddle",
1162 }
1163 }
1164}
1165impl Display for EquipmentSlot {
1166 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1167 write!(f, "{}", self.name())
1168 }
1169}
1170
1171#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1172pub struct Glider;
1173
1174#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1175#[serde(transparent)]
1176pub struct TooltipStyle {
1177 pub resource_location: Identifier,
1178}
1179
1180#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1181pub struct DeathProtection {
1182 pub death_effects: Vec<ConsumeEffect>,
1183}
1184
1185#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1186pub struct Weapon {
1187 #[var]
1188 #[serde(skip_serializing_if = "is_default_item_damage_per_attack")]
1189 pub item_damage_per_attack: i32,
1190 #[serde(skip_serializing_if = "is_default")]
1191 pub disable_blocking_for_seconds: f32,
1192}
1193fn is_default_item_damage_per_attack(value: &i32) -> bool {
1194 *value == 1
1195}
1196
1197impl Weapon {
1198 pub const fn new() -> Self {
1199 Self {
1200 item_damage_per_attack: 1,
1201 disable_blocking_for_seconds: 0.,
1202 }
1203 }
1204}
1205impl Default for Weapon {
1206 fn default() -> Self {
1207 Self::new()
1208 }
1209}
1210
1211#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1212#[serde(transparent)]
1213pub struct PotionDurationScale {
1214 pub value: f32,
1215}
1216
1217#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1218#[serde(transparent)]
1219pub struct VillagerVariant {
1220 pub variant: VillagerKind,
1221}
1222
1223#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1224#[serde(transparent)]
1225pub struct WolfVariant {
1226 pub variant: data::WolfVariant,
1227}
1228
1229#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1230#[serde(transparent)]
1231pub struct WolfCollar {
1232 pub color: DyeColor,
1233}
1234
1235#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1236#[serde(transparent)]
1237pub struct FoxVariant {
1238 pub variant: FoxVariantKind,
1239}
1240
1241#[derive(AzBuf, Clone, Copy, Debug, Default, PartialEq)]
1242pub enum FoxVariantKind {
1243 #[default]
1244 Red,
1245 Snow,
1246}
1247impl Display for FoxVariantKind {
1248 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1249 match self {
1250 Self::Red => write!(f, "minecraft:red"),
1251 Self::Snow => write!(f, "minecraft:snow"),
1252 }
1253 }
1254}
1255impl Serialize for FoxVariantKind {
1256 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1257 where
1258 S: Serializer,
1259 {
1260 serializer.serialize_str(&self.to_string())
1261 }
1262}
1263
1264#[derive(AzBuf, Clone, Copy, Debug, PartialEq, Serialize)]
1265#[serde(rename_all = "snake_case")]
1266pub enum SalmonSize {
1267 Small,
1268 Medium,
1269 Large,
1270}
1271
1272#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1273#[serde(transparent)]
1274pub struct ParrotVariant {
1275 pub variant: ParrotVariantKind,
1276}
1277#[derive(AzBuf, Clone, Copy, Debug, PartialEq)]
1278pub enum ParrotVariantKind {
1279 RedBlue,
1280 Blue,
1281 Green,
1282 YellowBlue,
1283 Gray,
1284}
1285impl Display for ParrotVariantKind {
1286 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1287 match self {
1288 Self::RedBlue => write!(f, "minecraft:red_blue"),
1289 Self::Blue => write!(f, "minecraft:blue"),
1290 Self::Green => write!(f, "minecraft:green"),
1291 Self::YellowBlue => write!(f, "minecraft:yellow_blue"),
1292 Self::Gray => write!(f, "minecraft:gray"),
1293 }
1294 }
1295}
1296impl Serialize for ParrotVariantKind {
1297 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1298 where
1299 S: Serializer,
1300 {
1301 serializer.serialize_str(&self.to_string())
1302 }
1303}
1304
1305#[derive(AzBuf, Clone, Copy, Debug, PartialEq, Serialize)]
1306#[serde(rename_all = "snake_case")]
1307pub enum TropicalFishPattern {
1308 Kob,
1309 Sunstreak,
1310 Snooper,
1311 Dasher,
1312 Brinely,
1313 Spotty,
1314 Flopper,
1315 Stripey,
1316 Glitter,
1317 Blockfish,
1318 Betty,
1319 Clayfish,
1320}
1321
1322#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1323#[serde(transparent)]
1324pub struct TropicalFishBaseColor {
1325 pub color: DyeColor,
1326}
1327
1328#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1329#[serde(transparent)]
1330pub struct TropicalFishPatternColor {
1331 pub color: DyeColor,
1332}
1333
1334#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1335#[serde(transparent)]
1336pub struct MooshroomVariant {
1337 pub variant: MooshroomVariantKind,
1338}
1339#[derive(AzBuf, Clone, Copy, Debug, Default, PartialEq)]
1340pub enum MooshroomVariantKind {
1341 #[default]
1342 Red,
1343 Brown,
1344}
1345impl Display for MooshroomVariantKind {
1346 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1347 match self {
1348 Self::Red => write!(f, "minecraft:red"),
1349 Self::Brown => write!(f, "minecraft:brown"),
1350 }
1351 }
1352}
1353impl Serialize for MooshroomVariantKind {
1354 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1355 where
1356 S: Serializer,
1357 {
1358 serializer.serialize_str(&self.to_string())
1359 }
1360}
1361
1362#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1363#[serde(transparent)]
1364pub struct RabbitVariant {
1365 pub variant: RabbitVariantKind,
1366}
1367#[derive(AzBuf, Clone, Copy, Debug, Default, PartialEq)]
1368pub enum RabbitVariantKind {
1369 #[default]
1370 Brown,
1371 White,
1372 Black,
1373 WhiteSplotched,
1374 Gold,
1375 Salt,
1376 Evil,
1377}
1378impl Display for RabbitVariantKind {
1379 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1380 match self {
1381 Self::Brown => write!(f, "minecraft:brown"),
1382 Self::White => write!(f, "minecraft:white"),
1383 Self::Black => write!(f, "minecraft:black"),
1384 Self::WhiteSplotched => write!(f, "minecraft:white_splotched"),
1385 Self::Gold => write!(f, "minecraft:gold"),
1386 Self::Salt => write!(f, "minecraft:salt"),
1387 Self::Evil => write!(f, "minecraft:evil"),
1388 }
1389 }
1390}
1391impl Serialize for RabbitVariantKind {
1392 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1393 where
1394 S: Serializer,
1395 {
1396 serializer.serialize_str(&self.to_string())
1397 }
1398}
1399
1400#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1401#[serde(transparent)]
1402pub struct PigVariant {
1403 pub variant: data::PigVariant,
1404}
1405
1406#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1407#[serde(transparent)]
1408pub struct FrogVariant {
1409 pub variant: data::FrogVariant,
1410}
1411
1412#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1413#[serde(transparent)]
1414pub struct HorseVariant {
1415 pub variant: HorseVariantKind,
1416}
1417#[derive(AzBuf, Clone, Copy, Debug, Default, PartialEq)]
1418pub enum HorseVariantKind {
1419 #[default]
1420 White,
1421 Creamy,
1422 Chestnut,
1423 Brown,
1424 Black,
1425 Gray,
1426 DarkBrown,
1427}
1428impl Display for HorseVariantKind {
1429 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1430 match self {
1431 Self::White => write!(f, "minecraft:white"),
1432 Self::Creamy => write!(f, "minecraft:creamy"),
1433 Self::Chestnut => write!(f, "minecraft:chestnut"),
1434 Self::Brown => write!(f, "minecraft:brown"),
1435 Self::Black => write!(f, "minecraft:black"),
1436 Self::Gray => write!(f, "minecraft:gray"),
1437 Self::DarkBrown => write!(f, "minecraft:dark_brown"),
1438 }
1439 }
1440}
1441impl Serialize for HorseVariantKind {
1442 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1443 where
1444 S: Serializer,
1445 {
1446 serializer.serialize_str(&self.to_string())
1447 }
1448}
1449
1450#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1451#[serde(transparent)]
1452pub struct PaintingVariant {
1453 pub variant: Holder<data::PaintingVariant, PaintingVariantData>,
1454}
1455
1456#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1457pub struct PaintingVariantData {
1458 #[var]
1459 pub width: i32,
1460 #[var]
1461 pub height: i32,
1462 pub asset_id: Identifier,
1463 #[serde(skip_serializing_if = "is_default")]
1464 pub title: Option<FormattedText>,
1465 #[serde(skip_serializing_if = "is_default")]
1466 pub author: Option<FormattedText>,
1467}
1468
1469#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1470#[serde(transparent)]
1471pub struct LlamaVariant {
1472 pub variant: LlamaVariantKind,
1473}
1474#[derive(AzBuf, Clone, Copy, Debug, Default, PartialEq)]
1475pub enum LlamaVariantKind {
1476 #[default]
1477 Creamy,
1478 White,
1479 Brown,
1480 Gray,
1481}
1482impl Display for LlamaVariantKind {
1483 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1484 match self {
1485 Self::Creamy => write!(f, "minecraft:creamy"),
1486 Self::White => write!(f, "minecraft:white"),
1487 Self::Brown => write!(f, "minecraft:brown"),
1488 Self::Gray => write!(f, "minecraft:gray"),
1489 }
1490 }
1491}
1492impl Serialize for LlamaVariantKind {
1493 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1494 where
1495 S: Serializer,
1496 {
1497 serializer.serialize_str(&self.to_string())
1498 }
1499}
1500
1501#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1502#[serde(transparent)]
1503pub struct AxolotlVariant {
1504 pub variant: AxolotlVariantKind,
1505}
1506#[derive(AzBuf, Clone, Copy, Debug, Default, PartialEq)]
1507pub enum AxolotlVariantKind {
1508 #[default]
1509 Lucy,
1510 Wild,
1511 Gold,
1512 Cyan,
1513 Blue,
1514}
1515impl Display for AxolotlVariantKind {
1516 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1517 match self {
1518 Self::Lucy => write!(f, "minecraft:lucy"),
1519 Self::Wild => write!(f, "minecraft:wild"),
1520 Self::Gold => write!(f, "minecraft:gold"),
1521 Self::Cyan => write!(f, "minecraft:cyan"),
1522 Self::Blue => write!(f, "minecraft:blue"),
1523 }
1524 }
1525}
1526impl Serialize for AxolotlVariantKind {
1527 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1528 where
1529 S: Serializer,
1530 {
1531 serializer.serialize_str(&self.to_string())
1532 }
1533}
1534
1535#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1536#[serde(transparent)]
1537pub struct CatVariant {
1538 pub variant: data::CatVariant,
1539}
1540
1541#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1542#[serde(transparent)]
1543pub struct CatCollar {
1544 pub color: DyeColor,
1545}
1546
1547#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1548#[serde(transparent)]
1549pub struct SheepColor {
1550 pub color: DyeColor,
1551}
1552
1553#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1554#[serde(transparent)]
1555pub struct ShulkerColor {
1556 pub color: DyeColor,
1557}
1558
1559#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1560pub struct TooltipDisplay {
1561 #[serde(skip_serializing_if = "is_default")]
1562 pub hide_tooltip: bool,
1563 #[serde(skip_serializing_if = "is_default")]
1564 pub hidden_components: Vec<DataComponentKind>,
1565}
1566
1567impl TooltipDisplay {
1568 pub const fn new() -> Self {
1569 Self {
1570 hide_tooltip: false,
1571 hidden_components: Vec::new(),
1572 }
1573 }
1574}
1575impl Default for TooltipDisplay {
1576 fn default() -> Self {
1577 Self::new()
1578 }
1579}
1580
1581#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1582pub struct BlocksAttacks {
1583 #[serde(skip_serializing_if = "is_default")]
1584 pub block_delay_seconds: f32,
1585 #[serde(skip_serializing_if = "is_default_disable_cooldown_scale")]
1586 pub disable_cooldown_scale: f32,
1587 #[serde(skip_serializing_if = "is_default")]
1588 pub damage_reductions: Vec<DamageReduction>,
1589 #[serde(skip_serializing_if = "is_default")]
1590 pub item_damage: ItemDamageFunction,
1591 #[serde(skip_serializing_if = "is_default")]
1592 pub bypassed_by: Option<Identifier>,
1593 #[serde(skip_serializing_if = "is_default")]
1594 pub block_sound: Option<azalea_registry::Holder<SoundEvent, CustomSound>>,
1595 #[serde(skip_serializing_if = "is_default")]
1596 pub disabled_sound: Option<azalea_registry::Holder<SoundEvent, CustomSound>>,
1597}
1598fn is_default_disable_cooldown_scale(value: &f32) -> bool {
1599 *value == 1.
1600}
1601
1602impl BlocksAttacks {
1603 pub fn new() -> Self {
1604 Self {
1605 block_delay_seconds: 0.,
1606 disable_cooldown_scale: 1.,
1607 damage_reductions: vec![DamageReduction {
1608 horizontal_blocking_angle: 90.,
1609 kind: None,
1610 base: 0.,
1611 factor: 1.,
1612 }],
1613 item_damage: ItemDamageFunction::default(),
1614 bypassed_by: None,
1615 block_sound: None,
1616 disabled_sound: None,
1617 }
1618 }
1619}
1620impl Default for BlocksAttacks {
1621 fn default() -> Self {
1622 Self::new()
1623 }
1624}
1625
1626#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1627pub struct DamageReduction {
1628 #[serde(skip_serializing_if = "is_default_horizontal_blocking_angle")]
1629 pub horizontal_blocking_angle: f32,
1630 #[serde(skip_serializing_if = "is_default")]
1631 pub kind: Option<HolderSet<DamageKind, Identifier>>,
1632 pub base: f32,
1633 pub factor: f32,
1634}
1635fn is_default_horizontal_blocking_angle(value: &f32) -> bool {
1636 *value == 90.
1637}
1638#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1639pub struct ItemDamageFunction {
1640 pub threshold: f32,
1641 pub base: f32,
1642 pub factor: f32,
1643}
1644impl Default for ItemDamageFunction {
1645 fn default() -> Self {
1646 ItemDamageFunction {
1647 threshold: 1.,
1648 base: 0.,
1649 factor: 1.,
1650 }
1651 }
1652}
1653
1654#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1655#[serde(untagged)]
1656pub enum ProvidesTrimMaterial {
1657 Referenced(Identifier),
1658 Direct(Holder<TrimMaterial, DirectTrimMaterial>),
1659}
1660
1661#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1662pub struct DirectTrimMaterial {
1663 pub assets: MaterialAssetGroup,
1664 pub description: FormattedText,
1665}
1666#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1667pub struct MaterialAssetGroup {
1668 pub base: AssetInfo,
1669 #[serde(skip_serializing_if = "is_default")]
1670 pub overrides: Vec<(Identifier, AssetInfo)>,
1671}
1672
1673#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1674pub struct AssetInfo {
1675 pub suffix: String,
1676}
1677
1678#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1679#[serde(transparent)]
1680pub struct ProvidesBannerPatterns {
1681 pub key: Identifier,
1682}
1683
1684#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1685#[serde(transparent)]
1686pub struct BreakSound {
1687 pub sound: azalea_registry::Holder<SoundEvent, CustomSound>,
1688}
1689
1690#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1691#[serde(transparent)]
1692pub struct WolfSoundVariant {
1693 pub variant: azalea_registry::data::WolfSoundVariant,
1694}
1695
1696#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1697#[serde(transparent)]
1698pub struct CowVariant {
1699 pub variant: azalea_registry::data::CowVariant,
1700}
1701
1702#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1703#[serde(untagged)]
1704pub enum ChickenVariant {
1705 Referenced(Identifier),
1706 Direct(ChickenVariantData),
1707}
1708
1709#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1710pub struct ChickenVariantData {
1711 pub registry: azalea_registry::data::ChickenVariant,
1712}
1713
1714#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1716pub enum ZombieNautilusVariant {
1717 Referenced(Identifier),
1718 Direct(ZombieNautilusVariantData),
1719}
1720#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1721#[serde(transparent)]
1722pub struct ZombieNautilusVariantData {
1723 pub value: azalea_registry::data::ZombieNautilusVariant,
1724}
1725
1726#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1727pub struct UseEffects {
1728 pub can_sprint: bool,
1729 pub interact_vibrations: bool,
1730 pub speed_multiplier: f32,
1731}
1732impl UseEffects {
1733 pub const fn new() -> Self {
1734 Self {
1735 can_sprint: false,
1736 interact_vibrations: true,
1737 speed_multiplier: 0.2,
1738 }
1739 }
1740}
1741impl Default for UseEffects {
1742 fn default() -> Self {
1743 Self::new()
1744 }
1745}
1746
1747#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1748#[serde(transparent)]
1749pub struct MinimumAttackCharge {
1750 pub value: f32,
1751}
1752
1753#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1755#[serde(untagged)]
1756pub enum DamageType {
1757 Registry(DamageKind),
1758 Holder(Holder<DamageKind, DamageTypeElement>),
1759}
1760
1761#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1762pub struct PiercingWeapon {
1763 pub deals_knockback: bool,
1764 pub dismounts: bool,
1765 pub sound: Option<Holder<SoundEvent, azalea_core::sound::CustomSound>>,
1766 pub hit_sound: Option<Holder<SoundEvent, azalea_core::sound::CustomSound>>,
1767}
1768impl PiercingWeapon {
1769 pub const fn new() -> Self {
1770 Self {
1771 deals_knockback: true,
1772 dismounts: false,
1773 sound: None,
1774 hit_sound: None,
1775 }
1776 }
1777}
1778impl Default for PiercingWeapon {
1779 fn default() -> Self {
1780 Self::new()
1781 }
1782}
1783
1784#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1785pub struct KineticWeapon {
1786 #[var]
1787 pub contact_cooldown_ticks: i32,
1788 #[var]
1789 pub delay_ticks: i32,
1790 pub dismount_conditions: Option<KineticWeaponCondition>,
1791 pub knockback_conditions: Option<KineticWeaponCondition>,
1792 pub damage_conditions: Option<KineticWeaponCondition>,
1793 pub forward_movement: f32,
1794 pub damage_multiplier: f32,
1795 pub sound: Option<Holder<SoundEvent, azalea_core::sound::CustomSound>>,
1796 pub hit_sound: Option<Holder<SoundEvent, azalea_core::sound::CustomSound>>,
1797}
1798impl KineticWeapon {
1799 pub const fn new() -> Self {
1800 Self {
1801 contact_cooldown_ticks: 10,
1802 delay_ticks: 0,
1803 dismount_conditions: None,
1804 knockback_conditions: None,
1805 damage_conditions: None,
1806 forward_movement: 0.,
1807 damage_multiplier: 1.,
1808 sound: None,
1809 hit_sound: None,
1810 }
1811 }
1812}
1813impl Default for KineticWeapon {
1814 fn default() -> Self {
1815 Self::new()
1816 }
1817}
1818
1819#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1820pub struct KineticWeaponCondition {
1821 #[var]
1822 pub max_duration_ticks: i32,
1823 pub min_speed: f32,
1824 pub min_relative_speed: f32,
1825}
1826impl KineticWeaponCondition {
1827 pub const fn new() -> Self {
1828 Self {
1829 max_duration_ticks: 0,
1830 min_speed: 0.,
1831 min_relative_speed: 0.,
1832 }
1833 }
1834}
1835impl Default for KineticWeaponCondition {
1836 fn default() -> Self {
1837 Self::new()
1838 }
1839}
1840
1841#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1842pub struct SwingAnimation {
1843 #[serde(rename = "type")]
1844 pub kind: SwingAnimationKind,
1845 #[var]
1846 pub duration: i32,
1847}
1848impl SwingAnimation {
1849 pub const fn new() -> Self {
1850 Self {
1851 kind: SwingAnimationKind::Whack,
1852 duration: 6,
1853 }
1854 }
1855}
1856impl Default for SwingAnimation {
1857 fn default() -> Self {
1858 Self::new()
1859 }
1860}
1861
1862#[derive(AzBuf, Clone, Copy, Debug, PartialEq, Serialize)]
1863#[serde(rename_all = "snake_case")]
1864pub enum SwingAnimationKind {
1865 None,
1866 Whack,
1867 Stab,
1868}
1869
1870#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1871pub struct AttackRange {
1872 pub min_reach: f32,
1873 pub max_reach: f32,
1874 pub min_creative_reach: f32,
1875 pub max_creative_reach: f32,
1876 pub hitbox_margin: f32,
1877 pub mob_factor: f32,
1878}
1879impl AttackRange {
1880 pub const fn new() -> Self {
1881 Self {
1882 min_reach: 0.,
1883 max_reach: 3.,
1884 min_creative_reach: 0.,
1885 max_creative_reach: 5.,
1886 hitbox_margin: 0.3,
1887 mob_factor: 1.,
1888 }
1889 }
1890}
1891impl Default for AttackRange {
1892 fn default() -> Self {
1893 Self::new()
1894 }
1895}