Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_MilitaryBaseSystem.c
Go to the documentation of this file.
1 void OnBaseFactionChangedDelegate(SCR_MilitaryBaseComponent base, Faction faction);
2 void OnLogicPresenceChangedDelegate(SCR_MilitaryBaseComponent base, SCR_MilitaryBaseLogicComponent logic);
3 
6 
7 typedef ScriptInvokerBase<OnBaseFactionChangedDelegate> OnBaseFactionChangedInvoker;
8 typedef ScriptInvokerBase<OnLogicPresenceChangedDelegate> OnLogicPresenceChangedInvoker;
9 
10 //------------------------------------------------------------------------------------------------
12 {
13  protected ref array<SCR_MilitaryBaseComponent> m_aBases = {};
14  protected ref array<SCR_MilitaryBaseLogicComponent> m_aLogicComponents = {};
15  protected ref array<int> m_aAvailableCallsignIds;
16 
17  protected ref OnBaseFactionChangedInvoker m_OnBaseFactionChanged;
18  protected ref OnLogicPresenceChangedInvoker m_OnLogicRegisteredInBase;
19  protected ref OnLogicPresenceChangedInvoker m_OnLogicUnregisteredInBase;
20 
21  //------------------------------------------------------------------------------------------------
22  static SCR_MilitaryBaseSystem GetInstance()
23  {
24  World world = GetGame().GetWorld();
25 
26  if (!world)
27  return null;
28 
29  return SCR_MilitaryBaseSystem.Cast(world.FindSystem(SCR_MilitaryBaseSystem));
30  }
31 
32  //------------------------------------------------------------------------------------------------
33  override event protected void OnCleanup()
34  {
36 
37  if (core)
38  core.Event_OnEntityTransformChanged.Remove(OnEntityTransformChanged);
39  }
40 
41  //------------------------------------------------------------------------------------------------
42  void OnBaseFactionChanged(Faction faction, SCR_MilitaryBaseComponent base)
43  {
44  if (m_OnBaseFactionChanged)
45  m_OnBaseFactionChanged.Invoke(base, faction);
46  }
47 
48  //------------------------------------------------------------------------------------------------
49  void OnLogicRegisteredInBase(SCR_MilitaryBaseLogicComponent logic, SCR_MilitaryBaseComponent base)
50  {
51  if (m_OnLogicRegisteredInBase)
52  m_OnLogicRegisteredInBase.Invoke(base, logic);
53  }
54 
55  //------------------------------------------------------------------------------------------------
56  void OnLogicUnregisteredInBase(SCR_MilitaryBaseLogicComponent logic, SCR_MilitaryBaseComponent base)
57  {
58  if (m_OnLogicUnregisteredInBase)
59  m_OnLogicUnregisteredInBase.Invoke(base, logic);
60  }
61 
62  //------------------------------------------------------------------------------------------------
63  OnBaseFactionChangedInvoker GetOnBaseFactionChanged()
64  {
65  if (!m_OnBaseFactionChanged)
66  m_OnBaseFactionChanged = new OnBaseFactionChangedInvoker();
67 
68  return m_OnBaseFactionChanged;
69  }
70 
71  //------------------------------------------------------------------------------------------------
72  OnLogicPresenceChangedInvoker GetOnLogicRegisteredInBase()
73  {
74  if (!m_OnLogicRegisteredInBase)
75  m_OnLogicRegisteredInBase = new OnLogicPresenceChangedInvoker();
76 
77  return m_OnLogicRegisteredInBase;
78  }
79 
80  //------------------------------------------------------------------------------------------------
81  OnLogicPresenceChangedInvoker GetOnLogicUnregisteredInBase()
82  {
83  if (!m_OnLogicUnregisteredInBase)
84  m_OnLogicUnregisteredInBase = new OnLogicPresenceChangedInvoker();
85 
86  return m_OnLogicUnregisteredInBase;
87  }
88 
89  //------------------------------------------------------------------------------------------------
90  protected void SetupInvokers()
91  {
93 
94  if (core)
95  core.Event_OnEntityTransformChanged.Insert(OnEntityTransformChanged);
96  }
97 
98  //------------------------------------------------------------------------------------------------
100  protected void OnEntityTransformChanged(notnull SCR_EditableEntityComponent editComponent)
101  {
102  array<IEntity> queue = {editComponent.GetOwner()};
103  SCR_MilitaryBaseComponent baseComponent;
104  SCR_MilitaryBaseLogicComponent logicComponent;
105  IEntity processedEntity;
106  IEntity nextInHierarchy;
107  bool checkeEditableEntityComponent;
108 
109  while (!queue.IsEmpty())
110  {
111  processedEntity = queue[0];
112  queue.Remove(0);
113 
114  if (!checkeEditableEntityComponent || !SCR_EditableEntityComponent.Cast(processedEntity.FindComponent(SCR_EditableEntityComponent)))
115  {
116  baseComponent = SCR_MilitaryBaseComponent.Cast(processedEntity.FindComponent(SCR_MilitaryBaseComponent));
117  logicComponent = SCR_MilitaryBaseLogicComponent.Cast(processedEntity.FindComponent(SCR_MilitaryBaseLogicComponent));
118 
119  if (baseComponent)
120  OnBaseTransformChanged(baseComponent);
121 
122  if (logicComponent)
123  OnLogicTransformChanged(logicComponent);
124  }
125 
126  nextInHierarchy = processedEntity.GetChildren();
127 
128  while (nextInHierarchy)
129  {
130  queue.Insert(nextInHierarchy);
131  nextInHierarchy = nextInHierarchy.GetSibling();
132  }
133  }
134  }
135 
136  //------------------------------------------------------------------------------------------------
138  protected void OnBaseTransformChanged(notnull SCR_MilitaryBaseComponent baseComponent)
139  {
140  vector position = baseComponent.GetOwner().GetOrigin();
141  int distanceLimit = baseComponent.GetRadius() * baseComponent.GetRadius();
142 
143  foreach (SCR_MilitaryBaseLogicComponent logicComponent : m_aLogicComponents)
144  {
145  if (vector.DistanceSqXZ(position, logicComponent.GetOwner().GetOrigin()) > distanceLimit)
146  {
147  baseComponent.UnregisterLogicComponent(logicComponent);
148  logicComponent.UnregisterBase(baseComponent);
149  }
150  else
151  {
152  baseComponent.RegisterLogicComponent(logicComponent);
153  logicComponent.RegisterBase(baseComponent);
154  }
155  }
156  }
157 
158  //------------------------------------------------------------------------------------------------
160  protected void OnLogicTransformChanged(notnull SCR_MilitaryBaseLogicComponent logicComponent)
161  {
162  vector position = logicComponent.GetOwner().GetOrigin();
163  int radius;
164 
165  foreach (SCR_MilitaryBaseComponent baseComponent : m_aBases)
166  {
167  radius = baseComponent.GetRadius();
168 
169  if (vector.DistanceSqXZ(position, baseComponent.GetOwner().GetOrigin()) > (radius * radius))
170  {
171  baseComponent.UnregisterLogicComponent(logicComponent);
172  logicComponent.UnregisterBase(baseComponent);
173  }
174  else
175  {
176  baseComponent.RegisterLogicComponent(logicComponent);
177  logicComponent.RegisterBase(baseComponent);
178  }
179  }
180  }
181 
182  //------------------------------------------------------------------------------------------------
183  void LoadAvailableCallsigns()
184  {
185  FactionManager fManager = GetGame().GetFactionManager();
186 
187  if (!fManager)
188  return;
189 
190  m_aAvailableCallsignIds = {};
191  array<Faction> allFactions = {};
192  array<SCR_Faction> playableFactions = {};
193  fManager.GetFactionsList(allFactions);
194  array<int> callsignIndexesSource = {};
195 
196  foreach (Faction faction : allFactions)
197  {
198  SCR_Faction factionCast = SCR_Faction.Cast(faction);
199 
200  if (factionCast && factionCast.IsPlayable())
201  playableFactions.Insert(factionCast);
202  }
203 
204  if (playableFactions.IsEmpty())
205  return;
206 
207  // All playable factions need to have a callsign with the same ID registered in order for it to be used
208  // Grab the indexes available from the first valid faction in the list so we can compare it with the other factions
209  callsignIndexesSource = playableFactions[0].GetBaseCallsignIndexes();
210  bool canAdd;
211 
212  foreach (int indexSource : callsignIndexesSource)
213  {
214  canAdd = true;
215 
216  // Ignore the index unless it's registered in all other factions
217  foreach (int i, SCR_Faction faction : playableFactions)
218  {
219  // No need to check it against the original source faction
220  if (i == 0)
221  continue;
222 
223  if (!faction.GetBaseCallsignByIndex(indexSource))
224  {
225  canAdd = false;
226  break;
227  }
228  }
229 
230  if (!canAdd)
231  continue;
232 
233  m_aAvailableCallsignIds.Insert(indexSource);
234  }
235  }
236 
237  //------------------------------------------------------------------------------------------------
238  void RegisterBase(notnull SCR_MilitaryBaseComponent base)
239  {
240  m_aBases.Insert(base);
241 
242  vector basePosition = base.GetOwner().GetOrigin();
243  int baseRadius = base.GetRadius();
244  int distanceLimit = baseRadius * baseRadius;
245 
246  if (Replication.IsServer())
247  {
248  // If not done already, grab all available callsign IDs
249  if (!m_aAvailableCallsignIds)
250  LoadAvailableCallsigns();
251 
252  // Assign random available callsign
253  if (m_aAvailableCallsignIds && !m_aAvailableCallsignIds.IsEmpty())
254  {
255  int i = m_aAvailableCallsignIds.GetRandomIndex();
256 
257  base.SetCallsignIndexAutomatic(m_aAvailableCallsignIds[i]);
258  m_aAvailableCallsignIds.Remove(i);
259  }
260  }
261 
262  foreach (SCR_MilitaryBaseLogicComponent component : m_aLogicComponents)
263  {
264  if (vector.DistanceSqXZ(component.GetOwner().GetOrigin(), basePosition) <= distanceLimit)
265  {
266  base.RegisterLogicComponent(component);
267  component.RegisterBase(base);
268  }
269  }
270  }
271 
272  //------------------------------------------------------------------------------------------------
273  void UnregisterBase(notnull SCR_MilitaryBaseComponent base)
274  {
275  if (m_aAvailableCallsignIds)
276  m_aAvailableCallsignIds.Insert(base.GetCallsign());
277 
278  m_aBases.RemoveItem(base);
279  }
280 
281  //------------------------------------------------------------------------------------------------
282  int GetBases(notnull out array<SCR_MilitaryBaseComponent> bases)
283  {
284  return bases.Copy(m_aBases);
285  }
286 
287  //------------------------------------------------------------------------------------------------
288  int GetBasesCount()
289  {
290  return m_aBases.Count();
291  }
292 
293  //------------------------------------------------------------------------------------------------
294  void RegisterLogicComponent(notnull SCR_MilitaryBaseLogicComponent component)
295  {
296  m_aLogicComponents.Insert(component);
297 
298  vector position = component.GetOwner().GetOrigin();
299  int radius;
300 
301  foreach (SCR_MilitaryBaseComponent base : m_aBases)
302  {
303  radius = base.GetRadius();
304 
305  if (vector.DistanceSqXZ(base.GetOwner().GetOrigin(), position) <= (radius * radius))
306  {
307  base.RegisterLogicComponent(component);
308  component.RegisterBase(base);
309  }
310  }
311  }
312 
313  //------------------------------------------------------------------------------------------------
314  void UnregisterLogicComponent(notnull SCR_MilitaryBaseLogicComponent component)
315  {
316  m_aLogicComponents.RemoveItem(component);
317  }
318 }
SCR_EditableEntityCore
Definition: SCR_EditableEntityCore.c:10
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
SCR_MilitaryBaseSystem
Definition: SCR_MilitaryBaseSystem.c:11
func
func
Definition: SCR_AIThreatSystem.c:5
m_aBases
SCR_MilitaryBaseLogicComponentClass m_aBases
GameSystem
Definition: GameSystem.c:12
OnLogicPresenceChangedInvoker
ScriptInvokerBase< OnLogicPresenceChangedDelegate > OnLogicPresenceChangedInvoker
Definition: SCR_MilitaryBaseSystem.c:8
OnBaseFactionChangedDelegate
func OnBaseFactionChangedDelegate
Definition: SCR_MilitaryBaseSystem.c:4
SCR_EditableEntityComponent
Definition: SCR_EditableEntityComponent.c:13
Faction
Definition: Faction.c:12
OnBaseFactionChangedInvoker
ScriptInvokerBase< OnBaseFactionChangedDelegate > OnBaseFactionChangedInvoker
Definition: SCR_MilitaryBaseSystem.c:7
OnLogicPresenceChangedDelegate
func OnLogicPresenceChangedDelegate
Definition: SCR_MilitaryBaseSystem.c:5
position
vector position
Definition: SCR_DestructibleTreeV2.c:30
SCR_Faction
Definition: SCR_Faction.c:6