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.

326 lines
11 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "c_vehicle_jeep.h"
  8. #include "movevars_shared.h"
  9. #include "view.h"
  10. #include "flashlighteffect.h"
  11. #include "c_baseplayer.h"
  12. #include "c_te_effect_dispatch.h"
  13. #include "fx.h"
  14. // memdbgon must be the last include file in a .cpp file!!!
  15. #include "tier0/memdbgon.h"
  16. extern ConVar default_fov;
  17. ConVar r_JeepViewBlendTo( "r_JeepViewBlendTo", "1", FCVAR_CHEAT );
  18. ConVar r_JeepViewBlendToScale( "r_JeepViewBlendToScale", "0.03", FCVAR_CHEAT );
  19. ConVar r_JeepViewBlendToTime( "r_JeepViewBlendToTime", "1.5", FCVAR_CHEAT );
  20. #define JEEP_DELTA_LENGTH_MAX 12.0f // 1 foot
  21. #define JEEP_FRAMETIME_MIN 1e-6
  22. #define JEEP_HEADLIGHT_DISTANCE 1000
  23. IMPLEMENT_CLIENTCLASS_DT( C_PropJeep, DT_PropJeep, CPropJeep )
  24. RecvPropBool( RECVINFO( m_bHeadlightIsOn ) ),
  25. END_RECV_TABLE()
  26. //-----------------------------------------------------------------------------
  27. // Purpose: Constructor
  28. //-----------------------------------------------------------------------------
  29. C_PropJeep::C_PropJeep()
  30. {
  31. m_vecEyeSpeed.Init();
  32. m_flViewAngleDeltaTime = 0.0f;
  33. m_pHeadlight = NULL;
  34. ConVarRef r_JeepFOV( "r_JeepFOV" );
  35. m_ViewSmoothingData.flFOV = r_JeepFOV.GetFloat();
  36. }
  37. //-----------------------------------------------------------------------------
  38. // Purpose: Deconstructor
  39. //-----------------------------------------------------------------------------
  40. C_PropJeep::~C_PropJeep()
  41. {
  42. if ( m_pHeadlight )
  43. {
  44. delete m_pHeadlight;
  45. }
  46. }
  47. bool C_PropJeep::Simulate( void )
  48. {
  49. // The dim light is the flashlight.
  50. if ( m_bHeadlightIsOn )
  51. {
  52. if ( m_pHeadlight == NULL )
  53. {
  54. // Turned on the headlight; create it.
  55. m_pHeadlight = new CHeadlightEffect;
  56. if ( m_pHeadlight == NULL )
  57. return true;
  58. m_pHeadlight->TurnOn();
  59. }
  60. QAngle vAngle;
  61. Vector vVector;
  62. Vector vecForward, vecRight, vecUp;
  63. int iAttachment = LookupAttachment( "headlight" );
  64. if ( iAttachment != -1 )
  65. {
  66. GetAttachment( iAttachment, vVector, vAngle );
  67. AngleVectors( vAngle, &vecForward, &vecRight, &vecUp );
  68. m_pHeadlight->UpdateLight( vVector, vecForward, vecRight, vecUp, JEEP_HEADLIGHT_DISTANCE );
  69. }
  70. }
  71. else if ( m_pHeadlight )
  72. {
  73. // Turned off the flashlight; delete it.
  74. delete m_pHeadlight;
  75. m_pHeadlight = NULL;
  76. }
  77. BaseClass::Simulate();
  78. return true;
  79. }
  80. //-----------------------------------------------------------------------------
  81. // Purpose: Blend view angles.
  82. //-----------------------------------------------------------------------------
  83. void C_PropJeep::UpdateViewAngles( C_BasePlayer *pLocalPlayer, CUserCmd *pCmd )
  84. {
  85. if ( r_JeepViewBlendTo.GetInt() )
  86. {
  87. // Check to see if the mouse has been touched in a bit or that we are not throttling.
  88. if ( ( pCmd->mousedx != 0 || pCmd->mousedy != 0 ) || ( fabsf( m_flThrottle ) < 0.01f ) )
  89. {
  90. m_flViewAngleDeltaTime = 0.0f;
  91. }
  92. else
  93. {
  94. m_flViewAngleDeltaTime += gpGlobals->frametime;
  95. }
  96. if ( m_flViewAngleDeltaTime > r_JeepViewBlendToTime.GetFloat() )
  97. {
  98. // Blend the view angles.
  99. int eyeAttachmentIndex = LookupAttachment( "vehicle_driver_eyes" );
  100. Vector vehicleEyeOrigin;
  101. QAngle vehicleEyeAngles;
  102. GetAttachmentLocal( eyeAttachmentIndex, vehicleEyeOrigin, vehicleEyeAngles );
  103. QAngle outAngles;
  104. InterpolateAngles( pCmd->viewangles, vehicleEyeAngles, outAngles, r_JeepViewBlendToScale.GetFloat() );
  105. pCmd->viewangles = outAngles;
  106. }
  107. }
  108. BaseClass::UpdateViewAngles( pLocalPlayer, pCmd );
  109. }
  110. //-----------------------------------------------------------------------------
  111. // Purpose:
  112. //-----------------------------------------------------------------------------
  113. void C_PropJeep::DampenEyePosition( Vector &vecVehicleEyePos, QAngle &vecVehicleEyeAngles )
  114. {
  115. #ifdef HL2_CLIENT_DLL
  116. // Get the frametime. (Check to see if enough time has passed to warrent dampening).
  117. float flFrameTime = gpGlobals->frametime;
  118. if ( flFrameTime < JEEP_FRAMETIME_MIN )
  119. {
  120. vecVehicleEyePos = m_vecLastEyePos;
  121. DampenUpMotion( vecVehicleEyePos, vecVehicleEyeAngles, 0.0f );
  122. return;
  123. }
  124. // Keep static the sideways motion.
  125. // Dampen forward/backward motion.
  126. DampenForwardMotion( vecVehicleEyePos, vecVehicleEyeAngles, flFrameTime );
  127. // Blend up/down motion.
  128. DampenUpMotion( vecVehicleEyePos, vecVehicleEyeAngles, flFrameTime );
  129. #endif
  130. }
  131. //-----------------------------------------------------------------------------
  132. // Use the controller as follows:
  133. // speed += ( pCoefficientsOut[0] * ( targetPos - currentPos ) + pCoefficientsOut[1] * ( targetSpeed - currentSpeed ) ) * flDeltaTime;
  134. //-----------------------------------------------------------------------------
  135. void C_PropJeep::ComputePDControllerCoefficients( float *pCoefficientsOut,
  136. float flFrequency, float flDampening,
  137. float flDeltaTime )
  138. {
  139. float flKs = 9.0f * flFrequency * flFrequency;
  140. float flKd = 4.5f * flFrequency * flDampening;
  141. float flScale = 1.0f / ( 1.0f + flKd * flDeltaTime + flKs * flDeltaTime * flDeltaTime );
  142. pCoefficientsOut[0] = flKs * flScale;
  143. pCoefficientsOut[1] = ( flKd + flKs * flDeltaTime ) * flScale;
  144. }
  145. //-----------------------------------------------------------------------------
  146. // Purpose:
  147. //-----------------------------------------------------------------------------
  148. void C_PropJeep::DampenForwardMotion( Vector &vecVehicleEyePos, QAngle &vecVehicleEyeAngles, float flFrameTime )
  149. {
  150. // vecVehicleEyePos = real eye position this frame
  151. // m_vecLastEyePos = eye position last frame
  152. // m_vecEyeSpeed = eye speed last frame
  153. // vecPredEyePos = predicted eye position this frame (assuming no acceleration - it will get that from the pd controller).
  154. // vecPredEyeSpeed = predicted eye speed
  155. Vector vecPredEyePos = m_vecLastEyePos + m_vecEyeSpeed * flFrameTime;
  156. Vector vecPredEyeSpeed = m_vecEyeSpeed;
  157. // m_vecLastEyeTarget = real eye position last frame (used for speed calculation).
  158. // Calculate the approximate speed based on the current vehicle eye position and the eye position last frame.
  159. Vector vecVehicleEyeSpeed = ( vecVehicleEyePos - m_vecLastEyeTarget ) / flFrameTime;
  160. m_vecLastEyeTarget = vecVehicleEyePos;
  161. if (vecVehicleEyeSpeed.Length() == 0.0)
  162. return;
  163. // Calculate the delta between the predicted eye position and speed and the current eye position and speed.
  164. Vector vecDeltaSpeed = vecVehicleEyeSpeed - vecPredEyeSpeed;
  165. Vector vecDeltaPos = vecVehicleEyePos - vecPredEyePos;
  166. // Forward vector.
  167. Vector vecForward;
  168. AngleVectors( vecVehicleEyeAngles, &vecForward );
  169. float flDeltaLength = vecDeltaPos.Length();
  170. if ( flDeltaLength > JEEP_DELTA_LENGTH_MAX )
  171. {
  172. // Clamp.
  173. float flDelta = flDeltaLength - JEEP_DELTA_LENGTH_MAX;
  174. if ( flDelta > 40.0f )
  175. {
  176. // This part is a bit of a hack to get rid of large deltas (at level load, etc.).
  177. m_vecLastEyePos = vecVehicleEyePos;
  178. m_vecEyeSpeed = vecVehicleEyeSpeed;
  179. }
  180. else
  181. {
  182. // Position clamp.
  183. float flRatio = JEEP_DELTA_LENGTH_MAX / flDeltaLength;
  184. vecDeltaPos *= flRatio;
  185. Vector vecForwardOffset = vecForward * ( vecForward.Dot( vecDeltaPos ) );
  186. vecVehicleEyePos -= vecForwardOffset;
  187. m_vecLastEyePos = vecVehicleEyePos;
  188. // Speed clamp.
  189. vecDeltaSpeed *= flRatio;
  190. float flCoefficients[2];
  191. ComputePDControllerCoefficients( flCoefficients, r_JeepViewDampenFreq.GetFloat(), r_JeepViewDampenDamp.GetFloat(), flFrameTime );
  192. m_vecEyeSpeed += ( ( flCoefficients[0] * vecDeltaPos + flCoefficients[1] * vecDeltaSpeed ) * flFrameTime );
  193. }
  194. }
  195. else
  196. {
  197. // Generate an updated (dampening) speed for use in next frames position prediction.
  198. float flCoefficients[2];
  199. ComputePDControllerCoefficients( flCoefficients, r_JeepViewDampenFreq.GetFloat(), r_JeepViewDampenDamp.GetFloat(), flFrameTime );
  200. m_vecEyeSpeed += ( ( flCoefficients[0] * vecDeltaPos + flCoefficients[1] * vecDeltaSpeed ) * flFrameTime );
  201. // Save off data for next frame.
  202. m_vecLastEyePos = vecPredEyePos;
  203. // Move eye forward/backward.
  204. Vector vecForwardOffset = vecForward * ( vecForward.Dot( vecDeltaPos ) );
  205. vecVehicleEyePos -= vecForwardOffset;
  206. }
  207. }
  208. //-----------------------------------------------------------------------------
  209. // Purpose:
  210. //-----------------------------------------------------------------------------
  211. void C_PropJeep::DampenUpMotion( Vector &vecVehicleEyePos, QAngle &vecVehicleEyeAngles, float flFrameTime )
  212. {
  213. // Get up vector.
  214. Vector vecUp;
  215. AngleVectors( vecVehicleEyeAngles, NULL, NULL, &vecUp );
  216. vecUp.z = clamp( vecUp.z, 0.0f, vecUp.z );
  217. vecVehicleEyePos.z += r_JeepViewZHeight.GetFloat() * vecUp.z;
  218. // NOTE: Should probably use some damped equation here.
  219. }
  220. //-----------------------------------------------------------------------------
  221. // Purpose:
  222. //-----------------------------------------------------------------------------
  223. void C_PropJeep::OnEnteredVehicle( C_BasePlayer *pPlayer )
  224. {
  225. int eyeAttachmentIndex = LookupAttachment( "vehicle_driver_eyes" );
  226. Vector vehicleEyeOrigin;
  227. QAngle vehicleEyeAngles;
  228. GetAttachment( eyeAttachmentIndex, vehicleEyeOrigin, vehicleEyeAngles );
  229. m_vecLastEyeTarget = vehicleEyeOrigin;
  230. m_vecLastEyePos = vehicleEyeOrigin;
  231. m_vecEyeSpeed = vec3_origin;
  232. }
  233. //-----------------------------------------------------------------------------
  234. // Purpose:
  235. // Input : &data -
  236. //-----------------------------------------------------------------------------
  237. void WheelDustCallback( const CEffectData &data )
  238. {
  239. CSmartPtr<CSimpleEmitter> pSimple = CSimpleEmitter::Create( "dust" );
  240. pSimple->SetSortOrigin( data.m_vOrigin );
  241. pSimple->SetNearClip( 32, 64 );
  242. SimpleParticle *pParticle;
  243. Vector offset;
  244. //FIXME: Better sampling area
  245. offset = data.m_vOrigin + ( data.m_vNormal * data.m_flScale );
  246. //Find area ambient light color and use it to tint smoke
  247. Vector worldLight = WorldGetLightForPoint( offset, true );
  248. //Throw puffs
  249. offset.Random( -(data.m_flScale*16.0f), data.m_flScale*16.0f );
  250. offset.z = 0.0f;
  251. offset += data.m_vOrigin + ( data.m_vNormal * data.m_flScale );
  252. pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof(SimpleParticle), g_Mat_DustPuff[0], offset );
  253. if ( pParticle != NULL )
  254. {
  255. pParticle->m_flLifetime = 0.0f;
  256. pParticle->m_flDieTime = random->RandomFloat( 0.25f, 0.5f );
  257. pParticle->m_vecVelocity = RandomVector( -1.0f, 1.0f );
  258. VectorNormalize( pParticle->m_vecVelocity );
  259. pParticle->m_vecVelocity[2] += random->RandomFloat( 16.0f, 32.0f ) * (data.m_flScale*2.0f);
  260. int color = random->RandomInt( 100, 150 );
  261. pParticle->m_uchColor[0] = 16 + ( worldLight[0] * (float) color );
  262. pParticle->m_uchColor[1] = 8 + ( worldLight[1] * (float) color );
  263. pParticle->m_uchColor[2] = ( worldLight[2] * (float) color );
  264. pParticle->m_uchStartAlpha = random->RandomInt( 64.0f*data.m_flScale, 128.0f*data.m_flScale );
  265. pParticle->m_uchEndAlpha = 0;
  266. pParticle->m_uchStartSize = random->RandomInt( 16, 24 ) * data.m_flScale;
  267. pParticle->m_uchEndSize = random->RandomInt( 32, 48 ) * data.m_flScale;
  268. pParticle->m_flRoll = random->RandomInt( 0, 360 );
  269. pParticle->m_flRollDelta = random->RandomFloat( -2.0f, 2.0f );
  270. }
  271. }
  272. DECLARE_CLIENT_EFFECT( WheelDust, WheelDustCallback );