ItemRouter system
parent
6385ea4461
commit
4cb85f069f
|
@ -18,6 +18,7 @@ ECS_COMPONENT_DECLARE(ItemContainer);
|
||||||
ECS_COMPONENT_DECLARE(Producer);
|
ECS_COMPONENT_DECLARE(Producer);
|
||||||
ECS_COMPONENT_DECLARE(EnergySource);
|
ECS_COMPONENT_DECLARE(EnergySource);
|
||||||
ECS_COMPONENT_DECLARE(Ingredient);
|
ECS_COMPONENT_DECLARE(Ingredient);
|
||||||
|
ECS_COMPONENT_DECLARE(ItemRouter);
|
||||||
ECS_COMPONENT_DECLARE(Device);
|
ECS_COMPONENT_DECLARE(Device);
|
||||||
ECS_COMPONENT_DECLARE(Blueprint);
|
ECS_COMPONENT_DECLARE(Blueprint);
|
||||||
ECS_COMPONENT_DECLARE(DemoNPC);
|
ECS_COMPONENT_DECLARE(DemoNPC);
|
||||||
|
@ -25,7 +26,7 @@ ECS_COMPONENT_DECLARE(StreamInfo);
|
||||||
|
|
||||||
void ComponentsImport(ecs_world_t *ecs) {
|
void ComponentsImport(ecs_world_t *ecs) {
|
||||||
ECS_MODULE(ecs, Components);
|
ECS_MODULE(ecs, Components);
|
||||||
|
|
||||||
ECS_COMPONENT_DEFINE(ecs, Vector2D);
|
ECS_COMPONENT_DEFINE(ecs, Vector2D);
|
||||||
ECS_COMPONENT_DEFINE(ecs, Position);
|
ECS_COMPONENT_DEFINE(ecs, Position);
|
||||||
ECS_COMPONENT_DEFINE(ecs, Velocity);
|
ECS_COMPONENT_DEFINE(ecs, Velocity);
|
||||||
|
@ -44,6 +45,7 @@ void ComponentsImport(ecs_world_t *ecs) {
|
||||||
ECS_COMPONENT_DEFINE(ecs, Producer);
|
ECS_COMPONENT_DEFINE(ecs, Producer);
|
||||||
ECS_COMPONENT_DEFINE(ecs, EnergySource);
|
ECS_COMPONENT_DEFINE(ecs, EnergySource);
|
||||||
ECS_COMPONENT_DEFINE(ecs, Ingredient);
|
ECS_COMPONENT_DEFINE(ecs, Ingredient);
|
||||||
|
ECS_COMPONENT_DEFINE(ecs, ItemRouter);
|
||||||
ECS_COMPONENT_DEFINE(ecs, Device);
|
ECS_COMPONENT_DEFINE(ecs, Device);
|
||||||
ECS_COMPONENT_DEFINE(ecs, Blueprint);
|
ECS_COMPONENT_DEFINE(ecs, Blueprint);
|
||||||
ECS_COMPONENT_DEFINE(ecs, DemoNPC);
|
ECS_COMPONENT_DEFINE(ecs, DemoNPC);
|
||||||
|
|
|
@ -135,6 +135,10 @@ typedef struct {
|
||||||
float energy_level;
|
float energy_level;
|
||||||
} Producer;
|
} Producer;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char _unused;
|
||||||
|
} ItemRouter;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
asset_id kind;
|
asset_id kind;
|
||||||
float energy_level;
|
float energy_level;
|
||||||
|
@ -185,6 +189,7 @@ extern ECS_COMPONENT_DECLARE(ItemContainer);
|
||||||
extern ECS_COMPONENT_DECLARE(Producer);
|
extern ECS_COMPONENT_DECLARE(Producer);
|
||||||
extern ECS_COMPONENT_DECLARE(EnergySource);
|
extern ECS_COMPONENT_DECLARE(EnergySource);
|
||||||
extern ECS_COMPONENT_DECLARE(Ingredient);
|
extern ECS_COMPONENT_DECLARE(Ingredient);
|
||||||
|
extern ECS_COMPONENT_DECLARE(ItemRouter);
|
||||||
extern ECS_COMPONENT_DECLARE(Device);
|
extern ECS_COMPONENT_DECLARE(Device);
|
||||||
extern ECS_COMPONENT_DECLARE(Blueprint);
|
extern ECS_COMPONENT_DECLARE(Blueprint);
|
||||||
extern ECS_COMPONENT_DECLARE(DemoNPC);
|
extern ECS_COMPONENT_DECLARE(DemoNPC);
|
||||||
|
|
|
@ -7,13 +7,15 @@
|
||||||
|
|
||||||
uint64_t furnace_spawn(void) {
|
uint64_t furnace_spawn(void) {
|
||||||
ecs_entity_t e = device_spawn(ASSET_FURNACE);
|
ecs_entity_t e = device_spawn(ASSET_FURNACE);
|
||||||
|
|
||||||
ItemContainer *storage = ecs_get_mut(world_ecs(), e, ItemContainer);
|
ItemContainer *storage = ecs_get_mut(world_ecs(), e, ItemContainer);
|
||||||
*storage = (ItemContainer){0};
|
*storage = (ItemContainer){0};
|
||||||
|
|
||||||
Producer *producer = ecs_get_mut(world_ecs(), e, Producer);
|
Producer *producer = ecs_get_mut(world_ecs(), e, Producer);
|
||||||
*producer = (Producer){0};
|
*producer = (Producer){0};
|
||||||
producer->energy_level = 69.0f;
|
producer->energy_level = 69.0f;
|
||||||
|
|
||||||
|
ecs_add(world_ecs(), e, ItemRouter);
|
||||||
return (uint64_t)e;
|
return (uint64_t)e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
static inline
|
||||||
|
asset_id FetchAssetAtPos(float x, float y) {
|
||||||
|
world_block_lookup lookup = world_block_from_realpos(x, y);
|
||||||
|
if (lookup.is_outer) {
|
||||||
|
return blocks_get_asset(lookup.bid);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ASSET_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// NOTE(zaklaus): Expects float[4] dx, dy
|
||||||
|
static inline
|
||||||
|
uint8_t CheckForNearbyBelts(Position *p, float *dx, float *dy) {
|
||||||
|
asset_id bid = ASSET_INVALID;
|
||||||
|
float o = WORLD_BLOCK_SIZE;
|
||||||
|
uint8_t nodes = 0x0;
|
||||||
|
|
||||||
|
// up
|
||||||
|
bid = FetchAssetAtPos(p->x + 0, p->y - o);
|
||||||
|
if (bid == ASSET_BELT_UP) {
|
||||||
|
dx[0] = 0;
|
||||||
|
dy[0] = -o;
|
||||||
|
nodes |= ZPL_BIT(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// down
|
||||||
|
bid = FetchAssetAtPos(p->x + 0, p->y + o);
|
||||||
|
if (bid == ASSET_BELT_DOWN) {
|
||||||
|
dx[1] = 0;
|
||||||
|
dy[1] = o;
|
||||||
|
nodes |= ZPL_BIT(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// left
|
||||||
|
bid = FetchAssetAtPos(p->x - o, p->y + 0);
|
||||||
|
if (bid == ASSET_BELT_LEFT) {
|
||||||
|
dx[2] = -o;
|
||||||
|
dy[2] = 0;
|
||||||
|
nodes |= ZPL_BIT(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// right
|
||||||
|
bid = FetchAssetAtPos(p->x + o, p->y + 0);
|
||||||
|
if (bid == ASSET_BELT_RIGHT) {
|
||||||
|
dx[3] = o;
|
||||||
|
dy[3] = 0;
|
||||||
|
nodes |= ZPL_BIT(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PushItemsOnNodes(ecs_iter_t *it) {
|
||||||
|
ItemContainer *storage = ecs_field(it, ItemContainer, 1);
|
||||||
|
Position *p = ecs_field(it, Position, 2);
|
||||||
|
Device *d = ecs_field(it, Device, 3);
|
||||||
|
ItemRouter *r = ecs_field(it, ItemRouter, 4);
|
||||||
|
|
||||||
|
for (int i = 0; i < it->count; i++) {
|
||||||
|
// TODO(zaklaus): Cache output nodes so we avoid
|
||||||
|
// calling world_block_from_realpos each time.
|
||||||
|
// We need a way to refer to specific blocks in the world so we can do easy block ID checks
|
||||||
|
// and re-build the cache when a change is detected.
|
||||||
|
|
||||||
|
float push_dx[4], push_dy[4];
|
||||||
|
uint8_t nodes = CheckForNearbyBelts(&p[i], push_dx, push_dy);
|
||||||
|
uint8_t num_nodes = (uint8_t)zpl_count_set_bits(nodes);
|
||||||
|
uint8_t counter = 0;
|
||||||
|
|
||||||
|
if (num_nodes == 0) {
|
||||||
|
// NOTE(zaklaus): We don't have any output nodes yet.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = 0; j < ITEMS_CONTAINER_SIZE; j++) {
|
||||||
|
ecs_entity_t item_slot_ent = storage[i].items[j];
|
||||||
|
if (item_slot_ent == 0) continue;
|
||||||
|
Item *item = item_get_data(item_slot_ent);
|
||||||
|
|
||||||
|
const Ingredient *ing = 0;
|
||||||
|
// NOTE(zaklaus): Make sure we don't push out items from input node
|
||||||
|
if ((ing = ecs_get_if(it->world, item_slot_ent, Ingredient))) {
|
||||||
|
if (ing->producer == d->asset) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (item->quantity > 0 && num_nodes > 0) {
|
||||||
|
// NOTE(zaklaus): Use a rolling counter to select an output node.
|
||||||
|
while (!(nodes & (1 << counter)) && counter < 4) ++counter;
|
||||||
|
if (counter > 3) {
|
||||||
|
counter = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t e = item_spawn(item->kind, 1);
|
||||||
|
entity_set_position(e, p[i].x + push_dx[counter], p[i].y + push_dy[counter]);
|
||||||
|
|
||||||
|
Velocity *e_vel = ecs_get_mut_ex(it->world, e, Velocity);
|
||||||
|
e_vel->x = push_dx[counter];
|
||||||
|
e_vel->y = push_dy[counter];
|
||||||
|
|
||||||
|
--item->quantity;
|
||||||
|
--num_nodes;
|
||||||
|
++counter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,58 +1,3 @@
|
||||||
static inline
|
|
||||||
asset_id FetchAssetAtPos(float x, float y) {
|
|
||||||
world_block_lookup lookup = world_block_from_realpos(x, y);
|
|
||||||
if (lookup.is_outer) {
|
|
||||||
return blocks_get_asset(lookup.bid);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ASSET_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline
|
|
||||||
bool CheckForNearbyBelt(Position *p, float *dx, float *dy) {
|
|
||||||
asset_id bid = ASSET_INVALID;
|
|
||||||
float o = WORLD_BLOCK_SIZE;
|
|
||||||
|
|
||||||
// up
|
|
||||||
bid = FetchAssetAtPos(p->x + 0, p->y - o);
|
|
||||||
{
|
|
||||||
debug_v2 a = {p->x, p->y};
|
|
||||||
debug_v2 b = {p->x, p->y-WORLD_BLOCK_SIZE};
|
|
||||||
debug_push_line(a, b, 0xFFFFFFFF);
|
|
||||||
}
|
|
||||||
if (bid == ASSET_BELT_UP) {
|
|
||||||
*dx = 0;
|
|
||||||
*dy = -o;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// down
|
|
||||||
bid = FetchAssetAtPos(p->x + 0, p->y + o);
|
|
||||||
if (bid == ASSET_BELT_DOWN) {
|
|
||||||
*dx = 0;
|
|
||||||
*dy = o;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// left
|
|
||||||
bid = FetchAssetAtPos(p->x - o, p->y + 0);
|
|
||||||
if (bid == ASSET_BELT_LEFT) {
|
|
||||||
*dx = -o;
|
|
||||||
*dy = 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// right
|
|
||||||
bid = FetchAssetAtPos(p->x + o, p->y + 0);
|
|
||||||
if (bid == ASSET_BELT_RIGHT) {
|
|
||||||
*dx = o;
|
|
||||||
*dy = 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProduceItems(ecs_iter_t *it) {
|
void ProduceItems(ecs_iter_t *it) {
|
||||||
ItemContainer *storage = ecs_field(it, ItemContainer, 1);
|
ItemContainer *storage = ecs_field(it, ItemContainer, 1);
|
||||||
Producer *producer = ecs_field(it, Producer, 2);
|
Producer *producer = ecs_field(it, Producer, 2);
|
||||||
|
@ -60,9 +5,6 @@ void ProduceItems(ecs_iter_t *it) {
|
||||||
Device *d = ecs_field(it, Device, 4);
|
Device *d = ecs_field(it, Device, 4);
|
||||||
|
|
||||||
for (int i = 0; i < it->count; i++) {
|
for (int i = 0; i < it->count; i++) {
|
||||||
float push_dx=0.0f, push_dy=0.0f;
|
|
||||||
bool has_output_node = CheckForNearbyBelt(&p[i], &push_dx, &push_dy);
|
|
||||||
|
|
||||||
for (int j = 0; j < ITEMS_CONTAINER_SIZE; j++) {
|
for (int j = 0; j < ITEMS_CONTAINER_SIZE; j++) {
|
||||||
ecs_entity_t item_slot_ent = storage[i].items[j];
|
ecs_entity_t item_slot_ent = storage[i].items[j];
|
||||||
Item *item = item_get_data(item_slot_ent);
|
Item *item = item_get_data(item_slot_ent);
|
||||||
|
@ -81,16 +23,8 @@ void ProduceItems(ecs_iter_t *it) {
|
||||||
if (producer[i].process_time < game_time()) {
|
if (producer[i].process_time < game_time()) {
|
||||||
if (producer[i].processed_item > 0) {
|
if (producer[i].processed_item > 0) {
|
||||||
uint64_t e = item_spawn(producer[i].processed_item, 1);
|
uint64_t e = item_spawn(producer[i].processed_item, 1);
|
||||||
|
entity_set_position(e, p[i].x, p[i].y);
|
||||||
producer[i].processed_item = 0;
|
producer[i].processed_item = 0;
|
||||||
|
|
||||||
if (has_output_node) {
|
|
||||||
entity_set_position(e, p[i].x+push_dx, p[i].y+push_dy);
|
|
||||||
Velocity *e_vel = ecs_get_mut_ex(it->world, e, Velocity);
|
|
||||||
e_vel->x = push_dx;
|
|
||||||
e_vel->y = push_dy;
|
|
||||||
} else {
|
|
||||||
entity_set_position(e, p[i].x, p[i].y);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
const Ingredient *ing = 0;
|
const Ingredient *ing = 0;
|
||||||
if ((ing = ecs_get_if(it->world, item_slot_ent, Ingredient))) {
|
if ((ing = ecs_get_if(it->world, item_slot_ent, Ingredient))) {
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "modules/system_demo.c"
|
#include "modules/system_demo.c"
|
||||||
#include "modules/system_vehicle.c"
|
#include "modules/system_vehicle.c"
|
||||||
#include "modules/system_items.c"
|
#include "modules/system_items.c"
|
||||||
|
#include "modules/system_logistics.c"
|
||||||
#include "modules/system_producer.c"
|
#include "modules/system_producer.c"
|
||||||
#include "modules/system_blueprint.c"
|
#include "modules/system_blueprint.c"
|
||||||
|
|
||||||
|
@ -32,7 +33,7 @@ void IntegratePositions(ecs_iter_t *it) {
|
||||||
profile(PROF_INTEGRATE_POS) {
|
profile(PROF_INTEGRATE_POS) {
|
||||||
Position *p = ecs_field(it, Position, 1);
|
Position *p = ecs_field(it, Position, 1);
|
||||||
Velocity *v = ecs_field(it, Velocity, 2);
|
Velocity *v = ecs_field(it, Velocity, 2);
|
||||||
|
|
||||||
for (int i = 0; i < it->count; i++) {
|
for (int i = 0; i < it->count; i++) {
|
||||||
if (ecs_get(it->world, it->entities[i], IsInVehicle)) {
|
if (ecs_get(it->world, it->entities[i], IsInVehicle)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -45,59 +46,59 @@ void IntegratePositions(ecs_iter_t *it) {
|
||||||
p[i].x = zpl_clamp(p[i].x, 0, w-1);
|
p[i].x = zpl_clamp(p[i].x, 0, w-1);
|
||||||
p[i].y = zpl_clamp(p[i].y, 0, w-1);
|
p[i].y = zpl_clamp(p[i].y, 0, w-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PHY_BLOCK_COLLISION==1
|
#if PHY_BLOCK_COLLISION==1
|
||||||
// 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.bid);
|
uint32_t flags = blocks_get_flags(lookup.bid);
|
||||||
float bounce = blocks_get_bounce(lookup.bid);
|
float bounce = blocks_get_bounce(lookup.bid);
|
||||||
if (flags & BLOCK_FLAG_COLLISION && physics_check_aabb(p[i].x-WORLD_BLOCK_SIZE/4, p[i].x+WORLD_BLOCK_SIZE/4, p[i].y-0.5f, p[i].y+0.5f, lookup.aox-WORLD_BLOCK_SIZE/2, lookup.aox+WORLD_BLOCK_SIZE/2, lookup.aoy-WORLD_BLOCK_SIZE/2, lookup.aoy+WORLD_BLOCK_SIZE/2)) {
|
if (flags & BLOCK_FLAG_COLLISION && physics_check_aabb(p[i].x-WORLD_BLOCK_SIZE/4, p[i].x+WORLD_BLOCK_SIZE/4, p[i].y-0.5f, p[i].y+0.5f, lookup.aox-WORLD_BLOCK_SIZE/2, lookup.aox+WORLD_BLOCK_SIZE/2, lookup.aoy-WORLD_BLOCK_SIZE/2, lookup.aoy+WORLD_BLOCK_SIZE/2)) {
|
||||||
#if 1
|
#if 1
|
||||||
{
|
{
|
||||||
debug_v2 a = {p[i].x-WORLD_BLOCK_SIZE/4 + PHY_LOOKAHEAD(v[i].x), p[i].y-0.5f};
|
debug_v2 a = {p[i].x-WORLD_BLOCK_SIZE/4 + PHY_LOOKAHEAD(v[i].x), p[i].y-0.5f};
|
||||||
debug_v2 b = {p[i].x+WORLD_BLOCK_SIZE/4 + PHY_LOOKAHEAD(v[i].x), p[i].y+0.5f};
|
debug_v2 b = {p[i].x+WORLD_BLOCK_SIZE/4 + PHY_LOOKAHEAD(v[i].x), p[i].y+0.5f};
|
||||||
debug_push_rect(a, b, 0xFF0000FF);
|
debug_push_rect(a, b, 0xFF0000FF);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
v[i].x = physics_correction(lookup.ox, v[i].x, bounce, WORLD_BLOCK_SIZE/2);
|
v[i].x = physics_correction(lookup.ox, v[i].x, bounce, WORLD_BLOCK_SIZE/2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.bid);
|
uint32_t flags = blocks_get_flags(lookup.bid);
|
||||||
float bounce = blocks_get_bounce(lookup.bid);
|
float bounce = blocks_get_bounce(lookup.bid);
|
||||||
#if 0
|
#if 0
|
||||||
{
|
{
|
||||||
debug_v2 a = {lookup.aox-WORLD_BLOCK_SIZE/2, lookup.aoy-WORLD_BLOCK_SIZE/2};
|
debug_v2 a = {lookup.aox-WORLD_BLOCK_SIZE/2, lookup.aoy-WORLD_BLOCK_SIZE/2};
|
||||||
debug_v2 b = {lookup.aox+WORLD_BLOCK_SIZE/2, lookup.aoy+WORLD_BLOCK_SIZE/2};
|
debug_v2 b = {lookup.aox+WORLD_BLOCK_SIZE/2, lookup.aoy+WORLD_BLOCK_SIZE/2};
|
||||||
debug_push_rect(a, b, 0xFFFFFFFF);
|
debug_push_rect(a, b, 0xFFFFFFFF);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (flags & BLOCK_FLAG_COLLISION && physics_check_aabb(p[i].x-WORLD_BLOCK_SIZE/4, p[i].x+WORLD_BLOCK_SIZE/4, p[i].y-0.5f, p[i].y+0.5f, lookup.aox-WORLD_BLOCK_SIZE/2, lookup.aox+WORLD_BLOCK_SIZE/2, lookup.aoy-WORLD_BLOCK_SIZE/2, lookup.aoy+WORLD_BLOCK_SIZE/2)) {
|
if (flags & BLOCK_FLAG_COLLISION && physics_check_aabb(p[i].x-WORLD_BLOCK_SIZE/4, p[i].x+WORLD_BLOCK_SIZE/4, p[i].y-0.5f, p[i].y+0.5f, lookup.aox-WORLD_BLOCK_SIZE/2, lookup.aox+WORLD_BLOCK_SIZE/2, lookup.aoy-WORLD_BLOCK_SIZE/2, lookup.aoy+WORLD_BLOCK_SIZE/2)) {
|
||||||
#if 1
|
#if 1
|
||||||
{
|
{
|
||||||
debug_v2 a = {p[i].x-WORLD_BLOCK_SIZE/4, p[i].y-0.5f + PHY_LOOKAHEAD(v[i].y)};
|
debug_v2 a = {p[i].x-WORLD_BLOCK_SIZE/4, p[i].y-0.5f + PHY_LOOKAHEAD(v[i].y)};
|
||||||
debug_v2 b = {p[i].x+WORLD_BLOCK_SIZE/4, p[i].y+0.5f + PHY_LOOKAHEAD(v[i].y)};
|
debug_v2 b = {p[i].x+WORLD_BLOCK_SIZE/4, p[i].y+0.5f + PHY_LOOKAHEAD(v[i].y)};
|
||||||
debug_push_rect(a, b, 0xFF0000FF);
|
debug_push_rect(a, b, 0xFF0000FF);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
v[i].y = physics_correction(lookup.oy, v[i].y, bounce, WORLD_BLOCK_SIZE/4);
|
v[i].y = physics_correction(lookup.oy, v[i].y, bounce, WORLD_BLOCK_SIZE/4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
entity_set_position(it->entities[i], p[i].x+v[i].x*safe_dt(it), p[i].y+v[i].y*safe_dt(it));
|
entity_set_position(it->entities[i], p[i].x+v[i].x*safe_dt(it), p[i].y+v[i].y*safe_dt(it));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
debug_v2 a = {p[i].x, p[i].y};
|
debug_v2 a = {p[i].x, p[i].y};
|
||||||
debug_v2 b = {p[i].x+v[i].x, p[i].y+v[i].y};
|
debug_v2 b = {p[i].x+v[i].x, p[i].y+v[i].y};
|
||||||
debug_push_line(a, b, 0xFFFFFFFF);
|
debug_push_line(a, b, 0xFFFFFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
debug_v2 a = {p[i].x-WORLD_BLOCK_SIZE/4, p[i].y-0.5f};
|
debug_v2 a = {p[i].x-WORLD_BLOCK_SIZE/4, p[i].y-0.5f};
|
||||||
debug_v2 b = {p[i].x+WORLD_BLOCK_SIZE/4, p[i].y+0.5f};
|
debug_v2 b = {p[i].x+WORLD_BLOCK_SIZE/4, p[i].y+0.5f};
|
||||||
|
@ -113,7 +114,7 @@ void IntegratePositions(ecs_iter_t *it) {
|
||||||
void HurtOnHazardBlock(ecs_iter_t *it) {
|
void HurtOnHazardBlock(ecs_iter_t *it) {
|
||||||
Position *p = ecs_field(it, Position, 1);
|
Position *p = ecs_field(it, Position, 1);
|
||||||
Health *h = ecs_field(it, Health, 2);
|
Health *h = ecs_field(it, Health, 2);
|
||||||
|
|
||||||
for (int i = 0; i < it->count; i++) {
|
for (int i = 0; i < it->count; i++) {
|
||||||
if (h->pain_time < 0.0f) {
|
if (h->pain_time < 0.0f) {
|
||||||
h->pain_time = HAZARD_BLOCK_TIME;
|
h->pain_time = HAZARD_BLOCK_TIME;
|
||||||
|
@ -132,7 +133,7 @@ void HurtOnHazardBlock(ecs_iter_t *it) {
|
||||||
|
|
||||||
void RegenerateHP(ecs_iter_t *it) {
|
void RegenerateHP(ecs_iter_t *it) {
|
||||||
Health *h = ecs_field(it, Health, 1);
|
Health *h = ecs_field(it, Health, 1);
|
||||||
|
|
||||||
for (int i = 0; i < it->count; i++) {
|
for (int i = 0; i < it->count; i++) {
|
||||||
if (h[i].pain_time < 0.0f) {
|
if (h[i].pain_time < 0.0f) {
|
||||||
if (h[i].heal_time < 0.0f && h[i].hp < h[i].max_hp) {
|
if (h[i].heal_time < 0.0f && h[i].hp < h[i].max_hp) {
|
||||||
|
@ -151,7 +152,7 @@ void RegenerateHP(ecs_iter_t *it) {
|
||||||
|
|
||||||
void ResetActivators(ecs_iter_t *it) {
|
void ResetActivators(ecs_iter_t *it) {
|
||||||
Input *in = ecs_field(it, Input, 1);
|
Input *in = ecs_field(it, Input, 1);
|
||||||
|
|
||||||
for (int i = 0; i < it->count; i++) {
|
for (int i = 0; i < it->count; i++) {
|
||||||
in[i].use = false;
|
in[i].use = false;
|
||||||
in[i].swap = false;
|
in[i].swap = false;
|
||||||
|
@ -164,7 +165,7 @@ void ResetActivators(ecs_iter_t *it) {
|
||||||
void ApplyWorldDragOnVelocity(ecs_iter_t *it) {
|
void ApplyWorldDragOnVelocity(ecs_iter_t *it) {
|
||||||
Position *p = ecs_field(it, Position, 1);
|
Position *p = ecs_field(it, Position, 1);
|
||||||
Velocity *v = ecs_field(it, Velocity, 2);
|
Velocity *v = ecs_field(it, Velocity, 2);
|
||||||
|
|
||||||
for (int i = 0; i < it->count; i++) {
|
for (int i = 0; i < it->count; i++) {
|
||||||
if (zpl_abs(v[i].x) < 0.001f && zpl_abs(v[i].y) < 0.001f) continue;
|
if (zpl_abs(v[i].x) < 0.001f && zpl_abs(v[i].y) < 0.001f) continue;
|
||||||
if (ecs_get(it->world, it->entities[i], IsInVehicle)) {
|
if (ecs_get(it->world, it->entities[i], IsInVehicle)) {
|
||||||
|
@ -177,7 +178,7 @@ void ApplyWorldDragOnVelocity(ecs_iter_t *it) {
|
||||||
float vely = blocks_get_vely(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].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));
|
||||||
|
|
||||||
if ( zpl_abs(v[i].x) > ENTITY_ACTION_VELOCITY_THRESHOLD
|
if ( zpl_abs(v[i].x) > ENTITY_ACTION_VELOCITY_THRESHOLD
|
||||||
|| zpl_abs(v[i].y) > ENTITY_ACTION_VELOCITY_THRESHOLD) {
|
|| zpl_abs(v[i].y) > ENTITY_ACTION_VELOCITY_THRESHOLD) {
|
||||||
entity_wake(it->entities[i]);
|
entity_wake(it->entities[i]);
|
||||||
|
@ -189,18 +190,18 @@ void ApplyWorldDragOnVelocity(ecs_iter_t *it) {
|
||||||
|
|
||||||
void PlayerClosestInteractable(ecs_iter_t *it){
|
void PlayerClosestInteractable(ecs_iter_t *it){
|
||||||
Input *in = ecs_field(it, Input, 1);
|
Input *in = ecs_field(it, Input, 1);
|
||||||
|
|
||||||
for (int i = 0; i < it->count; ++i) {
|
for (int i = 0; i < it->count; ++i) {
|
||||||
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);
|
||||||
|
|
||||||
ecs_entity_t closest_pick = 0;
|
ecs_entity_t closest_pick = 0;
|
||||||
float min_pick = ZPL_F32_MAX;
|
float min_pick = ZPL_F32_MAX;
|
||||||
|
|
||||||
for (size_t j = 0; j < ents_count; j++) {
|
for (size_t j = 0; j < ents_count; j++) {
|
||||||
const Position *p2 = ecs_get(it->world, ents[j], Position);
|
const Position *p2 = ecs_get(it->world, ents[j], Position);
|
||||||
if (!p2) continue;
|
if (!p2) continue;
|
||||||
|
|
||||||
float dx = p2->x - in[i].bx;
|
float dx = p2->x - in[i].bx;
|
||||||
float dy = p2->y - in[i].by;
|
float dy = p2->y - in[i].by;
|
||||||
float range = zpl_sqrt(dx*dx + dy*dy);
|
float range = zpl_sqrt(dx*dx + dy*dy);
|
||||||
|
@ -209,9 +210,9 @@ void PlayerClosestInteractable(ecs_iter_t *it){
|
||||||
closest_pick = ents[j];
|
closest_pick = ents[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
in[i].pick_ent = closest_pick;
|
in[i].pick_ent = closest_pick;
|
||||||
|
|
||||||
if (in[i].pick)
|
if (in[i].pick)
|
||||||
in[i].sel_ent = (in[i].sel_ent == closest_pick) ? 0 : closest_pick;
|
in[i].sel_ent = (in[i].sel_ent == closest_pick) ? 0 : closest_pick;
|
||||||
}
|
}
|
||||||
|
@ -229,28 +230,33 @@ void DisableWorldEdit(ecs_iter_t *it) {
|
||||||
#define ECO2D_TICK_RATE (1.0f/20.f)
|
#define ECO2D_TICK_RATE (1.0f/20.f)
|
||||||
|
|
||||||
#define ECS_SYSTEM_TICKED(world, id, stage, ...)\
|
#define ECS_SYSTEM_TICKED(world, id, stage, ...)\
|
||||||
ECS_SYSTEM(world, id, stage, __VA_ARGS__);\
|
ECS_SYSTEM(world, id, stage, __VA_ARGS__);\
|
||||||
ecs_set_tick_source(world, id, timer);
|
ecs_set_tick_source(world, id, timer);
|
||||||
|
|
||||||
|
#define ECS_SYSTEM_TICKED_EX(world, id, stage, time, ...)\
|
||||||
|
ECS_SYSTEM(world, id, stage, __VA_ARGS__);\
|
||||||
|
ecs_entity_t timer_##id = ecs_set_interval(ecs, 0, ECO2D_TICK_RATE*time);\
|
||||||
|
ecs_set_tick_source(world, id, timer_##id);
|
||||||
|
|
||||||
void SystemsImport(ecs_world_t *ecs) {
|
void SystemsImport(ecs_world_t *ecs) {
|
||||||
ECS_MODULE(ecs, Systems);
|
ECS_MODULE(ecs, Systems);
|
||||||
|
|
||||||
ecs_entity_t timer = ecs_set_interval(ecs, 0, ECO2D_TICK_RATE);
|
ecs_entity_t timer = ecs_set_interval(ecs, 0, ECO2D_TICK_RATE);
|
||||||
|
|
||||||
ECS_SYSTEM(ecs, EnableWorldEdit, EcsOnLoad);
|
ECS_SYSTEM(ecs, EnableWorldEdit, EcsOnLoad);
|
||||||
ECS_SYSTEM(ecs, MovementImpulse, EcsOnLoad, components.Input, components.Velocity, components.Position, !components.IsInVehicle);
|
ECS_SYSTEM(ecs, MovementImpulse, EcsOnLoad, components.Input, components.Velocity, components.Position, !components.IsInVehicle);
|
||||||
ECS_SYSTEM(ecs, DemoNPCMoveAround, EcsOnLoad, components.Velocity, components.DemoNPC);
|
ECS_SYSTEM(ecs, DemoNPCMoveAround, EcsOnLoad, components.Velocity, components.DemoNPC);
|
||||||
|
|
||||||
ECS_SYSTEM(ecs, ApplyWorldDragOnVelocity, EcsOnUpdate, components.Position, components.Velocity);
|
ECS_SYSTEM(ecs, ApplyWorldDragOnVelocity, EcsOnUpdate, components.Position, components.Velocity);
|
||||||
ECS_SYSTEM_TICKED(ecs, HurtOnHazardBlock, EcsOnUpdate, components.Position, components.Health);
|
ECS_SYSTEM_TICKED(ecs, HurtOnHazardBlock, EcsOnUpdate, components.Position, components.Health);
|
||||||
ECS_SYSTEM_TICKED(ecs, RegenerateHP, EcsOnUpdate, components.Health);
|
ECS_SYSTEM_TICKED(ecs, RegenerateHP, EcsOnUpdate, components.Health);
|
||||||
ECS_SYSTEM(ecs, VehicleHandling, EcsOnUpdate, components.Vehicle, components.Position, components.Velocity);
|
ECS_SYSTEM(ecs, VehicleHandling, EcsOnUpdate, components.Vehicle, components.Position, components.Velocity);
|
||||||
|
|
||||||
ECS_SYSTEM(ecs, IntegratePositions, EcsOnValidate, components.Position, components.Velocity);
|
ECS_SYSTEM(ecs, IntegratePositions, EcsOnValidate, components.Position, components.Velocity);
|
||||||
|
|
||||||
ECS_SYSTEM(ecs, EnterVehicle, EcsPostUpdate, components.Input, components.Position, !components.IsInVehicle);
|
ECS_SYSTEM(ecs, EnterVehicle, EcsPostUpdate, components.Input, components.Position, !components.IsInVehicle);
|
||||||
ECS_SYSTEM(ecs, LeaveVehicle, EcsPostUpdate, components.Input, components.IsInVehicle, components.Velocity);
|
ECS_SYSTEM(ecs, LeaveVehicle, EcsPostUpdate, components.Input, components.IsInVehicle, components.Velocity);
|
||||||
|
|
||||||
ECS_SYSTEM(ecs, PlayerClosestInteractable, EcsPostUpdate, components.Input);
|
ECS_SYSTEM(ecs, PlayerClosestInteractable, EcsPostUpdate, components.Input);
|
||||||
ECS_SYSTEM(ecs, PickItem, EcsPostUpdate, components.Input, components.Position, components.Inventory, !components.IsInVehicle);
|
ECS_SYSTEM(ecs, PickItem, EcsPostUpdate, components.Input, components.Position, components.Inventory, !components.IsInVehicle);
|
||||||
ECS_SYSTEM(ecs, DropItem, EcsPostUpdate, components.Input, components.Position, components.Inventory, !components.IsInVehicle);
|
ECS_SYSTEM(ecs, DropItem, EcsPostUpdate, components.Input, components.Position, components.Inventory, !components.IsInVehicle);
|
||||||
|
@ -258,16 +264,17 @@ void SystemsImport(ecs_world_t *ecs) {
|
||||||
//ECS_SYSTEM(ecs, MergeItems, EcsPostUpdate, components.Position, components.ItemDrop);
|
//ECS_SYSTEM(ecs, MergeItems, EcsPostUpdate, components.Position, components.ItemDrop);
|
||||||
ECS_SYSTEM(ecs, UseItem, EcsPostUpdate, components.Input, components.Position, components.Inventory, !components.IsInVehicle);
|
ECS_SYSTEM(ecs, UseItem, EcsPostUpdate, components.Input, components.Position, components.Inventory, !components.IsInVehicle);
|
||||||
ECS_SYSTEM(ecs, InspectContainers, EcsPostUpdate, components.Input, !components.IsInVehicle);
|
ECS_SYSTEM(ecs, InspectContainers, EcsPostUpdate, components.Input, !components.IsInVehicle);
|
||||||
|
|
||||||
ECS_SYSTEM_TICKED(ecs, HarvestIntoContainers, EcsPostUpdate, components.ItemContainer, components.Position, !components.BlockHarvest);
|
ECS_SYSTEM_TICKED(ecs, HarvestIntoContainers, EcsPostUpdate, components.ItemContainer, components.Position, !components.BlockHarvest);
|
||||||
ECS_SYSTEM_TICKED(ecs, ProduceItems, EcsPostUpdate, components.ItemContainer, components.Producer, components.Position, components.Device);
|
ECS_SYSTEM_TICKED(ecs, ProduceItems, EcsPostUpdate, components.ItemContainer, components.Producer, components.Position, components.Device);
|
||||||
|
ECS_SYSTEM_TICKED_EX(ecs, PushItemsOnNodes, EcsPostUpdate, 20, components.ItemContainer, components.Position, components.Device, components.ItemRouter);
|
||||||
ECS_SYSTEM_TICKED(ecs, BuildBlueprints, EcsPostUpdate, components.Blueprint, components.Device, components.Position);
|
ECS_SYSTEM_TICKED(ecs, BuildBlueprints, EcsPostUpdate, components.Blueprint, components.Device, components.Position);
|
||||||
|
|
||||||
ECS_SYSTEM(ecs, ResetActivators, EcsPostUpdate, components.Input);
|
ECS_SYSTEM(ecs, ResetActivators, EcsPostUpdate, components.Input);
|
||||||
|
|
||||||
ECS_SYSTEM(ecs, ClearVehicle, EcsUnSet, components.Vehicle);
|
ECS_SYSTEM(ecs, ClearVehicle, EcsUnSet, components.Vehicle);
|
||||||
ECS_SYSTEM(ecs, ThrowItemsOut, EcsUnSet, components.ItemContainer, components.Position);
|
ECS_SYSTEM(ecs, ThrowItemsOut, EcsUnSet, components.ItemContainer, components.Position);
|
||||||
|
|
||||||
ECS_SYSTEM(ecs, DisableWorldEdit, EcsPostUpdate);
|
ECS_SYSTEM(ecs, DisableWorldEdit, EcsPostUpdate);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue