Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_BaseScoringSystemComponent.c
Go to the documentation of this file.
2 {
3 }
4 
5 void OnPlayerEventDelegate(int playerId);
7 typedef ScriptInvokerBase<OnPlayerEventDelegate> OnPlayerEventInvoker;
8 
9 void OnPlayerScoreChangedDelegate(int playerId, SCR_ScoreInfo scoreInfo);
11 typedef ScriptInvokerBase<OnPlayerScoreChangedDelegate> OnPlayerScoreChangedInvoker;
12 
13 void OnFactionScoreChangedDelegate(Faction faction, SCR_ScoreInfo scoreInfo);
15 typedef ScriptInvokerBase<OnFactionScoreChangedDelegate> OnFactionScoreChangedInvoker;
16 
27 {
30  protected ref map<int, ref SCR_ScoreInfo> m_mPlayerScores = new map<int, ref SCR_ScoreInfo>();
31 
33  protected ref map<Faction, ref SCR_ScoreInfo> m_mFactionScores = new map<Faction, ref SCR_ScoreInfo>();
34 
36  protected ref OnPlayerScoreChangedInvoker m_OnPlayerScoreChangedInvoker;
37 
38  //------------------------------------------------------------------------------------------------
40  OnPlayerScoreChangedInvoker GetOnPlayerScoreChanged()
41  {
42  if (!m_OnPlayerScoreChangedInvoker)
43  m_OnPlayerScoreChangedInvoker = new OnPlayerScoreChangedInvoker();
44 
45  return m_OnPlayerScoreChangedInvoker;
46  }
47 
49  protected ref OnFactionScoreChangedInvoker m_OnFactionScoreChangedInvoker;
50 
51  //------------------------------------------------------------------------------------------------
53  OnFactionScoreChangedInvoker GetOnFactionScoreChanged()
54  {
55  if (!m_OnFactionScoreChangedInvoker)
56  m_OnFactionScoreChangedInvoker = new OnFactionScoreChangedInvoker();
57 
58  return m_OnFactionScoreChangedInvoker;
59  }
60 
62  protected ref OnPlayerEventInvoker m_OnPlayerAdded;
63 
64  //------------------------------------------------------------------------------------------------
66  OnPlayerEventInvoker GetOnPlayerAdded()
67  {
68  if (!m_OnPlayerAdded)
69  m_OnPlayerAdded = new OnPlayerEventInvoker();
70 
71  return m_OnPlayerAdded;
72  }
73 
75  protected ref OnPlayerEventInvoker m_OnPlayerRemoved;
76 
77  //------------------------------------------------------------------------------------------------
79  OnPlayerEventInvoker GetOnPlayerRemoved()
80  {
81  if (!m_OnPlayerRemoved)
82  m_OnPlayerRemoved = new OnPlayerEventInvoker();
83 
84  return m_OnPlayerRemoved;
85  }
86 
87  //------------------------------------------------------------------------------------------------
91  override bool RplSave(ScriptBitWriter writer)
92  {
93  super.RplSave(writer);
94 
95  int players = m_mPlayerScores.Count();
96  writer.WriteInt(players);
97 
98  foreach (int playerId, SCR_ScoreInfo scoreInfo : m_mPlayerScores)
99  {
100  writer.WriteInt(playerId);
101  scoreInfo.RplSave(writer);
102  }
103 
104  int factions = m_mFactionScores.Count();
105  writer.WriteInt(factions);
106 
107  foreach (Faction faction, SCR_ScoreInfo scoreInfo : m_mFactionScores)
108  {
109  int factionId = GetGame().GetFactionManager().GetFactionIndex(faction);
110  writer.WriteInt(factionId);
111  scoreInfo.RplSave(writer);
112  }
113 
114  return true;
115  }
116 
117  //------------------------------------------------------------------------------------------------
121  override bool RplLoad(ScriptBitReader reader)
122  {
123  super.RplLoad(reader);
124 
125  int players;
126  if (!reader.ReadInt(players))
127  return false;
128 
129  array<int> playerIds = {};
130  array<ref SCR_ScoreInfo> playerScores = {};
131 
132  for (int i = 0; i < players; i++)
133  {
134  int playerId;
135  SCR_ScoreInfo scoreInfo = new SCR_ScoreInfo();
136 
137  if (!reader.ReadInt(playerId))
138  return false;
139 
140  if (!scoreInfo.RplLoad(reader))
141  return false;
142 
143  playerIds.Insert(playerId);
144  playerScores.Insert(scoreInfo);
145  }
146 
147  int factions;
148  if (!reader.ReadInt(factions))
149  return false;
150 
151  array<int> factionIds = {};
152  array<ref SCR_ScoreInfo> factionScores = {};
153 
154  SCR_ScoreInfo scoreInfo;
155  for (int i = 0; i < factions; i++)
156  {
157  int factionId;
158  scoreInfo = new SCR_ScoreInfo();
159 
160  if (!reader.ReadInt(factionId))
161  return false;
162 
163  if (!scoreInfo.RplLoad(reader))
164  return false;
165 
166  factionIds.Insert(factionId);
167  factionScores.Insert(scoreInfo);
168  }
169 
170  // Fill our instance with newly received data
171  m_mPlayerScores.Clear();
172  for (int i = 0; i < players; i++)
173  {
174  m_mPlayerScores.Insert(playerIds[i], playerScores[i]);
175  }
176 
177  FactionManager factionManager = GetGame().GetFactionManager();
178  if (!factionManager)
179  {
180  Print("Score deserialization fail, no FactionManager present in the world, faction scoring will not work properly!", LogLevel.WARNING);
181  return false;
182  }
183 
184  array<Faction> _ = {};
185  int facCnt = factionManager.GetFactionsList(_);
186  m_mFactionScores.Clear();
187  Faction faction;
188  for (int i = 0; i < factions; i++)
189  {
190  int factionIndex = factionIds[i];
191  Print(string.Format("idx=%1, facIdx=%2, facMan=%3, facCnt=%4", i, factionIndex, factionManager, facCnt), LogLevel.NORMAL);
192  faction = factionManager.GetFactionByIndex(factionIndex);
193  m_mFactionScores.Insert(faction, factionScores[i]);
194 
195  }
196 
197  return true;
198  }
199 
200  //------------------------------------------------------------------------------------------------
203  private int GetPlayerFactionIndex(int playerId)
204  {
205  SCR_FactionManager factionManager = SCR_FactionManager.Cast(GetGame().GetFactionManager());
206  if (factionManager)
207  {
208  Faction playerFaction = factionManager.GetPlayerFaction(playerId);
209  return factionManager.GetFactionIndex(playerFaction);
210  }
211 
212  return -1;
213  }
214 
215  //------------------------------------------------------------------------------------------------
218  private Faction GetFactionByIndex(int factionIndex)
219  {
220  if (factionIndex < 0)
221  return null;
222 
223  return GetGame().GetFactionManager().GetFactionByIndex(factionIndex);
224  }
225 
226  //------------------------------------------------------------------------------------------------
229  private int GetFactionIndex(Faction faction)
230  {
231  if (!faction)
232  return -1;
233 
234  return GetGame().GetFactionManager().GetFactionIndex(faction);
235  }
236 
237  //------------------------------------------------------------------------------------------------
238  [RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
239  private void RpcDo_AddKill(int playerId, int factionIdx, int count)
240  {
241  SCR_ScoreInfo playerScore = m_mPlayerScores[playerId];
242  playerScore.m_iKills += count;
243  OnPlayerScoreChanged(playerId, playerScore);
244 
245  Faction faction = GetFactionByIndex(factionIdx);
246  if (faction)
247  {
248  SCR_ScoreInfo factionScore = m_mFactionScores[faction];
249  factionScore.m_iKills += count;
250  OnFactionScoreChanged(faction, factionScore);
251  }
252  }
253 
254  //------------------------------------------------------------------------------------------------
259  void AddKill(int playerId, int count = 1)
260  {
261  // Server only
262  if (!m_pGameMode.IsMaster())
263  return;
264 
265  int factionIdx = GetPlayerFactionIndex(playerId);
266  RpcDo_AddKill(playerId, factionIdx, count);
267  Rpc(RpcDo_AddKill, playerId, factionIdx, count);
268  }
269 
270  //------------------------------------------------------------------------------------------------
271  [RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
272  private void RpcDo_AddDeath(int playerId, int factionIdx, int count)
273  {
274  SCR_ScoreInfo playerScore = m_mPlayerScores[playerId];
275  playerScore.m_iDeaths += count;
276  OnPlayerScoreChanged(playerId, playerScore);
277 
278  Faction faction = GetFactionByIndex(factionIdx);
279  if (faction)
280  {
281  SCR_ScoreInfo factionScore = m_mFactionScores[faction];
282  factionScore.m_iDeaths += count;
283  OnFactionScoreChanged(faction, factionScore);
284  }
285  }
286 
287  //------------------------------------------------------------------------------------------------
292  void AddDeath(int playerId, int count = 1)
293  {
294  // Server only
295  if (!m_pGameMode.IsMaster())
296  return;
297 
298  int factionIdx = GetPlayerFactionIndex(playerId);
299  RpcDo_AddDeath(playerId, factionIdx, count);
300  Rpc(RpcDo_AddDeath, playerId, factionIdx, count);
301  }
302 
303  //------------------------------------------------------------------------------------------------
304  [RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
305  private void RpcDo_AddTeamKill(int playerId, int factionIdx, int count)
306  {
307  SCR_ScoreInfo playerScore = m_mPlayerScores[playerId];
308  playerScore.m_iTeamKills += count;
309  OnPlayerScoreChanged(playerId, playerScore);
310 
311  Faction faction = GetFactionByIndex(factionIdx);
312  if (faction)
313  {
314  SCR_ScoreInfo factionScore = m_mFactionScores[faction];
315  factionScore.m_iTeamKills += count;
316  OnFactionScoreChanged(faction, factionScore);
317  }
318  }
319 
320  //------------------------------------------------------------------------------------------------
325  void AddTeamKill(int playerId, int count = 1)
326  {
327  // Server only
328  if (!m_pGameMode.IsMaster())
329  return;
330 
331  int factionIdx = GetPlayerFactionIndex(playerId);
332  RpcDo_AddTeamKill(playerId, factionIdx, count);
333  Rpc(RpcDo_AddTeamKill, playerId, factionIdx, count);
334  }
335 
336  //------------------------------------------------------------------------------------------------
337  [RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
338  private void RpcDo_AddSuicide(int playerId, int factionIdx, int count)
339  {
340  SCR_ScoreInfo playerScore = m_mPlayerScores[playerId];
341  playerScore.m_iSuicides += count;
342  OnPlayerScoreChanged(playerId, playerScore);
343 
344  Faction faction = GetFactionByIndex(factionIdx);
345  if (faction)
346  {
347  SCR_ScoreInfo factionScore = m_mFactionScores[faction];
348  factionScore.m_iSuicides += count;
349  OnFactionScoreChanged(faction, factionScore);
350  }
351  }
352 
353  //------------------------------------------------------------------------------------------------
358  void AddSuicide(int playerId, int count = 1)
359  {
360  // Server only
361  if (!m_pGameMode.IsMaster())
362  return;
363 
364  int factionIdx = GetPlayerFactionIndex(playerId);
365  RpcDo_AddSuicide(playerId, factionIdx, count);
366  Rpc(RpcDo_AddSuicide, playerId, factionIdx, count);
367  }
368 
369  //------------------------------------------------------------------------------------------------
370  [RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
371  private void RpcDo_AddObjective(int playerId, int factionIdx, int count)
372  {
373  SCR_ScoreInfo playerScore = m_mPlayerScores[playerId];
374  playerScore.m_iObjectives += count;
375  OnPlayerScoreChanged(playerId, playerScore);
376 
377  Faction faction = GetFactionByIndex(factionIdx);
378  if (faction)
379  {
380  SCR_ScoreInfo factionScore = m_mFactionScores[faction];
381  factionScore.m_iObjectives += count;
382  OnFactionScoreChanged(faction, factionScore);
383  }
384  }
385 
386  //------------------------------------------------------------------------------------------------
392  void AddObjective(int playerId, int count = 1, bool addToFaction = true)
393  {
394  // Server only
395  if (!m_pGameMode.IsMaster())
396  return;
397 
398  int factionIdx = -1;
399  if (addToFaction)
400  factionIdx = GetPlayerFactionIndex(playerId);
401 
402  RpcDo_AddObjective(playerId, factionIdx, count);
403  Rpc(RpcDo_AddObjective, playerId, factionIdx, count);
404  }
405 
406  //------------------------------------------------------------------------------------------------
407  [RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
408  private void RpcDo_AddFactionObjective(int factionIdx, int count)
409  {
410  Faction faction = GetFactionByIndex(factionIdx);
411  if (faction)
412  {
413  SCR_ScoreInfo factionScore = m_mFactionScores[faction];
414  factionScore.m_iObjectives += count;
415  OnFactionScoreChanged(faction, factionScore);
416  }
417  }
418 
419  //------------------------------------------------------------------------------------------------
424  void AddFactionObjective(notnull Faction faction, int count = 1)
425  {
426  // Server only
427  if (!m_pGameMode.IsMaster())
428  return;
429 
430  int factionIdx = GetFactionIndex(faction);
431  RpcDo_AddFactionObjective(factionIdx, count);
432  Rpc(RpcDo_AddFactionObjective, factionIdx, count);
433  }
434 
435  //------------------------------------------------------------------------------------------------
439  protected void OnPlayerScoreChanged(int playerId, SCR_ScoreInfo scoreInfo)
440  {
441  if (m_OnPlayerScoreChangedInvoker)
442  m_OnPlayerScoreChangedInvoker.Invoke(playerId, scoreInfo);
443 
444  GameStatsApi statsApi = GetGame().GetStatsApi();
445  if (statsApi)
446  statsApi.PlayerScore(playerId, scoreInfo);
447  }
448 
449  //------------------------------------------------------------------------------------------------
453  protected void OnFactionScoreChanged(Faction faction, SCR_ScoreInfo scoreInfo)
454  {
455  if (m_OnFactionScoreChangedInvoker)
456  m_OnFactionScoreChangedInvoker.Invoke(faction, scoreInfo);
457  }
458 
459  //------------------------------------------------------------------------------------------------
464  protected int CalculateScore(SCR_ScoreInfo info)
465  {
466  int val = (info.m_iKills + info.m_iObjectives) - info.m_iSuicides - info.m_iTeamKills;
467  if (val < 0)
468  return 0;
469 
470  return val;
471  }
472 
473  //------------------------------------------------------------------------------------------------
475  int GetPlayerScore(int playerId)
476  {
477  SCR_ScoreInfo info = GetPlayerScoreInfo(playerId);
478  if (!info)
479  return false;
480 
481  return CalculateScore(info);
482  }
483 
484  //------------------------------------------------------------------------------------------------
486  SCR_ScoreInfo GetPlayerScoreInfo(int playerId)
487  {
488  if (!m_mPlayerScores.Contains(playerId))
489  return null;
490 
491  return m_mPlayerScores[playerId];
492  }
493 
494  //------------------------------------------------------------------------------------------------
496  int GetFactionScore(notnull Faction faction)
497  {
498  SCR_ScoreInfo info = GetFactionScoreInfo(faction);
499  if (!info)
500  return false;
501 
502  return CalculateScore(info);
503  }
504 
505  //------------------------------------------------------------------------------------------------
507  SCR_ScoreInfo GetFactionScoreInfo(notnull Faction faction)
508  {
509  if (!m_mFactionScores.Contains(faction))
510  return null;
511 
512  return m_mFactionScores[faction];
513  }
514 
515  //------------------------------------------------------------------------------------------------
516  override void OnPlayerRegistered(int playerId)
517  {
518  super.OnPlayerRegistered(playerId);
519 
520  // Register player info
521  if (!m_mPlayerScores.Contains(playerId))
522  {
523  SCR_ScoreInfo scoreInfo = new SCR_ScoreInfo();
524  m_mPlayerScores.Insert(playerId, scoreInfo);
525  if (m_OnPlayerScoreChangedInvoker)
526  m_OnPlayerScoreChangedInvoker.Invoke(playerId, scoreInfo);
527  }
528 
529  if (m_OnPlayerAdded)
530  m_OnPlayerAdded.Invoke(playerId);
531  }
532 
533  //------------------------------------------------------------------------------------------------
534  override void OnPlayerDisconnected(int playerId, KickCauseCode cause, int timeout)
535  {
536  super.OnPlayerDisconnected(playerId, cause, timeout);
537 
538  if (m_OnPlayerRemoved)
539  m_OnPlayerRemoved.Invoke(playerId);
540  }
541 
542  //------------------------------------------------------------------------------------------------
543  override void EOnDiag(IEntity owner, float timeSlice)
544  {
545  super.EOnDiag(owner, timeSlice);
546 
547  #ifdef ENABLE_DIAG
548  if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_SCORING_SYSTEM))
549  {
550  string title = Type().ToString() + " Diagnostics";
551  DbgUI.Begin(title);
552  {
553  DbgUI.Text("--Faction Scoring--");
554  string factionFormat = "[%1] Score=%2 || Kills=%3 | Deaths=%4 | TeamKills=%5 | Suicides=%6 | Objectives=%7";
555  foreach (Faction faction, SCR_ScoreInfo scoreInfo : m_mFactionScores)
556  {
557  int score = CalculateScore(scoreInfo);
558  string factionText = string.Format(factionFormat, faction.GetFactionKey(), score, scoreInfo.m_iKills, scoreInfo.m_iDeaths, scoreInfo.m_iTeamKills, scoreInfo.m_iSuicides, scoreInfo.m_iObjectives);
559  DbgUI.Text(factionText);
560  }
561 
562  DbgUI.Text("--Player Scoring--");
563  string playerFormat = "pId=%1: \"%2\" Score=%3 || Kills=%4 | Deaths=%5 | TeamKills=%6 | Suicides=%7 | Objectives=%8";
564  foreach (int playerId, SCR_ScoreInfo scoreInfo : m_mPlayerScores)
565  {
566  string name = GetGame().GetPlayerManager().GetPlayerName(playerId);
567  int score = CalculateScore(scoreInfo);
568  string playerText = string.Format(playerFormat, playerId, name, score, scoreInfo.m_iKills, scoreInfo.m_iDeaths, scoreInfo.m_iTeamKills, scoreInfo.m_iSuicides, scoreInfo.m_iObjectives);
569  DbgUI.Text(playerText);
570  }
571  }
572  DbgUI.End();
573 
574  int targetId = 1;
575  DbgUI.InputInt("Player Id", targetId);
576 
577  int cnt = 1;
578  DbgUI.InputInt("n (count): ", cnt);
579 
580  if (DbgUI.Button("Add n Kills"))
581  AddKill(targetId, cnt);
582  if (DbgUI.Button("Add n Deaths"))
583  AddDeath(targetId, cnt);
584  if (DbgUI.Button("Add n TeamKills"))
585  AddTeamKill(targetId, cnt);
586  if (DbgUI.Button("Add n Suicides"))
587  AddSuicide(targetId, cnt);
588  if (DbgUI.Button("Add n Objectives"))
589  AddObjective(targetId, cnt);
590  if (DbgUI.Button("Add n Faction Objectives (Player Faction Only)"))
591  {
592  int facIdx = GetPlayerFactionIndex(targetId);
593  Faction f = GetFactionByIndex(facIdx);
594  AddFactionObjective(f, cnt);
595  }
596  }
597  #endif
598  }
599 
600  //------------------------------------------------------------------------------------------------
602  int GetScoreLimit()
603  {
604  return -1;
605  }
606 
607  //------------------------------------------------------------------------------------------------
608  override void EOnInit(IEntity owner)
609  {
610  super.EOnInit(owner);
611 
612  FactionManager factionManager = GetGame().GetFactionManager();
613  if (factionManager)
614  {
615  array<Faction> factions = {};
616  factionManager.GetFactionsList(factions);
617 
618  foreach (Faction faction : factions)
619  {
620  m_mFactionScores.Insert(faction, new SCR_ScoreInfo);
621  }
622  }
623 
624  #ifdef ENABLE_DIAG
625  DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_SCORING_SYSTEM, "", "Scoring System", "GameMode");
626  #endif
627  }
628 
629  //------------------------------------------------------------------------------------------------
630  override void OnPostInit(IEntity owner)
631  {
632  super.OnPostInit(owner);
633 
634  SetEventMask(owner, EntityEvent.INIT);
635  #ifdef ENABLE_DIAG
636  ConnectToDiagSystem(owner);
637  #endif
638  }
639 
640  //------------------------------------------------------------------------------------------------
641  override void OnDelete(IEntity owner)
642  {
643  #ifdef ENABLE_DIAG
644  DisconnectFromDiagSystem(owner);
645  #endif
646 
647  super.OnDelete(owner);
648  }
649 }
OnFactionScoreChangedDelegate
func OnFactionScoreChangedDelegate
Definition: SCR_BaseScoringSystemComponent.c:14
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
SCR_BaseScoringSystemComponent
Definition: SCR_BaseScoringSystemComponent.c:26
OnFactionScoreChangedInvoker
ScriptInvokerBase< OnFactionScoreChangedDelegate > OnFactionScoreChangedInvoker
Definition: SCR_BaseScoringSystemComponent.c:15
RplRpc
SCR_AchievementsHandlerClass ScriptComponentClass RplRpc(RplChannel.Reliable, RplRcver.Owner)] void UnlockOnClient(AchievementId achievement)
Definition: SCR_AchievementsHandler.c:11
func
func
Definition: SCR_AIThreatSystem.c:5
KickCauseCode
KickCauseCode
Definition: KickCauseCode.c:19
if
if(!destructionManager) return
OnPlayerScoreChangedInvoker
ScriptInvokerBase< OnPlayerScoreChangedDelegate > OnPlayerScoreChangedInvoker
Definition: SCR_BaseScoringSystemComponent.c:11
OnPlayerEventInvoker
ScriptInvokerBase< OnPlayerEventDelegate > OnPlayerEventInvoker
Definition: SCR_BaseScoringSystemComponent.c:7
m_pGameMode
SCR_BaseGameModeComponentClass m_pGameMode
The game mode entity this component is attached to.
SCR_BaseScoringSystemComponentClass
Definition: SCR_BaseScoringSystemComponent.c:1
SCR_ScoreInfo
Definition: SCR_ScoreInfo.c:6
Faction
Definition: Faction.c:12
GameStatsApi
Statistical Api - Analytics.
Definition: GameStatsApi.c:13
SCR_FactionManager
void SCR_FactionManager(IEntitySource src, IEntity parent)
Definition: SCR_FactionManager.c:461
OnPlayerEventDelegate
func OnPlayerEventDelegate
Definition: SCR_BaseScoringSystemComponent.c:6
SCR_DebugMenuID
SCR_DebugMenuID
This enum contains all IDs for DiagMenu entries added in script.
Definition: DebugMenuID.c:3
SCR_BaseGameModeComponentClass
Definition: SCR_BaseGameModeComponent.c:2
OnPlayerScoreChangedDelegate
func OnPlayerScoreChangedDelegate
Definition: SCR_BaseScoringSystemComponent.c:10
SCR_BaseGameModeComponent
void SCR_BaseGameModeComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
Definition: SCR_BaseGameModeComponent.c:199