Rename ship/station scrap drop entities to "debris"
This commit is contained in:
@@ -52,15 +52,15 @@
|
||||
#include "PositionComponent.h"
|
||||
#include "RepairBehavior.h"
|
||||
#include "SalvageScrapBehavior.h"
|
||||
#include "ScrapSelectionChangedEvent.h"
|
||||
#include "ScrapSystem.h"
|
||||
#include "DebrisSelectionChangedEvent.h"
|
||||
#include "DebrisSystem.h"
|
||||
#include "SelectionChangedEvent.h"
|
||||
#include "SensorRangeComponent.h"
|
||||
#include "ShipIdentityComponent.h"
|
||||
#include "ShipSystem.h"
|
||||
#include "Simulation.h"
|
||||
#include "StationBodyComponent.h"
|
||||
#include "ScrapDataComponent.h"
|
||||
#include "DebrisComponent.h"
|
||||
#include "SurfaceMask.h"
|
||||
#include "Tick.h"
|
||||
#include "TunnelCompletion.h"
|
||||
@@ -350,9 +350,9 @@ void GameWorldView::onFrame()
|
||||
m_activeBeams = std::move(live);
|
||||
}
|
||||
|
||||
// Drop selected scrap piles that were collected or despawned this frame, so the
|
||||
// panel stops counting them and the selection empties out (REQ-UI-SCRAP-CLICK-SELECT).
|
||||
pruneDespawnedScrap();
|
||||
// Drop selected debris that were collected or despawned this frame, so the
|
||||
// panel stops counting them and the selection empties out (REQ-UI-DEBRIS-CLICK-SELECT).
|
||||
pruneDespawnedDebris();
|
||||
pruneDespawnedActors();
|
||||
|
||||
// Expire copy/paste flashes. Lifetime is wall-clock (the frame delta), so the
|
||||
@@ -504,7 +504,7 @@ void GameWorldView::paintGL()
|
||||
drawCopyConfigFeedback(painter);
|
||||
drawStations(painter);
|
||||
drawBeltItems(painter);
|
||||
drawScrap(painter);
|
||||
drawDebris(painter);
|
||||
if (m_debugDraw)
|
||||
{
|
||||
drawDebugSensorRanges(painter);
|
||||
@@ -779,33 +779,33 @@ std::optional<QVector2D> GameWorldView::entityPosition(entt::entity entity) cons
|
||||
return m_sim->getAdmin().get<PositionComponent>(entity).value;
|
||||
}
|
||||
|
||||
void GameWorldView::clearScrapSelection()
|
||||
void GameWorldView::clearDebrisSelection()
|
||||
{
|
||||
if (m_selectedScrap.empty()) { return; }
|
||||
m_selectedScrap.clear();
|
||||
if (m_selectedDebris.empty()) { return; }
|
||||
m_selectedDebris.clear();
|
||||
EventManager::getInstance()->sendEventImmediately(
|
||||
std::make_shared<ScrapSelectionChangedEvent>(m_selectedScrap));
|
||||
std::make_shared<DebrisSelectionChangedEvent>(m_selectedDebris));
|
||||
}
|
||||
|
||||
void GameWorldView::pruneDespawnedScrap()
|
||||
void GameWorldView::pruneDespawnedDebris()
|
||||
{
|
||||
if (m_selectedScrap.empty()) { return; }
|
||||
if (m_selectedDebris.empty()) { return; }
|
||||
|
||||
std::vector<entt::entity> live;
|
||||
for (const ScrapInfo& info : m_sim->getScraps().getAllScrapInfo())
|
||||
for (const DebrisInfo& info : m_sim->getDebrisSystem().getAllDebrisInfo())
|
||||
{
|
||||
if (std::find(m_selectedScrap.begin(), m_selectedScrap.end(), info.entity)
|
||||
!= m_selectedScrap.end())
|
||||
if (std::find(m_selectedDebris.begin(), m_selectedDebris.end(), info.entity)
|
||||
!= m_selectedDebris.end())
|
||||
{
|
||||
live.push_back(info.entity);
|
||||
}
|
||||
}
|
||||
|
||||
if (live.size() != m_selectedScrap.size())
|
||||
if (live.size() != m_selectedDebris.size())
|
||||
{
|
||||
m_selectedScrap = std::move(live);
|
||||
m_selectedDebris = std::move(live);
|
||||
EventManager::getInstance()->sendEventImmediately(
|
||||
std::make_shared<ScrapSelectionChangedEvent>(m_selectedScrap));
|
||||
std::make_shared<DebrisSelectionChangedEvent>(m_selectedDebris));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1510,16 +1510,16 @@ void GameWorldView::drawSelectionHighlights(QPainter& painter)
|
||||
painter.drawRect(rect->adjusted(-1, -1, 1, 1));
|
||||
}
|
||||
|
||||
// A ring around each selected scrap pile, sitting just outside the pile's
|
||||
// rendered circle (radius getTilePx()*0.2, matching drawScrap) (REQ-UI-SCRAP-CLICK-SELECT).
|
||||
if (!m_selectedScrap.empty())
|
||||
// A ring around each selected piece of debris, sitting just outside the debris's
|
||||
// rendered circle (radius getTilePx()*0.2, matching drawDebris) (REQ-UI-DEBRIS-CLICK-SELECT).
|
||||
if (!m_selectedDebris.empty())
|
||||
{
|
||||
const qreal outlineRadius = static_cast<qreal>(getTilePx() * 0.2f) + 3.0;
|
||||
for (const ScrapInfo& scrap : m_sim->getScraps().getAllScrapInfo())
|
||||
for (const DebrisInfo& debris : m_sim->getDebrisSystem().getAllDebrisInfo())
|
||||
{
|
||||
if (std::find(m_selectedScrap.begin(), m_selectedScrap.end(), scrap.entity)
|
||||
== m_selectedScrap.end()) { continue; }
|
||||
painter.drawEllipse(worldToWidget(scrap.position), outlineRadius, outlineRadius);
|
||||
if (std::find(m_selectedDebris.begin(), m_selectedDebris.end(), debris.entity)
|
||||
== m_selectedDebris.end()) { continue; }
|
||||
painter.drawEllipse(worldToWidget(debris.position), outlineRadius, outlineRadius);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1646,12 +1646,12 @@ void GameWorldView::drawBeltItems(QPainter& painter)
|
||||
});
|
||||
}
|
||||
|
||||
void GameWorldView::drawScrap(QPainter& painter)
|
||||
void GameWorldView::drawDebris(QPainter& painter)
|
||||
{
|
||||
const float r = getTilePx() * 0.2f;
|
||||
for (const ScrapInfo& scrap : m_sim->getScraps().getAllScrapInfo())
|
||||
for (const DebrisInfo& debris : m_sim->getDebrisSystem().getAllDebrisInfo())
|
||||
{
|
||||
const QPointF center = worldToWidget(scrap.position);
|
||||
const QPointF center = worldToWidget(debris.position);
|
||||
painter.setBrush(QColor(128, 110, 90));
|
||||
painter.setPen(QPen(QColor(50, 40, 30), 1));
|
||||
painter.drawEllipse(center,
|
||||
@@ -1838,9 +1838,9 @@ void GameWorldView::drawDebugTargetLines(QPainter& painter)
|
||||
[&](entt::entity /*e*/, const ShipIdentityComponent& si,
|
||||
const PositionComponent& pos, const SalvageScrapBehavior& salvage)
|
||||
{
|
||||
if (!salvage.scrapTarget.has_value()) { return; }
|
||||
if (!salvage.debrisTarget.has_value()) { return; }
|
||||
|
||||
drawTargetLine(si.schematicId, pos.value, *salvage.scrapTarget);
|
||||
drawTargetLine(si.schematicId, pos.value, *salvage.debrisTarget);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2567,7 +2567,7 @@ void GameWorldView::mousePressEvent(QMouseEvent* event)
|
||||
const bool ctrl = (event->modifiers() & Qt::ControlModifier) != 0;
|
||||
const QVector2D worldPos = widgetToWorld(event->pos());
|
||||
|
||||
// Point hit-test precedence: buildings win over actors, which win over scrap
|
||||
// Point hit-test precedence: buildings win over actors, which win over debris
|
||||
// (REQ-UI-SELECTION-CATEGORIES).
|
||||
std::optional<BuildingId> buildingHit = buildingAtTile(tile);
|
||||
if (!buildingHit.has_value()) { buildingHit = siteAtTile(tile); }
|
||||
@@ -2576,9 +2576,9 @@ void GameWorldView::mousePressEvent(QMouseEvent* event)
|
||||
{
|
||||
const BuildingId id = *buildingHit;
|
||||
// A building selection is exclusive: it clears any field selection —
|
||||
// actors and scrap — because buildings win (REQ-UI-SELECTION-CATEGORIES).
|
||||
// actors and debris — because buildings win (REQ-UI-SELECTION-CATEGORIES).
|
||||
clearEntitySelection();
|
||||
clearScrapSelection();
|
||||
clearDebrisSelection();
|
||||
if (ctrl)
|
||||
{
|
||||
bool found = false;
|
||||
@@ -2600,8 +2600,8 @@ void GameWorldView::mousePressEvent(QMouseEvent* event)
|
||||
return;
|
||||
}
|
||||
|
||||
// Selecting a field object (actor or scrap) clears any building selection but
|
||||
// lets actors and scrap coexist (REQ-UI-SELECTION-CATEGORIES).
|
||||
// Selecting a field object (actor or debris) clears any building selection but
|
||||
// lets actors and debris coexist (REQ-UI-SELECTION-CATEGORIES).
|
||||
const entt::entity actorHit = entityAtWorldPos(m_sim->getAdmin(), worldPos);
|
||||
if (actorHit != entt::null)
|
||||
{
|
||||
@@ -2613,7 +2613,7 @@ void GameWorldView::mousePressEvent(QMouseEvent* event)
|
||||
}
|
||||
if (ctrl)
|
||||
{
|
||||
// Toggle this actor within the field selection, leaving scrap intact
|
||||
// Toggle this actor within the field selection, leaving debris intact
|
||||
// (REQ-UI-ENTITY-CLICK-SELECT).
|
||||
bool found = false;
|
||||
std::vector<entt::entity> newSel;
|
||||
@@ -2629,15 +2629,15 @@ void GameWorldView::mousePressEvent(QMouseEvent* event)
|
||||
{
|
||||
// A plain click makes this actor the sole selection.
|
||||
m_selectedEntities = { actorHit };
|
||||
clearScrapSelection();
|
||||
clearDebrisSelection();
|
||||
}
|
||||
EventManager::getInstance()->sendEventImmediately(
|
||||
std::make_shared<EntitySelectionChangedEvent>(m_selectedEntities));
|
||||
return;
|
||||
}
|
||||
|
||||
if (const entt::entity scrapHit =
|
||||
scrapAtWorldPos(m_sim->getAdmin(), worldPos); scrapHit != entt::null)
|
||||
if (const entt::entity debrisHit =
|
||||
debrisAtWorldPos(m_sim->getAdmin(), worldPos); debrisHit != entt::null)
|
||||
{
|
||||
if (!m_selectedBuildingIds.empty())
|
||||
{
|
||||
@@ -2647,26 +2647,26 @@ void GameWorldView::mousePressEvent(QMouseEvent* event)
|
||||
}
|
||||
if (ctrl)
|
||||
{
|
||||
// Toggle this pile within the field selection, leaving actors intact
|
||||
// (REQ-UI-SCRAP-MULTI-SELECT).
|
||||
// Toggle this debris within the field selection, leaving actors intact
|
||||
// (REQ-UI-DEBRIS-MULTI-SELECT).
|
||||
bool found = false;
|
||||
std::vector<entt::entity> newSel;
|
||||
for (entt::entity sel : m_selectedScrap)
|
||||
for (entt::entity sel : m_selectedDebris)
|
||||
{
|
||||
if (sel == scrapHit) { found = true; }
|
||||
if (sel == debrisHit) { found = true; }
|
||||
else { newSel.push_back(sel); }
|
||||
}
|
||||
if (!found) { newSel.push_back(scrapHit); }
|
||||
m_selectedScrap = newSel;
|
||||
if (!found) { newSel.push_back(debrisHit); }
|
||||
m_selectedDebris = newSel;
|
||||
}
|
||||
else
|
||||
{
|
||||
// A plain click makes this pile the sole selection.
|
||||
m_selectedScrap = { scrapHit };
|
||||
// A plain click makes this debris the sole selection.
|
||||
m_selectedDebris = { debrisHit };
|
||||
clearEntitySelection();
|
||||
}
|
||||
EventManager::getInstance()->sendEventImmediately(
|
||||
std::make_shared<ScrapSelectionChangedEvent>(m_selectedScrap));
|
||||
std::make_shared<DebrisSelectionChangedEvent>(m_selectedDebris));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2681,7 +2681,7 @@ void GameWorldView::mousePressEvent(QMouseEvent* event)
|
||||
std::make_shared<SelectionChangedEvent>(m_selectedBuildingIds));
|
||||
}
|
||||
clearEntitySelection();
|
||||
clearScrapSelection();
|
||||
clearDebrisSelection();
|
||||
}
|
||||
m_boxSelecting = true;
|
||||
m_boxStartTile = tile;
|
||||
@@ -2815,9 +2815,9 @@ void GameWorldView::mouseReleaseEvent(QMouseEvent* event)
|
||||
if (!boxIds.empty())
|
||||
{
|
||||
// A box covering any building selects buildings; field objects (actors and
|
||||
// scrap) in the box are ignored — buildings win (REQ-UI-MULTI-SELECT).
|
||||
// debris) in the box are ignored — buildings win (REQ-UI-MULTI-SELECT).
|
||||
clearEntitySelection();
|
||||
clearScrapSelection();
|
||||
clearDebrisSelection();
|
||||
if (!ctrl)
|
||||
{
|
||||
m_selectedBuildingIds = boxIds;
|
||||
@@ -2840,12 +2840,12 @@ void GameWorldView::mouseReleaseEvent(QMouseEvent* event)
|
||||
}
|
||||
|
||||
// No buildings in the box: select the field objects it covers — ships, defence
|
||||
// stations, and scrap together (REQ-UI-MULTI-SELECT, REQ-UI-SCRAP-MULTI-SELECT).
|
||||
// stations, and debris together (REQ-UI-MULTI-SELECT, REQ-UI-DEBRIS-MULTI-SELECT).
|
||||
const std::vector<entt::entity> boxActors =
|
||||
actorsInBox(m_sim->getAdmin(), m_boxStartTile, m_boxCurrentTile);
|
||||
const std::vector<entt::entity> boxScrap =
|
||||
scrapInBox(m_sim->getAdmin(), m_boxStartTile, m_boxCurrentTile);
|
||||
if (!boxActors.empty() || !boxScrap.empty())
|
||||
const std::vector<entt::entity> boxDebris =
|
||||
debrisInBox(m_sim->getAdmin(), m_boxStartTile, m_boxCurrentTile);
|
||||
if (!boxActors.empty() || !boxDebris.empty())
|
||||
{
|
||||
if (!m_selectedBuildingIds.empty())
|
||||
{
|
||||
@@ -2856,7 +2856,7 @@ void GameWorldView::mouseReleaseEvent(QMouseEvent* event)
|
||||
if (!ctrl)
|
||||
{
|
||||
m_selectedEntities = boxActors;
|
||||
m_selectedScrap = boxScrap;
|
||||
m_selectedDebris = boxDebris;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2869,20 +2869,20 @@ void GameWorldView::mouseReleaseEvent(QMouseEvent* event)
|
||||
}
|
||||
if (!found) { m_selectedEntities.push_back(e); }
|
||||
}
|
||||
for (entt::entity e : boxScrap)
|
||||
for (entt::entity e : boxDebris)
|
||||
{
|
||||
bool found = false;
|
||||
for (entt::entity sel : m_selectedScrap)
|
||||
for (entt::entity sel : m_selectedDebris)
|
||||
{
|
||||
if (sel == e) { found = true; break; }
|
||||
}
|
||||
if (!found) { m_selectedScrap.push_back(e); }
|
||||
if (!found) { m_selectedDebris.push_back(e); }
|
||||
}
|
||||
}
|
||||
EventManager::getInstance()->sendEventImmediately(
|
||||
std::make_shared<EntitySelectionChangedEvent>(m_selectedEntities));
|
||||
EventManager::getInstance()->sendEventImmediately(
|
||||
std::make_shared<ScrapSelectionChangedEvent>(m_selectedScrap));
|
||||
std::make_shared<DebrisSelectionChangedEvent>(m_selectedDebris));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2893,7 +2893,7 @@ void GameWorldView::mouseReleaseEvent(QMouseEvent* event)
|
||||
EventManager::getInstance()->sendEventImmediately(
|
||||
std::make_shared<SelectionChangedEvent>(m_selectedBuildingIds));
|
||||
clearEntitySelection();
|
||||
clearScrapSelection();
|
||||
clearDebrisSelection();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3115,7 +3115,7 @@ void GameWorldView::resetForNewGame()
|
||||
std::make_shared<DeconstructModeChangedEvent>(false));
|
||||
m_selectedBuildingIds.clear();
|
||||
clearEntitySelection();
|
||||
clearScrapSelection();
|
||||
clearDebrisSelection();
|
||||
m_copiedConfig = std::nullopt;
|
||||
m_copyConfigFlashes.clear();
|
||||
m_boxSelecting = false;
|
||||
@@ -3151,7 +3151,7 @@ void GameWorldView::handleEvent(std::shared_ptr<const BeamFiredEvent> event)
|
||||
{
|
||||
// Endpoint offset is a fraction of the target's visual size (REQ-SHP-FIRING-BEAM):
|
||||
// half a ship's rendered radius, half a station's shorter footprint side, or
|
||||
// half a scrap pile's rendered radius (scrap is drawn at getTilePx()*0.2).
|
||||
// half a piece of debris's rendered radius (debris is drawn at getTilePx()*0.2).
|
||||
float maxRadius = 0.125f;
|
||||
if (m_sim->getAdmin().isValid(event->target)
|
||||
&& m_sim->getAdmin().hasAll<StationBodyComponent>(event->target))
|
||||
@@ -3161,7 +3161,7 @@ void GameWorldView::handleEvent(std::shared_ptr<const BeamFiredEvent> event)
|
||||
maxRadius = shorter / 2.0f;
|
||||
}
|
||||
else if (m_sim->getAdmin().isValid(event->target)
|
||||
&& m_sim->getAdmin().hasAll<ScrapDataComponent>(event->target))
|
||||
&& m_sim->getAdmin().hasAll<DebrisComponent>(event->target))
|
||||
{
|
||||
maxRadius = 0.1f;
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ private:
|
||||
void drawCopyConfigFeedback(QPainter& painter);
|
||||
void drawStations(QPainter& painter);
|
||||
void drawBeltItems(QPainter& painter);
|
||||
void drawScrap(QPainter& painter);
|
||||
void drawDebris(QPainter& painter);
|
||||
void drawShips(QPainter& painter);
|
||||
void drawHpBar(QPainter& painter, qreal left, qreal top, qreal width,
|
||||
float fraction, bool isEnemy);
|
||||
@@ -206,13 +206,13 @@ private:
|
||||
void placeBlueprintAtTile(QPoint center);
|
||||
|
||||
std::optional<QVector2D> entityPosition(entt::entity entity) const;
|
||||
// Clears the scrap selection, emitting an empty ScrapSelectionChangedEvent when
|
||||
// it was non-empty (REQ-UI-SCRAP-CLICK-SELECT). Used when another selection
|
||||
// Clears the debris selection, emitting an empty DebrisSelectionChangedEvent when
|
||||
// it was non-empty (REQ-UI-DEBRIS-CLICK-SELECT). Used when another selection
|
||||
// category takes over.
|
||||
void clearScrapSelection();
|
||||
// Drops despawned or fully-collected piles from the scrap selection and re-emits
|
||||
// when it changed (REQ-UI-SCRAP-CLICK-SELECT). Called each frame from onFrame().
|
||||
void pruneDespawnedScrap();
|
||||
void clearDebrisSelection();
|
||||
// Drops despawned or fully-collected debris from the selection and re-emits
|
||||
// when it changed (REQ-UI-DEBRIS-CLICK-SELECT). Called each frame from onFrame().
|
||||
void pruneDespawnedDebris();
|
||||
// Clears the actor selection, emitting an empty EntitySelectionChangedEvent when it was
|
||||
// non-empty (REQ-UI-ENTITY-CLICK-SELECT). Used when buildings take over.
|
||||
void clearEntitySelection();
|
||||
@@ -361,7 +361,7 @@ private:
|
||||
|
||||
std::vector<BuildingId> m_selectedBuildingIds;
|
||||
std::vector<entt::entity> m_selectedEntities;
|
||||
std::vector<entt::entity> m_selectedScrap;
|
||||
std::vector<entt::entity> m_selectedDebris;
|
||||
bool m_boxSelecting;
|
||||
QPoint m_boxStartTile;
|
||||
QPoint m_boxCurrentTile;
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#include "RecipeSelectionDialog.h"
|
||||
#include "RecipeSelectionRequestedEvent.h"
|
||||
#include "Rotation.h"
|
||||
#include "ScrapSystem.h"
|
||||
#include "DebrisSystem.h"
|
||||
#include "ShipLayoutPreview.h"
|
||||
#include "Simulation.h"
|
||||
#include "WeaponComponent.h"
|
||||
@@ -225,7 +225,7 @@ void SelectedBuildingPanel::onSelectionChanged(const std::vector<BuildingId>& id
|
||||
// A building selection is exclusive: it supersedes any field selection —
|
||||
// actors and scrap (REQ-UI-SELECTION-CATEGORIES).
|
||||
clearEntityDisplay();
|
||||
m_selectedScrap.clear();
|
||||
m_selectedDebris.clear();
|
||||
m_scrapLabel->hide();
|
||||
}
|
||||
rebuild();
|
||||
@@ -667,19 +667,19 @@ void SelectedBuildingPanel::handleEvent(
|
||||
|
||||
void SelectedBuildingPanel::refreshSelectionDisplay(RefreshReason reason)
|
||||
{
|
||||
if (!m_selectedEntities.empty() || !m_selectedScrap.empty())
|
||||
if (!m_selectedEntities.empty() || !m_selectedDebris.empty())
|
||||
{
|
||||
// Field selection. Keep the live values current: the single-actor stats panel,
|
||||
// the standalone scrap total, or the count summary (whose scrap line shrinks as
|
||||
// piles are collected) — matching the layout chosen by buildFieldSelection()
|
||||
// (REQ-UI-SHIP-STATS-PANEL, REQ-UI-SCRAP-PANEL).
|
||||
if (m_selectedEntities.size() == 1 && m_selectedScrap.empty())
|
||||
// the single-debris stats panel (whose Scrap row shrinks as it is collected), or
|
||||
// the count summary (whose Scrap line shrinks likewise) — matching the layout
|
||||
// chosen by buildFieldSelection() (REQ-UI-SHIP-STATS-PANEL, REQ-UI-DEBRIS-PANEL).
|
||||
if (m_selectedEntities.size() == 1 && m_selectedDebris.empty())
|
||||
{
|
||||
refreshEntityStats();
|
||||
}
|
||||
else if (m_selectedEntities.empty())
|
||||
else if (m_selectedEntities.empty() && m_selectedDebris.size() == 1)
|
||||
{
|
||||
refreshScrapTotal();
|
||||
buildDebrisSingle();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -936,7 +936,7 @@ void SelectedBuildingPanel::handleEvent(std::shared_ptr<const EntitySelectionCha
|
||||
|
||||
void SelectedBuildingPanel::buildFieldSelection()
|
||||
{
|
||||
if (m_selectedEntities.empty() && m_selectedScrap.empty())
|
||||
if (m_selectedEntities.empty() && m_selectedDebris.empty())
|
||||
{
|
||||
// Nothing in the field category. Fall back to empty unless buildings own the panel.
|
||||
clearEntityDisplay();
|
||||
@@ -953,10 +953,11 @@ void SelectedBuildingPanel::buildFieldSelection()
|
||||
|
||||
EntityAdmin& admin = m_sim->getAdmin();
|
||||
|
||||
// Full single-actor stats are shown only for a lone actor with no scrap. As soon as
|
||||
// the selection holds more than one object (multiple actors, or an actor plus scrap),
|
||||
// the panel switches to the compact count summary (REQ-UI-FIELD-MULTI-SELECTION).
|
||||
if (m_selectedEntities.size() == 1 && m_selectedScrap.empty())
|
||||
// A full single-object stats panel is shown only for a lone field object: one actor
|
||||
// with no debris, or one piece of debris with no actors. As soon as the selection holds
|
||||
// more than one object (multiple actors, multiple debris, or actors plus debris), the
|
||||
// panel switches to the compact count summary (REQ-UI-FIELD-MULTI-SELECTION).
|
||||
if (m_selectedEntities.size() == 1 && m_selectedDebris.empty())
|
||||
{
|
||||
m_entitySummaryLabel->hide();
|
||||
m_scrapLabel->hide();
|
||||
@@ -978,25 +979,36 @@ void SelectedBuildingPanel::buildFieldSelection()
|
||||
return;
|
||||
}
|
||||
|
||||
m_entityTitleLabel->hide();
|
||||
m_entityStatsPanel->hide();
|
||||
m_stationStatsLabel->hide();
|
||||
|
||||
if (m_selectedEntities.empty())
|
||||
if (m_selectedEntities.empty() && m_selectedDebris.size() == 1)
|
||||
{
|
||||
// Scrap only: a single "Scrap: N" line.
|
||||
// Single piece of debris: a "Debris" heading plus a "Scrap" stat row, styled like
|
||||
// the ship/station stats panels (REQ-UI-DEBRIS-PANEL).
|
||||
m_entitySummaryLabel->hide();
|
||||
refreshScrapTotal();
|
||||
m_scrapLabel->show();
|
||||
m_entityStatsPanel->hide();
|
||||
m_stationStatsLabel->hide();
|
||||
buildDebrisSingle();
|
||||
return;
|
||||
}
|
||||
|
||||
// Actor counts, with the scrap total appended into the same label so every line
|
||||
// shares the same spacing.
|
||||
// More than one field object: a compact count summary. buildEntitySummary() appends the
|
||||
// "Debris x N" and "Scrap x N" lines when debris is part of the selection.
|
||||
m_entityTitleLabel->hide();
|
||||
m_entityStatsPanel->hide();
|
||||
m_stationStatsLabel->hide();
|
||||
m_scrapLabel->hide();
|
||||
buildEntitySummary();
|
||||
}
|
||||
|
||||
void SelectedBuildingPanel::buildDebrisSingle()
|
||||
{
|
||||
// "Debris" heading + a single "Scrap" stat row for the piece's remaining amount,
|
||||
// mirroring the single-actor stats panels (REQ-UI-DEBRIS-PANEL).
|
||||
m_entityTitleLabel->setText(tr("Debris"));
|
||||
m_entityTitleLabel->show();
|
||||
m_scrapLabel->setText(tr("Scrap: %1").arg(selectedDebrisScrapTotal()));
|
||||
m_scrapLabel->show();
|
||||
}
|
||||
|
||||
void SelectedBuildingPanel::buildEntitySummary()
|
||||
{
|
||||
EntityAdmin& admin = m_sim->getAdmin();
|
||||
@@ -1042,16 +1054,18 @@ void SelectedBuildingPanel::buildEntitySummary()
|
||||
}
|
||||
|
||||
// One "<type> x <count>" line per group (matching the recipe tooltip and the building
|
||||
// multi-selection). No total-count header, consistent with the building panel. The
|
||||
// scrap total, when present, is appended as another line in the same label so the
|
||||
// line spacing is uniform (REQ-UI-FIELD-MULTI-SELECTION, REQ-UI-SCRAP-PANEL).
|
||||
// multi-selection). No total-count header, consistent with the building panel. When
|
||||
// debris is part of the selection, a "Debris x <count>" line followed by a
|
||||
// "Scrap x <total>" line are appended into the same label so the line spacing is
|
||||
// uniform (REQ-UI-FIELD-MULTI-SELECTION, REQ-UI-DEBRIS-PANEL).
|
||||
QStringList lines;
|
||||
for (const QString& key : keys)
|
||||
{
|
||||
lines << tr("%1 x %2").arg(labels[key]).arg(counts[key]);
|
||||
}
|
||||
if (!m_selectedScrap.empty())
|
||||
if (!m_selectedDebris.empty())
|
||||
{
|
||||
lines << tr("Debris x %1").arg(static_cast<int>(m_selectedDebris.size()));
|
||||
lines << scrapTotalText();
|
||||
}
|
||||
m_entitySummaryLabel->setText(lines.join('\n'));
|
||||
@@ -1173,36 +1187,36 @@ void SelectedBuildingPanel::handleEvent(std::shared_ptr<const SelectionChangedEv
|
||||
}
|
||||
|
||||
void SelectedBuildingPanel::handleEvent(
|
||||
std::shared_ptr<const ScrapSelectionChangedEvent> event)
|
||||
std::shared_ptr<const DebrisSelectionChangedEvent> event)
|
||||
{
|
||||
m_selectedScrap = event->scrap;
|
||||
if (!m_selectedScrap.empty())
|
||||
m_selectedDebris = event->debris;
|
||||
if (!m_selectedDebris.empty())
|
||||
{
|
||||
// Scrap is a field object: it supersedes any building selection but coexists
|
||||
// Debris is a field object: it supersedes any building selection but coexists
|
||||
// with actors (REQ-UI-SELECTION-CATEGORIES).
|
||||
m_selectedBuildingIds.clear();
|
||||
}
|
||||
buildFieldSelection();
|
||||
}
|
||||
|
||||
QString SelectedBuildingPanel::scrapTotalText() const
|
||||
int SelectedBuildingPanel::selectedDebrisScrapTotal() const
|
||||
{
|
||||
// Sum the remaining amounts of the still-living selected piles (REQ-UI-SCRAP-PANEL).
|
||||
// Sum the remaining scrap across the still-living selected debris (REQ-UI-DEBRIS-PANEL).
|
||||
int total = 0;
|
||||
for (const ScrapInfo& info : m_sim->getScraps().getAllScrapInfo())
|
||||
for (const DebrisInfo& info : m_sim->getDebrisSystem().getAllDebrisInfo())
|
||||
{
|
||||
if (std::find(m_selectedScrap.begin(), m_selectedScrap.end(), info.entity)
|
||||
!= m_selectedScrap.end())
|
||||
if (std::find(m_selectedDebris.begin(), m_selectedDebris.end(), info.entity)
|
||||
!= m_selectedDebris.end())
|
||||
{
|
||||
total += info.amount;
|
||||
}
|
||||
}
|
||||
return tr("Scrap x %1").arg(total);
|
||||
return total;
|
||||
}
|
||||
|
||||
void SelectedBuildingPanel::refreshScrapTotal()
|
||||
QString SelectedBuildingPanel::scrapTotalText() const
|
||||
{
|
||||
m_scrapLabel->setText(scrapTotalText());
|
||||
return tr("Scrap x %1").arg(selectedDebrisScrapTotal());
|
||||
}
|
||||
|
||||
void SelectedBuildingPanel::handleEvent(std::shared_ptr<const DebugDrawToggledEvent> event)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include "GameConfig.h"
|
||||
#include "PlayerCommandsAppliedEvent.h"
|
||||
#include "RecipesConfig.h"
|
||||
#include "ScrapSelectionChangedEvent.h"
|
||||
#include "DebrisSelectionChangedEvent.h"
|
||||
#include "SelectionChangedEvent.h"
|
||||
#include "ShipLayout.h"
|
||||
#include "ShipsConfig.h"
|
||||
@@ -38,7 +38,7 @@ class SelectedBuildingPanel : public QWidget,
|
||||
PlayerCommandsAppliedEvent,
|
||||
EntitySelectionChangedEvent,
|
||||
SelectionChangedEvent,
|
||||
ScrapSelectionChangedEvent,
|
||||
DebrisSelectionChangedEvent,
|
||||
DebugDrawToggledEvent>
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -53,7 +53,7 @@ private:
|
||||
void handleEvent(std::shared_ptr<const PlayerCommandsAppliedEvent> event) override;
|
||||
void handleEvent(std::shared_ptr<const EntitySelectionChangedEvent> event) override;
|
||||
void handleEvent(std::shared_ptr<const SelectionChangedEvent> event) override;
|
||||
void handleEvent(std::shared_ptr<const ScrapSelectionChangedEvent> event) override;
|
||||
void handleEvent(std::shared_ptr<const DebrisSelectionChangedEvent> event) override;
|
||||
void handleEvent(std::shared_ptr<const DebugDrawToggledEvent> event) override;
|
||||
|
||||
private slots:
|
||||
@@ -80,8 +80,9 @@ private:
|
||||
void buildEmpty();
|
||||
void buildSingle(BuildingId id);
|
||||
void buildMulti(const std::vector<BuildingId>& ids);
|
||||
void refreshScrapTotal();
|
||||
// "Scrap: N" for the summed remaining amount of the selected piles (REQ-UI-SCRAP-PANEL).
|
||||
// Summed remaining scrap across the selected debris (REQ-UI-DEBRIS-PANEL).
|
||||
int selectedDebrisScrapTotal() const;
|
||||
// "Scrap x N" line for the multi-object summary (REQ-UI-FIELD-MULTI-SELECTION).
|
||||
QString scrapTotalText() const;
|
||||
void refreshBuffers(const Building* b);
|
||||
void refreshSiteProgress(const ConstructionSite* s);
|
||||
@@ -117,23 +118,26 @@ private:
|
||||
|
||||
bool m_debugDraw = false;
|
||||
// The selected ships/defence stations. Shares the "field" selection category with
|
||||
// scrap (m_selectedScrap): both can be non-empty at once (REQ-UI-SELECTION-CATEGORIES).
|
||||
// debris (m_selectedDebris): both can be non-empty at once (REQ-UI-SELECTION-CATEGORIES).
|
||||
std::vector<entt::entity> m_selectedEntities;
|
||||
ShipStatsPanel* m_entityStatsPanel;
|
||||
QLabel* m_entityTitleLabel;
|
||||
QLabel* m_stationStatsLabel;
|
||||
QLabel* m_entitySummaryLabel;
|
||||
|
||||
std::vector<entt::entity> m_selectedScrap;
|
||||
std::vector<entt::entity> m_selectedDebris;
|
||||
// Shows the debris "Scrap" stat row (single selection) — the scrap total for the
|
||||
// multi-object summary lives in m_entitySummaryLabel instead.
|
||||
QLabel* m_scrapLabel;
|
||||
|
||||
// Renders the combined field selection (actors + scrap): a single-actor stats panel
|
||||
// or a multi-actor summary, plus the scrap total when scrap is also selected
|
||||
// (REQ-UI-FIELD-MULTI-SELECTION).
|
||||
// Renders the combined field selection (actors + debris): a single-object stats panel
|
||||
// (ship, station, or debris) or a multi-object count summary that appends the debris
|
||||
// count and scrap total when debris is also selected (REQ-UI-FIELD-MULTI-SELECTION).
|
||||
void buildFieldSelection();
|
||||
void buildEntityShip(entt::entity entity);
|
||||
void buildEntityStation(entt::entity entity);
|
||||
void buildEntitySummary();
|
||||
void buildDebrisSingle();
|
||||
void refreshEntityStats();
|
||||
void clearEntityDisplay();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user