Compare commits

..

7 commits

13 changed files with 144 additions and 35 deletions

View file

@ -1,3 +1,3 @@
source_md5="d864960022980c4270042a1ed80b9ac4"
dest_md5="5f766eea69301dc969f05fac899cb4cb"
source_md5="30885b768ea8e61f6f1072099ba8c3af"
dest_md5="3858a5d8c4a4ecf0f3bd148fa4d0440a"

Binary file not shown.

View file

@ -18,6 +18,12 @@ config/icon="res://icon.png"
StateServer="*res://native/StateServer.tscn"
[display]
window/size/width=1920
window/size/height=1080
window/dpi/allow_hidpi=true
[importer_defaults]
texture={

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 7 KiB

View file

@ -1,13 +1,9 @@
extends Node
export var xsize = 256
export var ysize = 256
export var xsize = 64
export var ysize = 64
export var zsize = 6
export var cityname = "night city"
func _ready():
StateServer.generate_world(xsize, ysize, zsize)
print(StateServer.get_tile_at(0,0,0))
func respawn_tilemaps(amount: int):
$Tilemaps.respawn_tilemaps(amount)
StateServer.generate_world(xsize, ysize, zsize, cityname)

View file

@ -1,8 +1,8 @@
extends TileMap
func set_tile_graphics(pos: Vector2, id: int):
var flip = true
set_cell(pos.x,pos.y,0,false,false,false,get_atlas_vec_for_id(id))
if id == 0: set_cellv(pos, -1)
set_cellv(pos,0,false,false,false,get_atlas_vec_for_id(id))
func get_atlas_vec_for_id(id: int) -> Vector2:
return Vector2(randi() % 4, id)

View file

@ -21,8 +21,11 @@ func get_tile_at(pos: Vector3) -> String:
func update_tiles(tile_positions: PoolVector3Array):
for tile in tile_positions:
if !StateServer.is_tile_hidden(int(tile.x), int(tile.y), int(tile.z)):
tilemaps[tile.z].set_tile_graphics(Vector2(tile.x, tile.y),
get_tile_at(tile))
for map in tilemaps:
map.update_dirty_quadrants()
func _on_StateServer_request_init():
call_deferred("respawn_tilemaps")

Binary file not shown.

View file

@ -13,9 +13,8 @@ gdnative = {version = "0.10", features = ["async"]}
strum = { version = "0.24", features = ["derive"] }
strum_macros = "0.24"
derive_builder = "0.11.2"
# tokio = {version = "1.18.0", features = ["sync"]}
# lazy_static = "1.4.0"
# pathfinding = "3.0.12"
rand_seeder = "0.2.3"
rand = "0.8.5"
toml = "0.5.9"
[profile.dev.package."*"]

View file

@ -14,7 +14,7 @@ pub struct StateServer {
impl StateServer {
fn new(_owner: &Node) -> Self {
StateServer {
world: world::World::new(0, 0, 0),
world: world::World::new(0, 0, 0, "seed".to_string()),
}
}
@ -32,8 +32,8 @@ impl StateServer {
fn _ready(&self, _owner: &Node) {}
#[export]
fn generate_world(&mut self, _owner: &Node, xsize: usize, ysize: usize, zsize: usize) {
self.world = world::World::new(xsize, ysize, zsize);
fn generate_world(&mut self, _owner: &Node, xsize: usize, ysize: usize, zsize: usize, seed: String) {
self.world = world::World::new(xsize, ysize, zsize, seed);
let w = self.world.generate();
_owner.emit_signal("request_init", &[]);
_owner.emit_signal("changed_tiletypes", &[Variant::new(&w)]);
@ -41,13 +41,22 @@ impl StateServer {
#[export]
fn get_world_size(&self, _ownser: &Node) -> Vector3 {
Vector3::new(self.world.xsize as f32, self.world.ysize as f32, self.world.zsize as f32)
Vector3::new(
self.world.xsize as f32,
self.world.ysize as f32,
self.world.zsize as f32,
)
}
#[export]
fn get_tile_at(&self, _owner: &Node, x: usize, y: usize, z: usize) -> u16 {
self.world.get_tile_at(x, y, z)
}
#[export]
fn is_tile_hidden(&self, _owner: &Node, x: usize, y: usize, z: usize) -> bool {
self.world.is_tile_hidden(x, y, z)
}
}
// signals

View file

@ -1,4 +1,8 @@
use gdnative::prelude::*;
use rand::prelude::StdRng;
use rand::prelude::*;
use rand_seeder::Seeder;
use strum::EnumCount;
mod tiles;
@ -7,32 +11,75 @@ pub struct World {
pub ysize: usize,
pub zsize: usize,
tiles: Vec<Vec<Vec<tiles::Tiletypes>>>,
seed: String,
tileattributes: tiles::Attributelists,
}
impl World {
pub fn get_tile_at(&self, x: usize, y: usize, z: usize) -> u16{
//TODO: error handling, or maybe just do that in godot
pub fn get_tile_at(&self, x: usize, y: usize, z: usize) -> u16 {
self.tiles[x][y][z] as u16
}
pub fn generate(&mut self) -> Vector3Array{
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) -> Vector3Array {
let mut rng: StdRng = Seeder::from(self.seed.to_owned()).make_rng();
self.tiles = get_vec3(self.xsize, self.ysize, self.zsize);
let mut ret: Vector3Array = Vector3Array::new();
for x in 0..self.xsize {
for y in 0..self.ysize {
for z in 0..self.zsize {
ret.push(Vector3::new(x as f32, y as f32, z as f32));
self.tiles[x][y][z] = tiles::Tiletypes::Grass;
self.tiles[x][y][z] = self.new_tile_init_step(x, y, z, &mut rng)
}
}
}
ret
}
pub fn new(xsize: usize, ysize: usize, zsize: usize) -> World {
fn new_tile_init_step(&self, x: usize, y: usize, z: usize, rng: &mut StdRng) -> tiles::Tiletypes {
// first generate bedrock
if z == 0 {
if y == 0 || x == 0 || y == self.ysize - 1 || x == self.xsize - 1{
return tiles::Tiletypes::Water;
}
let random = rng.gen_range(0..3) as u8;
match random {
0 => return tiles::Tiletypes::Grass,
_ => return self.tileattributes.bedrock.choose(rng).unwrap().to_owned(),
}
}
// then make sure the top row of tiles is air
if z == self.zsize - 1
|| !tiles::Tile::new(self.tiles[x][y][z - 1]).is_support
|| tiles::Tile::new(self.tiles[x][y][z - 1]).must_be_on_top
{
return tiles::Tiletypes::Air;
}
// if no tile fits, then return air
tiles::Tiletypes::Air
}
pub fn new(xsize: usize, ysize: usize, zsize: usize, seed: String) -> World {
World {
xsize,
ysize,
zsize,
tiles: get_vec3(xsize, ysize, zsize),
seed,
tileattributes: tiles::Attributelists::new(),
}
}
}

View file

@ -1,7 +1,7 @@
use derive_builder::Builder;
use strum::{AsRefStr, EnumDiscriminants, EnumIter, FromRepr};
use strum::{AsRefStr, EnumCount, EnumDiscriminants, EnumIter, FromRepr, IntoEnumIterator};
#[derive(AsRefStr, EnumIter, FromRepr, EnumDiscriminants, Clone, Copy)]
#[derive(AsRefStr, EnumIter, FromRepr, EnumDiscriminants, Clone, Copy, PartialEq, EnumCount)]
#[repr(u8)]
pub enum Tiletypes {
Air,
@ -9,6 +9,7 @@ pub enum Tiletypes {
Grass,
Dirt,
Sand,
Rock,
}
#[allow(dead_code)]
@ -16,20 +17,68 @@ pub enum Tiletypes {
pub struct Tile {
kind: Tiletypes,
#[builder(default = "true")]
is_support: bool,
pub is_support: bool,
#[builder(default = "true")]
needs_support: bool,
#[builder(default = "vec![]")]
can_be_above: Vec<Tiletypes>,
#[builder(default = "vec![]")]
can_be_next_to: Vec<Tiletypes>,
pub hide_top_left: bool,
#[builder(default = "true")]
pub hide_top_right: bool,
#[builder(default = "true")]
pub hide_below: bool,
#[builder(default = "false")]
pub must_be_on_top: bool,
#[builder(default = "true")]
pub can_be_bedrock: bool,
}
impl Tile {
pub fn new(kind: Tiletypes) -> Tile {
TileBuilder::default().kind(kind).is_support(false).build().unwrap()
let tile: Tile;
match kind {
Tiletypes::Air => {
tile = TileBuilder::default()
.kind(kind)
.is_support(false)
.hide_below(false)
.hide_top_right(false)
.hide_top_left(false)
.can_be_bedrock(false)
.build()
.unwrap()
}
Tiletypes::Water => {
tile = TileBuilder::default()
.kind(kind)
.is_support(false)
.build()
.unwrap()
}
Tiletypes::Grass => {
tile = TileBuilder::default()
.kind(kind)
.must_be_on_top(true)
.build()
.unwrap()
}
_ => tile = TileBuilder::default().kind(kind).build().unwrap(),
};
tile
}
pub fn kind_to_string(&self) -> String {
self.kind.as_ref().to_string()
}
}
pub struct Attributelists {
pub bedrock: Vec<Tiletypes>,
}
impl Attributelists {
pub fn new() -> Attributelists{
let mut bedrock: Vec<Tiletypes> = vec![];
for tiletype in Tiletypes::iter(){
let tile = Tile::new(tiletype);
if tile.can_be_bedrock { bedrock.push(tiletype); }
}
Attributelists { bedrock }
}
}