Skip to main content

steel_core/behavior/blocks/decoration/
end_rod_block.rs

1//! Vanilla `EndRodBlock` behavior.
2
3use steel_macros::block_behavior;
4use steel_registry::blocks::BlockRef;
5use steel_registry::blocks::block_state_ext::BlockStateExt;
6use steel_registry::blocks::properties::{BlockStateProperties, EnumProperty};
7use steel_utils::{BlockStateId, Direction};
8
9use crate::behavior::{BlockBehavior, BlockPlaceContext};
10
11const FACING: &EnumProperty<Direction> = &BlockStateProperties::FACING;
12
13/// End rods use the clicked face for their orientation and reverse against an aligned rod.
14#[block_behavior]
15pub struct EndRodBlock {
16    block: BlockRef,
17}
18
19impl EndRodBlock {
20    /// Creates an end rod behavior for the given block.
21    #[must_use]
22    pub const fn new(block: BlockRef) -> Self {
23        Self { block }
24    }
25}
26
27impl BlockBehavior for EndRodBlock {
28    fn get_state_for_placement(&self, context: &BlockPlaceContext<'_>) -> Option<BlockStateId> {
29        let clicked_face = context.clicked_face();
30        let adjacent_pos = context.place_pos().relative(clicked_face.opposite());
31        let adjacent = context.world.get_block_state(adjacent_pos);
32        let facing =
33            if adjacent.get_block() == self.block && adjacent.get_value(FACING) == clicked_face {
34                clicked_face.opposite()
35            } else {
36                clicked_face
37            };
38
39        Some(self.block.default_state().set_value(FACING, facing))
40    }
41}