Dayz Explorer  1.24.157551 (v105080)
Dayz Code Explorer by Zeroy
dayzplayerimplementaiming.c
Go to the documentation of this file.
1 /*
2 DayZPlayerImplement
3 
4 this file is implemenation of dayzPlayer in script
5 - logic of movement
6 - camera switching logic
7 
8 */
9 
11 {
17 }
18 
19 class PlayerSwayConstants
20 {
21  static const float SWAY_MULTIPLIER_DEFAULT = 1.0;
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;
29 }
30 
32 {
33 
34  //-------------------------------------------------------------
38 
39  protected const float SWAY_WEIGHT_SCALER = 1;//use this to scale the sway effect up/down
40  protected float m_HorizontalNoise;
41  protected float m_HorizontalTargetValue;
42  protected float m_HorizontalNoiseVelocity[1] = {0};
43  protected DayZPlayerImplement m_PlayerDpi;
44  protected PlayerBase m_PlayerPb;
45  protected float m_TotalTime;
46  protected float m_ReferenceTime = 0;
47  protected float m_SwayStateStartTime;
48  //protected float m_SwayStateStartTime[eSwayStates.MAX];
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;
57  protected ref RecoilBase m_CurrentRecoil;
58  protected int m_ShakeCount;
59  protected float m_SwayWeight;
60  protected float m_MaxVelocity;
61  protected ref KuruShake m_KuruShake;
62  protected float m_CamShakeX;
63  protected float m_CamShakeY;
64  protected vector m_SwayModifier = "1 1 1";//"max_speed_noise radius_noise overall_speed"
65  protected int m_SwayState = -1;
66 
67  protected float m_StealthAimY_Last;
68  protected float m_FilterVelocityStealthAimY[1] = {0};
69 
70  protected static float m_AimXClampRanges[] = { -180, -20, 90, 0, -50, 90, 180, -20, 90 };
71 
73  {
74  m_PlayerDpi = player;
75  Class.CastTo(m_PlayerPb, player);
76  UpdateSwayState(eSwayStates.DEFAULT);
77  }
78 
79  void SetRecoil(Weapon_Base weapon)
80  {
81  if (m_ProceduralRecoilEnabled)
82  {
83  m_CurrentRecoil = weapon.SpawnRecoilObject();
84  }
85  }
86 
87  void RequestKuruShake(float amount)
88  {
89  if (!m_KuruShake)
90  m_KuruShake = new KuruShake(m_PlayerPb, amount);
91  }
92 
93  void OnRaiseBegin(DayZPlayerImplement player)
94  {
95  Weapon_Base weapon = Weapon_Base.Cast(player.GetHumanInventory().GetEntityInHands());
96  if (weapon)
97  {
98  m_SwayModifier = weapon.GetPropertyModifierObject().m_SwayModifiers;
99  }
100  }
101 
102  void OnFinisherBegin(float currentAimY)
103  {
104  m_StealthAimY_Last = currentAimY;
105  m_FilterVelocityStealthAimY[0] = 0;
106  }
107 
108  void OnSwayStateChange(int state)
109  {
110  switch (state)
111  {
112  case eSwayStates.HOLDBREATH_EXHAUSTED:
113  m_PlayerPb.OnHoldBreathExhausted();
114  break;
115 
116  default:
117  break;
118  }
119  }
120 
121  float GetSwayWeight()
122  {
123  return m_SwayWeight;
124  }
125 
126  void SetAimNoiseAllowed(bool state)
127  {
128  m_AimNoiseAllowed = state;
129  }
130 
131  bool IsAimNoiseAllowed()
132  {
133  return m_AimNoiseAllowed;
134  }
135 
136  void SetProceduralRecoilEnabled(bool state)
137  {
138  m_ProceduralRecoilEnabled = state;
139  }
140 
141  bool IsProceduralRecoilEnabled()
142  {
143  return m_ProceduralRecoilEnabled;
144  }
145 
146  void SetCamShakeValues(float x_axis, float y_axis)
147  {
148  m_CamShakeX = x_axis;
149  m_CamShakeY = y_axis;
150  }
151 
152  bool ProcessStealthFilters(float pDt, SDayZPlayerAimingModel pModel)
153  {
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);
156  return true;
157  }
158 
159  bool ProcessAimFilters(float pDt, SDayZPlayerAimingModel pModel, int stance_index)
160  {
161  float breathing_offset_x;
162  float breathing_offset_y;
163 
164  float noise_offset_x;
165  float noise_offset_y;
166 
167  float shake_offset_x;
168  float shake_offset_y;
169 
170  float recoil_offset_mouse_x;
171  float recoil_offset_mouse_y;
172 
173  float recoil_offset_hands_x;
174  float recoil_offset_hands_y;
175 
176  float kuru_offset_x;
177  float kuru_offset_y;
178 
179  float player_stamina = m_PlayerPb.GetStaminaHandler().GetSyncedStaminaNormalized();
180 
181  #ifdef DEVELOPER
182  DbgPrintAimingImplement("Player: " + m_PlayerPb + " | ProcessAimFilters | timestamp: " + m_PlayerPb.GetSimulationTimeStamp());
183  #endif
184 
185  //negates stamina effect during hold breath
186  if (m_PlayerPb.IsHoldingBreath())
187  {
188  player_stamina = 1;
189  }
190  float speed = CalculateSpeedMultiplier(player_stamina);
191  m_TotalTime += pDt * speed;
192 
193  if (m_PlayerPb.IsHoldingBreath() && !m_HoldingBreathSet)
194  {
195  m_ReferenceTime = m_TotalTime;
196  }
197  else if (!m_PlayerPb.IsHoldingBreath() && m_HoldingBreathSet)
198  {
199  m_ReferenceTime = m_TotalTime;
200  }
201 
202  float adjusted_sway_multiplier = CalculateSwayMultiplier();
203  m_LastSwayMultiplier = adjusted_sway_multiplier;
204 
205  m_SwayWeight = CalculateWeight( stance_index, player_stamina, 0.5/*m_PlayerPb.m_CameraSwayModifier*/, m_PlayerPb.IsHoldingBreath()) * adjusted_sway_multiplier;
206 
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);
210 
211  int shake_level = m_PlayerPb.GetShakeLevel();
212  if (shake_level != 0)
213  {
214  ApplyShakes(shake_offset_x, shake_offset_y, shake_level);
215  }
216 
218  if (m_CurrentRecoil)
219  {
220  m_CurrentRecoil.Update(pModel, recoil_offset_mouse_x, recoil_offset_mouse_y, recoil_offset_hands_x, recoil_offset_hands_y, pDt);
221  }
222 
223  if (m_KuruShake)
224  {
225  m_KuruShake.Update(pDt, kuru_offset_x, kuru_offset_y);
226  }
227 
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;
231 
232  #ifdef DEVELOPER
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);
239  #endif
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;
243 
244 
245  #ifdef DEVELOPER
246  DbgPrintAimingImplement("m_CamShakeY: " + m_CamShakeY);
247  DbgPrintAimingImplement("pModel.m_fAimYCamOffset: " + pModel.m_fAimYCamOffset);
248  #endif
249 
251  if (stance_index == DayZPlayerConstants.STANCEIDX_RAISEDPRONE)
252  {
253  float newVal = DayZPlayerUtils.LinearRangeClamp(pModel.m_fCurrentAimX, pModel.m_fCurrentAimY, m_AimXClampRanges);
254  pModel.m_fAimYHandsOffset += newVal - pModel.m_fCurrentAimY;
255  }
256  float absAimY = Math.AbsFloat(pModel.m_fCurrentAimY);
257  pModel.m_fAimYHandsOffset = Math.Clamp(pModel.m_fAimYHandsOffset,absAimY - 89.9,89.9 - absAimY); //'90' leads to rounding errors down the line
258 
259  if (m_PlayerDpi.IsInOptics() && m_KuruShake)
260  {
261  //TODO - do not offset mouse
262  }
264  pModel.m_fAimXMouseShift = recoil_offset_mouse_x -kuru_offset_x / 10;
265  pModel.m_fAimYMouseShift = recoil_offset_mouse_y + kuru_offset_y / 10;
266 
267  #ifdef DEVELOPER
268  DbgPrintAimingImplement("recoil_offset_mouse_y: " + recoil_offset_mouse_y);
269  DbgPrintAimingImplement("pModel.m_fAimYMouseShift: " + pModel.m_fAimYMouseShift);
270  #endif
271 
272  if (m_PlayerPb.IsHoldingBreath() && !m_HoldingBreathSet)
273  {
274  m_HoldingBreathSet = true;
275  m_HorizontalNoiseXAxisOffset = noise_offset_x;
276  m_BreathingXAxisOffset = breathing_offset_x;
277  m_BreathingYAxisOffset = breathing_offset_y;
278  }
279  else if (!m_PlayerPb.IsHoldingBreath() && m_HoldingBreathSet)
280  {
281  m_HoldingBreathSet = false;
282  }
283 
284  if (!m_PlayerPb.IsHoldingBreath() && m_LastSwayMultiplier == PlayerSwayConstants.SWAY_MULTIPLIER_DEFAULT && m_HorizontalNoiseXAxisOffset != 0)
285  {
286  m_HorizontalNoiseXAxisOffset = 0;
287  m_BreathingXAxisOffset = 0;
288  m_BreathingYAxisOffset = 0;
289  }
290 
291  if (m_PlayerPb.IsHoldingBreath())
292  {
293  m_PlayerPb.DepleteStamina(EStaminaModifiers.HOLD_BREATH,pDt*speed);
294  }
295  #ifdef DEVELOPER
296  DbgPrintAimingImplement("----------------------------");
297  #endif
298  return true;
299  }
300 
301  protected float CalculateSwayMultiplier()
302  {
303  float max;
304  float time;
305  float time_clamped;
306  float ret;
307 
308  if (m_PlayerPb.IsHoldingBreath())
309  {
310  time = m_TotalTime - m_ReferenceTime;
311 
312  if (time < PlayerSwayConstants.SWAY_TIME_IN)
313  {
314  UpdateSwayState(eSwayStates.HOLDBREATH_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);
318  }
319  else if (time >= PlayerSwayConstants.SWAY_TIME_IN && time < (PlayerSwayConstants.SWAY_TIME_IN + PlayerSwayConstants.SWAY_TIME_STABLE))
320  {
321  UpdateSwayState(eSwayStates.HOLDBREATH_STABLE);
322  ret = PlayerSwayConstants.SWAY_MULTIPLIER_STABLE;
323  }
324  else
325  {
326  UpdateSwayState(eSwayStates.HOLDBREATH_EXHAUSTED);
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));
330  }
331  }
332  else
333  {
334  UpdateSwayState(eSwayStates.DEFAULT);
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);
338  }
339  return ret;
340  }
341 
342  float CalculateSpeedMultiplier(float stamina)
343  {
344  return (((1.0 - stamina) * 3.0) + 1.0) * m_SwayModifier[2]; // just 'm_SwayModifier[2]' for HoldBreath
345  }
346 
347  protected bool UpdateSwayState(int state)
348  {
349  if (state != m_SwayState)
350  {
351  m_SwayState = state;
352  m_SwayStateStartTime = m_TotalTime;
353  m_StateStartSwayMultiplier = m_LastSwayMultiplier;
354  OnSwayStateChange(state);
355  return true;
356  }
357 
358  return false;
359  }
360 
361  int GetCurrentSwayState()
362  {
363  return m_SwayState;
364  }
365 
366  protected void ApplyBreathingPattern(out float x_axis, out float y_axis, float pAmplitude, float pTotalTime, float weight)
367  {
368 
369  float multiplier = Math.Lerp(PlayerSwayConstants.SWAY_MULTIPLIER_DEFAULT,0,m_LastSwayMultiplier); //TODO revise
370  #ifdef DEVELOPER
371  DbgPrintAimingImplement("m_LastSwayMultiplier: " + m_LastSwayMultiplier);
372  DbgPrintAimingImplement("pAmplitude: " + pAmplitude);
373  DbgPrintAimingImplement("pTotalTime: " + pTotalTime);
374  DbgPrintAimingImplement("weight: " + weight);
375  DbgPrintAimingImplement("multiplier: " + multiplier);
376  #endif
377 
378  x_axis = (Math.Sin(pTotalTime) * pAmplitude / 4) * weight;
379  y_axis = (Math.Sin((pTotalTime) * 0.8 + 0.6) * pAmplitude) * weight;
380  #ifdef DEVELOPER
381  DbgPrintAimingImplement("y_axis_midproduct: " + y_axis);
382  #endif
383  x_axis += m_BreathingXAxisOffset * multiplier;
384  y_axis += m_BreathingYAxisOffset * multiplier;
385  }
386 
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)
388  {
389  if (Math.AbsFloat(m_HorizontalTargetValue - m_HorizontalNoise) < 0.01)
390  {
391  //acquire new target
392  m_MaxVelocity = m_PlayerPb.GetRandomGeneratorSyncManager().GetRandomInRange(RandomGeneratorSyncUsage.RGSAimingModel, max_velocity_low, max_velocity_high);
393 
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;
397  }
398 
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); //TODO revise
402  x_axis += m_HorizontalNoiseXAxisOffset * multiplier;
403  }
404 
405  protected void ApplyShakes(out float x_axis, out float y_axis, int level)
406  {
407  float weight = level / PlayerBase.SHAKE_LEVEL_MAX;
408  m_ShakeCount++;
409  int shakes_threshold = Math.Round(m_PlayerPb.GetRandomGeneratorSyncManager().GetRandomInRange(RandomGeneratorSyncUsage.RGSAimingModel, 2, 4));
410  if (m_ShakeCount > shakes_threshold)
411  {
412  m_ShakeCount = 0;
413 
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);
417  }
418  }
419 
420  protected float CalculateWeight(int stance_index, float current_stamina, float camera_sway_modifier, bool holding_breath)
421  {
422  if (m_PlayerDpi.GetCommand_Move() && m_PlayerDpi.GetCommand_Move().IsInRoll())//when the player is rolling, set a constant and disregard everything else
423  {
424  return PlayerSwayConstants.SWAY_ROLL;
425  }
426  float stance_modifier;
427  switch (stance_index)
428  {
429  case DayZPlayerConstants.STANCEIDX_RAISEDERECT:
430  stance_modifier = 0.5;
431  break;
432  case DayZPlayerConstants.STANCEIDX_RAISEDCROUCH:
433  stance_modifier = 0.75;
434  break;
435  case DayZPlayerConstants.STANCEIDX_RAISEDPRONE:
436  stance_modifier = 0.9;
437  break;
438  default:
439  stance_modifier = 0.75;
440  //Debug.LogError("stance mask out of definition");
441  break;
442  }
443 
444  #ifdef DEVELOPER
445  DbgPrintAimingImplement("current_stamina: " + current_stamina);
446  DbgPrintAimingImplement("camera_sway_modifier: " + camera_sway_modifier);
447  DbgPrintAimingImplement("holding_breath: " + holding_breath);
448  #endif
449 
450  return (1 - stance_modifier) * m_AimNoiseAllowed * camera_sway_modifier * SWAY_WEIGHT_SCALER;
451  }
452 
453  void DbgPrintAimingImplement(string val)
454  {
455  #ifdef DEVELOPER
456  if (GetDayZGame().IsAimLogEnabled())
457  Print("DayZPlayerImplementAiming | " + val);
458  #endif
459  }
460 }
461 
HOLDBREATH_STABLE
@ HOLDBREATH_STABLE
Definition: dayzplayerimplementaiming.c:14
DayZPlayerUtils
private void DayZPlayerUtils()
cannot be instantiated
Definition: dayzplayerutils.c:461
GetDayZGame
DayZGame GetDayZGame()
Definition: dayzgame.c:3729
EStaminaModifiers
EStaminaModifiers
Definition: estaminamodifiers.c:1
eSwayStates
eSwayStates
Definition: dayzplayerimplementaiming.c:10
HOLDBREATH_IN
@ HOLDBREATH_IN
Definition: dayzplayerimplementaiming.c:13
SDayZPlayerAimingModel
Definition: dayzplayer.c:1088
Print
proto void Print(void var)
Prints content of variable to console/log.
DayZPlayerImplementAiming
Definition: dayzplayerimplementaiming.c:31
KuruShake
Definition: kurushake.c:1
DEFAULT
@ DEFAULT
Definition: dayzplayerimplementaiming.c:12
RandomGeneratorSyncUsage
RandomGeneratorSyncUsage
Definition: randomgeneratorsyncmanager.c:1
PlayerBase
Definition: playerbaseclient.c:1
vector
Definition: enconvert.c:105
RecoilBase
Definition: recoilbase.c:1
DayZPlayerConstants
DayZPlayerConstants
defined in C++
Definition: dayzplayer.c:601
DayZPlayerImplement
Definition: manbase.c:1
Weapon_Base
shorthand
Definition: boltactionrifle_base.c:5
SWAY_MULTIPLIER_DEFAULT
enum eSwayStates SWAY_MULTIPLIER_DEFAULT
HOLDBREATH_EXHAUSTED
@ HOLDBREATH_EXHAUSTED
Definition: dayzplayerimplementaiming.c:15
Math
Definition: enmath.c:6
Class
Super root of all classes in Enforce script.
Definition: enscript.c:10
MAX
@ MAX
Definition: dayzplayerimplementaiming.c:16