Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_AIUtilityComponent.c
Go to the documentation of this file.
1 [ComponentEditorProps(category: "GameScripted/AI", description: "Component for utility AI system calculations")]
3 {
4 }
5 
6 class SCR_AIUtilityComponent : SCR_AIBaseUtilityComponent
7 {
10  SCR_AIConfigComponent m_ConfigComponent;
11  SCR_AIInfoComponent m_AIInfo;
12  SCR_AICombatComponent m_CombatComponent;
13  PerceptionComponent m_PerceptionComponent;
14  SCR_MailboxComponent m_Mailbox;
15 
20  ref SCR_AICombatMoveState m_CombatMoveState;
21 
22  protected ref BaseTarget m_UnknownTarget;
24 
25  protected float m_fLastUpdateTime;
26 
27  protected static const float DISTANCE_HYSTERESIS_FACTOR = 0.45;
28  protected static const float NEARBY_DISTANCE_SQ = 2500;
29  protected static const float REACTION_TO_SAME_UNKNOWN_TARGET_INTERVAL_MS = 2500;
30 
31  //------------------------------------------------------------------------------------------------
36  {
38  return null;
39 
40  #ifdef AI_DEBUG
41  AddDebugMessage("EvaluateBehavior START");
42  if (m_bEvaluationBreakpoint)
43  {
44  Print("EvaluateBehavior breakpoint triggered", LogLevel.NORMAL);
45  debug;
46  m_bEvaluationBreakpoint = false;
47  }
48  #endif
49 
50  // Update delta time and players's position
51  float time = m_OwnerEntity.GetWorld().GetWorldTime();
52  float deltaTime = time - m_fLastUpdateTime;
53  m_fLastUpdateTime = time;
54 
55  // Create events from commands, danger events, new targets
56  m_ThreatSystem.Update(this, deltaTime);
58 
59  // Read messages
60  AIMessage msgBase = m_Mailbox.ReadMessage(true);
61  if (msgBase)
62  {
63  SCR_AIMessageGoal msgGoal = SCR_AIMessageGoal.Cast(msgBase);
64  if (msgGoal)
65  {
66  // Process goal message
67  #ifdef AI_DEBUG
68  AddDebugMessage(string.Format("PerformGoalReaction: %1, from BT: %2", msgGoal, msgGoal.m_sSentFromBt));
69  #endif
70  m_ConfigComponent.PerformGoalReaction(this, msgGoal);
71  }
72  else
73  {
74  SCR_AIMessageInfo msgInfo = SCR_AIMessageInfo.Cast(msgBase);
75  if (msgInfo)
76  {
77  // Process info message
78 
79  // Try to notify actions about the message
80  bool overrideReaction = CallActionsOnMessage(msgInfo);
81 
82  #ifdef AI_DEBUG
83  if (overrideReaction)
84  {
85  AddDebugMessage(string.Format("InfoMessage consumed by action: %1, from BT: %2", msgInfo, msgInfo.m_sSentFromBt));
86  }
87  #endif
88 
89  // If message was not consumed by action, process it
90  if (!overrideReaction)
91  {
92  #ifdef AI_DEBUG
93  AddDebugMessage(string.Format("PerformInfoReaction: %1, from BT: %2", msgInfo, msgInfo.m_sSentFromBt));
94  #endif
95  m_ConfigComponent.PerformInfoReaction(this, msgInfo);
96  }
97  }
98  }
99  }
100 
101  bool reactToUnknownTarget = false;
102  if (unknownTarget)
103  {
104  if (unknownTarget == m_UnknownTarget)
105  { // Same target
106  if (GetGame().GetWorld().GetWorldTime() - m_fReactionUnknownTargetTime_ms > REACTION_TO_SAME_UNKNOWN_TARGET_INTERVAL_MS)
107  reactToUnknownTarget = true;
108  }
109  else
110  { // Different target
111  reactToUnknownTarget = true;
112  }
113  }
114  if (reactToUnknownTarget && m_ConfigComponent.m_Reaction_UnknownTarget)
115  {
116  #ifdef AI_DEBUG
117  AddDebugMessage(string.Format("PerformReaction: Unknown Target: %1", unknownTarget));
118  #endif
119 
120  m_ConfigComponent.m_Reaction_UnknownTarget.PerformReaction(this, m_ThreatSystem, unknownTarget, unknownTarget.GetLastSeenPosition());
121  m_fReactionUnknownTargetTime_ms = GetGame().GetWorld().GetWorldTime();
122  }
123  m_UnknownTarget = unknownTarget;
124 
125  //------------------------------------------------------------------------------------------------
126  // Evaluate current weapon and target
127 
128  bool weaponEvent;
129  bool selectedTargetChanged;
130  bool retreatTargetChanged;
131  bool compartmentChanged;
132  BaseTarget prevTarget;
133  BaseTarget selectedTarget;
134  m_CombatComponent.EvaluateWeaponAndTarget(weaponEvent, selectedTargetChanged,
135  prevTarget, selectedTarget, retreatTargetChanged, compartmentChanged);
136 
137  if (selectedTargetChanged && m_ConfigComponent.m_Reaction_SelectedTargetChanged)
138  {
139  #ifdef AI_DEBUG
140  AddDebugMessage(string.Format("PerformReaction: Selected Target Changed: %1", selectedTarget));
141  #endif
142 
143  m_ConfigComponent.m_Reaction_SelectedTargetChanged.PerformReaction(this, prevTarget, selectedTarget);
144  }
145 
146  BaseTarget retreatTarget = m_CombatComponent.GetRetreatTarget();
147  if (retreatTarget &&
148  ((selectedTargetChanged && !selectedTarget && retreatTarget) || // Nothing to attack any more and must retreat from some target
149  (!selectedTarget && retreatTargetChanged))) // Not attacking anything and must retreat from a different target
150  {
151  if (m_ConfigComponent.m_Reaction_RetreatFromTarget)
152  {
153  #ifdef AI_DEBUG
154  AddDebugMessage(string.Format("PerformReaction: Retreat From Target: %1", retreatTarget));
155  #endif
156 
157  m_ConfigComponent.m_Reaction_RetreatFromTarget.PerformReaction(this, m_ThreatSystem, retreatTarget, retreatTarget.GetLastSeenPosition());
158  }
159  }
160 
161  //------------------------------------------------------------------------------------------------
162  // Update combat component
163  m_CombatComponent.Update(deltaTime);
164 
165  // Evaluation: Remove completed behaviors, evaluate, set new behavior
167  AIActionBase selectedAction = EvaluateActions();
168  #ifdef AI_DEBUG
170  DebugLogActionsPriority();
171  #endif
172 
173  if (selectedAction && selectedAction != m_CurrentBehavior && (!m_CurrentBehavior || m_CurrentBehavior.IsActionInterruptable()))
174  {
175  SetCurrentAction(selectedAction);
176  m_CurrentBehavior = SCR_AIBehaviorBase.Cast(selectedAction);
177 #ifdef WORKBENCH
178  SCR_AIDebugVisualization.VisualizeMessage(m_OwnerEntity, SCR_AIDebug.GetBehaviorName(m_CurrentBehavior), EAIDebugCategory.BEHAVIOR, 5);
179 #endif
180  }
181 
182  m_CurrentBehavior.OnActionExecuted();
183 
184  // Update comms handler
185  if (m_CommsHandler.m_bNeedUpdate)
186  m_CommsHandler.Update(deltaTime);
187 
188  // Update combat move state
189  if (m_CombatMoveState.m_bInCover && m_CombatMoveState.GetAssignedCover())
190  m_CombatMoveState.VerifyCurrentCover(m_OwnerEntity.GetOrigin());
191 
192  #ifdef AI_DEBUG
193  AddDebugMessage("EvaluateBehavior END\n");
194  #endif
195 
196  return m_CurrentBehavior;
197  }
198 
199  //------------------------------------------------------------------------------------------------
204  {
205  if (m_AIInfo && m_AIInfo.HasUnitState(EUnitState.IN_TURRET))
206  return false;
207 
208  return true;
209  }
210 
211  //------------------------------------------------------------------------------------------------
214  {
215  return m_CurrentBehavior;
216  }
217 
218  //------------------------------------------------------------------------------------------------
222  {
223 
224  CompartmentAccessComponent compartmentAccess = CompartmentAccessComponent.Cast(m_OwnerEntity.FindComponent(CompartmentAccessComponent));
225  if (!compartmentAccess)
226  return;
227 
228  if (!compartmentAccess.IsInCompartment())
229  return;
230 
231  SCR_AIActivityBase relatedActivity;
232  SCR_AIBehaviorBase behavior = SCR_AIBehaviorBase.Cast(action);
233  if (behavior)
234  relatedActivity = SCR_AIActivityBase.Cast(behavior.GetRelatedGroupActivity());
235 
236  float score = action.Evaluate();
237  float priorityLevel = action.EvaluatePriorityLevel();
238  IEntity vehicle = compartmentAccess.GetCompartment().GetOwner();
239  ECompartmentType compartmentType = SCR_AICompartmentHandling.CompartmentClassToType(compartmentAccess.GetCompartment().Type());
240  AddAction(new SCR_AIGetOutVehicle(this, relatedActivity, vehicle, priority: score + 100, priorityLevel: priorityLevel));
241  AddAction(new SCR_AIGetInVehicle(this, relatedActivity, vehicle, compartmentType, priorityLevel: priorityLevel));
242  }
243 
244  //------------------------------------------------------------------------------------------------
245  override void EOnInit(IEntity owner)
246  {
247  super.EOnInit(owner);
248  AIAgent agent = AIAgent.Cast(GetOwner());
249  if (!agent)
250  return;
251 
252  m_ConfigComponent = SCR_AIConfigComponent.Cast(agent.FindComponent(SCR_AIConfigComponent));
253 
254  m_OwnerEntity = GenericEntity.Cast(agent.GetControlledEntity());
255  if (!m_OwnerEntity)
256  return;
257 
258  m_AIInfo = SCR_AIInfoComponent.Cast(agent.FindComponent(SCR_AIInfoComponent));
259  m_CombatComponent = SCR_AICombatComponent.Cast(m_OwnerEntity.FindComponent(SCR_AICombatComponent));
260  m_PerceptionComponent = PerceptionComponent.Cast(m_OwnerEntity.FindComponent(PerceptionComponent));
263  m_AIInfo.InitThreatSystem(m_ThreatSystem); // let the AIInfo know about the threat system - move along with creating threat system instance!
264  m_LookAction = new SCR_AILookAction(this, false); // LookAction is not regular behavior and is evaluated separately
265  m_ConfigComponent.AddDefaultBehaviors(this);
266  m_Mailbox = SCR_MailboxComponent.Cast(owner.FindComponent(SCR_MailboxComponent));
268  m_CombatMoveState = new SCR_AICombatMoveState();
269  }
270 
271  //------------------------------------------------------------------------------------------------
272  override void EOnDiag(IEntity owner, float timeSlice)
273  {
274  m_CommsHandler.EOnDiag(timeSlice);
275  }
276 
277  //------------------------------------------------------------------------------------------------
279  vector GetOrigin()
280  {
281  return m_OwnerEntity.GetOrigin();
282  }
283 }
ComponentEditorProps
SCR_FragmentEntityClass ComponentEditorProps
SCR_AIBaseUtilityComponentClass
Definition: SCR_AIBaseUtilityComponent.c:2
SCR_AILookAction
Definition: SCR_AILookAction.c:1
SCR_AIDebugVisualization
Definition: SCR_AIDebugVisualization.c:9
SetCurrentAction
proto external void SetCurrentAction(AIActionBase executed)
RemoveObsoleteActions
proto external bool RemoveObsoleteActions()
Removes actions which are failed or completed.
m_CombatMoveState
ref SCR_AICombatMoveState m_CombatMoveState
Definition: SCR_AIUtilityComponent.c:20
SCR_AIActionBase
Definition: SCR_AIAction.c:1
EvaluateBehavior
SCR_AIBehaviorBase EvaluateBehavior(BaseTarget unknownTarget)
Definition: SCR_AIUtilityComponent.c:35
AddAction
proto external void AddAction(AIActionBase action)
Adds an action.
m_OwnerController
protected SCR_CharacterControllerComponent m_OwnerController
Definition: SCR_AIUtilityComponent.c:9
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
ECompartmentType
ECompartmentType
Definition: ECompartmentType.c:7
m_CommsHandler
ref SCR_AICommsHandler m_CommsHandler
Definition: SCR_AIUtilityComponent.c:18
m_PerceptionComponent
PerceptionComponent m_PerceptionComponent
Definition: SCR_AIUtilityComponent.c:13
m_fReactionUnknownTargetTime_ms
protected float m_fReactionUnknownTargetTime_ms
WorldTime timestamp.
Definition: SCR_AIUtilityComponent.c:23
GenericEntity
SCR_GenericBoxEntityClass GenericEntity
BaseTarget
Definition: BaseTarget.c:12
SCR_CharacterControllerComponent
Definition: SCR_CharacterControllerComponent.c:35
SCR_AIMessageGoal
Definition: SCR_AIMessage.c:69
AIActionBase
Definition: AIActionBase.c:12
SCR_AIActivityBase
Definition: SCR_AIActivity.c:1
GetOrigin
vector GetOrigin()
Definition: SCR_AIUtilityComponent.c:279
GetCurrentBehavior
SCR_AIBehaviorBase GetCurrentBehavior()
Definition: SCR_AIUtilityComponent.c:213
EAIDebugCategory
EAIDebugCategory
Definition: SCR_AIWorld.c:11
SCR_AIGetOutVehicle
Definition: SCR_AIVehicleBehavior.c:118
SCR_AIUtilityComponentClass
Definition: SCR_AIUtilityComponent.c:2
CanIndependentlyMove
bool CanIndependentlyMove()
Definition: SCR_AIUtilityComponent.c:203
WrapBehaviorOutsideOfVehicle
void WrapBehaviorOutsideOfVehicle(SCR_AIActionBase action)
Definition: SCR_AIUtilityComponent.c:221
m_Mailbox
SCR_MailboxComponent m_Mailbox
Definition: SCR_AIUtilityComponent.c:14
m_CombatComponent
SCR_AICombatComponent m_CombatComponent
Definition: SCR_AIUtilityComponent.c:12
m_ConfigComponent
SCR_AIConfigComponent m_ConfigComponent
Definition: SCR_AIUtilityComponent.c:10
m_LookAction
ref SCR_AILookAction m_LookAction
Definition: SCR_AIUtilityComponent.c:17
m_CurrentBehavior
ref SCR_AIBehaviorBase m_CurrentBehavior
Used for avoiding constant casting, outside of this class use GetCurrentBehavior()
Definition: SCR_AIUtilityComponent.c:19
GetOwner
IEntity GetOwner()
Owner entity of the fuel tank.
Definition: SCR_FuelNode.c:128
EOnDiag
override void EOnDiag(IEntity owner, float timeSlice)
Definition: SCR_AIUtilityComponent.c:272
m_UnknownTarget
protected ref BaseTarget m_UnknownTarget
Definition: SCR_AIUtilityComponent.c:22
m_ThreatSystem
ref SCR_AIThreatSystem m_ThreatSystem
Definition: SCR_AIUtilityComponent.c:16
EOnInit
override void EOnInit(IEntity owner)
Definition: SCR_AIUtilityComponent.c:245
SCR_AIDebug
Game core which persists through whole game and stores various data for AI debugging.
Definition: SCR_AIDebug.c:3
SCR_AIMessageInfo
Definition: SCR_AIMessage.c:95
SCR_AICommsHandler
Definition: SCR_AICommsHandler.c:19
m_AIInfo
SCR_AIInfoComponent m_AIInfo
Definition: SCR_AIUtilityComponent.c:11
EvaluateActions
void EvaluateActions(notnull array< SCR_BaseEditorAction > actions, vector cursorWorldPosition, out notnull array< ref SCR_EditorActionData > filteredActions, out int flags=0)
Definition: SCR_BaseActionsEditorComponent.c:184
CallActionsOnMessage
proto external bool CallActionsOnMessage(AIMessage msg)
SCR_AIGetInVehicle
Definition: SCR_AIVehicleBehavior.c:37
DiagIncreaseCounter
void DiagIncreaseCounter()
Definition: SCR_AIBaseUtilityComponent.c:44
SCR_AIBehaviorBase
Definition: SCR_AIBehavior.c:1
m_fLastUpdateTime
protected float m_fLastUpdateTime
Definition: SCR_AIUtilityComponent.c:25
SCR_AIThreatSystem
Definition: SCR_AIThreatSystem.c:17
SCR_AICompartmentHandling
Definition: SCR_AIUtils.c:76
m_OwnerEntity
SCR_AIUtilityComponentClass m_OwnerEntity
category
params category
Definition: SCR_VehicleDamageManagerComponent.c:180