Skip to main content

steel_core/behavior/blocks/container/
anvil_block.rs

1use std::sync::Arc;
2
3use steel_macros::block_behavior;
4use steel_registry::{
5    blocks::{BlockRef, block_state_ext::BlockStateExt, properties::BlockStateProperties},
6    items::item::BlockHitResult,
7    vanilla_blocks,
8};
9use steel_utils::{BlockStateId, translations};
10use text_components::TextComponent;
11
12use crate::{
13    behavior::{BlockBehavior, BlockPlaceContext, InteractionResult, InventoryAccess},
14    inventory::menu::kinds::anvil,
15    player::Player,
16    world::World,
17};
18
19/// Behavior for Anvils
20#[block_behavior]
21pub struct AnvilBlock {
22    block: BlockRef,
23}
24
25impl AnvilBlock {
26    /// Creates a new Anvil Block Behavior
27    #[must_use]
28    pub const fn new(block: BlockRef) -> Self {
29        Self { block }
30    }
31
32    /// Returns the next damage level block state for anvil `BlockStates`
33    #[must_use]
34    pub fn damage(state: BlockStateId) -> Option<BlockStateId> {
35        let block = state.get_block();
36        if block == &vanilla_blocks::ANVIL {
37            Some(
38                vanilla_blocks::CHIPPED_ANVIL
39                    .default_state()
40                    .copy_value(&BlockStateProperties::FACING, &state),
41            )
42        } else if block == &vanilla_blocks::CHIPPED_ANVIL {
43            Some(
44                vanilla_blocks::DAMAGED_ANVIL
45                    .default_state()
46                    .copy_value(&BlockStateProperties::FACING, &state),
47            )
48        } else {
49            None
50        }
51    }
52}
53
54impl BlockBehavior for AnvilBlock {
55    fn get_state_for_placement(&self, context: &BlockPlaceContext<'_>) -> Option<BlockStateId> {
56        Some(self.block.default_state().set_value(
57            &BlockStateProperties::HORIZONTAL_FACING,
58            context.horizontal_direction().rotate_y_clockwise(),
59        ))
60    }
61
62    fn use_without_item(
63        &self,
64        _state: BlockStateId,
65        _world: &Arc<World>,
66        pos: steel_utils::BlockPos,
67        player: &Player,
68        _hit_result: &BlockHitResult,
69        _inv: &mut InventoryAccess,
70    ) -> InteractionResult {
71        let inventory = player.inventory.clone();
72        player.open_menu(
73            TextComponent::translated(translations::CONTAINER_REPAIR.msg()),
74            move |context| anvil(inventory, context.container_id, pos, context.world),
75        );
76        InteractionResult::Success
77    }
78}