Team Fortress 2 Source Code as on 22/4/2020
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.

213 lines
5.1 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "weapon_csbasegun.h"
  8. #if defined( CLIENT_DLL )
  9. #define CWeaponG3SG1 C_WeaponG3SG1
  10. #include "c_cs_player.h"
  11. #else
  12. #include "cs_player.h"
  13. #include "KeyValues.h"
  14. #endif
  15. class CWeaponG3SG1 : public CWeaponCSBaseGun
  16. {
  17. public:
  18. DECLARE_CLASS( CWeaponG3SG1, CWeaponCSBaseGun );
  19. DECLARE_NETWORKCLASS();
  20. DECLARE_PREDICTABLE();
  21. CWeaponG3SG1();
  22. virtual void Spawn();
  23. virtual void SecondaryAttack();
  24. virtual void PrimaryAttack();
  25. virtual bool Reload();
  26. virtual bool Deploy();
  27. virtual float GetInaccuracy() const;
  28. virtual float GetMaxSpeed();
  29. virtual CSWeaponID GetWeaponID( void ) const { return WEAPON_G3SG1; }
  30. private:
  31. CWeaponG3SG1( const CWeaponG3SG1 & );
  32. float m_flLastFire;
  33. };
  34. IMPLEMENT_NETWORKCLASS_ALIASED( WeaponG3SG1, DT_WeaponG3SG1 )
  35. BEGIN_NETWORK_TABLE( CWeaponG3SG1, DT_WeaponG3SG1 )
  36. END_NETWORK_TABLE()
  37. #if defined CLIENT_DLL
  38. BEGIN_PREDICTION_DATA( CWeaponG3SG1 )
  39. DEFINE_FIELD( m_flLastFire, FIELD_FLOAT ),
  40. END_PREDICTION_DATA()
  41. #endif
  42. LINK_ENTITY_TO_CLASS( weapon_g3sg1, CWeaponG3SG1 );
  43. PRECACHE_WEAPON_REGISTER( weapon_g3sg1 );
  44. CWeaponG3SG1::CWeaponG3SG1()
  45. {
  46. m_flLastFire = gpGlobals->curtime;
  47. }
  48. void CWeaponG3SG1::Spawn()
  49. {
  50. BaseClass::Spawn();
  51. m_flAccuracy = 0.98;
  52. }
  53. void CWeaponG3SG1::SecondaryAttack()
  54. {
  55. const float kZoomTime = 0.10f;
  56. CCSPlayer *pPlayer = GetPlayerOwner();
  57. if ( !pPlayer )
  58. return;
  59. if ( pPlayer->GetFOV() == pPlayer->GetDefaultFOV() )
  60. {
  61. pPlayer->SetFOV( pPlayer, 40, kZoomTime );
  62. m_weaponMode = Secondary_Mode;
  63. m_fAccuracyPenalty += GetCSWpnData().m_fInaccuracyAltSwitch;
  64. }
  65. else if (pPlayer->GetFOV() == 40)
  66. {
  67. pPlayer->SetFOV( pPlayer, 15, kZoomTime );
  68. m_weaponMode = Secondary_Mode;
  69. }
  70. else if (pPlayer->GetFOV() == 15)
  71. {
  72. pPlayer->SetFOV( pPlayer, pPlayer->GetDefaultFOV(), kZoomTime );
  73. m_weaponMode = Primary_Mode;
  74. }
  75. #ifndef CLIENT_DLL
  76. // If this isn't guarded, the sound will be emitted twice, once by the server and once by the client.
  77. // Let the server play it since if only the client plays it, it's liable to get played twice cause of
  78. // a prediction error. joy.
  79. //=============================================================================
  80. // HPE_BEGIN:
  81. // [tj] Playing this from the player so that we don't try to play the sound outside the level.
  82. //=============================================================================
  83. if ( GetPlayerOwner() )
  84. {
  85. GetPlayerOwner()->EmitSound( "Default.Zoom" ); // zoom sound
  86. }
  87. //=============================================================================
  88. // HPE_END
  89. //=============================================================================
  90. // let the bots hear the rifle zoom
  91. IGameEvent * event = gameeventmanager->CreateEvent( "weapon_zoom" );
  92. if( event )
  93. {
  94. event->SetInt( "userid", pPlayer->GetUserID() );
  95. gameeventmanager->FireEvent( event );
  96. }
  97. #endif
  98. m_flNextSecondaryAttack = gpGlobals->curtime + 0.3f;
  99. m_zoomFullyActiveTime = gpGlobals->curtime + 0.3; // The worst zoom time from above.
  100. }
  101. float CWeaponG3SG1::GetInaccuracy() const
  102. {
  103. if ( weapon_accuracy_model.GetInt() == 1 )
  104. {
  105. CCSPlayer *pPlayer = GetPlayerOwner();
  106. if ( !pPlayer )
  107. return 0.0f;
  108. float fSpread = 0.0f;
  109. if ( !FBitSet( pPlayer->GetFlags(), FL_ONGROUND ) )
  110. fSpread = 0.45f * (1.0f - m_flAccuracy);
  111. else if (pPlayer->GetAbsVelocity().Length2D() > 5)
  112. fSpread = 0.15f;
  113. else if ( FBitSet( pPlayer->GetFlags(), FL_DUCKING ) )
  114. fSpread = 0.035f * (1.0f - m_flAccuracy);
  115. else
  116. fSpread = 0.055f * (1.0f - m_flAccuracy);
  117. // If we are not zoomed in, or we have very recently zoomed and are still transitioning, the bullet diverts more.
  118. if (pPlayer->GetFOV() == pPlayer->GetDefaultFOV() || (gpGlobals->curtime < m_zoomFullyActiveTime))
  119. fSpread += 0.025;
  120. return fSpread;
  121. }
  122. else
  123. return BaseClass::GetInaccuracy();
  124. }
  125. void CWeaponG3SG1::PrimaryAttack()
  126. {
  127. CCSPlayer *pPlayer = GetPlayerOwner();
  128. if ( !pPlayer )
  129. return;
  130. // Mark the time of this shot and determine the accuracy modifier based on the last shot fired...
  131. m_flAccuracy = 0.55 + (0.3) * (gpGlobals->curtime - m_flLastFire);
  132. if (m_flAccuracy > 0.98)
  133. m_flAccuracy = 0.98;
  134. m_flLastFire = gpGlobals->curtime;
  135. if ( !CSBaseGunFire( GetCSWpnData().m_flCycleTime, m_weaponMode ) )
  136. return;
  137. // Adjust the punch angle.
  138. QAngle angle = pPlayer->GetPunchAngle();
  139. angle.x -= SharedRandomFloat("G3SG1PunchAngleX", 0.75, 1.75 ) + ( angle.x / 4 );
  140. angle.y += SharedRandomFloat("G3SG1PunchAngleY", -0.75, 0.75 );
  141. pPlayer->SetPunchAngle( angle );
  142. }
  143. bool CWeaponG3SG1::Reload()
  144. {
  145. bool ret = BaseClass::Reload();
  146. m_flAccuracy = 0.98;
  147. m_weaponMode = Primary_Mode;
  148. return ret;
  149. }
  150. bool CWeaponG3SG1::Deploy()
  151. {
  152. bool ret = BaseClass::Deploy();
  153. m_flAccuracy = 0.98;
  154. m_weaponMode = Primary_Mode;
  155. return ret;
  156. }
  157. float CWeaponG3SG1::GetMaxSpeed()
  158. {
  159. CCSPlayer *pPlayer = GetPlayerOwner();
  160. if ( pPlayer && pPlayer->GetFOV() == pPlayer->GetDefaultFOV() )
  161. return BaseClass::GetMaxSpeed();
  162. else
  163. return 150; // zoomed in
  164. }