code: add 2nd world layer
parent
083b89abd3
commit
25e9b9e57e
|
@ -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;
|
||||
|
|
|
@ -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 },
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
typedef enum {
|
||||
BLOCK_KIND_EMPTY,
|
||||
BLOCK_KIND_DEV,
|
||||
BLOCK_KIND_GROUND,
|
||||
BLOCK_KIND_DIRT,
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue