steel_core/worldgen/feature/features/
desert_well.rs1#![expect(
2 clippy::too_many_lines,
3 reason = "desert well placement is kept linear to mirror vanilla"
4)]
5
6use super::super::prelude::*;
7use super::super::runner::FeatureDecorationRunner;
8
9const DESERT_WELL_ARCHAEOLOGY: &str = "minecraft:archaeology/desert_well";
10
11impl FeatureDecorationRunner {
12 pub(in crate::worldgen::feature) fn place_desert_well_feature(
13 region: &WorldGenRegion<'_>,
14 random: &mut WorldgenRandom,
15 origin: BlockPos,
16 ) -> bool {
17 let mut origin = origin.above();
18 while region.block_state(origin).is_air() && origin.y() > region.min_y() + 2 {
19 origin = origin.below();
20 }
21
22 if region.block_state(origin).get_block() != &vanilla_blocks::SAND {
23 return false;
24 }
25
26 for ox in -2..=2 {
27 for oz in -2..=2 {
28 if region.block_state(origin.offset(ox, -1, oz)).is_air()
29 && region.block_state(origin.offset(ox, -2, oz)).is_air()
30 {
31 return false;
32 }
33 }
34 }
35
36 let sandstone = vanilla_blocks::SANDSTONE.default_state();
37 let sand = vanilla_blocks::SAND.default_state();
38 let sand_slab = vanilla_blocks::SANDSTONE_SLAB.default_state();
39 let water = vanilla_blocks::WATER.default_state();
40
41 for oy in -2..=0 {
42 for ox in -2..=2 {
43 for oz in -2..=2 {
44 let _ = region.set_block_state(
45 origin.offset(ox, oy, oz),
46 sandstone,
47 UpdateFlags::UPDATE_CLIENTS,
48 );
49 }
50 }
51 }
52
53 let _ = region.set_block_state(origin, water, UpdateFlags::UPDATE_CLIENTS);
54 for direction in Self::VANILLA_HORIZONTAL_DIRECTIONS {
55 let _ = region.set_block_state(
56 origin.relative(direction),
57 water,
58 UpdateFlags::UPDATE_CLIENTS,
59 );
60 }
61
62 let sand_center = origin.below();
63 let _ = region.set_block_state(sand_center, sand, UpdateFlags::UPDATE_CLIENTS);
64 for direction in Self::VANILLA_HORIZONTAL_DIRECTIONS {
65 let _ = region.set_block_state(
66 sand_center.relative(direction),
67 sand,
68 UpdateFlags::UPDATE_CLIENTS,
69 );
70 }
71
72 for ox in -2..=2 {
73 for oz in -2..=2 {
74 if ox == -2 || ox == 2 || oz == -2 || oz == 2 {
75 let _ = region.set_block_state(
76 origin.offset(ox, 1, oz),
77 sandstone,
78 UpdateFlags::UPDATE_CLIENTS,
79 );
80 }
81 }
82 }
83
84 let _ = region.set_block_state(
85 origin.offset(2, 1, 0),
86 sand_slab,
87 UpdateFlags::UPDATE_CLIENTS,
88 );
89 let _ = region.set_block_state(
90 origin.offset(-2, 1, 0),
91 sand_slab,
92 UpdateFlags::UPDATE_CLIENTS,
93 );
94 let _ = region.set_block_state(
95 origin.offset(0, 1, 2),
96 sand_slab,
97 UpdateFlags::UPDATE_CLIENTS,
98 );
99 let _ = region.set_block_state(
100 origin.offset(0, 1, -2),
101 sand_slab,
102 UpdateFlags::UPDATE_CLIENTS,
103 );
104
105 for ox in -1..=1 {
106 for oz in -1..=1 {
107 let state = if ox == 0 && oz == 0 {
108 sandstone
109 } else {
110 sand_slab
111 };
112 let _ = region.set_block_state(
113 origin.offset(ox, 4, oz),
114 state,
115 UpdateFlags::UPDATE_CLIENTS,
116 );
117 }
118 }
119
120 for oy in 1..=3 {
121 let _ = region.set_block_state(
122 origin.offset(-1, oy, -1),
123 sandstone,
124 UpdateFlags::UPDATE_CLIENTS,
125 );
126 let _ = region.set_block_state(
127 origin.offset(-1, oy, 1),
128 sandstone,
129 UpdateFlags::UPDATE_CLIENTS,
130 );
131 let _ = region.set_block_state(
132 origin.offset(1, oy, -1),
133 sandstone,
134 UpdateFlags::UPDATE_CLIENTS,
135 );
136 let _ = region.set_block_state(
137 origin.offset(1, oy, 1),
138 sandstone,
139 UpdateFlags::UPDATE_CLIENTS,
140 );
141 }
142
143 let water_positions = [
144 origin,
145 origin.east(),
146 origin.south(),
147 origin.west(),
148 origin.north(),
149 ];
150 let first = water_positions[random.next_i32_bounded(5) as usize].below();
151 Self::place_suspicious_sand(region, first);
152 let second = water_positions[random.next_i32_bounded(5) as usize].below_n(2);
153 Self::place_suspicious_sand(region, second);
154 true
155 }
156
157 fn place_suspicious_sand(region: &WorldGenRegion<'_>, pos: BlockPos) {
158 let state = vanilla_blocks::SUSPICIOUS_SAND.default_state();
159 if region.set_block_state(pos, state, UpdateFlags::UPDATE_ALL) {
160 Self::set_brushable_loot_table(region, pos, state, DESERT_WELL_ARCHAEOLOGY);
161 }
162 }
163}