Skip to main content

steel_core/behavior/blocks/vegetation/
carpet_block.rs

1use steel_macros::block_behavior;
2use steel_registry::DyeColor;
3use steel_registry::blocks::block_state_ext::BlockStateExt;
4use steel_utils::{BlockPos, BlockStateId, Direction};
5
6use crate::behavior::block::BlockBehavior;
7use crate::behavior::blocks::vegetation::vegetation_block::survival_update_shape;
8use crate::behavior::context::BlockPlaceContext;
9use crate::world::{LevelReader, ScheduledTickAccess};
10
11use super::{BlockRef, default_surviving_state};
12
13/// Vanilla `CarpetBlock` survival and shape updates.
14#[block_behavior]
15pub struct CarpetBlock {
16    block: BlockRef,
17}
18
19impl CarpetBlock {
20    /// Creates a new carpet block behavior.
21    #[must_use]
22    pub const fn new(block: BlockRef) -> Self {
23        Self { block }
24    }
25}
26
27impl BlockBehavior for CarpetBlock {
28    fn update_shape(
29        &self,
30        state: BlockStateId,
31        world: &dyn ScheduledTickAccess,
32        pos: BlockPos,
33        _direction: Direction,
34        _neighbor_pos: BlockPos,
35        _neighbor_state: BlockStateId,
36    ) -> BlockStateId {
37        // Vanilla `CarpetBlock.updateShape`: break when support is removed.
38        survival_update_shape(self, state, world, pos)
39    }
40
41    fn can_survive(&self, _state: BlockStateId, world: &dyn LevelReader, pos: BlockPos) -> bool {
42        !world.get_block_state(pos.below()).is_air()
43    }
44
45    fn get_state_for_placement(&self, context: &BlockPlaceContext<'_>) -> Option<BlockStateId> {
46        default_surviving_state(self.block, self, context)
47    }
48}
49
50/// Vanilla `WoolCarpetBlock` behavior for dyed wool carpets.
51#[block_behavior]
52pub struct WoolCarpetBlock {
53    block: BlockRef,
54    #[json_arg(
55        r#enum = "DyeColor",
56        json = "color",
57        module = "steel_registry::dye_color"
58    )]
59    #[expect(unused, reason = "Stored for dye color reference")]
60    color: DyeColor,
61}
62
63impl WoolCarpetBlock {
64    /// Creates a new wool carpet block behavior.
65    #[must_use]
66    pub const fn new(block: BlockRef, color: DyeColor) -> Self {
67        Self { block, color }
68    }
69}
70
71impl BlockBehavior for WoolCarpetBlock {
72    fn update_shape(
73        &self,
74        state: BlockStateId,
75        world: &dyn ScheduledTickAccess,
76        pos: BlockPos,
77        _direction: Direction,
78        _neighbor_pos: BlockPos,
79        _neighbor_state: BlockStateId,
80    ) -> BlockStateId {
81        survival_update_shape(self, state, world, pos)
82    }
83
84    fn can_survive(&self, _state: BlockStateId, world: &dyn LevelReader, pos: BlockPos) -> bool {
85        !world.get_block_state(pos.below()).is_air()
86    }
87
88    fn get_state_for_placement(&self, context: &BlockPlaceContext<'_>) -> Option<BlockStateId> {
89        default_surviving_state(self.block, self, context)
90    }
91}