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.

218 lines
4.7 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "weapon_csbasegun.h"
  8. #include "fx_cs_shared.h"
  9. #ifdef CLIENT_DLL
  10. #include "c_cs_player.h"
  11. #else
  12. #include "cs_player.h"
  13. #endif
  14. IMPLEMENT_NETWORKCLASS_ALIASED( WeaponCSBaseGun, DT_WeaponCSBaseGun )
  15. BEGIN_NETWORK_TABLE( CWeaponCSBaseGun, DT_WeaponCSBaseGun )
  16. END_NETWORK_TABLE()
  17. BEGIN_PREDICTION_DATA( CWeaponCSBaseGun )
  18. END_PREDICTION_DATA()
  19. LINK_ENTITY_TO_CLASS( weapon_csbase_gun, CWeaponCSBaseGun );
  20. CWeaponCSBaseGun::CWeaponCSBaseGun()
  21. {
  22. }
  23. void CWeaponCSBaseGun::Spawn()
  24. {
  25. m_flAccuracy = 0.2;
  26. m_bDelayFire = false;
  27. m_zoomFullyActiveTime = -1.0f;
  28. BaseClass::Spawn();
  29. }
  30. bool CWeaponCSBaseGun::Deploy()
  31. {
  32. CCSPlayer *pPlayer = GetPlayerOwner();
  33. if ( !pPlayer )
  34. return false;
  35. m_flAccuracy = 0.2;
  36. pPlayer->m_iShotsFired = 0;
  37. m_bDelayFire = false;
  38. m_zoomFullyActiveTime = -1.0f;
  39. return BaseClass::Deploy();
  40. }
  41. void CWeaponCSBaseGun::ItemPostFrame()
  42. {
  43. CCSPlayer *pPlayer = GetPlayerOwner();
  44. if ( !pPlayer )
  45. return;
  46. //GOOSEMAN : Return zoom level back to previous zoom level before we fired a shot. This is used only for the AWP.
  47. // And Scout.
  48. if ( (m_flNextPrimaryAttack <= gpGlobals->curtime) && (pPlayer->m_bResumeZoom == TRUE) )
  49. {
  50. pPlayer->m_bResumeZoom = false;
  51. if ( m_iClip1 != 0 || ( GetWeaponFlags() & ITEM_FLAG_NOAUTORELOAD ) )
  52. {
  53. m_weaponMode = Secondary_Mode;
  54. pPlayer->SetFOV( pPlayer, pPlayer->m_iLastZoom, 0.05f );
  55. m_zoomFullyActiveTime = gpGlobals->curtime + 0.05f;// Make sure we think that we are zooming on the server so we don't get instant acc bonus
  56. }
  57. }
  58. BaseClass::ItemPostFrame();
  59. }
  60. void CWeaponCSBaseGun::PrimaryAttack()
  61. {
  62. // Derived classes should implement this and call CSBaseGunFire.
  63. Assert( false );
  64. }
  65. bool CWeaponCSBaseGun::CSBaseGunFire( float flCycleTime, CSWeaponMode weaponMode )
  66. {
  67. CCSPlayer *pPlayer = GetPlayerOwner();
  68. if ( !pPlayer )
  69. return false;
  70. const CCSWeaponInfo &pCSInfo = GetCSWpnData();
  71. m_bDelayFire = true;
  72. if ( m_iClip1 > 0 )
  73. {
  74. pPlayer->m_iShotsFired++;
  75. // These modifications feed back into flSpread eventually.
  76. if ( pCSInfo.m_flAccuracyDivisor != -1 )
  77. {
  78. int iShotsFired = pPlayer->m_iShotsFired;
  79. if ( pCSInfo.m_bAccuracyQuadratic )
  80. iShotsFired = iShotsFired * iShotsFired;
  81. else
  82. iShotsFired = iShotsFired * iShotsFired * iShotsFired;
  83. m_flAccuracy = ( iShotsFired / pCSInfo.m_flAccuracyDivisor ) + pCSInfo.m_flAccuracyOffset;
  84. if ( m_flAccuracy > pCSInfo.m_flMaxInaccuracy )
  85. m_flAccuracy = pCSInfo.m_flMaxInaccuracy;
  86. }
  87. }
  88. else
  89. {
  90. m_flAccuracy = 0;
  91. if ( m_bFireOnEmpty )
  92. {
  93. PlayEmptySound();
  94. // NOTE[pmf]: we don't want to actually play the dry fire animations, as most seem to depict the weapon actually firing.
  95. // SendWeaponAnim( ACT_VM_DRYFIRE );
  96. m_bFireOnEmpty = false;
  97. m_flNextPrimaryAttack = gpGlobals->curtime + 0.1f;
  98. }
  99. return false;
  100. }
  101. float flCurAttack = CalculateNextAttackTime( flCycleTime );
  102. SendWeaponAnim( ACT_VM_PRIMARYATTACK );
  103. m_iClip1--;
  104. // player "shoot" animation
  105. pPlayer->SetAnimation( PLAYER_ATTACK1 );
  106. FX_FireBullets(
  107. pPlayer->entindex(),
  108. pPlayer->Weapon_ShootPosition(),
  109. pPlayer->EyeAngles() + 2.0f * pPlayer->GetPunchAngle(),
  110. GetWeaponID(),
  111. weaponMode,
  112. CBaseEntity::GetPredictionRandomSeed() & 255,
  113. GetInaccuracy(),
  114. GetSpread(),
  115. flCurAttack );
  116. DoFireEffects();
  117. SetWeaponIdleTime( gpGlobals->curtime + GetCSWpnData().m_flTimeToIdleAfterFire );
  118. // update accuracy
  119. m_fAccuracyPenalty += GetCSWpnData().m_fInaccuracyImpulseFire[weaponMode];
  120. return true;
  121. }
  122. void CWeaponCSBaseGun::DoFireEffects()
  123. {
  124. CCSPlayer *pPlayer = GetPlayerOwner();
  125. if ( pPlayer )
  126. pPlayer->DoMuzzleFlash();
  127. }
  128. bool CWeaponCSBaseGun::Reload()
  129. {
  130. CCSPlayer *pPlayer = GetPlayerOwner();
  131. if ( !pPlayer )
  132. return false;
  133. if (pPlayer->GetAmmoCount( GetPrimaryAmmoType() ) <= 0)
  134. return false;
  135. pPlayer->SetFOV( pPlayer, pPlayer->GetDefaultFOV(), 0.0f );
  136. int iResult = DefaultReload( GetMaxClip1(), GetMaxClip2(), ACT_VM_RELOAD );
  137. if ( !iResult )
  138. return false;
  139. pPlayer->SetAnimation( PLAYER_RELOAD );
  140. if ((iResult) && (pPlayer->GetFOV() != pPlayer->GetDefaultFOV()))
  141. {
  142. pPlayer->SetFOV( pPlayer, pPlayer->GetDefaultFOV() );
  143. }
  144. m_flAccuracy = 0.2;
  145. pPlayer->m_iShotsFired = 0;
  146. m_bDelayFire = false;
  147. pPlayer->SetShieldDrawnState( false );
  148. return true;
  149. }
  150. void CWeaponCSBaseGun::WeaponIdle()
  151. {
  152. if (m_flTimeWeaponIdle > gpGlobals->curtime)
  153. return;
  154. // only idle if the slid isn't back
  155. if ( m_iClip1 != 0 )
  156. {
  157. SetWeaponIdleTime( gpGlobals->curtime + GetCSWpnData().m_flIdleInterval );
  158. SendWeaponAnim( ACT_VM_IDLE );
  159. }
  160. }