steel_core/behavior/items/
ink_sac.rs1use steel_macros::item_behavior;
11use steel_protocol::packets::game::SoundSource;
12use steel_registry::{
13 sound_event::SoundEventRef,
14 sound_events::{ITEM_GLOW_INK_SAC_USE, ITEM_INK_SAC_USE},
15 stat::vanilla_stat_types,
16 vanilla_game_events,
17};
18use steel_utils::Downcast as _;
19
20use crate::{
21 behavior::{InteractionResult, ItemBehavior, UseOnContext, blocks::is_facing_front_text},
22 block_entity::{BlockEntity, entities::SignBlockEntity},
23 world::game_event::GameEventContext,
24};
25
26fn apply_glow(context: &mut UseOnContext, glowing: bool) -> InteractionResult {
28 let pos = context.hit_result.block_pos;
29
30 let Some(block_entity) = context.world.get_block_entity(pos) else {
31 return InteractionResult::Pass;
32 };
33 let Some(sign) = block_entity.downcast_ref::<SignBlockEntity>() else {
34 return InteractionResult::Pass;
35 };
36
37 if !context.player.abilities.lock().may_build
38 || sign.is_waxed()
39 || sign.is_other_player_editing(context.player.gameprofile.id)
40 {
41 return InteractionResult::TryEmptyHandInteraction;
42 }
43
44 let state = context.world.get_block_state(pos);
45 let is_front_text = is_facing_front_text(state, pos, context.player);
46
47 if !sign.get_text(is_front_text).has_message() {
49 return InteractionResult::TryEmptyHandInteraction;
50 }
51
52 if !sign.set_glowing(is_front_text, glowing) {
53 return InteractionResult::TryEmptyHandInteraction;
54 }
55
56 sign.set_changed();
57 if let Some(nbt) = sign.get_update_tag() {
58 context
59 .world
60 .broadcast_block_entity_update(pos, sign.get_type(), nbt);
61 }
62
63 context.world.game_event(
64 &vanilla_game_events::BLOCK_CHANGE,
65 pos,
66 &GameEventContext::new(Some(context.player), Some(state)),
67 );
68
69 let has_infinite_materials = context.player.has_infinite_materials();
70 let item_used = context.inv.with_item(|item| {
71 item.consume_one(has_infinite_materials);
72 item.item
73 });
74 context
75 .player
76 .award_stat(&vanilla_stat_types::ITEM_USED, item_used);
77
78 context
79 .world
80 .play_sound(sound_for(glowing), SoundSource::Blocks, pos, 1.0, 1.0, None);
81
82 InteractionResult::Success
83}
84
85const fn sound_for(glowing: bool) -> SoundEventRef {
86 if glowing {
87 &ITEM_GLOW_INK_SAC_USE
88 } else {
89 &ITEM_INK_SAC_USE
90 }
91}
92
93#[item_behavior]
95pub struct InkSacItem;
96
97impl ItemBehavior for InkSacItem {
98 fn use_on(&self, context: &mut UseOnContext) -> InteractionResult {
99 apply_glow(context, false)
100 }
101}
102
103#[item_behavior]
105pub struct GlowInkSacItem;
106
107impl ItemBehavior for GlowInkSacItem {
108 fn use_on(&self, context: &mut UseOnContext) -> InteractionResult {
109 apply_glow(context, true)
110 }
111}