steel_core/worldgen/feature/features/
disk.rs1use super::super::prelude::*;
2use super::super::runner::FeatureDecorationRunner;
3
4impl FeatureDecorationRunner {
5 pub(in crate::worldgen::feature) fn place_disk_feature(
6 region: &mut WorldGenRegion<'_>,
7 registry: &Registry,
8 random: &mut WorldgenRandom,
9 config: &DiskConfiguration,
10 origin: BlockPos,
11 ) -> bool {
12 let top = origin.y() + config.half_height;
13 let bottom = origin.y() - config.half_height - 1;
14 let radius = config.radius.sample(random);
15 let mut placed_any = false;
16
17 Self::for_each_vanilla_between_closed(
18 origin.offset(-radius, 0, -radius),
19 origin.offset(radius, 0, radius),
20 |column_pos| {
21 let dx = column_pos.x() - origin.x();
22 let dz = column_pos.z() - origin.z();
23 if dx * dx + dz * dz <= radius * radius {
24 placed_any |= Self::place_disk_column(
25 region, registry, random, config, top, bottom, column_pos,
26 );
27 }
28 },
29 );
30
31 placed_any
32 }
33
34 pub(in crate::worldgen::feature) fn place_disk_column(
35 region: &mut WorldGenRegion<'_>,
36 registry: &Registry,
37 random: &mut WorldgenRandom,
38 config: &DiskConfiguration,
39 top: i32,
40 bottom: i32,
41 column_pos: BlockPos,
42 ) -> bool {
43 let mut placed_any = false;
44 let mut placed_above = false;
45
46 for y in (bottom + 1..=top).rev() {
47 let pos = BlockPos::new(column_pos.x(), y, column_pos.z());
48 if Self::test_block_predicate(region, registry, &config.target, pos) {
49 if let Some(state) = Self::sample_block_state_provider_optional(
50 region,
51 registry,
52 random,
53 &config.state_provider,
54 pos,
55 ) {
56 let _ = region.set_block_state(pos, state, UpdateFlags::UPDATE_CLIENTS);
57 if !placed_above {
58 Self::mark_above_for_postprocessing(region, pos);
59 }
60 placed_any = true;
61 placed_above = true;
62 }
63 } else {
64 placed_above = false;
65 }
66 }
67
68 placed_any
69 }
70
71 pub(in crate::worldgen::feature) fn mark_above_for_postprocessing(
72 region: &WorldGenRegion<'_>,
73 pos: BlockPos,
74 ) {
75 let mut mark_pos = pos;
76 for _ in 0..2 {
77 mark_pos = mark_pos.above();
78 if region.block_state(mark_pos).is_air() {
79 return;
80 }
81 region.mark_pos_for_postprocessing(mark_pos);
82 }
83 }
84}