client-side block query api
parent
2527a40231
commit
026a1e01c7
|
@ -69,7 +69,7 @@ void buildmode_draw(void) {
|
||||||
qty = item->quantity;
|
qty = item->quantity;
|
||||||
}
|
}
|
||||||
|
|
||||||
world_block_lookup l = world_block_from_realpos((float)cam.x, (float)cam.y);
|
world_view_block_lookup l = world_view_block_from_realpos(game_world_view_get_active(), (float)cam.x, (float)cam.y);
|
||||||
if (build_is_deletion_mode && !l.is_outer){
|
if (build_is_deletion_mode && !l.is_outer){
|
||||||
renderer_draw_single((float)cam.x, (float)cam.y, ASSET_BUILDMODE_HIGHLIGHT, ColorAlpha(RED, 0.4f));
|
renderer_draw_single((float)cam.x, (float)cam.y, ASSET_BUILDMODE_HIGHLIGHT, ColorAlpha(RED, 0.4f));
|
||||||
goto build_skip_placements;
|
goto build_skip_placements;
|
||||||
|
|
|
@ -15,7 +15,8 @@ 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, 2) }, // NOTE(zaklaus): skip blocks for anything else
|
{ PKT_SKIP_IF(entity_view, blocks_used, 0, 3) }, // NOTE(zaklaus): skip blocks for anything else
|
||||||
|
{ PKT_UINT(entity_view, chk_id) },
|
||||||
{ PKT_ARRAY(entity_view, blocks) },
|
{ PKT_ARRAY(entity_view, blocks) },
|
||||||
{ PKT_ARRAY(entity_view, outer_blocks) },
|
{ PKT_ARRAY(entity_view, outer_blocks) },
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ typedef struct entity_view {
|
||||||
float max_hp;
|
float max_hp;
|
||||||
|
|
||||||
// TODO(zaklaus): Find a way to stream dynamic arrays
|
// TODO(zaklaus): Find a way to stream dynamic arrays
|
||||||
|
uint32_t chk_id;
|
||||||
uint8_t blocks_used;
|
uint8_t blocks_used;
|
||||||
block_id blocks[256];
|
block_id blocks[256];
|
||||||
block_id outer_blocks[256];
|
block_id outer_blocks[256];
|
||||||
|
|
|
@ -108,6 +108,7 @@ entity_view *world_build_entity_view(int64_t e) {
|
||||||
|
|
||||||
Chunk *chunk = 0;
|
Chunk *chunk = 0;
|
||||||
if ((chunk = ecs_get_mut_if(world_ecs(), e, Chunk))) {
|
if ((chunk = ecs_get_mut_if(world_ecs(), e, Chunk))) {
|
||||||
|
view.chk_id = chunk->id;
|
||||||
view.x = chunk->x;
|
view.x = chunk->x;
|
||||||
view.y = chunk->y;
|
view.y = chunk->y;
|
||||||
view.blocks_used = 1;
|
view.blocks_used = 1;
|
||||||
|
|
|
@ -11,6 +11,12 @@
|
||||||
int32_t tracker_read_remove(librg_world *w, librg_event *e) {
|
int32_t tracker_read_remove(librg_world *w, librg_event *e) {
|
||||||
int64_t entity_id = librg_event_entity_get(w, e);
|
int64_t entity_id = librg_event_entity_get(w, e);
|
||||||
world_view *view = (world_view*)librg_world_userdata_get(w);
|
world_view *view = (world_view*)librg_world_userdata_get(w);
|
||||||
|
entity_view *ent = entity_view_get(&view->entities, entity_id);
|
||||||
|
|
||||||
|
if (ent && ent->kind == EKIND_CHUNK) {
|
||||||
|
world_view_clear_chunk(view, ent);
|
||||||
|
}
|
||||||
|
|
||||||
entity_view_remove_chunk_texture(&view->entities, entity_id);
|
entity_view_remove_chunk_texture(&view->entities, entity_id);
|
||||||
entity_view_destroy(&view->entities, entity_id);
|
entity_view_destroy(&view->entities, entity_id);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -40,6 +46,11 @@ int32_t tracker_read_update(librg_world *w, librg_event *e) {
|
||||||
entity_view_update_or_create(&view->entities, entity_id, data);
|
entity_view_update_or_create(&view->entities, entity_id, data);
|
||||||
entity_view_remove_chunk_texture(&view->entities, entity_id);
|
entity_view_remove_chunk_texture(&view->entities, entity_id);
|
||||||
entity_view_update_chunk_texture(&view->entities, entity_id, view);
|
entity_view_update_chunk_texture(&view->entities, entity_id, view);
|
||||||
|
|
||||||
|
if (data.kind == EKIND_CHUNK) {
|
||||||
|
entity_view *chk = entity_view_get(&view->entities, entity_id);
|
||||||
|
world_view_setup_chunk(view, chk);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,6 +73,11 @@ int32_t tracker_read_create(librg_world *w, librg_event *e) {
|
||||||
entity_view_update_or_create(&view->entities, entity_id, data);
|
entity_view_update_or_create(&view->entities, entity_id, data);
|
||||||
entity_view_mark_for_fadein(&view->entities, entity_id);
|
entity_view_mark_for_fadein(&view->entities, entity_id);
|
||||||
entity_view_update_chunk_texture(&view->entities, entity_id, view);
|
entity_view_update_chunk_texture(&view->entities, entity_id, view);
|
||||||
|
|
||||||
|
if (data.kind == EKIND_CHUNK) {
|
||||||
|
entity_view *chk = entity_view_get(&view->entities, entity_id);
|
||||||
|
world_view_setup_chunk(view, chk);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,10 +95,14 @@ void world_view_init(world_view *view, uint32_t seed, uint64_t ent_id, uint16_t
|
||||||
view->chunk_size = chunk_size;
|
view->chunk_size = chunk_size;
|
||||||
view->chunk_amount = chunk_amount;
|
view->chunk_amount = chunk_amount;
|
||||||
view->dim = WORLD_BLOCK_SIZE * chunk_size * chunk_amount;
|
view->dim = WORLD_BLOCK_SIZE * chunk_size * chunk_amount;
|
||||||
|
view->chk_dim = chunk_size * chunk_amount;
|
||||||
view->size = view->dim * view->dim;
|
view->size = view->dim * view->dim;
|
||||||
|
view->chunk_mapping = zpl_malloc(sizeof(entity_view*)*zpl_square(view->chunk_amount));
|
||||||
|
view->block_mapping = zpl_malloc(sizeof(block_id*)*zpl_square(view->chunk_amount));
|
||||||
|
view->outer_block_mapping = zpl_malloc(sizeof(block_id*)*zpl_square(view->chunk_amount));
|
||||||
|
|
||||||
librg_config_chunksize_set(view->tracker, WORLD_BLOCK_SIZE * chunk_size, WORLD_BLOCK_SIZE * chunk_size, 1);
|
librg_config_chunksize_set(view->tracker, WORLD_BLOCK_SIZE * chunk_size, WORLD_BLOCK_SIZE * chunk_size, 1);
|
||||||
librg_config_chunkamount_set(view->tracker, chunk_amount, chunk_amount, 1);
|
librg_config_chunkamount_set(view->tracker, chunk_amount, chunk_amount, 0);
|
||||||
librg_config_chunkoffset_set(view->tracker, LIBRG_OFFSET_BEG, LIBRG_OFFSET_BEG, LIBRG_OFFSET_BEG);
|
librg_config_chunkoffset_set(view->tracker, LIBRG_OFFSET_BEG, LIBRG_OFFSET_BEG, LIBRG_OFFSET_BEG);
|
||||||
|
|
||||||
librg_event_set(view->tracker, LIBRG_READ_CREATE, tracker_read_create);
|
librg_event_set(view->tracker, LIBRG_READ_CREATE, tracker_read_create);
|
||||||
|
@ -92,6 +112,83 @@ void world_view_init(world_view *view, uint32_t seed, uint64_t ent_id, uint16_t
|
||||||
}
|
}
|
||||||
|
|
||||||
void world_view_destroy(world_view *view) {
|
void world_view_destroy(world_view *view) {
|
||||||
|
zpl_mfree(view->chunk_mapping);
|
||||||
|
for (int i = 0; i < zpl_square(view->chunk_amount); i+=1) {
|
||||||
|
zpl_mfree(view->block_mapping[i]);
|
||||||
|
zpl_mfree(view->outer_block_mapping[i]);
|
||||||
|
}
|
||||||
|
zpl_mfree(view->block_mapping);
|
||||||
|
zpl_mfree(view->outer_block_mapping);
|
||||||
librg_world_destroy(view->tracker);
|
librg_world_destroy(view->tracker);
|
||||||
entity_view_free(&view->entities);
|
entity_view_free(&view->entities);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void world_view_setup_chunk(world_view *view, entity_view *chk) {
|
||||||
|
librg_chunk chunk_id = chk->chk_id;
|
||||||
|
view->chunk_mapping[chunk_id] = chk;
|
||||||
|
if (!view->block_mapping[chunk_id])
|
||||||
|
view->block_mapping[chunk_id] = zpl_malloc(sizeof(block_id)*zpl_square(view->chunk_size));
|
||||||
|
if (!view->outer_block_mapping[chunk_id])
|
||||||
|
view->outer_block_mapping[chunk_id] = zpl_malloc(sizeof(block_id)*zpl_square(view->chunk_size));
|
||||||
|
|
||||||
|
for (int i = 0; i < zpl_square(view->chunk_size); i += 1) {
|
||||||
|
view->block_mapping[chunk_id][i] = chk->blocks[i];
|
||||||
|
view->outer_block_mapping[chunk_id][i] = chk->outer_blocks[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void world_view_clear_chunk(world_view *view, entity_view *chk) {
|
||||||
|
librg_chunk chunk_id = chk->chk_id;
|
||||||
|
view->chunk_mapping[chunk_id] = NULL;
|
||||||
|
zpl_mfree(view->block_mapping[chunk_id]); view->block_mapping[chunk_id] = NULL;
|
||||||
|
zpl_mfree(view->outer_block_mapping[chunk_id]); view->outer_block_mapping[chunk_id] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
world_view_block_lookup world_view_block_from_realpos(world_view *view, float x, float y) {
|
||||||
|
x = zpl_clamp(x, 0, view->dim-1);
|
||||||
|
y = zpl_clamp(y, 0, view->dim-1);
|
||||||
|
librg_chunk chunk_id = librg_chunk_from_realpos(view->tracker, x, y, 0);
|
||||||
|
entity_view *e = view->chunk_mapping[chunk_id];
|
||||||
|
if (!e) {
|
||||||
|
return (world_view_block_lookup){0};
|
||||||
|
}
|
||||||
|
int32_t size = view->chunk_size * WORLD_BLOCK_SIZE;
|
||||||
|
int16_t chunk_x, chunk_y;
|
||||||
|
librg_chunk_to_chunkpos(view->tracker, chunk_id, &chunk_x, &chunk_y, NULL);
|
||||||
|
|
||||||
|
// NOTE(zaklaus): pos relative to chunk
|
||||||
|
float chx = x - chunk_x * size;
|
||||||
|
float chy = y - chunk_y * size;
|
||||||
|
|
||||||
|
uint16_t bx = (uint16_t)chx / WORLD_BLOCK_SIZE;
|
||||||
|
uint16_t by = (uint16_t)chy / WORLD_BLOCK_SIZE;
|
||||||
|
uint16_t block_idx = (by*view->chunk_size)+bx;
|
||||||
|
block_id bid = view->outer_block_mapping[chunk_id][block_idx];
|
||||||
|
bool is_outer = true;
|
||||||
|
if (bid == 0) {
|
||||||
|
bid = view->block_mapping[chunk_id][block_idx];
|
||||||
|
is_outer = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE(zaklaus): pos relative to block's center
|
||||||
|
float box = chx - bx * WORLD_BLOCK_SIZE - WORLD_BLOCK_SIZE/2.0f;
|
||||||
|
float boy = chy - by * WORLD_BLOCK_SIZE - WORLD_BLOCK_SIZE/2.0f;
|
||||||
|
|
||||||
|
// NOTE(zaklaus): absolute pos in world.
|
||||||
|
float abox = (uint16_t)(x / WORLD_BLOCK_SIZE) * (float)WORLD_BLOCK_SIZE + WORLD_BLOCK_SIZE/2.0f;
|
||||||
|
float aboy = (uint16_t)(y / WORLD_BLOCK_SIZE) * (float)WORLD_BLOCK_SIZE + WORLD_BLOCK_SIZE/2.0f;
|
||||||
|
|
||||||
|
world_view_block_lookup lookup = {
|
||||||
|
.id = block_idx,
|
||||||
|
.bid = bid,
|
||||||
|
.chunk_id = chunk_id,
|
||||||
|
.chunk_e = e,
|
||||||
|
.ox = box,
|
||||||
|
.oy = boy,
|
||||||
|
.aox = abox,
|
||||||
|
.aoy = aboy,
|
||||||
|
.is_outer = is_outer,
|
||||||
|
};
|
||||||
|
|
||||||
|
return lookup;
|
||||||
|
}
|
||||||
|
|
|
@ -11,10 +11,14 @@ typedef struct {
|
||||||
|
|
||||||
uint32_t seed;
|
uint32_t seed;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint32_t dim;
|
uint32_t dim, chk_dim;
|
||||||
uint16_t chunk_size;
|
uint16_t chunk_size;
|
||||||
uint16_t chunk_amount;
|
uint16_t chunk_amount;
|
||||||
|
|
||||||
|
block_id **block_mapping;
|
||||||
|
block_id **outer_block_mapping;
|
||||||
|
entity_view **chunk_mapping;
|
||||||
|
|
||||||
// NOTE(zaklaus): metrics
|
// NOTE(zaklaus): metrics
|
||||||
float last_update[WORLD_TRACKER_LAYERS];
|
float last_update[WORLD_TRACKER_LAYERS];
|
||||||
float delta_time[WORLD_TRACKER_LAYERS];
|
float delta_time[WORLD_TRACKER_LAYERS];
|
||||||
|
@ -24,3 +28,18 @@ typedef struct {
|
||||||
world_view world_view_create(uint16_t view_id);
|
world_view world_view_create(uint16_t view_id);
|
||||||
void world_view_init(world_view *view, uint32_t seed, uint64_t ent_id, uint16_t chunk_size, uint16_t chunk_amount);
|
void world_view_init(world_view *view, uint32_t seed, uint64_t ent_id, uint16_t chunk_size, uint16_t chunk_amount);
|
||||||
void world_view_destroy(world_view *view);
|
void world_view_destroy(world_view *view);
|
||||||
|
|
||||||
|
void world_view_setup_chunk(world_view *view, entity_view *chk);
|
||||||
|
void world_view_clear_chunk(world_view *view, entity_view *chk);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t id;
|
||||||
|
block_id bid;
|
||||||
|
entity_view* chunk_e;
|
||||||
|
int64_t chunk_id;
|
||||||
|
float ox, oy;
|
||||||
|
float aox, aoy;
|
||||||
|
bool is_outer;
|
||||||
|
} world_view_block_lookup;
|
||||||
|
|
||||||
|
world_view_block_lookup world_view_block_from_realpos(world_view *view, float x, float y);
|
||||||
|
|
Loading…
Reference in New Issue