Added WorldGenerator traits and a GenericWorldGenerator.

This commit is contained in:
DaniD3v
2024-08-28 10:49:05 +02:00
parent 4031c4dc13
commit 9149e82508
5 changed files with 111 additions and 0 deletions

8
Cargo.lock generated
View File

@@ -1980,11 +1980,13 @@ dependencies = [
"futures",
"itertools 0.13.0",
"lazy_static",
"log",
"num-derive",
"num-traits",
"rayon",
"serde",
"serde_json",
"static_assertions",
"thiserror",
"tokio",
]
@@ -2565,6 +2567,12 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "subtle"
version = "2.6.1"

View File

@@ -16,6 +16,8 @@ flate2 = "1.0.33"
serde = { version = "1.0", features = ["derive"] }
lazy_static = "1.5.0"
serde_json = "1.0"
static_assertions = "1.1.0"
log.workspace = true
num-traits = "0.2"
num-derive = "0.4"

View File

@@ -0,0 +1,25 @@
use static_assertions::assert_obj_safe;
use crate::biome::Biome;
use crate::block::BlockId;
use crate::chunk::ChunkData;
use crate::coordinates::{BlockCoordinates, ChunkCoordinates, XZBlockCoordinates};
use crate::world_gen::Seed;
pub trait GeneratorInit {
fn new(seed: Seed) -> Self;
}
pub trait WorldGenerator: Sync + Send {
#[allow(dead_code)]
fn generate_chunk(&self, at: ChunkCoordinates) -> ChunkData;
}
assert_obj_safe! {WorldGenerator}
pub(crate) trait BiomeGenerator: Sync + Send {
fn generate_biome(&self, at: XZBlockCoordinates) -> Biome;
}
pub(crate) trait TerrainGenerator: Sync + Send {
fn generate_block(&self, at: BlockCoordinates, biome: Biome) -> BlockId;
}

View File

@@ -0,0 +1,66 @@
use crate::{
chunk::{ChunkBlocks, ChunkData},
coordinates::{
ChunkCoordinates, ChunkRelativeBlockCoordinates, ChunkRelativeXZBlockCoordinates,
},
WORLD_LOWEST_Y, WORLD_MAX_Y,
};
use super::{
generator::{BiomeGenerator, GeneratorInit, TerrainGenerator, WorldGenerator},
Seed,
};
pub struct GenericGenerator<B: BiomeGenerator, T: TerrainGenerator> {
biome_generator: B,
terrain_generator: T,
}
impl<B: BiomeGenerator + GeneratorInit, T: TerrainGenerator + GeneratorInit> GeneratorInit
for GenericGenerator<B, T>
{
fn new(seed: Seed) -> Self {
Self {
biome_generator: B::new(seed),
terrain_generator: T::new(seed),
}
}
}
impl<B: BiomeGenerator, T: TerrainGenerator> WorldGenerator for GenericGenerator<B, T> {
fn generate_chunk(&self, at: ChunkCoordinates) -> ChunkData {
let mut blocks = ChunkBlocks::default();
for x in 0..16u8 {
for z in 0..16u8 {
let biome = self.biome_generator.generate_biome(
ChunkRelativeXZBlockCoordinates {
x: x.into(),
z: z.into(),
}
.with_chunk_coordinates(at),
);
// Iterate from the highest block to the lowest, in order to minimize the heightmap updates
for y in (WORLD_LOWEST_Y..WORLD_MAX_Y).rev() {
let coordinates = ChunkRelativeBlockCoordinates {
x: x.into(),
y: y.into(),
z: z.into(),
};
blocks.set_block(
coordinates,
self.terrain_generator
.generate_block(coordinates.with_chunk_coordinates(at), biome),
);
}
}
}
ChunkData {
blocks,
position: at,
}
}
}

View File

@@ -1 +1,11 @@
mod generator;
mod generic_generator;
mod seed;
pub use generator::WorldGenerator;
pub use seed::Seed;
#[allow(dead_code)]
pub fn get_world_gen(_: Seed) -> Box<dyn WorldGenerator> {
todo!()
}