introduce block_id
parent
16d2b41f3c
commit
331ee39672
|
@ -48,9 +48,9 @@ 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
|
||||||
uint16_t blocks_used;
|
uint8_t blocks_used;
|
||||||
uint16_t blocks[256];
|
block_id blocks[256];
|
||||||
uint16_t outer_blocks[256];
|
block_id outer_blocks[256];
|
||||||
uint32_t color;
|
uint32_t color;
|
||||||
uint8_t is_dirty;
|
uint8_t is_dirty;
|
||||||
int64_t tex;
|
int64_t tex;
|
||||||
|
|
|
@ -54,8 +54,8 @@ void item_use(ecs_world_t *ecs, ItemDrop *it, Position p, uint64_t udata) {
|
||||||
case UKIND_HOLD: /* NOOP */ break;
|
case UKIND_HOLD: /* NOOP */ break;
|
||||||
case UKIND_PLACE:{
|
case UKIND_PLACE:{
|
||||||
world_block_lookup l = world_block_from_realpos(p.x, p.y);
|
world_block_lookup l = world_block_from_realpos(p.x, p.y);
|
||||||
if (l.is_outer && l.block_id > 0) {
|
if (l.is_outer && l.bid > 0) {
|
||||||
asset_id item_asset = blocks_get_asset(l.block_id);
|
asset_id item_asset = blocks_get_asset(l.bid);
|
||||||
uint16_t item_asset_id = item_find(item_asset);
|
uint16_t item_asset_id = item_find(item_asset);
|
||||||
if (item_asset_id == ASSET_INVALID) return;
|
if (item_asset_id == ASSET_INVALID) return;
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ void item_use(ecs_world_t *ecs, ItemDrop *it, Position p, uint64_t udata) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// NOTE(zaklaus): This is an inner layer block, we can't build over it if it has a collision!
|
// NOTE(zaklaus): This is an inner layer block, we can't build over it if it has a collision!
|
||||||
else if (l.block_id > 0 && blocks_get_flags(l.block_id) & (BLOCK_FLAG_COLLISION|BLOCK_FLAG_ESSENTIAL)) {
|
else if (l.bid > 0 && blocks_get_flags(l.bid) & (BLOCK_FLAG_COLLISION|BLOCK_FLAG_ESSENTIAL)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
world_chunk_replace_block(l.chunk_id, l.id, blocks_find(desc->place.kind + (asset_id)udata));
|
world_chunk_replace_block(l.chunk_id, l.id, blocks_find(desc->place.kind + (asset_id)udata));
|
||||||
|
|
|
@ -31,13 +31,13 @@ typedef struct {
|
||||||
float vely;
|
float vely;
|
||||||
|
|
||||||
// NOTE(zaklaus): viewer data
|
// NOTE(zaklaus): viewer data
|
||||||
uint16_t slot;
|
block_id slot;
|
||||||
} block;
|
} block;
|
||||||
|
|
||||||
#include "blocks_list.c"
|
#include "blocks_list.c"
|
||||||
|
|
||||||
int32_t blocks_setup(void) {
|
int32_t blocks_setup(void) {
|
||||||
for (uint16_t i=0; i<BLOCKS_COUNT; i++) {
|
for (block_id i=0; i<BLOCKS_COUNT; i++) {
|
||||||
blocks[i].slot = assets_find(blocks[i].kind);
|
blocks[i].slot = assets_find(blocks[i].kind);
|
||||||
}
|
}
|
||||||
blocks__chunk_tbl_init(&baked_chunks, zpl_heap());
|
blocks__chunk_tbl_init(&baked_chunks, zpl_heap());
|
||||||
|
@ -49,51 +49,51 @@ void blocks_destroy(void) {
|
||||||
blocks__chunk_tbl_destroy(&baked_chunks);
|
blocks__chunk_tbl_destroy(&baked_chunks);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t blocks_find(asset_id kind) {
|
block_id blocks_find(asset_id kind) {
|
||||||
for (uint16_t i=0; i<BLOCKS_COUNT; i++) {
|
for (block_id i=0; i<BLOCKS_COUNT; i++) {
|
||||||
if (blocks[i].kind == kind)
|
if (blocks[i].kind == kind)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
return 0xF;
|
return 0xF;
|
||||||
}
|
}
|
||||||
|
|
||||||
asset_id blocks_get_asset(uint16_t id) {
|
asset_id blocks_get_asset(block_id id) {
|
||||||
return blocks[id].kind;
|
return blocks[id].kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
char blocks_get_symbol(uint16_t id) {
|
char blocks_get_symbol(block_id id) {
|
||||||
return blocks[id].symbol;
|
return blocks[id].symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t blocks_get_flags(uint16_t id) {
|
uint32_t blocks_get_flags(block_id id) {
|
||||||
return blocks[id].flags;
|
return blocks[id].flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
float blocks_get_drag(uint16_t id) {
|
float blocks_get_drag(block_id id) {
|
||||||
return blocks[id].drag;
|
return blocks[id].drag;
|
||||||
}
|
}
|
||||||
|
|
||||||
float blocks_get_friction(uint16_t id) {
|
float blocks_get_friction(block_id id) {
|
||||||
return blocks[id].friction;
|
return blocks[id].friction;
|
||||||
}
|
}
|
||||||
|
|
||||||
float blocks_get_bounce(uint16_t id) {
|
float blocks_get_bounce(block_id id) {
|
||||||
return blocks[id].bounce;
|
return blocks[id].bounce;
|
||||||
}
|
}
|
||||||
|
|
||||||
float blocks_get_velx(uint16_t id) {
|
float blocks_get_velx(block_id id) {
|
||||||
return blocks[id].velx;
|
return blocks[id].velx;
|
||||||
}
|
}
|
||||||
|
|
||||||
float blocks_get_vely(uint16_t id) {
|
float blocks_get_vely(block_id id) {
|
||||||
return blocks[id].vely;
|
return blocks[id].vely;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *blocks_get_img(uint16_t id) {
|
void *blocks_get_img(block_id id) {
|
||||||
return assets_get_tex(blocks[id].slot);
|
return assets_get_tex(blocks[id].slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
void blocks_build_chunk_tex(uint64_t id, uint16_t *chunk_blocks, void *raw_view) {
|
void blocks_build_chunk_tex(uint64_t id, block_id *chunk_blocks, void *raw_view) {
|
||||||
world_view *view = (world_view*)raw_view;
|
world_view *view = (world_view*)raw_view;
|
||||||
uint16_t blk_dims = (uint16_t)(WORLD_BLOCK_SIZE * WORLD_TEXTURE_BLOCK_SCALE);
|
uint16_t blk_dims = (uint16_t)(WORLD_BLOCK_SIZE * WORLD_TEXTURE_BLOCK_SCALE);
|
||||||
uint16_t dims = blk_dims * view->chunk_size;
|
uint16_t dims = blk_dims * view->chunk_size;
|
||||||
|
|
|
@ -8,23 +8,25 @@ typedef enum {
|
||||||
BLOCK_FLAG_ESSENTIAL = (1 << 3),
|
BLOCK_FLAG_ESSENTIAL = (1 << 3),
|
||||||
} block_flags;
|
} block_flags;
|
||||||
|
|
||||||
|
typedef uint8_t block_id;
|
||||||
|
|
||||||
int32_t blocks_setup(void);
|
int32_t blocks_setup(void);
|
||||||
void blocks_destroy(void);
|
void blocks_destroy(void);
|
||||||
|
|
||||||
uint16_t blocks_find(asset_id kind);
|
block_id blocks_find(asset_id kind);
|
||||||
|
|
||||||
asset_id blocks_get_asset(uint16_t id);
|
asset_id blocks_get_asset(block_id id);
|
||||||
char blocks_get_symbol(uint16_t id);
|
char blocks_get_symbol(block_id id);
|
||||||
uint32_t blocks_get_flags(uint16_t id);
|
uint32_t blocks_get_flags(block_id id);
|
||||||
float blocks_get_drag(uint16_t id);
|
float blocks_get_drag(block_id id);
|
||||||
float blocks_get_friction(uint16_t id);
|
float blocks_get_friction(block_id id);
|
||||||
float blocks_get_bounce(uint16_t id);
|
float blocks_get_bounce(block_id id);
|
||||||
float blocks_get_velx(uint16_t id);
|
float blocks_get_velx(block_id id);
|
||||||
float blocks_get_vely(uint16_t id);
|
float blocks_get_vely(block_id id);
|
||||||
|
|
||||||
// NOTE(zaklaus): viewer-related functions
|
// NOTE(zaklaus): viewer-related functions
|
||||||
void *blocks_get_img(uint16_t id);
|
void *blocks_get_img(block_id id);
|
||||||
|
|
||||||
void blocks_build_chunk_tex(uint64_t id, uint16_t *blocks, void *view);
|
void blocks_build_chunk_tex(uint64_t id, block_id *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);
|
|
@ -173,8 +173,8 @@ int32_t world_init(int32_t seed, uint16_t chunk_size, uint16_t chunk_amount) {
|
||||||
librg_event_set(world.tracker, LIBRG_WRITE_REMOVE, tracker_write_remove);
|
librg_event_set(world.tracker, LIBRG_WRITE_REMOVE, tracker_write_remove);
|
||||||
librg_event_set(world.tracker, LIBRG_WRITE_UPDATE, tracker_write_update);
|
librg_event_set(world.tracker, LIBRG_WRITE_UPDATE, tracker_write_update);
|
||||||
|
|
||||||
world.data = zpl_malloc(sizeof(uint16_t)*world.size);
|
world.data = zpl_malloc(sizeof(block_id)*world.size);
|
||||||
world.outer_data = zpl_malloc(sizeof(uint16_t)*world.size);
|
world.outer_data = zpl_malloc(sizeof(block_id)*world.size);
|
||||||
|
|
||||||
if (!world.data || !world.outer_data) {
|
if (!world.data || !world.outer_data) {
|
||||||
return WORLD_ERROR_OUTOFMEM;
|
return WORLD_ERROR_OUTOFMEM;
|
||||||
|
@ -186,8 +186,8 @@ int32_t world_init(int32_t seed, uint16_t chunk_size, uint16_t chunk_amount) {
|
||||||
ECS_IMPORT(world.ecs, Systems);
|
ECS_IMPORT(world.ecs, Systems);
|
||||||
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(uint16_t*)*zpl_square(chunk_amount));
|
world.block_mapping = zpl_malloc(sizeof(block_id*)*zpl_square(chunk_amount));
|
||||||
world.outer_block_mapping = zpl_malloc(sizeof(uint16_t*)*zpl_square(chunk_amount));
|
world.outer_block_mapping = zpl_malloc(sizeof(block_id*)*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);
|
||||||
|
@ -208,8 +208,8 @@ int32_t world_init(int32_t seed, uint16_t chunk_size, uint16_t chunk_amount) {
|
||||||
librg_entity_chunk_set(world.tracker, e, i);
|
librg_entity_chunk_set(world.tracker, e, i);
|
||||||
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(uint16_t)*zpl_square(chunk_size));
|
world.block_mapping[i] = zpl_malloc(sizeof(block_id)*zpl_square(chunk_size));
|
||||||
world.outer_block_mapping[i] = zpl_malloc(sizeof(uint16_t)*zpl_square(chunk_size));
|
world.outer_block_mapping[i] = zpl_malloc(sizeof(block_id)*zpl_square(chunk_size));
|
||||||
chunk->id = i;
|
chunk->id = i;
|
||||||
chunk->is_dirty = false;
|
chunk->is_dirty = false;
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ int32_t world_init(int32_t seed, uint16_t chunk_size, uint16_t chunk_amount) {
|
||||||
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;
|
||||||
|
|
||||||
uint16_t *c = &world.block_mapping[i][(y*chunk_size)+x];
|
block_id *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 = &world.outer_block_mapping[i][(y*chunk_size)+x];
|
||||||
|
@ -333,7 +333,7 @@ int32_t world_write(pkt_header *pkt, void *udata) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t world_buf(uint16_t const **ptr, uint32_t *width) {
|
uint32_t world_buf(block_id const **ptr, uint32_t *width) {
|
||||||
ZPL_ASSERT_NOT_NULL(world.data);
|
ZPL_ASSERT_NOT_NULL(world.data);
|
||||||
ZPL_ASSERT_NOT_NULL(ptr);
|
ZPL_ASSERT_NOT_NULL(ptr);
|
||||||
*ptr = world.data;
|
*ptr = world.data;
|
||||||
|
@ -413,10 +413,10 @@ world_block_lookup world_block_from_realpos(float x, float y) {
|
||||||
uint16_t bx = (uint16_t)chx / WORLD_BLOCK_SIZE;
|
uint16_t bx = (uint16_t)chx / WORLD_BLOCK_SIZE;
|
||||||
uint16_t by = (uint16_t)chy / WORLD_BLOCK_SIZE;
|
uint16_t by = (uint16_t)chy / WORLD_BLOCK_SIZE;
|
||||||
uint16_t block_idx = (by*world.chunk_size)+bx;
|
uint16_t block_idx = (by*world.chunk_size)+bx;
|
||||||
uint16_t block_id = world.outer_block_mapping[chunk_id][block_idx];
|
block_id bid = world.outer_block_mapping[chunk_id][block_idx];
|
||||||
bool is_outer = true;
|
bool is_outer = true;
|
||||||
if (block_id == 0) {
|
if (bid == 0) {
|
||||||
block_id = world.block_mapping[chunk_id][block_idx];
|
bid = world.block_mapping[chunk_id][block_idx];
|
||||||
is_outer = false;
|
is_outer = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,7 +426,7 @@ world_block_lookup world_block_from_realpos(float x, float y) {
|
||||||
|
|
||||||
world_block_lookup lookup = {
|
world_block_lookup lookup = {
|
||||||
.id = block_idx,
|
.id = block_idx,
|
||||||
.block_id = block_id,
|
.bid = bid,
|
||||||
.chunk_id = chunk_id,
|
.chunk_id = chunk_id,
|
||||||
.chunk_e = e,
|
.chunk_e = e,
|
||||||
.ox = box,
|
.ox = box,
|
||||||
|
@ -441,8 +441,8 @@ void world_chunk_destroy_block(float x, float y, bool drop_item) {
|
||||||
world_block_lookup l = world_block_from_realpos(x, y);
|
world_block_lookup l = world_block_from_realpos(x, y);
|
||||||
world_chunk_replace_block(l.chunk_id, l.id, 0);
|
world_chunk_replace_block(l.chunk_id, l.id, 0);
|
||||||
|
|
||||||
if (l.is_outer && l.block_id > 0 && drop_item) {
|
if (l.is_outer && l.bid > 0 && drop_item) {
|
||||||
asset_id item_asset = blocks_get_asset(l.block_id);
|
asset_id item_asset = blocks_get_asset(l.bid);
|
||||||
if (item_find(item_asset) == ASSET_INVALID) return;
|
if (item_find(item_asset) == ASSET_INVALID) return;
|
||||||
uint64_t e = item_spawn(item_asset, 1);
|
uint64_t e = item_spawn(item_asset, 1);
|
||||||
|
|
||||||
|
@ -453,14 +453,14 @@ void world_chunk_destroy_block(float x, float y, bool drop_item) {
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
uint16_t block_id = world.outer_block_mapping[id][block_idx];
|
block_id bid = world.outer_block_mapping[id][block_idx];
|
||||||
if (block_id == 0) {
|
if (bid == 0) {
|
||||||
block_id = world.block_mapping[id][block_idx];
|
bid = world.block_mapping[id][block_idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
world_block_lookup lookup = {
|
world_block_lookup lookup = {
|
||||||
.id = block_idx,
|
.id = block_idx,
|
||||||
.block_id = block_id,
|
.bid = bid,
|
||||||
.chunk_id = id,
|
.chunk_id = id,
|
||||||
.chunk_e = world.chunk_mapping[id],
|
.chunk_e = world.chunk_mapping[id],
|
||||||
};
|
};
|
||||||
|
@ -477,27 +477,27 @@ int64_t world_chunk_from_entity(ecs_entity_t id) {
|
||||||
return librg_entity_chunk_get(world.tracker, id);
|
return librg_entity_chunk_get(world.tracker, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void world_chunk_replace_worldgen_block(int64_t id, uint16_t block_idx, uint16_t block_id) {
|
void world_chunk_replace_worldgen_block(int64_t id, uint16_t block_idx, block_id bid) {
|
||||||
ZPL_ASSERT(block_idx >= 0 && block_idx < zpl_square(world.chunk_size));
|
ZPL_ASSERT(block_idx >= 0 && block_idx < zpl_square(world.chunk_size));
|
||||||
world.block_mapping[id][block_idx] = block_id;
|
world.block_mapping[id][block_idx] = bid;
|
||||||
world_chunk_mark_dirty(world.chunk_mapping[id]);
|
world_chunk_mark_dirty(world.chunk_mapping[id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void world_chunk_replace_block(int64_t id, uint16_t block_idx, uint16_t block_id) {
|
void world_chunk_replace_block(int64_t id, uint16_t block_idx, block_id bid) {
|
||||||
ZPL_ASSERT(block_idx >= 0 && block_idx < zpl_square(world.chunk_size));
|
ZPL_ASSERT(block_idx >= 0 && block_idx < zpl_square(world.chunk_size));
|
||||||
world.outer_block_mapping[id][block_idx] = block_id;
|
world.outer_block_mapping[id][block_idx] = bid;
|
||||||
world_chunk_mark_dirty(world.chunk_mapping[id]);
|
world_chunk_mark_dirty(world.chunk_mapping[id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool world_chunk_place_block(int64_t id, uint16_t block_idx, uint16_t block_id) {
|
bool world_chunk_place_block(int64_t id, uint16_t block_idx, block_id bid) {
|
||||||
ZPL_ASSERT(block_idx >= 0 && block_idx < zpl_square(world.chunk_size));
|
ZPL_ASSERT(block_idx >= 0 && block_idx < zpl_square(world.chunk_size));
|
||||||
if (world.outer_block_mapping[id][block_idx] != 0 && block_id != 0) return false;
|
if (world.outer_block_mapping[id][block_idx] != 0 && bid != 0) return false;
|
||||||
world.outer_block_mapping[id][block_idx] = block_id;
|
world.outer_block_mapping[id][block_idx] = bid;
|
||||||
world_chunk_mark_dirty(world.chunk_mapping[id]);
|
world_chunk_mark_dirty(world.chunk_mapping[id]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t *world_chunk_get_blocks(int64_t id) {
|
block_id *world_chunk_get_blocks(int64_t id) {
|
||||||
return world.block_mapping[id];
|
return world.block_mapping[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -508,7 +508,7 @@ void world_chunk_mark_dirty(ecs_entity_t e) {
|
||||||
if (chunk) chunk->is_dirty = true;
|
if (chunk) chunk->is_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t world_chunk_is_dirty(ecs_entity_t e) {
|
bool world_chunk_is_dirty(ecs_entity_t e) {
|
||||||
bool was_added=false;
|
bool was_added=false;
|
||||||
Chunk *chunk = ecs_get_mut(world_ecs(), e, Chunk, &was_added);
|
Chunk *chunk = ecs_get_mut(world_ecs(), e, Chunk, &was_added);
|
||||||
ZPL_ASSERT(!was_added);
|
ZPL_ASSERT(!was_added);
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
#include "flecs/flecs.h"
|
#include "flecs/flecs.h"
|
||||||
#include "flecs/flecs_meta.h"
|
#include "flecs/flecs_meta.h"
|
||||||
|
#include "world/blocks.h"
|
||||||
#include "modules/components.h"
|
#include "modules/components.h"
|
||||||
|
|
||||||
#define WORLD_ERROR_NONE +0x0000
|
#define WORLD_ERROR_NONE +0x0000
|
||||||
|
@ -31,14 +32,14 @@ typedef WORLD_PKT_WRITER(world_pkt_writer_proc);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool is_paused;
|
bool is_paused;
|
||||||
uint16_t *data;
|
block_id *data;
|
||||||
uint16_t *outer_data;
|
block_id *outer_data;
|
||||||
uint32_t seed;
|
uint32_t seed;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint16_t chunk_size;
|
uint16_t chunk_size;
|
||||||
uint16_t chunk_amount;
|
uint16_t chunk_amount;
|
||||||
uint16_t **block_mapping;
|
block_id **block_mapping;
|
||||||
uint16_t **outer_block_mapping;
|
block_id **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;
|
||||||
|
@ -59,7 +60,7 @@ int32_t world_update(void);
|
||||||
int32_t world_read(void* data, uint32_t datalen, void *udata);
|
int32_t world_read(void* data, uint32_t datalen, void *udata);
|
||||||
int32_t world_write(pkt_header *pkt, void *udata);
|
int32_t world_write(pkt_header *pkt, void *udata);
|
||||||
|
|
||||||
uint32_t world_buf(uint16_t const **ptr, uint32_t *width);
|
uint32_t world_buf(block_id const **ptr, uint32_t *width);
|
||||||
uint32_t world_seed(void);
|
uint32_t world_seed(void);
|
||||||
ecs_world_t *world_ecs(void);
|
ecs_world_t *world_ecs(void);
|
||||||
void world_set_stage(ecs_world_t *ecs);
|
void world_set_stage(ecs_world_t *ecs);
|
||||||
|
@ -78,7 +79,7 @@ ecs_entity_t world_chunk_mapping(librg_chunk id);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t id;
|
uint16_t id;
|
||||||
uint16_t block_id;
|
block_id bid;
|
||||||
ecs_entity_t chunk_e;
|
ecs_entity_t chunk_e;
|
||||||
int64_t chunk_id;
|
int64_t chunk_id;
|
||||||
float ox, oy;
|
float ox, oy;
|
||||||
|
@ -91,21 +92,21 @@ 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);
|
||||||
|
|
||||||
// NOTE(zaklaus): This changes the inner chunk layer, it should only be used for terraforming!
|
// NOTE(zaklaus): This changes the inner chunk layer, it should only be used for terraforming!
|
||||||
void world_chunk_replace_worldgen_block(int64_t id, uint16_t block_idx, uint16_t block_id);
|
void world_chunk_replace_worldgen_block(int64_t id, uint16_t block_idx, block_id bid);
|
||||||
|
|
||||||
// NOTE(zaklaus): Replaces a block unconditionally
|
// NOTE(zaklaus): Replaces a block unconditionally
|
||||||
void world_chunk_replace_block(int64_t id, uint16_t block_idx, uint16_t block_id);
|
void world_chunk_replace_block(int64_t id, uint16_t block_idx, block_id bid);
|
||||||
|
|
||||||
// NOTE(zaklaus): Places a block only if the outer layer's chunk slot is empty,
|
// NOTE(zaklaus): Places a block only if the outer layer's chunk slot is empty,
|
||||||
// it also allows us to remove a block from outer layer unconditionally
|
// it also allows us to remove a block from outer layer unconditionally
|
||||||
bool world_chunk_place_block(int64_t id, uint16_t block_idx, uint16_t block_id);
|
bool world_chunk_place_block(int64_t id, uint16_t block_idx, block_id bid);
|
||||||
|
|
||||||
// NOTE(zaklaus): Convenience method to replace block with air and drop item optionally
|
// NOTE(zaklaus): Convenience method to replace block with air and drop item optionally
|
||||||
void world_chunk_destroy_block(float x, float y, bool drop_item);
|
void world_chunk_destroy_block(float x, float y, bool drop_item);
|
||||||
|
|
||||||
uint16_t *world_chunk_get_blocks(int64_t id);
|
block_id *world_chunk_get_blocks(int64_t id);
|
||||||
void world_chunk_mark_dirty(ecs_entity_t e);
|
void world_chunk_mark_dirty(ecs_entity_t e);
|
||||||
uint16_t world_chunk_is_dirty(ecs_entity_t e);
|
bool world_chunk_is_dirty(ecs_entity_t e);
|
||||||
|
|
||||||
// NOTE(zaklaus): Uses locally persistent buffer !!
|
// NOTE(zaklaus): Uses locally persistent buffer !!
|
||||||
int64_t *world_chunk_fetch_entities(librg_chunk chunk_id, size_t *ents_len);
|
int64_t *world_chunk_fetch_entities(librg_chunk chunk_id, size_t *ents_len);
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include "items.h"
|
#include "items.h"
|
||||||
#include "world/blocks_info.h"
|
#include "world/blocks_info.h"
|
||||||
|
|
||||||
#define WORLD_BLOCK_OBSERVER(name) uint16_t name(uint16_t *data, uint16_t id, uint32_t block_idx)
|
#define WORLD_BLOCK_OBSERVER(name) block_id name(block_id *data, block_id id, uint32_t block_idx)
|
||||||
typedef WORLD_BLOCK_OBSERVER(world_block_observer_proc);
|
typedef WORLD_BLOCK_OBSERVER(world_block_observer_proc);
|
||||||
|
|
||||||
#define WORLD_PERLIN_FREQ 100
|
#define WORLD_PERLIN_FREQ 100
|
||||||
|
@ -20,7 +20,7 @@ typedef WORLD_BLOCK_OBSERVER(world_block_observer_proc);
|
||||||
|
|
||||||
#define BLOCK_INVALID 0xF
|
#define BLOCK_INVALID 0xF
|
||||||
|
|
||||||
uint16_t worldgen_biome_find(uint32_t biome, uint32_t kind) {
|
block_id worldgen_biome_find(uint32_t biome, uint32_t kind) {
|
||||||
asset_id asset = ASSET_INVALID;
|
asset_id asset = ASSET_INVALID;
|
||||||
switch (biome) {
|
switch (biome) {
|
||||||
case BLOCK_BIOME_DEV: {
|
case BLOCK_BIOME_DEV: {
|
||||||
|
@ -41,7 +41,7 @@ uint16_t worldgen_biome_find(uint32_t biome, uint32_t kind) {
|
||||||
|
|
||||||
static world_data *world;
|
static world_data *world;
|
||||||
|
|
||||||
static void world_fill_rect(uint16_t *data, uint16_t id, uint32_t x, uint32_t y, uint32_t w, uint32_t h, world_block_observer_proc *proc) {
|
static void world_fill_rect(block_id *data, block_id id, uint32_t x, uint32_t y, uint32_t w, uint32_t h, world_block_observer_proc *proc) {
|
||||||
for (uint32_t cy=y; cy<y+h; cy++) {
|
for (uint32_t cy=y; cy<y+h; cy++) {
|
||||||
for (uint32_t cx=x; cx<x+w; cx++) {
|
for (uint32_t cx=x; cx<x+w; cx++) {
|
||||||
if (cx < 0 || cx >= world->dim) continue;
|
if (cx < 0 || cx >= world->dim) continue;
|
||||||
|
@ -49,7 +49,7 @@ static void world_fill_rect(uint16_t *data, uint16_t id, uint32_t x, uint32_t y,
|
||||||
uint32_t i = (cy*world->dim) + cx;
|
uint32_t i = (cy*world->dim) + cx;
|
||||||
|
|
||||||
if (proc) {
|
if (proc) {
|
||||||
uint16_t new_id = (*proc)(data, id, i);
|
block_id new_id = (*proc)(data, id, i);
|
||||||
if (new_id != BLOCK_INVALID) {
|
if (new_id != BLOCK_INVALID) {
|
||||||
id = new_id;
|
id = new_id;
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ static void world_fill_rect(uint16_t *data, uint16_t id, uint32_t x, uint32_t y,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void world_fill_circle(uint16_t *data, uint16_t id, uint32_t x, uint32_t y, uint32_t w, uint32_t h, world_block_observer_proc *proc) {
|
static void world_fill_circle(block_id *data, block_id id, uint32_t x, uint32_t y, uint32_t w, uint32_t h, world_block_observer_proc *proc) {
|
||||||
for (uint32_t cy=y; cy<y+h; cy++) {
|
for (uint32_t cy=y; cy<y+h; cy++) {
|
||||||
for (uint32_t cx=x; cx<x+w; cx++) {
|
for (uint32_t cx=x; cx<x+w; cx++) {
|
||||||
if (cx < 0 || cx >= world->dim) continue;
|
if (cx < 0 || cx >= world->dim) continue;
|
||||||
|
@ -69,7 +69,7 @@ static void world_fill_circle(uint16_t *data, uint16_t id, uint32_t x, uint32_t
|
||||||
uint32_t i = (cy*world->dim) + cx;
|
uint32_t i = (cy*world->dim) + cx;
|
||||||
|
|
||||||
if (proc) {
|
if (proc) {
|
||||||
uint16_t new_id = (*proc)(data, id, i);
|
block_id new_id = (*proc)(data, id, i);
|
||||||
if (new_id != BLOCK_INVALID) {
|
if (new_id != BLOCK_INVALID) {
|
||||||
id = new_id;
|
id = new_id;
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ static void world_fill_circle(uint16_t *data, uint16_t id, uint32_t x, uint32_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void world_fill_rect_anchor(uint16_t *data, uint16_t id, uint32_t x, uint32_t y, uint32_t w, uint32_t h, float ax, float ay, world_block_observer_proc *proc) {
|
static void world_fill_rect_anchor(block_id *data, block_id 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 w2 = (uint32_t)floorf(w*ax);
|
||||||
uint32_t h2 = (uint32_t)floorf(h*ay);
|
uint32_t h2 = (uint32_t)floorf(h*ay);
|
||||||
world_fill_rect(data, id, x-w2, y-h2, w, h, proc);
|
world_fill_rect(data, id, x-w2, y-h2, w, h, proc);
|
||||||
|
@ -101,14 +101,14 @@ static WORLD_BLOCK_OBSERVER(shaper) {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t world_perlin_cond_offset(uint32_t block_idx, double chance, uint32_t ofx, uint32_t ofy) {
|
static block_id world_perlin_cond_offset(uint32_t block_idx, double chance, uint32_t ofx, uint32_t ofy) {
|
||||||
uint32_t x = block_idx % world->dim + ofx;
|
uint32_t x = block_idx % world->dim + ofx;
|
||||||
uint32_t y = block_idx / world->dim + ofy;
|
uint32_t y = block_idx / world->dim + ofy;
|
||||||
|
|
||||||
return perlin_fbm(world->seed, x, y, WORLD_PERLIN_FREQ, WORLD_PERLIN_OCTAVES) < chance;
|
return perlin_fbm(world->seed, x, y, WORLD_PERLIN_FREQ, WORLD_PERLIN_OCTAVES) < chance;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t world_perlin_cond(uint32_t block_idx, double chance) {
|
static block_id world_perlin_cond(uint32_t block_idx, double chance) {
|
||||||
return world_perlin_cond_offset(block_idx, chance, 0, 0);
|
return world_perlin_cond_offset(block_idx, chance, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,12 +162,12 @@ int32_t worldgen_test(world_data *wld) {
|
||||||
|
|
||||||
// TODO: perform world gen
|
// TODO: perform world gen
|
||||||
// atm, we will fill the world with ground and surround it by walls
|
// atm, we will fill the world with ground and surround it by walls
|
||||||
uint16_t wall_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_WALL);
|
block_id wall_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_WALL);
|
||||||
uint16_t grnd_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_GROUND);
|
block_id grnd_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_GROUND);
|
||||||
uint16_t dirt_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_DIRT);
|
block_id dirt_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_DIRT);
|
||||||
uint16_t watr_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_WATER);
|
block_id watr_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_WATER);
|
||||||
uint16_t lava_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_LAVA);
|
block_id lava_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_LAVA);
|
||||||
uint16_t tree_id = blocks_find(ASSET_TREE);
|
block_id tree_id = blocks_find(ASSET_TREE);
|
||||||
|
|
||||||
srand(world->seed);
|
srand(world->seed);
|
||||||
|
|
||||||
|
|
|
@ -38,8 +38,8 @@ void IntegratePositions(ecs_iter_t *it) {
|
||||||
// NOTE(zaklaus): X axis
|
// NOTE(zaklaus): X axis
|
||||||
{
|
{
|
||||||
world_block_lookup lookup = world_block_from_realpos(p[i].x+PHY_LOOKAHEAD(v[i].x), p[i].y);
|
world_block_lookup lookup = world_block_from_realpos(p[i].x+PHY_LOOKAHEAD(v[i].x), p[i].y);
|
||||||
uint32_t flags = blocks_get_flags(lookup.block_id);
|
uint32_t flags = blocks_get_flags(lookup.bid);
|
||||||
float bounce = blocks_get_bounce(lookup.block_id);
|
float bounce = blocks_get_bounce(lookup.bid);
|
||||||
if (flags & BLOCK_FLAG_COLLISION) {
|
if (flags & BLOCK_FLAG_COLLISION) {
|
||||||
v[i].x = physics_correction(lookup.ox, v[i].x, bounce);
|
v[i].x = physics_correction(lookup.ox, v[i].x, bounce);
|
||||||
}
|
}
|
||||||
|
@ -48,8 +48,8 @@ void IntegratePositions(ecs_iter_t *it) {
|
||||||
// NOTE(zaklaus): Y axis
|
// NOTE(zaklaus): Y axis
|
||||||
{
|
{
|
||||||
world_block_lookup lookup = world_block_from_realpos(p[i].x, p[i].y+PHY_LOOKAHEAD(v[i].y));
|
world_block_lookup lookup = world_block_from_realpos(p[i].x, p[i].y+PHY_LOOKAHEAD(v[i].y));
|
||||||
uint32_t flags = blocks_get_flags(lookup.block_id);
|
uint32_t flags = blocks_get_flags(lookup.bid);
|
||||||
float bounce = blocks_get_bounce(lookup.block_id);
|
float bounce = blocks_get_bounce(lookup.bid);
|
||||||
if (flags & BLOCK_FLAG_COLLISION) {
|
if (flags & BLOCK_FLAG_COLLISION) {
|
||||||
v[i].y = physics_correction(lookup.oy, v[i].y, bounce);
|
v[i].y = physics_correction(lookup.oy, v[i].y, bounce);
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,7 @@ void HurtOnHazardBlock(ecs_iter_t *it) {
|
||||||
|
|
||||||
for (int i = 0; i < it->count; i++) {
|
for (int i = 0; i < it->count; i++) {
|
||||||
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);
|
||||||
if (blocks_get_flags(l.block_id) & BLOCK_FLAG_HAZARD) {
|
if (blocks_get_flags(l.bid) & BLOCK_FLAG_HAZARD) {
|
||||||
if (h->pain_time < 0.0f) {
|
if (h->pain_time < 0.0f) {
|
||||||
h->pain_time = HAZARD_BLOCK_TIME;
|
h->pain_time = HAZARD_BLOCK_TIME;
|
||||||
h->hp -= HAZARD_BLOCK_DMG;
|
h->hp -= HAZARD_BLOCK_DMG;
|
||||||
|
@ -140,10 +140,10 @@ void ApplyWorldDragOnVelocity(ecs_iter_t *it) {
|
||||||
|
|
||||||
for (int i = 0; i < it->count; i++) {
|
for (int i = 0; i < it->count; i++) {
|
||||||
world_block_lookup lookup = world_block_from_realpos(p[i].x, p[i].y);
|
world_block_lookup lookup = world_block_from_realpos(p[i].x, p[i].y);
|
||||||
float drag = zpl_clamp(blocks_get_drag(lookup.block_id), 0.0f, 1.0f);
|
float drag = zpl_clamp(blocks_get_drag(lookup.bid), 0.0f, 1.0f);
|
||||||
float friction = blocks_get_friction(lookup.block_id);
|
float friction = blocks_get_friction(lookup.bid);
|
||||||
float velx = blocks_get_velx(lookup.block_id);
|
float velx = blocks_get_velx(lookup.bid);
|
||||||
float vely = blocks_get_vely(lookup.block_id);
|
float vely = blocks_get_vely(lookup.bid);
|
||||||
v[i].x = zpl_lerp(v[i].x, zpl_max(0.0f, zpl_abs(velx))*zpl_sign(velx), PHY_WALK_DRAG*drag*friction*safe_dt(it));
|
v[i].x = zpl_lerp(v[i].x, zpl_max(0.0f, zpl_abs(velx))*zpl_sign(velx), PHY_WALK_DRAG*drag*friction*safe_dt(it));
|
||||||
v[i].y = zpl_lerp(v[i].y, zpl_max(0.0f, zpl_abs(vely))*zpl_sign(vely), PHY_WALK_DRAG*drag*friction*safe_dt(it));
|
v[i].y = zpl_lerp(v[i].y, zpl_max(0.0f, zpl_abs(vely))*zpl_sign(vely), PHY_WALK_DRAG*drag*friction*safe_dt(it));
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ void DemoNPCMoveAround(ecs_iter_t *it) {
|
||||||
Velocity *v = ecs_column(it, Velocity, 1);
|
Velocity *v = ecs_column(it, Velocity, 1);
|
||||||
for (int i = 0; i < it->count; i++) {
|
for (int i = 0; i < it->count; i++) {
|
||||||
float d = zpl_quake_rsqrt(v[i].x*v[i].x + v[i].y*v[i].y);
|
float d = zpl_quake_rsqrt(v[i].x*v[i].x + v[i].y*v[i].y);
|
||||||
v[i].x += (v[i].x*d*DEMO_NPC_MOVE_SPEED*safe_dt(it) + zpl_cos(zpl_to_radians(rand()%360))*DEMO_NPC_STEER_SPEED*safe_dt(it));
|
v[i].x += (v[i].x*d*DEMO_NPC_MOVE_SPEED*safe_dt(it) + zpl_cos(zpl_to_radians((float)(rand()%360)))*DEMO_NPC_STEER_SPEED*safe_dt(it));
|
||||||
v[i].y += (v[i].y*d*DEMO_NPC_MOVE_SPEED*safe_dt(it) + zpl_sin(zpl_to_radians(rand()%360))*DEMO_NPC_STEER_SPEED*safe_dt(it));
|
v[i].y += (v[i].y*d*DEMO_NPC_MOVE_SPEED*safe_dt(it) + zpl_sin(zpl_to_radians((float)(rand()%360)))*DEMO_NPC_STEER_SPEED*safe_dt(it));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#define PLR_MOVE_SPEED 800.0
|
#define PLR_MOVE_SPEED 800.0f
|
||||||
#define PLR_MOVE_SPEED_MULT 1.5
|
#define PLR_MOVE_SPEED_MULT 1.5f
|
||||||
|
|
||||||
void MovementImpulse(ecs_iter_t *it) {
|
void MovementImpulse(ecs_iter_t *it) {
|
||||||
Input *in = ecs_column(it, Input, 1);
|
Input *in = ecs_column(it, Input, 1);
|
||||||
|
@ -8,8 +8,8 @@ void MovementImpulse(ecs_iter_t *it) {
|
||||||
|
|
||||||
for (int i = 0; i < it->count; i++) {
|
for (int i = 0; i < it->count; i++) {
|
||||||
world_block_lookup lookup = world_block_from_realpos(p[i].x, p[i].y);
|
world_block_lookup lookup = world_block_from_realpos(p[i].x, p[i].y);
|
||||||
float drag = zpl_clamp(blocks_get_drag(lookup.block_id), 0.0f, 1.0f);
|
float drag = zpl_clamp(blocks_get_drag(lookup.bid), 0.0f, 1.0f);
|
||||||
double speed = PLR_MOVE_SPEED * (in[i].sprint ? PLR_MOVE_SPEED_MULT : 1.0);
|
float speed = PLR_MOVE_SPEED * (in[i].sprint ? PLR_MOVE_SPEED_MULT : 1.0f);
|
||||||
v[i].x += in[i].x*speed*drag*safe_dt(it);
|
v[i].x += in[i].x*speed*drag*safe_dt(it);
|
||||||
v[i].y -= in[i].y*speed*drag*safe_dt(it);
|
v[i].y -= in[i].y*speed*drag*safe_dt(it);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,10 @@ void LeaveVehicle(ecs_iter_t *it) {
|
||||||
Input *in = ecs_column(it, Input, 1);
|
Input *in = ecs_column(it, Input, 1);
|
||||||
IsInVehicle *vehp = ecs_column(it, IsInVehicle, 2);
|
IsInVehicle *vehp = ecs_column(it, IsInVehicle, 2);
|
||||||
Velocity *v = ecs_column(it, Velocity, 3);
|
Velocity *v = ecs_column(it, Velocity, 3);
|
||||||
|
|
||||||
for (int i = 0; i < it->count; i++) {
|
for (int i = 0; i < it->count; i++) {
|
||||||
if (!in[i].use) continue;
|
if (!in[i].use) continue;
|
||||||
|
|
||||||
Vehicle *veh = 0;
|
Vehicle *veh = 0;
|
||||||
if ((veh = ecs_get_mut_if(it->world, vehp->veh, Vehicle))) {
|
if ((veh = ecs_get_mut_if(it->world, vehp->veh, Vehicle))) {
|
||||||
for (int k = 0; k < 4; k++) {
|
for (int k = 0; k < 4; k++) {
|
||||||
|
@ -18,10 +18,10 @@ void LeaveVehicle(ecs_iter_t *it) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
in[i].use = false;
|
in[i].use = false;
|
||||||
ecs_remove(it->world, it->entities[i], IsInVehicle);
|
ecs_remove(it->world, it->entities[i], IsInVehicle);
|
||||||
|
|
||||||
// NOTE(zaklaus): push passenger out
|
// NOTE(zaklaus): push passenger out
|
||||||
{
|
{
|
||||||
float px = zpl_cos(veh->heading)*400.0f;
|
float px = zpl_cos(veh->heading)*400.0f;
|
||||||
|
@ -38,29 +38,29 @@ void LeaveVehicle(ecs_iter_t *it) {
|
||||||
void EnterVehicle(ecs_iter_t *it) {
|
void EnterVehicle(ecs_iter_t *it) {
|
||||||
Input *in = ecs_column(it, Input, 1);
|
Input *in = ecs_column(it, Input, 1);
|
||||||
Position *p = ecs_column(it, Position, 2);
|
Position *p = ecs_column(it, Position, 2);
|
||||||
|
|
||||||
for (int i = 0; i < it->count; i++) {
|
for (int i = 0; i < it->count; i++) {
|
||||||
if (!in[i].use) continue;
|
if (!in[i].use) continue;
|
||||||
|
|
||||||
size_t ents_count;
|
size_t ents_count;
|
||||||
int64_t *ents = world_chunk_query_entities(it->entities[i], &ents_count, 2);
|
int64_t *ents = world_chunk_query_entities(it->entities[i], &ents_count, 2);
|
||||||
bool has_entered_veh = false;
|
bool has_entered_veh = false;
|
||||||
|
|
||||||
for (size_t j = 0; j < ents_count; j++) {
|
for (size_t j = 0; j < ents_count; j++) {
|
||||||
Vehicle *veh = 0;
|
Vehicle *veh = 0;
|
||||||
|
|
||||||
if (has_entered_veh) break;
|
if (has_entered_veh) break;
|
||||||
|
|
||||||
if ((veh = ecs_get_mut_if(it->world, ents[j], Vehicle))) {
|
if ((veh = ecs_get_mut_if(it->world, ents[j], Vehicle))) {
|
||||||
Position const* p2 = ecs_get(it->world, ents[j], Position);
|
Position const* p2 = ecs_get(it->world, ents[j], Position);
|
||||||
|
|
||||||
float dx = p2->x - p[i].x;
|
float dx = p2->x - p[i].x;
|
||||||
float dy = p2->y - p[i].y;
|
float dy = p2->y - p[i].y;
|
||||||
float range = zpl_sqrt(dx*dx + dy*dy);
|
float range = zpl_sqrt(dx*dx + dy*dy);
|
||||||
if (range <= VEH_ENTER_RADIUS) {
|
if (range <= VEH_ENTER_RADIUS) {
|
||||||
for (int k = 0; k < 4; k++) {
|
for (int k = 0; k < 4; k++) {
|
||||||
if (veh->seats[k] != 0) continue;
|
if (veh->seats[k] != 0) continue;
|
||||||
|
|
||||||
// NOTE(zaklaus): We can enter the vehicle, yay!
|
// NOTE(zaklaus): We can enter the vehicle, yay!
|
||||||
veh->seats[k] = it->entities[i];
|
veh->seats[k] = it->entities[i];
|
||||||
ecs_set(it->world, it->entities[i], IsInVehicle, {
|
ecs_set(it->world, it->entities[i], IsInVehicle, {
|
||||||
|
@ -90,27 +90,27 @@ void VehicleHandling(ecs_iter_t *it) {
|
||||||
Vehicle *veh = ecs_column(it, Vehicle, 1);
|
Vehicle *veh = ecs_column(it, Vehicle, 1);
|
||||||
Position *p = ecs_column(it, Position, 2);
|
Position *p = ecs_column(it, Position, 2);
|
||||||
Velocity *v = ecs_column(it, Velocity, 3);
|
Velocity *v = ecs_column(it, Velocity, 3);
|
||||||
|
|
||||||
for (int i = 0; i < it->count; i++) {
|
for (int i = 0; i < it->count; i++) {
|
||||||
Vehicle *car = &veh[i];
|
Vehicle *car = &veh[i];
|
||||||
|
|
||||||
for (int j = 0; j < 4; j++) {
|
for (int j = 0; j < 4; j++) {
|
||||||
// NOTE(zaklaus): Perform seat cleanup
|
// NOTE(zaklaus): Perform seat cleanup
|
||||||
if (!world_entity_valid(veh[i].seats[j])) {
|
if (!world_entity_valid(veh[i].seats[j])) {
|
||||||
veh[i].seats[j] = 0;
|
veh[i].seats[j] = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ecs_entity_t pe = veh[i].seats[j];
|
ecs_entity_t pe = veh[i].seats[j];
|
||||||
|
|
||||||
// NOTE(zaklaus): Handle driver input
|
// NOTE(zaklaus): Handle driver input
|
||||||
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, (zpl_sign(in->y) == zpl_sign(car->force) ? 1.0f : 3.0f) * VEHICLE_ACCEL*safe_dt(it));
|
car->force += zpl_lerp(0.0f, in->y * VEHICLE_FORCE, (zpl_sign(in->y) == zpl_sign(car->force) ? 1.0f : 3.0f) * VEHICLE_ACCEL*safe_dt(it));
|
||||||
if (in->sprint) {
|
if (in->sprint) {
|
||||||
car->force = zpl_lerp(car->force, 0.0f, VEHICLE_BRAKE_FORCE*safe_dt(it));
|
car->force = zpl_lerp(car->force, 0.0f, VEHICLE_BRAKE_FORCE*safe_dt(it));
|
||||||
|
|
||||||
if (zpl_abs(car->force) < 5.5f)
|
if (zpl_abs(car->force) < 5.5f)
|
||||||
car->force = 0.0f;
|
car->force = 0.0f;
|
||||||
}
|
}
|
||||||
|
@ -120,38 +120,38 @@ void VehicleHandling(ecs_iter_t *it) {
|
||||||
car->steer = zpl_clamp(car->steer, -60.0f, 60.0f);
|
car->steer = zpl_clamp(car->steer, -60.0f, 60.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
car->force = zpl_clamp(car->force, car->reverse_speed, car->speed);
|
car->force = zpl_clamp(car->force, car->reverse_speed, car->speed);
|
||||||
|
|
||||||
// NOTE(zaklaus): Vehicle physics
|
// NOTE(zaklaus): Vehicle physics
|
||||||
float fr_x = p[i].x + (car->wheel_base/2.0f) * zpl_cos(car->heading);
|
float fr_x = p[i].x + (car->wheel_base/2.0f) * zpl_cos(car->heading);
|
||||||
float fr_y = p[i].y + (car->wheel_base/2.0f) * zpl_sin(car->heading);
|
float fr_y = p[i].y + (car->wheel_base/2.0f) * zpl_sin(car->heading);
|
||||||
|
|
||||||
float bk_x = p[i].x - (car->wheel_base/2.0f) * zpl_cos(car->heading);
|
float bk_x = p[i].x - (car->wheel_base/2.0f) * zpl_cos(car->heading);
|
||||||
float bk_y = p[i].y - (car->wheel_base/2.0f) * zpl_sin(car->heading);
|
float bk_y = p[i].y - (car->wheel_base/2.0f) * zpl_sin(car->heading);
|
||||||
|
|
||||||
world_block_lookup lookup = world_block_from_realpos(p[i].x, p[i].y);
|
world_block_lookup lookup = world_block_from_realpos(p[i].x, p[i].y);
|
||||||
float drag = zpl_clamp(blocks_get_drag(lookup.block_id), 0.0f, 1.0f);
|
float drag = zpl_clamp(blocks_get_drag(lookup.bid), 0.0f, 1.0f);
|
||||||
|
|
||||||
bk_x += car->force * drag * zpl_cos(car->heading) * safe_dt(it)*VEHICLE_POWER;
|
bk_x += car->force * drag * zpl_cos(car->heading) * safe_dt(it)*VEHICLE_POWER;
|
||||||
bk_y += car->force * drag * zpl_sin(car->heading) * safe_dt(it)*VEHICLE_POWER;
|
bk_y += car->force * drag * zpl_sin(car->heading) * safe_dt(it)*VEHICLE_POWER;
|
||||||
fr_x += car->force * drag * zpl_cos(car->heading + zpl_to_radians(car->steer)) * safe_dt(it)*VEHICLE_POWER;
|
fr_x += car->force * drag * zpl_cos(car->heading + zpl_to_radians(car->steer)) * safe_dt(it)*VEHICLE_POWER;
|
||||||
fr_y += car->force * drag * zpl_sin(car->heading + zpl_to_radians(car->steer)) * safe_dt(it)*VEHICLE_POWER;
|
fr_y += car->force * drag * zpl_sin(car->heading + zpl_to_radians(car->steer)) * safe_dt(it)*VEHICLE_POWER;
|
||||||
|
|
||||||
v[i].x += ((fr_x + bk_x) / 2.0f - p[i].x);
|
v[i].x += ((fr_x + bk_x) / 2.0f - p[i].x);
|
||||||
v[i].y += ((fr_y + bk_y) / 2.0f - p[i].y);
|
v[i].y += ((fr_y + bk_y) / 2.0f - p[i].y);
|
||||||
car->heading = zpl_arctan2(fr_y - bk_y, fr_x - bk_x);
|
car->heading = zpl_arctan2(fr_y - bk_y, fr_x - bk_x);
|
||||||
|
|
||||||
world_block_lookup lookahead = world_block_from_realpos(p[i].x+PHY_LOOKAHEAD(v[i].x), p[i].y+PHY_LOOKAHEAD(v[i].y));
|
world_block_lookup lookahead = world_block_from_realpos(p[i].x+PHY_LOOKAHEAD(v[i].x), p[i].y+PHY_LOOKAHEAD(v[i].y));
|
||||||
uint32_t flags = blocks_get_flags(lookahead.block_id);
|
uint32_t flags = blocks_get_flags(lookahead.bid);
|
||||||
if (flags & BLOCK_FLAG_COLLISION) {
|
if (flags & BLOCK_FLAG_COLLISION) {
|
||||||
car->force = 0.0f;
|
car->force = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < 4; j++) {
|
for (int j = 0; j < 4; j++) {
|
||||||
if (!world_entity_valid(veh[i].seats[j])) continue;
|
if (!world_entity_valid(veh[i].seats[j])) continue;
|
||||||
ecs_entity_t pe = veh[i].seats[j];
|
ecs_entity_t pe = veh[i].seats[j];
|
||||||
|
|
||||||
// NOTE(zaklaus): Update passenger position
|
// NOTE(zaklaus): Update passenger position
|
||||||
{
|
{
|
||||||
Position *p2 = ecs_get_mut(it->world, pe, Position, NULL);
|
Position *p2 = ecs_get_mut(it->world, pe, Position, NULL);
|
||||||
|
@ -160,18 +160,18 @@ void VehicleHandling(ecs_iter_t *it) {
|
||||||
*v2 = v[i];
|
*v2 = v[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
debug_v2 b2 = {p[i].x + zpl_cos(car->heading)*(car->wheel_base), p[i].y + zpl_sin(car->heading)*(car->wheel_base)};
|
debug_v2 b2 = {p[i].x + zpl_cos(car->heading)*(car->wheel_base), p[i].y + zpl_sin(car->heading)*(car->wheel_base)};
|
||||||
debug_push_line((debug_v2){p[i].x, p[i].y}, b2, 0x0000FFFF);
|
debug_push_line((debug_v2){p[i].x, p[i].y}, b2, 0x0000FFFF);
|
||||||
|
|
||||||
// NOTE(zaklaus): force
|
// NOTE(zaklaus): force
|
||||||
{
|
{
|
||||||
float dx = zpl_cos(car->heading);
|
float dx = zpl_cos(car->heading);
|
||||||
float dy = zpl_sin(car->heading);
|
float dy = zpl_sin(car->heading);
|
||||||
debug_push_circle((debug_v2){p[i].x+dx*car->force, p[i].y+dy*car->force}, 5.0f, 0x00FF00FF);
|
debug_push_circle((debug_v2){p[i].x+dx*car->force, p[i].y+dy*car->force}, 5.0f, 0x00FF00FF);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE(zaklaus): steer
|
// NOTE(zaklaus): steer
|
||||||
{
|
{
|
||||||
float dx = zpl_sin(car->heading);
|
float dx = zpl_sin(car->heading);
|
||||||
|
@ -185,7 +185,7 @@ void VehicleHandling(ecs_iter_t *it) {
|
||||||
|
|
||||||
void ClearVehicle(ecs_iter_t *it) {
|
void ClearVehicle(ecs_iter_t *it) {
|
||||||
Vehicle *veh = ecs_column(it, Vehicle, 1);
|
Vehicle *veh = ecs_column(it, Vehicle, 1);
|
||||||
|
|
||||||
for (int i = 0; i < it->count; i++) {
|
for (int i = 0; i < it->count; i++) {
|
||||||
for (int k = 0; k < 4; k++) {
|
for (int k = 0; k < 4; k++) {
|
||||||
if (world_entity_valid(veh[i].seats[k])) {
|
if (world_entity_valid(veh[i].seats[k])) {
|
||||||
|
|
Loading…
Reference in New Issue