#include "RepairEvaluator.h" #include #include "BehaviorScores.h" #include "BehaviorTargeting.h" #include "EntityAdmin.h" #include "FactionComponent.h" #include "HealthComponent.h" #include "PositionComponent.h" #include "RepairBehavior.h" #include "SensorRangeComponent.h" #include "tracing.h" void RepairEvaluator::evaluate(EntityAdmin& admin) { TRACE(); const std::vector repairables = buildRepairables(admin); admin.forEach( [&](entt::entity e, RepairBehavior& repair, const PositionComponent& pos, const SensorRangeComponent& sensor, const FactionComponent& faction) { // Validate current target: same faction, alive and still damaged. bool targetValid = false; if (repair.currentTarget) { const entt::entity t = *repair.currentTarget; if (admin.isValid(t) && admin.hasAll(t)) { const HealthComponent& th = admin.get(t); const FactionComponent& tf = admin.get(t); if (tf.isEnemy == faction.isEnemy && th.hp > 0.0f && th.hp < th.maxHp) { targetValid = true; } } } // Acquire nearest damaged friendly within sensor range. Friendly is // relative to this ship's faction, not the absolute isEnemy flag. if (!targetValid) { repair.currentTarget = std::nullopt; float bestDist = sensor.value_tiles; 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; } const float dist = (r.position - pos.value).length(); if (dist < bestDist) { bestDist = dist; repair.currentTarget = r.entity; } } } repair.score = repair.currentTarget ? BehaviorScores::kRepair : BehaviorScores::kInactive; }); }