aboutsummaryrefslogtreecommitdiff
path: root/sp/src/game/client/c_vehicle_jeep.cpp
diff options
context:
space:
mode:
authorJoe Ludwig <[email protected]>2013-06-26 15:22:04 -0700
committerJoe Ludwig <[email protected]>2013-06-26 15:22:04 -0700
commit39ed87570bdb2f86969d4be821c94b722dc71179 (patch)
treeabc53757f75f40c80278e87650ea92808274aa59 /sp/src/game/client/c_vehicle_jeep.cpp
downloadsource-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz
source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip
First version of the SOurce SDK 2013
Diffstat (limited to 'sp/src/game/client/c_vehicle_jeep.cpp')
-rw-r--r--sp/src/game/client/c_vehicle_jeep.cpp326
1 files changed, 326 insertions, 0 deletions
diff --git a/sp/src/game/client/c_vehicle_jeep.cpp b/sp/src/game/client/c_vehicle_jeep.cpp
new file mode 100644
index 00000000..9ddb32af
--- /dev/null
+++ b/sp/src/game/client/c_vehicle_jeep.cpp
@@ -0,0 +1,326 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "c_vehicle_jeep.h"
+#include "movevars_shared.h"
+#include "view.h"
+#include "flashlighteffect.h"
+#include "c_baseplayer.h"
+#include "c_te_effect_dispatch.h"
+#include "fx.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+extern ConVar default_fov;
+
+ConVar r_JeepViewBlendTo( "r_JeepViewBlendTo", "1", FCVAR_CHEAT );
+ConVar r_JeepViewBlendToScale( "r_JeepViewBlendToScale", "0.03", FCVAR_CHEAT );
+ConVar r_JeepViewBlendToTime( "r_JeepViewBlendToTime", "1.5", FCVAR_CHEAT );
+
+#define JEEP_DELTA_LENGTH_MAX 12.0f // 1 foot
+#define JEEP_FRAMETIME_MIN 1e-6
+#define JEEP_HEADLIGHT_DISTANCE 1000
+
+IMPLEMENT_CLIENTCLASS_DT( C_PropJeep, DT_PropJeep, CPropJeep )
+ RecvPropBool( RECVINFO( m_bHeadlightIsOn ) ),
+END_RECV_TABLE()
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+C_PropJeep::C_PropJeep()
+{
+ m_vecEyeSpeed.Init();
+ m_flViewAngleDeltaTime = 0.0f;
+ m_pHeadlight = NULL;
+
+ ConVarRef r_JeepFOV( "r_JeepFOV" );
+ m_ViewSmoothingData.flFOV = r_JeepFOV.GetFloat();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Deconstructor
+//-----------------------------------------------------------------------------
+C_PropJeep::~C_PropJeep()
+{
+ if ( m_pHeadlight )
+ {
+ delete m_pHeadlight;
+ }
+}
+
+void C_PropJeep::Simulate( void )
+{
+ // The dim light is the flashlight.
+ if ( m_bHeadlightIsOn )
+ {
+ if ( m_pHeadlight == NULL )
+ {
+ // Turned on the headlight; create it.
+ m_pHeadlight = new CHeadlightEffect;
+
+ if ( m_pHeadlight == NULL )
+ return;
+
+ m_pHeadlight->TurnOn();
+ }
+
+ QAngle vAngle;
+ Vector vVector;
+ Vector vecForward, vecRight, vecUp;
+
+ int iAttachment = LookupAttachment( "headlight" );
+
+ if ( iAttachment != INVALID_PARTICLE_ATTACHMENT )
+ {
+ GetAttachment( iAttachment, vVector, vAngle );
+ AngleVectors( vAngle, &vecForward, &vecRight, &vecUp );
+
+ m_pHeadlight->UpdateLight( vVector, vecForward, vecRight, vecUp, JEEP_HEADLIGHT_DISTANCE );
+ }
+ }
+ else if ( m_pHeadlight )
+ {
+ // Turned off the flashlight; delete it.
+ delete m_pHeadlight;
+ m_pHeadlight = NULL;
+ }
+
+ BaseClass::Simulate();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Blend view angles.
+//-----------------------------------------------------------------------------
+void C_PropJeep::UpdateViewAngles( C_BasePlayer *pLocalPlayer, CUserCmd *pCmd )
+{
+ if ( r_JeepViewBlendTo.GetInt() )
+ {
+ // Check to see if the mouse has been touched in a bit or that we are not throttling.
+ if ( ( pCmd->mousedx != 0 || pCmd->mousedy != 0 ) || ( fabsf( m_flThrottle ) < 0.01f ) )
+ {
+ m_flViewAngleDeltaTime = 0.0f;
+ }
+ else
+ {
+ m_flViewAngleDeltaTime += gpGlobals->frametime;
+ }
+
+ if ( m_flViewAngleDeltaTime > r_JeepViewBlendToTime.GetFloat() )
+ {
+ // Blend the view angles.
+ int eyeAttachmentIndex = LookupAttachment( "vehicle_driver_eyes" );
+ Vector vehicleEyeOrigin;
+ QAngle vehicleEyeAngles;
+ GetAttachmentLocal( eyeAttachmentIndex, vehicleEyeOrigin, vehicleEyeAngles );
+
+ QAngle outAngles;
+ InterpolateAngles( pCmd->viewangles, vehicleEyeAngles, outAngles, r_JeepViewBlendToScale.GetFloat() );
+ pCmd->viewangles = outAngles;
+ }
+ }
+
+ BaseClass::UpdateViewAngles( pLocalPlayer, pCmd );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_PropJeep::DampenEyePosition( Vector &vecVehicleEyePos, QAngle &vecVehicleEyeAngles )
+{
+#ifdef HL2_CLIENT_DLL
+ // Get the frametime. (Check to see if enough time has passed to warrent dampening).
+ float flFrameTime = gpGlobals->frametime;
+
+ if ( flFrameTime < JEEP_FRAMETIME_MIN )
+ {
+ vecVehicleEyePos = m_vecLastEyePos;
+ DampenUpMotion( vecVehicleEyePos, vecVehicleEyeAngles, 0.0f );
+ return;
+ }
+
+ // Keep static the sideways motion.
+ // Dampen forward/backward motion.
+ DampenForwardMotion( vecVehicleEyePos, vecVehicleEyeAngles, flFrameTime );
+
+ // Blend up/down motion.
+ DampenUpMotion( vecVehicleEyePos, vecVehicleEyeAngles, flFrameTime );
+#endif
+}
+
+
+//-----------------------------------------------------------------------------
+// Use the controller as follows:
+// speed += ( pCoefficientsOut[0] * ( targetPos - currentPos ) + pCoefficientsOut[1] * ( targetSpeed - currentSpeed ) ) * flDeltaTime;
+//-----------------------------------------------------------------------------
+void C_PropJeep::ComputePDControllerCoefficients( float *pCoefficientsOut,
+ float flFrequency, float flDampening,
+ float flDeltaTime )
+{
+ float flKs = 9.0f * flFrequency * flFrequency;
+ float flKd = 4.5f * flFrequency * flDampening;
+
+ float flScale = 1.0f / ( 1.0f + flKd * flDeltaTime + flKs * flDeltaTime * flDeltaTime );
+
+ pCoefficientsOut[0] = flKs * flScale;
+ pCoefficientsOut[1] = ( flKd + flKs * flDeltaTime ) * flScale;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_PropJeep::DampenForwardMotion( Vector &vecVehicleEyePos, QAngle &vecVehicleEyeAngles, float flFrameTime )
+{
+ // vecVehicleEyePos = real eye position this frame
+
+ // m_vecLastEyePos = eye position last frame
+ // m_vecEyeSpeed = eye speed last frame
+ // vecPredEyePos = predicted eye position this frame (assuming no acceleration - it will get that from the pd controller).
+ // vecPredEyeSpeed = predicted eye speed
+ Vector vecPredEyePos = m_vecLastEyePos + m_vecEyeSpeed * flFrameTime;
+ Vector vecPredEyeSpeed = m_vecEyeSpeed;
+
+ // m_vecLastEyeTarget = real eye position last frame (used for speed calculation).
+ // Calculate the approximate speed based on the current vehicle eye position and the eye position last frame.
+ Vector vecVehicleEyeSpeed = ( vecVehicleEyePos - m_vecLastEyeTarget ) / flFrameTime;
+ m_vecLastEyeTarget = vecVehicleEyePos;
+ if (vecVehicleEyeSpeed.Length() == 0.0)
+ return;
+
+ // Calculate the delta between the predicted eye position and speed and the current eye position and speed.
+ Vector vecDeltaSpeed = vecVehicleEyeSpeed - vecPredEyeSpeed;
+ Vector vecDeltaPos = vecVehicleEyePos - vecPredEyePos;
+
+ // Forward vector.
+ Vector vecForward;
+ AngleVectors( vecVehicleEyeAngles, &vecForward );
+
+ float flDeltaLength = vecDeltaPos.Length();
+ if ( flDeltaLength > JEEP_DELTA_LENGTH_MAX )
+ {
+ // Clamp.
+ float flDelta = flDeltaLength - JEEP_DELTA_LENGTH_MAX;
+ if ( flDelta > 40.0f )
+ {
+ // This part is a bit of a hack to get rid of large deltas (at level load, etc.).
+ m_vecLastEyePos = vecVehicleEyePos;
+ m_vecEyeSpeed = vecVehicleEyeSpeed;
+ }
+ else
+ {
+ // Position clamp.
+ float flRatio = JEEP_DELTA_LENGTH_MAX / flDeltaLength;
+ vecDeltaPos *= flRatio;
+ Vector vecForwardOffset = vecForward * ( vecForward.Dot( vecDeltaPos ) );
+ vecVehicleEyePos -= vecForwardOffset;
+ m_vecLastEyePos = vecVehicleEyePos;
+
+ // Speed clamp.
+ vecDeltaSpeed *= flRatio;
+ float flCoefficients[2];
+ ComputePDControllerCoefficients( flCoefficients, r_JeepViewDampenFreq.GetFloat(), r_JeepViewDampenDamp.GetFloat(), flFrameTime );
+ m_vecEyeSpeed += ( ( flCoefficients[0] * vecDeltaPos + flCoefficients[1] * vecDeltaSpeed ) * flFrameTime );
+ }
+ }
+ else
+ {
+ // Generate an updated (dampening) speed for use in next frames position prediction.
+ float flCoefficients[2];
+ ComputePDControllerCoefficients( flCoefficients, r_JeepViewDampenFreq.GetFloat(), r_JeepViewDampenDamp.GetFloat(), flFrameTime );
+ m_vecEyeSpeed += ( ( flCoefficients[0] * vecDeltaPos + flCoefficients[1] * vecDeltaSpeed ) * flFrameTime );
+
+ // Save off data for next frame.
+ m_vecLastEyePos = vecPredEyePos;
+
+ // Move eye forward/backward.
+ Vector vecForwardOffset = vecForward * ( vecForward.Dot( vecDeltaPos ) );
+ vecVehicleEyePos -= vecForwardOffset;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_PropJeep::DampenUpMotion( Vector &vecVehicleEyePos, QAngle &vecVehicleEyeAngles, float flFrameTime )
+{
+ // Get up vector.
+ Vector vecUp;
+ AngleVectors( vecVehicleEyeAngles, NULL, NULL, &vecUp );
+ vecUp.z = clamp( vecUp.z, 0.0f, vecUp.z );
+ vecVehicleEyePos.z += r_JeepViewZHeight.GetFloat() * vecUp.z;
+
+ // NOTE: Should probably use some damped equation here.
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_PropJeep::OnEnteredVehicle( C_BasePlayer *pPlayer )
+{
+ int eyeAttachmentIndex = LookupAttachment( "vehicle_driver_eyes" );
+ Vector vehicleEyeOrigin;
+ QAngle vehicleEyeAngles;
+ GetAttachment( eyeAttachmentIndex, vehicleEyeOrigin, vehicleEyeAngles );
+
+ m_vecLastEyeTarget = vehicleEyeOrigin;
+ m_vecLastEyePos = vehicleEyeOrigin;
+ m_vecEyeSpeed = vec3_origin;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : &data -
+//-----------------------------------------------------------------------------
+void WheelDustCallback( const CEffectData &data )
+{
+ CSmartPtr<CSimpleEmitter> pSimple = CSimpleEmitter::Create( "dust" );
+ pSimple->SetSortOrigin( data.m_vOrigin );
+ pSimple->SetNearClip( 32, 64 );
+
+ SimpleParticle *pParticle;
+
+ Vector offset;
+
+ //FIXME: Better sampling area
+ offset = data.m_vOrigin + ( data.m_vNormal * data.m_flScale );
+
+ //Find area ambient light color and use it to tint smoke
+ Vector worldLight = WorldGetLightForPoint( offset, true );
+
+ //Throw puffs
+ offset.Random( -(data.m_flScale*16.0f), data.m_flScale*16.0f );
+ offset.z = 0.0f;
+ offset += data.m_vOrigin + ( data.m_vNormal * data.m_flScale );
+
+ pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof(SimpleParticle), g_Mat_DustPuff[0], offset );
+
+ if ( pParticle != NULL )
+ {
+ pParticle->m_flLifetime = 0.0f;
+ pParticle->m_flDieTime = random->RandomFloat( 0.25f, 0.5f );
+
+ pParticle->m_vecVelocity = RandomVector( -1.0f, 1.0f );
+ VectorNormalize( pParticle->m_vecVelocity );
+ pParticle->m_vecVelocity[2] += random->RandomFloat( 16.0f, 32.0f ) * (data.m_flScale*2.0f);
+
+ int color = random->RandomInt( 100, 150 );
+
+ pParticle->m_uchColor[0] = 16 + ( worldLight[0] * (float) color );
+ pParticle->m_uchColor[1] = 8 + ( worldLight[1] * (float) color );
+ pParticle->m_uchColor[2] = ( worldLight[2] * (float) color );
+
+ pParticle->m_uchStartAlpha = random->RandomInt( 64.0f*data.m_flScale, 128.0f*data.m_flScale );
+ pParticle->m_uchEndAlpha = 0;
+ pParticle->m_uchStartSize = random->RandomInt( 16, 24 ) * data.m_flScale;
+ pParticle->m_uchEndSize = random->RandomInt( 32, 48 ) * data.m_flScale;
+ pParticle->m_flRoll = random->RandomInt( 0, 360 );
+ pParticle->m_flRollDelta = random->RandomFloat( -2.0f, 2.0f );
+ }
+}
+
+DECLARE_CLIENT_EFFECT( "WheelDust", WheelDustCallback ); \ No newline at end of file