diff --git a/code/apps/server/header/blocks.h b/code/apps/server/header/blocks.h index c9b7730..5fe3c3e 100644 --- a/code/apps/server/header/blocks.h +++ b/code/apps/server/header/blocks.h @@ -16,3 +16,5 @@ char *blocks_get_name(uint8_t id); uint8_t blocks_get_tex_id(uint8_t id); char blocks_get_symbol(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); diff --git a/code/apps/server/header/blocks_info.h b/code/apps/server/header/blocks_info.h index 547b70c..de479c1 100644 --- a/code/apps/server/header/blocks_info.h +++ b/code/apps/server/header/blocks_info.h @@ -5,6 +5,7 @@ typedef enum { BLOCK_KIND_GROUND, BLOCK_KIND_WATER, BLOCK_KIND_WALL, + BLOCK_KIND_HILL, BLOCK_KIND_HOLE, } block_kind; diff --git a/code/apps/server/source/blocks.c b/code/apps/server/source/blocks.c index 221abaa..625623b 100644 --- a/code/apps/server/source/blocks.c +++ b/code/apps/server/source/blocks.c @@ -40,3 +40,11 @@ char blocks_get_symbol(uint8_t id) { uint32_t blocks_get_flags(uint8_t id) { 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; +} diff --git a/code/apps/server/source/blocks_list.c b/code/apps/server/source/blocks_list.c index 47c0731..45d93c3 100644 --- a/code/apps/server/source/blocks_list.c +++ b/code/apps/server/source/blocks_list.c @@ -4,5 +4,6 @@ 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(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 = '~'}, }; diff --git a/code/apps/server/source/world_gen.c b/code/apps/server/source/world_gen.c index 2747476..da910c7 100644 --- a/code/apps/server/source/world_gen.c +++ b/code/apps/server/source/world_gen.c @@ -4,19 +4,45 @@ #include -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= world_width) continue; + if (cy < 0 || cy >= world_height) continue; 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; } } } -static void world_fill_dot(uint32_t id, uint32_t x, uint32_t y, uint32_t w, uint32_t h) { - uint32_t w2 = (uint32_t)floor(w/2.0); - uint32_t h2 = (uint32_t)floor(h/2.0); - world_fill_rect(id, x-w2, y-h2, w, 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)floorf(w*ax); + uint32_t h2 = (uint32_t)floorf(h*ay); + 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) { @@ -27,13 +53,18 @@ int32_t world_gen(int32_t seed) { uint32_t watr_id = blocks_find(BLOCK_BIOME_DEV, BLOCK_KIND_WATER); // 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 - 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 - 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; }