steel_core/worldgen/feature/features/
block_blob.rs1use super::super::prelude::*;
2use super::super::runner::FeatureDecorationRunner;
3
4impl FeatureDecorationRunner {
5 pub(in crate::worldgen::feature) fn place_block_blob_feature(
6 region: &mut WorldGenRegion<'_>,
7 registry: &Registry,
8 random: &mut WorldgenRandom,
9 config: &BlockBlobConfiguration,
10 mut origin: BlockPos,
11 ) -> bool {
12 while origin.y() > region.min_y() + 3
13 && !BlockStateProviderEvaluator::test_block_predicate(
14 region,
15 registry,
16 &config.can_place_on,
17 origin.below(),
18 )
19 {
20 origin = origin.below();
21 }
22
23 if origin.y() <= region.min_y() + 3 {
24 return false;
25 }
26
27 let state = BlockStateProviderEvaluator::block_state_from_data(registry, &config.state);
28 for _ in 0..3 {
29 let x_radius = random.next_i32_bounded(2);
30 let y_radius = random.next_i32_bounded(2);
31 let z_radius = random.next_i32_bounded(2);
32 let threshold = (x_radius + y_radius + z_radius) as f32 * 0.333 + 0.5;
33 let threshold_squared = threshold * threshold;
34
35 for x in origin.x() - x_radius..=origin.x() + x_radius {
36 for y in origin.y() - y_radius..=origin.y() + y_radius {
37 for z in origin.z() - z_radius..=origin.z() + z_radius {
38 let dx = x - origin.x();
39 let dy = y - origin.y();
40 let dz = z - origin.z();
41 if (dx * dx + dy * dy + dz * dz) as f32 <= threshold_squared {
42 let _ = region.set_block_state(
43 BlockPos::new(x, y, z),
44 state,
45 UpdateFlags::UPDATE_ALL,
46 );
47 }
48 }
49 }
50 }
51
52 origin = origin.offset(
53 -1 + random.next_i32_bounded(2),
54 -random.next_i32_bounded(2),
55 -1 + random.next_i32_bounded(2),
56 );
57 }
58
59 true
60 }
61}