Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_AIGetOverwatchMembers.c
Go to the documentation of this file.
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 static 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 int selectedIndexForMovementPrevious = m_selectedIndexForMovement;
60 for (int i = 0; i < length; i++)
61 {
62 aIInfoComponent = m_GroupUtilityComponent.m_aInfoComponents[i];
63 if( !aIInfoComponent )
64 continue;
65
66 // Handeling of fireteams should be reworked so we can have geter for firetam members insted iteration over whole team each time
67 // todo fix this
68 /*
69 if (aIInfoComponent.GetFireTeam() == teamSelection && aIInfoComponent.HasRole(EUnitRole.RIFLEMAN))
70 {
71 if (aIInfoComponent.GetAIState() == EUnitAIState.AVAILABLE)
72 {
73 isMovingPresent = true;
74
75 AIAgent memberAgent = AIAgent.Cast(aIInfoComponent.GetOwner());
76 IEntity memberEnt = memberAgent.GetControlledEntity();
77 float distToTarget = vector.Distance(memberEnt.GetOrigin(), targetEntity.GetOrigin());
78
79 if (distToTarget > distMax)
80 {
81 isMovingSelected = true;
82 m_selectedIndexForMovement = i;
83 distMax = distToTarget;
84 }
85 }
86 }
87 */
88 }
89
90 if (!isMovingPresent)
91 {
92 return ENodeResult.FAIL;
93 }
94
95 if (!isMovingSelected)
96 {
97 return ENodeResult.RUNNING;
98 }
99
100 for (int i = 1; i <= length; i++)
101 {
102 int indexForCover = (i + m_selectedIndexForCovering) % length;
103
104 if (indexForCover == m_selectedIndexForMovement)
105 continue;
106
107 aIInfoComponent = m_GroupUtilityComponent.m_aInfoComponents[indexForCover];
108 if( !aIInfoComponent )
109 continue;
110
111 // todo fix this
112 /*
113 if (aIInfoComponent.GetFireTeam() == teamSelection &&
114 (aIInfoComponent.HasRole(EUnitRole.RIFLEMAN) || aIInfoComponent.HasRole(EUnitRole.MACHINEGUNNER) || aIInfoComponent.HasUnitState(EUnitState.IN_TURRET)))
115 {
116 isCoveringPresent = true;
117 //Selection conditions could be improved
118 //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.
119 if (aIInfoComponent.GetAIState() == EUnitAIState.AVAILABLE)
120 {
121 isCoveringSelected = true;
122 m_selectedIndexForCovering = indexForCover;
123 break;
124 }
125 }
126 */
127 }
128
129 if (!isCoveringPresent)
130 {
131 return ENodeResult.FAIL;
132 }
133
134 if (!isCoveringSelected)
135 {
136 //we shouldn't iterate when selection wasn't succesfull
137 m_selectedIndexForMovement = selectedIndexForMovementPrevious;
138 return ENodeResult.RUNNING;
139 }
140
141 agent = AIAgent.Cast(m_GroupUtilityComponent.m_aInfoComponents[m_selectedIndexForMovement].GetOwner());
142 if (agent)
143 SetVariableOut(PORT_MOVING_MEMBER_OUT,agent);
144 else
145 return ENodeResult.FAIL;
146
147 agent = AIAgent.Cast(m_GroupUtilityComponent.m_aInfoComponents[m_selectedIndexForCovering].GetOwner());
148 if (agent)
149 SetVariableOut(PORT_COVERING_MEMBER_OUT,agent);
150 else
151 {
152 ClearVariable(PORT_MOVING_MEMBER_OUT);
153 return ENodeResult.FAIL;
154 }
155
156 return ENodeResult.SUCCESS;
157 }
158
159 //------------------------------------------------------------------------------------------------
160 static override protected bool CanReturnRunning()
161 {
162 return true;
163 }
164
165 //------------------------------------------------------------------------------------------------
166 protected static ref TStringArray s_aVarsOut = {
167 PORT_MOVING_MEMBER_OUT,
168 PORT_COVERING_MEMBER_OUT
169 };
171 {
172 return s_aVarsOut;
173 }
174
175 //------------------------------------------------------------------------------------------------
176 protected static ref TStringArray s_aVarsIn = {
177 PORT_FIRETEAM_IN,
178 PORT_TARGET_IN
179 };
181 {
182 return s_aVarsIn;
183 }
184
185 //------------------------------------------------------------------------------------------------
186 protected static override string GetOnHoverDescription()
187 {
188 return "Getter returns unit available for cover and unit available for movement";
189 }
190};
ENodeResult NodeError(Node node, AIAgent owner, string msg)
Error call to be used in scripted BT nodes.
Definition NodeError.c:3
proto void SetVariableOut(string name, void val)
proto bool GetVariableIn(string name, out void val)
bool VisibleInPalette()
proto void ClearVariable(string name)
static override string GetOnHoverDescription()
override TStringArray GetVariablesOut()
override TStringArray GetVariablesIn()
ENodeResult
Definition ENodeResult.c:13
array< string > TStringArray
Definition Types.c:385