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