make repair ships not retreat if someone needs help
This commit is contained in:
@@ -6,10 +6,12 @@
|
|||||||
|
|
||||||
#include "AttackBehavior.h"
|
#include "AttackBehavior.h"
|
||||||
#include "BehaviorScores.h"
|
#include "BehaviorScores.h"
|
||||||
|
#include "BehaviorTargeting.h"
|
||||||
#include "EntityAdmin.h"
|
#include "EntityAdmin.h"
|
||||||
#include "FactionComponent.h"
|
#include "FactionComponent.h"
|
||||||
#include "HealthComponent.h"
|
#include "HealthComponent.h"
|
||||||
#include "PositionComponent.h"
|
#include "PositionComponent.h"
|
||||||
|
#include "RepairBehavior.h"
|
||||||
#include "RetreatBehavior.h"
|
#include "RetreatBehavior.h"
|
||||||
#include "SensorRangeComponent.h"
|
#include "SensorRangeComponent.h"
|
||||||
#include "ShipIdentityComponent.h"
|
#include "ShipIdentityComponent.h"
|
||||||
@@ -28,9 +30,15 @@ void RetreatEvaluator::evaluate(EntityAdmin& admin)
|
|||||||
if (f.isEnemy) { enemyShips.push_back(pos.value); }
|
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,
|
[&](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)
|
const bool lowHp = (health.maxHp > 0.0f)
|
||||||
&& (health.hp / health.maxHp < retreat.retreatHpFraction);
|
&& (health.hp / health.maxHp < retreat.retreatHpFraction);
|
||||||
@@ -39,14 +47,36 @@ void RetreatEvaluator::evaluate(EntityAdmin& admin)
|
|||||||
const bool hasWeapons = admin.hasAll<AttackBehavior>(e);
|
const bool hasWeapons = admin.hasAll<AttackBehavior>(e);
|
||||||
if (!hasWeapons)
|
if (!hasWeapons)
|
||||||
{
|
{
|
||||||
|
bool enemyInRange = false;
|
||||||
for (const QVector2D& enemy : enemyShips)
|
for (const QVector2D& enemy : enemyShips)
|
||||||
{
|
{
|
||||||
if ((enemy - pos.value).length() <= sensor.value_tiles)
|
if ((enemy - pos.value).length() <= sensor.value_tiles)
|
||||||
{
|
{
|
||||||
threatened = true;
|
enemyInRange = true;
|
||||||
break;
|
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)
|
retreat.score = (lowHp || threatened)
|
||||||
|
|||||||
Reference in New Issue
Block a user