source-engine/game/shared/tf2base/tf_weapon_wrench.cpp
2022-08-10 19:52:28 +03:00

137 lines
3.4 KiB
C++

//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#include "cbase.h"
#include "tf_weapon_wrench.h"
#include "decals.h"
#include "baseobject_shared.h"
// Client specific.
#ifdef CLIENT_DLL
#include "c_tf_player.h"
// Server specific.
#else
#include "tf_player.h"
#include "variant_t.h"
#endif
//=============================================================================
//
// Weapon Wrench tables.
//
IMPLEMENT_NETWORKCLASS_ALIASED( TFWrench, DT_TFWeaponWrench )
BEGIN_NETWORK_TABLE( CTFWrench, DT_TFWeaponWrench )
END_NETWORK_TABLE()
BEGIN_PREDICTION_DATA( CTFWrench )
END_PREDICTION_DATA()
LINK_ENTITY_TO_CLASS( tf_weapon_wrench, CTFWrench );
PRECACHE_WEAPON_REGISTER( tf_weapon_wrench );
//=============================================================================
//
// Weapon Wrench functions.
//
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CTFWrench::CTFWrench()
{
}
#ifdef GAME_DLL
void CTFWrench::OnFriendlyBuildingHit( CBaseObject *pObject, CTFPlayer *pPlayer )
{
// Did this object hit do any work? repair or upgrade?
bool bUsefulHit = pObject->InputWrenchHit( pPlayer );
CDisablePredictionFiltering disabler;
if ( bUsefulHit )
{
// play success sound
WeaponSound( SPECIAL1 );
}
else
{
// play failure sound
WeaponSound( SPECIAL2 );
}
}
#endif
class CTraceFilterIgnorePlayers : public CTraceFilterSimple
{
public:
// It does have a base, but we'll never network anything below here..
DECLARE_CLASS( CTraceFilterIgnorePlayers, CTraceFilterSimple );
CTraceFilterIgnorePlayers( const IHandleEntity *passentity, int collisionGroup )
: CTraceFilterSimple( passentity, collisionGroup )
{
}
virtual bool ShouldHitEntity( IHandleEntity *pServerEntity, int contentsMask )
{
CBaseEntity *pEntity = EntityFromEntityHandle( pServerEntity );
return pEntity && !pEntity->IsPlayer();
}
};
void CTFWrench::Smack( void )
{
// see if we can hit an object with a higher range
// Get the current player.
CTFPlayer *pPlayer = GetTFPlayerOwner();
if ( !pPlayer )
return;
if ( !CanAttack() )
return;
// Setup a volume for the melee weapon to be swung - approx size, so all melee behave the same.
static Vector vecSwingMins( -18, -18, -18 );
static Vector vecSwingMaxs( 18, 18, 18 );
// Setup the swing range.
Vector vecForward;
AngleVectors( pPlayer->EyeAngles(), &vecForward );
Vector vecSwingStart = pPlayer->Weapon_ShootPosition();
Vector vecSwingEnd = vecSwingStart + vecForward * 70;
// only trace against objects
// See if we hit anything.
trace_t trace;
CTraceFilterIgnorePlayers traceFilter( NULL, COLLISION_GROUP_NONE );
UTIL_TraceLine( vecSwingStart, vecSwingEnd, MASK_SOLID, &traceFilter, &trace );
if ( trace.fraction >= 1.0 )
{
UTIL_TraceHull( vecSwingStart, vecSwingEnd, vecSwingMins, vecSwingMaxs, MASK_SOLID, &traceFilter, &trace );
}
// We hit, setup the smack.
if ( trace.fraction < 1.0f &&
trace.m_pEnt &&
trace.m_pEnt->IsBaseObject() &&
trace.m_pEnt->GetTeamNumber() == pPlayer->GetTeamNumber() )
{
#ifdef GAME_DLL
OnFriendlyBuildingHit( dynamic_cast< CBaseObject * >( trace.m_pEnt ), pPlayer );
#endif
}
else
{
// if we cannot, Smack as usual for player hits
BaseClass::Smack();
}
}