Skip to main content

steel_core/worldgen/feature/features/
void_start_platform.rs

1use super::super::prelude::*;
2use super::super::runner::FeatureDecorationRunner;
3
4const PLATFORM_OFFSET_X: i32 = 8;
5const PLATFORM_OFFSET_Y: i32 = 3;
6const PLATFORM_OFFSET_Z: i32 = 8;
7const PLATFORM_RADIUS: i32 = 16;
8const PLATFORM_RADIUS_CHUNKS: i32 = 1;
9
10impl FeatureDecorationRunner {
11    pub(in crate::worldgen::feature) fn place_void_start_platform_feature(
12        region: &mut WorldGenRegion<'_>,
13        origin: BlockPos,
14    ) -> bool {
15        let chunk_x = SectionPos::block_to_section_coord(origin.x());
16        let chunk_z = SectionPos::block_to_section_coord(origin.z());
17        let platform_origin_chunk_x = SectionPos::block_to_section_coord(PLATFORM_OFFSET_X);
18        let platform_origin_chunk_z = SectionPos::block_to_section_coord(PLATFORM_OFFSET_Z);
19
20        if Self::checkerboard_distance(
21            chunk_x,
22            chunk_z,
23            platform_origin_chunk_x,
24            platform_origin_chunk_z,
25        ) > PLATFORM_RADIUS_CHUNKS
26        {
27            return true;
28        }
29
30        let platform_origin = BlockPos::new(
31            PLATFORM_OFFSET_X,
32            origin.y() + PLATFORM_OFFSET_Y,
33            PLATFORM_OFFSET_Z,
34        );
35        let stone = vanilla_blocks::STONE.default_state();
36        let cobblestone = vanilla_blocks::COBBLESTONE.default_state();
37        let min_x = chunk_x * 16;
38        let min_z = chunk_z * 16;
39
40        for z in min_z..=min_z + 15 {
41            for x in min_x..=min_x + 15 {
42                if Self::checkerboard_distance(platform_origin.x(), platform_origin.z(), x, z)
43                    <= PLATFORM_RADIUS
44                {
45                    let pos = BlockPos::new(x, platform_origin.y(), z);
46                    let state = if pos == platform_origin {
47                        cobblestone
48                    } else {
49                        stone
50                    };
51                    let _ = region.set_block_state(pos, state, UpdateFlags::UPDATE_CLIENTS);
52                }
53            }
54        }
55
56        true
57    }
58
59    const fn checkerboard_distance(xa: i32, za: i32, xb: i32, zb: i32) -> i32 {
60        let dx = if xa >= xb { xa - xb } else { xb - xa };
61        let dz = if za >= zb { za - zb } else { zb - za };
62        if dx > dz { dx } else { dz }
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use super::FeatureDecorationRunner;
69
70    #[test]
71    fn void_start_platform_checkerboard_distance_matches_vanilla() {
72        assert_eq!(
73            FeatureDecorationRunner::checkerboard_distance(0, 0, 0, 0),
74            0
75        );
76        assert_eq!(
77            FeatureDecorationRunner::checkerboard_distance(0, 0, 1, -1),
78            1
79        );
80        assert_eq!(
81            FeatureDecorationRunner::checkerboard_distance(-2, 3, 4, 1),
82            6
83        );
84    }
85}