diff options
Diffstat (limited to 'game/shared/cstrike/weapon_awp.cpp')
| -rw-r--r-- | game/shared/cstrike/weapon_awp.cpp | 306 |
1 files changed, 306 insertions, 0 deletions
diff --git a/game/shared/cstrike/weapon_awp.cpp b/game/shared/cstrike/weapon_awp.cpp new file mode 100644 index 0000000..bcd4113 --- /dev/null +++ b/game/shared/cstrike/weapon_awp.cpp @@ -0,0 +1,306 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "cbase.h" +#include "weapon_csbasegun.h" + + +#if defined( CLIENT_DLL ) + + #define CWeaponAWP C_WeaponAWP + #include "c_cs_player.h" + +#else + + #include "cs_player.h" + #include "KeyValues.h" + +#endif + +#define SNIPER_ZOOM_CONTEXT "SniperRifleThink" + +const int cAWPMidZoomFOV = 40; +const int cAWPMaxZoomFOV = 10; + +#ifdef AWP_UNZOOM + ConVar sv_awpunzoomdelay( + "sv_awpunzoomdelay", + "1.0", + 0, + "how many seconds to zoom the zoom up after firing", + true, 0, // min value + false, 0 // max value + ); +#endif + + +class CWeaponAWP : public CWeaponCSBaseGun +{ +public: + DECLARE_CLASS( CWeaponAWP, CWeaponCSBaseGun ); + DECLARE_NETWORKCLASS(); + DECLARE_PREDICTABLE(); + +#ifndef CLIENT_DLL + DECLARE_DATADESC(); +#endif + + CWeaponAWP(); + + virtual void Spawn(); + + virtual void PrimaryAttack(); + virtual void SecondaryAttack(); + + virtual float GetInaccuracy() const; + virtual float GetMaxSpeed() const; + virtual bool IsAwp() const; + virtual bool Reload(); + virtual bool Deploy(); + + virtual CSWeaponID GetWeaponID( void ) const { return WEAPON_AWP; } + +private: + +#ifdef AWP_UNZOOM + void UnzoomThink( void ); +#endif + + CWeaponAWP( const CWeaponAWP & ); +}; + +IMPLEMENT_NETWORKCLASS_ALIASED( WeaponAWP, DT_WeaponAWP ) + +BEGIN_NETWORK_TABLE( CWeaponAWP, DT_WeaponAWP ) +END_NETWORK_TABLE() + +BEGIN_PREDICTION_DATA( CWeaponAWP ) +END_PREDICTION_DATA() + +LINK_ENTITY_TO_CLASS( weapon_awp, CWeaponAWP ); +PRECACHE_WEAPON_REGISTER( weapon_awp ); + +#ifndef CLIENT_DLL + + BEGIN_DATADESC( CWeaponAWP ) +#ifdef AWP_UNZOOM + DEFINE_THINKFUNC( UnzoomThink ), +#endif + END_DATADESC() + +#endif + +CWeaponAWP::CWeaponAWP() +{ +} + +void CWeaponAWP::Spawn() +{ + Precache(); + + BaseClass::Spawn(); +} + + +void CWeaponAWP::SecondaryAttack() +{ + const float kZoomTime = 0.10f; + + CCSPlayer *pPlayer = GetPlayerOwner(); + + if ( pPlayer == NULL ) + { + Assert( pPlayer != NULL ); + return; + } + + if ( pPlayer->GetFOV() == pPlayer->GetDefaultFOV() ) + { + pPlayer->SetFOV( pPlayer, cAWPMidZoomFOV, kZoomTime ); + m_weaponMode = Secondary_Mode; + m_fAccuracyPenalty += GetCSWpnData().m_fInaccuracyAltSwitch; + } + else if ( pPlayer->GetFOV() == cAWPMidZoomFOV ) + { + pPlayer->SetFOV( pPlayer, cAWPMaxZoomFOV, kZoomTime ); + m_weaponMode = Secondary_Mode; + } + else + { + pPlayer->SetFOV( pPlayer, pPlayer->GetDefaultFOV(), kZoomTime ); + m_weaponMode = Primary_Mode; + } + + +#ifndef CLIENT_DLL + // If this isn't guarded, the sound will be emitted twice, once by the server and once by the client. + // Let the server play it since if only the client plays it, it's liable to get played twice cause of + // a prediction error. joy. + + //============================================================================= + // HPE_BEGIN: + // [tj] Playing this from the player so that we don't try to play the sound outside the level. + //============================================================================= + if ( GetPlayerOwner() ) + { + GetPlayerOwner()->EmitSound( "Default.Zoom" ); + } + //============================================================================= + // HPE_END + //============================================================================= + // let the bots hear the rifle zoom + IGameEvent * event = gameeventmanager->CreateEvent( "weapon_zoom" ); + if ( event ) + { + event->SetInt( "userid", pPlayer->GetUserID() ); + gameeventmanager->FireEvent( event ); + } +#endif + + m_flNextSecondaryAttack = gpGlobals->curtime + 0.3f; + m_zoomFullyActiveTime = gpGlobals->curtime + 0.15; // The worst zoom time from above. + +} + +float CWeaponAWP::GetInaccuracy() const +{ + if ( weapon_accuracy_model.GetInt() == 1 ) + { + CCSPlayer *pPlayer = GetPlayerOwner(); + if ( !pPlayer ) + return 0.0f; + + float fSpread = 0.0f; + + if ( !FBitSet( pPlayer->GetFlags(), FL_ONGROUND ) ) + fSpread = 0.85f; + + else if ( pPlayer->GetAbsVelocity().Length2D() > 140 ) + fSpread = 0.25f; + + else if ( pPlayer->GetAbsVelocity().Length2D() > 10 ) + fSpread = 0.10f; + + else if ( FBitSet( pPlayer->GetFlags(), FL_DUCKING ) ) + fSpread = 0.0f; + + else + fSpread = 0.001f; + + // If we are not zoomed in, or we have very recently zoomed and are still transitioning, the bullet diverts more. + if (pPlayer->GetFOV() == pPlayer->GetDefaultFOV() || (gpGlobals->curtime < m_zoomFullyActiveTime)) + { + fSpread += 0.08f; + } + + return fSpread; + } + else + { + return BaseClass::GetInaccuracy(); + } +} + +void CWeaponAWP::PrimaryAttack() +{ + CCSPlayer *pPlayer = GetPlayerOwner(); + if ( !pPlayer ) + return; + + if ( !CSBaseGunFire( GetCSWpnData().m_flCycleTime, m_weaponMode ) ) + return; + + if ( m_weaponMode == Secondary_Mode ) + { + float midFOVdistance = fabs( pPlayer->GetFOV() - (float)cAWPMidZoomFOV ); + float farFOVdistance = fabs( pPlayer->GetFOV() - (float)cAWPMaxZoomFOV ); + if ( midFOVdistance < farFOVdistance ) + { + pPlayer->m_iLastZoom = cAWPMidZoomFOV; + } + else + { + pPlayer->m_iLastZoom = cAWPMaxZoomFOV; + } + + #ifdef AWP_UNZOOM + SetContextThink( &CWeaponAWP::UnzoomThink, gpGlobals->curtime + sv_awpunzoomdelay.GetFloat(), SNIPER_ZOOM_CONTEXT ); + #else + pPlayer->m_bResumeZoom = true; + pPlayer->SetFOV( pPlayer, pPlayer->GetDefaultFOV(), 0.1f ); + m_weaponMode = Primary_Mode; + #endif + } + + QAngle angle = pPlayer->GetPunchAngle(); + angle.x -= 2; + pPlayer->SetPunchAngle( angle ); +} + +#ifdef AWP_UNZOOM +void CWeaponAWP::UnzoomThink( void ) +{ + CCSPlayer *pPlayer = GetPlayerOwner(); + + if (pPlayer == NULL) + { + Assert(pPlayer != NULL); + return; + } + + pPlayer->SetFOV( pPlayer, pPlayer->GetDefaultFOV(), 0.1f ); +} +#endif + + +float CWeaponAWP::GetMaxSpeed() const +{ + CCSPlayer *pPlayer = GetPlayerOwner(); + + if (pPlayer == NULL) + { + Assert(pPlayer != NULL); + return BaseClass::GetMaxSpeed(); + } + + if ( pPlayer->GetFOV() == pPlayer->GetDefaultFOV() ) + { + return BaseClass::GetMaxSpeed(); + } + else + { + // Slower speed when zoomed in. + return 150; + } +} + + +bool CWeaponAWP::IsAwp() const +{ + return true; +} + + +bool CWeaponAWP::Reload() +{ + m_weaponMode = Primary_Mode; + return BaseClass::Reload(); +} + +bool CWeaponAWP::Deploy() +{ + // don't allow weapon switching to shortcut cycle time (quickswitch exploit) + float fOldNextPrimaryAttack = m_flNextPrimaryAttack; + float fOldNextSecondaryAttack = m_flNextSecondaryAttack; + + if ( !BaseClass::Deploy() ) + return false; + + m_weaponMode = Primary_Mode; + m_flNextPrimaryAttack = MAX( m_flNextPrimaryAttack, fOldNextPrimaryAttack ); + m_flNextSecondaryAttack = MAX( m_flNextSecondaryAttack, fOldNextSecondaryAttack ); + return true; +} |