Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_CampaignMilitaryBaseComponent.c
Go to the documentation of this file.
2 {
3  [Attribute("{F7E8D4834A3AFF2F}UI/Imagesets/Conflict/conflict-icons-bw.imageset", UIWidgets.ResourceNamePicker, "Imageset with foreground textures", "imageset", category: "Campaign")]
4  ResourceName m_sBuildingIconImageset;
5 
6  [Attribute("{C35F29E48086221A}Configs/Campaign/CampaignGraphLinesConfig.conf", UIWidgets.ResourceNamePicker, "", "conf", category: "Campaign")]
7  protected ref SCR_GraphLinesData m_GraphLinesData;
8 
9  [Attribute("3", category: "Campaign")]
10  protected float m_fLineWidth;
11 
12  //------------------------------------------------------------------------------------------------
14  ResourceName GetBuildingIconImageset()
15  {
17  }
18 
19  //------------------------------------------------------------------------------------------------
21  SCR_GraphLinesData GetGraphLinesData()
22  {
23  return m_GraphLinesData;
24  }
25 
26  //------------------------------------------------------------------------------------------------
28  float GetLineWidth()
29  {
30  return m_fLineWidth;
31  }
32 }
33 
36 typedef ScriptInvokerBase<OnSpawnPointAssignedDelegate> OnSpawnPointAssignedInvoker;
37 
38 class SCR_CampaignMilitaryBaseComponent : SCR_MilitaryBaseComponent
39 {
40  [Attribute("0", category: "Campaign"), RplProp()]
41  protected bool m_bIsControlPoint;
42 
43  [Attribute("0", desc: "Can this base be picked as a faction's main base?", category: "Campaign")]
44  protected bool m_bCanBeHQ;
45 
46  [Attribute("1", category: "Campaign")]
47  protected bool m_bDisableWhenUnusedAsHQ;
48 
49  [Attribute("0", desc: "If enabled, this base will be treated as an HQ when handling supply income.", category: "Campaign")]
50  protected bool m_bIsSupplyHub;
51 
52  [Attribute("#AR-MapSymbol_Installation", desc: "The display name of this base.", category: "Campaign")]
53  protected string m_sBaseName;
54 
55  [Attribute("#AR-MapSymbol_Installation", desc: "The display name of this base, in upper case.", category: "Campaign")]
56  protected string m_sBaseNameUpper;
57 
58  [Attribute("", desc: "Name of associated map location (to hide its label)", category: "Campaign")]
59  protected string m_sMapLocationName;
60 
61  [Attribute(defvalue: "0", uiwidget: UIWidgets.ComboBox, desc: "Type", enums: ParamEnumArray.FromEnum(SCR_ECampaignBaseType), category: "Campaign")]
62  protected SCR_ECampaignBaseType m_eType;
63 
64  protected ref map<int, WorldTimestamp> m_mDefendersData = new map<int, WorldTimestamp>();
65 
66  static const float RADIO_RECONFIGURATION_DURATION = 10.0;
67  static const float BARRACKS_REDUCED_DEPLOY_COST = 0.5;
68  static const int UNDER_ATTACK_WARNING_PERIOD = 60;
69  static const int INVALID_PLAYER_INDEX = -1;
70  static const int INVALID_FACTION_INDEX = -1;
71  static const int RESPAWN_DELAY_AFTER_CAPTURE = 180000;
72  static const int RELAY_BASE_RADIUS = 100;
73 
74  static const int SUPPLY_DEPOT_CAPACITY = 4500;
75  static const int DEFENDERS_CHECK_PERIOD = 30000;
76  static const int DEFENDERS_REWARD_PERIOD = 120000;
77  static const int DEFENDERS_REWARD_MULTIPLIER = 3;
78 
79  protected static const int TICK_TIME = 1;
80  protected static const int CONTESTED_RESPAWN_DELAY = 35;
81  protected static const int BASES_IN_RANGE_RESUPPLY_THRESHOLD = 5; // max bases to be taken into account when calculating supply income
82  protected static const float HQ_VEHICLE_SPAWN_RADIUS = 40;
83  protected static const float HQ_VEHICLE_QUERY_SPACE = 6;
84  protected static const string RADIO_CHATTER_SIGNAL_NAME = "RadioChatter";
85  protected static const string ESTABLISH_ACTION_SIGNAL_NAME = "EstablishAction";
86 
87  protected ref OnSpawnPointAssignedInvoker m_OnSpawnPointAssigned;
88 
89  protected ref array<SCR_CampaignMilitaryBaseComponent> m_aBasesInRadioRange = {};
90  protected ref array<SCR_AmbientPatrolSpawnPointComponent> m_aRemnants = {};
91  protected ref array<IEntity> m_aStartingVehicles = {};
92  protected ref array<SCR_ERadioMsg> m_aServiceBuiltMsgQueue = {};
93 
94  protected float m_fStartingSupplies;
95  protected float m_fSuppliesArrivalTime = float.MAX;
96  protected float m_fNextFrameCheck;
97  protected float m_fTimer;
98  protected float m_fRadioRangeDefault;
99  protected WorldTimestamp m_fLastEnemyContactTimestamp;
100 
101  protected bool m_bLocalPlayerPresent;
102 
103  protected SCR_CampaignMilitaryBaseMapDescriptorComponent m_MapDescriptor;
104 
105  protected SCR_SpawnPoint m_SpawnPoint;
106 
107  protected SCR_CampaignFaction m_CapturingFaction;
108  protected SCR_CampaignFaction m_OwningFactionPrevious;
109 
110  protected BaseRadioComponent m_RadioComponent;
111 
112  protected IEntity m_HQRadio;
113  protected IEntity m_HQTent;
114 
115  protected SCR_CampaignMapUIBase m_UIElement;
116 
117  protected SCR_TimedWaypoint m_SeekDestroyWP;
118 
119  protected ref array<SCR_AIGroup> m_aDefendersGroups = {};
120 
121  [RplProp(onRplName: "OnHQSet")]
122  protected bool m_bIsHQ;
123 
124  [RplProp(onRplName: "OnInitialized")]
125  protected bool m_bInitialized;
126 
127  [RplProp()]
128  protected int m_iSupplyRegenAmount;
129 
130  [RplProp(onRplName: "OnHasSignalChanged")]
131  protected SCR_ECampaignHQRadioComms m_eRadioCoverageBLUFOR = SCR_ECampaignHQRadioComms.NONE;
132 
133  [RplProp(onRplName: "OnHasSignalChanged")]
134  protected SCR_ECampaignHQRadioComms m_eRadioCoverageOPFOR = SCR_ECampaignHQRadioComms.NONE;
135 
136  [RplProp(onRplName: "OnCapturingFactionChanged")]
137  protected int m_iCapturingFaction = INVALID_FACTION_INDEX;
138 
139  [RplProp()]
140  protected int m_iReconfiguredBy = INVALID_PLAYER_INDEX;
141 
142  [RplProp(onRplName: "OnRadioRangeChanged")]
143  protected float m_fRadioRange;
144 
145  [RplProp(onRplName: "OnRespawnCooldownChanged")]
146  protected WorldTimestamp m_fRespawnAvailableSince;
147 
148  [RplProp(onRplName: "OnAttackingFactionChanged")]
149  protected int m_iAttackingFaction = -1;
150 
151  //------------------------------------------------------------------------------------------------
154  bool IsControlPoint()
155  {
156  return m_bIsControlPoint;
157  }
158 
159  //------------------------------------------------------------------------------------------------
162  bool CanBeHQ()
163  {
164  return m_bCanBeHQ;
165  }
166 
167  //------------------------------------------------------------------------------------------------
170  bool DisableWhenUnusedAsHQ()
171  {
173  }
174 
175  //------------------------------------------------------------------------------------------------
177  WorldTimestamp GetRespawnTimestamp()
178  {
180  }
181 
182  //------------------------------------------------------------------------------------------------
184  void Initialize()
185  {
186  if (IsProxy())
187  return;
188 
189  m_bInitialized = true;
190  Replication.BumpMe();
191  OnInitialized();
192  }
193 
194  //------------------------------------------------------------------------------------------------
196  void Disable()
197  {
198  if (IsProxy())
199  return;
200 
201  GetGame().GetCallqueue().Remove(SpawnBuilding);
202  GetGame().GetCallqueue().Remove(SpawnStartingVehicles);
203  GetGame().GetCallqueue().Remove(EvaluateDefenders);
204  GetGame().GetCallqueue().Remove(SupplyIncomeTimer);
205  GetGame().GetCallqueue().Remove(HandleSpawnPointFaction);
206  //GetGame().GetCallqueue().Remove(SpawnSavedBuildings);
207  DeleteStartingVehicles();
208 
209  m_FactionComponent.SetAffiliatedFaction(null);
210 
211  if (m_HQTent)
212  RplComponent.DeleteRplEntity(m_HQTent, false);
213 
214  m_bInitialized = false;
215  Replication.BumpMe();
216  OnDisabled();
217  }
218 
219  //------------------------------------------------------------------------------------------------
221  void OnInitialized()
222  {
223  if (!m_bInitialized)
224  return;
225 
226  SCR_GameModeCampaign campaign = SCR_GameModeCampaign.GetInstance();
227 
228  if (!campaign)
229  return;
230 
231  // Register default base spawnpoint
232  SCR_SpawnPoint spawnpoint;
233  IEntity child = GetOwner().GetChildren();
234 
235  while (child)
236  {
237  spawnpoint = SCR_SpawnPoint.Cast(child);
238 
239  if (spawnpoint)
240  {
241  m_SpawnPoint = spawnpoint;
242 
243  SCR_CampaignBuildingProviderComponent buildingProvider = SCR_CampaignBuildingProviderComponent.Cast(GetOwner().FindComponent(SCR_CampaignBuildingProviderComponent));
244  if (buildingProvider)
245  m_SpawnPoint.SetSpawnPositionRange(buildingProvider.GetBuildingRadius());
246  else
247  m_SpawnPoint.SetSpawnPositionRange(m_iRadius);
248 
250  m_OnSpawnPointAssigned.Invoke(spawnpoint);
251 
252  break;
253  }
254 
255  child = child.GetSibling();
256  }
257 
258  // Initialize registered services
259  array<SCR_ServicePointComponent> services = {};
260  GetServices(services);
261 
262  foreach (SCR_ServicePointComponent service : services)
263  {
264  OnServiceBuilt(service);
265  }
266 
267  if (RplSession.Mode() != RplMode.Dedicated)
268  {
269  ConnectToCampaignBasesSystem();
270 
271  Faction playerFaction = SCR_FactionManager.SGetLocalPlayerFaction();
272 
273  if (!playerFaction)
274  playerFaction = campaign.GetBaseManager().GetLocalPlayerFaction();
275 
276  if (playerFaction)
277  OnLocalPlayerFactionAssigned(playerFaction);
278  else
279  campaign.GetOnFactionAssignedLocalPlayer().Insert(OnLocalPlayerFactionAssigned);
280  }
281 
282  campaign.GetBaseManager().GetOnAllBasesInitialized().Insert(OnAllBasesInitialized);
283 
284  if (IsProxy())
285  {
286  campaign.GetBaseManager().AddActiveBase();
287  return;
288  }
289  else if (!m_bIsHQ && SCR_XPHandlerComponent.Cast(GetGame().GetGameMode().FindComponent(SCR_XPHandlerComponent)))
290  {
291  Math.Randomize(-1);
292  GetGame().GetCallqueue().CallLater(EvaluateDefenders, DEFENDERS_CHECK_PERIOD + Math.RandomIntInclusive(0, DEFENDERS_CHECK_PERIOD * 0.1), true);
293  }
294 
295  SCR_CampaignSeizingComponent seizingComponent = SCR_CampaignSeizingComponent.Cast(GetOwner().FindComponent(SCR_CampaignSeizingComponent));
296 
297  if (seizingComponent)
298  {
299  seizingComponent.GetOnCaptureStart().Insert(OnCaptureStart);
300  seizingComponent.GetOnCaptureInterrupt().Insert(EndCapture);
301  }
302 
303  if (m_eType == SCR_ECampaignBaseType.BASE && !campaign.IsTutorial())
304  {
305  // Supplies autoregen loop
306  GetGame().GetCallqueue().CallLater(SupplyIncomeTimer, SCR_GameModeCampaign.UI_UPDATE_DELAY, true, false);
307 
308  // Refresh spawnpoint faction after loaded data has been applied
309  GetGame().GetCallqueue().CallLater(HandleSpawnPointFaction, SCR_GameModeCampaign.BACKEND_DELAY);
310  }
311  }
312 
313  //------------------------------------------------------------------------------------------------
316  void ApplyHeaderSettings(notnull SCR_CampaignCustomBase settings)
317  {
318  m_bCanBeHQ = settings.GetCanBeHQ();
319  m_bDisableWhenUnusedAsHQ = settings.GetDisableWhenUnusedAsHQ();
320  m_bIsControlPoint = settings.IsControlPoint();
321 
322  float radioRange = settings.GetRadioRange();
323 
324  if (radioRange < 0)
325  return;
326 
327  BaseRadioComponent radio = BaseRadioComponent.Cast(GetOwner().FindComponent(BaseRadioComponent));
328 
329  if (!radio)
330  return;
331 
332  BaseTransceiver transceiver = radio.GetTransceiver(0);
333 
334  if (!transceiver)
335  return;
336 
337  m_fRadioRangeDefault = radioRange;
338  transceiver.SetRange(radioRange);
339  RecalculateRadioRange();
340  }
341 
342  //------------------------------------------------------------------------------------------------
343  override void OnServiceStateChanged(SCR_EServicePointStatus state, notnull SCR_ServicePointComponent serviceComponent)
344  {
345  switch (state)
346  {
347  case SCR_EServicePointStatus.UNDER_CONSTRUCTION:
348  {
349  return;
350  }
351 
352  case SCR_EServicePointStatus.ONLINE:
353  {
354  OnServiceBuilt(serviceComponent);
355 
356  SCR_GameModeCampaign campaign = SCR_GameModeCampaign.GetInstance();
357  if (!campaign)
358  return;
359 
360  SCR_CampaignMilitaryBaseManager baseManager = campaign.GetBaseManager();
361  if (!baseManager)
362  return;
363 
364  baseManager.OnServiceBuilt(state, serviceComponent);
365  return;
366  }
367  }
368  }
369 
370  //------------------------------------------------------------------------------------------------
372  void OnServiceBuilt(notnull SCR_ServicePointComponent service)
373  {
374  bool duringInit = (GetGame().GetWorld().GetWorldTime() <= 0);
375 
376  // Delayed call so the composition has time to properly load and register its entire hierarchy on clients as well
377  GetGame().GetCallqueue().CallLater(OnServiceBuilt_AfterInit, SCR_GameModeCampaign.MEDIUM_DELAY, false, service);
378 
379  EEditableEntityLabel serviceType = service.GetLabel();
380  SCR_ERadioMsg radio = SCR_ERadioMsg.NONE;
381  SCR_CampaignFaction owner = GetCampaignFaction();
382 
383  switch (serviceType)
384  {
385  case EEditableEntityLabel.SERVICE_SUPPLY_STORAGE:
386  {
387  radio = SCR_ERadioMsg.BUILT_SUPPLY;
388  break;
389  }
390 
391  case EEditableEntityLabel.SERVICE_FUEL:
392  {
393  radio = SCR_ERadioMsg.BUILT_FUEL;
394  break;
395  }
396 
397  case EEditableEntityLabel.SERVICE_ARMORY:
398  {
399  radio = SCR_ERadioMsg.BUILT_ARMORY;
400  break;
401  }
402 
403  case EEditableEntityLabel.SERVICE_VEHICLE_DEPOT_LIGHT:
404  {
405  radio = SCR_ERadioMsg.BUILT_VEHICLES_LIGHT;
406  break;
407  }
408 
409  case EEditableEntityLabel.SERVICE_VEHICLE_DEPOT_HEAVY:
410  {
411  radio = SCR_ERadioMsg.BUILT_VEHICLES_HEAVY;
412  break;
413  }
414 
415  case EEditableEntityLabel.SERVICE_ANTENNA:
416  {
417  radio = SCR_ERadioMsg.BUILT_ANTENNA;
418 
419  if (!IsProxy())
420  RecalculateRadioRange();
421 
422  break;
423  }
424 
425  case EEditableEntityLabel.SERVICE_LIVING_AREA:
426  {
427  radio = SCR_ERadioMsg.BUILT_BARRACKS;
428  break;
429  }
430 
431  case EEditableEntityLabel.SERVICE_FIELD_HOSPITAL:
432  {
433  radio = SCR_ERadioMsg.BUILT_FIELD_HOSPITAL;
434  break;
435  }
436 
437  case EEditableEntityLabel.SERVICE_HELIPAD:
438  {
439  radio = SCR_ERadioMsg.BUILT_HELIPAD;
440  break;
441  }
442  }
443 
444  if (IsProxy())
445  return;
446 
447  SCR_CampaignBuildingCompositionComponent buildingComponent = SCR_CampaignBuildingCompositionComponent.Cast(SCR_EntityHelper.GetMainParent(service.GetOwner(), true).FindComponent(SCR_CampaignBuildingCompositionComponent));
448 
449  if (buildingComponent && !buildingComponent.GetProviderEntity())
450  buildingComponent.SetProviderEntityServer(GetOwner());
451 
452  if (radio != SCR_ERadioMsg.NONE && owner && IsHQRadioTrafficPossible(GetFaction(), SCR_ECampaignHQRadioComms.BOTH_WAYS) && !duringInit)
453  {
454  m_aServiceBuiltMsgQueue.Insert(radio);
455  GetGame().GetCallqueue().Remove(SendHighestPriorityMessage);
456 
457  // Delayed call so we have all messages gathered
458  GetGame().GetCallqueue().CallLater(SendHighestPriorityMessage, SCR_GameModeCampaign.UI_UPDATE_DELAY, false, owner);
459  }
460 
461  foreach (SCR_MilitaryBaseLogicComponent logic : m_aSystems)
462  {
463  SCR_CampaignSeizingComponent seizingComponent = SCR_CampaignSeizingComponent.Cast(logic);
464 
465  if (!seizingComponent)
466  continue;
467 
468  seizingComponent.RefreshSeizingTimer();
469  }
470  }
471 
472  //------------------------------------------------------------------------------------------------
473  protected void SendHighestPriorityMessage(notnull SCR_CampaignFaction faction)
474  {
475  if (m_aServiceBuiltMsgQueue.IsEmpty())
476  return;
477 
478  SCR_ERadioMsg topPriorityEnum = m_aServiceBuiltMsgQueue[0];
479 
480  foreach (SCR_ERadioMsg msg : m_aServiceBuiltMsgQueue)
481  {
482  if (msg < topPriorityEnum)
483  topPriorityEnum = msg;
484  }
485 
486  m_aServiceBuiltMsgQueue.Clear();
487  faction.SendHQMessage(topPriorityEnum, m_iCallsign);
488  }
489 
490  //------------------------------------------------------------------------------------------------
492  void OnServiceRemoved(notnull SCR_MilitaryBaseLogicComponent service)
493  {
494  SCR_ServicePointComponent serviceCast = SCR_ServicePointComponent.Cast(service);
495 
496  if (!serviceCast || serviceCast.GetServiceState() != SCR_EServicePointStatus.ONLINE)
497  return;
498 
499  if (IsProxy())
500  return;
501 
502  if (serviceCast.GetType() == SCR_EServicePointType.RADIO_ANTENNA)
503  RecalculateRadioRange();
504 
505  foreach (SCR_MilitaryBaseLogicComponent logic : m_aSystems)
506  {
507  SCR_CampaignSeizingComponent seizingComponent = SCR_CampaignSeizingComponent.Cast(logic);
508 
509  if (!seizingComponent)
510  continue;
511 
512  seizingComponent.RefreshSeizingTimer();
513  }
514  }
515 
516  //------------------------------------------------------------------------------------------------
518  void OnServiceBuilt_AfterInit(SCR_ServicePointComponent service)
519  {
520  // In case the composition has been deleted in the meantime
521  if (!service)
522  return;
523 
524  if (!IsProxy())
525  {
526  ResourceName delegatePrefab = service.GetDelegatePrefab();
527 
528  if (delegatePrefab.IsEmpty())
529  return;
530 
531  Resource delegateResource = Resource.Load(delegatePrefab);
532 
533  if (!delegateResource || !delegateResource.IsValid())
534  return;
535 
536  EntitySpawnParams params = EntitySpawnParams();
537  params.TransformMode = ETransformMode.WORLD;
538  service.GetOwner().GetTransform(params.Transform);
539  IEntity delegateEntity = GetGame().SpawnEntityPrefab(delegateResource, null, params);
540 
541  if (!delegateEntity)
542  return;
543 
544  SCR_ServicePointDelegateComponent delegateComponent = SCR_ServicePointDelegateComponent.Cast(delegateEntity.FindComponent(SCR_ServicePointDelegateComponent));
545 
546  if (!delegateComponent)
547  return;
548 
549  service.SetDelegate(delegateComponent);
550  delegateComponent.SetParentBaseId(Replication.FindId(this));
551  }
552 
553  // Delayed call so clients know about the new delegate
554  if (RplSession.Mode() != RplMode.Dedicated)
555  GetGame().GetCallqueue().CallLater(m_MapDescriptor.HandleMapInfo, SCR_GameModeCampaign.DEFAULT_DELAY, false, null);
556  }
557 
558  //------------------------------------------------------------------------------------------------
560  void OnDisabled()
561  {
562  SCR_GameModeCampaign campaign = SCR_GameModeCampaign.GetInstance();
563 
564  if (!campaign)
565  return;
566 
567  if (m_SpawnPoint)
568  {
569  m_SpawnPoint.SetFactionKey(string.Empty);
570  m_SpawnPoint = null;
571  }
572 
573  if (m_MapDescriptor)
574  m_MapDescriptor.Item().SetVisible(false);
575 
576  if (m_UIElement)
577  m_UIElement.SetVisible(false);
578 
579  campaign.GetOnFactionAssignedLocalPlayer().Remove(OnLocalPlayerFactionAssigned);
580 
581  if (RplSession.Mode() != RplMode.Dedicated)
582  DisconnectFromCampaignBasesSystem();
583 
584  campaign.GetBaseManager().GetOnAllBasesInitialized().Remove(OnAllBasesInitialized);
585 
586  SCR_CampaignSeizingComponent seizingComponent = SCR_CampaignSeizingComponent.Cast(GetOwner().FindComponent(SCR_CampaignSeizingComponent));
587 
588  if (seizingComponent)
589  {
590  seizingComponent.GetOnCaptureStart().Remove(OnCaptureStart);
591  seizingComponent.GetOnCaptureInterrupt().Remove(EndCapture);
592  }
593  }
594 
595  //------------------------------------------------------------------------------------------------
598  bool IsInitialized()
599  {
600  return m_bInitialized;
601  }
602 
603  //------------------------------------------------------------------------------------------------
605  void SetAsHQ(bool isHQ)
606  {
607  if (IsProxy())
608  return;
609 
610  m_bIsHQ = isHQ;
611  SCR_CampaignFaction faction = GetCampaignFaction();
612 
613  if (m_bIsHQ)
614  {
615  SCR_CampaignMilitaryBaseComponent previousHQ = faction.GetMainBase();
616  SCR_CampaignMilitaryBaseComponent enemyHQ = SCR_CampaignFactionManager.Cast(GetGame().GetFactionManager()).GetEnemyFaction(faction).GetMainBase();
617 
618  if (previousHQ && previousHQ != this && previousHQ != enemyHQ)
619  {
620  if (previousHQ.GetDisableWhenUnusedAsHQ())
621  previousHQ.Disable();
622  }
623  }
624 
625  Replication.BumpMe();
626  OnHQSet();
627  }
628 
629  //------------------------------------------------------------------------------------------------
630  protected void OnHQSet()
631  {
633 
634  if (owner && m_bIsHQ)
635  owner.SetMainBase(this);
636 
637  if (IsProxy())
638  return;
639 
640  HandleSpawnPointFaction();
641 
642  GetGame().GetCallqueue().Remove(SpawnStartingVehicles);
643 
644  if (m_bIsHQ)
645  {
646  SupplyIncomeTimer(true);
647  GetGame().GetCallqueue().CallLater(SpawnStartingVehicles, 1500, false); // Delay so we don't spawn stuff during init
648  }
649  }
650 
651  //------------------------------------------------------------------------------------------------
654  bool IsHQ()
655  {
656  return m_bIsHQ;
657  }
658 
659  //------------------------------------------------------------------------------------------------
661  bool CostSuppliesToSpawn()
662  {
663  return !m_bIsHQ;
664  }
665 
666  //------------------------------------------------------------------------------------------------
668  OnSpawnPointAssignedInvoker GetOnSpawnPointAssigned()
669  {
672 
673  return m_OnSpawnPointAssigned;
674  }
675 
676  //------------------------------------------------------------------------------------------------
678  float GetRadioRange()
679  {
680  return m_fRadioRange;
681  }
682 
683  //------------------------------------------------------------------------------------------------
684  protected float GetRelayRadioRange(notnull BaseRadioComponent radio)
685  {
686  float range;
687  int transceiversCount;
688  RelayTransceiver transceiver;
689  float thisRange;
690 
691  for (int i = 0, count = radio.TransceiversCount(); i < count; i++)
692  {
693  transceiver = RelayTransceiver.Cast(radio.GetTransceiver(i));
694 
695  if (!transceiver)
696  continue;
697 
698  thisRange = transceiver.GetRange();
699 
700  if (thisRange <= range)
701  continue;
702 
703  range = thisRange;
704  }
705 
706  return range;
707  }
708 
709  //------------------------------------------------------------------------------------------------
711  void UpdateBasesInRadioRange()
712  {
713  SCR_MilitaryBaseSystem baseManager = SCR_MilitaryBaseSystem.GetInstance();
714  array<SCR_MilitaryBaseComponent> bases = {};
715  baseManager.GetBases(bases);
716 
718  float radioRange = GetRadioRange();
719  radioRange = radioRange * radioRange; // We're checking square distance
720  vector basePosition = GetOwner().GetOrigin();
721 
723 
724  foreach (SCR_MilitaryBaseComponent base : bases)
725  {
726  campaignBase = SCR_CampaignMilitaryBaseComponent.Cast(base);
727 
728  if (!campaignBase || !campaignBase.IsInitialized() || campaignBase == this)
729  continue;
730 
731  if (vector.DistanceSqXZ(basePosition, campaignBase.GetOwner().GetOrigin()) < radioRange)
732  m_aBasesInRadioRange.Insert(campaignBase);
733  }
734  }
735 
736  //------------------------------------------------------------------------------------------------
740  bool CanReachByRadio(notnull SCR_CampaignMilitaryBaseComponent base)
741  {
742  return m_aBasesInRadioRange.Contains(base);
743  }
744 
745  //------------------------------------------------------------------------------------------------
749  bool CanReachByRadio(notnull SCR_CampaignMobileAssemblyStandaloneComponent mobileAssembly)
750  {
751  return (vector.DistanceXZ(GetOwner().GetOrigin(), mobileAssembly.GetOwner().GetOrigin()) <= GetRadioRange());
752  }
753 
754  //------------------------------------------------------------------------------------------------
757  void SetHQRadioConverage(notnull SCR_Faction faction, SCR_ECampaignHQRadioComms coverage)
758  {
759  SCR_GameModeCampaign campaign = SCR_GameModeCampaign.GetInstance();
760 
761  if (!campaign)
762  return;
763 
764  if (faction == campaign.GetFactionByEnum(SCR_ECampaignFaction.BLUFOR))
765  {
766  if (m_eRadioCoverageBLUFOR == coverage)
767  return;
768 
769  m_eRadioCoverageBLUFOR = coverage;
770  }
771  else if (faction == campaign.GetFactionByEnum(SCR_ECampaignFaction.OPFOR))
772  {
773  if (m_eRadioCoverageOPFOR == coverage)
774  return;
775 
776  m_eRadioCoverageOPFOR = coverage;
777  }
778 
779  Replication.BumpMe();
780  OnHasSignalChanged();
781  }
782 
783  //------------------------------------------------------------------------------------------------
786  SCR_ECampaignHQRadioComms GetHQRadioCoverage(notnull Faction faction)
787  {
788  SCR_GameModeCampaign campaign = SCR_GameModeCampaign.GetInstance();
789 
790  if (!campaign)
791  return SCR_ECampaignHQRadioComms.NONE;
792 
793  if (faction == campaign.GetFactionByEnum(SCR_ECampaignFaction.BLUFOR))
794  return m_eRadioCoverageBLUFOR;
795  else if (faction == campaign.GetFactionByEnum(SCR_ECampaignFaction.OPFOR))
796  return m_eRadioCoverageOPFOR;
797 
798  return SCR_ECampaignHQRadioComms.NONE;
799  }
800 
801  //------------------------------------------------------------------------------------------------
806  bool IsHQRadioTrafficPossible(Faction faction, SCR_ECampaignHQRadioComms direction = SCR_ECampaignHQRadioComms.RECEIVE)
807  {
808  SCR_GameModeCampaign campaign = SCR_GameModeCampaign.GetInstance();
809 
810  if (!campaign)
811  return false;
812 
813  bool isBLUFOR = (faction == campaign.GetFactionByEnum(SCR_ECampaignFaction.BLUFOR));
814 
815  if (!isBLUFOR && faction != campaign.GetFactionByEnum(SCR_ECampaignFaction.OPFOR))
816  return false;
817 
818  switch (direction)
819  {
820  case SCR_ECampaignHQRadioComms.RECEIVE:
821  {
822  if (isBLUFOR)
823  return (m_eRadioCoverageBLUFOR == SCR_ECampaignHQRadioComms.RECEIVE || m_eRadioCoverageBLUFOR == SCR_ECampaignHQRadioComms.BOTH_WAYS);
824  else
825  return (m_eRadioCoverageOPFOR == SCR_ECampaignHQRadioComms.RECEIVE || m_eRadioCoverageOPFOR == SCR_ECampaignHQRadioComms.BOTH_WAYS);
826 
827  break;
828  }
829 
830  case SCR_ECampaignHQRadioComms.SEND:
831  {
832  if (isBLUFOR)
833  return (m_eRadioCoverageBLUFOR == SCR_ECampaignHQRadioComms.SEND || m_eRadioCoverageBLUFOR == SCR_ECampaignHQRadioComms.BOTH_WAYS);
834  else
835  return (m_eRadioCoverageOPFOR == SCR_ECampaignHQRadioComms.SEND || m_eRadioCoverageOPFOR == SCR_ECampaignHQRadioComms.BOTH_WAYS);
836 
837  break;
838  }
839  }
840 
841  if (isBLUFOR)
842  return (direction == m_eRadioCoverageBLUFOR);
843 
844  return (direction == m_eRadioCoverageOPFOR);
845  }
846 
847  //------------------------------------------------------------------------------------------------
848  protected void OnLocalPlayerFactionAssigned(Faction assignedFaction)
849  {
850  UpdateBasesInRadioRange();
851  m_MapDescriptor.MapSetup(assignedFaction);
852  m_MapDescriptor.HandleMapInfo(SCR_CampaignFaction.Cast(assignedFaction));
853  HideMapLocationLabel();
854  }
855 
856  //------------------------------------------------------------------------------------------------
858  float GetBaseSpawnCostFactor()
859  {
861  return BARRACKS_REDUCED_DEPLOY_COST;
862 
863  return 1.0;
864  }
865 
866  //------------------------------------------------------------------------------------------------
868  int GetBaseSpawnCost()
869  {
870  SCR_GameModeCampaign campaign = SCR_GameModeCampaign.GetInstance();
871 
872  if (!campaign)
873  return -1;
874 
875  //reduce spawning cost if barracks are built
876  return campaign.GetSpawnCost() * GetBaseSpawnCostFactor();
877  }
878 
879  //------------------------------------------------------------------------------------------------
880  protected void OnCaptureStart(SCR_Faction faction)
881  {
882  SCR_CampaignFaction factionC = SCR_CampaignFaction.Cast(faction);
883 
884  if (!factionC)
885  return;
886 
887  BeginCapture(factionC);
888  }
889 
890  //------------------------------------------------------------------------------------------------
892  void RefreshTasks()
893  {
894  if (IsProxy())
895  return;
896 
898 
899  if (supportClass)
900  supportClass.GenerateCaptureTasks(GetOwner());
901  }
902 
903  //------------------------------------------------------------------------------------------------
906  void NotifyAboutEnemyAttack(notnull Faction attackingFaction)
907  {
908  if (!GetFaction())
909  return;
910 
911  if (!IsHQRadioTrafficPossible(GetFaction()))
912  return;
913 
914  ChimeraWorld world = GetOwner().GetWorld();
915  WorldTimestamp curTime = world.GetServerTimestamp();
917  {
918  if (m_fLastEnemyContactTimestamp.PlusSeconds(SCR_CampaignMilitaryBaseComponent.UNDER_ATTACK_WARNING_PERIOD).Greater(curTime))
919  return;
920  }
921 
922  GetCampaignFaction().SendHQMessage(SCR_ERadioMsg.BASE_UNDER_ATTACK, GetCallsign());
924 
925  if (!GetCapturingFaction())
926  SetAttackingFaction(GetGame().GetFactionManager().GetFactionIndex(attackingFaction));
927  }
928 
929  //------------------------------------------------------------------------------------------------
931  void EndCapture()
932  {
933  if (IsProxy())
934  return;
935 
936  if (!m_CapturingFaction)
937  return;
938 
939  m_CapturingFaction = null;
940 
941  m_iCapturingFaction = INVALID_FACTION_INDEX;
942  Replication.BumpMe();
943  OnCapturingFactionChanged();
944  }
945 
946  //------------------------------------------------------------------------------------------------
948  int GetReconfiguredByID()
949  {
950  return m_iReconfiguredBy;
951  }
952 
953  //------------------------------------------------------------------------------------------------
955  bool GetDisableWhenUnusedAsHQ()
956  {
958  }
959 
960  //------------------------------------------------------------------------------------------------
962  bool BeginCapture(SCR_CampaignFaction faction, int playerID = INVALID_PLAYER_INDEX)
963  {
964  if (IsProxy() || !faction)
965  return false;
966 
967  // The capturing faction already owns this base, return
968  if (faction == GetFaction())
969  return false;
970 
971  // Change the capturing faction
972  m_CapturingFaction = faction;
973 
974  m_iCapturingFaction = SCR_CampaignFactionManager.Cast(GetGame().GetFactionManager()).GetFactionIndex(faction);
975 
976  m_iReconfiguredBy = playerID;
977  Replication.BumpMe();
978  OnCapturingFactionChanged();
979  NotifyAboutEnemyAttack(faction);
980 
981  return true;
982  }
983 
984  //------------------------------------------------------------------------------------------------
986  protected void HandleSpawnPointFaction()
987  {
988  if (!m_SpawnPoint)
989  return;
990 
991  SCR_CampaignFaction owner = GetCampaignFaction();
992  FactionKey currentKey = m_SpawnPoint.GetFactionKey();
993  FactionKey ownerKey;
994  FactionKey finalKey;
995 
996  if (owner)
997  {
998  ownerKey = owner.GetFactionKey();
999  finalKey = ownerKey;
1000  }
1001 
1002  if (ownerKey == FactionKey.Empty)
1003  {
1004  if (currentKey != FactionKey.Empty)
1005  m_SpawnPoint.SetFactionKey(FactionKey.Empty);
1006 
1007  return;
1008  }
1009 
1010  if (!m_bIsHQ && !IsHQRadioTrafficPossible(owner, SCR_ECampaignHQRadioComms.BOTH_WAYS))
1011  finalKey = FactionKey.Empty;
1012 
1013  ChimeraWorld world = GetOwner().GetWorld();
1014  if (world.GetServerTimestamp().Less(m_fRespawnAvailableSince) && !m_bIsHQ)
1015  finalKey = FactionKey.Empty;
1016 
1017  if (GetSupplies() < GetBaseSpawnCost() && !m_bIsHQ)
1018  finalKey = FactionKey.Empty;
1019 
1020  if (finalKey == currentKey)
1021  return;
1022 
1023  m_SpawnPoint.SetFactionKey(finalKey);
1024  }
1025  //------------------------------------------------------------------------------------------------
1027  SCR_SpawnPoint GetSpawnPoint()
1028  {
1029  return m_SpawnPoint;
1030  }
1032  //------------------------------------------------------------------------------------------------
1034  override void OnCapturingFactionChanged()
1035  {
1036  super.OnCapturingFactionChanged();
1037 
1038  m_CapturingFaction = SCR_CampaignFactionManager.Cast(GetGame().GetFactionManager()).GetCampaignFactionByIndex(m_iCapturingFaction);
1039 
1040  if (m_SpawnPoint)
1041  {
1043  m_SpawnPoint.SetRespawnTime(CONTESTED_RESPAWN_DELAY);
1044  else
1045  m_SpawnPoint.SetRespawnTime(0);
1046  }
1047 
1048  // Play or stop radio tuning SFX
1049  if (m_HQRadio)
1050  {
1051  SignalsManagerComponent comp = SignalsManagerComponent.Cast(m_HQRadio.FindComponent(SignalsManagerComponent));
1052 
1053  if (comp)
1054  {
1055  if (m_CapturingFaction)
1056  comp.SetSignalValue(comp.AddOrFindSignal(ESTABLISH_ACTION_SIGNAL_NAME), 1);
1057  else
1058  comp.SetSignalValue(comp.AddOrFindSignal(ESTABLISH_ACTION_SIGNAL_NAME), 0);
1059  }
1060  }
1061 
1062  if (!IsProxy())
1063  {
1064  SCR_GameModeCampaign campaign = SCR_GameModeCampaign.GetInstance();
1065 
1066  if (campaign)
1067  campaign.GetBaseManager().EvaluateControlPoints();
1068  }
1069 
1070  if (RplSession.Mode() != RplMode.Dedicated)
1071  {
1072  if (m_CapturingFaction && GetFaction() == SCR_FactionManager.SGetLocalPlayerFaction())
1073  FlashBaseIcon(faction: m_CapturingFaction, infiniteTimer: true);
1074  else
1075  FlashBaseIcon(changeToDefault: true);
1076  }
1077  }
1079  //------------------------------------------------------------------------------------------------
1081  void FlashBaseIcon(float remainingTime = 0, Faction faction = null, bool changeToDefault = false, bool infiniteTimer = false)
1082  {
1083  GetGame().GetCallqueue().Remove(FlashBaseIcon);
1084 
1085  if (m_UIElement)
1086  m_UIElement.FlashBaseIcon(faction, changeToDefault);
1087 
1088  remainingTime -= SCR_CampaignFeedbackComponent.ICON_FLASH_PERIOD;
1089 
1090  if (infiniteTimer || remainingTime > 0 || !changeToDefault)
1091  GetGame().GetCallqueue().CallLater(FlashBaseIcon, SCR_CampaignFeedbackComponent.ICON_FLASH_PERIOD * 1000, false, remainingTime, faction, !changeToDefault, infiniteTimer);
1092  }
1094  //------------------------------------------------------------------------------------------------
1096  void OnHasSignalChanged()
1097  {
1098  if (!IsProxy())
1099  {
1100  HandleSpawnPointFaction();
1101  SupplyIncomeTimer(true);
1102  }
1103 
1104  if (RplSession.Mode() != RplMode.Dedicated)
1105  m_MapDescriptor.HandleMapInfo();
1106 
1107  SCR_GameModeCampaign campaign = SCR_GameModeCampaign.GetInstance();
1108 
1109  if (campaign)
1110  campaign.GetBaseManager().GetOnSignalChanged().Invoke(this);
1111  }
1112 
1113  //------------------------------------------------------------------------------------------------
1114  protected void OnSuppliesChanged()
1115  {
1116  if (!IsProxy() && !m_bIsHQ)
1117  HandleSpawnPointFaction();
1118 
1119  if (RplSession.Mode() != RplMode.Dedicated && m_UIElement)
1120  m_UIElement.SetIconInfoText();
1121  }
1123  //------------------------------------------------------------------------------------------------
1125  override protected void OnFactionChanged(FactionAffiliationComponent owner, Faction previousFaction, Faction faction)
1126  {
1127  super.OnFactionChanged(owner, previousFaction, faction);
1128 
1129  if (!GetGame().InPlayMode())
1130  return;
1131 
1132  SCR_CampaignFaction newCampaignFaction = SCR_CampaignFaction.Cast(faction);
1133 
1134  if (!newCampaignFaction)
1135  return;
1136 
1137  SCR_GameModeCampaign campaign = SCR_GameModeCampaign.GetInstance();
1138 
1139  if (!campaign)
1140  return;
1141 
1142  float curTime = GetGame().GetWorld().GetWorldTime();
1143 
1144  if (!IsProxy())
1145  {
1146  EndCapture();
1147  m_mDefendersData.Clear();
1149  Replication.BumpMe();
1150 
1151  // Update signal coverage only if the base was seized during normal play, not at the start
1152  if (curTime > 10000)
1153  {
1154  campaign.GetBaseManager().RecalculateRadioCoverage(campaign.GetFactionByEnum(SCR_ECampaignFaction.BLUFOR));
1155  campaign.GetBaseManager().RecalculateRadioCoverage(campaign.GetFactionByEnum(SCR_ECampaignFaction.OPFOR));
1156  }
1157 
1158  ChangeRadioSettings(newCampaignFaction);
1159 
1160  // Reset timer for reinforcements
1161  SupplyIncomeTimer(true);
1162 
1163  // Delay respawn possibility at newly-captured bases
1164  if (!m_bIsHQ && m_bInitialized && newCampaignFaction.IsPlayable() && campaign.GetBaseManager().IsBasesInitDone() && curTime > SCR_GameModeCampaign.BACKEND_DELAY)
1165  {
1166  ChimeraWorld world = GetOwner().GetWorld();
1167  m_fRespawnAvailableSince = world.GetServerTimestamp().PlusMilliseconds(RESPAWN_DELAY_AFTER_CAPTURE);
1168  OnRespawnCooldownChanged();
1169  Replication.BumpMe();
1170  }
1171 
1172  HandleSpawnPointFaction();
1173  SendHQMessageBaseCaptured();
1174 
1175  // If some Remnants live, send them to recapture
1176  if (newCampaignFaction.IsPlayable() && !m_bIsHQ)
1177  {
1178  foreach (SCR_AmbientPatrolSpawnPointComponent remnants : m_aRemnants)
1179  {
1180  AIGroup grp = remnants.GetSpawnedGroup();
1181 
1182  if (!grp)
1183  continue;
1184 
1185  if (m_HQRadio)
1186  {
1187  EntitySpawnParams params = EntitySpawnParams();
1188  params.TransformMode = ETransformMode.WORLD;
1189  params.Transform[3] = m_HQRadio.GetOrigin();
1190  m_SeekDestroyWP = SCR_TimedWaypoint.Cast(GetGame().SpawnEntityPrefabLocal(Resource.Load(SCR_GameModeCampaign.GetInstance().GetSeekDestroyWaypointPrefab()), null, params));
1191  m_SeekDestroyWP.SetHoldingTime(60);
1192  }
1193 
1194  if (m_SeekDestroyWP)
1195  grp.AddWaypointAt(m_SeekDestroyWP, 0);
1196  }
1197  }
1198 
1199  if (GetGame().GetWorld().GetWorldTime() != 0)
1200  GetGame().GetSaveManager().Save(ESaveType.AUTO);
1201  }
1202 
1203  if (RplSession.Mode() != RplMode.Dedicated)
1204  {
1205  if (m_UIElement)
1206  m_UIElement.FlashBaseIcon(changeToDefault: true);
1207 
1208  if (m_MapDescriptor)
1209  m_MapDescriptor.HandleMapInfo();
1210 
1211  SetRadioChatterSignal(newCampaignFaction);
1212 
1213  SCR_CampaignFaction playerFaction = SCR_CampaignFaction.Cast(SCR_FactionManager.SGetLocalPlayerFaction());
1214  IEntity player = SCR_PlayerController.GetLocalControlledEntity();
1215 
1216  // TODO: Move this to PlayRadioMsg so it is checked for player being inside radio range
1217  if (campaign)
1218  {
1219  if (player && playerFaction && playerFaction != GetCampaignFaction() && IsHQRadioTrafficPossible(playerFaction))
1220  {
1221  if (GetCampaignFaction())
1222  SCR_PopUpNotification.GetInstance().PopupMsg("#AR-Campaign_BaseSeized-UC", prio: SCR_ECampaignPopupPriority.BASE_LOST, param1: GetCampaignFaction().GetFactionNameUpperCase(), param2: GetBaseNameUpperCase());
1223  else
1224  {
1225  SCR_CampaignFaction factionR = campaign.GetFactionByEnum(SCR_ECampaignFaction.BLUFOR);
1226 
1227  if (factionR)
1228  SCR_PopUpNotification.GetInstance().PopupMsg("#AR-Campaign_BaseSeized-UC", prio: SCR_ECampaignPopupPriority.BASE_LOST, param1: factionR.GetFactionNameUpperCase(), param2: GetBaseNameUpperCase());
1229  }
1230 
1231  if (playerFaction == m_OwningFactionPrevious)
1232  //campaign.ShowHint(SCR_ECampaignHints.BASE_LOST);
1233  }
1234  }
1235  }
1236 
1237  m_OwningFactionPrevious = newCampaignFaction;
1238  }
1240  //------------------------------------------------------------------------------------------------
1242  void OnSpawnPointFactionAssigned(FactionKey faction)
1243  {
1244  if (RplSession.Mode() != RplMode.Dedicated)
1245  m_MapDescriptor.HandleMapInfo();
1246  }
1247 
1248  //------------------------------------------------------------------------------------------------
1251  void ChangeRadioSettings(notnull SCR_Faction faction)
1252  {
1253  if (!m_RadioComponent || m_RadioComponent.TransceiversCount() == 0)
1254  return;
1255 
1256  BaseTransceiver tsv = BaseTransceiver.Cast(m_RadioComponent.GetTransceiver(0));
1257 
1258  if (!tsv)
1259  return;
1260 
1261  m_RadioComponent.SetEncryptionKey(faction.GetFactionRadioEncryptionKey());
1262 
1263  int factionFrequency = faction.GetFactionRadioFrequency();
1264 
1265  // Setting frequency outside of limits causes a VME
1266  if (factionFrequency < tsv.GetMinFrequency() || factionFrequency > tsv.GetMaxFrequency())
1267  return;
1268 
1269  tsv.SetFrequency(factionFrequency);
1270  }
1271 
1272  //------------------------------------------------------------------------------------------------
1275  void RegisterRemnants(notnull SCR_AmbientPatrolSpawnPointComponent remnants)
1276  {
1277  m_aRemnants.Insert(remnants);
1278  }
1279 
1280  //------------------------------------------------------------------------------------------------
1282  ResourceName GetBuildingIconImageset()
1283  {
1285 
1286  if (!componentData)
1287  return ResourceName.Empty;
1288 
1289  return componentData.GetBuildingIconImageset();
1290  }
1291 
1292  //------------------------------------------------------------------------------------------------
1294  SCR_GraphLinesData GetGraphLinesData()
1295  {
1297 
1298  if (!componentData)
1299  return null;
1300 
1301  return componentData.GetGraphLinesData();
1302  }
1303 
1304  //------------------------------------------------------------------------------------------------
1306  float GetLineWidth()
1307  {
1309 
1310  if (!componentData)
1311  return 0;
1312 
1313  return componentData.GetLineWidth();
1314  }
1316  //------------------------------------------------------------------------------------------------
1318  void SetDefendersGroup(SCR_AIGroup grp)
1319  {
1320  // event is called for every spawned entity of the AI group. Prevent adding duplicates.
1321  if (m_aDefendersGroups.Contains(grp))
1322  return;
1323 
1324  m_aDefendersGroups.Insert(grp);
1325  grp.GetOnEmpty().Insert(RemoveGroup);
1326  }
1328  //------------------------------------------------------------------------------------------------
1330  void RemoveGroup(SCR_AIGroup grp)
1331  {
1332  m_aDefendersGroups.RemoveItem(grp);
1333  }
1335  //------------------------------------------------------------------------------------------------
1337  bool ContainsGroup(SCR_AIGroup grp)
1338  {
1339  return m_aDefendersGroups.Contains(grp);
1340  }
1341 
1342  //------------------------------------------------------------------------------------------------
1343  override void SetCallsign(notnull SCR_Faction faction)
1344  {
1345  SCR_GameModeCampaign campaign = SCR_GameModeCampaign.GetInstance();
1346 
1347  if (!campaign)
1348  return;
1349 
1350  if (m_iCallsign == INVALID_BASE_CALLSIGN)
1351  return;
1352 
1353  int callsignOffset = campaign.GetCallsignOffset();
1354  campaign.GetOnCallsignOffsetChanged().Remove(OnCallsignAssigned);
1355 
1356  if (callsignOffset == INVALID_BASE_CALLSIGN)
1357  {
1358  campaign.GetOnCallsignOffsetChanged().Insert(OnCallsignAssigned);
1359  return;
1360  }
1361 
1362  SCR_MilitaryBaseCallsign callsignInfo;
1363 
1364  // Use index offset for OPFOR so callsigns are not comparable (i.e. Alabama will not always mean Avrora etc.)
1365  if (faction == campaign.GetFactionByEnum(SCR_ECampaignFaction.BLUFOR))
1366  callsignInfo = faction.GetBaseCallsignByIndex(m_iCallsign);
1367  else
1368  callsignInfo = faction.GetBaseCallsignByIndex(m_iCallsign, callsignOffset);
1369 
1370  if (!callsignInfo)
1371  return;
1372 
1373  m_sCallsign = callsignInfo.GetCallsign();
1374  m_sCallsignNameOnly = callsignInfo.GetCallsignShort();
1375  m_sCallsignNameOnlyUC = callsignInfo.GetCallsignUpperCase();
1376  m_iCallsignSignal = callsignInfo.GetSignalIndex();
1377  }
1378 
1379  //------------------------------------------------------------------------------------------------
1380  override void SetCallsignIndexAutomatic(int index)
1381  {
1382  // Handled separately in SCR_CampaignMilitaryBaseManager.InitializeBases()
1383  return;
1384  }
1385 
1386  //------------------------------------------------------------------------------------------------
1389  protected void SupplyIncomeTimer(bool reset = false)
1390  {
1391  ChimeraWorld world = GetOwner().GetWorld();
1392 
1393  if (!world)
1394  {
1396  Replication.BumpMe();
1397  return;
1398  }
1399 
1400  float curTime = world.GetWorldTime();
1401 
1402  if (reset)
1403  {
1404  m_fSuppliesArrivalTime = curTime + (SCR_GameModeCampaign.GetInstance().GetSuppliesArrivalInterval() * 1000);
1405  return;
1406  }
1407 
1408  Faction owner = GetFaction();
1409 
1410  // Add supplies only to captured bases in HQ radio range which are not under attack
1411  if (!owner || !m_SpawnPoint || !IsHQRadioTrafficPossible(owner, SCR_ECampaignHQRadioComms.BOTH_WAYS) || (m_CapturingFaction && m_CapturingFaction != owner) || world.GetServerTimestamp().Less(m_fRespawnAvailableSince))
1412  {
1414  Replication.BumpMe();
1415  return;
1416  }
1417 
1418  if (curTime >= m_fSuppliesArrivalTime)
1419  {
1420  AddRegularSupplyPackage(owner);
1421  m_fSuppliesArrivalTime = curTime + (SCR_GameModeCampaign.GetInstance().GetSuppliesArrivalInterval() * 1000);
1422  }
1423  }
1425  //------------------------------------------------------------------------------------------------
1427  protected void AddRegularSupplyPackage(notnull Faction faction)
1428  {
1429  SCR_GameModeCampaign campaign = SCR_GameModeCampaign.GetInstance();
1430  float currentSupplies = GetSupplies();
1431  float maxSupplies = GetSuppliesMax();
1432  float spaceLimit;
1433 
1434  if (m_bIsHQ)
1435  spaceLimit = float.MAX;
1436  else
1437  spaceLimit = campaign.GetSuppliesReplenishThreshold() - currentSupplies;
1438 
1439  if (spaceLimit <= 0 || currentSupplies >= maxSupplies)
1440  {
1442  Replication.BumpMe();
1443  return;
1444  }
1445 
1446  int quickReplenishThreshold = campaign.GetQuickSuppliesReplenishThreshold();
1447  float quickReplenishMultiplier = campaign.GetQuickSuppliesReplenishMultiplier();
1448  int income = campaign.GetRegularSuppliesIncomeBase();
1449  int incomeHQ = campaign.GetRegularSuppliesIncome();
1450  int toAdd;
1451 
1452  if (m_bIsHQ || m_bIsSupplyHub)
1453  {
1454  if (currentSupplies < quickReplenishThreshold)
1455  {
1456  int incomeHQQuick = incomeHQ * quickReplenishMultiplier;
1457  incomeHQQuick = Math.Min(incomeHQQuick, quickReplenishThreshold - currentSupplies);
1458  toAdd = Math.Max(incomeHQQuick, incomeHQ);
1459  }
1460  else
1461  {
1462  toAdd = incomeHQ;
1463  }
1464  }
1465  else
1466  {
1467  if (currentSupplies < quickReplenishThreshold)
1468  {
1469  int incomeQuick = income * quickReplenishMultiplier;
1470  incomeQuick = Math.Min(incomeQuick, quickReplenishThreshold - currentSupplies);
1471  toAdd = Math.Max(incomeQuick, income);
1472  }
1473  else
1474  {
1475  toAdd = income;
1476  }
1477  }
1478 
1479  int extraBasesCount;
1480 
1481  if (!m_bIsHQ)
1482  {
1484  {
1485  if (base.GetType() != SCR_ECampaignBaseType.BASE)
1486  continue;
1487 
1488  if (base.GetFaction() != faction)
1489  continue;
1490 
1491  if (!base.IsHQRadioTrafficPossible(faction))
1492  continue;
1493 
1494  extraBasesCount++;
1495 
1496  if (extraBasesCount == BASES_IN_RANGE_RESUPPLY_THRESHOLD)
1497  break;
1498  }
1499  }
1500 
1501  toAdd += (SCR_GameModeCampaign.GetInstance().GetRegularSuppliesIncomeExtra() * extraBasesCount);
1502  AddSupplies(Math.Min(toAdd, spaceLimit));
1503 
1504  m_iSupplyRegenAmount = toAdd;
1505  Replication.BumpMe();
1506  }
1508  //------------------------------------------------------------------------------------------------
1510  SCR_CampaignMilitaryBaseMapDescriptorComponent GetMapDescriptor()
1511  {
1512  return m_MapDescriptor;
1513  }
1515  //------------------------------------------------------------------------------------------------
1517  SCR_CampaignMapUIBase GetMapUI()
1518  {
1519  return m_UIElement;
1520  }
1521 
1522  //------------------------------------------------------------------------------------------------
1525  bool GetIsEntityInMyRange(notnull IEntity entity)
1526  {
1527  return vector.Distance(entity.GetOrigin(), GetOwner().GetOrigin()) <= GetRadioRange();
1528  }
1530  //------------------------------------------------------------------------------------------------
1532  float GetSupplies()
1533  {
1534  SCR_ResourceComponent resourceComponent = GetResourceComponent();
1535 
1536  if (!resourceComponent)
1537  return 0.0;
1538 
1539  SCR_ResourceConsumer resourceConsumer = resourceComponent.GetConsumer(EResourceGeneratorID.DEFAULT, EResourceType.SUPPLIES);
1540 
1541  if (!resourceConsumer)
1542  return 0.0;
1543 
1544  if (!IsProxy())
1545  GetGame().GetResourceGrid().UpdateInteractor(resourceConsumer);
1546 
1547  return resourceConsumer.GetAggregatedResourceValue();
1548  }
1550  //------------------------------------------------------------------------------------------------
1552  float GetSuppliesMax()
1553  {
1554  SCR_ResourceComponent resourceComponent = GetResourceComponent();
1555 
1556  if (!resourceComponent)
1557  return 0.0;
1558 
1559  SCR_ResourceConsumer resourceConsumer = resourceComponent.GetConsumer(EResourceGeneratorID.DEFAULT, EResourceType.SUPPLIES);
1560 
1561  if (!resourceConsumer)
1562  return 0.0;
1563 
1564  if (!IsProxy())
1565  GetGame().GetResourceGrid().UpdateInteractor(resourceConsumer);
1566 
1567  return resourceConsumer.GetAggregatedMaxResourceValue();
1568  }
1570  //------------------------------------------------------------------------------------------------
1572  int GetSuppliesIncome()
1573  {
1574  return m_iSupplyRegenAmount;
1575  }
1576 
1577  //------------------------------------------------------------------------------------------------
1580  void RegisterHQRadio(notnull IEntity radio)
1581  {
1582  m_HQRadio = radio;
1583  SetRadioChatterSignal(GetCampaignFaction());
1584  }
1585 
1586  //------------------------------------------------------------------------------------------------
1587  override void RegisterLogicComponent(notnull SCR_MilitaryBaseLogicComponent component)
1588  {
1589  super.RegisterLogicComponent(component);
1590 
1591  SCR_FlagComponent flag = SCR_FlagComponent.Cast(component);
1592 
1593  // This is indeed a repeated call from super
1594  // Sandbox mil bases spawned via HQ tents are interfering with shown flag as they have different faction
1595  // It's a temporary fix until we switch to full free building and bases on top of each other will no longer be a thing
1596  if (flag && GetFaction())
1597  GetGame().GetCallqueue().CallLater(ChangeFlags, 1000, false, GetFaction());
1598  }
1600  //------------------------------------------------------------------------------------------------
1602  void SetRadioChatterSignal(SCR_Faction faction)
1603  {
1604  if (!m_HQRadio)
1605  return;
1606 
1607  SCR_GameModeCampaign campaign = SCR_GameModeCampaign.GetInstance();
1608 
1609  if (!campaign)
1610  return;
1611 
1612  SignalsManagerComponent comp = SignalsManagerComponent.Cast(m_HQRadio.FindComponent(SignalsManagerComponent));
1613 
1614  if (!comp)
1615  return;
1616 
1617  if (!faction || faction.GetFactionKey() == campaign.GetFactionKeyByEnum(SCR_ECampaignFaction.INDFOR))
1618  {
1619  comp.SetSignalValue(comp.AddOrFindSignal(RADIO_CHATTER_SIGNAL_NAME), 0);
1620  }
1621  else
1622  {
1623  if (faction.GetFactionKey() == campaign.GetFactionKeyByEnum(SCR_ECampaignFaction.BLUFOR))
1624  {
1625  comp.SetSignalValue(comp.AddOrFindSignal(RADIO_CHATTER_SIGNAL_NAME), 1);
1626  }
1627  else
1628  {
1629  comp.SetSignalValue(comp.AddOrFindSignal(RADIO_CHATTER_SIGNAL_NAME), 2);
1630  }
1631  }
1632  }
1634  //------------------------------------------------------------------------------------------------
1636  IEntity GetHQRadio()
1637  {
1638  return m_HQRadio;
1639  }
1641  //------------------------------------------------------------------------------------------------
1643  void HideMapLocationLabel()
1644  {
1645  if (m_sMapLocationName.IsEmpty() || !GetGame().GetWorld())
1646  return;
1647 
1649 
1650  if (!ent)
1651  return;
1652 
1653  MapDescriptorComponent comp = MapDescriptorComponent.Cast(ent.FindComponent(MapDescriptorComponent));
1654 
1655  if (!comp)
1656  return;
1657 
1658  MapItem item = comp.Item();
1659 
1660  if (!item)
1661  return;
1662 
1663  item.SetVisible(false);
1664  }
1666  //------------------------------------------------------------------------------------------------
1668  SCR_ResourceComponent GetResourceComponent()
1669  {
1670  return SCR_ResourceComponent.FindResourceComponent(GetOwner());
1671  }
1672 
1673  //------------------------------------------------------------------------------------------------
1677  void AddSupplies(int suppliesCount, bool replicate = true)
1678  {
1679  if (suppliesCount == 0)
1680  return;
1681 
1682  SCR_ResourceComponent resourceComponent = GetResourceComponent();
1683 
1684  if (!resourceComponent)
1685  return;
1686 
1687  if (suppliesCount > 0)
1688  {
1689  SCR_ResourceGenerator resourceGenerator = resourceComponent.GetGenerator(EResourceGeneratorID.DEFAULT, EResourceType.SUPPLIES);
1690 
1691  if (!resourceGenerator)
1692  return;
1693 
1694  resourceGenerator.RequestGeneration(suppliesCount);
1695  }
1696  else
1697  {
1698  SCR_ResourceConsumer resourceConsumer = resourceComponent.GetConsumer(EResourceGeneratorID.DEFAULT, EResourceType.SUPPLIES);
1699 
1700  if (!resourceConsumer)
1701  return;
1702 
1703  resourceConsumer.RequestConsumtion(-suppliesCount);
1704  }
1705 
1706  HandleSpawnPointFaction();
1707  }
1709  //------------------------------------------------------------------------------------------------
1711  void SetSupplies(float suppliesCount)
1712  {
1713  SCR_ResourceComponent resourceComponent = GetResourceComponent();
1714 
1715  if (!resourceComponent)
1716  return;
1717 
1718  SCR_ResourceConsumer resourceConsumer = resourceComponent.GetConsumer(EResourceGeneratorID.DEFAULT, EResourceType.SUPPLIES);
1719 
1720  if (!resourceConsumer)
1721  return;
1722 
1723  if (!IsProxy())
1724  GetGame().GetResourceGrid().UpdateInteractor(resourceConsumer);
1725 
1726  AddSupplies(suppliesCount - resourceConsumer.GetAggregatedResourceValue());
1727  }
1729  //------------------------------------------------------------------------------------------------
1731  void SetInitialSupplies(float suppliesCount)
1732  {
1733  SCR_ResourceComponent resourceComponent = GetResourceComponent();
1734 
1735  if (!resourceComponent)
1736  return;
1737 
1738  SCR_ResourceConsumer resourceConsumer = resourceComponent.GetConsumer(EResourceGeneratorID.DEFAULT, EResourceType.SUPPLIES);
1739 
1740  if (!resourceConsumer)
1741  return;
1742 
1743  if (!IsProxy())
1744  GetGame().GetResourceGrid().UpdateInteractor(resourceConsumer);
1745 
1746  // Set starting supplies only if no bigger supply caches are already in the vicinity
1747  if (suppliesCount > resourceConsumer.GetAggregatedResourceValue())
1748  SetSupplies(suppliesCount);
1749  }
1751  //------------------------------------------------------------------------------------------------
1753  void SetStartingSupplies(float suppliesCount)
1754  {
1755  m_fStartingSupplies = suppliesCount;
1756  }
1757 
1758  //------------------------------------------------------------------------------------------------
1761  void AlterSupplyIncomeTimer(float time)
1762  {
1763  m_fSuppliesArrivalTime += time
1764  }
1766  //------------------------------------------------------------------------------------------------
1768  int GetBasesInRange(SCR_ECampaignBaseType filter, notnull out array<SCR_CampaignMilitaryBaseComponent> basesInRange)
1769  {
1770  int count = 0;
1771 
1772  if (!m_aBasesInRadioRange)
1773  return count;
1774 
1776  {
1777  SCR_ECampaignBaseType baseType = base.GetType();
1778 
1779  if ((filter & baseType) == baseType)
1780  {
1781  basesInRange.Insert(base);
1782  count++;
1783  }
1784  }
1785 
1786  return count;
1787  }
1789  //------------------------------------------------------------------------------------------------
1791  void SetFaction(SCR_CampaignFaction faction)
1792  {
1793  if (IsProxy())
1794  return;
1795 
1796  if (!m_FactionComponent)
1797  return;
1798 
1799  m_FactionComponent.SetAffiliatedFaction(faction);
1800  }
1802  //------------------------------------------------------------------------------------------------
1804  SCR_CampaignFaction GetCampaignFaction()
1805  {
1806  return SCR_CampaignFaction.Cast(GetFaction());
1807  }
1809  //------------------------------------------------------------------------------------------------
1811  SCR_ECampaignBaseType GetType()
1812  {
1813  return m_eType;
1814  }
1816  //------------------------------------------------------------------------------------------------
1818  string GetBaseName()
1819  {
1820  return m_sBaseName;
1821  }
1823  //------------------------------------------------------------------------------------------------
1825  string GetBaseNameUpperCase()
1826  {
1827  return m_sBaseNameUpper;
1828  }
1830  //------------------------------------------------------------------------------------------------
1832  bool IsBeingCaptured()
1833  {
1834  // The capturing faction exists, return true
1835  if (m_CapturingFaction)
1836  return true;
1837 
1838  // No faction is capturing this base, return false
1839  return false;
1840  }
1842  //------------------------------------------------------------------------------------------------
1844  void SetAttackingFaction(int enemyFaction)
1845  {
1846  m_iAttackingFaction = enemyFaction;
1847 
1848  if (m_iAttackingFaction < 0)
1849  return;
1850 
1851  Replication.BumpMe();
1852  OnAttackingFactionChanged();
1853  }
1855  //------------------------------------------------------------------------------------------------
1857  void OnAttackingFactionChanged()
1858  {
1859  Faction enemyFaction = GetGame().GetFactionManager().GetFactionByIndex(m_iAttackingFaction);
1860  Faction playerFaction = SCR_FactionManager.SGetLocalPlayerFaction();
1861 
1862  if (!IsProxy())
1863  GetGame().GetCallqueue().CallLater(SetAttackingFaction, 1000, false, -1);
1864  else
1865  m_iAttackingFaction = -1;
1866 
1867  if (RplSession.Mode() != RplMode.Dedicated && enemyFaction != playerFaction && GetFaction() == playerFaction)
1868  FlashBaseIcon(SCR_CampaignFeedbackComponent.ICON_FLASH_DURATION, enemyFaction);
1869  }
1871  //------------------------------------------------------------------------------------------------
1873  void OnRespawnCooldownChanged()
1874  {
1875  ChimeraWorld world = GetOwner().GetWorld();
1876  WorldTimestamp curTime = world.GetServerTimestamp();
1877 
1878  // Make sure the spawnpoint becomes available after timer runs out
1879  if (!IsProxy())
1880  GetGame().GetCallqueue().CallLater(HandleSpawnPointFaction, m_fRespawnAvailableSince.DiffMilliseconds(curTime) + SCR_GameModeCampaign.MEDIUM_DELAY);
1881 
1882  // Handle respawn cooldown UI
1883  if (RplSession.Mode() != RplMode.Dedicated)
1884  UpdateRespawnCooldown();
1885  }
1887  //------------------------------------------------------------------------------------------------
1889  void UpdateRespawnCooldown()
1890  {
1891  ChimeraWorld world = GetOwner().GetWorld();
1892  WorldTimestamp curTime = world.GetServerTimestamp();
1893 
1894  if (m_UIElement && SCR_FactionManager.SGetLocalPlayerFaction() == GetFaction())
1895  m_UIElement.SetIconInfoText();
1896 
1897  GetGame().GetCallqueue().Remove(UpdateRespawnCooldown);
1898 
1899  if (curTime.Less(m_fRespawnAvailableSince))
1900  GetGame().GetCallqueue().CallLater(UpdateRespawnCooldown, SCR_GameModeCampaign.UI_UPDATE_DELAY);
1901  }
1902 
1903  //------------------------------------------------------------------------------------------------
1904  override void OnCallsignAssigned()
1905  {
1906  SCR_Faction faction = SCR_Faction.Cast(SCR_FactionManager.SGetLocalPlayerFaction());
1907 
1908  if (!faction)
1909  faction = SCR_GameModeCampaign.GetInstance().GetBaseManager().GetLocalPlayerFaction();
1910 
1911  if (!faction)
1912  return;
1913 
1914  SCR_GameModeCampaign campaign = SCR_GameModeCampaign.GetInstance();
1915 
1916  if (!campaign)
1917  return;
1918 
1919  campaign.GetOnCallsignOffsetChanged().Remove(OnCallsignAssigned);
1920  int callsignOffset = campaign.GetCallsignOffset();
1921 
1922  if (callsignOffset == INVALID_BASE_CALLSIGN)
1923  {
1924  campaign.GetOnCallsignOffsetChanged().Insert(OnCallsignAssigned);
1925  return;
1926  }
1927 
1928  SetCallsign(faction);
1929  }
1931  //------------------------------------------------------------------------------------------------
1933  void OnAllBasesInitialized()
1934  {
1935  if (IsProxy())
1936  {
1937  UpdateBasesInRadioRange();
1938  return;
1939  }
1940 
1941  // Spawn HQ composition
1942  if (GetType() == SCR_ECampaignBaseType.BASE)
1943  {
1944  SCR_GameModeCampaign campaign = SCR_GameModeCampaign.GetInstance();
1945  ResourceName buildingPrefab = GetCampaignFaction().GetBuildingPrefab(EEditableEntityLabel.SERVICE_HQ);
1946 
1947  if (!buildingPrefab)
1948  {
1949  Math.Randomize(-1);
1950 
1951  if (Math.RandomFloat01() >= 0.5)
1952  buildingPrefab = campaign.GetFactionByEnum(SCR_ECampaignFaction.BLUFOR).GetBuildingPrefab(EEditableEntityLabel.SERVICE_HQ);
1953  else
1954  buildingPrefab = campaign.GetFactionByEnum(SCR_ECampaignFaction.OPFOR).GetBuildingPrefab(EEditableEntityLabel.SERVICE_HQ);
1955  }
1956 
1957  if (buildingPrefab)
1958  GetGame().GetCallqueue().CallLater(SpawnBuilding, 1000, false, buildingPrefab, GetOwner().GetOrigin(), GetOwner().GetYawPitchRoll(), true); // Delay so we don't spawn stuff during init
1959  }
1960  }
1962  //------------------------------------------------------------------------------------------------
1964  void RecalculateRadioRange()
1965  {
1966  float range = m_fRadioRangeDefault;
1967  float thisRange;
1968  array<SCR_ServicePointComponent> antennas = {};
1969  GetServicesByType(antennas, SCR_EServicePointType.RADIO_ANTENNA);
1970  BaseRadioComponent radio;
1971 
1972  // Find antenna services, read max radio range from the radio component on their owners
1973  foreach (SCR_ServicePointComponent service : antennas)
1974  {
1975  SCR_AntennaServicePointComponent antenna = SCR_AntennaServicePointComponent.Cast(service);
1976  radio = BaseRadioComponent.Cast(antenna.GetOwner().FindComponent(BaseRadioComponent));
1977 
1978  if (!radio)
1979  continue;
1980 
1981  // Turn off the radio so we don't hit performance too much with every antenna built
1982  if (radio.IsPowered())
1983  radio.SetPower(false);
1984 
1985  thisRange = GetRelayRadioRange(radio);
1986 
1987  if (thisRange > range)
1988  range = thisRange;
1989  }
1990 
1991  if (m_fRadioRange == range)
1992  return;
1993 
1994  // Instead of relying on antenna radio which has been turned off, apply the antenna's signal range to the radio component on the base itself
1995  if (m_RadioComponent)
1996  {
1997  RelayTransceiver transceiver;
1998 
1999  for (int i = 0, count = m_RadioComponent.TransceiversCount(); i < count; i++)
2000  {
2001  transceiver = RelayTransceiver.Cast(m_RadioComponent.GetTransceiver(i));
2002 
2003  if (!transceiver)
2004  continue;
2005 
2006  transceiver.SetRange(range);
2007  }
2008  }
2009 
2010  m_fRadioRange = range;
2011  Replication.BumpMe();
2012  OnRadioRangeChanged();
2013  }
2015  //------------------------------------------------------------------------------------------------
2017  void OnRadioRangeChanged()
2018  {
2019  UpdateBasesInRadioRange();
2020 
2021  if (m_MapDescriptor)
2022  m_MapDescriptor.HandleMapLinks();
2023 
2024  if (IsProxy())
2025  return;
2026 
2027  SCR_GameModeCampaign campaign = SCR_GameModeCampaign.GetInstance();
2028 
2029  if (!campaign)
2030  return;
2031 
2032  SCR_CampaignMilitaryBaseManager bManager = campaign.GetBaseManager();
2033 
2034  if (!bManager)
2035  return;
2036 
2037  if (GetGame().GetWorld().GetWorldTime() > campaign.BACKEND_DELAY)
2038  {
2039  // Process recalculation immediately unless we're still within save loading period
2040  bManager.RecalculateRadioCoverage(GetCampaignFaction());
2041  }
2042  else
2043  {
2044  // Otherwise process for both factions only once so we're not doing it for each antenna loaded
2045  GetGame().GetCallqueue().Remove(bManager.RecalculateRadioCoverage);
2046  GetGame().GetCallqueue().CallLater(bManager.RecalculateRadioCoverage, campaign.DEFAULT_DELAY, false, campaign.GetFactionByEnum(SCR_ECampaignFaction.BLUFOR));
2047  GetGame().GetCallqueue().CallLater(bManager.RecalculateRadioCoverage, campaign.DEFAULT_DELAY, false, campaign.GetFactionByEnum(SCR_ECampaignFaction.OPFOR));
2048  }
2049 
2050  RefreshTasks();
2051  }
2053  //------------------------------------------------------------------------------------------------
2055  void SetBaseUI(SCR_CampaignMapUIBase base)
2056  {
2057  m_UIElement = base;
2058  }
2060  //------------------------------------------------------------------------------------------------
2062  void SendHQMessageBaseCaptured()
2063  {
2064  SCR_GameModeCampaign campaign = SCR_GameModeCampaign.GetInstance();
2065  if (!campaign)
2066  return;
2067 
2068  SCR_CampaignFaction newOwner = GetCampaignFaction();
2069  if (!newOwner)
2070  return;
2071 
2072  int newOwnerPoints = newOwner.GetControlPointsHeld();
2073 
2074  if (newOwnerPoints == campaign.GetControlPointTreshold() && IsControlPoint())
2075  {
2076  newOwner.SendHQMessage(SCR_ERadioMsg.WINNING);
2077 
2078  SCR_CampaignFaction losingFaction;
2079  FactionManager factionManager = GetGame().GetFactionManager();
2080  if (!factionManager)
2081  return;
2082 
2083  if (newOwner.GetFactionKey() == campaign.GetFactionKeyByEnum(SCR_ECampaignFaction.BLUFOR))
2084  losingFaction = SCR_CampaignFaction.Cast(factionManager.GetFactionByKey(campaign.GetFactionKeyByEnum(SCR_ECampaignFaction.OPFOR)));
2085  else
2086  losingFaction = SCR_CampaignFaction.Cast(factionManager.GetFactionByKey(campaign.GetFactionKeyByEnum(SCR_ECampaignFaction.BLUFOR)));
2087 
2088  if (losingFaction)
2089  losingFaction.SendHQMessage(SCR_ERadioMsg.LOSING);
2090  }
2091  else
2092  {
2093  if (IsHQ())
2094  newOwner.SendHQMessage(SCR_ERadioMsg.SEIZED_MAIN, m_iCallsign);
2095  else if (IsControlPoint())
2096  newOwner.SendHQMessage(SCR_ERadioMsg.SEIZED_MAJOR, m_iCallsign);
2097  else if (GetType() == SCR_ECampaignBaseType.BASE)
2098  newOwner.SendHQMessage(SCR_ERadioMsg.SEIZED_SMALL, m_iCallsign);
2099 
2101  {
2102  if (GetType() == SCR_ECampaignBaseType.RELAY)
2103  m_OwningFactionPrevious.SendHQMessage(SCR_ERadioMsg.RELAY_LOST, m_iCallsign);
2104  else
2105  m_OwningFactionPrevious.SendHQMessage(SCR_ERadioMsg.BASE_LOST, m_iCallsign);
2106  }
2107  }
2108  }
2109 
2110  //------------------------------------------------------------------------------------------------
2111  protected void SpawnStartingVehicles()
2112  {
2113  SCR_GameModeCampaign campaign = SCR_GameModeCampaign.GetInstance();
2114 
2115  if (!campaign)
2116  return;
2117 
2118  if (campaign.IsTutorial())
2119  return;
2120 
2121  EntitySpawnParams params = new EntitySpawnParams();
2122  params.TransformMode = ETransformMode.WORLD;
2123  vector pos, oldPos;
2124  IEntity vehicleEntity;
2125  Physics physicsComponent;
2126 
2127  array<ResourceName> prefabNames = {};
2128  GetCampaignFaction().GetStartingVehiclePrefabs(prefabNames);
2129 
2130  foreach (ResourceName prefabName : prefabNames)
2131  {
2132  oldPos = pos;
2133  SCR_WorldTools.FindEmptyTerrainPosition(pos, GetOwner().GetOrigin(), HQ_VEHICLE_SPAWN_RADIUS, HQ_VEHICLE_QUERY_SPACE);
2134 
2135  //Should found empty terrain position be too close to last one, do another search with previous position as areaCenter.
2136  if (vector.DistanceSqXZ(pos, oldPos) < 1)
2137  SCR_WorldTools.FindEmptyTerrainPosition(pos, oldPos, HQ_VEHICLE_SPAWN_RADIUS, HQ_VEHICLE_QUERY_SPACE);
2138 
2139  params.Transform[3] = pos;
2140 
2141  Resource veh = Resource.Load(prefabName);
2142 
2143  if (!veh || !veh.IsValid())
2144  return;
2145 
2146  vehicleEntity = GetGame().SpawnEntityPrefab(veh, GetGame().GetWorld(), params);
2147 
2148  if (vehicleEntity)
2149  {
2150  physicsComponent = vehicleEntity.GetPhysics();
2151 
2152  if (physicsComponent)
2153  physicsComponent.SetVelocity("0 -0.1 0"); // Make vehicle copy the terrain properly
2154 
2155  m_aStartingVehicles.Insert(vehicleEntity);
2156  }
2157  }
2158  }
2159 
2160  //------------------------------------------------------------------------------------------------
2161  protected void DeleteStartingVehicles()
2162  {
2163  foreach (IEntity veh : m_aStartingVehicles)
2164  {
2165  if (veh)
2166  RplComponent.DeleteRplEntity(veh, false);
2167  }
2168  }
2169 
2170  //------------------------------------------------------------------------------------------------
2171  protected void RemoveFortifications()
2172  {
2173  IEntity child = GetOwner().GetChildren();
2174  IEntity prevChild;
2175 
2176  while (child)
2177  {
2178  if (child.FindComponent(SCR_CampaignBuildingCompositionComponent))
2179  prevChild = child;
2180 
2181  child = child.GetSibling();
2182 
2183  if (prevChild)
2184  SCR_EntityHelper.DeleteEntityAndChildren(prevChild);
2185  }
2186  }
2187 
2188  //------------------------------------------------------------------------------------------------
2191  void LoadState(notnull SCR_CampaignBaseStruct baseStruct)
2192  {
2193  SetCallsignIndex(baseStruct.GetCallsignIndex());
2194 
2195  if (!m_bInitialized)
2196  Initialize();
2197 
2198  FactionManager factionManager = GetGame().GetFactionManager();
2199 
2200  if (!factionManager)
2201  return;
2202 
2203  SCR_CampaignFaction faction = SCR_CampaignFaction.Cast(factionManager.GetFactionByIndex(baseStruct.GetFaction()));
2204 
2205  if (faction && GetCampaignFaction() != faction)
2206  {
2207  SetFaction(faction);
2208  RemoveFortifications();
2209  }
2210 
2211  m_fStartingSupplies = -1;
2212 
2213  SetAsHQ(baseStruct.IsHQ());
2214  UpdateBasesInRadioRange();
2215 
2216  GetGame().GetCallqueue().Remove(SpawnBuilding);
2217  //GetGame().GetCallqueue().CallLater(SpawnSavedBuildings, SCR_GameModeCampaign.DEFAULT_DELAY, false, baseStruct); // Delay so we don't spawn stuff during init
2218 
2219  if (m_HQTent)
2220  RplComponent.DeleteRplEntity(m_HQTent, false);
2221 
2222  // Starting vehicles have been presumably spent at this point
2223  GetGame().GetCallqueue().Remove(SpawnStartingVehicles);
2224  GetGame().GetCallqueue().Remove(SetInitialSupplies);
2225  DeleteStartingVehicles();
2226  }
2227 
2228  //------------------------------------------------------------------------------------------------
2229 // void SpawnSavedBuildings(notnull SCR_CampaignBaseStruct loadedData)
2230 // {
2231 // if (m_HQTent)
2232 // RplComponent.DeleteRplEntity(m_HQTent, false);
2233 //
2234 // SpawnBuilding(loadedData.GetHQPrefab(), loadedData.GetHQPosition(), loadedData.GetHQRotation(), true);
2235 //
2236 // array<SCR_EServicePointType> types = {};
2237 // SCR_Enum.GetEnumValues(SCR_EServicePointType, types);
2238 //
2239 // foreach (SCR_EServicePointType type : types)
2240 // {
2241 // if (GetServiceByType(type))
2242 // continue;
2243 //
2244 // SpawnBuilding(loadedData.GetServicePrefab(type), loadedData.GetServicePosition(type), loadedData.GetServiceRotation(type));
2245 // }
2246 // }
2247 
2248  //------------------------------------------------------------------------------------------------
2254  void SpawnBuilding(ResourceName prefab, vector position, vector rotation, bool isMainTent = false)
2255  {
2256  if (prefab.IsEmpty())
2257  return;
2258 
2259  if (position == vector.Zero)
2260  return;
2261 
2262  EntitySpawnParams params = EntitySpawnParams();
2263  GetOwner().GetWorldTransform(params.Transform);
2264  params.TransformMode = ETransformMode.WORLD;
2265  Math3D.AnglesToMatrix(rotation, params.Transform);
2266  params.Transform[3] = position;
2267 
2268  IEntity composition = GetGame().SpawnEntityPrefab(Resource.Load(prefab), null, params);
2269 
2270  if (!composition)
2271  return;
2272 
2273  if (isMainTent)
2274  {
2275  m_HQTent = composition;
2276 
2277  // Delayed call so the supplies system has time to process all the containers first
2278  if (m_fStartingSupplies >= 0)
2279  GetGame().GetCallqueue().CallLater(SetInitialSupplies, SCR_GameModeCampaign.MEDIUM_DELAY, false, m_fStartingSupplies);
2280  }
2281 
2282  SCR_AIWorld aiWorld = SCR_AIWorld.Cast(GetGame().GetAIWorld());
2283 
2284  if (aiWorld)
2285  aiWorld.RequestNavmeshRebuildEntity(composition);
2286 
2287  SCR_EditableEntityComponent editableEntity = SCR_EditableEntityComponent.Cast(composition.FindComponent(SCR_EditableEntityComponent));
2288  vector transform[4];
2289 
2290  if (!editableEntity)
2291  {
2292  GetOwner().GetTransform(transform);
2293  SCR_TerrainHelper.SnapToTerrain(transform, composition.GetWorld());
2294  composition.SetTransform(transform);
2295  return;
2296  }
2297 
2298  editableEntity.GetTransform(transform);
2299 
2300  if (!SCR_TerrainHelper.SnapToTerrain(transform, composition.GetWorld()))
2301  return;
2302 
2303  editableEntity.SetTransformWithChildren(transform);
2304  }
2306  //------------------------------------------------------------------------------------------------
2308  void EvaluateDefenders()
2309  {
2310  SCR_CampaignFaction baseFaction = GetCampaignFaction();
2311 
2312  if (!baseFaction.IsPlayable())
2313  return;
2314 
2315  SCR_CampaignFactionManager factionManager = SCR_CampaignFactionManager.Cast(GetGame().GetFactionManager());
2316 
2317  if (!factionManager)
2318  return;
2319 
2320  if (GetHQRadioCoverage(factionManager.GetEnemyFaction(baseFaction)) == SCR_ECampaignHQRadioComms.NONE)
2321  return;
2322 
2323  PlayerManager playerManager = GetGame().GetPlayerManager();
2324  array<int> playerIds = {};
2325  array<int> playerIdsPresent = {};
2326  playerManager.GetPlayers(playerIds);
2327  int radiusSq;
2328  vector basePos = GetOwner().GetOrigin();
2329  SCR_XPHandlerComponent compXP = SCR_XPHandlerComponent.Cast(GetGame().GetGameMode().FindComponent(SCR_XPHandlerComponent));
2330  bool enemiesPresent;
2331 
2332  if (m_eType == SCR_ECampaignBaseType.BASE)
2333  radiusSq = m_iRadius * m_iRadius;
2334  else
2335  radiusSq = RELAY_BASE_RADIUS * RELAY_BASE_RADIUS;
2336 
2337  foreach (int playerId : playerIds)
2338  {
2339  SCR_ChimeraCharacter player = SCR_ChimeraCharacter.Cast(playerManager.GetPlayerControlledEntity(playerId));
2340 
2341  if (!player)
2342  continue;
2343 
2344  CharacterControllerComponent charController = player.GetCharacterController();
2345 
2346  if (charController.IsDead())
2347  continue;
2348 
2349  if (vector.DistanceSqXZ(player.GetOrigin(), basePos) > radiusSq)
2350  continue;
2351 
2352  if (player.GetFaction() == baseFaction)
2353  playerIdsPresent.Insert(playerId);
2354  else
2355  enemiesPresent = true;
2356  }
2357 
2358  ChimeraWorld world = GetOwner().GetWorld();
2359  WorldTimestamp curTime = world.GetServerTimestamp();
2360  foreach (int playerId : playerIdsPresent)
2361  {
2362  WorldTimestamp startedDefendingAt = m_mDefendersData.Get(playerId);
2363  if (startedDefendingAt == 0)
2364  {
2365  m_mDefendersData.Set(playerId, curTime)
2366  }
2367  else if (curTime.DiffMilliseconds(startedDefendingAt) >= DEFENDERS_REWARD_PERIOD)
2368  {
2369  m_mDefendersData.Set(playerId, curTime);
2370 
2371  if (enemiesPresent)
2372  compXP.AwardXP(playerManager.GetPlayerController(playerId), SCR_EXPRewards.BASE_DEFENDED, DEFENDERS_REWARD_MULTIPLIER);
2373  else
2374  compXP.AwardXP(playerManager.GetPlayerController(playerId), SCR_EXPRewards.BASE_DEFENDED);
2375  }
2376  }
2377 
2378  // Clean up non-present players from the list
2379  for (int i = m_mDefendersData.Count() - 1; i >= 0; i--)
2380  {
2381  int playerId = m_mDefendersData.GetKey(i);
2382 
2383  if (playerIdsPresent.Contains(playerId))
2384  continue;
2385 
2386  m_mDefendersData.Remove(playerId);
2387  }
2388  }
2389 
2390  //------------------------------------------------------------------------------------------------
2393  void StoreState(out SCR_CampaignBaseStruct baseStruct)
2394  {
2395  baseStruct.SetIsHQ(IsHQ());
2396  baseStruct.SetCallsignIndex(GetCallsign());
2397  baseStruct.SetPosition(GetOwner().GetOrigin());
2398  baseStruct.SetOwningFaction(GetGame().GetFactionManager().GetFactionIndex(GetFaction()));
2399  baseStruct.SetSupplies(GetSupplies());
2400  //baseStruct.SetBuildingsData(this);
2401  }
2402 
2403  protected void ConnectToCampaignBasesSystem()
2404  {
2405  World world = GetOwner().GetWorld();
2406  CampaignBasesSystem updateSystem = CampaignBasesSystem.Cast(world.FindSystem(CampaignBasesSystem));
2407  if (!updateSystem)
2408  return;
2409 
2410  updateSystem.Register(this);
2411  }
2412 
2413  protected void DisconnectFromCampaignBasesSystem()
2414  {
2415  World world = GetOwner().GetWorld();
2416  CampaignBasesSystem updateSystem = CampaignBasesSystem.Cast(world.FindSystem(CampaignBasesSystem));
2417  if (!updateSystem)
2418  return;
2419 
2420  updateSystem.Unregister(this);
2421  }
2422 
2423  //------------------------------------------------------------------------------------------------
2426  void Update(float timeSlice)
2427  {
2428  m_fTimer += timeSlice;
2429 
2430  // Periodic calls, add random delay to avoid spikes
2432  return;
2433 
2434  m_fTimer = 0;
2435  m_fNextFrameCheck = TICK_TIME + (Math.RandomFloat01() * TICK_TIME * 0.5);
2436  bool playerPresentPreviously = m_bLocalPlayerPresent;
2438 
2439  SCR_GameModeCampaign campaign = SCR_GameModeCampaign.GetInstance();
2440 
2441  if (campaign && m_bLocalPlayerPresent != playerPresentPreviously)
2442  campaign.GetBaseManager().OnLocalPlayerPresenceChanged(this, m_bLocalPlayerPresent);
2443  }
2444 
2445  //------------------------------------------------------------------------------------------------
2446  override void EOnInit(IEntity owner)
2447  {
2448  super.EOnInit(owner);
2449 
2450  if (RplSession.Mode() != RplMode.Dedicated)
2451  m_MapDescriptor = SCR_CampaignMilitaryBaseMapDescriptorComponent.Cast(GetOwner().FindComponent(SCR_CampaignMilitaryBaseMapDescriptorComponent));
2452  else
2453  return;
2454 
2455  if (!m_MapDescriptor)
2456  return;
2457 
2458  m_MapDescriptor.SetParentBase(this);
2459  m_MapDescriptor.Item().SetVisible(true);
2460 
2461  SCR_ResourceComponent resourceComponent = GetResourceComponent();
2462  if (resourceComponent)
2463  {
2464  SCR_ResourceConsumer consumerComponent = resourceComponent.GetConsumer(EResourceGeneratorID.DEFAULT, EResourceType.SUPPLIES);
2465  if (consumerComponent)
2466  {
2467  consumerComponent.GetOnResourcesChanged().Insert(HandleSpawnPointFaction);
2468  }
2469  }
2470  }
2471 
2472  //------------------------------------------------------------------------------------------------
2473  override void OnPostInit(IEntity owner)
2474  {
2475  super.OnPostInit(owner);
2476 
2477  m_RadioComponent = BaseRadioComponent.Cast(GetOwner().FindComponent(BaseRadioComponent));
2478 
2479  if (m_fRadioRange == 0 && m_RadioComponent)
2480  {
2481  m_fRadioRange = GetRelayRadioRange(m_RadioComponent);
2483  }
2484  }
2485 
2486  //------------------------------------------------------------------------------------------------
2487  override void OnDelete(IEntity owner)
2488  {
2489  DisconnectFromCampaignBasesSystem();
2490 
2491  SCR_CampaignSeizingComponent seizingComponent = SCR_CampaignSeizingComponent.Cast(GetOwner().FindComponent(SCR_CampaignSeizingComponent));
2492 
2493  if (seizingComponent)
2494  {
2495  seizingComponent.GetOnCaptureStart().Remove(OnCaptureStart);
2496  seizingComponent.GetOnCaptureInterrupt().Remove(EndCapture);
2497  }
2498 
2499  SCR_GameModeCampaign campaign = SCR_GameModeCampaign.GetInstance();
2500 
2501  if (campaign)
2502  {
2503  campaign.GetOnFactionAssignedLocalPlayer().Remove(OnLocalPlayerFactionAssigned);
2504  campaign.GetBaseManager().GetOnAllBasesInitialized().Remove(OnAllBasesInitialized);
2505  campaign.GetOnCallsignOffsetChanged().Remove(OnCallsignAssigned);
2506  }
2507 
2508  SCR_ResourceComponent resourceComponent = GetResourceComponent();
2509  if (resourceComponent)
2510  {
2511  SCR_ResourceConsumer consumerComponent = resourceComponent.GetConsumer(EResourceGeneratorID.DEFAULT, EResourceType.SUPPLIES);
2512  if (consumerComponent)
2513  {
2514  consumerComponent.GetOnResourcesChanged().Remove(HandleSpawnPointFaction);
2515  }
2516  }
2517 
2518  super.OnDelete(owner);
2519  }
2520 }
2521 
2523 class SCR_CampaignCustomBase
2524 {
2525  [Attribute("", UIWidgets.EditBox, "Base entity name as set up in World Editor.")]
2526  protected string m_sBaseName;
2527 
2528  [Attribute(defvalue: "0", uiwidget: UIWidgets.CheckBox)]
2529  protected bool m_bIsControlPoint;
2530 
2531  [Attribute(defvalue: "0", uiwidget: UIWidgets.CheckBox)]
2532  protected bool m_bCanBeHQ;
2533 
2534  [Attribute(defvalue: "1", uiwidget: UIWidgets.CheckBox)]
2535  protected bool m_bDisableWhenUnusedAsHQ;
2536 
2537  [Attribute("-1", desc: "Use -1 for default base setting.")]
2538  protected float m_fRadioRange;
2539 
2540  //------------------------------------------------------------------------------------------------
2542  string GetBaseName()
2543  {
2544  return m_sBaseName;
2545  }
2546 
2547  //------------------------------------------------------------------------------------------------
2550  bool IsControlPoint()
2551  {
2552  return m_bIsControlPoint;
2553  }
2554 
2555  //------------------------------------------------------------------------------------------------
2557  bool GetCanBeHQ()
2558  {
2559  return m_bCanBeHQ;
2560  }
2561 
2562  //------------------------------------------------------------------------------------------------
2565  {
2566  return m_bDisableWhenUnusedAsHQ;
2567  }
2568 
2569  //------------------------------------------------------------------------------------------------
2571  float GetRadioRange()
2572  {
2573  return m_fRadioRange;
2574  }
2575 }
2576 
2578 {
2581 }
2582 
2583 enum EFactionMapID
2584 {
2585  UNKNOWN = 0,
2586  EAST = 1,
2587  WEST = 2,
2588  FIA = 3
2589 }
SCR_CampaignMilitaryBaseComponentClass
Definition: SCR_CampaignMilitaryBaseComponent.c:1
BaseContainerProps
SCR_CampaignMilitaryBaseComponent SCR_MilitaryBaseComponent BaseContainerProps()
SCR_TerrainHelper
Definition: SCR_TerrainHelper.c:1
m_iCallsign
protected int m_iCallsign
Definition: SCR_MilitaryBaseComponent.c:52
m_sMapLocationName
protected string m_sMapLocationName
Definition: SCR_CampaignMilitaryBaseComponent.c:56
ChimeraWorld
Definition: ChimeraWorld.c:12
EEditableEntityLabel
EEditableEntityLabel
Definition: EEditableEntityLabel.c:1
BASE
@ BASE
Definition: SCR_CampaignMilitaryBaseComponent.c:2579
direction
vector direction
Definition: SCR_DestructibleTreeV2.c:31
GetCapturingFaction
Faction GetCapturingFaction()
Definition: SCR_MilitaryBaseComponent.c:556
SCR_PlayerController
Definition: SCR_PlayerController.c:31
SCR_EntityHelper
Definition: SCR_EntityHelper.c:1
m_FactionComponent
protected SCR_FactionAffiliationComponent m_FactionComponent
Definition: SCR_MilitaryBaseComponent.c:46
SCR_ECampaignFaction
SCR_ECampaignFaction
Definition: SCR_CampaignFactionManager.c:130
m_OnSpawnPointAssigned
protected ref OnSpawnPointAssignedInvoker m_OnSpawnPointAssigned
Definition: SCR_CampaignMilitaryBaseComponent.c:84
SCR_BaseContainerCustomTitleResourceName
SCR_CampaignMilitaryBaseComponent SCR_MilitaryBaseComponent SCR_BaseContainerCustomTitleResourceName("m_sBaseName", true)
Definition: SCR_CampaignMilitaryBaseComponent.c:2522
OnSpawnPointAssignedDelegate
func OnSpawnPointAssignedDelegate
Definition: SCR_CampaignMilitaryBaseComponent.c:35
IsControlPoint
bool IsControlPoint()
Definition: SCR_CampaignMilitaryBaseComponent.c:151
m_fRespawnAvailableSince
protected WorldTimestamp m_fRespawnAvailableSince
Definition: SCR_CampaignMobileAssemblyStandaloneComponent.c:36
m_aServiceBuiltMsgQueue
protected ref array< SCR_ERadioMsg > m_aServiceBuiltMsgQueue
Definition: SCR_CampaignMilitaryBaseComponent.c:89
m_sBaseNameUpper
protected string m_sBaseNameUpper
Definition: SCR_CampaignMilitaryBaseComponent.c:53
m_eRadioCoverageOPFOR
protected SCR_ECampaignHQRadioComms m_eRadioCoverageOPFOR
Definition: SCR_CampaignMilitaryBaseComponent.c:131
SCR_CampaignTaskSupportEntity
Definition: SCR_CampaignTaskSupportEntity.c:8
RplProp
SCR_RplTestEntityClass RplProp
Used for handling entity spawning requests for SCR_CatalogEntitySpawnerComponent and inherited classe...
m_mDefendersData
protected ref map< int, WorldTimestamp > m_mDefendersData
Definition: SCR_CampaignMilitaryBaseComponent.c:61
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
GetFactionIndex
int GetFactionIndex()
Definition: SCR_EditableFactionComponent.c:57
m_iReconfiguredBy
protected int m_iReconfiguredBy
Definition: SCR_CampaignMilitaryBaseComponent.c:137
SCR_ERadioMsg
SCR_ERadioMsg
Definition: SCR_CampaignRadioMsg.c:138
GetIsLocalPlayerPresent
protected bool GetIsLocalPlayerPresent()
Definition: SCR_MilitaryBaseComponent.c:775
SCR_CampaignMapUIBase
Definition: SCR_CampaignMapUIBase.c:2
m_iAttackingFaction
protected int m_iAttackingFaction
Definition: SCR_CampaignMilitaryBaseComponent.c:146
m_fRadioRangeDefault
protected float m_fRadioRangeDefault
Definition: SCR_CampaignMilitaryBaseComponent.c:95
SCR_MilitaryBaseSystem
Definition: SCR_MilitaryBaseSystem.c:11
desc
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
Definition: SCR_RespawnBriefingComponent.c:17
m_CapturingFaction
protected SCR_CampaignFaction m_CapturingFaction
Definition: SCR_CampaignMilitaryBaseComponent.c:104
RELAY
@ RELAY
Definition: SCR_CampaignMilitaryBaseComponent.c:2580
SCR_WorldTools
Definition: SCR_WorldTools.c:1
SCR_SpawnPoint
Spawn point entity defines positions on which players can possibly spawn.
Definition: SCR_SpawnPoint.c:27
GetCallsign
int GetCallsign()
Definition: SCR_MilitaryBaseComponent.c:140
GenericEntity
SCR_GenericBoxEntityClass GenericEntity
SCR_PopUpNotification
Takes care of dynamic and static onscreen popups.
Definition: SCR_PopupNotification.c:24
FindEntityByName
IEntity FindEntityByName(string name)
Definition: SCR_ScenarioFrameworkActionsGetters.c:40
ChangeFlags
protected void ChangeFlags(notnull Faction faction)
Definition: SCR_MilitaryBaseComponent.c:758
func
func
Definition: SCR_AIThreatSystem.c:5
GetBaseName
string GetBaseName()
Returns the name of this base.
Definition: SCR_CampaignMilitaryBaseComponent.c:1815
SCR_ECampaignBaseType
SCR_ECampaignBaseType
Definition: SCR_CampaignMilitaryBaseComponent.c:2577
m_fRadioRange
protected float m_fRadioRange
Definition: SCR_CampaignMilitaryBaseComponent.c:140
m_aStartingVehicles
protected ref array< IEntity > m_aStartingVehicles
Definition: SCR_CampaignMilitaryBaseComponent.c:88
GetServiceDelegateByType
SCR_ServicePointDelegateComponent GetServiceDelegateByType(SCR_EServicePointType type)
Definition: SCR_MilitaryBaseComponent.c:364
m_fTimer
protected float m_fTimer
Definition: SCR_CampaignMilitaryBaseComponent.c:94
WEST
enum SCR_ECampaignBaseType WEST
m_RadioComponent
protected BaseRadioComponent m_RadioComponent
Definition: SCR_CampaignMilitaryBaseComponent.c:107
GetGameMode
SCR_BaseGameMode GetGameMode()
Definition: SCR_BaseGameModeComponent.c:15
SCR_TimedWaypoint
Definition: SCR_TimedWaypoint.c:5
m_bCanBeHQ
protected bool m_bCanBeHQ
Definition: SCR_CampaignMilitaryBaseComponent.c:41
RelayTransceiver
Definition: RelayTransceiver.c:12
SCR_GameModeCampaign
void SCR_GameModeCampaign(IEntitySource src, IEntity parent)
Definition: SCR_GameModeCampaign.c:1927
SCR_AIWorld
Definition: SCR_AIWorld.c:23
GetOrigin
vector GetOrigin()
Definition: SCR_AIUtilityComponent.c:279
IsProxy
protected bool IsProxy()
Definition: SCR_CampaignBuildingCompositionComponent.c:456
m_GraphLinesData
protected ref SCR_GraphLinesData m_GraphLinesData
Definition: SCR_CampaignMilitaryBaseComponent.c:6
ESaveType
ESaveType
Definition: ESaveType.c:1
Attribute
typedef Attribute
Post-process effect of scripted camera.
m_sBuildingIconImageset
ResourceName m_sBuildingIconImageset
Definition: SCR_CampaignMilitaryBaseComponent.c:3
UNKNOWN
enum SCR_ECampaignBaseType UNKNOWN
CampaignBasesSystem
Definition: CampaignBasesSystem.c:1
m_UIElement
protected SCR_CampaignMapUIBase m_UIElement
Definition: SCR_CampaignMilitaryBaseComponent.c:112
m_aBasesInRadioRange
protected ref array< SCR_CampaignMilitaryBaseComponent > m_aBasesInRadioRange
Definition: SCR_CampaignMobileAssemblyComponent.c:25
MapItem
Definition: MapItem.c:12
m_iCapturingFaction
protected int m_iCapturingFaction
Definition: SCR_CampaignMilitaryBaseComponent.c:134
GetTaskManager
SCR_BaseTaskManager GetTaskManager()
Definition: SCR_BaseTaskManager.c:7
m_fStartingSupplies
protected float m_fStartingSupplies
Definition: SCR_CampaignMilitaryBaseComponent.c:91
SCR_GraphLinesData
Definition: SCR_GraphLinesData.c:3
SCR_ECampaignPopupPriority
SCR_ECampaignPopupPriority
Popup message priorities sorted from lowest to highest.
Definition: SCR_CampaignFeedbackComponent.c:1419
m_bLocalPlayerPresent
protected bool m_bLocalPlayerPresent
Definition: SCR_CampaignMilitaryBaseComponent.c:98
rotation
RespawnSystemComponentClass GameComponentClass vector vector rotation
Definition: RespawnSystemComponent.c:23
SCR_MilitaryBaseComponentClass
Definition: SCR_MilitaryBaseComponent.c:5
EResourceType
EResourceType
Definition: SCR_ResourceContainer.c:1
GetDisableWhenUnusedAsHQ
bool GetDisableWhenUnusedAsHQ()
Definition: SCR_CampaignMilitaryBaseComponent.c:952
m_SpawnPoint
protected SCR_SpawnPoint m_SpawnPoint
Definition: SCR_CampaignMobileAssemblyComponent.c:28
BaseTransceiver
Definition: BaseTransceiver.c:12
GetOwner
IEntity GetOwner()
Owner entity of the fuel tank.
Definition: SCR_FuelNode.c:128
SCR_CampaignBaseStruct
Definition: SCR_CampaignStruct.c:245
m_MapDescriptor
protected SCR_CampaignMilitaryBaseMapDescriptorComponent m_MapDescriptor
Definition: SCR_CampaignMilitaryBaseComponent.c:100
m_bIsHQ
protected bool m_bIsHQ
Definition: SCR_CampaignMilitaryBaseComponent.c:119
SCR_EditableEntityComponent
Definition: SCR_EditableEntityComponent.c:13
m_fSuppliesArrivalTime
protected float m_fSuppliesArrivalTime
Definition: SCR_CampaignMilitaryBaseComponent.c:92
GetServices
int GetServices(out array< SCR_ServicePointComponent > services=null)
Definition: SCR_MilitaryBaseComponent.c:228
Faction
Definition: Faction.c:12
GetServicesByType
int GetServicesByType(out array< SCR_ServicePointComponent > services, SCR_EServicePointType type)
Definition: SCR_MilitaryBaseComponent.c:252
SCR_EXPRewards
SCR_EXPRewards
Definition: SCR_XPHandlerComponent.c:403
m_eType
protected SCR_ECampaignBaseType m_eType
Definition: SCR_CampaignMilitaryBaseComponent.c:59
index
SCR_DestructionSynchronizationComponentClass ScriptComponentClass int index
Definition: SCR_DestructionSynchronizationComponent.c:17
m_aRemnants
protected ref array< SCR_AmbientPatrolSpawnPointComponent > m_aRemnants
Definition: SCR_CampaignMilitaryBaseComponent.c:87
m_iSupplyRegenAmount
protected int m_iSupplyRegenAmount
Definition: SCR_CampaignMilitaryBaseComponent.c:125
SCR_CampaignMilitaryBaseManager
Created in SCR_GameModeCampaign.
Definition: SCR_CampaignMilitaryBaseManager.c:21
SCR_CampaignFaction
Definition: SCR_CampaignFaction.c:2
SCR_AIGroup
Definition: SCR_AIGroup.c:68
OnSpawnPointAssignedInvoker
ScriptInvokerBase< OnSpawnPointAssignedDelegate > OnSpawnPointAssignedInvoker
Definition: SCR_CampaignMilitaryBaseComponent.c:36
m_fLineWidth
protected float m_fLineWidth
Definition: SCR_CampaignMilitaryBaseComponent.c:9
params
Configs ServerBrowser KickDialogs params
Definition: SCR_NotificationSenderComponent.c:24
m_eRadioCoverageBLUFOR
protected SCR_ECampaignHQRadioComms m_eRadioCoverageBLUFOR
Definition: SCR_CampaignMilitaryBaseComponent.c:128
EAST
enum SCR_ECampaignBaseType EAST
m_fLastEnemyContactTimestamp
protected WorldTimestamp m_fLastEnemyContactTimestamp
Definition: SCR_CampaignMilitaryBaseComponent.c:96
m_OwningFactionPrevious
protected SCR_CampaignFaction m_OwningFactionPrevious
Definition: SCR_CampaignMilitaryBaseComponent.c:105
SCR_FactionManager
void SCR_FactionManager(IEntitySource src, IEntity parent)
Definition: SCR_FactionManager.c:461
m_fNextFrameCheck
protected float m_fNextFrameCheck
Definition: SCR_CampaignMilitaryBaseComponent.c:93
m_bIsSupplyHub
protected bool m_bIsSupplyHub
Definition: SCR_CampaignMilitaryBaseComponent.c:47
GetFaction
SCR_CampaignFaction GetFaction()
Definition: SCR_CampaignMobileAssemblyStandaloneComponent.c:351
m_aDefendersGroups
protected ref array< SCR_AIGroup > m_aDefendersGroups
Definition: SCR_CampaignMilitaryBaseComponent.c:116
m_SeekDestroyWP
protected SCR_TimedWaypoint m_SeekDestroyWP
Definition: SCR_CampaignMilitaryBaseComponent.c:114
position
vector position
Definition: SCR_DestructibleTreeV2.c:30
m_HQRadio
protected IEntity m_HQRadio
Definition: SCR_CampaignMilitaryBaseComponent.c:109
SCR_EServicePointType
SCR_EServicePointType
Definition: SCR_ServicePointComponent.c:180
PlayerManager
Definition: PlayerManager.c:12
m_bIsControlPoint
protected bool m_bIsControlPoint
Definition: SCR_CampaignMilitaryBaseComponent.c:38
SCR_Faction
Definition: SCR_Faction.c:6
m_sBaseName
protected string m_sBaseName
Definition: SCR_CampaignMilitaryBaseComponent.c:50
SCR_ResourceGenerator
Definition: SCR_ResourceGenerator.c:79
m_bDisableWhenUnusedAsHQ
protected bool m_bDisableWhenUnusedAsHQ
Definition: SCR_CampaignMilitaryBaseComponent.c:44
SetCallsignIndex
void SetCallsignIndex(int index)
Definition: SCR_MilitaryBaseComponent.c:85
GetRadioRange
float GetRadioRange()
Definition: SCR_CampaignMilitaryBaseComponent.c:675
SCR_CampaignMilitaryBaseComponent
Definition: SCR_CampaignMilitaryBaseComponent.c:38
m_bInitialized
protected bool m_bInitialized
Definition: SCR_CampaignMilitaryBaseComponent.c:122
category
params category
Definition: SCR_VehicleDamageManagerComponent.c:180
EResourceGeneratorID
EResourceGeneratorID
Definition: SCR_ResourceGenerator.c:1
m_HQTent
protected IEntity m_HQTent
Definition: SCR_CampaignMilitaryBaseComponent.c:110