Counter Strike : Global Offensive Source Code
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.

273 lines
5.4 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "weapon_csbase.h"
  8. #include "fx_cs_shared.h"
  9. #if defined( CLIENT_DLL )
  10. #define CWeaponM3 C_WeaponM3
  11. #include "c_cs_player.h"
  12. #else
  13. #include "cs_player.h"
  14. #include "te_shotgun_shot.h"
  15. #endif
  16. class CWeaponM3 : public CWeaponCSBase
  17. {
  18. public:
  19. DECLARE_CLASS( CWeaponM3, CWeaponCSBase );
  20. DECLARE_NETWORKCLASS();
  21. DECLARE_PREDICTABLE();
  22. CWeaponM3();
  23. virtual void PrimaryAttack();
  24. virtual bool Reload();
  25. virtual void WeaponIdle();
  26. virtual CSWeaponID GetCSWeaponID( void ) const { return WEAPON_M3; }
  27. virtual int GetShotgunReloadState( void ) { return m_reloadState; }
  28. private:
  29. CWeaponM3( const CWeaponM3 & );
  30. float m_flPumpTime;
  31. CNetworkVar( int, m_reloadState );
  32. };
  33. IMPLEMENT_NETWORKCLASS_ALIASED( WeaponM3, DT_WeaponM3 )
  34. BEGIN_NETWORK_TABLE( CWeaponM3, DT_WeaponM3 )
  35. #ifdef CLIENT_DLL
  36. RecvPropInt( RECVINFO( m_reloadState ) )
  37. #else
  38. SendPropInt( SENDINFO( m_reloadState ), 2, SPROP_UNSIGNED )
  39. #endif
  40. END_NETWORK_TABLE()
  41. #if defined(CLIENT_DLL)
  42. BEGIN_PREDICTION_DATA( CWeaponM3 )
  43. DEFINE_PRED_FIELD( m_reloadState, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
  44. END_PREDICTION_DATA()
  45. #endif
  46. LINK_ENTITY_TO_CLASS_ALIASED( weapon_m3, WeaponM3 );
  47. // PRECACHE_REGISTER( weapon_m3 );
  48. CWeaponM3::CWeaponM3()
  49. {
  50. m_flPumpTime = 0;
  51. m_reloadState = 0;
  52. }
  53. void CWeaponM3::PrimaryAttack()
  54. {
  55. CCSPlayer *pPlayer = GetPlayerOwner();
  56. if ( !pPlayer )
  57. return;
  58. const CCSWeaponInfo& weaponInfo = GetCSWpnData();
  59. float flCycleTime = GetCycleTime();
  60. // don't fire underwater
  61. if (pPlayer->GetWaterLevel() == WL_Eyes)
  62. {
  63. PlayEmptySound( );
  64. m_flNextPrimaryAttack = gpGlobals->curtime + 0.15;
  65. return;
  66. }
  67. // Out of ammo?
  68. if ( m_iClip1 <= 0 )
  69. {
  70. Reload();
  71. if ( m_iClip1 == 0 )
  72. {
  73. PlayEmptySound();
  74. m_flNextPrimaryAttack = gpGlobals->curtime + 0.2;
  75. }
  76. return;
  77. }
  78. SendWeaponAnim( ACT_VM_PRIMARYATTACK );
  79. pPlayer->DoMuzzleFlash();
  80. // player "shoot" animation
  81. pPlayer->SetAnimation( PLAYER_ATTACK1 );
  82. uint16 nItemDefIndex = 0;
  83. // Dispatch the FX right away with full accuracy.
  84. float flCurAttack = CalculateNextAttackTime( flCycleTime );
  85. FX_FireBullets(
  86. pPlayer->entindex(),
  87. nItemDefIndex,
  88. pPlayer->Weapon_ShootPosition(),
  89. pPlayer->GetFinalAimAngle(),
  90. GetCSWeaponID(),
  91. Primary_Mode,
  92. CBaseEntity::GetPredictionRandomSeed( SERVER_PLATTIME_RNG ) & 255, // wrap it for network traffic so it's the same between client and server
  93. GetInaccuracy(),
  94. GetSpread(),
  95. GetAccuracyFishtail(),
  96. flCurAttack,
  97. SINGLE,
  98. m_flRecoilIndex );
  99. // are we firing the last round in the clip?
  100. if ( m_iClip1 == 1 )
  101. {
  102. SetWeaponIdleTime( gpGlobals->curtime + 0.875f );
  103. }
  104. else
  105. {
  106. m_flPumpTime = gpGlobals->curtime + 0.5f;
  107. SetWeaponIdleTime( gpGlobals->curtime + 2.5f );
  108. }
  109. m_reloadState = 0;
  110. // update accuracy
  111. m_fAccuracyPenalty += weaponInfo.GetInaccuracyFire( GetEconItemView(), Primary_Mode );
  112. // table driven recoil
  113. Recoil( Primary_Mode );
  114. ++pPlayer->m_iShotsFired;
  115. m_flRecoilIndex += 1.0f;
  116. --m_iClip1;
  117. }
  118. bool CWeaponM3::Reload()
  119. {
  120. CCSPlayer *pPlayer = GetPlayerOwner();
  121. if ( !pPlayer )
  122. return false;
  123. if ( GetReserveAmmoCount( AMMO_POSITION_PRIMARY ) <= 0 || m_iClip1 == GetMaxClip1())
  124. return true;
  125. // don't reload until recoil is done
  126. if (m_flNextPrimaryAttack > gpGlobals->curtime)
  127. return true;
  128. // check to see if we're ready to reload
  129. if (m_reloadState == 0)
  130. {
  131. pPlayer->SetAnimation( PLAYER_RELOAD );
  132. SendWeaponAnim( ACT_SHOTGUN_RELOAD_START );
  133. m_reloadState = 1;
  134. pPlayer->m_flNextAttack = gpGlobals->curtime + 0.5;
  135. m_flNextPrimaryAttack = gpGlobals->curtime + 0.5;
  136. m_flNextSecondaryAttack = gpGlobals->curtime + 0.5;
  137. SetWeaponIdleTime( gpGlobals->curtime + 0.5 );
  138. #ifdef GAME_DLL
  139. pPlayer->DoAnimationEvent( PLAYERANIMEVENT_RELOAD_START );
  140. #endif
  141. return true;
  142. }
  143. else if (m_reloadState == 1)
  144. {
  145. if (m_flTimeWeaponIdle > gpGlobals->curtime)
  146. return true;
  147. // was waiting for gun to move to side
  148. m_reloadState = 2;
  149. SendWeaponAnim( ACT_VM_RELOAD );
  150. SetWeaponIdleTime( gpGlobals->curtime + 0.5 );
  151. #ifdef GAME_DLL
  152. if ( m_iClip1 == 7 )
  153. {
  154. pPlayer->DoAnimationEvent( PLAYERANIMEVENT_RELOAD_END );
  155. }
  156. else
  157. {
  158. pPlayer->DoAnimationEvent( PLAYERANIMEVENT_RELOAD_LOOP );
  159. }
  160. #endif
  161. }
  162. else
  163. {
  164. // Add them to the clip
  165. m_iClip1 += 1;
  166. #ifdef GAME_DLL
  167. SendActivityEvents();
  168. #endif
  169. CCSPlayer *pPlayer = GetPlayerOwner();
  170. if ( pPlayer )
  171. GiveReserveAmmo( AMMO_POSITION_PRIMARY, -1 );
  172. m_reloadState = 1;
  173. }
  174. return true;
  175. }
  176. void CWeaponM3::WeaponIdle()
  177. {
  178. CCSPlayer *pPlayer = GetPlayerOwner();
  179. if ( !pPlayer )
  180. return;
  181. if (m_flPumpTime && m_flPumpTime < gpGlobals->curtime)
  182. {
  183. // play pumping sound
  184. m_flPumpTime = 0;
  185. }
  186. if (m_flTimeWeaponIdle < gpGlobals->curtime)
  187. {
  188. if (m_iClip1 == 0 && m_reloadState == 0 && GetReserveAmmoCount( AMMO_POSITION_PRIMARY ))
  189. {
  190. Reload( );
  191. }
  192. else if (m_reloadState != 0)
  193. {
  194. if (m_iClip1 != 8 && GetReserveAmmoCount( AMMO_POSITION_PRIMARY ))
  195. {
  196. Reload( );
  197. }
  198. else
  199. {
  200. // reload debounce has timed out
  201. //MIKETODO: shotgun anims
  202. SendWeaponAnim( ACT_SHOTGUN_RELOAD_FINISH );
  203. // play cocking sound
  204. m_reloadState = 0;
  205. SetWeaponIdleTime( gpGlobals->curtime + 1.5 );
  206. }
  207. }
  208. else
  209. {
  210. SendWeaponAnim( ACT_VM_IDLE );
  211. }
  212. }
  213. }