mirror of
https://github.com/zyllian/classics.git
synced 2025-01-18 03:32:41 -08:00
make world generation configurable
This commit is contained in:
parent
c78303cf44
commit
38164a6cc5
4 changed files with 101 additions and 9 deletions
|
@ -1,3 +1,5 @@
|
||||||
|
pub mod generation;
|
||||||
|
|
||||||
/// a classic level
|
/// a classic level
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Level {
|
pub struct Level {
|
||||||
|
|
93
src/level/generation.rs
Normal file
93
src/level/generation.rs
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
use rand::Rng;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use super::Level;
|
||||||
|
|
||||||
|
/// enum for different kinds of level generation
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(tag = "type")]
|
||||||
|
pub enum LevelGeneration {
|
||||||
|
/// an empty level
|
||||||
|
Empty,
|
||||||
|
/// a level where every block up to the given height is randomized
|
||||||
|
FullRandom { height: usize },
|
||||||
|
/// a flat level with the given preset
|
||||||
|
Flat(FlatPreset),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// enum for level presents
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(tag = "flat_type")]
|
||||||
|
pub enum FlatPreset {
|
||||||
|
/// the level is mostly stone, then dirt, then a layer of grass on the top
|
||||||
|
StoneAndGrass,
|
||||||
|
/// the level layers are custom as defined in server config
|
||||||
|
Custom { layers: Vec<FlatLayer> },
|
||||||
|
}
|
||||||
|
|
||||||
|
/// description of a flat world's layer
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct FlatLayer {
|
||||||
|
/// the block for the layer
|
||||||
|
pub block: u8,
|
||||||
|
/// the depth of the layer
|
||||||
|
pub depth: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LevelGeneration {
|
||||||
|
/// generates the level
|
||||||
|
pub fn generate<R>(&self, level: &mut Level, rng: &mut R)
|
||||||
|
where
|
||||||
|
R: Rng,
|
||||||
|
{
|
||||||
|
match self {
|
||||||
|
Self::Empty => {}
|
||||||
|
Self::FullRandom { height } => {
|
||||||
|
let height = *height.min(&level.y_size);
|
||||||
|
for x in 0..level.x_size {
|
||||||
|
for y in 0..height {
|
||||||
|
for z in 0..level.z_size {
|
||||||
|
level.set_block(x, y, z, rng.gen_range(0..49));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Self::Flat(preset) => {
|
||||||
|
let custom_layers;
|
||||||
|
let layers_ref;
|
||||||
|
|
||||||
|
match preset {
|
||||||
|
FlatPreset::StoneAndGrass => {
|
||||||
|
custom_layers = vec![
|
||||||
|
FlatLayer {
|
||||||
|
block: 1,
|
||||||
|
depth: level.y_size / 2 - 4,
|
||||||
|
},
|
||||||
|
FlatLayer { block: 3, depth: 3 },
|
||||||
|
FlatLayer { block: 2, depth: 1 },
|
||||||
|
];
|
||||||
|
layers_ref = &custom_layers;
|
||||||
|
}
|
||||||
|
FlatPreset::Custom { layers } => {
|
||||||
|
layers_ref = layers;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut y = 0;
|
||||||
|
for layer in layers_ref {
|
||||||
|
for _ in 0..layer.depth {
|
||||||
|
for x in 0..level.x_size {
|
||||||
|
for z in 0..level.z_size {
|
||||||
|
level.set_block(x, y, z, layer.block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
y += 1;
|
||||||
|
if y >= level.y_size {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,8 +3,6 @@ mod network;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
// use parking_lot::RwLock;
|
|
||||||
use rand::Rng;
|
|
||||||
use tokio::{net::TcpListener, sync::RwLock};
|
use tokio::{net::TcpListener, sync::RwLock};
|
||||||
|
|
||||||
use crate::{level::Level, player::Player};
|
use crate::{level::Level, player::Player};
|
||||||
|
@ -50,13 +48,7 @@ impl Server {
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
let mut level = Level::new(level_x, level_y, level_z);
|
let mut level = Level::new(level_x, level_y, level_z);
|
||||||
for x in 0..level.x_size {
|
config.generation.generate(&mut level, &mut rng);
|
||||||
for y in 0..(level.y_size / 2) {
|
|
||||||
for z in 0..level.z_size {
|
|
||||||
level.set_block(x, y, z, rng.gen_range(0..50));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
println!("done!");
|
println!("done!");
|
||||||
|
|
||||||
Self::new_with_level(config, level).await
|
Self::new_with_level(config, level).await
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::level::generation::LevelGeneration;
|
||||||
|
|
||||||
/// configuration for the server
|
/// configuration for the server
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct ServerConfig {
|
pub struct ServerConfig {
|
||||||
|
@ -13,6 +15,8 @@ pub struct ServerConfig {
|
||||||
pub level_size: Option<ConfigCoordinates>,
|
pub level_size: Option<ConfigCoordinates>,
|
||||||
/// the level's spawn point
|
/// the level's spawn point
|
||||||
pub spawn: Option<ConfigCoordinates>,
|
pub spawn: Option<ConfigCoordinates>,
|
||||||
|
/// the method to generate the server's level with
|
||||||
|
pub generation: LevelGeneration,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ServerConfig {
|
impl Default for ServerConfig {
|
||||||
|
@ -23,6 +27,7 @@ impl Default for ServerConfig {
|
||||||
password: None,
|
password: None,
|
||||||
level_size: None,
|
level_size: None,
|
||||||
spawn: None,
|
spawn: None,
|
||||||
|
generation: LevelGeneration::Empty,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue