Skip to main content

steel_core/behavior/blocks/vegetation/
spore_blossom_block.rs

1use steel_macros::block_behavior;
2use steel_registry::blocks::shapes::SupportType;
3use steel_registry::{blocks::properties::Direction, vanilla_blocks};
4use steel_utils::{BlockPos, BlockStateId};
5
6use crate::behavior::block::BlockBehavior;
7use crate::behavior::context::BlockPlaceContext;
8use crate::fluid::get_fluid_state_from_block;
9use crate::world::{LevelReader, ScheduledTickAccess};
10
11use super::{BlockRef, default_surviving_state};
12
13/// Vanilla `SporeBlossomBlock` survival.
14#[block_behavior]
15pub struct SporeBlossomBlock {
16    block: BlockRef,
17}
18
19impl SporeBlossomBlock {
20    /// Creates a new spore blossom block behavior.
21    #[must_use]
22    pub const fn new(block: BlockRef) -> Self {
23        Self { block }
24    }
25}
26
27impl BlockBehavior for SporeBlossomBlock {
28    fn can_survive(&self, _state: BlockStateId, world: &dyn LevelReader, pos: BlockPos) -> bool {
29        let above_pos = pos.above();
30        world.is_face_sturdy_for(
31            world.get_block_state(above_pos),
32            above_pos,
33            Direction::Down,
34            SupportType::Center,
35        ) && get_fluid_state_from_block(world.get_block_state(pos)).is_empty()
36    }
37
38    fn get_state_for_placement(&self, context: &BlockPlaceContext<'_>) -> Option<BlockStateId> {
39        default_surviving_state(self.block, self, context)
40    }
41
42    fn update_shape(
43        &self,
44        state: BlockStateId,
45        world: &dyn ScheduledTickAccess,
46        pos: BlockPos,
47        direction: Direction,
48        _neighbor_pos: BlockPos,
49        _neighbor_state: BlockStateId,
50    ) -> BlockStateId {
51        if direction == Direction::Up && !self.can_survive(state, world, pos) {
52            return vanilla_blocks::AIR.default_state();
53        }
54        state
55    }
56}