mirror of
https://github.com/mapbase-source/source-sdk-2013.git
synced 2025-01-23 12:17:57 +03:00
beaae8ac45
* Adds support for Visual Studio 2012 and 2013 * VR Mode: . Switches from headtrack.dll to sourcevr.dll . Improved readability of the UI in VR . Removed the IPD calibration tool. TF2 will now obey the Oculus configuration file. Use the Oculus calibration tool in your SDK or install and run "OpenVR" under Tools in Steam to calibrate your IPD. . Added dropdown to enable VR mode in the Video options. Removed the -vr command line option. . Added the ability to switch in and out of VR mode without quitting the game . By default VR mode will run full screen. To switch back to a borderless window set the vr_force_windowed convar. . Added support for VR mode on Linux * Many assorted bug fixes and other changes from Team Fortress in various shared files
423 lines
13 KiB
C++
423 lines
13 KiB
C++
//========= 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
|
|
}
|
|
|