Skip to main content

steel_core/behavior/items/
honeycomb.rs

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