Skip to main content

steel_core/worldgen/feature/features/
delta.rs

1use super::super::prelude::*;
2use super::super::runner::FeatureDecorationRunner;
3
4impl FeatureDecorationRunner {
5    pub(in crate::worldgen::feature) fn place_delta_feature(
6        region: &mut WorldGenRegion<'_>,
7        registry: &Registry,
8        random: &mut WorldgenRandom,
9        config: &DeltaFeatureConfiguration,
10        origin: BlockPos,
11    ) -> bool {
12        let contents = Self::block_state_from_data(registry, &config.contents);
13        let rim = Self::block_state_from_data(registry, &config.rim);
14        let spawn_rim = random.next_f64() < 0.9;
15        let rim_x = if spawn_rim {
16            config.rim_size.sample(random)
17        } else {
18            0
19        };
20        let rim_z = if spawn_rim {
21            config.rim_size.sample(random)
22        } else {
23            0
24        };
25        let has_rim = spawn_rim && rim_x != 0 && rim_z != 0;
26        let radius_x = config.size.sample(random);
27        let radius_z = config.size.sample(random);
28        let radius_limit = radius_x.max(radius_z);
29        let mut any_placed = false;
30
31        Self::for_each_vanilla_within_manhattan(origin, radius_x, 0, radius_z, |pos| {
32            if Self::manhattan_distance(pos, origin) > radius_limit {
33                return false;
34            }
35
36            if Self::delta_is_clear(region, pos, contents) {
37                if has_rim {
38                    let _ = region.set_block_state(pos, rim, UpdateFlags::UPDATE_CLIENTS);
39                    any_placed = true;
40                }
41
42                let offset_pos = pos.offset(rim_x, 0, rim_z);
43                if Self::delta_is_clear(region, offset_pos, contents) {
44                    let _ =
45                        region.set_block_state(offset_pos, contents, UpdateFlags::UPDATE_CLIENTS);
46                    any_placed = true;
47                }
48            }
49
50            true
51        });
52
53        any_placed
54    }
55
56    fn delta_is_clear(region: &WorldGenRegion<'_>, pos: BlockPos, contents: BlockStateId) -> bool {
57        let state = region.block_state(pos);
58        if state.get_block() == contents.get_block() {
59            return false;
60        }
61
62        if Self::delta_cannot_replace(state.get_block()) {
63            return false;
64        }
65
66        for direction in Self::VANILLA_DIRECTION_VALUES {
67            let is_air = region.block_state(pos.relative(direction)).is_air();
68            if (is_air && direction != Direction::Up) || (!is_air && direction == Direction::Up) {
69                return false;
70            }
71        }
72
73        true
74    }
75
76    fn delta_cannot_replace(block: BlockRef) -> bool {
77        block == &vanilla_blocks::BEDROCK
78            || block == &vanilla_blocks::NETHER_BRICKS
79            || block == &vanilla_blocks::NETHER_BRICK_FENCE
80            || block == &vanilla_blocks::NETHER_BRICK_STAIRS
81            || block == &vanilla_blocks::NETHER_WART
82            || block == &vanilla_blocks::CHEST
83            || block == &vanilla_blocks::SPAWNER
84    }
85}