19 static const float AUTONOMOUS_DISTANCE_MAX_DEFAULT = 9999;
22 SCR_AIConfigComponent m_ConfigComponent;
23 SCR_AIGroupInfoComponent m_GroupInfo;
24 SCR_AIGroupMovementComponent m_GroupMovementComponent;
25 SCR_MailboxComponent m_Mailbox;
26 SCR_AIGroupSettingsComponent m_SettingsComponent;
27 ref array<SCR_AIInfoComponent> m_aInfoComponents = {};
30 ref ScriptInvokerBase<SCR_AIOnAgentLifeStateChanged> m_OnAgentLifeStateChanged =
new ScriptInvokerBase<SCR_AIOnAgentLifeStateChanged>();
33 const float SUPPRESS_MAX_CLUSTER_INFO_AGE_S = 90;
34 const float SUPPRESS_OLD_CLUSTER_INFO_AGE_S = 15;
35 const float SUPPRESS_MAX_DESTROYED_CLUSTER_INFO_AGE_S = 10;
36 const float SUPPRESS_MIN_DIST_TO_CLUSTER_M = 30;
37 const float SUPPRESS_MAX_DIST_TO_CLUSTER_M = 800;
85 float count = m_aInfoComponents.Count();
91 threat += infoComp.GetThreatSystem().GetThreatMeasure();
105 SCR_AICombatComponent comp = infoComp.GetCombatComponent();
107 comp.SetGroupFireRateCoef(coef, overridePersistent);
165 SCR_AIActionBase activity;
166 restartActivity =
false;
168 if (!m_ConfigComponent)
171 float currentTime =
GetGame().GetWorld().GetWorldTime();
172 float deltaTime_ms = 0;
177 AddDebugMessage(
"EvaluateActivity START");
178 if (m_bEvaluationBreakpoint)
180 Print(
"EvaluateActivity breakpoint triggered");
182 m_bEvaluationBreakpoint =
false;
187 AIMessage msgBase = m_Mailbox.ReadMessage(
true);
195 AddDebugMessage(
string.Format(
"PerformGoalReaction: %1, from BT: %2", msgGoal, msgGoal.m_sSentFromBt));
197 m_ConfigComponent.PerformGoalReaction(
this, msgGoal);
208 if (!overrideReaction)
211 AddDebugMessage(
string.Format(
"PerformInfoReaction: %1, from BT: %2", msgInfo, msgInfo.m_sSentFromBt));
214 m_ConfigComponent.PerformInfoReaction(
this, msgInfo);
220 AddDebugMessage(
string.Format(
"InfoMessage consumed by action: %1, from BT: %2", msgInfo, msgInfo.m_sSentFromBt));
233 DebugLogActionsPriority();
237 restartActivity =
true;
239 restartActivity =
true;
254 AddDebugMessage(
"EvaluateActivity END\n");
259 bool isSlave = m_Owner.IsSlave();
316 if (c.m_State && c.m_State.m_iCountEndangering != 0 && c.m_State.m_iCountAlive != 0)
332 if (!
SCR_AIWorldHandling.IsLowLightEnvironment() || !m_GroupInfo || !m_GroupInfo.IsIllumFlareAllowed())
341 if (illumFeature.Execute(
this, targetPosition, null))
342 m_GroupInfo.OnIllumFlareUsed();
357 AIAgent agent = AIAgent.Cast(infoComp.GetOwner());
361 IEntity character = agent.GetControlledEntity();
367 if (
Math.IsInRange(unitPos[0], bbMin[0], bbMax[0]) &&
Math.IsInRange(unitPos[1], bbMin[1], bbMax[1]) &&
Math.IsInRange(unitPos[2], bbMin[2], bbMax[2]))
382 if (clusterState.m_iCountIdentified == 0 && clusterState.m_iCountEndangering == 0)
386 if (clusterState.m_fDistMin < SUPPRESS_MIN_DIST_TO_CLUSTER_M || clusterState.m_fDistMin > SUPPRESS_MAX_DIST_TO_CLUSTER_M)
390 float maxSuppressionTime = SUPPRESS_MAX_CLUSTER_INFO_AGE_S;
391 if (clusterState.m_iCountAlive == 0)
392 maxSuppressionTime = SUPPRESS_MAX_DESTROYED_CLUSTER_INFO_AGE_S;
395 if (clusterState.GetTimeSinceLastNewInformation() > maxSuppressionTime)
398 vector bbMin = clusterState.m_vBBMin;
399 vector bbMax = clusterState.m_vBBMax;
402 SCR_AISuppressionObjectVolumeBox.ScaleTargetBBox(bbMin, bbMax, clusterState.m_fDistMin, clusterState.m_iCountIdentified > 0);
419 state = cluster.m_State;
432 SCR_AICombatComponent comp = infoComp.GetCombatComponent();
434 comp.SetGroupSuppressClusterState(state);
454 m_aInfoComponents.Insert(info);
474 SCR_AIUtilityComponent utility = SCR_AIUtilityComponent.Cast(agent.FindComponent(SCR_AIUtilityComponent));
476 return Debug.Error(
"Null AI utility");
479 utility.CancelAllGroupActivityBehaviors(
this);
482 for (
int i = m_aInfoComponents.Count() - 1; i >= 0; i--)
484 if (!m_aInfoComponents[i])
486 Debug.Error(
"Null AI info occured");
487 m_aInfoComponents.RemoveOrdered(i);
489 else if (m_aInfoComponents[i].IsOwnerAgent(agent))
496 m_aInfoComponents.RemoveOrdered(i);
522 if (isCurrentWaypoint)
534 if (!agent || !targetEntity)
538 if (!vehicleUsageComp)
553 if (agent.GetParentGroup() != m_Owner)
558 if (m_GroupMovementComponent && compSlot)
569 m_FireteamMgr.OnAgentAssignedToVehicle(agent, vehicleUsageComp, compSlot.GetType());
573 protected void JoinSubgroup(AIAgent agent,
int handleId,
bool isSubgroupLeader)
576 int oldHandleId = m_GroupMovementComponent.GetAgentMoveHandlerId(agent);
577 if (isSubgroupLeader)
578 m_GroupMovementComponent.SetMoveHandlerLeader(agent, oldHandleId, handleId);
580 m_GroupMovementComponent.MoveAgentToHandler(agent, oldHandleId, handleId);
589 CompartmentAccessComponent comp = charact.GetCompartmentAccessComponent();
592 IEntity vehicleEntity = comp.GetVehicleIn(charact);
596 if (!vehicleUsageComp)
603 OnAgentCompartmentEntered(agent, vehicleEntity, compartment.GetManager(), compartment.GetCompartmentMgrID(), compartment.GetCompartmentSlotID(),
false);
610 int oldHandleId = m_GroupMovementComponent.GetAgentMoveHandlerId(agent);
614 string formationType = formationDef.GetName();
615 int newHandleId = m_GroupMovementComponent.CreateGroupMoveHandler(formationType);
616 if (isSubgroupLeader)
617 m_GroupMovementComponent.SetMoveHandlerLeader(agent, oldHandleId, newHandleId);
619 m_GroupMovementComponent.MoveAgentToHandler(agent, oldHandleId, newHandleId);
627 int oldHandleId = m_GroupMovementComponent.GetAgentMoveHandlerId(agent);
628 m_GroupMovementComponent.MoveAgentToHandler(agent, oldHandleId, AIGroupMovementComponent.DEFAULT_HANDLER_ID);
629 bool isHandleEmpty = m_GroupMovementComponent.GetMoveHandlerAgentCount(oldHandleId) == 0;
632 m_GroupMovementComponent.RemoveGroupMoveHandler(oldHandleId);
641 if (!agent || !targetEntity)
648 if (agent.GetParentGroup() != m_Owner)
654 if (!vehicleUsageComp)
660 m_FireteamMgr.OnAgentUnassignedFromVehicle(agent, vehicleUsageComp);
666 m_OnAgentLifeStateChanged.Invoke(incapacitatedAgent, infoIncap, vehicle, lifeState);
718 enumSignal: 0, transmitIfNoReceivers:
true, transmitIfPassenger:
true, preset: SCR_EAITalkRequestPreset.MEDIUM);
740 AIAgent reporterAgent = ftLock.GetFireteam().GetMember(0);
743 SCR_AICommsHandler commsHandler = SCR_AISoundHandling.FindCommsHandler(reporterAgent);
763 array<ref AIActionBase> actions = {};
765 bool checkType = activityType !=
typename.Empty;
770 if (!activity || (checkType && !activity.IsInherited(activityType)))
778 if (activity.m_RelatedWaypoint == waypoint)
779 activity.Fail(doNotCompleteWaypoint);
788 array<ref AIActionBase> allActions = {};
791 array<AIActionBase> subactions = {};
815 m_OnMoveFailed.Invoke(moveResult, vehicleUsed, isWaypointRelated, moveLocation);
824 return m_OnMoveFailed;
830 super.EOnInit(owner);
835 m_ConfigComponent = SCR_AIConfigComponent.Cast(m_Owner.FindComponent(SCR_AIConfigComponent));
837 m_ConfigComponent.AddDefaultActivities(
this);
846 m_GroupInfo = SCR_AIGroupInfoComponent.Cast(m_Owner.FindComponent(SCR_AIGroupInfoComponent));
858 m_Mailbox = SCR_MailboxComponent.Cast(m_Owner.FindComponent(SCR_MailboxComponent));
860 m_SettingsComponent = SCR_AIGroupSettingsComponent.Cast(m_Owner.FindComponent(SCR_AIGroupSettingsComponent));
864 m_GroupMovementComponent = SCR_AIGroupMovementComponent.Cast(owner.
FindComponent(SCR_AIGroupMovementComponent));
877 m_GroupMovementComponent.DiagDrawSubgroups(m_Owner);
886 AddDebugMessage(
"UpdateGroupControlMode");
893 if (currentActivity && currentActivity.m_bIsWaypointRelated.m_Value)
894 m_GroupInfo.SetGroupControlMode(EGroupControlMode.FOLLOWING_WAYPOINT);
896 m_GroupInfo.SetGroupControlMode(EGroupControlMode.IDLE);
898 m_GroupInfo.SetGroupControlMode(EGroupControlMode.AUTONOMOUS);
919 AIWaypoint wp = m_Owner.GetCurrentWaypoint();
925 return vector.Distance(defendWp.GetOrigin(), pos) < defendWp.GetCompletionRadius();
943 if (!vehicleUsageComp)
946 return m_VehicleMgr.FindVehicle(vehicleUsageComp) != null;
994 if (vehicleCombatActivity)
995 vehicleCombatActivity.Fail();
ArmaReforgerScripted GetGame()
void SCR_AIActivityBase(SCR_AIGroupUtilityComponent utility, AIWaypoint relatedWaypoint)
void DiagIncreaseCounter()
array< ref SCR_AIGroupFireteamLock > TFireteamLockRefArray
ScriptInvokerBase< ScriptInvoker_GroupMoveFailed_Callback > ScriptInvoker_GroupMoveFailed
func ScriptInvoker_GroupMoveFailed_Callback
enum EAIGroupCombatMode ComponentEditorProps(category:"GameScripted/AI", description:"Component for utility AI system for groups")
void SCR_AITalkRequest(ECommunicationType type, IEntity entity, vector pos, int enumSignal, bool transmitIfNoReceivers, bool transmitIfPassenger, SCR_EAITalkRequestPreset preset)
void SCR_AITargetClusterState(SCR_AIGroupTargetCluster cluster)
Base class for all messages related to AI.
proto external Managed FindComponent(typename typeName)
proto external vector GetOrigin()
void AddRequest(SCR_AITalkRequest request)
bool CanBypass(SCR_AITalkRequest request=null)
void GetSubactions(notnull array< AIActionBase > outSubactions)
void GetAssignedFireteams(notnull TFireteamLockRefArray outFireteams)
ScriptInvoker GetOnAgentAdded()
void OnAgentAdded(AIAgent agent)
void SetMaxAutonomousDistance(float dist)
Sets max distance for various autonomous behaviors.
bool IsPositionAllowed(vector pos)
EAIGroupCombatMode m_eCombatModeActual
float GetMaxAutonomousDistance()
EAIGroupCombatMode GetCombatModeActual()
Returns actual combat mode. See comment to EvaluateCombatMode method.
void AddUsableVehicle(notnull SCR_AIVehicleUsageComponent vehicleUsageComp)
void OnExecuteWaypointTree()
void OnAgentCompartmentLeft(AIAgent agent, IEntity targetEntity, BaseCompartmentManagerComponent manager, int mgrID, int slotID, bool move)
ScriptInvoker_GroupMoveFailed GetOnMoveFailed()
void UpdateClustersState(float deltaTime_ms)
ref SCR_AITargetClusterState m_CurrentSuppressClusterState
void UpdateThreatMeasure()
void OnVehicleDeleted(SCR_AIVehicleUsageComponent comp)
void UpdateGroupControlMode(SCR_AIActionBase currentAction)
void EvaluateFlareUsage()
float m_fMaxAutonomousDistance
float m_fPerceptionUpdateTimer_ms
void SetFireRateCoef(float coef=1, bool overridePersistent=false)
bool IsUsableVehicle(notnull IEntity vehicleEntity)
void OnWaypointCompleted(AIWaypoint waypoint)
void OnEnemyDetectedFiltered(SCR_AIGroup group, SCR_AITargetInfo target, AIAgent reporter)
Called from m_Perception.
SCR_AIActionBase EvaluateActivity(out bool restartActivity)
void OnVehicleDamageStateChanged(SCR_AIVehicleUsageComponent comp, EDamageState state)
void RemoveUsableVehicle(notnull SCR_AIVehicleUsageComponent vehicleUsageComp)
void OnMoveFailed(int moveResult, IEntity vehicleUsed, bool isWaypointRelated, vector moveLocation)
void OnAgentRemoved(SCR_AIGroup group, AIAgent agent)
void OnTargetClusterStateChanged(SCR_AITargetClusterState state, EAITargetClusterState prevState, EAITargetClusterState newState)
void UpdateSuppressCluster()
void OnCurrentWaypointChanged(AIWaypoint currentWp, AIWaypoint prevWp)
void OnAgentCompartmentEntered(AIAgent agent, IEntity targetEntity, BaseCompartmentManagerComponent manager, int mgrID, int slotID, bool move)
void OnAgentLifeStateChanged(AIAgent incapacitatedAgent, SCR_AIInfoComponent infoIncap, IEntity vehicle, ECharacterLifeState lifeState)
bool ShouldSuppressCluster(SCR_AITargetClusterState clusterState)
int m_iGetMemberByGoalNextIndex
bool CanRebalanceFireteams()
Determines when we can rebalance fireteams. We don't want to do that when fighting for example.
override void EOnInit(IEntity owner)
EAIGroupCombatMode m_eCombatModeExternal
ref SCR_AIGroupFireteamManager m_FireteamMgr
ref SCR_AIGroupTargetClusterProcessor m_TargetClusterProcessor
SCR_AITargetClusterState GetCurrentSuppressClusterState()
void EvaluateCombatMode()
bool OnJoinGroupFromVehicle(AIAgent agent, bool isDriving)
void CancelActivitiesRelatedToWaypoint(notnull AIWaypoint waypoint, typename activityType=typename.Empty, bool doNotCompleteWaypoint=false)
bool IsUsableVehicle(notnull SCR_AIVehicleUsageComponent vehicleUsageComp)
void LeaveSubgroup(AIAgent agent, SCR_AIGroupVehicle groupVehicle)
bool AnyMembersInsideBBox(vector bbMin, vector bbMax)
EAIGroupCombatMode GetCombatModeExternal()
See SetCombatMode.
bool m_bNewGroupMemberAdded
bool IsMilitary()
Are we a military AI or not?
int CreateNewSubgroup(AIAgent agent, bool isSubgroupLeader, SCR_AIGroupVehicle groupVehicle)
ref SCR_AIWaypointState m_WaypointState
const float PERCEPTION_UPDATE_TIMER_MS
void JoinSubgroup(AIAgent agent, int handleId, bool isSubgroupLeader)
override void EOnDiag(IEntity owner, float timeSlice)
ref SCR_AIActionBase m_CurrentActivity
void OnWaypointToRemove(AIWaypoint waypoint, bool isCurrentWaypoint)
void SetCombatMode(EAIGroupCombatMode combatMode)
Sets combat mode as desired by external means, such as scenario, or commanding, or game master.
ref SCR_AIGroupVehicleManager m_VehicleMgr
ref SCR_AIGroupPerception m_Perception
This class is used for keeping track of vehicles assigned to group.
void SetSubgroupHandleId(int handleId=-1)
int GetSubgroupHandleId()
bool HasUnitState(EUnitState state)
ref ScriptInvokerBase< SCR_AIOnCompartmentLeft > m_OnCompartmentLeft
ref ScriptInvokerBase< SCR_AIOnCompartmentEntered > m_OnCompartmentEntered
ref ScriptInvokerBase< SCR_AIOnAgentLifeStateChanged > m_OnAgentLifeStateChanged
Activity which handles combat of a group if it has vehicles.
static void ErrorIncorrectType(notnull IEntity entity)
bool IsVehicleTypeValid()
static SCR_AIVehicleUsageComponent FindOnNearestParent(notnull IEntity ent, out IEntity componentOwner)
static void ErrorNoComponent(notnull IEntity entity)
SCR_AIWaypointState CreateWaypointState(SCR_AIGroupUtilityComponent groupUtilityComp)
proto external bool CallActionsOnMessage(AIMessage msg)
proto external bool HasActionOfType(typename actionType)
Returns true when there is an action of exactly this type.
AIBaseUtilityComponentClass AIComponentClass EvaluateActions()
Evaluate all actions and return the highest evaluated action which is not suspended....
proto external void AddAction(AIActionBase action)
Adds an action.
proto external bool RemoveObsoleteActions()
Removes actions which are failed or completed.
proto external void SetCurrentAction(AIActionBase executed)
proto external AIActionBase FindActionOfType(typename actionType)
Finds action of exactly this type.
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
proto void PrintFormat(string fmt, void param1=NULL, void param2=NULL, void param3=NULL, void param4=NULL, void param5=NULL, void param6=NULL, void param7=NULL, void param8=NULL, void param9=NULL, LogLevel level=LogLevel.NORMAL)