Modified source engine (2017) developed by valve and leaked in 2020. Not for commercial purporses
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.
 
 
 
 
 
 

150 lines
4.7 KiB

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: The Infiltrator's Weapon
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "tf_player.h"
#include "tf_defines.h"
#include "in_buttons.h"
#include "weapon_infiltrator.h"
#include "gamerules.h"
#include "ammodef.h"
#define INFILTRATOR_STAB_RANGE 64.0f
// Damage CVars
ConVar weapon_infiltrator_damage( "weapon_infiltrator_damage","0", FCVAR_NONE, "Infiltrator backstab damage" );
ConVar weapon_infiltrator_range( "weapon_infiltrator_range","0", FCVAR_NONE, "Infiltrator backstab range" );
//=====================================================================================================
// INFILTRATOR WEAPON
//=====================================================================================================
IMPLEMENT_SERVERCLASS_ST(CWeaponInfiltrator, DT_WeaponInfiltrator)
END_SEND_TABLE()
LINK_ENTITY_TO_CLASS( weapon_infiltrator, CWeaponInfiltrator );
PRECACHE_WEAPON_REGISTER(weapon_infiltrator);
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CWeaponInfiltrator::CWeaponInfiltrator( void )
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponInfiltrator::Precache( void )
{
BaseClass::Precache();
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CWeaponInfiltrator::ComputeEMPFireState( void )
{
if (IsOwnerEMPed())
{
// FIXME: Need a sound
//UTIL_EmitSound( pPlayer->pev, CHAN_WEAPON, g_pszEMPGatlingFizzle, 1.0, ATTN_NORM );
return false;
}
return true;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CWeaponInfiltrator::Deploy( void )
{
// Play a shing! sound
WeaponSound( SPECIAL1 );
return DefaultDeploy( (char*)GetViewModel(), (char*)GetWorldModel(), ACT_VM_DRAW, (char*)GetAnimPrefix() );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponInfiltrator::PrimaryAttack( void )
{
CBaseTFPlayer *pTarget = GetAssassinationTarget();
if ( pTarget == NULL )
return;
WeaponSound( SINGLE );
PlayAttackAnimation( ACT_VM_PRIMARYATTACK );
m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration( m_nSequence ) * 0.5;
// Instant kill
pTarget->TakeDamage( CTakeDamageInfo( this, GetOwner(), 500.0f, DMG_SLASH ) );
// Gag until respawn
pTarget->SetGagged( true );
CheckRemoveDisguise();
}
//-----------------------------------------------------------------------------
// Purpose: Overloaded to handle the hold-down healing
//-----------------------------------------------------------------------------
void CWeaponInfiltrator::ItemPostFrame( void )
{
CBaseTFPlayer *pOwner = ToBaseTFPlayer( GetOwner() );
if ( !pOwner )
return;
// Stab 'em
if (( pOwner->m_nButtons & IN_ATTACK ) && (m_flNextPrimaryAttack <= gpGlobals->curtime) )
{
PrimaryAttack();
}
WeaponIdle();
}
//-----------------------------------------------------------------------------
// Purpose: See if there's an assassination target in front of the player.
// Output : Returns true if a target's found.
//-----------------------------------------------------------------------------
CBaseTFPlayer *CWeaponInfiltrator::GetAssassinationTarget( void )
{
if ( !ComputeEMPFireState() )
return NULL;
CBaseTFPlayer *pPlayer = static_cast< CBaseTFPlayer * >( GetOwner() );
if ( !pPlayer )
return NULL;
trace_t tr;
Vector vecForward;
pPlayer->EyeVectors( &vecForward );
Vector vecOrigin = pPlayer->EyePosition();
UTIL_TraceLine( vecOrigin, vecOrigin + INFILTRATOR_STAB_RANGE * vecForward, MASK_SHOT, pPlayer, GetCollisionGroup(), &tr );
if ( tr.fraction == 1.0f || !tr.m_pEnt )
return NULL;
CBaseEntity *pEntity = tr.m_pEnt;
if ( !pEntity || !pEntity->IsPlayer() )
return NULL;
if ( !pEntity->IsPlayer() )
return NULL;
// Don't target friendlies
if ( pEntity->InSameTeam( pPlayer ) )
return NULL;
// See if the player is facing the right direction
Vector fwd1, fwd2;
AngleVectors( pPlayer->GetAbsAngles(), &fwd1, NULL, NULL );
AngleVectors( pEntity->GetAbsAngles(), &fwd2, NULL, NULL );
float dot = fwd1.Dot( fwd2 );
if ( dot <= 0.0f )
return NULL;
return (CBaseTFPlayer*)pEntity;
}