Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_CallsignManagerComponent.c
Go to the documentation of this file.
1 [ComponentEditorProps(category: "GameScripted/Callsign", description: "")]
4 {
5 }
6 
7 //~ ScriptInvokers
8 //~ Called when callsign changed or is assigned
9 void SCR_GroupsManagerComponent_OnPlayerCallsignChanged(int playerId, int companyCallsignIndex, int platoonCallsignIndex, int squadCallsignIndex, int characterCallsignNumber, ERoleCallsign characterRole);
11 
13 {
15  protected ref map<Faction, ref SCR_FactionCallsignData> m_mAvailableCallsigns = new map<Faction, ref SCR_FactionCallsignData>;
16 
18  protected ref array<ref array<int>> m_aDuplicateCallsigns = {};
19 
21  protected ref map<int, ref SCR_PlayerCallsignData> m_mPlayerCallsignData = new map<int, ref SCR_PlayerCallsignData>;
22 
23  //~ Script invoker (Server only)
24  protected ref ScriptInvokerBase<SCR_GroupsManagerComponent_OnPlayerCallsignChanged> m_OnPlayerCallsignChanged = new ScriptInvokerBase<SCR_GroupsManagerComponent_OnPlayerCallsignChanged>();
25 
26  //~ Ref (Server only)
27  SCR_GroupsManagerComponent m_GroupManager;
28 
29 
30  //======================================== GET CALLSIGN ========================================\\
31  //------------------------------------------------------------------------------------------------
40  bool GetEntityCallsignIndexes(IEntity entity, out int companyCallsignIndex, out int platoonCallsignIndex, out int squadCallsignIndex, out int characterCallsignIndex)
41  {
42  SCR_CallsignBaseComponent callsignComponent = SCR_CallsignBaseComponent.Cast(entity.FindComponent(SCR_CallsignBaseComponent));
43 
44  return callsignComponent && callsignComponent.GetCallsignIndexes(companyCallsignIndex, platoonCallsignIndex, squadCallsignIndex, characterCallsignIndex);
45  }
46 
47  //------------------------------------------------------------------------------------------------
56  bool GetEntityCallsignIndexes(SCR_EditableEntityComponent editableEntity, out int companyCallsignIndex, out int platoonCallsignIndex, out int squadCallsignIndex, out int characterCallsignIndex)
57  {
58  return GetEntityCallsignIndexes(editableEntity.GetOwner(), companyCallsignIndex, platoonCallsignIndex, squadCallsignIndex, characterCallsignIndex);
59  }
60 
61  //------------------------------------------------------------------------------------------------
71  bool GetEntityCallsignNames(IEntity entity, out string companyCallsignName, out string platoonCallsignName, out string squadCallsignName, out string characterCallsignName, out string format)
72  {
73  SCR_CallsignBaseComponent callsignComponent = SCR_CallsignBaseComponent.Cast(entity.FindComponent(SCR_CallsignBaseComponent));
74 
75  if (!callsignComponent)
76  return false;
77 
78  return callsignComponent.GetCallsignNames(companyCallsignName, platoonCallsignName, squadCallsignName, characterCallsignName, format);
79  }
80 
81  //------------------------------------------------------------------------------------------------
91  bool GetEntityCallsignNames(SCR_EditableEntityComponent editableEntity, out string companyCallsignName, out string platoonCallsignName, out string squadCallsignName, out string characterCallsignName, out string format)
92  {
93  return GetEntityCallsignNames(editableEntity.GetOwner(), companyCallsignName, platoonCallsignName, squadCallsignName, characterCallsignName, format);
94  }
95 
96  //------------------------------------------------------------------------------------------------
102  void AssignCallGroupCallsign(Faction faction, SCR_CallsignGroupComponent masterCallsignComponent, out int companyIndex, out int platoonIndex, out int squadIndex)
103  {
104  companyIndex = -1;
105  platoonIndex = -1;
106  squadIndex = -1;
107 
108  //~ Use master callsign
109  if (masterCallsignComponent)
110  {
111  masterCallsignComponent.GetCallsignIndexes(companyIndex, platoonIndex, squadIndex);
112  return;
113  }
114 
115  //Faction has no callsigns
116  if (!m_mAvailableCallsigns.Contains(faction))
117  return;
118 
119  SCR_Faction ScrFaction = SCR_Faction.Cast(faction);
120 
121  if (!ScrFaction)
122  return;
123 
124  SCR_FactionCallsignInfo callsignInfo = ScrFaction.GetCallsignInfo();
125  if (!callsignInfo)
126  return;
127 
128  //~Todo: Add logic for assigning same company callsigns by getting closest (same faction) company
129 
130  //Assign the first available callsign
131  if (!callsignInfo.GetIsAssignedRandomly())
132  AssignFirstAvailableGroupCallsign(faction, companyIndex, platoonIndex, squadIndex);
133  //Assign a random available callsign
134  else
135  AssignRandomGroupCallsigns(faction, companyIndex, platoonIndex, squadIndex);
136  }
137 
138  //------------------------------------------------------------------------------------------------
139  protected void AssignFirstAvailableGroupCallsign(Faction faction, out int companyIndex, out int platoonIndex, out int squadIndex)
140  {
141  SCR_FactionCallsignData factionCallsign;
142  if (m_mAvailableCallsigns.Find(faction, factionCallsign))
143  {
144  if (factionCallsign.GetFirstAvailibleCallsign(companyIndex, platoonIndex, squadIndex))
145  {
146  RemoveAvailableGroupCallsign(faction, companyIndex, platoonIndex, squadIndex);
147  return;
148  }
149  }
150 
151  //Callsign was not assigned as all callsigns are taken
152  AssignRandomDuplicateCallsign(faction, companyIndex, platoonIndex, squadIndex);
153  Print(string.Format("All available callsigns are taken for faction '%1', so a random duplicate is assigned instead. If this happenes a lot then more callsigns should be added for this faction!", faction.GetFactionName()), LogLevel.WARNING);
154  }
155 
156  //------------------------------------------------------------------------------------------------
157  //~Todo: Not yet used. Should check neighbouring groups and assign the same company if close to same faction group
158  protected void AssignCompanySpecificGroupCallsign(Faction faction, out int specificCompanyIndex, out int platoonIndex, out int squadIndex)
159  {
160  SCR_FactionCallsignData factionCallsign;
161  if (m_mAvailableCallsigns.Find(faction, factionCallsign))
162  {
163  if (factionCallsign.GetSpecificCompanyCallsign(specificCompanyIndex, platoonIndex, squadIndex))
164  {
165  RemoveAvailableGroupCallsign(faction, specificCompanyIndex, platoonIndex, squadIndex);
166  return;
167  }
168  }
169 
170  //Callsign was not assigned as all callsigns are taken
171  AssignRandomDuplicateCallsign(faction, specificCompanyIndex, platoonIndex, squadIndex);
172  Print(string.Format("All available callsigns are taken for faction '%1', so a random duplicate is assigned instead. If this happenes a lot then more callsigns should be added for this faction!", faction.GetFactionName()), LogLevel.WARNING);
173  }
174 
175  //------------------------------------------------------------------------------------------------
181  void AssignRandomGroupCallsigns(Faction faction, out int companyIndex, out int platoonIndex, out int squadIndex)
182  {
183  SCR_FactionCallsignData factionCallsign;
184  if (m_mAvailableCallsigns.Find(faction, factionCallsign))
185  {
186  if (factionCallsign.GetRandomCallsign(companyIndex, platoonIndex, squadIndex))
187  {
188  RemoveAvailableGroupCallsign(faction, companyIndex, platoonIndex, squadIndex);
189  return;
190  }
191  }
192 
193  //Callsign was not assigned as all callsigns are taken
194  AssignRandomDuplicateCallsign(faction, companyIndex, platoonIndex, squadIndex);
195  Print(string.Format("All available callsigns are taken for faction '%1', so a random duplicate is assigned instead. If this happenes a lot then more callsigns should be added for this faction!", faction.GetFactionName()), LogLevel.WARNING);
196  }
197 
198  //------------------------------------------------------------------------------------------------
205  // TODO: available -> available
206  void MakeGroupCallsignAvailible(Faction faction, int companyIndex, int platoonIndex, int squadIndex)
207  {
208  //Check if callsign was assigned duplicate
209  if (!m_aDuplicateCallsigns.IsEmpty())
210  {
211  int count = m_aDuplicateCallsigns.Count();
212 
213  for(int i = 0; i < count; i++)
214  {
215  //The assigned callsign was a duplicate safty. So it is removed from the duplicate list instead of making it available again
216  if (m_aDuplicateCallsigns[i][0] == companyIndex && m_aDuplicateCallsigns[i][1] == platoonIndex && m_aDuplicateCallsigns[i][2] == squadIndex)
217  {
218  m_aDuplicateCallsigns.Remove(i);
219  return;
220  }
221  }
222  }
223 
224  SCR_FactionCallsignData factionCallsignData;
225 
226  if (m_mAvailableCallsigns.Find(faction, factionCallsignData))
227  factionCallsignData.AddCallsign(companyIndex, platoonIndex, squadIndex);
228  }
229 
230  //------------------------------------------------------------------------------------------------
231  //A callsign is assigned
232  protected void RemoveAvailableGroupCallsign(Faction faction, int companyIndex, int platoonIndex, int squadIndex)
233  {
234  SCR_FactionCallsignData factionCallsignData;
235 
236  if (m_mAvailableCallsigns.Find(faction, factionCallsignData))
237  factionCallsignData.RemoveCallsign(companyIndex, platoonIndex, squadIndex);
238  }
239 
240  //------------------------------------------------------------------------------------------------
242  protected void AssignRandomDuplicateCallsign(Faction faction, out int company, out int platoon, out int squad)
243  {
244  SCR_Faction ScrFaction = SCR_Faction.Cast(faction);
245  if (!ScrFaction)
246  return;
247 
248  SCR_FactionCallsignInfo factionCallsignInfo = ScrFaction.GetCallsignInfo();
249  if (!factionCallsignInfo)
250  return;
251 
252  if (factionCallsignInfo.GetRandomCallsign(company, platoon, squad))
253  {
254  array<int> duplicateCallsign = {};
255  duplicateCallsign.Insert(company);
256  duplicateCallsign.Insert(platoon);
257  duplicateCallsign.Insert(squad);
258 
259  m_aDuplicateCallsigns.Insert(duplicateCallsign);
260  }
261  }
262 
263  //------------------------------------------------------------------------------------------------
265  protected void OnPlayerSpawn(int playerId, IEntity playerEntity)
266  {
267  if (!m_GroupManager)
268  return;
269 
270  SCR_CallsignCharacterComponent characterCallsign = SCR_CallsignCharacterComponent.Cast(playerEntity.FindComponent(SCR_CallsignCharacterComponent));
271  if (!characterCallsign)
272  return;
273 
274  //~ Init player Callsign component to make sure it knows it is a player and it listens to on Callsign Changed
275  characterCallsign.InitPlayerOnServer(playerId);
276 
277  //~ Get player Group
278  SCR_AIGroup playerGroup = m_GroupManager.GetPlayerGroup(playerId);
279  if (!playerGroup)
280  return;
281 
282  //~ Get master if group is slave
283  if (playerGroup.IsSlave())
284  {
285  SCR_AIGroup master = playerGroup.GetMaster();
286 
287  if (master)
288  playerGroup = master;
289  }
290 
291  int companyIndex, platoonIndex, squadIndex, characterNumber;
292  ERoleCallsign characterRole;
293 
294  //~ Get player callsign from manager (If any)
295  if (!GetPlayerCallsign(playerId, companyIndex, platoonIndex, squadIndex, characterNumber, characterRole))
296  return;
297 
298  //~ Assign player callsign if found
299  characterCallsign.AssignCharacterCallsign(playerGroup.GetFaction(), companyIndex, platoonIndex, squadIndex, characterNumber, characterRole, playerGroup.GetPlayerAndAgentCount(true) <= 1);
300  }
301 
302  //------------------------------------------------------------------------------------------------
309  void SetPlayerCallsign(int playerId, int companyIndex, int platoonIndex, int squadIndex, int characterNumber, ERoleCallsign characterRole = ERoleCallsign.NONE)
310  {
311  if (playerId <= 0)
312  {
313  Print("'SetPlayerCallsign': Invalid player ID: " + playerId, LogLevel.ERROR);
314  return;
315  }
316 
317  SCR_PlayerCallsignData playerCallsignData;
318 
319  //~ Create new Data if non existing
320  if (!m_mPlayerCallsignData.Find(playerId, playerCallsignData))
321  playerCallsignData = new SCR_PlayerCallsignData();
322 
323  //~ Set new player callsign data
324  playerCallsignData.SetPlayerCallsignIndexes(companyIndex, platoonIndex, squadIndex, characterNumber, characterRole);
325  m_mPlayerCallsignData.Set(playerId, playerCallsignData);
326 
327  //~ Call On player callsign changed
328  m_OnPlayerCallsignChanged.Invoke(playerId, companyIndex, platoonIndex, squadIndex, characterNumber, characterRole);
329  }
330 
331  //------------------------------------------------------------------------------------------------
332  protected void OnPlayerLeftGame(int playerId)
333  {
334  if (m_mPlayerCallsignData.Contains(playerId))
335  m_mPlayerCallsignData.Remove(playerId);
336  }
337 
338  //------------------------------------------------------------------------------------------------
346  bool GetPlayerCallsign(int playerId, out int companyIndex, out int platoonIndex, out int squadIndex, out int characterNumber = -1, out ERoleCallsign characterRole = ERoleCallsign.NONE)
347  {
348  SCR_PlayerCallsignData playerCallsignData;
349  if (m_mPlayerCallsignData.Find(playerId, playerCallsignData))
350  return playerCallsignData.GetPlayerCallsignIndexes(companyIndex, platoonIndex, squadIndex, characterNumber, characterRole);
351  else
352  return false;
353  }
354 
355  //------------------------------------------------------------------------------------------------
357  ScriptInvokerBase<SCR_GroupsManagerComponent_OnPlayerCallsignChanged> GetOnPlayerCallsignChanged()
358  {
359  return m_OnPlayerCallsignChanged;
360  }
361 
362  //------------------------------------------------------------------------------------------------
363  protected void FillAvailableCallsigns()
364  {
365  array<Faction> factions = {};
366  FactionManager factionManager = GetGame().GetFactionManager();
367 
368  if (!factionManager)
369  return;
370 
371  factionManager.GetFactionsList(factions);
372 
373  foreach (Faction faction: factions)
374  {
375  SCR_Faction ScrFaction = SCR_Faction.Cast(faction);
376 
377  if (!ScrFaction)
378  continue;
379 
380  SCR_FactionCallsignInfo factionCallsignInfo = ScrFaction.GetCallsignInfo();
381 
382  if (!factionCallsignInfo)
383  continue;
384 
385  array<ref SCR_CallsignInfo> companyArray = {};
386  array<ref SCR_CallsignInfo> platoonArray = {};
387  array<ref SCR_CallsignInfo> squadArray = {};
388 
389  factionCallsignInfo.GetCompanyArray(companyArray);
390  if (companyArray.IsEmpty())
391  continue;
392 
393  factionCallsignInfo.GetPlatoonArray(platoonArray);
394  if (platoonArray.IsEmpty())
395  continue;
396 
397  factionCallsignInfo.GetSquadArray(squadArray);
398  if (squadArray.IsEmpty())
399  continue;
400 
401  SCR_FactionCallsignData factionCallsignData = new SCR_FactionCallsignData(factionCallsignInfo);
402 
403  m_mAvailableCallsigns.Insert(faction, factionCallsignData);
404  }
405  }
406 
407  //------------------------------------------------------------------------------------------------
408  override void EOnInit(IEntity owner)
409  {
410  super.EOnInit(owner);
411 
412  FillAvailableCallsigns();
413 
414  if (GetGameMode().IsMaster())
415  {
416  m_GroupManager = SCR_GroupsManagerComponent.GetInstance();
417  if (!m_GroupManager)
418  Debug.Error2("SCR_CallsignManagerComponent: EOnInit", "Could not find SCR_GroupsManagerComponent!");
419 
420  GetGameMode().GetOnPlayerDisconnected().Insert(OnPlayerLeftGame);
421  GetGameMode().GetOnPlayerSpawned().Insert(OnPlayerSpawn);
422  }
423  }
424 
425  //------------------------------------------------------------------------------------------------
426  override void OnPostInit(IEntity owner)
427  {
428  super.OnPostInit(owner);
429 
430  if (SCR_Global.IsEditMode(owner))
431  return;
432 
433  SetEventMask(owner, EntityEvent.INIT);
434  }
435 
436  //------------------------------------------------------------------------------------------------
437  // destructor
439  {
440  if (!GetGameMode())
441  return;
442 
443  if (GetGameMode().IsMaster())
444  {
445  GetGameMode().GetOnPlayerDisconnected().Remove(OnPlayerLeftGame);
446  GetGameMode().GetOnPlayerSpawned().Remove(OnPlayerSpawn);
447  }
448  }
449 }
ComponentEditorProps
SCR_FragmentEntityClass ComponentEditorProps
SCR_CallsignManagerComponentClass
Manages available callsigns for each faction.
Definition: SCR_CallsignManagerComponent.c:3
SCR_PlayerCallsignData
Definition: SCR_PlayerCallsignData.c:4
SCR_FactionCallsignData
For each faction, holds available companies, which in turn hold available platoons,...
Definition: SCR_FactionCallsignData.c:2
IsMaster
protected bool IsMaster()
Definition: SCR_DataCollectorComponent.c:190
SCR_GroupsManagerComponent_OnPlayerCallsignChanged
func SCR_GroupsManagerComponent_OnPlayerCallsignChanged
Definition: SCR_CallsignManagerComponent.c:10
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
SCR_FactionCallsignInfo
Definition: SCR_FactionCallsignInfo.c:5
ERoleCallsign
ERoleCallsign
Definition: ERoleCallsign.c:4
func
func
Definition: SCR_AIThreatSystem.c:5
SCR_CallsignBaseComponent
Component of assigning and storing squad names.
Definition: SCR_CallsignBaseComponent.c:11
GetGameMode
SCR_BaseGameMode GetGameMode()
Definition: SCR_BaseGameModeComponent.c:15
SCR_EditableEntityComponent
Definition: SCR_EditableEntityComponent.c:13
Faction
Definition: Faction.c:12
SCR_GroupsManagerComponent
void SCR_GroupsManagerComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
Definition: SCR_GroupsManagerComponent.c:1320
SCR_Global
Definition: Functions.c:6
SCR_AIGroup
Definition: SCR_AIGroup.c:68
SCR_CallsignManagerComponent
Definition: SCR_CallsignManagerComponent.c:12
SCR_BaseGameModeComponentClass
Definition: SCR_BaseGameModeComponent.c:2
SCR_Faction
Definition: SCR_Faction.c:6
category
params category
Definition: SCR_VehicleDamageManagerComponent.c:180
SCR_BaseGameModeComponent
void SCR_BaseGameModeComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
Definition: SCR_BaseGameModeComponent.c:199