steel_core/worldgen/feature/features/
end_podium.rs1use 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}