unify Weapon and StationWeapon components
This commit is contained in:
@@ -16,147 +16,92 @@ void CombatSystem::tick(Tick currentTick,
|
||||
std::vector<FireEvent>& outFireEvents)
|
||||
{
|
||||
// Ship weapons.
|
||||
admin.forEach<Weapon, ThreatResponse, Position>(
|
||||
[&](entt::entity e, Weapon& weapon, ThreatResponse& threat, Position& pos)
|
||||
admin.forEach<Weapon, ThreatResponse, Position, Faction>(
|
||||
[&](entt::entity e, Weapon& weapon, ThreatResponse& threat, Position& pos, Faction& faction)
|
||||
{
|
||||
resolveShipWeapon(e, weapon, threat, pos, currentTick, admin, outFireEvents);
|
||||
weapon.currentTarget = threat.currentTarget;
|
||||
resolveWeapon(e, weapon, pos, faction, currentTick, admin, outFireEvents);
|
||||
});
|
||||
|
||||
// Station weapons.
|
||||
admin.forEach<StationWeapon, Position, Faction>(
|
||||
[&](entt::entity e, StationWeapon& weapon, Position& pos, Faction& faction)
|
||||
admin.forEach<Weapon, Position, Faction>(
|
||||
[&](entt::entity e, Weapon& weapon, Position& pos, Faction& faction)
|
||||
{
|
||||
resolveStationWeapon(e, weapon, pos, faction, currentTick, admin, outFireEvents);
|
||||
resolveWeapon(e, weapon, pos, faction, currentTick, admin, outFireEvents);
|
||||
});
|
||||
}
|
||||
|
||||
void CombatSystem::resolveShipWeapon(entt::entity shipEntity, Weapon& weapon,
|
||||
const ThreatResponse& threat,
|
||||
const Position& pos, Tick currentTick,
|
||||
EntityAdmin& admin,
|
||||
std::vector<FireEvent>& out)
|
||||
void CombatSystem::resolveWeapon(
|
||||
entt::entity shipEntity,
|
||||
Weapon& weapon,
|
||||
const Position& ownPos,
|
||||
const Faction& ownFaction,
|
||||
Tick currentTick,
|
||||
EntityAdmin& admin,
|
||||
std::vector<FireEvent>& out)
|
||||
{
|
||||
if (!threat.currentTarget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (weapon.cooldownTicks > 0.0f)
|
||||
{
|
||||
weapon.cooldownTicks -= 1.0f;
|
||||
}
|
||||
if (weapon.cooldownTicks > 0.0f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (weapon.cooldownTicks > 0.0f)
|
||||
{
|
||||
weapon.cooldownTicks -= 1.0f;
|
||||
}
|
||||
if (weapon.cooldownTicks > 0.0f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Validate or clear existing target.
|
||||
if (weapon.currentTarget)
|
||||
{
|
||||
const entt::entity t = *weapon.currentTarget;
|
||||
if (!admin.isValid(t) || !admin.hasAll<Position>(t))
|
||||
{
|
||||
weapon.currentTarget = std::nullopt;
|
||||
}
|
||||
else
|
||||
{
|
||||
const float distanceSquared = (ownPos.value - admin.get<Position>(t).value).lengthSquared();
|
||||
if (distanceSquared > weapon.range * weapon.range)
|
||||
{
|
||||
weapon.currentTarget = std::nullopt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const entt::entity targetEntity = *threat.currentTarget;
|
||||
if (!admin.isValid(targetEntity) || !admin.hasAll<Position>(targetEntity))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const QVector2D targetPos = admin.get<Position>(targetEntity).value;
|
||||
const float dist = (pos.value - targetPos).length();
|
||||
if (dist > weapon.range)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_pendingDamage.push_back({targetEntity, weapon.damage,
|
||||
currentTick + kWeaponImpactDelayTicks});
|
||||
|
||||
FireEvent evt;
|
||||
evt.shooter = shipEntity;
|
||||
evt.target = targetEntity;
|
||||
evt.emittedAt = currentTick;
|
||||
out.push_back(evt);
|
||||
|
||||
weapon.cooldownTicks = static_cast<float>(kTickRateHz) / weapon.fireRateHz;
|
||||
}
|
||||
|
||||
void CombatSystem::resolveStationWeapon(entt::entity stationEntity,
|
||||
StationWeapon& weapon,
|
||||
const Position& stationPos,
|
||||
const Faction& stationFaction,
|
||||
Tick currentTick,
|
||||
EntityAdmin& admin,
|
||||
std::vector<FireEvent>& out)
|
||||
{
|
||||
// Validate or clear existing target.
|
||||
if (weapon.currentTarget)
|
||||
{
|
||||
const entt::entity t = *weapon.currentTarget;
|
||||
if (!admin.isValid(t) || !admin.hasAll<Position>(t))
|
||||
{
|
||||
weapon.currentTarget = std::nullopt;
|
||||
}
|
||||
else
|
||||
{
|
||||
const float dist = (stationPos.value - admin.get<Position>(t).value).length();
|
||||
if (dist > weapon.range)
|
||||
{
|
||||
weapon.currentTarget = std::nullopt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Acquire a new target if needed (nearest opposing-faction ship).
|
||||
if (!weapon.currentTarget)
|
||||
{
|
||||
float bestDist = weapon.range;
|
||||
admin.forEach<ShipIdentity, Position, Faction>(
|
||||
[&](entt::entity candidate, const ShipIdentity& /*si*/,
|
||||
const Position& candidatePos, const Faction& candidateFaction)
|
||||
{
|
||||
const bool isValidTarget = stationFaction.isEnemy
|
||||
? !candidateFaction.isEnemy
|
||||
: candidateFaction.isEnemy;
|
||||
if (!isValidTarget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
const float dist = (candidatePos.value - stationPos.value).length();
|
||||
if (dist < bestDist)
|
||||
{
|
||||
bestDist = dist;
|
||||
weapon.currentTarget = candidate;
|
||||
}
|
||||
});
|
||||
}
|
||||
// Acquire a new target if needed (nearest opposing-faction ship).
|
||||
if (!weapon.currentTarget)
|
||||
{
|
||||
float bestDistanceSquared = weapon.range * weapon.range;
|
||||
admin.forEach<ShipIdentity, Position, Faction>(
|
||||
[&](entt::entity candidate, const ShipIdentity& /*si*/,
|
||||
const Position& candidatePos, const Faction& candidateFaction)
|
||||
{
|
||||
const bool isValidTarget = ownFaction.isEnemy
|
||||
? !candidateFaction.isEnemy
|
||||
: candidateFaction.isEnemy;
|
||||
if (!isValidTarget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
const float distanceSquared = (candidatePos.value - ownPos.value).lengthSquared();
|
||||
if (distanceSquared < bestDistanceSquared)
|
||||
{
|
||||
bestDistanceSquared = distanceSquared;
|
||||
weapon.currentTarget = candidate;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!weapon.currentTarget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (weapon.cooldownTicks > 0.0f)
|
||||
{
|
||||
weapon.cooldownTicks -= 1.0f;
|
||||
}
|
||||
if (weapon.cooldownTicks > 0.0f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const entt::entity targetEntity = *weapon.currentTarget;
|
||||
if (!admin.isValid(targetEntity) || !admin.hasAll<Position>(targetEntity))
|
||||
{
|
||||
weapon.currentTarget = std::nullopt;
|
||||
return;
|
||||
}
|
||||
|
||||
const QVector2D targetPos = admin.get<Position>(targetEntity).value;
|
||||
if ((stationPos.value - targetPos).length() > weapon.range)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_pendingDamage.push_back({targetEntity, weapon.damage,
|
||||
currentTick + kWeaponImpactDelayTicks});
|
||||
|
||||
FireEvent evt;
|
||||
evt.shooter = stationEntity;
|
||||
evt.shooter = shipEntity;
|
||||
evt.target = targetEntity;
|
||||
evt.emittedAt = currentTick;
|
||||
out.push_back(evt);
|
||||
@@ -183,3 +128,4 @@ void CombatSystem::applyPendingDamage(Tick currentTick, EntityAdmin& admin)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user