allow to (multi) select scrap
This commit is contained in:
@@ -69,9 +69,9 @@ std::vector<ScrapInfo> ScrapSystem::allScrapInfo() const
|
||||
{
|
||||
std::vector<ScrapInfo> result;
|
||||
m_admin.forEach<ScrapDataComponent>(
|
||||
[&result, this](entt::entity e, const ScrapDataComponent& /*sd*/)
|
||||
[&result, this](entt::entity e, const ScrapDataComponent& sd)
|
||||
{
|
||||
result.push_back(ScrapInfo{e, m_admin.get<PositionComponent>(e).value});
|
||||
result.push_back(ScrapInfo{e, m_admin.get<PositionComponent>(e).value, sd.amount});
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ struct ScrapInfo
|
||||
{
|
||||
entt::entity entity;
|
||||
QVector2D position;
|
||||
int amount;
|
||||
};
|
||||
|
||||
class ScrapSystem
|
||||
|
||||
18
src/lib/eventsystem/event/ScrapSelectionChangedEvent.h
Normal file
18
src/lib/eventsystem/event/ScrapSelectionChangedEvent.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "entt/entity/entity.hpp"
|
||||
|
||||
#include "Event.h"
|
||||
|
||||
// The set of currently selected scrap piles (REQ-UI-SCRAP-CLICK-SELECT,
|
||||
// REQ-UI-SCRAP-MULTI-SELECT). An empty list means no scrap is selected. Scrap forms
|
||||
// its own selection category, mutually exclusive with buildings and entities.
|
||||
class ScrapSelectionChangedEvent : public Event
|
||||
{
|
||||
public:
|
||||
explicit ScrapSelectionChangedEvent(std::vector<entt::entity> scrap)
|
||||
: scrap(std::move(scrap)) {}
|
||||
const std::vector<entt::entity> scrap;
|
||||
};
|
||||
@@ -1,9 +1,11 @@
|
||||
#include "EntityHitTest.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
#include "EntityAdmin.h"
|
||||
#include "PositionComponent.h"
|
||||
#include "ScrapDataComponent.h"
|
||||
#include "StationBodyComponent.h"
|
||||
#include "HealthComponent.h"
|
||||
|
||||
@@ -54,3 +56,48 @@ entt::entity entityAtWorldPos(EntityAdmin& admin, QVector2D worldPos)
|
||||
|
||||
return bestShip;
|
||||
}
|
||||
|
||||
entt::entity scrapAtWorldPos(EntityAdmin& admin, QVector2D worldPos)
|
||||
{
|
||||
// Slightly larger than the scrap's rendered radius (0.2 tiles) so small piles
|
||||
// remain easy to click; tunable.
|
||||
constexpr float kScrapHitRadiusSquared = 0.35f * 0.35f;
|
||||
entt::entity bestScrap = entt::null;
|
||||
float bestDistSquared = kScrapHitRadiusSquared;
|
||||
|
||||
admin.forEach<ScrapDataComponent, PositionComponent>(
|
||||
[&](entt::entity entity, const ScrapDataComponent& /*sd*/, const PositionComponent& pos)
|
||||
{
|
||||
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;
|
||||
bestScrap = entity;
|
||||
}
|
||||
});
|
||||
|
||||
return bestScrap;
|
||||
}
|
||||
|
||||
std::vector<entt::entity> scrapInBox(EntityAdmin& admin, QPoint tileA, QPoint tileB)
|
||||
{
|
||||
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<ScrapDataComponent, PositionComponent>(
|
||||
[&](entt::entity entity, const ScrapDataComponent& /*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);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <QPoint>
|
||||
#include <QVector2D>
|
||||
|
||||
#include "entt/entity/entity.hpp"
|
||||
@@ -7,3 +10,12 @@
|
||||
class EntityAdmin;
|
||||
|
||||
entt::entity entityAtWorldPos(EntityAdmin& admin, QVector2D worldPos);
|
||||
|
||||
// Returns the nearest scrap pile whose center is within the scrap pick radius of
|
||||
// worldPos, or entt::null if none (REQ-UI-SCRAP-CLICK-SELECT). Scrap is picked only
|
||||
// after actors: entityAtWorldPos never returns scrap (scrap has no HealthComponent).
|
||||
entt::entity scrapAtWorldPos(EntityAdmin& admin, QVector2D worldPos);
|
||||
|
||||
// Returns every scrap pile whose position falls within the inclusive tile rectangle
|
||||
// spanned by tileA and tileB, in any corner order (REQ-UI-SCRAP-MULTI-SELECT).
|
||||
std::vector<entt::entity> scrapInBox(EntityAdmin& admin, QPoint tileA, QPoint tileB);
|
||||
|
||||
Reference in New Issue
Block a user