Skip to main content

steel_core/behavior/items/
player_head.rs

1use std::borrow::Cow;
2
3use steel_macros::item_behavior;
4use steel_registry::{
5    blocks::{BlockRef, properties::Direction},
6    data_components::vanilla_components::PROFILE,
7    item_stack::ItemStack,
8    resolvable_profile::ResolvableProfileContents,
9};
10use text_components::TextComponent;
11
12use crate::behavior::{InteractionResult, ItemBehavior, UseOnContext};
13
14use super::{
15    StandingAndWallBlockItem,
16    dynamic_name::{default_name, description_id, translated},
17};
18
19/// Player-head placement behavior with the profile-specific name.
20#[item_behavior]
21pub struct PlayerHeadItem {
22    #[json_arg(vanilla_blocks, json = "block")]
23    _standing_block: BlockRef,
24    #[json_arg(vanilla_blocks, json = "wall_block")]
25    _wall_block: BlockRef,
26    #[json_arg(
27        r#enum = "Direction",
28        module = "steel_registry::blocks::properties",
29        json = "attachment_direction"
30    )]
31    _attachment_direction: Direction,
32    base: StandingAndWallBlockItem,
33}
34
35impl PlayerHeadItem {
36    /// Creates player-head behavior for the standing and wall block pair.
37    #[must_use]
38    pub const fn new(
39        standing_block: BlockRef,
40        wall_block: BlockRef,
41        attachment_direction: Direction,
42    ) -> Self {
43        Self {
44            _standing_block: standing_block,
45            _wall_block: wall_block,
46            _attachment_direction: attachment_direction,
47            base: StandingAndWallBlockItem::new(standing_block, wall_block, attachment_direction),
48        }
49    }
50}
51
52impl ItemBehavior for PlayerHeadItem {
53    fn use_on(&self, context: &mut UseOnContext) -> InteractionResult {
54        self.base.use_on(context)
55    }
56
57    fn get_name<'a>(&self, stack: &'a ItemStack) -> Cow<'a, TextComponent> {
58        let Some(profile) = stack.get(PROFILE) else {
59            return default_name(stack);
60        };
61        let name = match profile.contents() {
62            ResolvableProfileContents::DynamicName(name) => Some(name.as_str()),
63            ResolvableProfileContents::StaticFull(profile) => Some(profile.name()),
64            ResolvableProfileContents::StaticPartial(profile) => profile.name(),
65            ResolvableProfileContents::DynamicId(_) => None,
66        };
67        let Some(name) = name else {
68            return default_name(stack);
69        };
70        let Some(description_id) = description_id(stack) else {
71            return default_name(stack);
72        };
73        translated(
74            format!("{description_id}.named"),
75            Some(Box::new([TextComponent::plain(name.to_owned())])),
76        )
77    }
78}