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.

304 lines
6.2 KiB

  1. //========= Copyright 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 CWeaponXM1014 C_WeaponXM1014
  11. #include "c_cs_player.h"
  12. #else
  13. #include "cs_player.h"
  14. #include "te_shotgun_shot.h"
  15. #endif
  16. class CWeaponXM1014 : public CWeaponCSBase
  17. {
  18. public:
  19. DECLARE_CLASS( CWeaponXM1014, CWeaponCSBase );
  20. DECLARE_NETWORKCLASS();
  21. DECLARE_PREDICTABLE();
  22. CWeaponXM1014();
  23. virtual void Spawn();
  24. virtual void PrimaryAttack();
  25. virtual bool Reload();
  26. virtual void WeaponIdle();
  27. virtual float GetInaccuracy() const;
  28. virtual float GetSpread() const;
  29. virtual CSWeaponID GetWeaponID( void ) const { return WEAPON_XM1014; }
  30. private:
  31. CWeaponXM1014( const CWeaponXM1014 & );
  32. float m_flPumpTime;
  33. CNetworkVar( int, m_reloadState ); // special reload state for shotgun
  34. };
  35. IMPLEMENT_NETWORKCLASS_ALIASED( WeaponXM1014, DT_WeaponXM1014 )
  36. BEGIN_NETWORK_TABLE( CWeaponXM1014, DT_WeaponXM1014 )
  37. #ifdef 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( CWeaponXM1014 )
  45. DEFINE_PRED_FIELD( m_reloadState, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
  46. END_PREDICTION_DATA()
  47. #endif
  48. LINK_ENTITY_TO_CLASS( weapon_xm1014, CWeaponXM1014 );
  49. PRECACHE_WEAPON_REGISTER( weapon_xm1014 );
  50. CWeaponXM1014::CWeaponXM1014()
  51. {
  52. m_flPumpTime = 0;
  53. m_reloadState = 0;
  54. }
  55. void CWeaponXM1014::Spawn()
  56. {
  57. //m_iDefaultAmmo = M3_DEFAULT_GIVE;
  58. //FallInit();// get ready to fall
  59. BaseClass::Spawn();
  60. }
  61. float CWeaponXM1014::GetInaccuracy() const
  62. {
  63. if ( weapon_accuracy_model.GetInt() == 1 )
  64. return 0.0f;
  65. else
  66. return BaseClass::GetInaccuracy();
  67. }
  68. float CWeaponXM1014::GetSpread() const
  69. {
  70. if ( weapon_accuracy_model.GetInt() == 1 )
  71. return 0.0725f;
  72. return GetCSWpnData().m_fSpread[Primary_Mode];
  73. }
  74. void CWeaponXM1014::PrimaryAttack()
  75. {
  76. CCSPlayer *pPlayer = GetPlayerOwner();
  77. if ( !pPlayer )
  78. return;
  79. float flCycleTime = GetCSWpnData().m_flCycleTime;
  80. // don't fire underwater
  81. if (pPlayer->GetWaterLevel() == 3)
  82. {
  83. PlayEmptySound( );
  84. m_flNextPrimaryAttack = gpGlobals->curtime + 0.15;
  85. return;
  86. }
  87. if (m_iClip1 <= 0)
  88. {
  89. Reload();
  90. if (m_iClip1 == 0)
  91. {
  92. PlayEmptySound( );
  93. m_flNextPrimaryAttack = gpGlobals->curtime + 0.25;
  94. }
  95. return;
  96. }
  97. SendWeaponAnim( ACT_VM_PRIMARYATTACK );
  98. //pPlayer->m_iWeaponVolume = LOUD_GUN_VOLUME;
  99. //pPlayer->m_iWeaponFlash = BRIGHT_GUN_FLASH;
  100. m_iClip1--;
  101. pPlayer->DoMuzzleFlash();
  102. // player "shoot" animation
  103. pPlayer->SetAnimation( PLAYER_ATTACK1 );
  104. // Dispatch the FX right away with full accuracy.
  105. float flCurAttack = CalculateNextAttackTime( flCycleTime );
  106. FX_FireBullets(
  107. pPlayer->entindex(),
  108. pPlayer->Weapon_ShootPosition(),
  109. pPlayer->EyeAngles() + 2.0f * pPlayer->GetPunchAngle(),
  110. GetWeaponID(),
  111. Primary_Mode,
  112. CBaseEntity::GetPredictionRandomSeed() & 255, // wrap it for network traffic so it's the same between client and server
  113. GetInaccuracy(),
  114. GetSpread(), // flSpread
  115. flCurAttack );
  116. if (!m_iClip1 && pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) <= 0)
  117. {
  118. // HEV suit - indicate out of ammo condition
  119. pPlayer->SetSuitUpdate("!HEV_AMO0", false, 0);
  120. }
  121. if (m_iClip1 != 0)
  122. m_flPumpTime = gpGlobals->curtime + 0.5;
  123. if (m_iClip1 != 0)
  124. SetWeaponIdleTime( gpGlobals->curtime + 2.5 );
  125. else
  126. SetWeaponIdleTime( gpGlobals->curtime + 0.25 );
  127. m_reloadState = 0;
  128. // update accuracy
  129. m_fAccuracyPenalty += GetCSWpnData().m_fInaccuracyImpulseFire[Primary_Mode];
  130. // Update punch angles.
  131. QAngle angle = pPlayer->GetPunchAngle();
  132. if ( pPlayer->GetFlags() & FL_ONGROUND )
  133. {
  134. angle.x -= SharedRandomInt( "XM1014PunchAngleGround", 3, 5 );
  135. }
  136. else
  137. {
  138. angle.x -= SharedRandomInt( "XM1014PunchAngleAir", 7, 10 );
  139. }
  140. pPlayer->SetPunchAngle( angle );
  141. }
  142. bool CWeaponXM1014::Reload()
  143. {
  144. CCSPlayer *pPlayer = GetPlayerOwner();
  145. if ( !pPlayer )
  146. return false;
  147. if (pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 || m_iClip1 == GetMaxClip1())
  148. return true;
  149. // don't reload until recoil is done
  150. if (m_flNextPrimaryAttack > gpGlobals->curtime)
  151. return true;
  152. //MIKETODO: shotgun reloading (wait until we get content)
  153. // check to see if we're ready to reload
  154. if (m_reloadState == 0)
  155. {
  156. pPlayer->SetAnimation( PLAYER_RELOAD );
  157. SendWeaponAnim( ACT_SHOTGUN_RELOAD_START );
  158. m_reloadState = 1;
  159. pPlayer->m_flNextAttack = gpGlobals->curtime + 0.5;
  160. SetWeaponIdleTime( gpGlobals->curtime + 0.5 );
  161. m_flNextPrimaryAttack = gpGlobals->curtime + 0.5;
  162. m_flNextSecondaryAttack = gpGlobals->curtime + 0.5;
  163. #ifdef GAME_DLL
  164. pPlayer->DoAnimationEvent( PLAYERANIMEVENT_RELOAD_START );
  165. #endif
  166. return true;
  167. }
  168. else if (m_reloadState == 1)
  169. {
  170. if (m_flTimeWeaponIdle > gpGlobals->curtime)
  171. return true;
  172. // was waiting for gun to move to side
  173. m_reloadState = 2;
  174. SendWeaponAnim( ACT_VM_RELOAD );
  175. SetWeaponIdleTime( gpGlobals->curtime + 0.5 );
  176. #ifdef GAME_DLL
  177. if ( m_iClip1 == 6 )
  178. {
  179. pPlayer->DoAnimationEvent( PLAYERANIMEVENT_RELOAD_END );
  180. }
  181. else
  182. {
  183. pPlayer->DoAnimationEvent( PLAYERANIMEVENT_RELOAD_LOOP );
  184. }
  185. #endif
  186. }
  187. else
  188. {
  189. // Add them to the clip
  190. m_iClip1 += 1;
  191. #ifdef GAME_DLL
  192. SendReloadEvents();
  193. #endif
  194. CCSPlayer *pPlayer = GetPlayerOwner();
  195. if ( pPlayer )
  196. pPlayer->RemoveAmmo( 1, m_iPrimaryAmmoType );
  197. m_reloadState = 1;
  198. }
  199. return true;
  200. }
  201. void CWeaponXM1014::WeaponIdle()
  202. {
  203. CCSPlayer *pPlayer = GetPlayerOwner();
  204. if ( !pPlayer )
  205. return;
  206. if (m_flPumpTime && m_flPumpTime < gpGlobals->curtime)
  207. {
  208. // play pumping sound
  209. m_flPumpTime = 0;
  210. }
  211. if (m_flTimeWeaponIdle < gpGlobals->curtime)
  212. {
  213. if (m_iClip1 == 0 && m_reloadState == 0 && pPlayer->GetAmmoCount( m_iPrimaryAmmoType ))
  214. {
  215. Reload( );
  216. }
  217. else if (m_reloadState != 0)
  218. {
  219. if (m_iClip1 != 7 && pPlayer->GetAmmoCount( m_iPrimaryAmmoType ))
  220. {
  221. Reload( );
  222. }
  223. else
  224. {
  225. // reload debounce has timed out
  226. //MIKETODO: shotgun anims
  227. SendWeaponAnim( ACT_SHOTGUN_RELOAD_FINISH );
  228. // play cocking sound
  229. m_reloadState = 0;
  230. SetWeaponIdleTime( gpGlobals->curtime + 1.5 );
  231. }
  232. }
  233. else
  234. {
  235. SendWeaponAnim( ACT_VM_IDLE );
  236. }
  237. }
  238. }