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.

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