make selection box sub-tile aware
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
#include <cmath>
|
||||
|
||||
#include "EntityAdmin.h"
|
||||
#include "SelectionBox.h"
|
||||
#include "PositionComponent.h"
|
||||
#include "DebrisComponent.h"
|
||||
#include "ShipIdentityComponent.h"
|
||||
@@ -82,45 +83,29 @@ entt::entity debrisAtWorldPos(EntityAdmin& admin, QVector2D worldPos)
|
||||
return bestDebris;
|
||||
}
|
||||
|
||||
std::vector<entt::entity> debrisInBox(EntityAdmin& admin, QPoint tileA, QPoint tileB)
|
||||
std::vector<entt::entity> debrisInBox(EntityAdmin& admin, const QRectF& worldBox)
|
||||
{
|
||||
const int minX = std::min(tileA.x(), tileB.x());
|
||||
const int maxX = std::max(tileA.x(), tileB.x());
|
||||
const int minY = std::min(tileA.y(), tileB.y());
|
||||
const int maxY = std::max(tileA.y(), tileB.y());
|
||||
|
||||
std::vector<entt::entity> result;
|
||||
admin.forEach<DebrisComponent, PositionComponent>(
|
||||
[&](entt::entity entity, const DebrisComponent& /*sd*/, const PositionComponent& pos)
|
||||
{
|
||||
const int tileX = static_cast<int>(std::floor(pos.value.x()));
|
||||
const int tileY = static_cast<int>(std::floor(pos.value.y()));
|
||||
if (tileX >= minX && tileX <= maxX && tileY >= minY && tileY <= maxY)
|
||||
{
|
||||
result.push_back(entity);
|
||||
}
|
||||
if (boxCoversPoint(worldBox, pos.value)) { result.push_back(entity); }
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<entt::entity> actorsInBox(EntityAdmin& admin, QPoint tileA, QPoint tileB)
|
||||
std::vector<entt::entity> actorsInBox(EntityAdmin& admin, const QRectF& worldBox)
|
||||
{
|
||||
const int minX = std::min(tileA.x(), tileB.x());
|
||||
const int maxX = std::max(tileA.x(), tileB.x());
|
||||
const int minY = std::min(tileA.y(), tileB.y());
|
||||
const int maxY = std::max(tileA.y(), tileB.y());
|
||||
|
||||
std::vector<entt::entity> result;
|
||||
|
||||
// Stations: included when any occupied body cell lies in the box.
|
||||
// Stations occupy whole tiles: included when the box overlaps any occupied cell.
|
||||
admin.forEach<StationBodyComponent, HealthComponent>(
|
||||
[&](entt::entity entity, const StationBodyComponent& sb, const HealthComponent& h)
|
||||
{
|
||||
if (h.hp <= 0.0f) { return; }
|
||||
for (const QPoint& cell : sb.bodyCells)
|
||||
{
|
||||
if (cell.x() >= minX && cell.x() <= maxX
|
||||
&& cell.y() >= minY && cell.y() <= maxY)
|
||||
if (boxCoversTile(worldBox, cell))
|
||||
{
|
||||
result.push_back(entity);
|
||||
return;
|
||||
@@ -128,19 +113,15 @@ std::vector<entt::entity> actorsInBox(EntityAdmin& admin, QPoint tileA, QPoint t
|
||||
}
|
||||
});
|
||||
|
||||
// Ships: included when the floored position tile lies in the box. Requiring
|
||||
// ShipIdentityComponent excludes the HQ proxy and any station bodies.
|
||||
// Ships have a position rather than a footprint: included when the box contains
|
||||
// that position. Requiring ShipIdentityComponent excludes the HQ proxy and any
|
||||
// station bodies.
|
||||
admin.forEach<ShipIdentityComponent, PositionComponent, HealthComponent>(
|
||||
[&](entt::entity entity, const ShipIdentityComponent& /*id*/,
|
||||
const PositionComponent& pos, const HealthComponent& h)
|
||||
{
|
||||
if (h.hp <= 0.0f) { return; }
|
||||
const int tileX = static_cast<int>(std::floor(pos.value.x()));
|
||||
const int tileY = static_cast<int>(std::floor(pos.value.y()));
|
||||
if (tileX >= minX && tileX <= maxX && tileY >= minY && tileY <= maxY)
|
||||
{
|
||||
result.push_back(entity);
|
||||
}
|
||||
if (boxCoversPoint(worldBox, pos.value)) { result.push_back(entity); }
|
||||
});
|
||||
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user