diff options
Diffstat (limited to 'game/server/tf2/tf_vehicle_battering_ram.cpp')
| -rw-r--r-- | game/server/tf2/tf_vehicle_battering_ram.cpp | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/game/server/tf2/tf_vehicle_battering_ram.cpp b/game/server/tf2/tf_vehicle_battering_ram.cpp new file mode 100644 index 0000000..122cfba --- /dev/null +++ b/game/server/tf2/tf_vehicle_battering_ram.cpp @@ -0,0 +1,226 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: A moving vehicle that is used as a battering ram +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" +#include "tf_vehicle_battering_ram.h" +#include "engine/IEngineSound.h" +#include "VGuiScreen.h" +#include "ammodef.h" +#include "in_buttons.h" +#include "shake.h" + +#define BATTERING_RAM_MINS Vector(-30, -50, -10) +#define BATTERING_RAM_MAXS Vector( 30, 50, 55) +#define BATTERING_RAM_MODEL "models/objects/vehicle_battering_ram.mdl" + +IMPLEMENT_SERVERCLASS_ST(CVehicleBatteringRam, DT_VehicleBatteringRam) +END_SEND_TABLE(); + +LINK_ENTITY_TO_CLASS(vehicle_battering_ram, CVehicleBatteringRam); +PRECACHE_REGISTER(vehicle_battering_ram); + +// CVars +ConVar vehicle_battering_ram_health( "vehicle_battering_ram_health","800", FCVAR_NONE, "Battering ram health" ); +ConVar vehicle_battering_ram_damage( "vehicle_battering_ram_damage","300", FCVAR_NONE, "Battering ram damage" ); +ConVar vehicle_battering_ram_damage_boostmod( "vehicle_battering_ram_damage_boostmod", "1.5", FCVAR_NONE, "Battering ram boosted damage modifier" ); +ConVar vehicle_battering_ram_mindamagevel( "vehicle_battering_ram_mindamagevel","100", FCVAR_NONE, "Battering ram velocity for min damage" ); +ConVar vehicle_battering_ram_maxdamagevel( "vehicle_battering_ram_maxdamagevel","260", FCVAR_NONE, "Battering ram velocity for max damage" ); +ConVar vehicle_battering_ram_impact_time( "vehicle_battering_ram_impact_time", "1.0", FCVAR_NONE, "Battering ram impact wait time." ); + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CVehicleBatteringRam::CVehicleBatteringRam() +{ +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CVehicleBatteringRam::Precache() +{ + PrecacheModel( BATTERING_RAM_MODEL ); + + PrecacheVGuiScreen( "screen_vehicle_battering_ram" ); + PrecacheVGuiScreen( "screen_vulnerable_point"); + + PrecacheScriptSound( "VehicleBatteringRam.BashSound" ); + + BaseClass::Precache(); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CVehicleBatteringRam::Spawn() +{ + SetModel( BATTERING_RAM_MODEL ); + + // This size is used for placement only... + UTIL_SetSize(this, BATTERING_RAM_MINS, BATTERING_RAM_MAXS); + m_takedamage = DAMAGE_YES; + m_iHealth = vehicle_battering_ram_health.GetInt(); + m_nBarrelAttachment = LookupAttachment( "barrel" ); + + SetType( OBJ_BATTERING_RAM ); + SetMaxPassengerCount( 4 ); +// SetTouch( BashTouch ); + + m_flNextBashTime = 0.0f; + + BaseClass::Spawn(); +} + + +//----------------------------------------------------------------------------- +// Does the player use his normal weapons while in this mode? +//----------------------------------------------------------------------------- +bool CVehicleBatteringRam::IsPassengerUsingStandardWeapons( int nRole ) +{ + return (nRole > 1); +} + + +//----------------------------------------------------------------------------- +// Purpose: Gets info about the control panels +//----------------------------------------------------------------------------- +void CVehicleBatteringRam::GetControlPanelInfo( int nPanelIndex, const char *&pPanelName ) +{ + pPanelName = "screen_vulnerable_point"; +} + + +//----------------------------------------------------------------------------- +// Purpose: Ram!!! +//----------------------------------------------------------------------------- +void CVehicleBatteringRam::VPhysicsCollision( int index, gamevcollisionevent_t *pEvent ) +{ + int otherIndex = !index; + CBaseEntity *pEntity = pEvent->pEntities[otherIndex]; + + // We only damage objects... + // And only if we're travelling fast enough... + 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_flNextBashTime > gpGlobals->curtime ) + return; + + // Use the attachment point to make sure we damage stuff that hit our front + // FIXME: Should we be using hitboxes here? + // And damage them all + // We only damage objects... + QAngle vecAng; + Vector vecSrc, vecAim; + GetAttachment( m_nBarrelAttachment, vecSrc, vecAng ); + + // Check the forward direction + Vector forward; + AngleVectors( vecAng, &forward ); + + // Did we hit it in front of the vehicle? + Vector vecDelta; + VectorSubtract( pEntity->WorldSpaceCenter(), vecSrc, vecDelta ); + if ( ( DotProduct( vecDelta, forward ) <= 0 ) || pEntity->IsPlayer() ) + { + BaseClass::VPhysicsCollision( index, pEvent ); + return; + } + + // Call our parents base class. + BaseClass::BaseClass::VPhysicsCollision( index, pEvent ); + + // Do damage based on velocity (and only if we were heading forward) + Vector vecVelocity = pEvent->preVelocity[index]; + if (DotProduct( vecVelocity, forward ) <= 0) + return; + + CTakeDamageInfo info; + info.SetInflictor( this ); + info.SetAttacker( GetDriverPlayer() ); + info.SetDamageType( DMG_CLUB ); + + float flMaxDamage = vehicle_battering_ram_damage.GetFloat(); + float flMaxDamageVel = vehicle_battering_ram_maxdamagevel.GetFloat(); + float flMinDamageVel = vehicle_battering_ram_mindamagevel.GetFloat(); + + float flVel = vecVelocity.Length(); + if (flVel < flMinDamageVel) + return; + + // FIXME: Play a sound here... + EmitSound( "VehicleBatteringRam.BashSound" ); + + // Apply the damage + float flDamageFactor = flMaxDamage; + if ( IsBoosting() ) + { + flDamageFactor *= vehicle_battering_ram_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; + } + + UTIL_ScreenShakeObject( pEntity, vecSrc, 45.0f * flDamageFactor / flMaxDamage, 30.0f, 0.5f, 250.0f, SHAKE_START ); + + 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 ram time + m_flNextBashTime = gpGlobals->curtime + vehicle_battering_ram_impact_time.GetFloat(); +} + +//----------------------------------------------------------------------------- +// Here's where we deal with weapons, ladders, etc. +//----------------------------------------------------------------------------- +void CVehicleBatteringRam::OnItemPostFrame( CBaseTFPlayer *pDriver ) +{ + // I can't do anything if I'm not active + if ( !ShouldBeActive() ) + return; + + if ( GetPassengerRole( pDriver ) != VEHICLE_ROLE_DRIVER ) + return; + + if ( pDriver->m_nButtons & (IN_ATTACK2 | IN_SPEED) ) + { + StartBoost(); + } + + BaseClass::OnItemPostFrame( pDriver ); +} |