code: add 2nd world layer

isolation_bkp/dynres
Dominik Madarász 2021-08-30 11:59:36 +02:00
parent 083b89abd3
commit 25e9b9e57e
14 changed files with 78 additions and 21 deletions

View File

@ -10,6 +10,7 @@ typedef enum {
// NOTE(zaklaus): Special actions // NOTE(zaklaus): Special actions
RPKIND_SPAWN_CAR, RPKIND_SPAWN_CAR,
RPKIND_PLACE_ICE_RINK, RPKIND_PLACE_ICE_RINK,
RPKIND_PLACE_ERASE_CHANGES,
RPKIND_SPAWN_CIRCLING_DRIVER, RPKIND_SPAWN_CIRCLING_DRIVER,
} replay_kind; } replay_kind;
@ -152,6 +153,7 @@ void debug_replay_run(void) {
void ActPlaceIceRink(); void ActPlaceIceRink();
void ActSpawnCirclingDriver(void); void ActSpawnCirclingDriver(void);
void ActEraseWorldChanges(void);
void debug_replay_update(void) { void debug_replay_update(void) {
if (!is_playing) return; if (!is_playing) return;
@ -183,6 +185,9 @@ void debug_replay_update(void) {
case RPKIND_SPAWN_CIRCLING_DRIVER: { case RPKIND_SPAWN_CIRCLING_DRIVER: {
ActSpawnCirclingDriver(); ActSpawnCirclingDriver();
}break; }break;
case RPKIND_PLACE_ERASE_CHANGES:{
ActEraseWorldChanges();
}break;
default: { default: {
ZPL_PANIC("unreachable"); ZPL_PANIC("unreachable");
}break; }break;

View File

@ -113,6 +113,7 @@ static debug_item items[] = {
.items = (debug_item[]) { .items = (debug_item[]) {
{ .kind = DITEM_BUTTON, .name = "spawn car", .on_click = ActSpawnCar }, { .kind = DITEM_BUTTON, .name = "spawn car", .on_click = ActSpawnCar },
{ .kind = DITEM_BUTTON, .name = "place ice rink", .on_click = ActPlaceIceRink }, { .kind = DITEM_BUTTON, .name = "place ice rink", .on_click = ActPlaceIceRink },
{ .kind = DITEM_BUTTON, .name = "erase world changes", .on_click = ActEraseWorldChanges },
{ .kind = DITEM_BUTTON, .name = "spawn circling driver", .on_click = ActSpawnCirclingDriver }, { .kind = DITEM_BUTTON, .name = "spawn circling driver", .on_click = ActSpawnCirclingDriver },
{ .kind = DITEM_BUTTON, .name = "spawn icemaker item", .on_click = ActSpawnIcemaker }, { .kind = DITEM_BUTTON, .name = "spawn icemaker item", .on_click = ActSpawnIcemaker },
{ {

View File

@ -63,13 +63,29 @@ ActPlaceIceRink(void) {
for (int y = 0; y < 100; y++) { for (int y = 0; y < 100; y++) {
for (int x = 0; x < 100; x++) { for (int x = 0; x < 100; x++) {
world_block_lookup l = world_block_from_realpos((p->x - (x*bs)/2.0f), p->y - (y*bs)/2.0f); world_block_lookup l = world_block_from_realpos((p->x - (x*bs)/2.0f), p->y - (y*bs)/2.0f);
world_chunk_replace_block(world_ecs(), l.chunk_id, l.id, watr_id); world_chunk_replace_outer_block(world_ecs(), l.chunk_id, l.id, watr_id);
} }
} }
debug_replay_special_action(RPKIND_PLACE_ICE_RINK); debug_replay_special_action(RPKIND_PLACE_ICE_RINK);
} }
void
ActEraseWorldChanges(void) {
ecs_entity_t plr = camera_get().ent_id;
Position const *p = ecs_get(world_ecs(), plr, Position);
float const bs = WORLD_BLOCK_SIZE;
for (int y = 0; y < 100; y++) {
for (int x = 0; x < 100; x++) {
world_block_lookup l = world_block_from_realpos((p->x - (x*bs)/2.0f), p->y - (y*bs)/2.0f);
world_chunk_replace_outer_block(world_ecs(), l.chunk_id, l.id, 0);
}
}
debug_replay_special_action(RPKIND_PLACE_ERASE_CHANGES);
}
// NOTE(zaklaus): Replay system // NOTE(zaklaus): Replay system
uint8_t uint8_t

View File

@ -15,8 +15,9 @@ pkt_desc pkt_entity_view_desc[] = {
{ PKT_HALF(entity_view, vx) }, { PKT_HALF(entity_view, vx) },
{ PKT_HALF(entity_view, vy) }, { PKT_HALF(entity_view, vy) },
{ PKT_SKIP_IF(entity_view, blocks_used, 0, 1) }, // NOTE(zaklaus): skip blocks for anything else { PKT_SKIP_IF(entity_view, blocks_used, 0, 2) }, // NOTE(zaklaus): skip blocks for anything else
{ PKT_ARRAY(entity_view, blocks) }, { PKT_ARRAY(entity_view, blocks) },
{ PKT_ARRAY(entity_view, outer_blocks) },
{ PKT_KEEP_IF(entity_view, blocks_used, 0, 2) }, // NOTE(zaklaus): skip hp for chunks { PKT_KEEP_IF(entity_view, blocks_used, 0, 2) }, // NOTE(zaklaus): skip hp for chunks
{ PKT_HALF(entity_view, hp) }, { PKT_HALF(entity_view, hp) },
@ -96,7 +97,7 @@ void entity_view_mark_for_fadein(entity_view_tbl *map, uint64_t ent_id) {
void entity_view_update_chunk_texture(entity_view_tbl *map, uint64_t ent_id, void *world_view) { void entity_view_update_chunk_texture(entity_view_tbl *map, uint64_t ent_id, void *world_view) {
entity_view *view = entity_view_tbl_get(map, ent_id); entity_view *view = entity_view_tbl_get(map, ent_id);
if (view->kind != EKIND_CHUNK) return; if (view->kind != EKIND_CHUNK) return;
blocks_build_chunk_tex(ent_id, view->blocks, sizeof(view->blocks), world_view); blocks_build_chunk_tex(ent_id, view->blocks, view->outer_blocks, world_view);
} }
void entity_view_remove_chunk_texture(entity_view_tbl *map, uint64_t ent_id) { void entity_view_remove_chunk_texture(entity_view_tbl *map, uint64_t ent_id) {

View File

@ -47,6 +47,7 @@ typedef struct entity_view {
// TODO(zaklaus): Find a way to stream dynamic arrays // TODO(zaklaus): Find a way to stream dynamic arrays
uint8_t blocks_used; uint8_t blocks_used;
uint8_t blocks[256]; uint8_t blocks[256];
uint8_t outer_blocks[256];
uint32_t color; uint32_t color;
uint8_t is_dirty; uint8_t is_dirty;
int64_t tex; int64_t tex;

View File

@ -69,7 +69,7 @@ void renderer_debug_draw(void) {
void renderer_bake_chunk(uint64_t key, entity_view * data) { void renderer_bake_chunk(uint64_t key, entity_view * data) {
if (data->kind != EKIND_CHUNK) return; if (data->kind != EKIND_CHUNK) return;
world_view *view = game_world_view_get_active(); world_view *view = game_world_view_get_active();
blocks_build_chunk_tex(key, data->blocks, sizeof(data->blocks), view); blocks_build_chunk_tex(key, data->blocks, data->outer_blocks, view);
} }
void renderer_switch(int kind) { void renderer_switch(int kind) {

View File

@ -96,8 +96,7 @@ void *blocks_get_img(uint8_t id) {
return (void*)&blocks[id].img; return (void*)&blocks[id].img;
} }
void blocks_build_chunk_tex(uint64_t id, uint8_t *chunk_blocks, size_t blocks_len, void *raw_view) { void blocks_build_chunk_tex(uint64_t id, uint8_t *chunk_blocks, uint8_t *outer_chunk_blocks, void *raw_view) {
(void)blocks_len;
world_view *view = (world_view*)raw_view; world_view *view = (world_view*)raw_view;
uint16_t dims = WORLD_BLOCK_SIZE * view->chunk_size; uint16_t dims = WORLD_BLOCK_SIZE * view->chunk_size;
RenderTexture2D canvas = LoadRenderTexture(dims, dims); RenderTexture2D canvas = LoadRenderTexture(dims, dims);
@ -118,6 +117,11 @@ void blocks_build_chunk_tex(uint64_t id, uint8_t *chunk_blocks, size_t blocks_le
Rectangle src = {0, 0, WORLD_BLOCK_SIZE, WORLD_BLOCK_SIZE}; Rectangle src = {0, 0, WORLD_BLOCK_SIZE, WORLD_BLOCK_SIZE};
Rectangle dst = {x*WORLD_BLOCK_SIZE + half_block, y*WORLD_BLOCK_SIZE + half_block, WORLD_BLOCK_SIZE, WORLD_BLOCK_SIZE}; Rectangle dst = {x*WORLD_BLOCK_SIZE + half_block, y*WORLD_BLOCK_SIZE + half_block, WORLD_BLOCK_SIZE, WORLD_BLOCK_SIZE};
DrawTexturePro(blk, src, dst, (Vector2){half_block, half_block}, rot, WHITE); DrawTexturePro(blk, src, dst, (Vector2){half_block, half_block}, rot, WHITE);
if (outer_chunk_blocks[(y*view->chunk_size)+x] != 0) {
Texture2D blk2 = blocks[outer_chunk_blocks[(y*view->chunk_size)+x]].img;
DrawTexturePro(blk2, src, dst, (Vector2){half_block, half_block}, rot, WHITE);
}
#endif #endif
} }
} }

View File

@ -27,6 +27,6 @@ float blocks_get_bounce(uint8_t id);
// NOTE(zaklaus): viewer-related functions // NOTE(zaklaus): viewer-related functions
void *blocks_get_img(uint8_t id); void *blocks_get_img(uint8_t id);
void blocks_build_chunk_tex(uint64_t id, uint8_t *blocks, size_t blocks_len, void *view); void blocks_build_chunk_tex(uint64_t id, uint8_t *blocks, uint8_t *outer_blocks, void *view);
void *blocks_get_chunk_tex(uint64_t id); void *blocks_get_chunk_tex(uint64_t id);
void blocks_remove_chunk_tex(uint64_t id); void blocks_remove_chunk_tex(uint64_t id);

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
typedef enum { typedef enum {
BLOCK_KIND_EMPTY,
BLOCK_KIND_DEV, BLOCK_KIND_DEV,
BLOCK_KIND_GROUND, BLOCK_KIND_GROUND,
BLOCK_KIND_DIRT, BLOCK_KIND_DIRT,

View File

@ -1,6 +1,7 @@
#include "world/blocks.h" #include "world/blocks.h"
static block blocks[] = { static block blocks[] = {
{.name = "empty", .flags = 0, .kind = BLOCK_KIND_EMPTY, .biome = 0, .symbol = ' ', .drag = 1.0f, .friction = 1.0f },
{.name = "base-ground", .flags = 0, .kind = BLOCK_KIND_GROUND, .biome = 0, .symbol = '.', .drag = 1.0f, .friction = 1.0f }, {.name = "base-ground", .flags = 0, .kind = BLOCK_KIND_GROUND, .biome = 0, .symbol = '.', .drag = 1.0f, .friction = 1.0f },
{.name = "base-dirt", .flags = 0, .kind = BLOCK_KIND_DIRT, .biome = 0, .symbol = ',', .drag = 2.1f , .friction = 1.0f }, {.name = "base-dirt", .flags = 0, .kind = BLOCK_KIND_DIRT, .biome = 0, .symbol = ',', .drag = 2.1f , .friction = 1.0f },
{.name = "base-wall", .flags = BLOCK_FLAG_COLLISION, .kind = BLOCK_KIND_WALL, .biome = 0, .symbol = '#', .drag = 1.0f , .friction = 1.0f, .bounce = 1.0f }, {.name = "base-wall", .flags = BLOCK_FLAG_COLLISION, .kind = BLOCK_KIND_WALL, .biome = 0, .symbol = '#', .drag = 1.0f , .friction = 1.0f, .bounce = 1.0f },

View File

@ -68,6 +68,10 @@ entity_view world_build_entity_view(int64_t e) {
for (int i = 0; i < world.chunk_size*world.chunk_size; i += 1) { for (int i = 0; i < world.chunk_size*world.chunk_size; i += 1) {
view.blocks[i] = world.block_mapping[chpos->id][i]; view.blocks[i] = world.block_mapping[chpos->id][i];
} }
for (int i = 0; i < world.chunk_size*world.chunk_size; i += 1) {
view.outer_blocks[i] = world.outer_block_mapping[chpos->id][i];
}
} }
world_snapshot_set(&streamer_snapshot, e, view); world_snapshot_set(&streamer_snapshot, e, view);
@ -164,6 +168,7 @@ int32_t world_init(int32_t seed, uint16_t chunk_size, uint16_t chunk_amount) {
world.ecs_update = ecs_query_new(world.ecs, "components.ClientInfo, components.Position"); world.ecs_update = ecs_query_new(world.ecs, "components.ClientInfo, components.Position");
world.chunk_mapping = zpl_malloc(sizeof(ecs_entity_t)*zpl_square(chunk_amount)); world.chunk_mapping = zpl_malloc(sizeof(ecs_entity_t)*zpl_square(chunk_amount));
world.block_mapping = zpl_malloc(sizeof(uint8_t*)*zpl_square(chunk_amount)); world.block_mapping = zpl_malloc(sizeof(uint8_t*)*zpl_square(chunk_amount));
world.outer_block_mapping = zpl_malloc(sizeof(uint8_t*)*zpl_square(chunk_amount));
world_snapshot_init(&streamer_snapshot, zpl_heap()); world_snapshot_init(&streamer_snapshot, zpl_heap());
int32_t world_build_status = worldgen_test(&world); int32_t world_build_status = worldgen_test(&world);
@ -178,6 +183,7 @@ int32_t world_init(int32_t seed, uint16_t chunk_size, uint16_t chunk_amount) {
librg_chunk_to_chunkpos(world.tracker, i, &chunk->x, &chunk->y, NULL); librg_chunk_to_chunkpos(world.tracker, i, &chunk->x, &chunk->y, NULL);
world.chunk_mapping[i] = e; world.chunk_mapping[i] = e;
world.block_mapping[i] = zpl_malloc(sizeof(uint8_t)*zpl_square(chunk_size)); world.block_mapping[i] = zpl_malloc(sizeof(uint8_t)*zpl_square(chunk_size));
world.outer_block_mapping[i] = zpl_malloc(sizeof(uint8_t)*zpl_square(chunk_size));
chunk->id = i; chunk->id = i;
chunk->is_dirty = false; chunk->is_dirty = false;
@ -185,12 +191,19 @@ int32_t world_init(int32_t seed, uint16_t chunk_size, uint16_t chunk_amount) {
for (int x = 0; x < chunk_size; x += 1) { for (int x = 0; x < chunk_size; x += 1) {
int chk_x = chunk->x * chunk_size; int chk_x = chunk->x * chunk_size;
int chk_y = chunk->y * chunk_size; int chk_y = chunk->y * chunk_size;
uint8_t *c = &world.block_mapping[i][(y*chunk_size)+x]; uint8_t *c = &world.block_mapping[i][(y*chunk_size)+x];
*c = world.data[(chk_y+y)*world.dim + (chk_x+x)]; *c = world.data[(chk_y+y)*world.dim + (chk_x+x)];
c = &world.outer_block_mapping[i][(y*chunk_size)+x];
*c = 0;
} }
} }
} }
zpl_mfree(world.data);
world.data = NULL;
zpl_printf("[INFO] Created a new server world\n"); zpl_printf("[INFO] Created a new server world\n");
return world_build_status; return world_build_status;
@ -199,12 +212,12 @@ int32_t world_init(int32_t seed, uint16_t chunk_size, uint16_t chunk_amount) {
int32_t world_destroy(void) { int32_t world_destroy(void) {
librg_world_destroy(world.tracker); librg_world_destroy(world.tracker);
ecs_fini(world.ecs); ecs_fini(world.ecs);
zpl_mfree(world.data);
zpl_mfree(world.chunk_mapping); zpl_mfree(world.chunk_mapping);
for (int i = 0; i < zpl_square(world.chunk_amount); i+=1) { for (int i = 0; i < zpl_square(world.chunk_amount); i+=1) {
zpl_mfree(world.block_mapping[i]); zpl_mfree(world.block_mapping[i]);
} }
zpl_mfree(world.block_mapping); zpl_mfree(world.block_mapping);
zpl_mfree(world.outer_block_mapping);
world_snapshot_destroy(&streamer_snapshot); world_snapshot_destroy(&streamer_snapshot);
zpl_memset(&world, 0, sizeof(world)); zpl_memset(&world, 0, sizeof(world));
zpl_printf("[INFO] World was destroyed.\n"); zpl_printf("[INFO] World was destroyed.\n");
@ -331,7 +344,10 @@ world_block_lookup world_block_from_realpos(float x, float y) {
uint32_t bx = (uint32_t)chx / WORLD_BLOCK_SIZE; uint32_t bx = (uint32_t)chx / WORLD_BLOCK_SIZE;
uint32_t by = (uint32_t)chy / WORLD_BLOCK_SIZE; uint32_t by = (uint32_t)chy / WORLD_BLOCK_SIZE;
uint32_t block_idx = (by*world.chunk_size)+bx; uint32_t block_idx = (by*world.chunk_size)+bx;
uint8_t block_id = world.block_mapping[chunk_id][block_idx]; uint8_t block_id = world.outer_block_mapping[chunk_id][block_idx];
if (block_id == 0) {
block_id = world.block_mapping[chunk_id][block_idx];
}
// NOTE(zaklaus): pos relative to block's center // NOTE(zaklaus): pos relative to block's center
float box = chx - bx * WORLD_BLOCK_SIZE - WORLD_BLOCK_SIZE/2.0f; float box = chx - bx * WORLD_BLOCK_SIZE - WORLD_BLOCK_SIZE/2.0f;
@ -350,7 +366,10 @@ world_block_lookup world_block_from_realpos(float x, float y) {
} }
world_block_lookup world_block_from_index(int64_t id, uint16_t block_idx) { world_block_lookup world_block_from_index(int64_t id, uint16_t block_idx) {
uint8_t block_id = world.block_mapping[id][block_idx]; uint8_t block_id = world.outer_block_mapping[id][block_idx];
if (block_id == 0) {
block_id = world.block_mapping[id][block_idx];
}
world_block_lookup lookup = { world_block_lookup lookup = {
.id = block_idx, .id = block_idx,
@ -377,6 +396,12 @@ void world_chunk_replace_block(ecs_world_t *ecs, int64_t id, uint16_t block_idx,
world_chunk_mark_dirty(ecs, world.chunk_mapping[id]); world_chunk_mark_dirty(ecs, world.chunk_mapping[id]);
} }
void world_chunk_replace_outer_block(ecs_world_t *ecs, int64_t id, uint16_t block_idx, uint8_t block_id) {
ZPL_ASSERT(block_idx >= 0 && block_idx < zpl_square(world.chunk_size));
world.outer_block_mapping[id][block_idx] = block_id;
world_chunk_mark_dirty(ecs, world.chunk_mapping[id]);
}
uint8_t *world_chunk_get_blocks(int64_t id) { uint8_t *world_chunk_get_blocks(int64_t id) {
return world.block_mapping[id]; return world.block_mapping[id];
} }

View File

@ -33,6 +33,7 @@ typedef struct {
uint16_t chunk_size; uint16_t chunk_size;
uint16_t chunk_amount; uint16_t chunk_amount;
uint8_t **block_mapping; uint8_t **block_mapping;
uint8_t **outer_block_mapping;
uint16_t dim; uint16_t dim;
uint64_t tracker_update[3]; uint64_t tracker_update[3];
uint8_t active_layer_id; uint8_t active_layer_id;
@ -74,6 +75,7 @@ world_block_lookup world_block_from_index(int64_t id, uint16_t block_idx);
int64_t world_chunk_from_realpos(float x, float y); int64_t world_chunk_from_realpos(float x, float y);
int64_t world_chunk_from_entity(ecs_entity_t id); int64_t world_chunk_from_entity(ecs_entity_t id);
void world_chunk_replace_block(ecs_world_t *ecs, int64_t id, uint16_t block_idx, uint8_t block_id); void world_chunk_replace_block(ecs_world_t *ecs, int64_t id, uint16_t block_idx, uint8_t block_id);
void world_chunk_replace_outer_block(ecs_world_t *ecs, int64_t id, uint16_t block_idx, uint8_t block_id);
uint8_t *world_chunk_get_blocks(int64_t id); uint8_t *world_chunk_get_blocks(int64_t id);
void world_chunk_mark_dirty(ecs_world_t *ecs, ecs_entity_t e); void world_chunk_mark_dirty(ecs_world_t *ecs, ecs_entity_t e);
uint8_t world_chunk_is_dirty(ecs_world_t *ecs, ecs_entity_t e); uint8_t world_chunk_is_dirty(ecs_world_t *ecs, ecs_entity_t e);

View File

@ -20,7 +20,7 @@ void DemoPlaceIceBlock(ecs_iter_t *it) {
if (in[i].use) { if (in[i].use) {
in[i].use = false; in[i].use = false;
world_block_lookup l = world_block_from_realpos(p[i].x, p[i].y); world_block_lookup l = world_block_from_realpos(p[i].x, p[i].y);
world_chunk_replace_block(it->world, l.chunk_id, l.id, watr_id); world_chunk_replace_outer_block(it->world, l.chunk_id, l.id, watr_id);
} }
} }
} }

View File

@ -24,10 +24,10 @@ void LeaveVehicle(ecs_iter_t *it) {
// NOTE(zaklaus): push passenger out // NOTE(zaklaus): push passenger out
{ {
float px = zpl_sin(veh->heading)*400.0f; float px = zpl_cos(veh->heading)*400.0f;
float py = zpl_cos(veh->heading)*400.0f; float py = zpl_sin(veh->heading)*400.0f;
v->x += px; v->x += py;
v->y += py; v->y -= px;
} }
} else { } else {
ZPL_PANIC("unreachable code"); ZPL_PANIC("unreachable code");
@ -73,10 +73,10 @@ void EnterVehicle(ecs_iter_t *it) {
} }
#define VEHICLE_FORCE 34.8f #define VEHICLE_FORCE 34.8f
#define VEHICLE_ACCEL 0.02f #define VEHICLE_ACCEL 0.42f
#define VEHICLE_DECEL 0.28f #define VEHICLE_DECEL 0.28f
#define VEHICLE_STEER 0.09f #define VEHICLE_STEER 3.89f
#define VEHICLE_BRAKE_FORCE 0.04f #define VEHICLE_BRAKE_FORCE 0.84f
void VehicleHandling(ecs_iter_t *it) { void VehicleHandling(ecs_iter_t *it) {
Vehicle *veh = ecs_column(it, Vehicle, 1); Vehicle *veh = ecs_column(it, Vehicle, 1);
@ -102,14 +102,14 @@ void VehicleHandling(ecs_iter_t *it) {
if (j == 0) { if (j == 0) {
Input const* in = ecs_get(it->world, pe, Input); Input const* in = ecs_get(it->world, pe, Input);
car->force += zpl_lerp(0.0f, in->y * VEHICLE_FORCE, VEHICLE_ACCEL); car->force += zpl_lerp(0.0f, in->y * VEHICLE_FORCE, VEHICLE_ACCEL*it->delta_time);
if (in->sprint) { if (in->sprint) {
car->force = zpl_lerp(car->force, 0.0f, VEHICLE_BRAKE_FORCE); car->force = zpl_lerp(car->force, 0.0f, VEHICLE_BRAKE_FORCE*it->delta_time);
if (zpl_abs(car->force) < 5.5f) if (zpl_abs(car->force) < 5.5f)
car->force = 0.0f; car->force = 0.0f;
} }
car->steer += in->x * VEHICLE_STEER; car->steer += (in->x * VEHICLE_STEER)*it->delta_time;
car->steer = zpl_clamp(car->steer, -40.0f, 40.0f); car->steer = zpl_clamp(car->steer, -40.0f, 40.0f);
} }
} }