Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_CampaignDefendTask.c
Go to the documentation of this file.
1 //------------------------------------------------------------------------------------------------
3 {
4 };
5 
6 //------------------------------------------------------------------------------------------------
8 {
9  static const float DEFEND_TASK_DEFAULT_MIN_ALLY_DISTANCE = 300;
10  static const float DEFEND_TASK_DEFAULT_MAX_ALLY_DISTANCE = 400;
11  static const float DEFEND_TASK_DEFAULT_MIN_ENEMY_DISTANCE = 300;
12  static const float DEFEND_TASK_DEFAULT_MAX_ENEMY_DISTANCE = 400;
13 
14  //**************************//
15  //PROTECTED STATIC VARIABLES//
16  //**************************//
17  protected static SCR_CampaignMilitaryBaseComponent s_ClosestBase; //This is the closest base to the local player's character (only updated when task list is open)
18 
19  //*********************//
20  //PUBLIC STATIC METHODS//
21  //*********************//
22 
23  //------------------------------------------------------------------------------------------------
24  static float GetMinAllyDistance()
25  {
26  if (!GetTaskManager())
27  return DEFEND_TASK_DEFAULT_MIN_ALLY_DISTANCE;
28 
30  if (supportEntity)
31  return supportEntity.GetMinAllyDistance();
32 
33  return DEFEND_TASK_DEFAULT_MIN_ALLY_DISTANCE;
34  }
35 
36  //------------------------------------------------------------------------------------------------
37  static float GetMaxAllyDistance()
38  {
39  if (!GetTaskManager())
40  return DEFEND_TASK_DEFAULT_MAX_ALLY_DISTANCE;
41 
43  if (supportEntity)
44  return supportEntity.GetMaxAllyDistance();
45 
46  return DEFEND_TASK_DEFAULT_MAX_ALLY_DISTANCE;
47  }
48 
49  //------------------------------------------------------------------------------------------------
50  static float GetMinEnemyDistance()
51  {
52  if (!GetTaskManager())
53  return DEFEND_TASK_DEFAULT_MIN_ENEMY_DISTANCE;
54 
56  if (supportEntity)
57  return supportEntity.GetMinEnemyDistance();
58 
59  return DEFEND_TASK_DEFAULT_MIN_ENEMY_DISTANCE;
60  }
61 
62  //------------------------------------------------------------------------------------------------
63  static float GetMaxEnemyDistance()
64  {
65  if (!GetTaskManager())
66  return DEFEND_TASK_DEFAULT_MAX_ENEMY_DISTANCE;
67 
69  if (supportEntity)
70  return supportEntity.GetMaxEnemyDistance();
71 
72  return DEFEND_TASK_DEFAULT_MAX_ENEMY_DISTANCE;
73  }
74 
75  //------------------------------------------------------------------------------------------------
76  static SCR_CampaignDefendTask FindDefendTask(SCR_CampaignMilitaryBaseComponent targetBase, SCR_CampaignFaction targetFaction)
77  {
78  array<SCR_BaseTask> tasks = new array<SCR_BaseTask>();
79  GetTaskManager().GetTasks(tasks);
80 
81  if (!tasks)
82  return null;
83 
84  for (int i = tasks.Count() - 1; i >= 0; i--)
85  {
86  SCR_CampaignDefendTask defendTask = SCR_CampaignDefendTask.Cast(tasks[i]);
87  if (!defendTask)
88  continue;
89 
90  if (defendTask.GetTargetBase() == targetBase && defendTask.GetTargetFaction() == targetFaction)
91  return defendTask;
92  }
93 
94  return null;
95  }
96 
97  //------------------------------------------------------------------------------------------------
98  static SCR_CampaignMilitaryBaseComponent FindClosestFriendlyBase(notnull IEntity controlledEntity, notnull Faction faction)
99  {
100 
101  array<SCR_MilitaryBaseComponent> bases = {};
102  SCR_MilitaryBaseSystem.GetInstance().GetBases(bases);
103 
104  if (!bases)
105  return null;
106 
107  int closestBaseIndex = -1;
108  float closestBaseDistance = float.MAX;
109  float minAllyDistanceSq = Math.Pow(GetMinAllyDistance(), 2);
110  vector controlledEntityOrigin = controlledEntity.GetOrigin();
111 
112  for (int i = bases.Count() - 1; i >= 0; i--)
113  {
115 
116  if (!campaignBase)
117  continue;
118 
119  if (!campaignBase.IsInitialized())
120  continue;
121 
122  if (campaignBase.GetFaction() != faction)
123  continue;
124 
125  float distance = vector.DistanceSq(campaignBase.GetOwner().GetOrigin(), controlledEntityOrigin);
126 
127  if (distance < minAllyDistanceSq && distance < closestBaseDistance)
128  {
129  closestBaseDistance = distance;
130  closestBaseIndex = i;
131  }
132  }
133 
134  if (closestBaseIndex != -1)
135  return SCR_CampaignMilitaryBaseComponent.Cast(bases[closestBaseIndex]);
136  return null;
137  }
138 
139  //------------------------------------------------------------------------------------------------
140  static bool CheckDefendRequestConditions(notnull SCR_PlayerController playerController, out SCR_CampaignMilitaryBaseComponent closestBase)
141  {
142  IEntity locallyControlledEntity = playerController.GetMainEntity();
143 
144  if (!locallyControlledEntity)
145  return false;
146 
147  FactionAffiliationComponent factionAffiliationComponent = FactionAffiliationComponent.Cast(locallyControlledEntity.FindComponent(FactionAffiliationComponent));
148  if (!factionAffiliationComponent)
149  return false;
150 
151  SCR_CampaignFaction faction = SCR_CampaignFaction.Cast(factionAffiliationComponent.GetAffiliatedFaction());
152  if (!faction)
153  return false;
154 
155  closestBase = FindClosestFriendlyBase(locallyControlledEntity, faction);
156 
157  if (!closestBase)
158  return false;
159  else
160  {
161  if (FindDefendTask(closestBase, faction))
162  return false;
163 
164  if (!FindEnemyPresence(closestBase, faction))
165  return false;
166 
167  return true;
168  }
169  }
170 
171  //------------------------------------------------------------------------------------------------
173  static bool FindEnemyPresence(notnull SCR_CampaignMilitaryBaseComponent base, notnull SCR_CampaignFaction alliedFaction, bool initialCheck = true)
174  {
175  SCR_CampaignFaction enemyFaction = SCR_CampaignFactionManager.Cast(GetGame().GetFactionManager()).GetEnemyFaction(alliedFaction);
176  if (!enemyFaction)
177  return false;
178 
180  if (!supportEntity)
181  return false;
182 
183  float distanceSq;
184  if (initialCheck)
185  distanceSq = supportEntity.GetMinEnemyDistance();
186  else
187  distanceSq = supportEntity.GetMaxEnemyDistance();
188 
189  distanceSq *= distanceSq;
190 
191  array<SCR_ChimeraCharacter> enemyCharacters = supportEntity.GetCharactersByFaction(enemyFaction);
192  if (!enemyCharacters)
193  return false;
194 
195  vector baseOrigin = base.GetOwner().GetOrigin();
196  for (int i = enemyCharacters.Count() - 1; i >= 0; i--)
197  {
198  if (vector.DistanceSq(baseOrigin, enemyCharacters[i].GetOrigin()) < distanceSq)
199  return true;
200  }
201 
202  return false;
203  }
204 
205  //------------------------------------------------------------------------------------------------
206  static bool IsCharacterInAnyDefendTaskRange(SCR_ChimeraCharacter character)
207  {
208  array<SCR_BaseTask> tasks = new array<SCR_BaseTask>();
209  GetTaskManager().GetTasks(tasks);
210 
211  if (!tasks)
212  return false;
213 
215  if (!supportEntity)
216  return false;
217 
218  for (int i = tasks.Count() - 1; i >= 0; i--)
219  {
220  SCR_CampaignDefendTask defendTask = SCR_CampaignDefendTask.Cast(tasks[i]);
221  if (!defendTask)
222  continue;
223 
224  if (defendTask.IsCharacterInDefendTaskRange(character, supportEntity))
225  return true;
226  }
227 
228  return false;
229  }
230 
231  //*********************************//
232  //PROTECTED OVERRIDE MEMBER METHODS//
233  //*********************************//
234 
235  //------------------------------------------------------------------------------------------------
236  protected override void UpdateMapInfo()
237  {
238  //Insert task icon into base's map UI
239  //m_TargetBase cannot be null here
240  }
241 
242  //------------------------------------------------------------------------------------------------
244  protected override void ShowAvailableTask(bool afterAssigneeRemoved = false)
245  {
247  if (CanBeAssigned(reason))
248  {
249  SCR_GameModeCampaign campaign = SCR_GameModeCampaign.GetInstance();
250  if (campaign)
251  {
252  string text = TASK_AVAILABLE_TEXT + " " + GetTitle();
253  string baseName;
254 
255  if (m_TargetBase)
256  baseName = m_TargetBase.GetBaseNameUpperCase();
257 
258  SCR_PopUpNotification.GetInstance().PopupMsg(text, prio: SCR_ECampaignPopupPriority.TASK_AVAILABLE, param1: baseName, text2: TASK_HINT_TEXT, text2param1: SCR_PopUpNotification.TASKS_KEY_IMAGE_FORMAT);
259  }
260  }
261  }
262 
263  //------------------------------------------------------------------------------------------------
264  override protected void ShowTaskProgress(bool showMsg = true)
265  {
266  SCR_GameModeCampaign campaign = SCR_GameModeCampaign.GetInstance();
267  if (campaign && showMsg)
268  {
269  string baseName;
270 
271  if (m_TargetBase)
272  baseName = m_TargetBase.GetBaseNameUpperCase();
273 
274  SCR_PopUpNotification.GetInstance().PopupMsg(TASK_PROGRESS_TEXT + " " + GetTitle() + " " + TASK_AMOUNT_COMPLETED_TEXT, prio: SCR_ECampaignPopupPriority.TASK_PROGRESS, param1: baseName);
275  }
276  }
277 
278  //******************************//
279  //PUBLIC OVERRIDE MEMBER METHODS//
280  //******************************//
281 
282  //------------------------------------------------------------------------------------------------
283  override void SetDescriptionWidgetText(notnull TextWidget textWidget, string taskText)
284  {
285  string baseName;
286 
287  if (m_TargetBase)
288  baseName = m_TargetBase.GetBaseName();
289 
290  textWidget.SetTextFormat(taskText, baseName);
291  }
292 
293  //------------------------------------------------------------------------------------------------
294  override void Finish(bool showMsg = true)
295  {
296  showMsg = SCR_FactionManager.SGetLocalPlayerFaction() == m_TargetFaction;
297  super.Finish(showMsg);
298 
299  if (!m_TargetBase)
300  return;
301 
302  SCR_GameModeCampaign campaign = SCR_GameModeCampaign.GetInstance();
303  if (!campaign)
304  return;
305 
306  if (showMsg)
307  {
308  SCR_PopUpNotification.GetInstance().PopupMsg(TASK_COMPLETED_TEXT + " " + GetTitle(), prio: SCR_ECampaignPopupPriority.TASK_DONE, param1: m_TargetBase.GetBaseNameUpperCase(), sound: SCR_SoundEvent.TASK_SUCCEED, text2: SCR_BaseTask.TASK_HINT_TEXT, text2param1: SCR_PopUpNotification.TASKS_KEY_IMAGE_FORMAT);
309  }
310 
311  SCR_XPHandlerComponent comp = SCR_XPHandlerComponent.Cast(GetGame().GetGameMode().FindComponent(SCR_XPHandlerComponent));
312 
313  if (!comp)
314  return;
315 
316  // Reward XP for reconfiguring a relay
317  if (!GetTaskManager().IsProxy())
318  {
320  if (!supportClass)
321  return;
322 
323  array<SCR_ChimeraCharacter> characters = supportClass.GetCharactersByFaction(SCR_CampaignFaction.Cast(GetTargetFaction()));
324  if (!characters)
325  return;
326 
327  for (int i = characters.Count() - 1; i >= 0; i--)
328  {
329  if (IsCharacterInDefendTaskRange(characters[i]))
330  comp.AwardXP(GetGame().GetPlayerManager().GetPlayerIdFromControlledEntity(characters[i]), SCR_EXPRewards.TASK_DEFEND, 1.0);
331  }
332  };
333  }
334 
335  //------------------------------------------------------------------------------------------------
337  override void Fail(bool showMsg = true)
338  {
339  showMsg = SCR_FactionManager.SGetLocalPlayerFaction() == m_TargetFaction;
340  super.Fail(showMsg);
341 
342  if (!m_TargetBase)
343  return;
344 
345  SCR_GameModeCampaign campaign = SCR_GameModeCampaign.GetInstance();
346  if (campaign && showMsg)
347  {
348  SCR_PopUpNotification.GetInstance().PopupMsg(TASK_FAILED_TEXT + " " + GetTitle(), prio: SCR_ECampaignPopupPriority.TASK_DONE, param1: m_TargetBase.GetBaseNameUpperCase(), sound: SCR_SoundEvent.TASK_FAILED);
349  }
350  }
351 
352  //*********************//
353  //PUBLIC MEMBER METHODS//
354  //*********************//
355 
356  //------------------------------------------------------------------------------------------------
357  bool IsCharacterInDefendTaskRange(notnull SCR_ChimeraCharacter character, SCR_CampaignDefendTaskSupportEntity supportClass = null)
358  {
359  if (!supportClass)
360  {
362  if (!supportClass)
363  return false;
364  }
365 
366  float maxDistanceSq;
367  // Is ally, use ally distance
368  if (character.GetFaction() == GetTargetFaction())
369  maxDistanceSq = supportClass.GetMaxAllyDistance();
370  else
371  maxDistanceSq = supportClass.GetMaxEnemyDistance();
372 
373  maxDistanceSq *= maxDistanceSq;
374 
375  float distanceSq = vector.DistanceSq(character.GetOrigin(), GetTargetBase().GetOwner().GetOrigin());
376 
377  return (distanceSq < maxDistanceSq);
378  }
379 
380  //***************************//
381  //PUBLIC MEMBER EVENT METHODS//
382  //***************************//
383 
384  //------------------------------------------------------------------------------------------------
385  void PeriodicalCheck()
386  {
388  if (!m_TargetBase || !campaignFaction)
389  return;
390 
391  if (!GetTaskManager())
392  return;
393 
395  if (!supportEntity)
396  return;
397 
398  // Enemy presence not found == success
399  if (!FindEnemyPresence(m_TargetBase, campaignFaction, false))
400  supportEntity.FinishTask(this);
401  }
402 
403  //------------------------------------------------------------------------------------------------
404  void OnCharacterDeath(SCR_ChimeraCharacter character)
405  {
406  // Enemy died in range of this tasks target base, let's check if the town is safe
407  if (character.GetFaction() != GetTargetFaction() && IsCharacterInDefendTaskRange(character))
408  PeriodicalCheck();
409  }
410 
411  //------------------------------------------------------------------------------------------------
413  void OnBaseCaptured(SCR_MilitaryBaseComponent base, Faction faction)
414  {
415  if (!base || base != m_TargetBase || !GetTaskManager())
416  return;
417 
418  if (base.GetFaction() == m_TargetFaction)
419  return;
420 
422  if (!supportEntity)
423  return;
424 
425  supportEntity.FailTask(this);
426  }
427 
428  //------------------------------------------------------------------------------------------------
429  override string GetMapDescriptorText()
430  {
431  return GetTaskListTaskText();
432  }
433 
434  //------------------------------------------------------------------------------------------------
435  void SCR_CampaignDefendTask(IEntitySource src, IEntity parent)
436  {
437  if (SCR_Global.IsEditMode(this))
438  return;
439 
440  if (GetTaskManager().IsProxy())
441  return;
442 
443  if (SCR_BaseTaskManager.s_OnPeriodicalCheck60Second)
444  SCR_BaseTaskManager.s_OnPeriodicalCheck60Second.Insert(PeriodicalCheck);
445 
446  SCR_MilitaryBaseSystem.GetInstance().GetOnBaseFactionChanged().Insert(OnBaseCaptured);
447 
449  if (supportClass)
450  supportClass.GetOnCharacterDeath().Insert(OnCharacterDeath);
451  }
452 
453  //------------------------------------------------------------------------------------------------
454  void ~SCR_CampaignDefendTask(string description)
455  {
456  if (SCR_Global.IsEditMode(this) || !GetGame().GetGameMode())
457  return;
458 
459  if (GetTaskManager().IsProxy())
460  return;
461 
462  if (SCR_BaseTaskManager.s_OnPeriodicalCheck60Second)
463  SCR_BaseTaskManager.s_OnPeriodicalCheck60Second.Remove(PeriodicalCheck);
464 
465  SCR_MilitaryBaseSystem baseManager = SCR_MilitaryBaseSystem.GetInstance();
466 
467  if (baseManager)
468  baseManager.GetOnBaseFactionChanged().Remove(OnBaseCaptured);
469 
471  if (supportClass)
472  supportClass.GetOnCharacterDeath().Remove(OnCharacterDeath);
473  }
474 };
SCR_PlayerController
Definition: SCR_PlayerController.c:31
SCR_CampaignBaseTaskClass
Definition: SCR_CampaignBaseTask.c:2
SCR_CampaignBaseTask
Definition: SCR_CampaignBaseTask.c:9
SCR_CampaignDefendTaskClass
Definition: SCR_CampaignDefendTask.c:2
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
SCR_SoundEvent
Definition: SCR_SoundEvent.c:1
SCR_MilitaryBaseSystem
Definition: SCR_MilitaryBaseSystem.c:11
SCR_CampaignDefendTaskSupportEntity
Definition: SCR_CampaignDefendTaskSupportEntity.c:13
SCR_PopUpNotification
Takes care of dynamic and static onscreen popups.
Definition: SCR_PopupNotification.c:24
func
func
Definition: SCR_AIThreatSystem.c:5
SCR_BaseTask
A base class for tasks.
Definition: SCR_BaseTask.c:8
GetGameMode
SCR_BaseGameMode GetGameMode()
Definition: SCR_BaseGameModeComponent.c:15
SCR_GameModeCampaign
void SCR_GameModeCampaign(IEntitySource src, IEntity parent)
Definition: SCR_GameModeCampaign.c:1927
SCR_ECannotAssignReasons
SCR_ECannotAssignReasons
Definition: SCR_ECampaignTaskReasons.c:1
GetOrigin
vector GetOrigin()
Definition: SCR_AIUtilityComponent.c:279
IsProxy
protected bool IsProxy()
Definition: SCR_CampaignBuildingCompositionComponent.c:456
m_TargetFaction
protected Faction m_TargetFaction
Definition: SCR_EditableTaskComponent.c:22
distance
float distance
Definition: SCR_DestructibleTreeV2.c:29
GetTaskManager
SCR_BaseTaskManager GetTaskManager()
Definition: SCR_BaseTaskManager.c:7
SCR_ECampaignPopupPriority
SCR_ECampaignPopupPriority
Popup message priorities sorted from lowest to highest.
Definition: SCR_CampaignFeedbackComponent.c:1419
SCR_BaseTaskManager
Definition: SCR_BaseTaskManager.c:25
GetOwner
IEntity GetOwner()
Owner entity of the fuel tank.
Definition: SCR_FuelNode.c:128
SCR_BaseTaskSupportEntity
Definition: SCR_BaseTaskSupportEntity.c:8
Faction
Definition: Faction.c:12
SCR_EXPRewards
SCR_EXPRewards
Definition: SCR_XPHandlerComponent.c:403
SCR_Global
Definition: Functions.c:6
SCR_CampaignFaction
Definition: SCR_CampaignFaction.c:2
SCR_FactionManager
void SCR_FactionManager(IEntitySource src, IEntity parent)
Definition: SCR_FactionManager.c:461
SCR_CampaignDefendTask
Definition: SCR_CampaignDefendTask.c:7
SCR_CampaignMilitaryBaseComponent
Definition: SCR_CampaignMilitaryBaseComponent.c:38