diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/server/tf2/tf_basefourwheelvehicle.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'game/server/tf2/tf_basefourwheelvehicle.cpp')
| -rw-r--r-- | game/server/tf2/tf_basefourwheelvehicle.cpp | 762 |
1 files changed, 762 insertions, 0 deletions
diff --git a/game/server/tf2/tf_basefourwheelvehicle.cpp b/game/server/tf2/tf_basefourwheelvehicle.cpp new file mode 100644 index 0000000..f2b0808 --- /dev/null +++ b/game/server/tf2/tf_basefourwheelvehicle.cpp @@ -0,0 +1,762 @@ +//========= 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(); +} |