Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_AIStaticArtilleryActivity.c
Go to the documentation of this file.
2{
3 // Requested parameters
6 protected int m_iTargetShotCount;
7
8 // Runtime data
9 protected ref array<AIAgent> m_aAssignedAgents = {};// Agents to which we sent messages
10 protected ref array<AIAgent> m_aFailedAgents = {}; // Agents which reported their failing of behavior
11 protected int m_iActualShotCount;
12
13 //------------------------------------------------------------------------------------------------------------------------
16 void SCR_AIStaticArtilleryActivity(SCR_AIGroupUtilityComponent utility, AIWaypoint relatedWaypoint, vector targetPos, SCR_EAIArtilleryAmmoType ammoType, int targetShotCount, float priorityLevel = PRIORITY_LEVEL_NORMAL)
17 {
18 m_iTargetShotCount = targetShotCount;
19 m_eAmmoType = ammoType;
20 m_vTargetPos = targetPos;
21 SetPriority(PRIORITY_ACTIVITY_ARTILLERY_SUPPORT);
22 m_fPriorityLevel.m_Value = priorityLevel;
23 SetIsUniqueInActionQueue(false); // Otherwise it will fail if a second one is added, which causes waypoint to be completed, which we don't want
24 }
25
26 //------------------------------------------------------------------------------------------------------------------------
27 override void OnActionSelected()
28 {
29 super.OnActionSelected();
30
31 // Assign agents to turrets, send them messages
32
33 array<ref SCR_AIGroupVehicle> allVehicles = {}; // All vehicles from vehicle mgr
34 array<ref SCR_AIGroupVehicle> usableTurrets = {}; // All artillery turrets which we will consider
35 array<AIAgent> freeAgents = {}; // Agents free for assignment to artillery
36 array<AIAgent> assignedAgents = {}; // Agent for that turret in usableTurrets array
37
38 m_Utility.m_VehicleMgr.GetAllVehicles(allVehicles);
39 m_Utility.m_Owner.GetAgents(freeAgents);
40
41 foreach (SCR_AIGroupVehicle v : allVehicles)
42 {
43 SCR_AIVehicleUsageComponent vehicleUsageComp = v.GetVehicleUsageComponent();
44
45 if (!vehicleUsageComp)
46 continue;
47
48 if (vehicleUsageComp.GetVehicleType() != EAIVehicleType.STATIC_ARTILLERY)
49 continue;
50
51 // Check if it's occupied by someone not in our group
52 TurretCompartmentSlot slot = vehicleUsageComp.GetTurretCompartmentSlot();
53 if (!slot)
54 continue;
55
56 IEntity occupant = slot.GetOccupant();
57 if (occupant)
58 {
59 AIAgent occupantAgent = SCR_AIUtils.GetAIAgent(occupant);
60 if (!occupantAgent)
61 continue; // No agent, ignore
62 else if (occupantAgent.GetParentGroup() != m_Utility.m_Owner)
63 continue; // Agent not in this group, ignore
64
65 // Agent is in this group, assign to this turret
66 usableTurrets.Insert(v);
67 assignedAgents.Insert(occupantAgent);
68 freeAgents.RemoveItem(occupantAgent);
69 }
70 else
71 {
72 // Noone inside, put it in usableTurrets array, assign operator later
73 usableTurrets.Insert(v);
74 assignedAgents.Insert(null);
75 }
76 }
77
78 // Assign remaining agents and turrets
79 for (int i = 0; i < usableTurrets.Count(); i++)
80 {
81 // Continue if already assigned
82 if (assignedAgents[i])
83 continue;
84
85 // Break if no more free agents
86 if (freeAgents.IsEmpty())
87 break;
88
89 int bestAgentId = -1;
90 AIAgent bestAgent = FindBestAgentForArtillery(freeAgents, usableTurrets[i].GetEntity(), bestAgentId);
91
92 if (!bestAgent)
93 break;
94
95 assignedAgents[i] = bestAgent;
96 freeAgents.Remove(bestAgentId);
97 }
98
99 // Send goal messages
100 SendMessages(usableTurrets, assignedAgents);
101
102 // Store the list of involved agents
103 m_aAssignedAgents.Clear();
104 foreach (auto a : assignedAgents)
105 {
106 if (a)
107 m_aAssignedAgents.Insert(a);
108 }
109 m_aFailedAgents.Clear();
110 }
111
112 //------------------------------------------------------------------------------------
114 protected AIAgent FindBestAgentForArtillery(notnull array<AIAgent> agents, notnull IEntity artilleryEntity, out int outIndex)
115 {
116 float minDistSq = float.MAX;
117 AIAgent bestAgent = null;
118 int bestAgentIndex = -1;
119 vector artilleryPos = artilleryEntity.GetOrigin();
120
121 foreach (int i, AIAgent agent : agents)
122 {
123 IEntity controlledEntity = agent.GetControlledEntity();
124 if (!controlledEntity)
125 continue;
126 vector controlledEntityPos = controlledEntity.GetOrigin();
127 float distSq = vector.DistanceSq(controlledEntityPos, artilleryPos);
128 if (distSq < minDistSq)
129 {
130 bestAgent = agent;
131 bestAgentIndex = i;
132 minDistSq = distSq;
133 }
134 }
135
136 outIndex = bestAgentIndex;
137 return bestAgent;
138 }
139
140 //------------------------------------------------------------------------------------
141 override void OnActionDeselected()
142 {
143 super.OnActionDeselected();
145 }
146
147 //------------------------------------------------------------------------------------
148 override void OnActionCompleted()
149 {
150 super.OnActionCompleted();
152 }
153
154 //------------------------------------------------------------------------------------
155 override void OnActionFailed()
156 {
157 super.OnActionFailed();
159
160 // If this is failed, also fail the waypoint
162 m_Utility.m_Owner.CompleteWaypoint(m_RelatedWaypoint);
163 }
164
165 //------------------------------------------------------------------------------------------------------------------------
166 protected void SendMessages(notnull array<ref SCR_AIGroupVehicle> turrets, notnull array<AIAgent> assignedAgents)
167 {
168 AICommunicationComponent myComms = m_Utility.m_Owner.GetCommunicationComponent();
169 if (!myComms)
170 return;
171
172 for (int i = 0; i < turrets.Count(); i++)
173 {
174 SCR_AIGroupVehicle turret = turrets[i];
175 AIAgent agent = assignedAgents[i];
176
177 if (!agent) // It's possible that noone was assigned to this turret
178 continue;
179
181 msg.m_RelatedGroupActivity = this;
182 msg.m_fPriorityLevel = m_fPriorityLevel.m_Value;
183 msg.m_ArtilleryEntity = turret.GetEntity();
184 msg.m_vTargetPos = m_vTargetPos;
185 msg.m_eAmmoType = m_eAmmoType;
186 msg.SetReceiver(agent);
187
188 myComms.RequestBroadcast(msg, agent);
189 }
190 }
191
192 //------------------------------------------------------------------------------------------------------------------------
193 override void OnChildBehaviorCreated(SCR_AIBehaviorBase childBehavior)
194 {
195 // Subscribe to events of the child behavior
196
197 SCR_AIStaticArtilleryBehavior artilleryBehavior = SCR_AIStaticArtilleryBehavior.Cast(childBehavior);
198
199 if (!artilleryBehavior)
200 return;
201
202 artilleryBehavior.GetOnArtilleryFired().Insert(OnChildBehaviorArtilleryFired);
203 }
204
205 //------------------------------------------------------------------------------------------------------------------------
207 override void OnChildBehaviorFinished(SCR_AIBehaviorBase childBehavior)
208 {
209 // Ignore if this activity is already over
210 if (GetActionState() != EAIActionState.RUNNING)
211 return;
212
213 // Ignore if the child behavior is not failed
214 if (childBehavior.GetActionState() != EAIActionState.FAILED)
215 return;
216
217 // Ignore if it was cancelled by this group, there is no reason to fail this activity in this case.
218 // For instance the behavior could be cancelled because the group temporary selected another activity.
219 int failReason = childBehavior.GetFailReason();
220 if (failReason == EAIActionFailReason.CANCELLED)
221 return;
222
223 AIAgent agent = childBehavior.m_Utility.GetAIAgent();
224 m_aFailedAgents.Insert(agent);
225
226 // If m_aFailedAgents and m_aAssignedAgents are same, fail
227 int nFailed = 0;
228 int nValidAssigned = 0;
229 foreach (AIAgent a : m_aAssignedAgents)
230 {
231 if (!a)
232 continue;
233
234 nValidAssigned++;
235
236 if (m_aFailedAgents.Contains(a))
237 nFailed++;
238 }
239
240 if (nValidAssigned == nFailed)
241 {
242 // All assigned agents have failed their behaviors
243 Fail();
244 Print(string.Format("SCR_AIStaticArtilleryActivity: FAILED, noone can shoot at the target position: %1, or there is no ammo", m_vTargetPos), LogLevel.DEBUG);
245 }
246 }
247
248 //------------------------------------------------------------------------------------------------------------------------
249 protected void OnChildBehaviorArtilleryFired(SCR_AIStaticArtilleryBehavior behavior, AIAgent agent)
250 {
252
254 {
255 // We're done with fire mission, complete the activity, and complete the waypoint
256 Complete();
258 m_Utility.m_Owner.CompleteWaypoint(m_RelatedWaypoint);
259 }
260 }
261}
ref SCR_BTParam< float > m_fPriorityLevel
enum EAIActionFailReason PRIORITY_LEVEL_NORMAL
EAIActionFailReason
Fail reasons of actions. They can be generic or specific to some behavior.
Definition SCR_AIAction.c:3
void Fail(bool doNotCompleteWaypoint)
void SendCancelMessagesToAllAgents()
void SCR_AIActivityBase(SCR_AIGroupUtilityComponent utility, AIWaypoint relatedWaypoint)
enum SCR_EAIActivityCause m_Utility
AIWaypoint m_RelatedWaypoint
void SCR_AIBehaviorBase(SCR_AIUtilityComponent utility, SCR_AIActivityBase groupActivity)
void SCR_AIMessage_ArtillerySupport()
EAIVehicleType
Vehicle type from point view of AI usage.
proto external vector GetOrigin()
This class is used for keeping track of vehicles assigned to group.
override void OnChildBehaviorCreated(SCR_AIBehaviorBase childBehavior)
void OnChildBehaviorArtilleryFired(SCR_AIStaticArtilleryBehavior behavior, AIAgent agent)
void SendMessages(notnull array< ref SCR_AIGroupVehicle > turrets, notnull array< AIAgent > assignedAgents)
AIAgent FindBestAgentForArtillery(notnull array< AIAgent > agents, notnull IEntity artilleryEntity, out int outIndex)
Selects best agent to operate artillery entity. Now selects nearest agent.
void SCR_AIStaticArtilleryActivity(SCR_AIGroupUtilityComponent utility, AIWaypoint relatedWaypoint, vector targetPos, SCR_EAIArtilleryAmmoType ammoType, int targetShotCount, float priorityLevel=PRIORITY_LEVEL_NORMAL)
override void OnChildBehaviorFinished(SCR_AIBehaviorBase childBehavior)
Called by agent when he failed his behavior related to this activity.
ScriptInvokerBase< SCR_AIStaticArtilleryBehavior_OnArtilleryFired > GetOnArtilleryFired()
Returns event which is invoked every time AI who executes this behavior fires an artillery.
TurretCompartmentSlot GetTurretCompartmentSlot()
EAIActionState
IEntity GetEntity()
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
LogLevel
Enum with severity of the logging message.
Definition LogLevel.c:14