Skip to content

Commit

Permalink
Improved: Plains biome
Browse files Browse the repository at this point in the history
- Flowers
- Grass
- More natural height variation
  • Loading branch information
Snowiiii committed Oct 22, 2024
1 parent 4d01ab6 commit d9b3d04
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 25 deletions.
2 changes: 1 addition & 1 deletion pumpkin-world/src/coordinates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize};
Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, AsRef, AsMut, Into, Display,
)]
#[serde(transparent)]
pub struct Height(i16);
pub struct Height(pub i16);

impl Height {
pub fn from_absolute(height: u16) -> Self {
Expand Down
17 changes: 14 additions & 3 deletions pumpkin-world/src/world_gen/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use pumpkin_core::math::vector2::Vector2;

use crate::biome::Biome;
use crate::block::block_state::BlockState;
use crate::chunk::ChunkData;
use crate::coordinates::{BlockCoordinates, XZBlockCoordinates};
use crate::chunk::{ChunkBlocks, ChunkData};
use crate::coordinates::{BlockCoordinates, ChunkRelativeBlockCoordinates, XZBlockCoordinates};
use crate::world_gen::Seed;

pub trait GeneratorInit {
Expand All @@ -28,8 +28,19 @@ pub(crate) trait TerrainGenerator: Sync + Send {
}

pub(crate) trait PerlinTerrainGenerator: Sync + Send {
fn height_variation(&self) -> f64 {
4.0
}

fn prepare_chunk(&self, at: &Vector2<i32>, perlin: &Perlin);

/// Dependens on the perlin noise height
fn generate_block(&self, at: BlockCoordinates, chunk_height: i16, biome: Biome) -> BlockState;
fn generate_block(
&self,
coordinates: ChunkRelativeBlockCoordinates,
at: BlockCoordinates,
blocks: &mut ChunkBlocks,
chunk_height: i16,
biome: Biome,
);
}
20 changes: 9 additions & 11 deletions pumpkin-world/src/world_gen/generic_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ impl<B: BiomeGenerator, T: PerlinTerrainGenerator> WorldGenerator for GenericGen
let noise_value = self.perlin.get([at.x as f64 / 16.0, at.z as f64 / 16.0]);

let base_height = 64.0;
let height_variation = 16.0;
let chunk_height = noise_value.mul_add(height_variation, base_height) as i32;
let chunk_height =
noise_value.mul_add(self.terrain_generator.height_variation(), base_height) as i16;

for x in 0..16u8 {
for z in 0..16u8 {
Expand All @@ -53,22 +53,20 @@ impl<B: BiomeGenerator, T: PerlinTerrainGenerator> WorldGenerator for GenericGen
);

// Iterate from the highest block to the lowest, in order to minimize the heightmap updates
for y in (WORLD_LOWEST_Y..chunk_height as i16).rev() {
for y in (WORLD_LOWEST_Y..chunk_height).rev() {
let coordinates = ChunkRelativeBlockCoordinates {
x: x.into(),
y: y.into(),
z: z.into(),
};

blocks.set_block(
//coordinates,
self.terrain_generator.generate_block(
coordinates,
self.terrain_generator
.generate_block(
coordinates.with_chunk_coordinates(at),
chunk_height as i16,
biome,
)
.into(),
coordinates.with_chunk_coordinates(at),
&mut blocks,
chunk_height,
biome,
);
}
}
Expand Down
54 changes: 54 additions & 0 deletions pumpkin-world/src/world_gen/implementation/overworld/biome/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,55 @@
use std::ops::Add;

use crate::{block::BlockState, coordinates::ChunkRelativeBlockCoordinates};

pub mod plains;

pub fn generate_tree(
chunk_relative_coordinates: ChunkRelativeBlockCoordinates,
) -> Vec<(ChunkRelativeBlockCoordinates, BlockState)> {
let x = chunk_relative_coordinates.x;
let z = chunk_relative_coordinates.z;

// TODO: Adjust tree height and trunk width based on biome
let tree_height: i8 = 7;
let trunk_width: i8 = 1;

let mut tree_blocks = Vec::new();

// Generate trunk
for y in 0..tree_height {
for dx in 0 - trunk_width..=trunk_width {
for dz in 0 - trunk_width..=trunk_width {
let block_coordinates = ChunkRelativeBlockCoordinates {
x: x.add(dx as u8).into(),
y: (chunk_relative_coordinates.y.add(y as i16)).into(),
z: z.add(dz as u8).into(),
};
tree_blocks.push((
block_coordinates,
pumpkin_macros::block!("minecraft:oak_log"),
));
}
}
}

// Generate leaves
let leaf_radius = trunk_width + 1;
for y in tree_height..tree_height + 3 {
for dx in 0 - leaf_radius..=leaf_radius {
for dz in 0 - leaf_radius..=leaf_radius {
let block_coordinates = ChunkRelativeBlockCoordinates {
x: x.add(dx as u8).into(),
y: (chunk_relative_coordinates.y.add(y as i16)).into(),
z: z.add(dz as u8).into(),
};
tree_blocks.push((
block_coordinates,
pumpkin_macros::block!("minecraft:oak_leaves"),
));
}
}
}

tree_blocks
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use noise::Perlin;
use pumpkin_core::math::vector2::Vector2;
use rand::Rng;

use crate::{
biome::Biome,
block::block_state::BlockState,
coordinates::{BlockCoordinates, XZBlockCoordinates},
chunk::ChunkBlocks,
coordinates::{BlockCoordinates, ChunkRelativeBlockCoordinates, XZBlockCoordinates},
world_gen::{
generator::{BiomeGenerator, GeneratorInit, PerlinTerrainGenerator},
generic_generator::GenericGenerator,
Expand Down Expand Up @@ -40,21 +41,82 @@ impl GeneratorInit for PlainsTerrainGenerator {
impl PerlinTerrainGenerator for PlainsTerrainGenerator {
fn prepare_chunk(&self, _at: &Vector2<i32>, _perlin: &Perlin) {}
// TODO allow specifying which blocks should be at which height in the config.
fn generate_block(&self, at: BlockCoordinates, chunk_height: i16, _: Biome) -> BlockState {
fn generate_block(
&self,
coordinates: ChunkRelativeBlockCoordinates,
at: BlockCoordinates,
blocks: &mut ChunkBlocks,
chunk_height: i16,
_: Biome,
) {
let begin_stone_height = chunk_height - 5;
let begin_dirt_height = chunk_height - 1;
let begin_dirt_height = chunk_height - 2;

let y = *at.y;
if y == -64 {
pumpkin_macros::block!("minecraft:bedrock")
blocks.set_block(
coordinates,
pumpkin_macros::block!("minecraft:bedrock").into(),
);
} else if y >= -63 && y <= begin_stone_height {
pumpkin_macros::block!("minecraft:stone")
blocks.set_block(
coordinates,
pumpkin_macros::block!("minecraft:stone").into(),
);
} else if y >= begin_stone_height && y < begin_dirt_height {
pumpkin_macros::block!("minecraft:dirt")
blocks.set_block(coordinates, pumpkin_macros::block!("minecraft:dirt").into());
} else if y == chunk_height - 2 {
blocks.set_block(
coordinates,
pumpkin_macros::block!("minecraft:grass_block").into(),
);
} else if y == chunk_height - 1 {
pumpkin_macros::block!("minecraft:grass_block")
} else {
BlockState::AIR
// TODO: generate flowers and grass
let grass: u8 = rand::thread_rng().gen_range(0..7);
if grass == 3 {
let flower: u8 = rand::thread_rng().gen_range(0..20);
if flower == 6 {
match rand::thread_rng().gen_range(0..4) {
0 => {
blocks.set_block(
coordinates,
pumpkin_macros::block!("minecraft:dandelion").into(),
);
}
1 => {
blocks.set_block(
coordinates,
pumpkin_macros::block!("minecraft:oxeye_daisy").into(),
);
}
2 => {
blocks.set_block(
coordinates,
pumpkin_macros::block!("minecraft:cornflower").into(),
);
}
3 => {
blocks.set_block(
coordinates,
pumpkin_macros::block!("minecraft:poppy").into(),
);
}
_ => {
blocks.set_block(
coordinates,
pumpkin_macros::block!("minecraft:azure_bluet").into(),
);
}
}
} else {
// TODO: Tall grass, Tall grass data called `half`, There is `upper` and `lower`
blocks.set_block(
coordinates,
pumpkin_macros::block!("minecraft:short_grass").into(),
);
}
}
}
// BlockState::AIR
}
}

0 comments on commit d9b3d04

Please sign in to comment.