diff options
Diffstat (limited to 'game/shared/cstrike/weapon_famas.cpp')
| -rw-r--r-- | game/shared/cstrike/weapon_famas.cpp | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/game/shared/cstrike/weapon_famas.cpp b/game/shared/cstrike/weapon_famas.cpp new file mode 100644 index 0000000..1f22cad --- /dev/null +++ b/game/shared/cstrike/weapon_famas.cpp @@ -0,0 +1,243 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "cbase.h" +#include "weapon_csbasegun.h" +#include "fx_cs_shared.h" + + +#if defined( CLIENT_DLL ) + + #define CWeaponFamas C_WeaponFamas + #include "c_cs_player.h" + +#else + + #include "cs_player.h" + +#endif + + +class CWeaponFamas : public CWeaponCSBaseGun +{ +public: + DECLARE_CLASS( CWeaponFamas, CWeaponCSBase ); + DECLARE_NETWORKCLASS(); + DECLARE_PREDICTABLE(); + + CWeaponFamas(); + + virtual void PrimaryAttack(); + virtual void SecondaryAttack(); + virtual bool Deploy(); + + virtual float GetInaccuracy() const; + + virtual void ItemPostFrame(); + + void FamasFire( float flSpread, bool bFireBurst ); + void FireRemaining(); + + virtual CSWeaponID GetWeaponID( void ) const { return WEAPON_FAMAS; } + +private: + + CWeaponFamas( const CWeaponFamas & ); + CNetworkVar( bool, m_bBurstMode ); + CNetworkVar( int, m_iBurstShotsRemaining ); + float m_fNextBurstShot; // time to shoot the next bullet in burst fire mode +}; + +IMPLEMENT_NETWORKCLASS_ALIASED( WeaponFamas, DT_WeaponFamas ) + +BEGIN_NETWORK_TABLE( CWeaponFamas, DT_WeaponFamas ) + #ifdef CLIENT_DLL + RecvPropBool( RECVINFO( m_bBurstMode ) ), + RecvPropInt( RECVINFO( m_iBurstShotsRemaining ) ), + #else + SendPropBool( SENDINFO( m_bBurstMode ) ), + SendPropInt( SENDINFO( m_iBurstShotsRemaining ) ), + #endif +END_NETWORK_TABLE() + +#if defined(CLIENT_DLL) +BEGIN_PREDICTION_DATA( CWeaponFamas ) +DEFINE_PRED_FIELD( m_iBurstShotsRemaining, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ), +DEFINE_PRED_FIELD( m_fNextBurstShot, FIELD_FLOAT, 0 ), +END_PREDICTION_DATA() +#endif + +LINK_ENTITY_TO_CLASS( weapon_famas, CWeaponFamas ); +PRECACHE_WEAPON_REGISTER( weapon_famas ); + + +const float kFamasBurstCycleTime = 0.075f; + + +CWeaponFamas::CWeaponFamas() +{ + m_bBurstMode = false; +} + + +bool CWeaponFamas::Deploy( ) +{ + m_iBurstShotsRemaining = 0; + m_fNextBurstShot = 0.0f; + m_flAccuracy = 0.9f; + + return BaseClass::Deploy(); +} + + +// Secondary attack could be three-round burst mode +void CWeaponFamas::SecondaryAttack() +{ + CCSPlayer *pPlayer = GetPlayerOwner(); + if ( !pPlayer ) + return; + + if ( m_bBurstMode ) + { + ClientPrint( pPlayer, HUD_PRINTCENTER, "#Switch_To_FullAuto" ); + m_bBurstMode = false; + m_weaponMode = Primary_Mode; + } + else + { + ClientPrint( pPlayer, HUD_PRINTCENTER, "#Switch_To_BurstFire" ); + m_bBurstMode = true; + m_weaponMode = Secondary_Mode; + } + m_flNextSecondaryAttack = gpGlobals->curtime + 0.3; +} + +float CWeaponFamas::GetInaccuracy() const +{ + if ( weapon_accuracy_model.GetInt() == 1 ) + { + float fAutoPenalty = m_bBurstMode ? 0.0f : 0.01f; + + CCSPlayer *pPlayer = GetPlayerOwner(); + if ( !pPlayer ) + return 0.0f; + + if ( !FBitSet( pPlayer->GetFlags(), FL_ONGROUND ) ) // if player is in air + return 0.03f + 0.3f * m_flAccuracy + fAutoPenalty; + + else if ( pPlayer->GetAbsVelocity().Length2D() > 140 ) // if player is moving + return 0.03f + 0.07f * m_flAccuracy + fAutoPenalty; + /* new code */ + else + return 0.02f * m_flAccuracy + fAutoPenalty; + } + else + return BaseClass::GetInaccuracy(); +} + + +void CWeaponFamas::ItemPostFrame() +{ + if ( m_iBurstShotsRemaining > 0 && gpGlobals->curtime >= m_fNextBurstShot ) + FireRemaining(); + + BaseClass::ItemPostFrame(); +} + + + +// GOOSEMAN : FireRemaining used by Glock18 +void CWeaponFamas::FireRemaining() +{ + m_iClip1--; + + if (m_iClip1 < 0) + { + m_iClip1 = 0; + m_iBurstShotsRemaining = 0; + m_fNextBurstShot = 0.0f; + return; + } + + CCSPlayer *pPlayer = GetPlayerOwner(); + if ( !pPlayer ) + Error( "!pPlayer" ); + + // Famas burst mode + FX_FireBullets( + pPlayer->entindex(), + pPlayer->Weapon_ShootPosition(), + pPlayer->EyeAngles() + 2.0f * pPlayer->GetPunchAngle(), + GetWeaponID(), + Secondary_Mode, + CBaseEntity::GetPredictionRandomSeed() & 255, + GetInaccuracy(), + GetSpread(), + m_fNextBurstShot); + + SendWeaponAnim( ACT_VM_PRIMARYATTACK ); + + pPlayer->DoMuzzleFlash(); + pPlayer->SetAnimation( PLAYER_ATTACK1 ); + + pPlayer->m_iShotsFired++; + + --m_iBurstShotsRemaining; + if ( m_iBurstShotsRemaining > 0 ) + m_fNextBurstShot += kFamasBurstCycleTime; + else + m_fNextBurstShot = 0.0f; + + // update accuracy + m_fAccuracyPenalty += GetCSWpnData().m_fInaccuracyImpulseFire[Secondary_Mode]; +} + + +void CWeaponFamas::PrimaryAttack() +{ + CCSPlayer *pPlayer = GetPlayerOwner(); + if ( !pPlayer ) + return; + + // don't fire underwater + if (pPlayer->GetWaterLevel() == 3) + { + PlayEmptySound( ); + m_flNextPrimaryAttack = gpGlobals->curtime + 0.15; + return; + } + + pPlayer = GetPlayerOwner(); + if ( !pPlayer ) + return; + + float flCycleTime = GetCSWpnData().m_flCycleTime; + + // change a few things if we're in burst mode + if ( m_bBurstMode ) + { + flCycleTime = 0.55f; + m_iBurstShotsRemaining = 2; + m_fNextBurstShot = gpGlobals->curtime + kFamasBurstCycleTime; + } + + if ( !CSBaseGunFire( flCycleTime, m_weaponMode ) ) + return; + + if ( pPlayer->GetAbsVelocity().Length2D() > 5 ) + pPlayer->KickBack ( 1, 0.45, 0.275, 0.05, 4, 2.5, 7 ); + + else if ( !FBitSet( pPlayer->GetFlags(), FL_ONGROUND ) ) + pPlayer->KickBack ( 1.25, 0.45, 0.22, 0.18, 5.5, 4, 5 ); + + else if ( FBitSet( pPlayer->GetFlags(), FL_DUCKING ) ) + pPlayer->KickBack ( 0.575, 0.325, 0.2, 0.011, 3.25, 2, 8 ); + + else + pPlayer->KickBack ( 0.625, 0.375, 0.25, 0.0125, 3.5, 2.25, 8 ); +} + + |