mirror of
https://github.com/celisej567/source-engine.git
synced 2026-09-06 20:13:51 +03:00
upload "kind" alien swarm
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
@@ -11,18 +11,8 @@
|
||||
#include "SoundEmitterSystem/isoundemittersystembase.h"
|
||||
#include "physics_saverestore.h"
|
||||
#include "datacache/imdlcache.h"
|
||||
#include "activitylist.h"
|
||||
|
||||
// NVNT start extra includes
|
||||
#include "haptics/haptic_utils.h"
|
||||
#ifdef CLIENT_DLL
|
||||
#include "prediction.h"
|
||||
#endif
|
||||
// NVNT end extra includes
|
||||
|
||||
#if defined ( TF_DLL ) || defined ( TF_CLIENT_DLL )
|
||||
#include "tf_shareddefs.h"
|
||||
#endif
|
||||
#include "tier0/vprof.h"
|
||||
#include "collisionutils.h"
|
||||
|
||||
#if !defined( CLIENT_DLL )
|
||||
|
||||
@@ -32,10 +22,6 @@
|
||||
#include "fmtstr.h"
|
||||
#include "gameweaponmanager.h"
|
||||
|
||||
#ifdef HL2MP
|
||||
#include "hl2mp_gamerules.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
@@ -51,16 +37,7 @@
|
||||
|
||||
extern bool UTIL_ItemCanBeTouchedByPlayer( CBaseEntity *pItem, CBasePlayer *pPlayer );
|
||||
|
||||
#if defined ( TF_CLIENT_DLL ) || defined ( TF_DLL )
|
||||
#ifdef _DEBUG
|
||||
ConVar tf_weapon_criticals_force_random( "tf_weapon_criticals_force_random", "0", FCVAR_REPLICATED | FCVAR_CHEAT );
|
||||
#endif // _DEBUG
|
||||
ConVar tf_weapon_criticals_bucket_cap( "tf_weapon_criticals_bucket_cap", "1000.0", FCVAR_REPLICATED | FCVAR_CHEAT );
|
||||
ConVar tf_weapon_criticals_bucket_bottom( "tf_weapon_criticals_bucket_bottom", "-250.0", FCVAR_REPLICATED | FCVAR_CHEAT );
|
||||
ConVar tf_weapon_criticals_bucket_default( "tf_weapon_criticals_bucket_default", "300.0", FCVAR_REPLICATED | FCVAR_CHEAT );
|
||||
#endif // TF
|
||||
|
||||
CBaseCombatWeapon::CBaseCombatWeapon() : BASECOMBATWEAPON_DERIVED_FROM()
|
||||
CBaseCombatWeapon::CBaseCombatWeapon()
|
||||
{
|
||||
// Constructor must call this
|
||||
// CONSTRUCT_PREDICTABLE( CBaseCombatWeapon );
|
||||
@@ -76,9 +53,6 @@ CBaseCombatWeapon::CBaseCombatWeapon() : BASECOMBATWEAPON_DERIVED_FROM()
|
||||
// Defaults to zero
|
||||
m_nViewModelIndex = 0;
|
||||
|
||||
m_bFlipViewModel = false;
|
||||
m_iSubType = 0;
|
||||
|
||||
#if defined( CLIENT_DLL )
|
||||
m_iState = m_iOldState = WEAPON_NOT_CARRIED;
|
||||
m_iClip1 = -1;
|
||||
@@ -94,15 +68,7 @@ CBaseCombatWeapon::CBaseCombatWeapon() : BASECOMBATWEAPON_DERIVED_FROM()
|
||||
|
||||
m_hWeaponFileInfo = GetInvalidWeaponInfoHandle();
|
||||
|
||||
#if defined( TF_DLL )
|
||||
UseClientSideAnimation();
|
||||
#endif
|
||||
|
||||
#if defined ( TF_CLIENT_DLL ) || defined ( TF_DLL )
|
||||
m_flCritTokenBucket = tf_weapon_criticals_bucket_default.GetFloat();
|
||||
m_nCritChecks = 1;
|
||||
m_nCritSeedRequests = 0;
|
||||
#endif // TF
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -137,12 +103,13 @@ void CBaseCombatWeapon::Activate( void )
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void CBaseCombatWeapon::GiveDefaultAmmo( void )
|
||||
{
|
||||
// If I use clips, set my clips to the default
|
||||
if ( UsesClipsForAmmo1() )
|
||||
{
|
||||
m_iClip1 = AutoFiresFullClip() ? 0 : GetDefaultClip1();
|
||||
m_iClip1 = GetDefaultClip1();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -167,8 +134,6 @@ void CBaseCombatWeapon::Spawn( void )
|
||||
{
|
||||
Precache();
|
||||
|
||||
BaseClass::Spawn();
|
||||
|
||||
SetSolid( SOLID_BBOX );
|
||||
m_flNextEmptySoundTime = 0.0f;
|
||||
|
||||
@@ -176,17 +141,21 @@ void CBaseCombatWeapon::Spawn( void )
|
||||
RemoveEFlags( EFL_USE_PARTITION_WHEN_NOT_SOLID );
|
||||
|
||||
m_iState = WEAPON_NOT_CARRIED;
|
||||
SetGlobalFadeScale( 0.0f );
|
||||
|
||||
// Assume
|
||||
m_nViewModelIndex = 0;
|
||||
|
||||
GiveDefaultAmmo();
|
||||
|
||||
if ( GetWorldModel() )
|
||||
{
|
||||
SetModel( GetWorldModel() );
|
||||
}
|
||||
SetModel( GetWorldModel() );
|
||||
|
||||
#if !defined( CLIENT_DLL )
|
||||
if ( GetWpnData().szAIAddOn[ 0 ] != '\0' )
|
||||
{
|
||||
SetAIAddOn( AllocPooledString( GetWpnData().szAIAddOn ) );
|
||||
}
|
||||
|
||||
if( IsX360() )
|
||||
{
|
||||
AddEffects( EF_ITEM_BLINK );
|
||||
@@ -235,6 +204,7 @@ void CBaseCombatWeapon::Precache( void )
|
||||
Assert( Q_strlen( GetClassname() ) > 0 );
|
||||
// Msg( "Client got %s\n", GetClassname() );
|
||||
#endif
|
||||
|
||||
m_iPrimaryAmmoType = m_iSecondaryAmmoType = -1;
|
||||
|
||||
// Add this weapon to the weapon registry, and get our index into it
|
||||
@@ -249,16 +219,7 @@ void CBaseCombatWeapon::Precache( void )
|
||||
{
|
||||
Msg("ERROR: Weapon (%s) using undefined primary ammo type (%s)\n",GetClassname(), GetWpnData().szAmmo1);
|
||||
}
|
||||
#if defined ( TF_DLL ) || defined ( TF_CLIENT_DLL )
|
||||
// Ammo override
|
||||
int iModUseMetalOverride = 0;
|
||||
CALL_ATTRIB_HOOK_INT( iModUseMetalOverride, mod_use_metal_ammo_type );
|
||||
if ( iModUseMetalOverride )
|
||||
{
|
||||
m_iPrimaryAmmoType = (int)TF_AMMO_METAL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if ( GetWpnData().szAmmo2[0] )
|
||||
{
|
||||
m_iSecondaryAmmoType = GetAmmoDef()->Index( GetWpnData().szAmmo2 );
|
||||
@@ -299,8 +260,18 @@ void CBaseCombatWeapon::Precache( void )
|
||||
Warning( "Error reading weapon data file for: %s\n", GetClassname() );
|
||||
// Remove( ); //don't remove, this gets released soon!
|
||||
}
|
||||
|
||||
const char *pszTracerName = GetTracerType();
|
||||
if ( pszTracerName )
|
||||
{
|
||||
PrecacheEffect( pszTracerName );
|
||||
}
|
||||
|
||||
PrecacheEffect( "ParticleTracer" );
|
||||
PrecacheParticleSystem( "weapon_tracers" );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Get my data in the file weapon info array
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -347,13 +318,6 @@ const char *CBaseCombatWeapon::GetPrintName( void ) const
|
||||
//-----------------------------------------------------------------------------
|
||||
int CBaseCombatWeapon::GetMaxClip1( void ) const
|
||||
{
|
||||
#if defined ( TF_DLL ) || defined ( TF_CLIENT_DLL )
|
||||
int iModMaxClipOverride = 0;
|
||||
CALL_ATTRIB_HOOK_INT( iModMaxClipOverride, mod_max_primary_clip_override );
|
||||
if ( iModMaxClipOverride != 0 )
|
||||
return iModMaxClipOverride;
|
||||
#endif
|
||||
|
||||
return GetWpnData().iMaxClip1;
|
||||
}
|
||||
|
||||
@@ -554,20 +518,6 @@ CBaseCombatCharacter *CBaseCombatWeapon::GetOwner() const
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseCombatWeapon::SetOwner( CBaseCombatCharacter *owner )
|
||||
{
|
||||
if ( !owner )
|
||||
{
|
||||
#ifndef CLIENT_DLL
|
||||
// Make sure the weapon updates its state when it's removed from the player
|
||||
// We have to force an active state change, because it's being dropped and won't call UpdateClientData()
|
||||
int iOldState = m_iState;
|
||||
m_iState = WEAPON_NOT_CARRIED;
|
||||
OnActiveStateChanged( iOldState );
|
||||
#endif
|
||||
|
||||
// make sure we clear out our HideThink if we have one pending
|
||||
SetContextThink( NULL, 0, HIDEWEAPON_THINK_CONTEXT );
|
||||
}
|
||||
|
||||
m_hOwner = owner;
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
@@ -658,7 +608,6 @@ float CBaseCombatWeapon::GetWeaponIdleTime( void )
|
||||
void CBaseCombatWeapon::Drop( const Vector &vecVelocity )
|
||||
{
|
||||
#if !defined( CLIENT_DLL )
|
||||
|
||||
// Once somebody drops a gun, it's fair game for removal when/if
|
||||
// a game_weapon_manager does a cleanup on surplus weapons in the
|
||||
// world.
|
||||
@@ -754,10 +703,6 @@ void CBaseCombatWeapon::OnPickedUp( CBaseCombatCharacter *pNewOwner )
|
||||
m_OnNPCPickup.FireOutput(pNewOwner, this);
|
||||
}
|
||||
|
||||
#ifdef HL2MP
|
||||
HL2MPRules()->RemoveLevelDesignerPlacedObject( this );
|
||||
#endif
|
||||
|
||||
// Someone picked me up, so make it so that I can't be removed.
|
||||
SetRemoveable( false );
|
||||
#endif
|
||||
@@ -780,6 +725,10 @@ void CBaseCombatWeapon::MakeTracer( const Vector &vecTracerSrc, const trace_t &t
|
||||
}
|
||||
|
||||
const char *pszTracerName = GetTracerType();
|
||||
if ( !pszTracerName )
|
||||
{
|
||||
pszTracerName = "weapon_tracers";
|
||||
}
|
||||
|
||||
Vector vNewSrc = vecTracerSrc;
|
||||
int iEntIndex = pOwner->entindex();
|
||||
@@ -787,25 +736,22 @@ void CBaseCombatWeapon::MakeTracer( const Vector &vecTracerSrc, const trace_t &t
|
||||
if ( g_pGameRules->IsMultiplayer() )
|
||||
{
|
||||
iEntIndex = entindex();
|
||||
#ifdef CLIENT_DLL
|
||||
C_BasePlayer *player = ToBasePlayer( pOwner );
|
||||
if ( C_BasePlayer::IsLocalPlayer( player ) )
|
||||
{
|
||||
CBaseEntity *vm = player->GetViewModel();
|
||||
if ( vm )
|
||||
{
|
||||
iEntIndex = vm->entindex();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int iAttachment = GetTracerAttachment();
|
||||
|
||||
switch ( iTracerType )
|
||||
{
|
||||
case TRACER_LINE:
|
||||
UTIL_Tracer( vNewSrc, tr.endpos, iEntIndex, iAttachment, 0.0f, true, pszTracerName );
|
||||
break;
|
||||
|
||||
case TRACER_LINE_AND_WHIZ:
|
||||
UTIL_Tracer( vNewSrc, tr.endpos, iEntIndex, iAttachment, 0.0f, true, pszTracerName );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CBaseCombatWeapon::GiveTo( CBaseEntity *pOther )
|
||||
{
|
||||
DefaultTouch( pOther );
|
||||
UTIL_ParticleTracer( pszTracerName, vNewSrc, tr.endpos, iEntIndex, iAttachment, true );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -1008,10 +954,7 @@ void CBaseCombatWeapon::Equip( CBaseCombatCharacter *pOwner )
|
||||
|
||||
void CBaseCombatWeapon::SetActivity( Activity act, float duration )
|
||||
{
|
||||
//Adrian: Oh man...
|
||||
#if !defined( CLIENT_DLL ) && (defined( HL2MP ) || defined( PORTAL ))
|
||||
SetModel( GetWorldModel() );
|
||||
#endif
|
||||
|
||||
|
||||
int sequence = SelectWeightedSequence( act );
|
||||
|
||||
@@ -1019,10 +962,7 @@ void CBaseCombatWeapon::SetActivity( Activity act, float duration )
|
||||
if ( sequence == ACTIVITY_NOT_AVAILABLE )
|
||||
sequence = SelectWeightedSequence( ACT_VM_IDLE );
|
||||
|
||||
//Adrian: Oh man again...
|
||||
#if !defined( CLIENT_DLL ) && (defined( HL2MP ) || defined( PORTAL ))
|
||||
SetModel( GetViewModel() );
|
||||
#endif
|
||||
|
||||
|
||||
if ( sequence != ACTIVITY_NOT_AVAILABLE )
|
||||
{
|
||||
@@ -1035,7 +975,8 @@ void CBaseCombatWeapon::SetActivity( Activity act, float duration )
|
||||
{
|
||||
// FIXME: does this even make sense in non-shoot animations?
|
||||
m_flPlaybackRate = SequenceDuration( sequence ) / duration;
|
||||
m_flPlaybackRate = MIN( m_flPlaybackRate, 12.0); // FIXME; magic number!, network encoding range
|
||||
m_flPlaybackRate = fpmin( m_flPlaybackRate, 12.0); // FIXME; magic number!, network encoding range
|
||||
Assert( IsFinite( m_flPlaybackRate ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1053,14 +994,7 @@ int CBaseCombatWeapon::UpdateClientData( CBasePlayer *pPlayer )
|
||||
|
||||
if ( pPlayer->GetActiveWeapon() == this )
|
||||
{
|
||||
if ( pPlayer->m_fOnTarget )
|
||||
{
|
||||
iNewState = WEAPON_IS_ONTARGET;
|
||||
}
|
||||
else
|
||||
{
|
||||
iNewState = WEAPON_IS_ACTIVE;
|
||||
}
|
||||
iNewState = WEAPON_IS_ACTIVE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1069,9 +1003,7 @@ int CBaseCombatWeapon::UpdateClientData( CBasePlayer *pPlayer )
|
||||
|
||||
if ( m_iState != iNewState )
|
||||
{
|
||||
int iOldState = m_iState;
|
||||
m_iState = iNewState;
|
||||
OnActiveStateChanged( iOldState );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -1105,7 +1037,7 @@ void CBaseCombatWeapon::SendViewModelAnim( int nSequence )
|
||||
if ( pOwner == NULL )
|
||||
return;
|
||||
|
||||
CBaseViewModel *vm = pOwner->GetViewModel( m_nViewModelIndex, false );
|
||||
CBaseViewModel *vm = pOwner->GetViewModel( m_nViewModelIndex );
|
||||
|
||||
if ( vm == NULL )
|
||||
return;
|
||||
@@ -1167,7 +1099,7 @@ void CBaseCombatWeapon::SetViewModel()
|
||||
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
|
||||
if ( pOwner == NULL )
|
||||
return;
|
||||
CBaseViewModel *vm = pOwner->GetViewModel( m_nViewModelIndex, false );
|
||||
CBaseViewModel *vm = pOwner->GetViewModel( m_nViewModelIndex );
|
||||
if ( vm == NULL )
|
||||
return;
|
||||
Assert( vm->ViewModelIndex() == m_nViewModelIndex );
|
||||
@@ -1180,18 +1112,10 @@ void CBaseCombatWeapon::SetViewModel()
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CBaseCombatWeapon::SendWeaponAnim( int iActivity )
|
||||
{
|
||||
#ifdef USES_ECON_ITEMS
|
||||
#ifdef USES_PERSISTENT_ITEMS
|
||||
iActivity = TranslateViewmodelHandActivity( (Activity)iActivity );
|
||||
#endif
|
||||
// NVNT notify the haptics system of this weapons new activity
|
||||
#ifdef WIN32
|
||||
#ifdef CLIENT_DLL
|
||||
if ( prediction->InPrediction() && prediction->IsFirstTimePredicted() )
|
||||
#endif
|
||||
#ifndef _X360
|
||||
HapticSendWeaponAnim(this,iActivity);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//For now, just set the ideal activity and be done with it
|
||||
return SetIdealActivity( (Activity) iActivity );
|
||||
}
|
||||
@@ -1331,7 +1255,13 @@ bool CBaseCombatWeapon::IsWeaponVisible( void )
|
||||
{
|
||||
vm = pOwner->GetViewModel( m_nViewModelIndex );
|
||||
if ( vm )
|
||||
{
|
||||
#ifdef CLIENT_DLL
|
||||
return !vm->IsDormant() && !vm->IsEffectActive(EF_NODRAW);
|
||||
#else
|
||||
return ( !vm->IsEffectActive(EF_NODRAW) );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -1361,7 +1291,7 @@ bool CBaseCombatWeapon::ReloadOrSwitchWeapons( void )
|
||||
else
|
||||
{
|
||||
// Weapon is useable. Reload if empty and weapon has waited as long as it has to after firing
|
||||
if ( UsesClipsForAmmo1() && !AutoFiresFullClip() &&
|
||||
if ( UsesClipsForAmmo1() &&
|
||||
(m_iClip1 == 0) &&
|
||||
(GetWeaponFlags() & ITEM_FLAG_NOAUTORELOAD) == false &&
|
||||
m_flNextPrimaryAttack < gpGlobals->curtime &&
|
||||
@@ -1369,7 +1299,9 @@ bool CBaseCombatWeapon::ReloadOrSwitchWeapons( void )
|
||||
{
|
||||
// if we're successfully reloading, we're done
|
||||
if ( Reload() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1417,8 +1349,6 @@ bool CBaseCombatWeapon::DefaultDeploy( char *szViewModel, char *szWeaponModel, i
|
||||
m_bReloadHudHintDisplayed = false;
|
||||
m_flHudHintPollTime = gpGlobals->curtime + 5.0f;
|
||||
|
||||
WeaponSound( DEPLOY );
|
||||
|
||||
SetWeaponVisible( true );
|
||||
|
||||
/*
|
||||
@@ -1456,7 +1386,6 @@ bool CBaseCombatWeapon::Holster( CBaseCombatWeapon *pSwitchingTo )
|
||||
|
||||
// cancel any reload in progress.
|
||||
m_bInReload = false;
|
||||
m_bFiringWholeClip = false;
|
||||
|
||||
// kill any think functions
|
||||
SetThink(NULL);
|
||||
@@ -1542,66 +1471,6 @@ void CBaseCombatWeapon::HideThink( void )
|
||||
}
|
||||
}
|
||||
|
||||
bool CBaseCombatWeapon::CanReload( void )
|
||||
{
|
||||
if ( AutoFiresFullClip() && m_bFiringWholeClip )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined ( TF_CLIENT_DLL ) || defined ( TF_DLL )
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Anti-hack
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseCombatWeapon::AddToCritBucket( float flAmount )
|
||||
{
|
||||
float flCap = tf_weapon_criticals_bucket_cap.GetFloat();
|
||||
|
||||
// Regulate crit frequency to reduce client-side seed hacking
|
||||
if ( m_flCritTokenBucket < flCap )
|
||||
{
|
||||
// Treat raw damage as the resource by which we add or subtract from the bucket
|
||||
m_flCritTokenBucket += flAmount;
|
||||
m_flCritTokenBucket = Min( m_flCritTokenBucket, flCap );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Anti-hack
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CBaseCombatWeapon::IsAllowedToWithdrawFromCritBucket( float flDamage )
|
||||
{
|
||||
// Note: If we're in this block of code, the assumption is that the
|
||||
// seed said we should grant a random crit. If allowed, the cost
|
||||
// will be deducted here.
|
||||
|
||||
// Track each seed request - in cases where a player is hacking, we'll
|
||||
// see a silly ratio.
|
||||
m_nCritSeedRequests++;
|
||||
|
||||
// Adjust token cost based on the ratio of requests vs granted, except
|
||||
// melee, which crits much more than ranged (as high as 60% chance)
|
||||
float flMult = ( IsMeleeWeapon() ) ? 0.5f : RemapValClamped( ( (float)m_nCritSeedRequests / (float)m_nCritChecks ), 0.1f, 1.f, 1.f, 3.f );
|
||||
|
||||
// Would this take us below our limit?
|
||||
float flCost = ( flDamage * TF_DAMAGE_CRIT_MULTIPLIER ) * flMult;
|
||||
if ( flCost > m_flCritTokenBucket )
|
||||
return false;
|
||||
|
||||
// Withdraw
|
||||
RemoveFromCritBucket( flCost );
|
||||
|
||||
float flBottom = tf_weapon_criticals_bucket_bottom.GetFloat();
|
||||
if ( m_flCritTokenBucket < flBottom )
|
||||
m_flCritTokenBucket = flBottom;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif // TF_DLL
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -1653,8 +1522,6 @@ void CBaseCombatWeapon::ItemPostFrame( void )
|
||||
if (!pOwner)
|
||||
return;
|
||||
|
||||
UpdateAutoFire();
|
||||
|
||||
//Track the duration of the fire
|
||||
//FIXME: Check for IN_ATTACK2 as well?
|
||||
//FIXME: What if we're calling ItemBusyFrame?
|
||||
@@ -1695,7 +1562,7 @@ void CBaseCombatWeapon::ItemPostFrame( void )
|
||||
if( !IsX360() || !ClassMatches("weapon_crossbow") )
|
||||
#endif
|
||||
{
|
||||
bFired = ShouldBlockPrimaryFire();
|
||||
bFired = true;
|
||||
}
|
||||
|
||||
SecondaryAttack();
|
||||
@@ -1743,22 +1610,13 @@ void CBaseCombatWeapon::ItemPostFrame( void )
|
||||
}
|
||||
|
||||
PrimaryAttack();
|
||||
|
||||
if ( AutoFiresFullClip() )
|
||||
{
|
||||
m_bFiringWholeClip = true;
|
||||
}
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
pOwner->SetFiredWeapon( true );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------
|
||||
// Reload pressed / Clip Empty
|
||||
// -----------------------
|
||||
if ( ( pOwner->m_nButtons & IN_RELOAD ) && UsesClipsForAmmo1() && !m_bInReload )
|
||||
if ( (pOwner->m_nButtons & IN_RELOAD) && UsesClipsForAmmo1() && !m_bInReload )
|
||||
{
|
||||
// reload when reload is pressed, or if no buttons are down and weapon is empty.
|
||||
Reload();
|
||||
@@ -1768,10 +1626,10 @@ void CBaseCombatWeapon::ItemPostFrame( void )
|
||||
// -----------------------
|
||||
// No buttons down
|
||||
// -----------------------
|
||||
if (!((pOwner->m_nButtons & IN_ATTACK) || (pOwner->m_nButtons & IN_ATTACK2) || (CanReload() && pOwner->m_nButtons & IN_RELOAD)))
|
||||
if (!((pOwner->m_nButtons & IN_ATTACK) || (pOwner->m_nButtons & IN_ATTACK2) || (pOwner->m_nButtons & IN_RELOAD)))
|
||||
{
|
||||
// no fire buttons down or reloading
|
||||
if ( !ReloadOrSwitchWeapons() && ( m_bInReload == false ) )
|
||||
if ( ( m_bInReload == false ) && !ReloadOrSwitchWeapons() )
|
||||
{
|
||||
WeaponIdle();
|
||||
}
|
||||
@@ -1802,7 +1660,6 @@ void CBaseCombatWeapon::HandleFireOnEmpty()
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseCombatWeapon::ItemBusyFrame( void )
|
||||
{
|
||||
UpdateAutoFire();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -2015,27 +1872,6 @@ bool CBaseCombatWeapon::DefaultReload( int iClipSize1, int iClipSize2, int iActi
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBaseCombatWeapon::ReloadsSingly( void ) const
|
||||
{
|
||||
#if defined ( TF_DLL ) || defined ( TF_CLIENT_DLL )
|
||||
float fHasReload = 1.0f;
|
||||
CALL_ATTRIB_HOOK_FLOAT( fHasReload, mod_no_reload_display_only );
|
||||
if ( fHasReload != 1.0f )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int iWeaponMod = 0;
|
||||
CALL_ATTRIB_HOOK_INT( iWeaponMod, set_scattergun_no_reload_single );
|
||||
if ( iWeaponMod == 1 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif // TF_DLL || TF_CLIENT_DLL
|
||||
|
||||
return m_bReloadsSingly;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -2187,54 +2023,6 @@ void CBaseCombatWeapon::AbortReload( void )
|
||||
m_bInReload = false;
|
||||
}
|
||||
|
||||
void CBaseCombatWeapon::UpdateAutoFire( void )
|
||||
{
|
||||
if ( !AutoFiresFullClip() )
|
||||
return;
|
||||
|
||||
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
|
||||
if ( !pOwner )
|
||||
return;
|
||||
|
||||
if ( m_iClip1 == 0 )
|
||||
{
|
||||
// Ready to reload again
|
||||
m_bFiringWholeClip = false;
|
||||
}
|
||||
|
||||
if ( m_bFiringWholeClip )
|
||||
{
|
||||
// If it's firing the clip don't let them repress attack to reload
|
||||
pOwner->m_nButtons &= ~IN_ATTACK;
|
||||
}
|
||||
|
||||
// Don't use the regular reload key
|
||||
if ( pOwner->m_nButtons & IN_RELOAD )
|
||||
{
|
||||
pOwner->m_nButtons &= ~IN_RELOAD;
|
||||
}
|
||||
|
||||
// Try to fire if there's ammo in the clip and we're not holding the button
|
||||
bool bReleaseClip = m_iClip1 > 0 && !( pOwner->m_nButtons & IN_ATTACK );
|
||||
|
||||
if ( !bReleaseClip )
|
||||
{
|
||||
if ( CanReload() && ( pOwner->m_nButtons & IN_ATTACK ) )
|
||||
{
|
||||
// Convert the attack key into the reload key
|
||||
pOwner->m_nButtons |= IN_RELOAD;
|
||||
}
|
||||
|
||||
// Don't allow attack button if we're not attacking
|
||||
pOwner->m_nButtons &= ~IN_ATTACK;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fake the attack key
|
||||
pOwner->m_nButtons |= IN_ATTACK;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Primary fire button attack
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -2303,7 +2091,7 @@ void CBaseCombatWeapon::PrimaryAttack( void )
|
||||
info.m_vecSpread = pPlayer->GetAttackSpread( this );
|
||||
#else
|
||||
//!!!HACKHACK - what does the client want this function for?
|
||||
info.m_vecSpread = GetActiveWeapon()->GetBulletSpread();
|
||||
info.m_vecSpread = pPlayer->GetActiveWeapon()->GetBulletSpread();
|
||||
#endif // CLIENT_DLL
|
||||
|
||||
pPlayer->FireBullets( info );
|
||||
@@ -2318,6 +2106,82 @@ void CBaseCombatWeapon::PrimaryAttack( void )
|
||||
AddViewKick();
|
||||
}
|
||||
|
||||
void CBaseCombatWeapon::BaseForceFire( CBaseCombatCharacter *pOperator, CBaseEntity *pTarget )
|
||||
{
|
||||
// Ensure we have enough rounds in the clip
|
||||
m_iClip1++;
|
||||
|
||||
// If my clip is empty (and I use clips) start reload
|
||||
if ( UsesClipsForAmmo1() && !m_iClip1 )
|
||||
{
|
||||
Reload();
|
||||
return;
|
||||
}
|
||||
|
||||
pOperator->DoMuzzleFlash();
|
||||
|
||||
SendWeaponAnim( GetPrimaryAttackActivity() );
|
||||
|
||||
// player "shoot" animation
|
||||
//pOperator->SetAnimation( PLAYER_ATTACK1 );
|
||||
|
||||
FireBulletsInfo_t info;
|
||||
|
||||
QAngle angShootDir;
|
||||
GetAttachment( LookupAttachment( "muzzle" ), info.m_vecSrc, angShootDir );
|
||||
|
||||
if ( pTarget )
|
||||
{
|
||||
info.m_vecDirShooting = pTarget->WorldSpaceCenter() - info.m_vecSrc;
|
||||
VectorNormalize( info.m_vecDirShooting );
|
||||
}
|
||||
else
|
||||
{
|
||||
AngleVectors( angShootDir, &info.m_vecDirShooting );
|
||||
}
|
||||
|
||||
// To make the firing framerate independent, we may have to fire more than one bullet here on low-framerate systems,
|
||||
// especially if the weapon we're firing has a really fast rate of fire.
|
||||
info.m_iShots = 0;
|
||||
float fireRate = GetFireRate();
|
||||
|
||||
while ( m_flNextPrimaryAttack <= gpGlobals->curtime )
|
||||
{
|
||||
// MUST call sound before removing a round from the clip of a CMachineGun
|
||||
WeaponSound(SINGLE, m_flNextPrimaryAttack);
|
||||
m_flNextPrimaryAttack = m_flNextPrimaryAttack + fireRate;
|
||||
info.m_iShots++;
|
||||
if ( !fireRate )
|
||||
break;
|
||||
}
|
||||
|
||||
// Make sure we don't fire more than the amount in the clip
|
||||
if ( UsesClipsForAmmo1() )
|
||||
{
|
||||
info.m_iShots = MIN( info.m_iShots, m_iClip1 );
|
||||
m_iClip1 -= info.m_iShots;
|
||||
}
|
||||
else
|
||||
{
|
||||
info.m_iShots = MIN( info.m_iShots, pOperator->GetAmmoCount( m_iPrimaryAmmoType ) );
|
||||
pOperator->RemoveAmmo( info.m_iShots, m_iPrimaryAmmoType );
|
||||
}
|
||||
|
||||
info.m_flDistance = MAX_TRACE_LENGTH;
|
||||
info.m_iAmmoType = m_iPrimaryAmmoType;
|
||||
info.m_iTracerFreq = 2;
|
||||
|
||||
#if !defined( CLIENT_DLL )
|
||||
// Fire the bullets
|
||||
info.m_vecSpread = pOperator->GetAttackSpread( this );
|
||||
#else
|
||||
//!!!HACKHACK - what does the client want this function for?
|
||||
info.m_vecSpread = GetBulletSpread();
|
||||
#endif // CLIENT_DLL
|
||||
|
||||
pOperator->FireBullets( info );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called every frame to check if the weapon is going through transition animations
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -2340,7 +2204,7 @@ void CBaseCombatWeapon::MaintainIdealActivity( void )
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Sets the ideal activity for the weapon to be in, allowing for transitional animations inbetween
|
||||
// Purpose: Sets the ideal activity for the weapon to be in, allowing for transitional animations in between
|
||||
// Input : ideal - activity to end up at, ideally
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CBaseCombatWeapon::SetIdealActivity( Activity ideal )
|
||||
@@ -2439,81 +2303,79 @@ Activity CBaseCombatWeapon::ActivityOverride( Activity baseAct, bool *pRequired
|
||||
return baseAct;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CDmgAccumulator::CDmgAccumulator( void )
|
||||
class CWeaponList : public CAutoGameSystem
|
||||
{
|
||||
#ifdef GAME_DLL
|
||||
SetDefLessFunc( m_TargetsDmgInfo );
|
||||
#endif // GAME_DLL
|
||||
|
||||
m_bActive = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CDmgAccumulator::~CDmgAccumulator()
|
||||
{
|
||||
// Did a weapon get deleted while aggregating CTakeDamageInfo events?
|
||||
Assert( !m_bActive );
|
||||
}
|
||||
|
||||
#ifdef GAME_DLL
|
||||
//-----------------------------------------------------------------------------
|
||||
// Collect trace attacks for weapons that fire multiple bullets per attack that also penetrate
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmgAccumulator::AccumulateMultiDamage( const CTakeDamageInfo &info, CBaseEntity *pEntity )
|
||||
{
|
||||
if ( !pEntity )
|
||||
return;
|
||||
|
||||
Assert( m_bActive );
|
||||
|
||||
#if defined( GAME_DLL )
|
||||
int iIndex = m_TargetsDmgInfo.Find( pEntity->entindex() );
|
||||
if ( iIndex == m_TargetsDmgInfo.InvalidIndex() )
|
||||
public:
|
||||
CWeaponList( char const *name ) : CAutoGameSystem( name )
|
||||
{
|
||||
m_TargetsDmgInfo.Insert( pEntity->entindex(), info );
|
||||
}
|
||||
else
|
||||
|
||||
|
||||
virtual void LevelShutdownPostEntity()
|
||||
{
|
||||
m_list.Purge();
|
||||
}
|
||||
|
||||
void AddWeapon( CBaseCombatWeapon *pWeapon )
|
||||
{
|
||||
CTakeDamageInfo *pInfo = &m_TargetsDmgInfo[iIndex];
|
||||
if ( pInfo )
|
||||
m_list.AddToTail( pWeapon );
|
||||
}
|
||||
|
||||
void RemoveWeapon( CBaseCombatWeapon *pWeapon )
|
||||
{
|
||||
m_list.FindAndRemove( pWeapon );
|
||||
}
|
||||
CUtlLinkedList< CBaseCombatWeapon * > m_list;
|
||||
};
|
||||
|
||||
CWeaponList g_WeaponList( "CWeaponList" );
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
void OnBaseCombatWeaponCreated( CBaseCombatWeapon *pWeapon )
|
||||
{
|
||||
g_WeaponList.AddWeapon( pWeapon );
|
||||
}
|
||||
|
||||
void OnBaseCombatWeaponDestroyed( CBaseCombatWeapon *pWeapon )
|
||||
{
|
||||
g_WeaponList.RemoveWeapon( pWeapon );
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
CUtlLinkedList< CBaseCombatWeapon * >& CBaseCombatWeapon::GetWeaponList( void )
|
||||
{
|
||||
return g_WeaponList.m_list;
|
||||
}
|
||||
#else
|
||||
int CBaseCombatWeapon::GetAvailableWeaponsInBox( CBaseCombatWeapon **pList, int listMax, const Vector &mins, const Vector &maxs )
|
||||
{
|
||||
// linear search all weapons
|
||||
int count = 0;
|
||||
int index = g_WeaponList.m_list.Head();
|
||||
while ( index != g_WeaponList.m_list.InvalidIndex() )
|
||||
{
|
||||
CBaseCombatWeapon *pWeapon = g_WeaponList.m_list[index];
|
||||
// skip any held weapon
|
||||
if ( !pWeapon->GetOwner() )
|
||||
{
|
||||
// Update
|
||||
m_TargetsDmgInfo[iIndex].AddDamageType( info.GetDamageType() );
|
||||
m_TargetsDmgInfo[iIndex].SetDamage( pInfo->GetDamage() + info.GetDamage() );
|
||||
m_TargetsDmgInfo[iIndex].SetDamageForce( pInfo->GetDamageForce() + info.GetDamageForce() );
|
||||
m_TargetsDmgInfo[iIndex].SetDamagePosition( info.GetDamagePosition() );
|
||||
m_TargetsDmgInfo[iIndex].SetReportedPosition( info.GetReportedPosition() );
|
||||
m_TargetsDmgInfo[iIndex].SetMaxDamage( MAX( pInfo->GetMaxDamage(), info.GetDamage() ) );
|
||||
m_TargetsDmgInfo[iIndex].SetAmmoType( info.GetAmmoType() );
|
||||
}
|
||||
|
||||
}
|
||||
#endif // GAME_DLL
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Send aggregate info
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmgAccumulator::Process( void )
|
||||
{
|
||||
FOR_EACH_MAP( m_TargetsDmgInfo, i )
|
||||
{
|
||||
CBaseEntity *pEntity = UTIL_EntityByIndex( m_TargetsDmgInfo.Key( i ) );
|
||||
if ( pEntity )
|
||||
{
|
||||
AddMultiDamage( m_TargetsDmgInfo[i], pEntity );
|
||||
// restrict to mins/maxs
|
||||
if ( IsPointInBox( pWeapon->GetAbsOrigin(), mins, maxs ) )
|
||||
{
|
||||
if ( count < listMax )
|
||||
{
|
||||
pList[count] = pWeapon;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
index = g_WeaponList.m_list.Next( index );
|
||||
}
|
||||
|
||||
m_bActive = false;
|
||||
m_TargetsDmgInfo.Purge();
|
||||
return count;
|
||||
}
|
||||
#endif // GAME_DLL
|
||||
#endif
|
||||
|
||||
|
||||
#if defined( CLIENT_DLL )
|
||||
|
||||
@@ -2523,7 +2385,7 @@ BEGIN_PREDICTION_DATA( CBaseCombatWeapon )
|
||||
// Networked
|
||||
DEFINE_PRED_FIELD( m_hOwner, FIELD_EHANDLE, FTYPEDESC_INSENDTABLE ),
|
||||
// DEFINE_FIELD( m_hWeaponFileInfo, FIELD_SHORT ),
|
||||
DEFINE_PRED_FIELD( m_iState, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
|
||||
DEFINE_PRED_FIELD( m_iState, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
|
||||
DEFINE_PRED_FIELD( m_iViewModelIndex, FIELD_INTEGER, FTYPEDESC_INSENDTABLE | FTYPEDESC_MODELINDEX ),
|
||||
DEFINE_PRED_FIELD( m_iWorldModelIndex, FIELD_INTEGER, FTYPEDESC_INSENDTABLE | FTYPEDESC_MODELINDEX ),
|
||||
DEFINE_PRED_FIELD_TOL( m_flNextPrimaryAttack, FIELD_FLOAT, FTYPEDESC_INSENDTABLE, TD_MSECTOLERANCE ),
|
||||
@@ -2539,10 +2401,8 @@ BEGIN_PREDICTION_DATA( CBaseCombatWeapon )
|
||||
|
||||
// Not networked
|
||||
|
||||
DEFINE_PRED_FIELD( m_flTimeWeaponIdle, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
|
||||
DEFINE_FIELD( m_bInReload, FIELD_BOOLEAN ),
|
||||
DEFINE_FIELD( m_bFireOnEmpty, FIELD_BOOLEAN ),
|
||||
DEFINE_FIELD( m_bFiringWholeClip, FIELD_BOOLEAN ),
|
||||
DEFINE_FIELD( m_flNextEmptySoundTime, FIELD_FLOAT ),
|
||||
DEFINE_FIELD( m_Activity, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( m_fFireDuration, FIELD_FLOAT ),
|
||||
@@ -2704,29 +2564,6 @@ void* SendProxy_SendLocalWeaponDataTable( const SendProp *pProp, const void *pSt
|
||||
return NULL;
|
||||
}
|
||||
REGISTER_SEND_PROXY_NON_MODIFIED_POINTER( SendProxy_SendLocalWeaponDataTable );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Only send to non-local players
|
||||
//-----------------------------------------------------------------------------
|
||||
void* SendProxy_SendNonLocalWeaponDataTable( const SendProp *pProp, const void *pStruct, const void *pVarData, CSendProxyRecipients *pRecipients, int objectID )
|
||||
{
|
||||
pRecipients->SetAllRecipients();
|
||||
|
||||
CBaseCombatWeapon *pWeapon = (CBaseCombatWeapon*)pVarData;
|
||||
if ( pWeapon )
|
||||
{
|
||||
CBasePlayer *pPlayer = ToBasePlayer( pWeapon->GetOwner() );
|
||||
if ( pPlayer )
|
||||
{
|
||||
pRecipients->ClearRecipient( pPlayer->GetClientIndex() );
|
||||
return ( void * )pVarData;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
REGISTER_SEND_PROXY_NON_MODIFIED_POINTER( SendProxy_SendNonLocalWeaponDataTable );
|
||||
|
||||
#endif
|
||||
|
||||
#if PREDICTION_ERROR_CHECK_LEVEL > 1
|
||||
@@ -2744,9 +2581,7 @@ BEGIN_NETWORK_TABLE_NOBASE( CBaseCombatWeapon, DT_LocalActiveWeaponData )
|
||||
SendPropInt( SENDINFO( m_nNextThinkTick ) ),
|
||||
SendPropTime( SENDINFO( m_flTimeWeaponIdle ) ),
|
||||
|
||||
#if defined( TF_DLL )
|
||||
SendPropExclude( "DT_AnimTimeMustBeFirst" , "m_flAnimTime" ),
|
||||
#endif
|
||||
|
||||
|
||||
#else
|
||||
RecvPropTime( RECVINFO( m_flNextPrimaryAttack ) ),
|
||||
@@ -2768,11 +2603,7 @@ BEGIN_NETWORK_TABLE_NOBASE( CBaseCombatWeapon, DT_LocalWeaponData )
|
||||
|
||||
SendPropInt( SENDINFO( m_nViewModelIndex ), VIEWMODEL_INDEX_BITS, SPROP_UNSIGNED ),
|
||||
|
||||
SendPropInt( SENDINFO( m_bFlipViewModel ) ),
|
||||
|
||||
#if defined( TF_DLL )
|
||||
SendPropExclude( "DT_AnimTimeMustBeFirst" , "m_flAnimTime" ),
|
||||
#endif
|
||||
|
||||
#else
|
||||
RecvPropIntWithMinusOneFlag( RECVINFO(m_iClip1 )),
|
||||
@@ -2782,8 +2613,6 @@ BEGIN_NETWORK_TABLE_NOBASE( CBaseCombatWeapon, DT_LocalWeaponData )
|
||||
|
||||
RecvPropInt( RECVINFO( m_nViewModelIndex ) ),
|
||||
|
||||
RecvPropBool( RECVINFO( m_bFlipViewModel ) ),
|
||||
|
||||
#endif
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
@@ -2793,7 +2622,7 @@ BEGIN_NETWORK_TABLE(CBaseCombatWeapon, DT_BaseCombatWeapon)
|
||||
SendPropDataTable("LocalActiveWeaponData", 0, &REFERENCE_SEND_TABLE(DT_LocalActiveWeaponData), SendProxy_SendActiveLocalWeaponDataTable ),
|
||||
SendPropModelIndex( SENDINFO(m_iViewModelIndex) ),
|
||||
SendPropModelIndex( SENDINFO(m_iWorldModelIndex) ),
|
||||
SendPropInt( SENDINFO(m_iState ), 8, SPROP_UNSIGNED ),
|
||||
SendPropInt( SENDINFO( m_iState ), 2, SPROP_UNSIGNED ),
|
||||
SendPropEHandle( SENDINFO(m_hOwner) ),
|
||||
#else
|
||||
RecvPropDataTable("LocalWeaponData", 0, 0, &REFERENCE_RECV_TABLE(DT_LocalWeaponData)),
|
||||
@@ -2804,3 +2633,32 @@ BEGIN_NETWORK_TABLE(CBaseCombatWeapon, DT_BaseCombatWeapon)
|
||||
RecvPropEHandle( RECVINFO(m_hOwner ) ),
|
||||
#endif
|
||||
END_NETWORK_TABLE()
|
||||
#if defined( CLIENT_DLL )
|
||||
|
||||
int Studio_FindAttachment( const CStudioHdr *pStudioHdr, const char *pAttachmentName );
|
||||
|
||||
int CBaseCombatWeapon::LookupAttachment( const char *pAttachmentName )
|
||||
{
|
||||
int newIndex = GetWorldModelIndex();
|
||||
if ( newIndex != m_nModelIndex )
|
||||
{
|
||||
const model_t *pWorldModel = modelinfo->GetModel( newIndex );
|
||||
if ( pWorldModel )
|
||||
{
|
||||
MDLHandle_t hStudioHdr = modelinfo->GetCacheHandle( pWorldModel );
|
||||
if ( MDLHANDLE_INVALID != hStudioHdr )
|
||||
{
|
||||
const studiohdr_t *pStudioHdr = mdlcache->GetStudioHdr( hStudioHdr );
|
||||
if ( pStudioHdr )
|
||||
{
|
||||
CStudioHdr studioHdrContainer( pStudioHdr, mdlcache );
|
||||
int iRet = Studio_FindAttachment( &studioHdrContainer, pAttachmentName ) + 1;
|
||||
return iRet;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return BaseClass::LookupAttachment( pAttachmentName );
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user