refactor AI system

This commit is contained in:
2026-06-15 09:16:56 +02:00
parent 8451f5a281
commit e8dd73bcb0
67 changed files with 1731 additions and 919 deletions

View File

@@ -6,6 +6,10 @@
#include <utility>
#include <vector>
#include "AdvanceBehavior.h"
#include "AttackBehavior.h"
#include "BehaviorScores.h"
#include "DeliverScrapBehavior.h"
#include "DynamicBodyComponent.h"
#include "EntityAdmin.h"
#include "FactionComponent.h"
@@ -13,14 +17,15 @@
#include "ModuleOwnerComponent.h"
#include "ModulesConfig.h"
#include "MovementIntentComponent.h"
#include "RallyBehaviorComponent.h"
#include "RepairBehaviorComponent.h"
#include "RallyBehavior.h"
#include "RepairBehavior.h"
#include "RepairToolComponent.h"
#include "SalvageBehaviorComponent.h"
#include "RetreatBehavior.h"
#include "SalvageCargoComponent.h"
#include "SalvageScrapBehavior.h"
#include "SelectedBehaviorComponent.h"
#include "SensorRangeComponent.h"
#include "Tick.h"
#include "ThreatResponseBehaviorComponent.h"
#include "tracing.h"
#include "WeaponComponent.h"
@@ -321,15 +326,30 @@ entt::entity ShipSystem::spawn(const std::string& schematicId, int level,
// --- Pass 3: attach behavior components based on capability presence -----
// Baseline: every ship can always fall back to advancing, and needs a slot
// for the per-tick behavior selection result.
m_admin.addComponent<AdvanceBehavior>(entity, AdvanceBehavior{});
m_admin.addComponent<SelectedBehaviorComponent>(entity, SelectedBehaviorComponent{});
// Player ships retreat to the rally point when threatened or badly damaged
// (disabled by the balancing tool to keep arena fights symmetric).
if (!isEnemy && m_retreatEnabled)
{
RetreatBehavior retreat;
retreat.retreatHpFraction = BehaviorScores::kLowHpFraction;
retreat.retreatPoint = m_rallyPoint;
m_admin.addComponent<RetreatBehavior>(entity, retreat);
}
if (!weaponChildren.empty())
{
m_admin.addComponent<ThreatResponseBehaviorComponent>(
entity, ThreatResponseBehaviorComponent{});
m_admin.addComponent<AttackBehavior>(entity, AttackBehavior{});
if (!isEnemy)
{
m_admin.addComponent<RallyBehaviorComponent>(
entity, RallyBehaviorComponent{m_rallyPoint});
RallyBehavior rally;
rally.rallyPoint = m_rallyPoint;
m_admin.addComponent<RallyBehavior>(entity, rally);
}
}
@@ -342,11 +362,14 @@ entt::entity ShipSystem::spawn(const std::string& schematicId, int level,
if (r > maxCollRange) { maxCollRange = r; }
}
SalvageBehaviorComponent sb;
sb.scrapTarget = std::nullopt;
sb.deliveryBay = kInvalidBuildingId;
sb.maxCollectionRange_tiles = maxCollRange;
m_admin.addComponent<SalvageBehaviorComponent>(entity, sb);
SalvageScrapBehavior salvage;
salvage.scrapTarget = std::nullopt;
salvage.maxCollectionRange_tiles = maxCollRange;
m_admin.addComponent<SalvageScrapBehavior>(entity, salvage);
DeliverScrapBehavior deliver;
deliver.deliveryBay = kInvalidBuildingId;
m_admin.addComponent<DeliverScrapBehavior>(entity, deliver);
}
if (!repairChildren.empty())
@@ -358,10 +381,10 @@ entt::entity ShipSystem::spawn(const std::string& schematicId, int level,
if (r > maxRepairRange) { maxRepairRange = r; }
}
RepairBehaviorComponent rb;
rb.currentTarget = std::nullopt;
rb.maxRepairRange_tiles = maxRepairRange;
m_admin.addComponent<RepairBehaviorComponent>(entity, rb);
RepairBehavior repair;
repair.currentTarget = std::nullopt;
repair.maxRepairRange_tiles = maxRepairRange;
m_admin.addComponent<RepairBehavior>(entity, repair);
}
return entity;
@@ -385,7 +408,7 @@ void ShipSystem::clearMovementIntents()
m_admin.forEach<MovementIntentComponent>(
[](entt::entity /*e*/, MovementIntentComponent& i)
{
i = MovementIntentComponent{0, QVector2D(0.0f, 0.0f)};
i = MovementIntentComponent{false, QVector2D(0.0f, 0.0f)};
});
}
@@ -394,12 +417,17 @@ void ShipSystem::setRallyPoint(QVector2D point)
m_rallyPoint = point;
}
void ShipSystem::setRetreatEnabled(bool enabled)
{
m_retreatEnabled = enabled;
}
void ShipSystem::triggerRallyDeparture()
{
TRACE();
std::vector<entt::entity> toRemove;
m_admin.forEach<RallyBehaviorComponent, FactionComponent>(
[&toRemove](entt::entity e, const RallyBehaviorComponent& /*rb*/,
m_admin.forEach<RallyBehavior, FactionComponent>(
[&toRemove](entt::entity e, const RallyBehavior& /*rb*/,
const FactionComponent& f)
{
if (!f.isEnemy)
@@ -409,6 +437,6 @@ void ShipSystem::triggerRallyDeparture()
});
for (entt::entity e : toRemove)
{
m_admin.removeComponent<RallyBehaviorComponent>(e);
m_admin.removeComponent<RallyBehavior>(e);
}
}