aboutsummaryrefslogtreecommitdiff
path: root/azalea-inventory/src/components.rs
diff options
context:
space:
mode:
authormat <27899617+mat-1@users.noreply.github.com>2025-08-10 18:55:23 -0500
committerGitHub <noreply@github.com>2025-08-10 18:55:23 -0500
commit7120842f9d2c659a2f12d8922299c2a761bc5582 (patch)
tree0d7976ceec82d914e4c75f23adcdd5839f9960a4 /azalea-inventory/src/components.rs
parent3b659833c1ad4cca89b4cd553193edcb6d223163 (diff)
downloadazalea-drasl-7120842f9d2c659a2f12d8922299c2a761bc5582.tar.xz
Send correct data component checksums (#234)
* start implementing data component crc32 hashes * start doing serde impls for checksums * make more components hashable * make all data components serializable * support recursive components * fix simdnbt dep * update changelog * clippy
Diffstat (limited to 'azalea-inventory/src/components.rs')
-rw-r--r--azalea-inventory/src/components.rs1122
1 files changed, 563 insertions, 559 deletions
diff --git a/azalea-inventory/src/components.rs b/azalea-inventory/src/components.rs
index e11a4491..09923af0 100644
--- a/azalea-inventory/src/components.rs
+++ b/azalea-inventory/src/components.rs
@@ -3,30 +3,40 @@ use std::{
any::Any,
collections::HashMap,
io::{self, Cursor},
+ mem::ManuallyDrop,
};
use azalea_buf::{AzBuf, AzaleaRead, AzaleaWrite, BufReadError};
use azalea_chat::FormattedText;
use azalea_core::{
- filterable::Filterable, position::GlobalPos, resource_location::ResourceLocation,
+ checksum::{Checksum, get_checksum},
+ codec_utils::*,
+ filterable::Filterable,
+ position::GlobalPos,
+ registry_holder::RegistryHolder,
+ resource_location::ResourceLocation,
sound::CustomSound,
};
use azalea_registry::{
self as registry, Attribute, Block, DamageKind, DataComponentKind, Enchantment, EntityKind,
Holder, HolderSet, Item, MobEffect, Potion, SoundEvent, TrimMaterial, TrimPattern,
};
+use serde::{Serialize, ser::SerializeMap};
use simdnbt::owned::{Nbt, NbtCompound};
use tracing::trace;
use uuid::Uuid;
use crate::{ItemStack, item::consume_effect::ConsumeEffect};
-pub trait DataComponent: Send + Sync + Any + Clone {
+pub trait DataComponentTrait:
+ Send + Sync + Any + Clone + Serialize + Into<DataComponentUnion>
+{
const KIND: DataComponentKind;
}
pub trait EncodableDataComponent: Send + Sync + Any {
fn encode(&self, buf: &mut Vec<u8>) -> io::Result<()>;
+ fn crc_hash(&self, registries: &RegistryHolder) -> Checksum;
// using the Clone trait makes it not be object-safe, so we have our own clone
// function instead
fn clone(&self) -> Box<dyn EncodableDataComponent>;
@@ -36,11 +46,14 @@ pub trait EncodableDataComponent: Send + Sync + Any {
impl<T> EncodableDataComponent for T
where
- T: DataComponent + Clone + AzaleaWrite + AzaleaRead + PartialEq,
+ T: DataComponentTrait + Clone + AzaleaWrite + AzaleaRead + PartialEq,
{
fn encode(&self, buf: &mut Vec<u8>) -> io::Result<()> {
self.azalea_write(buf)
}
+ fn crc_hash(&self, registries: &RegistryHolder) -> Checksum {
+ get_checksum(self, registries).expect("serializing data components should always succeed")
+ }
fn clone(&self) -> Box<dyn EncodableDataComponent> {
let cloned = self.clone();
Box::new(cloned)
@@ -54,220 +67,286 @@ where
}
}
-pub fn from_kind(
- kind: registry::DataComponentKind,
- buf: &mut Cursor<&[u8]>,
-) -> Result<Box<dyn EncodableDataComponent>, BufReadError> {
- // if this is causing a compile-time error, look at DataComponents.java in the
- // decompiled vanilla code to see how to implement new components
-
- trace!("Reading data component {kind}");
-
- // note that this match statement is updated by genitemcomponents.py
- Ok(match kind {
- DataComponentKind::CustomData => Box::new(CustomData::azalea_read(buf)?),
- DataComponentKind::MaxStackSize => Box::new(MaxStackSize::azalea_read(buf)?),
- DataComponentKind::MaxDamage => Box::new(MaxDamage::azalea_read(buf)?),
- DataComponentKind::Damage => Box::new(Damage::azalea_read(buf)?),
- DataComponentKind::Unbreakable => Box::new(Unbreakable::azalea_read(buf)?),
- DataComponentKind::CustomName => Box::new(CustomName::azalea_read(buf)?),
- DataComponentKind::ItemName => Box::new(ItemName::azalea_read(buf)?),
- DataComponentKind::Lore => Box::new(Lore::azalea_read(buf)?),
- DataComponentKind::Rarity => Box::new(Rarity::azalea_read(buf)?),
- DataComponentKind::Enchantments => Box::new(Enchantments::azalea_read(buf)?),
- DataComponentKind::CanPlaceOn => Box::new(CanPlaceOn::azalea_read(buf)?),
- DataComponentKind::CanBreak => Box::new(CanBreak::azalea_read(buf)?),
- DataComponentKind::AttributeModifiers => Box::new(AttributeModifiers::azalea_read(buf)?),
- DataComponentKind::CustomModelData => Box::new(CustomModelData::azalea_read(buf)?),
- DataComponentKind::RepairCost => Box::new(RepairCost::azalea_read(buf)?),
- DataComponentKind::CreativeSlotLock => Box::new(CreativeSlotLock::azalea_read(buf)?),
- DataComponentKind::EnchantmentGlintOverride => {
- Box::new(EnchantmentGlintOverride::azalea_read(buf)?)
- }
- DataComponentKind::IntangibleProjectile => {
- Box::new(IntangibleProjectile::azalea_read(buf)?)
- }
- DataComponentKind::Food => Box::new(Food::azalea_read(buf)?),
- DataComponentKind::Tool => Box::new(Tool::azalea_read(buf)?),
- DataComponentKind::StoredEnchantments => Box::new(StoredEnchantments::azalea_read(buf)?),
- DataComponentKind::DyedColor => Box::new(DyedColor::azalea_read(buf)?),
- DataComponentKind::MapColor => Box::new(MapColor::azalea_read(buf)?),
- DataComponentKind::MapId => Box::new(MapId::azalea_read(buf)?),
- DataComponentKind::MapDecorations => Box::new(MapDecorations::azalea_read(buf)?),
- DataComponentKind::MapPostProcessing => Box::new(MapPostProcessing::azalea_read(buf)?),
- DataComponentKind::ChargedProjectiles => Box::new(ChargedProjectiles::azalea_read(buf)?),
- DataComponentKind::BundleContents => Box::new(BundleContents::azalea_read(buf)?),
- DataComponentKind::PotionContents => Box::new(PotionContents::azalea_read(buf)?),
- DataComponentKind::SuspiciousStewEffects => {
- Box::new(SuspiciousStewEffects::azalea_read(buf)?)
- }
- DataComponentKind::WritableBookContent => Box::new(WritableBookContent::azalea_read(buf)?),
- DataComponentKind::WrittenBookContent => Box::new(WrittenBookContent::azalea_read(buf)?),
- DataComponentKind::Trim => Box::new(Trim::azalea_read(buf)?),
- DataComponentKind::DebugStickState => Box::new(DebugStickState::azalea_read(buf)?),
- DataComponentKind::EntityData => Box::new(EntityData::azalea_read(buf)?),
- DataComponentKind::BucketEntityData => Box::new(BucketEntityData::azalea_read(buf)?),
- DataComponentKind::BlockEntityData => Box::new(BlockEntityData::azalea_read(buf)?),
- DataComponentKind::Instrument => Box::new(Instrument::azalea_read(buf)?),
- DataComponentKind::OminousBottleAmplifier => {
- Box::new(OminousBottleAmplifier::azalea_read(buf)?)
+#[macro_export]
+macro_rules! define_data_components {
+ ( $( $x:ident ),* $(,)? ) => {
+ /// A union of all data components.
+ ///
+ /// You probably don't want to use this directly. Consider [`DataComponentPatch`] instead.
+ ///
+ /// This type does not know its own value, and as such every function for it requires the
+ /// `DataComponentKind` to be passed in. Passing the wrong `DataComponentKind` will result
+ /// in undefined behavior. Also, all of the values are `ManuallyDrop`.
+ ///
+ /// [`DataComponentPatch`]: crate::DataComponentPatch
+ #[allow(non_snake_case)]
+ pub union DataComponentUnion {
+ $( $x: ManuallyDrop<$x>, )*
}
- DataComponentKind::Recipes => Box::new(Recipes::azalea_read(buf)?),
- DataComponentKind::LodestoneTracker => Box::new(LodestoneTracker::azalea_read(buf)?),
- DataComponentKind::FireworkExplosion => Box::new(FireworkExplosion::azalea_read(buf)?),
- DataComponentKind::Fireworks => Box::new(Fireworks::azalea_read(buf)?),
- DataComponentKind::Profile => Box::new(Profile::azalea_read(buf)?),
- DataComponentKind::NoteBlockSound => Box::new(NoteBlockSound::azalea_read(buf)?),
- DataComponentKind::BannerPatterns => Box::new(BannerPatterns::azalea_read(buf)?),
- DataComponentKind::BaseColor => Box::new(BaseColor::azalea_read(buf)?),
- DataComponentKind::PotDecorations => Box::new(PotDecorations::azalea_read(buf)?),
- DataComponentKind::Container => Box::new(Container::azalea_read(buf)?),
- DataComponentKind::BlockState => Box::new(BlockState::azalea_read(buf)?),
- DataComponentKind::Bees => Box::new(Bees::azalea_read(buf)?),
- DataComponentKind::Lock => Box::new(Lock::azalea_read(buf)?),
- DataComponentKind::ContainerLoot => Box::new(ContainerLoot::azalea_read(buf)?),
- DataComponentKind::JukeboxPlayable => Box::new(JukeboxPlayable::azalea_read(buf)?),
- DataComponentKind::Consumable => Box::new(Consumable::azalea_read(buf)?),
- DataComponentKind::UseRemainder => Box::new(UseRemainder::azalea_read(buf)?),
- DataComponentKind::UseCooldown => Box::new(UseCooldown::azalea_read(buf)?),
- DataComponentKind::Enchantable => Box::new(Enchantable::azalea_read(buf)?),
- DataComponentKind::Repairable => Box::new(Repairable::azalea_read(buf)?),
- DataComponentKind::ItemModel => Box::new(ItemModel::azalea_read(buf)?),
- DataComponentKind::DamageResistant => Box::new(DamageResistant::azalea_read(buf)?),
- DataComponentKind::Equippable => Box::new(Equippable::azalea_read(buf)?),
- DataComponentKind::Glider => Box::new(Glider::azalea_read(buf)?),
- DataComponentKind::TooltipStyle => Box::new(TooltipStyle::azalea_read(buf)?),
- DataComponentKind::DeathProtection => Box::new(DeathProtection::azalea_read(buf)?),
- DataComponentKind::Weapon => Box::new(Weapon::azalea_read(buf)?),
- DataComponentKind::PotionDurationScale => Box::new(PotionDurationScale::azalea_read(buf)?),
- DataComponentKind::VillagerVariant => Box::new(VillagerVariant::azalea_read(buf)?),
- DataComponentKind::WolfVariant => Box::new(WolfVariant::azalea_read(buf)?),
- DataComponentKind::WolfCollar => Box::new(WolfCollar::azalea_read(buf)?),
- DataComponentKind::FoxVariant => Box::new(FoxVariant::azalea_read(buf)?),
- DataComponentKind::SalmonSize => Box::new(SalmonSize::azalea_read(buf)?),
- DataComponentKind::ParrotVariant => Box::new(ParrotVariant::azalea_read(buf)?),
- DataComponentKind::TropicalFishPattern => Box::new(TropicalFishPattern::azalea_read(buf)?),
- DataComponentKind::TropicalFishBaseColor => {
- Box::new(TropicalFishBaseColor::azalea_read(buf)?)
+ impl DataComponentUnion {
+ /// # Safety
+ ///
+ /// `kind` must be the correct value for this union.
+ pub unsafe fn serialize_entry_as<S: SerializeMap>(
+ &self,
+ serializer: &mut S,
+ kind: DataComponentKind,
+ ) -> Result<(), S::Error> {
+ match kind {
+ $( DataComponentKind::$x => { unsafe { serializer.serialize_entry(&kind, &*self.$x) } }, )*
+ }
+ }
+ /// # Safety
+ ///
+ /// `kind` must be the correct value for this union.
+ pub unsafe fn drop_as(&mut self, kind: DataComponentKind) {
+ match kind {
+ $( DataComponentKind::$x => { unsafe { ManuallyDrop::drop(&mut self.$x) } }, )*
+ }
+ }
+ /// # Safety
+ ///
+ /// `kind` must be the correct value for this union.
+ pub unsafe fn as_kind(&self, kind: DataComponentKind) -> &dyn EncodableDataComponent {
+ match kind {
+ $( DataComponentKind::$x => { unsafe { &**(&self.$x as &ManuallyDrop<dyn EncodableDataComponent>) } }, )*
+ }
+ }
+ pub fn azalea_read_as(
+ kind: registry::DataComponentKind,
+ buf: &mut Cursor<&[u8]>,
+ ) -> Result<Self, BufReadError> {
+ trace!("Reading data component {kind}");
+
+ Ok(match kind {
+ $( DataComponentKind::$x => {
+ Self { $x: ManuallyDrop::new($x::azalea_read(buf)?) }
+ }, )*
+ })
+ }
+ /// # Safety
+ ///
+ /// `kind` must be the correct value for this union.
+ pub unsafe fn azalea_write_as(
+ &self,
+ kind: registry::DataComponentKind,
+ buf: &mut Vec<u8>,
+ ) -> io::Result<()> {
+ match kind {
+ $( DataComponentKind::$x => unsafe { self.$x.encode(buf) }, )*
+ }
+ }
+ /// # Safety
+ ///
+ /// `kind` must be the correct value for this union.
+ pub unsafe fn clone_as(
+ &self,
+ kind: registry::DataComponentKind,
+ ) -> Self {
+ match kind {
+ $( DataComponentKind::$x => {
+ Self { $x: unsafe { self.$x.clone() } }
+ }, )*
+ }
+ }
+ /// # Safety
+ ///
+ /// `kind` must be the correct value for this union.
+ pub unsafe fn eq_as(
+ &self,
+ other: &Self,
+ kind: registry::DataComponentKind,
+ ) -> bool {
+ match kind {
+ $( DataComponentKind::$x => unsafe { self.$x.eq(&other.$x) }, )*
+ }
+ }
}
- DataComponentKind::TropicalFishPatternColor => {
- Box::new(TropicalFishPatternColor::azalea_read(buf)?)
- }
- DataComponentKind::MooshroomVariant => Box::new(MooshroomVariant::azalea_read(buf)?),
- DataComponentKind::RabbitVariant => Box::new(RabbitVariant::azalea_read(buf)?),
- DataComponentKind::PigVariant => Box::new(PigVariant::azalea_read(buf)?),
- DataComponentKind::FrogVariant => Box::new(FrogVariant::azalea_read(buf)?),
- DataComponentKind::HorseVariant => Box::new(HorseVariant::azalea_read(buf)?),
- DataComponentKind::PaintingVariant => Box::new(PaintingVariant::azalea_read(buf)?),
- DataComponentKind::LlamaVariant => Box::new(LlamaVariant::azalea_read(buf)?),
- DataComponentKind::AxolotlVariant => Box::new(AxolotlVariant::azalea_read(buf)?),
- DataComponentKind::CatVariant => Box::new(CatVariant::azalea_read(buf)?),
- DataComponentKind::CatCollar => Box::new(CatCollar::azalea_read(buf)?),
- DataComponentKind::SheepColor => Box::new(SheepColor::azalea_read(buf)?),
- DataComponentKind::ShulkerColor => Box::new(ShulkerColor::azalea_read(buf)?),
- DataComponentKind::TooltipDisplay => Box::new(TooltipDisplay::azalea_read(buf)?),
- DataComponentKind::BlocksAttacks => Box::new(BlocksAttacks::azalea_read(buf)?),
- DataComponentKind::ProvidesTrimMaterial => {
- Box::new(ProvidesTrimMaterial::azalea_read(buf)?)
- }
- DataComponentKind::ProvidesBannerPatterns => {
- Box::new(ProvidesBannerPatterns::azalea_read(buf)?)
- }
- DataComponentKind::BreakSound => Box::new(BreakSound::azalea_read(buf)?),
- DataComponentKind::WolfSoundVariant => Box::new(WolfSoundVariant::azalea_read(buf)?),
- DataComponentKind::CowVariant => Box::new(CowVariant::azalea_read(buf)?),
- DataComponentKind::ChickenVariant => Box::new(ChickenVariant::azalea_read(buf)?),
- })
-}
-
-#[derive(Clone, PartialEq, AzBuf)]
+ $(
+ impl From<$x> for DataComponentUnion {
+ fn from(value: $x) -> Self {
+ DataComponentUnion { $x: ManuallyDrop::new(value) }
+ }
+ }
+ )*
+
+ $(
+ impl DataComponentTrait for $x {
+ const KIND: DataComponentKind = DataComponentKind::$x;
+ }
+ )*
+ };
+}
+
+// if this is causing a compile-time error, look at DataComponents.java in the
+// decompiled vanilla code to see how to implement new components
+
+// note that this statement is updated by genitemcomponents.py
+define_data_components!(
+ CustomData,
+ MaxStackSize,
+ MaxDamage,
+ Damage,
+ Unbreakable,
+ CustomName,
+ ItemName,
+ ItemModel,
+ Lore,
+ Rarity,
+ Enchantments,
+ CanPlaceOn,
+ CanBreak,
+ AttributeModifiers,
+ CustomModelData,
+ TooltipDisplay,
+ RepairCost,
+ CreativeSlotLock,
+ EnchantmentGlintOverride,
+ IntangibleProjectile,
+ Food,
+ Consumable,
+ UseRemainder,
+ UseCooldown,
+ DamageResistant,
+ Tool,
+ Weapon,
+ Enchantable,
+ Equippable,
+ Repairable,
+ Glider,
+ TooltipStyle,
+ DeathProtection,
+ BlocksAttacks,
+ StoredEnchantments,
+ DyedColor,
+ MapColor,
+ MapId,
+ MapDecorations,
+ MapPostProcessing,
+ ChargedProjectiles,
+ BundleContents,
+ PotionContents,
+ PotionDurationScale,
+ SuspiciousStewEffects,
+ WritableBookContent,
+ WrittenBookContent,
+ Trim,
+ DebugStickState,
+ EntityData,
+ BucketEntityData,
+ BlockEntityData,
+ Instrument,
+ ProvidesTrimMaterial,
+ OminousBottleAmplifier,
+ JukeboxPlayable,
+ ProvidesBannerPatterns,
+ Recipes,
+ LodestoneTracker,
+ FireworkExplosion,
+ Fireworks,
+ Profile,
+ NoteBlockSound,
+ BannerPatterns,
+ BaseColor,
+ PotDecorations,
+ Container,
+ BlockState,
+ Bees,
+ Lock,
+ ContainerLoot,
+ BreakSound,
+ VillagerVariant,
+ WolfVariant,
+ WolfSoundVariant,
+ WolfCollar,
+ FoxVariant,
+ SalmonSize,
+ ParrotVariant,
+ TropicalFishPattern,
+ TropicalFishBaseColor,
+ TropicalFishPatternColor,
+ MooshroomVariant,
+ RabbitVariant,
+ PigVariant,
+ CowVariant,
+ ChickenVariant,
+ FrogVariant,
+ HorseVariant,
+ PaintingVariant,
+ LlamaVariant,
+ AxolotlVariant,
+ CatVariant,
+ CatCollar,
+ SheepColor,
+ ShulkerColor,
+);
+
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct CustomData {
pub nbt: Nbt,
}
-impl DataComponent for CustomData {
- const KIND: DataComponentKind = DataComponentKind::CustomData;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct MaxStackSize {
#[var]
pub count: i32,
}
-impl DataComponent for MaxStackSize {
- const KIND: DataComponentKind = DataComponentKind::MaxStackSize;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct MaxDamage {
#[var]
pub amount: i32,
}
-impl DataComponent for MaxDamage {
- const KIND: DataComponentKind = DataComponentKind::MaxDamage;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct Damage {
#[var]
pub amount: i32,
}
-impl DataComponent for Damage {
- const KIND: DataComponentKind = DataComponentKind::Damage;
-}
-
-#[derive(Clone, PartialEq, Default, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct Unbreakable;
-impl DataComponent for Unbreakable {
- const KIND: DataComponentKind = DataComponentKind::Unbreakable;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct CustomName {
pub name: FormattedText,
}
-impl DataComponent for CustomName {
- const KIND: DataComponentKind = DataComponentKind::CustomName;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct ItemName {
pub name: FormattedText,
}
-impl DataComponent for ItemName {
- const KIND: DataComponentKind = DataComponentKind::ItemName;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct Lore {
pub lines: Vec<FormattedText>,
// vanilla also has styled_lines here but it doesn't appear to be used for the protocol
}
-impl DataComponent for Lore {
- const KIND: DataComponentKind = DataComponentKind::Lore;
-}
-#[derive(Clone, PartialEq, Copy, AzBuf)]
+#[derive(Clone, Copy, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(rename_all = "snake_case")]
pub enum Rarity {
Common,
Uncommon,
Rare,
Epic,
}
-impl DataComponent for Rarity {
- const KIND: DataComponentKind = DataComponentKind::Rarity;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Serialize)]
+#[serde(transparent)]
pub struct Enchantments {
#[var]
pub levels: HashMap<Enchantment, u32>,
}
-impl DataComponent for Enchantments {
- const KIND: DataComponentKind = DataComponentKind::Enchantments;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub enum BlockStateValueMatcher {
Exact {
value: String,
@@ -278,41 +357,43 @@ pub enum BlockStateValueMatcher {
},
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct BlockStatePropertyMatcher {
pub name: String,
pub value_matcher: BlockStateValueMatcher,
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct BlockPredicate {
+ #[serde(skip_serializing_if = "is_default")]
pub blocks: Option<HolderSet<Block, ResourceLocation>>,
+ #[serde(skip_serializing_if = "is_default")]
pub properties: Option<Vec<BlockStatePropertyMatcher>>,
+ #[serde(skip_serializing_if = "is_default")]
pub nbt: Option<NbtCompound>,
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct AdventureModePredicate {
+ #[serde(serialize_with = "flatten_array")]
pub predicates: Vec<BlockPredicate>,
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct CanPlaceOn {
pub predicate: AdventureModePredicate,
}
-impl DataComponent for CanPlaceOn {
- const KIND: DataComponentKind = DataComponentKind::CanPlaceOn;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct CanBreak {
pub predicate: AdventureModePredicate,
}
-impl DataComponent for CanBreak {
- const KIND: DataComponentKind = DataComponentKind::CanBreak;
-}
-#[derive(Clone, Copy, PartialEq, AzBuf)]
+#[derive(Clone, Copy, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(rename_all = "snake_case")]
pub enum EquipmentSlotGroup {
Any,
Mainhand,
@@ -326,7 +407,8 @@ pub enum EquipmentSlotGroup {
Body,
}
-#[derive(Clone, Copy, PartialEq, AzBuf)]
+#[derive(Clone, Copy, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(rename_all = "snake_case")]
pub enum AttributeModifierOperation {
AddValue,
AddMultipliedBase,
@@ -336,85 +418,86 @@ pub enum AttributeModifierOperation {
// this is duplicated in azalea-entity, BUT the one there has a different
// protocol format (and we can't use it anyways because it would cause a
// circular dependency)
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct AttributeModifier {
pub id: ResourceLocation,
pub amount: f64,
pub operation: AttributeModifierOperation,
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct AttributeModifiersEntry {
- pub attribute: Attribute,
+ #[serde(rename = "type")]
+ pub kind: Attribute,
+ #[serde(flatten)]
pub modifier: AttributeModifier,
pub slot: EquipmentSlotGroup,
+ #[serde(skip_serializing_if = "is_default")]
pub display: AttributeModifierDisplay,
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct AttributeModifiers {
pub modifiers: Vec<AttributeModifiersEntry>,
}
-impl DataComponent for AttributeModifiers {
- const KIND: DataComponentKind = DataComponentKind::AttributeModifiers;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Default, Serialize)]
+#[serde(rename_all = "snake_case")]
pub enum AttributeModifierDisplay {
+ #[default]
Default,
Hidden,
- Override { text: FormattedText },
+ Override {
+ text: FormattedText,
+ },
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct CustomModelData {
+ #[serde(skip_serializing_if = "Vec::is_empty")]
pub floats: Vec<f32>,
+ #[serde(skip_serializing_if = "Vec::is_empty")]
pub flags: Vec<bool>,
+ #[serde(skip_serializing_if = "Vec::is_empty")]
pub strings: Vec<String>,
+ #[serde(skip_serializing_if = "Vec::is_empty")]
pub colors: Vec<i32>,
}
-impl DataComponent for CustomModelData {
- const KIND: DataComponentKind = DataComponentKind::CustomModelData;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct RepairCost {
#[var]
pub cost: u32,
}
-impl DataComponent for RepairCost {
- const KIND: DataComponentKind = DataComponentKind::RepairCost;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct CreativeSlotLock;
-impl DataComponent for CreativeSlotLock {
- const KIND: DataComponentKind = DataComponentKind::CreativeSlotLock;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct EnchantmentGlintOverride {
pub show_glint: bool,
}
-impl DataComponent for EnchantmentGlintOverride {
- const KIND: DataComponentKind = DataComponentKind::EnchantmentGlintOverride;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct IntangibleProjectile;
-impl DataComponent for IntangibleProjectile {
- const KIND: DataComponentKind = DataComponentKind::IntangibleProjectile;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct MobEffectDetails {
#[var]
+ #[serde(skip_serializing_if = "is_default")]
pub amplifier: i32,
#[var]
+ #[serde(skip_serializing_if = "is_default")]
pub duration: i32,
+ #[serde(skip_serializing_if = "is_default")]
pub ambient: bool,
+ #[serde(skip_serializing_if = "is_default")]
pub show_particles: bool,
pub show_icon: bool,
+ #[serde(skip_serializing_if = "is_default")]
pub hidden_effect: Option<Box<MobEffectDetails>>,
}
impl MobEffectDetails {
@@ -424,7 +507,7 @@ impl MobEffectDetails {
duration: 0,
ambient: false,
show_particles: true,
- show_icon: false,
+ show_icon: true,
hidden_effect: None,
}
}
@@ -435,28 +518,28 @@ impl Default for MobEffectDetails {
}
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct MobEffectInstance {
pub id: MobEffect,
+ #[serde(flatten)]
pub details: MobEffectDetails,
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct PossibleEffect {
pub effect: MobEffectInstance,
pub probability: f32,
}
-#[derive(Clone, PartialEq, Default, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Default, Serialize)]
pub struct Food {
#[var]
pub nutrition: i32,
pub saturation: f32,
+ #[serde(skip_serializing_if = "is_default")]
pub can_always_eat: bool,
}
-impl DataComponent for Food {
- const KIND: DataComponentKind = DataComponentKind::Food;
-}
+
impl Food {
pub const fn new() -> Self {
Food {
@@ -467,10 +550,12 @@ impl Food {
}
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct ToolRule {
pub blocks: HolderSet<Block, ResourceLocation>,
+ #[serde(skip_serializing_if = "is_default")]
pub speed: Option<f32>,
+ #[serde(skip_serializing_if = "is_default")]
pub correct_for_drops: Option<bool>,
}
impl ToolRule {
@@ -488,17 +573,19 @@ impl Default for ToolRule {
}
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct Tool {
+ #[serde(serialize_with = "flatten_array")]
pub rules: Vec<ToolRule>,
+ #[serde(skip_serializing_if = "is_default")]
pub default_mining_speed: f32,
#[var]
+ #[serde(skip_serializing_if = "is_default")]
pub damage_per_block: i32,
+ #[serde(skip_serializing_if = "is_default")]
pub can_destroy_blocks_in_creative: bool,
}
-impl DataComponent for Tool {
- const KIND: DataComponentKind = DataComponentKind::Tool;
-}
+
impl Tool {
pub const fn new() -> Self {
Tool {
@@ -515,83 +602,68 @@ impl Default for Tool {
}
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct StoredEnchantments {
#[var]
pub enchantments: HashMap<Enchantment, i32>,
}
-impl DataComponent for StoredEnchantments {
- const KIND: DataComponentKind = DataComponentKind::StoredEnchantments;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct DyedColor {
pub rgb: i32,
}
-impl DataComponent for DyedColor {
- const KIND: DataComponentKind = DataComponentKind::DyedColor;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct MapColor {
pub color: i32,
}
-impl DataComponent for MapColor {
- const KIND: DataComponentKind = DataComponentKind::MapColor;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct MapId {
#[var]
pub id: i32,
}
-impl DataComponent for MapId {
- const KIND: DataComponentKind = DataComponentKind::MapId;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct MapDecorations {
pub decorations: NbtCompound,
}
-impl DataComponent for MapDecorations {
- const KIND: DataComponentKind = DataComponentKind::MapDecorations;
-}
-#[derive(Clone, Copy, PartialEq, AzBuf)]
+#[derive(Clone, Copy, PartialEq, AzBuf, Debug, Serialize)]
pub enum MapPostProcessing {
Lock,
Scale,
}
-impl DataComponent for MapPostProcessing {
- const KIND: DataComponentKind = DataComponentKind::MapPostProcessing;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct ChargedProjectiles {
pub items: Vec<ItemStack>,
}
-impl DataComponent for ChargedProjectiles {
- const KIND: DataComponentKind = DataComponentKind::ChargedProjectiles;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct BundleContents {
pub items: Vec<ItemStack>,
}
-impl DataComponent for BundleContents {
- const KIND: DataComponentKind = DataComponentKind::BundleContents;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct PotionContents {
+ #[serde(skip_serializing_if = "is_default")]
pub potion: Option<Potion>,
+ #[serde(skip_serializing_if = "is_default")]
pub custom_color: Option<i32>,
+ #[serde(skip_serializing_if = "is_default")]
pub custom_effects: Vec<MobEffectInstance>,
+ #[serde(skip_serializing_if = "is_default")]
pub custom_name: Option<String>,
}
-impl DataComponent for PotionContents {
- const KIND: DataComponentKind = DataComponentKind::PotionContents;
-}
+
impl PotionContents {
pub const fn new() -> Self {
PotionContents {
@@ -608,95 +680,78 @@ impl Default for PotionContents {
}
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct SuspiciousStewEffect {
+ #[serde(rename = "id")]
pub effect: MobEffect,
#[var]
+ #[serde(skip_serializing_if = "is_default")]
pub duration: i32,
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct SuspiciousStewEffects {
pub effects: Vec<SuspiciousStewEffect>,
}
-impl DataComponent for SuspiciousStewEffects {
- const KIND: DataComponentKind = DataComponentKind::SuspiciousStewEffects;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct WritableBookContent {
pub pages: Vec<String>,
}
-impl DataComponent for WritableBookContent {
- const KIND: DataComponentKind = DataComponentKind::WritableBookContent;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Serialize)]
pub struct WrittenBookContent {
#[limit(32)]
pub title: Filterable<String>,
pub author: String,
#[var]
+ #[serde(skip_serializing_if = "is_default")]
pub generation: i32,
+ #[serde(skip_serializing_if = "is_default")]
pub pages: Vec<Filterable<FormattedText>>,
+ #[serde(skip_serializing_if = "is_default")]
pub resolved: bool,
}
-impl DataComponent for WrittenBookContent {
- const KIND: DataComponentKind = DataComponentKind::WrittenBookContent;
-}
-
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct Trim {
pub material: TrimMaterial,
pub pattern: TrimPattern,
}
-impl DataComponent for Trim {
- const KIND: DataComponentKind = DataComponentKind::Trim;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct DebugStickState {
pub properties: NbtCompound,
}
-impl DataComponent for DebugStickState {
- const KIND: DataComponentKind = DataComponentKind::DebugStickState;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct EntityData {
pub entity: NbtCompound,
}
-impl DataComponent for EntityData {
- const KIND: DataComponentKind = DataComponentKind::EntityData;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct BucketEntityData {
pub entity: NbtCompound,
}
-impl DataComponent for BucketEntityData {
- const KIND: DataComponentKind = DataComponentKind::BucketEntityData;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct BlockEntityData {
pub entity: NbtCompound,
}
-impl DataComponent for BlockEntityData {
- const KIND: DataComponentKind = DataComponentKind::BlockEntityData;
-}
-#[derive(Clone, PartialEq, Debug, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(untagged)]
pub enum Instrument {
Registry(registry::Instrument),
Holder(Holder<registry::Instrument, InstrumentData>),
}
-impl DataComponent for Instrument {
- const KIND: DataComponentKind = DataComponentKind::Instrument;
-}
-#[derive(Clone, PartialEq, Debug, AzBuf)]
+#[derive(Clone, PartialEq, Debug, AzBuf, Serialize)]
pub struct InstrumentData {
pub sound_event: Holder<SoundEvent, azalea_core::sound::CustomSound>,
pub use_duration: f32,
@@ -704,33 +759,29 @@ pub struct InstrumentData {
pub description: FormattedText,
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct OminousBottleAmplifier {
#[var]
pub amplifier: i32,
}
-impl DataComponent for OminousBottleAmplifier {
- const KIND: DataComponentKind = DataComponentKind::OminousBottleAmplifier;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct Recipes {
pub recipes: Vec<ResourceLocation>,
}
-impl DataComponent for Recipes {
- const KIND: DataComponentKind = DataComponentKind::Recipes;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct LodestoneTracker {
+ #[serde(skip_serializing_if = "is_default")]
pub target: Option<GlobalPos>,
+ #[serde(skip_serializing_if = "is_true")]
pub tracked: bool,
}
-impl DataComponent for LodestoneTracker {
- const KIND: DataComponentKind = DataComponentKind::LodestoneTracker;
-}
-#[derive(Clone, Copy, PartialEq, AzBuf)]
+#[derive(Clone, Copy, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(rename_all = "snake_case")]
pub enum FireworkExplosionShape {
SmallBall,
LargeBall,
@@ -739,28 +790,28 @@ pub enum FireworkExplosionShape {
Burst,
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct FireworkExplosion {
pub shape: FireworkExplosionShape,
+ #[serde(skip_serializing_if = "is_default")]
pub colors: Vec<i32>,
+ #[serde(skip_serializing_if = "is_default")]
pub fade_colors: Vec<i32>,
+ #[serde(skip_serializing_if = "is_default")]
pub has_trail: bool,
+ #[serde(skip_serializing_if = "is_default")]
pub has_twinkle: bool,
}
-impl DataComponent for FireworkExplosion {
- const KIND: DataComponentKind = DataComponentKind::FireworkExplosion;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct Fireworks {
#[var]
+ #[serde(skip_serializing_if = "is_default")]
pub flight_duration: i32,
#[limit(256)]
pub explosions: Vec<FireworkExplosion>,
}
-impl DataComponent for Fireworks {
- const KIND: DataComponentKind = DataComponentKind::Fireworks;
-}
+
impl Fireworks {
pub const fn new() -> Self {
Fireworks {
@@ -775,32 +826,32 @@ impl Default for Fireworks {
}
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct GameProfileProperty {
pub name: String,
pub value: String,
+ #[serde(skip_serializing_if = "is_default")]
pub signature: Option<String>,
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct Profile {
+ #[serde(skip_serializing_if = "is_default")]
pub name: Option<String>,
+ #[serde(skip_serializing_if = "is_default")]
+ #[serde(serialize_with = "azalea_core::codec_utils::uuid")]
pub id: Option<Uuid>,
+ #[serde(skip_serializing_if = "is_default")]
pub properties: Vec<GameProfileProperty>,
}
-impl DataComponent for Profile {
- const KIND: DataComponentKind = DataComponentKind::Profile;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct NoteBlockSound {
pub sound: ResourceLocation,
}
-impl DataComponent for NoteBlockSound {
- const KIND: DataComponentKind = DataComponentKind::NoteBlockSound;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct BannerPattern {
#[var]
pub pattern: i32,
@@ -808,15 +859,14 @@ pub struct BannerPattern {
pub color: i32,
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct BannerPatterns {
pub patterns: Vec<BannerPattern>,
}
-impl DataComponent for BannerPatterns {
- const KIND: DataComponentKind = DataComponentKind::BannerPatterns;
-}
-#[derive(Clone, Copy, PartialEq, AzBuf)]
+#[derive(Clone, Copy, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(rename_all = "snake_case")]
pub enum DyeColor {
White,
Orange,
@@ -836,40 +886,33 @@ pub enum DyeColor {
Black,
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct BaseColor {
pub color: DyeColor,
}
-impl DataComponent for BaseColor {
- const KIND: DataComponentKind = DataComponentKind::BaseColor;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct PotDecorations {
- pub items: Vec<Item>,
-}
-impl DataComponent for PotDecorations {
- const KIND: DataComponentKind = DataComponentKind::PotDecorations;
+ pub items: [Item; 4],
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct Container {
pub items: Vec<ItemStack>,
}
-impl DataComponent for Container {
- const KIND: DataComponentKind = DataComponentKind::Container;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct BlockState {
pub properties: HashMap<String, String>,
}
-impl DataComponent for BlockState {
- const KIND: DataComponentKind = DataComponentKind::BlockState;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct BeehiveOccupant {
+ #[serde(skip_serializing_if = "is_default")]
pub entity_data: NbtCompound,
#[var]
pub ticks_in_hive: i32,
@@ -877,39 +920,30 @@ pub struct BeehiveOccupant {
pub min_ticks_in_hive: i32,
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct Bees {
pub occupants: Vec<BeehiveOccupant>,
}
-impl DataComponent for Bees {
- const KIND: DataComponentKind = DataComponentKind::Bees;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct Lock {
pub key: String,
}
-impl DataComponent for Lock {
- const KIND: DataComponentKind = DataComponentKind::Lock;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct ContainerLoot {
- pub loot: NbtCompound,
-}
-impl DataComponent for ContainerLoot {
- const KIND: DataComponentKind = DataComponentKind::ContainerLoot;
+ pub loot_table: NbtCompound,
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(untagged)]
pub enum JukeboxPlayable {
Referenced(ResourceLocation),
Direct(Holder<registry::JukeboxSong, JukeboxSongData>),
}
-impl DataComponent for JukeboxPlayable {
- const KIND: DataComponentKind = DataComponentKind::JukeboxPlayable;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct JukeboxSongData {
pub sound_event: Holder<SoundEvent, CustomSound>,
pub description: FormattedText,
@@ -918,17 +952,26 @@ pub struct JukeboxSongData {
pub comparator_output: i32,
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct Consumable {
+ #[serde(skip_serializing_if = "is_default")]
pub consume_seconds: f32,
+ #[serde(skip_serializing_if = "is_default")]
pub animation: ItemUseAnimation,
+ #[serde(skip_serializing_if = "is_default_eat_sound")]
pub sound: azalea_registry::Holder<SoundEvent, CustomSound>,
+ #[serde(skip_serializing_if = "is_default")]
pub has_consume_particles: bool,
+ #[serde(skip_serializing_if = "is_default")]
pub on_consume_effects: Vec<ConsumeEffect>,
}
-impl DataComponent for Consumable {
- const KIND: DataComponentKind = DataComponentKind::Consumable;
+fn is_default_eat_sound(sound: &azalea_registry::Holder<SoundEvent, CustomSound>) -> bool {
+ matches!(
+ sound,
+ azalea_registry::Holder::Reference(SoundEvent::EntityGenericEat)
+ )
}
+
impl Consumable {
pub const fn new() -> Self {
Self {
@@ -946,8 +989,10 @@ impl Default for Consumable {
}
}
-#[derive(Clone, Copy, PartialEq, AzBuf)]
+#[derive(Clone, Copy, PartialEq, AzBuf, Debug, Default, Serialize)]
+#[serde(rename_all = "snake_case")]
pub enum ItemUseAnimation {
+ #[default]
None,
Eat,
Drink,
@@ -960,22 +1005,19 @@ pub enum ItemUseAnimation {
Brush,
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct UseRemainder {
pub convert_into: ItemStack,
}
-impl DataComponent for UseRemainder {
- const KIND: DataComponentKind = DataComponentKind::UseRemainder;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct UseCooldown {
pub seconds: f32,
+ #[serde(skip_serializing_if = "is_default")]
pub cooldown_group: Option<ResourceLocation>,
}
-impl DataComponent for UseCooldown {
- const KIND: DataComponentKind = DataComponentKind::UseCooldown;
-}
+
impl UseCooldown {
pub const fn new() -> Self {
Self {
@@ -990,66 +1032,60 @@ impl Default for UseCooldown {
}
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct Enchantable {
#[var]
pub value: u32,
}
-impl DataComponent for Enchantable {
- const KIND: DataComponentKind = DataComponentKind::Enchantable;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct Repairable {
pub items: HolderSet<Item, ResourceLocation>,
}
-impl DataComponent for Repairable {
- const KIND: DataComponentKind = DataComponentKind::Repairable;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct ItemModel {
pub resource_location: ResourceLocation,
}
-impl DataComponent for ItemModel {
- const KIND: DataComponentKind = DataComponentKind::ItemModel;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct DamageResistant {
- // in the vanilla code this is
- // ```
- // StreamCodec.composite(
- // TagKey.streamCodec(Registries.DAMAGE_TYPE),
- // DamageResistant::types,
- // DamageResistant::new,
- // );
- // ```
- // i'm not entirely sure if this is meant to be a vec or something, i just made it a
- // resourcelocation for now
+ /// In vanilla this only allows tag keys, i.e. it must start with '#'
pub types: ResourceLocation,
}
-impl DataComponent for DamageResistant {
- const KIND: DataComponentKind = DataComponentKind::DamageResistant;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct Equippable {
pub slot: EquipmentSlot,
+ #[serde(skip_serializing_if = "is_default_equip_sound")]
pub equip_sound: SoundEvent,
+ #[serde(skip_serializing_if = "is_default")]
pub asset_id: Option<ResourceLocation>,
+ #[serde(skip_serializing_if = "is_default")]
pub camera_overlay: Option<ResourceLocation>,
+ #[serde(skip_serializing_if = "is_default")]
pub allowed_entities: Option<HolderSet<EntityKind, ResourceLocation>>,
+ #[serde(skip_serializing_if = "is_true")]
pub dispensable: bool,
+ #[serde(skip_serializing_if = "is_true")]
pub swappable: bool,
+ #[serde(skip_serializing_if = "is_true")]
pub damage_on_hurt: bool,
+ #[serde(skip_serializing_if = "is_default")]
pub equip_on_interact: bool,
+ #[serde(skip_serializing_if = "is_default")]
pub can_be_sheared: bool,
+ #[serde(skip_serializing_if = "is_default_shearing_sound")]
pub shearing_sound: SoundEvent,
}
-impl DataComponent for Equippable {
- const KIND: DataComponentKind = DataComponentKind::Equippable;
+fn is_default_equip_sound(sound: &SoundEvent) -> bool {
+ matches!(sound, SoundEvent::ItemArmorEquipGeneric)
}
+fn is_default_shearing_sound(sound: &SoundEvent) -> bool {
+ matches!(sound, SoundEvent::ItemShearsSnip)
+}
+
impl Equippable {
pub const fn new() -> Self {
Self {
@@ -1073,7 +1109,8 @@ impl Default for Equippable {
}
}
-#[derive(Clone, Copy, Debug, PartialEq, AzBuf)]
+#[derive(Clone, Copy, Debug, PartialEq, AzBuf, Serialize)]
+#[serde(rename_all = "snake_case")]
pub enum EquipmentSlot {
Mainhand,
Offhand,
@@ -1085,37 +1122,32 @@ pub enum EquipmentSlot {
Saddle,
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct Glider;
-impl DataComponent for Glider {
- const KIND: DataComponentKind = DataComponentKind::Glider;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct TooltipStyle {
pub resource_location: ResourceLocation,
}
-impl DataComponent for TooltipStyle {
- const KIND: DataComponentKind = DataComponentKind::TooltipStyle;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct DeathProtection {
pub death_effects: Vec<ConsumeEffect>,
}
-impl DataComponent for DeathProtection {
- const KIND: DataComponentKind = DataComponentKind::DeathProtection;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct Weapon {
#[var]
+ #[serde(skip_serializing_if = "is_default_item_damage_per_attack")]
pub item_damage_per_attack: i32,
+ #[serde(skip_serializing_if = "is_default")]
pub disable_blocking_for_seconds: f32,
}
-impl DataComponent for Weapon {
- const KIND: DataComponentKind = DataComponentKind::Weapon;
+fn is_default_item_damage_per_attack(value: &i32) -> bool {
+ *value == 1
}
+
impl Weapon {
pub const fn new() -> Self {
Self {
@@ -1130,65 +1162,52 @@ impl Default for Weapon {
}
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct PotionDurationScale {
pub value: f32,
}
-impl DataComponent for PotionDurationScale {
- const KIND: DataComponentKind = DataComponentKind::PotionDurationScale;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct VillagerVariant {
pub variant: registry::VillagerKind,
}
-impl DataComponent for VillagerVariant {
- const KIND: DataComponentKind = DataComponentKind::VillagerVariant;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct WolfVariant {
pub variant: registry::WolfVariant,
}
-impl DataComponent for WolfVariant {
- const KIND: DataComponentKind = DataComponentKind::WolfVariant;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct WolfCollar {
pub color: DyeColor,
}
-impl DataComponent for WolfCollar {
- const KIND: DataComponentKind = DataComponentKind::WolfCollar;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct FoxVariant {
pub variant: registry::FoxVariant,
}
-impl DataComponent for FoxVariant {
- const KIND: DataComponentKind = DataComponentKind::FoxVariant;
-}
-#[derive(Clone, Copy, PartialEq, AzBuf)]
+#[derive(Clone, Copy, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(rename_all = "snake_case")]
pub enum SalmonSize {
Small,
Medium,
Large,
}
-impl DataComponent for SalmonSize {
- const KIND: DataComponentKind = DataComponentKind::SalmonSize;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct ParrotVariant {
pub variant: registry::ParrotVariant,
}
-impl DataComponent for ParrotVariant {
- const KIND: DataComponentKind = DataComponentKind::ParrotVariant;
-}
-#[derive(Clone, Copy, PartialEq, AzBuf)]
+#[derive(Clone, Copy, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(rename_all = "snake_case")]
pub enum TropicalFishPattern {
Kob,
Sunstreak,
@@ -1203,140 +1222,112 @@ pub enum TropicalFishPattern {
Betty,
Clayfish,
}
-impl DataComponent for TropicalFishPattern {
- const KIND: DataComponentKind = DataComponentKind::TropicalFishPattern;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct TropicalFishBaseColor {
pub color: DyeColor,
}
-impl DataComponent for TropicalFishBaseColor {
- const KIND: DataComponentKind = DataComponentKind::TropicalFishBaseColor;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct TropicalFishPatternColor {
pub color: DyeColor,
}
-impl DataComponent for TropicalFishPatternColor {
- const KIND: DataComponentKind = DataComponentKind::TropicalFishPatternColor;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct MooshroomVariant {
pub variant: registry::MooshroomVariant,
}
-impl DataComponent for MooshroomVariant {
- const KIND: DataComponentKind = DataComponentKind::MooshroomVariant;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct RabbitVariant {
pub variant: registry::RabbitVariant,
}
-impl DataComponent for RabbitVariant {
- const KIND: DataComponentKind = DataComponentKind::RabbitVariant;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct PigVariant {
pub variant: registry::PigVariant,
}
-impl DataComponent for PigVariant {
- const KIND: DataComponentKind = DataComponentKind::PigVariant;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct FrogVariant {
pub variant: registry::FrogVariant,
}
-impl DataComponent for FrogVariant {
- const KIND: DataComponentKind = DataComponentKind::FrogVariant;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct HorseVariant {
pub variant: registry::HorseVariant,
}
-impl DataComponent for HorseVariant {
- const KIND: DataComponentKind = DataComponentKind::HorseVariant;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct PaintingVariant {
pub variant: Holder<registry::PaintingVariant, PaintingVariantData>,
}
-impl DataComponent for PaintingVariant {
- const KIND: DataComponentKind = DataComponentKind::PaintingVariant;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct PaintingVariantData {
#[var]
pub width: i32,
#[var]
pub height: i32,
pub asset_id: ResourceLocation,
+ #[serde(skip_serializing_if = "is_default")]
pub title: Option<FormattedText>,
+ #[serde(skip_serializing_if = "is_default")]
pub author: Option<FormattedText>,
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct LlamaVariant {
pub variant: registry::LlamaVariant,
}
-impl DataComponent for LlamaVariant {
- const KIND: DataComponentKind = DataComponentKind::LlamaVariant;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct AxolotlVariant {
pub variant: registry::AxolotlVariant,
}
-impl DataComponent for AxolotlVariant {
- const KIND: DataComponentKind = DataComponentKind::AxolotlVariant;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct CatVariant {
pub variant: registry::CatVariant,
}
-impl DataComponent for CatVariant {
- const KIND: DataComponentKind = DataComponentKind::CatVariant;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct CatCollar {
pub color: DyeColor,
}
-impl DataComponent for CatCollar {
- const KIND: DataComponentKind = DataComponentKind::CatCollar;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct SheepColor {
pub color: DyeColor,
}
-impl DataComponent for SheepColor {
- const KIND: DataComponentKind = DataComponentKind::SheepColor;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct ShulkerColor {
pub color: DyeColor,
}
-impl DataComponent for ShulkerColor {
- const KIND: DataComponentKind = DataComponentKind::ShulkerColor;
-}
-#[derive(Clone, PartialEq, AzBuf, Default)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct TooltipDisplay {
+ #[serde(skip_serializing_if = "is_default")]
pub hide_tooltip: bool,
+ #[serde(skip_serializing_if = "is_default")]
pub hidden_components: Vec<DataComponentKind>,
}
-impl DataComponent for TooltipDisplay {
- const KIND: DataComponentKind = DataComponentKind::TooltipDisplay;
-}
+
impl TooltipDisplay {
pub const fn new() -> Self {
Self {
@@ -1345,20 +1336,33 @@ impl TooltipDisplay {
}
}
}
+impl Default for TooltipDisplay {
+ fn default() -> Self {
+ Self::new()
+ }
+}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct BlocksAttacks {
+ #[serde(skip_serializing_if = "is_default")]
pub block_delay_seconds: f32,
+ #[serde(skip_serializing_if = "is_default_disable_cooldown_scale")]
pub disable_cooldown_scale: f32,
+ #[serde(skip_serializing_if = "is_default")]
pub damage_reductions: Vec<DamageReduction>,
+ #[serde(skip_serializing_if = "is_default")]
pub item_damage: ItemDamageFunction,
+ #[serde(skip_serializing_if = "is_default")]
pub bypassed_by: Option<ResourceLocation>,
+ #[serde(skip_serializing_if = "is_default")]
pub block_sound: Option<azalea_registry::Holder<SoundEvent, CustomSound>>,
+ #[serde(skip_serializing_if = "is_default")]
pub disabled_sound: Option<azalea_registry::Holder<SoundEvent, CustomSound>>,
}
-impl DataComponent for BlocksAttacks {
- const KIND: DataComponentKind = DataComponentKind::BlocksAttacks;
+fn is_default_disable_cooldown_scale(value: &f32) -> bool {
+ *value == 1.
}
+
impl BlocksAttacks {
pub fn new() -> Self {
Self {
@@ -1370,11 +1374,7 @@ impl BlocksAttacks {
base: 0.,
factor: 1.,
}],
- item_damage: ItemDamageFunction {
- threshold: 1.,
- base: 0.,
- factor: 1.,
- },
+ item_damage: ItemDamageFunction::default(),
bypassed_by: None,
block_sound: None,
disabled_sound: None,
@@ -1387,86 +1387,90 @@ impl Default for BlocksAttacks {
}
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct DamageReduction {
+ #[serde(skip_serializing_if = "is_default_horizontal_blocking_angle")]
pub horizontal_blocking_angle: f32,
+ #[serde(skip_serializing_if = "is_default")]
pub kind: Option<HolderSet<DamageKind, ResourceLocation>>,
pub base: f32,
pub factor: f32,
}
-#[derive(Clone, PartialEq, AzBuf)]
+fn is_default_horizontal_blocking_angle(value: &f32) -> bool {
+ *value == 90.
+}
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct ItemDamageFunction {
pub threshold: f32,
pub base: f32,
pub factor: f32,
}
+impl Default for ItemDamageFunction {
+ fn default() -> Self {
+ ItemDamageFunction {
+ threshold: 1.,
+ base: 0.,
+ factor: 1.,
+ }
+ }
+}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(untagged)]
pub enum ProvidesTrimMaterial {
Referenced(ResourceLocation),
Direct(Holder<TrimMaterial, DirectTrimMaterial>),
}
-impl DataComponent for ProvidesTrimMaterial {
- const KIND: DataComponentKind = DataComponentKind::ProvidesTrimMaterial;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct DirectTrimMaterial {
pub assets: MaterialAssetGroup,
pub description: FormattedText,
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct MaterialAssetGroup {
pub base: AssetInfo,
+ #[serde(skip_serializing_if = "is_default")]
pub overrides: Vec<(ResourceLocation, AssetInfo)>,
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct AssetInfo {
pub suffix: String,
}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct ProvidesBannerPatterns {
pub key: ResourceLocation,
}
-impl DataComponent for ProvidesBannerPatterns {
- const KIND: DataComponentKind = DataComponentKind::ProvidesBannerPatterns;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct BreakSound {
pub sound: azalea_registry::Holder<SoundEvent, CustomSound>,
}
-impl DataComponent for BreakSound {
- const KIND: DataComponentKind = DataComponentKind::BreakSound;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct WolfSoundVariant {
pub variant: azalea_registry::WolfSoundVariant,
}
-impl DataComponent for WolfSoundVariant {
- const KIND: DataComponentKind = DataComponentKind::WolfSoundVariant;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(transparent)]
pub struct CowVariant {
pub variant: azalea_registry::CowVariant,
}
-impl DataComponent for CowVariant {
- const KIND: DataComponentKind = DataComponentKind::CowVariant;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
+#[serde(untagged)]
pub enum ChickenVariant {
Referenced(ResourceLocation),
Direct(ChickenVariantData),
}
-impl DataComponent for ChickenVariant {
- const KIND: DataComponentKind = DataComponentKind::ChickenVariant;
-}
-#[derive(Clone, PartialEq, AzBuf)]
+
+#[derive(Clone, PartialEq, AzBuf, Debug, Serialize)]
pub struct ChickenVariantData {
pub registry: azalea_registry::ChickenVariant,
}