recoilbase.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. class RecoilBase
  2. {
  3. bool m_DebugMode;
  4. Weapon_Base m_Weapon;
  5. PlayerBase m_Player;
  6. protected bool m_DeleteRequested;
  7. protected float m_Time;//how much time has elapsed since first update
  8. protected float m_ReloadTime;//reload time config parameter of the weapon
  9. protected vector m_RecoilModifier;
  10. protected bool m_IsClient;
  11. // for mouse offset
  12. float m_MouseOffsetRangeMin;//in degrees min
  13. float m_MouseOffsetRangeMax;//in degrees max
  14. float m_MouseOffsetRelativeTime = 1;//[0..1] a time it takes to move the mouse the required distance relative to the reload time of the weapon(firing mode)
  15. float m_HandsOffsetRelativeTime = 1;//[0..1] a time it takes to move the hands the required distance given by the curve relative to the reload time of the weapon(firing mode)
  16. float m_CamOffsetRelativeTime = 1;//[0..1] a time it takes to move the camera the required distance relative to the reload time of the weapon(firing mode)
  17. float m_CamOffsetDistance = 0.05;//how far the camera will travel along the z-axis in cm
  18. float m_MouseOffsetDistance;//how far should the mouse travel
  19. float m_TimeNormalized;
  20. //protected float m_MouseOffsetResult;//in degrees max
  21. protected vector m_MouseOffsetTarget;//move the mouse towards this point
  22. protected vector m_MouseOffsetTargetAccum;//the overall mouse offset so far(all deltas accumulated)
  23. protected float m_Angle;//result between the min and max
  24. // mouse end
  25. protected ref array<vector> m_HandsCurvePoints;
  26. void RecoilBase(Weapon_Base weapon)
  27. {
  28. m_Weapon = weapon;
  29. //m_DebugMode = false;
  30. m_DebugMode = GetDayZGame().IsAimLogEnabled();
  31. m_Player = PlayerBase.Cast(weapon.GetHierarchyRootPlayer());
  32. m_HandsCurvePoints = new array<vector>;
  33. Init();
  34. PostInit(weapon);
  35. }
  36. void Init();
  37. Weapon_Base GetWeapon()
  38. {
  39. return m_Weapon;
  40. }
  41. void PostInit(Weapon_Base weapon)
  42. {
  43. int muzzleIndex = weapon.GetCurrentMuzzle();
  44. m_Angle = m_Player.GetRandomGeneratorSyncManager().GetRandomInRange(RandomGeneratorSyncUsage.RGSRecoil, m_MouseOffsetRangeMin, m_MouseOffsetRangeMax);
  45. m_RecoilModifier = GetRecoilModifier( GetWeapon() );
  46. if(m_DebugMode) Print(m_Angle);
  47. m_ReloadTime = weapon.GetReloadTime(muzzleIndex);
  48. m_MouseOffsetTarget = vector.YawToVector(m_Angle);
  49. m_MouseOffsetTarget = m_MouseOffsetTarget * m_MouseOffsetDistance;
  50. m_IsClient = !GetGame().IsDedicatedServer();
  51. m_CamOffsetDistance *= m_RecoilModifier[2];
  52. }
  53. //! Destroys this object next update tick
  54. void Destroy()
  55. {
  56. m_DeleteRequested = true;
  57. }
  58. // called externally per update, not to be overriden in children
  59. void Update( SDayZPlayerAimingModel pModel, out float axis_mouse_x, out float axis_mouse_y, out float axis_hands_x, out float axis_hands_y, float pDt )
  60. {
  61. if( m_DeleteRequested )
  62. {
  63. delete this;
  64. }
  65. m_TimeNormalized = Math.InverseLerp(0, m_ReloadTime, m_Time);
  66. m_TimeNormalized = Math.Clamp(m_TimeNormalized, 0,0.99);
  67. ApplyMouseOffset(pDt, axis_mouse_x, axis_mouse_y);
  68. ApplyHandsOffset(pDt, axis_hands_x, axis_hands_y);
  69. if(m_IsClient)
  70. ApplyCamOffset(pModel);
  71. #ifdef DEVELOPER
  72. if(m_DebugMode)
  73. PrintString("RecoilBase | BEFORE | axis_mouse_y: " + axis_mouse_y.ToString());
  74. #endif
  75. axis_mouse_x = axis_mouse_x * m_RecoilModifier[0];
  76. axis_mouse_y = axis_mouse_y * m_RecoilModifier[1];
  77. axis_hands_x = axis_hands_x * m_RecoilModifier[0];
  78. axis_hands_y = axis_hands_y * m_RecoilModifier[1];
  79. #ifdef DEVELOPER
  80. if(m_DebugMode)
  81. {
  82. PrintString("RecoilBase | AFTER | axis_mouse_y: " + axis_mouse_y.ToString());
  83. }
  84. #endif
  85. m_Time += pDt;
  86. if( m_Time >= m_ReloadTime )
  87. {
  88. Destroy();
  89. }
  90. }
  91. void ApplyCamOffset(SDayZPlayerAimingModel pModel)
  92. {
  93. float time_rel = Math.Clamp(Math.InverseLerp(0, m_CamOffsetRelativeTime, m_TimeNormalized), 0, 1);
  94. float offset = 0;
  95. float time = Easing.EaseOutBack(time_rel);
  96. if(time == 1)
  97. {
  98. offset = 0;
  99. }
  100. else
  101. {
  102. offset = Math.Lerp(0,m_CamOffsetDistance,time);
  103. }
  104. pModel.m_fCamPosOffsetZ = offset;
  105. m_Player.GetCurrentCamera().SendRecoilOffsetZ(offset);
  106. }
  107. void ApplyHandsOffset(float pDt, out float pRecResultX, out float pRecResultY)
  108. {
  109. float relative_time = m_TimeNormalized / Math.Clamp(m_HandsOffsetRelativeTime, 0.001,1);
  110. vector pos_on_curve = GetPositionOnCurve(m_HandsCurvePoints, relative_time);
  111. /*if(m_DebugMode)
  112. {
  113. PrintString("pos_on_curve: " + pos_on_curve.ToString());
  114. PrintString("normalized time: " + m_TimeNormalized.ToString());
  115. PrintString("elapsed time: " + m_Time.ToString());
  116. PrintString("curve pos x: " + pos_on_curve[0].ToString());
  117. PrintString("curve pos y: " + pos_on_curve[1].ToString());
  118. PrintString("relative_time: " + relative_time.ToString());
  119. }*/
  120. pRecResultX = pos_on_curve[0];
  121. pRecResultY = pos_on_curve[1];
  122. }
  123. void ApplyMouseOffset(float pDt, out float pRecResultX, out float pRecResultY)
  124. {
  125. #ifdef DEVELOPER
  126. if(m_DebugMode)
  127. {
  128. bool b1 = m_MouseOffsetTargetAccum[1] < m_MouseOffsetTarget[1];
  129. PrintString( "RecoilBase | ApplyMouseOffset processing: " + b1 );
  130. PrintString( "RecoilBase | m_MouseOffsetTargetAccum : " + m_MouseOffsetTargetAccum.ToString() );
  131. PrintString( "RecoilBase | m_MouseOffsetTarget : " + m_MouseOffsetTarget.ToString() );
  132. }
  133. #endif
  134. if( m_MouseOffsetTargetAccum[1] < m_MouseOffsetTarget[1] )
  135. {
  136. float relative_delta = pDt / m_ReloadTime / Math.Clamp(m_MouseOffsetRelativeTime, 0.001,1);
  137. float delta_mouse_offset_x = m_MouseOffsetTarget[0] * relative_delta;
  138. float delta_mouse_offset_y = m_MouseOffsetTarget[1] * relative_delta;
  139. if( ( m_MouseOffsetTargetAccum[1] + delta_mouse_offset_y) > m_MouseOffsetTarget[1] )
  140. {
  141. delta_mouse_offset_x = m_MouseOffsetTarget[0] - m_MouseOffsetTargetAccum[0];
  142. delta_mouse_offset_y = m_MouseOffsetTarget[1] - m_MouseOffsetTargetAccum[1];
  143. }
  144. m_MouseOffsetTargetAccum[0] = m_MouseOffsetTargetAccum[0] + delta_mouse_offset_x;
  145. m_MouseOffsetTargetAccum[1] = m_MouseOffsetTargetAccum[1] + delta_mouse_offset_y;
  146. pRecResultX = delta_mouse_offset_x;
  147. pRecResultY = delta_mouse_offset_y;
  148. /*if(m_DebugMode)
  149. {
  150. PrintString( "delta x: "+ delta_mouse_offset_x );
  151. PrintString( "delta y: "+ delta_mouse_offset_y );
  152. PrintString( "target x: "+ m_MouseOffsetTarget[0] );
  153. PrintString( "target y: "+ m_MouseOffsetTarget[1] );
  154. PrintString( "accum x: "+ m_MouseOffsetTargetAccum[0] );
  155. PrintString( "accum y: "+ m_MouseOffsetTargetAccum[1] );
  156. }*/
  157. }
  158. #ifdef DEVELOPER
  159. if(m_DebugMode)
  160. {
  161. PrintString( "RecoilBase | pRecResultY: " + pRecResultY );
  162. }
  163. #endif
  164. }
  165. vector GetRecoilModifier(Weapon_Base weapon)
  166. {
  167. if( weapon )
  168. {
  169. return weapon.GetPropertyModifierObject().m_RecoilModifiers;
  170. }
  171. else return "1 1 1";
  172. }
  173. vector GetPositionOnCurve(array<vector> points, float time)
  174. {
  175. return Math3D.Curve(ECurveType.CatmullRom, time, points);
  176. }
  177. }