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
RPKIND_SPAWN_CAR,
RPKIND_PLACE_ICE_RINK,
RPKIND_PLACE_ERASE_CHANGES,
RPKIND_SPAWN_CIRCLING_DRIVER,
} replay_kind;
@ -152,6 +153,7 @@ void debug_replay_run(void) {
void ActPlaceIceRink();
void ActSpawnCirclingDriver(void);
void ActEraseWorldChanges(void);
void debug_replay_update(void) {
if (!is_playing) return;
@ -183,6 +185,9 @@ void debug_replay_update(void) {
case RPKIND_SPAWN_CIRCLING_DRIVER: {
ActSpawnCirclingDriver();
}break;
case RPKIND_PLACE_ERASE_CHANGES:{
ActEraseWorldChanges();
}break;
default: {
ZPL_PANIC("unreachable");
}break;

View File

@ -113,6 +113,7 @@ static debug_item items[] = {
.items = (debug_item[]) {
{ .kind = DITEM_BUTTON, .name = "spawn car", .on_click = ActSpawnCar },
{ .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 icemaker item", .on_click = ActSpawnIcemaker },
{

View File

@ -63,13 +63,29 @@ ActPlaceIceRink(void) {
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_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);
}
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
uint8_t

View File

@ -15,8 +15,9 @@ pkt_desc pkt_entity_view_desc[] = {
{ PKT_HALF(entity_view, vx) },
{ 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, outer_blocks) },
{ PKT_KEEP_IF(entity_view, blocks_used, 0, 2) }, // NOTE(zaklaus): skip hp for chunks
{ 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) {
entity_view *view = entity_view_tbl_get(map, ent_id);
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) {

View File

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

View File

@ -69,7 +69,7 @@ void renderer_debug_draw(void) {
void renderer_bake_chunk(uint64_t key, entity_view * data) {
if (data->kind != EKIND_CHUNK) return;
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) {

View File

@ -96,8 +96,7 @@ void *blocks_get_img(uint8_t id) {
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_len;
void blocks_build_chunk_tex(uint64_t id, uint8_t *chunk_blocks, uint8_t *outer_chunk_blocks, void *raw_view) {
world_view *view = (world_view*)raw_view;
uint16_t dims = WORLD_BLOCK_SIZE * view->chunk_size;
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 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);
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
}
}

View File

@ -27,6 +27,6 @@ float blocks_get_bounce(uint8_t id);
// NOTE(zaklaus): viewer-related functions
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_remove_chunk_tex(uint64_t id);

View File

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

View File

@ -1,6 +1,7 @@
#include "world/blocks.h"
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-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 },

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) {
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);
@ -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.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.outer_block_mapping = zpl_malloc(sizeof(uint8_t*)*zpl_square(chunk_amount));
world_snapshot_init(&streamer_snapshot, zpl_heap());
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);
world.chunk_mapping[i] = e;
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->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) {
int chk_x = chunk->x * chunk_size;
int chk_y = chunk->y * chunk_size;
uint8_t *c = &world.block_mapping[i][(y*chunk_size)+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");
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) {
librg_world_destroy(world.tracker);
ecs_fini(world.ecs);
zpl_mfree(world.data);
zpl_mfree(world.chunk_mapping);
for (int i = 0; i < zpl_square(world.chunk_amount); i+=1) {
zpl_mfree(world.block_mapping[i]);
}
zpl_mfree(world.block_mapping);
zpl_mfree(world.outer_block_mapping);
world_snapshot_destroy(&streamer_snapshot);
zpl_memset(&world, 0, sizeof(world));
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 by = (uint32_t)chy / WORLD_BLOCK_SIZE;
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
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) {
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 = {
.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]);
}
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) {
return world.block_mapping[id];
}

View File

@ -33,6 +33,7 @@ typedef struct {
uint16_t chunk_size;
uint16_t chunk_amount;
uint8_t **block_mapping;
uint8_t **outer_block_mapping;
uint16_t dim;
uint64_t tracker_update[3];
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_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_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);
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);

View File

@ -20,7 +20,7 @@ void DemoPlaceIceBlock(ecs_iter_t *it) {
if (in[i].use) {
in[i].use = false;
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
{
float px = zpl_sin(veh->heading)*400.0f;
float py = zpl_cos(veh->heading)*400.0f;
v->x += px;
v->y += py;
float px = zpl_cos(veh->heading)*400.0f;
float py = zpl_sin(veh->heading)*400.0f;
v->x += py;
v->y -= px;
}
} else {
ZPL_PANIC("unreachable code");
@ -73,10 +73,10 @@ void EnterVehicle(ecs_iter_t *it) {
}
#define VEHICLE_FORCE 34.8f
#define VEHICLE_ACCEL 0.02f
#define VEHICLE_ACCEL 0.42f
#define VEHICLE_DECEL 0.28f
#define VEHICLE_STEER 0.09f
#define VEHICLE_BRAKE_FORCE 0.04f
#define VEHICLE_STEER 3.89f
#define VEHICLE_BRAKE_FORCE 0.84f
void VehicleHandling(ecs_iter_t *it) {
Vehicle *veh = ecs_column(it, Vehicle, 1);
@ -102,14 +102,14 @@ void VehicleHandling(ecs_iter_t *it) {
if (j == 0) {
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) {
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)
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);
}
}