steel_core/behavior/blocks/vegetation/
mycelium_block.rs1use steel_macros::block_behavior;
2use steel_registry::blocks::BlockRef;
3use steel_registry::vanilla_blocks;
4use steel_utils::{BlockPos, BlockStateId, Direction};
5
6use super::snowy_block::{snowy_placement_state, update_snowy_shape};
7use super::spreading_grass_block::SpreadingGrassBlock;
8use crate::behavior::block::BlockBehavior;
9use crate::behavior::context::BlockPlaceContext;
10use crate::world::{ScheduledTickAccess, World};
11use std::sync::Arc;
12
13#[block_behavior]
15pub struct MyceliumBlock {
16 block: BlockRef,
17}
18
19impl MyceliumBlock {
20 #[must_use]
22 pub const fn new(block: BlockRef) -> Self {
23 Self { block }
24 }
25}
26
27impl BlockBehavior for MyceliumBlock {
28 fn get_state_for_placement(&self, context: &BlockPlaceContext<'_>) -> Option<BlockStateId> {
29 Some(snowy_placement_state(self.block, context))
30 }
31
32 fn update_shape(
33 &self,
34 state: BlockStateId,
35 _world: &dyn ScheduledTickAccess,
36 _pos: BlockPos,
37 direction: Direction,
38 _neighbor_pos: BlockPos,
39 neighbor_state: BlockStateId,
40 ) -> BlockStateId {
41 update_snowy_shape(state, direction, neighbor_state)
42 }
43
44 fn random_tick(&self, state: BlockStateId, world: &Arc<World>, pos: BlockPos) {
45 SpreadingGrassBlock::random_tick(
46 &vanilla_blocks::MYCELIUM,
47 &vanilla_blocks::DIRT,
48 state,
49 world,
50 pos,
51 );
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use steel_registry::blocks::block_state_ext::BlockStateExt;
58 use steel_registry::blocks::properties::BlockStateProperties;
59 use steel_registry::{init_vanilla_registry, vanilla_blocks};
60 use steel_utils::{BlockPos, Direction};
61
62 use super::*;
63 use crate::behavior::init_behaviors;
64 use crate::test_support::TestLevel;
65
66 #[test]
67 fn mycelium_block_updates_snowy_state() {
68 init_vanilla_registry();
69 init_behaviors();
70
71 let level = TestLevel::default();
72 let pos = BlockPos::new(0, 64, 0);
73 let behavior = MyceliumBlock::new(&vanilla_blocks::MYCELIUM);
74
75 let non_snowy = vanilla_blocks::MYCELIUM.default_state();
76 let snowy = behavior.update_shape(
77 non_snowy,
78 &level,
79 pos,
80 Direction::Up,
81 pos.above(),
82 vanilla_blocks::SNOW.default_state(),
83 );
84 assert!(snowy.get_value(&BlockStateProperties::SNOWY));
85
86 let cleared = behavior.update_shape(
87 snowy,
88 &level,
89 pos,
90 Direction::Up,
91 pos.above(),
92 vanilla_blocks::AIR.default_state(),
93 );
94 assert!(!cleared.get_value(&BlockStateProperties::SNOWY));
95 }
96}