Skip to main content

steel_worldgen/structure/mansion/
mod.rs

1//! Woodland mansion. Vanilla's `WoodlandMansionPieces`: grid-based layout with
2//! template pieces for walls, corridors, rooms, and roofs.
3
4use glam::IVec3;
5use steel_registry::structure::{LiquidSettingsData, StructureData};
6use steel_utils::random::Random;
7use steel_utils::random::legacy_random::LegacyRandom;
8use steel_utils::{BoundingBox, Direction, Identifier, Rotation};
9
10use crate::structure::{
11    GenerationStub, Structure, StructureBlockIgnore, StructureGenerationContext, StructureMirror,
12    StructurePiece, StructurePiecePayload, TemplateMarkerHandling, TemplatePieceData,
13    TemplatePlacementAdjustment, TemplatePlacementClip, TemplatePostProcess, TemplateProcessorList,
14};
15
16mod grid;
17mod placement;
18mod roof;
19mod rooms;
20mod template;
21mod walls;
22
23#[cfg(test)]
24mod tests;
25
26use placement::generate_mansion_pieces;
27use template::MansionTemplatePiece;
28
29/// `Structure` impl — registered under `"minecraft:woodland_mansion"`.
30///
31/// Vanilla's `WoodlandMansionStructure.findGenerationPoint`: consumes a
32/// rotation, probes a rotation-dependent 5×5 box for the lowest Y, rejects
33/// if `< 60`, then runs `generate_mansion_pieces`.
34pub struct WoodlandMansionStructure;
35
36impl Structure for WoodlandMansionStructure {
37    fn find_generation_point(
38        &self,
39        ctx: &mut dyn StructureGenerationContext,
40        structure: &StructureData,
41        rng: &mut LegacyRandom,
42    ) -> Option<GenerationStub> {
43        let rotation = Rotation::get_random(rng);
44
45        let (off_x, off_z) = match rotation {
46            Rotation::None => (5, 5),
47            Rotation::Clockwise90 => (-5, 5),
48            Rotation::Clockwise180 => (-5, -5),
49            Rotation::CounterClockwise90 => (5, -5),
50        };
51        let bx = ctx.chunk_min_x() + 7;
52        let bz = ctx.chunk_min_z() + 7;
53        let h0 = ctx.base_height(bx, bz, false);
54        let h1 = ctx.base_height(bx, bz + off_z, false);
55        let h2 = ctx.base_height(bx + off_x, bz, false);
56        let h3 = ctx.base_height(bx + off_x, bz + off_z, false);
57        let lowest = h0.min(h1).min(h2).min(h3);
58        if lowest < 60 {
59            return None;
60        }
61
62        let biome = ctx.biome_at(bx, lowest, bz);
63        if !structure.allowed_biomes.contains(&biome.key) {
64            return None;
65        }
66
67        let origin = IVec3::new(bx, lowest, bz);
68        let pieces = generate_mansion_pieces(origin, rotation, rng)
69            .into_iter()
70            .map(MansionTemplatePiece::into_structure_piece)
71            .collect();
72
73        Some(GenerationStub {
74            position: (origin.x, origin.y, origin.z),
75            pieces,
76        })
77    }
78}