mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-08 01:39:36 +00:00
1
This commit is contained in:
@@ -0,0 +1,346 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "cbase.h"
|
||||
#include "tf_weapon_invis.h"
|
||||
#include "in_buttons.h"
|
||||
|
||||
#if !defined( CLIENT_DLL )
|
||||
#include "vguiscreen.h"
|
||||
#include "tf_player.h"
|
||||
#else
|
||||
#include "c_tf_player.h"
|
||||
#endif
|
||||
|
||||
extern ConVar tf_spy_invis_unstealth_time;
|
||||
extern ConVar tf_spy_cloak_consume_rate;
|
||||
extern ConVar tf_spy_cloak_regen_rate;
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// TFWeaponBase Melee tables.
|
||||
//
|
||||
IMPLEMENT_NETWORKCLASS_ALIASED( TFWeaponInvis, DT_TFWeaponInvis )
|
||||
|
||||
BEGIN_NETWORK_TABLE( CTFWeaponInvis, DT_TFWeaponInvis )
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
BEGIN_PREDICTION_DATA( CTFWeaponInvis )
|
||||
END_PREDICTION_DATA()
|
||||
|
||||
LINK_ENTITY_TO_CLASS( tf_weapon_invis, CTFWeaponInvis );
|
||||
PRECACHE_WEAPON_REGISTER( tf_weapon_invis );
|
||||
|
||||
// Server specific.
|
||||
#if !defined( CLIENT_DLL )
|
||||
BEGIN_DATADESC( CTFWeaponInvis )
|
||||
END_DATADESC()
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Use the offhand view model
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTFWeaponInvis::Spawn( void )
|
||||
{
|
||||
BaseClass::Spawn();
|
||||
|
||||
SetViewModelIndex( 1 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTFWeaponInvis::OnActiveStateChanged( int iOldState )
|
||||
{
|
||||
BaseClass::OnActiveStateChanged( iOldState );
|
||||
|
||||
// If we are being removed, we need to remove all stealth effects from our owner
|
||||
if ( m_iState == WEAPON_NOT_CARRIED && iOldState != WEAPON_NOT_CARRIED )
|
||||
{
|
||||
CleanupInvisibilityWatch();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Clear out the view model when we hide
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTFWeaponInvis::HideThink( void )
|
||||
{
|
||||
SetWeaponVisible( false );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CTFWeaponInvis::GetViewModel( int viewmodelindex ) const
|
||||
{
|
||||
// Watch uses the player model as its viewmodel, because it's never seen being carried by the player
|
||||
const CEconItemView *pItem = GetAttributeContainer()->GetItem();
|
||||
if ( pItem->IsValid() )
|
||||
{
|
||||
int iClass = 0;
|
||||
int iTeam = 0;
|
||||
CTFPlayer *pTFPlayer = ToTFPlayer( GetOwnerEntity() );
|
||||
if ( pTFPlayer )
|
||||
{
|
||||
iClass = pTFPlayer->GetPlayerClass()->GetClassIndex();
|
||||
iTeam = pTFPlayer->GetTeamNumber();
|
||||
}
|
||||
|
||||
return pItem->GetPlayerDisplayModel( iClass, iTeam );
|
||||
}
|
||||
|
||||
return BaseClass::GetViewModel( viewmodelindex );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Show/hide weapon and corresponding view model if any
|
||||
// Input : visible -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTFWeaponInvis::SetWeaponVisible( bool visible )
|
||||
{
|
||||
CBaseViewModel *vm = NULL;
|
||||
|
||||
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
|
||||
if ( pOwner )
|
||||
{
|
||||
vm = pOwner->GetViewModel( m_nViewModelIndex );
|
||||
}
|
||||
|
||||
if ( visible )
|
||||
{
|
||||
RemoveEffects( EF_NODRAW );
|
||||
if ( vm )
|
||||
{
|
||||
vm->RemoveEffects( EF_NODRAW );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddEffects( EF_NODRAW );
|
||||
if ( vm )
|
||||
{
|
||||
vm->AddEffects( EF_NODRAW );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CTFWeaponInvis::Deploy( void )
|
||||
{
|
||||
bool b = BaseClass::Deploy();
|
||||
|
||||
SetWeaponIdleTime( gpGlobals->curtime + 1.5 );
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CTFWeaponInvis::Holster( CBaseCombatWeapon *pSwitchingTo )
|
||||
{
|
||||
bool bHolster = BaseClass::Holster( pSwitchingTo );
|
||||
|
||||
// far in the future
|
||||
SetWeaponIdleTime( gpGlobals->curtime + 10 );
|
||||
|
||||
return bHolster;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTFWeaponInvis::PrimaryAttack( void )
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTFWeaponInvis::SecondaryAttack( void )
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTFWeaponInvis::ItemBusyFrame( void )
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: the player alt-fired or otherwise activated the functionality of
|
||||
// the invisibility watch
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CTFWeaponInvis::ActivateInvisibilityWatch( void )
|
||||
{
|
||||
CTFPlayer *pOwner = ToTFPlayer( GetOwner() );
|
||||
if ( !pOwner )
|
||||
return false;
|
||||
|
||||
SetCloakRates();
|
||||
|
||||
bool bDoSkill = false;
|
||||
// If we're in TF_COND_STEALTHED - which means we gave it ourselves - always remove it
|
||||
// If we're in TF_COND_STEALTHED_USER_BUFF and we have Dead Ringer, allow it to be toggled
|
||||
// since we're allowed to fire from stealth
|
||||
if ( pOwner->m_Shared.InCond( TF_COND_STEALTHED ) )
|
||||
{
|
||||
// De-cloak.
|
||||
float flDecloakRate = 0.0f;
|
||||
CALL_ATTRIB_HOOK_FLOAT( flDecloakRate, mult_decloak_rate );
|
||||
if ( flDecloakRate <= 0.0f )
|
||||
flDecloakRate = 1.0f;
|
||||
|
||||
pOwner->m_Shared.FadeInvis( 1.0f );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( HasFeignDeath() )
|
||||
{
|
||||
if ( pOwner->m_Shared.IsFeignDeathReady() )
|
||||
{
|
||||
// Turn it off...
|
||||
SetFeignDeathState( false );
|
||||
}
|
||||
else if ( pOwner->m_Shared.GetSpyCloakMeter() == 100.f )
|
||||
{
|
||||
// Turn it on...
|
||||
SetFeignDeathState( true );
|
||||
}
|
||||
}
|
||||
else if ( pOwner->CanGoInvisible() && ( pOwner->m_Shared.GetSpyCloakMeter() > 8.0f ) ) // must have over 10% cloak to start
|
||||
{
|
||||
// Do standard cloak.
|
||||
pOwner->m_Shared.AddCond( TF_COND_STEALTHED, -1.f, pOwner );
|
||||
|
||||
#ifdef STAGING_ONLY
|
||||
if ( pOwner->m_Shared.HasPhaseCloakAbility() )
|
||||
{
|
||||
pOwner->m_Shared.AddCond( TF_COND_STEALTHED_PHASE, -1.f, pOwner );
|
||||
}
|
||||
#endif // STAGING_ONLY
|
||||
|
||||
bDoSkill = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( bDoSkill )
|
||||
{
|
||||
pOwner->m_Shared.SetNextStealthTime( gpGlobals->curtime + 0.5 );
|
||||
}
|
||||
else
|
||||
{
|
||||
pOwner->m_Shared.SetNextStealthTime( gpGlobals->curtime + 0.1 );
|
||||
}
|
||||
|
||||
return bDoSkill;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: the player has changed loadouts or done something else that causes
|
||||
// us to clean up any side effects of our watch
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTFWeaponInvis::CleanupInvisibilityWatch( void )
|
||||
{
|
||||
CTFPlayer *pOwner = ToTFPlayer( GetOwner() );
|
||||
if ( !pOwner )
|
||||
return;
|
||||
|
||||
pOwner->m_Shared.SetFeignDeathReady( false );
|
||||
|
||||
if ( pOwner->m_Shared.IsStealthed() )
|
||||
{
|
||||
// De-cloak.
|
||||
pOwner->m_Shared.FadeInvis( 1.0f );
|
||||
}
|
||||
|
||||
pOwner->HolsterOffHandWeapon();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTFWeaponInvis::SetFeignDeathState( bool bEnabled )
|
||||
{
|
||||
CTFPlayer *pOwner = ToTFPlayer( GetOwner() );
|
||||
if ( !pOwner )
|
||||
return;
|
||||
|
||||
if ( pOwner->m_Shared.InCond( TF_COND_GRAPPLINGHOOK ) )
|
||||
return;
|
||||
|
||||
if ( bEnabled )
|
||||
{
|
||||
pOwner->m_Shared.SetFeignDeathReady( true );
|
||||
pOwner->SetOffHandWeapon( this );
|
||||
pOwner->m_Shared.SetNextStealthTime( gpGlobals->curtime + 0.5 );
|
||||
}
|
||||
else
|
||||
{
|
||||
pOwner->m_Shared.SetFeignDeathReady( false );
|
||||
if ( !pOwner->m_Shared.InCond( TF_COND_STEALTHED ) )
|
||||
{
|
||||
pOwner->HolsterOffHandWeapon();
|
||||
if ( pOwner->GetActiveWeapon() )
|
||||
{
|
||||
pOwner->GetActiveWeapon()->m_flNextPrimaryAttack = gpGlobals->curtime + 0.1f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Set the correct cloak consume & regen rates for this item.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTFWeaponInvis::SetCloakRates( void )
|
||||
{
|
||||
CTFPlayer *pOwner = ToTFPlayer( GetOwner() );
|
||||
|
||||
float fCloakConsumeRate = tf_spy_cloak_consume_rate.GetFloat();
|
||||
float fCloakConsumeFactor = 1.0f;
|
||||
CALL_ATTRIB_HOOK_FLOAT_ON_OTHER( pOwner, fCloakConsumeFactor, mult_cloak_meter_consume_rate ); // Ask the owner since this attr may come from another weapon
|
||||
|
||||
// This value is a inverse scale and does not match expectations on description
|
||||
// so we subtract and invert to make it align
|
||||
// ie 25% (0.75% in schema) makes 10seconds go to 13.3 when we want 12.5
|
||||
// 2 - 0.75 = 1.25... 1 / 1.25 = 0.8.. Consume rate "8". 10s / 0.8 = 12.5s
|
||||
if ( fCloakConsumeFactor < 1.0f )
|
||||
{
|
||||
fCloakConsumeFactor = 1.0f / (2.0f - fCloakConsumeFactor);
|
||||
}
|
||||
|
||||
pOwner->m_Shared.SetCloakConsumeRate( fCloakConsumeRate * fCloakConsumeFactor );
|
||||
|
||||
float fCloakRegenRate = tf_spy_cloak_regen_rate.GetFloat();
|
||||
float fCloakRegenFactor = 1.0f;
|
||||
CALL_ATTRIB_HOOK_FLOAT( fCloakRegenFactor, mult_cloak_meter_regen_rate );
|
||||
pOwner->m_Shared.SetCloakRegenRate( fCloakRegenRate * fCloakRegenFactor );
|
||||
}
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return the right pda panel for the watch model we're using
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTFWeaponInvis::GetControlPanelInfo( int nPanelIndex, const char *&pPanelName )
|
||||
{
|
||||
const char *pszViewModel = GetViewModel(0);
|
||||
if ( Q_stristr( pszViewModel, "pocket" ) )
|
||||
{
|
||||
pPanelName = "pda_panel_spy_invis_pocket";
|
||||
}
|
||||
else if ( Q_stristr( pszViewModel, "ttg_watch_spy" ) )
|
||||
{
|
||||
pPanelName = "pda_panel_spy_invis_pocket_ttg";
|
||||
}
|
||||
else if ( Q_stristr( pszViewModel, "hm_watch" ) )
|
||||
{
|
||||
pPanelName = "pda_panel_spy_invis_pocket_hm";
|
||||
}
|
||||
else
|
||||
{
|
||||
pPanelName = "pda_panel_spy_invis";
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user