Skip to main content

steel_core/worldgen/feature/features/
replace_blobs.rs

1use super::super::prelude::*;
2use super::super::runner::FeatureDecorationRunner;
3
4impl FeatureDecorationRunner {
5    pub(in crate::worldgen::feature) fn place_netherrack_replace_blobs_feature(
6        region: &mut WorldGenRegion<'_>,
7        registry: &Registry,
8        random: &mut WorldgenRandom,
9        config: &NetherrackReplaceBlobsConfiguration,
10        origin: BlockPos,
11    ) -> bool {
12        let target = Self::block_state_from_data(registry, &config.target);
13        let replacement = Self::block_state_from_data(registry, &config.state);
14        let clamped_origin = BlockPos::new(
15            origin.x(),
16            origin
17                .y()
18                .clamp(region.min_y() + 1, region.max_y_exclusive() - 1),
19            origin.z(),
20        );
21        let Some(center) = Self::find_replace_blobs_target(region, clamped_origin, target) else {
22            return false;
23        };
24
25        let radius_x = config.radius.sample(random);
26        let radius_y = config.radius.sample(random);
27        let radius_z = config.radius.sample(random);
28        let maximum_radius = radius_x.max(radius_y).max(radius_z);
29        let target_block = target.get_block();
30        let mut replaced_any = false;
31
32        Self::for_each_vanilla_within_manhattan(center, radius_x, radius_y, radius_z, |pos| {
33            if Self::manhattan_distance(pos, center) > maximum_radius {
34                return false;
35            }
36
37            if region.block_state(pos).get_block() == target_block {
38                let _ = region.set_block_state(pos, replacement, UpdateFlags::UPDATE_CLIENTS);
39                replaced_any = true;
40            }
41
42            true
43        });
44
45        replaced_any
46    }
47
48    fn find_replace_blobs_target(
49        region: &WorldGenRegion<'_>,
50        mut cursor: BlockPos,
51        target: BlockStateId,
52    ) -> Option<BlockPos> {
53        let target_block = target.get_block();
54        while cursor.y() > region.min_y() + 1 {
55            if region.block_state(cursor).get_block() == target_block {
56                return Some(cursor);
57            }
58            cursor = cursor.below();
59        }
60
61        None
62    }
63}