Skip to main content

steel_core/worldgen/structure/piece_placer/
swamp_hut.rs

1use glam::DVec3;
2use steel_registry::blocks::block_state_ext::BlockStateExt as _;
3use steel_registry::blocks::properties::{BlockStateProperties, StairsShape};
4use steel_registry::entity_type::EntityTypeRef;
5use steel_registry::{Registry, vanilla_blocks, vanilla_entities};
6use steel_utils::random::worldgen_random::WorldgenRandom;
7use steel_utils::{BlockStateId, BoundingBox, Direction};
8
9use crate::worldgen::region::WorldGenRegion;
10use steel_worldgen::structure::swamp_hut::SwampHutPieceData;
11
12use super::StructurePiecePlacer;
13use super::scattered_feature::ScatteredFeaturePlacer;
14
15impl StructurePiecePlacer {
16    pub(super) fn place_swamp_hut_piece(
17        region: &mut WorldGenRegion<'_>,
18        registry: &Registry,
19        bounding_box: &mut BoundingBox,
20        orientation: Option<Direction>,
21        data: &mut SwampHutPieceData,
22        clip: BoundingBox,
23        _random: &mut WorldgenRandom,
24    ) -> bool {
25        let mut placer =
26            ScatteredFeaturePlacer::new(region, registry, bounding_box, orientation, clip);
27        if !placer.update_average_ground_height(&mut data.height_position, 0) {
28            return false;
29        }
30
31        place_swamp_hut(&mut placer, data);
32        true
33    }
34}
35
36fn place_swamp_hut(placer: &mut ScatteredFeaturePlacer<'_, '_>, data: &mut SwampHutPieceData) {
37    let spruce_planks = vanilla_blocks::SPRUCE_PLANKS.default_state();
38    let oak_log = vanilla_blocks::OAK_LOG.default_state();
39    let oak_fence = vanilla_blocks::OAK_FENCE.default_state();
40    let air = vanilla_blocks::AIR.default_state();
41
42    placer.generate_box(1, 1, 1, 5, 1, 7, spruce_planks, spruce_planks, false);
43    placer.generate_box(1, 4, 2, 5, 4, 7, spruce_planks, spruce_planks, false);
44    placer.generate_box(2, 1, 0, 4, 1, 0, spruce_planks, spruce_planks, false);
45    placer.generate_box(2, 2, 2, 3, 3, 2, spruce_planks, spruce_planks, false);
46    placer.generate_box(1, 2, 3, 1, 3, 6, spruce_planks, spruce_planks, false);
47    placer.generate_box(5, 2, 3, 5, 3, 6, spruce_planks, spruce_planks, false);
48    placer.generate_box(2, 2, 7, 4, 3, 7, spruce_planks, spruce_planks, false);
49    placer.generate_box(1, 0, 2, 1, 3, 2, oak_log, oak_log, false);
50    placer.generate_box(5, 0, 2, 5, 3, 2, oak_log, oak_log, false);
51    placer.generate_box(1, 0, 7, 1, 3, 7, oak_log, oak_log, false);
52    placer.generate_box(5, 0, 7, 5, 3, 7, oak_log, oak_log, false);
53    placer.place_block(oak_fence, 2, 3, 2);
54    placer.place_block(oak_fence, 3, 3, 7);
55    placer.place_block(air, 1, 3, 4);
56    placer.place_block(air, 5, 3, 4);
57    placer.place_block(air, 5, 3, 5);
58    placer.place_block(vanilla_blocks::POTTED_RED_MUSHROOM.default_state(), 1, 3, 5);
59    placer.place_block(vanilla_blocks::CRAFTING_TABLE.default_state(), 3, 2, 6);
60    placer.place_block(vanilla_blocks::CAULDRON.default_state(), 4, 2, 6);
61    placer.place_block(oak_fence, 1, 2, 1);
62    placer.place_block(oak_fence, 5, 2, 1);
63
64    let north_stairs = stairs(Direction::North);
65    let east_stairs = stairs(Direction::East);
66    let west_stairs = stairs(Direction::West);
67    let south_stairs = stairs(Direction::South);
68    placer.generate_box(0, 4, 1, 6, 4, 1, north_stairs, north_stairs, false);
69    placer.generate_box(0, 4, 2, 0, 4, 7, east_stairs, east_stairs, false);
70    placer.generate_box(6, 4, 2, 6, 4, 7, west_stairs, west_stairs, false);
71    placer.generate_box(0, 4, 8, 6, 4, 8, south_stairs, south_stairs, false);
72    placer.place_block(stairs_shape(north_stairs, StairsShape::OuterRight), 0, 4, 1);
73    placer.place_block(stairs_shape(north_stairs, StairsShape::OuterLeft), 6, 4, 1);
74    placer.place_block(stairs_shape(south_stairs, StairsShape::OuterLeft), 0, 4, 8);
75    placer.place_block(stairs_shape(south_stairs, StairsShape::OuterRight), 6, 4, 8);
76
77    for z in [2, 7] {
78        for x in [1, 5] {
79            placer.fill_column_down(oak_log, x, -1, z);
80        }
81    }
82
83    spawn_swamp_hut_mob(placer, &mut data.spawned_witch, &vanilla_entities::WITCH);
84    spawn_swamp_hut_mob(placer, &mut data.spawned_cat, &vanilla_entities::CAT);
85}
86
87fn spawn_swamp_hut_mob(
88    placer: &mut ScatteredFeaturePlacer<'_, '_>,
89    spawned: &mut bool,
90    entity_type: EntityTypeRef,
91) {
92    if *spawned {
93        return;
94    }
95
96    let pos = placer.world_pos(2, 2, 5);
97    if !placer.clip().contains_blockpos(pos) {
98        return;
99    }
100
101    *spawned = true;
102    let Some(entity) = StructurePiecePlacer::create_mob(
103        entity_type,
104        DVec3::new(
105            f64::from(pos.x()) + 0.5,
106            f64::from(pos.y()),
107            f64::from(pos.z()) + 0.5,
108        ),
109        placer.weak_world(),
110        true,
111    ) else {
112        return;
113    };
114    let _ = placer.add_fresh_entity(entity);
115}
116
117fn stairs(facing: Direction) -> BlockStateId {
118    vanilla_blocks::SPRUCE_STAIRS
119        .default_state()
120        .set_value(&BlockStateProperties::FACING, facing)
121}
122
123fn stairs_shape(state: BlockStateId, shape: StairsShape) -> BlockStateId {
124    state.set_value(&BlockStateProperties::STAIRS_SHAPE, shape)
125}