Skip to main content

steel_core/worldgen/feature/features/
bamboo.rs

1use steel_registry::vanilla_block_tags::BlockTag;
2
3use super::super::prelude::*;
4use super::super::runner::FeatureDecorationRunner;
5
6impl FeatureDecorationRunner {
7    pub(in crate::worldgen::feature) fn place_bamboo_feature(
8        region: &mut WorldGenRegion<'_>,
9        random: &mut WorldgenRandom,
10        config: &BambooConfiguration,
11        origin: BlockPos,
12    ) -> bool {
13        let mut placed = 0;
14        let mut bamboo_pos = origin;
15
16        if region.block_state(bamboo_pos).is_air() {
17            let bamboo = vanilla_blocks::BAMBOO.default_state();
18            let behavior = BLOCK_BEHAVIORS.get_behavior(&vanilla_blocks::BAMBOO);
19            if behavior.can_survive(bamboo, region, bamboo_pos) {
20                let height = random.next_i32_bounded(12) + 5;
21                if random.next_f32() < config.probability {
22                    Self::place_bamboo_podzol_disc(region, random, origin);
23                }
24
25                let trunk = Self::bamboo_trunk_state();
26                for _ in 0..height {
27                    if !region.block_state(bamboo_pos).is_air() {
28                        break;
29                    }
30                    let _ = region.set_block_state(bamboo_pos, trunk, UpdateFlags::UPDATE_CLIENTS);
31                    bamboo_pos = bamboo_pos.above();
32                }
33
34                if bamboo_pos.y() - origin.y() >= 3 {
35                    let _ = region.set_block_state(
36                        bamboo_pos,
37                        Self::bamboo_final_large_state(),
38                        UpdateFlags::UPDATE_CLIENTS,
39                    );
40                    bamboo_pos = bamboo_pos.below();
41                    let _ = region.set_block_state(
42                        bamboo_pos,
43                        Self::bamboo_top_large_state(),
44                        UpdateFlags::UPDATE_CLIENTS,
45                    );
46                    bamboo_pos = bamboo_pos.below();
47                    let _ = region.set_block_state(
48                        bamboo_pos,
49                        Self::bamboo_top_small_state(),
50                        UpdateFlags::UPDATE_CLIENTS,
51                    );
52                }
53            }
54
55            placed += 1;
56        }
57
58        placed > 0
59    }
60
61    fn place_bamboo_podzol_disc(
62        region: &mut WorldGenRegion<'_>,
63        random: &mut WorldgenRandom,
64        origin: BlockPos,
65    ) {
66        let radius = random.next_i32_bounded(4) + 1;
67        for x in origin.x() - radius..=origin.x() + radius {
68            for z in origin.z() - radius..=origin.z() + radius {
69                let dx = x - origin.x();
70                let dz = z - origin.z();
71                if dx * dx + dz * dz > radius * radius {
72                    continue;
73                }
74
75                let y = region.height_at(HeightmapType::WorldSurface, x, z) - 1;
76                let pos = BlockPos::new(x, y, z);
77                let state = region.block_state(pos);
78                if state
79                    .get_block()
80                    .has_tag(&BlockTag::BENEATH_BAMBOO_PODZOL_REPLACEABLE)
81                {
82                    let _ = region.set_block_state(
83                        pos,
84                        vanilla_blocks::PODZOL.default_state(),
85                        UpdateFlags::UPDATE_CLIENTS,
86                    );
87                }
88            }
89        }
90    }
91
92    fn bamboo_trunk_state() -> BlockStateId {
93        vanilla_blocks::BAMBOO
94            .default_state()
95            .set_value(&BlockStateProperties::AGE_1, 1)
96            .set_value(&BlockStateProperties::BAMBOO_LEAVES, BambooLeaves::None)
97            .set_value(&BlockStateProperties::STAGE, 0)
98    }
99
100    fn bamboo_final_large_state() -> BlockStateId {
101        Self::bamboo_trunk_state()
102            .set_value(&BlockStateProperties::BAMBOO_LEAVES, BambooLeaves::Large)
103            .set_value(&BlockStateProperties::STAGE, 1)
104    }
105
106    fn bamboo_top_large_state() -> BlockStateId {
107        Self::bamboo_trunk_state()
108            .set_value(&BlockStateProperties::BAMBOO_LEAVES, BambooLeaves::Large)
109    }
110
111    fn bamboo_top_small_state() -> BlockStateId {
112        Self::bamboo_trunk_state()
113            .set_value(&BlockStateProperties::BAMBOO_LEAVES, BambooLeaves::Small)
114    }
115}