Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_AIAgentDebugPanel.c
Go to the documentation of this file.
1 
4 class SCR_AIAgentDebugPanel : Managed
5 {
6  AIAgent m_Agent;
7  SCR_AIGroup m_Group;
8  IEntity m_Entity;
9  protected bool m_bRequestClose = false;
10 
11  protected string m_sWindowTitle;
12 
13  protected bool m_bShowPerception;
14 
15  // The debug panel can be created for non-AI as well, for instance for vehicles.
16  void SCR_AIAgentDebugPanel(AIAgent agent, IEntity entity)
17  {
18  m_Agent = agent;
19  m_Group = SCR_AIGroup.Cast(agent);
20  m_Entity = entity;
21  }
22 
23  bool Update(float timeSlice)
24  {
25  IEntity objForTitle;
26  if (m_Agent)
27  objForTitle = m_Agent;
28  else if (m_Entity)
29  objForTitle = m_Entity;
30  if (m_sWindowTitle.IsEmpty())
31  {
32  string entityPtrStr = GetEntityShortName(objForTitle);
33  m_sWindowTitle = string.Format("DbgPnl %1", entityPtrStr);
34  }
35 
36  DbgUI.Begin(m_sWindowTitle);
37 
38  SCR_AIInfoBaseComponent baseInfoComp;
39  SCR_AIInfoComponent infoComp; // For units
40  SCR_AIGroupInfoComponent groupInfoComp; // For groups
41  SCR_AIGroupUtilityComponent groupUtilityComp;
42  SCR_MailboxComponent mailboxComp;
43  PerceptionComponent perception;
44  PerceivableComponent perceivable;
45  SCR_AIBaseUtilityComponent utilityComp;
46  SCR_AIUtilityComponent unitUtilityComp;
47  SCR_AICombatComponent combatComp;
48 
49  if (!m_Agent && !m_Group && !m_Entity)
50  {
51  DbgUI.Text("The target doesn't exist!");
52  }
53  else
54  {
55  // Agent name
56  string agentName = GetAgentDebugName();
57  DbgUI.Text(agentName);
58 
59  if (m_Agent)
60  {
61  baseInfoComp = SCR_AIInfoBaseComponent.Cast(m_Agent.FindComponent(SCR_AIInfoBaseComponent));
62  infoComp = SCR_AIInfoComponent.Cast(baseInfoComp);
63  groupInfoComp = SCR_AIGroupInfoComponent.Cast(baseInfoComp);
64  mailboxComp = SCR_MailboxComponent.Cast(m_Agent.FindComponent(SCR_MailboxComponent));
65  utilityComp = SCR_AIBaseUtilityComponent.Cast(m_Agent.FindComponent(SCR_AIBaseUtilityComponent));
66  groupUtilityComp = SCR_AIGroupUtilityComponent.Cast(utilityComp);
67  unitUtilityComp = SCR_AIUtilityComponent.Cast(utilityComp);
68  }
69 
70 
71  if (m_Entity)
72  {
73  combatComp = SCR_AICombatComponent.Cast(m_Entity.FindComponent(SCR_AICombatComponent));
74  perception = PerceptionComponent.Cast(m_Entity.FindComponent(PerceptionComponent));
75  perceivable = PerceivableComponent.Cast(m_Entity.FindComponent(PerceivableComponent));
76  }
77 
78  if (m_Agent)
79  DbgUI.Text(string.Format("LOD: %1", m_Agent.GetLOD()));
80 
81  if (infoComp)
82  {
83  string strUnitState = string.Format("Unit State: %1", EnumFlagsToString(EUnitState, infoComp.GetUnitStates()));
84  string strUnitRoles = string.Format("Unit Roles: %1", EnumFlagsToString(EUnitRole, infoComp.GetRoles()));
85  string strUnitBusy = string.Format("Unit Busy: %1", typename.EnumToString(EUnitAIState, infoComp.GetAIState()));
86  DbgUI.Text(strUnitState);
87  DbgUI.Text(strUnitRoles);
88  DbgUI.Text(strUnitBusy);
89  }
90  else if (groupInfoComp)
91  {
92  DbgUI.Text(string.Format("Control Mode: %1", typename.EnumToString(EGroupControlMode, groupInfoComp.GetGroupControlMode())));
93  }
94 
95  if (combatComp)
96  {
97  EAICombatType combatType = combatComp.GetCombatType();
98  BaseTarget currentEnemy = combatComp.GetCurrentTarget();
99  EAICombatActions allowedActions = combatComp.GetAllowedActions();
100  DbgUI.Text(string.Format("Combat Type: %1", typename.EnumToString(EAICombatType, combatType)));
101  DbgUI.Text(string.Format("Enemy: %1", currentEnemy.ToString()));
102  DbgUI.Text(string.Format("Allowed actions: %1", EnumFlagsToString(EAICombatActions, allowedActions)));
103  }
104 
105  if (mailboxComp)
106  {
107  int nRxMessages = mailboxComp.GetMessageCount();
108  int nRxOrders = mailboxComp.GetOrderCount();
109  int nRxDangers = m_Agent.GetDangerEventsCount();
110  DbgUI.Text(string.Format("Mailbox Queue: Msg: %1, Order: %2, Dngr: %3", nRxMessages, nRxOrders, nRxDangers));
111  }
112 
113  // Utility component actions
114  if (utilityComp)
115  {
116  // Threat
117  if (unitUtilityComp)
118  {
119  EAIThreatState threatState = unitUtilityComp.m_ThreatSystem.GetState();
120  DbgUI.Text(string.Format("Threat: %1 %2", unitUtilityComp.m_ThreatSystem.GetThreatMeasure().ToString(6, 3), typename.EnumToString(EAIThreatState, threatState)));
121  }
122 
123  AIActionBase currentAction = utilityComp.GetCurrentAction();
124  if (!currentAction)
125  DbgUI.Text("Current Action: null");
126  else
127  {
128  DbgUI.Text("Current Action:");
129  float actionPriority = currentAction.Evaluate() + currentAction.EvaluatePriorityLevel();
130  string currentActionStr = string.Format(" > %1 %2", actionPriority.ToString(5, 1), currentAction.Type().ToString());
131  DbgUI.Text(currentActionStr);
132  }
133 
134  // Spinner
135  array<string> spinnerStrings = {"[|]", "[/]", "[-]", "[\\]"};
136  string strSpinner = spinnerStrings[utilityComp.DiagGetCounter() % spinnerStrings.Count()];
137 
138  DbgUI.Text(string.Format("%1 Actions:", strSpinner));
139  array<ref AIActionBase> allActions = {};
140  utilityComp.GetActions(allActions);
141  foreach (int i, AIActionBase action : allActions)
142  {
143  string actionStr = GetActionString(action, i);
144  DbgUI.Text(actionStr);
145 
146  SCR_AICompositeActionParallel compositeAction = SCR_AICompositeActionParallel.Cast(action);
147  if (compositeAction)
148  {
149  array<AIActionBase> subactions = {};
150  compositeAction.GetSubactions(subactions);
151  foreach (AIActionBase subaction : subactions)
152  {
153  string subactionStr = " " + GetActionString(subaction, i);
154  DbgUI.Text(subactionStr);
155  }
156  }
157  }
158 
159  delete allActions;
160  }
161 
162  if (groupUtilityComp)
163  {
164  DbgUI.Text(groupUtilityComp.m_FireteamMgr.DiagGetFireteamsData());
165  }
166 
167  // Dump debug messages button
168  if (baseInfoComp)
169  {
170  int dumpDbgMsgsDuration;
171  EAIDebugMsgType dbgMsgType;
172  DbgUI.Text("Dump Debug Messages:");
173 
174  DbgUI.Combo("Age", dumpDbgMsgsDuration, {"All", "120 sec", "30 sec", "5 sec"});
175 
176  int dbgMsgTypeSelection;
177  array<string> dbgMsgTypeNames = {};
178  dbgMsgTypeNames.Copy(SCR_AIDebugMessage.s_aAiDebugMsgTypeLabels);
179  dbgMsgTypeNames.InsertAt("All", 0);
180  DbgUI.SameLine();
181  DbgUI.Combo("Type", dbgMsgTypeSelection, dbgMsgTypeNames);
182  dbgMsgType = dbgMsgTypeSelection - 1;
183  bool useDbgMsgTypeFilter = dbgMsgTypeSelection != 0;
184 
185  DbgUI.SameLine();
186  bool dumpMsgs = DbgUI.Button("Dump");
187 
188  if (dumpMsgs)
189  {
190  int msgAgeThresholdMs;
191  switch (dumpDbgMsgsDuration)
192  {
193  case 0: msgAgeThresholdMs = -1; break;
194  case 1: msgAgeThresholdMs = 120*1000; break;
195  case 2: msgAgeThresholdMs = 30*1000; break;
196  case 3: msgAgeThresholdMs = 5*1000; break;
197  }
198  #ifdef AI_DEBUG
199  baseInfoComp.DumpDebugMessages(useTypeFilter: useDbgMsgTypeFilter, msgTypeFilter: dbgMsgType, ageThresholdMs: msgAgeThresholdMs);
200  #endif
201  }
202  }
203 
204  // Request breakpoint button
205  if (utilityComp)
206  {
207  DbgUI.Text("Breakpoint At:");
208  DbgUI.SameLine();
209  bool rqBreak = DbgUI.Button("Utility Comp.");
210  if (rqBreak && utilityComp)
211  {
212  utilityComp.DiagSetBreakpoint();
213  }
214  }
215 
216  // Show perceivable component
217  if (perceivable)
218  {
219  bool showPerceivable;
220  DbgUI.Check("Show Perceivable", showPerceivable);
221  if (showPerceivable)
222  {
223  ShowPerceivableComponent(perceivable);
224  }
225  }
226 
227  // Show perception
228  if (perception && combatComp)
229  {
230  DbgUI.Check("Show Targets", m_bShowPerception);
231  if (m_bShowPerception)
232  {
233  ShowPerceptionEnemies(m_Entity, perception, combatComp);
234  }
235  }
236 
237  // Show combat move state
238  if (unitUtilityComp && unitUtilityComp.m_CombatMoveState)
239  {
240  bool showCombatMoveState;
241  DbgUI.Check("Show combat move state", showCombatMoveState);
242  if (showCombatMoveState)
243  {
244  ShowCombatMoveState(unitUtilityComp.m_CombatMoveState);
245  }
246  }
247  }
248 
249  // Close button
250  m_bRequestClose = DbgUI.Button("Close");
251 
252  // Locate button
253  DbgUI.SameLine();
254  bool locate = DbgUI.Button("Locate");
255  if (locate)
256  {
257  array<string> locateTexts = {"I am here!", "Look at me!", "Hey! Look here!", "Here I am!"};
258  IEntity ent;
259  if (m_Agent)
260  ent = m_Agent.GetControlledEntity();
261  else if (m_Group)
262  ent = m_Group;
263  else
264  ent = m_Entity;
265  SCR_AIDebugVisualization.VisualizeMessage(ent, locateTexts.GetRandomElement(), EAIDebugCategory.NONE, 0.75, Color.FromInt(Color.RED), fontSize: 20, ignoreCategory: true);
266  }
267 
268  // Kill button
269  if (m_Agent && !m_Group)
270  {
271  DbgUI.SameLine();
272  bool forceDeath = DbgUI.Button("Kill");
273  if (forceDeath)
274  {
275  CharacterControllerComponent cntrlComp = CharacterControllerComponent.Cast(m_Entity.FindComponent(CharacterControllerComponent));
276  if (cntrlComp)
277  cntrlComp.ForceDeath();
278  }
279  }
280 
281  DbgUI.End();
282 
283  return m_bRequestClose;
284  }
285 
286  string GetActionString(AIActionBase action, int actionId)
287  {
288  float actionPriority = action.Evaluate() + action.EvaluatePriorityLevel();
289  string strState = string.Format("(%1)", typename.EnumToString(EAIActionState, action.GetActionState()) );
290 
291  string debugText;
292  SCR_AIActionBase scrActionBase = SCR_AIActionBase.Cast(action);
293  if (scrActionBase)
294  debugText = scrActionBase.GetDebugPanelText();
295 
296  string actionStr = string.Format(" %1 %2 %3 %4 %5", actionId, strState, actionPriority.ToString(5, 1), action.Type().ToString(), debugText);
297 
298  return actionStr;
299  }
300 
302  void ShowPerceptionEnemies(IEntity myEntity, PerceptionComponent perception, SCR_AICombatComponent combatComponent)
303  {
304  vector myPos = myEntity.GetOrigin();
305 
306 
307  // Resolve which types to show
308  bool showUnknown;
309  bool showFriendly;
310  bool showEnemy;
311  DbgUI.Check(" Show Unknown", showUnknown);
312  DbgUI.Check(" Show Friendly", showFriendly);
313  DbgUI.Check(" Show Enemy", showEnemy);
314 
315 
316  array<ETargetCategory> targetCategories = {};
317  if (showUnknown)
318  targetCategories.Insert(ETargetCategory.UNKNOWN);
319  if (showFriendly)
320  targetCategories.Insert(ETargetCategory.FRIENDLY);
321  if (showEnemy)
322  {
323  targetCategories.Insert(ETargetCategory.DETECTED);
324  targetCategories.Insert(ETargetCategory.ENEMY);
325  }
326 
327  FactionAffiliationComponent myFactionComp = FactionAffiliationComponent.Cast(myEntity.FindComponent(FactionAffiliationComponent));
328  Faction myFaction = myFactionComp.GetAffiliatedFaction();
329 
330  BaseTarget selectedTarget = combatComponent.GetCurrentTarget();
331 
332  DbgUI.Text("[ID Category TimeSinceSeen Dngr Type (Exp TraceFraction) (Detect Ident Sound)]");
333 
334  array<BaseTarget> targets = {};
335  int targetId = 0;
336  foreach (ETargetCategory targetCategory : targetCategories)
337  {
338  targets.Clear();
339  perception.GetTargetsList(targets, targetCategory);
340  foreach (int i, BaseTarget baseTarget : targets)
341  {
342  IEntity targetEntity = baseTarget.GetTargetEntity();
343  if (!targetEntity)
344  continue;
345 
346  // Don't list target if it has same faction as we do
347  //FactionAffiliationComponent targetFactionComp = FactionAffiliationComponent.Cast(targetEntity.FindComponent(FactionAffiliationComponent));
348  //if (targetFactionComp)
349  //{
350  // if (targetFactionComp.GetAffiliatedFaction() == myFaction)
351  // continue;
352  //}
353 
354  EntityPrefabData prefabData = targetEntity.GetPrefabData();
355  ResourceName prefabName = prefabData.GetPrefabName();
356 
357  /*
358  array<IEntity> __entities = {};
359  array<ResourceName> __prefabNames = {};
360 
361  Print(string.Format("Target: %1", targetEntity));
362  IEntity __parent = targetEntity;
363  while (__parent)
364  {
365  __entities.Insert(__parent);
366  ResourceName __prefabName = __parent.GetPrefabData().GetPrefabName();
367  __prefabNames.Insert(__prefabName);
368 
369  Print(string.Format(" %1 %2", __parent, __prefabName));
370 
371  __parent = __parent.GetParent();
372  }
373 
374  Print(" ");
375  */
376 
377  string strTimeSinceSeenOrDetected = string.Format("(%1 %2)",
378  baseTarget.GetTimeSinceSeen().ToString(4, 1),
379  baseTarget.GetTimeSinceDetected().ToString(4, 1));
380  string strState;
381  if (baseTarget.IsEndangering())
382  strState = strState + "DNGR ";
383  if (baseTarget.IsDisarmed())
384  strState = strState + "DISARMED ";
385 
386  array<string> substrings = {};
387  substrings.Clear();
388  string strPrefabName = string.Empty;
389  if (!prefabName.IsEmpty())
390  {
391  prefabName.Split("/", substrings, true);
392  if (!substrings.IsEmpty())
393  strPrefabName = substrings[substrings.Count()-1];
394  }
395 
396  string strSelected = " ";
397  if (selectedTarget == baseTarget)
398  strSelected = ">";
399 
400  string strDistance = vector.Distance(myPos, targetEntity.GetOrigin()).ToString(5, 2);
401 
402  string strType = typename.EnumToString(EAIUnitType, baseTarget.GetUnitType());
403 
404  float recognitionDetect;
405  float recognitionIdentify;
406  baseTarget.GetAccumulatedRecognition(recognitionDetect, recognitionIdentify);
407 
408  // Same code as in ears sensor
409  float emittedSoundPower = baseTarget.GetPerceivableComponent().GetSoundPower();
410  float targetDistance = baseTarget.GetDistance();
411  float observedSoundIntensity = -999;
412  if (targetDistance != 0)
413  observedSoundIntensity = emittedSoundPower / (4.0 * Math.PI * targetDistance * targetDistance);
414  string strSoundIntensity;
415  if (observedSoundIntensity != 0)
416  strSoundIntensity = string.Format("%1 dB", (10*Math.Log10(observedSoundIntensity/1e-12)).ToString(5,1));
417  else
418  strSoundIntensity = "-inf dB";
419 
420  string strExposure = string.Format("(%1 %2) ", baseTarget.GetExposure().ToString(3,2), baseTarget.GetTraceFraction().ToString(3, 2));
421 
422  string strRecognition = string.Format("(%1 %2 %3)", recognitionDetect.ToString(3, 2), recognitionIdentify.ToString(3, 2), strSoundIntensity);
423 
424  string str = string.Format("%1 %2 %3 %4s %5 %6 %7 %8",
425  targetId, // 1
426  strSelected, // 2
427  typename.EnumToString(ETargetCategory, targetCategory), // 3
428  strTimeSinceSeenOrDetected, // 4
429  strState, // 5
430  strType, // 6
431  strExposure, // 7
432  strRecognition); // 8
433  DbgUI.Text(str);
434 
435  DbgUI.Text(string.Format("%1 %2 %3", targetId, GetEntityShortName(targetEntity), strPrefabName));
436 
437  bool showRecognition = false;
438  DbgUI.Check(string.Format("%1 Recognition", targetId), showRecognition);
439  if (showRecognition)
440  {
441 
442  DbgUI.Text(string.Format("%1 Exp: %2, Rec: Detect: %3 Identify: %4",
443  targetId, baseTarget.GetExposure().ToString(3, 2), recognitionDetect.ToString(3, 2), recognitionIdentify.ToString(3, 2)));
444 
445  int plotWidth = 200;
446  int plotHeight = 150;
447  int plotHistory = 800;
448  DbgUI.PlotLive(string.Format("%1 Detection", targetId), plotWidth, plotHeight, recognitionDetect, 300);
449  DbgUI.PlotLive(string.Format("%1 Identification", targetId), plotWidth, plotHeight, recognitionIdentify, 300);
450  }
451 
452  targetId++;
453  }
454  }
455  }
456 
457  void ShowPerceivableComponent(PerceivableComponent p)
458  {
459  DbgUI.Text("Recognition Factors:");
460  DbgUI.Text(string.Format(" Visual: %1", p.GetVisualRecognitionFactor()));
461  DbgUI.Text(string.Format(" Illumination: %1", p.GetIlluminationFactor()));
462  DbgUI.Text(string.Format(" Sound pwr: %1 dB", 10*Math.Log10(p.GetSoundPower()/1e-12)));
463  DbgUI.Text(string.Format("Est. visual size: %1", p.GetEstimatedVisualSize()));
464  DbgUI.Text(string.Format("Ambient LV: %1", p.GetAmbientLV()));
465  }
466 
467  void ShowCombatMoveState(SCR_AICombatMoveState s)
468  {
469  string strRqType;
470  string strRqState;
471 
472  if (s.GetRequest())
473  {
474  strRqType = s.GetRequest().ToString();
475  strRqState = typename.EnumToString(SCR_EAICombatMoveRequestState, s.GetRequest().m_eState);
476  }
477  else
478  {
479  strRqType = "-";
480  strRqState = "-";
481  }
482 
483  DbgUI.Text(string.Format("Request Type: %1", strRqType));
484  DbgUI.Text(string.Format("Request State: %1", strRqState));
485  DbgUI.Text(string.Format("TimerRequest: %1", s.m_fTimerRequest_s.ToString(5,2)));
486  DbgUI.Text(string.Format("TimerInCover: %1", s.m_fTimerInCover_s.ToString(5,2)));
487  DbgUI.Text(string.Format("TimerStopped: %1", s.m_fTimerStopped_s.ToString(5,2)));
488 
489  string str;
490  if (s.m_bInCover)
491  str = str + "IN_COVER ";
492  if (s.m_bExposedInCover)
493  str = str + "EXPOSED_IN_COVER ";
494  if (s.m_bAimAtTarget)
495  str = str + "AIM_AT_TARGET";
496  if (!str.IsEmpty())
497  DbgUI.Text(str);
498  }
499 
501  string GetAgentDebugName()
502  {
503  if (m_Group)
504  {
505  // Group
506  string company, platoon, squad, character, format, returnString;
507  m_Group.GetCallsigns(company, platoon, squad, character, format);
508  returnString.Format(format, company, platoon, squad, character);
509  return returnString;
510 
511  }
512  else if (m_Agent)
513  {
514  // Unit
515  SCR_CallsignCharacterComponent callsignComp = SCR_CallsignCharacterComponent.Cast(m_Agent.GetControlledEntity().FindComponent(SCR_CallsignCharacterComponent));
516 
517  FactionAffiliationComponent factionComp = FactionAffiliationComponent.Cast(m_Agent.GetControlledEntity().FindComponent(FactionAffiliationComponent));
518 
519  string str;
520 
521  if (factionComp)
522  {
523  string faction = factionComp.GetAffiliatedFaction().GetFactionKey();
524  str = str + string.Format("[%1] ", faction);
525  }
526 
527  if (callsignComp)
528  {
529  string company, platoon, squad, character, format;
530  bool setCallsign = callsignComp.GetCallsignNames(company, platoon, squad, character, format);
531  if (setCallsign)
532  {
533  string callsign = WidgetManager.Translate(format, company, platoon, squad, character);
534  str = str + string.Format(" %1", callsign);
535  }
536  }
537  return str;
538  }
539  else
540  {
541  return string.Empty;
542  }
543  }
544 
546  static string EnumFlagsToString(typename t, int value)
547  {
548  int tVarCount = t.GetVariableCount();
549  string strOut;
550  for (int i = 0; i < tVarCount; i++)
551  {
552  int flag;
553  t.GetVariableValue(null, i, flag);
554  if (value & flag)
555  strOut = strOut + string.Format("%1 ", typename.EnumToString(t, flag));
556  }
557  return strOut;
558  }
559 
560  static string GetEntityShortName(IEntity entity)
561  {
562  string entityRawName = string.Format("%1", entity);
563  int _a = entityRawName.IndexOf("<");
564  int _b = entityRawName.IndexOfFrom(_a, ">");
565  string entityPtrStr = entityRawName.Substring(_a+1, _b - _a - 1);
566  return entityPtrStr;
567  }
568 };
SCR_AIDebugVisualization
Definition: SCR_AIDebugVisualization.c:9
EAIDebugMsgType
EAIDebugMsgType
Definition: SCR_AIDebugMessage.c:1
m_Agent
SCR_ChimeraAIAgent m_Agent
Definition: SCR_AIActivitySmokeCoverFeature.c:42
SCR_AIActionBase
Definition: SCR_AIAction.c:1
ETargetCategory
ETargetCategory
Definition: ETargetCategory.c:12
m_Group
protected SCR_AIGroup m_Group
Definition: SCR_CallsignGroupComponent.c:10
m_Entity
enum EAITargetInfoCategory m_Entity
BaseTarget
Definition: BaseTarget.c:12
AIActionBase
Definition: AIActionBase.c:12
EAIDebugCategory
EAIDebugCategory
Definition: SCR_AIWorld.c:11
SCR_AIDebugMessage
Definition: SCR_AIDebugMessage.c:17
EAIUnitType
EAIUnitType
Definition: EAIUnitType.c:12
Faction
Definition: Faction.c:12
SCR_AICompositeActionParallel
Definition: SCR_AICompositeActionParallel.c:1
SCR_AIGroup
Definition: SCR_AIGroup.c:68
SCR_EAICombatMoveRequestState
SCR_EAICombatMoveRequestState
Definition: SCR_AICombatMoveState.c:1
EAIActionState
EAIActionState
Definition: EAIActionState.c:12
SCR_AIAgentDebugPanel
Definition: SCR_AIAgentDebugPanel.c:4