steel_core/worldgen/feature/features/
delta.rs1use 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}