diff --git a/build.sh b/build_native.sh similarity index 100% rename from build.sh rename to build_native.sh diff --git a/godot/native/libroutes_native.so b/godot/native/libroutes_native.so index 7b2aaea..66aec21 100755 Binary files a/godot/native/libroutes_native.so and b/godot/native/libroutes_native.so differ diff --git a/godot/world/Tools.gd b/godot/world/Tools.gd new file mode 100644 index 0000000..0204956 --- /dev/null +++ b/godot/world/Tools.gd @@ -0,0 +1,6 @@ +extends Node2D + +enum ACTIVE {PLACE} + +func _process(_delta): + pass diff --git a/godot/world/World.tscn b/godot/world/World.tscn index 93f171c..1e5c5c0 100644 --- a/godot/world/World.tscn +++ b/godot/world/World.tscn @@ -1,7 +1,8 @@ -[gd_scene load_steps=4 format=2] +[gd_scene load_steps=5 format=2] [ext_resource path="res://world/StateApi.gd" type="Script" id=1] [ext_resource path="res://world/Cam.tscn" type="PackedScene" id=2] +[ext_resource path="res://world/Tools.gd" type="Script" id=3] [ext_resource path="res://world/Tilemaps.gd" type="Script" id=4] [node name="World" type="Node"] @@ -11,3 +12,6 @@ script = ExtResource( 1 ) [node name="Tilemaps" type="Node" parent="."] script = ExtResource( 4 ) + +[node name="Tools" type="Node2D" parent="Tilemaps"] +script = ExtResource( 3 ) diff --git a/routes-native/src/stateserver.rs b/routes-native/src/stateserver.rs index 9ff061d..077a7ee 100644 --- a/routes-native/src/stateserver.rs +++ b/routes-native/src/stateserver.rs @@ -1,12 +1,15 @@ use gdnative::prelude::*; -mod saves; +use self::gen::GameRng; + mod world; +mod gen; #[derive(NativeClass)] #[inherit(Node)] #[register_with(Self::register)] pub struct StateServer { + rng: GameRng, world: world::World, } @@ -14,27 +17,19 @@ pub struct StateServer { impl StateServer { fn new(_owner: &Node) -> Self { StateServer { - world: world::World::new(0, 0, 0, "seed".to_string()), + world: world::World::new(0, 0, 0), + rng: gen::get_rng("seed".to_string()) } } - #[export] - fn load_from_file(&self, _owner: &Node, file: GodotString) { - saves::load(&file.to_string()); - } - - #[export] - fn save_from_file(&self, _owner: &Node, file: GodotString) { - saves::save(&file.to_string()); - } - #[export] fn _ready(&self, _owner: &Node) {} #[export] 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(); + self.rng = gen::get_rng(seed); + self.world = world::World::new(xsize, ysize, zsize); + let w = self.world.generate(&mut self.rng); _owner.emit_signal("request_init", &[]); _owner.emit_signal("changed_tiletypes", &[Variant::new(&w)]); } @@ -57,6 +52,17 @@ impl StateServer { fn is_tile_hidden(&self, _owner: &Node, x: usize, y: usize, z: usize) -> bool { self.world.is_tile_hidden(x, y, z) } + + #[export] + fn can_put_tile_at(&self, _owner: &Node, x: usize, y: usize, z: usize, id: usize) -> bool{ + self.world.can_put_tile_at(x, y, z, id) + } + + #[export] + fn put_tile_at(&mut self, _owner: &Node, x: usize, y: usize, z: usize, id: usize) -> bool{ + let success = self.world.put_tile_at(x, y, z, id); + success + } } // signals diff --git a/routes-native/src/stateserver/gen.rs b/routes-native/src/stateserver/gen.rs new file mode 100644 index 0000000..092bcf6 --- /dev/null +++ b/routes-native/src/stateserver/gen.rs @@ -0,0 +1,10 @@ +use rand::SeedableRng; + +pub type GameRng = rand_xoshiro::Xoshiro256PlusPlus; + +pub fn get_rng(seed: impl AsRef<[u8]> /* implemented by String */) -> GameRng { + // blake3::Hash is a [u8; 32] under the hood and implements From and Into to convert to and from it + let hash: [u8; 32] = blake3::hash(seed.as_ref()).into(); + // Xoshiro256++ seeds are [u8; 32] :3 + GameRng::from_seed(hash) +} diff --git a/routes-native/src/stateserver/saves.rs b/routes-native/src/stateserver/saves.rs deleted file mode 100644 index da80bd1..0000000 --- a/routes-native/src/stateserver/saves.rs +++ /dev/null @@ -1,9 +0,0 @@ -use toml; - -pub fn load (file: &str){ - -} - -pub fn save (file: &str){ - -} diff --git a/routes-native/src/stateserver/world.rs b/routes-native/src/stateserver/world.rs index 548fcd9..6da4eb2 100644 --- a/routes-native/src/stateserver/world.rs +++ b/routes-native/src/stateserver/world.rs @@ -1,5 +1,7 @@ use gdnative::prelude::*; +use self::gen::GameRng; + mod gen; mod tiles; @@ -8,7 +10,7 @@ pub struct World { pub ysize: usize, pub zsize: usize, tiles: Vec>>, - seed: String, + attributes: tiles::Attributelists, } impl World { @@ -28,10 +30,9 @@ impl World { true } - pub fn generate(&mut self) -> Vector3Array { + pub fn generate(&mut self, rng: &mut GameRng) -> Vector3Array { self.tiles = get_vec3(self.xsize, self.ysize, self.zsize); - let mut rng = gen::get_rng(self.seed.to_owned()); - let noisemap = gen::get_noise(&mut rng, (self.xsize, self.ysize)); + let noisemap = gen::get_noise(rng, (self.xsize, self.ysize)); let mut ret: Vector3Array = Vector3Array::new(); for x in 0..self.xsize { @@ -89,13 +90,29 @@ impl World { positions } - pub fn new(xsize: usize, ysize: usize, zsize: usize, seed: String) -> World { + pub fn put_tile_at(&mut self, x: usize, y: usize, z: usize, id: usize) -> bool{ + if !self.can_put_tile_at(x, y, z, id){ + return false; + } + self.tiles[x][y][z] = tiles::Tiletypes::from_repr(id as u8).unwrap(); + true + } + + 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), - seed, + attributes: tiles::Attributelists::new(), } } } diff --git a/routes-native/src/stateserver/world/gen.rs b/routes-native/src/stateserver/world/gen.rs index ad1e0a6..f4c64cb 100644 --- a/routes-native/src/stateserver/world/gen.rs +++ b/routes-native/src/stateserver/world/gen.rs @@ -2,16 +2,9 @@ use noise::{ utils::{NoiseMap, NoiseMapBuilder, PlaneMapBuilder}, Seedable, SuperSimplex, }; -use rand::{Rng, SeedableRng}; +use rand::Rng; +pub use crate::stateserver::gen::GameRng; -pub type GameRng = rand_xoshiro::Xoshiro256PlusPlus; - -pub fn get_rng(seed: impl AsRef<[u8]> /* implemented by String */) -> GameRng { - // blake3::Hash is a [u8; 32] under the hood and implements From and Into to convert to and from it - let hash: [u8; 32] = blake3::hash(seed.as_ref()).into(); - // Xoshiro256++ seeds are [u8; 32] :3 - GameRng::from_seed(hash) -} pub fn get_noise(rng: &mut GameRng, size: (usize, usize)) -> NoiseMap { // rng.gen::() generates a random u32 which is already between 0 and u32::MAX diff --git a/routes-native/src/stateserver/world/tiles.rs b/routes-native/src/stateserver/world/tiles.rs index 33f556a..d3eb774 100644 --- a/routes-native/src/stateserver/world/tiles.rs +++ b/routes-native/src/stateserver/world/tiles.rs @@ -12,6 +12,18 @@ pub enum Tiletypes { Rock, WaterSlab, GrassSlab, + SandPathTlBr, + SandPathTrBl, + SandPathCross, + SandPathCurveDD, + SandPathCurveUU, + SandPathCurveLL, + SandPathCurveRR, + SandPathTTlBr, + SandPathTrBlBr, + SandPathTrTlBl, + SandPathTlTrBr, + } #[allow(dead_code)] @@ -30,6 +42,8 @@ pub struct Tile { pub must_be_on_top: bool, #[builder(default = "true")] pub can_be_bedrock: bool, + #[builder(default = "false")] + pub is_grass: bool, } impl Tile { @@ -58,6 +72,7 @@ impl Tile { tile = TileBuilder::default() .kind(kind) .must_be_on_top(true) + .is_grass(true) .build() .unwrap() } @@ -66,6 +81,7 @@ impl Tile { .kind(kind) .must_be_on_top(true) .is_support(false) + .is_grass(true) .build() .unwrap() } @@ -87,15 +103,19 @@ impl Tile { pub struct Attributelists { pub bedrock: Vec, + pub grass: Vec, } impl Attributelists { pub fn new() -> Attributelists{ let mut bedrock: Vec = vec![]; + let mut grass: Vec = vec![]; for tiletype in Tiletypes::iter(){ let tile = Tile::new(tiletype); - if tile.can_be_bedrock { bedrock.push(tiletype); } + if tile.can_be_bedrock { bedrock.push(tiletype); + if tile.is_grass {grass.push(tiletype);} + } } - Attributelists { bedrock } + Attributelists { bedrock, grass } } }