1use super::{ConfiguredFeatureEntryRef, PlacedFeatureEntryRef};
9use crate::blocks::BlockRef;
10use crate::fluid::FluidRef;
11use glam::IVec3;
12use steel_utils::{
13 Direction, Identifier, Rotation,
14 value_providers::{FloatProvider, HeightProvider, IntProvider, UniformIntProvider},
15};
16
17#[derive(Debug, Clone)]
19pub enum ConfiguredFeatureRef {
20 Reference(ConfiguredFeatureEntryRef),
22 Inline(Box<ConfiguredFeatureKind>),
24}
25
26#[derive(Debug, Clone)]
28pub enum PlacedFeatureRef {
29 Reference(PlacedFeatureEntryRef),
31 Inline(Box<PlacedFeatureData>),
33}
34
35#[derive(Debug, Clone)]
37pub struct PlacedFeatureData {
38 pub feature: ConfiguredFeatureRef,
40 pub placement: Vec<PlacementModifier>,
42}
43
44#[derive(Debug, Clone)]
46#[expect(
47 clippy::large_enum_variant,
48 reason = "typed feature configs are registry data moved by reference; boxing individual variants would add noise before placement implementations use them"
49)]
50pub enum ConfiguredFeatureKind {
51 Bamboo(BambooConfiguration),
52 BasaltColumns(BasaltColumnsConfiguration),
53 BasaltPillar,
54 BlockBlob(BlockBlobConfiguration),
55 BlockColumn(BlockColumnConfiguration),
56 BlockPile(BlockPileConfiguration),
57 BlueIce,
58 BonusChest,
59 ChorusPlant,
60 CoralClaw,
61 CoralMushroom,
62 CoralTree,
63 DeltaFeature(DeltaFeatureConfiguration),
64 DesertWell,
65 Disk(DiskConfiguration),
66 DripstoneCluster(DripstoneClusterConfiguration),
67 EndGateway(EndGatewayConfiguration),
68 EndIsland,
69 EndPlatform,
70 EndSpike(EndSpikeConfiguration),
71 FallenTree(FallenTreeConfiguration),
72 Fossil(FossilConfiguration),
73 FreezeTopLayer,
74 Geode(GeodeConfiguration),
75 GlowstoneBlob,
76 HugeBrownMushroom(HugeMushroomConfiguration),
77 HugeFungus(HugeFungusConfiguration),
78 HugeRedMushroom(HugeMushroomConfiguration),
79 Iceberg(BlockStateData),
80 Kelp,
81 Lake(LakeConfiguration),
82 LargeDripstone(LargeDripstoneConfiguration),
83 MonsterRoom,
84 MultifaceGrowth(MultifaceGrowthConfiguration),
85 NetherForestVegetation(NetherForestVegetationConfiguration),
86 NetherrackReplaceBlobs(NetherrackReplaceBlobsConfiguration),
87 Ore(OreConfiguration),
88 PointedDripstone(PointedDripstoneConfiguration),
89 RandomBooleanSelector(RandomBooleanSelectorConfiguration),
90 RandomSelector(RandomSelectorConfiguration),
91 RootSystem(RootSystemConfiguration),
92 ScatteredOre(OreConfiguration),
93 SculkPatch(SculkPatchConfiguration),
94 SeaPickle(SeaPickleConfiguration),
95 Seagrass(SeagrassConfiguration),
96 Sequence(CompositeFeatureConfiguration),
97 SimpleBlock(SimpleBlockConfiguration),
98 SimpleRandomSelector(SimpleRandomSelectorConfiguration),
99 Speleothem(SpeleothemConfiguration),
100 SpeleothemCluster(SpeleothemClusterConfiguration),
101 Spike(SpikeConfiguration),
102 SpringFeature(SpringConfiguration),
103 Template(TemplateFeatureConfiguration),
104 Tree(TreeConfiguration),
105 TwistingVines(TwistingVinesConfiguration),
106 UnderwaterMagma(UnderwaterMagmaConfiguration),
107 VegetationPatch(VegetationPatchConfiguration),
108 Vines,
109 VoidStartPlatform,
110 WaterloggedVegetationPatch(VegetationPatchConfiguration),
111 WeightedRandomSelector(WeightedRandomFeatureConfiguration),
112 WeepingVines,
113}
114
115#[derive(Debug, Clone)]
117pub struct BlockRefList(pub Vec<BlockRef>);
118
119#[derive(Debug, Clone)]
121pub struct FluidRefList(pub Vec<FluidRef>);
122
123#[derive(Debug, Clone)]
125pub enum BlockHolderSet {
126 Tag(Identifier),
127 Entries(Vec<BlockRef>),
128}
129
130#[derive(Debug, Clone)]
132pub struct BlockStateData {
133 pub block: BlockRef,
135 pub properties: &'static [(&'static str, &'static str)],
137}
138
139#[derive(Debug, Clone)]
141pub struct FluidStateData {
142 pub fluid: FluidRef,
144 pub properties: &'static [(&'static str, &'static str)],
146}
147
148pub type Offset = IVec3;
150
151#[derive(Debug, Clone)]
153pub enum BlockPredicate {
154 True,
155 AllOf {
156 predicates: Vec<BlockPredicate>,
157 },
158 AnyOf {
159 predicates: Vec<BlockPredicate>,
160 },
161 Not {
162 predicate: Box<BlockPredicate>,
163 },
164 MatchingBlockTag {
165 tag: Identifier,
166 offset: Offset,
167 },
168 MatchingBlocks {
169 blocks: BlockRefList,
170 offset: Offset,
171 },
172 MatchingFluids {
173 fluids: FluidRefList,
174 offset: Offset,
175 },
176 Solid {
177 offset: Offset,
178 },
179 WouldSurvive {
180 state: BlockStateData,
181 offset: Offset,
182 },
183 Replaceable {
184 offset: Offset,
185 },
186 HasSturdyFace {
187 direction: Direction,
188 offset: Offset,
189 },
190 InsideWorldBounds {
191 offset: Offset,
192 },
193}
194
195#[derive(Debug, Clone)]
197pub enum BlockStateProvider {
198 Simple {
199 state: BlockStateData,
200 },
201 Weighted {
202 entries: Vec<WeightedBlockState>,
203 },
204 RotatedBlock {
205 state: BlockStateData,
206 },
207 RandomizedInt {
208 property: String,
209 source: Box<BlockStateProvider>,
210 values: IntProvider,
211 },
212 RuleBased {
213 fallback: Option<Box<BlockStateProvider>>,
214 rules: Vec<RuleBasedStateProviderRule>,
215 },
216 Noise(NoiseProvider),
217 NoiseThreshold(NoiseThresholdProvider),
218 DualNoise(DualNoiseProvider),
219}
220
221#[derive(Debug, Clone)]
223pub struct WeightedBlockState {
224 pub data: BlockStateData,
225 pub weight: i32,
226}
227
228#[derive(Debug, Clone)]
230pub struct RuleBasedStateProviderRule {
231 pub if_true: BlockPredicate,
232 pub then: BlockStateProvider,
233}
234
235#[derive(Debug, Clone)]
237pub struct FeatureNoiseParameters {
238 pub first_octave: i32,
239 pub amplitudes: Vec<f64>,
240}
241
242#[derive(Debug, Clone)]
243pub struct NoiseProvider {
244 pub noise: FeatureNoiseParameters,
245 pub scale: f32,
246 pub seed: i64,
247 pub states: Vec<BlockStateData>,
248}
249
250#[derive(Debug, Clone)]
251pub struct NoiseThresholdProvider {
252 pub noise: FeatureNoiseParameters,
253 pub scale: f32,
254 pub seed: i64,
255 pub threshold: f32,
256 pub high_chance: f32,
257 pub default_state: BlockStateData,
258 pub low_states: Vec<BlockStateData>,
259 pub high_states: Vec<BlockStateData>,
260}
261
262#[derive(Debug, Clone)]
263pub struct DualNoiseProvider {
264 pub noise: FeatureNoiseParameters,
265 pub scale: f32,
266 pub seed: i64,
267 pub slow_noise: FeatureNoiseParameters,
268 pub slow_scale: f32,
269 pub states: Vec<BlockStateData>,
270 pub variety: [i32; 2],
271}
272
273#[derive(Debug, Clone)]
275pub enum PlacementModifier {
276 Biome,
277 BlockPredicateFilter {
278 predicate: BlockPredicate,
279 },
280 Count {
281 count: IntProvider,
282 },
283 CountOnEveryLayer {
284 count: IntProvider,
285 },
286 EnvironmentScan {
287 direction_of_search: Direction,
288 target_condition: BlockPredicate,
289 allowed_search_condition: Option<BlockPredicate>,
290 max_steps: i32,
291 },
292 FixedPlacement {
293 positions: Vec<Offset>,
294 },
295 HeightRange {
296 height: HeightProvider,
297 },
298 Heightmap {
299 heightmap: FeatureHeightmap,
300 },
301 InSquare,
302 NoiseBasedCount {
303 noise_to_count_ratio: i32,
304 noise_factor: f64,
305 noise_offset: f64,
306 },
307 NoiseThresholdCount {
308 noise_level: f64,
309 below_noise: i32,
310 above_noise: i32,
311 },
312 RandomOffset {
313 xz_spread: IntProvider,
314 y_spread: IntProvider,
315 },
316 RarityFilter {
317 chance: i32,
318 },
319 SurfaceRelativeThresholdFilter {
320 heightmap: FeatureHeightmap,
321 min_inclusive: Option<i32>,
322 max_inclusive: Option<i32>,
323 },
324 SurfaceWaterDepthFilter {
325 max_water_depth: i32,
326 },
327}
328
329#[derive(Debug, Clone, Copy, PartialEq, Eq)]
331pub enum FeatureHeightmap {
332 WorldSurface,
333 MotionBlocking,
334 MotionBlockingNoLeaves,
335 OceanFloor,
336 WorldSurfaceWg,
337 OceanFloorWg,
338}
339
340#[derive(Debug, Clone)]
341pub struct BambooConfiguration {
342 pub probability: f32,
343}
344
345#[derive(Debug, Clone)]
346pub struct BasaltColumnsConfiguration {
347 pub height: IntProvider,
348 pub reach: IntProvider,
349}
350
351#[derive(Debug, Clone)]
352pub struct BlockBlobConfiguration {
353 pub state: BlockStateData,
354 pub can_place_on: BlockPredicate,
355}
356
357#[derive(Debug, Clone)]
358pub struct BlockColumnConfiguration {
359 pub direction: Direction,
360 pub allowed_placement: BlockPredicate,
361 pub layers: Vec<BlockColumnLayer>,
362 pub prioritize_tip: bool,
363}
364
365#[derive(Debug, Clone)]
366pub struct BlockColumnLayer {
367 pub height: IntProvider,
368 pub provider: BlockStateProvider,
369}
370
371#[derive(Debug, Clone)]
372pub struct BlockPileConfiguration {
373 pub state_provider: BlockStateProvider,
374}
375
376#[derive(Debug, Clone)]
377pub struct DeltaFeatureConfiguration {
378 pub contents: BlockStateData,
379 pub rim: BlockStateData,
380 pub size: IntProvider,
381 pub rim_size: IntProvider,
382}
383
384#[derive(Debug, Clone)]
385pub struct DiskConfiguration {
386 pub state_provider: BlockStateProvider,
387 pub target: BlockPredicate,
388 pub radius: IntProvider,
389 pub half_height: i32,
390}
391
392#[derive(Debug, Clone)]
393pub struct DripstoneClusterConfiguration {
394 pub floor_to_ceiling_search_range: i32,
395 pub height: IntProvider,
396 pub radius: IntProvider,
397 pub max_stalagmite_stalactite_height_diff: i32,
398 pub height_deviation: i32,
399 pub dripstone_block_layer_thickness: IntProvider,
400 pub density: FloatProvider,
401 pub wetness: FloatProvider,
402 pub chance_of_dripstone_column_at_max_distance_from_center: f32,
403 pub max_distance_from_center_affecting_height_bias: i32,
404 pub max_distance_from_edge_affecting_chance_of_dripstone_column: i32,
405}
406
407#[derive(Debug, Clone)]
408pub struct SpeleothemClusterConfiguration {
409 pub base_block: BlockStateData,
410 pub pointed_block: BlockStateData,
411 pub replaceable_blocks: BlockHolderSet,
412 pub floor_to_ceiling_search_range: i32,
413 pub height: IntProvider,
414 pub radius: IntProvider,
415 pub max_stalagmite_stalactite_height_diff: i32,
416 pub height_deviation: i32,
417 pub speleothem_block_layer_thickness: IntProvider,
418 pub density: FloatProvider,
419 pub wetness: FloatProvider,
420 pub chance_of_speleothem_at_max_distance_from_center: f32,
421 pub max_distance_from_edge_affecting_chance_of_speleothem: i32,
422 pub max_distance_from_center_affecting_height_bias: i32,
423}
424
425#[derive(Debug, Clone)]
426pub struct SpeleothemConfiguration {
427 pub base_block: BlockStateData,
428 pub pointed_block: BlockStateData,
429 pub replaceable_blocks: BlockHolderSet,
430 pub chance_of_taller_generation: f32,
431 pub chance_of_directional_spread: f32,
432 pub chance_of_spread_radius2: f32,
433 pub chance_of_spread_radius3: f32,
434}
435
436#[derive(Debug, Clone)]
437pub struct EndGatewayConfiguration {
438 pub exit: Option<Offset>,
439 pub exact: bool,
440}
441
442#[derive(Debug, Clone)]
443pub struct EndSpikeConfiguration {
444 pub spikes: Vec<EndSpike>,
445 pub crystal_invulnerable: bool,
446 pub crystal_beam_target: Option<Offset>,
447}
448
449#[derive(Debug, Clone)]
450pub struct EndSpike {
451 pub center_x: i32,
452 pub center_z: i32,
453 pub radius: i32,
454 pub height: i32,
455 pub guarded: bool,
456}
457
458#[derive(Debug, Clone)]
459pub struct FallenTreeConfiguration {
460 pub trunk_provider: BlockStateProvider,
461 pub log_length: IntProvider,
462 pub stump_decorators: Vec<TreeDecorator>,
463 pub log_decorators: Vec<TreeDecorator>,
464}
465
466#[derive(Debug, Clone)]
467pub struct FossilConfiguration {
468 pub fossil_structures: Vec<Identifier>,
469 pub overlay_structures: Vec<Identifier>,
470 pub fossil_processors: Identifier,
471 pub overlay_processors: Identifier,
472 pub max_empty_corners_allowed: i32,
473}
474
475#[derive(Debug, Clone)]
476pub struct GeodeConfiguration {
477 pub blocks: GeodeBlockSettings,
478 pub layers: GeodeLayerSettings,
479 pub crack: GeodeCrackSettings,
480 pub use_potential_placements_chance: f64,
481 pub use_alternate_layer0_chance: f64,
482 pub placements_require_layer0_alternate: bool,
483 pub outer_wall_distance: IntProvider,
484 pub distribution_points: IntProvider,
485 pub point_offset: IntProvider,
486 pub min_gen_offset: i32,
487 pub max_gen_offset: i32,
488 pub invalid_blocks_threshold: i32,
489 pub noise_multiplier: f64,
490}
491
492#[derive(Debug, Clone)]
493pub struct GeodeBlockSettings {
494 pub filling_provider: BlockStateProvider,
495 pub inner_layer_provider: BlockStateProvider,
496 pub alternate_inner_layer_provider: BlockStateProvider,
497 pub middle_layer_provider: BlockStateProvider,
498 pub outer_layer_provider: BlockStateProvider,
499 pub inner_placements: Vec<BlockStateData>,
500 pub cannot_replace: Identifier,
501 pub invalid_blocks: Identifier,
502}
503
504#[derive(Debug, Clone)]
505pub struct GeodeLayerSettings {
506 pub filling: f64,
507 pub inner_layer: f64,
508 pub middle_layer: f64,
509 pub outer_layer: f64,
510}
511
512#[derive(Debug, Clone)]
513pub struct GeodeCrackSettings {
514 pub generate_crack_chance: f64,
515 pub base_crack_size: f64,
516 pub crack_point_offset: i32,
517}
518
519#[derive(Debug, Clone)]
520pub struct HugeMushroomConfiguration {
521 pub cap_provider: BlockStateProvider,
522 pub stem_provider: BlockStateProvider,
523 pub foliage_radius: i32,
524 pub can_place_on: BlockPredicate,
525}
526
527#[derive(Debug, Clone)]
528pub struct HugeFungusConfiguration {
529 pub valid_base_block: BlockStateData,
530 pub stem_state: BlockStateData,
531 pub hat_state: BlockStateData,
532 pub decor_state: BlockStateData,
533 pub replaceable_blocks: BlockPredicate,
534 pub planted: bool,
535}
536
537#[derive(Debug, Clone)]
538pub struct LakeConfiguration {
539 pub fluid: BlockStateProvider,
540 pub barrier: BlockStateProvider,
541 pub can_place_feature: BlockPredicate,
542 pub can_replace_with_air_or_fluid: BlockPredicate,
543 pub can_replace_with_barrier: BlockPredicate,
544}
545
546#[derive(Debug, Clone)]
547pub struct LargeDripstoneConfiguration {
548 pub replaceable_blocks: BlockHolderSet,
549 pub floor_to_ceiling_search_range: i32,
550 pub column_radius: IntProvider,
551 pub height_scale: FloatProvider,
552 pub max_column_radius_to_cave_height_ratio: f32,
553 pub stalactite_bluntness: FloatProvider,
554 pub stalagmite_bluntness: FloatProvider,
555 pub wind_speed: FloatProvider,
556 pub min_radius_for_wind: i32,
557 pub min_bluntness_for_wind: f32,
558}
559
560#[derive(Debug, Clone)]
561pub struct MultifaceGrowthConfiguration {
562 pub block: BlockRef,
563 pub search_range: i32,
564 pub can_place_on_floor: bool,
565 pub can_place_on_ceiling: bool,
566 pub can_place_on_wall: bool,
567 pub chance_of_spreading: f32,
568 pub can_be_placed_on: Vec<BlockRef>,
569}
570
571#[derive(Debug, Clone)]
572pub struct NetherForestVegetationConfiguration {
573 pub state_provider: BlockStateProvider,
574 pub spread_width: i32,
575 pub spread_height: i32,
576}
577
578#[derive(Debug, Clone)]
579pub struct NetherrackReplaceBlobsConfiguration {
580 pub target: BlockStateData,
581 pub state: BlockStateData,
582 pub radius: IntProvider,
583}
584
585#[derive(Debug, Clone)]
586pub struct OreConfiguration {
587 pub targets: Vec<OreTarget>,
588 pub size: i32,
589 pub discard_chance_on_air_exposure: f32,
590}
591
592#[derive(Debug, Clone)]
593pub struct OreTarget {
594 pub target: RuleTest,
595 pub state: BlockStateData,
596}
597
598#[derive(Debug, Clone)]
599pub enum RuleTest {
600 BlockMatch { block: BlockRef },
601 TagMatch { tag: Identifier },
602}
603
604#[derive(Debug, Clone)]
605pub struct PointedDripstoneConfiguration {
606 pub chance_of_taller_dripstone: f32,
607 pub chance_of_directional_spread: f32,
608 pub chance_of_spread_radius2: f32,
609 pub chance_of_spread_radius3: f32,
610}
611
612#[derive(Debug, Clone)]
613pub struct RandomBooleanSelectorConfiguration {
614 pub feature_true: PlacedFeatureRef,
615 pub feature_false: PlacedFeatureRef,
616}
617
618#[derive(Debug, Clone)]
619pub struct RandomSelectorConfiguration {
620 pub features: Vec<WeightedPlacedFeature>,
621 pub default: PlacedFeatureRef,
622}
623
624#[derive(Debug, Clone)]
625pub struct WeightedPlacedFeature {
626 pub chance: f32,
627 pub feature: PlacedFeatureRef,
628}
629
630#[derive(Debug, Clone)]
631pub struct WeightedRandomFeatureConfiguration {
632 pub features: Vec<WeightedRandomPlacedFeature>,
633}
634
635#[derive(Debug, Clone)]
636pub struct WeightedRandomPlacedFeature {
637 pub data: PlacedFeatureRef,
638 pub weight: u32,
639}
640
641#[derive(Debug, Clone)]
642pub struct SimpleRandomSelectorConfiguration {
643 pub features: Vec<PlacedFeatureRef>,
644}
645
646#[derive(Debug, Clone)]
647pub struct CompositeFeatureConfiguration {
648 pub features: Vec<PlacedFeatureRef>,
649}
650
651#[derive(Debug, Clone)]
652pub struct RootSystemConfiguration {
653 pub feature: PlacedFeatureRef,
654 pub required_vertical_space_for_tree: i32,
655 pub level_test_distance: i32,
656 pub max_level_deviation: i32,
657 pub root_radius: i32,
658 pub root_placement_attempts: i32,
659 pub root_column_max_height: i32,
660 pub hanging_root_radius: i32,
661 pub hanging_roots_vertical_span: i32,
662 pub hanging_root_placement_attempts: i32,
663 pub allowed_vertical_water_for_tree: i32,
664 pub root_state_provider: BlockStateProvider,
665 pub hanging_root_state_provider: BlockStateProvider,
666 pub root_replaceable: BlockHolderSet,
667 pub allowed_tree_position: BlockPredicate,
668}
669
670#[derive(Debug, Clone)]
671pub struct SculkPatchConfiguration {
672 pub charge_count: i32,
673 pub amount_per_charge: i32,
674 pub spread_attempts: i32,
675 pub growth_rounds: i32,
676 pub spread_rounds: i32,
677 pub extra_rare_growths: IntProvider,
678 pub catalyst_chance: f32,
679}
680
681#[derive(Debug, Clone)]
682pub struct SeaPickleConfiguration {
683 pub count: IntProvider,
684}
685
686#[derive(Debug, Clone)]
687pub struct SeagrassConfiguration {
688 pub probability: f32,
689}
690
691#[derive(Debug, Clone)]
692pub struct SimpleBlockConfiguration {
693 pub to_place: BlockStateProvider,
694 pub schedule_tick: bool,
695}
696
697#[derive(Debug, Clone)]
698pub struct SpikeConfiguration {
699 pub state: BlockStateData,
700 pub can_place_on: BlockPredicate,
701 pub can_replace: BlockPredicate,
702}
703
704#[derive(Debug, Clone)]
705pub struct SpringConfiguration {
706 pub state: FluidStateData,
707 pub requires_block_below: bool,
708 pub rock_count: i32,
709 pub hole_count: i32,
710 pub valid_blocks: BlockHolderSet,
711}
712
713#[derive(Debug, Clone)]
714pub struct TemplateFeatureConfiguration {
715 pub templates: Vec<WeightedTemplateEntry>,
716}
717
718#[derive(Debug, Clone)]
719pub struct WeightedTemplateEntry {
720 pub data: TemplateEntry,
721 pub weight: u32,
722}
723
724#[derive(Debug, Clone)]
725pub struct TemplateEntry {
726 pub id: Identifier,
727 pub rotations: Vec<Rotation>,
728}
729
730#[derive(Debug, Clone)]
731pub struct TreeConfiguration {
732 pub trunk_provider: BlockStateProvider,
733 pub below_trunk_provider: BlockStateProvider,
734 pub foliage_provider: BlockStateProvider,
735 pub trunk_placer: TrunkPlacer,
736 pub foliage_placer: FoliagePlacer,
737 pub minimum_size: FeatureSize,
738 pub decorators: Vec<TreeDecorator>,
739 pub root_placer: Option<RootPlacer>,
740 pub ignore_vines: bool,
741}
742
743#[derive(Debug, Clone)]
744pub enum TrunkPlacer {
745 Straight(TrunkPlacerBase),
746 Giant(TrunkPlacerBase),
747 Fancy(TrunkPlacerBase),
748 Forking(TrunkPlacerBase),
749 DarkOak(TrunkPlacerBase),
750 MegaJungle(TrunkPlacerBase),
751 Bending(BendingTrunkPlacer),
752 UpwardsBranching(UpwardsBranchingTrunkPlacer),
753 Cherry(CherryTrunkPlacer),
754}
755
756#[derive(Debug, Clone)]
757pub struct TrunkPlacerBase {
758 pub base_height: i32,
759 pub height_rand_a: i32,
760 pub height_rand_b: i32,
761}
762
763#[derive(Debug, Clone)]
764pub struct BendingTrunkPlacer {
765 pub base_height: i32,
766 pub height_rand_a: i32,
767 pub height_rand_b: i32,
768 pub min_height_for_leaves: i32,
769 pub bend_length: IntProvider,
770}
771
772#[derive(Debug, Clone)]
773pub struct UpwardsBranchingTrunkPlacer {
774 pub base_height: i32,
775 pub height_rand_a: i32,
776 pub height_rand_b: i32,
777 pub extra_branch_steps: IntProvider,
778 pub extra_branch_length: IntProvider,
779 pub place_branch_per_log_probability: f32,
780 pub can_grow_through: Identifier,
781}
782
783#[derive(Debug, Clone)]
784pub struct CherryTrunkPlacer {
785 pub base_height: i32,
786 pub height_rand_a: i32,
787 pub height_rand_b: i32,
788 pub branch_count: IntProvider,
789 pub branch_horizontal_length: IntProvider,
790 pub branch_start_offset_from_top: UniformIntProvider,
791 pub branch_end_offset_from_top: IntProvider,
792}
793
794#[derive(Debug, Clone)]
795pub enum FoliagePlacer {
796 Blob(BlobFoliagePlacer),
797 Spruce(SpruceFoliagePlacer),
798 Pine(PineFoliagePlacer),
799 Acacia(FoliagePlacerBase),
800 Bush(BlobFoliagePlacer),
801 Fancy(BlobFoliagePlacer),
802 Jungle(BlobFoliagePlacer),
803 MegaPine(MegaPineFoliagePlacer),
804 DarkOak(FoliagePlacerBase),
805 RandomSpread(RandomSpreadFoliagePlacer),
806 Cherry(CherryFoliagePlacer),
807}
808
809#[derive(Debug, Clone)]
810pub struct FoliagePlacerBase {
811 pub radius: IntProvider,
812 pub offset: IntProvider,
813}
814
815#[derive(Debug, Clone)]
816pub struct BlobFoliagePlacer {
817 pub radius: IntProvider,
818 pub offset: IntProvider,
819 pub height: IntProvider,
820}
821
822#[derive(Debug, Clone)]
823pub struct SpruceFoliagePlacer {
824 pub radius: IntProvider,
825 pub offset: IntProvider,
826 pub trunk_height: IntProvider,
827}
828
829#[derive(Debug, Clone)]
830pub struct PineFoliagePlacer {
831 pub radius: IntProvider,
832 pub offset: IntProvider,
833 pub height: IntProvider,
834}
835
836#[derive(Debug, Clone)]
837pub struct MegaPineFoliagePlacer {
838 pub radius: IntProvider,
839 pub offset: IntProvider,
840 pub crown_height: IntProvider,
841}
842
843#[derive(Debug, Clone)]
844pub struct RandomSpreadFoliagePlacer {
845 pub radius: IntProvider,
846 pub offset: IntProvider,
847 pub foliage_height: i32,
848 pub leaf_placement_attempts: i32,
849}
850
851#[derive(Debug, Clone)]
852pub struct CherryFoliagePlacer {
853 pub radius: IntProvider,
854 pub offset: IntProvider,
855 pub height: IntProvider,
856 pub wide_bottom_layer_hole_chance: f32,
857 pub corner_hole_chance: f32,
858 pub hanging_leaves_chance: f32,
859 pub hanging_leaves_extension_chance: f32,
860}
861
862#[derive(Debug, Clone)]
863pub enum FeatureSize {
864 TwoLayers(TwoLayersFeatureSize),
865 ThreeLayers(ThreeLayersFeatureSize),
866}
867
868#[derive(Debug, Clone)]
869pub struct TwoLayersFeatureSize {
870 pub limit: i32,
871 pub lower_size: i32,
872 pub upper_size: i32,
873 pub min_clipped_height: Option<i32>,
874}
875
876#[derive(Debug, Clone)]
877pub struct ThreeLayersFeatureSize {
878 pub limit: i32,
879 pub lower_size: i32,
880 pub middle_size: i32,
881 pub upper_limit: i32,
882 pub upper_size: i32,
883 pub min_clipped_height: Option<i32>,
884}
885
886#[derive(Debug, Clone)]
887pub enum RootPlacer {
888 Mangrove(MangroveRootPlacer),
889}
890
891#[derive(Debug, Clone)]
892pub struct MangroveRootPlacer {
893 pub trunk_offset_y: IntProvider,
894 pub root_provider: BlockStateProvider,
895 pub above_root_placement: AboveRootPlacement,
896 pub mangrove_root_placement: MangroveRootPlacement,
897}
898
899#[derive(Debug, Clone)]
900pub struct AboveRootPlacement {
901 pub above_root_provider: BlockStateProvider,
902 pub above_root_placement_chance: f32,
903}
904
905#[derive(Debug, Clone)]
906pub struct MangroveRootPlacement {
907 pub can_grow_through: Identifier,
908 pub muddy_roots_in: Vec<Identifier>,
909 pub muddy_roots_provider: BlockStateProvider,
910 pub max_root_width: i32,
911 pub max_root_length: i32,
912 pub random_skew_chance: f32,
913}
914
915#[derive(Debug, Clone)]
916pub enum TreeDecorator {
917 AlterGround {
918 provider: BlockStateProvider,
919 },
920 Beehive {
921 probability: f32,
922 },
923 Cocoa {
924 probability: f32,
925 },
926 CreakingHeart {
927 probability: f32,
928 },
929 LeaveVine {
930 probability: f32,
931 },
932 TrunkVine,
933 AttachedToLeaves(AttachedToLeavesDecorator),
934 AttachedToLogs(AttachedToLogsDecorator),
935 PlaceOnGround(PlaceOnGroundDecorator),
936 PaleMoss {
937 leaves_probability: f32,
938 trunk_probability: f32,
939 ground_probability: f32,
940 },
941}
942
943#[derive(Debug, Clone)]
944pub struct AttachedToLeavesDecorator {
945 pub probability: f32,
946 pub exclusion_radius_xz: i32,
947 pub exclusion_radius_y: i32,
948 pub required_empty_blocks: i32,
949 pub block_provider: BlockStateProvider,
950 pub directions: Vec<Direction>,
951}
952
953#[derive(Debug, Clone)]
954pub struct AttachedToLogsDecorator {
955 pub probability: f32,
956 pub block_provider: BlockStateProvider,
957 pub directions: Vec<Direction>,
958}
959
960#[derive(Debug, Clone)]
961pub struct PlaceOnGroundDecorator {
962 pub block_state_provider: BlockStateProvider,
963 pub tries: i32,
964 pub radius: i32,
965 pub height: i32,
966}
967
968#[derive(Debug, Clone)]
969pub struct TwistingVinesConfiguration {
970 pub spread_width: i32,
971 pub spread_height: i32,
972 pub max_height: i32,
973}
974
975#[derive(Debug, Clone)]
976pub struct UnderwaterMagmaConfiguration {
977 pub floor_search_range: i32,
978 pub placement_radius_around_floor: i32,
979 pub placement_probability_per_valid_position: f32,
980}
981
982#[derive(Debug, Clone)]
983pub struct VegetationPatchConfiguration {
984 pub replaceable: Identifier,
985 pub ground_state: BlockStateProvider,
986 pub vegetation_feature: PlacedFeatureRef,
987 pub surface: VerticalSurface,
988 pub depth: IntProvider,
989 pub extra_bottom_block_chance: f32,
990 pub vertical_range: i32,
991 pub vegetation_chance: f32,
992 pub xz_radius: IntProvider,
993 pub extra_edge_column_chance: f32,
994}
995
996#[derive(Debug, Clone, Copy, PartialEq, Eq)]
998pub enum VerticalSurface {
999 Floor,
1000 Ceiling,
1001}