Add chase/evade behaviour

This commit is contained in:
2024-02-13 18:27:53 +01:00
parent e6ddafd3e2
commit 24abf94faa
8 changed files with 189 additions and 59 deletions

View File

@@ -47,11 +47,89 @@ BzBTStatus aiResetElapsed(AIBlackboard *data, f32 dt) {
return BZ_BT_SUCCESS;
}
#define ENEMY_NEARBY_DST 26.0f
BzBTStatus aiIsEnemyNearby(AIBlackboard *data, f32 dt) {
if (data->seenEnemy && ecs_is_alive(ECS, data->seenEnemy)) {
Position enemyPos = *ecs_get(ECS, data->seenEnemy, Position);
Position pos = *ecs_get(ECS, data->entity, Position);
if (Vector2Distance(enemyPos, pos) > ENEMY_NEARBY_DST)
return BZ_BT_SUCCESS;
}
const f32 range = 20.0f;
Position pos = *ecs_get(ECS, data->entity, Position);
HitBox hb = *ecs_get(ECS, data->entity, HitBox);
Vector2 center = entityGetCenter(pos, hb);
Owner owner = *ecs_get(ECS, data->entity, Owner);
ecs_entity_t closest = 0;
f32 closestDst = 10000.0f;
Game *game = ecs_singleton_get_mut(ECS, Game);
BzSpatialGridIter it = bzSpatialGridIter(game->entityGrid,
center.x - range, center.y - range,
center.x + range, center.y + range);
while (bzSpatialGridQueryNext(&it)) {
ecs_entity_t other = *(ecs_entity_t *) it.data;
if (!ecs_is_alive(ECS, other)) continue;
if (!ecs_has(ECS, other, Owner) ||
ecs_get(ECS, other, Owner)->player == owner.player)
continue;
Position otherPos = *ecs_get(ECS, other, Position);
HitBox otherHB = *ecs_get(ECS, other, HitBox);
Vector2 otherCenter = entityGetCenter(otherPos, otherHB);
f32 dst = Vector2Distance(center, otherCenter);
if (dst > range) continue;
if (!bzTileMapCanRayCastLine(&game->map, center, otherCenter))
continue;
if (dst < closestDst) {
closest = other;
closestDst = dst;
}
}
if (closest) {
data->seenEnemy = closest;
return BZ_BT_SUCCESS;
}
return BZ_BT_FAIL;
}
BzBTStatus aiEvadeTarget(AIBlackboard *data, f32 dt) {
return BZ_BT_SUCCESS;
BzBTStatus aiAttackEnemy(AIBlackboard *data, f32 dt) {
if (!ecs_is_alive(ECS, data->seenEnemy))
return BZ_BT_SUCCESS;
Position enemyPos = *ecs_get(ECS, data->seenEnemy, Position);
Position pos = *ecs_get(ECS, data->entity, Position);
Vector2 dif = Vector2Subtract(enemyPos, pos);
// Overload steering
Steering *steering = ecs_get_mut(ECS, data->entity, Steering);
*steering = Vector2Normalize(dif);
return BZ_BT_RUNNING;
}
BzBTStatus aiEvadeEnemy(AIBlackboard *data, f32 dt) {
if (!ecs_is_alive(ECS, data->seenEnemy))
return BZ_BT_SUCCESS;
Position enemyPos = *ecs_get(ECS, data->seenEnemy, Position);
Position pos = *ecs_get(ECS, data->entity, Position);
Vector2 dif = Vector2Subtract(pos, enemyPos);
// Overload steering
Steering *steering = ecs_get_mut(ECS, data->entity, Steering);
*steering = Vector2Normalize(dif);
return BZ_BT_RUNNING;
}
BzBTStatus aiFindNextHarvestable(AIBlackboard *data, f32 dt) {