steel_core/worldgen/feature/features/
spring.rs1use 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}