Added logic to generate chunks if they can't be read from the world file.
Moved warning about ./world folder to only appear when necessary + Updated warning contents to reflect changes Made the save_file in the `Level` struct optional in case someone wants an entirely generated World. Removed now redundant asserts.
This commit is contained in:
parent
43c724dec7
commit
112a899559
@ -1,7 +1,7 @@
|
|||||||
use std::{
|
use std::{
|
||||||
fs::OpenOptions,
|
fs::OpenOptions,
|
||||||
io::{Read, Seek},
|
io::{Read, Seek},
|
||||||
path::{Path, PathBuf},
|
path::PathBuf,
|
||||||
};
|
};
|
||||||
|
|
||||||
use flate2::{bufread::ZlibDecoder, read::GzDecoder};
|
use flate2::{bufread::ZlibDecoder, read::GzDecoder};
|
||||||
@ -10,11 +10,20 @@ use rayon::prelude::*;
|
|||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
|
|
||||||
use crate::{chunk::ChunkData, coordinates::ChunkCoordinates};
|
use crate::{
|
||||||
|
chunk::ChunkData,
|
||||||
|
coordinates::ChunkCoordinates,
|
||||||
|
world_gen::{get_world_gen, Seed, WorldGenerator},
|
||||||
|
};
|
||||||
|
|
||||||
#[allow(dead_code)]
|
/// The Level represents a single Dimension.
|
||||||
/// The Level represents a
|
|
||||||
pub struct Level {
|
pub struct Level {
|
||||||
|
save_file: Option<SaveFile>,
|
||||||
|
world_gen: Box<dyn WorldGenerator>,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SaveFile {
|
||||||
|
#[allow(dead_code)]
|
||||||
root_folder: PathBuf,
|
root_folder: PathBuf,
|
||||||
region_folder: PathBuf,
|
region_folder: PathBuf,
|
||||||
}
|
}
|
||||||
@ -84,16 +93,31 @@ impl Compression {
|
|||||||
|
|
||||||
impl Level {
|
impl Level {
|
||||||
pub fn from_root_folder(root_folder: PathBuf) -> Self {
|
pub fn from_root_folder(root_folder: PathBuf) -> Self {
|
||||||
assert!(root_folder.exists(), "World root folder does not exist!");
|
let world_gen = get_world_gen(Seed(0)); // TODO Read Seed from config.
|
||||||
let region_folder = root_folder.join("region");
|
|
||||||
assert!(
|
|
||||||
region_folder.exists(),
|
|
||||||
"World region folder does not exist!"
|
|
||||||
);
|
|
||||||
|
|
||||||
Level {
|
if root_folder.exists() {
|
||||||
root_folder,
|
let region_folder = root_folder.join("region");
|
||||||
region_folder,
|
assert!(
|
||||||
|
region_folder.exists(),
|
||||||
|
"World region folder does not exist, despite there being a root folder."
|
||||||
|
);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
world_gen,
|
||||||
|
save_file: Some(SaveFile {
|
||||||
|
root_folder,
|
||||||
|
region_folder,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log::warn!(
|
||||||
|
"Pumpkin currently only supports Superflat World generation. Use a vanilla ./world folder to play in a normal world."
|
||||||
|
);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
world_gen,
|
||||||
|
save_file: None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,19 +145,27 @@ impl Level {
|
|||||||
let channel = channel.clone();
|
let channel = channel.clone();
|
||||||
|
|
||||||
channel
|
channel
|
||||||
.blocking_send(match Self::read_chunk(&self.region_folder, at) {
|
.blocking_send(match &self.save_file {
|
||||||
Err(WorldError::ChunkNotGenerated(_)) => {
|
Some(save_file) => {
|
||||||
// This chunk was not generated yet.
|
match Self::read_chunk(save_file, at) {
|
||||||
todo!("generate chunk here")
|
Err(WorldError::ChunkNotGenerated(_)) => {
|
||||||
|
// This chunk was not generated yet.
|
||||||
|
Ok(self.world_gen.generate_chunk(at))
|
||||||
|
}
|
||||||
|
// TODO this doesn't warn the user about the error. fix.
|
||||||
|
result => result,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
// There is no savefile yet -> generate the chunks
|
||||||
|
Ok(self.world_gen.generate_chunk(at))
|
||||||
}
|
}
|
||||||
// TODO this doesn't warn the user about the error. fix.
|
|
||||||
result => result,
|
|
||||||
})
|
})
|
||||||
.expect("Failed sending ChunkData.");
|
.expect("Failed sending ChunkData.");
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_chunk(region_folder: &Path, at: ChunkCoordinates) -> Result<ChunkData, WorldError> {
|
fn read_chunk(save_file: &SaveFile, at: ChunkCoordinates) -> Result<ChunkData, WorldError> {
|
||||||
let region = (
|
let region = (
|
||||||
((at.x as f32) / 32.0).floor() as i32,
|
((at.x as f32) / 32.0).floor() as i32,
|
||||||
((at.z as f32) / 32.0).floor() as i32,
|
((at.z as f32) / 32.0).floor() as i32,
|
||||||
@ -141,7 +173,11 @@ impl Level {
|
|||||||
|
|
||||||
let mut region_file = OpenOptions::new()
|
let mut region_file = OpenOptions::new()
|
||||||
.read(true)
|
.read(true)
|
||||||
.open(region_folder.join(format!("r.{}.{}.mca", region.0, region.1)))
|
.open(
|
||||||
|
save_file
|
||||||
|
.region_folder
|
||||||
|
.join(format!("r.{}.{}.mca", region.0, region.1)),
|
||||||
|
)
|
||||||
.map_err(|err| match err.kind() {
|
.map_err(|err| match err.kind() {
|
||||||
std::io::ErrorKind::NotFound => {
|
std::io::ErrorKind::NotFound => {
|
||||||
WorldError::ChunkNotGenerated(ChunkNotGeneratedError::RegionFileMissing)
|
WorldError::ChunkNotGenerated(ChunkNotGeneratedError::RegionFileMissing)
|
||||||
|
|||||||
@ -102,7 +102,6 @@ impl Server {
|
|||||||
log::info!("Loading Plugins");
|
log::info!("Loading Plugins");
|
||||||
let plugin_loader = PluginLoader::load();
|
let plugin_loader = PluginLoader::load();
|
||||||
|
|
||||||
log::warn!("Pumpkin does currently not have World or Chunk generation, Using ../world folder with vanilla pregenerated chunks");
|
|
||||||
let world = World::load(Dimension::OverWorld.into_level(
|
let world = World::load(Dimension::OverWorld.into_level(
|
||||||
// TODO: load form config
|
// TODO: load form config
|
||||||
"./world".parse().unwrap(),
|
"./world".parse().unwrap(),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user