Skip to main content

steel_core/worldgen/feature/features/
block_pile.rs

1use super::super::prelude::*;
2use super::super::runner::FeatureDecorationRunner;
3
4impl FeatureDecorationRunner {
5    pub(in crate::worldgen::feature) fn place_block_pile_feature(
6        region: &mut WorldGenRegion<'_>,
7        registry: &Registry,
8        random: &mut WorldgenRandom,
9        config: &BlockPileConfiguration,
10        origin: BlockPos,
11    ) -> bool {
12        if origin.y() < region.min_y() + 5 {
13            return false;
14        }
15
16        let x_radius = 2 + random.next_i32_bounded(2);
17        let z_radius = 2 + random.next_i32_bounded(2);
18
19        Self::for_each_vanilla_between_closed(
20            origin.offset(-x_radius, 0, -z_radius),
21            origin.offset(x_radius, 1, z_radius),
22            |pos| {
23                let dx = origin.x() - pos.x();
24                let dz = origin.z() - pos.z();
25                let distance_squared = (dx * dx + dz * dz) as f32;
26                if distance_squared <= random.next_f32() * 10.0 - random.next_f32() * 6.0
27                    || random.next_f32() < 0.031
28                {
29                    Self::try_place_block_pile_block(region, registry, random, config, pos);
30                }
31            },
32        );
33
34        true
35    }
36
37    pub(in crate::worldgen::feature) fn try_place_block_pile_block(
38        region: &mut WorldGenRegion<'_>,
39        registry: &Registry,
40        random: &mut WorldgenRandom,
41        config: &BlockPileConfiguration,
42        pos: BlockPos,
43    ) {
44        if !region.block_state(pos).is_air() || !Self::block_pile_may_place_on(region, random, pos)
45        {
46            return;
47        }
48
49        let state = Self::sample_block_state_provider(
50            region,
51            registry,
52            random,
53            &config.state_provider,
54            pos,
55        );
56        let _ = region.set_block_state(pos, state, UpdateFlags::UPDATE_NONE);
57    }
58
59    pub(in crate::worldgen::feature) fn block_pile_may_place_on(
60        region: &WorldGenRegion<'_>,
61        random: &mut WorldgenRandom,
62        pos: BlockPos,
63    ) -> bool {
64        let below_pos = pos.below();
65        let below = region.block_state(below_pos);
66        if below.get_block() == &vanilla_blocks::DIRT_PATH {
67            return random.next_bool();
68        }
69
70        below.is_face_sturdy_at(below_pos, Direction::Up)
71    }
72}