57 lines
1.7 KiB
C++
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;
|
|
}
|