#include "StandbyExecutor.h" #include #include #include "BehaviorKind.h" #include "Centroid.h" #include "EntityAdmin.h" #include "FactionComponent.h" #include "HealthComponent.h" #include "MovementIntentComponent.h" #include "PositionComponent.h" #include "SelectedBehaviorComponent.h" #include "ShipIdentityComponent.h" #include "StandbyBehavior.h" #include "StationBodyComponent.h" #include "tracing.h" void StandbyExecutor::execute(EntityAdmin& admin) { TRACE(); // Centroid of each faction's alive ships; a standing-by ship steers toward the // center of its other same-faction ships so it stays among potential patients. Centroid enemyShips; Centroid playerShips; admin.forEach( [&enemyShips, &playerShips](entt::entity /*e*/, const ShipIdentityComponent& /*si*/, const PositionComponent& pos, const FactionComponent& faction, const HealthComponent& health) { if (health.hp <= 0.0f) { return; } Centroid& centroid = faction.isEnemy ? enemyShips : playerShips; centroid.add(pos.value); }); // Fallback per faction: the centroid of that side's own alive defence stations. Centroid enemyStations; Centroid playerStations; admin.forEach( [&enemyStations, &playerStations](entt::entity /*e*/, const StationBodyComponent& /*sb*/, const PositionComponent& pos, const FactionComponent& faction, const HealthComponent& health) { if (health.hp <= 0.0f) { return; } Centroid& centroid = faction.isEnemy ? enemyStations : playerStations; centroid.add(pos.value); }); const std::optional enemyStationCenter = enemyStations.value(); const std::optional playerStationCenter = playerStations.value(); admin.forEach( [&](entt::entity /*e*/, const StandbyBehavior& /*standby*/, const SelectedBehaviorComponent& selected, const PositionComponent& pos, const FactionComponent& faction, MovementIntentComponent& intent) { if (selected.winner != BehaviorKind::Standby) { return; } const Centroid& allyShips = faction.isEnemy ? enemyShips : playerShips; const std::optional& friendlyStationCenter = faction.isEnemy ? enemyStationCenter : playerStationCenter; // Aim at the centroid of the other allied ships (excluding self), then // fall back to the friendly stations, then hold position when alone. QVector2D target = pos.value; if (allyShips.count > 1) { target = (allyShips.sum - pos.value) / static_cast(allyShips.count - 1); } else if (friendlyStationCenter) { target = *friendlyStationCenter; } intent = MovementIntentComponent{true, target}; }); }