Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_RespawnTimerComponent.c
Go to the documentation of this file.
1 [ComponentEditorProps(category: "GameScripted/GameMode/Components", description: "Handles respawn timers for players.")]
3 {
4 }
5 
6 #define RESPAWN_TIMER_COMPONENT_DEBUG
7 
10 {
11  [Attribute("10", UIWidgets.EditBox, "Default time in seconds that a player has to wait after dead to respawn.", category: "Respawn Timers")]
12  protected float m_fRespawnTime;
13 
17  protected ref map<int, ref SCR_RespawnTimer> m_mRespawnTimers = new map<int, ref SCR_RespawnTimer>();
18 
20  protected RplComponent m_RplComponent;
21 
22  #ifdef RESPAWN_TIMER_COMPONENT_DEBUG
23  protected static bool s_DebugRegistered = false;
24  #endif
25 
26  //------------------------------------------------------------------------------------------------
30  override bool RplSave(ScriptBitWriter writer)
31  {
32  writer.WriteFloat(m_fRespawnTime);
33  writer.WriteInt(m_mRespawnTimers.Count());
34  foreach (int playerId, SCR_RespawnTimer timer : m_mRespawnTimers)
35  {
36  writer.WriteInt(playerId);
37  timer.RplSave(writer);
38  }
39 
40  return true;
41  }
42 
43  //------------------------------------------------------------------------------------------------
47  override bool RplLoad(ScriptBitReader reader)
48  {
49  reader.ReadFloat(m_fRespawnTime);
50 
51  int count;
52  reader.ReadInt(count);
53 
54  for (int i = 0; i < count; i++)
55  {
56  int playerId;
57  reader.ReadInt(playerId);
58 
59  // Create new instance
60  if (!m_mRespawnTimers.Contains(playerId))
61  m_mRespawnTimers.Insert(playerId, new SCR_RespawnTimer());
62 
63  // Load instance data
64  m_mRespawnTimers[playerId].RplLoad(reader);
65  }
66 
67  return true;
68  }
69 
70  //------------------------------------------------------------------------------------------------
72  protected bool IsMaster()
73  {
74  return (!m_RplComponent || m_RplComponent.IsMaster());
75  }
76 
77  //------------------------------------------------------------------------------------------------
79  protected WorldTimestamp GetCurrentTime()
80  {
81  ChimeraWorld world = GetGame().GetWorld();
82  if (!world)
83  return null;
84 
85  return world.GetServerTimestamp();
86  }
87 
88  //------------------------------------------------------------------------------------------------
91  void SetRespawnTime(int playerID, float respawnTime)
92  {
93  // Server only
94  if (!IsMaster())
95  return;
96 
97  // Set duration and replicate to all clients
98  RpcDo_SetDuration_BC(playerID, respawnTime);
99  Rpc(RpcDo_SetDuration_BC, playerID, respawnTime);
100  }
101 
102  //------------------------------------------------------------------------------------------------
105  bool IsPlayerEnqueued(int playerID)
106  {
107  return m_mRespawnTimers.Contains(playerID);
108  }
109 
110  //------------------------------------------------------------------------------------------------
115  bool GetCanPlayerSpawn(int playerID, float additionalTime = 0)
116  {
117  if (!IsPlayerEnqueued(playerID))
118  {
119  Print("Provided playerId: (" + playerID + ") in SCR_RespawnTimerComponent was invalid!", LogLevel.ERROR);
120  return false;
121  }
122 
123  return m_mRespawnTimers[playerID].IsFinished(GetCurrentTime(), additionalTime);
124  }
125 
126  //------------------------------------------------------------------------------------------------
130  int GetPlayerRemainingTime(int playerID, float additionalTime = 0)
131  {
132  if (!m_mRespawnTimers.Contains(playerID))
133  {
134  Print("Provided playerId: (" + playerID + ") in SCR_RespawnTimerComponent was invalid!", LogLevel.ERROR);
135  return false;
136  }
137 
138  float remainingTime = m_mRespawnTimers[playerID].GetRemainingTime(GetCurrentTime(), additionalTime);
139  return Math.Ceil(remainingTime);
140  }
141 
142  //------------------------------------------------------------------------------------------------
148  override void OnPlayerKilled(int playerId, IEntity playerEntity, IEntity killerEntity, notnull Instigator killer)
149  {
150  super.OnPlayerKilled(playerId, playerEntity, killerEntity, killer);
151 
152  // Invalid playerID
153  if (playerId <= 0)
154  return;
155 
156  if (playerEntity.IsDeleted()) //todo(@langepau): remove hack after character event flow rework
157  return;
158 
159  // TODO@AS: Propagate change to owner
160  WorldTimestamp rplTime = GetCurrentTime();
161 
162  // Notify all clients, fire locally
163  RpcDo_StartTimer_BC(playerId, rplTime);
164  Rpc(RpcDo_StartTimer_BC, playerId, rplTime);
165  }
166 
167  //------------------------------------------------------------------------------------------------
168  override void OnPlayerDeleted(int playerId, IEntity player)
169  {
170  OnPlayerKilled(playerId, player, null, Instigator.CreateInstigator(null));
171  }
172 
173  //------------------------------------------------------------------------------------------------
177  [RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
178  private void RpcDo_StartTimer_BC(int playerId, WorldTimestamp rplTime)
179  {
180  m_mRespawnTimers[playerId].Start(rplTime);
181  }
182 
183  //------------------------------------------------------------------------------------------------
187  [RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
188  private void RpcDo_SetDuration_BC(int playerId, float duration)
189  {
190  m_mRespawnTimers[playerId].SetDuration(duration);
191  }
192 
193  //------------------------------------------------------------------------------------------------
196  [RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
197  private void RpcDo_SetDurationAll_BC(float duration)
198  {
199  foreach (SCR_RespawnTimer timer : m_mRespawnTimers)
200  {
201  timer.SetDuration(duration);
202  }
203  }
204 
205  //------------------------------------------------------------------------------------------------
207  override void OnPlayerRegistered(int playerId)
208  {
209  super.OnPlayerRegistered(playerId);
210 
211  // Prepare timer
212  SCR_RespawnTimer respawnTimer = new SCR_RespawnTimer();
213 
214  // For first spawn to be already finished even when time == 0
215  respawnTimer.SetDuration(m_fRespawnTime);
216  WorldTimestamp startTime;
217  startTime = startTime.PlusSeconds(-m_fRespawnTime);
218  respawnTimer.Start(startTime);
219 
220  if (!m_mRespawnTimers.Contains(playerId))
221  m_mRespawnTimers.Insert(playerId, respawnTimer);
222  }
223 
224  //------------------------------------------------------------------------------------------------
226  // TODO: Editor team would like to set respawn time for Factions specific
227  void SetRespawnTime(float respawnTime)
228  {
229  // Set default respawn time value
230  m_fRespawnTime = respawnTime;
231 
232  // Propagate changes to existing timers for both self and all clients
233  RpcDo_SetDurationAll_BC(respawnTime);
234  Rpc(RpcDo_SetDurationAll_BC, respawnTime);
235  }
236 
237  //------------------------------------------------------------------------------------------------
240  {
241  return m_fRespawnTime;
242  }
243 
244 // //------------------------------------------------------------------------------------------------
245 // override void OnPlayerDisconnected(int playerId, KickCauseCode cause, int timeout)
246 // {
247 // super.OnPlayerDisconnected(playerId, cause, timeout);
248 //
249 // // Do nothing for now,
250 // // TODO@AS: If needed, remove unused respawn timers?
251 // }
252 
253  #ifdef RESPAWN_TIMER_COMPONENT_DEBUG
254  protected void DrawDebugInfo()
255  {
256  ArmaReforgerScripted game = GetGame();
257  // Prepare strings to display
258  const string header = "[PlayerID] [PlayerName] [Timer] [IsFinished] [TimerObject]";
259  const string tableFmt = "%1 | %2 | %3 | %4 | %5";
260 
261  // Find local pyl
262  int localId = -1;
263  PlayerController playerController = game.GetPlayerController();
264  if (playerController)
265  localId = playerController.GetPlayerId();
266 
267  DbgUI.Begin("Respawn Timer Component Diag");
268  DbgUI.Text("RplTime: " + GetCurrentTime());
269  DbgUI.Spacer(10);
270  DbgUI.Text(header);
271 
272  WorldTimestamp timeNow = GetCurrentTime();
273  PlayerManager playerManager = GetGame().GetPlayerManager();
274  foreach (int playerId, SCR_RespawnTimer timer : m_mRespawnTimers)
275  {
276  string isFinished = "False";
277  if (timer.IsFinished(timeNow))
278  isFinished = "True";
279 
280  string playerIdentifier = playerId.ToString();
281  string playerName = playerManager.GetPlayerName(playerId);
282  string time = timer.GetRemainingTime(timeNow).ToString();
283  string obj = timer.ToString();
284 
285  // if (playerId == localId)
286  string text = string.Format(tableFmt, playerIdentifier, playerName, time, isFinished, obj);
287  if (playerId == localId)
288  text = " > " + text;
289 
290  DbgUI.Text(text);
291  DbgUI.Spacer(4);
292  }
293 
294  DbgUI.End();
295  }
296  #endif
297 
298  //------------------------------------------------------------------------------------------------
299  override void EOnDiag(IEntity owner, float timeSlice)
300  {
301  super.EOnDiag(owner, timeSlice);
302 
303  #ifdef RESPAWN_TIMER_COMPONENT_DEBUG
304  if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_RESPAWN_TIMER_COMPONENT))
305  {
306  DrawDebugInfo();
307  }
308  #endif
309  }
310 
311  //------------------------------------------------------------------------------------------------
312  override void OnPostInit(IEntity owner)
313  {
314  super.OnPostInit(owner);
315  ConnectToDiagSystem(owner);
316 
317  m_RplComponent = RplComponent.Cast(owner.FindComponent(RplComponent));
318  }
319 
320  //------------------------------------------------------------------------------------------------
321  override void OnDelete(IEntity owner)
322  {
323  DisconnectFromDiagSystem(owner);
324 
325  super.OnDelete(owner);
326  }
327 
328  //------------------------------------------------------------------------------------------------
329  // constructor
333  void SCR_RespawnTimerComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
334  {
335  #ifdef RESPAWN_TIMER_COMPONENT_DEBUG
336  if (!s_DebugRegistered)
337  {
338  DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_RESPAWN_TIMER_COMPONENT, "", "Respawn Timer", "GameMode");
339  s_DebugRegistered = true;
340  }
341  #endif
342  }
343 
344  //------------------------------------------------------------------------------------------------
345  // destructor
347  {
348  #ifdef RESPAWN_TIMER_COMPONENT_DEBUG
349  if (s_DebugRegistered)
350  {
351  DiagMenu.Unregister(SCR_DebugMenuID.DEBUGUI_RESPAWN_TIMER_COMPONENT );
352  s_DebugRegistered = false;
353  }
354  #endif
355  }
356 }
~SCR_RespawnTimerComponent
void ~SCR_RespawnTimerComponent()
Definition: SCR_RespawnTimerComponent.c:346
ComponentEditorProps
SCR_FragmentEntityClass ComponentEditorProps
ChimeraWorld
Definition: ChimeraWorld.c:12
OnPlayerDeleted
override void OnPlayerDeleted(int playerId, IEntity player)
Definition: SCR_RespawnTimerComponent.c:168
RplSave
override bool RplSave(ScriptBitWriter writer)
Definition: SCR_RespawnTimerComponent.c:30
RpcDo_StartTimer_BC
private void RpcDo_StartTimer_BC(int playerId, WorldTimestamp rplTime)
Definition: SCR_RespawnTimerComponent.c:178
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
OnDelete
override void OnDelete(IEntity owner)
Definition: SCR_RespawnTimerComponent.c:321
GetPlayerRemainingTime
int GetPlayerRemainingTime(int playerID, float additionalTime=0)
Definition: SCR_RespawnTimerComponent.c:130
IsPlayerEnqueued
bool IsPlayerEnqueued(int playerID)
Definition: SCR_RespawnTimerComponent.c:105
RpcDo_SetDurationAll_BC
private void RpcDo_SetDurationAll_BC(float duration)
Definition: SCR_RespawnTimerComponent.c:197
RplRpc
SCR_AchievementsHandlerClass ScriptComponentClass RplRpc(RplChannel.Reliable, RplRcver.Owner)] void UnlockOnClient(AchievementId achievement)
Definition: SCR_AchievementsHandler.c:11
Instigator
Definition: Instigator.c:6
GetRespawnTime
float GetRespawnTime()
Definition: SCR_RespawnTimerComponent.c:239
SCR_RespawnTimerComponentClass
Definition: SCR_RespawnTimerComponent.c:2
GetCurrentTime
protected WorldTimestamp GetCurrentTime()
Definition: SCR_RespawnTimerComponent.c:79
DrawDebugInfo
protected void DrawDebugInfo()
Definition: SCR_RespawnTimerComponent.c:254
SCR_RespawnTimerComponent
void SCR_RespawnTimerComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
Definition: SCR_RespawnTimerComponent.c:333
OnPlayerRegistered
override void OnPlayerRegistered(int playerId)
Register provided client's respawn timer.
Definition: SCR_RespawnTimerComponent.c:207
IsMaster
protected bool IsMaster()
Are we the master of this component's RplComponent node?
Definition: SCR_RespawnTimerComponent.c:72
OnPlayerKilled
override void OnPlayerKilled(int playerId, IEntity playerEntity, IEntity killerEntity, notnull Instigator killer)
Definition: SCR_RespawnTimerComponent.c:148
SetRespawnTime
void SetRespawnTime(int playerID, float respawnTime)
Definition: SCR_RespawnTimerComponent.c:91
OnPostInit
override void OnPostInit(IEntity owner)
Editable Mine.
Definition: SCR_RespawnTimerComponent.c:312
RplLoad
override bool RplLoad(ScriptBitReader reader)
Definition: SCR_RespawnTimerComponent.c:47
RpcDo_SetDuration_BC
private void RpcDo_SetDuration_BC(int playerId, float duration)
Definition: SCR_RespawnTimerComponent.c:188
m_mRespawnTimers
protected ref map< int, ref SCR_RespawnTimer > m_mRespawnTimers
Definition: SCR_RespawnTimerComponent.c:17
EOnDiag
override void EOnDiag(IEntity owner, float timeSlice)
Definition: SCR_RespawnTimerComponent.c:299
m_RplComponent
protected RplComponent m_RplComponent
RplComponent attached to this component's owner entity.
Definition: SCR_RespawnTimerComponent.c:20
SCR_RespawnTimer
Definition: SCR_RespawnTimer.c:1
SCR_DebugMenuID
SCR_DebugMenuID
This enum contains all IDs for DiagMenu entries added in script.
Definition: DebugMenuID.c:3
PlayerManager
Definition: PlayerManager.c:12
SCR_BaseGameModeComponentClass
Definition: SCR_BaseGameModeComponent.c:2
Attribute
SCR_RespawnTimerComponentClass SCR_BaseGameModeComponentClass Attribute("10", UIWidgets.EditBox, "Default time in seconds that a player has to wait after dead to respawn.", category:"Respawn Timers")] protected float m_fRespawnTime
Must be attached to a GameMode.
GetCanPlayerSpawn
bool GetCanPlayerSpawn(int playerID, float additionalTime=0)
Definition: SCR_RespawnTimerComponent.c:115
category
params category
Definition: SCR_VehicleDamageManagerComponent.c:180
SCR_BaseGameModeComponent
void SCR_BaseGameModeComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
Definition: SCR_BaseGameModeComponent.c:199