Improve hashtable entry removal performance

isolation_bkp/dynres
Dominik Madarász 2021-10-28 16:05:17 +02:00
parent a589845065
commit 296857df71
9 changed files with 18600 additions and 18562 deletions

View File

@ -90,7 +90,6 @@ static debug_item items[] = {
{ .kind = DITEM_TEXT, .name = "delta time", .proc = DrawDeltaTime },
{ .kind = DITEM_TEXT, .name = "pos", .proc = DrawCameraPos },
{ .kind = DITEM_TEXT, .name = "zoom", .proc = DrawZoom },
{ .kind = DITEM_SLIDER, .name = "slider", .slider = { .min = 0.0f, .max = 1.0f, .val = 0.5f } },
{ .kind = DITEM_END },
}
}
@ -180,6 +179,7 @@ static debug_item items[] = {
{ .kind = DITEM_END },
},
.is_sp_only = true,
.is_collapsed = true,
}
},
{

View File

@ -226,9 +226,7 @@ void
ActDespawnDemoNPCs(void) {
if (!demo_npcs) return;
for (uint32_t i = 0; i < zpl_array_count(demo_npcs); i++) {
entity_despawn(demo_npcs[i]);
}
entity_batch_despawn(demo_npcs, zpl_array_count(demo_npcs));
zpl_array_free(demo_npcs);
demo_npcs = 0;

View File

@ -12,19 +12,20 @@
uint64_t entity_spawn(uint16_t class_id) {
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);
#if 1
pos->x=rand() % world_dim();
pos->y=rand() % world_dim();
#else
pos->x=350;
pos->y=88;
#endif
if (class_id != EKIND_SERVER) {
ecs_set(world_ecs(), e, Velocity, {0});
ecs_add(world_ecs(), e, Walking);
Position *pos = ecs_get_mut(world_ecs(), e, Position, NULL);
#if 1
pos->x=(float)(rand() % world_dim());
pos->y=(float)(rand() % world_dim());
#else
pos->x=350.0f;
pos->y=88.0f;
#endif
librg_entity_track(world_tracker(), e);
librg_entity_chunk_set(world_tracker(), e, librg_chunk_from_realpos(world_tracker(), pos->x, pos->y, 0));
librg_entity_owner_set(world_tracker(), e, (int64_t)e);
@ -33,6 +34,13 @@ uint64_t entity_spawn(uint16_t class_id) {
return (uint64_t)e;
}
void entity_batch_despawn(uint64_t *ids, size_t num_ids) {
for (size_t i = 0; i < num_ids; i++ ) {
librg_entity_untrack(world_tracker(), ids[i]);
ecs_delete(world_ecs(), ids[i]);
}
}
void entity_despawn(uint64_t ent_id) {
librg_entity_untrack(world_tracker(), ent_id);
ecs_delete(world_ecs(), ent_id);

View File

@ -1,188 +1,188 @@
#include "zpl.h"
#define ENET_IMPLEMENTATION
#include "enet.h"
#define LIBRG_IMPL
#define LIBRG_CUSTOM_ZPL
#define LIBRG_ENTITY_MAXCHUNKS 1
#include "librg.h"
#include "network.h"
#include "packet.h"
#include "world/world.h"
#include "game.h"
#include "player.h"
#define NETWORK_UPDATE_DELAY 0.100
static ENetHost *host = NULL;
static ENetHost *server = NULL;
static ENetPeer *peer = NULL;
static librg_world *world = NULL;
int32_t network_init() {
return enet_initialize() != 0;
}
int32_t network_destroy() {
enet_deinitialize();
return 0;
}
//~ NOTE(zaklaus): client
int32_t network_client_connect(const char *hostname, uint16_t port) {
ENetAddress address = {0}; address.port = port;
enet_address_set_host(&address, hostname);
host = enet_host_create(NULL, 1, 2, 0, 0);
peer = enet_host_connect(host, &address, 2, 0);
if (peer == NULL) {
zpl_printf("[ERROR] Cannot connect to specicied server: %s:%d\n", hostname, port);
return 1;
}
world = librg_world_create();
librg_world_userdata_set(world, peer);
return 0;
}
int32_t network_client_disconnect() {
enet_peer_disconnect_now(peer, 0);
enet_host_destroy(host);
librg_world_destroy(world);
peer = NULL;
host = NULL;
world = NULL;
return 0;
}
int32_t network_client_tick() {
ENetEvent event = {0};
while (enet_host_service(host, &event, 1) > 0) {
switch (event.type) {
case ENET_EVENT_TYPE_CONNECT: {
zpl_printf("[INFO] We connected to the server.\n");
pkt_00_init_send(0);
} break;
case ENET_EVENT_TYPE_DISCONNECT:
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT: {
zpl_printf("[INFO] We disconnected from server.\n");
} break;
case ENET_EVENT_TYPE_RECEIVE: {
if (!world_read(event.packet->data, event.packet->dataLength, event.peer)) {
zpl_printf("[INFO] Server sent us an unsupported packet.\n");
}
/* Clean up the packet now that we're done using it. */
enet_packet_destroy(event.packet);
} break;
case ENET_EVENT_TYPE_NONE: break;
}
}
return 0;
}
bool network_client_is_connected() {
return peer ? enet_peer_get_state(peer) == ENET_PEER_STATE_CONNECTED : false;
}
//~ NOTE(zaklaus): server
int32_t network_server_start(const char *host, uint16_t port) {
(void)host;
ENetAddress address = {0};
address.host = ENET_HOST_ANY;
address.port = port;
server = enet_host_create(&address, 8, 2, 0, 0);
if (server == NULL) {
zpl_printf("[ERROR] An error occured while trying to create a server host.\n");
return 1;
}
return 0;
}
int32_t network_server_stop(void) {
enet_host_destroy(server);
server = 0;
return 0;
}
int32_t network_server_tick(void) {
ENetEvent event = {0};
while (enet_host_service(server, &event, 1) > 0) {
switch (event.type) {
case ENET_EVENT_TYPE_CONNECT: {
zpl_printf("[INFO] A new user %d connected.\n", event.peer->incomingPeerID);
} break;
case ENET_EVENT_TYPE_DISCONNECT:
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT: {
zpl_printf("[INFO] A user %d disconnected.\n", event.peer->incomingPeerID);
if (event.peer->data) {
player_despawn((ecs_entity_t)event.peer->data);
event.peer->data = 0;
}
} break;
case ENET_EVENT_TYPE_RECEIVE: {
if (!world_read(event.packet->data, event.packet->dataLength, event.peer)) {
zpl_printf("[INFO] User %d sent us a malformed packet.\n", event.peer->incomingPeerID);
}
/* Clean up the packet now that we're done using it. */
enet_packet_destroy(event.packet);
} break;
case ENET_EVENT_TYPE_NONE: break;
}
}
return 0;
}
void network_server_assign_entity(void *peer_id, uint64_t ent_id) {
ENetPeer *peer = (ENetPeer *)peer_id;
peer->data = (void*)ent_id;
}
uint64_t network_server_get_entity(void *peer_id) {
if (game_get_kind() == GAMEKIND_SINGLE) {
return (uint64_t)peer_id;
}
ENetPeer *peer = (ENetPeer *)peer_id;
ZPL_ASSERT(peer->data);
return (uint64_t)peer->data;
}
//~ NOTE(zaklaus): messaging
static int32_t network_msg_send_raw(ENetPeer *peer_id, void *data, size_t datalen, uint32_t flags, uint16_t channel_id) {
if (peer_id == 0) peer_id = peer;
ENetPacket *packet = enet_packet_create(data, datalen, flags);
return enet_peer_send(peer_id, channel_id, packet);
}
int32_t network_msg_send(void *peer_id, void *data, size_t datalen, uint16_t channel_id) {
return network_msg_send_raw(peer_id, data, datalen, ENET_PACKET_FLAG_RELIABLE, channel_id);
}
int32_t network_msg_send_unreliable(void *peer_id, void *data, size_t datalen, uint16_t channel_id) {
return network_msg_send_raw(peer_id, data, datalen, 0, channel_id);
}
#include "zpl.h"
#define ENET_IMPLEMENTATION
#include "enet.h"
#define LIBRG_IMPL
#define LIBRG_CUSTOM_ZPL
#define LIBRG_ENTITY_MAXCHUNKS 1
#include "librg.h"
#include "network.h"
#include "packet.h"
#include "world/world.h"
#include "game.h"
#include "player.h"
#define NETWORK_UPDATE_DELAY 0.100
static ENetHost *host = NULL;
static ENetHost *server = NULL;
static ENetPeer *peer = NULL;
static librg_world *world = NULL;
int32_t network_init() {
return enet_initialize() != 0;
}
int32_t network_destroy() {
enet_deinitialize();
return 0;
}
//~ NOTE(zaklaus): client
int32_t network_client_connect(const char *hostname, uint16_t port) {
ENetAddress address = {0}; address.port = port;
enet_address_set_host(&address, hostname);
host = enet_host_create(NULL, 1, 2, 0, 0);
peer = enet_host_connect(host, &address, 2, 0);
if (peer == NULL) {
zpl_printf("[ERROR] Cannot connect to specicied server: %s:%d\n", hostname, port);
return 1;
}
world = librg_world_create();
librg_world_userdata_set(world, peer);
return 0;
}
int32_t network_client_disconnect() {
enet_peer_disconnect_now(peer, 0);
enet_host_destroy(host);
librg_world_destroy(world);
peer = NULL;
host = NULL;
world = NULL;
return 0;
}
int32_t network_client_tick() {
ENetEvent event = {0};
while (enet_host_service(host, &event, 1) > 0) {
switch (event.type) {
case ENET_EVENT_TYPE_CONNECT: {
zpl_printf("[INFO] We connected to the server.\n");
pkt_00_init_send(0);
} break;
case ENET_EVENT_TYPE_DISCONNECT:
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT: {
zpl_printf("[INFO] We disconnected from server.\n");
} break;
case ENET_EVENT_TYPE_RECEIVE: {
if (!world_read(event.packet->data, event.packet->dataLength, event.peer)) {
zpl_printf("[INFO] Server sent us an unsupported packet.\n");
}
/* Clean up the packet now that we're done using it. */
enet_packet_destroy(event.packet);
} break;
case ENET_EVENT_TYPE_NONE: break;
}
}
return 0;
}
bool network_client_is_connected() {
return peer ? enet_peer_get_state(peer) == ENET_PEER_STATE_CONNECTED : false;
}
//~ NOTE(zaklaus): server
int32_t network_server_start(const char *host, uint16_t port) {
(void)host;
ENetAddress address = {0};
address.host = ENET_HOST_ANY;
address.port = port;
server = enet_host_create(&address, 8, 2, 0, 0);
if (server == NULL) {
zpl_printf("[ERROR] An error occured while trying to create a server host.\n");
return 1;
}
return 0;
}
int32_t network_server_stop(void) {
enet_host_destroy(server);
server = 0;
return 0;
}
int32_t network_server_tick(void) {
ENetEvent event = {0};
while (enet_host_service(server, &event, 1) > 0) {
switch (event.type) {
case ENET_EVENT_TYPE_CONNECT: {
zpl_printf("[INFO] A new user %d connected.\n", event.peer->incomingPeerID);
} break;
case ENET_EVENT_TYPE_DISCONNECT:
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT: {
zpl_printf("[INFO] A user %d disconnected.\n", event.peer->incomingPeerID);
if (event.peer->data) {
player_despawn((ecs_entity_t)event.peer->data);
event.peer->data = 0;
}
} break;
case ENET_EVENT_TYPE_RECEIVE: {
if (!world_read(event.packet->data, event.packet->dataLength, event.peer)) {
zpl_printf("[INFO] User %d sent us a malformed packet.\n", event.peer->incomingPeerID);
}
/* Clean up the packet now that we're done using it. */
enet_packet_destroy(event.packet);
} break;
case ENET_EVENT_TYPE_NONE: break;
}
}
return 0;
}
void network_server_assign_entity(void *peer_id, uint64_t ent_id) {
ENetPeer *peer = (ENetPeer *)peer_id;
peer->data = (void*)ent_id;
}
uint64_t network_server_get_entity(void *peer_id) {
if (game_get_kind() == GAMEKIND_SINGLE) {
return (uint64_t)peer_id;
}
ENetPeer *peer = (ENetPeer *)peer_id;
ZPL_ASSERT(peer->data);
return (uint64_t)peer->data;
}
//~ NOTE(zaklaus): messaging
static int32_t network_msg_send_raw(ENetPeer *peer_id, void *data, size_t datalen, uint32_t flags, uint16_t channel_id) {
if (peer_id == 0) peer_id = peer;
ENetPacket *packet = enet_packet_create(data, datalen, flags);
return enet_peer_send(peer_id, channel_id, packet);
}
int32_t network_msg_send(void *peer_id, void *data, size_t datalen, uint16_t channel_id) {
return network_msg_send_raw(peer_id, data, datalen, ENET_PACKET_FLAG_RELIABLE, channel_id);
}
int32_t network_msg_send_unreliable(void *peer_id, void *data, size_t datalen, uint16_t channel_id) {
return network_msg_send_raw(peer_id, data, datalen, 0, channel_id);
}

View File

@ -1,36 +1,36 @@
#include "player.h"
#include "entity.h"
#include "entity_view.h"
#include "flecs/flecs.h"
#include "flecs/flecs_meta.h"
#include "librg.h"
#include "world/world.h"
#include "modules/components.h"
#include "modules/systems.h"
#include "zpl.h"
#define PLAYER_MAX_HP 100.0f
uint64_t player_spawn(char *name) {
ecs_entity_t e = entity_spawn(EKIND_PLAYER);
if (!name) {
name = zpl_bprintf("player_%d", e);
}
ecs_set_name(world_ecs(), e, name);
ecs_set(world_ecs(), e, ClientInfo, {0});
ecs_set(world_ecs(), e, Input, {0});
ecs_set(world_ecs(), e, Inventory, {0});
ecs_set(world_ecs(), e, Health, {.hp = PLAYER_MAX_HP, .max_hp = PLAYER_MAX_HP});
ecs_add(world_ecs(), e, Player);
librg_entity_owner_set(world_tracker(), e, (int64_t)e);
return (uint64_t)e;
}
void player_despawn(uint64_t ent_id) {
entity_despawn(ent_id);
}
#include "player.h"
#include "entity.h"
#include "entity_view.h"
#include "flecs/flecs.h"
#include "flecs/flecs_meta.h"
#include "librg.h"
#include "world/world.h"
#include "modules/components.h"
#include "modules/systems.h"
#include "zpl.h"
#define PLAYER_MAX_HP 100.0f
uint64_t player_spawn(char *name) {
ecs_entity_t e = entity_spawn(EKIND_PLAYER);
if (!name) {
name = zpl_bprintf("player_%d", e);
}
ecs_set_name(world_ecs(), e, name);
ecs_set(world_ecs(), e, ClientInfo, {0});
ecs_set(world_ecs(), e, Input, {0});
ecs_set(world_ecs(), e, Inventory, {0});
ecs_set(world_ecs(), e, Health, {.hp = PLAYER_MAX_HP, .max_hp = PLAYER_MAX_HP});
ecs_add(world_ecs(), e, Player);
librg_entity_owner_set(world_tracker(), e, (int64_t)e);
return (uint64_t)e;
}
void player_despawn(uint64_t ent_id) {
entity_despawn(ent_id);
}

View File

@ -1,171 +1,171 @@
#pragma once
#include "flecs/flecs.h"
#include "flecs/flecs_meta.h"
//NOTE(zaklaus): custom macro to define meta components outside the current scope
#ifndef ECS_META_DEFINE
#define ECS_META_DEFINE(world, T)\
ECS_COMPONENT_DEFINE(world, T);\
ecs_new_meta(world, ecs_entity(T), &__##T##__);
#endif
#ifndef ecs_get_mut_if
#define ecs_get_mut_if(world, entity, component)\
(ecs_get(world, entity, component) ? ecs_get_mut(world, entity, component, NULL) : NULL)
#endif
#define ITEMS_INVENTORY_SIZE 9
ECS_STRUCT(Vector2D, {
float x;
float y;
});
ECS_STRUCT(Chunk, {
uint32_t id;
int16_t x;
int16_t y;
uint8_t is_dirty;
});
ECS_STRUCT(Drawable, {
uint16_t id;
});
ECS_ALIAS(Vector2D, Position);
ECS_ALIAS(Vector2D, Velocity);
ECS_STRUCT(Input, {
float x;
float y;
float mx;
float my;
uint8_t use;
uint8_t sprint;
uint8_t ctrl;
uint8_t is_blocked;
// NOTE(zaklaus): inventory
uint8_t selected_item;
uint8_t drop;
uint8_t swap;
uint8_t swap_from;
uint8_t swap_to;
});
ECS_STRUCT(ClientInfo, {
uintptr_t peer;
uint16_t view_id;
});
ECS_STRUCT(Health, {
float hp;
float max_hp;
//NOTE(zaklaus): Intentionally global, to allow for creative use of damage combos
float pain_time;
float heal_time;
});
ECS_STRUCT(Classify, {
uint16_t id;
});
ECS_STRUCT(Vehicle, {
uint64_t seats[4];
float force;
float heading;
float steer;
float wheel_base;
float speed;
float reverse_speed;
});
typedef struct {
ecs_entity_t veh;
} IsInVehicle;
typedef struct {
uint16_t kind;
uint32_t quantity;
float merger_time;
} ItemDrop;
typedef struct {
ItemDrop items[ITEMS_INVENTORY_SIZE];
float pickup_time;
} Inventory;
ECS_COMPONENT_EXTERN(Chunk);
ECS_COMPONENT_EXTERN(Position);
ECS_COMPONENT_EXTERN(Vector2D);
ECS_COMPONENT_EXTERN(Drawable);
ECS_COMPONENT_EXTERN(Input);
ECS_COMPONENT_EXTERN(Velocity);
ECS_COMPONENT_EXTERN(ClientInfo);
ECS_COMPONENT_EXTERN(Health);
ECS_COMPONENT_EXTERN(Classify);
ECS_COMPONENT_EXTERN(Vehicle);
ECS_COMPONENT_EXTERN(IsInVehicle);
ECS_COMPONENT_EXTERN(ItemDrop);
ECS_COMPONENT_EXTERN(Inventory);
ECS_TAG_EXTERN(EcsActor);
ECS_TAG_EXTERN(EcsDemoNPC);
ECS_TYPE_EXTERN(Player);
ECS_TYPE_EXTERN(Movement);
ECS_TYPE_EXTERN(Walking);
ECS_TYPE_EXTERN(Flying);
ECS_TYPE_EXTERN(EcsClient);
// NOTE(zaklaus): @1 EXTERN
typedef struct {
ECS_DECLARE_COMPONENT(Chunk);
ECS_DECLARE_COMPONENT(Position);
ECS_DECLARE_COMPONENT(Vector2D);
ECS_DECLARE_COMPONENT(Drawable);
ECS_DECLARE_COMPONENT(Input);
ECS_DECLARE_COMPONENT(Velocity);
ECS_DECLARE_COMPONENT(ClientInfo);
ECS_DECLARE_COMPONENT(Health);
ECS_DECLARE_COMPONENT(Classify);
ECS_DECLARE_COMPONENT(Vehicle);
ECS_DECLARE_COMPONENT(IsInVehicle);
ECS_DECLARE_COMPONENT(ItemDrop);
ECS_DECLARE_COMPONENT(Inventory);
ECS_DECLARE_ENTITY(EcsActor);
ECS_DECLARE_ENTITY(EcsDemoNPC);
ECS_DECLARE_TYPE(Player);
ECS_DECLARE_TYPE(Builder);
ECS_DECLARE_TYPE(Movement);
ECS_DECLARE_ENTITY(Walking);
ECS_DECLARE_ENTITY(Flying);
// NOTE(zaklaus): @2 DECLARE
} Components;
#define ComponentsImportHandles(handles)\
ECS_IMPORT_COMPONENT(handles, Chunk);\
ECS_IMPORT_COMPONENT(handles, Vector2D);\
ECS_IMPORT_COMPONENT(handles, Position);\
ECS_IMPORT_COMPONENT(handles, Drawable);\
ECS_IMPORT_COMPONENT(handles, Input);\
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_COMPONENT(handles, IsInVehicle);\
ECS_IMPORT_COMPONENT(handles, ItemDrop);\
ECS_IMPORT_COMPONENT(handles, Inventory);\
ECS_IMPORT_TYPE(handles, Player);\
ECS_IMPORT_TYPE(handles, Builder);\
ECS_IMPORT_TYPE(handles, Movement);\
ECS_IMPORT_ENTITY(handles, EcsActor);\
ECS_IMPORT_ENTITY(handles, EcsDemoNPC);\
ECS_IMPORT_ENTITY(handles, Walking);\
ECS_IMPORT_ENTITY(handles, Flying);\
// NOTE(zaklaus): @3 IMPORT
void ComponentsImport(ecs_world_t *ecs);
#pragma once
#include "flecs/flecs.h"
#include "flecs/flecs_meta.h"
//NOTE(zaklaus): custom macro to define meta components outside the current scope
#ifndef ECS_META_DEFINE
#define ECS_META_DEFINE(world, T)\
ECS_COMPONENT_DEFINE(world, T);\
ecs_new_meta(world, ecs_entity(T), &__##T##__);
#endif
#ifndef ecs_get_mut_if
#define ecs_get_mut_if(world, entity, component)\
(ecs_get(world, entity, component) ? ecs_get_mut(world, entity, component, NULL) : NULL)
#endif
#define ITEMS_INVENTORY_SIZE 9
ECS_STRUCT(Vector2D, {
float x;
float y;
});
ECS_STRUCT(Chunk, {
uint32_t id;
int16_t x;
int16_t y;
uint8_t is_dirty;
});
ECS_STRUCT(Drawable, {
uint16_t id;
});
ECS_ALIAS(Vector2D, Position);
ECS_ALIAS(Vector2D, Velocity);
ECS_STRUCT(Input, {
float x;
float y;
float mx;
float my;
uint8_t use;
uint8_t sprint;
uint8_t ctrl;
uint8_t is_blocked;
// NOTE(zaklaus): inventory
uint8_t selected_item;
uint8_t drop;
uint8_t swap;
uint8_t swap_from;
uint8_t swap_to;
});
ECS_STRUCT(ClientInfo, {
uintptr_t peer;
uint16_t view_id;
});
ECS_STRUCT(Health, {
float hp;
float max_hp;
//NOTE(zaklaus): Intentionally global, to allow for creative use of damage combos
float pain_time;
float heal_time;
});
ECS_STRUCT(Classify, {
uint16_t id;
});
ECS_STRUCT(Vehicle, {
uint64_t seats[4];
float force;
float heading;
float steer;
float wheel_base;
float speed;
float reverse_speed;
});
typedef struct {
ecs_entity_t veh;
} IsInVehicle;
typedef struct {
uint16_t kind;
uint32_t quantity;
float merger_time;
} ItemDrop;
typedef struct {
ItemDrop items[ITEMS_INVENTORY_SIZE];
float pickup_time;
} Inventory;
ECS_COMPONENT_EXTERN(Chunk);
ECS_COMPONENT_EXTERN(Position);
ECS_COMPONENT_EXTERN(Vector2D);
ECS_COMPONENT_EXTERN(Drawable);
ECS_COMPONENT_EXTERN(Input);
ECS_COMPONENT_EXTERN(Velocity);
ECS_COMPONENT_EXTERN(ClientInfo);
ECS_COMPONENT_EXTERN(Health);
ECS_COMPONENT_EXTERN(Classify);
ECS_COMPONENT_EXTERN(Vehicle);
ECS_COMPONENT_EXTERN(IsInVehicle);
ECS_COMPONENT_EXTERN(ItemDrop);
ECS_COMPONENT_EXTERN(Inventory);
ECS_TAG_EXTERN(EcsActor);
ECS_TAG_EXTERN(EcsDemoNPC);
ECS_TYPE_EXTERN(Player);
ECS_TYPE_EXTERN(Movement);
ECS_TYPE_EXTERN(Walking);
ECS_TYPE_EXTERN(Flying);
ECS_TYPE_EXTERN(EcsClient);
// NOTE(zaklaus): @1 EXTERN
typedef struct {
ECS_DECLARE_COMPONENT(Chunk);
ECS_DECLARE_COMPONENT(Position);
ECS_DECLARE_COMPONENT(Vector2D);
ECS_DECLARE_COMPONENT(Drawable);
ECS_DECLARE_COMPONENT(Input);
ECS_DECLARE_COMPONENT(Velocity);
ECS_DECLARE_COMPONENT(ClientInfo);
ECS_DECLARE_COMPONENT(Health);
ECS_DECLARE_COMPONENT(Classify);
ECS_DECLARE_COMPONENT(Vehicle);
ECS_DECLARE_COMPONENT(IsInVehicle);
ECS_DECLARE_COMPONENT(ItemDrop);
ECS_DECLARE_COMPONENT(Inventory);
ECS_DECLARE_ENTITY(EcsActor);
ECS_DECLARE_ENTITY(EcsDemoNPC);
ECS_DECLARE_TYPE(Player);
ECS_DECLARE_TYPE(Builder);
ECS_DECLARE_TYPE(Movement);
ECS_DECLARE_ENTITY(Walking);
ECS_DECLARE_ENTITY(Flying);
// NOTE(zaklaus): @2 DECLARE
} Components;
#define ComponentsImportHandles(handles)\
ECS_IMPORT_COMPONENT(handles, Chunk);\
ECS_IMPORT_COMPONENT(handles, Vector2D);\
ECS_IMPORT_COMPONENT(handles, Position);\
ECS_IMPORT_COMPONENT(handles, Drawable);\
ECS_IMPORT_COMPONENT(handles, Input);\
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_COMPONENT(handles, IsInVehicle);\
ECS_IMPORT_COMPONENT(handles, ItemDrop);\
ECS_IMPORT_COMPONENT(handles, Inventory);\
ECS_IMPORT_TYPE(handles, Player);\
ECS_IMPORT_TYPE(handles, Builder);\
ECS_IMPORT_TYPE(handles, Movement);\
ECS_IMPORT_ENTITY(handles, EcsActor);\
ECS_IMPORT_ENTITY(handles, EcsDemoNPC);\
ECS_IMPORT_ENTITY(handles, Walking);\
ECS_IMPORT_ENTITY(handles, Flying);\
// NOTE(zaklaus): @3 IMPORT
void ComponentsImport(ecs_world_t *ecs);

View File

@ -92,8 +92,8 @@ 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 (h->pain_time < game_time()) {
h->pain_time = game_time() + HAZARD_BLOCK_TIME;
if (h->pain_time < 0.0f) {
h->pain_time = HAZARD_BLOCK_TIME;
h->hp -= HAZARD_BLOCK_DMG;
h->hp = zpl_max(0.0f, h->hp);
}
@ -109,12 +109,16 @@ void RegenerateHP(ecs_iter_t *it) {
Health *h = ecs_column(it, Health, 1);
for (int i = 0; i < it->count; i++) {
if (h->pain_time < game_time() - HP_REGEN_PAIN_COOLDOWN) {
if (h->heal_time < game_time() && h->hp < h->max_hp) {
h->heal_time = game_time() + HP_REGEN_TIME;
h->hp += HP_REGEN_RECOVERY;
h->hp = zpl_min(h->max_hp, h->hp);
if (h[i].pain_time < 0.0f) {
if (h[i].heal_time < 0.0f && h[i].hp < h[i].max_hp) {
h[i].heal_time = HP_REGEN_TIME;
h[i].hp += HP_REGEN_RECOVERY;
h[i].hp = zpl_min(h[i].max_hp, h[i].hp);
} else {
h[i].heal_time -= safe_dt(it);
}
} else {
h[i].pain_time -= safe_dt(it);
}
}
}

View File

@ -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*it->delta_time + zpl_cos(zpl_to_radians(rand()%360))*DEMO_NPC_STEER_SPEED*it->delta_time);
v[i].y += (v[i].y*d*DEMO_NPC_MOVE_SPEED*it->delta_time + zpl_sin(zpl_to_radians(rand()%360))*DEMO_NPC_STEER_SPEED*it->delta_time);
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));
}
}

36316
code/vendors/zpl.h vendored

File diff suppressed because it is too large Load Diff