#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, HitBox, 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); }