add worldgen block observer
parent
f6dd28e5ee
commit
181168e9fd
|
@ -16,3 +16,5 @@ char *blocks_get_name(uint8_t id);
|
||||||
uint8_t blocks_get_tex_id(uint8_t id);
|
uint8_t blocks_get_tex_id(uint8_t id);
|
||||||
char blocks_get_symbol(uint8_t id);
|
char blocks_get_symbol(uint8_t id);
|
||||||
uint32_t blocks_get_flags(uint8_t id);
|
uint32_t blocks_get_flags(uint8_t id);
|
||||||
|
uint32_t blocks_get_biome(uint8_t id);
|
||||||
|
uint32_t blocks_get_kind(uint8_t id);
|
||||||
|
|
|
@ -5,6 +5,7 @@ typedef enum {
|
||||||
BLOCK_KIND_GROUND,
|
BLOCK_KIND_GROUND,
|
||||||
BLOCK_KIND_WATER,
|
BLOCK_KIND_WATER,
|
||||||
BLOCK_KIND_WALL,
|
BLOCK_KIND_WALL,
|
||||||
|
BLOCK_KIND_HILL,
|
||||||
BLOCK_KIND_HOLE,
|
BLOCK_KIND_HOLE,
|
||||||
} block_kind;
|
} block_kind;
|
||||||
|
|
||||||
|
|
|
@ -40,3 +40,11 @@ char blocks_get_symbol(uint8_t id) {
|
||||||
uint32_t blocks_get_flags(uint8_t id) {
|
uint32_t blocks_get_flags(uint8_t id) {
|
||||||
return blocks[id].flags;
|
return blocks[id].flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t blocks_get_biome(uint8_t id) {
|
||||||
|
return blocks[id].biome;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t blocks_get_kind(uint8_t id) {
|
||||||
|
return blocks[id].kind;
|
||||||
|
}
|
||||||
|
|
|
@ -4,5 +4,6 @@
|
||||||
static block blocks[] = {
|
static block blocks[] = {
|
||||||
{.tex_id = ATLAS_XY(0, 0), .name = "base-ground", .flags = 0, .kind = BLOCK_KIND_GROUND, .biome = 0, .symbol = '.'},
|
{.tex_id = ATLAS_XY(0, 0), .name = "base-ground", .flags = 0, .kind = BLOCK_KIND_GROUND, .biome = 0, .symbol = '.'},
|
||||||
{.tex_id = ATLAS_XY(1, 0), .name = "base-wall", .flags = BLOCK_FLAG_COLLISION, .kind = BLOCK_KIND_WALL, .biome = 0, .symbol = '#'},
|
{.tex_id = ATLAS_XY(1, 0), .name = "base-wall", .flags = BLOCK_FLAG_COLLISION, .kind = BLOCK_KIND_WALL, .biome = 0, .symbol = '#'},
|
||||||
|
{.tex_id = ATLAS_XY(2, 0), .name = "base-hill", .flags = BLOCK_FLAG_COLLISION, .kind = BLOCK_KIND_HILL, .biome = 0, .symbol = '^'},
|
||||||
{.tex_id = ATLAS_XY(0, 1), .name = "base-water", .flags = BLOCK_FLAG_COLLISION, .kind = BLOCK_KIND_WATER, .biome = 0, .symbol = '~'},
|
{.tex_id = ATLAS_XY(0, 1), .name = "base-water", .flags = BLOCK_FLAG_COLLISION, .kind = BLOCK_KIND_WATER, .biome = 0, .symbol = '~'},
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,19 +4,45 @@
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
static void world_fill_rect(uint32_t id, uint32_t x, uint32_t y, uint32_t w, uint32_t h) {
|
#define WORLD_BLOCK_OBSERVER(name) uint32_t name(uint32_t id, uint32_t block_idx)
|
||||||
|
typedef WORLD_BLOCK_OBSERVER(world_block_observer_proc);
|
||||||
|
|
||||||
|
static void world_fill_rect(uint32_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 cy=y; cy<y+h; cy++) {
|
||||||
for (uint32_t cx=x; cx<x+w; cx++) {
|
for (uint32_t cx=x; cx<x+w; cx++) {
|
||||||
|
if (cx < 0 || cx >= world_width) continue;
|
||||||
|
if (cy < 0 || cy >= world_height) continue;
|
||||||
uint32_t i = (cy*world_width) + cx;
|
uint32_t i = (cy*world_width) + cx;
|
||||||
|
|
||||||
|
if (proc) {
|
||||||
|
uint32_t new_id = (*proc)(id, i);
|
||||||
|
id = (new_id != BLOCK_INVALID) ? new_id : id;
|
||||||
|
}
|
||||||
|
|
||||||
world[i] = id;
|
world[i] = id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void world_fill_dot(uint32_t id, uint32_t x, uint32_t y, uint32_t w, uint32_t h) {
|
static void world_fill_rect_anchor(uint32_t id, uint32_t x, uint32_t y, uint32_t w, uint32_t h, float ax, float ay, world_block_observer_proc *proc) {
|
||||||
uint32_t w2 = (uint32_t)floor(w/2.0);
|
uint32_t w2 = (uint32_t)floorf(w*ax);
|
||||||
uint32_t h2 = (uint32_t)floor(h/2.0);
|
uint32_t h2 = (uint32_t)floorf(h*ay);
|
||||||
world_fill_rect(id, x-w2, y-h2, w, h);
|
world_fill_rect(id, x-w2, y-h2, w, h, proc);
|
||||||
|
}
|
||||||
|
|
||||||
|
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[block_idx]);
|
||||||
|
uint32_t old_kind = blocks_get_kind(world[block_idx]);
|
||||||
|
|
||||||
|
if (biome == old_biome) {
|
||||||
|
if (kind == BLOCK_KIND_WALL && kind == old_kind) {
|
||||||
|
return blocks_find(biome, BLOCK_KIND_HILL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t world_gen(int32_t seed) {
|
int32_t world_gen(int32_t seed) {
|
||||||
|
@ -27,13 +53,18 @@ int32_t world_gen(int32_t seed) {
|
||||||
uint32_t watr_id = blocks_find(BLOCK_BIOME_DEV, BLOCK_KIND_WATER);
|
uint32_t watr_id = blocks_find(BLOCK_BIOME_DEV, BLOCK_KIND_WATER);
|
||||||
|
|
||||||
// walls
|
// walls
|
||||||
world_fill_rect(wall_id, 0, 0, world_width, world_height);
|
world_fill_rect(wall_id, 0, 0, world_width, world_height, NULL);
|
||||||
|
|
||||||
// ground
|
// ground
|
||||||
world_fill_rect(grnd_id, 1, 1, world_width-2, world_height-2);
|
world_fill_rect(grnd_id, 1, 1, world_width-2, world_height-2, NULL);
|
||||||
|
|
||||||
// water
|
// water
|
||||||
world_fill_dot(watr_id, 8, 8, 4, 4);
|
world_fill_rect_anchor(watr_id, 8, 8, 4, 4, 0.5f, 0.5f, NULL);
|
||||||
|
|
||||||
|
// hills
|
||||||
|
world_fill_rect_anchor(wall_id, 14, 21, 8, 8, 0.5f, 0.5f, shaper);
|
||||||
|
world_fill_rect_anchor(wall_id, 14, 21, 4, 4, 0.5f, 0.5f, shaper);
|
||||||
|
|
||||||
|
|
||||||
return WORLD_ERROR_NONE;
|
return WORLD_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue