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