Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_AIGetOverwatchMembers.c
Go to the documentation of this file.
1 class SCR_AIGetOverwatchMembers: AITaskScripted
2 {
3  static const string PORT_FIRETEAM_IN = "FireteamIn";
4  static const string PORT_TARGET_IN = "TargetIn";
5  static const string PORT_MOVING_MEMBER_OUT = "MovingMemberOut";
6  static const string PORT_COVERING_MEMBER_OUT = "CoveringMemberOut";
7 
8  SCR_AIGroupUtilityComponent m_GroupUtilityComponent;
9 
10  int m_selectedIndexForMovement = 0, m_selectedIndexForCovering = 0;
11 
12  //------------------------------------------------------------------------------------------------
13  override bool VisibleInPalette() {return true;}
14 
15  //------------------------------------------------------------------------------------------------
16  override void OnInit(AIAgent owner)
17  {
18  AIGroup group = AIGroup.Cast(owner);
19  if (group)
20  m_GroupUtilityComponent = SCR_AIGroupUtilityComponent.Cast(group.FindComponent(SCR_AIGroupUtilityComponent));
21  }
22 
23  // We are selecting always a pair of AI. The one who is moving and other one for covering.
24  // Node will fails if roles are missing and we can never select a pair.
25  // The assumption about selection is that AIs are selected for move till there is only one left who is covering.
26  // So at least one member of fire team is covering the rest.
27  // Node is running till a pair is selected.
28  //------------------------------------------------------------------------------------------------
29  override ENodeResult EOnTaskSimulate(AIAgent owner, float dt)
30  {
31  if (!m_GroupUtilityComponent || !m_GroupUtilityComponent.m_aInfoComponents)
32  return ENodeResult.FAIL;
33 
34  ClearVariable(PORT_MOVING_MEMBER_OUT);
35  ClearVariable(PORT_COVERING_MEMBER_OUT);
36 
37  int teamSelection,length;
38  if (!GetVariableIn(PORT_FIRETEAM_IN,teamSelection))
39  {
40  return NodeError(this, owner, "Missing team selection for this node.");
41  }
42 
43  IEntity targetEntity;
44  if (!GetVariableIn(PORT_TARGET_IN, targetEntity))
45  return NodeError(this, owner, "Missing target entity for this node");
46 
47  if (!targetEntity)
48  return ENodeResult.FAIL;
49 
50  AIAgent agent;
51 
52  bool isCoveringPresent = false, isMovingPresent = false, isCoveringSelected = false, isMovingSelected = false;
53  SCR_AIInfoComponent aIInfoComponent;
54  length = m_GroupUtilityComponent.m_aInfoComponents.Count();
55  if (length <= 1)
56  return ENodeResult.FAIL;
57 
58  // Select moving team member, take furthest member in our fireteam
59  float distMax = 0;
60  int selectedIndexForMovement;
61  int selectedIndexForMovementPrevious = m_selectedIndexForMovement;
62  for (int i = 0; i < length; i++)
63  {
64  aIInfoComponent = m_GroupUtilityComponent.m_aInfoComponents[i];
65  if( !aIInfoComponent )
66  continue;
67 
68  // Handeling of fireteams should be reworked so we can have geter for firetam members insted iteration over whole team each time
69  // todo fix this
70  /*
71  if (aIInfoComponent.GetFireTeam() == teamSelection && aIInfoComponent.HasRole(EUnitRole.RIFLEMAN))
72  {
73  if (aIInfoComponent.GetAIState() == EUnitAIState.AVAILABLE)
74  {
75  isMovingPresent = true;
76 
77  AIAgent memberAgent = AIAgent.Cast(aIInfoComponent.GetOwner());
78  IEntity memberEnt = memberAgent.GetControlledEntity();
79  float distToTarget = vector.Distance(memberEnt.GetOrigin(), targetEntity.GetOrigin());
80 
81  if (distToTarget > distMax)
82  {
83  isMovingSelected = true;
84  m_selectedIndexForMovement = i;
85  distMax = distToTarget;
86  }
87  }
88  }
89  */
90  }
91 
92  if (!isMovingPresent)
93  {
94  return ENodeResult.FAIL;
95  }
96 
97  if (!isMovingSelected)
98  {
99  return ENodeResult.RUNNING;
100  }
101 
102  for (int i = 1; i <= length; i++)
103  {
104  int indexForCover = (i + m_selectedIndexForCovering) % length;
105 
106  if (indexForCover == m_selectedIndexForMovement)
107  continue;
108 
109  aIInfoComponent = m_GroupUtilityComponent.m_aInfoComponents[indexForCover];
110  if( !aIInfoComponent )
111  continue;
112 
113  // todo fix this
114  /*
115  if (aIInfoComponent.GetFireTeam() == teamSelection &&
116  (aIInfoComponent.HasRole(EUnitRole.RIFLEMAN) || aIInfoComponent.HasRole(EUnitRole.MACHINEGUNNER) || aIInfoComponent.HasUnitState(EUnitState.IN_TURRET)))
117  {
118  isCoveringPresent = true;
119  //Selection conditions could be improved
120  //We doesn't ensure that covering element is actually able to cover e.g. has ammo, isn't somewhere behind the wall or far away.
121  if (aIInfoComponent.GetAIState() == EUnitAIState.AVAILABLE)
122  {
123  isCoveringSelected = true;
124  m_selectedIndexForCovering = indexForCover;
125  break;
126  }
127  }
128  */
129  }
130 
131  if (!isCoveringPresent)
132  {
133  return ENodeResult.FAIL;
134  }
135 
136  if (!isCoveringSelected)
137  {
138  //we shouldn't iterate when selection wasn't succesfull
139  m_selectedIndexForMovement = selectedIndexForMovementPrevious;
140  return ENodeResult.RUNNING;
141  }
142 
143  agent = AIAgent.Cast(m_GroupUtilityComponent.m_aInfoComponents[m_selectedIndexForMovement].GetOwner());
144  if (agent)
145  SetVariableOut(PORT_MOVING_MEMBER_OUT,agent);
146  else
147  return ENodeResult.FAIL;
148 
149  agent = AIAgent.Cast(m_GroupUtilityComponent.m_aInfoComponents[m_selectedIndexForCovering].GetOwner());
150  if (agent)
151  SetVariableOut(PORT_COVERING_MEMBER_OUT,agent);
152  else
153  {
154  ClearVariable(PORT_MOVING_MEMBER_OUT);
155  return ENodeResult.FAIL;
156  }
157 
158  return ENodeResult.SUCCESS;
159  }
160 
161  //------------------------------------------------------------------------------------------------
162  override protected bool CanReturnRunning()
163  {
164  return true;
165  }
166 
167  //------------------------------------------------------------------------------------------------
168  protected static ref TStringArray s_aVarsOut = {
169  PORT_MOVING_MEMBER_OUT,
170  PORT_COVERING_MEMBER_OUT
171  };
172  override TStringArray GetVariablesOut()
173  {
174  return s_aVarsOut;
175  }
176 
177  //------------------------------------------------------------------------------------------------
178  protected static ref TStringArray s_aVarsIn = {
179  PORT_FIRETEAM_IN,
180  PORT_TARGET_IN
181  };
182  override TStringArray GetVariablesIn()
183  {
184  return s_aVarsIn;
185  }
186 
187  //------------------------------------------------------------------------------------------------
188  protected override string GetOnHoverDescription()
189  {
190  return "Getter returns unit available for cover and unit available for movement";
191  }
192 };
s_aVarsOut
SCR_AIPickupInventoryItemsBehavior s_aVarsOut
Definition: SCR_AIGetCombatMoveRequestParameters.c:149
SCR_AIGetOverwatchMembers
Definition: SCR_AIGetOverwatchMembers.c:1
NodeError
ENodeResult NodeError(Node node, AIAgent owner, string msg)
Error call to be used in scripted BT nodes.
Definition: NodeError.c:3