Pumpkin/pumpkin-world/src/generation/feature/features/tree/trunk/bending.rs
2026-07-03 18:51:47 +02:00

88 lines
2.4 KiB
Rust

use pumpkin_data::{BlockDirection, BlockState};
use pumpkin_util::{
math::{int_provider::IntProvider, position::BlockPos},
random::{RandomGenerator, RandomImpl},
};
use crate::generation::proto_chunk::GenerationCache;
use crate::{
generation::{
block_state_provider::BlockStateProvider,
feature::features::tree::{TreeNode, trunk::TrunkPlacer},
},
world::WorldPortalExt,
};
pub struct BendingTrunkPlacer {
pub min_height_for_leaves: u32,
pub bend_length: IntProvider,
}
impl BendingTrunkPlacer {
#[expect(clippy::too_many_arguments)]
pub fn generate<T: GenerationCache>(
&self,
block_registry: &dyn WorldPortalExt,
_placer: &TrunkPlacer,
height: u32,
start_pos: BlockPos,
chunk: &mut T,
random: &mut RandomGenerator,
below_trunk_provider: &BlockStateProvider,
trunk_block: &BlockState,
) -> (Vec<TreeNode>, Vec<BlockPos>) {
let horizontal_directions = BlockDirection::horizontal();
let direction = horizontal_directions[random.next_bounded_i32(4) as usize];
let log_height = height as i32 - 1;
let mut pos = start_pos;
TrunkPlacer::set_dirt(
block_registry,
chunk,
random,
&pos.down(),
below_trunk_provider,
);
let mut trunk_poses = Vec::new();
let mut nodes = Vec::new();
for i in 0..=log_height {
if i + 1 >= log_height + random.next_bounded_i32(2) {
pos = pos.offset(direction.to_offset());
}
if TrunkPlacer::place(chunk, &pos, trunk_block) {
trunk_poses.push(pos);
}
if i >= self.min_height_for_leaves as i32 {
nodes.push(TreeNode {
center: pos,
foliage_radius: 0,
giant_trunk: false,
});
}
pos = pos.up();
}
let dir_length = self.bend_length.get(random);
for _ in 0..=dir_length {
if TrunkPlacer::place(chunk, &pos, trunk_block) {
trunk_poses.push(pos);
}
nodes.push(TreeNode {
center: pos,
foliage_radius: 0,
giant_trunk: false,
});
pos = pos.offset(direction.to_offset());
}
(nodes, trunk_poses)
}
}