Files
dota_factory/src/lib/sim/EntityHitTest.cpp
2026-06-07 22:06:37 +02:00

57 lines
1.7 KiB
C++

#include "EntityHitTest.h"
#include <cmath>
#include "EntityAdmin.h"
#include "PositionComponent.h"
#include "StationBodyComponent.h"
#include "HealthComponent.h"
entt::entity entityAtWorldPos(EntityAdmin& admin, QVector2D worldPos)
{
const QPoint tile(static_cast<int>(std::floor(worldPos.x())),
static_cast<int>(std::floor(worldPos.y())));
entt::entity stationHit = entt::null;
admin.forEach<StationBodyComponent, HealthComponent>(
[&](entt::entity entity, const StationBodyComponent& sb, const HealthComponent& h)
{
if (stationHit != entt::null) { return; }
if (h.hp <= 0.0f) { return; }
for (const QPoint& cell : sb.bodyCells)
{
if (cell == tile)
{
stationHit = entity;
return;
}
}
});
if (stationHit != entt::null)
{
return stationHit;
}
constexpr float kShipHitRadiusSquared = 0.5f * 0.5f;
entt::entity bestShip = entt::null;
float bestDistSquared = kShipHitRadiusSquared;
admin.forEach<PositionComponent, HealthComponent>(
[&](entt::entity entity, const PositionComponent& pos, const HealthComponent& h)
{
if (h.hp <= 0.0f) { return; }
if (admin.hasAll<StationBodyComponent>(entity)) { return; }
const float dx = pos.value.x() - worldPos.x();
const float dy = pos.value.y() - worldPos.y();
const float distSquared = dx * dx + dy * dy;
if (distSquared < bestDistSquared)
{
bestDistSquared = distSquared;
bestShip = entity;
}
});
return bestShip;
}