Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_DataCollectorAchievementsModule.c
Go to the documentation of this file.
3 {
4 
5  //------------------------------------------------------------------------------------------------
6  protected override void InitModule()
7  {
8  // Achievement COMBAT_HYGIENE
9  SCR_FlushToilet.GetOnToiletFlushed().Insert(ToiletFlushed);
10 
11  RplComponent rplComp = RplComponent.Cast(GetGame().GetGameMode().FindComponent(RplComponent));
12  if (rplComp.IsMaster())
13  {
14  // Invoke thhose only as authority
15  // Achievement NUTCRACKER
16  SCR_VehicleDamageManagerComponent.GetOnVehicleDestroyed().Insert(VehicleDestroyed);
17  // Achievement TRUCKER_JOE
18  SCR_CampaignNetworkComponent.GetOnSuppliesDelivered().Insert(SuppliesDelivered);
19  // Achievements HELPING_HAND, BATTLEFIELD_ANGEL (Support stations)
20  SCR_SupportStationManagerComponent supportStationManager = SCR_SupportStationManagerComponent.GetInstance();
21  if (supportStationManager)
22  {
23  supportStationManager.GetOnSupportStationExecutedSuccessfully().Insert(OnSupportStationUsed);
24  }
25  }
26 
27  // Achievement MAJOR_PROMOTION
28  SCR_CharacterRankComponent.s_OnRankChanged.Insert(RankedUp);
29 
30  // Achievement MINED_OUT
31  SCR_MineInventoryItemComponent.GetOnMinePlaced().Insert(MinePlaced);
32 
33  // Achievement IVORY_TICKLER || PIPING_UP
34  SCR_PlayInstrument.GetOnInstrumentPlayed().Insert(InstrumentPlayed);
35  }
36 
37  //------------------------------------------------------------------------------------------------
38  protected override void AddInvokers(IEntity player)
39  {
40  // Achievement HELPING_HAND || BATTLEFIELD_ANGEL
41  SCR_ChimeraCharacter chimeraPlayer = SCR_ChimeraCharacter.Cast(player);
42  if (!chimeraPlayer)
43  return;
44 
45  SCR_CharacterControllerComponent characterController = SCR_CharacterControllerComponent.Cast(chimeraPlayer.GetCharacterController());
46  if (!characterController)
47  return;
48 
49  characterController.m_OnItemUseEndedInvoker.Insert(OnItemUsed);
50  }
51 
52  //------------------------------------------------------------------------------------------------
53  protected override void RemoveInvokers(IEntity player)
54  {
55  SCR_ChimeraCharacter chimeraPlayer = SCR_ChimeraCharacter.Cast(player);
56  if (!chimeraPlayer)
57  return;
58 
59  SCR_CharacterControllerComponent characterController = SCR_CharacterControllerComponent.Cast(chimeraPlayer.GetCharacterController());
60  if (!characterController)
61  return;
62 
63  characterController.m_OnItemUseEndedInvoker.Remove(OnItemUsed);
64  }
65 
66  //------------------------------------------------------------------------------------------------
67  //Removing the invokers that do not belong to an entity
68  protected void ~SCR_DataCollectorAchievementsModule()
69  {
70  SCR_FlushToilet.GetOnToiletFlushed().Remove(ToiletFlushed);
71  SCR_VehicleDamageManagerComponent.GetOnVehicleDestroyed().Remove(VehicleDestroyed);
72  SCR_CharacterRankComponent.s_OnRankChanged.Remove(RankedUp);
73  SCR_MineInventoryItemComponent.GetOnMinePlaced().Remove(MinePlaced);
74  SCR_PlayInstrument.GetOnInstrumentPlayed().Remove(InstrumentPlayed);
75  SCR_CampaignNetworkComponent.GetOnSuppliesDelivered().Remove(SuppliesDelivered);
76 
77  SCR_SupportStationManagerComponent supportStationManager = SCR_SupportStationManagerComponent.GetInstance();
78  if (supportStationManager)
79  {
80  supportStationManager.GetOnSupportStationExecutedSuccessfully().Remove(OnSupportStationUsed);
81  }
82  }
83 
84  //------------------------------------------------------------------------------------------------
85  override void OnPlayerKilled(int playerId, IEntity playerEntity, IEntity killerEntity, notnull Instigator killer)
86  {
87  // Only players are counted towards stats & achievements
88  if (killer.GetInstigatorType() != InstigatorType.INSTIGATOR_PLAYER)
89  {
90  return;
91  }
92 
93  const int killerId = killer.GetInstigatorPlayerID();
94 
95  // Self harm doesn't count
96  if (playerId == killerId)
97  {
98  return;
99  }
100 
101  // Handle achievement statistic PLAYER_KILLED (achievement TRUE_GRIT)
102  // Note: PLAYER_KILLED is counted even for friendlies - oopsies makes fun
103  IncrementAchievementProgress(playerId, AchievementStatId.PLAYER_KILLED);
104 
105  // Handle achievement statistic ENEMIES_NEUTRALIZED (achievements ONE_TO_WATCH, ARMY_OF_ONE)
106 
107  // Note: faction less games couldn't count towards achievement, this will need fixing
108  // in case where player could be "kicked" out of the faction - e.g. becoming rogue
109  SCR_FactionManager factionManager = SCR_FactionManager.Cast(GetGame().GetFactionManager());
110  if (!factionManager)
111  {
112  return;
113  }
114 
115  Faction victimFaction = factionManager.GetPlayerFaction(playerId);
116  if (!victimFaction)
117  {
118  return;
119  }
120 
121  Faction killerFaction = factionManager.GetPlayerFaction(killerId);
122  if (!killerFaction)
123  {
124  return;
125  }
126 
127  // Teamkill? - doesn't count
128  if (victimFaction.IsFactionFriendly(killerFaction))
129  {
130  return;
131  }
132 
133  // Increment stat for the killer
134  IncrementAchievementProgress(killerId, AchievementStatId.ENEMIES_NEUTRALIZED);
135  }
136 
137  //------------------------------------------------------------------------------------------------
138  override void OnGameModeEnd()
139  {
140  array<int> players = {};
141  GetGame().GetPlayerManager().GetPlayers(players);
142  int playerCount = players.Count();
143 
144  SCR_GameModeCombatOpsManager combatOps = SCR_GameModeCombatOpsManager.Cast(GetGame().GetGameMode().FindComponent(SCR_GameModeCombatOpsManager));
146 
147  if (!combatOps && !conflict)
148  return;
149 
150  SCR_BaseTaskManager taskManager = GetTaskManager();
151  if (!taskManager)
152  return;
153 
154  array<SCR_BaseTask> activeTasks = {};
155  array<SCR_BaseTask> finishedTasks = {};
156  taskManager.GetTasks(activeTasks);
157  taskManager.GetFinishedTasks(finishedTasks);
158 
159  if (combatOps)
160  {
161  /* Achievement CLEAN_SWEEP || PAPER_PUSHER */
162 
163  if (finishedTasks.Count() > activeTasks.Count())
164  {
165  for(int i = 0; i < playerCount; i++)
166  {
167  CleanSweepCombatOps(players[i]);
168  SecureIntelCombatOps(players[i]);
169  }
170  return;
171  }
172  /* Achievement 008 - meaningless number I cannot deduce */
173  else
174  {
175  //unnecesary if finishedTasks are not nulls
176  bool foundIntel = false;
177  foreach (SCR_BaseTask task : finishedTasks)
178  {
179  //Currently, all tasks on finishedTasks are null
180  //@todo Task system refactor will fix this
181  if (!task)
182  continue;
183 
184  if (task.GetTitle().Contains("Intel"))
185  {
186  foundIntel = true;
187  for(int i = 0; i < playerCount; i++)
188  {
189  SecureIntelCombatOps(players[i]);
190  }
191  break;
192  }
193  }
194 
195  /* Doing this in case finishedTasks tasks are null, which should not happen. @todo fix */
196  if (!foundIntel)
197  {
198  foreach (SCR_BaseTask task : activeTasks)
199  {
200  if (!task)
201  continue;
202 
203  if (task.GetTaskState() == SCR_TaskState.FINISHED && task.GetTitle().Contains("Intel"))
204  {
205  foundIntel = true;
206  for(int i = 0; i < playerCount; i++)
207  {
208  SecureIntelCombatOps(players[i]);
209  }
210  break;
211  }
212  }
213  }
214  /* Achievement 009 - meaningless number */
215  }
216  }
217  else if (conflict && conflict.IsTutorial())
218  {
219  /* Achievement SWEAT_SAVES_BLOOD */
220  if (finishedTasks.Count() >= activeTasks.Count())
221  {
222  for(int i = 0; i < playerCount; i++)
223  {
224  CleanSweepTutorial(players[i]);
225  }
226  return;
227  }
228  /* Achievement SWEAT_SAVES_BLOOD */
229  }
230  }
231 
232  //------------------------------------------------------------------------------------------------
233  protected void OnItemUsed(IEntity item, bool actionCompleted, ItemUseParameters animParams)
234  {
235  // This is invoked for multiple items being used, including mines, but mines are handled separately
236  if (!item || !actionCompleted)
237  {
238  return;
239  }
240 
241  // We are interested only in consumables
242  SCR_ConsumableItemComponent consumableComp = SCR_ConsumableItemComponent.Cast(item.FindComponent(SCR_ConsumableItemComponent));
243  if (!consumableComp)
244  {
245  return;
246  }
247 
248  // We are interested only in medical consumables
249  SCR_EConsumableType consumType = consumableComp.GetConsumableType();
250 
251  // All consumables are medical at this time, but I try to make check, that would skip any newly added consumables
252  // and should produce error, if the existing medical consumable is removed/changed in SCR_EConsumableType
253  // TODO: Turn into something more serious when general "medical" type is available
254  if (consumType != SCR_EConsumableType.BANDAGE &&
255  consumType != SCR_EConsumableType.HEALTH &&
256  consumType != SCR_EConsumableType.TOURNIQUET &&
257  consumType != SCR_EConsumableType.SALINE &&
258  consumType != SCR_EConsumableType.MORPHINE &&
259  consumType != SCR_EConsumableType.MED_KIT)
260  {
261  return;
262  }
263 
264  IEntity userCharacter = consumableComp.GetCharacterOwner();
265  if (!userCharacter)
266  {
267  return;
268  }
269 
270  IEntity targetCharacter = consumableComp.GetTargetCharacter();
271  if (!targetCharacter)
272  {
273  return;
274  }
275 
276  // Self usage doesn't count
277  if (userCharacter == targetCharacter)
278  {
279  return;
280  }
281 
282  // Only player as a user is counted
283  int userPlayerId = GetGame().GetPlayerManager().GetPlayerIdFromControlledEntity(userCharacter);
284  if (userPlayerId == 0)
285  {
286  return;
287  }
288 
289  // Only player as a target is counted
290  int targetPlayerId = GetGame().GetPlayerManager().GetPlayerIdFromControlledEntity(targetCharacter);
291  if (targetPlayerId == 0)
292  {
293  return;
294  }
295 
296  // Tracking for achievements HELPING_HAND, BATTLEFIELD_ANGEL
297  IncrementAchievementProgress(userPlayerId, AchievementStatId.MEDICAL_ASSISTS);
298  }
299 
300  //------------------------------------------------------------------------------------------------
301  protected void OnSupportStationUsed(SCR_BaseSupportStationComponent supportStation, ESupportStationType supportStationType, IEntity actionTarget, IEntity actionUser, SCR_BaseUseSupportStationAction action)
302  {
303  // Achievements are interested only in HEAL type
304  if (supportStationType != ESupportStationType.HEAL)
305  {
306  return;
307  }
308 
309  // Not interested in self aplication
310  if (actionTarget == actionUser)
311  {
312  return;
313  }
314 
315  // Only player as a user is counted
316  int userPlayerId = GetGame().GetPlayerManager().GetPlayerIdFromControlledEntity(actionUser);
317  if (userPlayerId == 0)
318  {
319  return;
320  }
321 
322  // Only player as a target is counted
323  int targetPlayerId = GetGame().GetPlayerManager().GetPlayerIdFromControlledEntity(actionTarget);
324  if (targetPlayerId == 0)
325  {
326  return;
327  }
328 
329  // Increment the stat of HELPING_HAND, BATTLEFIELD_ANGEL achievement
330  IncrementAchievementProgress(userPlayerId, AchievementStatId.MEDICAL_ASSISTS);
331  }
332 
333  //------------------------------------------------------------------------------------------------
334  protected void InstrumentPlayed(int playerId, SCR_EInstrumentType instrumentType)
335  {
336  // Achievement IVORY_TICKLER || PIPING_UP
337 
338  switch (instrumentType)
339  {
340  case SCR_EInstrumentType.PIANO:
341  PianoPlayed(playerId);
342  break;
343  case SCR_EInstrumentType.ORGAN:
344  OrganPlayed(playerId);
345  break;
346  }
347  }
348 
349  //------------------------------------------------------------------------------------------------
350  protected void UnlockAchievement(int playerId, AchievementId achievementId)
351  {
352  PlayerController playerController = GetGame().GetPlayerManager().GetPlayerController(playerId);
353  if (!playerController)
354  return;
355 
356  SCR_AchievementsHandler handler = SCR_AchievementsHandler.Cast(playerController.FindComponent(SCR_AchievementsHandler));
357  if (!handler)
358  return;
359 
360  handler.UnlockAchievement(achievementId);
361  }
362 
363  //------------------------------------------------------------------------------------------------
364  protected void IncrementAchievementProgress(int playerId, AchievementStatId achievementStatId)
365  {
366  PlayerController playerController = GetGame().GetPlayerManager().GetPlayerController(playerId);
367  if (!playerController)
368  return;
369 
370  SCR_AchievementsHandler handler = SCR_AchievementsHandler.Cast(playerController.FindComponent(SCR_AchievementsHandler));
371  if (!handler)
372  return;
373 
374  handler.IncrementAchievementProgress(achievementStatId);
375  }
376 
377  //------------------------------------------------------------------------------------------------
378  protected void ToiletFlushed(int playerId)
379  {
380  // Achievement COMBAT_HYGIENE
381  Print("Player with id " + playerId + " flushed a toilet!", LogLevel.DEBUG);
382  UnlockAchievement(playerId, AchievementId.COMBAT_HYGIENE);
383  }
384 
385  //------------------------------------------------------------------------------------------------
386  protected void VehicleDestroyed(int playerId)
387  {
388  // Achievement NUTCRACKER
389  IncrementAchievementProgress(playerId, AchievementStatId.VEHICLES_DESTROYED);
390  }
391 
392  //------------------------------------------------------------------------------------------------
393  protected void RankedUp(SCR_ECharacterRank prevRank, SCR_ECharacterRank newRank, IEntity playerEntity, bool silent)
394  {
395  // Achievement MAJOR_PROMOTION
396  if (newRank != SCR_ECharacterRank.MAJOR || prevRank > newRank)
397  return;
398 
399  int playerId = GetGame().GetPlayerManager().GetPlayerIdFromControlledEntity(playerEntity);
400  if (playerId <= 0)
401  return;
402 
403  Print("Player with id " + playerId + " ranked up to major!", LogLevel.DEBUG);
404  UnlockAchievement(playerId, AchievementId.MAJOR_PROMOTION);
405  }
406 
407  //------------------------------------------------------------------------------------------------
408  protected void SuppliesDelivered(int playerId, int suppliesDelivered, int totalSuppliesDelivered)
409  {
410  // Achievement TRUCKER_JOE
411  const int TARGET_AMOUNT = 5000;
412 
413  if (totalSuppliesDelivered < TARGET_AMOUNT)
414  return;
415 
416  Print("Player with id " + playerId + " delivered lots of supplies!", LogLevel.DEBUG);
417  UnlockAchievement(playerId, AchievementId.TRUCKER_JOE);
418  }
419 
420  //------------------------------------------------------------------------------------------------
421  protected void CleanSweepCombatOps(int playerId)
422  {
423  // Achievement CLEAN_SWEEP
424  Print("Player with id " + playerId + " cleanswept combat ops!", LogLevel.DEBUG);
425  UnlockAchievement(playerId, AchievementId.CLEAN_SWEEP);
426  }
427 
428  //------------------------------------------------------------------------------------------------
429  protected void SecureIntelCombatOps(int playerId)
430  {
431  // Achievement PAPER_PUSHER
432  Print("Player with id " + playerId + " has secured the intel!", LogLevel.DEBUG);
433  UnlockAchievement(playerId, AchievementId.PAPER_PUSHER);
434  }
435 
436  //------------------------------------------------------------------------------------------------
437  protected void CleanSweepTutorial(int playerId)
438  {
439  //Achievement SWEAT_SAVES_BLOOD
440  Print("Player with id " + playerId + " has cleanswept the tutorial!", LogLevel.DEBUG);
441  UnlockAchievement(playerId, AchievementId.SWEAT_SAVES_BLOOD);
442  }
443 
444  //------------------------------------------------------------------------------------------------
445  protected void MinePlaced(int playerId)
446  {
447  // Achievement MINED_OUT
448  Print("Player with id " + playerId + " placed a mine!", LogLevel.DEBUG);
449  IncrementAchievementProgress(playerId, AchievementStatId.MINES_PLACED);
450  }
451 
452  //------------------------------------------------------------------------------------------------
453  protected void PianoPlayed(int playerId)
454  {
455  // Achievement IVORY_TICKLER
456  Print("Player with id " + playerId + " played a Piano!", LogLevel.DEBUG);
457  UnlockAchievement(playerId, AchievementId.IVORY_TICKLER);
458  }
459 
460  //------------------------------------------------------------------------------------------------
461  protected void OrganPlayed(int playerId)
462  {
463  //Achievement PIPING_UP
464  Print("Player with id " + playerId + " played an Organ!", LogLevel.DEBUG);
465  UnlockAchievement(playerId, AchievementId.PIPING_UP);
466  }
467 };
SCR_EConsumableType
SCR_EConsumableType
Type of consumable gadget.
Definition: SCR_ConsumableEffectBase.c:2
InstigatorType
InstigatorType
Definition: InstigatorType.c:12
BaseContainerProps
SCR_DataCollectorAchievementsModule BaseContainerProps
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
ItemUseParameters
Definition: ItemUseParameters.c:15
SCR_ECharacterRank
SCR_ECharacterRank
Definition: SCR_CharacterRankComponent.c:305
SCR_VehicleDamageManagerComponent
void SCR_VehicleDamageManagerComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
Definition: SCR_VehicleDamageManagerComponent.c:1720
SCR_BaseTask
A base class for tasks.
Definition: SCR_BaseTask.c:8
SCR_CharacterControllerComponent
Definition: SCR_CharacterControllerComponent.c:35
Instigator
Definition: Instigator.c:6
SCR_CharacterRankComponent
void SCR_CharacterRankComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
Definition: SCR_CharacterRankComponent.c:209
GetGameMode
SCR_BaseGameMode GetGameMode()
Definition: SCR_BaseGameModeComponent.c:15
AchievementId
AchievementId
Definition: AchievementId.c:12
SCR_GameModeCampaign
void SCR_GameModeCampaign(IEntitySource src, IEntity parent)
Definition: SCR_GameModeCampaign.c:1927
AchievementStatId
AchievementStatId
Definition: AchievementStatId.c:12
SCR_SupportStationManagerComponent
Definition: SCR_SupportStationManagerComponent.c:10
GetTaskManager
SCR_BaseTaskManager GetTaskManager()
Definition: SCR_BaseTaskManager.c:7
ESupportStationType
ESupportStationType
Definition: ESupportStationType.c:2
SCR_EInstrumentType
SCR_EInstrumentType
Definition: SCR_PlayInstrument.c:89
SCR_BaseTaskManager
Definition: SCR_BaseTaskManager.c:25
SCR_FlushToilet
Definition: SCR_FlushToilet.c:2
Faction
Definition: Faction.c:12
SCR_DataCollectorAchievementsModule
Definition: SCR_DataCollectorAchievementsModule.c:2
SCR_TaskState
SCR_TaskState
Definition: SCR_TaskState.c:2
SCR_FactionManager
void SCR_FactionManager(IEntitySource src, IEntity parent)
Definition: SCR_FactionManager.c:461
SCR_BaseUseSupportStationAction
Definition: SCR_BaseUseSupportStationAction.c:1
SCR_PlayInstrument
Definition: SCR_PlayInstrument.c:2
SCR_DataCollectorModule
Definition: SCR_DataCollectorModule.c:2