Skip to main content

steel_core/worldgen/feature/features/
end_podium.rs

1use super::super::prelude::*;
2use super::super::runner::FeatureDecorationRunner;
3
4impl FeatureDecorationRunner {
5    pub(in crate::worldgen::feature) fn place_end_podium_feature(
6        region: &mut WorldGenRegion<'_>,
7        origin: BlockPos,
8        active: bool,
9    ) -> bool {
10        let bedrock = vanilla_blocks::BEDROCK.default_state();
11        let end_stone = vanilla_blocks::END_STONE.default_state();
12        let air = vanilla_blocks::AIR.default_state();
13        let end_portal = vanilla_blocks::END_PORTAL.default_state();
14
15        for pos in BlockPos::between_closed(origin.offset(-4, -1, -4), origin.offset(4, 32, 4)) {
16            let inside_rim = Self::end_podium_closer_than(pos, origin, 2.5);
17            if !inside_rim && !Self::end_podium_closer_than(pos, origin, 3.5) {
18                continue;
19            }
20
21            if pos.y() < origin.y() {
22                if inside_rim {
23                    let _ = region.set_block_state(pos, bedrock, UpdateFlags::UPDATE_CLIENTS);
24                } else if active {
25                    Self::drop_previous_and_set(region, pos, end_stone);
26                } else {
27                    let _ = region.set_block_state(pos, end_stone, UpdateFlags::UPDATE_CLIENTS);
28                }
29            } else if pos.y() > origin.y() {
30                if active {
31                    Self::drop_previous_and_set(region, pos, air);
32                } else {
33                    let _ = region.set_block_state(pos, air, UpdateFlags::UPDATE_CLIENTS);
34                }
35            } else if !inside_rim {
36                let _ = region.set_block_state(pos, bedrock, UpdateFlags::UPDATE_CLIENTS);
37            } else if active {
38                Self::drop_previous_and_set(region, pos, end_portal);
39            } else {
40                let _ = region.set_block_state(pos, air, UpdateFlags::UPDATE_CLIENTS);
41            }
42        }
43
44        for y in 0..4 {
45            let _ = region.set_block_state(origin.above_n(y), bedrock, UpdateFlags::UPDATE_CLIENTS);
46        }
47
48        let center = origin.above_n(2);
49        for facing in Self::VANILLA_HORIZONTAL_DIRECTIONS {
50            let torch = vanilla_blocks::WALL_TORCH
51                .default_state()
52                .set_value(&BlockStateProperties::HORIZONTAL_FACING, facing);
53            let _ =
54                region.set_block_state(center.relative(facing), torch, UpdateFlags::UPDATE_CLIENTS);
55        }
56
57        true
58    }
59
60    fn end_podium_closer_than(pos: BlockPos, origin: BlockPos, distance: f64) -> bool {
61        let dx = f64::from(pos.x() - origin.x());
62        let dy = f64::from(pos.y() - origin.y());
63        let dz = f64::from(pos.z() - origin.z());
64        dx * dx + dy * dy + dz * dz < distance * distance
65    }
66
67    fn drop_previous_and_set(region: &mut WorldGenRegion<'_>, pos: BlockPos, state: BlockStateId) {
68        if region.block_state(pos).get_block() == state.get_block() {
69            return;
70        }
71
72        let _ = region.destroy_block(pos, true);
73        let _ = region.set_block_state(pos, state, UpdateFlags::UPDATE_CLIENTS);
74    }
75}