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 6 => Self::Body,
1136 7 => Self::Saddle,
1137 _ => return None,
1138 };
1139 Some(value)
1140 }
1141 pub fn values() -> [Self; 8] {
1142 [
1143 Self::Mainhand,
1144 Self::Offhand,
1145 Self::Feet,
1146 Self::Legs,
1147 Self::Chest,
1148 Self::Head,
1149 Self::Body,
1150 Self::Saddle,
1151 ]
1152 }
1153 pub fn name(self) -> &'static str {
1155 match self {
1156 Self::Mainhand => "mainhand",
1157 Self::Offhand => "offhand",
1158 Self::Feet => "feet",
1159 Self::Legs => "legs",
1160 Self::Chest => "chest",
1161 Self::Head => "head",
1162 Self::Body => "body",
1163 Self::Saddle => "saddle",
1164 }
1165 }
1166}
1167impl Display for EquipmentSlot {
1168 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1169 write!(f, "{}", self.name())
1170 }
1171}
1172
1173#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1174pub struct Glider;
1175
1176#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1177#[serde(transparent)]
1178pub struct TooltipStyle {
1179 pub resource_location: Identifier,
1180}
1181
1182#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1183pub struct DeathProtection {
1184 pub death_effects: Vec<ConsumeEffect>,
1185}
1186
1187#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1188pub struct Weapon {
1189 #[var]
1190 #[serde(skip_serializing_if = "is_default_item_damage_per_attack")]
1191 pub item_damage_per_attack: i32,
1192 #[serde(skip_serializing_if = "is_default")]
1193 pub disable_blocking_for_seconds: f32,
1194}
1195fn is_default_item_damage_per_attack(value: &i32) -> bool {
1196 *value == 1
1197}
1198
1199impl Weapon {
1200 pub const fn new() -> Self {
1201 Self {
1202 item_damage_per_attack: 1,
1203 disable_blocking_for_seconds: 0.,
1204 }
1205 }
1206}
1207impl Default for Weapon {
1208 fn default() -> Self {
1209 Self::new()
1210 }
1211}
1212
1213#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1214#[serde(transparent)]
1215pub struct PotionDurationScale {
1216 pub value: f32,
1217}
1218
1219#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1220#[serde(transparent)]
1221pub struct VillagerVariant {
1222 pub variant: VillagerKind,
1223}
1224
1225#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1226#[serde(transparent)]
1227pub struct WolfVariant {
1228 pub variant: data::WolfVariant,
1229}
1230
1231#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1232#[serde(transparent)]
1233pub struct WolfCollar {
1234 pub color: DyeColor,
1235}
1236
1237#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1238#[serde(transparent)]
1239pub struct FoxVariant {
1240 pub variant: FoxVariantKind,
1241}
1242
1243#[derive(AzBuf, Clone, Copy, Debug, Default, PartialEq)]
1244pub enum FoxVariantKind {
1245 #[default]
1246 Red,
1247 Snow,
1248}
1249impl Display for FoxVariantKind {
1250 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1251 match self {
1252 Self::Red => write!(f, "minecraft:red"),
1253 Self::Snow => write!(f, "minecraft:snow"),
1254 }
1255 }
1256}
1257impl Serialize for FoxVariantKind {
1258 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1259 where
1260 S: Serializer,
1261 {
1262 serializer.serialize_str(&self.to_string())
1263 }
1264}
1265
1266#[derive(AzBuf, Clone, Copy, Debug, PartialEq, Serialize)]
1267#[serde(rename_all = "snake_case")]
1268pub enum SalmonSize {
1269 Small,
1270 Medium,
1271 Large,
1272}
1273
1274#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1275#[serde(transparent)]
1276pub struct ParrotVariant {
1277 pub variant: ParrotVariantKind,
1278}
1279#[derive(AzBuf, Clone, Copy, Debug, PartialEq)]
1280pub enum ParrotVariantKind {
1281 RedBlue,
1282 Blue,
1283 Green,
1284 YellowBlue,
1285 Gray,
1286}
1287impl Display for ParrotVariantKind {
1288 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1289 match self {
1290 Self::RedBlue => write!(f, "minecraft:red_blue"),
1291 Self::Blue => write!(f, "minecraft:blue"),
1292 Self::Green => write!(f, "minecraft:green"),
1293 Self::YellowBlue => write!(f, "minecraft:yellow_blue"),
1294 Self::Gray => write!(f, "minecraft:gray"),
1295 }
1296 }
1297}
1298impl Serialize for ParrotVariantKind {
1299 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1300 where
1301 S: Serializer,
1302 {
1303 serializer.serialize_str(&self.to_string())
1304 }
1305}
1306
1307#[derive(AzBuf, Clone, Copy, Debug, PartialEq, Serialize)]
1308#[serde(rename_all = "snake_case")]
1309pub enum TropicalFishPattern {
1310 Kob,
1311 Sunstreak,
1312 Snooper,
1313 Dasher,
1314 Brinely,
1315 Spotty,
1316 Flopper,
1317 Stripey,
1318 Glitter,
1319 Blockfish,
1320 Betty,
1321 Clayfish,
1322}
1323
1324#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1325#[serde(transparent)]
1326pub struct TropicalFishBaseColor {
1327 pub color: DyeColor,
1328}
1329
1330#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1331#[serde(transparent)]
1332pub struct TropicalFishPatternColor {
1333 pub color: DyeColor,
1334}
1335
1336#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1337#[serde(transparent)]
1338pub struct MooshroomVariant {
1339 pub variant: MooshroomVariantKind,
1340}
1341#[derive(AzBuf, Clone, Copy, Debug, Default, PartialEq)]
1342pub enum MooshroomVariantKind {
1343 #[default]
1344 Red,
1345 Brown,
1346}
1347impl Display for MooshroomVariantKind {
1348 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1349 match self {
1350 Self::Red => write!(f, "minecraft:red"),
1351 Self::Brown => write!(f, "minecraft:brown"),
1352 }
1353 }
1354}
1355impl Serialize for MooshroomVariantKind {
1356 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1357 where
1358 S: Serializer,
1359 {
1360 serializer.serialize_str(&self.to_string())
1361 }
1362}
1363
1364#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1365#[serde(transparent)]
1366pub struct RabbitVariant {
1367 pub variant: RabbitVariantKind,
1368}
1369#[derive(AzBuf, Clone, Copy, Debug, Default, PartialEq)]
1370pub enum RabbitVariantKind {
1371 #[default]
1372 Brown,
1373 White,
1374 Black,
1375 WhiteSplotched,
1376 Gold,
1377 Salt,
1378 Evil,
1379}
1380impl Display for RabbitVariantKind {
1381 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1382 match self {
1383 Self::Brown => write!(f, "minecraft:brown"),
1384 Self::White => write!(f, "minecraft:white"),
1385 Self::Black => write!(f, "minecraft:black"),
1386 Self::WhiteSplotched => write!(f, "minecraft:white_splotched"),
1387 Self::Gold => write!(f, "minecraft:gold"),
1388 Self::Salt => write!(f, "minecraft:salt"),
1389 Self::Evil => write!(f, "minecraft:evil"),
1390 }
1391 }
1392}
1393impl Serialize for RabbitVariantKind {
1394 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1395 where
1396 S: Serializer,
1397 {
1398 serializer.serialize_str(&self.to_string())
1399 }
1400}
1401
1402#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1403#[serde(transparent)]
1404pub struct PigVariant {
1405 pub variant: data::PigVariant,
1406}
1407
1408#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1409#[serde(transparent)]
1410pub struct FrogVariant {
1411 pub variant: data::FrogVariant,
1412}
1413
1414#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1415#[serde(transparent)]
1416pub struct HorseVariant {
1417 pub variant: HorseVariantKind,
1418}
1419#[derive(AzBuf, Clone, Copy, Debug, Default, PartialEq)]
1420pub enum HorseVariantKind {
1421 #[default]
1422 White,
1423 Creamy,
1424 Chestnut,
1425 Brown,
1426 Black,
1427 Gray,
1428 DarkBrown,
1429}
1430impl Display for HorseVariantKind {
1431 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1432 match self {
1433 Self::White => write!(f, "minecraft:white"),
1434 Self::Creamy => write!(f, "minecraft:creamy"),
1435 Self::Chestnut => write!(f, "minecraft:chestnut"),
1436 Self::Brown => write!(f, "minecraft:brown"),
1437 Self::Black => write!(f, "minecraft:black"),
1438 Self::Gray => write!(f, "minecraft:gray"),
1439 Self::DarkBrown => write!(f, "minecraft:dark_brown"),
1440 }
1441 }
1442}
1443impl Serialize for HorseVariantKind {
1444 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1445 where
1446 S: Serializer,
1447 {
1448 serializer.serialize_str(&self.to_string())
1449 }
1450}
1451
1452#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1453#[serde(transparent)]
1454pub struct PaintingVariant {
1455 pub variant: Holder<data::PaintingVariant, PaintingVariantData>,
1456}
1457
1458#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1459pub struct PaintingVariantData {
1460 #[var]
1461 pub width: i32,
1462 #[var]
1463 pub height: i32,
1464 pub asset_id: Identifier,
1465 #[serde(skip_serializing_if = "is_default")]
1466 pub title: Option<FormattedText>,
1467 #[serde(skip_serializing_if = "is_default")]
1468 pub author: Option<FormattedText>,
1469}
1470
1471#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1472#[serde(transparent)]
1473pub struct LlamaVariant {
1474 pub variant: LlamaVariantKind,
1475}
1476#[derive(AzBuf, Clone, Copy, Debug, Default, PartialEq)]
1477pub enum LlamaVariantKind {
1478 #[default]
1479 Creamy,
1480 White,
1481 Brown,
1482 Gray,
1483}
1484impl Display for LlamaVariantKind {
1485 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1486 match self {
1487 Self::Creamy => write!(f, "minecraft:creamy"),
1488 Self::White => write!(f, "minecraft:white"),
1489 Self::Brown => write!(f, "minecraft:brown"),
1490 Self::Gray => write!(f, "minecraft:gray"),
1491 }
1492 }
1493}
1494impl Serialize for LlamaVariantKind {
1495 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1496 where
1497 S: Serializer,
1498 {
1499 serializer.serialize_str(&self.to_string())
1500 }
1501}
1502
1503#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1504#[serde(transparent)]
1505pub struct AxolotlVariant {
1506 pub variant: AxolotlVariantKind,
1507}
1508#[derive(AzBuf, Clone, Copy, Debug, Default, PartialEq)]
1509pub enum AxolotlVariantKind {
1510 #[default]
1511 Lucy,
1512 Wild,
1513 Gold,
1514 Cyan,
1515 Blue,
1516}
1517impl Display for AxolotlVariantKind {
1518 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1519 match self {
1520 Self::Lucy => write!(f, "minecraft:lucy"),
1521 Self::Wild => write!(f, "minecraft:wild"),
1522 Self::Gold => write!(f, "minecraft:gold"),
1523 Self::Cyan => write!(f, "minecraft:cyan"),
1524 Self::Blue => write!(f, "minecraft:blue"),
1525 }
1526 }
1527}
1528impl Serialize for AxolotlVariantKind {
1529 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1530 where
1531 S: Serializer,
1532 {
1533 serializer.serialize_str(&self.to_string())
1534 }
1535}
1536
1537#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1538#[serde(transparent)]
1539pub struct CatVariant {
1540 pub variant: data::CatVariant,
1541}
1542
1543#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1544#[serde(transparent)]
1545pub struct CatCollar {
1546 pub color: DyeColor,
1547}
1548
1549#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1550#[serde(transparent)]
1551pub struct SheepColor {
1552 pub color: DyeColor,
1553}
1554
1555#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1556#[serde(transparent)]
1557pub struct ShulkerColor {
1558 pub color: DyeColor,
1559}
1560
1561#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1562pub struct TooltipDisplay {
1563 #[serde(skip_serializing_if = "is_default")]
1564 pub hide_tooltip: bool,
1565 #[serde(skip_serializing_if = "is_default")]
1566 pub hidden_components: Vec<DataComponentKind>,
1567}
1568
1569impl TooltipDisplay {
1570 pub const fn new() -> Self {
1571 Self {
1572 hide_tooltip: false,
1573 hidden_components: Vec::new(),
1574 }
1575 }
1576}
1577impl Default for TooltipDisplay {
1578 fn default() -> Self {
1579 Self::new()
1580 }
1581}
1582
1583#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1584pub struct BlocksAttacks {
1585 #[serde(skip_serializing_if = "is_default")]
1586 pub block_delay_seconds: f32,
1587 #[serde(skip_serializing_if = "is_default_disable_cooldown_scale")]
1588 pub disable_cooldown_scale: f32,
1589 #[serde(skip_serializing_if = "is_default")]
1590 pub damage_reductions: Vec<DamageReduction>,
1591 #[serde(skip_serializing_if = "is_default")]
1592 pub item_damage: ItemDamageFunction,
1593 #[serde(skip_serializing_if = "is_default")]
1594 pub bypassed_by: Option<Identifier>,
1595 #[serde(skip_serializing_if = "is_default")]
1596 pub block_sound: Option<azalea_registry::Holder<SoundEvent, CustomSound>>,
1597 #[serde(skip_serializing_if = "is_default")]
1598 pub disabled_sound: Option<azalea_registry::Holder<SoundEvent, CustomSound>>,
1599}
1600fn is_default_disable_cooldown_scale(value: &f32) -> bool {
1601 *value == 1.
1602}
1603
1604impl BlocksAttacks {
1605 pub fn new() -> Self {
1606 Self {
1607 block_delay_seconds: 0.,
1608 disable_cooldown_scale: 1.,
1609 damage_reductions: vec![DamageReduction {
1610 horizontal_blocking_angle: 90.,
1611 kind: None,
1612 base: 0.,
1613 factor: 1.,
1614 }],
1615 item_damage: ItemDamageFunction::default(),
1616 bypassed_by: None,
1617 block_sound: None,
1618 disabled_sound: None,
1619 }
1620 }
1621}
1622impl Default for BlocksAttacks {
1623 fn default() -> Self {
1624 Self::new()
1625 }
1626}
1627
1628#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1629pub struct DamageReduction {
1630 #[serde(skip_serializing_if = "is_default_horizontal_blocking_angle")]
1631 pub horizontal_blocking_angle: f32,
1632 #[serde(skip_serializing_if = "is_default")]
1633 pub kind: Option<HolderSet<DamageKind, Identifier>>,
1634 pub base: f32,
1635 pub factor: f32,
1636}
1637fn is_default_horizontal_blocking_angle(value: &f32) -> bool {
1638 *value == 90.
1639}
1640#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1641pub struct ItemDamageFunction {
1642 pub threshold: f32,
1643 pub base: f32,
1644 pub factor: f32,
1645}
1646impl Default for ItemDamageFunction {
1647 fn default() -> Self {
1648 ItemDamageFunction {
1649 threshold: 1.,
1650 base: 0.,
1651 factor: 1.,
1652 }
1653 }
1654}
1655
1656#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1657#[serde(untagged)]
1658pub enum ProvidesTrimMaterial {
1659 Referenced(Identifier),
1660 Direct(Holder<TrimMaterial, DirectTrimMaterial>),
1661}
1662
1663#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1664pub struct DirectTrimMaterial {
1665 pub assets: MaterialAssetGroup,
1666 pub description: FormattedText,
1667}
1668#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1669pub struct MaterialAssetGroup {
1670 pub base: AssetInfo,
1671 #[serde(skip_serializing_if = "is_default")]
1672 pub overrides: Vec<(Identifier, AssetInfo)>,
1673}
1674
1675#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1676pub struct AssetInfo {
1677 pub suffix: String,
1678}
1679
1680#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1681#[serde(transparent)]
1682pub struct ProvidesBannerPatterns {
1683 pub key: Identifier,
1684}
1685
1686#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1687#[serde(transparent)]
1688pub struct BreakSound {
1689 pub sound: azalea_registry::Holder<SoundEvent, CustomSound>,
1690}
1691
1692#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1693#[serde(transparent)]
1694pub struct WolfSoundVariant {
1695 pub variant: azalea_registry::data::WolfSoundVariant,
1696}
1697
1698#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1699#[serde(transparent)]
1700pub struct CowVariant {
1701 pub variant: azalea_registry::data::CowVariant,
1702}
1703
1704#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1705#[serde(untagged)]
1706pub enum ChickenVariant {
1707 Referenced(Identifier),
1708 Direct(ChickenVariantData),
1709}
1710
1711#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1712pub struct ChickenVariantData {
1713 pub registry: azalea_registry::data::ChickenVariant,
1714}
1715
1716#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1718pub enum ZombieNautilusVariant {
1719 Referenced(Identifier),
1720 Direct(ZombieNautilusVariantData),
1721}
1722#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1723#[serde(transparent)]
1724pub struct ZombieNautilusVariantData {
1725 pub value: azalea_registry::data::ZombieNautilusVariant,
1726}
1727
1728#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1729pub struct UseEffects {
1730 pub can_sprint: bool,
1731 pub interact_vibrations: bool,
1732 pub speed_multiplier: f32,
1733}
1734impl UseEffects {
1735 pub const fn new() -> Self {
1736 Self {
1737 can_sprint: false,
1738 interact_vibrations: true,
1739 speed_multiplier: 0.2,
1740 }
1741 }
1742}
1743impl Default for UseEffects {
1744 fn default() -> Self {
1745 Self::new()
1746 }
1747}
1748
1749#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1750#[serde(transparent)]
1751pub struct MinimumAttackCharge {
1752 pub value: f32,
1753}
1754
1755#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1757#[serde(untagged)]
1758pub enum DamageType {
1759 Registry(DamageKind),
1760 Holder(Holder<DamageKind, DamageTypeElement>),
1761}
1762
1763#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1764pub struct PiercingWeapon {
1765 pub deals_knockback: bool,
1766 pub dismounts: bool,
1767 pub sound: Option<Holder<SoundEvent, azalea_core::sound::CustomSound>>,
1768 pub hit_sound: Option<Holder<SoundEvent, azalea_core::sound::CustomSound>>,
1769}
1770impl PiercingWeapon {
1771 pub const fn new() -> Self {
1772 Self {
1773 deals_knockback: true,
1774 dismounts: false,
1775 sound: None,
1776 hit_sound: None,
1777 }
1778 }
1779}
1780impl Default for PiercingWeapon {
1781 fn default() -> Self {
1782 Self::new()
1783 }
1784}
1785
1786#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1787pub struct KineticWeapon {
1788 #[var]
1789 pub contact_cooldown_ticks: i32,
1790 #[var]
1791 pub delay_ticks: i32,
1792 pub dismount_conditions: Option<KineticWeaponCondition>,
1793 pub knockback_conditions: Option<KineticWeaponCondition>,
1794 pub damage_conditions: Option<KineticWeaponCondition>,
1795 pub forward_movement: f32,
1796 pub damage_multiplier: f32,
1797 pub sound: Option<Holder<SoundEvent, azalea_core::sound::CustomSound>>,
1798 pub hit_sound: Option<Holder<SoundEvent, azalea_core::sound::CustomSound>>,
1799}
1800impl KineticWeapon {
1801 pub const fn new() -> Self {
1802 Self {
1803 contact_cooldown_ticks: 10,
1804 delay_ticks: 0,
1805 dismount_conditions: None,
1806 knockback_conditions: None,
1807 damage_conditions: None,
1808 forward_movement: 0.,
1809 damage_multiplier: 1.,
1810 sound: None,
1811 hit_sound: None,
1812 }
1813 }
1814}
1815impl Default for KineticWeapon {
1816 fn default() -> Self {
1817 Self::new()
1818 }
1819}
1820
1821#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1822pub struct KineticWeaponCondition {
1823 #[var]
1824 pub max_duration_ticks: i32,
1825 pub min_speed: f32,
1826 pub min_relative_speed: f32,
1827}
1828impl KineticWeaponCondition {
1829 pub const fn new() -> Self {
1830 Self {
1831 max_duration_ticks: 0,
1832 min_speed: 0.,
1833 min_relative_speed: 0.,
1834 }
1835 }
1836}
1837impl Default for KineticWeaponCondition {
1838 fn default() -> Self {
1839 Self::new()
1840 }
1841}
1842
1843#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1844pub struct SwingAnimation {
1845 #[serde(rename = "type")]
1846 pub kind: SwingAnimationKind,
1847 #[var]
1848 pub duration: i32,
1849}
1850impl SwingAnimation {
1851 pub const fn new() -> Self {
1852 Self {
1853 kind: SwingAnimationKind::Whack,
1854 duration: 6,
1855 }
1856 }
1857}
1858impl Default for SwingAnimation {
1859 fn default() -> Self {
1860 Self::new()
1861 }
1862}
1863
1864#[derive(AzBuf, Clone, Copy, Debug, PartialEq, Serialize)]
1865#[serde(rename_all = "snake_case")]
1866pub enum SwingAnimationKind {
1867 None,
1868 Whack,
1869 Stab,
1870}
1871
1872#[derive(AzBuf, Clone, Debug, PartialEq, Serialize)]
1873pub struct AttackRange {
1874 pub min_reach: f32,
1875 pub max_reach: f32,
1876 pub min_creative_reach: f32,
1877 pub max_creative_reach: f32,
1878 pub hitbox_margin: f32,
1879 pub mob_factor: f32,
1880}
1881impl AttackRange {
1882 pub const fn new() -> Self {
1883 Self {
1884 min_reach: 0.,
1885 max_reach: 3.,
1886 min_creative_reach: 0.,
1887 max_creative_reach: 5.,
1888 hitbox_margin: 0.3,
1889 mob_factor: 1.,
1890 }
1891 }
1892}
1893impl Default for AttackRange {
1894 fn default() -> Self {
1895 Self::new()
1896 }
1897}