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 = "delta time", .proc = DrawDeltaTime },
{ .kind = DITEM_TEXT, .name = "pos", .proc = DrawCameraPos }, { .kind = DITEM_TEXT, .name = "pos", .proc = DrawCameraPos },
{ .kind = DITEM_TEXT, .name = "zoom", .proc = DrawZoom }, { .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 }, { .kind = DITEM_END },
} }
} }
@ -180,6 +179,7 @@ static debug_item items[] = {
{ .kind = DITEM_END }, { .kind = DITEM_END },
}, },
.is_sp_only = true, .is_sp_only = true,
.is_collapsed = true,
} }
}, },
{ {

View File

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

View File

@ -12,19 +12,20 @@
uint64_t entity_spawn(uint16_t class_id) { uint64_t entity_spawn(uint16_t class_id) {
ecs_entity_t e = ecs_new(world_ecs(), 0); 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_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) { 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_track(world_tracker(), e);
librg_entity_chunk_set(world_tracker(), e, librg_chunk_from_realpos(world_tracker(), pos->x, pos->y, 0)); 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); 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; 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) { void entity_despawn(uint64_t ent_id) {
librg_entity_untrack(world_tracker(), ent_id); librg_entity_untrack(world_tracker(), ent_id);
ecs_delete(world_ecs(), ent_id); ecs_delete(world_ecs(), ent_id);

View File

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

View File

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

View File

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