Skip to main content

steel_core/behavior/items/
honeycomb.rs

1use steel_macros::item_behavior;
2use steel_registry::item_stack::ItemStack;
3use steel_registry::{
4    REGISTRY, blocks::block_state_ext::BlockStateExt, level_events, vanilla_game_events,
5};
6use steel_utils::Downcast as _;
7use steel_utils::types::UpdateFlags;
8
9use crate::{
10    behavior::{
11        InteractionResult, ItemBehavior, UseOnContext, waxables::get_waxed_from_normal_variant,
12    },
13    block_entity::{BlockEntity, entities::SignBlockEntity},
14    entity::Entity,
15    world::game_event::GameEventContext,
16};
17
18use super::copper_chest_events::emit_connected_chest_block_change;
19
20/// Behavior for the honeycomb item. Waxes copper blocks and signs.
21#[item_behavior]
22pub struct HoneycombItem;
23
24impl ItemBehavior for HoneycombItem {
25    fn use_on(&self, context: &mut UseOnContext) -> InteractionResult {
26        let pos = context.hit_result.block_pos;
27
28        // Try block waxing first
29        let old_block_state = context.world.get_block_state(pos);
30        if let Some(waxed_block) = get_waxed_from_normal_variant(old_block_state.get_block()) {
31            context.inv.with_item(ItemStack::shrink_one);
32            // TODO: trigger CriteriaTriggers.ITEM_USED_ON_BLOCK advancement
33            let waxed_state = REGISTRY
34                .blocks
35                .copy_matching_properties(old_block_state, waxed_block);
36            context
37                .world
38                .set_block(pos, waxed_state, UpdateFlags::UPDATE_ALL);
39            context.world.game_event(
40                &vanilla_game_events::BLOCK_CHANGE,
41                pos,
42                &GameEventContext::new(Some(context.player), Some(waxed_state)),
43            );
44            context.world.level_event(
45                level_events::PARTICLES_AND_SOUND_WAX_ON,
46                pos,
47                0,
48                Some(context.player.id()),
49            );
50            emit_connected_chest_block_change(
51                context.world,
52                pos,
53                old_block_state,
54                context.player,
55                Some(level_events::PARTICLES_AND_SOUND_WAX_ON),
56            );
57            return InteractionResult::Success;
58        }
59
60        // Fall through to sign waxing
61        let Some(block_entity) = context.world.get_block_entity(pos) else {
62            return InteractionResult::Pass;
63        };
64
65        let Some(sign) = block_entity.downcast_ref::<SignBlockEntity>() else {
66            return InteractionResult::Pass;
67        };
68
69        if !sign.wax() {
70            return InteractionResult::Pass;
71        }
72
73        sign.set_changed();
74        context.inv.with_item(ItemStack::shrink_one);
75        context.world.level_event(
76            level_events::PARTICLES_AND_SOUND_WAX_ON,
77            pos,
78            0,
79            Some(context.player.id()),
80        );
81        InteractionResult::Success
82    }
83}