steel_core/worldgen/feature/features/
basalt_pillar.rs1use super::super::prelude::*;
2use super::super::runner::FeatureDecorationRunner;
3
4impl FeatureDecorationRunner {
5 pub(in crate::worldgen::feature) fn place_basalt_pillar_feature(
6 region: &mut WorldGenRegion<'_>,
7 random: &mut WorldgenRandom,
8 origin: BlockPos,
9 ) -> bool {
10 if !region.block_state(origin).is_air() || region.block_state(origin.above()).is_air() {
11 return false;
12 }
13
14 let basalt = vanilla_blocks::BASALT.default_state();
15 let mut pos = origin;
16 let mut place_north_hangoff = true;
17 let mut place_south_hangoff = true;
18 let mut place_west_hangoff = true;
19 let mut place_east_hangoff = true;
20
21 while region.block_state(pos).is_air() {
22 if region.is_outside_build_height(pos.y()) {
23 return true;
24 }
25
26 let _ = region.set_block_state(pos, basalt, UpdateFlags::UPDATE_CLIENTS);
27 if place_north_hangoff {
28 place_north_hangoff =
29 Self::place_basalt_pillar_hangoff(region, random, basalt, pos.north());
30 }
31 if place_south_hangoff {
32 place_south_hangoff =
33 Self::place_basalt_pillar_hangoff(region, random, basalt, pos.south());
34 }
35 if place_west_hangoff {
36 place_west_hangoff =
37 Self::place_basalt_pillar_hangoff(region, random, basalt, pos.west());
38 }
39 if place_east_hangoff {
40 place_east_hangoff =
41 Self::place_basalt_pillar_hangoff(region, random, basalt, pos.east());
42 }
43
44 pos = pos.below();
45 }
46
47 pos = pos.above();
48 Self::place_basalt_pillar_base_hangoff(region, random, basalt, pos.north());
49 Self::place_basalt_pillar_base_hangoff(region, random, basalt, pos.south());
50 Self::place_basalt_pillar_base_hangoff(region, random, basalt, pos.west());
51 Self::place_basalt_pillar_base_hangoff(region, random, basalt, pos.east());
52 pos = pos.below();
53
54 for dx in -3i32..4 {
55 for dz in -3i32..4 {
56 let probability = dx.abs() * dz.abs();
57 if random.next_i32_bounded(10) < 10 - probability {
58 let mut base_pos = pos.offset(dx, 0, dz);
59 let mut max_drop = 3;
60
61 while region.block_state(base_pos.below()).is_air() {
62 base_pos = base_pos.below();
63 max_drop -= 1;
64 if max_drop <= 0 {
65 break;
66 }
67 }
68
69 if !region.block_state(base_pos.below()).is_air() {
70 let _ =
71 region.set_block_state(base_pos, basalt, UpdateFlags::UPDATE_CLIENTS);
72 }
73 }
74 }
75 }
76
77 true
78 }
79
80 pub(in crate::worldgen::feature) fn place_basalt_pillar_base_hangoff(
81 region: &mut WorldGenRegion<'_>,
82 random: &mut WorldgenRandom,
83 basalt: BlockStateId,
84 pos: BlockPos,
85 ) {
86 if random.next_bool() {
87 let _ = region.set_block_state(pos, basalt, UpdateFlags::UPDATE_CLIENTS);
88 }
89 }
90
91 pub(in crate::worldgen::feature) fn place_basalt_pillar_hangoff(
92 region: &mut WorldGenRegion<'_>,
93 random: &mut WorldgenRandom,
94 basalt: BlockStateId,
95 pos: BlockPos,
96 ) -> bool {
97 if random.next_i32_bounded(10) == 0 {
98 return false;
99 }
100
101 let _ = region.set_block_state(pos, basalt, UpdateFlags::UPDATE_CLIENTS);
102 true
103 }
104}