Dayz Explorer  1.24.157551 (v105080)
Dayz Code Explorer by Zeroy
staminahandler.c
Go to the documentation of this file.
2 {
3  MASK = 1,
4  FATIGUE,
6  DROWNING,
7 }
8 
9 
16 class StaminaConsumer
17 {
18  protected float m_ActivationThreshold;
19  protected float m_DrainThreshold
20  protected bool m_State;
21 
22  void StaminaConsumer(float threshold, float threshold2, bool state)
23  {
24  m_ActivationThreshold = threshold; //can be activated if above this threshold
25  m_DrainThreshold = threshold2; //can continually drain until it reaches this threshold
26  m_State = state;
27  }
28 
29  bool GetState() { return m_State; }
30  void SetState(bool state) { m_State = state; }
31 
33  void SetActivationThreshold(float threshold) { m_ActivationThreshold = threshold; }
34 
35  float GetDrainThreshold() { return m_DrainThreshold; }
36  void SetDrainThreshold(float threshold) { m_DrainThreshold = threshold; }
37 }
38 
40 {
41  protected ref map<EStaminaConsumers, ref StaminaConsumer> m_StaminaConsumers;
42 
43  void StaminaConsumers()
44  {
46  }
47 
48  void RegisterConsumer(EStaminaConsumers consumer, float threshold, float depletion_threshold = -1)
49  {
50  if (depletion_threshold == -1)
51  {
52  depletion_threshold = threshold;
53  }
54 
55  if ( !m_StaminaConsumers.Contains(consumer) )
56  {
58  StaminaConsumer sc = new StaminaConsumer(threshold, depletion_threshold, true);
59  m_StaminaConsumers.Set(consumer, sc);
60  }
61  }
62 
63  bool HasEnoughStaminaFor(EStaminaConsumers consumer, float curStamina, bool isDepleted, float cap)
64  {
65  if ( m_StaminaConsumers && m_StaminaConsumers.Contains(consumer) )
66  {
67  StaminaConsumer sc = m_StaminaConsumers.Get(consumer);
68 
69  if ( consumer != EStaminaConsumers.SPRINT )
70  {
71  if ( (isDepleted || (curStamina < sc.GetDrainThreshold()/* && curStamina < cap*/)) )
72  {
73  sc.SetState(false);
74  return false;
75  }
76  }
77  else
78  {
79  if ( !isDepleted )
80  {
81  if ( sc.GetState() )
82  {
83  sc.SetState(true);
84  return true;
85  }
86  }
87  else
88  {
89  sc.SetState(false);
90  return false;
91  }
92  }
93 
94  if ( curStamina > sc.GetDrainThreshold() || curStamina == cap ) //Sometimes player can't go up to drain threshold
95  {
96  sc.SetState(true);
97  return true;
98  }
99  }
100 
101  return false;
102  }
103 
104  bool HasEnoughStaminaToStart(EStaminaConsumers consumer, float curStamina, bool isDepleted, float cap)
105  {
106  if ( m_StaminaConsumers && m_StaminaConsumers.Contains(consumer) )
107  {
108  StaminaConsumer sc = m_StaminaConsumers.Get(consumer);
109 
110  if ( (isDepleted || (curStamina < sc.GetActivationThreshold() && curStamina < cap)) )
111  {
112  sc.SetState(false);
113  return false;
114  }
115  else
116  {
117  sc.SetState(true);
118  return true;
119  }
120  }
121 
122  return false;
123  }
124 }
125 
126 
136 {
137  bool m_InUse = false;
138  int m_Type;
140 
141  void StaminaModifier(int type, float min, float max, float cooldown, float startTime = 0, float duration = 0)
142  {
143  m_Type = type;
144  m_MinValue = min;
145  m_MaxValue = max;
146  m_Cooldown = cooldown;
147  m_StartTimeAdjustment = startTime;
148  m_Duration = duration;
149  m_Tick = 1;
150  }
151 
152  int GetType() { return m_Type; }
153 
154  float GetMinValue() { return m_MinValue; }
155  void SetMinValue(float val) { m_MinValue = val; }
156 
157  float GetMaxValue() { return m_MaxValue; }
158  void SetMaxValue(float val) { m_MaxValue = val; }
159 
160  float GetCooldown() { return m_Cooldown; }
161  void SetCooldown(float val) { m_Cooldown = val; }
162 
163  float GetStartTime() { return m_StartTime; } //Actual game time (progressive modifiers only)
164  void SetStartTime(float val) { m_StartTime = val; }
165 
166  float GetStartTimeAdjustment() {return m_StartTimeAdjustment;} //adjustment to current time (progressive modifiers only)
167 
168  float GetDuration() { return m_Duration; }
169  float GetDurationAdjusted() { return m_Duration / m_Tick; }
170 
171  bool IsInUse() { return m_InUse; }
172  void SetInUse(bool val) { m_InUse = val; }
173 
174  float GetRunTime() { return m_ProgressTime; }
175  void AddRunTime(float val) { m_ProgressTime += val; }
176  void SetRunTimeTick(float val) { m_Tick = val; }
178 }
179 
181 {
182  protected ref SMDataExponential m_SMDataEx;
183 
184  float GetBaseValue() { return m_SMDataEx.m_BaseValue; }
185  float GetExponent() { return m_SMDataEx.m_Exponent; }
186  float GetMultiplier() { return m_SMDataEx.m_Multiplier; }
187  override float GetCooldown() { return m_SMDataEx.m_Cooldown; }
188  override float GetStartTimeAdjustment() { return m_SMDataEx.m_StartTimeAdjustment; }
189  override float GetDuration() { return m_SMDataEx.m_Duration; }
190  override float GetDurationAdjusted() { return m_SMDataEx.m_Duration / m_Tick; }
191 
192  void SetData(SMDataExponential data) { m_SMDataEx = data; }
193 }
194 
195 class StaminaModifiers
196 {
197  const int FIXED = 0;
198  const int RANDOMIZED = 1;
199  const int LINEAR = 2; //Useful ONLY for regular, over-time stamina drain
200  const int EXPONENTIAL = 3; //Useful ONLY for regular, over-time stamina drain
201 
203 
205  {
207  }
208 
210  void RegisterFixed(EStaminaModifiers modifier, float value, float cooldown = GameConstants.STAMINA_REGEN_COOLDOWN_DEPLETION)
211  {
212  if ( !m_StaminaModifiers.Contains(modifier) )
213  {
215  StaminaModifier sm = new StaminaModifier(FIXED, -1, value, cooldown);
216  m_StaminaModifiers.Set(modifier, sm);
217  }
218  }
219 
221  void RegisterRandomized(EStaminaModifiers modifier, float minValue, float maxValue, float cooldown = GameConstants.STAMINA_REGEN_COOLDOWN_DEPLETION)
222  {
223  if ( !m_StaminaModifiers.Contains(modifier) )
224  {
226  StaminaModifier sm = new StaminaModifier(RANDOMIZED, minValue, maxValue, cooldown);
227  m_StaminaModifiers.Set(modifier, sm);
228  }
229  }
230 
232  void RegisterLinear(EStaminaModifiers modifier, float startValue, float endValue, float startTime, float duration, float cooldown = GameConstants.STAMINA_REGEN_COOLDOWN_DEPLETION)
233  {
234  StaminaModifier sm = new StaminaModifier(LINEAR, startValue, endValue, cooldown, startTime, duration);
235  m_StaminaModifiers.Set(modifier, sm);
236  }
237 
239  void RegisterExponential(EStaminaModifiers modifier, float startValue, float exponent, float startTime, float duration, float cooldown = GameConstants.STAMINA_REGEN_COOLDOWN_DEPLETION)
240  {
241  StaminaModifier sm = new StaminaModifier(EXPONENTIAL, startValue, exponent, cooldown, startTime, duration);
242  m_StaminaModifiers.Set(modifier, sm);
243  }
244 
246  void RegisterExponentialEx(EStaminaModifiers modifier, SMDataExponential data)
247  {
248  StaminaModifierExponential smex = new StaminaModifierExponential(EXPONENTIAL, data.m_BaseValue, data.m_Exponent, data.m_Cooldown, data.m_StartTimeAdjustment, data.m_Duration);
249  smex.SetData(data);
250  m_StaminaModifiers.Set(modifier, smex);
251  }
252 
254  {
255  return m_StaminaModifiers.Get(modifier);
256  }
257 }
258 
259 
261 {
262  protected float m_PlayerLoad;
263  protected float m_StaminaDelta;
264  protected float m_Stamina;
265  protected float m_StaminaSynced; //guaranteed to be identical on server and client
266  protected float m_StaminaCap;
267  protected float m_StaminaDepletion;
268  protected float m_StaminaDepletionMultiplier; //controls depletion rate
269  protected float m_StaminaRecoveryMultiplier; //controls recovery rate
270  protected float m_Time;
271  protected ref Param3<float,float,bool> m_StaminaParams;
272  protected ref HumanMovementState m_State;
273  protected SHumanCommandMoveSettings m_HumanMoveSettings;
274  protected PlayerBase m_Player;
275 
276  protected bool m_Debug;
277  protected bool m_StaminaDepleted;
278 
279  protected ref map<int,ref Timer> m_TimerMap;
280  ref map<EStaminaMultiplierTypes, float> m_RegisteredDepletionModifiers;
281  ref set<EStaminaMultiplierTypes> m_ActiveDepletionModifiers;
282 
283  ref map<EStaminaMultiplierTypes, float> m_RegisteredRecoveryModifiers;
284  ref set<EStaminaMultiplierTypes> m_ActiveRecoveryModifiers;
285 
286  protected bool m_IsInCooldown;
287 
288  protected ref StaminaConsumers m_StaminaConsumers;
289  protected ref StaminaModifiers m_StaminaModifiers;
290 
291  #ifdef DIAG_DEVELOPER
292  protected bool m_StaminaDisabled;
293  #endif
294 
295  void StaminaHandler(PlayerBase player)
296  {
297  if (GetGame().IsServer() || !GetGame().IsMultiplayer())
298  m_StaminaParams = new Param3<float,float,bool>(0,0, false);
299 
300  m_State = new HumanMovementState();
301  m_Player = player;
302  m_Stamina = CfgGameplayHandler.GetStaminaMax();
303  m_StaminaCap = CfgGameplayHandler.GetStaminaMax();
304  m_StaminaDepletion = 0;
305  m_StaminaDepletionMultiplier = 1;
306  m_StaminaRecoveryMultiplier = 1;
307  m_Time = 0;
308  m_StaminaDepleted = false;
309  m_IsInCooldown = false;
310  m_HumanMoveSettings = m_Player.GetDayZPlayerType().CommandMoveSettingsW();
311 
312  RegisterStaminaConsumers();
313  RegisterStaminaModifiers();
314 
315  m_TimerMap = new map<int,ref Timer>;
316 
317  //----------------- depletion --------------------
318  m_RegisteredDepletionModifiers = new map<EStaminaMultiplierTypes, float>;
319  m_ActiveDepletionModifiers = new set<EStaminaMultiplierTypes>;
320 
321  //----------------- recovery --------------------
322  m_RegisteredRecoveryModifiers = new map<EStaminaMultiplierTypes, float>;
323  m_ActiveRecoveryModifiers = new set<EStaminaMultiplierTypes>;
324 
325  Init();
326  }
327 
328 
329  void Init()
330  {
331  //----------------- depletion --------------------
332  m_RegisteredDepletionModifiers.Insert(EStaminaMultiplierTypes.MASK, MaskMdfr.STAMINA_DEPLETION_MODIFIER);
333  m_RegisteredDepletionModifiers.Insert(EStaminaMultiplierTypes.FATIGUE, FatigueMdfr.STAMINA_DEPLETION_MULTIPLIER);
334  m_RegisteredDepletionModifiers.Insert(EStaminaMultiplierTypes.EPINEPHRINE, EpinephrineMdfr.STAMINA_DEPLETION_MULTIPLIER);
335 
336  //----------------- recovery --------------------
337  m_RegisteredRecoveryModifiers.Insert(EStaminaMultiplierTypes.MASK, MaskMdfr.STAMINA_RECOVERY_MODIFIER);
338  m_RegisteredRecoveryModifiers.Insert(EStaminaMultiplierTypes.FATIGUE, FatigueMdfr.STAMINA_RECOVERY_MULTIPLIER);
339  m_RegisteredRecoveryModifiers.Insert(EStaminaMultiplierTypes.DROWNING, DrowningMdfr.STAMINA_RECOVERY_MULTIPLIER);
340 
341  }
342 
343  void ActivateDepletionModifier(EStaminaMultiplierTypes type)
344  {
345  if (m_RegisteredDepletionModifiers.Contains(type))
346  {
347  m_ActiveDepletionModifiers.Insert(type);
348  RecalculateDepletionMultiplier();
349  }
350  else
351  {
352  Error("attempting to activate unregistered depletion modifier");
353  }
354  }
355 
356  void DeactivateDepletionModifier(EStaminaMultiplierTypes type)
357  {
358  int index = m_ActiveDepletionModifiers.Find(type);
359  if (index != -1)
360  {
361  m_ActiveDepletionModifiers.Remove(index);
362  RecalculateDepletionMultiplier();
363  }
364  }
365 
366  void RecalculateDepletionMultiplier()
367  {
368  float value = 1;
369 
370  foreach (int multiplier: m_ActiveDepletionModifiers)
371  {
372  value *= m_RegisteredDepletionModifiers.Get(multiplier);
373  }
374 
375  if (value != m_StaminaDepletionMultiplier)
376  SetDepletionMultiplier(value);
377  }
378 
379  void ActivateRecoveryModifier(EStaminaMultiplierTypes type)
380  {
381  if (m_RegisteredRecoveryModifiers.Contains(type))
382  {
383  m_ActiveRecoveryModifiers.Insert(type);
384  RecalculateRecoveryMultiplier();
385  }
386  else
387  {
388  Error("attempting to activate unregistered recovery modifier");
389  }
390  }
391 
392 
393  void DeactivateRecoveryModifier(EStaminaMultiplierTypes type)
394  {
395  int index = m_ActiveRecoveryModifiers.Find(type);
396  if (index != -1)
397  {
398  m_ActiveRecoveryModifiers.Remove(index);
399  RecalculateRecoveryMultiplier();
400  }
401  }
402 
403  void RecalculateRecoveryMultiplier()
404  {
405  float value = 1;
406 
407  foreach (int multiplier: m_ActiveRecoveryModifiers)
408  {
409  value *= m_RegisteredRecoveryModifiers.Get(multiplier);
410  }
411 
412  if (value != m_StaminaRecoveryMultiplier)
413  {
414  SetRecoveryMultiplier(value);
415  }
416  }
417 
418  void Update(float deltaT, int pCurrentCommandID)
419  {
420  #ifdef DIAG_DEVELOPER
421  if (m_StaminaDisabled)
422  return;
423  #endif
424  if (m_Player)
425  {
426  // Calculates actual max stamina based on player's load
427  if (GetGame().IsServer() || !GetGame().IsMultiplayer())
428  {
430  m_PlayerLoad = m_Player.GetWeightEx();
431 
433  if (m_PlayerLoad >= CfgGameplayHandler.GetStaminaWeightLimitThreshold())
434  {
435  m_StaminaCap = Math.Max((CfgGameplayHandler.GetStaminaMax() - (((m_PlayerLoad - CfgGameplayHandler.GetStaminaWeightLimitThreshold())/GameConstants.STAMINA_KG_TO_GRAMS) * CfgGameplayHandler.GetStaminaKgToStaminaPercentPenalty())),CfgGameplayHandler.GetStaminaMinCap());
436  }
437  else
438  {
439  m_StaminaCap = CfgGameplayHandler.GetStaminaMax();
440  }
441  }
442 
443  // Calculates stamina gain/loss based on movement and load
444  m_Player.GetMovementState(m_State);
445 
446  switch (m_State.m_CommandTypeId)
447  {
448  case DayZPlayerConstants.COMMANDID_MOVE:
449  StaminaProcessor_Move(m_State);
450  break;
451  case DayZPlayerConstants.COMMANDID_LADDER:
452  StaminaProcessor_Ladder(m_State);
453  break;
454  case DayZPlayerConstants.COMMANDID_SWIM:
455  StaminaProcessor_Swimming(m_State);
456  break;
457  case DayZPlayerConstants.COMMANDID_FALL:
458  case DayZPlayerConstants.COMMANDID_MELEE2:
459  case DayZPlayerConstants.COMMANDID_CLIMB:
460  break;
461  default:
462  if (!m_IsInCooldown)
463  {
464  m_StaminaDelta = GameConstants.STAMINA_GAIN_IDLE_PER_SEC;
465  }
466  break;
467  }
468 
469  //Sets current stamina & stores + syncs data with client
470  float temp = m_StaminaDelta * deltaT;
471  if (temp < 0)
472  {
473  temp *= m_StaminaDepletionMultiplier;
474  }
475  else
476  {
477  temp *= m_StaminaRecoveryMultiplier;
478  }
479 
480  m_Stamina = Math.Max(0, Math.Min((m_Stamina + temp), m_StaminaCap));
481  m_Stamina = m_Stamina - m_StaminaDepletion;
482 
483  if (GetGame().IsServer() || !GetGame().IsMultiplayer())
484  {
485  m_Player.GetStatStamina().Set(m_Stamina);
486  m_Time += deltaT;
487 
488  if (m_Time >= GameConstants.STAMINA_SYNC_RATE)
489  {
490  m_Time = 0;
491  SetStamina(m_Stamina);
492  }
493  }
494 
495  #ifndef SERVER
496  m_Player.SetStamina(m_StaminaSynced, m_StaminaCap);
497  #endif
498 
499  ApplyExhaustion();
500  CheckStaminaState();
501 
502  m_StaminaDelta = 0;
503  m_StaminaDepletion = 0; // resets depletion modifier
504 
505  }
506  }
507 
509  void OnRPC(float stamina, float stamina_cap, bool cooldown)
510  {
511  }
512 
514  void OnSyncJuncture(int pJunctureID, ParamsReadContext pCtx)
515  {
516  switch ( pJunctureID )
517  {
518  case DayZPlayerSyncJunctures.SJ_STAMINA:
519  float stamina;
520  float stamina_cap;
521  bool cooldown;
522 
523  if (!pCtx.Read(stamina) || !pCtx.Read(stamina_cap) || !pCtx.Read(cooldown))
524  {
525  return;
526  }
527 
528  m_Stamina = stamina; //?
529  m_StaminaSynced = stamina;
530 
531  if (m_Player.GetInstanceType() != DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
532  {
533  return;
534  }
535 
536  if ( stamina_cap != m_StaminaCap )
537  {
538  m_StaminaCap = stamina_cap;
539  }
540 
541  m_IsInCooldown = cooldown;
542  m_Player.SetStamina(m_Stamina, m_StaminaCap);
543  break;
544 
545  case DayZPlayerSyncJunctures.SJ_STAMINA_MISC:
546  ReadAdditionalStaminaInfo(pCtx);
547  break;
548  }
549  }
550 
551  protected void StaminaProcessor_Move(HumanMovementState pHumanMovementState)
552  {
553  switch (pHumanMovementState.m_iMovement)
554  {
555  case DayZPlayerConstants.MOVEMENTIDX_SPRINT: //sprint
556  if (pHumanMovementState.m_iStanceIdx == DayZPlayerConstants.STANCEIDX_ERECT)
557  {
558  m_StaminaDelta = -GameConstants.STAMINA_DRAIN_STANDING_SPRINT_PER_SEC * CfgGameplayHandler.GetSprintStaminaModifierErc();
559  SetCooldown(GameConstants.STAMINA_REGEN_COOLDOWN_DEPLETION);
560  break;
561  }
562  else if ( pHumanMovementState.m_iStanceIdx == DayZPlayerConstants.STANCEIDX_CROUCH)
563  {
564  m_StaminaDelta = -GameConstants.STAMINA_DRAIN_CROUCHED_SPRINT_PER_SEC * CfgGameplayHandler.GetSprintStaminaModifierCro();
565  SetCooldown(GameConstants.STAMINA_REGEN_COOLDOWN_DEPLETION);
566  break;
567  }
568 
569  m_StaminaDelta = GameConstants.STAMINA_GAIN_JOG_PER_SEC;
570  break;
571 
572  case DayZPlayerConstants.MOVEMENTIDX_RUN: //jog
573  if (m_Player.GetCurrentWaterLevel() >= m_HumanMoveSettings.m_fWaterLevelSpeedRectrictionHigh)
574  {
575  m_StaminaDelta = -GameConstants.STAMINA_DRAIN_STANDING_SPRINT_PER_SEC * CfgGameplayHandler.GetSprintStaminaModifierErc();
576  break;
577  }
578 
579  if (!m_IsInCooldown)
580  {
581  m_StaminaDelta = (GameConstants.STAMINA_GAIN_JOG_PER_SEC + CalcStaminaGainBonus());
582  }
583  break;
584 
585  case DayZPlayerConstants.MOVEMENTIDX_WALK: //walk
586  if (!m_IsInCooldown)
587  {
588  m_StaminaDelta = (GameConstants.STAMINA_GAIN_WALK_PER_SEC + CalcStaminaGainBonus());
589  }
590  break;
591 
592  case DayZPlayerConstants.MOVEMENTIDX_IDLE: //idle
593  if (m_Player.IsRolling())
594  {
595  m_StaminaDelta = GameConstants.STAMINA_GAIN_ROLL_PER_SEC;
596  break;
597  }
598 
599  if (!m_IsInCooldown)
600  {
601  m_StaminaDelta = (GameConstants.STAMINA_GAIN_IDLE_PER_SEC + CalcStaminaGainBonus());
602  }
603  break;
604 
605  default:
606  if (!m_IsInCooldown)
607  {
608  m_StaminaDelta = GameConstants.STAMINA_GAIN_IDLE_PER_SEC;
609  }
610  break;
611  }
612  }
613 
614  protected void StaminaProcessor_Ladder(HumanMovementState pHumanMovementState)
615  {
616  switch (pHumanMovementState.m_iMovement)
617  {
618  case 2: //climb up (fast)
619  m_StaminaDelta = -GameConstants.STAMINA_DRAIN_LADDER_FAST_PER_SEC * CfgGameplayHandler.GetSprintLadderStaminaModifier();
620  SetCooldown(GameConstants.STAMINA_REGEN_COOLDOWN_DEPLETION);
621  break;
622 
623  case 1: //climb up (slow)
624  if (!m_IsInCooldown)
625  {
626  m_StaminaDelta = (GameConstants.STAMINA_GAIN_LADDER_PER_SEC + CalcStaminaGainBonus());
627  }
628  break;
629 
630  default:
631  if (!m_IsInCooldown)
632  {
633  m_StaminaDelta = GameConstants.STAMINA_GAIN_IDLE_PER_SEC + CalcStaminaGainBonus();
634  }
635  break;
636  }
637  }
638 
639  protected void StaminaProcessor_Swimming(HumanMovementState pHumanMovementState)
640  {
641  switch (pHumanMovementState.m_iMovement)
642  {
643  case 3: //swim fast
644  m_StaminaDelta = -GameConstants.STAMINA_DRAIN_SWIM_FAST_PER_SEC * CfgGameplayHandler.GetSprintSwimmingStaminaModifier();
645  SetCooldown(GameConstants.STAMINA_REGEN_COOLDOWN_DEPLETION);
646  break;
647 
648 
649  case 2: //swim slow
650  if (!m_IsInCooldown)
651  {
652  m_StaminaDelta = (GameConstants.STAMINA_GAIN_SWIM_PER_SEC + CalcStaminaGainBonus());
653  }
654  break;
655 
656  default:
657  if (!m_IsInCooldown)
658  {
659  m_StaminaDelta = GameConstants.STAMINA_GAIN_IDLE_PER_SEC + CalcStaminaGainBonus();
660  }
661  break;
662  }
663  }
664 
666  protected void SyncStamina(float stamina, float stamina_cap, bool cooldown)
667  {
668  m_Player.GetStatStamina().Set(m_Stamina);
670  pCtx.Write(m_Stamina);
671  pCtx.Write(m_StaminaCap);
672  pCtx.Write(m_IsInCooldown);
673  m_Player.SendSyncJuncture(DayZPlayerSyncJunctures.SJ_STAMINA,pCtx);
674  }
675 
677  protected void SyncAdditionalStaminaInfo(Param par)
678  {
680 
682  pCtx.Write(p.param1);
683  pCtx.Write(p.param2);
684  m_Player.SendSyncJuncture(DayZPlayerSyncJunctures.SJ_STAMINA_MISC,pCtx);
685  }
686 
688  protected void ReadAdditionalStaminaInfo(ParamsReadContext pCtx)
689  {
690  float depletionMultiplier;
691  float recoveryMultiplier;
692  if (!pCtx.Read(depletionMultiplier) || !pCtx.Read(recoveryMultiplier))
693  {
694  return;
695  }
696 
697  m_StaminaDepletionMultiplier = depletionMultiplier;
698  m_StaminaRecoveryMultiplier = recoveryMultiplier;
699  }
700 
701  protected void RegisterStaminaConsumers()
702  {
704 
705  m_StaminaConsumers.RegisterConsumer(
706  EStaminaConsumers.HOLD_BREATH,
707  GameConstants.STAMINA_HOLD_BREATH_THRESHOLD_ACTIVATE,
708  GameConstants.STAMINA_HOLD_BREATH_THRESHOLD_DRAIN,
709  );
710  m_StaminaConsumers.RegisterConsumer(
711  EStaminaConsumers.SPRINT,
712  CfgGameplayHandler.GetStaminaMinCap() + 15,
713  );
714  m_StaminaConsumers.RegisterConsumer(
715  EStaminaConsumers.JUMP,
716  GameConstants.STAMINA_JUMP_THRESHOLD,
717  );
718  m_StaminaConsumers.RegisterConsumer(
719  EStaminaConsumers.VAULT,
720  GameConstants.STAMINA_VAULT_THRESHOLD,
721  );
722  m_StaminaConsumers.RegisterConsumer(
723  EStaminaConsumers.CLIMB,
724  GameConstants.STAMINA_CLIMB_THRESHOLD,
725  );
726  m_StaminaConsumers.RegisterConsumer(
727  EStaminaConsumers.MELEE_HEAVY,
728  GameConstants.STAMINA_MELEE_HEAVY_THRESHOLD,
729  );
730  m_StaminaConsumers.RegisterConsumer(
731  EStaminaConsumers.MELEE_EVADE,
732  GameConstants.STAMINA_MELEE_EVADE_THRESHOLD,
733  );
734  m_StaminaConsumers.RegisterConsumer(
735  EStaminaConsumers.ROLL,
736  GameConstants.STAMINA_ROLL_THRESHOLD,
737  );
738  m_StaminaConsumers.RegisterConsumer(EStaminaConsumers.DROWN, 0);
739  m_StaminaConsumers.RegisterConsumer(EStaminaConsumers.PUSH, 0);
740  }
741 
742  protected void RegisterStaminaModifiers()
743  {
745 
746  SMDataHoldBreath data = new SMDataHoldBreath();
747  m_StaminaModifiers.RegisterExponentialEx(
748  EStaminaModifiers.HOLD_BREATH,
749  data,
750  );
751  m_StaminaModifiers.RegisterExponentialEx(
752  EStaminaModifiers.PUSH_CAR,
753  data,
754  );
755  m_StaminaModifiers.RegisterFixed(EStaminaModifiers.DROWN, 10);
756  m_StaminaModifiers.RegisterFixed(
757  EStaminaModifiers.JUMP,
758  GameConstants.STAMINA_DRAIN_JUMP * CfgGameplayHandler.GetObstacleTraversalStaminaModifier(),
759  );
760  m_StaminaModifiers.RegisterFixed(
761  EStaminaModifiers.VAULT,
762  GameConstants.STAMINA_DRAIN_VAULT * CfgGameplayHandler.GetObstacleTraversalStaminaModifier(),
763  );
764  m_StaminaModifiers.RegisterFixed(
765  EStaminaModifiers.CLIMB,
766  GameConstants.STAMINA_DRAIN_CLIMB * CfgGameplayHandler.GetObstacleTraversalStaminaModifier(),
767  );
768  m_StaminaModifiers.RegisterFixed(
769  EStaminaModifiers.MELEE_LIGHT,
770  GameConstants.STAMINA_DRAIN_MELEE_LIGHT * CfgGameplayHandler.GetMeleeStaminaModifier(),
771  );
772  m_StaminaModifiers.RegisterFixed(
773  EStaminaModifiers.MELEE_HEAVY,
774  GameConstants.STAMINA_DRAIN_MELEE_HEAVY * CfgGameplayHandler.GetMeleeStaminaModifier(),
775  );
776  m_StaminaModifiers.RegisterFixed(
777  EStaminaModifiers.OVERALL_DRAIN,
778  CfgGameplayHandler.GetStaminaMax(),
779  5.0,
780  );
781  m_StaminaModifiers.RegisterRandomized(
782  EStaminaModifiers.MELEE_EVADE,
783  3 * CfgGameplayHandler.GetMeleeStaminaModifier(),
784  GameConstants.STAMINA_DRAIN_MELEE_EVADE * CfgGameplayHandler.GetMeleeStaminaModifier(),
785  );
786  m_StaminaModifiers.RegisterFixed(EStaminaModifiers.ROLL, GameConstants.STAMINA_DRAIN_ROLL);
787  }
788 
790  protected float CalcStaminaGainBonus()
791  {
792  if (m_StaminaDepletion > 0)
793  return 0;
794 
795  if (m_Stamina > 25)
796  return Math.Min((m_Stamina/10),GameConstants.STAMINA_GAIN_BONUS_CAP); // exp version
797  else
798  return GameConstants.STAMINA_GAIN_BONUS_CAP; // linear version
799  }
800 
801  protected void ApplyExhaustion()
802  {
804  HumanCommandAdditives ad = m_Player.GetCommandModifier_Additives();
805 
806  float exhaustion_value = 1;
807  if (m_StaminaCap != 0)
808  {
809  exhaustion_value = 1 - ((m_Stamina / (m_StaminaCap * 0.01)) * 0.01);
810  }
811 
812  exhaustion_value = Math.Min(1, exhaustion_value);
813  if (ad)
814  {
815  // do not apply exhaustion on local client if player is in ADS/Optics (camera shakes)
816  if (m_Player.GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT && (m_Player.IsInOptics() || m_Player.IsInIronsights()))
817  {
818  ad.SetExhaustion(0, true);
819  }
820  else
821  {
822  ad.SetExhaustion(exhaustion_value, true);
823  }
824  }
825  }
826 
828  protected void CheckStaminaState()
829  {
830  if (m_Stamina <= 0)
831  {
832  m_StaminaDepleted = true;
834  if (!m_IsInCooldown)
835  {
836  // set this only once
837  SetCooldown(GameConstants.STAMINA_REGEN_COOLDOWN_EXHAUSTION);
838  }
839  }
840  else
841  {
842  m_StaminaDepleted = false;
843  }
844  }
845 
847  protected void SetCooldown(float time, int modifier = -1)
848  {
849  if ( m_StaminaDepleted || m_Stamina <= 0.0 )
850  {
851  ResetCooldown(modifier);
852  return;
853  }
854 
855  m_IsInCooldown = true;
856 
857  Timer timer;
858  if (m_TimerMap.Find(modifier, timer) && timer.IsRunning())
859  {
860  timer.Stop();
861  }
862  else
863  {
864  timer = new ref Timer;
865  m_TimerMap.Set(modifier,timer);
866  }
867  timer.Run(time, this, "ResetCooldown", new Param1<int>( modifier ));
868  //Print(m_TimerMap.Count());
869  }
870 
871  protected void ResetCooldown(int modifier = -1)
872  {
873  StaminaModifier sm = m_StaminaModifiers.GetModifierData(modifier);
874  if (sm)
875  {
876  //Print(modifier);
877  //Error("Error: No StaminaModifier found! | StaminaHandler | ResetCooldown");
878  sm.SetStartTime(-1);
879  sm.ResetRunTime();
880  sm.SetInUse(false);
881  }
882  m_IsInCooldown = false;
883  }
884 
885  Timer GetCooldownTimer(int modifier)
886  {
887 
888  }
889 
890  // ---------------------------------------------------
891  bool HasEnoughStaminaFor(EStaminaConsumers consumer)
892  {
893  return m_StaminaConsumers.HasEnoughStaminaFor(consumer, m_Stamina, m_StaminaDepleted, m_StaminaCap);
894  }
895 
896  bool HasEnoughStaminaToStart(EStaminaConsumers consumer)
897  {
898  return m_StaminaConsumers.HasEnoughStaminaToStart(consumer, m_Stamina, m_StaminaDepleted, m_StaminaCap);
899  }
900 
901  void SetStamina(float stamina_value)
902  {
903  m_Stamina = Math.Clamp(stamina_value, 0, CfgGameplayHandler.GetStaminaMax());
904  SyncStamina(m_Stamina, m_StaminaCap, m_IsInCooldown);
905  }
906 
907  float GetStamina()
908  {
909  return m_Stamina;
910  }
911 
912  float GetStaminaNormalized()
913  {
914  return m_Stamina / GetStaminaMax();
915  }
916 
917  float GetSyncedStamina()
918  {
919  return m_StaminaSynced;
920  }
921 
922  float GetSyncedStaminaNormalized()
923  {
924  return GetSyncedStamina() / GetStaminaMax();
925  }
926 
927  float GetStaminaCap()
928  {
929  return m_StaminaCap;
930  }
931 
932  float GetStaminaMax()
933  {
934  return CfgGameplayHandler.GetStaminaMax();
935  }
936 
937  //obsolete, use ActivateDepletionModifier/DeactivateDepletionModifier instead
938  void SetDepletionMultiplier(float val)
939  {
940  if (m_StaminaDepletionMultiplier < 0)
941  m_StaminaDepletionMultiplier = 0;
942  m_StaminaDepletionMultiplier = val;
943  SyncAdditionalStaminaInfo(new Param2<float,float>(m_StaminaDepletionMultiplier,m_StaminaRecoveryMultiplier));
944  }
945  //obsolete, use ActivateRecoveryModifier/DeactivateRecoveryModifier instead
946  void SetRecoveryMultiplier(float val)
947  {
948  if (m_StaminaRecoveryMultiplier < 0)
949  m_StaminaRecoveryMultiplier = 0;
950  m_StaminaRecoveryMultiplier = val;
951  SyncAdditionalStaminaInfo(new Param2<float,float>(m_StaminaDepletionMultiplier,m_StaminaRecoveryMultiplier));
952  }
953 
954  float GetDepletionMultiplier()
955  {
956  return m_StaminaDepletionMultiplier;
957  }
958 
959  float GetRecoveryMultiplier()
960  {
961  return m_StaminaRecoveryMultiplier;
962  }
963 
964  void DepleteStamina(EStaminaModifiers modifier, float dT = -1)
965  {
966  #ifdef DIAG_DEVELOPER
967  if (m_StaminaDisabled)
968  return;
969  #endif
970  float val = 0.0;
971  float current_time = m_Player.GetSimulationTimeStamp();
972  float valueProgress;
973  StaminaModifier sm = m_StaminaModifiers.GetModifierData(modifier);
974 
975  // select by modifier type and drain stamina
976  switch (sm.GetType())
977  {
978  case m_StaminaModifiers.FIXED:
979  if (dT == -1)
980  {
981  dT = 1;
982  }
983  m_StaminaDepletion = m_StaminaDepletion + sm.GetMaxValue() * dT;
984 
985  break;
986 
987  case m_StaminaModifiers.RANDOMIZED:
988  val = Math.RandomFloat(sm.GetMinValue(), sm.GetMaxValue());
989  m_StaminaDepletion = m_StaminaDepletion + val;
990 
991  break;
992 
993  case m_StaminaModifiers.LINEAR:
994  if (!sm.IsInUse())
995  {
996  sm.SetStartTime(current_time + sm.GetStartTimeAdjustment()/dT);
997  sm.SetRunTimeTick(dT);
998  sm.SetInUse(true);
999  }
1000  valueProgress = Math.Clamp((current_time - sm.GetStartTime())/sm.GetDurationAdjusted(), 0, 1 );
1001  val = Math.Lerp(sm.GetMinValue(), sm.GetMaxValue(), valueProgress);
1002  m_StaminaDepletion = m_StaminaDepletion + val;
1003 
1004  break;
1005 
1006  case m_StaminaModifiers.EXPONENTIAL:
1008  if (!Class.CastTo(smex,sm))
1009  {
1010  ErrorEx("StaminaModifierExponential not found for modifier type: " + sm.GetType());
1011  break;
1012  }
1013 
1014  if (!smex.IsInUse())
1015  {
1016  smex.SetStartTime(current_time + smex.GetStartTimeAdjustment()/dT);
1017  smex.SetRunTimeTick(dT);
1018  smex.SetInUse(true);
1019  }
1020  valueProgress = Math.Clamp((current_time - smex.GetStartTime())/smex.GetDurationAdjusted(), 0, 1 );
1021  float exp;
1022  if (Math.AbsFloat(smex.GetBaseValue()) < 1)
1023  {
1024  exp = 1 - Math.Lerp(0, smex.GetExponent(), valueProgress);
1025  val = Math.Pow(smex.GetBaseValue(),exp);
1026  }
1027  else
1028  {
1029  exp = Math.Lerp(Math.Min(0, smex.GetExponent()), Math.Max(0, smex.GetExponent()), valueProgress);
1030  val = Math.Pow(smex.GetBaseValue(),exp) + smex.GetBaseValue() - 1;
1031  }
1032 
1033  m_StaminaDepletion = m_StaminaDepletion + val;
1034  m_StaminaDepletion *= smex.GetMultiplier();
1035 
1036  break;
1037  }
1038 
1040  SetCooldown(sm.GetCooldown(),modifier);
1041  m_StaminaDepletion = Math.Clamp(m_StaminaDepletion, 0, CfgGameplayHandler.GetStaminaMax());
1042 
1043  m_StaminaDepletion = m_StaminaDepletion * m_StaminaDepletionMultiplier;
1044  }
1045 
1046  #ifdef DIAG_DEVELOPER
1047  void SetStaminaDisabled(bool value)
1048  {
1049  m_StaminaDisabled = value;
1050  }
1051  #endif
1052 }
Param2< float, float >
GetGame
proto native CGame GetGame()
SetCooldown
void SetCooldown(float val)
Definition: staminahandler.c:161
StaminaModifierExponential
Definition: staminahandler.c:180
m_Time
protected float m_Time
Definition: carscript.c:146
HumanCommandAdditives
class HumanCommandWeapons HumanCommandAdditives()
Definition: human.c:1099
Error
void Error(string err)
Messagebox with error message.
Definition: endebug.c:90
StaminaModifier
void StaminaModifier(int type, float min, float max, float cooldown, float startTime=0, float duration=0)
Definition: staminahandler.c:141
StaminaModifiers
void StaminaModifiers()
Definition: staminahandler.c:204
RegisterExponential
void RegisterExponential(EStaminaModifiers modifier, float startValue, float exponent, float startTime, float duration, float cooldown=GameConstants.STAMINA_REGEN_COOLDOWN_DEPLETION)
register exponential modifier - depletes stamina for startValue, and, after a startTime,...
Definition: staminahandler.c:239
Param
Base Param Class with no parameters. Used as general purpose parameter overloaded with Param1 to Para...
Definition: param.c:11
m_Duration
float m_Duration
Definition: staminahandler.c:139
MASK
MASK
Definition: staminahandler.c:11
m_StaminaModifiers
protected ref map< EStaminaModifiers, ref StaminaModifier > m_StaminaModifiers
Definition: staminahandler.c:202
MaskMdfr
Definition: mask.c:1
GetStartTimeAdjustment
float GetStartTimeAdjustment()
Definition: staminahandler.c:166
SetStartTime
void SetStartTime(float val)
Definition: staminahandler.c:164
EStaminaModifiers
EStaminaModifiers
Definition: estaminamodifiers.c:1
GetMinValue
float GetMinValue()
Definition: staminahandler.c:154
LINEAR
const int LINEAR
Definition: staminahandler.c:199
IsInUse
bool IsInUse()
Definition: staminahandler.c:171
SetDrainThreshold
void SetDrainThreshold(float threshold)
Definition: staminahandler.c:36
GetActivationThreshold
float GetActivationThreshold()
Definition: staminahandler.c:32
GetMaxValue
float GetMaxValue()
Definition: staminahandler.c:157
m_MinValue
float m_MinValue
Definition: staminahandler.c:139
StaminaHandler
Definition: staminahandler.c:260
m_ProgressTime
float m_ProgressTime
Definition: staminahandler.c:139
EpinephrineMdfr
Definition: epinephrinemdfr.c:1
StaminaConsumers
void StaminaConsumers()
Definition: staminahandler.c:130
EStaminaMultiplierTypes
EStaminaMultiplierTypes
Definition: staminahandler.c:1
Param3< float, float, bool >
RegisterRandomized
void RegisterRandomized(EStaminaModifiers modifier, float minValue, float maxValue, float cooldown=GameConstants.STAMINA_REGEN_COOLDOWN_DEPLETION)
register randomized modifier - stamina will be depleted by value between min and max value;
Definition: staminahandler.c:221
GetModifierData
StaminaModifier GetModifierData(EStaminaModifiers modifier)
Definition: staminahandler.c:253
SHumanCommandMoveSettings
class SHumanGlobalSettings SHumanCommandMoveSettings()
Definition: humansettings.c:12
ScriptJunctureData
Definition: gameplay.c:150
ErrorEx
enum ShapeType ErrorEx
SetInUse
void SetInUse(bool val)
Definition: staminahandler.c:172
HumanMovementState
Definition: human.c:1125
DrowningMdfr
Definition: drowning.c:1
m_StartTimeAdjustment
float m_StartTimeAdjustment
Definition: staminahandler.c:139
Serializer
Serialization general interface. Serializer API works with:
Definition: serializer.c:55
SetRunTimeTick
void SetRunTimeTick(float val)
Definition: staminahandler.c:176
SetActivationThreshold
void SetActivationThreshold(float threshold)
Definition: staminahandler.c:33
SMDataHoldBreath
Definition: staminamodifierdata.c:41
SetMinValue
void SetMinValue(float val)
Definition: staminahandler.c:155
PlayerBase
Definition: playerbaseclient.c:1
map
map
Definition: controlsxboxnew.c:3
m_StaminaConsumers
protected ref map< EStaminaConsumers, ref StaminaConsumer > m_StaminaConsumers
Definition: staminahandler.c:128
SetState
void SetState(bool state)
Definition: staminahandler.c:30
EStaminaConsumers
EStaminaConsumers
Definition: estaminaconsumers.c:1
RegisterFixed
void RegisterFixed(EStaminaModifiers modifier, float value, float cooldown=GameConstants.STAMINA_REGEN_COOLDOWN_DEPLETION)
register single value modifier - depletes stamina for that value
Definition: staminahandler.c:210
GetDrainThreshold
float GetDrainThreshold()
Definition: staminahandler.c:35
EPINEPHRINE
EPINEPHRINE
Definition: staminahandler.c:13
DayZPlayerConstants
DayZPlayerConstants
defined in C++
Definition: dayzplayer.c:601
SetMaxValue
void SetMaxValue(float val)
Definition: staminahandler.c:158
FIXED
StaminaModifierExponential FIXED
m_Tick
float m_Tick
Definition: staminahandler.c:139
GetType
int GetType()
Definition: staminahandler.c:152
m_Player
DayZPlayer m_Player
Definition: hand_events.c:42
DROWNING
DROWNING
Definition: staminahandler.c:14
GetDuration
float GetDuration()
Definition: staminahandler.c:168
DayZPlayerSyncJunctures
Definition: dayzplayersyncjunctures.c:4
GetState
bool GetState()
returns one of STATE_...
Definition: staminahandler.c:29
CfgGameplayHandler
Definition: cfggameplayhandler.c:1
m_StartTime
float m_StartTime
Definition: staminahandler.c:139
AddRunTime
void AddRunTime(float val)
Definition: staminahandler.c:175
m_Stamina
class StaminaSoundHandlerBase extends SoundHandlerBase m_Stamina
RegisterLinear
void RegisterLinear(EStaminaModifiers modifier, float startValue, float endValue, float startTime, float duration, float cooldown=GameConstants.STAMINA_REGEN_COOLDOWN_DEPLETION)
register lerped modifier - depletes stamina for startValue, and, after a startTime,...
Definition: staminahandler.c:232
GameConstants
Definition: constants.c:612
m_MaxValue
float m_MaxValue
Definition: staminahandler.c:139
Timer
Definition: dayzplayerimplement.c:62
m_ActivationThreshold
m_ActivationThreshold
ResetRunTime
void ResetRunTime()
Definition: staminahandler.c:177
FatigueMdfr
Definition: fatigue.c:1
StaminaConsumers
Definition: staminahandler.c:39
GetRunTime
float GetRunTime()
Definition: staminahandler.c:174
RANDOMIZED
const int RANDOMIZED
Definition: staminahandler.c:198
Math
Definition: enmath.c:6
Class
Super root of all classes in Enforce script.
Definition: enscript.c:10
m_Cooldown
float m_Cooldown
Definition: staminahandler.c:139
m_Multiplier
float m_Multiplier
Definition: staminahandler.c:139
GetStartTime
float GetStartTime()
Definition: staminahandler.c:163
EXPONENTIAL
const int EXPONENTIAL
Definition: staminahandler.c:200
m_InUse
m_InUse
m_State
protected float m_DrainThreshold protected bool m_State
Definition: staminahandler.c:20
StaminaConsumer
void StaminaConsumer(float threshold, float threshold2, bool state)
Definition: staminahandler.c:22
RegisterExponentialEx
void RegisterExponentialEx(EStaminaModifiers modifier, SMDataExponential data)
register exponential modifier, extended parameters
Definition: staminahandler.c:246
GetCooldown
float GetCooldown()
Definition: staminahandler.c:160
GetDurationAdjusted
float GetDurationAdjusted()
Definition: staminahandler.c:169
FATIGUE
FATIGUE
Definition: staminahandler.c:12
m_Type
int m_Type
Definition: staminahandler.c:138
DayZPlayerInstanceType
DayZPlayerInstanceType
defined in C++
Definition: dayzplayer.c:1058