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.
226 lines
7.3 KiB
226 lines
7.3 KiB
//========= 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 ); |
|
}
|
|
|