change repair_tool application and add beams for salvager and repair_tool

This commit is contained in:
2026-06-18 22:14:09 +02:00
parent 7924e037aa
commit 9573b9789a
37 changed files with 498 additions and 199 deletions

View File

@@ -277,15 +277,16 @@ ArenaStatus ArenaSimulation::status() const
void ArenaSimulation::tick()
{
// Ship behavior systems (tick step 7): evaluate, select winner, execute.
// Module + combat systems emit their tool beams into a shared buffer.
m_shipSystem->clearMovementIntents();
m_aiSystem->tick(m_admin, *m_buildingSystem, *m_scrapSystem);
m_salvagerSystem->tick(*m_scrapSystem, *m_buildingSystem);
m_repairSystem->tick();
std::vector<BeamFiredEvent> beamFiredEvents;
m_salvagerSystem->tick(m_currentTick, *m_scrapSystem, *m_buildingSystem, beamFiredEvents);
m_repairSystem->tick(m_currentTick, beamFiredEvents);
// Combat resolution (tick step 8).
std::vector<WeaponFiredEvent> weaponFiredEvents;
m_combatSystem->tick(m_currentTick, m_admin, *m_buildingSystem, weaponFiredEvents);
m_weaponFiredEvents.insert(m_weaponFiredEvents.end(), weaponFiredEvents.begin(), weaponFiredEvents.end());
m_combatSystem->tick(m_currentTick, m_admin, *m_buildingSystem, beamFiredEvents);
m_beamFiredEvents.insert(m_beamFiredEvents.end(), beamFiredEvents.begin(), beamFiredEvents.end());
m_combatSystem->applyPendingDamage(m_currentTick, m_admin);
// Deaths (tick step 9, simplified).
@@ -417,10 +418,10 @@ void ArenaSimulation::tickOnce()
}
}
std::vector<WeaponFiredEvent> ArenaSimulation::drainWeaponFiredEvents()
std::vector<BeamFiredEvent> ArenaSimulation::drainBeamFiredEvents()
{
std::vector<WeaponFiredEvent> result;
result.swap(m_weaponFiredEvents);
std::vector<BeamFiredEvent> result;
result.swap(m_beamFiredEvents);
return result;
}

View File

@@ -13,7 +13,7 @@
#include "BuildingId.h"
#include "entt/entity/entity.hpp"
#include "WeaponFiredEvent.h"
#include "BeamFiredEvent.h"
#include "GameConfig.h"
#include "Tick.h"
@@ -61,7 +61,7 @@ public:
void requestStop();
void tickOnce();
std::vector<WeaponFiredEvent> drainWeaponFiredEvents();
std::vector<BeamFiredEvent> drainBeamFiredEvents();
ArenaStatus status() const;
bool isFinished() const;
@@ -112,7 +112,7 @@ private:
// Static accumulated threat per team, computed once from the configured roster.
double m_teamThreat[2] = {0.0, 0.0};
std::vector<WeaponFiredEvent> m_weaponFiredEvents;
std::vector<BeamFiredEvent> m_beamFiredEvents;
mutable std::mutex m_statusMutex;
ArenaStatus m_status;

View File

@@ -28,6 +28,7 @@
#include "SensorRangeComponent.h"
#include "ShipIdentityComponent.h"
#include "StationBodyComponent.h"
#include "ScrapDataComponent.h"
namespace
{
@@ -111,11 +112,11 @@ void ArenaView::onFrame()
// Emit fire events via EventManager
{
const std::vector<WeaponFiredEvent> fires = m_sim->drainWeaponFiredEvents();
for (const WeaponFiredEvent& fe : fires)
const std::vector<BeamFiredEvent> fires = m_sim->drainBeamFiredEvents();
for (const BeamFiredEvent& fe : fires)
{
EventManager::getInstance()->sendEventImmediately(
std::make_shared<WeaponFiredEvent>(fe));
std::make_shared<BeamFiredEvent>(fe));
}
}
@@ -140,7 +141,7 @@ void ArenaView::onFrame()
update();
}
void ArenaView::handleEvent(std::shared_ptr<const WeaponFiredEvent> event)
void ArenaView::handleEvent(std::shared_ptr<const BeamFiredEvent> event)
{
float maxRadius = 0.125f;
if (m_sim->admin().isValid(event->target)
@@ -151,6 +152,11 @@ void ArenaView::handleEvent(std::shared_ptr<const WeaponFiredEvent> event)
sb.footprint.height());
maxRadius = shorter / 2.0f;
}
else if (m_sim->admin().isValid(event->target)
&& m_sim->admin().hasAll<ScrapDataComponent>(event->target))
{
maxRadius = 0.1f;
}
std::uniform_real_distribution<float> angleDist(0.0f, 6.28318530f);
std::uniform_real_distribution<float> radiusDist(0.0f, maxRadius);
@@ -526,12 +532,20 @@ void ArenaView::drawDebugTargetLines(QPainter& painter)
void ArenaView::drawBeams(QPainter& painter)
{
painter.setPen(QPen(m_visuals->beams.color, m_visuals->beams.widthPx));
for (const ActiveBeam& beam : m_activeBeams)
{
const std::optional<QVector2D> shooterPos = entityPosition(beam.event.shooter);
const std::optional<QVector2D> targetPos = entityPosition(beam.event.target);
if (!shooterPos.has_value() || !targetPos.has_value()) { continue; }
QColor color = m_visuals->beams.weaponColor;
switch (beam.event.kind)
{
case BeamKind::Weapon: color = m_visuals->beams.weaponColor; break;
case BeamKind::Repair: color = m_visuals->beams.repairColor; break;
case BeamKind::Salvage: color = m_visuals->beams.salvageColor; break;
}
painter.setPen(QPen(color, m_visuals->beams.widthPx));
painter.drawLine(worldToWidget(*shooterPos),
worldToWidget(*targetPos + beam.targetOffset));
}

View File

@@ -10,7 +10,7 @@
#include <QVector2D>
#include "EventHandler.h"
#include "WeaponFiredEvent.h"
#include "BeamFiredEvent.h"
#include "entt/entity/entity.hpp"
#include "EntitySelectedEvent.h"
@@ -22,7 +22,7 @@ class ArenaSimulation;
class QPainter;
class ArenaView : public QOpenGLWidget,
public EventHandler<WeaponFiredEvent>
public EventHandler<BeamFiredEvent>
{
Q_OBJECT
@@ -45,7 +45,7 @@ private slots:
void onFrame();
private:
void handleEvent(std::shared_ptr<const WeaponFiredEvent> event) override;
void handleEvent(std::shared_ptr<const BeamFiredEvent> event) override;
void drawTiles(QPainter& painter);
void drawBuildings(QPainter& painter);
@@ -66,7 +66,7 @@ private:
struct ActiveBeam
{
WeaponFiredEvent event;
BeamFiredEvent event;
qint64 emittedWallMs;
QVector2D targetOffset;
};