Skip to main content

steel_core/worldgen/feature/features/
blue_ice.rs

1use super::super::prelude::*;
2use super::super::runner::FeatureDecorationRunner;
3
4impl FeatureDecorationRunner {
5    pub(in crate::worldgen::feature) fn place_blue_ice_feature(
6        region: &mut WorldGenRegion<'_>,
7        random: &mut WorldgenRandom,
8        origin: BlockPos,
9    ) -> bool {
10        if origin.y() > region.sea_level() - 1 {
11            return false;
12        }
13
14        if !Self::is_water(region.block_state(origin))
15            && !Self::is_water(region.block_state(origin.below()))
16        {
17            return false;
18        }
19
20        let mut found_packed_ice = false;
21        for direction in Self::VANILLA_DIRECTION_VALUES {
22            if direction != Direction::Down
23                && region.block_state(origin.relative(direction)).get_block()
24                    == &vanilla_blocks::PACKED_ICE
25            {
26                found_packed_ice = true;
27                break;
28            }
29        }
30
31        if !found_packed_ice {
32            return false;
33        }
34
35        let blue_ice = vanilla_blocks::BLUE_ICE.default_state();
36        let _ = region.set_block_state(origin, blue_ice, UpdateFlags::UPDATE_CLIENTS);
37
38        for _ in 0..200 {
39            let y_offset = random.next_i32_bounded(5) - random.next_i32_bounded(6);
40            let xz_diff = Self::blue_ice_xz_diff(y_offset);
41
42            if xz_diff < 1 {
43                continue;
44            }
45
46            let place_pos = origin.offset(
47                random.next_i32_bounded(xz_diff) - random.next_i32_bounded(xz_diff),
48                y_offset,
49                random.next_i32_bounded(xz_diff) - random.next_i32_bounded(xz_diff),
50            );
51            let place_state = region.block_state(place_pos);
52            if !place_state.is_air()
53                && !Self::is_water(place_state)
54                && place_state.get_block() != &vanilla_blocks::PACKED_ICE
55                && place_state.get_block() != &vanilla_blocks::ICE
56            {
57                continue;
58            }
59
60            for direction in Self::VANILLA_DIRECTION_VALUES {
61                if region
62                    .block_state(place_pos.relative(direction))
63                    .get_block()
64                    == &vanilla_blocks::BLUE_ICE
65                {
66                    let _ =
67                        region.set_block_state(place_pos, blue_ice, UpdateFlags::UPDATE_CLIENTS);
68                    break;
69                }
70            }
71        }
72
73        true
74    }
75
76    fn is_water(state: BlockStateId) -> bool {
77        state.get_block() == &vanilla_blocks::WATER
78    }
79
80    pub(in crate::worldgen::feature) const fn blue_ice_xz_diff(y_offset: i32) -> i32 {
81        let mut xz_diff = 3;
82        if y_offset < 2 {
83            xz_diff += y_offset / 2;
84        }
85        xz_diff
86    }
87}