mcrizzledizzle/src/world.rs

95 lines
2.9 KiB
Rust

use std::fs::{self, File};
use std::io::Write;
use std::sync::{Arc, Mutex};
use log::info;
use crate::error::AppError;
#[derive(Debug)]
pub struct World {
pub size_x: i16,
pub size_y: i16,
pub size_z: i16,
pub data: Vec<u8>,
}
impl World {
fn build(size_x: i16, size_y: i16, size_z: i16) -> Vec<u8> {
let mut world_dat: Vec<u8> = Vec::new();
for y in 0..size_y {
for _z in 0..size_z {
for _x in 0..size_x {
match y {
0..15 => world_dat.push(0x03), // Dirt
15 => world_dat.push(0x02), // Grass
_ => world_dat.push(0x00), // Air
}
}
}
}
world_dat
}
pub fn load() -> Result<Self, AppError> {
if fs::metadata("world.wrld").is_ok() {
let mut world: World = World {
size_x: 0,
size_y: 0,
size_z: 0,
data: Vec::new(),
};
let world_data_raw = fs::read("world.wrld")?;
if world_data_raw.len() < 6 {
return Err(AppError::InvalidWorldFile);
}
world.size_x = ((world_data_raw[0] as i16) << 8) + (world_data_raw[1] as i16);
world.size_y = ((world_data_raw[2] as i16) << 8) + (world_data_raw[3] as i16);
world.size_z = ((world_data_raw[4] as i16) << 8) + (world_data_raw[5] as i16);
if world.size_x > 512 || world.size_y > 256 || world.size_z > 512 {
return Err(AppError::InvalidWorldFile);
}
if world_data_raw.len()
!= (world.size_x as i32 * world.size_y as i32 * world.size_z as i32 + 6_i32)
as usize
{
return Err(AppError::InvalidWorldFile);
}
world.data = world_data_raw[6..].to_vec();
info!("Loaded world {}", "world.wrld");
Ok(world)
} else {
info!("Creating word {}", "world.wrld");
Ok(World {
size_x: 64,
size_y: 32,
size_z: 64,
data: World::build(64, 32, 64),
})
}
}
pub fn save(world_arc_clone: Arc<Mutex<World>>) -> Result<(), AppError> {
let mut to_write: Vec<u8> = Vec::new();
{
let mut world_dat = world_arc_clone.lock()?;
to_write.push((world_dat.size_x >> 8) as u8);
to_write.push((world_dat.size_x & 0xFF) as u8);
to_write.push((world_dat.size_y >> 8) as u8);
to_write.push((world_dat.size_y & 0xFF) as u8);
to_write.push((world_dat.size_z >> 8) as u8);
to_write.push((world_dat.size_z & 0xFF) as u8);
to_write.append(&mut world_dat.data);
}
let mut file = File::create("world.wrld")?;
Ok(file.write_all(&to_write)?)
}
}