Dayz Build 1.29.163047, Scripts Rev. 123548
Dayz Code Explorer by Zeroy
Loading...
Searching...
No Matches
staminahandler.c
Go to the documentation of this file.
10
11
12/**@class Stamina Consumer
13 * @brief Holds information about Stamina Consumer
14 *
15 * @param[in] threshold value needed to allow consume stamina
16 * @param[in] state keeps state of the consumer non-depleted/depleted
17 */
19{
20 protected float m_ActivationThreshold;
21 protected float m_DrainThreshold
22 protected bool m_State;
23
24 void StaminaConsumer(float threshold, float threshold2, bool state)
25 {
26 m_ActivationThreshold = threshold; //can be activated if above this threshold
27 m_DrainThreshold = threshold2; //can continually drain until it reaches this threshold
28 m_State = state;
29 }
30
31 bool GetState() { return m_State; }
32 void SetState(bool state) { m_State = state; }
33
35 void SetActivationThreshold(float threshold) { m_ActivationThreshold = threshold; }
36
37 float GetDrainThreshold() { return m_DrainThreshold; }
38 void SetDrainThreshold(float threshold) { m_DrainThreshold = threshold; }
39}
40
42{
44
49
50 void RegisterConsumer(EStaminaConsumers consumer, float threshold, float depletion_threshold = -1)
51 {
52 if (depletion_threshold == -1)
53 {
54 depletion_threshold = threshold;
55 }
56
57 if ( !m_StaminaConsumers.Contains(consumer) )
58 {
60 StaminaConsumer sc = new StaminaConsumer(threshold, depletion_threshold, true);
61 m_StaminaConsumers.Set(consumer, sc);
62 }
63 }
64
65 bool HasEnoughStaminaFor(EStaminaConsumers consumer, float curStamina, bool isDepleted, float cap)
66 {
68 if (m_StaminaConsumers && m_StaminaConsumers.Find(consumer, sc))
69 {
70 if (consumer != EStaminaConsumers.SPRINT)
71 {
72 if (isDepleted || (curStamina < sc.GetDrainThreshold()))
73 {
74 sc.SetState(false);
75 return false;
76 }
77 }
78 else
79 {
80 if (!isDepleted)
81 {
82 if (sc.GetState())
83 {
84 sc.SetState(true);
85 return true;
86 }
87 }
88 else
89 {
90 sc.SetState(false);
91 return false;
92 }
93 }
94
95 if (curStamina > sc.GetDrainThreshold() || curStamina == cap) //Sometimes player can't go up to drain threshold
96 {
97 sc.SetState(true);
98 return true;
99 }
100 }
101
102 return false;
103 }
104
105 bool HasEnoughStaminaToStart(EStaminaConsumers consumer, float curStamina, bool isDepleted, float cap)
106 {
108 if (m_StaminaConsumers && m_StaminaConsumers.Find(consumer, sc))
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
135class StaminaModifier
136{
137 bool m_InUse = false;
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; }
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
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
208
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
259typedef Param1<float> StaminaCooldownParams;
260
262{
263 protected const float STAMINA_GAIN_THRESHOLD = 25.0;
264 protected const float STAMINA_GAIN_MODIFIER = 10.0;
265
266 protected bool m_InitUpdate;
267 protected float m_PlayerLoad;
268 protected float m_StaminaDelta;
269 protected float m_Stamina;
270 protected float m_StaminaSynced; //guaranteed to be identical on server and client
271 protected float m_StaminaCap;
272 protected float m_StaminaCapSynced; //guaranteed to be identical on server and client
273 protected float m_StaminaDepletionMultiplierNext; // value being sent via SJ
274 protected float m_StaminaRecoveryMultiplierNext; // value being sent via SJ
275 protected float m_StaminaDepletion;
276 protected float m_StaminaDepletionMultiplier; //controls depletion rate
277 protected float m_StaminaRecoveryMultiplier; //controls recovery rate
278 protected float m_Time;
283
284 protected bool m_StaminaDepleted;
285
287 ref set<EStaminaMultiplierTypes> m_ActiveDepletionModifiers;
288
290 ref set<EStaminaMultiplierTypes> m_ActiveRecoveryModifiers;
291
292 protected bool m_IsInCooldown;
293
296
297 protected float m_LastPlayerLoad = -1;
298
301
303
304 // Movement state caching members
305 protected int m_LastCommandTypeId = -1;
306 protected int m_LastMovementIdx = -1;
307 protected int m_LastStanceIdx = -1;
308 protected bool m_MovementStateChanged = true; // Force initial processing
309
310 #ifdef DIAG_DEVELOPER
311 protected bool m_StaminaDisabled;
312 protected float m_DebugTimer = 0;
313 protected int m_LastPoolInUse = 0;
314 #endif
315
317 {
318 if (g_Game.IsServer() || !g_Game.IsMultiplayer())
319 m_StaminaParams = new Param3<float,float,bool>(0, 0, false);
320
322 m_Player = player;
323
324 m_InitUpdate = false;
334 m_Time = 0;
335 m_StaminaDepleted = false;
336 m_IsInCooldown = false;
337 m_HumanMoveSettings = m_Player.GetDayZPlayerType().CommandMoveSettingsW();
339
342
344
345 //----------------- depletion --------------------
347 m_ActiveDepletionModifiers = new set<EStaminaMultiplierTypes>;
348
349 //----------------- recovery --------------------
351 m_ActiveRecoveryModifiers = new set<EStaminaMultiplierTypes>;
352
353 Init();
354 }
355
357 {
358 if (m_CooldownMap)
359 {
360 m_CooldownMap.Clear();
361 }
362 }
363
380
382 {
383 if (m_RegisteredDepletionModifiers.Contains(type))
384 {
385 m_ActiveDepletionModifiers.Insert(type);
387 }
388 else
389 {
390 Error("attempting to activate unregistered depletion modifier");
391 }
392 }
393
395 {
396 int index = m_ActiveDepletionModifiers.Find(type);
397 if (index != -1)
398 {
399 m_ActiveDepletionModifiers.Remove(index);
401 }
402 }
403
405 {
406 float value = 1;
407
408 foreach (int multiplier: m_ActiveDepletionModifiers)
409 {
410 value *= m_RegisteredDepletionModifiers.Get(multiplier);
411 }
412
413 if (value != m_StaminaDepletionMultiplier)
415 }
416
418 {
419 if (m_RegisteredRecoveryModifiers.Contains(type))
420 {
421 m_ActiveRecoveryModifiers.Insert(type);
423 }
424 else
425 {
426 Error("attempting to activate unregistered recovery modifier");
427 }
428 }
429
431 {
432 int index = m_ActiveRecoveryModifiers.Find(type);
433 if (index != -1)
434 {
435 m_ActiveRecoveryModifiers.Remove(index);
437 }
438 }
439
441 {
442 float value = 1;
443
444 foreach (int multiplier: m_ActiveRecoveryModifiers)
445 {
446 value *= m_RegisteredRecoveryModifiers.Get(multiplier);
447 }
448
449 if (value != m_StaminaRecoveryMultiplier)
450 {
452 }
453 }
454
455 // Check if movement state has changed since last frame
456 protected bool HasMovementStateChanged()
457 {
458 // Only call GetMovementState if we need to check for changes
459 m_Player.GetMovementState(m_State);
460
461 bool changed = (m_State.m_CommandTypeId != m_LastCommandTypeId || m_State.m_iMovement != m_LastMovementIdx || m_State.m_iStanceIdx != m_LastStanceIdx);
462
463 if (changed)
464 {
465 // Update cached values
466 m_LastCommandTypeId = m_State.m_CommandTypeId;
467 m_LastMovementIdx = m_State.m_iMovement;
468 m_LastStanceIdx = m_State.m_iStanceIdx;
469 }
470
471 return changed;
472 }
473
474 void Update(float deltaT, int pCurrentCommandID)
475 {
476 #ifdef DIAG_DEVELOPER
477 if (m_StaminaDisabled)
478 return;
479 #endif
480
481 if (!m_Player)
482 return;
483
484 // Process cooldowns - subtract deltaT and remove expired ones
485 array<int> expiredCooldowns = new array<int>();
486 foreach (int modifier, StaminaCooldownParams cooldownParams : m_CooldownMap)
487 {
488 cooldownParams.param1 -= deltaT;
489 if (cooldownParams.param1 <= 0)
490 {
491 expiredCooldowns.Insert(modifier);
492 }
493 }
494
495 // Remove expired cooldowns
496 foreach (int expiredModifier : expiredCooldowns)
497 {
498 ResetCooldown(expiredModifier);
499 }
500
501 // Reset so we get current bonus value once in this update loop and then reuse the cached value within this update call
503
504 // Check if movement state has changed
506
507 bool isAiOrSingleplayer = m_Player.IsAuthorityOwner();
508 bool isServerOrSingleplayer = m_Player.IsAuthority();
509
510 // Calculates actual max stamina based on player's load
511 if (isServerOrSingleplayer)
512 {
514 m_PlayerLoad = m_Player.GetWeightEx();
516 {
519 }
520 }
521 else
522 {
523 PlayerBaseMove move = PlayerBaseMove.Cast(m_Player.GetNextMove());
524 if (move)
525 {
526 move.m_fStaminaValue = m_Stamina;
527 move.m_fStaminaCapacity = m_StaminaCap;
528 }
529 }
530
531 if (isAiOrSingleplayer)
532 {
535 }
536
537 // Process movement if: state changed, we have stamina delta, in cooldown, not initialized, or stamina is bewlow cap
540
541 // Sets current stamina & stores + syncs data with client
542 ProcessStaminaChanges(deltaT, isServerOrSingleplayer);
543
546
547 m_StaminaDelta = 0;
548 m_StaminaDepletion = 0; // resets depletion modifier
550 if (!m_InitUpdate)
551 m_InitUpdate = true;
552 }
553
554 protected void ProcessMovementState()
555 {
556 switch (m_State.m_CommandTypeId)
557 {
558 case DayZPlayerConstants.COMMANDID_MOVE:
560 break;
561 case DayZPlayerConstants.COMMANDID_LADDER:
563 break;
564 case DayZPlayerConstants.COMMANDID_SWIM:
566 break;
567 case DayZPlayerConstants.COMMANDID_FALL:
568 case DayZPlayerConstants.COMMANDID_MELEE2:
569 case DayZPlayerConstants.COMMANDID_CLIMB:
570 break;
571 default:
572 if (!m_IsInCooldown)
573 {
575 }
576 break;
577 }
578 }
579
580 protected void ProcessStaminaChanges(float deltaT, bool isServerOrSingleplayer)
581 {
582 // Calculate stamina changes
583 float temp = m_StaminaDelta * deltaT;
584 if (temp < 0)
585 {
587 }
588 else
589 {
591 }
592
593 // Apply stamina depletion first, then add/subtract the delta
594 float newStamina = m_Stamina - m_StaminaDepletion + temp;
595
596 // Clamp to valid range
597 m_Stamina = Math.Max(0, Math.Min(newStamina, m_StaminaCap));
598
599 // Handle floating-point precision issues - snap to cap if very close
600 if (m_Stamina > (m_StaminaCap - 0.01) && temp > 0)
601 {
603 }
604
605 if (isServerOrSingleplayer)
606 {
607 m_Player.GetStatStamina().Set(m_Stamina);
608 m_Time += deltaT;
609
611 {
612 m_Time = 0;
614 }
615 }
616
617 #ifndef SERVER
619 #endif
620 }
621
636
638 void OnSyncJuncture(int pJunctureID, ParamsReadContext pCtx)
639 {
640 switch (pJunctureID)
641 {
643 float stamina;
644 float staminaCap;
645 bool cooldown;
646
647 if (!pCtx.Read(stamina) || !pCtx.Read(staminaCap) || !pCtx.Read(cooldown))
648 {
649 return;
650 }
651
652 m_Stamina = stamina; //?
653 m_StaminaSynced = stamina;
654 m_StaminaCap = staminaCap;
655 m_StaminaCapSynced = staminaCap;
656
657 if (m_Player.GetInstanceType() != DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
658 {
659 return;
660 }
661
662 if (staminaCap != m_StaminaCap)
663 {
664 m_StaminaCap = staminaCap;
665 }
666
667 m_IsInCooldown = cooldown;
668 m_Player.SetStamina(m_Stamina, m_StaminaCap);
669 break;
670
673 break;
674 }
675 }
676
677 protected void StaminaProcessor_Move(HumanMovementState pHumanMovementState)
678 {
679 switch (pHumanMovementState.m_iMovement)
680 {
681 case DayZPlayerConstants.MOVEMENTIDX_SPRINT: //sprint
682 if (pHumanMovementState.m_iStanceIdx == DayZPlayerConstants.STANCEIDX_ERECT)
683 {
686 break;
687 }
688 else if ( pHumanMovementState.m_iStanceIdx == DayZPlayerConstants.STANCEIDX_CROUCH)
689 {
692 break;
693 }
694
696 break;
697
698 case DayZPlayerConstants.MOVEMENTIDX_RUN: //jog
699 if (m_Player.GetCurrentWaterLevel() >= m_HumanMoveSettings.m_fWaterLevelSpeedRectrictionHigh)
700 {
702 break;
703 }
704
705 if (!m_IsInCooldown)
706 {
708 }
709 break;
710
711 case DayZPlayerConstants.MOVEMENTIDX_WALK: //walk
712 if (!m_IsInCooldown)
713 {
715 }
716 break;
717
718 case DayZPlayerConstants.MOVEMENTIDX_IDLE: //idle
719 if (m_Player.IsRolling())
720 {
722 break;
723 }
724
725 if (!m_IsInCooldown)
726 {
728 }
729 break;
730
731 default:
732 if (!m_IsInCooldown)
733 {
735 }
736 break;
737 }
738 }
739
740 protected void StaminaProcessor_Ladder(HumanMovementState pHumanMovementState)
741 {
742 switch (pHumanMovementState.m_iMovement)
743 {
744 case 2: //climb up (fast)
747 break;
748
749 case 1: //climb up (slow)
750 if (!m_IsInCooldown)
751 {
753 }
754 break;
755
756 default:
757 if (!m_IsInCooldown)
758 {
760 }
761 break;
762 }
763 }
764
765 protected void StaminaProcessor_Swimming(HumanMovementState pHumanMovementState)
766 {
767 switch (pHumanMovementState.m_iMovement)
768 {
769 case 3: //swim fast
772 break;
773
774 case 2: //swim slow
775 if (!m_IsInCooldown)
776 {
778 }
779 break;
780
781 default:
782 if (!m_IsInCooldown)
783 {
785 }
786 break;
787 }
788 }
789
791 protected void SyncStaminaEx()
792 {
794 }
795
797 protected void SyncStamina(float stamina, float stamina_cap, bool cooldown)
798 {
799 m_Player.GetStatStamina().Set(stamina);
801 pCtx.Write(stamina);
802 pCtx.Write(stamina_cap);
803 pCtx.Write(cooldown);
804 m_Player.SendSyncJuncture(DayZPlayerSyncJunctures.SJ_STAMINA,pCtx);
805 }
806
809 {
811
813 pCtx.Write(p.param1);
814 pCtx.Write(p.param2);
815 m_Player.SendSyncJuncture(DayZPlayerSyncJunctures.SJ_STAMINA_MISC,pCtx);
816 }
817
820 {
821 float depletionMultiplier;
822 float recoveryMultiplier;
823 if (!pCtx.Read(depletionMultiplier) || !pCtx.Read(recoveryMultiplier))
824 {
825 return;
826 }
827
828 m_StaminaDepletionMultiplier = depletionMultiplier;
829 m_StaminaRecoveryMultiplier = recoveryMultiplier;
830 }
831
833 {
835
836 m_StaminaConsumers.RegisterConsumer(
837 EStaminaConsumers.HOLD_BREATH,
840 );
841 m_StaminaConsumers.RegisterConsumer(
842 EStaminaConsumers.SPRINT,
844 );
845 m_StaminaConsumers.RegisterConsumer(
846 EStaminaConsumers.JUMP,
848 );
849 m_StaminaConsumers.RegisterConsumer(
850 EStaminaConsumers.VAULT,
852 );
853 m_StaminaConsumers.RegisterConsumer(
854 EStaminaConsumers.CLIMB,
856 );
857 m_StaminaConsumers.RegisterConsumer(
858 EStaminaConsumers.MELEE_HEAVY,
860 );
861 m_StaminaConsumers.RegisterConsumer(
862 EStaminaConsumers.MELEE_EVADE,
864 );
865 m_StaminaConsumers.RegisterConsumer(
868 );
869 m_StaminaConsumers.RegisterConsumer(
870 EStaminaConsumers.DROWN,
871 0,
872 );
873 m_StaminaConsumers.RegisterConsumer(
875 0,
876 );
877 }
878
880 {
882
884 m_StaminaModifiers.RegisterExponentialEx(
885 EStaminaModifiers.HOLD_BREATH,
886 data,
887 );
888 m_StaminaModifiers.RegisterExponentialEx(
889 EStaminaModifiers.PUSH_CAR,
890 data,
891 );
892 m_StaminaModifiers.RegisterFixed(
893 EStaminaModifiers.DROWN,
894 10,
895 );
896 m_StaminaModifiers.RegisterFixed(
899 );
900 m_StaminaModifiers.RegisterFixed(
901 EStaminaModifiers.VAULT,
903 );
904 m_StaminaModifiers.RegisterFixed(
905 EStaminaModifiers.CLIMB,
907 );
908 m_StaminaModifiers.RegisterFixed(
909 EStaminaModifiers.MELEE_LIGHT,
911 );
912 m_StaminaModifiers.RegisterFixed(
913 EStaminaModifiers.MELEE_HEAVY,
915 );
916 m_StaminaModifiers.RegisterFixed(
917 EStaminaModifiers.OVERALL_DRAIN,
919 5.0,
920 );
921 m_StaminaModifiers.RegisterRandomized(
924 );
925 m_StaminaModifiers.RegisterFixed(
928 );
929 }
930
953
954 protected void ApplyExhaustion()
955 {
957 HumanCommandAdditives ad = m_Player.GetCommandModifier_Additives();
958
959 float exhaustion_value = 1;
960 if (m_StaminaCap != 0)
961 {
962 exhaustion_value = 1 - ((m_Stamina / (m_StaminaCap * 0.01)) * 0.01);
963 }
964
965 exhaustion_value = Math.Min(1, exhaustion_value);
966 if (ad)
967 {
968 // do not apply exhaustion on local client if player is in ADS/Optics (camera shakes)
969 if (m_Player.GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT && (m_Player.IsInOptics() || m_Player.IsInIronsights()))
970 {
971 ad.SetExhaustion(0, true);
972 }
973 else
974 {
975 ad.SetExhaustion(exhaustion_value, true);
976 }
977 }
978 }
979
981 protected void CheckStaminaState()
982 {
983 if (m_Stamina <= 0)
984 {
985 m_StaminaDepleted = true;
987 if (!m_IsInCooldown)
988 {
989 // set this only once
991 }
992 }
993 else
994 {
995 m_StaminaDepleted = false;
996 }
997 }
998
1000 protected void SetCooldown(float time, int modifier = -1)
1001 {
1002 StaminaCooldownParams cooldown;
1003 if (!m_CooldownMap.Find(modifier, cooldown))
1004 {
1005 cooldown = new StaminaCooldownParams(0);
1006 m_CooldownMap.Insert(modifier, cooldown);
1007 }
1008
1009 m_IsInCooldown = true;
1010 cooldown.param1 = time; // Set remaining time
1011 }
1012
1013 protected void ResetCooldown(int modifier = -1)
1014 {
1015 StaminaModifier sm = m_StaminaModifiers.GetModifierData(modifier);
1016 if (sm)
1017 {
1018 sm.SetStartTime(-1);
1019 sm.ResetRunTime();
1020 sm.SetInUse(false);
1021 }
1022
1023 // Remove from cooldown map
1024 m_CooldownMap.Remove(modifier);
1025
1026 // Update cooldown state based on remaining active cooldowns
1027 m_IsInCooldown = (m_CooldownMap.Count() > 0);
1028 }
1029
1030 // ---------------------------------------------------
1032 {
1033 return m_StaminaConsumers.HasEnoughStaminaFor(consumer, m_StaminaSynced, m_StaminaDepleted, m_StaminaCapSynced);
1034 }
1035
1037 {
1038 return m_StaminaConsumers.HasEnoughStaminaToStart(consumer, m_StaminaSynced, m_StaminaDepleted, m_StaminaCapSynced);
1039 }
1040
1041 void SetStamina(float stamina_value)
1042 {
1043 m_Stamina = Math.Clamp(stamina_value, 0, CfgGameplayHandler.GetStaminaMax());
1044 SyncStaminaEx();
1045 }
1046
1048 {
1049 return m_Stamina;
1050 }
1051
1053 {
1054 return m_Stamina / GetStaminaMax();
1055 }
1056
1058 {
1059 return m_StaminaSynced;
1060 }
1061
1063 {
1064 return GetSyncedStamina() / GetStaminaMax();
1065 }
1066
1068 {
1069 return m_StaminaCap;
1070 }
1071
1073 {
1074 return m_StaminaCapSynced;
1075 }
1076
1078 {
1080 }
1081
1082 // Only used internaly in this class, use ActivateDepletionModifier/DeactivateDepletionModifier instead
1090
1091 // Only used internaly in this class, use ActivateRecoveryModifier/DeactivateRecoveryModifier instead
1099
1101 {
1103 }
1104
1106 {
1108 }
1109
1110 void DepleteStaminaEx(EStaminaModifiers modifier, float dT = -1, float coef = 1.0)
1111 {
1112 #ifdef DIAG_DEVELOPER
1113 if (m_StaminaDisabled)
1114 return;
1115 #endif
1116 float val = 0.0;
1117 float current_time = m_Player.GetSimulationTimeStamp();
1118 float valueProgress;
1119 StaminaModifier sm = m_StaminaModifiers.GetModifierData(modifier);
1120
1121 // select by modifier type and drain stamina
1122 switch (sm.GetType())
1123 {
1124 case m_StaminaModifiers.FIXED:
1125 if (dT == -1)
1126 {
1127 dT = 1;
1128 }
1129 m_StaminaDepletion += sm.GetMaxValue() * dT * coef;
1130
1131 break;
1132
1133 case m_StaminaModifiers.RANDOMIZED:
1134 val = Math.RandomFloat(sm.GetMinValue(), sm.GetMaxValue());
1135 m_StaminaDepletion += val * coef;
1136
1137 break;
1138
1139 case m_StaminaModifiers.LINEAR:
1140 if (!sm.IsInUse())
1141 {
1142 sm.SetStartTime(current_time + sm.GetStartTimeAdjustment()/dT);
1143 sm.SetRunTimeTick(dT);
1144 sm.SetInUse(true);
1145 }
1146 valueProgress = Math.Clamp((current_time - sm.GetStartTime())/sm.GetDurationAdjusted(), 0, 1 );
1147 val = Math.Lerp(sm.GetMinValue(), sm.GetMaxValue(), valueProgress);
1148 m_StaminaDepletion += val * coef;
1149
1150 break;
1151
1152 case m_StaminaModifiers.EXPONENTIAL:
1154 if (!Class.CastTo(smex,sm))
1155 {
1156 ErrorEx("StaminaModifierExponential not found for modifier type: " + sm.GetType());
1157 break;
1158 }
1159
1160 if (!smex.IsInUse())
1161 {
1162 smex.SetStartTime(current_time + smex.GetStartTimeAdjustment()/dT);
1163 smex.SetRunTimeTick(dT);
1164 smex.SetInUse(true);
1165 }
1166 valueProgress = Math.Clamp((current_time - smex.GetStartTime())/smex.GetDurationAdjusted(), 0, 1 );
1167 float exp;
1168 if (Math.AbsFloat(smex.GetBaseValue()) < 1)
1169 {
1170 exp = 1 - Math.Lerp(0, smex.GetExponent(), valueProgress);
1171 val = Math.Pow(smex.GetBaseValue(),exp);
1172 }
1173 else
1174 {
1175 exp = Math.Lerp(Math.Min(0, smex.GetExponent()), Math.Max(0, smex.GetExponent()), valueProgress);
1176 val = Math.Pow(smex.GetBaseValue(),exp) + smex.GetBaseValue() - 1;
1177 }
1178
1179 m_StaminaDepletion += val * smex.GetMultiplier() * coef;
1180
1181 break;
1182 }
1183
1185 SetCooldown(sm.GetCooldown(),modifier);
1186
1189 }
1190
1191 // ADD these new methods - don't remove any existing ones
1192 void ObtainState(PlayerBaseOwnerState state)
1193 {
1194 // we are writing the state data for stamina to the move, use 'GetNextMove'
1195 }
1196
1197 void ObtainMove(PlayerBaseMove move)
1198 {
1199 // unused
1200 }
1201
1202 void RewindState(PlayerBaseOwnerState state, PlayerBaseMove move)
1203 {
1204 m_Stamina = move.m_fStaminaValue;
1205 m_StaminaCap = move.m_fStaminaCapacity;
1206 }
1207
1208 void ReplayMove(PlayerBaseMove move)
1209 {
1210 // mimick receiving of sync juncture
1211 if (move.m_bStaminaSynced)
1212 {
1213 m_StaminaSynced = move.m_fStaminaSyncedValue;
1214 m_StaminaCapSynced = move.m_fStaminaSyncedCapacity;
1215
1218 }
1219
1220 m_StaminaDepletion = move.m_fStaminaDepletion;
1221
1222 Update(move.GetTimeSlice(), m_Player.GetCurrentCommandID());
1223 }
1224
1225 #ifdef DIAG_DEVELOPER
1226 void SetStaminaDisabled(bool value)
1227 {
1228 m_StaminaDisabled = value;
1229 }
1230 #endif
1231
1233 //DEPRECATED BELOW
1235 protected bool m_Debug;
1236
1237 [Obsolete("No replacement")]
1238 void DepleteStamina(EStaminaModifiers modifier, float dT = -1)
1239 {
1240 DepleteStaminaEx(modifier,dT);
1241 }
1242
1243 [Obsolete("Deprecated use, StaminaHandler uses SyncJunctures now!")]
1244 void OnRPC(float stamina, float stamina_cap, bool cooldown);
1245}
eBleedingSourceType m_Type
eBleedingSourceType GetType()
float m_Duration
static float GetObstacleTraversalStaminaModifier()
static float GetStaminaMinCap()
static float GetStaminaKgToStaminaPercentPenalty()
static float GetSprintSwimmingStaminaModifier()
static float GetSprintLadderStaminaModifier()
static float GetSprintStaminaModifierCro()
static float GetSprintStaminaModifierErc()
static float GetStaminaWeightLimitThreshold()
static float GetMeleeStaminaModifier()
static float GetStaminaMax()
Super root of all classes in Enforce script.
Definition enscript.c:11
static const float STAMINA_RECOVERY_MULTIPLIER
Definition drowning.c:3
const float STAMINA_DEPLETION_MULTIPLIER
static const float STAMINA_DEPLETION_MULTIPLIER
Definition fatigue.c:9
static const float STAMINA_RECOVERY_MULTIPLIER
Definition fatigue.c:8
int m_iStanceIdx
current command's id
Definition human.c:1156
int m_iMovement
current stance (DayZPlayerConstants.STANCEIDX_ERECT, ...), only if the command has a stance
Definition human.c:1157
Definition mask.c:2
const float STAMINA_DEPLETION_MODIFIER
Definition mask.c:7
const float STAMINA_RECOVERY_MODIFIER
Definition mask.c:6
Definition enmath.c:7
Base Param Class with no parameters.
Definition param.c:12
const float STAMINA_DEPLETION_MULTIPLIER
Definition pneumonia.c:6
const float STAMINA_RECOVERY_MULTIPLIER
Definition pneumonia.c:7
proto bool Write(void value_out)
proto bool Read(void value_in)
bool HasEnoughStaminaToStart(EStaminaConsumers consumer, float curStamina, bool isDepleted, float cap)
ref map< EStaminaConsumers, ref StaminaConsumer > m_StaminaConsumers
void RegisterConsumer(EStaminaConsumers consumer, float threshold, float depletion_threshold=-1)
bool HasEnoughStaminaFor(EStaminaConsumers consumer, float curStamina, bool isDepleted, float cap)
SHumanCommandMoveSettings m_HumanMoveSettings
ref map< EStaminaMultiplierTypes, float > m_RegisteredDepletionModifiers
void ProcessMovementState()
void SetDepletionMultiplier(float val)
void SetRecoveryMultiplier(float val)
void SyncAdditionalStaminaInfo(Param par)
Method to sync more info for stamina manager. Template parameter means it is very extendable for furt...
ref HumanMovementState m_State
void Update(float deltaT, int pCurrentCommandID)
bool HasMovementStateChanged()
void StaminaHandler(PlayerBase player)
void ReadAdditionalStaminaInfo(ParamsReadContext pCtx)
Order of read parameters must match the order of writing above.
ref StaminaConsumers m_StaminaConsumers
float GetRecoveryMultiplier()
void RecalculateDepletionMultiplier()
void RewindState(PlayerBaseOwnerState state, PlayerBaseMove move)
float m_StaminaDepletionMultiplierNext
PlayerBase m_Player
void DepleteStaminaEx(EStaminaModifiers modifier, float dT=-1, float coef=1.0)
float GetSyncedStaminaNormalized()
void RegisterStaminaModifiers()
float CalcStaminaGainBonus()
Calulates stamina regain bonus coef based on current stamina cap and level and caches it during one U...
float m_StaminaRecoveryMultiplierNext
void ActivateDepletionModifier(EStaminaMultiplierTypes type)
float GetStaminaNormalized()
void ProcessStaminaChanges(float deltaT, bool isServerOrSingleplayer)
bool HasEnoughStaminaFor(EStaminaConsumers consumer)
float m_StaminaRecoveryMultiplier
float m_CachedStaminaGainBonus
void SetStamina(float stamina_value)
void DepleteStamina(EStaminaModifiers modifier, float dT=-1)
void StaminaProcessor_Ladder(HumanMovementState pHumanMovementState)
void SyncStamina(float stamina, float stamina_cap, bool cooldown)
stamina sync - server part
ref StaminaModifiers m_StaminaModifiers
void ReplayMove(PlayerBaseMove move)
const float STAMINA_GAIN_THRESHOLD
void OnRPC(float stamina, float stamina_cap, bool cooldown)
ref map< EStaminaMultiplierTypes, float > m_RegisteredRecoveryModifiers
void CheckStaminaState()
check if the stamina is completely depleted
ref set< EStaminaMultiplierTypes > m_ActiveDepletionModifiers
float m_StaminaDepletionMultiplier
void OnSyncJuncture(int pJunctureID, ParamsReadContext pCtx)
called from PlayerBase - syncs stamina values on server with client AND sets the value to match on se...
ref Param3< float, float, bool > m_StaminaParams
ref map< int, ref StaminaCooldownParams > m_CooldownMap
void StaminaProcessor_Swimming(HumanMovementState pHumanMovementState)
void ObtainState(PlayerBaseOwnerState state)
void StaminaProcessor_Move(HumanMovementState pHumanMovementState)
bool HasEnoughStaminaToStart(EStaminaConsumers consumer)
void RecalculateStaminaCap()
void SyncStaminaEx()
stamina sync - server part
void ResetCooldown(int modifier=-1)
void ActivateRecoveryModifier(EStaminaMultiplierTypes type)
bool m_IsStaminaGainBonusCached
void RegisterStaminaConsumers()
void ObtainMove(PlayerBaseMove move)
void SetCooldown(float time, int modifier=-1)
set cooldown timer between each consume of stamina
void DeactivateRecoveryModifier(EStaminaMultiplierTypes type)
void DeactivateDepletionModifier(EStaminaMultiplierTypes type)
float GetDepletionMultiplier()
const float STAMINA_GAIN_MODIFIER
float GetSyncedStaminaCap()
ref set< EStaminaMultiplierTypes > m_ActiveRecoveryModifiers
void RecalculateRecoveryMultiplier()
void SetData(SMDataExponential data)
ref SMDataExponential m_SMDataEx
override float GetStartTimeAdjustment()
override float GetDurationAdjusted()
static const float STAMINA_DEPLETION_MULTIPLIER
Definition vomitstate.c:3
static const float STAMINA_RECOVERY_MULTIPLIER
Definition vomitstate.c:4
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
DayZGame g_Game
Definition dayzgame.c:3942
DayZPlayerInstanceType
defined in C++
DayZPlayerConstants
defined in C++
Definition dayzplayer.c:602
EStaminaConsumers
EStaminaModifiers
Serializer ParamsReadContext
Definition gameplay.c:15
void Error(string err)
Messagebox with error message.
Definition endebug.c:90
enum ShapeType ErrorEx
static proto bool CastTo(out Class to, Class from)
Try to safely down-cast base class to child class.
void Obsolete(string msg="")
Definition enscript.c:371
static proto float Max(float x, float y)
Returns bigger of two given values.
static proto float Pow(float v, float power)
Return power of v ^ power.
static proto float Clamp(float value, float min, float max)
Clamps 'value' to 'min' if it is lower than 'min', or to 'max' if it is higher than 'max'.
static proto float RandomFloat(float min, float max)
Returns a random float number between and min[inclusive] and max[exclusive].
static proto float Min(float x, float y)
Returns smaller of two given values.
static proto float Lerp(float a, float b, float time)
Linearly interpolates between 'a' and 'b' given 'time'.
static proto float AbsFloat(float f)
Returns absolute value.
const float STAMINA_JUMP_THRESHOLD
Definition constants.c:702
const int STAMINA_GAIN_SWIM_PER_SEC
Definition constants.c:693
const float STAMINA_DRAIN_CLIMB
Definition constants.c:681
const float STAMINA_VAULT_THRESHOLD
Definition constants.c:703
const float STAMINA_REGEN_COOLDOWN_EXHAUSTION
Definition constants.c:711
const float STAMINA_CLIMB_THRESHOLD
Definition constants.c:704
const float STAMINA_KG_TO_GRAMS
in grams (weight where the player is not penalized by stamina)
Definition constants.c:713
const float STAMINA_DRAIN_MELEE_LIGHT
Definition constants.c:682
const float STAMINA_DRAIN_VAULT
Definition constants.c:680
const float STAMINA_SYNC_RATE
Definition constants.c:714
const int STAMINA_GAIN_IDLE_PER_SEC
Definition constants.c:692
const int STAMINA_GAIN_ROLL_PER_SEC
Definition constants.c:695
const float STAMINA_MELEE_EVADE_THRESHOLD
Definition constants.c:709
const int STAMINA_GAIN_JOG_PER_SEC
Definition constants.c:690
const float STAMINA_DRAIN_MELEE_HEAVY
Definition constants.c:683
const float STAMINA_DRAIN_JUMP
Definition constants.c:679
const float STAMINA_MELEE_HEAVY_THRESHOLD
Definition constants.c:708
const float STAMINA_DRAIN_MELEE_EVADE
Definition constants.c:684
const int STAMINA_DRAIN_SWIM_FAST_PER_SEC
Definition constants.c:674
const float STAMINA_GAIN_BONUS_CAP
Definition constants.c:696
const int STAMINA_DRAIN_STANDING_SPRINT_PER_SEC
Definition constants.c:671
const float STAMINA_ROLL_THRESHOLD
Definition constants.c:705
const float STAMINA_REGEN_COOLDOWN_DEPLETION
Definition constants.c:710
const float STAMINA_HOLD_BREATH_THRESHOLD_DRAIN
Definition constants.c:701
const int STAMINA_DRAIN_LADDER_FAST_PER_SEC
Definition constants.c:675
const float STAMINA_DRAIN_ROLL
Definition constants.c:685
const int STAMINA_DRAIN_CROUCHED_SPRINT_PER_SEC
Definition constants.c:672
const int STAMINA_GAIN_LADDER_PER_SEC
Definition constants.c:694
const int STAMINA_GAIN_WALK_PER_SEC
Definition constants.c:691
const float STAMINA_HOLD_BREATH_THRESHOLD_ACTIVATE
Definition constants.c:700
float GetRunTime()
Definition tools.c:323
float GetDuration()
Definition tools.c:313
proto native volatile void Update()
proto native int GetState()
returns one of STATE_...
class HumanCommandWeapons HumanCommandAdditives()
Definition human.c:1127
class SHumanGlobalSettings SHumanCommandMoveSettings()
enum EObjectTemperatureState m_State
class PlayerStatBase m_MinValue
T m_MaxValue
void StaminaConsumer(float threshold, float threshold2, bool state)
const int RANDOMIZED
m_ActivationThreshold
EStaminaMultiplierTypes
float GetMinValue()
void SetMaxValue(float val)
const int LINEAR
DISEASE_PNEUMONIA
float m_ProgressTime
void StaminaModifier(int type, float min, float max, float cooldown, float startTime=0, float duration=0)
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,...
void SetActivationThreshold(float threshold)
void ResetRunTime()
FATIGUE
float m_Tick
void SetStartTime(float val)
void SetInUse(bool val)
StaminaModifierExponential FIXED
m_InUse
void SetDrainThreshold(float threshold)
float m_StartTimeAdjustment
void SetState(bool state)
ref map< EStaminaModifiers, ref StaminaModifier > m_StaminaModifiers
void RegisterExponentialEx(EStaminaModifiers modifier, SMDataExponential data)
register exponential modifier, extended parameters
float GetMaxValue()
float GetStartTimeAdjustment()
bool IsInUse()
float m_Multiplier
float m_StartTime
VOMIT_EXHAUSTION
float GetDrainThreshold()
const int EXPONENTIAL
float GetActivationThreshold()
Param1< float > StaminaCooldownParams
void SetRunTimeTick(float val)
void StaminaModifiers()
void SetMinValue(float val)
void StaminaConsumers()
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,...
void RegisterFixed(EStaminaModifiers modifier, float value, float cooldown=GameConstants.STAMINA_REGEN_COOLDOWN_DEPLETION)
register single value modifier - depletes stamina for that value
EPINEPHRINE
float GetStartTime()
void SetCooldown(float val)
StaminaModifier GetModifierData(EStaminaModifiers modifier)
MASK
float GetCooldown()
float GetDurationAdjusted()
float m_Cooldown
void AddRunTime(float val)
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;