Skip to main content

steel_core/behavior/blocks/vegetation/
tall_flower_block.rs

1use std::sync::Arc;
2
3use steel_macros::block_behavior;
4use steel_registry::blocks::properties::Direction;
5use steel_registry::item_stack::ItemStack;
6use steel_registry::{REGISTRY, RegistryExt};
7use steel_utils::{BlockPos, BlockStateId};
8
9use crate::behavior::block::BlockBehavior;
10use crate::behavior::blocks::vegetation::bonemealable::Bonemealable;
11use crate::behavior::context::{BlockPlaceContext, PlacementSource};
12use crate::world::{LevelReader, ScheduledTickAccess, World};
13
14use super::{BlockRef, DoublePlantBlock};
15
16/// Behavior for two-block-tall flowers.
17#[block_behavior]
18pub struct TallFlowerBlock {
19    block: BlockRef,
20    base: DoublePlantBlock,
21}
22
23impl TallFlowerBlock {
24    /// Creates a new tall flower block behavior.
25    #[must_use]
26    pub const fn new(block: BlockRef) -> Self {
27        Self {
28            block,
29            base: DoublePlantBlock::new(block),
30        }
31    }
32}
33
34impl BlockBehavior for TallFlowerBlock {
35    fn update_shape(
36        &self,
37        state: BlockStateId,
38        world: &dyn ScheduledTickAccess,
39        pos: BlockPos,
40        direction: Direction,
41        neighbor_pos: BlockPos,
42        neighbor_state: BlockStateId,
43    ) -> BlockStateId {
44        self.base
45            .update_shape(state, world, pos, direction, neighbor_pos, neighbor_state)
46    }
47
48    fn can_survive(&self, state: BlockStateId, world: &dyn LevelReader, pos: BlockPos) -> bool {
49        self.base.can_survive(state, world, pos)
50    }
51
52    fn set_placed_by(
53        &self,
54        state: BlockStateId,
55        world: &Arc<World>,
56        pos: BlockPos,
57        source: &PlacementSource<'_>,
58    ) {
59        self.base.set_placed_by(state, world, pos, source);
60    }
61
62    fn get_state_for_placement(&self, context: &BlockPlaceContext<'_>) -> Option<BlockStateId> {
63        self.base.get_state_for_placement(context)
64    }
65
66    fn as_bonemealable(&self) -> Option<&dyn Bonemealable> {
67        Some(self)
68    }
69}
70
71impl Bonemealable for TallFlowerBlock {
72    fn is_valid_bonemeal_target(
73        &self,
74        _state: BlockStateId,
75        _world: &dyn LevelReader,
76        _pos: BlockPos,
77    ) -> bool {
78        true
79    }
80
81    fn perform_bonemeal(
82        &self,
83        _state: BlockStateId,
84        world: &Arc<World>,
85        _rng: &mut dyn rand::Rng,
86        pos: BlockPos,
87    ) {
88        if let Some(item) = REGISTRY.items.by_key(&self.block.key) {
89            world.pop_resource(pos, ItemStack::new(item));
90        }
91    }
92}