From 331ee3967269d5f39fb2e93ed3b635ddb0949adc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Madar=C3=A1sz?= Date: Wed, 3 Nov 2021 19:04:34 +0100 Subject: [PATCH] introduce block_id --- code/game/src/entity_view.h | 6 +- code/game/src/items.c | 6 +- code/game/src/world/blocks.c | 28 ++++----- code/game/src/world/blocks.h | 24 ++++---- code/game/src/world/world.c | 54 ++++++++--------- code/game/src/world/world.h | 23 +++---- code/game/src/world/worldgen/worldgen_test.c | 30 ++++----- code/modules/modules/systems.c | 18 +++--- code/modules/source/system_demo.c | 4 +- code/modules/source/system_onfoot.c | 8 +-- code/modules/source/system_vehicle.c | 64 ++++++++++---------- 11 files changed, 134 insertions(+), 131 deletions(-) diff --git a/code/game/src/entity_view.h b/code/game/src/entity_view.h index a0905f3..a95fda2 100644 --- a/code/game/src/entity_view.h +++ b/code/game/src/entity_view.h @@ -48,9 +48,9 @@ typedef struct entity_view { float max_hp; // TODO(zaklaus): Find a way to stream dynamic arrays - uint16_t blocks_used; - uint16_t blocks[256]; - uint16_t outer_blocks[256]; + uint8_t blocks_used; + block_id blocks[256]; + block_id outer_blocks[256]; uint32_t color; uint8_t is_dirty; int64_t tex; diff --git a/code/game/src/items.c b/code/game/src/items.c index 02be5c4..411f550 100644 --- a/code/game/src/items.c +++ b/code/game/src/items.c @@ -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_PLACE:{ world_block_lookup l = world_block_from_realpos(p.x, p.y); - if (l.is_outer && l.block_id > 0) { - asset_id item_asset = blocks_get_asset(l.block_id); + if (l.is_outer && l.bid > 0) { + asset_id item_asset = blocks_get_asset(l.bid); uint16_t item_asset_id = item_find(item_asset); 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! - 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; } world_chunk_replace_block(l.chunk_id, l.id, blocks_find(desc->place.kind + (asset_id)udata)); diff --git a/code/game/src/world/blocks.c b/code/game/src/world/blocks.c index d2edfaf..488fe5d 100644 --- a/code/game/src/world/blocks.c +++ b/code/game/src/world/blocks.c @@ -31,13 +31,13 @@ typedef struct { float vely; // NOTE(zaklaus): viewer data - uint16_t slot; + block_id slot; } block; #include "blocks_list.c" int32_t blocks_setup(void) { - for (uint16_t i=0; ichunk_size; diff --git a/code/game/src/world/blocks.h b/code/game/src/world/blocks.h index a466d3f..c5bbee8 100644 --- a/code/game/src/world/blocks.h +++ b/code/game/src/world/blocks.h @@ -8,23 +8,25 @@ typedef enum { BLOCK_FLAG_ESSENTIAL = (1 << 3), } block_flags; +typedef uint8_t block_id; + int32_t blocks_setup(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); -char blocks_get_symbol(uint16_t id); -uint32_t blocks_get_flags(uint16_t id); -float blocks_get_drag(uint16_t id); -float blocks_get_friction(uint16_t id); -float blocks_get_bounce(uint16_t id); -float blocks_get_velx(uint16_t id); -float blocks_get_vely(uint16_t id); +asset_id blocks_get_asset(block_id id); +char blocks_get_symbol(block_id id); +uint32_t blocks_get_flags(block_id id); +float blocks_get_drag(block_id id); +float blocks_get_friction(block_id id); +float blocks_get_bounce(block_id id); +float blocks_get_velx(block_id id); +float blocks_get_vely(block_id id); // 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_remove_chunk_tex(uint64_t id); \ No newline at end of file diff --git a/code/game/src/world/world.c b/code/game/src/world/world.c index 5d04569..a629c8e 100644 --- a/code/game/src/world/world.c +++ b/code/game/src/world/world.c @@ -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_UPDATE, tracker_write_update); - world.data = zpl_malloc(sizeof(uint16_t)*world.size); - world.outer_data = zpl_malloc(sizeof(uint16_t)*world.size); + world.data = zpl_malloc(sizeof(block_id)*world.size); + world.outer_data = zpl_malloc(sizeof(block_id)*world.size); if (!world.data || !world.outer_data) { 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); 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(uint16_t*)*zpl_square(chunk_amount)); - world.outer_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(block_id*)*zpl_square(chunk_amount)); world_snapshot_init(&streamer_snapshot, zpl_heap()); 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_chunk_to_chunkpos(world.tracker, i, &chunk->x, &chunk->y, NULL); world.chunk_mapping[i] = e; - world.block_mapping[i] = zpl_malloc(sizeof(uint16_t)*zpl_square(chunk_size)); - world.outer_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(block_id)*zpl_square(chunk_size)); chunk->id = i; 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_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.outer_block_mapping[i][(y*chunk_size)+x]; @@ -333,7 +333,7 @@ int32_t world_write(pkt_header *pkt, void *udata) { 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(ptr); *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 by = (uint16_t)chy / WORLD_BLOCK_SIZE; 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; - if (block_id == 0) { - block_id = world.block_mapping[chunk_id][block_idx]; + if (bid == 0) { + bid = world.block_mapping[chunk_id][block_idx]; is_outer = false; } @@ -426,7 +426,7 @@ world_block_lookup world_block_from_realpos(float x, float y) { world_block_lookup lookup = { .id = block_idx, - .block_id = block_id, + .bid = bid, .chunk_id = chunk_id, .chunk_e = e, .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_chunk_replace_block(l.chunk_id, l.id, 0); - if (l.is_outer && l.block_id > 0 && drop_item) { - asset_id item_asset = blocks_get_asset(l.block_id); + if (l.is_outer && l.bid > 0 && drop_item) { + asset_id item_asset = blocks_get_asset(l.bid); if (item_find(item_asset) == ASSET_INVALID) return; 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) { - uint16_t block_id = world.outer_block_mapping[id][block_idx]; - if (block_id == 0) { - block_id = world.block_mapping[id][block_idx]; + block_id bid = world.outer_block_mapping[id][block_idx]; + if (bid == 0) { + bid = world.block_mapping[id][block_idx]; } world_block_lookup lookup = { .id = block_idx, - .block_id = block_id, + .bid = bid, .chunk_id = 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); } -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)); - world.block_mapping[id][block_idx] = block_id; + world.block_mapping[id][block_idx] = bid; 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)); - 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]); } -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)); - if (world.outer_block_mapping[id][block_idx] != 0 && block_id != 0) return false; - world.outer_block_mapping[id][block_idx] = block_id; + if (world.outer_block_mapping[id][block_idx] != 0 && bid != 0) return false; + world.outer_block_mapping[id][block_idx] = bid; world_chunk_mark_dirty(world.chunk_mapping[id]); 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]; } @@ -508,7 +508,7 @@ void world_chunk_mark_dirty(ecs_entity_t e) { 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; Chunk *chunk = ecs_get_mut(world_ecs(), e, Chunk, &was_added); ZPL_ASSERT(!was_added); diff --git a/code/game/src/world/world.h b/code/game/src/world/world.h index d7e4b00..6116486 100644 --- a/code/game/src/world/world.h +++ b/code/game/src/world/world.h @@ -4,6 +4,7 @@ #include "packet.h" #include "flecs/flecs.h" #include "flecs/flecs_meta.h" +#include "world/blocks.h" #include "modules/components.h" #define WORLD_ERROR_NONE +0x0000 @@ -31,14 +32,14 @@ typedef WORLD_PKT_WRITER(world_pkt_writer_proc); typedef struct { bool is_paused; - uint16_t *data; - uint16_t *outer_data; + block_id *data; + block_id *outer_data; uint32_t seed; uint32_t size; uint16_t chunk_size; uint16_t chunk_amount; - uint16_t **block_mapping; - uint16_t **outer_block_mapping; + block_id **block_mapping; + block_id **outer_block_mapping; uint16_t dim; uint64_t tracker_update[3]; 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_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); ecs_world_t *world_ecs(void); void world_set_stage(ecs_world_t *ecs); @@ -78,7 +79,7 @@ ecs_entity_t world_chunk_mapping(librg_chunk id); typedef struct { uint16_t id; - uint16_t block_id; + block_id bid; ecs_entity_t chunk_e; int64_t chunk_id; 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); // 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 -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, // 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 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); -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 !! int64_t *world_chunk_fetch_entities(librg_chunk chunk_id, size_t *ents_len); diff --git a/code/game/src/world/worldgen/worldgen_test.c b/code/game/src/world/worldgen/worldgen_test.c index 21fc5a5..1a96def 100644 --- a/code/game/src/world/worldgen/worldgen_test.c +++ b/code/game/src/world/worldgen/worldgen_test.c @@ -12,7 +12,7 @@ #include "items.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); #define WORLD_PERLIN_FREQ 100 @@ -20,7 +20,7 @@ typedef WORLD_BLOCK_OBSERVER(world_block_observer_proc); #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; switch (biome) { case BLOCK_BIOME_DEV: { @@ -41,7 +41,7 @@ uint16_t worldgen_biome_find(uint32_t biome, uint32_t kind) { 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= 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; if (proc) { - uint16_t new_id = (*proc)(data, id, i); + block_id new_id = (*proc)(data, id, i); if (new_id != BLOCK_INVALID) { 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= 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; if (proc) { - uint16_t new_id = (*proc)(data, id, i); + block_id new_id = (*proc)(data, id, i); if (new_id != BLOCK_INVALID) { 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 h2 = (uint32_t)floorf(h*ay); world_fill_rect(data, id, x-w2, y-h2, w, h, proc); @@ -101,14 +101,14 @@ static WORLD_BLOCK_OBSERVER(shaper) { 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 y = block_idx / world->dim + ofy; 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); } @@ -162,12 +162,12 @@ int32_t worldgen_test(world_data *wld) { // TODO: perform world gen // 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); - uint16_t grnd_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_GROUND); - uint16_t dirt_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_DIRT); - uint16_t watr_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_WATER); - uint16_t lava_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_LAVA); - uint16_t tree_id = blocks_find(ASSET_TREE); + block_id wall_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_WALL); + block_id grnd_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_GROUND); + block_id dirt_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_DIRT); + block_id watr_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_WATER); + block_id lava_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_LAVA); + block_id tree_id = blocks_find(ASSET_TREE); srand(world->seed); diff --git a/code/modules/modules/systems.c b/code/modules/modules/systems.c index 899d58d..2f9021b 100644 --- a/code/modules/modules/systems.c +++ b/code/modules/modules/systems.c @@ -38,8 +38,8 @@ void IntegratePositions(ecs_iter_t *it) { // NOTE(zaklaus): X axis { 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); - float bounce = blocks_get_bounce(lookup.block_id); + uint32_t flags = blocks_get_flags(lookup.bid); + float bounce = blocks_get_bounce(lookup.bid); if (flags & BLOCK_FLAG_COLLISION) { 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 { 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); - float bounce = blocks_get_bounce(lookup.block_id); + uint32_t flags = blocks_get_flags(lookup.bid); + float bounce = blocks_get_bounce(lookup.bid); if (flags & BLOCK_FLAG_COLLISION) { 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++) { 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) { h->pain_time = HAZARD_BLOCK_TIME; h->hp -= HAZARD_BLOCK_DMG; @@ -140,10 +140,10 @@ void ApplyWorldDragOnVelocity(ecs_iter_t *it) { for (int i = 0; i < it->count; i++) { 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 friction = blocks_get_friction(lookup.block_id); - float velx = blocks_get_velx(lookup.block_id); - float vely = blocks_get_vely(lookup.block_id); + float drag = zpl_clamp(blocks_get_drag(lookup.bid), 0.0f, 1.0f); + float friction = blocks_get_friction(lookup.bid); + float velx = blocks_get_velx(lookup.bid); + 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].y = zpl_lerp(v[i].y, zpl_max(0.0f, zpl_abs(vely))*zpl_sign(vely), PHY_WALK_DRAG*drag*friction*safe_dt(it)); } diff --git a/code/modules/source/system_demo.c b/code/modules/source/system_demo.c index 494e6c4..4805103 100644 --- a/code/modules/source/system_demo.c +++ b/code/modules/source/system_demo.c @@ -6,7 +6,7 @@ void DemoNPCMoveAround(ecs_iter_t *it) { Velocity *v = ecs_column(it, Velocity, 1); 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); - 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].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].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((float)(rand()%360)))*DEMO_NPC_STEER_SPEED*safe_dt(it)); } } diff --git a/code/modules/source/system_onfoot.c b/code/modules/source/system_onfoot.c index 0a97616..20fca68 100644 --- a/code/modules/source/system_onfoot.c +++ b/code/modules/source/system_onfoot.c @@ -1,5 +1,5 @@ -#define PLR_MOVE_SPEED 800.0 -#define PLR_MOVE_SPEED_MULT 1.5 +#define PLR_MOVE_SPEED 800.0f +#define PLR_MOVE_SPEED_MULT 1.5f void MovementImpulse(ecs_iter_t *it) { 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++) { 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); - double speed = PLR_MOVE_SPEED * (in[i].sprint ? PLR_MOVE_SPEED_MULT : 1.0); + float drag = zpl_clamp(blocks_get_drag(lookup.bid), 0.0f, 1.0f); + 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].y -= in[i].y*speed*drag*safe_dt(it); } diff --git a/code/modules/source/system_vehicle.c b/code/modules/source/system_vehicle.c index 467a259..97bb7d7 100644 --- a/code/modules/source/system_vehicle.c +++ b/code/modules/source/system_vehicle.c @@ -6,10 +6,10 @@ void LeaveVehicle(ecs_iter_t *it) { Input *in = ecs_column(it, Input, 1); IsInVehicle *vehp = ecs_column(it, IsInVehicle, 2); Velocity *v = ecs_column(it, Velocity, 3); - + for (int i = 0; i < it->count; i++) { if (!in[i].use) continue; - + Vehicle *veh = 0; if ((veh = ecs_get_mut_if(it->world, vehp->veh, Vehicle))) { for (int k = 0; k < 4; k++) { @@ -18,10 +18,10 @@ void LeaveVehicle(ecs_iter_t *it) { break; } } - + in[i].use = false; ecs_remove(it->world, it->entities[i], IsInVehicle); - + // NOTE(zaklaus): push passenger out { float px = zpl_cos(veh->heading)*400.0f; @@ -38,29 +38,29 @@ void LeaveVehicle(ecs_iter_t *it) { void EnterVehicle(ecs_iter_t *it) { Input *in = ecs_column(it, Input, 1); Position *p = ecs_column(it, Position, 2); - + for (int i = 0; i < it->count; i++) { if (!in[i].use) continue; - + size_t ents_count; int64_t *ents = world_chunk_query_entities(it->entities[i], &ents_count, 2); bool has_entered_veh = false; - + for (size_t j = 0; j < ents_count; j++) { Vehicle *veh = 0; - + if (has_entered_veh) break; - + if ((veh = ecs_get_mut_if(it->world, ents[j], Vehicle))) { Position const* p2 = ecs_get(it->world, ents[j], Position); - + float dx = p2->x - p[i].x; float dy = p2->y - p[i].y; float range = zpl_sqrt(dx*dx + dy*dy); if (range <= VEH_ENTER_RADIUS) { for (int k = 0; k < 4; k++) { if (veh->seats[k] != 0) continue; - + // NOTE(zaklaus): We can enter the vehicle, yay! veh->seats[k] = it->entities[i]; 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); Position *p = ecs_column(it, Position, 2); Velocity *v = ecs_column(it, Velocity, 3); - + for (int i = 0; i < it->count; i++) { Vehicle *car = &veh[i]; - + for (int j = 0; j < 4; j++) { // NOTE(zaklaus): Perform seat cleanup if (!world_entity_valid(veh[i].seats[j])) { veh[i].seats[j] = 0; continue; } - + ecs_entity_t pe = veh[i].seats[j]; - + // NOTE(zaklaus): Handle driver input if (j == 0) { 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)); if (in->sprint) { car->force = zpl_lerp(car->force, 0.0f, VEHICLE_BRAKE_FORCE*safe_dt(it)); - + if (zpl_abs(car->force) < 5.5f) 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->force = zpl_clamp(car->force, car->reverse_speed, car->speed); - + // NOTE(zaklaus): Vehicle physics 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 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); - + 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_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_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].y += ((fr_y + bk_y) / 2.0f - p[i].y); 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)); - uint32_t flags = blocks_get_flags(lookahead.block_id); + uint32_t flags = blocks_get_flags(lookahead.bid); if (flags & BLOCK_FLAG_COLLISION) { car->force = 0.0f; } - + for (int j = 0; j < 4; j++) { if (!world_entity_valid(veh[i].seats[j])) continue; ecs_entity_t pe = veh[i].seats[j]; - + // NOTE(zaklaus): Update passenger position { Position *p2 = ecs_get_mut(it->world, pe, Position, NULL); @@ -160,18 +160,18 @@ void VehicleHandling(ecs_iter_t *it) { *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_push_line((debug_v2){p[i].x, p[i].y}, b2, 0x0000FFFF); - + // NOTE(zaklaus): force { float dx = zpl_cos(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); } - + // NOTE(zaklaus): steer { float dx = zpl_sin(car->heading); @@ -185,7 +185,7 @@ void VehicleHandling(ecs_iter_t *it) { void ClearVehicle(ecs_iter_t *it) { Vehicle *veh = ecs_column(it, Vehicle, 1); - + for (int i = 0; i < it->count; i++) { for (int k = 0; k < 4; k++) { if (world_entity_valid(veh[i].seats[k])) {