Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_DataCollectorComponent.c
Go to the documentation of this file.
1 [EntityEditorProps(category: "GameScripted/DataCollection/", description: "Main component used for collecting player data.")]
3 {
4 }
5 
6 class SCR_DataCollectorComponent : SCR_BaseGameModeComponent
7 {
8  [Attribute()]
9  protected ref array<ref SCR_DataCollectorModule> m_aModules;
10 
11  [Attribute()]
12  protected bool m_bOptionalKicking;
13 
14  [Attribute("3", desc: "Optional kicking: Penalty score for killing a friendly player.")]
16 
17  [Attribute("1", desc: "Penalty score for killing a friendly AI.")]
19 
20  [Attribute("10", desc: "Penalty score limit for a kick from the match.")]
22 
23  [Attribute("1800", desc: "Ban duration after a kick (in seconds, -1 for a session-long ban).")]
25 
26  [Attribute("900", desc: "How often penalty score subtraction happens (in seconds).")]
28 
29  [Attribute("2", desc: "How many penalty points get substracted after each subtraction period.")]
31 
33 
34  protected ref map<int, ref SCR_PlayerData> m_mPlayerData = new map<int, ref SCR_PlayerData>();
35 
36  protected IEntity m_Owner;
37 
39 
40  protected ref map<FactionKey, ref array<float>> m_mFactionScore = new map<FactionKey, ref array<float>>();
41 
42 #ifdef ENABLE_DIAG
43  protected bool m_bLocalEntityListening = false;
44  protected int m_iInitializingTimer = 0;
45  protected bool m_bVisualDisplay = false;
46 #endif
47 
48  //------------------------------------------------------------------------------------------------
49  protected override void OnGameModeEnd(SCR_GameModeEndData data)
50  {
51  foreach (SCR_DataCollectorModule module : m_aModules)
52  {
53  module.OnGameModeEnd();
54  }
55 
56  PlayerManager playerManager = GetGame().GetPlayerManager();
57  int playerID;
58  PlayerController playerController;
59  SCR_DataCollectorCommunicationComponent communicationComponent;
60 
61  // Here we add to the faction the scores of all the players who haven't disconnected yet
62  SCR_ChimeraCharacter playerChimera;
63  Faction faction;
64 
65  for (int i = m_mPlayerData.Count() - 1; i >= 0; i--)
66  {
67  playerID = m_mPlayerData.GetKey(i);
68 
69  // We update the duration of the session here because it should not be connected to any module
70  m_mPlayerData.Get(playerID).CalculateSessionDuration();
71 
72  playerChimera = SCR_ChimeraCharacter.Cast(playerManager.GetPlayerControlledEntity(playerID));
73  if (!playerChimera)
74  continue;
75 
76  faction = playerChimera.GetFaction();
77 
78  if (!faction)
79  continue;
80 
81  AddStatsToFaction(faction.GetFactionKey(), m_mPlayerData.Get(playerID).CalculateStatsDifference());
82  }
83 
84  // We replicate the faction stats now, so they can be found in the client's machine
85  array<FactionKey> factionKeys = {};
86  array<float> factionValues = {};
87  int valuesSize = 0;
88 
89  foreach (FactionKey key, array<float> value : m_mFactionScore)
90  {
91  factionKeys.Insert(key);
92  factionValues.InsertAll(value);
93  if (valuesSize == 0)
94  valuesSize = value.Count();
95  }
96 
97  for (int i = m_mPlayerData.Count() - 1; i >= 0; i--)
98  {
99  playerID = m_mPlayerData.GetKey(i);
100  playerController = playerManager.GetPlayerController(playerID);
101  if (!playerController)
102  continue;
103 
104  communicationComponent = SCR_DataCollectorCommunicationComponent.Cast(playerController.FindComponent(SCR_DataCollectorCommunicationComponent));
105  if (!communicationComponent)
106  continue;
107 
108  communicationComponent.SendData(m_mPlayerData.Get(playerID), factionKeys, factionValues, valuesSize);
109  }
110  }
111 
112  //------------------------------------------------------------------------------------------------
118  array<float> GetFactionStats(FactionKey key)
119  {
120  return m_mFactionScore.Get(key);
121  }
122 
123  //------------------------------------------------------------------------------------------------
129  map<FactionKey, ref array<float>> GetAllFactionStats()
130  {
131  return m_mFactionScore;
132  }
133 
134  //------------------------------------------------------------------------------------------------
138  void AddStatsToFaction(FactionKey key, notnull array<float> stats)
139  {
140  array<float> factionStats = m_mFactionScore.Get(key);
141  //If the faction doesn't exist in our map yet, just create it and initialize it with these stats
142  if (!factionStats)
143  {
144  m_mFactionScore.Insert(key, stats);
145  }
146  else
147  {
148  int statsCount = stats.Count();
149 
150  if (statsCount == 0 || factionStats.Count() != statsCount)
151  {
152  Print("ERROR WHEN ADDING FACTIONSTATS IN DATA COLLECTOR: Size of faction stats is different than expected size! Expected size was" + statsCount + " but real size was "+ factionStats.Count(), LogLevel.WARNING);
153  return;
154  }
155 
156  for (int i = 0; i < statsCount; i++)
157  {
158  factionStats[i] = factionStats[i] + stats[i];
159  }
160  }
161  }
162 
163  //------------------------------------------------------------------------------------------------
165  override void OnGameEnd()
166  {
167  for (int i = m_mPlayerData.Count() - 1; i >= 0; i--)
168  {
169  SCR_PlayerData playerData = GetPlayerData(m_mPlayerData.GetKey(i), false);
170  if (playerData)
171  playerData.StoreProfile();
172  }
173  }
174 
175  //------------------------------------------------------------------------------------------------
180  {
181  for (int i = m_aModules.Count() - 1; i >= 0; i--)
182  {
183  if (m_aModules[i].Type() == type)
184  return m_aModules[i];
185  }
186  return null;
187  }
188 
189  //------------------------------------------------------------------------------------------------
190  protected bool IsMaster()
191  {
192  RplComponent rplComponent = RplComponent.Cast(GetOwner().FindComponent(RplComponent));
193  return (rplComponent && rplComponent.IsMaster());
194  }
195 
196  //------------------------------------------------------------------------------------------------
199  Managed GetPlayerDataStats(int playerID)
200  {
201  SCR_PlayerData playerData = GetPlayerData(playerID);
202  //Now this instance of playerData can be deleted from the array
203  //We need this callqueue because we can't remove the instance from this array before it's sent to TD through c++
204  GetGame().GetCallqueue().CallLater(RemovePlayer, 500, false, playerID);
205 
206  return playerData.GetDataEventStats();
207  }
208 
209  //------------------------------------------------------------------------------------------------
210  protected void RemovePlayer(int playerID)
211  {
212  m_mPlayerData.Remove(playerID);
213  }
214 
215  //------------------------------------------------------------------------------------------------
220  SCR_PlayerData GetPlayerData(int playerID, bool createNew = true, bool requestFromBackend = true)
221  {
222  SCR_PlayerData playerData = m_mPlayerData.Get(playerID);
223  if (!playerData && createNew)
224  {
225  playerData = new SCR_PlayerData(playerID, true, requestFromBackend);
226  m_mPlayerData.Insert(playerID, playerData);
227  }
228 
229  return playerData;
230  }
231 
232  //------------------------------------------------------------------------------------------------
233  protected int GetPlayers(out notnull array<int> outPlayers)
234  {
235  if (m_mPlayerData.IsEmpty())
236  return 0;
237 
238  for (int i = m_mPlayerData.Count() - 1; i >= 0; i--)
239  {
240  outPlayers.Insert(m_mPlayerData.GetKey(i));
241  }
242 
243  return m_mPlayerData.Count();
244  }
245 
246  //------------------------------------------------------------------------------------------------
247  // OnAuditSuccess is the moment when the player has not only connected, but also been authenticated
248  protected override void OnPlayerAuditSuccess(int playerId)
249  {
250  Print("Player with id " + playerId + " was auditted succesfully and admitted on the Data Collector", LogLevel.DEBUG);
251  //We create the player's PlayerData here
252  GetPlayerData(playerId);
253 
254  //And then let the modules handle the newly connected player if they need to
255  foreach (SCR_DataCollectorModule module : m_aModules)
256  {
257  module.OnPlayerAuditSuccess(playerId);
258  }
259  }
260 
261  //------------------------------------------------------------------------------------------------
262  protected override void OnPlayerConnected(int playerId)
263  {
264  if (m_bOptionalKicking)
265  m_OptionalKicking.OnPlayerConnected(playerId);
266  }
267 
268  //------------------------------------------------------------------------------------------------
269  protected override void OnPlayerDisconnected(int playerId, KickCauseCode cause, int timeout)
270  {
271  SCR_PlayerData playerDisconnectedData = GetPlayerData(playerId);
272  foreach (SCR_DataCollectorModule module : m_aModules)
273  {
274  module.OnPlayerDisconnected(playerId);
275  }
276 
277  playerDisconnectedData.StoreProfile();
278 
279  // ADD STATS TO FACTION
280  // Here we add the stats of the individual player who desconnected to the faction
281  // We only do that if the game is not in POSTGAME state, because if it is we already added this player's stats to the faction in the OnGameModeEnd method
282 
284  if (gameMode.GetState() != SCR_EGameModeState.POSTGAME)
285  {
286  IEntity player = GetGame().GetPlayerManager().GetPlayerControlledEntity(playerId);
287  SCR_ChimeraCharacter playerChimera = SCR_ChimeraCharacter.Cast(player);
288  if (playerChimera)
289  {
290  Faction faction = playerChimera.GetFaction();
291  if (faction)
292  AddStatsToFaction(faction.GetFactionKey(), playerDisconnectedData.CalculateStatsDifference());
293  }
294  }
295 
296  // DONE ADDING STATS TO THE FACTION
297  //We cannot remove this instance of data from the player collector because the event has not been sent yet to the Database for tracking purposes
298  //m_mPlayerData.Remove(playerId);
299 
300  //As an alternative, in GetPlayerDataStats we put this instance to be removed after its used in C++
301  }
302 
303  //------------------------------------------------------------------------------------------------
304  protected override void OnPlayerSpawned(int playerId, IEntity controlledEntity)
305  {
306  foreach (SCR_DataCollectorModule module : m_aModules)
307  {
308  module.OnPlayerSpawned(playerId, controlledEntity);
309  }
310  }
311 
312  //------------------------------------------------------------------------------------------------
313  protected override void OnPlayerKilled(int playerId, IEntity playerEntity, IEntity killerEntity, notnull Instigator killer)
314  {
315  foreach (SCR_DataCollectorModule module : m_aModules)
316  {
317  module.OnPlayerKilled(playerId, playerEntity, killerEntity, killer);
318  }
319 
320  if (m_bOptionalKicking)
321  m_OptionalKicking.OnControllableDestroyed(playerEntity, killerEntity, killer);
322  }
323 
324  //------------------------------------------------------------------------------------------------
325  protected void OnAIKilled(IEntity AIEntity, IEntity killerEntity, notnull Instigator killer)
326  {
327  foreach (SCR_DataCollectorModule module : m_aModules)
328  {
329  module.OnAIKilled(AIEntity, killerEntity, killer);
330  }
331 
332  if (m_bOptionalKicking)
333  m_OptionalKicking.OnControllableDestroyed(AIEntity, killerEntity, killer);
334  }
335 
336  //------------------------------------------------------------------------------------------------
337  // This method is a hack to process killings when the dead entity is an AI
338  // Because there is no "OnAiKilled" method
339  protected override void OnControllableDestroyed(IEntity entity, IEntity killerEntity, notnull Instigator killer)
340  {
341  if (!SCR_ChimeraCharacter.Cast(entity))
342  {
343  // Spoiler - it was a vehicle, not an error
344  // Print("Error: The OnControllableDestroyed method from the Data Collector was invoked with an IEntity that is not a chimera character."
345  // + "Dead entity is" + entity +", and killerEntity is "+killerEntity, LogLevel.ERROR);
346  // PrintFormat("Dead: %1", entity);
347  // PrintFormat("KillerEntity: %1", killerEntity);
348  return;
349  }
350 
351  int playerId = GetGame().GetPlayerManager().GetPlayerIdFromControlledEntity(entity);
352  //If playerId is not 0 it means that the entity killed was a player
353  //Therefore it will be handled by the OnPlayerKilled event
354  //so we don't need to do anything else
355  if (playerId > 0)
356  return;
357 
358  OnAIKilled(entity, killerEntity, killer);
359  }
360 
361 #ifdef ENABLE_DIAG
362  //------------------------------------------------------------------------------------------------
365  void OnPlayerEntityChanged(IEntity from, IEntity to)
366  {
367  foreach (SCR_DataCollectorModule module : m_aModules)
368  {
369  module.OnControlledEntityChanged(from, to);
370  }
371  }
372 
373  //------------------------------------------------------------------------------------------------
375  protected void ListenToLocalControllerEntityChanged()
376  {
378 
379  if (playerController)
380  {
381  m_bLocalEntityListening = true;
382  playerController.m_OnControlledEntityChanged.Insert(OnPlayerEntityChanged);
383  }
384  }
385 
386  //------------------------------------------------------------------------------------------------
387  // Prototyping method. ENABLE_DIAG CLI or #define required
388  protected void CreateStatVisualizations()
389  {
390  if (!m_UiHandler)
392 
393  for (int i = m_aModules.Count() - 1; i >= 0; i--)
394  {
395  m_aModules[i].CreateVisualization();
396  }
397  }
398 
399  //------------------------------------------------------------------------------------------------
401  SCR_DataCollectorUI GetUIHandler()
402  {
403  return m_UiHandler;
404  }
405 #endif
406 
407  //------------------------------------------------------------------------------------------------
408  protected override void OnGameModeStart()
409  {
411  }
412 
413  //------------------------------------------------------------------------------------------------
415  protected void DisableModules()
416  {
417  m_aModules.Clear();
418  }
419 
420  //------------------------------------------------------------------------------------------------
425  {
426  //If it's no server, disable all tracking
427  if (!IsMaster())
428  {
429 #ifndef ENABLE_DIAG
430  DisableModules();
431  m_bOptionalKicking = false;
432  return;
433 #endif
434  }
435 
436  //Init all modules
437  foreach (SCR_DataCollectorModule module : m_aModules)
438  {
439  module.InitModule();
440  }
441 
442  bool writingRights = false;
443  BackendApi ba = GetGame().GetBackendApi();
444 
445  if (ba)
446  {
447  SessionStorage baStorage = ba.GetStorage();
448  if (baStorage)
449  writingRights = baStorage.GetOnlineWritePrivilege();
450  }
451 
452  //Local storage or online backend storage?
453  if (!writingRights)
454  Print("DataCollectorComponent: StartDataCollectorSession: This server has no writing privileges. Will use local storage instead.", LogLevel.DEBUG);
455  else
456  Print("DataCollectorComponent: StartDataCollectorSession: Using online backend storage.", LogLevel.DEBUG);
457 
458  if (!m_Owner)
459  Print("DataCollectorComponent: StartDataCollectorSession: m_Owner is null. Can't add the EntityEvent.FRAME flag thus data collector will not work properly.", LogLevel.ERROR);
460  else
461  SetEventMask(m_Owner, EntityEvent.FRAME); //Activate the FRAME flag
462  }
463 
464  //------------------------------------------------------------------------------------------------
465  protected override void EOnFrame(IEntity owner, float timeSlice)
466  {
467 #ifdef ENABLE_DIAG
468 
469  // Hotfix: AND I AM DISABLING THIS, because it causes other invokers to be duplicit after respawn
470  // TODO: Make something more serious
471  /*
472  //I am doing this because the OnAudit invoker is only used on server-side
473  //Here we want to be able to debug the tracking of career stuff on client-side
474  //since there's no event for it, we need to check periodically until
475  //a local player controller is found
476  if (!m_bLocalEntityListening)
477  {
478  if (m_iInitializingTimer % 100)
479  {
480  ListenToLocalControllerEntityChanged();
481  }
482  m_iInitializingTimer++;
483  }
484  */
485 
486  if (m_bVisualDisplay != DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_DATA_COLLECTION_ENABLE_DIAG))
487  {
488  if (!m_UiHandler)
489  CreateStatVisualizations();
490 
491  m_bVisualDisplay = DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_DATA_COLLECTION_ENABLE_DIAG);
492  m_UiHandler.SetVisible(m_bVisualDisplay);
493  }
494 #endif
495 
496  for (int i = m_aModules.Count() - 1; i >= 0; i--)
497  {
498  m_aModules[i].Update(timeSlice);
499  }
500  }
501 
502  //------------------------------------------------------------------------------------------------
503  protected override void OnPostInit(IEntity owner)
504  {
505  //If there is a data collector instance already, return
506  if (GetGame().GetDataCollector())
507  return;
508 
510 
511  //Register the data collector
512  GetGame().RegisterDataCollector(this);
513 
514  m_Owner = owner;
515  }
516 }
EOnFrame
protected override void EOnFrame(IEntity owner, float timeSlice)
Definition: SCR_DataCollectorComponent.c:465
OnGameEnd
override void OnGameEnd()
When game shuts down, store the profile of every player who hasn't disconnected yet.
Definition: SCR_DataCollectorComponent.c:165
StartDataCollectorSession
void StartDataCollectorSession()
Definition: SCR_DataCollectorComponent.c:424
SCR_BaseGameMode
Definition: SCR_BaseGameMode.c:137
IsMaster
protected bool IsMaster()
Definition: SCR_DataCollectorComponent.c:190
SCR_PlayerController
Definition: SCR_PlayerController.c:31
EntityEditorProps
enum EQueryType EntityEditorProps(category:"GameScripted/Sound", description:"THIS IS THE SCRIPT DESCRIPTION.", color:"0 0 255 255")
Definition: SCR_AmbientSoundsComponent.c:12
AddStatsToFaction
void AddStatsToFaction(FactionKey key, notnull array< float > stats)
Definition: SCR_DataCollectorComponent.c:138
GetPlayers
protected int GetPlayers(out notnull array< int > outPlayers)
Definition: SCR_DataCollectorComponent.c:233
SCR_DataCollectorComponentClass
Definition: SCR_DataCollectorComponent.c:2
OnAIKilled
protected void OnAIKilled(IEntity AIEntity, IEntity killerEntity, notnull Instigator killer)
Definition: SCR_DataCollectorComponent.c:325
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
m_iOptionalKickingPenaltySubtractionPoints
protected int m_iOptionalKickingPenaltySubtractionPoints
Definition: SCR_DataCollectorComponent.c:30
m_bOptionalKicking
protected bool m_bOptionalKicking
Definition: SCR_DataCollectorComponent.c:12
OnPlayerAuditSuccess
protected override void OnPlayerAuditSuccess(int playerId)
Definition: SCR_DataCollectorComponent.c:248
Attribute
SCR_DataCollectorComponentClass SCR_BaseGameModeComponentClass Attribute()] protected ref array< ref SCR_DataCollectorModule > m_aModules
Post-process effect of scripted camera.
OnPlayerConnected
protected override void OnPlayerConnected(int playerId)
Definition: SCR_DataCollectorComponent.c:262
desc
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
Definition: SCR_RespawnBriefingComponent.c:17
SCR_LocalPlayerPenalty
void SCR_LocalPlayerPenalty(int friendlyPlayerKillPenalty, int friendlyAIKillPenalty, int penaltyLimit, int banDuration, int penaltySubtractionPeriod, int penaltySubtractionPoints)
Definition: SCR_LocalPlayerPenalty.c:224
OnGameModeStart
protected override void OnGameModeStart()
Definition: SCR_DataCollectorComponent.c:408
SCR_PlayerData
Definition: SCR_PlayerData.c:2
KickCauseCode
KickCauseCode
Definition: KickCauseCode.c:19
GetPlayerController
proto external PlayerController GetPlayerController()
Definition: SCR_PlayerDeployMenuHandlerComponent.c:307
Instigator
Definition: Instigator.c:6
OnControllableDestroyed
protected override void OnControllableDestroyed(IEntity entity, IEntity killerEntity, notnull Instigator killer)
Definition: SCR_DataCollectorComponent.c:339
m_iOptionalKickingBanDuration
protected int m_iOptionalKickingBanDuration
Definition: SCR_DataCollectorComponent.c:24
GetGameMode
SCR_BaseGameMode GetGameMode()
Definition: SCR_BaseGameModeComponent.c:15
m_mPlayerData
protected ref map< int, ref SCR_PlayerData > m_mPlayerData
Definition: SCR_DataCollectorComponent.c:34
OnPlayerKilled
protected override void OnPlayerKilled(int playerId, IEntity playerEntity, IEntity killerEntity, notnull Instigator killer)
Definition: SCR_DataCollectorComponent.c:313
SCR_GameModeEndData
Definition: SCR_GameModeEndData.c:4
RemovePlayer
protected void RemovePlayer(int playerID)
Definition: SCR_DataCollectorComponent.c:210
GetPlayerData
SCR_PlayerData GetPlayerData(int playerID, bool createNew=true, bool requestFromBackend=true)
Definition: SCR_DataCollectorComponent.c:220
m_iOptionalKickingFriendlyPlayerKillPenalty
protected int m_iOptionalKickingFriendlyPlayerKillPenalty
Definition: SCR_DataCollectorComponent.c:15
OnPostInit
protected override void OnPostInit(IEntity owner)
Called on PostInit when all components are added.
Definition: SCR_DataCollectorComponent.c:503
m_iOptionalKickingFriendlyAIKillPenalty
protected int m_iOptionalKickingFriendlyAIKillPenalty
Definition: SCR_DataCollectorComponent.c:18
m_mFactionScore
protected ref map< FactionKey, ref array< float > > m_mFactionScore
Definition: SCR_DataCollectorComponent.c:40
SCR_DataCollectorUI
Definition: SCR_DataCollectorUI.c:2
GetOwner
IEntity GetOwner()
Owner entity of the fuel tank.
Definition: SCR_FuelNode.c:128
OnPlayerSpawned
protected override void OnPlayerSpawned(int playerId, IEntity controlledEntity)
Definition: SCR_DataCollectorComponent.c:304
DisableModules
protected void DisableModules()
Use this method to disable all the modules.
Definition: SCR_DataCollectorComponent.c:415
Faction
Definition: Faction.c:12
GetAllFactionStats
map< FactionKey, ref array< float > > GetAllFactionStats()
Definition: SCR_DataCollectorComponent.c:129
m_Owner
protected IEntity m_Owner
Definition: SCR_DataCollectorComponent.c:36
m_iOptionalKickingKickPenaltyLimit
protected int m_iOptionalKickingKickPenaltyLimit
Definition: SCR_DataCollectorComponent.c:21
type
EDamageType type
Definition: SCR_DestructibleTreeV2.c:32
data
Get all prefabs that have the spawner data
Definition: SCR_EntityCatalogManagerComponent.c:305
GetDataCollector
SCR_DataCollectorComponent GetDataCollector()
Definition: game.c:90
GetPlayerDataStats
Managed GetPlayerDataStats(int playerID)
Definition: SCR_DataCollectorComponent.c:199
GetFactionStats
array< float > GetFactionStats(FactionKey key)
Definition: SCR_DataCollectorComponent.c:118
m_OptionalKicking
protected ref SCR_LocalPlayerPenalty m_OptionalKicking
Definition: SCR_DataCollectorComponent.c:32
SCR_DebugMenuID
SCR_DebugMenuID
This enum contains all IDs for DiagMenu entries added in script.
Definition: DebugMenuID.c:3
m_UiHandler
protected ref SCR_DataCollectorUI m_UiHandler
Definition: SCR_DataCollectorComponent.c:38
SCR_EGameModeState
SCR_EGameModeState
Definition: SCR_EGameModeState.c:4
PlayerManager
Definition: PlayerManager.c:12
SCR_DataCollectorModule
Definition: SCR_DataCollectorModule.c:2
OnPlayerDisconnected
protected override void OnPlayerDisconnected(int playerId, KickCauseCode cause, int timeout)
Definition: SCR_DataCollectorComponent.c:269
SCR_BaseGameModeComponentClass
Definition: SCR_BaseGameModeComponent.c:2
FindModule
SCR_DataCollectorModule FindModule(typename type)
Definition: SCR_DataCollectorComponent.c:179
OnGameModeEnd
protected override void OnGameModeEnd(SCR_GameModeEndData data)
Definition: SCR_DataCollectorComponent.c:49
m_iOptionalKickingPenaltySubtractionPeriod
protected int m_iOptionalKickingPenaltySubtractionPeriod
Definition: SCR_DataCollectorComponent.c:27
category
params category
Definition: SCR_VehicleDamageManagerComponent.c:180
SCR_BaseGameModeComponent
void SCR_BaseGameModeComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
Definition: SCR_BaseGameModeComponent.c:199