Implement REQ-UI-SHIP-BEHAVIOR: show selected ship's current behavior
Add a live behavior label to the ship stats panel that names the ship's top-priority behavior (Retreating/Engaging/Salvaging/Repairing/Rallying/ Standby/Advancing) as resolved by the AiSystem selection pass. Wired into both the in-game selected building panel and the balancing InspectWindow, for player and enemy ships. The label is hidden in the static design preview. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DZR44tA8sn4dPqDzAVXyps
This commit is contained in:
@@ -14,6 +14,7 @@
|
|||||||
#include "HealthComponent.h"
|
#include "HealthComponent.h"
|
||||||
#include "InspectWindowClosedEvent.h"
|
#include "InspectWindowClosedEvent.h"
|
||||||
#include "ModuleOwnerComponent.h"
|
#include "ModuleOwnerComponent.h"
|
||||||
|
#include "SelectedBehaviorComponent.h"
|
||||||
#include "ShipIdentityComponent.h"
|
#include "ShipIdentityComponent.h"
|
||||||
#include "ShipStatsCalculator.h"
|
#include "ShipStatsCalculator.h"
|
||||||
#include "ShipStatsPanel.h"
|
#include "ShipStatsPanel.h"
|
||||||
@@ -278,6 +279,8 @@ void InspectWindow::handleEvent(std::shared_ptr<const EntitySelectedEvent> event
|
|||||||
|
|
||||||
const ShipStats stats = buildShipStatsFromEntity(admin, entity);
|
const ShipStats stats = buildShipStatsFromEntity(admin, entity);
|
||||||
m_entityStatsPanel->refreshFromLive(stats, health.hp);
|
m_entityStatsPanel->refreshFromLive(stats, health.hp);
|
||||||
|
m_entityStatsPanel->setBehavior(
|
||||||
|
admin.get<SelectedBehaviorComponent>(entity).winner);
|
||||||
m_entityStatsPanel->show();
|
m_entityStatsPanel->show();
|
||||||
m_stationStatsLabel->hide();
|
m_stationStatsLabel->hide();
|
||||||
}
|
}
|
||||||
@@ -355,6 +358,8 @@ void InspectWindow::refreshEntityStats()
|
|||||||
{
|
{
|
||||||
const ShipStats stats = buildShipStatsFromEntity(admin, entity);
|
const ShipStats stats = buildShipStatsFromEntity(admin, entity);
|
||||||
m_entityStatsPanel->refreshFromLive(stats, health.hp);
|
m_entityStatsPanel->refreshFromLive(stats, health.hp);
|
||||||
|
m_entityStatsPanel->setBehavior(
|
||||||
|
admin.get<SelectedBehaviorComponent>(entity).winner);
|
||||||
}
|
}
|
||||||
else if (admin.hasAll<StationBodyComponent>(entity))
|
else if (admin.hasAll<StationBodyComponent>(entity))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "FactionComponent.h"
|
#include "FactionComponent.h"
|
||||||
#include "HealthComponent.h"
|
#include "HealthComponent.h"
|
||||||
#include "ModuleOwnerComponent.h"
|
#include "ModuleOwnerComponent.h"
|
||||||
|
#include "SelectedBehaviorComponent.h"
|
||||||
#include "ShipIdentityComponent.h"
|
#include "ShipIdentityComponent.h"
|
||||||
#include "ShipStatsCalculator.h"
|
#include "ShipStatsCalculator.h"
|
||||||
#include "ShipStatsPanel.h"
|
#include "ShipStatsPanel.h"
|
||||||
@@ -948,6 +949,8 @@ void SelectedBuildingPanel::buildEntityShip(entt::entity entity)
|
|||||||
|
|
||||||
const ShipStats stats = buildShipStatsFromEntity(admin, entity);
|
const ShipStats stats = buildShipStatsFromEntity(admin, entity);
|
||||||
m_entityStatsPanel->refreshFromLive(stats, health.hp);
|
m_entityStatsPanel->refreshFromLive(stats, health.hp);
|
||||||
|
m_entityStatsPanel->setBehavior(
|
||||||
|
admin.get<SelectedBehaviorComponent>(entity).winner);
|
||||||
m_entityStatsPanel->setDebugDrawEnabled(m_debugDraw);
|
m_entityStatsPanel->setDebugDrawEnabled(m_debugDraw);
|
||||||
|
|
||||||
for (const ShipDef& def : m_config->ships.ships)
|
for (const ShipDef& def : m_config->ships.ships)
|
||||||
@@ -1027,6 +1030,8 @@ void SelectedBuildingPanel::refreshEntityStats()
|
|||||||
{
|
{
|
||||||
const ShipStats stats = buildShipStatsFromEntity(admin, entity);
|
const ShipStats stats = buildShipStatsFromEntity(admin, entity);
|
||||||
m_entityStatsPanel->refreshFromLive(stats, health.hp);
|
m_entityStatsPanel->refreshFromLive(stats, health.hp);
|
||||||
|
m_entityStatsPanel->setBehavior(
|
||||||
|
admin.get<SelectedBehaviorComponent>(entity).winner);
|
||||||
}
|
}
|
||||||
else if (admin.hasAll<StationBodyComponent>(entity))
|
else if (admin.hasAll<StationBodyComponent>(entity))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -42,6 +42,12 @@ ShipStatsPanel::ShipStatsPanel(const GameConfig* config, QWidget* parent)
|
|||||||
layout->setSpacing(2);
|
layout->setSpacing(2);
|
||||||
layout->setAlignment(Qt::AlignTop);
|
layout->setAlignment(Qt::AlignTop);
|
||||||
|
|
||||||
|
// Current behavior — live entities only; hidden in the static design
|
||||||
|
// preview (REQ-UI-SHIP-BEHAVIOR).
|
||||||
|
m_behaviorLabel = makeSectionHeader(QString(), this);
|
||||||
|
m_behaviorLabel->setVisible(false);
|
||||||
|
layout->addWidget(m_behaviorLabel);
|
||||||
|
|
||||||
// Hull stats — always visible.
|
// Hull stats — always visible.
|
||||||
m_hpLabel = makeStatLabel(this);
|
m_hpLabel = makeStatLabel(this);
|
||||||
m_speedLabel = makeStatLabel(this);
|
m_speedLabel = makeStatLabel(this);
|
||||||
@@ -125,6 +131,9 @@ void ShipStatsPanel::refresh(const std::string& shipId,
|
|||||||
const double threat = calculateShipThreatCost(m_config->threatCosts, *m_config,
|
const double threat = calculateShipThreatCost(m_config->threatCosts, *m_config,
|
||||||
shipId, modules);
|
shipId, modules);
|
||||||
setThreatCost(threat);
|
setThreatCost(threat);
|
||||||
|
|
||||||
|
// The static design preview has no live behavior to show.
|
||||||
|
m_behaviorLabel->setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShipStatsPanel::refreshFromLive(const ShipStats& stats, float currentHp)
|
void ShipStatsPanel::refreshFromLive(const ShipStats& stats, float currentHp)
|
||||||
@@ -204,6 +213,32 @@ void ShipStatsPanel::applyStats(const ShipStats& stats, const QString& hpText)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShipStatsPanel::setBehavior(BehaviorKind kind)
|
||||||
|
{
|
||||||
|
QString label;
|
||||||
|
switch (kind)
|
||||||
|
{
|
||||||
|
case BehaviorKind::Retreat: label = tr("Retreating"); break;
|
||||||
|
case BehaviorKind::Attack: label = tr("Engaging"); break;
|
||||||
|
case BehaviorKind::SalvageScrap:
|
||||||
|
case BehaviorKind::DeliverScrap: label = tr("Salvaging"); break;
|
||||||
|
case BehaviorKind::Repair: label = tr("Repairing"); break;
|
||||||
|
case BehaviorKind::Rally: label = tr("Rallying"); break;
|
||||||
|
case BehaviorKind::Standby: label = tr("Standby"); break;
|
||||||
|
case BehaviorKind::Advance: label = tr("Advancing"); break;
|
||||||
|
case BehaviorKind::None: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (label.isEmpty())
|
||||||
|
{
|
||||||
|
m_behaviorLabel->setVisible(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_behaviorLabel->setText(tr("Behavior: %1").arg(label));
|
||||||
|
m_behaviorLabel->setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
void ShipStatsPanel::setThreatCost(double cost)
|
void ShipStatsPanel::setThreatCost(double cost)
|
||||||
{
|
{
|
||||||
m_threatCostLabel->setText(tr("Threat Cost: %1").arg(cost, 0, 'f', 1));
|
m_threatCostLabel->setText(tr("Threat Cost: %1").arg(cost, 0, 'f', 1));
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
|
#include "BehaviorKind.h"
|
||||||
#include "ShipLayout.h"
|
#include "ShipLayout.h"
|
||||||
#include "ShipStatsCalculator.h"
|
#include "ShipStatsCalculator.h"
|
||||||
|
|
||||||
@@ -24,6 +25,9 @@ public:
|
|||||||
|
|
||||||
void refreshFromLive(const ShipStats& stats, float currentHp);
|
void refreshFromLive(const ShipStats& stats, float currentHp);
|
||||||
|
|
||||||
|
// Displays the ship's current top-priority behavior (REQ-UI-SHIP-BEHAVIOR).
|
||||||
|
void setBehavior(BehaviorKind kind);
|
||||||
|
|
||||||
void setThreatCost(double cost);
|
void setThreatCost(double cost);
|
||||||
void setDebugDrawEnabled(bool enabled);
|
void setDebugDrawEnabled(bool enabled);
|
||||||
|
|
||||||
@@ -33,6 +37,7 @@ private:
|
|||||||
const GameConfig* m_config;
|
const GameConfig* m_config;
|
||||||
bool m_debugDraw = false;
|
bool m_debugDraw = false;
|
||||||
|
|
||||||
|
QLabel* m_behaviorLabel;
|
||||||
QLabel* m_hpLabel;
|
QLabel* m_hpLabel;
|
||||||
QLabel* m_speedLabel;
|
QLabel* m_speedLabel;
|
||||||
QLabel* m_sensorRangeLabel;
|
QLabel* m_sensorRangeLabel;
|
||||||
|
|||||||
Reference in New Issue
Block a user