diff options
Diffstat (limited to 'game/client/c_prop_vehicle.cpp')
| -rw-r--r-- | game/client/c_prop_vehicle.cpp | 422 |
1 files changed, 422 insertions, 0 deletions
diff --git a/game/client/c_prop_vehicle.cpp b/game/client/c_prop_vehicle.cpp new file mode 100644 index 0000000..d093656 --- /dev/null +++ b/game/client/c_prop_vehicle.cpp @@ -0,0 +1,422 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + + +#include "cbase.h" +#include "c_prop_vehicle.h" +#include "hud.h" +#include <vgui_controls/Controls.h> +#include <Color.h> +#include "view.h" +#include "engine/ivdebugoverlay.h" +#include "movevars_shared.h" +#include "iviewrender.h" +#include "vgui/ISurface.h" +#include "client_virtualreality.h" +#include "../hud_crosshair.h" +#include "sourcevr/isourcevirtualreality.h" +// NVNT haptic utils +#include "haptics/haptic_utils.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +int ScreenTransform( const Vector& point, Vector& screen ); + +extern ConVar default_fov; +extern ConVar joy_response_move_vehicle; + + +IMPLEMENT_CLIENTCLASS_DT(C_PropVehicleDriveable, DT_PropVehicleDriveable, CPropVehicleDriveable) + RecvPropEHandle( RECVINFO(m_hPlayer) ), + RecvPropInt( RECVINFO( m_nSpeed ) ), + RecvPropInt( RECVINFO( m_nRPM ) ), + RecvPropFloat( RECVINFO( m_flThrottle ) ), + RecvPropInt( RECVINFO( m_nBoostTimeLeft ) ), + RecvPropInt( RECVINFO( m_nHasBoost ) ), + RecvPropInt( RECVINFO( m_nScannerDisabledWeapons ) ), + RecvPropInt( RECVINFO( m_nScannerDisabledVehicle ) ), + RecvPropInt( RECVINFO( m_bEnterAnimOn ) ), + RecvPropInt( RECVINFO( m_bExitAnimOn ) ), + RecvPropInt( RECVINFO( m_bUnableToFire ) ), + RecvPropVector( RECVINFO( m_vecEyeExitEndpoint ) ), + RecvPropBool( RECVINFO( m_bHasGun ) ), + RecvPropVector( RECVINFO( m_vecGunCrosshair ) ), +END_RECV_TABLE() + + +BEGIN_DATADESC( C_PropVehicleDriveable ) + DEFINE_EMBEDDED( m_ViewSmoothingData ), +END_DATADESC() + +ConVar r_VehicleViewClamp( "r_VehicleViewClamp", "1", FCVAR_CHEAT ); + +#define ROLL_CURVE_ZERO 20 // roll less than this is clamped to zero +#define ROLL_CURVE_LINEAR 90 // roll greater than this is copied out + +#define PITCH_CURVE_ZERO 10 // pitch less than this is clamped to zero +#define PITCH_CURVE_LINEAR 45 // pitch greater than this is copied out + // spline in between + + +//----------------------------------------------------------------------------- +// Purpose: Constructor +//----------------------------------------------------------------------------- +C_PropVehicleDriveable::C_PropVehicleDriveable() : + m_iv_vecGunCrosshair( "C_PropVehicleDriveable::m_iv_vecGunCrosshair" ) + +{ + m_hPrevPlayer = NULL; + + memset( &m_ViewSmoothingData, 0, sizeof( m_ViewSmoothingData ) ); + + m_ViewSmoothingData.pVehicle = this; + m_ViewSmoothingData.bClampEyeAngles = true; + m_ViewSmoothingData.bDampenEyePosition = true; + + m_ViewSmoothingData.flPitchCurveZero = PITCH_CURVE_ZERO; + m_ViewSmoothingData.flPitchCurveLinear = PITCH_CURVE_LINEAR; + m_ViewSmoothingData.flRollCurveZero = ROLL_CURVE_ZERO; + m_ViewSmoothingData.flRollCurveLinear = ROLL_CURVE_LINEAR; + + m_ViewSmoothingData.flFOV = m_flFOV = default_fov.GetFloat(); + + AddVar( &m_vecGunCrosshair, &m_iv_vecGunCrosshair, LATCH_SIMULATION_VAR ); +} + +//----------------------------------------------------------------------------- +// Purpose: De-constructor +//----------------------------------------------------------------------------- +C_PropVehicleDriveable::~C_PropVehicleDriveable() +{ +} + + +//----------------------------------------------------------------------------- +// By default all driveable vehicles use the curve defined by the convar. +//----------------------------------------------------------------------------- +int C_PropVehicleDriveable::GetJoystickResponseCurve() const +{ + return joy_response_move_vehicle.GetInt(); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +C_BaseCombatCharacter *C_PropVehicleDriveable::GetPassenger( int nRole ) +{ + if ( nRole == VEHICLE_ROLE_DRIVER ) + return m_hPlayer.Get(); + + return NULL; +} + +//----------------------------------------------------------------------------- +// Returns the role of the passenger +//----------------------------------------------------------------------------- +int C_PropVehicleDriveable::GetPassengerRole( C_BaseCombatCharacter *pPassenger ) +{ + if ( m_hPlayer.Get() == pPassenger ) + return VEHICLE_ROLE_DRIVER; + + return VEHICLE_ROLE_NONE; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : updateType - +//----------------------------------------------------------------------------- +void C_PropVehicleDriveable::OnPreDataChanged( DataUpdateType_t updateType ) +{ + BaseClass::OnPreDataChanged( updateType ); + + m_hPrevPlayer = m_hPlayer; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_PropVehicleDriveable::OnDataChanged( DataUpdateType_t updateType ) +{ + BaseClass::OnDataChanged( updateType ); + + if ( m_hPlayer && !m_hPrevPlayer ) + { + OnEnteredVehicle( m_hPlayer ); + SetNextClientThink( CLIENT_THINK_ALWAYS ); + g_ClientVirtualReality.AlignTorsoAndViewToWeapon(); + } + else if ( !m_hPlayer && m_hPrevPlayer ) + { + // NVNT notify haptics system of navigation exit + OnExitedVehicle( m_hPrevPlayer ); + // They have just exited the vehicle. + // Sometimes we never reach the end of our exit anim, such as if the + // animation doesn't have fadeout 0 specified in the QC, so we fail to + // catch it in VehicleViewSmoothing. Catch it here instead. + m_ViewSmoothingData.bWasRunningAnim = false; + SetNextClientThink( CLIENT_THINK_NEVER ); + } +} + +//----------------------------------------------------------------------------- +// Should this object cast render-to-texture shadows? +//----------------------------------------------------------------------------- +ShadowType_t C_PropVehicleDriveable::ShadowCastType() +{ + CStudioHdr *pStudioHdr = GetModelPtr(); + if ( !pStudioHdr ) + return SHADOWS_NONE; + + if ( IsEffectActive(EF_NODRAW | EF_NOSHADOW) ) + return SHADOWS_NONE; + + // Always use render-to-texture. We'll always the dirty bits in our think function + return SHADOWS_RENDER_TO_TEXTURE; +} + + +//----------------------------------------------------------------------------- +// Mark the shadow as dirty while the vehicle is being driven +//----------------------------------------------------------------------------- +void C_PropVehicleDriveable::ClientThink( void ) +{ + // The vehicle is always dirty owing to pose parameters while it's being driven. + g_pClientShadowMgr->MarkRenderToTextureShadowDirty( GetShadowHandle() ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_PropVehicleDriveable::DampenEyePosition( Vector &vecVehicleEyePos, QAngle &vecVehicleEyeAngles ) +{ +} + +//----------------------------------------------------------------------------- +// Purpose: Modify the player view/camera while in a vehicle +//----------------------------------------------------------------------------- +void C_PropVehicleDriveable::GetVehicleViewPosition( int nRole, Vector *pAbsOrigin, QAngle *pAbsAngles, float *pFOV /*=NULL*/ ) +{ + SharedVehicleViewSmoothing( m_hPlayer, + pAbsOrigin, pAbsAngles, + m_bEnterAnimOn, m_bExitAnimOn, + m_vecEyeExitEndpoint, + &m_ViewSmoothingData, + pFOV ); +} + + +//----------------------------------------------------------------------------- +// Futzes with the clip planes +//----------------------------------------------------------------------------- +void C_PropVehicleDriveable::GetVehicleClipPlanes( float &flZNear, float &flZFar ) const +{ + // FIXME: Need something a better long-term, this fixes the buggy. + flZNear = 6; +} + + +//----------------------------------------------------------------------------- +// Renders hud elements +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Simply used to return intensity value based upon current timer passed in +//----------------------------------------------------------------------------- +int GetFlashColorIntensity( int LowIntensity, int HighIntensity, bool Dimming, int Increment, int Timer ) +{ + if ( Dimming ) + return ( HighIntensity - Timer * Increment ); + else + return ( LowIntensity + Timer * Increment ); +} + +#define TRIANGULATED_CROSSHAIR 1 + +void C_PropVehicleDriveable::DrawHudElements( ) +{ + CHudTexture *pIcon; + int iIconX, iIconY; + + if (m_bHasGun) + { + // draw crosshairs for vehicle gun + pIcon = gHUD.GetIcon( "gunhair" ); + + if ( pIcon != NULL ) + { + float x, y; + + if( UseVR() ) + { + C_BasePlayer *pPlayer = (C_BasePlayer *)GetPassenger( VEHICLE_ROLE_DRIVER ); + Vector vecStart, vecDirection; + pPlayer->EyePositionAndVectors( &vecStart, &vecDirection, NULL, NULL ); + Vector vecEnd = vecStart + vecDirection * MAX_TRACE_LENGTH; + + trace_t tr; + UTIL_TraceLine( vecStart, vecEnd, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr ); + + Vector screen; + screen.Init(); + ScreenTransform(tr.endpos, screen); + + int vx, vy, vw, vh; + vgui::surface()->GetFullscreenViewport( vx, vy, vw, vh ); + + float screenWidth = vw; + float screenHeight = vh; + + x = 0.5f * ( 1.0f + screen[0] ) * screenWidth + 0.5f; + y = 0.5f * ( 1.0f - screen[1] ) * screenHeight + 0.5f; + } + else + { + Vector screen; + + x = ScreenWidth()/2; + y = ScreenHeight()/2; + +#if TRIANGULATED_CROSSHAIR + ScreenTransform( m_vecGunCrosshair, screen ); + x += 0.5 * screen[0] * ScreenWidth() + 0.5; + y -= 0.5 * screen[1] * ScreenHeight() + 0.5; +#endif + } + + + x -= pIcon->Width() / 2; + y -= pIcon->Height() / 2; + + Color clr = ( m_bUnableToFire ) ? gHUD.m_clrCaution : gHUD.m_clrNormal; + pIcon->DrawSelf( x, y, clr ); + } + + if ( m_nScannerDisabledWeapons ) + { + // Draw icons for scanners "weps disabled" + pIcon = gHUD.GetIcon( "dmg_bio" ); + if ( pIcon ) + { + iIconY = 467 - pIcon->Height() / 2; + iIconX = 385; + if ( !m_bScannerWepIcon ) + { + pIcon->DrawSelf( XRES(iIconX), YRES(iIconY), Color( 0, 0, 255, 255 ) ); + m_bScannerWepIcon = true; + m_iScannerWepFlashTimer = 0; + m_bScannerWepDim = true; + } + else + { + pIcon->DrawSelf( XRES(iIconX), YRES(iIconY), Color( 0, 0, GetFlashColorIntensity(55, 255, m_bScannerWepDim, 10, m_iScannerWepFlashTimer), 255 ) ); + m_iScannerWepFlashTimer++; + m_iScannerWepFlashTimer %= 20; + if(!m_iScannerWepFlashTimer) + m_bScannerWepDim ^= 1; + } + } + } + } + + if ( m_nScannerDisabledVehicle ) + { + // Draw icons for scanners "vehicle disabled" + pIcon = gHUD.GetIcon( "dmg_bio" ); + if ( pIcon ) + { + iIconY = 467 - pIcon->Height() / 2; + iIconX = 410; + if ( !m_bScannerVehicleIcon ) + { + pIcon->DrawSelf( XRES(iIconX), YRES(iIconY), Color( 0, 0, 255, 255 ) ); + m_bScannerVehicleIcon = true; + m_iScannerVehicleFlashTimer = 0; + m_bScannerVehicleDim = true; + } + else + { + pIcon->DrawSelf( XRES(iIconX), YRES(iIconY), Color( 0, 0, GetFlashColorIntensity(55, 255, m_bScannerVehicleDim, 10, m_iScannerVehicleFlashTimer), 255 ) ); + m_iScannerVehicleFlashTimer++; + m_iScannerVehicleFlashTimer %= 20; + if(!m_iScannerVehicleFlashTimer) + m_bScannerVehicleDim ^= 1; + } + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_PropVehicleDriveable::RestrictView( float *pYawBounds, float *pPitchBounds, + float *pRollBounds, QAngle &vecViewAngles ) +{ + int eyeAttachmentIndex = LookupAttachment( "vehicle_driver_eyes" ); + Vector vehicleEyeOrigin; + QAngle vehicleEyeAngles; + GetAttachmentLocal( eyeAttachmentIndex, vehicleEyeOrigin, vehicleEyeAngles ); + + // Limit the yaw. + if ( pYawBounds ) + { + float flAngleDiff = AngleDiff( vecViewAngles.y, vehicleEyeAngles.y ); + flAngleDiff = clamp( flAngleDiff, pYawBounds[0], pYawBounds[1] ); + vecViewAngles.y = vehicleEyeAngles.y + flAngleDiff; + } + + // Limit the pitch. + if ( pPitchBounds ) + { + float flAngleDiff = AngleDiff( vecViewAngles.x, vehicleEyeAngles.x ); + flAngleDiff = clamp( flAngleDiff, pPitchBounds[0], pPitchBounds[1] ); + vecViewAngles.x = vehicleEyeAngles.x + flAngleDiff; + } + + // Limit the roll. + if ( pRollBounds ) + { + float flAngleDiff = AngleDiff( vecViewAngles.z, vehicleEyeAngles.z ); + flAngleDiff = clamp( flAngleDiff, pRollBounds[0], pRollBounds[1] ); + vecViewAngles.z = vehicleEyeAngles.z + flAngleDiff; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_PropVehicleDriveable::UpdateViewAngles( C_BasePlayer *pLocalPlayer, CUserCmd *pCmd ) +{ + if ( r_VehicleViewClamp.GetInt() ) + { + float pitchBounds[2] = { -85.0f, 25.0f }; + RestrictView( NULL, pitchBounds, NULL, pCmd->viewangles ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_PropVehicleDriveable::OnEnteredVehicle( C_BaseCombatCharacter *pPassenger ) +{ +#if defined( WIN32 ) && !defined( _X360 ) + // NVNT notify haptics system of navigation change + HapticsEnteredVehicle(this,pPassenger); +#endif +} + +// NVNT - added function +void C_PropVehicleDriveable::OnExitedVehicle( C_BaseCombatCharacter *pPassenger ) +{ +#if defined( WIN32 ) && !defined( _X360 ) + // NVNT notify haptics system of navigation exit + HapticsExitedVehicle(this,pPassenger); +#endif +} + |