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