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