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.
581 lines
18 KiB
581 lines
18 KiB
//========= Copyright Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose:
|
|
//
|
|
//=============================================================================
|
|
|
|
#include "cbase.h"
|
|
#include "tf_weapon_shotgun.h"
|
|
#include "decals.h"
|
|
#include "tf_fx_shared.h"
|
|
#include "takedamageinfo.h"
|
|
#include "tf_gamerules.h"
|
|
|
|
// Client specific.
|
|
#if defined( CLIENT_DLL )
|
|
#include "c_tf_player.h"
|
|
// Server specific.
|
|
#else
|
|
#include "tf_player.h"
|
|
#include "ilagcompensationmanager.h"
|
|
#include "collisionutils.h"
|
|
#include "in_buttons.h"
|
|
#endif
|
|
|
|
//=============================================================================
|
|
//
|
|
// Weapon Shotgun tables.
|
|
//
|
|
|
|
CREATE_SIMPLE_WEAPON_TABLE( TFShotgun, tf_weapon_shotgun_primary )
|
|
CREATE_SIMPLE_WEAPON_TABLE( TFShotgun_Soldier, tf_weapon_shotgun_soldier )
|
|
CREATE_SIMPLE_WEAPON_TABLE( TFShotgun_HWG, tf_weapon_shotgun_hwg )
|
|
CREATE_SIMPLE_WEAPON_TABLE( TFShotgun_Pyro, tf_weapon_shotgun_pyro )
|
|
CREATE_SIMPLE_WEAPON_TABLE( TFScatterGun, tf_weapon_scattergun )
|
|
CREATE_SIMPLE_WEAPON_TABLE( TFShotgun_Revenge, tf_weapon_sentry_revenge )
|
|
CREATE_SIMPLE_WEAPON_TABLE( TFSodaPopper, tf_weapon_soda_popper )
|
|
CREATE_SIMPLE_WEAPON_TABLE( TFPEPBrawlerBlaster, tf_weapon_pep_brawler_blaster )
|
|
CREATE_SIMPLE_WEAPON_TABLE( TFShotgunBuildingRescue, tf_weapon_shotgun_building_rescue )
|
|
|
|
#define SCATTERGUN_KNOCKBACK_MIN_DMG 30.0f
|
|
#define SCATTERGUN_KNOCKBACK_MIN_RANGE_SQ 160000.0f //400x400
|
|
//=============================================================================
|
|
//
|
|
// Weapon Shotgun functions.
|
|
//
|
|
bool CanScatterGunKnockBack( CTFWeaponBase *pWeapon, float flDamage, float flDistanceSq )
|
|
{
|
|
int nBulletKnockBack = 0;
|
|
CALL_ATTRIB_HOOK_INT_ON_OTHER( pWeapon, nBulletKnockBack, set_scattergun_has_knockback );
|
|
if ( nBulletKnockBack != 0 )
|
|
{
|
|
if (flDamage > SCATTERGUN_KNOCKBACK_MIN_DMG && flDistanceSq < SCATTERGUN_KNOCKBACK_MIN_RANGE_SQ )
|
|
return true;
|
|
|
|
float flKnockbackMult = 1.0f;
|
|
CALL_ATTRIB_HOOK_FLOAT_ON_OTHER( pWeapon, flKnockbackMult, scattergun_knockback_mult );
|
|
if ( flKnockbackMult > 1.0f )
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
CTFShotgun::CTFShotgun()
|
|
{
|
|
m_bReloadsSingly = true;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CTFShotgun::PrimaryAttack()
|
|
{
|
|
if ( !CanAttack() )
|
|
return;
|
|
|
|
// Set the weapon mode.
|
|
m_iWeaponMode = TF_WEAPON_PRIMARY_MODE;
|
|
|
|
BaseClass::PrimaryAttack();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CTFShotgun::UpdatePunchAngles( CTFPlayer *pPlayer )
|
|
{
|
|
// Update the player's punch angle.
|
|
QAngle angle = pPlayer->GetPunchAngle();
|
|
float flPunchAngle = m_pWeaponInfo->GetWeaponData( m_iWeaponMode ).m_flPunchAngle;
|
|
angle.x -= SharedRandomInt( "ShotgunPunchAngle", ( flPunchAngle - 1 ), ( flPunchAngle + 1 ) );
|
|
pPlayer->SetPunchAngle( angle );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CTFShotgun::PlayWeaponShootSound( void )
|
|
{
|
|
BaseClass::PlayWeaponShootSound();
|
|
|
|
if ( TFGameRules()->GameModeUsesUpgrades() )
|
|
{
|
|
PlayUpgradedShootSound( "Weapon_Upgrade.DamageBonus" );
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// CTFShotgun_Revenge
|
|
//-----------------------------------------------------------------------------
|
|
CTFShotgun_Revenge::CTFShotgun_Revenge()
|
|
{
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CTFShotgun_Revenge::Precache()
|
|
{
|
|
int iModelIndex = PrecacheModel( TF_WEAPON_TAUNT_FRONTIER_JUSTICE_GUITAR_MODEL );
|
|
PrecacheGibsForModel( iModelIndex );
|
|
PrecacheParticleSystem( "blood_impact_backscatter" );
|
|
|
|
BaseClass::Precache();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CTFShotgun_Revenge::PrimaryAttack()
|
|
{
|
|
if ( !CanAttack() )
|
|
return;
|
|
|
|
BaseClass::PrimaryAttack();
|
|
|
|
// Do this after the attack, so that we know if we are doing custom damage
|
|
CTFPlayer *pOwner = ToTFPlayer( GetPlayerOwner() );
|
|
if ( pOwner )
|
|
{
|
|
int iRevengeCrits = pOwner->m_Shared.GetRevengeCrits();
|
|
pOwner->m_Shared.SetRevengeCrits( iRevengeCrits-1 );
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CTFShotgun_Revenge::SentryKilled( int iCrits )
|
|
{
|
|
int val = 0;
|
|
CALL_ATTRIB_HOOK_INT( val, sentry_killed_revenge );
|
|
if ( val == 1 )
|
|
{
|
|
CTFPlayer *pOwner = ToTFPlayer( GetPlayerOwner() );
|
|
if ( pOwner )
|
|
{
|
|
pOwner->m_Shared.SetRevengeCrits( pOwner->m_Shared.GetRevengeCrits() + iCrits );
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
bool CTFShotgun_Revenge::Holster( CBaseCombatWeapon *pSwitchingTo )
|
|
{
|
|
#ifdef GAME_DLL
|
|
CTFPlayer *pOwner = ToTFPlayer( GetPlayerOwner() );
|
|
if ( pOwner && pOwner->m_Shared.GetRevengeCrits() )
|
|
{
|
|
pOwner->m_Shared.RemoveCond( TF_COND_CRITBOOSTED );
|
|
}
|
|
#endif
|
|
|
|
return BaseClass::Holster( pSwitchingTo );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
bool CTFShotgun_Revenge::Deploy( void )
|
|
{
|
|
#ifdef GAME_DLL
|
|
CTFPlayer *pOwner = ToTFPlayer( GetOwner() );
|
|
if ( pOwner && pOwner->m_Shared.GetRevengeCrits() )
|
|
{
|
|
pOwner->m_Shared.AddCond( TF_COND_CRITBOOSTED );
|
|
}
|
|
#endif
|
|
|
|
return BaseClass::Deploy();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
int CTFShotgun_Revenge::GetCustomDamageType() const
|
|
{
|
|
CTFPlayer *pOwner = ToTFPlayer( GetPlayerOwner() );
|
|
if ( pOwner )
|
|
{
|
|
int iRevengeCrits = pOwner->m_Shared.GetRevengeCrits();
|
|
return iRevengeCrits > 0 ? TF_DMG_CUSTOM_SHOTGUN_REVENGE_CRIT : TF_DMG_CUSTOM_NONE;
|
|
}
|
|
return TF_DMG_CUSTOM_NONE;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
int CTFShotgun_Revenge::GetCount( void )
|
|
{
|
|
CTFPlayer *pOwner = ToTFPlayer( GetPlayerOwner() );
|
|
if ( pOwner )
|
|
{
|
|
return pOwner->m_Shared.GetRevengeCrits();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#ifdef CLIENT_DLL
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// ----------------------------------------------------------------------------
|
|
void CTFShotgun_Revenge::SetWeaponVisible( bool visible )
|
|
{
|
|
if ( !visible )
|
|
{
|
|
CTFPlayer *pPlayer = ToTFPlayer( GetOwner() );
|
|
if ( pPlayer && pPlayer->m_Shared.InCond( TF_COND_TAUNTING ) && pPlayer->GetPlayerClass()->GetClassIndex() == TF_CLASS_ENGINEER && pPlayer->m_Shared.GetTauntIndex() == TAUNT_BASE_WEAPON )
|
|
{
|
|
int nModelIndex = modelinfo->GetModelIndex( TF_WEAPON_TAUNT_FRONTIER_JUSTICE_GUITAR_MODEL );
|
|
CUtlVector<breakmodel_t> guitarGibs;
|
|
BuildGibList( guitarGibs, nModelIndex, 1.0f, COLLISION_GROUP_NONE );
|
|
if ( guitarGibs.Count() > 0 )
|
|
{
|
|
Vector vForward, vRight, vUp;
|
|
AngleVectors( GetAbsAngles(), &vForward, &vRight, &vUp );
|
|
|
|
Vector vecBreakVelocity = Vector(0,0,200);
|
|
AngularImpulse angularImpulse( RandomFloat( 0.0f, 120.0f ), RandomFloat( 0.0f, 120.0f ), 0.0 );
|
|
Vector vecOrigin = GetAbsOrigin() + vForward*70 + vUp*10;
|
|
QAngle vecAngle = GetAbsAngles();
|
|
breakablepropparams_t breakParams( vecOrigin, vecAngle, vecBreakVelocity, angularImpulse );
|
|
breakParams.impactEnergyScale = 1.0f;
|
|
|
|
CreateGibsFromList( guitarGibs, nModelIndex, NULL, breakParams, NULL, -1 , false, true );
|
|
}
|
|
}
|
|
}
|
|
|
|
BaseClass::SetWeaponVisible( visible );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// ----------------------------------------------------------------------------
|
|
int CTFShotgun_Revenge::GetWorldModelIndex( void )
|
|
{
|
|
// Engineer guitar support.
|
|
CTFPlayer *pPlayer = ToTFPlayer( GetOwner() );
|
|
if ( pPlayer && pPlayer->GetPlayerClass() && ( pPlayer->GetPlayerClass()->GetClassIndex() == TF_CLASS_ENGINEER ) &&
|
|
( pPlayer->m_Shared.InCond( TF_COND_TAUNTING ) ) && ( pPlayer->m_Shared.GetTauntIndex() == TAUNT_BASE_WEAPON ) )
|
|
{
|
|
// While we are taunting, replace our normal world model with the guitar.
|
|
m_iWorldModelIndex = modelinfo->GetModelIndex( TF_WEAPON_TAUNT_FRONTIER_JUSTICE_GUITAR_MODEL );
|
|
return m_iWorldModelIndex;
|
|
}
|
|
|
|
return BaseClass::GetWorldModelIndex();
|
|
}
|
|
#endif
|
|
|
|
#ifdef GAME_DLL
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Reset revenge crits when the shotgun is changed
|
|
//-----------------------------------------------------------------------------
|
|
void CTFShotgun_Revenge::Detach( void )
|
|
{
|
|
CTFPlayer *pPlayer = GetTFPlayerOwner();
|
|
if ( pPlayer )
|
|
{
|
|
pPlayer->m_Shared.SetRevengeCrits( 0 );
|
|
pPlayer->m_Shared.RemoveCond( TF_COND_CRITBOOSTED );
|
|
}
|
|
|
|
BaseClass::Detach();
|
|
}
|
|
#endif
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
bool CTFScatterGun::Reload( void )
|
|
{
|
|
int iWeaponMod = 0;
|
|
CALL_ATTRIB_HOOK_INT( iWeaponMod, set_scattergun_no_reload_single );
|
|
if ( iWeaponMod == 1 )
|
|
{
|
|
m_bReloadsSingly = false;
|
|
}
|
|
|
|
return BaseClass::Reload();
|
|
}
|
|
|
|
#define JUMP_SPEED 268.3281572999747f
|
|
extern ConVar tf_player_movement_stun_time;
|
|
extern float AirBurstDamageForce( const Vector &size, float damage, float scale );
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CTFScatterGun::FireBullet( CTFPlayer *pPlayer )
|
|
{
|
|
#ifndef CLIENT_DLL
|
|
if ( HasKnockback() )
|
|
{
|
|
// Perform some knock back.
|
|
CTFPlayer *pOwner = ToTFPlayer( GetPlayerOwner() );
|
|
if ( !pOwner )
|
|
return;
|
|
|
|
// No knockback during pre-round freeze.
|
|
if ( TFGameRules() && (TFGameRules()->State_Get() == GR_STATE_PREROUND) )
|
|
return;
|
|
|
|
// Knock the firer back!
|
|
if ( !(pOwner->GetFlags() & FL_ONGROUND) && !pPlayer->m_bScattergunJump )
|
|
{
|
|
pPlayer->m_bScattergunJump = true;
|
|
|
|
pOwner->m_Shared.StunPlayer( 0.3f, 1.f, TF_STUN_MOVEMENT | TF_STUN_MOVEMENT_FORWARD_ONLY );
|
|
|
|
float flForce = AirBurstDamageForce( pOwner->WorldAlignSize(), 60, 6.f );
|
|
|
|
Vector vecForward;
|
|
AngleVectors( pOwner->EyeAngles(), &vecForward );
|
|
Vector vecForce = vecForward * -flForce;
|
|
|
|
EntityMatrix mtxPlayer;
|
|
mtxPlayer.InitFromEntity( pOwner );
|
|
Vector vecAbsVelocity = pOwner->GetAbsVelocity();
|
|
Vector vecAbsVelocityAsPoint = vecAbsVelocity + pOwner->GetAbsOrigin();
|
|
Vector vecLocalVelocity = mtxPlayer.WorldToLocal( vecAbsVelocityAsPoint );
|
|
|
|
vecLocalVelocity.x = -300;
|
|
|
|
vecAbsVelocityAsPoint = mtxPlayer.LocalToWorld( vecLocalVelocity );
|
|
vecAbsVelocity = vecAbsVelocityAsPoint - pOwner->GetAbsOrigin();
|
|
pOwner->SetAbsVelocity( vecAbsVelocity );
|
|
|
|
// Impulse an additional bit of Z push.
|
|
pOwner->ApplyAbsVelocityImpulse( Vector(0,0,50.f) );
|
|
|
|
// Slow player movement for a brief period of time.
|
|
pOwner->RemoveFlag( FL_ONGROUND );
|
|
}
|
|
}
|
|
#endif
|
|
|
|
BaseClass::FireBullet( pPlayer );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CTFScatterGun::ApplyPostHitEffects( const CTakeDamageInfo &inputInfo, CTFPlayer *pPlayer )
|
|
{
|
|
#ifndef CLIENT_DLL
|
|
if ( !HasKnockback() )
|
|
return;
|
|
|
|
CTFPlayer *pAttacker = ToTFPlayer( inputInfo.GetAttacker() );
|
|
if ( !pAttacker )
|
|
return;
|
|
|
|
CTFPlayer *pTarget = pPlayer;
|
|
if ( !pTarget )
|
|
return;
|
|
|
|
if ( pTarget->m_Shared.GetWeaponKnockbackID() > -1 )
|
|
return;
|
|
|
|
float flDam = inputInfo.GetDamage();
|
|
Vector vecDir = pAttacker->WorldSpaceCenter() - pTarget->WorldSpaceCenter();
|
|
if ( !CanScatterGunKnockBack( this, flDam, vecDir.LengthSqr() ) )
|
|
return;
|
|
|
|
// Immune to pushback/knockback
|
|
if ( pTarget->m_Shared.InCond( TF_COND_MEGAHEAL ) )
|
|
return;
|
|
|
|
VectorNormalize( vecDir );
|
|
|
|
float flKnockbackMult = 3.0f;
|
|
CALL_ATTRIB_HOOK_FLOAT_ON_OTHER( this, flKnockbackMult, scattergun_knockback_mult );
|
|
|
|
float flForce = AirBurstDamageForce( pTarget->WorldAlignSize(), flDam, flKnockbackMult );
|
|
Vector vecForce = vecDir * -flForce;
|
|
vecForce.z += JUMP_SPEED;
|
|
|
|
pTarget->ApplyAirBlastImpulse( vecForce );
|
|
|
|
pTarget->m_Shared.StunPlayer( 0.3f, 1.f, TF_STUN_MOVEMENT | TF_STUN_MOVEMENT_FORWARD_ONLY, pAttacker );
|
|
pTarget->m_Shared.SetWeaponKnockbackID( pAttacker->GetUserID() );
|
|
|
|
#endif
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CTFScatterGun::FinishReload( void )
|
|
{
|
|
CTFPlayer* pOwner = ToTFPlayer( GetOwner() );
|
|
if ( !pOwner )
|
|
return;
|
|
|
|
if ( UsesClipsForAmmo1() && !m_bReloadsSingly )
|
|
{
|
|
int primary = MIN( GetMaxClip1() - m_iClip1, pOwner->GetAmmoCount(m_iPrimaryAmmoType));
|
|
m_iClip1 += primary;
|
|
|
|
// Takes a whole clip worth of ammo to reload, causing us to lose whatever was chambered.
|
|
pOwner->RemoveAmmo( GetMaxClip1(), m_iPrimaryAmmoType);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
bool CTFScatterGun::HasKnockback( void )
|
|
{
|
|
int iWeaponMod = 0;
|
|
CALL_ATTRIB_HOOK_INT( iWeaponMod, set_scattergun_has_knockback );
|
|
if ( iWeaponMod == 1 )
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Play animation appropriate to ball status.
|
|
//-----------------------------------------------------------------------------
|
|
bool CTFScatterGun::SendWeaponAnim( int iActivity )
|
|
{
|
|
CTFPlayer *pPlayer = GetTFPlayerOwner();
|
|
if ( !pPlayer )
|
|
return BaseClass::SendWeaponAnim( iActivity );
|
|
|
|
if ( HasKnockback() )
|
|
{
|
|
// Knockback version uses a different model and animation set.
|
|
switch ( iActivity )
|
|
{
|
|
case ACT_VM_DRAW:
|
|
iActivity = ACT_ITEM2_VM_DRAW;
|
|
break;
|
|
case ACT_VM_HOLSTER:
|
|
iActivity = ACT_ITEM2_VM_HOLSTER;
|
|
break;
|
|
case ACT_VM_IDLE:
|
|
iActivity = ACT_ITEM2_VM_IDLE;
|
|
break;
|
|
case ACT_VM_PULLBACK:
|
|
iActivity = ACT_ITEM2_VM_PULLBACK;
|
|
break;
|
|
case ACT_VM_PRIMARYATTACK:
|
|
iActivity = ACT_ITEM2_VM_PRIMARYATTACK;
|
|
break;
|
|
case ACT_VM_SECONDARYATTACK:
|
|
iActivity = ACT_ITEM2_VM_SECONDARYATTACK;
|
|
break;
|
|
case ACT_VM_RELOAD:
|
|
iActivity = ACT_ITEM2_VM_RELOAD;
|
|
break;
|
|
case ACT_VM_DRYFIRE:
|
|
iActivity = ACT_ITEM2_VM_DRYFIRE;
|
|
break;
|
|
case ACT_VM_IDLE_TO_LOWERED:
|
|
iActivity = ACT_ITEM2_VM_IDLE_TO_LOWERED;
|
|
break;
|
|
case ACT_VM_IDLE_LOWERED:
|
|
iActivity = ACT_ITEM2_VM_IDLE_LOWERED;
|
|
break;
|
|
case ACT_VM_LOWERED_TO_IDLE:
|
|
iActivity = ACT_ITEM2_VM_LOWERED_TO_IDLE;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return BaseClass::SendWeaponAnim( iActivity );
|
|
}
|
|
|
|
#ifdef GAME_DLL
|
|
//-----------------------------------------------------------------------------
|
|
void CTFScatterGun::Equip( CBaseCombatCharacter *pOwner )
|
|
{
|
|
CTFPlayer *pPlayer = dynamic_cast<CTFPlayer*>( pOwner );
|
|
if ( pPlayer )
|
|
{
|
|
pPlayer->m_Shared.SetScoutHypeMeter( 0.0f );
|
|
}
|
|
|
|
BaseClass::Equip( pOwner );
|
|
}
|
|
#endif // GAME_DLL
|
|
//-----------------------------------------------------------------------------
|
|
// CTFSodaPopper
|
|
//-----------------------------------------------------------------------------
|
|
float CTFSodaPopper::GetProgress( void )
|
|
{
|
|
CTFPlayer *pPlayer = GetTFPlayerOwner();
|
|
if ( !pPlayer )
|
|
return 0.f;
|
|
|
|
return pPlayer->m_Shared.GetScoutHypeMeter() * 0.01f;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void CTFSodaPopper::ItemBusyFrame( void )
|
|
{
|
|
#ifdef GAME_DLL
|
|
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
|
|
if ( pOwner && pOwner->m_nButtons & IN_ATTACK2 )
|
|
{
|
|
// Check here so we can always activate buff when we want (similar to stickies)
|
|
SecondaryAttack();
|
|
}
|
|
#endif
|
|
|
|
BaseClass::ItemBusyFrame();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void CTFSodaPopper::SecondaryAttack()
|
|
{
|
|
CTFPlayer *pPlayer = GetTFPlayerOwner( );
|
|
if ( !pPlayer || pPlayer->m_Shared.IsHypeBuffed() )
|
|
return;
|
|
|
|
if ( pPlayer->m_Shared.GetScoutHypeMeter() >= 100.f )
|
|
{
|
|
pPlayer->m_Shared.AddCond( TF_COND_SODAPOPPER_HYPE );
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
float CTFPEPBrawlerBlaster::GetProgress( void )
|
|
{
|
|
CTFPlayer *pPlayer = GetTFPlayerOwner();
|
|
if ( !pPlayer )
|
|
return 0.f;
|
|
|
|
return pPlayer->m_Shared.GetScoutHypeMeter() * 0.01f;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
float CTFShotgunBuildingRescue::GetProjectileSpeed( void )
|
|
{
|
|
return RemapValClamped( 0.75f, 0.0f, 1.f, 1800, 2600 ); // Temp, if we want to ramp.
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
float CTFShotgunBuildingRescue::GetProjectileGravity( void )
|
|
{
|
|
return RemapValClamped( 0.75f, 0.0f, 1.f, 0.5f, 0.1f ); // Temp, if we want to ramp.
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool CTFShotgunBuildingRescue::IsViewModelFlipped( void )
|
|
{
|
|
return !BaseClass::IsViewModelFlipped(); // Invert because arrows are backwards by default.
|
|
}
|