#include "unit_actions.h" #include "game_state.h" #include "components.h" #include "systems.h" #include void actionMoveTo(ecs_entity_t entity, Action *action, Game *game) { if (action->finished) return; const Vector2 target = action->as.moveTo.target; if (!ecs_has(ECS, entity, Path)) { entitySetPath(entity, target, game); return; } Vector2 pos = *ecs_get(ECS, entity, Position); f32 dst = Vector2Distance(pos, target); if (dst < action->as.moveTo.proximityThreshold) { action->finished = true; ecs_remove(ECS, entity, Path); } } void actionCollectResource(ecs_entity_t entity, Action *action, Game *game) { if (action->finished) return; if (action->elapsed > 2.0f) { action->finished = true; ecs_entity_t target = action->as.collectResource.entity; ecs_delete(ECS, target); } } void actionDepositResource(ecs_entity_t entity, Action *action, Game *game) { if (action->elapsed > 0.2f) action->finished = true; } void handleAction(ecs_entity_t entity, UnitAction *unitAction, Game *game) { Action *action = unitAction->first; if (action == NULL) return; if (action->finished || action->failed) return; switch (action->type) { case ACTION_NONE: break; case ACTION_MOVE_TO: actionMoveTo(entity, action, game); break; case ACTION_COLLECT_RESOURCE: actionCollectResource(entity, action, game); break; case ACTION_DEPOSIT_RESOURCE: actionDepositResource(entity, action, game); break; default: BZ_ASSERT(0); break; } } void updateAction(UnitAction *unitAction, Game *game) { Action *action = unitAction->first; if (action == NULL) return; if (action->failed) return; action->elapsed += GetFrameTime(); if (action->finished) { unitAction->first = action->next; if (unitAction->last == action) { unitAction->last = NULL; BZ_ASSERT(unitAction->first == unitAction->last); } BzObjectPool *pool = game->pools.actions; bzObjectPoolRelease(pool, action); } } void clearActions(ecs_entity_t entity, Game *game) { if (!ecs_has(ECS, entity, UnitAction)) return; UnitAction *unitAction = ecs_get_mut(ECS, entity, UnitAction); BzObjectPool *pool = game->pools.actions; Action *pAction = unitAction->first; while (pAction) { bzObjectPoolRelease(pool, pAction); pAction = pAction->next; } unitAction->first = NULL; unitAction->last = NULL; } void addAction(ecs_entity_t entity, Game *game, const Action *action) { BZ_ASSERT(action); BZ_ASSERT(ecs_has(ECS, entity, UnitAction)); UnitAction *unitAction = ecs_get_mut(ECS, entity, UnitAction); BzObjectPool *pool = game->pools.actions; Action *newAction = bzObjectPool(pool); BZ_ASSERT(newAction); *newAction = *action; newAction->next = NULL; if (unitAction->last) { Action *last = unitAction->last; last->next = newAction; unitAction->last = newAction; } else { unitAction->first = newAction; unitAction->last = newAction; } } const char *actionTypeToPrettyStr(ActionType type) { switch (type) { case ACTION_MOVE_TO: return "MOVE TO"; case ACTION_COLLECT_RESOURCE: return "COLLECT RESOURCE"; case ACTION_DEPOSIT_RESOURCE: return "DEPOSIT RESOURCE"; default: return "NONE"; } }