fix tests
This commit is contained in:
@@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
#include "EntityAdmin.h"
|
#include "EntityAdmin.h"
|
||||||
#include "FactionComponent.h"
|
#include "FactionComponent.h"
|
||||||
|
#include "StationBodyComponent.h"
|
||||||
#include "HealthComponent.h"
|
#include "HealthComponent.h"
|
||||||
#include "PositionComponent.h"
|
#include "PositionComponent.h"
|
||||||
|
#include "SensorRangeComponent.h"
|
||||||
#include "ShipIdentityComponent.h"
|
#include "ShipIdentityComponent.h"
|
||||||
#include "ThreatResponseBehaviorComponent.h"
|
#include "ThreatResponseBehaviorComponent.h"
|
||||||
#include "WeaponComponent.h"
|
#include "WeaponComponent.h"
|
||||||
@@ -31,10 +33,11 @@ void CombatSystem::tick(Tick currentTick,
|
|||||||
resolveWeapon(e, weapon, pos, faction, currentTick, admin, outFireEvents);
|
resolveWeapon(e, weapon, pos, faction, currentTick, admin, outFireEvents);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Station weapons.
|
// Station weapons (entities with StationBodyComponent; ships are excluded because
|
||||||
admin.forEach<WeaponComponent, PositionComponent, FactionComponent>(
|
// they lack that component and are already handled by the ship loop above).
|
||||||
|
admin.forEach<WeaponComponent, PositionComponent, FactionComponent, StationBodyComponent>(
|
||||||
[&](entt::entity e, WeaponComponent& weapon, PositionComponent& pos,
|
[&](entt::entity e, WeaponComponent& weapon, PositionComponent& pos,
|
||||||
FactionComponent& faction)
|
FactionComponent& faction, const StationBodyComponent& /*sb*/)
|
||||||
{
|
{
|
||||||
resolveWeapon(e, weapon, pos, faction, currentTick, admin, outFireEvents);
|
resolveWeapon(e, weapon, pos, faction, currentTick, admin, outFireEvents);
|
||||||
});
|
});
|
||||||
@@ -77,10 +80,14 @@ void CombatSystem::resolveWeapon(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Acquire a new target if needed (nearest opposing-faction ship).
|
// Acquire a new target if needed.
|
||||||
|
// Ships use their sensor range; stations fall back to weapon range.
|
||||||
if (!weapon.currentTarget)
|
if (!weapon.currentTarget)
|
||||||
{
|
{
|
||||||
float bestDistanceSquared = weapon.range * weapon.range;
|
const float acquisitionRange = admin.hasAll<SensorRangeComponent>(shipEntity)
|
||||||
|
? admin.get<SensorRangeComponent>(shipEntity).value
|
||||||
|
: weapon.range;
|
||||||
|
float bestDistanceSquared = acquisitionRange * acquisitionRange;
|
||||||
admin.forEach<ShipIdentityComponent, PositionComponent, FactionComponent>(
|
admin.forEach<ShipIdentityComponent, PositionComponent, FactionComponent>(
|
||||||
[&](entt::entity candidate, const ShipIdentityComponent& /*si*/,
|
[&](entt::entity candidate, const ShipIdentityComponent& /*si*/,
|
||||||
const PositionComponent& candidatePos,
|
const PositionComponent& candidatePos,
|
||||||
|
|||||||
@@ -91,9 +91,11 @@ void MovementIntentSystem::tick(EntityAdmin& admin)
|
|||||||
const float manAccel = body.maneuveringAccelerationPerTick;
|
const float manAccel = body.maneuveringAccelerationPerTick;
|
||||||
const float stoppingDist = (body.maxSpeedPerTick * body.maxSpeedPerTick)
|
const float stoppingDist = (body.maxSpeedPerTick * body.maxSpeedPerTick)
|
||||||
/ (2.0f * manAccel);
|
/ (2.0f * manAccel);
|
||||||
const float desiredSpeed = (dist <= stoppingDist)
|
// Cap to dist so the ship never overshoots the target in a single tick.
|
||||||
|
const float baseDesiredSpeed = (dist <= stoppingDist)
|
||||||
? std::sqrt(2.0f * manAccel * dist)
|
? std::sqrt(2.0f * manAccel * dist)
|
||||||
: body.maxSpeedPerTick;
|
: body.maxSpeedPerTick;
|
||||||
|
const float desiredSpeed = std::min(dist, baseDesiredSpeed);
|
||||||
|
|
||||||
const QVector2D desiredVel = delta.normalized() * desiredSpeed;
|
const QVector2D desiredVel = delta.normalized() * desiredSpeed;
|
||||||
const QVector2D velError = desiredVel - body.velocity;
|
const QVector2D velError = desiredVel - body.velocity;
|
||||||
|
|||||||
@@ -115,13 +115,24 @@ TEST_CASE("CombatSystem: cooldown prevents firing before it expires", "[combat]"
|
|||||||
f.wireEnemyTarget(enemy, player);
|
f.wireEnemyTarget(enemy, player);
|
||||||
f.admin.get<WeaponComponent>(enemy).cooldownTicks = 3.0f; // override to 3
|
f.admin.get<WeaponComponent>(enemy).cooldownTicks = 3.0f; // override to 3
|
||||||
|
|
||||||
|
auto enemyFiredIn = [&enemy](const std::vector<FireEvent>& evts)
|
||||||
|
{
|
||||||
|
for (const FireEvent& evt : evts)
|
||||||
|
{
|
||||||
|
if (evt.shooter == enemy) { return true; }
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
std::vector<FireEvent> events;
|
std::vector<FireEvent> events;
|
||||||
f.combat.tick(0, f.admin, f.buildings, events);
|
f.combat.tick(0, f.admin, f.buildings, events);
|
||||||
|
REQUIRE_FALSE(enemyFiredIn(events));
|
||||||
|
|
||||||
f.combat.tick(1, f.admin, f.buildings, events);
|
f.combat.tick(1, f.admin, f.buildings, events);
|
||||||
REQUIRE(events.empty());
|
REQUIRE_FALSE(enemyFiredIn(events));
|
||||||
|
|
||||||
f.combat.tick(2, f.admin, f.buildings, events);
|
f.combat.tick(2, f.admin, f.buildings, events);
|
||||||
REQUIRE(events.size() == 1);
|
REQUIRE(enemyFiredIn(events));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("CombatSystem: no fire when target is out of range", "[combat]")
|
TEST_CASE("CombatSystem: no fire when target is out of range", "[combat]")
|
||||||
|
|||||||
Reference in New Issue
Block a user