Files
dota_factory/src/lib/ecs/system/ai/SalvageScrapEvaluator.cpp
2026-06-15 09:16:56 +02:00

56 lines
1.8 KiB
C++

#include "SalvageScrapEvaluator.h"
#include <optional>
#include <unordered_map>
#include <vector>
#include <QVector2D>
#include "BehaviorScores.h"
#include "BehaviorTargeting.h"
#include "EntityAdmin.h"
#include "PositionComponent.h"
#include "SalvageScrapBehavior.h"
#include "ScrapSystem.h"
#include "SensorRangeComponent.h"
#include "tracing.h"
void SalvageScrapEvaluator::evaluate(EntityAdmin& admin, const ScrapSystem& scraps)
{
TRACE();
const std::unordered_map<entt::entity, CargoState> cargoByShip = buildCargoByShip(admin);
const std::vector<ScrapInfo> allScrap = scraps.allScrapInfo();
admin.forEach<SalvageScrapBehavior, PositionComponent, SensorRangeComponent>(
[&](entt::entity e, SalvageScrapBehavior& salvage, const PositionComponent& pos,
const SensorRangeComponent& sensor)
{
const std::unordered_map<entt::entity, CargoState>::const_iterator it =
cargoByShip.find(e);
const bool cargoFull = (it != cargoByShip.end()) && isCargoFull(it->second);
if (cargoFull)
{
salvage.scrapTarget = std::nullopt;
salvage.score = BehaviorScores::kInactive;
return;
}
// Find nearest scrap within sensor range.
float bestDist = sensor.value_tiles;
std::optional<QVector2D> bestPos;
for (const ScrapInfo& si : allScrap)
{
const float dist = (si.position - pos.value).length();
if (dist < bestDist)
{
bestDist = dist;
bestPos = si.position;
}
}
salvage.scrapTarget = bestPos;
salvage.score = bestPos ? BehaviorScores::kSalvage : BehaviorScores::kInactive;
});
}