Add chase/evade behaviour
This commit is contained in:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user