steel_core/behavior/blocks/vegetation/
firefly_bush_block.rs1use rand::Rng;
2use std::sync::Arc;
3use steel_macros::block_behavior;
4use steel_registry::vanilla_block_tags::BlockTag;
5use steel_utils::types::UpdateFlags;
6use steel_utils::{BlockPos, BlockStateId, Direction};
7
8use crate::behavior::blocks::vegetation::bonemealable::{
9 BonemealAction, find_spreadable_neighbor_pos, has_spreadable_neighbor_pos,
10};
11use crate::behavior::blocks::vegetation::vegetation_block::survival_update_shape;
12use crate::behavior::context::BlockPlaceContext;
13use crate::behavior::{block::BlockBehavior, blocks::vegetation::bonemealable::Bonemealable};
14use crate::world::{LevelReader, ScheduledTickAccess, World};
15
16use super::{BlockRef, default_surviving_state, survives_on_tag};
17
18#[block_behavior]
20pub struct FireflyBushBlock {
21 block: BlockRef,
22}
23
24impl FireflyBushBlock {
25 #[must_use]
27 pub const fn new(block: BlockRef) -> Self {
28 Self { block }
29 }
30}
31
32impl BlockBehavior for FireflyBushBlock {
33 fn can_survive(&self, _state: BlockStateId, world: &dyn LevelReader, pos: BlockPos) -> bool {
34 survives_on_tag(world, pos, &BlockTag::SUPPORTS_VEGETATION)
35 }
36
37 fn get_state_for_placement(&self, context: &BlockPlaceContext<'_>) -> Option<BlockStateId> {
38 default_surviving_state(self.block, self, context)
39 }
40 fn update_shape(
41 &self,
42 state: BlockStateId,
43 world: &dyn ScheduledTickAccess,
44 pos: BlockPos,
45 _direction: Direction,
46 _neighbor_pos: BlockPos,
47 _neighbor_state: BlockStateId,
48 ) -> BlockStateId {
49 survival_update_shape(self, state, world, pos)
50 }
51
52 fn as_bonemealable(&self) -> Option<&dyn super::bonemealable::Bonemealable> {
53 Some(self)
54 }
55}
56impl Bonemealable for FireflyBushBlock {
57 fn is_valid_bonemeal_target(
58 &self,
59 state: BlockStateId,
60 world: &dyn LevelReader,
61 pos: BlockPos,
62 ) -> bool {
63 has_spreadable_neighbor_pos(world, pos, state)
64 }
65
66 fn perform_bonemeal(
67 &self,
68 state: BlockStateId,
69 world: &Arc<World>,
70 _rng: &mut dyn Rng,
71 pos: BlockPos,
72 ) {
73 let Some(block_pos) = find_spreadable_neighbor_pos(world, pos, state) else {
74 return;
75 };
76 world.set_block(
77 block_pos,
78 self.block.default_state(),
79 UpdateFlags::UPDATE_ALL,
80 );
81 }
82
83 fn bonemeal_action_type(&self) -> BonemealAction {
84 BonemealAction::Grower
85 }
86}