Skip to main content

steel_core/behavior/blocks/container/
crafting_table_block.rs

1//! Crafting table block behavior implementation.
2//!
3//! Opens the 3x3 crafting grid when right-clicked.
4
5use std::sync::Arc;
6
7use steel_macros::block_behavior;
8use steel_registry::blocks::BlockRef;
9use steel_utils::{BlockPos, BlockStateId, translations};
10use text_components::TextComponent;
11
12use crate::behavior::InventoryAccess;
13use crate::behavior::block::BlockBehavior;
14use crate::behavior::context::{BlockHitResult, BlockPlaceContext, InteractionResult};
15use crate::inventory::menu::kinds::crafting;
16use crate::player::Player;
17use crate::world::World;
18
19/// Behavior for the crafting table block.
20///
21/// When a player interacts with the crafting table without an item (or with
22/// an item that doesn't consume the action), it opens the 3x3 crafting menu.
23#[block_behavior]
24pub struct CraftingTableBlock {
25    block: BlockRef,
26}
27
28impl CraftingTableBlock {
29    /// Creates a new crafting table block behavior.
30    #[must_use]
31    pub const fn new(block: BlockRef) -> Self {
32        Self { block }
33    }
34}
35
36impl BlockBehavior for CraftingTableBlock {
37    fn get_state_for_placement(&self, _context: &BlockPlaceContext<'_>) -> Option<BlockStateId> {
38        Some(self.block.default_state())
39    }
40
41    fn use_without_item(
42        &self,
43        _state: BlockStateId,
44        _world: &Arc<World>,
45        pos: BlockPos,
46        player: &Player,
47        _hit_result: &BlockHitResult,
48        _inv: &mut InventoryAccess,
49    ) -> InteractionResult {
50        let inventory = player.inventory.clone();
51        player.open_menu(
52            TextComponent::translated(translations::CONTAINER_CRAFTING.msg()),
53            move |context| crafting(inventory, context.container_id, pos),
54        );
55        // TODO: Award stat INTERACT_WITH_CRAFTING_TABLE
56        InteractionResult::Success
57    }
58}