Skip to main content

steel_core/behavior/items/
honeycomb.rs

1use steel_macros::item_behavior;
2use steel_protocol::packets::game::SoundSource;
3use steel_registry::item_stack::ItemStack;
4use steel_registry::{
5    REGISTRY, blocks::block_state_ext::BlockStateExt, level_events,
6    sound_events::ITEM_HONEYCOMB_WAX_ON, vanilla_game_events,
7};
8use steel_utils::types::{SignTextSlot, UpdateFlags};
9
10use crate::{
11    behavior::{
12        InteractionResult, ItemBehavior, SignApplicator, UseOnContext,
13        waxables::get_waxed_from_normal_variant,
14    },
15    block_entity::{
16        BlockEntity,
17        entities::{SignBlockEntity, SignText},
18    },
19    entity::Entity,
20    player::Player,
21    world::{World, game_event::GameEventContext},
22};
23
24use super::copper_chest_events::emit_connected_chest_block_change;
25
26/// Behavior for the honeycomb item. Waxes copper blocks and signs.
27#[item_behavior]
28pub struct HoneycombItem;
29
30impl ItemBehavior for HoneycombItem {
31    fn use_on(&self, context: &mut UseOnContext) -> InteractionResult {
32        let pos = context.hit_result.block_pos;
33
34        // Try block waxing first
35        let old_block_state = context.world.get_block_state(pos);
36        if let Some(waxed_block) = get_waxed_from_normal_variant(old_block_state.get_block()) {
37            context.inv.with_item(ItemStack::shrink_one);
38            // TODO: trigger CriteriaTriggers.ITEM_USED_ON_BLOCK advancement
39            let waxed_state = REGISTRY
40                .blocks
41                .copy_matching_properties(old_block_state, waxed_block);
42            context
43                .world
44                .set_block(pos, waxed_state, UpdateFlags::UPDATE_ALL);
45            context.world.game_event(
46                &vanilla_game_events::BLOCK_CHANGE,
47                pos,
48                &GameEventContext::new(Some(context.player.as_ref()), Some(waxed_state)),
49            );
50            context.world.level_event(
51                level_events::PARTICLES_WAX_ON,
52                pos,
53                0,
54                Some(context.player.id()),
55            );
56            emit_connected_chest_block_change(
57                context.world,
58                pos,
59                old_block_state,
60                context.player,
61                Some(level_events::PARTICLES_WAX_ON),
62            );
63            return InteractionResult::Success;
64        }
65
66        InteractionResult::Pass
67    }
68
69    fn as_sign_applicator(&self) -> Option<&dyn SignApplicator> {
70        Some(self)
71    }
72}
73
74impl SignApplicator for HoneycombItem {
75    fn can_apply_to_sign(&self, _text: &SignText, _item: &ItemStack, _player: &Player) -> bool {
76        true
77    }
78
79    fn try_apply_to_sign(
80        &self,
81        world: &World,
82        sign: &SignBlockEntity,
83        _slot: SignTextSlot,
84        _item: &ItemStack,
85        _player: &Player,
86    ) -> bool {
87        if !sign.wax() {
88            return false;
89        }
90        let pos = sign.get_block_pos();
91        world.level_event(level_events::PARTICLES_WAX_ON, pos, 0, None);
92        world.play_sound(
93            &ITEM_HONEYCOMB_WAX_ON,
94            SoundSource::Blocks,
95            pos,
96            1.0,
97            1.0,
98            None,
99        );
100        true
101    }
102}