Skip to main content

steel_core/worldgen/feature/features/
spring.rs

1use super::super::prelude::*;
2use super::super::runner::FeatureDecorationRunner;
3
4impl FeatureDecorationRunner {
5    pub(in crate::worldgen::feature) fn place_spring_feature(
6        region: &mut WorldGenRegion<'_>,
7        registry: &Registry,
8        config: &SpringConfiguration,
9        origin: BlockPos,
10    ) -> bool {
11        if !Self::block_matches_holder_set(
12            region.block_state(origin.above()).get_block(),
13            &config.valid_blocks,
14        ) {
15            return false;
16        }
17
18        if config.requires_block_below
19            && !Self::block_matches_holder_set(
20                region.block_state(origin.below()).get_block(),
21                &config.valid_blocks,
22            )
23        {
24            return false;
25        }
26
27        let current_state = region.block_state(origin);
28        if !current_state.is_air()
29            && !Self::block_matches_holder_set(current_state.get_block(), &config.valid_blocks)
30        {
31            return false;
32        }
33
34        let rock_count = [
35            origin.west(),
36            origin.east(),
37            origin.north(),
38            origin.south(),
39            origin.below(),
40        ]
41        .into_iter()
42        .filter(|&pos| {
43            Self::block_matches_holder_set(
44                region.block_state(pos).get_block(),
45                &config.valid_blocks,
46            )
47        })
48        .count();
49
50        let hole_count = [
51            origin.west(),
52            origin.east(),
53            origin.north(),
54            origin.south(),
55            origin.below(),
56        ]
57        .into_iter()
58        .filter(|&pos| region.block_state(pos).is_air())
59        .count();
60
61        let Ok(expected_rock_count) = usize::try_from(config.rock_count) else {
62            panic!(
63                "spring feature rock_count {} is negative",
64                config.rock_count
65            );
66        };
67        let Ok(expected_hole_count) = usize::try_from(config.hole_count) else {
68            panic!(
69                "spring feature hole_count {} is negative",
70                config.hole_count
71            );
72        };
73
74        if rock_count != expected_rock_count || hole_count != expected_hole_count {
75            return false;
76        }
77
78        let fluid_state = Self::fluid_state_from_data(&config.state);
79        let block_state = Self::legacy_block_from_fluid_state(registry, fluid_state);
80        let placed = region.set_block_state(origin, block_state, UpdateFlags::UPDATE_CLIENTS);
81        if placed {
82            let _ = region.schedule_fluid_tick_default(origin, fluid_state.fluid_id, 0);
83        }
84        placed
85    }
86}