Compare commits

..

5 commits

Author SHA1 Message Date
zoe
25acc57024 start work on placing tiles 2022-05-19 19:55:24 +02:00
zoe
2a47a75b91 start work on placing tiles 2022-05-19 19:50:00 +02:00
zoe
13ae90769b clean up codebase 2022-05-19 19:35:28 +02:00
zoe
cf27ccca4b clean up generation 2022-05-19 19:12:10 +02:00
zoe
8a98462f69 clean up generation 2022-05-19 19:01:57 +02:00
10 changed files with 88 additions and 41 deletions

Binary file not shown.

6
godot/world/Tools.gd Normal file
View file

@ -0,0 +1,6 @@
extends Node2D
enum ACTIVE {PLACE}
func _process(_delta):
pass

View file

@ -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 )

View file

@ -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

View file

@ -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)
}

View file

@ -1,9 +0,0 @@
use toml;
pub fn load (file: &str){
}
pub fn save (file: &str){
}

View file

@ -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<Vec<Vec<tiles::Tiletypes>>>,
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(),
}
}
}

View file

@ -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::<u32>() generates a random u32 which is already between 0 and u32::MAX

View file

@ -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<Tiletypes>,
pub grass: Vec<Tiletypes>,
}
impl Attributelists {
pub fn new() -> Attributelists{
let mut bedrock: Vec<Tiletypes> = vec![];
let mut grass: Vec<Tiletypes> = 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 }
}
}