make repair ships not retreat if someone needs help
This commit is contained in:
@@ -6,10 +6,12 @@
|
||||
|
||||
#include "AttackBehavior.h"
|
||||
#include "BehaviorScores.h"
|
||||
#include "BehaviorTargeting.h"
|
||||
#include "EntityAdmin.h"
|
||||
#include "FactionComponent.h"
|
||||
#include "HealthComponent.h"
|
||||
#include "PositionComponent.h"
|
||||
#include "RepairBehavior.h"
|
||||
#include "RetreatBehavior.h"
|
||||
#include "SensorRangeComponent.h"
|
||||
#include "ShipIdentityComponent.h"
|
||||
@@ -28,9 +30,15 @@ void RetreatEvaluator::evaluate(EntityAdmin& admin)
|
||||
if (f.isEnemy) { enemyShips.push_back(pos.value); }
|
||||
});
|
||||
|
||||
admin.forEach<RetreatBehavior, PositionComponent, HealthComponent, SensorRangeComponent>(
|
||||
// Snapshot repairables so weaponless repair ships can decide whether there is
|
||||
// still a damaged ally worth holding ground for.
|
||||
const std::vector<RepairableInfo> repairables = buildRepairables(admin);
|
||||
|
||||
admin.forEach<RetreatBehavior, PositionComponent, HealthComponent,
|
||||
SensorRangeComponent, FactionComponent>(
|
||||
[&](entt::entity e, RetreatBehavior& retreat, const PositionComponent& pos,
|
||||
const HealthComponent& health, const SensorRangeComponent& sensor)
|
||||
const HealthComponent& health, const SensorRangeComponent& sensor,
|
||||
const FactionComponent& faction)
|
||||
{
|
||||
const bool lowHp = (health.maxHp > 0.0f)
|
||||
&& (health.hp / health.maxHp < retreat.retreatHpFraction);
|
||||
@@ -39,14 +47,36 @@ void RetreatEvaluator::evaluate(EntityAdmin& admin)
|
||||
const bool hasWeapons = admin.hasAll<AttackBehavior>(e);
|
||||
if (!hasWeapons)
|
||||
{
|
||||
bool enemyInRange = false;
|
||||
for (const QVector2D& enemy : enemyShips)
|
||||
{
|
||||
if ((enemy - pos.value).length() <= sensor.value_tiles)
|
||||
{
|
||||
threatened = true;
|
||||
enemyInRange = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// A weaponless ship with a repair tool holds its ground while a
|
||||
// damaged ally remains within sensor range; it only flees once
|
||||
// there is nothing left to repair.
|
||||
bool repairTargetInRange = false;
|
||||
if (enemyInRange && admin.hasAll<RepairBehavior>(e))
|
||||
{
|
||||
for (const RepairableInfo& r : repairables)
|
||||
{
|
||||
if (r.entity == e) { continue; }
|
||||
if (r.isEnemy != faction.isEnemy) { continue; }
|
||||
if (r.hp <= 0.0f || r.hp >= r.maxHp) { continue; }
|
||||
if ((r.position - pos.value).length() <= sensor.value_tiles)
|
||||
{
|
||||
repairTargetInRange = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
threatened = enemyInRange && !repairTargetInRange;
|
||||
}
|
||||
|
||||
retreat.score = (lowHp || threatened)
|
||||
|
||||
Reference in New Issue
Block a user