small worldgen reorg

isolation_bkp/dynres
Dominik Madarász 2021-05-12 16:02:12 +02:00
parent 468a78873c
commit 1c72255e09
5 changed files with 52 additions and 44 deletions

View File

@ -3,6 +3,8 @@ set(SRCS ${SRCS}
world/blocks.c
world/perlin.c
world/world.c
world/worldgen/worldgen_test.c
)
include_directories(../modules . world)
add_library(eco2d-common STATIC ${SRCS})

View File

@ -5,31 +5,13 @@
#include "modules/physics.h"
#include "world/world.h"
#include "entity_view.h"
#include "worldgen/worldgen.h"
#include "platform.h"
#include "packets/pkt_send_librg_update.h"
typedef struct {
uint8_t *data;
uint32_t seed;
uint32_t size;
uint16_t block_size;
uint16_t chunk_size;
uint16_t chunk_amount;
uint16_t dim;
uint64_t tracker_update[3];
uint8_t active_layer_id;
ecs_world_t *ecs;
ecs_query_t *ecs_update;
librg_world *tracker;
world_pkt_reader_proc *reader_proc;
world_pkt_writer_proc *writer_proc;
} world_data;
static world_data world = {0};
int32_t world_gen();
entity_view world_build_entity_view(int64_t e) {
ECS_IMPORT(world_ecs(), General);
ECS_IMPORT(world_ecs(), Physics);
@ -76,8 +58,8 @@ int32_t tracker_write_create(librg_world *w, librg_event *e) {
}
int32_t tracker_write_remove(librg_world *w, librg_event *e) {
zpl_unused(e);
zpl_unused(w);
(void)e;
(void)w;
#ifdef WORLD_LAYERING
if (world.active_layer_id != WORLD_TRACKER_LAYERS-1) {
// NOTE(zaklaus): reject updates from smaller layers
@ -153,7 +135,7 @@ int32_t world_init(int32_t seed, uint16_t block_size, uint16_t chunk_size, uint1
ECS_IMPORT(world.ecs, Net);
world.ecs_update = ecs_query_new(world.ecs, "net.ClientInfo, general.Position");
int32_t world_build_status = world_gen();
int32_t world_build_status = worldgen_test(&world);
ZPL_ASSERT(world_build_status >= 0);
for (int i = 0; i < world.chunk_amount * world.chunk_amount; ++i) {
@ -211,7 +193,7 @@ static void world_tracker_update(uint8_t ticker, uint32_t freq, uint8_t radius)
zpl_printf("[error] an error happened writing the world %d\n", result);
}
pkt_send_librg_update((void*)p[i].peer, p[i].view_id, ticker, buffer, datalen);
pkt_send_librg_update((uint64_t)p[i].peer, p[i].view_id, ticker, buffer, datalen);
}
}
}
@ -271,5 +253,3 @@ uint16_t world_chunk_amount(void) {
uint16_t world_dim(void) {
return world.block_size * world.chunk_size * world.chunk_amount;
}
#include "world_gen.c"

View File

@ -23,6 +23,23 @@ typedef WORLD_PKT_READER(world_pkt_reader_proc);
#define WORLD_PKT_WRITER(name) int32_t name(pkt_header *pkt, void *udata)
typedef WORLD_PKT_WRITER(world_pkt_writer_proc);
typedef struct {
uint8_t *data;
uint32_t seed;
uint32_t size;
uint16_t block_size;
uint16_t chunk_size;
uint16_t chunk_amount;
uint16_t dim;
uint64_t tracker_update[3];
uint8_t active_layer_id;
ecs_world_t *ecs;
ecs_query_t *ecs_update;
librg_world *tracker;
world_pkt_reader_proc *reader_proc;
world_pkt_writer_proc *writer_proc;
} world_data;
void world_setup_pkt_handlers(world_pkt_reader_proc *reader_proc, world_pkt_writer_proc *writer_proc);
int32_t world_init(int32_t seed, uint16_t block_size, uint16_t chunk_size, uint16_t chunk_amount);
int32_t world_destroy(void);

View File

@ -0,0 +1,4 @@
#pragma once
#include "system.h"
int32_t worldgen_test(void *world);

View File

@ -13,12 +13,14 @@ typedef WORLD_BLOCK_OBSERVER(world_block_observer_proc);
#define WORLD_PERLIN_FREQ 1.0
#define WORLD_PERLIN_OCTAVES 1
static world_data *world;
static void world_fill_rect(uint8_t id, uint32_t x, uint32_t y, uint32_t w, uint32_t h, world_block_observer_proc *proc) {
for (uint32_t cy=y; cy<y+h; cy++) {
for (uint32_t cx=x; cx<x+w; cx++) {
if (cx < 0 || cx >= world.dim) continue;
if (cy < 0 || cy >= world.dim) continue;
uint32_t i = (cy*world.dim) + cx;
if (cx < 0 || cx >= world->dim) continue;
if (cy < 0 || cy >= world->dim) continue;
uint32_t i = (cy*world->dim) + cx;
if (proc) {
uint8_t new_id = (*proc)(id, i);
@ -28,7 +30,7 @@ static void world_fill_rect(uint8_t id, uint32_t x, uint32_t y, uint32_t w, uint
else continue;
}
world.data[i] = id;
world->data[i] = id;
}
}
}
@ -36,9 +38,9 @@ static void world_fill_rect(uint8_t id, uint32_t x, uint32_t y, uint32_t w, uint
static void world_fill_circle(uint8_t id, uint32_t x, uint32_t y, uint32_t w, uint32_t h, world_block_observer_proc *proc) {
for (uint32_t cy=y; cy<y+h; cy++) {
for (uint32_t cx=x; cx<x+w; cx++) {
if (cx < 0 || cx >= world.dim) continue;
if (cy < 0 || cy >= world.dim) continue;
uint32_t i = (cy*world.dim) + cx;
if (cx < 0 || cx >= world->dim) continue;
if (cy < 0 || cy >= world->dim) continue;
uint32_t i = (cy*world->dim) + cx;
if (proc) {
uint8_t new_id = (*proc)(id, i);
@ -48,7 +50,7 @@ static void world_fill_circle(uint8_t id, uint32_t x, uint32_t y, uint32_t w, ui
else continue;
}
world.data[i] = id;
world->data[i] = id;
}
}
}
@ -62,8 +64,8 @@ static void world_fill_rect_anchor(uint8_t id, uint32_t x, uint32_t y, uint32_t
static WORLD_BLOCK_OBSERVER(shaper) {
uint32_t biome = blocks_get_biome(id);
uint32_t kind = blocks_get_kind(id);
uint32_t old_biome = blocks_get_biome(world.data[block_idx]);
uint32_t old_kind = blocks_get_kind(world.data[block_idx]);
uint32_t old_biome = blocks_get_biome(world->data[block_idx]);
uint32_t old_kind = blocks_get_kind(world->data[block_idx]);
if (biome == old_biome) {
if (kind == BLOCK_KIND_WALL && kind == old_kind) {
@ -78,10 +80,10 @@ static WORLD_BLOCK_OBSERVER(shaper) {
}
static uint8_t world_perlin_cond(uint32_t block_idx, double chance) {
uint32_t x = block_idx % world.dim;
uint32_t y = block_idx / world.dim;
uint32_t x = block_idx % world->dim;
uint32_t y = block_idx / world->dim;
return perlin_fbm(world.seed, x, y, WORLD_PERLIN_FREQ, WORLD_PERLIN_OCTAVES) < chance;
return perlin_fbm(world->seed, x, y, WORLD_PERLIN_FREQ, WORLD_PERLIN_OCTAVES) < chance;
}
static WORLD_BLOCK_OBSERVER(shaper_noise80) {
@ -104,31 +106,34 @@ static void world_fill_mountain(uint32_t x, uint32_t y) {
#define RAND_RANGE(x,y) (x + (int)rand()%(y-(x)))
int32_t world_gen() {
int32_t worldgen_test(world_data *wld) {
// TODO(zaklaus): pass world as an arg instead
world = wld;
// TODO: perform world gen
// atm, we will fill the world with ground and surround it by walls
uint8_t wall_id = blocks_find(BLOCK_BIOME_DEV, BLOCK_KIND_WALL);
uint8_t grnd_id = blocks_find(BLOCK_BIOME_DEV, BLOCK_KIND_GROUND);
uint8_t watr_id = blocks_find(BLOCK_BIOME_DEV, BLOCK_KIND_WATER);
srand(world.seed);
srand(world->seed);
// walls
world_fill_rect(wall_id, 0, 0, world.dim, world.dim, NULL);
world_fill_rect(wall_id, 0, 0, world->dim, world->dim, NULL);
// ground
world_fill_rect(grnd_id, 1, 1, world.dim-2, world.dim-2, NULL);
world_fill_rect(grnd_id, 1, 1, world->dim-2, world->dim-2, NULL);
// water
for (int i=0; i<RAND_RANGE(0, 12); i++) {
world_fill_rect_anchor(watr_id, RAND_RANGE(0, world.dim), RAND_RANGE(0, world.dim), 4+RAND_RANGE(0,3), 4+RAND_RANGE(0,3), 0.5f, 0.5f, shaper_noise33);
world_fill_rect_anchor(watr_id, RAND_RANGE(0, world->dim), RAND_RANGE(0, world->dim), 4+RAND_RANGE(0,3), 4+RAND_RANGE(0,3), 0.5f, 0.5f, shaper_noise33);
}
const uint32_t HILLS_SIZE = 21;
// hills
for (int i=0; i<RAND_RANGE(8, 224); i++) {
world_fill_rect_anchor(wall_id, RAND_RANGE(0, world.dim), RAND_RANGE(0, world.dim), RAND_RANGE(0,HILLS_SIZE), RAND_RANGE(0,HILLS_SIZE), 0.5f, 0.5f, shaper_noise33);
world_fill_rect_anchor(wall_id, RAND_RANGE(0, world->dim), RAND_RANGE(0, world->dim), RAND_RANGE(0,HILLS_SIZE), RAND_RANGE(0,HILLS_SIZE), 0.5f, 0.5f, shaper_noise33);
}
return WORLD_ERROR_NONE;