fix: match vanillas generation for huge mushrooms (#2430)

This commit is contained in:
Oswald
2026-08-24 07:56:10 +02:00
committed by GitHub
parent 17b37c3efc
commit 8be5ed1e58
2 changed files with 101 additions and 28 deletions

View File

@@ -1,11 +1,27 @@
use pumpkin_data::Block;
use pumpkin_util::{math::position::BlockPos, random::RandomGenerator, random::RandomImpl};
use pumpkin_data::{
Block, BlockState,
block_properties::{BlockProperties, BrownMushroomBlockLikeProperties},
};
use pumpkin_util::{
math::position::BlockPos,
random::{RandomGenerator, RandomImpl},
};
use crate::generation::proto_chunk::GenerationCache;
pub fn mushroom_tree_height(random: &mut RandomGenerator) -> i32 {
let mut height = random.next_bounded_i32(3) + 4;
if random.next_bounded_i32(12) == 0 {
height *= 2;
}
height
}
pub struct HugeBrownMushroomFeature;
impl HugeBrownMushroomFeature {
const FOLIAGE_RADIUS: i32 = 3;
#[allow(clippy::unused_self)]
pub fn generate<T: GenerationCache>(
&self,
@@ -16,23 +32,47 @@ impl HugeBrownMushroomFeature {
random: &mut RandomGenerator,
pos: BlockPos,
) -> bool {
let height = random.next_bounded_i32(3) + 4;
let tree_height = mushroom_tree_height(random);
for i in 0..height {
let stem_pos = BlockPos::new(pos.0.x, pos.0.y + i, pos.0.z);
chunk.set_block_state(&stem_pos.0, Block::MUSHROOM_STEM.default_state);
}
let radius = Self::FOLIAGE_RADIUS;
let cap_y = pos.0.y + tree_height;
for j in -radius..=radius {
for k in -radius..=radius {
let on_x_edge = j == -radius || j == radius;
let on_z_edge = k == -radius || k == radius;
let cap_y = pos.0.y + height;
for dx in -2i32..=2 {
for dz in -2i32..=2 {
let is_corner = dx.abs() == 2 && dz.abs() == 2;
if !is_corner {
let cap_pos = BlockPos::new(pos.0.x + dx, cap_y, pos.0.z + dz);
chunk.set_block_state(&cap_pos.0, Block::BROWN_MUSHROOM_BLOCK.default_state);
if on_x_edge && on_z_edge {
continue;
}
let props = BrownMushroomBlockLikeProperties {
up: true,
down: false,
west: j == -radius || (on_z_edge && j == 1 - radius),
east: j == radius || (on_z_edge && j == radius - 1),
north: k == -radius || (on_x_edge && k == 1 - radius),
south: k == radius || (on_x_edge && k == radius - 1),
};
let state_id = props.to_state_id(&Block::BROWN_MUSHROOM_BLOCK);
let cap_pos = BlockPos::new(pos.0.x + j, cap_y, pos.0.z + k);
chunk.set_block_state(&cap_pos.0, BlockState::from_id(state_id));
}
}
let stem_props = BrownMushroomBlockLikeProperties {
up: false,
down: false,
north: true,
east: true,
south: true,
west: true,
};
let stem_state = BlockState::from_id(stem_props.to_state_id(&Block::MUSHROOM_STEM));
for i in 0..tree_height {
let stem_pos = BlockPos::new(pos.0.x, pos.0.y + i, pos.0.z);
chunk.set_block_state(&stem_pos.0, stem_state);
}
true
}
}

View File

@@ -1,11 +1,16 @@
use pumpkin_data::Block;
use pumpkin_util::{math::position::BlockPos, random::RandomGenerator, random::RandomImpl};
use pumpkin_data::{
Block, BlockState,
block_properties::{BlockProperties, BrownMushroomBlockLikeProperties},
};
use pumpkin_util::{math::position::BlockPos, random::RandomGenerator};
use crate::generation::proto_chunk::GenerationCache;
pub struct HugeRedMushroomFeature;
impl HugeRedMushroomFeature {
const FOLIAGE_RADIUS: i32 = 2;
#[allow(clippy::unused_self)]
pub fn generate<T: GenerationCache>(
&self,
@@ -16,23 +21,51 @@ impl HugeRedMushroomFeature {
random: &mut RandomGenerator,
pos: BlockPos,
) -> bool {
let height = random.next_bounded_i32(3) + 5;
let tree_height = super::huge_brown_mushroom::mushroom_tree_height(random);
for i in 0..height {
let stem_pos = BlockPos::new(pos.0.x, pos.0.y + i, pos.0.z);
chunk.set_block_state(&stem_pos.0, Block::MUSHROOM_STEM.default_state);
}
let radius = Self::FOLIAGE_RADIUS;
for i in (tree_height - 3)..=tree_height {
let j = if i < tree_height { radius } else { radius - 1 };
let k = radius - 2;
let cap_y = pos.0.y + height;
for dy in 0..=2 {
let radius = if dy == 0 { 2 } else { 1 };
for dx in -radius..=radius {
for dz in -radius..=radius {
let cap_pos = BlockPos::new(pos.0.x + dx, cap_y + dy, pos.0.z + dz);
chunk.set_block_state(&cap_pos.0, Block::RED_MUSHROOM_BLOCK.default_state);
for l in -j..=j {
for m in -j..=j {
let on_x_edge = l == -j || l == j;
let on_z_edge = m == -j || m == j;
if i < tree_height && on_x_edge == on_z_edge {
continue;
}
let props = BrownMushroomBlockLikeProperties {
up: i >= tree_height - 1,
down: false,
west: l < -k,
east: l > k,
north: m < -k,
south: m > k,
};
let state_id = props.to_state_id(&Block::RED_MUSHROOM_BLOCK);
let cap_pos = BlockPos::new(pos.0.x + l, pos.0.y + i, pos.0.z + m);
chunk.set_block_state(&cap_pos.0, BlockState::from_id(state_id));
}
}
}
let stem_props = BrownMushroomBlockLikeProperties {
up: false,
down: false,
north: true,
east: true,
south: true,
west: true,
};
let stem_state = BlockState::from_id(stem_props.to_state_id(&Block::MUSHROOM_STEM));
for i in 0..tree_height {
let stem_pos = BlockPos::new(pos.0.x, pos.0.y + i, pos.0.z);
chunk.set_block_state(&stem_pos.0, stem_state);
}
true
}
}