72 lines
2.4 KiB
C++
72 lines
2.4 KiB
C++
#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;
|
|
});
|
|
}
|