diff --git a/godot/.import/default.png-13971fa1f37d4ea367b7aa5973d2bb0a.md5 b/godot/.import/default.png-13971fa1f37d4ea367b7aa5973d2bb0a.md5 index 2741d11..3b16f20 100644 --- a/godot/.import/default.png-13971fa1f37d4ea367b7aa5973d2bb0a.md5 +++ b/godot/.import/default.png-13971fa1f37d4ea367b7aa5973d2bb0a.md5 @@ -1,3 +1,3 @@ -source_md5="d864960022980c4270042a1ed80b9ac4" -dest_md5="5f766eea69301dc969f05fac899cb4cb" +source_md5="30885b768ea8e61f6f1072099ba8c3af" +dest_md5="3858a5d8c4a4ecf0f3bd148fa4d0440a" diff --git a/godot/.import/default.png-13971fa1f37d4ea367b7aa5973d2bb0a.stex b/godot/.import/default.png-13971fa1f37d4ea367b7aa5973d2bb0a.stex index f5db78d..fbd4bcb 100644 Binary files a/godot/.import/default.png-13971fa1f37d4ea367b7aa5973d2bb0a.stex and b/godot/.import/default.png-13971fa1f37d4ea367b7aa5973d2bb0a.stex differ diff --git a/godot/native/libroutes_native.so b/godot/native/libroutes_native.so index f273773..76f1528 100755 Binary files a/godot/native/libroutes_native.so and b/godot/native/libroutes_native.so differ diff --git a/godot/project.godot b/godot/project.godot index 957d385..f279bc3 100644 --- a/godot/project.godot +++ b/godot/project.godot @@ -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={ diff --git a/godot/sprite/tiles/terrain/default.png b/godot/sprite/tiles/terrain/default.png index 20ea306..ebfbb0b 100644 Binary files a/godot/sprite/tiles/terrain/default.png and b/godot/sprite/tiles/terrain/default.png differ diff --git a/godot/world/StateApi.gd b/godot/world/StateApi.gd index d271891..abbe739 100644 --- a/godot/world/StateApi.gd +++ b/godot/world/StateApi.gd @@ -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) diff --git a/godot/world/Tilemap.gd b/godot/world/Tilemap.gd index 9bd981a..d336796 100644 --- a/godot/world/Tilemap.gd +++ b/godot/world/Tilemap.gd @@ -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) diff --git a/godot/world/Tilemaps.gd b/godot/world/Tilemaps.gd index f39a136..44e9d6c 100644 --- a/godot/world/Tilemaps.gd +++ b/godot/world/Tilemaps.gd @@ -21,8 +21,11 @@ func get_tile_at(pos: Vector3) -> String: func update_tiles(tile_positions: PoolVector3Array): for tile in tile_positions: - tilemaps[tile.z].set_tile_graphics(Vector2(tile.x, tile.y), - get_tile_at(tile)) + 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") diff --git a/libresprite/tiles/default.ase b/libresprite/tiles/default.ase index 1266ca9..a47b9c8 100644 Binary files a/libresprite/tiles/default.ase and b/libresprite/tiles/default.ase differ diff --git a/routes-native/Cargo.toml b/routes-native/Cargo.toml index 631ac24..42fcf9f 100644 --- a/routes-native/Cargo.toml +++ b/routes-native/Cargo.toml @@ -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."*"] diff --git a/routes-native/src/stateserver.rs b/routes-native/src/stateserver.rs index c7d858f..9ff061d 100644 --- a/routes-native/src/stateserver.rs +++ b/routes-native/src/stateserver.rs @@ -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 diff --git a/routes-native/src/stateserver/world.rs b/routes-native/src/stateserver/world.rs index 44a89f0..eb5e3d2 100644 --- a/routes-native/src/stateserver/world.rs +++ b/routes-native/src/stateserver/world.rs @@ -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>>, + 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(), } } } diff --git a/routes-native/src/stateserver/world/tiles.rs b/routes-native/src/stateserver/world/tiles.rs index dd126f2..7c24176 100644 --- a/routes-native/src/stateserver/world/tiles.rs +++ b/routes-native/src/stateserver/world/tiles.rs @@ -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, - #[builder(default = "vec![]")] - can_be_next_to: Vec, + 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, +} + +impl Attributelists { + pub fn new() -> Attributelists{ + let mut bedrock: Vec = vec![]; + for tiletype in Tiletypes::iter(){ + let tile = Tile::new(tiletype); + if tile.can_be_bedrock { bedrock.push(tiletype); } + } + Attributelists { bedrock } + } +}