code: various bits and pieces
parent
f0dbc5a651
commit
999763f197
|
@ -16,6 +16,7 @@ add_executable(eco2d
|
|||
src/entity_view.c
|
||||
src/packet.c
|
||||
src/player.c
|
||||
src/vehicle.c
|
||||
src/signal_handling.c
|
||||
src/profiler.c
|
||||
src/debug_ui.c
|
||||
|
|
|
@ -89,6 +89,16 @@ static debug_item items[] = {
|
|||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
.kind = DITEM_LIST,
|
||||
.name = "debug actions",
|
||||
.list = {
|
||||
.items = (debug_item[]) {
|
||||
{ .kind = DITEM_BUTTON, .name = "spawn car", .on_click = ActSpawnCar },
|
||||
{ .kind = DITEM_END },
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
.kind = DITEM_LIST,
|
||||
.name = "profilers",
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
#include "debug_ui.h"
|
||||
#include "raylib.h"
|
||||
#include "vehicle.h"
|
||||
#include "game.h"
|
||||
|
||||
static inline void
|
||||
ActExitGame(void) {
|
||||
game_request_close();
|
||||
}
|
||||
|
||||
static inline void
|
||||
ActSpawnCar(void) {
|
||||
vehicle_spawn();
|
||||
}
|
|
@ -10,14 +10,12 @@
|
|||
#include "zpl.h"
|
||||
|
||||
uint64_t entity_spawn(uint16_t class_id) {
|
||||
ECS_IMPORT(world_ecs(), Components);
|
||||
|
||||
ecs_entity_t e = ecs_new(world_ecs(), 0);
|
||||
|
||||
ecs_set(world_ecs(), e, Velocity, {0});
|
||||
ecs_set(world_ecs(), e, Classify, { .id = class_id });
|
||||
ecs_add(world_ecs(), e, Walking);
|
||||
Position *pos = ecs_get_mut(world_ecs(), e, Position, NULL);
|
||||
w_ecs_set(e, Velocity, {0});
|
||||
w_ecs_set(e, Classify, { .id = class_id });
|
||||
w_ecs_add(e, Walking);
|
||||
Position *pos = w_ecs_get_mut(e, Position, NULL);
|
||||
#if 1
|
||||
pos->x=rand() % world_dim();
|
||||
pos->y=rand() % world_dim();
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
typedef enum {
|
||||
EKIND_SERVER = 0,
|
||||
EKIND_PLAYER,
|
||||
EKIND_VEHICLE,
|
||||
EKIND_DEMO_NPC,
|
||||
EKIND_MONSTER,
|
||||
EKIND_CHUNK,
|
||||
|
|
|
@ -81,7 +81,7 @@ world_view *game_world_view_get_active(void) {
|
|||
|
||||
void game_world_view_cycle_active(int8_t dir) {
|
||||
uint16_t idx = (uint16_t)(active_viewer - world_viewers);
|
||||
game_world_view_set_active_by_idx((idx+dir)%zpl_buffer_count(world_viewers));
|
||||
game_world_view_set_active_by_idx(zpl_max(0, (idx+dir)%zpl_buffer_count(world_viewers)));
|
||||
}
|
||||
void game_world_view_set_active_by_idx(uint16_t idx) {
|
||||
ZPL_ASSERT(idx >= 0 && idx < zpl_buffer_count(world_viewers));
|
||||
|
|
|
@ -28,13 +28,12 @@ size_t pkt_00_init_send(uint16_t view_id) {
|
|||
}
|
||||
|
||||
int32_t pkt_00_init_handler(pkt_header *header) {
|
||||
ECS_IMPORT(world_ecs(), Components);
|
||||
pkt_00_init table;
|
||||
PKT_IF(pkt_msg_decode(header, pkt_00_init_desc, pkt_pack_desc_args(pkt_00_init_desc), PKT_STRUCT_PTR(&table)));
|
||||
|
||||
uint64_t peer_id = (uint64_t)header->udata;
|
||||
uint64_t ent_id = player_spawn(NULL);
|
||||
ecs_set(world_ecs(), ent_id, ClientInfo, {.peer = ent_id, .view_id = header->view_id });
|
||||
w_ecs_set(ent_id, ClientInfo, {.peer = ent_id, .view_id = header->view_id });
|
||||
pkt_01_welcome_send(peer_id, header->view_id, ent_id, world_chunk_size(), world_chunk_amount());
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -32,11 +32,9 @@ int32_t pkt_send_keystate_handler(pkt_header *header) {
|
|||
pkt_send_keystate table;
|
||||
PKT_IF(pkt_msg_decode(header, pkt_send_keystate_desc, pkt_pack_desc_args(pkt_send_keystate_desc), PKT_STRUCT_PTR(&table)));
|
||||
ecs_entity_t e = PKT_GET_ENT(header);
|
||||
ecs_world_t *ecs = world_ecs();
|
||||
|
||||
ECS_IMPORT(ecs, Components);
|
||||
Input *i = ecs_get_mut(world_ecs(), e, Input, NULL);
|
||||
if (i) {
|
||||
Input *i = w_ecs_get_mut(e, Input, NULL);
|
||||
if (i && !i->is_blocked) {
|
||||
i->x = table.x;
|
||||
i->y = table.y;
|
||||
i->use = table.use;
|
||||
|
|
|
@ -19,14 +19,12 @@ uint64_t player_spawn(char *name) {
|
|||
name = zpl_bprintf("player_%d", e);
|
||||
}
|
||||
|
||||
ECS_IMPORT(world_ecs(), Components);
|
||||
|
||||
ecs_set(world_ecs(), e, EcsName, {.alloc_value = name });
|
||||
ecs_add(world_ecs(), e, EcsClient);
|
||||
ecs_set(world_ecs(), e, ClientInfo, {0});
|
||||
ecs_set(world_ecs(), e, Input, {0});
|
||||
ecs_set(world_ecs(), e, Health, {.hp = PLAYER_MAX_HP, .max_hp = PLAYER_MAX_HP});
|
||||
ecs_add(world_ecs(), e, Player);
|
||||
w_ecs_add(e, EcsClient);
|
||||
w_ecs_set(e, ClientInfo, {0});
|
||||
w_ecs_set(e, Input, {0});
|
||||
w_ecs_set(e, Health, {.hp = PLAYER_MAX_HP, .max_hp = PLAYER_MAX_HP});
|
||||
w_ecs_add(e, Player);
|
||||
|
||||
librg_entity_owner_set(world_tracker(), e, (int64_t)e);
|
||||
|
||||
|
@ -36,3 +34,6 @@ uint64_t player_spawn(char *name) {
|
|||
void player_despawn(uint64_t ent_id) {
|
||||
entity_despawn(ent_id);
|
||||
}
|
||||
|
||||
void player_freeze(uint64_t id, uint8_t state, uint8_t clear) {
|
||||
}
|
|
@ -3,3 +3,5 @@
|
|||
|
||||
uint64_t player_spawn(char *name);
|
||||
void player_despawn(uint64_t ent_id);
|
||||
|
||||
void player_freeze(uint64_t id, uint8_t state, uint8_t clear);
|
|
@ -0,0 +1,17 @@
|
|||
#include "vehicle.h"
|
||||
#include "entity.h"
|
||||
#include "entity_view.h"
|
||||
#include "world/world.h"
|
||||
|
||||
#include "modules/components.h"
|
||||
|
||||
uint64_t vehicle_spawn(void) {
|
||||
ecs_entity_t e = entity_spawn(EKIND_VEHICLE);
|
||||
|
||||
w_ecs_add(e, Vehicle);
|
||||
return (uint64_t)e;
|
||||
}
|
||||
|
||||
void vehicle_despawn(uint64_t ent_id) {
|
||||
entity_despawn(ent_id);
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
#pragma once
|
||||
#include "system.h"
|
||||
|
||||
uint64_t vehicle_spawn(void);
|
||||
void vehicle_despawn(uint64_t id);
|
||||
|
||||
|
|
@ -10,39 +10,44 @@
|
|||
|
||||
#include "packets/pkt_send_librg_update.h"
|
||||
|
||||
ZPL_TABLE(static, world_snapshot, world_snapshot_, entity_view);
|
||||
|
||||
static world_data world = {0};
|
||||
static Components const *ecs_components;
|
||||
static world_snapshot streamer_snapshot;
|
||||
static ecs_entity_t components_handle;
|
||||
|
||||
entity_view world_build_entity_view(int64_t e) {
|
||||
ECS_IMPORT(world.ecs, Components);
|
||||
entity_view *cached_ev = world_snapshot_get(&streamer_snapshot, e);
|
||||
if (cached_ev) return *cached_ev;
|
||||
|
||||
entity_view view = {0};
|
||||
|
||||
const Classify *classify = ecs_get(world.ecs, e, Classify);
|
||||
const Classify *classify = w_ecs_get(e, Classify);
|
||||
assert(classify);
|
||||
|
||||
view.kind = classify->id;
|
||||
|
||||
const Position *pos = ecs_get(world.ecs, e, Position);
|
||||
const Position *pos = w_ecs_get(e, Position);
|
||||
if (pos) {
|
||||
view.x = pos->x;
|
||||
view.y = pos->y;
|
||||
}
|
||||
|
||||
const Velocity *vel = ecs_get(world.ecs, e, Velocity);
|
||||
const Velocity *vel = w_ecs_get(e, Velocity);
|
||||
if (vel) {
|
||||
view.flag |= EFLAG_INTERP;
|
||||
view.vx = vel->x;
|
||||
view.vy = vel->y;
|
||||
}
|
||||
|
||||
const Health *health = ecs_get(world.ecs, e, Health);
|
||||
const Health *health = w_ecs_get(e, Health);
|
||||
if (health) {
|
||||
view.hp = health->hp;
|
||||
view.max_hp = health->max_hp;
|
||||
}
|
||||
|
||||
if (ecs_get(world.ecs, e, Chunk)) {
|
||||
Chunk *chpos = ecs_get_mut(world.ecs, e, Chunk, 0);
|
||||
if (w_ecs_get(e, Chunk)) {
|
||||
Chunk *chpos = w_ecs_get_mut(e, Chunk, 0);
|
||||
view.x = chpos->x;
|
||||
view.y = chpos->y;
|
||||
view.blocks_used = 1;
|
||||
|
@ -54,6 +59,7 @@ entity_view world_build_entity_view(int64_t e) {
|
|||
}
|
||||
}
|
||||
|
||||
world_snapshot_set(&streamer_snapshot, e, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
|
@ -90,7 +96,6 @@ int32_t tracker_write_update(librg_world *w, librg_event *e) {
|
|||
entity_view view = world_build_entity_view(entity_id);
|
||||
|
||||
// NOTE(zaklaus): exclude chunks from updates as they never move
|
||||
// TODO(zaklaus): use dirty flag to send updates if chunk changes
|
||||
{
|
||||
if (view.kind == EKIND_CHUNK && !view.is_dirty) {
|
||||
return LIBRG_WRITE_REJECT;
|
||||
|
@ -149,7 +154,8 @@ 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));
|
||||
ecs_components = ecs_get(world.ecs, ecs_typeid(Components), Components);
|
||||
components_handle = ecs_typeid(Components);
|
||||
world_snapshot_init(&streamer_snapshot, zpl_heap());
|
||||
|
||||
int32_t world_build_status = worldgen_test(&world);
|
||||
ZPL_ASSERT(world_build_status >= 0);
|
||||
|
@ -190,6 +196,7 @@ int32_t world_destroy(void) {
|
|||
zpl_mfree(world.block_mapping[i]);
|
||||
}
|
||||
zpl_mfree(world.block_mapping);
|
||||
world_snapshot_destroy(&streamer_snapshot);
|
||||
zpl_memset(&world, 0, sizeof(world));
|
||||
zpl_printf("[INFO] World was destroyed.\n");
|
||||
return WORLD_ERROR_NONE;
|
||||
|
@ -202,8 +209,6 @@ static void world_tracker_update(uint8_t ticker, uint32_t freq, uint8_t radius)
|
|||
world.tracker_update[ticker] = zpl_time_rel_ms() + freq;
|
||||
|
||||
profile(PROF_WORLD_WRITE) {
|
||||
ECS_IMPORT(world.ecs, Components);
|
||||
|
||||
ecs_iter_t it = ecs_query_iter(world.ecs_update);
|
||||
static char buffer[WORLD_LIBRG_BUFSIZ] = {0};
|
||||
world.active_layer_id = ticker;
|
||||
|
@ -230,13 +235,18 @@ static void world_tracker_update(uint8_t ticker, uint32_t freq, uint8_t radius)
|
|||
pkt_send_librg_update((uint64_t)p[i].peer, p[i].view_id, ticker, buffer, datalen);
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(zaklaus): clear out our streaming snapshot
|
||||
// TODO(zaklaus): move this to zpl
|
||||
{
|
||||
zpl_array_clear(streamer_snapshot.hashes);
|
||||
zpl_array_clear(streamer_snapshot.entries);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int32_t world_update() {
|
||||
ECS_IMPORT(world.ecs, Components);
|
||||
|
||||
profile (PROF_UPDATE_SYSTEMS) {
|
||||
ecs_progress(world.ecs, 0.0f);
|
||||
}
|
||||
|
@ -273,11 +283,12 @@ ecs_world_t * world_ecs() {
|
|||
return world.ecs;
|
||||
}
|
||||
|
||||
Components const* world_components(void) {
|
||||
return ecs_components;
|
||||
Components const *world_components(void) {
|
||||
ecs_entity_t ecs_typeid(Components) = components_handle;
|
||||
return ecs_get(world.ecs, ecs_typeid(Components), Components);
|
||||
}
|
||||
|
||||
librg_world * world_tracker() {
|
||||
librg_world *world_tracker() {
|
||||
return world.tracker;
|
||||
}
|
||||
|
||||
|
@ -366,14 +377,14 @@ uint8_t *world_chunk_get_blocks(int64_t id) {
|
|||
|
||||
void world_chunk_mark_dirty(ecs_entity_t e) {
|
||||
bool was_added=false;
|
||||
Chunk *chunk = (Chunk *)ecs_get_mut_w_entity(world.ecs, e, ecs_components->ecs_typeid(Chunk), &was_added);
|
||||
Chunk *chunk = w_ecs_get_mut(e, Chunk, &was_added);
|
||||
assert(!was_added);
|
||||
if (chunk) chunk->is_dirty = true;
|
||||
}
|
||||
|
||||
uint8_t world_chunk_is_dirty(ecs_entity_t e) {
|
||||
bool was_added=false;
|
||||
Chunk *chunk = (Chunk *)ecs_get_mut_w_entity(world.ecs, e, ecs_components->ecs_typeid(Chunk), &was_added);
|
||||
Chunk *chunk = w_ecs_get_mut(e, Chunk, &was_added);
|
||||
assert(!was_added);
|
||||
if (chunk) return chunk->is_dirty;
|
||||
return false;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "librg.h"
|
||||
#include "packet.h"
|
||||
#include "flecs/flecs.h"
|
||||
#include "flecs/flecs_meta.h"
|
||||
#include "modules/components.h"
|
||||
|
||||
#define WORLD_ERROR_NONE +0x0000
|
||||
|
@ -52,9 +53,9 @@ int32_t world_read(void* data, uint32_t datalen, void *udata);
|
|||
int32_t world_write(pkt_header *pkt, void *udata);
|
||||
|
||||
uint32_t world_buf(uint8_t const **ptr, uint32_t *width);
|
||||
ecs_world_t * world_ecs(void);
|
||||
Components const* world_components(void);
|
||||
librg_world * world_tracker(void);
|
||||
ecs_world_t *world_ecs(void);
|
||||
Components const *world_components(void);
|
||||
librg_world *world_tracker(void);
|
||||
|
||||
uint16_t world_chunk_size(void);
|
||||
uint16_t world_chunk_amount(void);
|
||||
|
@ -78,3 +79,20 @@ uint8_t *world_chunk_get_blocks(int64_t id);
|
|||
void world_chunk_mark_dirty(ecs_entity_t e);
|
||||
uint8_t world_chunk_is_dirty(ecs_entity_t e);
|
||||
|
||||
// NOTE(zaklaus): flecs wrappers for easier world access
|
||||
|
||||
#define w_ecs_set(entity, component, ...)\
|
||||
ecs_set_ptr_w_entity(world_ecs(), entity, world_components()->ecs_typeid(component), sizeof(component), &(component)__VA_ARGS__)
|
||||
|
||||
#define w_ecs_add(entity, component)\
|
||||
ecs_add_type(world_ecs(), entity, world_components()->ecs_type(component))
|
||||
|
||||
#define w_ecs_get(entity, component)\
|
||||
((const component*)ecs_get_w_entity(world_ecs(), entity, world_components()->ecs_typeid(component)))
|
||||
|
||||
#define w_ecs_get_ref(ref, entity, component)\
|
||||
((const component*)ecs_get_ref_w_entity(world_ecs(), ref, entity, world_components()->ecs_typeid(component)))
|
||||
|
||||
#define w_ecs_get_mut(entity, component, is_added)\
|
||||
((component*)ecs_get_mut_w_entity(world_ecs(), entity, world_components()->ecs_typeid(component), is_added))
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ void ComponentsImport(ecs_world_t *ecs) {
|
|||
ECS_META(ecs, Input);
|
||||
ECS_META(ecs, Health);
|
||||
ECS_META(ecs, Classify);
|
||||
ECS_META(ecs, Vehicle);
|
||||
|
||||
ECS_TAG(ecs, Walking);
|
||||
ECS_TAG(ecs, Flying);
|
||||
|
@ -37,6 +38,7 @@ void ComponentsImport(ecs_world_t *ecs) {
|
|||
ECS_SET_COMPONENT(Input);
|
||||
ECS_SET_COMPONENT(Health);
|
||||
ECS_SET_COMPONENT(Classify);
|
||||
ECS_SET_COMPONENT(Vehicle);
|
||||
ECS_SET_ENTITY(EcsClient);
|
||||
ECS_SET_ENTITY(Walking);
|
||||
ECS_SET_ENTITY(Flying);
|
||||
|
|
|
@ -26,6 +26,7 @@ ECS_STRUCT(Input, {
|
|||
float y;
|
||||
uint8_t use;
|
||||
uint8_t sprint;
|
||||
uint8_t is_blocked;
|
||||
});
|
||||
|
||||
ECS_STRUCT(ClientInfo, {
|
||||
|
@ -46,6 +47,10 @@ ECS_STRUCT(Classify, {
|
|||
uint16_t id;
|
||||
});
|
||||
|
||||
ECS_STRUCT(Vehicle, {
|
||||
uint64_t seats[4];
|
||||
});
|
||||
|
||||
typedef struct {
|
||||
ECS_DECLARE_COMPONENT(Chunk);
|
||||
ECS_DECLARE_COMPONENT(Position);
|
||||
|
@ -56,6 +61,7 @@ typedef struct {
|
|||
ECS_DECLARE_COMPONENT(ClientInfo);
|
||||
ECS_DECLARE_COMPONENT(Health);
|
||||
ECS_DECLARE_COMPONENT(Classify);
|
||||
ECS_DECLARE_COMPONENT(Vehicle);
|
||||
ECS_DECLARE_ENTITY(EcsActor);
|
||||
ECS_DECLARE_ENTITY(EcsPlayer);
|
||||
ECS_DECLARE_ENTITY(EcsBuilder);
|
||||
|
@ -78,6 +84,7 @@ ECS_IMPORT_COMPONENT(handles, Velocity);\
|
|||
ECS_IMPORT_COMPONENT(handles, ClientInfo);\
|
||||
ECS_IMPORT_COMPONENT(handles, Health);\
|
||||
ECS_IMPORT_COMPONENT(handles, Classify);\
|
||||
ECS_IMPORT_COMPONENT(handles, Vehicle);\
|
||||
ECS_IMPORT_TYPE(handles, Player);\
|
||||
ECS_IMPORT_TYPE(handles, Builder);\
|
||||
ECS_IMPORT_TYPE(handles, Movement);\
|
||||
|
|
|
@ -149,7 +149,6 @@ void MovementImpulse(ecs_iter_t *it) {
|
|||
|
||||
void DemoNPCMoveAround(ecs_iter_t *it) {
|
||||
Velocity *v = ecs_column(it, Velocity, 1);
|
||||
|
||||
for (int i = 0; i < it->count; i++) {
|
||||
v[i].x = zpl_lerp(v[i].x, (rand()%3-1)*DEMO_NPC_MOVE_SPEED, DEMO_NPC_CHANGEDIR_FACTOR);
|
||||
v[i].y = zpl_lerp(v[i].y, (rand()%3-1)*DEMO_NPC_MOVE_SPEED, DEMO_NPC_CHANGEDIR_FACTOR);
|
||||
|
|
Loading…
Reference in New Issue