138 lines
4.3 KiB
Rust
138 lines
4.3 KiB
Rust
use gdnative::prelude::*;
|
|
|
|
use self::gen::GameRng;
|
|
|
|
mod gen;
|
|
mod tiles;
|
|
|
|
pub struct World {
|
|
pub xsize: usize,
|
|
pub ysize: usize,
|
|
pub zsize: usize,
|
|
tiles: Vec<Vec<Vec<tiles::Tiletypes>>>,
|
|
attributes: tiles::Attributelists,
|
|
}
|
|
|
|
impl World {
|
|
pub fn get_tile_at(&self, x: usize, y: usize, z: usize) -> u16 {
|
|
self.tiles[x][y][z] as u16
|
|
}
|
|
pub fn is_tile_hidden(&self, x: usize, y: usize, z: usize) -> bool {
|
|
if x == self.xsize - 1 || y == self.ysize - 1 || z == self.zsize - 1 {
|
|
return false;
|
|
}
|
|
if !tiles::Tile::new(self.tiles[x + 1][y][z]).hide_top_left
|
|
|| !tiles::Tile::new(self.tiles[x][y + 1][z]).hide_top_right
|
|
|| !tiles::Tile::new(self.tiles[x][y][z + 1]).hide_below
|
|
{
|
|
return false;
|
|
}
|
|
true
|
|
}
|
|
|
|
pub fn generate(&mut self, rng: &mut GameRng) -> Vector3Array {
|
|
self.tiles = get_vec3(self.xsize, self.ysize, self.zsize);
|
|
let noisemap = gen::get_noise(rng, (self.xsize, self.ysize));
|
|
|
|
let mut ret: Vector3Array = Vector3Array::new();
|
|
for x in 0..self.xsize {
|
|
for y in 0..self.ysize {
|
|
ret.push(Vector3::new(x as f32, y as f32, 0.0));
|
|
if noisemap.get_value(x, y) > 0.4 {
|
|
ret.append(&self.stack_tiles(
|
|
4,
|
|
tiles::Tiletypes::Grass,
|
|
tiles::Tiletypes::Dirt,
|
|
(x, y),
|
|
));
|
|
} else if noisemap.get_value(x, y) > 0.3 {
|
|
ret.append(&self.stack_tiles(
|
|
3,
|
|
tiles::Tiletypes::Grass,
|
|
tiles::Tiletypes::Dirt,
|
|
(x, y),
|
|
));
|
|
} else if noisemap.get_value(x, y) > 0.2 {
|
|
ret.append(&self.stack_tiles(
|
|
2,
|
|
tiles::Tiletypes::Grass,
|
|
tiles::Tiletypes::Dirt,
|
|
(x, y),
|
|
));
|
|
} else if noisemap.get_value(x, y) > -0.3 {
|
|
self.tiles[x][y][0] = tiles::Tiletypes::Grass;
|
|
} else if noisemap.get_value(x, y) > -0.4 {
|
|
self.tiles[x][y][0] = tiles::Tiletypes::Sand;
|
|
} else {
|
|
self.tiles[x][y][0] = tiles::Tiletypes::WaterSlab;
|
|
}
|
|
}
|
|
}
|
|
ret
|
|
}
|
|
|
|
fn stack_tiles(
|
|
&mut self,
|
|
height: usize,
|
|
top: tiles::Tiletypes,
|
|
filler: tiles::Tiletypes,
|
|
pos: (usize, usize),
|
|
) -> Vector3Array {
|
|
let mut positions = Vector3Array::new();
|
|
for z in 0..height {
|
|
positions.push(Vector3::new(pos.0 as f32, pos.1 as f32, z as f32));
|
|
if z == height - 1 {
|
|
self.tiles[pos.0][pos.1][z] = top;
|
|
} else {
|
|
self.tiles[pos.0][pos.1][z] = filler;
|
|
}
|
|
}
|
|
positions
|
|
}
|
|
|
|
pub fn put_tile_at(&mut self, x: usize, y: usize, z: usize, id: usize) -> Vector3Array {
|
|
let mut changed = Vector3Array::new();
|
|
|
|
if !self.can_put_tile_at(x, y, z, id) {
|
|
return changed;
|
|
}
|
|
|
|
self.tiles[x][y][z] = tiles::Tiletypes::from_repr(id as u8).unwrap();
|
|
changed.push(Vector3::new(x as f32, y as f32, z as f32));
|
|
|
|
changed
|
|
}
|
|
|
|
pub fn can_put_tile_at(&self, x: usize, y: usize, z: usize, id: usize) -> bool {
|
|
if self.tiles[x][y][z] == tiles::Tiletypes::Air {
|
|
return true;
|
|
}
|
|
false
|
|
}
|
|
|
|
pub fn new(xsize: usize, ysize: usize, zsize: usize) -> World {
|
|
World {
|
|
xsize,
|
|
ysize,
|
|
zsize,
|
|
tiles: get_vec3(xsize, ysize, zsize),
|
|
attributes: tiles::Attributelists::new(),
|
|
}
|
|
}
|
|
}
|
|
|
|
fn get_vec3(xsize: usize, ysize: usize, zsize: usize) -> Vec<Vec<Vec<tiles::Tiletypes>>> {
|
|
let mut zvec: Vec<tiles::Tiletypes> = Vec::with_capacity(zsize);
|
|
zvec.resize(zsize, tiles::Tiletypes::Air);
|
|
|
|
let mut yvec: Vec<Vec<tiles::Tiletypes>> = Vec::with_capacity(ysize);
|
|
yvec.resize(ysize, zvec.clone());
|
|
|
|
let mut xvec: Vec<Vec<Vec<tiles::Tiletypes>>> = Vec::with_capacity(xsize);
|
|
xvec.resize(ysize, yvec.clone());
|
|
|
|
yvec.push(zvec);
|
|
xvec.push(yvec);
|
|
xvec
|
|
}
|