steel_core/behavior/blocks/vegetation/
mangrove_roots_block.rs1use steel_macros::block_behavior;
2use steel_registry::blocks::properties::Direction;
3use steel_utils::{BlockPos, BlockStateId};
4
5use crate::behavior::block::BlockBehavior;
6use crate::behavior::blocks::WaterloggedTransparentBlock;
7use crate::behavior::context::BlockPlaceContext;
8use crate::world::ScheduledTickAccess;
9
10use super::BlockRef;
11
12#[block_behavior]
14pub struct MangroveRootsBlock {
15 waterlogged: WaterloggedTransparentBlock,
16}
17
18impl MangroveRootsBlock {
19 #[must_use]
21 pub const fn new(block: BlockRef) -> Self {
22 Self {
23 waterlogged: WaterloggedTransparentBlock::new(block),
24 }
25 }
26}
27
28impl BlockBehavior for MangroveRootsBlock {
29 fn get_state_for_placement(&self, context: &BlockPlaceContext<'_>) -> Option<BlockStateId> {
30 self.waterlogged.get_state_for_placement(context)
31 }
32
33 fn update_shape(
34 &self,
35 state: BlockStateId,
36 world: &dyn ScheduledTickAccess,
37 pos: BlockPos,
38 direction: Direction,
39 neighbor_pos: BlockPos,
40 neighbor_state: BlockStateId,
41 ) -> BlockStateId {
42 self.waterlogged
43 .update_shape(state, world, pos, direction, neighbor_pos, neighbor_state)
44 }
45}
46
47#[cfg(test)]
48mod tests {
49 use steel_registry::blocks::block_state_ext::BlockStateExt;
50 use steel_registry::blocks::properties::{BlockStateProperties, BoolProperty};
51 use steel_registry::item_stack::ItemStack;
52 use steel_registry::{init_vanilla_registry, vanilla_blocks, vanilla_fluids, vanilla_items};
53 use steel_utils::{ChunkPos, types::UpdateFlags};
54
55 use super::*;
56 use crate::behavior::init_behaviors;
57 use crate::test_support::{TestLevel, fresh_test_world, insert_ready_full_chunk};
58
59 const WATERLOGGED: &BoolProperty = &BlockStateProperties::WATERLOGGED;
60
61 #[test]
62 fn placement_preserves_source_water() {
63 init_vanilla_registry();
64 init_behaviors();
65 let world = fresh_test_world("mangrove_roots_placement");
66 let wet_pos = BlockPos::new(8, 64, 8);
67 let dry_pos = wet_pos.east();
68 insert_ready_full_chunk(&world, ChunkPos::from_block_pos(wet_pos));
69 assert!(world.set_block(
70 wet_pos,
71 vanilla_blocks::WATER.default_state(),
72 UpdateFlags::UPDATE_NONE,
73 ));
74 let behavior = MangroveRootsBlock::new(&vanilla_blocks::MANGROVE_ROOTS);
75
76 let wet_state = {
77 let mut stack = ItemStack::new(&vanilla_items::MANGROVE_ROOTS);
78 let context = BlockPlaceContext::directional(
79 &world,
80 wet_pos,
81 Direction::Down,
82 &mut stack,
83 Direction::Up,
84 );
85 behavior
86 .get_state_for_placement(&context)
87 .expect("mangrove roots should have a wet placement state")
88 };
89 let dry_state = {
90 let mut stack = ItemStack::new(&vanilla_items::MANGROVE_ROOTS);
91 let context = BlockPlaceContext::directional(
92 &world,
93 dry_pos,
94 Direction::Down,
95 &mut stack,
96 Direction::Up,
97 );
98 behavior
99 .get_state_for_placement(&context)
100 .expect("mangrove roots should have a dry placement state")
101 };
102
103 assert!(wet_state.get_value(WATERLOGGED));
104 assert!(!dry_state.get_value(WATERLOGGED));
105 }
106
107 #[test]
108 fn waterlogged_neighbor_update_schedules_water_tick() {
109 init_vanilla_registry();
110 let behavior = MangroveRootsBlock::new(&vanilla_blocks::MANGROVE_ROOTS);
111 let wet_state = vanilla_blocks::MANGROVE_ROOTS
112 .default_state()
113 .set_value(WATERLOGGED, true);
114 let dry_state = wet_state.set_value(WATERLOGGED, false);
115 let wet_level = TestLevel::default();
116 let dry_level = TestLevel::default();
117
118 assert_eq!(
119 behavior.update_shape(
120 wet_state,
121 &wet_level,
122 BlockPos::ZERO,
123 Direction::Up,
124 BlockPos::ZERO.above(),
125 vanilla_blocks::AIR.default_state(),
126 ),
127 wet_state
128 );
129 assert_eq!(
130 behavior.update_shape(
131 dry_state,
132 &dry_level,
133 BlockPos::ZERO,
134 Direction::Up,
135 BlockPos::ZERO.above(),
136 vanilla_blocks::AIR.default_state(),
137 ),
138 dry_state
139 );
140 assert!(wet_level.scheduled_water_tick());
141 assert!(!dry_level.scheduled_water_tick());
142 }
143
144 #[test]
145 fn waterlogged_roots_contain_source_water() {
146 init_vanilla_registry();
147 let state = vanilla_blocks::MANGROVE_ROOTS
148 .default_state()
149 .set_value(WATERLOGGED, true);
150
151 let fluid = state.get_fluid_state();
152
153 assert_eq!(fluid.fluid_id, &vanilla_fluids::WATER);
154 assert!(fluid.is_source());
155 }
156}