12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058 |
- enum EStaminaMultiplierTypes
- {
- MASK = 1,
- FATIGUE,
- EPINEPHRINE,
- DROWNING,
- VOMIT_EXHAUSTION,
- DISEASE_PNEUMONIA
- }
- /**@class Stamina Consumer
- * @brief Holds information about Stamina Consumer
- *
- * @param[in] threshold value needed to allow consume stamina
- * @param[in] state keeps state of the consumer non-depleted/depleted
- */
- class StaminaConsumer
- {
- protected float m_ActivationThreshold;
- protected float m_DrainThreshold
- protected bool m_State;
-
- void StaminaConsumer(float threshold, float threshold2, bool state)
- {
- m_ActivationThreshold = threshold; //can be activated if above this threshold
- m_DrainThreshold = threshold2; //can continually drain until it reaches this threshold
- m_State = state;
- }
-
- bool GetState() { return m_State; }
- void SetState(bool state) { m_State = state; }
-
- float GetActivationThreshold() { return m_ActivationThreshold; }
- void SetActivationThreshold(float threshold) { m_ActivationThreshold = threshold; }
-
- float GetDrainThreshold() { return m_DrainThreshold; }
- void SetDrainThreshold(float threshold) { m_DrainThreshold = threshold; }
- }
- class StaminaConsumers
- {
- protected ref map<EStaminaConsumers, ref StaminaConsumer> m_StaminaConsumers;
- void StaminaConsumers()
- {
- m_StaminaConsumers = new map<EStaminaConsumers, ref StaminaConsumer>;
- }
- void RegisterConsumer(EStaminaConsumers consumer, float threshold, float depletion_threshold = -1)
- {
- if (depletion_threshold == -1)
- {
- depletion_threshold = threshold;
- }
-
- if ( !m_StaminaConsumers.Contains(consumer) )
- {
- //! init of StaminaConsumer - threshold, state
- StaminaConsumer sc = new StaminaConsumer(threshold, depletion_threshold, true);
- m_StaminaConsumers.Set(consumer, sc);
- }
- }
- bool HasEnoughStaminaFor(EStaminaConsumers consumer, float curStamina, bool isDepleted, float cap)
- {
- StaminaConsumer sc;
- if (m_StaminaConsumers && m_StaminaConsumers.Find(consumer, sc))
- {
- if (consumer != EStaminaConsumers.SPRINT)
- {
- if (isDepleted || (curStamina < sc.GetDrainThreshold()))
- {
- sc.SetState(false);
- return false;
- }
- }
- else
- {
- if (!isDepleted)
- {
- if (sc.GetState())
- {
- sc.SetState(true);
- return true;
- }
- }
- else
- {
- sc.SetState(false);
- return false;
- }
- }
- if (curStamina > sc.GetDrainThreshold() || curStamina == cap) //Sometimes player can't go up to drain threshold
- {
- sc.SetState(true);
- return true;
- }
- }
- return false;
- }
-
- bool HasEnoughStaminaToStart(EStaminaConsumers consumer, float curStamina, bool isDepleted, float cap)
- {
- StaminaConsumer sc;
- if (m_StaminaConsumers && m_StaminaConsumers.Find(consumer, sc))
- {
- if ((isDepleted || (curStamina < sc.GetActivationThreshold() && curStamina < cap)))
- {
- sc.SetState(false);
- return false;
- }
- else
- {
- sc.SetState(true);
- return true;
- }
- }
-
- return false;
- }
- }
- /**@class Stamina Modifier
- * @brief Holds information about Stamina Modifier
- *
- * @param[in] type calculation method
- * @param[in] minValue min value substracted from stamina (if type > 0)
- * @param[in] maxValue max value substracted from stamina
- * @param[in] cooldown how many seconds will not be the stamina replenishing after depleting
- */
- class StaminaModifier
- {
- bool m_InUse = false;
- int m_Type;
- float m_MinValue, m_MaxValue, m_Multiplier, m_Cooldown, m_StartTime, m_StartTimeAdjustment, m_Duration, m_ProgressTime, m_Tick;
- void StaminaModifier(int type, float min, float max, float cooldown, float startTime = 0, float duration = 0)
- {
- m_Type = type;
- m_MinValue = min;
- m_MaxValue = max;
- m_Cooldown = cooldown;
- m_StartTimeAdjustment = startTime;
- m_Duration = duration;
- m_Tick = 1;
- }
-
- int GetType() { return m_Type; }
-
- float GetMinValue() { return m_MinValue; }
- void SetMinValue(float val) { m_MinValue = val; }
-
- float GetMaxValue() { return m_MaxValue; }
- void SetMaxValue(float val) { m_MaxValue = val; }
-
- float GetCooldown() { return m_Cooldown; }
- void SetCooldown(float val) { m_Cooldown = val; }
-
- float GetStartTime() { return m_StartTime; } //Actual game time (progressive modifiers only)
- void SetStartTime(float val) { m_StartTime = val; }
-
- float GetStartTimeAdjustment() {return m_StartTimeAdjustment;} //adjustment to current time (progressive modifiers only)
-
- float GetDuration() { return m_Duration; }
- float GetDurationAdjusted() { return m_Duration / m_Tick; }
-
- bool IsInUse() { return m_InUse; }
- void SetInUse(bool val) { m_InUse = val; }
-
- float GetRunTime() { return m_ProgressTime; }
- void AddRunTime(float val) { m_ProgressTime += val; }
- void SetRunTimeTick(float val) { m_Tick = val; }
- void ResetRunTime() { m_ProgressTime = 0 }
- }
- class StaminaModifierExponential : StaminaModifier
- {
- protected ref SMDataExponential m_SMDataEx;
-
- float GetBaseValue() { return m_SMDataEx.m_BaseValue; }
- float GetExponent() { return m_SMDataEx.m_Exponent; }
- float GetMultiplier() { return m_SMDataEx.m_Multiplier; }
- override float GetCooldown() { return m_SMDataEx.m_Cooldown; }
- override float GetStartTimeAdjustment() { return m_SMDataEx.m_StartTimeAdjustment; }
- override float GetDuration() { return m_SMDataEx.m_Duration; }
- override float GetDurationAdjusted() { return m_SMDataEx.m_Duration / m_Tick; }
-
- void SetData(SMDataExponential data) { m_SMDataEx = data; }
- }
- class StaminaModifiers
- {
- const int FIXED = 0;
- const int RANDOMIZED = 1;
- const int LINEAR = 2; //Useful ONLY for regular, over-time stamina drain
- const int EXPONENTIAL = 3; //Useful ONLY for regular, over-time stamina drain
- protected ref map<EStaminaModifiers, ref StaminaModifier> m_StaminaModifiers;
- void StaminaModifiers()
- {
- m_StaminaModifiers = new map<EStaminaModifiers, ref StaminaModifier>;
- }
- //! register single value modifier - depletes stamina for that value
- void RegisterFixed(EStaminaModifiers modifier, float value, float cooldown = GameConstants.STAMINA_REGEN_COOLDOWN_DEPLETION)
- {
- if ( !m_StaminaModifiers.Contains(modifier) )
- {
- //! init of StaminaModifier - type and min, max values (min is not relevant for that type)
- StaminaModifier sm = new StaminaModifier(FIXED, -1, value, cooldown);
- m_StaminaModifiers.Set(modifier, sm);
- }
- }
-
- //! register randomized modifier - stamina will be depleted by value between min and max value;
- void RegisterRandomized(EStaminaModifiers modifier, float minValue, float maxValue, float cooldown = GameConstants.STAMINA_REGEN_COOLDOWN_DEPLETION)
- {
- if ( !m_StaminaModifiers.Contains(modifier) )
- {
- //! init of StaminaModifier - type, min, max values
- StaminaModifier sm = new StaminaModifier(RANDOMIZED, minValue, maxValue, cooldown);
- m_StaminaModifiers.Set(modifier, sm);
- }
- }
-
- //! register lerped modifier - depletes stamina for startValue, and, after a startTime, lerps to endValue over duration
- void RegisterLinear(EStaminaModifiers modifier, float startValue, float endValue, float startTime, float duration, float cooldown = GameConstants.STAMINA_REGEN_COOLDOWN_DEPLETION)
- {
- StaminaModifier sm = new StaminaModifier(LINEAR, startValue, endValue, cooldown, startTime, duration);
- m_StaminaModifiers.Set(modifier, sm);
- }
-
- //! register exponential modifier - depletes stamina for startValue, and, after a startTime, lerps from 0 to exponent over duration
- void RegisterExponential(EStaminaModifiers modifier, float startValue, float exponent, float startTime, float duration, float cooldown = GameConstants.STAMINA_REGEN_COOLDOWN_DEPLETION)
- {
- StaminaModifier sm = new StaminaModifier(EXPONENTIAL, startValue, exponent, cooldown, startTime, duration);
- m_StaminaModifiers.Set(modifier, sm);
- }
-
- //! register exponential modifier, extended parameters
- void RegisterExponentialEx(EStaminaModifiers modifier, SMDataExponential data)
- {
- StaminaModifierExponential smex = new StaminaModifierExponential(EXPONENTIAL, data.m_BaseValue, data.m_Exponent, data.m_Cooldown, data.m_StartTimeAdjustment, data.m_Duration);
- smex.SetData(data);
- m_StaminaModifiers.Set(modifier, smex);
- }
-
- StaminaModifier GetModifierData(EStaminaModifiers modifier)
- {
- return m_StaminaModifiers.Get(modifier);
- }
- }
- class StaminaHandler
- {
- protected float m_PlayerLoad;
- protected float m_StaminaDelta;
- protected float m_Stamina;
- protected float m_StaminaSynced; //guaranteed to be identical on server and client
- protected float m_StaminaCap;
- protected float m_StaminaDepletion;
- protected float m_StaminaDepletionMultiplier; //controls depletion rate
- protected float m_StaminaRecoveryMultiplier; //controls recovery rate
- protected float m_Time;
- protected ref Param3<float,float,bool> m_StaminaParams;
- protected ref HumanMovementState m_State;
- protected SHumanCommandMoveSettings m_HumanMoveSettings;
- protected PlayerBase m_Player;
- protected bool m_Debug; //! DEPRECATED
- protected bool m_StaminaDepleted;
- protected ref map<int,ref Timer> m_TimerMap;
- ref map<EStaminaMultiplierTypes, float> m_RegisteredDepletionModifiers;
- ref set<EStaminaMultiplierTypes> m_ActiveDepletionModifiers;
-
- ref map<EStaminaMultiplierTypes, float> m_RegisteredRecoveryModifiers;
- ref set<EStaminaMultiplierTypes> m_ActiveRecoveryModifiers;
-
- protected bool m_IsInCooldown;
-
- protected ref StaminaConsumers m_StaminaConsumers;
- protected ref StaminaModifiers m_StaminaModifiers;
-
- #ifdef DIAG_DEVELOPER
- protected bool m_StaminaDisabled;
- #endif
-
- void StaminaHandler(PlayerBase player)
- {
- if (GetGame().IsServer() || !GetGame().IsMultiplayer())
- m_StaminaParams = new Param3<float,float,bool>(0, 0, false);
- m_State = new HumanMovementState();
- m_Player = player;
- m_Stamina = CfgGameplayHandler.GetStaminaMax();
- m_StaminaCap = CfgGameplayHandler.GetStaminaMax();
- m_StaminaDepletion = 0;
- m_StaminaDepletionMultiplier = 1;
- m_StaminaRecoveryMultiplier = 1;
- m_Time = 0;
- m_StaminaDepleted = false;
- m_IsInCooldown = false;
- m_HumanMoveSettings = m_Player.GetDayZPlayerType().CommandMoveSettingsW();
- RegisterStaminaConsumers();
- RegisterStaminaModifiers();
-
- m_TimerMap = new map<int,ref Timer>;
-
- //----------------- depletion --------------------
- m_RegisteredDepletionModifiers = new map<EStaminaMultiplierTypes, float>;
- m_ActiveDepletionModifiers = new set<EStaminaMultiplierTypes>;
- //----------------- recovery --------------------
- m_RegisteredRecoveryModifiers = new map<EStaminaMultiplierTypes, float>;
- m_ActiveRecoveryModifiers = new set<EStaminaMultiplierTypes>;
-
- Init();
- }
-
-
- void Init()
- {
- //----------------- depletion --------------------
- m_RegisteredDepletionModifiers.Insert(EStaminaMultiplierTypes.MASK, MaskMdfr.STAMINA_DEPLETION_MODIFIER);
- m_RegisteredDepletionModifiers.Insert(EStaminaMultiplierTypes.FATIGUE, FatigueMdfr.STAMINA_DEPLETION_MULTIPLIER);
- m_RegisteredDepletionModifiers.Insert(EStaminaMultiplierTypes.EPINEPHRINE, EpinephrineMdfr.STAMINA_DEPLETION_MULTIPLIER);
- m_RegisteredDepletionModifiers.Insert(EStaminaMultiplierTypes.VOMIT_EXHAUSTION, VomitSymptom.STAMINA_DEPLETION_MULTIPLIER);
- m_RegisteredDepletionModifiers.Insert(EStaminaMultiplierTypes.DISEASE_PNEUMONIA, PneumoniaMdfr.STAMINA_DEPLETION_MULTIPLIER);
-
- //----------------- recovery --------------------
- m_RegisteredRecoveryModifiers.Insert(EStaminaMultiplierTypes.MASK, MaskMdfr.STAMINA_RECOVERY_MODIFIER);
- m_RegisteredRecoveryModifiers.Insert(EStaminaMultiplierTypes.FATIGUE, FatigueMdfr.STAMINA_RECOVERY_MULTIPLIER);
- m_RegisteredRecoveryModifiers.Insert(EStaminaMultiplierTypes.DROWNING, DrowningMdfr.STAMINA_RECOVERY_MULTIPLIER);
- m_RegisteredRecoveryModifiers.Insert(EStaminaMultiplierTypes.VOMIT_EXHAUSTION, VomitSymptom.STAMINA_RECOVERY_MULTIPLIER);
- m_RegisteredRecoveryModifiers.Insert(EStaminaMultiplierTypes.DISEASE_PNEUMONIA, PneumoniaMdfr.STAMINA_RECOVERY_MULTIPLIER);
-
- }
-
- void ActivateDepletionModifier(EStaminaMultiplierTypes type)
- {
- if (m_RegisteredDepletionModifiers.Contains(type))
- {
- m_ActiveDepletionModifiers.Insert(type);
- RecalculateDepletionMultiplier();
- }
- else
- {
- Error("attempting to activate unregistered depletion modifier");
- }
- }
-
- void DeactivateDepletionModifier(EStaminaMultiplierTypes type)
- {
- int index = m_ActiveDepletionModifiers.Find(type);
- if (index != -1)
- {
- m_ActiveDepletionModifiers.Remove(index);
- RecalculateDepletionMultiplier();
- }
- }
-
- void RecalculateDepletionMultiplier()
- {
- float value = 1;
-
- foreach (int multiplier: m_ActiveDepletionModifiers)
- {
- value *= m_RegisteredDepletionModifiers.Get(multiplier);
- }
- if (value != m_StaminaDepletionMultiplier)
- SetDepletionMultiplier(value);
- }
-
- void ActivateRecoveryModifier(EStaminaMultiplierTypes type)
- {
- if (m_RegisteredRecoveryModifiers.Contains(type))
- {
- m_ActiveRecoveryModifiers.Insert(type);
- RecalculateRecoveryMultiplier();
- }
- else
- {
- Error("attempting to activate unregistered recovery modifier");
- }
- }
-
- void DeactivateRecoveryModifier(EStaminaMultiplierTypes type)
- {
- int index = m_ActiveRecoveryModifiers.Find(type);
- if (index != -1)
- {
- m_ActiveRecoveryModifiers.Remove(index);
- RecalculateRecoveryMultiplier();
- }
- }
-
- void RecalculateRecoveryMultiplier()
- {
- float value = 1;
-
- foreach (int multiplier: m_ActiveRecoveryModifiers)
- {
- value *= m_RegisteredRecoveryModifiers.Get(multiplier);
- }
- if (value != m_StaminaRecoveryMultiplier)
- {
- SetRecoveryMultiplier(value);
- }
- }
-
- void Update(float deltaT, int pCurrentCommandID)
- {
- #ifdef DIAG_DEVELOPER
- if (m_StaminaDisabled)
- return;
- #endif
- if (m_Player)
- {
- bool isServerOrSingleplayer = GetGame().IsServer() || !GetGame().IsMultiplayer();
- // Calculates actual max stamina based on player's load
- if (isServerOrSingleplayer)
- {
- //! gets the actual players load
- m_PlayerLoad = m_Player.GetWeightEx();
- //! StaminaCap calculation starts when PlayerLoad exceeds STAMINA_WEIGHT_LIMIT_THRESHOLD
- if (m_PlayerLoad >= CfgGameplayHandler.GetStaminaWeightLimitThreshold())
- {
- m_StaminaCap = Math.Max((CfgGameplayHandler.GetStaminaMax() - (((m_PlayerLoad - CfgGameplayHandler.GetStaminaWeightLimitThreshold())/GameConstants.STAMINA_KG_TO_GRAMS) * CfgGameplayHandler.GetStaminaKgToStaminaPercentPenalty())),CfgGameplayHandler.GetStaminaMinCap());
- }
- else
- {
- m_StaminaCap = CfgGameplayHandler.GetStaminaMax();
- }
- }
-
- // Calculates stamina gain/loss based on movement and load
- m_Player.GetMovementState(m_State);
- switch (m_State.m_CommandTypeId)
- {
- case DayZPlayerConstants.COMMANDID_MOVE:
- StaminaProcessor_Move(m_State);
- break;
- case DayZPlayerConstants.COMMANDID_LADDER:
- StaminaProcessor_Ladder(m_State);
- break;
- case DayZPlayerConstants.COMMANDID_SWIM:
- StaminaProcessor_Swimming(m_State);
- break;
- case DayZPlayerConstants.COMMANDID_FALL: //! processed on event
- case DayZPlayerConstants.COMMANDID_MELEE2: //! processed on event
- case DayZPlayerConstants.COMMANDID_CLIMB: //! processed on event
- break;
- default:
- if (!m_IsInCooldown)
- {
- m_StaminaDelta = GameConstants.STAMINA_GAIN_IDLE_PER_SEC;
- }
- break;
- }
-
- //Sets current stamina & stores + syncs data with client
- float temp = m_StaminaDelta * deltaT;
- if (temp < 0)
- {
- temp *= m_StaminaDepletionMultiplier;
- }
- else
- {
- temp *= m_StaminaRecoveryMultiplier;
- }
-
- m_Stamina = Math.Max(0, Math.Min((m_Stamina + temp), m_StaminaCap));
- m_Stamina = m_Stamina - m_StaminaDepletion;
- if (isServerOrSingleplayer)
- {
- m_Player.GetStatStamina().Set(m_Stamina);
- m_Time += deltaT;
-
- if (m_Time >= GameConstants.STAMINA_SYNC_RATE)
- {
- m_Time = 0;
- SetStamina(m_Stamina);
- }
- }
- #ifndef SERVER
- m_Player.SetStamina(m_StaminaSynced, m_StaminaCap);
- #endif
- ApplyExhaustion();
- CheckStaminaState();
- m_StaminaDelta = 0;
- m_StaminaDepletion = 0; // resets depletion modifier
-
- }
- }
-
- //! deprecated use, StaminaHandler uses SyncJunctures now
- void OnRPC(float stamina, float stamina_cap, bool cooldown)
- {
- }
-
- //! called from PlayerBase - syncs stamina values on server with client AND sets the value to match on server and client both (m_StaminaSynced guarantees identical values)
- void OnSyncJuncture(int pJunctureID, ParamsReadContext pCtx)
- {
- switch ( pJunctureID )
- {
- case DayZPlayerSyncJunctures.SJ_STAMINA:
- float stamina;
- float stamina_cap;
- bool cooldown;
-
- if (!pCtx.Read(stamina) || !pCtx.Read(stamina_cap) || !pCtx.Read(cooldown))
- {
- return;
- }
-
- m_Stamina = stamina; //?
- m_StaminaSynced = stamina;
-
- if (m_Player.GetInstanceType() != DayZPlayerInstanceType.INSTANCETYPE_CLIENT)
- {
- return;
- }
-
- if ( stamina_cap != m_StaminaCap )
- {
- m_StaminaCap = stamina_cap;
- }
-
- m_IsInCooldown = cooldown;
- m_Player.SetStamina(m_Stamina, m_StaminaCap);
- break;
-
- case DayZPlayerSyncJunctures.SJ_STAMINA_MISC:
- ReadAdditionalStaminaInfo(pCtx);
- break;
- }
- }
-
- protected void StaminaProcessor_Move(HumanMovementState pHumanMovementState)
- {
- switch (pHumanMovementState.m_iMovement)
- {
- case DayZPlayerConstants.MOVEMENTIDX_SPRINT: //sprint
- if (pHumanMovementState.m_iStanceIdx == DayZPlayerConstants.STANCEIDX_ERECT)
- {
- m_StaminaDelta = -GameConstants.STAMINA_DRAIN_STANDING_SPRINT_PER_SEC * CfgGameplayHandler.GetSprintStaminaModifierErc();
- SetCooldown(GameConstants.STAMINA_REGEN_COOLDOWN_DEPLETION);
- break;
- }
- else if ( pHumanMovementState.m_iStanceIdx == DayZPlayerConstants.STANCEIDX_CROUCH)
- {
- m_StaminaDelta = -GameConstants.STAMINA_DRAIN_CROUCHED_SPRINT_PER_SEC * CfgGameplayHandler.GetSprintStaminaModifierCro();
- SetCooldown(GameConstants.STAMINA_REGEN_COOLDOWN_DEPLETION);
- break;
- }
- m_StaminaDelta = GameConstants.STAMINA_GAIN_JOG_PER_SEC;
- break;
-
- case DayZPlayerConstants.MOVEMENTIDX_RUN: //jog
- if (m_Player.GetCurrentWaterLevel() >= m_HumanMoveSettings.m_fWaterLevelSpeedRectrictionHigh)
- {
- m_StaminaDelta = -GameConstants.STAMINA_DRAIN_STANDING_SPRINT_PER_SEC * CfgGameplayHandler.GetSprintStaminaModifierErc();
- break;
- }
-
- if (!m_IsInCooldown)
- {
- m_StaminaDelta = (GameConstants.STAMINA_GAIN_JOG_PER_SEC + CalcStaminaGainBonus());
- }
- break;
-
- case DayZPlayerConstants.MOVEMENTIDX_WALK: //walk
- if (!m_IsInCooldown)
- {
- m_StaminaDelta = (GameConstants.STAMINA_GAIN_WALK_PER_SEC + CalcStaminaGainBonus());
- }
- break;
-
- case DayZPlayerConstants.MOVEMENTIDX_IDLE: //idle
- if (m_Player.IsRolling())
- {
- m_StaminaDelta = GameConstants.STAMINA_GAIN_ROLL_PER_SEC;
- break;
- }
- if (!m_IsInCooldown)
- {
- m_StaminaDelta = (GameConstants.STAMINA_GAIN_IDLE_PER_SEC + CalcStaminaGainBonus());
- }
- break;
-
- default:
- if (!m_IsInCooldown)
- {
- m_StaminaDelta = GameConstants.STAMINA_GAIN_IDLE_PER_SEC;
- }
- break;
- }
- }
-
- protected void StaminaProcessor_Ladder(HumanMovementState pHumanMovementState)
- {
- switch (pHumanMovementState.m_iMovement)
- {
- case 2: //climb up (fast)
- m_StaminaDelta = -GameConstants.STAMINA_DRAIN_LADDER_FAST_PER_SEC * CfgGameplayHandler.GetSprintLadderStaminaModifier();
- SetCooldown(GameConstants.STAMINA_REGEN_COOLDOWN_DEPLETION);
- break;
-
- case 1: //climb up (slow)
- if (!m_IsInCooldown)
- {
- m_StaminaDelta = (GameConstants.STAMINA_GAIN_LADDER_PER_SEC + CalcStaminaGainBonus());
- }
- break;
-
- default:
- if (!m_IsInCooldown)
- {
- m_StaminaDelta = GameConstants.STAMINA_GAIN_IDLE_PER_SEC + CalcStaminaGainBonus();
- }
- break;
- }
- }
- protected void StaminaProcessor_Swimming(HumanMovementState pHumanMovementState)
- {
- switch (pHumanMovementState.m_iMovement)
- {
- case 3: //swim fast
- m_StaminaDelta = -GameConstants.STAMINA_DRAIN_SWIM_FAST_PER_SEC * CfgGameplayHandler.GetSprintSwimmingStaminaModifier();
- SetCooldown(GameConstants.STAMINA_REGEN_COOLDOWN_DEPLETION);
- break;
-
-
- case 2: //swim slow
- if (!m_IsInCooldown)
- {
- m_StaminaDelta = (GameConstants.STAMINA_GAIN_SWIM_PER_SEC + CalcStaminaGainBonus());
- }
- break;
-
- default:
- if (!m_IsInCooldown)
- {
- m_StaminaDelta = GameConstants.STAMINA_GAIN_IDLE_PER_SEC + CalcStaminaGainBonus();
- }
- break;
- }
- }
-
- //! stamina sync - server part
- protected void SyncStamina(float stamina, float stamina_cap, bool cooldown)
- {
- m_Player.GetStatStamina().Set(m_Stamina);
- ScriptJunctureData pCtx = new ScriptJunctureData();
- pCtx.Write(m_Stamina);
- pCtx.Write(m_StaminaCap);
- pCtx.Write(m_IsInCooldown);
- m_Player.SendSyncJuncture(DayZPlayerSyncJunctures.SJ_STAMINA,pCtx);
- }
-
- //! Method to sync more info for stamina manager. Template parameter means it is very extendable for further use
- protected void SyncAdditionalStaminaInfo(Param par)
- {
- Param2<float,float> p = Param2<float,float>.Cast(par);
- ScriptJunctureData pCtx = new ScriptJunctureData();
- pCtx.Write(p.param1);
- pCtx.Write(p.param2);
- m_Player.SendSyncJuncture(DayZPlayerSyncJunctures.SJ_STAMINA_MISC,pCtx);
- }
-
- //! Order of read parameters must match the order of writing above
- protected void ReadAdditionalStaminaInfo(ParamsReadContext pCtx)
- {
- float depletionMultiplier;
- float recoveryMultiplier;
- if (!pCtx.Read(depletionMultiplier) || !pCtx.Read(recoveryMultiplier))
- {
- return;
- }
-
- m_StaminaDepletionMultiplier = depletionMultiplier;
- m_StaminaRecoveryMultiplier = recoveryMultiplier;
- }
-
- protected void RegisterStaminaConsumers()
- {
- m_StaminaConsumers = new StaminaConsumers();
- m_StaminaConsumers.RegisterConsumer(
- EStaminaConsumers.HOLD_BREATH,
- GameConstants.STAMINA_HOLD_BREATH_THRESHOLD_ACTIVATE,
- GameConstants.STAMINA_HOLD_BREATH_THRESHOLD_DRAIN,
- );
- m_StaminaConsumers.RegisterConsumer(
- EStaminaConsumers.SPRINT,
- CfgGameplayHandler.GetStaminaMinCap() + 15,
- );
- m_StaminaConsumers.RegisterConsumer(
- EStaminaConsumers.JUMP,
- GameConstants.STAMINA_JUMP_THRESHOLD,
- );
- m_StaminaConsumers.RegisterConsumer(
- EStaminaConsumers.VAULT,
- GameConstants.STAMINA_VAULT_THRESHOLD,
- );
- m_StaminaConsumers.RegisterConsumer(
- EStaminaConsumers.CLIMB,
- GameConstants.STAMINA_CLIMB_THRESHOLD,
- );
- m_StaminaConsumers.RegisterConsumer(
- EStaminaConsumers.MELEE_HEAVY,
- GameConstants.STAMINA_MELEE_HEAVY_THRESHOLD,
- );
- m_StaminaConsumers.RegisterConsumer(
- EStaminaConsumers.MELEE_EVADE,
- GameConstants.STAMINA_MELEE_EVADE_THRESHOLD,
- );
- m_StaminaConsumers.RegisterConsumer(
- EStaminaConsumers.ROLL,
- GameConstants.STAMINA_ROLL_THRESHOLD,
- );
- m_StaminaConsumers.RegisterConsumer(EStaminaConsumers.DROWN, 0);
- m_StaminaConsumers.RegisterConsumer(EStaminaConsumers.PUSH, 0);
- }
- protected void RegisterStaminaModifiers()
- {
- m_StaminaModifiers = new StaminaModifiers();
- SMDataHoldBreath data = new SMDataHoldBreath();
- m_StaminaModifiers.RegisterExponentialEx(
- EStaminaModifiers.HOLD_BREATH,
- data,
- );
- m_StaminaModifiers.RegisterExponentialEx(
- EStaminaModifiers.PUSH_CAR,
- data,
- );
- m_StaminaModifiers.RegisterFixed(EStaminaModifiers.DROWN, 10);
- m_StaminaModifiers.RegisterFixed(
- EStaminaModifiers.JUMP,
- GameConstants.STAMINA_DRAIN_JUMP * CfgGameplayHandler.GetObstacleTraversalStaminaModifier(),
- );
- m_StaminaModifiers.RegisterFixed(
- EStaminaModifiers.VAULT,
- GameConstants.STAMINA_DRAIN_VAULT * CfgGameplayHandler.GetObstacleTraversalStaminaModifier(),
- );
- m_StaminaModifiers.RegisterFixed(
- EStaminaModifiers.CLIMB,
- GameConstants.STAMINA_DRAIN_CLIMB * CfgGameplayHandler.GetObstacleTraversalStaminaModifier(),
- );
- m_StaminaModifiers.RegisterFixed(
- EStaminaModifiers.MELEE_LIGHT,
- GameConstants.STAMINA_DRAIN_MELEE_LIGHT * CfgGameplayHandler.GetMeleeStaminaModifier(),
- );
- m_StaminaModifiers.RegisterFixed(
- EStaminaModifiers.MELEE_HEAVY,
- GameConstants.STAMINA_DRAIN_MELEE_HEAVY * CfgGameplayHandler.GetMeleeStaminaModifier(),
- );
- m_StaminaModifiers.RegisterFixed(
- EStaminaModifiers.OVERALL_DRAIN,
- CfgGameplayHandler.GetStaminaMax(),
- 5.0,
- );
- m_StaminaModifiers.RegisterRandomized(
- EStaminaModifiers.MELEE_EVADE,
- 3 * CfgGameplayHandler.GetMeleeStaminaModifier(),
- GameConstants.STAMINA_DRAIN_MELEE_EVADE * CfgGameplayHandler.GetMeleeStaminaModifier(),
- );
- m_StaminaModifiers.RegisterFixed(EStaminaModifiers.ROLL, GameConstants.STAMINA_DRAIN_ROLL);
- }
- //! Calulates stamina regain bonus coef based on current stamina cap and level
- protected float CalcStaminaGainBonus()
- {
- if (m_StaminaDepletion > 0)
- return 0;
- if (m_Stamina > 25)
- return Math.Min((m_Stamina/10),GameConstants.STAMINA_GAIN_BONUS_CAP); // exp version
- else
- return GameConstants.STAMINA_GAIN_BONUS_CAP; // linear version
- }
- protected void ApplyExhaustion()
- {
- //! sets exhaustion look of player based on stamina level
- HumanCommandAdditives ad = m_Player.GetCommandModifier_Additives();
-
- float exhaustion_value = 1;
- if (m_StaminaCap != 0)
- {
- exhaustion_value = 1 - ((m_Stamina / (m_StaminaCap * 0.01)) * 0.01);
- }
-
- exhaustion_value = Math.Min(1, exhaustion_value);
- if (ad)
- {
- // do not apply exhaustion on local client if player is in ADS/Optics (camera shakes)
- if (m_Player.GetInstanceType() == DayZPlayerInstanceType.INSTANCETYPE_CLIENT && (m_Player.IsInOptics() || m_Player.IsInIronsights()))
- {
- ad.SetExhaustion(0, true);
- }
- else
- {
- ad.SetExhaustion(exhaustion_value, true);
- }
- }
- }
-
- //! check if the stamina is completely depleted
- protected void CheckStaminaState()
- {
- if (m_Stamina <= 0)
- {
- m_StaminaDepleted = true;
- //! in case of complete depletion - start a cooldown timer before the regeneration cycle start
- if (!m_IsInCooldown)
- {
- // set this only once
- SetCooldown(GameConstants.STAMINA_REGEN_COOLDOWN_EXHAUSTION);
- }
- }
- else
- {
- m_StaminaDepleted = false;
- }
- }
- //! set cooldown timer between each consume of stamina
- protected void SetCooldown(float time, int modifier = -1)
- {
- if ( m_StaminaDepleted || m_Stamina <= 0.0 )
- {
- ResetCooldown(modifier);
- return;
- }
- m_IsInCooldown = true;
-
- Timer timer;
- if (m_TimerMap.Find(modifier, timer) && timer.IsRunning())
- {
- timer.Stop();
- }
- else
- {
- timer = new Timer;
- m_TimerMap.Set(modifier,timer);
- }
- timer.Run(time, this, "ResetCooldown", new Param1<int>( modifier ));
- //Print(m_TimerMap.Count());
- }
-
- protected void ResetCooldown(int modifier = -1)
- {
- StaminaModifier sm = m_StaminaModifiers.GetModifierData(modifier);
- if (sm)
- {
- //Print(modifier);
- //Error("Error: No StaminaModifier found! | StaminaHandler | ResetCooldown");
- sm.SetStartTime(-1);
- sm.ResetRunTime();
- sm.SetInUse(false);
- }
- m_IsInCooldown = false;
- }
-
- Timer GetCooldownTimer(int modifier)
- {
-
- }
-
- // ---------------------------------------------------
- bool HasEnoughStaminaFor(EStaminaConsumers consumer)
- {
- return m_StaminaConsumers.HasEnoughStaminaFor(consumer, m_Stamina, m_StaminaDepleted, m_StaminaCap);
- }
-
- bool HasEnoughStaminaToStart(EStaminaConsumers consumer)
- {
- return m_StaminaConsumers.HasEnoughStaminaToStart(consumer, m_Stamina, m_StaminaDepleted, m_StaminaCap);
- }
- void SetStamina(float stamina_value)
- {
- m_Stamina = Math.Clamp(stamina_value, 0, CfgGameplayHandler.GetStaminaMax());
- SyncStamina(m_Stamina, m_StaminaCap, m_IsInCooldown);
- }
-
- float GetStamina()
- {
- return m_Stamina;
- }
- float GetStaminaNormalized()
- {
- return m_Stamina / GetStaminaMax();
- }
- float GetSyncedStamina()
- {
- return m_StaminaSynced;
- }
-
- float GetSyncedStaminaNormalized()
- {
- return GetSyncedStamina() / GetStaminaMax();
- }
-
- float GetStaminaCap()
- {
- return m_StaminaCap;
- }
-
- float GetStaminaMax()
- {
- return CfgGameplayHandler.GetStaminaMax();
- }
-
- //obsolete, use ActivateDepletionModifier/DeactivateDepletionModifier instead
- void SetDepletionMultiplier(float val)
- {
- if (m_StaminaDepletionMultiplier < 0)
- m_StaminaDepletionMultiplier = 0;
- m_StaminaDepletionMultiplier = val;
- SyncAdditionalStaminaInfo(new Param2<float,float>(m_StaminaDepletionMultiplier,m_StaminaRecoveryMultiplier));
- }
- //obsolete, use ActivateRecoveryModifier/DeactivateRecoveryModifier instead
- void SetRecoveryMultiplier(float val)
- {
- if (m_StaminaRecoveryMultiplier < 0)
- m_StaminaRecoveryMultiplier = 0;
- m_StaminaRecoveryMultiplier = val;
- SyncAdditionalStaminaInfo(new Param2<float,float>(m_StaminaDepletionMultiplier,m_StaminaRecoveryMultiplier));
- }
-
- float GetDepletionMultiplier()
- {
- return m_StaminaDepletionMultiplier;
- }
-
- float GetRecoveryMultiplier()
- {
- return m_StaminaRecoveryMultiplier;
- }
-
- void DepleteStamina(EStaminaModifiers modifier, float dT = -1)
- {
- #ifdef DIAG_DEVELOPER
- if (m_StaminaDisabled)
- return;
- #endif
- float val = 0.0;
- float current_time = m_Player.GetSimulationTimeStamp();
- float valueProgress;
- StaminaModifier sm = m_StaminaModifiers.GetModifierData(modifier);
- // select by modifier type and drain stamina
- switch (sm.GetType())
- {
- case m_StaminaModifiers.FIXED:
- if (dT == -1)
- {
- dT = 1;
- }
- m_StaminaDepletion = m_StaminaDepletion + sm.GetMaxValue() * dT;
- break;
-
- case m_StaminaModifiers.RANDOMIZED:
- val = Math.RandomFloat(sm.GetMinValue(), sm.GetMaxValue());
- m_StaminaDepletion = m_StaminaDepletion + val;
- break;
-
- case m_StaminaModifiers.LINEAR:
- if (!sm.IsInUse())
- {
- sm.SetStartTime(current_time + sm.GetStartTimeAdjustment()/dT);
- sm.SetRunTimeTick(dT);
- sm.SetInUse(true);
- }
- valueProgress = Math.Clamp((current_time - sm.GetStartTime())/sm.GetDurationAdjusted(), 0, 1 );
- val = Math.Lerp(sm.GetMinValue(), sm.GetMaxValue(), valueProgress);
- m_StaminaDepletion = m_StaminaDepletion + val;
-
- break;
-
- case m_StaminaModifiers.EXPONENTIAL:
- StaminaModifierExponential smex;
- if (!Class.CastTo(smex,sm))
- {
- ErrorEx("StaminaModifierExponential not found for modifier type: " + sm.GetType());
- break;
- }
-
- if (!smex.IsInUse())
- {
- smex.SetStartTime(current_time + smex.GetStartTimeAdjustment()/dT);
- smex.SetRunTimeTick(dT);
- smex.SetInUse(true);
- }
- valueProgress = Math.Clamp((current_time - smex.GetStartTime())/smex.GetDurationAdjusted(), 0, 1 );
- float exp;
- if (Math.AbsFloat(smex.GetBaseValue()) < 1)
- {
- exp = 1 - Math.Lerp(0, smex.GetExponent(), valueProgress);
- val = Math.Pow(smex.GetBaseValue(),exp);
- }
- else
- {
- exp = Math.Lerp(Math.Min(0, smex.GetExponent()), Math.Max(0, smex.GetExponent()), valueProgress);
- val = Math.Pow(smex.GetBaseValue(),exp) + smex.GetBaseValue() - 1;
- }
-
- m_StaminaDepletion = m_StaminaDepletion + val;
- m_StaminaDepletion *= smex.GetMultiplier();
-
- break;
- }
- //! run cooldown right after depletion
- SetCooldown(sm.GetCooldown(),modifier);
- m_StaminaDepletion = Math.Clamp(m_StaminaDepletion, 0, CfgGameplayHandler.GetStaminaMax());
- m_StaminaDepletion = m_StaminaDepletion * m_StaminaDepletionMultiplier;
- }
-
- #ifdef DIAG_DEVELOPER
- void SetStaminaDisabled(bool value)
- {
- m_StaminaDisabled = value;
- }
- #endif
- }
|