Skip to main content

steel_core/behavior/blocks/vegetation/
mangrove_roots_block.rs

1use 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/// Vanilla mangrove roots behavior.
13#[block_behavior]
14pub struct MangroveRootsBlock {
15    waterlogged: WaterloggedTransparentBlock,
16}
17
18impl MangroveRootsBlock {
19    /// Creates a new mangrove roots behavior.
20    #[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}