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.

246 lines
5.0 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "weapon_sdkbase.h"
  8. #include "sdk_fx_shared.h"
  9. #if defined( CLIENT_DLL )
  10. #define CWeaponShotgun C_WeaponShotgun
  11. #include "c_sdk_player.h"
  12. #else
  13. #include "sdk_player.h"
  14. #include "te_firebullets.h"
  15. #endif
  16. class CWeaponShotgun : public CWeaponSDKBase
  17. {
  18. public:
  19. DECLARE_CLASS( CWeaponShotgun, CWeaponSDKBase );
  20. DECLARE_NETWORKCLASS();
  21. DECLARE_PREDICTABLE();
  22. CWeaponShotgun();
  23. virtual void PrimaryAttack();
  24. virtual bool Reload();
  25. virtual void WeaponIdle();
  26. virtual SDKWeaponID GetWeaponID( void ) const { return WEAPON_SHOTGUN; }
  27. private:
  28. CWeaponShotgun( const CWeaponShotgun & );
  29. float m_flPumpTime;
  30. CNetworkVar( int, m_fInSpecialReload );
  31. };
  32. IMPLEMENT_NETWORKCLASS_ALIASED( WeaponShotgun, DT_WeaponShotgun )
  33. BEGIN_NETWORK_TABLE( CWeaponShotgun, DT_WeaponShotgun )
  34. #ifdef CLIENT_DLL
  35. RecvPropInt( RECVINFO( m_fInSpecialReload ) )
  36. #else
  37. SendPropInt( SENDINFO( m_fInSpecialReload ), 2, SPROP_UNSIGNED )
  38. #endif
  39. END_NETWORK_TABLE()
  40. BEGIN_PREDICTION_DATA( CWeaponShotgun )
  41. END_PREDICTION_DATA()
  42. LINK_ENTITY_TO_CLASS( weapon_shotgun, CWeaponShotgun );
  43. PRECACHE_WEAPON_REGISTER( weapon_shotgun );
  44. CWeaponShotgun::CWeaponShotgun()
  45. {
  46. m_flPumpTime = 0;
  47. }
  48. void CWeaponShotgun::PrimaryAttack()
  49. {
  50. CSDKPlayer *pPlayer = GetPlayerOwner();
  51. if ( !pPlayer )
  52. return;
  53. // don't fire underwater
  54. if (pPlayer->GetWaterLevel() == 3)
  55. {
  56. PlayEmptySound( );
  57. m_flNextPrimaryAttack = gpGlobals->curtime + 0.15;
  58. return;
  59. }
  60. // Out of ammo?
  61. if ( m_iClip1 <= 0 )
  62. {
  63. Reload();
  64. if ( m_iClip1 == 0 )
  65. {
  66. PlayEmptySound();
  67. m_flNextPrimaryAttack = gpGlobals->curtime + 0.2;
  68. }
  69. return;
  70. }
  71. SendWeaponAnim( ACT_VM_PRIMARYATTACK );
  72. m_iClip1--;
  73. pPlayer->DoMuzzleFlash();
  74. // player "shoot" animation
  75. pPlayer->SetAnimation( PLAYER_ATTACK1 );
  76. // Dispatch the FX right away with full accuracy.
  77. FX_FireBullets(
  78. pPlayer->entindex(),
  79. pPlayer->Weapon_ShootPosition(),
  80. pPlayer->EyeAngles() + 2.0f * pPlayer->GetPunchAngle(),
  81. GetWeaponID(),
  82. Primary_Mode,
  83. CBaseEntity::GetPredictionRandomSeed() & 255, // wrap it for network traffic so it's the same between client and server
  84. 0.0675 );
  85. if (!m_iClip1 && pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) <= 0)
  86. {
  87. // HEV suit - indicate out of ammo condition
  88. pPlayer->SetSuitUpdate("!HEV_AMO0", false, 0);
  89. }
  90. if (m_iClip1 != 0)
  91. m_flPumpTime = gpGlobals->curtime + 0.5;
  92. m_flNextPrimaryAttack = gpGlobals->curtime + 0.875;
  93. m_flNextSecondaryAttack = gpGlobals->curtime + 0.875;
  94. if (m_iClip1 != 0)
  95. SetWeaponIdleTime( gpGlobals->curtime + 2.5 );
  96. else
  97. SetWeaponIdleTime( gpGlobals->curtime + 0.875 );
  98. m_fInSpecialReload = 0;
  99. // Update punch angles.
  100. QAngle angle = pPlayer->GetPunchAngle();
  101. if ( pPlayer->GetFlags() & FL_ONGROUND )
  102. {
  103. angle.x -= SharedRandomInt( "ShotgunPunchAngleGround", 4, 6 );
  104. }
  105. else
  106. {
  107. angle.x -= SharedRandomInt( "ShotgunPunchAngleAir", 8, 11 );
  108. }
  109. pPlayer->SetPunchAngle( angle );
  110. }
  111. bool CWeaponShotgun::Reload()
  112. {
  113. CSDKPlayer *pPlayer = GetPlayerOwner();
  114. if (pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 || m_iClip1 == GetMaxClip1())
  115. return true;
  116. // don't reload until recoil is done
  117. if (m_flNextPrimaryAttack > gpGlobals->curtime)
  118. return true;
  119. // check to see if we're ready to reload
  120. if (m_fInSpecialReload == 0)
  121. {
  122. pPlayer->SetAnimation( PLAYER_RELOAD );
  123. SendWeaponAnim( ACT_SHOTGUN_RELOAD_START );
  124. m_fInSpecialReload = 1;
  125. pPlayer->m_flNextAttack = gpGlobals->curtime + 0.5;
  126. m_flNextPrimaryAttack = gpGlobals->curtime + 0.5;
  127. m_flNextSecondaryAttack = gpGlobals->curtime + 0.5;
  128. SetWeaponIdleTime( gpGlobals->curtime + 0.5 );
  129. return true;
  130. }
  131. else if (m_fInSpecialReload == 1)
  132. {
  133. if (m_flTimeWeaponIdle > gpGlobals->curtime)
  134. return true;
  135. // was waiting for gun to move to side
  136. m_fInSpecialReload = 2;
  137. SendWeaponAnim( ACT_VM_RELOAD );
  138. SetWeaponIdleTime( gpGlobals->curtime + 0.45 );
  139. }
  140. else
  141. {
  142. // Add them to the clip
  143. m_iClip1 += 1;
  144. #ifdef GAME_DLL
  145. SendReloadEvents();
  146. #endif
  147. CSDKPlayer *pPlayer = GetPlayerOwner();
  148. if ( pPlayer )
  149. pPlayer->RemoveAmmo( 1, m_iPrimaryAmmoType );
  150. m_fInSpecialReload = 1;
  151. }
  152. return true;
  153. }
  154. void CWeaponShotgun::WeaponIdle()
  155. {
  156. CSDKPlayer *pPlayer = GetPlayerOwner();
  157. if (m_flPumpTime && m_flPumpTime < gpGlobals->curtime)
  158. {
  159. // play pumping sound
  160. m_flPumpTime = 0;
  161. }
  162. if (m_flTimeWeaponIdle < gpGlobals->curtime)
  163. {
  164. if (m_iClip1 == 0 && m_fInSpecialReload == 0 && pPlayer->GetAmmoCount( m_iPrimaryAmmoType ))
  165. {
  166. Reload( );
  167. }
  168. else if (m_fInSpecialReload != 0)
  169. {
  170. if (m_iClip1 != 8 && pPlayer->GetAmmoCount( m_iPrimaryAmmoType ))
  171. {
  172. Reload( );
  173. }
  174. else
  175. {
  176. // reload debounce has timed out
  177. //MIKETODO: shotgun anims
  178. SendWeaponAnim( ACT_SHOTGUN_RELOAD_FINISH );
  179. // play cocking sound
  180. m_fInSpecialReload = 0;
  181. SetWeaponIdleTime( gpGlobals->curtime + 1.5 );
  182. }
  183. }
  184. else
  185. {
  186. SendWeaponAnim( ACT_VM_IDLE );
  187. }
  188. }
  189. }