chunkgen 0.2.0

Minecraft world generation library
Documentation
use serde::Deserialize;

use crate::util::rng::RandomSource;
use crate::world::worldgen::feature::features::tree::TreeConfig;
use crate::world::worldgen::feature::foliageplacers::FoliageAttachment;
use crate::world::worldgen::region::WorldGenRegion;
use shulkr::util::BlockPosition;
use shulkr::world::block::BlockState;

#[derive(Debug, Clone, Copy, Deserialize)]
pub struct GiantTrunkPlacer {
    pub base_height: i32,
    pub height_rand_a: i32,
    pub height_rand_b: i32,
}

impl GiantTrunkPlacer {
    #[expect(
        clippy::too_many_arguments,
        reason = "mirrors vanilla GiantTrunkPlacer.placeTrunk"
    )]
    pub fn place_trunk(
        &self,
        placer: &super::TrunkPlacer,
        region: &WorldGenRegion<'_>,
        trunk_setter: &mut dyn FnMut(BlockPosition, BlockState),
        random: &mut RandomSource,
        tree_height: i32,
        origin: BlockPosition,
        config: &TreeConfig,
    ) -> Vec<FoliageAttachment> {
        let below = origin.below();
        super::place_below_trunk_block(region, trunk_setter, random, below, config);
        super::place_below_trunk_block(region, trunk_setter, random, below.offset(1, 0, 0), config);
        super::place_below_trunk_block(region, trunk_setter, random, below.offset(0, 0, 1), config);
        super::place_below_trunk_block(region, trunk_setter, random, below.offset(1, 0, 1), config);

        for hh in 0..tree_height {
            placer.place_log_if_free(
                region,
                trunk_setter,
                random,
                origin.offset(0, hh, 0),
                config,
            );
            if hh < tree_height - 1 {
                placer.place_log_if_free(
                    region,
                    trunk_setter,
                    random,
                    origin.offset(1, hh, 0),
                    config,
                );
                placer.place_log_if_free(
                    region,
                    trunk_setter,
                    random,
                    origin.offset(1, hh, 1),
                    config,
                );
                placer.place_log_if_free(
                    region,
                    trunk_setter,
                    random,
                    origin.offset(0, hh, 1),
                    config,
                );
            }
        }

        vec![FoliageAttachment {
            pos: origin.above_n(tree_height),
            radius_offset: 0,
            double_trunk: true,
        }]
    }
}