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_fixture = fresh_test_world("mangrove_roots_placement");
66 let world = &world_fixture.world;
67 let wet_pos = BlockPos::new(8, 64, 8);
68 let dry_pos = wet_pos.east();
69 insert_ready_full_chunk(world, ChunkPos::from_block_pos(wet_pos));
70 assert!(world.set_block(
71 wet_pos,
72 vanilla_blocks::WATER.default_state(),
73 UpdateFlags::UPDATE_NONE,
74 ));
75 let behavior = MangroveRootsBlock::new(&vanilla_blocks::MANGROVE_ROOTS);
76
77 let wet_state = {
78 let mut stack = ItemStack::new(&vanilla_items::MANGROVE_ROOTS);
79 let context = BlockPlaceContext::directional(
80 world,
81 wet_pos,
82 Direction::Down,
83 &mut stack,
84 Direction::Up,
85 );
86 behavior
87 .get_state_for_placement(&context)
88 .expect("mangrove roots should have a wet placement state")
89 };
90 let dry_state = {
91 let mut stack = ItemStack::new(&vanilla_items::MANGROVE_ROOTS);
92 let context = BlockPlaceContext::directional(
93 world,
94 dry_pos,
95 Direction::Down,
96 &mut stack,
97 Direction::Up,
98 );
99 behavior
100 .get_state_for_placement(&context)
101 .expect("mangrove roots should have a dry placement state")
102 };
103
104 assert!(wet_state.get_value(WATERLOGGED));
105 assert!(!dry_state.get_value(WATERLOGGED));
106 }
107
108 #[test]
109 fn waterlogged_neighbor_update_schedules_water_tick() {
110 init_vanilla_registry();
111 let behavior = MangroveRootsBlock::new(&vanilla_blocks::MANGROVE_ROOTS);
112 let wet_state = vanilla_blocks::MANGROVE_ROOTS
113 .default_state()
114 .set_value(WATERLOGGED, true);
115 let dry_state = wet_state.set_value(WATERLOGGED, false);
116 let wet_level = TestLevel::default();
117 let dry_level = TestLevel::default();
118
119 assert_eq!(
120 behavior.update_shape(
121 wet_state,
122 &wet_level,
123 BlockPos::ZERO,
124 Direction::Up,
125 BlockPos::ZERO.above(),
126 vanilla_blocks::AIR.default_state(),
127 ),
128 wet_state
129 );
130 assert_eq!(
131 behavior.update_shape(
132 dry_state,
133 &dry_level,
134 BlockPos::ZERO,
135 Direction::Up,
136 BlockPos::ZERO.above(),
137 vanilla_blocks::AIR.default_state(),
138 ),
139 dry_state
140 );
141 assert!(wet_level.scheduled_water_tick());
142 assert!(!dry_level.scheduled_water_tick());
143 }
144
145 #[test]
146 fn waterlogged_roots_contain_source_water() {
147 init_vanilla_registry();
148 let state = vanilla_blocks::MANGROVE_ROOTS
149 .default_state()
150 .set_value(WATERLOGGED, true);
151
152 let fluid = state.get_fluid_state();
153
154 assert_eq!(fluid.fluid_id, &vanilla_fluids::WATER);
155 assert!(fluid.is_source());
156 }
157}