19 class PlayerSwayConstants
22 static const float SWAY_MULTIPLIER_STABLE = 0.05;
23 static const float SWAY_MULTIPLIER_EXHAUSTED = 0.6;
24 static const float SWAY_TIME_IN = 1.5;
25 static const float SWAY_TIME_STABLE = 3.0;
26 static const float SWAY_TIME_EXHAUSTED = 1.5;
27 static const float SWAY_TIME_OUT = 0.5;
28 static const float SWAY_ROLL = 3;
39 protected const float SWAY_WEIGHT_SCALER = 1;
40 protected float m_HorizontalNoise;
41 protected float m_HorizontalTargetValue;
42 protected float m_HorizontalNoiseVelocity[1] = {0};
45 protected float m_TotalTime;
46 protected float m_ReferenceTime = 0;
47 protected float m_SwayStateStartTime;
49 protected float m_LastSwayMultiplier = PlayerSwayConstants.SWAY_MULTIPLIER_DEFAULT;
50 protected float m_StateStartSwayMultiplier;
51 protected float m_HorizontalNoiseXAxisOffset;
52 protected float m_BreathingXAxisOffset;
53 protected float m_BreathingYAxisOffset;
54 protected bool m_HoldingBreathSet;
55 protected bool m_AimNoiseAllowed =
true;
56 protected bool m_ProceduralRecoilEnabled =
true;
58 protected int m_ShakeCount;
59 protected float m_SwayWeight;
60 protected float m_MaxVelocity;
62 protected float m_CamShakeX;
63 protected float m_CamShakeY;
64 protected vector m_SwayModifier =
"1 1 1";
65 protected int m_SwayState = -1;
67 protected float m_StealthAimY_Last;
68 protected float m_FilterVelocityStealthAimY[1] = {0};
70 protected static float m_AimXClampRanges[] = { -180, -20, 90, 0, -50, 90, 180, -20, 90 };
75 Class.CastTo(m_PlayerPb, player);
81 if (m_ProceduralRecoilEnabled)
83 m_CurrentRecoil = weapon.SpawnRecoilObject();
87 void RequestKuruShake(
float amount)
90 m_KuruShake =
new KuruShake(m_PlayerPb, amount);
98 m_SwayModifier = weapon.GetPropertyModifierObject().m_SwayModifiers;
102 void OnFinisherBegin(
float currentAimY)
104 m_StealthAimY_Last = currentAimY;
105 m_FilterVelocityStealthAimY[0] = 0;
108 void OnSwayStateChange(
int state)
113 m_PlayerPb.OnHoldBreathExhausted();
121 float GetSwayWeight()
126 void SetAimNoiseAllowed(
bool state)
128 m_AimNoiseAllowed = state;
131 bool IsAimNoiseAllowed()
133 return m_AimNoiseAllowed;
136 void SetProceduralRecoilEnabled(
bool state)
138 m_ProceduralRecoilEnabled = state;
141 bool IsProceduralRecoilEnabled()
143 return m_ProceduralRecoilEnabled;
146 void SetCamShakeValues(
float x_axis,
float y_axis)
148 m_CamShakeX = x_axis;
149 m_CamShakeY = y_axis;
154 m_StealthAimY_Last =
Math.SmoothCD(m_StealthAimY_Last, 0, m_FilterVelocityStealthAimY, 0.3, 1000, pDt);
155 pModel.m_fAimYMouseShift = -(pModel.m_fCurrentAimY - m_StealthAimY_Last);
161 float breathing_offset_x;
162 float breathing_offset_y;
164 float noise_offset_x;
165 float noise_offset_y;
167 float shake_offset_x;
168 float shake_offset_y;
170 float recoil_offset_mouse_x;
171 float recoil_offset_mouse_y;
173 float recoil_offset_hands_x;
174 float recoil_offset_hands_y;
179 float player_stamina = m_PlayerPb.GetStaminaHandler().GetSyncedStaminaNormalized();
182 DbgPrintAimingImplement(
"Player: " + m_PlayerPb +
" | ProcessAimFilters | timestamp: " + m_PlayerPb.GetSimulationTimeStamp());
186 if (m_PlayerPb.IsHoldingBreath())
190 float speed = CalculateSpeedMultiplier(player_stamina);
191 m_TotalTime += pDt * speed;
193 if (m_PlayerPb.IsHoldingBreath() && !m_HoldingBreathSet)
195 m_ReferenceTime = m_TotalTime;
197 else if (!m_PlayerPb.IsHoldingBreath() && m_HoldingBreathSet)
199 m_ReferenceTime = m_TotalTime;
202 float adjusted_sway_multiplier = CalculateSwayMultiplier();
203 m_LastSwayMultiplier = adjusted_sway_multiplier;
205 m_SwayWeight = CalculateWeight( stance_index, player_stamina, 0.5, m_PlayerPb.IsHoldingBreath()) * adjusted_sway_multiplier;
208 ApplyBreathingPattern(breathing_offset_x, breathing_offset_y, 3.0, m_TotalTime, m_SwayWeight);
209 ApplyHorizontalNoise(noise_offset_x, noise_offset_y, 0.2, 0.5, 3.0 * m_SwayModifier[0], speed, 3 * m_SwayModifier[1], m_SwayWeight, pDt);
211 int shake_level = m_PlayerPb.GetShakeLevel();
212 if (shake_level != 0)
214 ApplyShakes(shake_offset_x, shake_offset_y, shake_level);
220 m_CurrentRecoil.Update(pModel, recoil_offset_mouse_x, recoil_offset_mouse_y, recoil_offset_hands_x, recoil_offset_hands_y, pDt);
225 m_KuruShake.Update(pDt, kuru_offset_x, kuru_offset_y);
229 pModel.m_fAimXHandsOffset = breathing_offset_x + noise_offset_x + recoil_offset_hands_x + shake_offset_x + kuru_offset_x;
230 pModel.m_fAimYHandsOffset = breathing_offset_y + noise_offset_y + recoil_offset_hands_y + shake_offset_y + kuru_offset_y;
233 DbgPrintAimingImplement(
"breathing_offset_y: " + breathing_offset_y);
234 DbgPrintAimingImplement(
"noise_offset_y: " + noise_offset_y);
235 DbgPrintAimingImplement(
"recoil_offset_hands_y: " + recoil_offset_hands_y);
236 DbgPrintAimingImplement(
"shake_offset_y: " + shake_offset_y);
237 DbgPrintAimingImplement(
"kuru_offset_y: " + kuru_offset_y);
238 DbgPrintAimingImplement(
"pModel.m_fAimYHandsOffset: " + pModel.m_fAimYHandsOffset);
240 pModel.m_fAimXCamOffset = -shake_offset_x - recoil_offset_hands_x - kuru_offset_x + m_CamShakeX;
242 pModel.m_fAimYCamOffset = -shake_offset_y - recoil_offset_hands_y - kuru_offset_y + m_CamShakeY;
246 DbgPrintAimingImplement(
"m_CamShakeY: " + m_CamShakeY);
247 DbgPrintAimingImplement(
"pModel.m_fAimYCamOffset: " + pModel.m_fAimYCamOffset);
253 float newVal =
DayZPlayerUtils.LinearRangeClamp(pModel.m_fCurrentAimX, pModel.m_fCurrentAimY, m_AimXClampRanges);
254 pModel.m_fAimYHandsOffset += newVal - pModel.m_fCurrentAimY;
256 float absAimY =
Math.AbsFloat(pModel.m_fCurrentAimY);
257 pModel.m_fAimYHandsOffset =
Math.Clamp(pModel.m_fAimYHandsOffset,absAimY - 89.9,89.9 - absAimY);
259 if (m_PlayerDpi.IsInOptics() && m_KuruShake)
264 pModel.m_fAimXMouseShift = recoil_offset_mouse_x -kuru_offset_x / 10;
265 pModel.m_fAimYMouseShift = recoil_offset_mouse_y + kuru_offset_y / 10;
268 DbgPrintAimingImplement(
"recoil_offset_mouse_y: " + recoil_offset_mouse_y);
269 DbgPrintAimingImplement(
"pModel.m_fAimYMouseShift: " + pModel.m_fAimYMouseShift);
272 if (m_PlayerPb.IsHoldingBreath() && !m_HoldingBreathSet)
274 m_HoldingBreathSet =
true;
275 m_HorizontalNoiseXAxisOffset = noise_offset_x;
276 m_BreathingXAxisOffset = breathing_offset_x;
277 m_BreathingYAxisOffset = breathing_offset_y;
279 else if (!m_PlayerPb.IsHoldingBreath() && m_HoldingBreathSet)
281 m_HoldingBreathSet =
false;
284 if (!m_PlayerPb.IsHoldingBreath() && m_LastSwayMultiplier == PlayerSwayConstants.SWAY_MULTIPLIER_DEFAULT && m_HorizontalNoiseXAxisOffset != 0)
286 m_HorizontalNoiseXAxisOffset = 0;
287 m_BreathingXAxisOffset = 0;
288 m_BreathingYAxisOffset = 0;
291 if (m_PlayerPb.IsHoldingBreath())
296 DbgPrintAimingImplement(
"----------------------------");
301 protected float CalculateSwayMultiplier()
308 if (m_PlayerPb.IsHoldingBreath())
310 time = m_TotalTime - m_ReferenceTime;
312 if (time < PlayerSwayConstants.SWAY_TIME_IN)
315 max = PlayerSwayConstants.SWAY_TIME_IN;
316 time_clamped =
Math.Clamp((m_TotalTime - m_SwayStateStartTime),0,max);
317 ret =
Math.Lerp(m_LastSwayMultiplier,PlayerSwayConstants.SWAY_MULTIPLIER_STABLE,time_clamped/max);
319 else if (time >= PlayerSwayConstants.SWAY_TIME_IN && time < (PlayerSwayConstants.SWAY_TIME_IN + PlayerSwayConstants.SWAY_TIME_STABLE))
322 ret = PlayerSwayConstants.SWAY_MULTIPLIER_STABLE;
327 max = PlayerSwayConstants.SWAY_TIME_EXHAUSTED;
328 time_clamped =
Math.Clamp((m_TotalTime - m_SwayStateStartTime),0,max);
329 ret =
Math.Lerp(PlayerSwayConstants.SWAY_MULTIPLIER_STABLE,PlayerSwayConstants.SWAY_MULTIPLIER_EXHAUSTED,(time_clamped/max));
335 max = PlayerSwayConstants.SWAY_TIME_OUT;
336 time_clamped =
Math.Clamp((m_TotalTime - m_SwayStateStartTime),0,max);
337 ret =
Math.Lerp(m_LastSwayMultiplier,1,time_clamped/max);
342 float CalculateSpeedMultiplier(
float stamina)
344 return (((1.0 - stamina) * 3.0) + 1.0) * m_SwayModifier[2];
347 protected bool UpdateSwayState(
int state)
349 if (state != m_SwayState)
352 m_SwayStateStartTime = m_TotalTime;
353 m_StateStartSwayMultiplier = m_LastSwayMultiplier;
354 OnSwayStateChange(state);
361 int GetCurrentSwayState()
366 protected void ApplyBreathingPattern(out
float x_axis, out
float y_axis,
float pAmplitude,
float pTotalTime,
float weight)
369 float multiplier =
Math.Lerp(PlayerSwayConstants.SWAY_MULTIPLIER_DEFAULT,0,m_LastSwayMultiplier);
371 DbgPrintAimingImplement(
"m_LastSwayMultiplier: " + m_LastSwayMultiplier);
372 DbgPrintAimingImplement(
"pAmplitude: " + pAmplitude);
373 DbgPrintAimingImplement(
"pTotalTime: " + pTotalTime);
374 DbgPrintAimingImplement(
"weight: " + weight);
375 DbgPrintAimingImplement(
"multiplier: " + multiplier);
378 x_axis = (
Math.Sin(pTotalTime) * pAmplitude / 4) * weight;
379 y_axis = (
Math.Sin((pTotalTime) * 0.8 + 0.6) * pAmplitude) * weight;
381 DbgPrintAimingImplement(
"y_axis_midproduct: " + y_axis);
383 x_axis += m_BreathingXAxisOffset * multiplier;
384 y_axis += m_BreathingYAxisOffset * multiplier;
387 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)
389 if (
Math.AbsFloat(m_HorizontalTargetValue - m_HorizontalNoise) < 0.01)
392 m_MaxVelocity = m_PlayerPb.GetRandomGeneratorSyncManager().GetRandomInRange(
RandomGeneratorSyncUsage.RGSAimingModel, max_velocity_low, max_velocity_high);
394 float r = m_PlayerPb.GetRandomGeneratorSyncManager().GetRandomInRange(
RandomGeneratorSyncUsage.RGSAimingModel, 0, 1);
395 m_HorizontalTargetValue = (r - 0.5) * 2 * max_distance;
396 m_HorizontalNoiseVelocity[0] = 0;
399 m_HorizontalNoise =
Math.SmoothCD(m_HorizontalNoise, m_HorizontalTargetValue, m_HorizontalNoiseVelocity, smooth_time, m_MaxVelocity * velocity_modifier, pDt);
400 x_axis = m_HorizontalNoise * weight;
401 float multiplier =
Math.Lerp(PlayerSwayConstants.SWAY_MULTIPLIER_DEFAULT,0,m_LastSwayMultiplier);
402 x_axis += m_HorizontalNoiseXAxisOffset * multiplier;
405 protected void ApplyShakes(out
float x_axis, out
float y_axis,
int level)
407 float weight = level /
PlayerBase.SHAKE_LEVEL_MAX;
409 int shakes_threshold =
Math.Round(m_PlayerPb.GetRandomGeneratorSyncManager().GetRandomInRange(
RandomGeneratorSyncUsage.RGSAimingModel, 2, 4));
410 if (m_ShakeCount > shakes_threshold)
414 float modifier = m_PlayerPb.GetRandomGeneratorSyncManager().GetRandomInRange(
RandomGeneratorSyncUsage.RGSAimingModel, 0.45, 0.9);
415 x_axis = modifier * weight * m_PlayerPb.GetRandomGeneratorSyncManager().GetRandomInRange(
RandomGeneratorSyncUsage.RGSAimingModel, 0, 1);
416 y_axis = modifier * weight * m_PlayerPb.GetRandomGeneratorSyncManager().GetRandomInRange(
RandomGeneratorSyncUsage.RGSAimingModel, 0, 1);
420 protected float CalculateWeight(
int stance_index,
float current_stamina,
float camera_sway_modifier,
bool holding_breath)
422 if (m_PlayerDpi.GetCommand_Move() && m_PlayerDpi.GetCommand_Move().IsInRoll())
424 return PlayerSwayConstants.SWAY_ROLL;
426 float stance_modifier;
427 switch (stance_index)
430 stance_modifier = 0.5;
433 stance_modifier = 0.75;
436 stance_modifier = 0.9;
439 stance_modifier = 0.75;
445 DbgPrintAimingImplement(
"current_stamina: " + current_stamina);
446 DbgPrintAimingImplement(
"camera_sway_modifier: " + camera_sway_modifier);
447 DbgPrintAimingImplement(
"holding_breath: " + holding_breath);
450 return (1 - stance_modifier) * m_AimNoiseAllowed * camera_sway_modifier * SWAY_WEIGHT_SCALER;
453 void DbgPrintAimingImplement(
string val)
457 Print(
"DayZPlayerImplementAiming | " + val);