Method for shifting world nodes texture
This commit is contained in:
+60
-71
@@ -1,4 +1,5 @@
|
||||
mod generator;
|
||||
mod data;
|
||||
pub mod chunk;
|
||||
pub mod block;
|
||||
use std::time::Instant;
|
||||
@@ -6,17 +7,12 @@ use std::path::PathBuf;
|
||||
use std::io::Write;
|
||||
use std::io::Read;
|
||||
use std::fs;
|
||||
use cgmath::{Point3, Vector3};
|
||||
use cgmath::Vector3;
|
||||
use std::collections::HashMap;
|
||||
use generator::WorldGen;
|
||||
use chunk::WorldChunk;
|
||||
use block::WorldBlock;
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
||||
struct WorldData {
|
||||
#[serde(default)]
|
||||
pub name: String
|
||||
}
|
||||
use data::WorldData;
|
||||
|
||||
pub struct World {
|
||||
data: WorldData,
|
||||
@@ -25,43 +21,56 @@ pub struct World {
|
||||
|
||||
impl World {
|
||||
|
||||
pub fn new(name: String) -> Self {
|
||||
Self {
|
||||
data: WorldData { name },
|
||||
pub fn init(name: String) -> Self {
|
||||
let mut instance = Self {
|
||||
data: WorldData { name, ..Default::default() },
|
||||
chunks: HashMap::new(),
|
||||
};
|
||||
instance.load_metadata();
|
||||
instance.save_all();
|
||||
instance
|
||||
}
|
||||
|
||||
/*
|
||||
* Loads metadata
|
||||
*/
|
||||
fn load_metadata(&mut self) -> bool {
|
||||
let filepath = dirs::data_local_dir().unwrap().join("Voxelgame").join(self.data.name.clone()).join("world.dat");
|
||||
if let Ok(mut file) = fs::File::open(filepath) {
|
||||
let mut buf = Vec::new();
|
||||
file.read_to_end(&mut buf).unwrap();
|
||||
if let Ok(data) = toml::from_slice::<WorldData>(&buf[..]) {
|
||||
self.data = data;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
pub fn all_blocks(&self) -> Vec<(Vector3<i32>, &WorldBlock)> {
|
||||
self.chunks.iter().map(|(chunk_pos, chunk)| {
|
||||
let off = chunk_pos * chunk::SIZE as i32;
|
||||
let result: Vec<(Vector3<i32>, &WorldBlock)> = chunk.all_blocks().iter().map(|(pos, block)| {
|
||||
(
|
||||
Vector3{x: off.x+pos.x as i32, y: off.y+pos.y as i32, z: off.z+pos.z as i32},
|
||||
*block
|
||||
)
|
||||
}).collect();
|
||||
result
|
||||
}).flatten().collect()
|
||||
}
|
||||
|
||||
pub fn save(&self) {
|
||||
/*
|
||||
* Saves metadata and all loaded chunks
|
||||
*/
|
||||
pub fn save_all(&self) {
|
||||
// Get directory
|
||||
let dir = dirs::data_local_dir().unwrap().join("Voxelgame");
|
||||
fs::create_dir_all(&dir).expect("Failed to create directory");
|
||||
let dirpath = dirs::data_local_dir().unwrap().join("Voxelgame").join("saves").join(&self.data.name);
|
||||
fs::create_dir_all(&dirpath).expect("Failed to create world directory");
|
||||
|
||||
// Save all chunks
|
||||
for (pos, chunk) in self.chunks.iter() {
|
||||
let path = dir.with_file_name(format!("chunk_{}_{}_{}.dat", pos.x, pos.y, pos.z));
|
||||
let mut file = fs::File::create(path).expect("Failed to create file");
|
||||
file.write(&chunk.to_bytes()).unwrap();
|
||||
let filepath = dirpath.join(format!("chunk_{}_{}_{}.dat", pos.x, pos.y, pos.z));
|
||||
let mut file = fs::File::create(filepath).expect("Failed to create chunk file");
|
||||
file.write(&chunk.to_bytes()).expect("Failed to write chunk file");
|
||||
}
|
||||
|
||||
// Save metadata
|
||||
let data_str = toml::to_string(&self.data).unwrap();
|
||||
let data_path: PathBuf = [dir.to_str().unwrap(), "world.dat"].iter().collect();
|
||||
let mut data_file = fs::File::create(data_path).unwrap();
|
||||
data_file.write_all(data_str.as_bytes()).expect("Failed to write world metadata");
|
||||
let datastr = toml::to_string(&self.data).unwrap();
|
||||
let datapath: PathBuf = dirpath.join("world.dat");
|
||||
let mut datafile = fs::File::create(datapath).expect("Failed to create world metadata file");
|
||||
datafile.write_all(datastr.as_bytes()).expect("Failed to write world metadata");
|
||||
}
|
||||
|
||||
pub fn get_chunk(&mut self, chunk_wpos: &Vector3<i32>) -> Option<&mut WorldChunk> {
|
||||
self.chunks.get_mut(chunk_wpos)
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -76,12 +85,13 @@ impl World {
|
||||
|
||||
// Try loading chunk from file
|
||||
let filename = format!("chunk_{}_{}_{}.dat", pos.x, pos.y, pos.z);
|
||||
let filepath = dirs::data_local_dir().unwrap().join("Voxelgame").with_file_name(filename);
|
||||
let filepath = dirs::data_local_dir().unwrap().join("Voxelgame").join("saves").join(&self.data.name).join(filename);
|
||||
|
||||
if filepath.is_file() {
|
||||
let timer = Instant::now();
|
||||
let mut buff = Vec::new();
|
||||
let mut file = fs::File::open(filepath).expect("Failed to open file");
|
||||
file.read_to_end(&mut buff).expect("Failed to read file");
|
||||
let mut file = fs::File::open(filepath).expect("Failed to open chunk file");
|
||||
file.read_to_end(&mut buff).expect("Failed to read chunk file");
|
||||
let chunk = WorldChunk::from_bytes(buff);
|
||||
self.chunks.insert(pos, chunk);
|
||||
println!("Chunk at {:?} loaded ({} ms)", pos, timer.elapsed().as_millis());
|
||||
@@ -99,13 +109,11 @@ impl World {
|
||||
}
|
||||
}
|
||||
|
||||
// Save
|
||||
// Save generated chunk to file
|
||||
let timer1 = Instant::now();
|
||||
let dir = dirs::data_local_dir().unwrap().join("Voxelgame");
|
||||
fs::create_dir_all(&dir).expect("Failed to create directory");
|
||||
let path = dir.with_file_name(format!("chunk_{}_{}_{}.dat", pos.x, pos.y, pos.z));
|
||||
let mut file = fs::File::create(path).expect("Failed to create file");
|
||||
file.write(&chunk.to_bytes()).unwrap();
|
||||
fs::create_dir_all(&filepath.parent().unwrap()).expect("Failed to create world directory");
|
||||
let mut file = fs::File::create(filepath).expect("Failed to create chunk file");
|
||||
file.write(&chunk.to_bytes()).expect("Failed to write chunk file");
|
||||
|
||||
// Add to list
|
||||
self.chunks.insert(pos, chunk);
|
||||
@@ -117,33 +125,14 @@ impl World {
|
||||
true
|
||||
}
|
||||
|
||||
pub fn load(&mut self) -> bool {
|
||||
// Load metadata
|
||||
let filepath = dirs::data_local_dir().unwrap().join("Voxelgame").with_file_name("world.dat");
|
||||
if let Ok(mut file) = fs::File::open(filepath) {
|
||||
let mut buf = Vec::new();
|
||||
file.read_to_end(&mut buf).unwrap();
|
||||
if let Ok(data) = toml::from_slice::<WorldData>(&buf[..]) {
|
||||
self.data = data;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn get_block(&mut self, block_wpos: &Vector3<i32>) -> Option<&WorldBlock> {
|
||||
// Split world space to chunk and block space
|
||||
let ch_pos = block_wpos / chunk::SIZE as i32;
|
||||
let bl_pos = block_wpos % chunk::SIZE as i32;
|
||||
// Return block if exists
|
||||
if let Some(chunk) = self.chunks.get_mut(&ch_pos) {
|
||||
return Some(chunk.get_block(&bl_pos));
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get_chunk(&mut self, chunk_wpos: &Vector3<i32>) -> Option<&mut WorldChunk> {
|
||||
self.chunks.get_mut(chunk_wpos)
|
||||
}
|
||||
// pub fn get_block(&mut self, block_wpos: &Vector3<i32>) -> Option<&WorldBlock> {
|
||||
// // Split world space to chunk and block space
|
||||
// let ch_pos = block_wpos / chunk::SIZE as i32;
|
||||
// let bl_pos = block_wpos % chunk::SIZE as i32;
|
||||
// // Return block if exists
|
||||
// if let Some(chunk) = self.chunks.get_mut(&ch_pos) {
|
||||
// return Some(chunk.get_block(&bl_pos));
|
||||
// }
|
||||
// None
|
||||
// }
|
||||
}
|
||||
Reference in New Issue
Block a user