Skip to main content

steel_core/entity/projectile/
throwable_item.rs

1//! Vanilla `ThrowableItemProjectile` — carries a synced rendered item stack.
2//!
3//! Vanilla stores the item in `DATA_ITEM_STACK` (synced entity data). Steel keeps
4//! it in the generated `*EntityData` layer, so this trait has no base struct: the
5//! concrete entity implements [`ThrowableItemProjectile::set_item`] /
6//! [`ThrowableItemProjectile::get_item`] against its synced data.
7
8use simdnbt::ToNbtTag;
9use simdnbt::borrow::NbtCompound as BorrowedNbtCompoundView;
10use simdnbt::owned::NbtCompound;
11use steel_registry::item_stack::ItemStack;
12use steel_registry::items::ItemRef;
13
14use crate::entity::projectile::ThrowableProjectile;
15
16/// Vanilla-shaped behavior shared by entities that extend `ThrowableItemProjectile`.
17pub trait ThrowableItemProjectile: ThrowableProjectile {
18    /// Vanilla `ThrowableItemProjectile.getDefaultItem`.
19    fn get_default_item(&self) -> ItemRef;
20
21    /// Sets the rendered item stack (vanilla `setItem`, count clamped to 1).
22    ///
23    /// The concrete entity stores this in its synced data layer.
24    fn set_item(&self, item: ItemStack);
25
26    /// Returns the rendered item stack (vanilla `getItem`).
27    fn get_item(&self) -> ItemStack;
28
29    /// Vanilla `ThrowableItemProjectile.setItem` count-clamping helper.
30    fn set_item_clamped(&self, item: ItemStack) {
31        self.set_item(item.copy_with_count(1));
32    }
33
34    /// Saves the item stack (vanilla `addAdditionalSaveData`).
35    fn save_throwable_item(&self, nbt: &mut NbtCompound) {
36        let item = self.get_item();
37        if !item.is_empty() {
38            nbt.insert("Item", item.to_nbt_tag());
39        }
40    }
41
42    /// Loads the item stack, falling back to the default item (vanilla
43    /// `readAdditionalSaveData`).
44    fn load_throwable_item(&self, nbt: BorrowedNbtCompoundView<'_, '_>) {
45        let item = nbt
46            .compound("Item")
47            .and_then(|tag| ItemStack::from_borrowed_compound(&tag))
48            .unwrap_or_else(|| ItemStack::new(self.get_default_item()));
49        self.set_item_clamped(item);
50    }
51}