Skip to main content

steel_core/worldgen/feature/features/
desert_well.rs

1#![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}