Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_AIInfoComponent.c
Go to the documentation of this file.
1 [ComponentEditorProps(category: "GameScripted/AI", description: "Component for AI checking state of characters")]
3 {
4 }
5 
6 enum EUnitRole
7 {
8  NONE = 0,
9  RIFLEMAN = 1,
10  MEDIC = 2,
11  MACHINEGUNNER = 4,
12  AT_SPECIALIST = 8,
13  GRENADIER = 16,
14  SNIPER = 32,
15  HAS_SMOKE_GRENADE = 64,
16  HAS_FRAG_GRENADE = 128
17 }
18 
19 enum EUnitState
20 {
21  NONE = 0,
22  WOUNDED = 1,
23  IN_TURRET = 2,
24  IN_VEHICLE = 4,
25  UNCONSCIOUS = 8
26 }
27 
28 enum EUnitAIState
29 {
30  AVAILABLE,
31  BUSY,
32  UNRESPONSIVE,
33 }
34 
35 class SCR_AIInfoComponent : SCR_AIInfoBaseComponent
36 {
37  protected EUnitState m_iUnitStates;
38  protected EUnitAIState m_iAIStates;
39  protected SCR_InventoryStorageManagerComponent m_inventoryManagerComponent;
40  protected BaseWeaponManagerComponent m_weaponManagerComponent;
41  protected SCR_CompartmentAccessComponent m_CompartmentAccessComponent;
44  protected SCR_AICombatComponent m_CombatComponent;
46  PerceptionComponent m_Perception;
47 
48  protected SCR_CharacterBloodHitZone m_BloodHitZone;
49  protected float m_fUnconsciousBloodLevel;
50 
51  protected ECharacterStance m_eStance;
53  protected bool m_bWeaponRaised;
54  protected int m_iAttackCount;
55  protected int m_unitID;
56 
57  //------------------------------------------------------------------------------------------------
58  override protected void OnPostInit(IEntity owner)
59  {
60  super.OnPostInit(owner);
61  SetEventMask(owner, EntityEvent.INIT);
62  }
63 
64  //------------------------------------------------------------------------------------------------
69  void OnVehicleEntered( IEntity vehicle, BaseCompartmentManagerComponent manager, int mgrID, int slotID )
70  {
71  BaseCompartmentSlot compSlot = manager.FindCompartment(slotID, mgrID);
72  if (TurretCompartmentSlot.Cast(compSlot))
73  AddUnitState(EUnitState.IN_TURRET);
74  }
75 
76  //------------------------------------------------------------------------------------------------
81  void OnVehicleLeft( IEntity vehicle, BaseCompartmentManagerComponent manager, int mgrID, int slotID )
82  {
83  auto aiworld = SCR_AIWorld.Cast(GetGame().GetAIWorld());
84  if (!aiworld)
85  return;
86  BaseCompartmentSlot compSlot = manager.FindCompartment(slotID, mgrID);
87  if (!TurretCompartmentSlot.Cast(compSlot))
88  return;
89 
90  RemoveUnitState(EUnitState.IN_TURRET);
91  }
92 
93 
94  //------------------------------------------------------------------------------------------------
96  void InitBloodLevel()
97  {
98  m_BloodHitZone = SCR_CharacterBloodHitZone.Cast(m_DamageManager.GetBloodHitZone());
99  if (m_BloodHitZone)
100  m_fUnconsciousBloodLevel = m_BloodHitZone.GetMaxHealth() * m_BloodHitZone.GetDamageStateThreshold(EDamageState.STATE3);
101  }
102 
103  //------------------------------------------------------------------------------------------------
104  override protected void EOnInit(IEntity owner)
105  {
106  IEntity ent = owner;
107  AIAgent agent = AIAgent.Cast(owner);
108  if (agent)
109  ent = agent.GetControlledEntity();
110 
111  if (ent)
112  {
113  m_inventoryManagerComponent = SCR_InventoryStorageManagerComponent.Cast(ent.FindComponent(SCR_InventoryStorageManagerComponent));
114  m_weaponManagerComponent = BaseWeaponManagerComponent.Cast(ent.FindComponent(BaseWeaponManagerComponent));
115  m_CompartmentAccessComponent = SCR_CompartmentAccessComponent.Cast(ent.FindComponent(SCR_CompartmentAccessComponent));
117  m_CombatComponent = SCR_AICombatComponent.Cast(ent.FindComponent(SCR_AICombatComponent));
118 
121  m_CharacterController.m_OnLifeStateChanged.Insert(OnLifeStateChanged);
122 
123  m_Perception = PerceptionComponent.Cast(ent.FindComponent(PerceptionComponent));
124  }
125 
126  if (m_CompartmentAccessComponent)
127  {
128  m_CompartmentAccessComponent.GetOnCompartmentEntered().Insert(OnVehicleEntered);
129  m_CompartmentAccessComponent.GetOnCompartmentLeft().Insert(OnVehicleLeft);
130  }
131 
132  if (m_DamageManager)
133  {
134  InitBloodLevel();
135  m_DamageManager.GetOnDamageOverTimeAdded().Insert(OnDamageOverTimeAdded);
136  m_DamageManager.GetOnDamageOverTimeRemoved().Insert(OnDamageOverTimeRemoved);
137  EvaluateWoundedState();
138  }
139  }
140 
141  //------------------------------------------------------------------------------------------------
142  // destructor
143  void ~SCR_AIInfoComponent()
144  {
146  m_CharacterController.m_OnLifeStateChanged.Remove(OnLifeStateChanged);
147  }
148 
149  //------------------------------------------------------------------------------------------------
150  override protected void OnDelete(IEntity owner)
151  {
152  if (m_CompartmentAccessComponent)
153  {
154  m_CompartmentAccessComponent.GetOnCompartmentEntered().Remove(OnVehicleEntered);
155  m_CompartmentAccessComponent.GetOnCompartmentLeft().Remove(OnVehicleLeft);
156  }
157 
158  if (m_DamageManager)
159  {
160  m_DamageManager.GetOnDamageOverTimeAdded().Remove(OnDamageOverTimeAdded);
161  m_DamageManager.GetOnDamageOverTimeRemoved().Remove(OnDamageOverTimeRemoved);
162  }
163  }
164 
165  //------------------------------------------------------------------------------------------------
169  bool IsOwnerAgent(AIAgent agent)
170  {
171  return GetOwner() == agent;
172  }
173 
174 //----------- BIT operations on Roles
175 
176  //------------------------------------------------------------------------------------------------
180  bool HasRole(EUnitRole role)
181  {
182  switch (role)
183  {
184  case EUnitRole.MEDIC: return m_inventoryManagerComponent.GetHealthComponentCount() > 0;
185  case EUnitRole.MACHINEGUNNER: return m_CombatComponent.HasWeaponOfType(EWeaponType.WT_MACHINEGUN);
186  case EUnitRole.RIFLEMAN: return m_CombatComponent.HasWeaponOfType(EWeaponType.WT_RIFLE);
187  case EUnitRole.AT_SPECIALIST: return m_CombatComponent.HasWeaponOfType(EWeaponType.WT_ROCKETLAUNCHER);
188  case EUnitRole.GRENADIER: return m_CombatComponent.HasWeaponOfType(EWeaponType.WT_GRENADELAUNCHER); // todo right now it will not detect a UGL muzzle, because weapon type is still rifle
189  case EUnitRole.SNIPER: return m_CombatComponent.HasWeaponOfType(EWeaponType.WT_SNIPERRIFLE);
190  case EUnitRole.HAS_SMOKE_GRENADE: return m_CombatComponent.HasWeaponOfType(EWeaponType.WT_SMOKEGRENADE);
191  case EUnitRole.HAS_FRAG_GRENADE: return m_CombatComponent.HasWeaponOfType(EWeaponType.WT_FRAGGRENADE);
192  }
193 
194  return false;
195  }
196 
197  //------------------------------------------------------------------------------------------------
200  EUnitRole GetRoles()
201  {
202  typename t = EUnitRole;
203  int tVarCount = t.GetVariableCount();
204  EUnitRole roles = 0;
205  for (int i = 0; i < tVarCount; i++)
206  {
207  EUnitRole flag;
208  t.GetVariableValue(null, i, flag);
209  if (flag && HasRole(flag))
210  roles |= flag;
211  }
212  return roles;
213  }
214 
215 //---------- BIT operation on States
216 
217  //------------------------------------------------------------------------------------------------
220  void AddUnitState(EUnitState state)
221  {
222  m_iUnitStates = m_iUnitStates | state;
223  }
224 
225  //------------------------------------------------------------------------------------------------
228  void RemoveUnitState(EUnitState state)
229  {
230  if (HasUnitState(state))
231  m_iUnitStates = m_iUnitStates & ~state;
232  }
233 
234  //------------------------------------------------------------------------------------------------
238  bool HasUnitState(EUnitState state)
239  {
240  return ( m_iUnitStates & state );
241  }
242 
243  //------------------------------------------------------------------------------------------------
246  EUnitState GetUnitStates()
247  {
248  return m_iUnitStates;
249  }
250 
251 //--------- AI states are disjoined - one can be in only one state at the time
252 
253  //------------------------------------------------------------------------------------------------
255  void SetAIState(EUnitAIState state)
256  {
257  m_iAIStates = state;
258  }
259 
260  //------------------------------------------------------------------------------------------------
262  EUnitAIState GetAIState()
263  {
264  return m_iAIStates;
265  }
266 
267 //-------- Info about magazines available to SCR_AIResupplyActivity
268 
269  //------------------------------------------------------------------------------------------------
272  int GetMagazineCountByWellType(typename magazinyWellType)
273  {
274  return m_CombatComponent.GetMagazineCount(magazinyWellType, false);
275  }
276 
277 //-------- Set or get AI stance, speed, raising weapon etc.
278 
279  //------------------------------------------------------------------------------------------------
281  void SetStance(ECharacterStance stance)
282  {
283  m_eStance = stance;
284  }
285 
286  //------------------------------------------------------------------------------------------------
289  {
290  return m_eStance;
291  }
292 
293  //------------------------------------------------------------------------------------------------
295  void SetMovementType(EMovementType mode)
296  {
297  m_eMovementType = mode;
298  }
299 
300  //------------------------------------------------------------------------------------------------
302  EMovementType GetMovementType()
303  {
304  return m_eMovementType;
305  }
306 
307  //------------------------------------------------------------------------------------------------
309  void SetWeaponRaised(bool raised)
310  {
311  m_bWeaponRaised = raised;
312  }
313 
314  //------------------------------------------------------------------------------------------------
316  bool GetWeaponRaised()
317  {
318  return m_bWeaponRaised;
319  }
320 
321  //------------------------------------------------------------------------------------------------
324  void InitThreatSystem(SCR_AIThreatSystem threatSystem)
325  {
326  m_ThreatSystem = threatSystem;
327  }
328 
329  //------------------------------------------------------------------------------------------------
331  EAIThreatState GetThreatState()
332  {
333  if (m_ThreatSystem)
334  return m_ThreatSystem.GetState();
335  else
336  return EAIThreatState.SAFE;
337  }
338 
339  //------------------------------------------------------------------------------------------------
341  SCR_AIThreatSystem GetThreatSystem()
342  {
343  return m_ThreatSystem;
344  }
345 
346 //-------- Evaluation of wounded state of AI
347 
348  //------------------------------------------------------------------------------------------------
350  protected void EvaluateWoundedState()
351  {
352  bool wounded = m_DamageManager.IsDamagedOverTime(EDamageType.BLEEDING);
353  if (wounded)
354  AddUnitState(EUnitState.WOUNDED);
355  else
356  RemoveUnitState(EUnitState.WOUNDED);
357  }
358 
359  //------------------------------------------------------------------------------------------------
360  protected void OnDamageOverTimeAdded(EDamageType dType, float dps, HitZone hz)
361  {
362  if (dType != EDamageType.BLEEDING)
363  return;
364 
365  EvaluateWoundedState();
366  }
367 
368  //------------------------------------------------------------------------------------------------
369  protected void OnDamageOverTimeRemoved(EDamageType dType, HitZone hz)
370  {
371  if (dType != EDamageType.BLEEDING)
372  return;
373 
374  EvaluateWoundedState();
375  }
376 
377  //------------------------------------------------------------------------------------------------
379  void OnLifeStateChanged(ECharacterLifeState previousLifeState, ECharacterLifeState newLifeState)
380  {
381  if (newLifeState != ECharacterLifeState.INCAPACITATED)
382  RemoveUnitState(EUnitState.UNCONSCIOUS);
383  else
384  AddUnitState(EUnitState.UNCONSCIOUS);
385  }
386 
387  //------------------------------------------------------------------------------------------------
389  float GetBleedTimeToUnconscious()
390  {
391  if (!m_BloodHitZone || !m_fUnconsciousBloodLevel)
392  return -1;
393 
394  float bleedingPerSec = m_BloodHitZone.GetDamageOverTime(EDamageType.BLEEDING);
395 
396  float timeToUnconscious = -1;
397 
398  if (bleedingPerSec > 0)
399  timeToUnconscious = (m_BloodHitZone.GetHealth() - m_fUnconsciousBloodLevel) / bleedingPerSec;
400 
401  return timeToUnconscious;
402  }
403 
404 //-------- Debugging
405 
406  //------------------------------------------------------------------------------------------------
409  // Used in SCR_AIDebugInfoComponent
410  void DebugPrintToWidget(TextWidget w)
411  {
412  string str;
413  str = str + string.Format("\n%1 %2", m_iAIStates, typename.EnumToString(EUnitAIState, m_iAIStates));
414  w.SetText(str);
415  }
416 
417  //------------------------------------------------------------------------------------------------
419  string GetBehaviorEditorDebugName()
420  {
421  AIAgent agent = AIAgent.Cast(GetOwner());
422 
423  SCR_CallsignCharacterComponent callsignComp = SCR_CallsignCharacterComponent.Cast(agent.GetControlledEntity().FindComponent(SCR_CallsignCharacterComponent));
424 
425  FactionAffiliationComponent factionComp = FactionAffiliationComponent.Cast(agent.GetControlledEntity().FindComponent(FactionAffiliationComponent));
426 
427  string str;
428 
429  if (factionComp)
430  {
431  string faction = factionComp.GetAffiliatedFaction().GetFactionKey();
432  str = str + string.Format("[%1] ", faction);
433  }
434 
435  if (callsignComp)
436  {
437  string company, platoon, squad, character, format;
438  bool setCallsign = callsignComp.GetCallsignNames(company, platoon, squad, character, format);
439  if (setCallsign)
440  {
441  string callsign = WidgetManager.Translate(format, company, platoon, squad, character);
442  str = str + string.Format(" %1", callsign);
443  }
444  }
445  return str;
446  }
447 }
ComponentEditorProps
SCR_FragmentEntityClass ComponentEditorProps
SCR_CompartmentAccessComponent
Definition: SCR_CompartmentAccessComponent.c:15
ECharacterLifeState
ECharacterLifeState
Definition: ECharacterLifeState.c:12
HitZone
Definition: HitZone.c:12
EMovementType
EMovementType
Definition: EMovementType.c:12
MEDIC
SCR_AIInfoComponentClass MEDIC
OnDamageOverTimeAdded
void OnDamageOverTimeAdded(EDamageType dType, float dps, HitZone hz)
Definition: SCR_VehiclePerceivableComponent.c:36
ECharacterStance
ECharacterStance
Definition: ECharacterStance.c:12
GetStance
proto external ECharacterStance GetStance()
Returns the current stance of the character.
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
OnDelete
override void OnDelete(IEntity owner)
Definition: SCR_CampaignBuildingCompositionComponent.c:538
MACHINEGUNNER
SCR_AIInfoComponentClass MACHINEGUNNER
m_Perception
ref SCR_AIGroupPerception m_Perception
Definition: SCR_AIGroupUtilityComponent.c:33
EDamageState
EDamageState
Definition: EDamageState.c:12
m_CharacterController
SCR_CharacterPerceivableComponentClass m_CharacterController
func
func
Definition: SCR_AIThreatSystem.c:5
UNCONSCIOUS
@ UNCONSCIOUS
Definition: SCR_CharacterHitZone.c:17
SCR_CharacterControllerComponent
Definition: SCR_CharacterControllerComponent.c:35
SCR_AIInfoBaseComponentClass
Definition: SCR_AIInfoBaseComponent.c:2
SCR_CharacterBloodHitZone
Blood - does not receive damage directly, only via scripted events.
Definition: SCR_CharacterHitZone.c:480
SCR_AIWorld
Definition: SCR_AIWorld.c:23
SCR_AIInfoComponentClass
Definition: SCR_AIInfoComponent.c:2
m_eStance
SCR_AICombatMoveRequest_ChangeStanceInCover m_eStance
SCR_CharacterDamageManagerComponent
Definition: SCR_CharacterDamageManagerComponent.c:18
m_eMovementType
EMovementType m_eMovementType
Definition: SCR_AICombatMoveRequest.c:84
TurretCompartmentSlot
Definition: TurretCompartmentSlot.c:12
m_CombatComponent
SCR_AICombatComponent m_CombatComponent
Definition: SCR_AIUtilityComponent.c:12
OnPostInit
override void OnPostInit(IEntity owner)
Called on PostInit when all components are added.
Definition: SCR_AIConfigComponent.c:72
WOUNDED
@ WOUNDED
Definition: SCR_AIMessage.c:5
AT_SPECIALIST
SCR_AIInfoComponentClass AT_SPECIALIST
GetOwner
IEntity GetOwner()
Owner entity of the fuel tank.
Definition: SCR_FuelNode.c:128
SNIPER
SCR_AIInfoComponentClass SNIPER
m_ThreatSystem
ref SCR_AIThreatSystem m_ThreatSystem
Definition: SCR_AIUtilityComponent.c:16
HasRole
proto external bool HasRole(EPlayerRole role)
Returns True if the user has given role assigned.
EOnInit
override void EOnInit(IEntity owner)
Definition: SCR_AIConfigComponent.c:79
SetWeaponRaised
proto external void SetWeaponRaised(bool val)
Set the current weapon-raised state.
OnDamageOverTimeRemoved
void OnDamageOverTimeRemoved(EDamageType dType, HitZone hz)
Definition: SCR_VehiclePerceivableComponent.c:46
EDamageType
EDamageType
Definition: EDamageType.c:12
EWeaponType
EWeaponType
Definition: EWeaponType.c:12
NONE
SCR_AIInfoComponentClass NONE
HAS_SMOKE_GRENADE
SCR_AIInfoComponentClass HAS_SMOKE_GRENADE
m_DamageManager
DamageManagerComponent m_DamageManager
Definition: SCR_AITargetInfo.c:19
RIFLEMAN
SCR_AIInfoComponentClass RIFLEMAN
OnLifeStateChanged
func OnLifeStateChanged
Definition: SCR_CharacterControllerComponent.c:17
GRENADIER
SCR_AIInfoComponentClass GRENADIER
SCR_AIThreatSystem
Definition: SCR_AIThreatSystem.c:17
category
params category
Definition: SCR_VehicleDamageManagerComponent.c:180