16 ref ScriptInvokerBase<SCR_AITargetClusterStateChanged>
m_OnClusterStateChanged =
new ScriptInvokerBase<SCR_AITargetClusterStateChanged>();
21 s.m_fTimer_ms += deltaTime_ms;
23 if (s.m_eState != s.m_ePrevState)
35 if (newDesiredState == s.m_eState)
56 if (newDesiredState == s.m_eState)
75 if (newDesiredState == s.m_eState)
123 if (newDesiredState != s.m_eState)
136 vector centerPos = 0.5*(s.m_vBBMin + s.m_vBBMax);
138 bool playerControlled =
m_Utility.m_Owner.IsSlave();
144 if (s.GetTimeSinceLastNewInformation() > s.m_fMaxAge_s)
148 else if (!
m_Utility.IsPositionAllowed(centerPos))
152 if (s.m_iCountIdentified > 0)
165 if (s.m_iCountIdentified > 0)
167 else if ( ((s.m_iCountLost + s.m_iCountDetected + s.m_iCountDestroyed) > 0) &&
188 AddDebugMessage(
string.Format(
"%1: SwitchToState: %2", s,
typename.EnumToString(
EAITargetClusterState, newState)));
191 s.m_ePrevState = s.m_eState;
192 s.m_eState = newState;
199 AddDebugMessage(
string.Format(
"%1: AssignActivity: %2", s, activity));
209 parallelAction.AddAction(activity);
211 s.m_Activity = activity;
217 AddDebugMessage(
string.Format(
"%1: UnassignActivity: %2", s, s.m_Activity));
224 s.m_Activity.Complete();
252 array<SCR_AIGroupFireteam> newFireteams = {};
262 if (!inFtsMain.IsEmpty())
268 if (!inFtsAux.IsEmpty())
277 if (ftsMain.IsEmpty())
288 if (ftsAux.IsEmpty())
290 if (ftsMain.Count() > 1)
293 ftsMain.Remove(ftsMain.Count()-1);
294 ftsAux.Insert(ftLock);
301 else if(ftsAux.Count() > 1)
304 while (ftsAux.Count() > 1)
307 ftsMain.Insert(ftLock);
308 ftsAux.Remove(ftsAux.Count()-1);
317 if (!inFtsMain.IsEmpty() || !inFtsAux.IsEmpty())
322 foreach (
auto ft : inFtsMain)
324 foreach (
auto ft : inFtsAux)
387 float fEnemies = 1.3 * (
float)s.m_iCountDetected + 1.3*s.m_iCountIdentified + 1.3*s.m_iCountLost + 0.5*s.m_iCountDestroyed;
389 int nEnemies =
Math.Ceil(fEnemies);
392 int nSoldiersAllocated = 0;
394 nSoldiersAllocated += ftLock.GetFireteam().GetMemberCount();
396 nSoldiersAllocated += ftLock.GetFireteam().GetMemberCount();
399 array<SCR_AIGroupFireteam> freeFireteams = {};
401 while (nSoldiersAllocated < nEnemies && !freeFireteams.IsEmpty())
405 inOutFtLocksMain.Insert(newFtLock);
406 freeFireteams.Remove(0);
415 outMainFireteams.Clear();
416 outAuxFireteams.Clear();
439 int countAlive = s.m_iCountLost + s.m_iCountDetected + s.m_iCountIdentified;
450 vector tgtPos = 0.5 * (s.m_vBBMin + s.m_vBBMax);
452 float tgtCount = s.m_iCountDestroyed + s.m_iCountIdentified;
454 const float movementSpeed = 2.0;
455 float duration_s =
distance / movementSpeed + 15.0 * tgtCount;
456 duration_s =
Math.Max(20.0, duration_s);
468 void AddDebugMessage(
string str)
470 SCR_AIInfoBaseComponent infoComp =
m_Utility.m_GroupInfo;
471 infoComp.AddDebugMessage(
string.Format(
"%1: %2",
this, str), msgType:
EAIDebugMsgType.CLUSTER);
void SCR_AIActivityBase(SCR_AIGroupUtilityComponent utility, AIWaypoint relatedWaypoint)
enum SCR_EAIActivityCause m_Utility
array< ref SCR_AIGroupFireteamLock > TFireteamLockRefArray
func SCR_AITargetClusterStateChanged
void SCR_AITargetClusterState(SCR_AIGroupTargetCluster cluster)
void GetSpecificFireteams(notnull TFireteamLockRefArray fireteamsAttack, notnull TFireteamLockRefArray fireteamsCover)
SCR_AIGroupFireteamLock TryLock()
static void TryLockFireteams(notnull array< SCR_AIGroupFireteam > fireteams, notnull TFireteamLockRefArray locks, bool clearLockArray)
Tries to lock all fireteams, returns a new array of locks for those fireteams it was able to lock.
static TFireteamLockRefArray CopyLockArray(TFireteamLockRefArray other)
Creates a copy of locks array.
bool HasActivityForState(SCR_AITargetClusterState s, EAITargetClusterState eState)
void AllocateMoreFireteams(SCR_AITargetClusterState s, notnull TFireteamLockRefArray inOutFtLocksMain, notnull TFireteamLockRefArray ftLocksAux)
void UnassignActivity(SCR_AITargetClusterState s)
ref ScriptInvokerBase< SCR_AITargetClusterStateChanged > m_OnClusterStateChanged
void SCR_AIGroupTargetClusterProcessor(SCR_AIGroupUtilityComponent utility)
void UpdateCluster(SCR_AIGroupTargetCluster c, SCR_AITargetClusterState s, float deltaTime_ms)
void AssignActivity(notnull SCR_AITargetClusterState s, notnull SCR_AIActivityBase activity)
void OnEnterState(SCR_AITargetClusterState s, EAITargetClusterState newState)
const float INITIAL_DECISION_DELAY_MS
SCR_AIActivityBase TryCreateActivityForState(SCR_AITargetClusterState s, EAITargetClusterState estate, notnull TFireteamLockRefArray inFtsMain, notnull TFireteamLockRefArray inFtsAux)
float CalculateMaxAgeThreshold_s(SCR_AITargetClusterState s, EAITargetClusterState newState)
Calculates how long we should investigate this target cluster.
void SwitchToState(SCR_AITargetClusterState s, EAITargetClusterState newState)
SCR_AIGroupUtilityComponent m_Utility
void OnLeaveState(SCR_AITargetClusterState s, EAITargetClusterState oldState)
const float MAX_CLUSTER_AGE_S
EAITargetClusterState EvaluateNewDesiredState(SCR_AITargetClusterState s)
void GetAssignedFireteams(notnull SCR_AIFireteamsActivity fromActivity, notnull TFireteamLockRefArray outMainFireteams, notnull TFireteamLockRefArray outAuxFireteams)
Returns arrays with fireteams already assigned to this cluster, if there are any. Otherwise returns e...
void GetSpecificFireteams(notnull TFireteamLockRefArray fireteamsInvestigate, notnull TFireteamLockRefArray fireteamsCover)