Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_AIOccupyDriversInUsedVehicles.c
Go to the documentation of this file.
2{
3 [Attribute(defvalue: "0", uiwidget: UIWidgets.CheckBox, desc: "Test vehicles that are not registered inside the group?")]
4 protected bool m_bTestNewVehicles;
5
6 [Attribute(defvalue: "-1", uiwidget: UIWidgets.EditBox, desc: "Limit search for replacement by this distance [m]?")]
7 protected float m_fMaxDistanceOfSearch_m;
8
9 [Attribute(defvalue: "100", uiwidget: UIWidgets.EditBox, desc: "Update time of checks [ms]")]
10 protected float m_fUpdateInterval_ms;
11
12 static const string PORT_CAN_USE_VEHICLE = "CanUseVehicle";
13 static const string NODE_NAME = "SCR_AIOccupyDriversInUsedVehicles";
14
15 protected float m_fNextUpdate_ms;
16 protected ref array<AIAgent> m_aAgents = {};
17 protected ref array<AIAgent> m_aInformedAgents = {};
18 protected ref array<ref SCR_AIGroupVehicle> m_aUsedVehicles = {};
19 protected ref array<ref SCR_AIGroupVehicle> m_aVehiclesToOccupy = {};
22 protected int m_iStateOfExecution;
24
25 protected static int STATE_TESTING_STATE = 0; // testing initial setup
26 protected static int STATE_SENDING_SIGNALS = 1; // sending signals to agents
27 protected static int STATE_WAITING = 2; // waiting for agents to obey
28 protected static int STATE_FINISHED = 3; // done everything
29
30 //----------------------------------------------------------------------------------------------------------------------------------------------
31 override void OnEnter(AIAgent owner)
32 {
33 m_Group = SCR_AIGroup.Cast(owner);
34 if (!m_Group)
35 {
36 SCR_AgentMustBeAIGroup(this, owner);
37 return;
38 }
40 if (!m_Utility)
41 return;
42 m_aAgents.Clear();
43 m_aInformedAgents.Clear();
44 m_aUsedVehicles.Clear();
45 m_aVehiclesToOccupy.Clear();
46 m_Utility.m_OnAgentLifeStateChanged.Remove(OnAgentLifeStateChanged);
47 m_Utility.m_OnAgentLifeStateChanged.Insert(OnAgentLifeStateChanged);
50 }
51
52 //----------------------------------------------------------------------------------------------------------------------------------------------
53 override ENodeResult EOnTaskSimulate(AIAgent owner, float dt)
54 {
55 if (!m_Group || !m_Utility)
56 return ENodeResult.FAIL;
57
58 float currentTime_ms = GetGame().GetWorld().GetWorldTime();
59 if (currentTime_ms < m_fNextUpdate_ms)
60 return ENodeResult.RUNNING;
61 m_fNextUpdate_ms = currentTime_ms + m_fUpdateInterval_ms;
62
63 switch (m_iStateOfExecution)
64 {
66 {
67 return Testing_State(true);
68 }
70 {
71 return SendingMessages_State();
72 }
73 case STATE_WAITING:
74 {
75 return Waiting_State();
76 }
77 case STATE_FINISHED:
78 {
79 return Finished_State();
80 }
81 }
82 return ENodeResult.RUNNING;
83 }
84
85 //----------------------------------------------------------------------------------------------------------------------------------------------
86 protected ENodeResult Testing_State(bool isScheduled)
87 {
88 m_Group.GetAgents(m_aAgents);
89 if (isScheduled)
90 {
91 // check that AIAgents arent just moving in/out of compartments
92 foreach (AIAgent agent: m_aAgents)
93 {
94 ChimeraCharacter chChar = ChimeraCharacter.Cast(agent.GetControlledEntity());
95 if (!chChar)
96 continue;
97 CompartmentAccessComponent compAcc = chChar.GetCompartmentAccessComponent();
98 if (!compAcc)
99 continue;
100 bool inTransition = compAcc.IsGettingIn() || compAcc.IsGettingOut();
101 if (inTransition)
102 return ENodeResult.RUNNING;
103 }
104 // check all vehicles are registered as usable
106 {
107 foreach(AIAgent ag: m_aAgents)
108 {
109 ChimeraCharacter char = ChimeraCharacter.Cast(ag.GetControlledEntity());
110 if (!char || !char.IsInVehicle())
111 continue;
112 CompartmentAccessComponent acc = char.GetCompartmentAccessComponent();
113 if (!acc)
114 continue;
115 IEntity vehicleEntity = acc.GetVehicleIn(char);
116 SCR_AIVehicleUsageComponent vehicleUsageComp = SCR_AIVehicleUsageComponent.FindOnNearestParent(vehicleEntity, vehicleEntity);
117 m_Utility.AddUsableVehicle(vehicleUsageComp);
118 }
119 }
120 }
121 m_aVehiclesToOccupy.Clear();
122 m_Utility.m_VehicleMgr.GetAllVehicles(m_aUsedVehicles);
123
124 foreach (SCR_AIGroupVehicle groupVehicle : m_aUsedVehicles)
125 {
126 if (!groupVehicle)
127 continue;
128 // we skip group helicopters and static turrets
129 SCR_AIVehicleUsageComponent vehicleUsage = groupVehicle.GetVehicleUsageComponent();
130 if (groupVehicle.IsStatic() || (vehicleUsage && !vehicleUsage.CanBePiloted()))
131 {
133 continue;
134 }
135 // add vehicles that dont have operational driver
136 if (!groupVehicle.DriverIsConscious())
137 {
138 m_aVehiclesToOccupy.Insert(groupVehicle);
139 }
140 }
141 bool willTryToReoccupy = m_aVehiclesToOccupy.Count() > 0;
142 if (willTryToReoccupy)
144 else
146 return ENodeResult.RUNNING;
147 }
148
149 //----------------------------------------------------------------------------------------------------------------------------------------------
151 {
152 if (m_aVehiclesToOccupy.Count() == 0)
153 {
155 return ENodeResult.RUNNING;
156 };
157 m_aInformedAgents.Clear();
158 foreach (SCR_AIGroupVehicle groupVehicle : m_aVehiclesToOccupy)
159 {
160 AIAgent agentToUseAsDriver;
161 int vehicleHandleId = groupVehicle.GetSubgroupHandleId();
162 array<AIAgent> agentsOfHandler = {};
163 // try to occupy with driver in the same subgroup
164 m_Utility.m_GroupMovementComponent.GetAgentsInHandler(agentsOfHandler, vehicleHandleId);
165 agentToUseAsDriver = GetAgentThatIsConscious(agentsOfHandler, m_aInformedAgents, excludeDistance: m_fMaxDistanceOfSearch_m, locationOfAccident: groupVehicle.GetEntity().GetOrigin());
166 // try to occupy with driver subgroup on foot
167 if (!agentToUseAsDriver)
168 {
169 m_Utility.m_GroupMovementComponent.GetAgentsInHandler(agentsOfHandler, AIGroupMovementComponent.DEFAULT_HANDLER_ID);
170 agentToUseAsDriver = GetAgentThatIsConscious(agentsOfHandler, m_aInformedAgents, excludeDistance: m_fMaxDistanceOfSearch_m, locationOfAccident: groupVehicle.GetEntity().GetOrigin());
171 }
172 // try to occupy with any alive agent
173 if (!agentToUseAsDriver)
174 {
175 agentToUseAsDriver = GetAgentThatIsConscious(m_aAgents, m_aInformedAgents, true, excludeDistance: m_fMaxDistanceOfSearch_m, locationOfAccident: groupVehicle.GetEntity().GetOrigin());
176 }
177 if (agentToUseAsDriver)
178 {
179 AICommunicationComponent myComms = m_Utility.m_Owner.GetCommunicationComponent();
180 SCR_AIMessageHandling.SendGetInMessage(agentToUseAsDriver, groupVehicle.GetEntity(), EAICompartmentType.Pilot, null, myComms, NODE_NAME);
181 m_aInformedAgents.Insert(agentToUseAsDriver);
182 }
183 else
184 continue;
185 }
186 if (m_aInformedAgents.IsEmpty())
189 return ENodeResult.RUNNING;
190
191 }
192
193 //----------------------------------------------------------------------------------------------------------------------------------------------
195 {
196 foreach (AIAgent agent : m_aInformedAgents)
197 {
198 SCR_AIInfoComponent info = SCR_AIInfoComponent.Cast(agent.FindComponent(SCR_AIInfoComponent));
199 if (info && !info.HasUnitState(EUnitState.PILOT))
200 return ENodeResult.RUNNING;
201 }
203 return ENodeResult.RUNNING;
204 }
205
206 //----------------------------------------------------------------------------------------------------------------------------------------------
208 {
209 bool haveUsableVehicles = m_aUsedVehicles.Count() - m_iNumberOfUnpilotableVehicles > 0;
210 int vehiclesToOccupy = m_aVehiclesToOccupy.Count();
211 bool canOccupyVehicles = vehiclesToOccupy == 0 || m_aInformedAgents.Count() == vehiclesToOccupy;
212 bool canUseVehicles = haveUsableVehicles && canOccupyVehicles;
213 SetVariableOut(PORT_CAN_USE_VEHICLE, canUseVehicles);
214 if (canUseVehicles)
215 return ENodeResult.SUCCESS;
216 return ENodeResult.FAIL;
217 }
218
219 //----------------------------------------------------------------------------------------------------------------------------------------------
220 protected void CancelOrders()
221 {
222 AICommunicationComponent myComms = m_Utility.m_Owner.GetCommunicationComponent();
223 for (int index = m_aInformedAgents.Count() - 1; index >=0; index--)
224 {
226 SCR_AIMessageHandling.SendCancelMessage(m_aInformedAgents[index], null, myComms, NODE_NAME);
227 m_aInformedAgents.Remove(index);
228 }
229 }
230
231 //----------------------------------------------------------------------------------------------------------------------------------------------
232 override void OnAbort(AIAgent owner, Node nodeCausingAbort)
233 {
234 if (!m_Utility)
235 return;
236 m_Utility.m_OnAgentLifeStateChanged.Remove(OnAgentLifeStateChanged);
237 switch (m_iStateOfExecution)
238 {
240 {
241 CancelOrders();
242 break;
243 }
244 case STATE_WAITING:
245 {
246 CancelOrders();
247 break;
248 }
249 case STATE_FINISHED:
250 {
251 return;
252 }
253 }
254 }
255
256 //----------------------------------------------------------------------------------------------------------------------------------------------
257 void OnAgentLifeStateChanged(AIAgent incapacitatedAgent, SCR_AIInfoComponent infoIncap, IEntity vehicle, ECharacterLifeState lifeState)
258 {
259 if (vehicle && infoIncap.HasUnitState(EUnitState.PILOT) && m_iStateOfExecution != STATE_FINISHED)
260 Testing_State(false);
261 else if (m_aInformedAgents.Find(incapacitatedAgent) > -1)
263 }
264
265 //----------------------------------------------------------------------------------------------------------------------------------------------
266 protected AIAgent GetAgentThatIsConscious(notnull array<AIAgent> agents, array<AIAgent> restrictedAgents, bool excludeDrivers = false, float excludeDistance = -1, vector locationOfAccident = vector.Zero)
267 {
268 foreach (AIAgent agent : agents)
269 {
270 if (excludeDrivers)
271 {
272 SCR_AIInfoComponent info = SCR_AIInfoComponent.Cast(agent.FindComponent(SCR_AIInfoComponent));
273 if (!info || info.HasUnitState(EUnitState.PILOT))
274 continue;
275 }
276 IEntity agentEntity = agent.GetControlledEntity();
277 if (SCR_AIDamageHandling.IsConscious(agentEntity) && restrictedAgents.Find(agent) == -1)
278 {
279 if (excludeDistance > 0)
280 {
281 vector agentPos = agent.GetControlledEntity().GetOrigin();
282 if (vector.Distance(agentPos,locationOfAccident) > excludeDistance)
283 continue;
284 }
285 return agent;
286 }
287 }
288 return null;
289 }
290
291 //----------------------------------------------------------------------------------------------------------------------------------------------
292 static override bool VisibleInPalette()
293 {
294 return true;
295 };
296
297 //----------------------------------------------------------------------------------------------------------------------------------------
298 protected static ref TStringArray s_aVarsOut = { PORT_CAN_USE_VEHICLE };
299
300 //----------------------------------------------------------------------------------------------------------------------------------------
302
303 //----------------------------------------------------------------------------------------------------------------------------------------
304 static override string GetOnHoverDescription()
305 {
306 return "OccupyDriversInUsedVehicles: goes over the array of known vehicles and tries to occupy the drivers with alive group members. Is running while seats are not occupied.\nReturns bool if we can occupy (at least one) driver.";
307 };
308
309 //----------------------------------------------------------------------------------------------------------------------------------------
310 static override bool CanReturnRunning()
311 {
312 return true;
313 };
314};
ArmaReforgerScripted GetGame()
Definition game.c:1398
void SCR_AgentMustBeAIGroup(Node node, AIAgent owner)
Definition NodeError.c:14
EAICompartmentType
SCR_DestructionSynchronizationComponentClass ScriptComponentClass int index
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
Definition Node.c:13
proto void SetVariableOut(string name, void val)
This class is used for keeping track of vehicles assigned to group.
bool HasUnitState(EUnitState state)
ref array< ref SCR_AIGroupVehicle > m_aUsedVehicles
override ENodeResult EOnTaskSimulate(AIAgent owner, float dt)
void OnAgentLifeStateChanged(AIAgent incapacitatedAgent, SCR_AIInfoComponent infoIncap, IEntity vehicle, ECharacterLifeState lifeState)
ref array< ref SCR_AIGroupVehicle > m_aVehiclesToOccupy
override void OnAbort(AIAgent owner, Node nodeCausingAbort)
AIAgent GetAgentThatIsConscious(notnull array< AIAgent > agents, array< AIAgent > restrictedAgents, bool excludeDrivers=false, float excludeDistance=-1, vector locationOfAccident=vector.Zero)
bool CanBePiloted()
AI can use the pilot compartments on this vehicle.
static SCR_AIVehicleUsageComponent FindOnNearestParent(notnull IEntity ent, out IEntity componentOwner)
ENodeResult
Definition ENodeResult.c:13
ECharacterLifeState
SCR_FieldOfViewSettings Attribute
array< string > TStringArray
Definition Types.c:385