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.
763 lines
24 KiB
763 lines
24 KiB
![]()
4 years ago
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
//
|
||
|
// Purpose: A moving vehicle that is used as a battering ram
|
||
|
//
|
||
|
// $NoKeywords: $
|
||
|
//=============================================================================//
|
||
|
|
||
|
#include "cbase.h"
|
||
|
#include "tf_basefourwheelvehicle.h"
|
||
|
#include "engine/IEngineSound.h"
|
||
|
#include "soundenvelope.h"
|
||
|
#include "vcollide_parse.h"
|
||
|
#include "in_buttons.h"
|
||
|
#include "tf_movedata.h"
|
||
|
|
||
|
#define BASEFOURWHEELEDVEHICLE_THINK_CONTEXT "BaseFourWheeledThink"
|
||
|
#define BASEFOURWHEELEDVEHICLE_DEPLOYTHINK_CONTEXT "BaseFourWheeledDeployThink"
|
||
|
// HACK HAC
|
||
|
#define BASEFOURWHEELEDVEHICLE_STOPTHERODEO_CONTEXT "BaseFourWheeledVehicleStopTheRodeoMadnessThink"
|
||
|
|
||
|
ConVar road_feel( "road_feel", "0.1", FCVAR_NOTIFY | FCVAR_REPLICATED );
|
||
|
extern ConVar tf_fastbuild;
|
||
|
|
||
|
BEGIN_DATADESC( CBaseTFFourWheelVehicle )
|
||
|
|
||
|
DEFINE_EMBEDDED( m_VehiclePhysics ),
|
||
|
|
||
|
DEFINE_INPUTFUNC( FIELD_FLOAT, "Throttle", InputThrottle ),
|
||
|
DEFINE_INPUTFUNC( FIELD_FLOAT, "Steer", InputSteering ),
|
||
|
DEFINE_INPUTFUNC( FIELD_FLOAT, "Action", InputAction ),
|
||
|
DEFINE_INPUTFUNC( FIELD_VOID, "TurnOn", InputTurnOn ),
|
||
|
DEFINE_INPUTFUNC( FIELD_VOID, "TurnOff", InputTurnOff ),
|
||
|
|
||
|
END_DATADESC()
|
||
|
|
||
|
|
||
|
// Used for debugging to make vehicle deploying go really fast.
|
||
|
ConVar tf_fastdeploy( "tf_fastdeploy", "0", FCVAR_CHEAT );
|
||
|
|
||
|
|
||
|
IMPLEMENT_SERVERCLASS_ST(CBaseTFFourWheelVehicle, DT_BaseTFFourWheelVehicle)
|
||
|
SendPropFloat( SENDINFO( m_flDeployFinishTime ), 0, SPROP_NOSCALE ),
|
||
|
SendPropInt( SENDINFO( m_eDeployMode ), NUM_VEHICLE_DEPLOYMODE_BITS, SPROP_UNSIGNED ),
|
||
|
SendPropInt( SENDINFO( m_bBoostUpgrade ), 1, SPROP_UNSIGNED ),
|
||
|
SendPropInt( SENDINFO( m_nBoostTimeLeft ), 8, SPROP_UNSIGNED ),
|
||
|
END_SEND_TABLE()
|
||
|
|
||
|
ConVar fourwheelvehicle_hit_damage( "fourwheelvehicle_hit_damage","40", FCVAR_NONE, "Four-wheel vehicle hit damage" );
|
||
|
ConVar fourwheelvehicle_hit_damage_boostmod( "fourwheelvehicle_hit_damage_boostmod", "1.5", FCVAR_NONE, "Four-wheel vehicle boosted hit damage modifier" );
|
||
|
ConVar fourwheelvehicle_hit_mindamagevel( "fourwheelvehicle_hit_mindamagevel","100", FCVAR_NONE, "Four-wheel vehciel hit velocity for min damage" );
|
||
|
ConVar fourwheelvehicle_hit_maxdamagevel( "fourwheelvehicle_hit_maxdamagevel","230", FCVAR_NONE, "Four-wheel vehicle hit velocity for max damage" );
|
||
|
ConVar fourwheelvehicle_impact_time( "fourwheelvehicle_impact_time", "1.0", FCVAR_NONE, "Four-wheel vehicle impact wait time." );
|
||
|
ConVar fourwheelvehicle_hit_damage_player( "fourwheelvehicle_hit_damage_player", "30.0f", FCVAR_NONE, "Four-wheel vehicle hit player damage." );
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Constructor
|
||
|
//-----------------------------------------------------------------------------
|
||
|
#pragma warning( disable: 4355 )
|
||
|
CBaseTFFourWheelVehicle::CBaseTFFourWheelVehicle() : m_VehiclePhysics(this)
|
||
|
{
|
||
|
m_flDeployFinishTime = -1;
|
||
|
}
|
||
|
#pragma warning( default: 4355 )
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Destructor
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CBaseTFFourWheelVehicle::~CBaseTFFourWheelVehicle ()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Put a vehicle in a deploy state. Turn off the engine and run a
|
||
|
// deploy animation.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
bool CBaseTFFourWheelVehicle::Deploy( void )
|
||
|
{
|
||
|
// Make sure we're allowed to deploy here
|
||
|
if ( !IsReadyToDrive() )
|
||
|
return false;
|
||
|
|
||
|
// Check to see if we are already in a deploy mode.
|
||
|
if ( m_eDeployMode != VEHICLE_MODE_NORMAL )
|
||
|
return false;
|
||
|
|
||
|
// Disable the vehicle's motion.
|
||
|
DisableMotion();
|
||
|
|
||
|
// Save pre-deploy activity.
|
||
|
m_PreDeployActivity = GetActivity();
|
||
|
|
||
|
// Set the deploying activity - ACT_DEPLOY
|
||
|
SetActivity( ACT_DEPLOY );
|
||
|
|
||
|
// Get the deployment time.
|
||
|
float flDeployTime = SequenceDuration();
|
||
|
if ( tf_fastdeploy.GetBool() )
|
||
|
flDeployTime = 1;
|
||
|
|
||
|
m_flDeployFinishTime = gpGlobals->curtime + flDeployTime;
|
||
|
|
||
|
SetContextThink( BaseFourWheeledVehicleDeployThink, gpGlobals->curtime + flDeployTime,
|
||
|
BASEFOURWHEELEDVEHICLE_DEPLOYTHINK_CONTEXT );
|
||
|
|
||
|
// Set the deploy mode.
|
||
|
m_eDeployMode = VEHICLE_MODE_DEPLOYING;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Release a vehicle from a deployed state. Run a de-coupling
|
||
|
// animation and turn on the vehicle.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::UnDeploy( void )
|
||
|
{
|
||
|
// Make sure we are deployed.
|
||
|
if ( !IsDeployed() )
|
||
|
return;
|
||
|
|
||
|
// Enable motion and turn on the vehicle.
|
||
|
EnableMotion();
|
||
|
|
||
|
// Set the undeploying activity - ACT_UNDEPLOY
|
||
|
SetActivity( ACT_UNDEPLOY );
|
||
|
|
||
|
// Get the undeployment time.
|
||
|
float flUnDeployTime = SequenceDuration();
|
||
|
if ( tf_fastdeploy.GetBool() )
|
||
|
flUnDeployTime = 1;
|
||
|
|
||
|
m_flDeployFinishTime = gpGlobals->curtime + flUnDeployTime;
|
||
|
|
||
|
SetContextThink( BaseFourWheeledVehicleDeployThink, gpGlobals->curtime + flUnDeployTime,
|
||
|
BASEFOURWHEELEDVEHICLE_DEPLOYTHINK_CONTEXT );
|
||
|
|
||
|
// Set the deploy mode.
|
||
|
m_eDeployMode = VEHICLE_MODE_UNDEPLOYING;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::CancelDeploy( void )
|
||
|
{
|
||
|
// Check for the deploying state.
|
||
|
if ( !IsDeploying() )
|
||
|
return;
|
||
|
|
||
|
// Re-enable the motion.
|
||
|
EnableMotion();
|
||
|
|
||
|
// Reset the activity to the previous activity.
|
||
|
SetActivity( m_PreDeployActivity );
|
||
|
|
||
|
// Reset the deploy mode.
|
||
|
m_eDeployMode = VEHICLE_MODE_NORMAL;
|
||
|
|
||
|
m_flDeployFinishTime = -1;
|
||
|
|
||
|
// Turn off the context think.
|
||
|
SetContextThink( NULL, 0, BASEFOURWHEELEDVEHICLE_DEPLOYTHINK_CONTEXT );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::BaseFourWheeledVehicleDeployThink( void )
|
||
|
{
|
||
|
// Called from deploy.
|
||
|
if ( IsDeploying() )
|
||
|
{
|
||
|
OnFinishedDeploy();
|
||
|
m_flDeployFinishTime = -1;
|
||
|
}
|
||
|
// Called from undeploy.
|
||
|
else if ( IsUndeploying() )
|
||
|
{
|
||
|
OnFinishedUnDeploy();
|
||
|
m_flDeployFinishTime = -1;
|
||
|
}
|
||
|
|
||
|
// Turn off the context think.
|
||
|
SetContextThink( NULL, 0, BASEFOURWHEELEDVEHICLE_DEPLOYTHINK_CONTEXT );
|
||
|
}
|
||
|
|
||
|
void CBaseTFFourWheelVehicle::BaseFourWheeledVehicleStopTheRodeoMadnessThink( void )
|
||
|
{
|
||
|
// HACK HACK: See note above at FinishBuilding call
|
||
|
// This resets the handbrake, so the newly placed object doesn't roll down any hills.
|
||
|
m_VehiclePhysics.ResetControls();
|
||
|
|
||
|
// Turn off the context think.
|
||
|
SetContextThink( NULL, 0, BASEFOURWHEELEDVEHICLE_STOPTHERODEO_CONTEXT );
|
||
|
|
||
|
// Start our base think
|
||
|
SetContextThink( BaseFourWheeledVehicleThink, gpGlobals->curtime + 0.1, BASEFOURWHEELEDVEHICLE_THINK_CONTEXT );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::OnFinishedDeploy( void )
|
||
|
{
|
||
|
SetActivity( ACT_DEPLOY_IDLE );
|
||
|
m_eDeployMode = VEHICLE_MODE_DEPLOYED;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::OnFinishedUnDeploy( void )
|
||
|
{
|
||
|
m_eDeployMode = VEHICLE_MODE_NORMAL;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Allow the vehicle to move.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::EnableMotion( void )
|
||
|
{
|
||
|
// Enable vehicle chasis motion.
|
||
|
IPhysicsObject *pVehicleObject = VPhysicsGetObject();
|
||
|
if ( pVehicleObject )
|
||
|
{
|
||
|
pVehicleObject->EnableMotion( true );
|
||
|
}
|
||
|
|
||
|
// Enable motion on the tires.
|
||
|
m_VehiclePhysics.EnableMotion();
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Dis-allow the vehicle to move.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::DisableMotion( void )
|
||
|
{
|
||
|
// Disable vehicle chasis motion.
|
||
|
IPhysicsObject *pVehicleObject = VPhysicsGetObject();
|
||
|
if ( pVehicleObject )
|
||
|
{
|
||
|
pVehicleObject->EnableMotion( false );
|
||
|
}
|
||
|
|
||
|
// Disable motion on the tires.
|
||
|
m_VehiclePhysics.DisableMotion();
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Precache
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::Precache()
|
||
|
{
|
||
|
BaseClass::Precache();
|
||
|
|
||
|
PrecacheScriptSound( "BaseTFFourWheelVehicle.EMP" );
|
||
|
PrecacheScriptSound( "BaseTFFourWheelVehicle.RamSound" );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Spawn
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::Spawn( )
|
||
|
{
|
||
|
SetModel( STRING( GetModelName() ) );
|
||
|
// CFourWheelServerVehicle *pServerVehicle = dynamic_cast<CFourWheelServerVehicle*>(GetServerVehicle());
|
||
|
// m_VehiclePhysics.SetOuter( this, pServerVehicle );
|
||
|
m_VehiclePhysics.Spawn();
|
||
|
BaseClass::Spawn();
|
||
|
// The base class spawn sets a default collision group, so this needs to
|
||
|
// be called post.
|
||
|
SetCollisionGroup( COLLISION_GROUP_VEHICLE );
|
||
|
|
||
|
m_eDeployMode = VEHICLE_MODE_NORMAL;
|
||
|
|
||
|
SetBoostUpgrade( false );
|
||
|
|
||
|
m_flNextHitTime = 0.0f;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Teleport
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::Teleport( const Vector *newPosition, const QAngle *newAngles, const Vector *newVelocity )
|
||
|
{
|
||
|
// We basically just have to make sure the wheels are in the right place
|
||
|
// after teleportation occurs
|
||
|
matrix3x4_t startMatrixInv;
|
||
|
MatrixInvert( EntityToWorldTransform(), startMatrixInv );
|
||
|
|
||
|
BaseClass::Teleport( newPosition, newAngles, newVelocity );
|
||
|
|
||
|
// Teleport the vehicle physics from the starting position to the ending one
|
||
|
matrix3x4_t relativeTransform;
|
||
|
ConcatTransforms( EntityToWorldTransform(), startMatrixInv, relativeTransform );
|
||
|
m_VehiclePhysics.Teleport( relativeTransform );
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Debugging methods
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::DrawDebugGeometryOverlays()
|
||
|
{
|
||
|
if (m_debugOverlays & OVERLAY_BBOX_BIT)
|
||
|
{
|
||
|
m_VehiclePhysics.DrawDebugGeometryOverlays();
|
||
|
}
|
||
|
BaseClass::DrawDebugGeometryOverlays();
|
||
|
}
|
||
|
|
||
|
int CBaseTFFourWheelVehicle::DrawDebugTextOverlays()
|
||
|
{
|
||
|
int nOffset = BaseClass::DrawDebugTextOverlays();
|
||
|
if (m_debugOverlays & OVERLAY_TEXT_BIT)
|
||
|
{
|
||
|
nOffset = m_VehiclePhysics.DrawDebugTextOverlays( nOffset );
|
||
|
}
|
||
|
return nOffset;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
bool CBaseTFFourWheelVehicle::StartBuilding( CBaseEntity *pPlayer )
|
||
|
{
|
||
|
if (!BaseClass::StartBuilding(pPlayer))
|
||
|
return false;
|
||
|
|
||
|
// Until we're finished building, turn off vphysics-based motion
|
||
|
SetSolid( SOLID_VPHYSICS );
|
||
|
VPhysicsInitStatic();
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::FinishedBuilding( void )
|
||
|
{
|
||
|
BaseClass::FinishedBuilding();
|
||
|
|
||
|
char pScriptName[128];
|
||
|
Q_snprintf( pScriptName, sizeof( pScriptName ), "scripts/vehicles/%s.txt", GetClassname() );
|
||
|
m_VehiclePhysics.Initialize( pScriptName, true );
|
||
|
|
||
|
// HACK HACK: This is a hack to avoid physics spazzing out on a newly created vehicle with the handbrake
|
||
|
// set. We create and activate it, but then release the handbrake for a single Think function call and
|
||
|
// then zero out the controls right then. This seems to stabilize something in the physics simulator.
|
||
|
m_VehiclePhysics.ReleaseHandbrake();
|
||
|
SetContextThink( BaseFourWheeledVehicleStopTheRodeoMadnessThink, gpGlobals->curtime, BASEFOURWHEELEDVEHICLE_STOPTHERODEO_CONTEXT );
|
||
|
|
||
|
ResetDeteriorationTime();
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Input methods
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::InputThrottle( inputdata_t &inputdata )
|
||
|
{
|
||
|
m_VehiclePhysics.SetThrottle( inputdata.value.Float() );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::InputSteering( inputdata_t &inputdata )
|
||
|
{
|
||
|
m_VehiclePhysics.SetSteering( inputdata.value.Float(), 2*gpGlobals->frametime );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::InputAction( inputdata_t &inputdata )
|
||
|
{
|
||
|
m_VehiclePhysics.SetAction( inputdata.value.Float() );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::InputTurnOn( inputdata_t &inputdata )
|
||
|
{
|
||
|
if (!m_VehiclePhysics.IsOn())
|
||
|
{
|
||
|
SetContextThink( BaseFourWheeledVehicleThink, gpGlobals->curtime + 0.1, BASEFOURWHEELEDVEHICLE_THINK_CONTEXT );
|
||
|
m_VehiclePhysics.TurnOn( );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::InputTurnOff( inputdata_t &inputdata )
|
||
|
{
|
||
|
if ( m_VehiclePhysics.IsOn() )
|
||
|
{
|
||
|
m_VehiclePhysics.TurnOff( );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Input methods
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::BaseFourWheeledVehicleThink()
|
||
|
{
|
||
|
if (m_VehiclePhysics.Think())
|
||
|
{
|
||
|
SetNextThink( gpGlobals->curtime, BASEFOURWHEELEDVEHICLE_THINK_CONTEXT );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::VPhysicsUpdate( IPhysicsObject *pPhysics )
|
||
|
{
|
||
|
// must be a wheel
|
||
|
if (!m_VehiclePhysics.VPhysicsUpdate(pPhysics))
|
||
|
return;
|
||
|
|
||
|
BaseClass::VPhysicsUpdate( pPhysics );
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Methods related to getting in and out of the vehicle
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::SetPassenger( int nRole, CBasePlayer *pEnt )
|
||
|
{
|
||
|
if ( nRole == VEHICLE_ROLE_DRIVER )
|
||
|
{
|
||
|
if (pEnt)
|
||
|
{
|
||
|
PlayerControlInit( ToBasePlayer(pEnt) );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
PlayerControlShutdown( );
|
||
|
}
|
||
|
}
|
||
|
BaseClass::SetPassenger( nRole, pEnt );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::PlayerControlInit( CBasePlayer *pPlayer )
|
||
|
{
|
||
|
// Blat out the view offset
|
||
|
m_savedViewOffset = pPlayer->GetViewOffset();
|
||
|
pPlayer->SetViewOffset( vec3_origin );
|
||
|
|
||
|
m_playerOn.FireOutput( pPlayer, this, 0 );
|
||
|
InputTurnOn( inputdata_t() );
|
||
|
|
||
|
// Release the handbrake.
|
||
|
if ( !IsDeployed() )
|
||
|
{
|
||
|
m_VehiclePhysics.ReleaseHandbrake();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::ResetUseKey( CBasePlayer *pPlayer )
|
||
|
{
|
||
|
pPlayer->m_afButtonPressed &= ~IN_USE;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::PlayerControlShutdown()
|
||
|
{
|
||
|
CBasePlayer *pPlayer = GetDriverPlayer();
|
||
|
if ( !pPlayer )
|
||
|
return;
|
||
|
|
||
|
ResetUseKey( pPlayer );
|
||
|
pPlayer->SetViewOffset( m_savedViewOffset );
|
||
|
|
||
|
m_playerOff.FireOutput( pPlayer, this, 0 );
|
||
|
// clear out the fire buttons
|
||
|
m_attackaxis.Set( 0, pPlayer, this );
|
||
|
m_attack2axis.Set( 0, pPlayer, this );
|
||
|
|
||
|
InputTurnOff( inputdata_t() );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Powerup has just started
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::PowerupStart( int iPowerup, float flAmount, CBaseEntity *pAttacker, CDamageModifier *pDamageModifier )
|
||
|
{
|
||
|
switch( iPowerup )
|
||
|
{
|
||
|
case POWERUP_EMP:
|
||
|
m_VehiclePhysics.SetMaxThrottle( 0.1 );
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
BaseClass::PowerupStart( iPowerup, flAmount, pAttacker, pDamageModifier );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Powerup has just started
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::PowerupEnd( int iPowerup )
|
||
|
{
|
||
|
switch ( iPowerup )
|
||
|
{
|
||
|
case POWERUP_EMP:
|
||
|
m_VehiclePhysics.SetMaxThrottle( 1.0 );
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
BaseClass::PowerupEnd( iPowerup );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Methods related to actually driving the vehicle
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::DriveVehicle( CBasePlayer *pPlayer, CUserCmd *ucmd )
|
||
|
{
|
||
|
// Lose control when the player dies
|
||
|
if ( pPlayer->IsAlive() == false )
|
||
|
return;
|
||
|
|
||
|
// Only the driver gets to drive.
|
||
|
int nRole = GetPassengerRole( pPlayer );
|
||
|
if ( nRole != VEHICLE_ROLE_DRIVER )
|
||
|
return;
|
||
|
|
||
|
// No driving in the mothership, kids
|
||
|
if ( !tf_fastbuild.GetInt() && !IsReadyToDrive() )
|
||
|
{
|
||
|
m_VehiclePhysics.SetHandbrake( true );
|
||
|
m_VehiclePhysics.SetThrottle( 0 );
|
||
|
m_VehiclePhysics.SetSteering( 0, 0 );
|
||
|
m_attackaxis.Set( 0, pPlayer, this );
|
||
|
m_attack2axis.Set( 0, pPlayer, this );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Update the boost time.
|
||
|
m_nBoostTimeLeft = m_VehiclePhysics.BoostTimeLeft();
|
||
|
|
||
|
// If the vehicle's emped, it can't drive
|
||
|
if ( HasPowerup( POWERUP_EMP ) )
|
||
|
{
|
||
|
// Play sounds if they're trying to drive
|
||
|
if ( ucmd->buttons & (IN_MOVELEFT | IN_MOVERIGHT | IN_FORWARD | IN_BACK) )
|
||
|
{
|
||
|
if ( m_flNextEmpSound < gpGlobals->curtime )
|
||
|
{
|
||
|
EmitSound( "BaseTFFourWheelVehicle.EMP" );
|
||
|
m_flNextEmpSound = gpGlobals->curtime + 2.0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ResetDeteriorationTime();
|
||
|
|
||
|
m_VehiclePhysics.UpdateDriverControls( ucmd, TICK_INTERVAL );
|
||
|
|
||
|
float attack = 0, attack2 = 0;
|
||
|
|
||
|
if ( pPlayer->m_afButtonPressed & IN_ATTACK )
|
||
|
{
|
||
|
m_pressedAttack.FireOutput( pPlayer, this, 0 );
|
||
|
}
|
||
|
if ( pPlayer->m_afButtonPressed & IN_ATTACK2 )
|
||
|
{
|
||
|
m_pressedAttack2.FireOutput( pPlayer, this, 0 );
|
||
|
}
|
||
|
|
||
|
if ( ucmd->buttons & IN_ATTACK )
|
||
|
{
|
||
|
attack = 1;
|
||
|
}
|
||
|
if ( ucmd->buttons & IN_ATTACK2 )
|
||
|
{
|
||
|
attack2 = 1;
|
||
|
}
|
||
|
|
||
|
m_attackaxis.Set( attack, pPlayer, this );
|
||
|
m_attack2axis.Set( attack2, pPlayer, this );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::SetupMove( CBasePlayer *pPlayer, CUserCmd *ucmd, IMoveHelper *pHelper, CMoveData *move )
|
||
|
{
|
||
|
BaseClass::SetupMove( pPlayer, ucmd, pHelper, move );
|
||
|
|
||
|
if ( IsDeployed() )
|
||
|
return;
|
||
|
|
||
|
DriveVehicle( pPlayer, ucmd );
|
||
|
m_nMovementRole = GetPassengerRole( pPlayer );
|
||
|
Assert( m_nMovementRole >= 0 );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::ProcessMovement( CBasePlayer *pPlayer, CMoveData *pMoveData )
|
||
|
{
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::SetBoostUpgrade( bool bBoostUpgrade )
|
||
|
{
|
||
|
m_bBoostUpgrade = bBoostUpgrade;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
bool CBaseTFFourWheelVehicle::IsBoostable( void )
|
||
|
{
|
||
|
return m_bBoostUpgrade;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::StartBoost( void )
|
||
|
{
|
||
|
if ( IsBoostable() )
|
||
|
{
|
||
|
m_VehiclePhysics.SetBoost( 1.0f );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
bool CBaseTFFourWheelVehicle::IsBoosting( void )
|
||
|
{
|
||
|
return m_VehiclePhysics.IsBoosting();
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Vehicle damage!
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBaseTFFourWheelVehicle::VPhysicsCollision( int index, gamevcollisionevent_t *pEvent )
|
||
|
{
|
||
|
BaseClass::VPhysicsCollision( index, pEvent );
|
||
|
|
||
|
int otherIndex = !index;
|
||
|
CBaseEntity *pEntity = pEvent->pEntities[otherIndex];
|
||
|
|
||
|
// We only damage objects...
|
||
|
// And only if we're travelling fast enough...
|
||
|
Assert( pEntity );
|
||
|
if ( !pEntity->IsSolid() )
|
||
|
return;
|
||
|
|
||
|
// Ignore shields..
|
||
|
if ( pEntity->GetCollisionGroup() == TFCOLLISION_GROUP_SHIELD )
|
||
|
return;
|
||
|
|
||
|
// Ignore anything that's not an object
|
||
|
if ( pEntity->Classify() != CLASS_MILITARY && !pEntity->IsPlayer() )
|
||
|
return;
|
||
|
|
||
|
// Ignore teammates
|
||
|
if ( InSameTeam( pEntity ))
|
||
|
return;
|
||
|
|
||
|
// Ignore invulnerable stuff
|
||
|
if ( pEntity->m_takedamage == DAMAGE_NO )
|
||
|
return;
|
||
|
|
||
|
// See if we can damage again? (Time-based)
|
||
|
if ( m_flNextHitTime > gpGlobals->curtime )
|
||
|
return;
|
||
|
|
||
|
// Do damage based on velocity.
|
||
|
Vector vecVelocity = pEvent->preVelocity[index];
|
||
|
|
||
|
CTakeDamageInfo info;
|
||
|
info.SetInflictor( this );
|
||
|
info.SetAttacker( GetDriverPlayer() );
|
||
|
info.SetDamageType( DMG_CLUB );
|
||
|
|
||
|
float flMaxDamage = fourwheelvehicle_hit_damage.GetFloat();
|
||
|
float flMaxDamageVel = fourwheelvehicle_hit_maxdamagevel.GetFloat();
|
||
|
float flMinDamageVel = fourwheelvehicle_hit_mindamagevel.GetFloat();
|
||
|
|
||
|
float flVel = vecVelocity.Length();
|
||
|
if ( flVel < flMinDamageVel )
|
||
|
return;
|
||
|
|
||
|
EmitSound( "BaseTFFourWheelVehicle.RamSound" );
|
||
|
|
||
|
float flDamageFactor = flMaxDamage;
|
||
|
// Special damage for players.
|
||
|
if ( pEntity->IsPlayer() )
|
||
|
{
|
||
|
flDamageFactor = fourwheelvehicle_hit_damage_player.GetFloat();
|
||
|
|
||
|
if ( IsBoosting() )
|
||
|
{
|
||
|
flDamageFactor *= 4.0f;
|
||
|
}
|
||
|
|
||
|
// Knock the player up into the air
|
||
|
float flForceScale = (flVel*0.5) * 75 * 4;
|
||
|
Vector vecForce = vecVelocity;
|
||
|
VectorNormalize( vecForce );
|
||
|
vecForce.z += 0.7;
|
||
|
vecForce *= flForceScale;
|
||
|
info.SetDamageForce( vecForce );
|
||
|
}
|
||
|
// Damage to objects.
|
||
|
else
|
||
|
{
|
||
|
if ( IsBoosting() )
|
||
|
{
|
||
|
flDamageFactor *= fourwheelvehicle_hit_damage_boostmod.GetFloat();
|
||
|
}
|
||
|
|
||
|
if ( ( flMaxDamageVel > flMinDamageVel ) && ( flVel < flMaxDamageVel ) )
|
||
|
{
|
||
|
// Use less damage when we're not moving fast enough
|
||
|
float flVelocityFactor = ( flVel - flMinDamageVel ) / ( flMaxDamageVel - flMinDamageVel );
|
||
|
flVelocityFactor *= flVelocityFactor;
|
||
|
flDamageFactor *= flVelocityFactor;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
info.SetDamage( flDamageFactor );
|
||
|
Vector damagePos;
|
||
|
pEvent->pInternalData->GetContactPoint( damagePos );
|
||
|
Vector damageForce = pEvent->postVelocity[index] * pEvent->pObjects[index]->GetMass();
|
||
|
info.SetDamageForce( damageForce );
|
||
|
info.SetDamagePosition( damagePos );
|
||
|
PhysCallbackDamage( pEntity, info, *pEvent, index );
|
||
|
|
||
|
// Set next time hit time
|
||
|
m_flNextHitTime = gpGlobals->curtime + fourwheelvehicle_impact_time.GetFloat();
|
||
|
}
|