Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

313 lines
11 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "predicted_viewmodel.h"
  8. #ifdef CLIENT_DLL
  9. #include "prediction.h"
  10. #ifdef CSTRIKE15
  11. #include "c_cs_player.h"
  12. #endif
  13. #endif
  14. // memdbgon must be the last include file in a .cpp file!!!
  15. #include "tier0/memdbgon.h"
  16. IMPLEMENT_NETWORKCLASS_ALIASED( PredictedViewModel, DT_PredictedViewModel )
  17. LINK_ENTITY_TO_CLASS_ALIASED( predicted_viewmodel, PredictedViewModel );
  18. BEGIN_NETWORK_TABLE( CPredictedViewModel, DT_PredictedViewModel )
  19. END_NETWORK_TABLE()
  20. //-----------------------------------------------------------------------------
  21. // Purpose:
  22. //-----------------------------------------------------------------------------
  23. #ifdef CLIENT_DLL
  24. CPredictedViewModel::CPredictedViewModel() : m_LagAnglesHistory("CPredictedViewModel::m_LagAnglesHistory")
  25. {
  26. m_vLagAngles.Init();
  27. m_LagAnglesHistory.Setup( &m_vLagAngles, INTERPOLATE_LINEAR_ONLY );
  28. m_vPredictedOffset.Init();
  29. m_flInaccuracyTilt = 0;
  30. m_flOldAccuracyDiffSmoothed = 0;
  31. }
  32. #else
  33. CPredictedViewModel::CPredictedViewModel()
  34. {
  35. }
  36. #endif
  37. //-----------------------------------------------------------------------------
  38. // Purpose:
  39. //-----------------------------------------------------------------------------
  40. CPredictedViewModel::~CPredictedViewModel()
  41. {
  42. }
  43. #ifdef CLIENT_DLL
  44. ConVar cl_wpn_sway_interp( "cl_wpn_sway_interp", "0.1", FCVAR_CLIENTDLL );
  45. ConVar cl_wpn_sway_scale( "cl_wpn_sway_scale", "1.6", FCVAR_CLIENTDLL|FCVAR_CHEAT );
  46. #ifdef CSTRIKE15
  47. extern ConVar cl_use_new_headbob;
  48. #endif //CSTRIKE15
  49. #endif //CLIENT_DLL
  50. //-----------------------------------------------------------------------------
  51. // Purpose: Adds head bob for off hand models
  52. //-----------------------------------------------------------------------------
  53. void CPredictedViewModel::AddViewModelBob( CBasePlayer *owner, Vector& eyePosition, QAngle& eyeAngles )
  54. {
  55. #ifdef CSTRIKE15
  56. #ifdef CLIENT_DLL
  57. if ( cl_use_new_headbob.GetBool() == false )
  58. return;
  59. // if we are an off hand view model (index 1) and we have a model, add head bob.
  60. // (Head bob for main hand model added by the weapon itself.)
  61. if ( ViewModelIndex() == 1 && m_bShouldIgnoreOffsetAndAccuracy )
  62. {
  63. CalcViewModelBobHelper( owner, &m_BobState, 1 );
  64. AddViewModelBobHelper( eyePosition, eyeAngles, &m_BobState );
  65. }
  66. #endif
  67. #endif
  68. }
  69. void CPredictedViewModel::CalcViewModelLag( Vector& origin, QAngle& angles, QAngle& /*original_angles*/ )
  70. {
  71. #ifdef CLIENT_DLL
  72. float interp = cl_wpn_sway_interp.GetFloat();
  73. if ( !interp || m_bShouldIgnoreOffsetAndAccuracy )
  74. return;
  75. if ( prediction->InPrediction() && !prediction->IsFirstTimePredicted() )
  76. {
  77. origin += m_vPredictedOffset;
  78. return;
  79. }
  80. // Calculate our drift
  81. Vector forward, right, up;
  82. AngleVectors( angles, &forward, &right, &up );
  83. // Add an entry to the history.
  84. m_vLagAngles = angles;
  85. m_LagAnglesHistory.NoteChanged( gpGlobals->curtime, gpGlobals->curtime, interp, false );
  86. // Interpolate back 100ms.
  87. m_LagAnglesHistory.Interpolate( gpGlobals->curtime, interp );
  88. // Now take the 100ms angle difference and figure out how far the forward vector moved in local space.
  89. Vector vLaggedForward;
  90. QAngle angleDiff = m_vLagAngles - angles;
  91. AngleVectors( -angleDiff, &vLaggedForward, 0, 0 );
  92. Vector vForwardDiff = Vector(1,0,0) - vLaggedForward;
  93. if ( ShouldFlipModel() )
  94. right = -right;
  95. // Now offset the origin using that.
  96. vForwardDiff *= cl_wpn_sway_scale.GetFloat();
  97. m_vPredictedOffset = forward*vForwardDiff.x + right*-vForwardDiff.y + up*vForwardDiff.z;
  98. // reduce offset as viewmodel angle approaches nearly vertical
  99. float flMult = clamp( abs(DotProduct(up, Vector(0,0,1))) - 0.02f, 0, 1 );
  100. origin += (m_vPredictedOffset * flMult);
  101. #endif
  102. }
  103. #ifdef CLIENT_DLL
  104. ConVar cl_gunlowerangle( "cl_gunlowerangle", "2", FCVAR_CLIENTDLL );
  105. ConVar cl_gunlowerspeed( "cl_gunlowerspeed", "0.1", FCVAR_CLIENTDLL );
  106. #endif //CLIENT_DLL
  107. void CPredictedViewModel::ApplyViewModelPitchAndDip( CBasePlayer *owner, Vector& vecNewOrigin, QAngle& vecNewAngles )
  108. {
  109. //orients and moves weapon to provide visual feedback on weapon accuracy and player motion (like jumping and landing)
  110. #ifdef CLIENT_DLL
  111. // Check for lowering the weapon
  112. // C_CSPlayer *pPlayer = ToCSPlayer( owner );
  113. // Assert( pPlayer );
  114. bool bJumping = !( owner->GetFlags() & FL_ONGROUND );
  115. bool bLowered = bJumping;//pPlayer->IsWeaponLowered();
  116. QAngle vecLoweredAngles(0,0,0);
  117. m_vLoweredWeaponOffset.x = Approach( bLowered ? cl_gunlowerangle.GetFloat() : 0, m_vLoweredWeaponOffset.x, cl_gunlowerspeed.GetFloat() );
  118. vecLoweredAngles.x += m_vLoweredWeaponOffset.x;
  119. vecNewAngles -= vecLoweredAngles * 0.2f;
  120. vecNewOrigin.z -= vecLoweredAngles.x * 0.4f; // translation offset looks more natural than rotation
  121. float flDipAddAmt = 0.0f;
  122. float flOldFallVel = owner->m_Local.m_flOldFallVelocity;
  123. // This does the dip when you land
  124. // m_Local.m_bInLanding gets set on the client in baseplayer_shared.cpp -- mtw
  125. if ( owner && owner->m_Local.m_bInLanding == true )
  126. {
  127. float flDipAmt = 0.005;//weapon_land_dip_amt.GetFloat();
  128. float landseconds = MAX(gpGlobals->curtime - (owner->m_Local.m_flLandingTime - 0.1f), 0.0f);
  129. float landFraction = SmoothCurve( landseconds / 0.25f );
  130. clamp( landFraction, 0.0f, 1.0f );
  131. float flDipAmount = (1 / flOldFallVel) * flDipAmt;
  132. int dipHighOffset = 64;
  133. int dipLowOffset = dipHighOffset - flDipAmt;
  134. Vector temp = owner->GetViewOffset();
  135. temp.z = ( ( dipLowOffset - flDipAmount ) * landFraction ) +
  136. ( dipHighOffset * ( 1 - landFraction ) );
  137. if ( temp.z > dipHighOffset )
  138. {
  139. temp.z = dipHighOffset;
  140. }
  141. flDipAddAmt = ( dipHighOffset - temp.z );
  142. }
  143. // Replaced with CL #2056767 code in baseviewmodel_shared.cpp
  144. // that applies aimpunch to viewmodel angle
  145. //////////////////////////////////////////
  146. // C_WeaponCSBase *pWeapon = ( C_WeaponCSBase * )GetOwningWeapon();
  147. // // pitch the viewmodel up to match where the bullets are going
  148. // if ( pWeapon )
  149. // {
  150. // float flMaxMultiplier = 40;
  151. // float flMultiplier = flMaxMultiplier;
  152. //
  153. // if ( !m_bShouldIgnoreOffsetAndAccuracy )
  154. // flMultiplier -= MAX( 0, (gpGlobals->curtime - pWeapon->m_flNextPrimaryAttack) * flMaxMultiplier );
  155. //
  156. // float flMultMinClamp = 0;
  157. // if ( bJumping )
  158. // flMultMinClamp = 5.0f;
  159. //
  160. // flMultiplier = clamp( flMultiplier, flMultMinClamp, flMaxMultiplier );
  161. //
  162. // // get the player's default accuracy
  163. // float flBaseAccuracy = pWeapon->GetCSWpnData().GetInaccuracyStand( 0, pWeapon->GetAttributeContainer()->GetItem() );
  164. // // get the current accuracy of the player
  165. // float flAccuracy = m_bShouldIgnoreOffsetAndAccuracy ? 0 : pWeapon->GetInaccuracy();
  166. // //float flAccuracyFishtail = m_bShouldIgnoreOffsetAndAccuracy ? 0 : pWeapon->GetAccuracyFishtail();
  167. // // get the difference between the two
  168. // float flAccuracyDiff = m_bShouldIgnoreOffsetAndAccuracy ? 0 : abs((flAccuracy - flBaseAccuracy) * flMultiplier);
  169. //
  170. // float flApproachSpeed = 25.0f;
  171. // // if we are in the air, we just jumped, we are running really fast,
  172. // // adjust the appraoch speed based on how fast it changed
  173. // // this avoids big visual pops
  174. // if ( bJumping || (!m_bShouldIgnoreOffsetAndAccuracy && owner->GetAbsVelocity().Length2D() > 150.0f) )// && flAccuracyDiff > m_flOldAccuracyDiff )
  175. // {
  176. // float flMax = 7.5f;
  177. // float flDiv = 10.0f;
  178. // // if we're on the ground and moving fast
  179. // if ( owner->GetAbsVelocity().Length2D() > 150.0f && !bJumping )
  180. // {
  181. // flMax = 25.0f;
  182. // flDiv = 5.0f;
  183. // }
  184. //
  185. // float flOldToNewDiff = abs( ((flAccuracyDiff - m_flOldAccuracyDiffSmoothed) / flDiv) * flApproachSpeed );
  186. // // small differences, we go faster, large differences and we go slower
  187. // flApproachSpeed = clamp( flApproachSpeed - flOldToNewDiff, 5.0f, flMax );
  188. // }
  189. //
  190. // // save off the accuracy difference
  191. // m_flOldAccuracyDiffSmoothed = Approach( flAccuracyDiff, m_flOldAccuracyDiffSmoothed, abs( ((flAccuracyDiff)-m_flOldAccuracyDiffSmoothed )*gpGlobals->frametime) * 0.5f );
  192. //
  193. // // smooth out the tilting
  194. // m_flInaccuracyTilt = Approach( flAccuracyDiff, m_flInaccuracyTilt, abs( (flAccuracyDiff-m_flInaccuracyTilt)*gpGlobals->frametime) * flApproachSpeed );
  195. // m_flInaccuracyTilt = MIN( m_flInaccuracyTilt, 3.0f );
  196. // //Msg ( "owner->GetAbsVelocity().Length2D() = %f, flAccuracyDiff = %f, m_flInaccuracyTilt = %f, flMultiplier = %f\n", owner->GetAbsVelocity().Length2D(), flAccuracyDiff, m_flInaccuracyTilt, flMultiplier );
  197. // //Msg ( "flApproachSpeed = %f, flAccuracyDiff = %f, m_flOldAccuracyDiffSmoothed = %f\n", flApproachSpeed, flAccuracyDiff, m_flOldAccuracyDiffSmoothed );
  198. //
  199. // vecNewAngles.x -= m_flInaccuracyTilt;
  200. // //vecNewAngles.y += flAccuracyFishtail;
  201. // // dip the gun just a bit as well
  202. // vecNewOrigin.z -= (m_flInaccuracyTilt * 0.5f) + flDipAddAmt;
  203. // }
  204. #endif
  205. }
  206. #ifdef CSTRIKE15
  207. void CPredictedViewModel::CalcViewModelView( CBasePlayer *owner, const Vector& eyePosition, const QAngle& eyeAngles )
  208. {
  209. #if defined( CLIENT_DLL )
  210. if ( cl_use_new_headbob.GetBool() == false )
  211. return BaseClass::CalcViewModelView( owner, eyePosition, eyeAngles );
  212. Vector vecNewOrigin = eyePosition;
  213. QAngle vecNewAngles = eyeAngles;
  214. ApplyViewModelPitchAndDip( owner, vecNewOrigin, vecNewAngles );
  215. BaseClass::CalcViewModelView( owner, vecNewOrigin, vecNewAngles );
  216. #endif //CLIENT_DLL
  217. #ifdef IRONSIGHT
  218. CWeaponCSBase *pWeapon = ( CWeaponCSBase * )GetOwningWeapon();
  219. if ( pWeapon )
  220. {
  221. CIronSightController* pIronSightController = pWeapon->GetIronSightController();
  222. if ( pIronSightController )
  223. {
  224. #ifndef CLIENT_DLL
  225. pIronSightController->UpdateIronSightAmount();
  226. #else
  227. Vector vecEyeOrigin = eyePosition;
  228. QAngle angEyeAngles = eyeAngles;
  229. if ( !prediction->InPrediction() )
  230. {
  231. //Retrieve ironsight position and angles, then lerp the weapon there if we're at all ironsighted
  232. pIronSightController->ApplyIronSightPositioning( vecEyeOrigin, angEyeAngles, GetLocalOrigin(), GetLocalAngles() );
  233. if ( pIronSightController->IsInIronSight() )
  234. {
  235. SetLocalOrigin( Lerp( pIronSightController->GetIronSightAmountGained(), GetLocalOrigin(), vecEyeOrigin ) );
  236. SetLocalAngles( Lerp( pIronSightController->GetIronSightAmountGained(), GetLocalAngles(), angEyeAngles ) );
  237. }
  238. }
  239. #endif
  240. }
  241. }
  242. #endif //IRONSIGHT
  243. #ifdef CLIENT_DLL
  244. // bias the position of the viewmodel during observer camera interpolation
  245. C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
  246. if ( pLocalPlayer && pLocalPlayer->GetObserverInterpState() != C_BasePlayer::OBSERVER_INTERP_NONE )
  247. {
  248. C_CSPlayer *pCSPlayer = ToCSPlayer( pLocalPlayer );
  249. if ( pCSPlayer )
  250. {
  251. Vector vecOffset = pCSPlayer->GetObserverInterpolatedOffsetVector();
  252. // pull up from offscreen a little
  253. vecOffset.z -= vecOffset.Length() * 0.2f;
  254. // dampen overall
  255. vecOffset *= 0.5f;
  256. SetLocalOrigin( GetLocalOrigin() + vecOffset );
  257. }
  258. }
  259. #endif
  260. }
  261. #endif //CSTRIKE15