steel_core/worldgen/structure/piece_placer/
pool_element.rs1use steel_registry::structure::LiquidSettingsData;
2use steel_registry::structure_processor::StructureProcessorKind;
3use steel_registry::template_pool::{PoolElement, ProcessorList, Projection};
4use steel_registry::{Registry, RegistryExt};
5use steel_utils::random::worldgen_random::WorldgenRandom;
6use steel_utils::{BlockPos, BoundingBox, Identifier, Rotation};
7
8use crate::worldgen::feature::FeatureDecorationRunner;
9use crate::worldgen::region::WorldGenRegion;
10use crate::worldgen::template::{
11 StructurePlaceSettings, StructureProcessorRandom, StructureTemplate,
12};
13use steel_worldgen::structure::{StructureBlockIgnore, StructureMirror};
14
15use super::StructurePiecePlacer;
16
17impl StructurePiecePlacer {
18 #[expect(
19 clippy::too_many_arguments,
20 reason = "mirrors StructurePoolElement.place inputs"
21 )]
22 pub(super) fn place_pool_element(
23 region: &mut WorldGenRegion<'_>,
24 registry: &Registry,
25 element: &PoolElement,
26 position: BlockPos,
27 reference_pos: BlockPos,
28 rotation: Rotation,
29 clip: BoundingBox,
30 random: &mut WorldgenRandom,
31 liquid_settings: LiquidSettingsData,
32 biome_zoom_seed: i64,
33 ) -> bool {
34 match element {
35 PoolElement::Single {
36 location,
37 processors,
38 projection,
39 } => Self::place_single_pool_element(
40 region,
41 registry,
42 location,
43 processors,
44 *projection,
45 StructureBlockIgnore::StructureBlock,
46 StructureBlockIgnore::None,
47 position,
48 reference_pos,
49 rotation,
50 clip,
51 random,
52 liquid_settings,
53 ),
54 PoolElement::LegacySingle {
55 location,
56 processors,
57 projection,
58 } => Self::place_single_pool_element(
59 region,
60 registry,
61 location,
62 processors,
63 *projection,
64 StructureBlockIgnore::None,
65 StructureBlockIgnore::StructureAndAir,
66 position,
67 reference_pos,
68 rotation,
69 clip,
70 random,
71 liquid_settings,
72 ),
73 PoolElement::Empty => true,
74 PoolElement::Feature { feature, .. } => {
75 FeatureDecorationRunner::place_structure_pool_feature(
76 region,
77 registry,
78 random,
79 position,
80 feature,
81 biome_zoom_seed,
82 )
83 }
84 PoolElement::List { elements, .. } => {
85 for element in elements {
86 if !Self::place_pool_element(
87 region,
88 registry,
89 element,
90 position,
91 reference_pos,
92 rotation,
93 clip,
94 random,
95 liquid_settings,
96 biome_zoom_seed,
97 ) {
98 return false;
99 }
100 }
101 true
102 }
103 }
104 }
105
106 #[expect(
107 clippy::too_many_arguments,
108 reason = "mirrors SinglePoolElement.place and StructureTemplate.placeInWorld"
109 )]
110 fn place_single_pool_element(
111 region: &mut WorldGenRegion<'_>,
112 registry: &Registry,
113 location: &Identifier,
114 processors: &ProcessorList,
115 projection: Projection,
116 block_ignore: StructureBlockIgnore,
117 late_block_ignore: StructureBlockIgnore,
118 position: BlockPos,
119 reference_pos: BlockPos,
120 rotation: Rotation,
121 clip: BoundingBox,
122 random: &mut WorldgenRandom,
123 liquid_settings: LiquidSettingsData,
124 ) -> bool {
125 let template = match StructureTemplate::load_vanilla(registry, location) {
126 Ok(template) => template,
127 Err(err) => panic!("{err}"),
128 };
129 let processor_list = Self::pool_processors(registry, processors);
130 let settings = StructurePlaceSettings {
131 mirror: StructureMirror::None,
132 rotation,
133 rotation_pivot: BlockPos::ZERO,
134 bounding_box: clip,
135 processors: processor_list,
136 block_ignore,
137 late_block_ignore,
138 replace_jigsaws: true,
139 projection: Some(projection),
140 processor_random: StructureProcessorRandom::Positional,
141 liquid_settings,
142 };
143
144 template.place_in_world(
145 region,
146 registry,
147 position,
148 reference_pos,
149 &settings,
150 random,
151 Self::JIGSAW_UPDATE_FLAGS,
152 )
153 }
154
155 fn pool_processors<'a>(
156 registry: &'a Registry,
157 processors: &'a ProcessorList,
158 ) -> &'a [StructureProcessorKind] {
159 match processors {
160 ProcessorList::Empty => &[],
161 ProcessorList::Registry(key) => {
162 let Some(processor_list) = registry.structure_processors.by_key(key) else {
163 panic!("template pool references unknown processor list {key}");
164 };
165 &processor_list.data.processors
166 }
167 }
168 }
169}