implement beam rendering if shooter or target is already destroyed

This commit is contained in:
2026-04-28 21:01:00 +02:00
parent 9278425d44
commit e0c3217564
4 changed files with 271 additions and 20 deletions

View File

@@ -5,6 +5,8 @@
#include "Ship.h"
#include "ShipSystem.h"
static constexpr Tick kWeaponImpactDelayTicks = 5; // 0.15 s × 30 Hz, rounded to nearest
CombatSystem::CombatSystem(const GameConfig& config)
: m_config(config)
{
@@ -71,15 +73,7 @@ void CombatSystem::resolveShipWeapon(Ship& ship, Tick currentTick,
return;
}
// Apply damage to the correct pool.
if (ships.findShip(targetId))
{
ships.damageShip(targetId, w.damage);
}
else
{
buildings.damageBuilding(targetId, w.damage);
}
m_pendingDamage.push_back({targetId, w.damage, currentTick + kWeaponImpactDelayTicks});
FireEvent evt;
evt.shooter = ship.id;
@@ -153,14 +147,7 @@ void CombatSystem::resolveStationWeapon(Building& station, Tick currentTick,
return;
}
if (ships.findShip(targetId))
{
ships.damageShip(targetId, w.damage);
}
else
{
buildings.damageBuilding(targetId, w.damage);
}
m_pendingDamage.push_back({targetId, w.damage, currentTick + kWeaponImpactDelayTicks});
FireEvent evt;
evt.shooter = station.id;
@@ -203,6 +190,32 @@ std::optional<EntityId> CombatSystem::acquireStationTarget(
return best;
}
void CombatSystem::applyPendingDamage(Tick currentTick,
ShipSystem& ships,
BuildingSystem& buildings)
{
auto it = m_pendingDamage.begin();
while (it != m_pendingDamage.end())
{
if (it->appliesAt <= currentTick)
{
if (ships.findShip(it->target))
{
ships.damageShip(it->target, it->amount);
}
else if (buildings.findBuilding(it->target))
{
buildings.damageBuilding(it->target, it->amount);
}
it = m_pendingDamage.erase(it);
}
else
{
++it;
}
}
}
std::optional<QVector2D> CombatSystem::targetPosition(
EntityId id,
const ShipSystem& ships,

View File

@@ -23,15 +23,28 @@ public:
explicit CombatSystem(const GameConfig& config);
// Advance weapon cooldowns, acquire targets for stations, fire when ready,
// apply damage, and append FireEvents. Damage is applied immediately via
// ShipSystem::damageShip and BuildingSystem::damageBuilding; step 9
// removes entities whose HP dropped to zero or below.
// queue deferred damage, and append FireEvents. Call applyPendingDamage()
// after tick() (step 8b) and before death processing (step 9).
void tick(Tick currentTick,
ShipSystem& ships,
BuildingSystem& buildings,
std::vector<FireEvent>& outFireEvents);
// Apply any queued damage whose impact tick has arrived. Silently drops
// damage if the target no longer exists.
void applyPendingDamage(Tick currentTick,
ShipSystem& ships,
BuildingSystem& buildings);
private:
struct PendingDamage
{
EntityId target;
float amount;
Tick appliesAt;
};
std::vector<PendingDamage> m_pendingDamage;
// Process one ship's weapon for this tick.
void resolveShipWeapon(Ship& ship, Tick currentTick,
ShipSystem& ships,

View File

@@ -159,6 +159,9 @@ void Simulation::tick()
m_combatSystem->tick(m_currentTick, *m_shipSystem,
*m_buildingSystem, m_fireEvents);
// Step 8b: deferred damage whose impact tick has arrived
m_combatSystem->applyPendingDamage(m_currentTick, *m_shipSystem, *m_buildingSystem);
// Step 9: deaths & loot
if (!m_gameOver)
{