Skip to main content

steel_registry/feature/
data.rs

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