From c36201cc894bcc99a06358eea31d210800980dae Mon Sep 17 00:00:00 2001 From: mat Date: Thu, 28 Nov 2024 03:17:58 +0000 Subject: [PATCH] change DataComponentPatch::get to take in a generic (and add get_kind, has, and has_kind) --- azalea-client/src/interact.rs | 5 +- azalea-core/src/position.rs | 5 +- azalea-inventory/src/components.rs | 272 +++++++++++++++++++++-------- azalea-inventory/src/slot.rs | 45 ++++- azalea/src/auto_tool.rs | 12 +- codegen/genitemcomponents.py | 10 +- 6 files changed, 262 insertions(+), 87 deletions(-) diff --git a/azalea-client/src/interact.rs b/azalea-client/src/interact.rs index d2dfd93a2..0acc69925 100644 --- a/azalea-client/src/interact.rs +++ b/azalea-client/src/interact.rs @@ -10,14 +10,13 @@ use azalea_core::{ use azalea_entity::{ clamp_look_direction, view_vector, Attributes, EyeHeight, LocalEntity, LookDirection, Position, }; -use azalea_inventory::{ItemStack, ItemStackData}; +use azalea_inventory::{components, ItemStack, ItemStackData}; use azalea_physics::clip::{BlockShapeType, ClipContext, FluidPickType}; use azalea_protocol::packets::game::{ s_interact::InteractionHand, s_swing::ServerboundSwing, s_use_item_on::{BlockHit, ServerboundUseItemOn}, }; -use azalea_registry::DataComponentKind; use azalea_world::{Instance, InstanceContainer, InstanceName}; use bevy_app::{App, Plugin, Update}; use bevy_ecs::{ @@ -268,7 +267,7 @@ pub fn check_block_can_be_broken_by_item_in_adventure_mode( // minecraft caches the last checked block but that's kind of an unnecessary // optimization and makes the code too complicated - let Some(_can_destroy) = item.components.get(DataComponentKind::CanBreak) else { + if !item.components.has::() { // no CanDestroy tag return false; }; diff --git a/azalea-core/src/position.rs b/azalea-core/src/position.rs index c280a85a6..ccc816491 100755 --- a/azalea-core/src/position.rs +++ b/azalea-core/src/position.rs @@ -11,7 +11,6 @@ use std::{ }; use azalea_buf::{AzBuf, AzaleaRead, AzaleaWrite, BufReadError}; -use serde::{Deserialize, Serialize}; use crate::resource_location::ResourceLocation; @@ -213,7 +212,7 @@ macro_rules! vec3_impl { /// Used to represent an exact position in the world where an entity could be. /// For blocks, [`BlockPos`] is used instead. #[derive(Clone, Copy, Debug, Default, PartialEq, AzBuf)] -#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] +#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] pub struct Vec3 { pub x: f64, pub y: f64, @@ -238,7 +237,7 @@ impl Vec3 { /// The coordinates of a block in the world. For entities (if the coordinate /// with decimals), use [`Vec3`] instead. #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] +#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] pub struct BlockPos { pub x: i32, pub y: i32, diff --git a/azalea-inventory/src/components.rs b/azalea-inventory/src/components.rs index 10b00b360..e62288c61 100644 --- a/azalea-inventory/src/components.rs +++ b/azalea-inventory/src/components.rs @@ -13,7 +13,9 @@ use uuid::Uuid; use crate::ItemStack; -pub trait DataComponent: Send + Sync + Any {} +pub trait DataComponent: Send + Sync + Any { + const KIND: DataComponentKind; +} pub trait EncodableDataComponent: Send + Sync + Any { fn encode(&self, buf: &mut Vec) -> Result<(), std::io::Error>; @@ -138,21 +140,27 @@ pub fn from_kind( pub struct CustomData { pub nbt: Nbt, } -impl DataComponent for CustomData {} +impl DataComponent for CustomData { + const KIND: DataComponentKind = DataComponentKind::CustomData; +} #[derive(Clone, PartialEq, AzBuf)] pub struct MaxStackSize { #[var] pub count: i32, } -impl DataComponent for MaxStackSize {} +impl DataComponent for MaxStackSize { + const KIND: DataComponentKind = DataComponentKind::MaxStackSize; +} #[derive(Clone, PartialEq, AzBuf)] pub struct MaxDamage { #[var] pub amount: i32, } -impl DataComponent for MaxDamage {} +impl DataComponent for MaxDamage { + const KIND: DataComponentKind = DataComponentKind::MaxDamage; +} #[derive(Clone, PartialEq, AzBuf)] pub struct Damage { @@ -160,13 +168,17 @@ pub struct Damage { pub amount: i32, } -impl DataComponent for Damage {} +impl DataComponent for Damage { + const KIND: DataComponentKind = DataComponentKind::Damage; +} #[derive(Clone, PartialEq, AzBuf)] pub struct Unbreakable { pub show_in_tooltip: bool, } -impl DataComponent for Unbreakable {} +impl DataComponent for Unbreakable { + const KIND: DataComponentKind = DataComponentKind::Unbreakable; +} impl Default for Unbreakable { fn default() -> Self { Self { @@ -179,20 +191,26 @@ impl Default for Unbreakable { pub struct CustomName { pub name: FormattedText, } -impl DataComponent for CustomName {} +impl DataComponent for CustomName { + const KIND: DataComponentKind = DataComponentKind::CustomName; +} #[derive(Clone, PartialEq, AzBuf)] pub struct ItemName { pub name: FormattedText, } -impl DataComponent for ItemName {} +impl DataComponent for ItemName { + const KIND: DataComponentKind = DataComponentKind::ItemName; +} #[derive(Clone, PartialEq, AzBuf)] pub struct Lore { pub lines: Vec, // vanilla also has styled_lines here but it doesn't appear to be used for the protocol } -impl DataComponent for Lore {} +impl DataComponent for Lore { + const KIND: DataComponentKind = DataComponentKind::Lore; +} #[derive(Clone, PartialEq, Copy, AzBuf)] pub enum Rarity { @@ -201,7 +219,9 @@ pub enum Rarity { Rare, Epic, } -impl DataComponent for Rarity {} +impl DataComponent for Rarity { + const KIND: DataComponentKind = DataComponentKind::Rarity; +} #[derive(Clone, PartialEq, AzBuf)] pub struct Enchantments { @@ -209,7 +229,9 @@ pub struct Enchantments { pub levels: HashMap, pub show_in_tooltip: bool, } -impl DataComponent for Enchantments {} +impl DataComponent for Enchantments { + const KIND: DataComponentKind = DataComponentKind::Enchantments; +} #[derive(Clone, PartialEq, AzBuf)] pub enum BlockStateValueMatcher { @@ -245,13 +267,17 @@ pub struct AdventureModePredicate { pub struct CanPlaceOn { pub predicate: AdventureModePredicate, } -impl DataComponent for CanPlaceOn {} +impl DataComponent for CanPlaceOn { + const KIND: DataComponentKind = DataComponentKind::CanPlaceOn; +} #[derive(Clone, PartialEq, AzBuf)] pub struct CanBreak { pub predicate: AdventureModePredicate, } -impl DataComponent for CanBreak {} +impl DataComponent for CanBreak { + const KIND: DataComponentKind = DataComponentKind::CanBreak; +} #[derive(Clone, Copy, PartialEq, AzBuf)] pub enum EquipmentSlotGroup { @@ -297,43 +323,59 @@ pub struct AttributeModifiers { pub modifiers: Vec, pub show_in_tooltip: bool, } -impl DataComponent for AttributeModifiers {} +impl DataComponent for AttributeModifiers { + const KIND: DataComponentKind = DataComponentKind::AttributeModifiers; +} #[derive(Clone, PartialEq, AzBuf)] pub struct CustomModelData { #[var] pub value: i32, } -impl DataComponent for CustomModelData {} +impl DataComponent for CustomModelData { + const KIND: DataComponentKind = DataComponentKind::CustomModelData; +} #[derive(Clone, PartialEq, AzBuf)] pub struct HideAdditionalTooltip; -impl DataComponent for HideAdditionalTooltip {} +impl DataComponent for HideAdditionalTooltip { + const KIND: DataComponentKind = DataComponentKind::HideAdditionalTooltip; +} #[derive(Clone, PartialEq, AzBuf)] pub struct HideTooltip; -impl DataComponent for HideTooltip {} +impl DataComponent for HideTooltip { + const KIND: DataComponentKind = DataComponentKind::HideTooltip; +} #[derive(Clone, PartialEq, AzBuf)] pub struct RepairCost { #[var] pub cost: u32, } -impl DataComponent for RepairCost {} +impl DataComponent for RepairCost { + const KIND: DataComponentKind = DataComponentKind::RepairCost; +} #[derive(Clone, PartialEq, AzBuf)] pub struct CreativeSlotLock; -impl DataComponent for CreativeSlotLock {} +impl DataComponent for CreativeSlotLock { + const KIND: DataComponentKind = DataComponentKind::CreativeSlotLock; +} #[derive(Clone, PartialEq, AzBuf)] pub struct EnchantmentGlintOverride { pub show_glint: bool, } -impl DataComponent for EnchantmentGlintOverride {} +impl DataComponent for EnchantmentGlintOverride { + const KIND: DataComponentKind = DataComponentKind::EnchantmentGlintOverride; +} #[derive(Clone, PartialEq, AzBuf)] pub struct IntangibleProjectile; -impl DataComponent for IntangibleProjectile {} +impl DataComponent for IntangibleProjectile { + const KIND: DataComponentKind = DataComponentKind::IntangibleProjectile; +} #[derive(Clone, PartialEq, AzBuf)] pub struct MobEffectDetails { @@ -368,7 +410,9 @@ pub struct Food { pub eat_seconds: f32, pub effects: Vec, } -impl DataComponent for Food {} +impl DataComponent for Food { + const KIND: DataComponentKind = DataComponentKind::Food; +} #[derive(Clone, PartialEq, AzBuf)] pub struct ToolRule { @@ -384,7 +428,9 @@ pub struct Tool { #[var] pub damage_per_block: i32, } -impl DataComponent for Tool {} +impl DataComponent for Tool { + const KIND: DataComponentKind = DataComponentKind::Tool; +} #[derive(Clone, PartialEq, AzBuf)] pub struct StoredEnchantments { @@ -392,52 +438,68 @@ pub struct StoredEnchantments { pub enchantments: HashMap, pub show_in_tooltip: bool, } -impl DataComponent for StoredEnchantments {} +impl DataComponent for StoredEnchantments { + const KIND: DataComponentKind = DataComponentKind::StoredEnchantments; +} #[derive(Clone, PartialEq, AzBuf)] pub struct DyedColor { pub rgb: i32, pub show_in_tooltip: bool, } -impl DataComponent for DyedColor {} +impl DataComponent for DyedColor { + const KIND: DataComponentKind = DataComponentKind::DyedColor; +} #[derive(Clone, PartialEq, AzBuf)] pub struct MapColor { pub color: i32, } -impl DataComponent for MapColor {} +impl DataComponent for MapColor { + const KIND: DataComponentKind = DataComponentKind::MapColor; +} #[derive(Clone, PartialEq, AzBuf)] pub struct MapId { #[var] pub id: i32, } -impl DataComponent for MapId {} +impl DataComponent for MapId { + const KIND: DataComponentKind = DataComponentKind::MapId; +} #[derive(Clone, PartialEq, AzBuf)] pub struct MapDecorations { pub decorations: NbtCompound, } -impl DataComponent for MapDecorations {} +impl DataComponent for MapDecorations { + const KIND: DataComponentKind = DataComponentKind::MapDecorations; +} #[derive(Clone, Copy, PartialEq, AzBuf)] pub enum MapPostProcessing { Lock, Scale, } -impl DataComponent for MapPostProcessing {} +impl DataComponent for MapPostProcessing { + const KIND: DataComponentKind = DataComponentKind::MapPostProcessing; +} #[derive(Clone, PartialEq, AzBuf)] pub struct ChargedProjectiles { pub items: Vec, } -impl DataComponent for ChargedProjectiles {} +impl DataComponent for ChargedProjectiles { + const KIND: DataComponentKind = DataComponentKind::ChargedProjectiles; +} #[derive(Clone, PartialEq, AzBuf)] pub struct BundleContents { pub items: Vec, } -impl DataComponent for BundleContents {} +impl DataComponent for BundleContents { + const KIND: DataComponentKind = DataComponentKind::BundleContents; +} #[derive(Clone, PartialEq, AzBuf)] pub struct PotionContents { @@ -445,7 +507,9 @@ pub struct PotionContents { pub custom_color: Option, pub custom_effects: Vec, } -impl DataComponent for PotionContents {} +impl DataComponent for PotionContents { + const KIND: DataComponentKind = DataComponentKind::PotionContents; +} #[derive(Clone, PartialEq, AzBuf)] pub struct SuspiciousStewEffect { @@ -458,13 +522,17 @@ pub struct SuspiciousStewEffect { pub struct SuspiciousStewEffects { pub effects: Vec, } -impl DataComponent for SuspiciousStewEffects {} +impl DataComponent for SuspiciousStewEffects { + const KIND: DataComponentKind = DataComponentKind::SuspiciousStewEffects; +} #[derive(Clone, PartialEq, AzBuf)] pub struct WritableBookContent { pub pages: Vec, } -impl DataComponent for WritableBookContent {} +impl DataComponent for WritableBookContent { + const KIND: DataComponentKind = DataComponentKind::WritableBookContent; +} #[derive(Clone, PartialEq, AzBuf)] pub struct WrittenBookContent { @@ -475,7 +543,9 @@ pub struct WrittenBookContent { pub pages: Vec, pub resolved: bool, } -impl DataComponent for WrittenBookContent {} +impl DataComponent for WrittenBookContent { + const KIND: DataComponentKind = DataComponentKind::WrittenBookContent; +} #[derive(Clone, PartialEq, AzBuf)] pub struct Trim { @@ -483,57 +553,75 @@ pub struct Trim { pub pattern: TrimPattern, pub show_in_tooltip: bool, } -impl DataComponent for Trim {} +impl DataComponent for Trim { + const KIND: DataComponentKind = DataComponentKind::Trim; +} #[derive(Clone, PartialEq, AzBuf)] pub struct DebugStickState { pub properties: NbtCompound, } -impl DataComponent for DebugStickState {} +impl DataComponent for DebugStickState { + const KIND: DataComponentKind = DataComponentKind::DebugStickState; +} #[derive(Clone, PartialEq, AzBuf)] pub struct EntityData { pub entity: NbtCompound, } -impl DataComponent for EntityData {} +impl DataComponent for EntityData { + const KIND: DataComponentKind = DataComponentKind::EntityData; +} #[derive(Clone, PartialEq, AzBuf)] pub struct BucketEntityData { pub entity: NbtCompound, } -impl DataComponent for BucketEntityData {} +impl DataComponent for BucketEntityData { + const KIND: DataComponentKind = DataComponentKind::BucketEntityData; +} #[derive(Clone, PartialEq, AzBuf)] pub struct BlockEntityData { pub entity: NbtCompound, } -impl DataComponent for BlockEntityData {} +impl DataComponent for BlockEntityData { + const KIND: DataComponentKind = DataComponentKind::BlockEntityData; +} #[derive(Clone, PartialEq, AzBuf)] pub struct Instrument { pub instrument: azalea_registry::Instrument, } -impl DataComponent for Instrument {} +impl DataComponent for Instrument { + const KIND: DataComponentKind = DataComponentKind::Instrument; +} #[derive(Clone, PartialEq, AzBuf)] pub struct OminousBottleAmplifier { #[var] pub amplifier: i32, } -impl DataComponent for OminousBottleAmplifier {} +impl DataComponent for OminousBottleAmplifier { + const KIND: DataComponentKind = DataComponentKind::OminousBottleAmplifier; +} #[derive(Clone, PartialEq, AzBuf)] pub struct Recipes { pub recipes: Vec, } -impl DataComponent for Recipes {} +impl DataComponent for Recipes { + const KIND: DataComponentKind = DataComponentKind::Recipes; +} #[derive(Clone, PartialEq, AzBuf)] pub struct LodestoneTracker { pub target: Option, pub tracked: bool, } -impl DataComponent for LodestoneTracker {} +impl DataComponent for LodestoneTracker { + const KIND: DataComponentKind = DataComponentKind::LodestoneTracker; +} #[derive(Clone, Copy, PartialEq, AzBuf)] pub enum FireworkExplosionShape { @@ -552,7 +640,9 @@ pub struct FireworkExplosion { pub has_trail: bool, pub has_twinkle: bool, } -impl DataComponent for FireworkExplosion {} +impl DataComponent for FireworkExplosion { + const KIND: DataComponentKind = DataComponentKind::FireworkExplosion; +} #[derive(Clone, PartialEq, AzBuf)] pub struct Fireworks { @@ -560,7 +650,9 @@ pub struct Fireworks { pub flight_duration: i32, pub explosions: Vec, } -impl DataComponent for Fireworks {} +impl DataComponent for Fireworks { + const KIND: DataComponentKind = DataComponentKind::Fireworks; +} #[derive(Clone, PartialEq, AzBuf)] pub struct GameProfileProperty { @@ -575,13 +667,17 @@ pub struct Profile { pub id: Option, pub properties: Vec, } -impl DataComponent for Profile {} +impl DataComponent for Profile { + const KIND: DataComponentKind = DataComponentKind::Profile; +} #[derive(Clone, PartialEq, AzBuf)] pub struct NoteBlockSound { pub sound: ResourceLocation, } -impl DataComponent for NoteBlockSound {} +impl DataComponent for NoteBlockSound { + const KIND: DataComponentKind = DataComponentKind::NoteBlockSound; +} #[derive(Clone, PartialEq, AzBuf)] pub struct BannerPattern { @@ -595,7 +691,9 @@ pub struct BannerPattern { pub struct BannerPatterns { pub patterns: Vec, } -impl DataComponent for BannerPatterns {} +impl DataComponent for BannerPatterns { + const KIND: DataComponentKind = DataComponentKind::BannerPatterns; +} #[derive(Clone, Copy, PartialEq, AzBuf)] pub enum DyeColor { @@ -621,25 +719,33 @@ pub enum DyeColor { pub struct BaseColor { pub color: DyeColor, } -impl DataComponent for BaseColor {} +impl DataComponent for BaseColor { + const KIND: DataComponentKind = DataComponentKind::BaseColor; +} #[derive(Clone, PartialEq, AzBuf)] pub struct PotDecorations { pub items: Vec, } -impl DataComponent for PotDecorations {} +impl DataComponent for PotDecorations { + const KIND: DataComponentKind = DataComponentKind::PotDecorations; +} #[derive(Clone, PartialEq, AzBuf)] pub struct Container { pub items: Vec, } -impl DataComponent for Container {} +impl DataComponent for Container { + const KIND: DataComponentKind = DataComponentKind::Container; +} #[derive(Clone, PartialEq, AzBuf)] pub struct BlockState { pub properties: HashMap, } -impl DataComponent for BlockState {} +impl DataComponent for BlockState { + const KIND: DataComponentKind = DataComponentKind::BlockState; +} #[derive(Clone, PartialEq, AzBuf)] pub struct BeehiveOccupant { @@ -654,26 +760,34 @@ pub struct BeehiveOccupant { pub struct Bees { pub occupants: Vec, } -impl DataComponent for Bees {} +impl DataComponent for Bees { + const KIND: DataComponentKind = DataComponentKind::Bees; +} #[derive(Clone, PartialEq, AzBuf)] pub struct Lock { pub key: String, } -impl DataComponent for Lock {} +impl DataComponent for Lock { + const KIND: DataComponentKind = DataComponentKind::Lock; +} #[derive(Clone, PartialEq, AzBuf)] pub struct ContainerLoot { pub loot: NbtCompound, } -impl DataComponent for ContainerLoot {} +impl DataComponent for ContainerLoot { + const KIND: DataComponentKind = DataComponentKind::ContainerLoot; +} #[derive(Clone, PartialEq, AzBuf)] pub struct JukeboxPlayable { pub song: azalea_registry::JukeboxSong, pub show_in_tooltip: bool, } -impl DataComponent for JukeboxPlayable {} +impl DataComponent for JukeboxPlayable { + const KIND: DataComponentKind = DataComponentKind::JukeboxPlayable; +} #[derive(Clone, PartialEq, AzBuf)] pub struct Consumable { @@ -683,7 +797,9 @@ pub struct Consumable { pub has_consume_particles: bool, pub on_consuime_effects: Vec, } -impl DataComponent for Consumable {} +impl DataComponent for Consumable { + const KIND: DataComponentKind = DataComponentKind::Consumable; +} #[derive(Clone, Copy, PartialEq, AzBuf)] pub enum ItemUseAnimation { @@ -703,33 +819,43 @@ pub enum ItemUseAnimation { pub struct UseRemainder { pub convert_into: ItemStack, } -impl DataComponent for UseRemainder {} +impl DataComponent for UseRemainder { + const KIND: DataComponentKind = DataComponentKind::UseRemainder; +} #[derive(Clone, PartialEq, AzBuf)] pub struct UseCooldown { pub seconds: f32, pub cooldown_group: Option, } -impl DataComponent for UseCooldown {} +impl DataComponent for UseCooldown { + const KIND: DataComponentKind = DataComponentKind::UseCooldown; +} #[derive(Clone, PartialEq, AzBuf)] pub struct Enchantable { #[var] pub value: u32, } -impl DataComponent for Enchantable {} +impl DataComponent for Enchantable { + const KIND: DataComponentKind = DataComponentKind::Enchantable; +} #[derive(Clone, PartialEq, AzBuf)] pub struct Repairable { pub items: HolderSet, } -impl DataComponent for Repairable {} +impl DataComponent for Repairable { + const KIND: DataComponentKind = DataComponentKind::Repairable; +} #[derive(Clone, PartialEq, AzBuf)] pub struct ItemModel { pub resource_location: ResourceLocation, } -impl DataComponent for ItemModel {} +impl DataComponent for ItemModel { + const KIND: DataComponentKind = DataComponentKind::ItemModel; +} #[derive(Clone, PartialEq, AzBuf)] pub struct DamageResistant { @@ -743,7 +869,9 @@ pub struct DamageResistant { // resourcelocation for now pub types: ResourceLocation, } -impl DataComponent for DamageResistant {} +impl DataComponent for DamageResistant { + const KIND: DataComponentKind = DataComponentKind::DamageResistant; +} #[derive(Clone, PartialEq, AzBuf)] pub struct Equippable { @@ -752,7 +880,9 @@ pub struct Equippable { pub model: Option, pub allowed_entities: HolderSet, } -impl DataComponent for Equippable {} +impl DataComponent for Equippable { + const KIND: DataComponentKind = DataComponentKind::Equippable; +} #[derive(Clone, Copy, Debug, PartialEq, AzBuf)] pub enum EquipmentSlot { @@ -769,16 +899,22 @@ pub enum EquipmentSlot { #[derive(Clone, PartialEq, AzBuf)] pub struct Glider; -impl DataComponent for Glider {} +impl DataComponent for Glider { + const KIND: DataComponentKind = DataComponentKind::Glider; +} #[derive(Clone, PartialEq, AzBuf)] pub struct TooltipStyle { pub resource_location: ResourceLocation, } -impl DataComponent for TooltipStyle {} +impl DataComponent for TooltipStyle { + const KIND: DataComponentKind = DataComponentKind::TooltipStyle; +} #[derive(Clone, PartialEq, AzBuf)] pub struct DeathProtection { pub death_effects: Vec, } -impl DataComponent for DeathProtection {} +impl DataComponent for DeathProtection { + const KIND: DataComponentKind = DataComponentKind::DeathProtection; +} diff --git a/azalea-inventory/src/slot.rs b/azalea-inventory/src/slot.rs index 7d62bf69e..19963b34d 100644 --- a/azalea-inventory/src/slot.rs +++ b/azalea-inventory/src/slot.rs @@ -1,4 +1,5 @@ use std::{ + any::Any, collections::HashMap, fmt, io::{Cursor, Write}, @@ -177,9 +178,51 @@ pub struct DataComponentPatch { } impl DataComponentPatch { - pub fn get(&self, kind: DataComponentKind) -> Option<&dyn components::EncodableDataComponent> { + /// Returns the value of the component in the generic argument for this + /// item. + /// + /// ``` + /// # use azalea_inventory::{ItemStackData, DataComponentPatch, components}; + /// # use azalea_registry::Item; + /// # fn example(item: &ItemStackData) -> Option<()> { + /// let item_nutrition = item.components.get::()?.nutrition; + /// # Some(()) + /// # } + /// ``` + pub fn get(&self) -> Option<&T> { + let component = self.components.get(&T::KIND).and_then(|c| c.as_deref())?; + let component_any = component as &dyn Any; + component_any.downcast_ref::() + } + + pub fn get_kind( + &self, + kind: DataComponentKind, + ) -> Option<&dyn components::EncodableDataComponent> { self.components.get(&kind).and_then(|c| c.as_deref()) } + + /// Returns whether the component in the generic argument is present for + /// this item. + /// + /// ``` + /// # use azalea_inventory::{ItemStackData, DataComponentPatch, components}; + /// # use azalea_registry::Item; + /// # let item = ItemStackData { + /// # kind: Item::Stone, + /// # count: 1, + /// # components: Default::default(), + /// # }; + /// let is_edible = item.components.has::(); + /// # assert!(!is_edible); + /// ``` + pub fn has(&self) -> bool { + self.components.contains_key(&T::KIND) + } + + pub fn has_kind(&self, kind: DataComponentKind) -> bool { + self.components.contains_key(&kind) + } } impl AzaleaRead for DataComponentPatch { diff --git a/azalea/src/auto_tool.rs b/azalea/src/auto_tool.rs index 441f97917..1824e13c5 100644 --- a/azalea/src/auto_tool.rs +++ b/azalea/src/auto_tool.rs @@ -1,7 +1,7 @@ use azalea_block::{Block, BlockState}; use azalea_client::{inventory::Inventory, Client}; use azalea_entity::{FluidOnEyes, Physics}; -use azalea_inventory::{ItemStack, Menu}; +use azalea_inventory::{components, ItemStack, Menu}; use azalea_registry::{DataComponentKind, Fluid}; #[derive(Debug)] @@ -89,17 +89,13 @@ pub fn accurate_best_tool_in_hotbar_for_block( physics, )); } - ItemStack::Present(item_slot) => { + ItemStack::Present(item_stack) => { // lazy way to avoid checking durability since azalea doesn't have durability // data yet - if item_slot - .components - .get(DataComponentKind::Damage) - .is_none() - { + if !item_stack.components.has::() { this_item_speed = Some(azalea_entity::mining::get_mine_progress( block.as_ref(), - item_slot.kind, + item_stack.kind, menu, fluid_on_eyes, physics, diff --git a/codegen/genitemcomponents.py b/codegen/genitemcomponents.py index 73f03081d..625af847f 100644 --- a/codegen/genitemcomponents.py +++ b/codegen/genitemcomponents.py @@ -109,12 +109,12 @@ def remove_variant(variant: str): # now remove the struct line_before_struct = None # this is the #[derive] line - line_after_struct = None # impl DataComponent for ... {} + line_after_struct = None # impl DataComponent for ... {\n...\n} for i, line in enumerate(list(code)): if line == f'pub struct {variant} {{' or line == f'pub struct {variant};': line_before_struct = i - 1 - elif line == f'impl DataComponent for {variant} {{}}': - line_after_struct = i + 1 + elif line == f'impl DataComponent for {variant} {{': + line_after_struct = i + 3 break if line_before_struct is None: raise ValueError(f'Couldn\'t find struct {variant}') @@ -153,7 +153,9 @@ def add_variant(variant: str): code.append(f'pub struct {variant} {{') code.append(' pub todo: todo!(), // see DataComponents.java') code.append('}') - code.append(f'impl DataComponent for {variant} {{}}') + code.append(f'impl DataComponent for {variant} {{') + code.append(f' const KIND: DataComponentKind = DataComponentKind::{variant};') + code.append('}') with open(ITEM_COMPONENTS_DIR, 'w') as f: f.write('\n'.join(code))