Files
PixelDefense/game/systems/systems.c

218 lines
7.0 KiB
C

#include "systems.h"
#include "../game_state.h"
bool entityGetHitBox(ecs_entity_t entity, Position *outPos, Rectangle *outHitBox) {
if (!ecs_is_alive(ECS, entity))
return false;
const Position *pos = ecs_get(ECS, entity, Position);
if (!pos)
return false;
if (outPos)
*outPos = *pos;
const HitBox *hitbox = ecs_get(ECS, entity, HitBox);
if (!hitbox)
return false;
if (outHitBox) {
*outHitBox = *hitbox;
outHitBox->x += pos->x;
outHitBox->y = pos->y - hitbox->y - hitbox->height;
}
return true;
}
Rectangle entityTransformHitBox(Position position, HitBox hitBox) {
return (Rectangle) {
position.x + hitBox.x,
position.y - hitBox.y - hitBox.height,
hitBox.width,
hitBox.height
};
}
Vector2 entityGetCenter(Position position, HitBox hitBox) {
return (Vector2) {
position.x + hitBox.x + hitBox.width * 0.5f,
position.y - hitBox.y - hitBox.height * 0.5f
};
}
ecs_entity_t renderCollidersSystem;
ecs_entity_t renderOrientDirSystem;
ecs_entity_t renderDebugPathSystem;
ECS_DTOR(SpatialGridID, gridID, {
Game *game = ecs_singleton_get_mut(ECS, Game);
if (*gridID != -1) {
bzSpatialGridRemove(game->entityGrid, *gridID);
*gridID = -1;
}
})
ECS_MOVE(SpatialGridID, dst, src, {
*dst = *src;
*src = -1;
})
void spatialIDRemoved(ecs_iter_t *it) {
Game *game = ecs_singleton_get_mut(ECS, Game);
SpatialGridID *spatialID = ecs_field(it, SpatialGridID, 1);
for (int i = 0; i < it->count; i++) {
if (spatialID[i] == -1) continue;
bzSpatialGridRemove(game->entityGrid, spatialID[i]);
spatialID[i] = -1;
}
}
ECS_DTOR(Path, path, {
Game *game = ecs_singleton_get_mut(ECS, Game);
BzObjectPool *pool = game->pools.pathData;
PathData *cur = path->paths;
while (cur) {
bzObjectPoolRelease(pool, cur);
cur = cur->next;
}
})
ECS_MOVE(Path, dst, src, {
*dst = *src;
src->paths = NULL;
src->curWaypoint = 0;
})
void pathRemoved(ecs_iter_t *it) {
Game *game = ecs_singleton_get_mut(ECS, Game);
BzObjectPool *pool = game->pools.pathData;
Path *path = ecs_field(it, Path, 1);
for (int i = 0; i < it->count; i++) {
PathData *cur = path[i].paths;
while (cur) {
bzObjectPoolRelease(pool, cur);
cur = cur->next;
}
path[i].paths = NULL;
}
}
ECS_DTOR(Building, building, {
Vec2i pos = building->pos;
Vec2i size = building->size;
Game *game = ecs_singleton_get_mut(ECS, Game);
bzTileMapSetCollisions(&game->map, false, COLL_LAYER_BUILDINGS, pos.x, pos.y, size.x, size.y);
})
ECS_MOVE(Building, dst, src, {
*dst = *src;
*src = (Building) {.type = 0};
})
void buildingRemoved(ecs_iter_t *it) {
Game *game = ecs_singleton_get_mut(ECS, Game);
Building *building = ecs_field(it, Building, 1);
for (int i = 0; i < it->count; i++) {
Vec2i pos = building[i].pos;
Vec2i size = building[i].size;
bzTileMapSetCollisions(&game->map, false, COLL_LAYER_BUILDINGS, pos.x, pos.y, size.x, size.y);
}
}
ECS_DTOR(AttachedEntity, attached, {
if (ecs_is_alive(ECS, attached->entity))
ecs_delete(ECS, attached->entity);
attached->entity = 0;
})
ECS_MOVE(AttachedEntity, dst, src, {
*dst = *src;
src->entity = 0;
})
void attachedRemoved(ecs_iter_t *it) {
AttachedEntity *attached = ecs_field(it, AttachedEntity , 1);
for (int i = 0; i < it->count; i++) {
const ecs_entity_t entity = attached[i].entity;
if (ecs_is_alive(ECS, entity))
ecs_delete(ECS, entity);
}
}
void delayDeleteUpdate(ecs_iter_t *it) {
DelayDelete *delay = ecs_field(it, DelayDelete, 1);
f32 dt = GetFrameTime();
for (i32 i = 0; i < it->count; i++) {
delay[i].elapsed += dt;
if (delay[i].elapsed >= delay[i].time) {
ecs_delete(ECS, it->entities[i]);
}
}
}
void setupSystems() {
ecs_set_hooks(ECS, SpatialGridID, {
.dtor = ecs_dtor(SpatialGridID),
.move_dtor = ecs_move(SpatialGridID),
.on_remove = spatialIDRemoved,
});
ecs_set_hooks(ECS, Path, {
.dtor = ecs_dtor(Path),
.move = ecs_move(Path),
.on_remove = pathRemoved,
});
ecs_set_hooks(ECS, Building, {
.dtor = ecs_dtor(Building),
.move_dtor = ecs_move(Building),
.on_remove = buildingRemoved,
});
ecs_set_hooks(ECS, AttachedEntity, {
.dtor = ecs_dtor(AttachedEntity),
.move_dtor = ecs_move(AttachedEntity),
.on_remove = attachedRemoved,
});
ECS_OBSERVER(ECS, entityPathRemove, EcsOnRemove, Path);
ECS_OBSERVER(ECS, updateTextureOwnerTile, EcsOnSet, TextureRegion, Owner);
ECS_OBSERVER(ECS, buildingAddPopCapacity, EcsOnSet, AddPopCapacity, Owner);
ECS_OBSERVER(ECS, buildingRemovePopCapacity, EcsOnRemove, AddPopCapacity, Owner);
ECS_OBSERVER(ECS, entityConsumePopCapacity, EcsOnSet, ConsumePopCapacity);
ECS_OBSERVER(ECS, entityUnConsumePopCapacity, EcsOnRemove, ConsumePopCapacity);
ECS_SYSTEM(ECS, entityUpdateSpatialID, EcsOnUpdate, Position, HitBox, Velocity, SpatialGridID);
ECS_SYSTEM(ECS, entityUpdateKinematic, EcsOnUpdate, Position, Velocity, Steering, Unit);
ECS_SYSTEM(ECS, entityUpdate, EcsOnUpdate, Position, HitBox, Velocity, Unit, Owner, SpatialGridID);
ECS_SYSTEM(ECS, entityMoveToTarget, EcsOnUpdate, Position, Velocity, TargetPosition, Steering);
ECS_SYSTEM(ECS, entityMoveSwarm, EcsOnUpdate, Position, Velocity, HitBox, Swarm, Owner, Steering);
ECS_SYSTEM(ECS, entityFollowPath, EcsOnUpdate, Path);
ECS_SYSTEM(ECS, updateBuildingRecruitment, EcsOnUpdate, Owner, Building, BuildingRecruitInfo);
ECS_SYSTEM(ECS, resetHarvestCount, EcsOnUpdate, Harvestable);
ECS_SYSTEM(ECS, updateAISystem, EcsOnUpdate, BzBTState);
ECS_SYSTEM(ECS, updateTower, EcsOnUpdate, Owner, Tower, Position, Size);
ECS_SYSTEM(ECS, updateProjectile, EcsOnUpdate, Owner, Projectile, Position, Velocity);
ECS_SYSTEM(ECS, updateAnimationState, EcsOnUpdate, Animation, TextureRegion);
ECS_SYSTEM(ECS, updateAnimation, EcsOnUpdate, Animation, TextureRegion);
ECS_SYSTEM(ECS, updateEasingSystem, EcsOnUpdate, Easing, Position, HitBox, Rotation);
ECS_SYSTEM(ECS, renderHealthBar, EcsOnUpdate, Position, HitBox, Health);
ECS_SYSTEM(ECS, renderFloatyTextParticle, EcsOnUpdate, FloatyTextParticle);
ECS_SYSTEM(ECS, updateParticleEmitter, EcsOnUpdate, ParticleEmitter);
ECS_SYSTEM(ECS, renderDebugPath, EcsOnUpdate, Path);
ECS_SYSTEM(ECS, renderColliders, EcsOnUpdate, Position, HitBox);
ECS_SYSTEM(ECS, renderOrientationDirection, EcsOnUpdate, Position, Orientation);
ECS_SYSTEM(ECS, delayDeleteUpdate, EcsOnUpdate, DelayDelete);
renderDebugPathSystem = renderDebugPath;
renderOrientDirSystem = renderOrientationDirection;
renderCollidersSystem = renderColliders;
//ecs_enable(ECS, renderOrientDirSystem, false);
//ecs_enable(ECS, renderArmPositionSystem, false);
}