steel_worldgen/structure/
swamp_hut.rs1use steel_registry::structure::StructureData;
4use steel_utils::random::legacy_random::LegacyRandom;
5use steel_utils::{Direction, Identifier};
6
7use crate::structure::{
8 GenerationStub, ProceduralPieceData, Structure, StructureGenerationContext, StructurePiece,
9 StructurePiecePayload, make_oriented_piece_bounding_box, random_horizontal_direction,
10};
11
12pub(crate) const SWAMP_HUT_WIDTH: i32 = 7;
13pub(crate) const SWAMP_HUT_HEIGHT: i32 = 7;
14pub(crate) const SWAMP_HUT_DEPTH: i32 = 9;
15
16#[derive(Debug, Clone, Default)]
18pub struct SwampHutPieceData {
19 pub height_position: Option<i32>,
21 pub spawned_witch: bool,
23 pub spawned_cat: bool,
25}
26
27impl SwampHutPieceData {
28 #[must_use]
30 pub const fn new() -> Self {
31 Self {
32 height_position: None,
33 spawned_witch: false,
34 spawned_cat: false,
35 }
36 }
37}
38
39pub struct SwampHutStructure;
41
42const fn swamp_hut_piece(west: i32, north: i32, orientation: Direction) -> StructurePiece {
43 StructurePiece {
44 piece_type: Identifier::new_static("minecraft", "tesh"),
45 bounding_box: make_oriented_piece_bounding_box(
46 west,
47 64,
48 north,
49 orientation,
50 SWAMP_HUT_WIDTH,
51 SWAMP_HUT_HEIGHT,
52 SWAMP_HUT_DEPTH,
53 ),
54 gen_depth: 0,
55 orientation: Some(orientation),
56 payload: StructurePiecePayload::Procedural(ProceduralPieceData::SwampHut(
57 SwampHutPieceData::new(),
58 )),
59 ground_level_delta: 0,
60 junctions: Vec::new(),
61 projection: None,
62 }
63}
64
65impl Structure for SwampHutStructure {
66 fn find_generation_point(
67 &self,
68 ctx: &mut dyn StructureGenerationContext,
69 structure: &StructureData,
70 rng: &mut LegacyRandom,
71 ) -> Option<GenerationStub> {
72 let center_y = ctx.base_height(ctx.center_block_x(), ctx.center_block_z(), false) - 1;
73 let biome = ctx.biome_at(ctx.center_block_x(), center_y, ctx.center_block_z());
74 if !structure.allowed_biomes.contains(&biome.key) {
75 return None;
76 }
77
78 let orientation = random_horizontal_direction(rng);
79 Some(GenerationStub {
80 position: (ctx.center_block_x(), center_y, ctx.center_block_z()),
81 pieces: vec![swamp_hut_piece(
82 ctx.chunk_min_x(),
83 ctx.chunk_min_z(),
84 orientation,
85 )],
86 })
87 }
88}
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93
94 #[test]
95 fn swamp_hut_piece_uses_full_procedural_payload() {
96 let piece = swamp_hut_piece(16, 32, Direction::West);
97
98 assert_eq!(
99 piece.piece_type,
100 Identifier::new_static("minecraft", "tesh")
101 );
102 assert_eq!(piece.gen_depth, 0);
103 assert_eq!(piece.orientation, Some(Direction::West));
104 let StructurePiecePayload::Procedural(ProceduralPieceData::SwampHut(data)) = piece.payload
105 else {
106 panic!("swamp hut piece should use procedural payload");
107 };
108 assert_eq!(data.height_position, None);
109 assert!(!data.spawned_witch);
110 assert!(!data.spawned_cat);
111 }
112}