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.
227 lines
7.3 KiB
227 lines
7.3 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_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 );
|
||
|
}
|