refactor AI system
This commit is contained in:
71
src/lib/ecs/system/ai/AttackEvaluator.cpp
Normal file
71
src/lib/ecs/system/ai/AttackEvaluator.cpp
Normal file
@@ -0,0 +1,71 @@
|
||||
#include "AttackEvaluator.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <QVector2D>
|
||||
|
||||
#include "AttackBehavior.h"
|
||||
#include "BehaviorScores.h"
|
||||
#include "BehaviorTargeting.h"
|
||||
#include "EntityAdmin.h"
|
||||
#include "FactionComponent.h"
|
||||
#include "HealthComponent.h"
|
||||
#include "PositionComponent.h"
|
||||
#include "SensorRangeComponent.h"
|
||||
#include "tracing.h"
|
||||
|
||||
void AttackEvaluator::evaluate(EntityAdmin& admin)
|
||||
{
|
||||
TRACE();
|
||||
const std::vector<CombatantInfo> combatants = buildCombatants(admin);
|
||||
|
||||
admin.forEach<AttackBehavior, PositionComponent, FactionComponent,
|
||||
SensorRangeComponent, HealthComponent>(
|
||||
[&](entt::entity e, AttackBehavior& attack, const PositionComponent& pos,
|
||||
const FactionComponent& faction, const SensorRangeComponent& sensor,
|
||||
const HealthComponent& health)
|
||||
{
|
||||
const float range = sensor.value_tiles;
|
||||
|
||||
// Validate current target: still valid, still in range.
|
||||
bool targetValid = false;
|
||||
if (attack.currentTarget)
|
||||
{
|
||||
const entt::entity t = *attack.currentTarget;
|
||||
if (admin.isValid(t) && admin.hasAll<PositionComponent>(t))
|
||||
{
|
||||
const float dist =
|
||||
(admin.get<PositionComponent>(t).value - pos.value).length();
|
||||
if (dist <= range) { targetValid = true; }
|
||||
}
|
||||
}
|
||||
|
||||
// Acquire nearest valid target if needed.
|
||||
if (!targetValid)
|
||||
{
|
||||
attack.currentTarget = std::nullopt;
|
||||
float bestDist = range;
|
||||
for (const CombatantInfo& c : combatants)
|
||||
{
|
||||
if (c.entity == e) { continue; }
|
||||
const bool isValidTarget =
|
||||
faction.isEnemy ? !c.isEnemy : c.isEnemy;
|
||||
if (!isValidTarget) { continue; }
|
||||
|
||||
const float dist = (c.position - pos.value).length();
|
||||
if (dist < bestDist)
|
||||
{
|
||||
bestDist = dist;
|
||||
attack.currentTarget = c.entity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const bool healthy =
|
||||
(health.maxHp > 0.0f)
|
||||
&& (health.hp / health.maxHp >= BehaviorScores::kLowHpFraction);
|
||||
attack.score = (healthy && attack.currentTarget)
|
||||
? BehaviorScores::kAttack
|
||||
: BehaviorScores::kInactive;
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user