123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461 |
- /*
- DayZPlayerImplement
- this file is implemenation of dayzPlayer in script
- - logic of movement
- - camera switching logic
- */
- enum eSwayStates
- {
- DEFAULT,
- HOLDBREATH_IN,
- HOLDBREATH_STABLE,
- HOLDBREATH_EXHAUSTED,
- MAX
- }
- class PlayerSwayConstants
- {
- static const float SWAY_MULTIPLIER_DEFAULT = 1.0;
- static const float SWAY_MULTIPLIER_STABLE = 0.05;
- static const float SWAY_MULTIPLIER_EXHAUSTED = 0.6;
- static const float SWAY_TIME_IN = 1.5;
- static const float SWAY_TIME_STABLE = 3.0;
- static const float SWAY_TIME_EXHAUSTED = 1.5;
- static const float SWAY_TIME_OUT = 0.5;
- static const float SWAY_ROLL = 3;
- }
- class DayZPlayerImplementAiming
- {
- //-------------------------------------------------------------
- //!
- //! This HeadingModel - Clamps heading
- //!
-
- protected const float SWAY_WEIGHT_SCALER = 1;//use this to scale the sway effect up/down
- protected float m_HorizontalNoise;
- protected float m_HorizontalTargetValue;
- protected float m_HorizontalNoiseVelocity[1] = {0};
- protected DayZPlayerImplement m_PlayerDpi;
- protected PlayerBase m_PlayerPb;
- protected float m_TotalTime;
- protected float m_ReferenceTime = 0;
- protected float m_SwayStateStartTime;
- //protected float m_SwayStateStartTime[eSwayStates.MAX];
- protected float m_LastSwayMultiplier = PlayerSwayConstants.SWAY_MULTIPLIER_DEFAULT;
- protected float m_StateStartSwayMultiplier;
- protected float m_HorizontalNoiseXAxisOffset;
- protected float m_BreathingXAxisOffset;
- protected float m_BreathingYAxisOffset;
- protected bool m_HoldingBreathSet;
- protected bool m_AimNoiseAllowed = true;
- protected bool m_ProceduralRecoilEnabled = true;
- protected ref RecoilBase m_CurrentRecoil;
- protected int m_ShakeCount;
- protected float m_SwayWeight;
- protected float m_MaxVelocity;
- protected ref KuruShake m_KuruShake;
- protected float m_CamShakeX;
- protected float m_CamShakeY;
- protected vector m_SwayModifier = "1 1 1";//"max_speed_noise radius_noise overall_speed"
- protected int m_SwayState = -1;
-
- protected float m_StealthAimY_Last;
- protected float m_FilterVelocityStealthAimY[1] = {0};
-
- protected static float m_AimXClampRanges[] = { -180, -20, 90, 0, -50, 90, 180, -20, 90 };
-
- void DayZPlayerImplementAiming(DayZPlayerImplement player)
- {
- m_PlayerDpi = player;
- Class.CastTo(m_PlayerPb, player);
- UpdateSwayState(eSwayStates.DEFAULT);
- }
- void SetRecoil(Weapon_Base weapon)
- {
- if (m_ProceduralRecoilEnabled)
- {
- m_CurrentRecoil = weapon.SpawnRecoilObject();
- }
- }
-
- void RequestKuruShake(float amount)
- {
- if (!m_KuruShake)
- m_KuruShake = new KuruShake(m_PlayerPb, amount);
- }
-
- void OnRaiseBegin(DayZPlayerImplement player)
- {
- Weapon_Base weapon = Weapon_Base.Cast(player.GetHumanInventory().GetEntityInHands());
- if (weapon)
- {
- m_SwayModifier = weapon.GetPropertyModifierObject().m_SwayModifiers;
- }
- }
-
- void OnFinisherBegin(float currentAimY)
- {
- m_StealthAimY_Last = currentAimY;
- m_FilterVelocityStealthAimY[0] = 0;
- }
-
- void OnSwayStateChange(int state)
- {
- switch (state)
- {
- case eSwayStates.HOLDBREATH_EXHAUSTED:
- m_PlayerPb.OnHoldBreathExhausted();
- break;
-
- default:
- break;
- }
- }
-
- float GetSwayWeight()
- {
- return m_SwayWeight;
- }
-
- void SetAimNoiseAllowed(bool state)
- {
- m_AimNoiseAllowed = state;
- }
-
- bool IsAimNoiseAllowed()
- {
- return m_AimNoiseAllowed;
- }
- void SetProceduralRecoilEnabled(bool state)
- {
- m_ProceduralRecoilEnabled = state;
- }
- bool IsProceduralRecoilEnabled()
- {
- return m_ProceduralRecoilEnabled;
- }
-
- void SetCamShakeValues(float x_axis, float y_axis)
- {
- m_CamShakeX = x_axis;
- m_CamShakeY = y_axis;
- }
- bool ProcessStealthFilters(float pDt, SDayZPlayerAimingModel pModel)
- {
- m_StealthAimY_Last = Math.SmoothCD(m_StealthAimY_Last, 0, m_FilterVelocityStealthAimY, 0.3, 1000, pDt);
- pModel.m_fAimYMouseShift = -(pModel.m_fCurrentAimY - m_StealthAimY_Last);
- return true;
- }
-
- bool ProcessAimFilters(float pDt, SDayZPlayerAimingModel pModel, int stance_index)
- {
- float breathing_offset_x;
- float breathing_offset_y;
-
- float noise_offset_x;
- float noise_offset_y;
-
- float shake_offset_x;
- float shake_offset_y;
-
- float recoil_offset_mouse_x;
- float recoil_offset_mouse_y;
-
- float recoil_offset_hands_x;
- float recoil_offset_hands_y;
-
- float kuru_offset_x;
- float kuru_offset_y;
-
- float player_stamina = m_PlayerPb.GetStaminaHandler().GetSyncedStaminaNormalized();
-
- #ifdef DEVELOPER
- DbgPrintAimingImplement("Player: " + m_PlayerPb + " | ProcessAimFilters | timestamp: " + m_PlayerPb.GetSimulationTimeStamp());
- #endif
-
- //negates stamina effect during hold breath
- if (m_PlayerPb.IsHoldingBreath())
- {
- player_stamina = 1;
- }
- float speed = CalculateSpeedMultiplier(player_stamina);
- m_TotalTime += pDt * speed;
-
- if (m_PlayerPb.IsHoldingBreath() && !m_HoldingBreathSet)
- {
- m_ReferenceTime = m_TotalTime;
- }
- else if (!m_PlayerPb.IsHoldingBreath() && m_HoldingBreathSet)
- {
- m_ReferenceTime = m_TotalTime;
- }
-
- float adjusted_sway_multiplier = CalculateSwayMultiplier();
- m_LastSwayMultiplier = adjusted_sway_multiplier;
-
- m_SwayWeight = CalculateWeight( stance_index, player_stamina, 0.5/*m_PlayerPb.m_CameraSwayModifier*/, m_PlayerPb.IsHoldingBreath()) * adjusted_sway_multiplier;
- //! get sway
- ApplyBreathingPattern(breathing_offset_x, breathing_offset_y, 3.0, m_TotalTime, m_SwayWeight);
- ApplyHorizontalNoise(noise_offset_x, noise_offset_y, 0.2, 0.5, 3.0 * m_SwayModifier[0], speed, 3 * m_SwayModifier[1], m_SwayWeight, pDt);
-
- int shake_level = m_PlayerPb.GetShakeLevel();
- if (shake_level != 0)
- {
- ApplyShakes(shake_offset_x, shake_offset_y, shake_level);
- }
- //! get recoil
- if (m_CurrentRecoil)
- {
- m_CurrentRecoil.Update(pModel, recoil_offset_mouse_x, recoil_offset_mouse_y, recoil_offset_hands_x, recoil_offset_hands_y, pDt);
- }
-
- if (m_KuruShake)
- {
- m_KuruShake.Update(pDt, kuru_offset_x, kuru_offset_y);
- }
-
- //! hands offset
- pModel.m_fAimXHandsOffset = breathing_offset_x + noise_offset_x + recoil_offset_hands_x + shake_offset_x + kuru_offset_x;
- pModel.m_fAimYHandsOffset = breathing_offset_y + noise_offset_y + recoil_offset_hands_y + shake_offset_y + kuru_offset_y;
-
- #ifdef DEVELOPER
- DbgPrintAimingImplement("breathing_offset_y: " + breathing_offset_y);
- DbgPrintAimingImplement("noise_offset_y: " + noise_offset_y);
- DbgPrintAimingImplement("recoil_offset_hands_y: " + recoil_offset_hands_y);
- DbgPrintAimingImplement("shake_offset_y: " + shake_offset_y);
- DbgPrintAimingImplement("kuru_offset_y: " + kuru_offset_y);
- DbgPrintAimingImplement("pModel.m_fAimYHandsOffset: " + pModel.m_fAimYHandsOffset);
- #endif
- //! cam offset
- pModel.m_fAimXCamOffset = -shake_offset_x - recoil_offset_hands_x - kuru_offset_x + m_CamShakeX;
- pModel.m_fAimYCamOffset = -shake_offset_y - recoil_offset_hands_y - kuru_offset_y + m_CamShakeY;
-
-
- #ifdef DEVELOPER
- DbgPrintAimingImplement("m_CamShakeY: " + m_CamShakeY);
- DbgPrintAimingImplement("pModel.m_fAimYCamOffset: " + pModel.m_fAimYCamOffset);
- #endif
-
- //! clamp aim ranges
- if (stance_index == DayZPlayerConstants.STANCEIDX_RAISEDPRONE)
- {
- float newVal = DayZPlayerUtils.LinearRangeClamp(pModel.m_fCurrentAimX, pModel.m_fCurrentAimY, m_AimXClampRanges);
- pModel.m_fAimYHandsOffset += newVal - pModel.m_fCurrentAimY;
- }
- float absAimY = Math.AbsFloat(pModel.m_fCurrentAimY);
- pModel.m_fAimYHandsOffset = Math.Clamp(pModel.m_fAimYHandsOffset,absAimY - 89.9,89.9 - absAimY); //'90' leads to rounding errors down the line
-
- if (m_PlayerDpi.IsInOptics() && m_KuruShake)
- {
- //TODO - do not offset mouse
- }
- //! mouse offset
- pModel.m_fAimXMouseShift = recoil_offset_mouse_x -kuru_offset_x / 10;
- pModel.m_fAimYMouseShift = recoil_offset_mouse_y + kuru_offset_y / 10;
- #ifdef DEVELOPER
- DbgPrintAimingImplement("recoil_offset_mouse_y: " + recoil_offset_mouse_y);
- DbgPrintAimingImplement("pModel.m_fAimYMouseShift: " + pModel.m_fAimYMouseShift);
- #endif
-
- if (m_PlayerPb.IsHoldingBreath() && !m_HoldingBreathSet)
- {
- m_HoldingBreathSet = true;
- m_HorizontalNoiseXAxisOffset = noise_offset_x;
- m_BreathingXAxisOffset = breathing_offset_x;
- m_BreathingYAxisOffset = breathing_offset_y;
- }
- else if (!m_PlayerPb.IsHoldingBreath() && m_HoldingBreathSet)
- {
- m_HoldingBreathSet = false;
- }
-
- if (!m_PlayerPb.IsHoldingBreath() && m_LastSwayMultiplier == PlayerSwayConstants.SWAY_MULTIPLIER_DEFAULT && m_HorizontalNoiseXAxisOffset != 0)
- {
- m_HorizontalNoiseXAxisOffset = 0;
- m_BreathingXAxisOffset = 0;
- m_BreathingYAxisOffset = 0;
- }
-
- if (m_PlayerPb.IsHoldingBreath())
- {
- m_PlayerPb.DepleteStamina(EStaminaModifiers.HOLD_BREATH,pDt*speed);
- }
- #ifdef DEVELOPER
- DbgPrintAimingImplement("----------------------------");
- #endif
- return true;
- }
-
- protected float CalculateSwayMultiplier()
- {
- float max;
- float time;
- float time_clamped;
- float ret;
-
- if (m_PlayerPb.IsHoldingBreath())
- {
- time = m_TotalTime - m_ReferenceTime;
-
- if (time < PlayerSwayConstants.SWAY_TIME_IN)
- {
- UpdateSwayState(eSwayStates.HOLDBREATH_IN);
- max = PlayerSwayConstants.SWAY_TIME_IN;
- time_clamped = Math.Clamp((m_TotalTime - m_SwayStateStartTime),0,max);
- ret = Math.Lerp(m_LastSwayMultiplier,PlayerSwayConstants.SWAY_MULTIPLIER_STABLE,time_clamped/max);
- }
- else if (time >= PlayerSwayConstants.SWAY_TIME_IN && time < (PlayerSwayConstants.SWAY_TIME_IN + PlayerSwayConstants.SWAY_TIME_STABLE))
- {
- UpdateSwayState(eSwayStates.HOLDBREATH_STABLE);
- ret = PlayerSwayConstants.SWAY_MULTIPLIER_STABLE;
- }
- else
- {
- UpdateSwayState(eSwayStates.HOLDBREATH_EXHAUSTED);
- max = PlayerSwayConstants.SWAY_TIME_EXHAUSTED;
- time_clamped = Math.Clamp((m_TotalTime - m_SwayStateStartTime),0,max);
- ret = Math.Lerp(PlayerSwayConstants.SWAY_MULTIPLIER_STABLE,PlayerSwayConstants.SWAY_MULTIPLIER_EXHAUSTED,(time_clamped/max));
- }
- }
- else
- {
- UpdateSwayState(eSwayStates.DEFAULT);
- max = PlayerSwayConstants.SWAY_TIME_OUT;
- time_clamped = Math.Clamp((m_TotalTime - m_SwayStateStartTime),0,max);
- ret = Math.Lerp(m_LastSwayMultiplier,1,time_clamped/max);
- }
- return ret;
- }
-
- float CalculateSpeedMultiplier(float stamina)
- {
- return (((1.0 - stamina) * 3.0) + 1.0) * m_SwayModifier[2]; // just 'm_SwayModifier[2]' for HoldBreath
- }
-
- protected bool UpdateSwayState(int state)
- {
- if (state != m_SwayState)
- {
- m_SwayState = state;
- m_SwayStateStartTime = m_TotalTime;
- m_StateStartSwayMultiplier = m_LastSwayMultiplier;
- OnSwayStateChange(state);
- return true;
- }
-
- return false;
- }
-
- int GetCurrentSwayState()
- {
- return m_SwayState;
- }
- protected void ApplyBreathingPattern(out float x_axis, out float y_axis, float pAmplitude, float pTotalTime, float weight)
- {
- float multiplier = Math.Lerp(PlayerSwayConstants.SWAY_MULTIPLIER_DEFAULT,0,m_LastSwayMultiplier); //TODO revise
- #ifdef DEVELOPER
- DbgPrintAimingImplement("m_LastSwayMultiplier: " + m_LastSwayMultiplier);
- DbgPrintAimingImplement("pAmplitude: " + pAmplitude);
- DbgPrintAimingImplement("pTotalTime: " + pTotalTime);
- DbgPrintAimingImplement("weight: " + weight);
- DbgPrintAimingImplement("multiplier: " + multiplier);
- #endif
-
- x_axis = (Math.Sin(pTotalTime) * pAmplitude / 4) * weight;
- y_axis = (Math.Sin((pTotalTime) * 0.8 + 0.6) * pAmplitude) * weight;
- #ifdef DEVELOPER
- DbgPrintAimingImplement("y_axis_midproduct: " + y_axis);
- #endif
- x_axis += m_BreathingXAxisOffset * multiplier;
- y_axis += m_BreathingYAxisOffset * multiplier;
- }
- protected void ApplyHorizontalNoise(out float x_axis, out float y_axis, float smooth_time,float max_velocity_low, float max_velocity_high, float velocity_modifier, float max_distance, float weight, float pDt)
- {
- if (Math.AbsFloat(m_HorizontalTargetValue - m_HorizontalNoise) < 0.01)
- {
- //acquire new target
- m_MaxVelocity = m_PlayerPb.GetRandomGeneratorSyncManager().GetRandomInRange(RandomGeneratorSyncUsage.RGSAimingModel, max_velocity_low, max_velocity_high);
- float r = m_PlayerPb.GetRandomGeneratorSyncManager().GetRandomInRange(RandomGeneratorSyncUsage.RGSAimingModel, 0, 1);
- m_HorizontalTargetValue = (r - 0.5) * 2 * max_distance;
- m_HorizontalNoiseVelocity[0] = 0;
- }
- m_HorizontalNoise = Math.SmoothCD(m_HorizontalNoise, m_HorizontalTargetValue, m_HorizontalNoiseVelocity, smooth_time, m_MaxVelocity * velocity_modifier, pDt);
- x_axis = m_HorizontalNoise * weight;
- float multiplier = Math.Lerp(PlayerSwayConstants.SWAY_MULTIPLIER_DEFAULT,0,m_LastSwayMultiplier); //TODO revise
- x_axis += m_HorizontalNoiseXAxisOffset * multiplier;
- }
-
- protected void ApplyShakes(out float x_axis, out float y_axis, int level)
- {
- float weight = level / PlayerBase.SHAKE_LEVEL_MAX;
- m_ShakeCount++;
- int shakes_threshold = Math.Round(m_PlayerPb.GetRandomGeneratorSyncManager().GetRandomInRange(RandomGeneratorSyncUsage.RGSAimingModel, 2, 4));
- if (m_ShakeCount > shakes_threshold)
- {
- m_ShakeCount = 0;
- float modifier = m_PlayerPb.GetRandomGeneratorSyncManager().GetRandomInRange(RandomGeneratorSyncUsage.RGSAimingModel, 0.45, 0.9);
- x_axis = modifier * weight * m_PlayerPb.GetRandomGeneratorSyncManager().GetRandomInRange(RandomGeneratorSyncUsage.RGSAimingModel, 0, 1);
- y_axis = modifier * weight * m_PlayerPb.GetRandomGeneratorSyncManager().GetRandomInRange(RandomGeneratorSyncUsage.RGSAimingModel, 0, 1);
- }
- }
- protected float CalculateWeight(int stance_index, float current_stamina, float camera_sway_modifier, bool holding_breath)
- {
- if (m_PlayerDpi.GetCommand_Move() && m_PlayerDpi.GetCommand_Move().IsInRoll())//when the player is rolling, set a constant and disregard everything else
- {
- return PlayerSwayConstants.SWAY_ROLL;
- }
- float stance_modifier;
- switch (stance_index)
- {
- case DayZPlayerConstants.STANCEIDX_RAISEDERECT:
- stance_modifier = 0.5;
- break;
- case DayZPlayerConstants.STANCEIDX_RAISEDCROUCH:
- stance_modifier = 0.75;
- break;
- case DayZPlayerConstants.STANCEIDX_RAISEDPRONE:
- stance_modifier = 0.9;
- break;
- default:
- stance_modifier = 0.75;
- //Debug.LogError("stance mask out of definition");
- break;
- }
-
- #ifdef DEVELOPER
- DbgPrintAimingImplement("current_stamina: " + current_stamina);
- DbgPrintAimingImplement("camera_sway_modifier: " + camera_sway_modifier);
- DbgPrintAimingImplement("holding_breath: " + holding_breath);
- #endif
-
- return (1 - stance_modifier) * m_AimNoiseAllowed * camera_sway_modifier * SWAY_WEIGHT_SCALER;
- }
-
- void DbgPrintAimingImplement(string val)
- {
- #ifdef DEVELOPER
- if (GetDayZGame().IsAimLogEnabled())
- Print("DayZPlayerImplementAiming | " + val);
- #endif
- }
- }
|