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.

339 lines
7.6 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Hornetgun
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "npcevent.h"
  9. #include "hl1mp_basecombatweapon_shared.h"
  10. //#include "basecombatcharacter.h"
  11. //#include "AI_BaseNPC.h"
  12. #include "gamerules.h"
  13. #include "in_buttons.h"
  14. #ifdef CLIENT_DLL
  15. #include "hl1/c_hl1mp_player.h"
  16. #else
  17. #include "hl1mp_player.h"
  18. #include "soundent.h"
  19. #include "game.h"
  20. #endif
  21. #include "vstdlib/random.h"
  22. #include "engine/IEngineSound.h"
  23. #if !defined(CLIENT_DLL)
  24. #include "hl1_npc_hornet.h"
  25. #endif
  26. //-----------------------------------------------------------------------------
  27. // CWeaponHgun
  28. //-----------------------------------------------------------------------------
  29. #ifdef CLIENT_DLL
  30. #define CWeaponHgun C_WeaponHgun
  31. #endif
  32. class CWeaponHgun : public CBaseHL1MPCombatWeapon
  33. {
  34. DECLARE_CLASS( CWeaponHgun, CBaseHL1MPCombatWeapon );
  35. public:
  36. DECLARE_NETWORKCLASS();
  37. DECLARE_PREDICTABLE();
  38. CWeaponHgun( void );
  39. void Precache( void );
  40. void PrimaryAttack( void );
  41. void SecondaryAttack( void );
  42. void WeaponIdle( void );
  43. bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL );
  44. bool Reload( void );
  45. virtual void ItemPostFrame( void );
  46. // DECLARE_SERVERCLASS();
  47. DECLARE_DATADESC();
  48. private:
  49. // float m_flRechargeTime;
  50. // int m_iFirePhase;
  51. CNetworkVar( float, m_flRechargeTime );
  52. CNetworkVar( int, m_iFirePhase );
  53. };
  54. IMPLEMENT_NETWORKCLASS_ALIASED( WeaponHgun, DT_WeaponHgun );
  55. BEGIN_NETWORK_TABLE( CWeaponHgun, DT_WeaponHgun )
  56. #ifdef CLIENT_DLL
  57. RecvPropFloat( RECVINFO( m_flRechargeTime ) ),
  58. RecvPropInt( RECVINFO( m_iFirePhase ) ),
  59. #else
  60. SendPropFloat( SENDINFO( m_flRechargeTime ) ),
  61. SendPropInt( SENDINFO( m_iFirePhase ) ),
  62. #endif
  63. END_NETWORK_TABLE()
  64. BEGIN_PREDICTION_DATA( CWeaponHgun )
  65. #ifdef CLIENT_DLL
  66. DEFINE_PRED_FIELD( m_flRechargeTime, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
  67. DEFINE_PRED_FIELD( m_iFirePhase, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
  68. #endif
  69. END_PREDICTION_DATA()
  70. LINK_ENTITY_TO_CLASS( weapon_hornetgun, CWeaponHgun );
  71. PRECACHE_WEAPON_REGISTER( weapon_hornetgun );
  72. //IMPLEMENT_SERVERCLASS_ST( CWeaponHgun, DT_WeaponHgun )
  73. //END_SEND_TABLE()
  74. BEGIN_DATADESC( CWeaponHgun )
  75. DEFINE_FIELD( m_flRechargeTime, FIELD_TIME ),
  76. DEFINE_FIELD( m_iFirePhase, FIELD_INTEGER ),
  77. END_DATADESC()
  78. //-----------------------------------------------------------------------------
  79. // Purpose: Constructor
  80. //-----------------------------------------------------------------------------
  81. CWeaponHgun::CWeaponHgun( void )
  82. {
  83. m_bReloadsSingly = false;
  84. m_bFiresUnderwater = true;
  85. m_flRechargeTime = 0.0;
  86. m_iFirePhase = 0;
  87. }
  88. //-----------------------------------------------------------------------------
  89. // Purpose:
  90. //-----------------------------------------------------------------------------
  91. void CWeaponHgun::Precache( void )
  92. {
  93. #ifndef CLIENT_DLL
  94. UTIL_PrecacheOther( "hornet" );
  95. #endif
  96. BaseClass::Precache();
  97. }
  98. //-----------------------------------------------------------------------------
  99. // Purpose:
  100. //-----------------------------------------------------------------------------
  101. void CWeaponHgun::PrimaryAttack( void )
  102. {
  103. CHL1_Player *pPlayer = ToHL1Player( GetOwner() );
  104. if ( !pPlayer )
  105. {
  106. return;
  107. }
  108. if ( pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 )
  109. {
  110. return;
  111. }
  112. WeaponSound( SINGLE );
  113. #if !defined(CLIENT_DLL)
  114. CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), 200, 0.2 );
  115. #endif
  116. pPlayer->DoMuzzleFlash();
  117. SendWeaponAnim( ACT_VM_PRIMARYATTACK );
  118. pPlayer->SetAnimation( PLAYER_ATTACK1 );
  119. Vector vForward, vRight, vUp;
  120. QAngle vecAngles;
  121. pPlayer->EyeVectors( &vForward, &vRight, &vUp );
  122. VectorAngles( vForward, vecAngles );
  123. #if !defined(CLIENT_DLL)
  124. CBaseEntity *pHornet = CBaseEntity::Create( "hornet", pPlayer->Weapon_ShootPosition() + vForward * 16 + vRight * 8 + vUp * -12, vecAngles, pPlayer );
  125. pHornet->SetAbsVelocity( vForward * 300 );
  126. #endif
  127. m_flRechargeTime = gpGlobals->curtime + 0.5;
  128. pPlayer->RemoveAmmo( 1, m_iPrimaryAmmoType );
  129. pPlayer->ViewPunch( QAngle( -2, 0, 0 ) );
  130. m_flNextPrimaryAttack = m_flNextPrimaryAttack + 0.25;
  131. if (m_flNextPrimaryAttack < gpGlobals->curtime )
  132. {
  133. m_flNextPrimaryAttack = gpGlobals->curtime + 0.25;
  134. }
  135. SetWeaponIdleTime( random->RandomFloat( 10, 15 ) );
  136. }
  137. //-----------------------------------------------------------------------------
  138. // Purpose:
  139. //-----------------------------------------------------------------------------
  140. void CWeaponHgun::SecondaryAttack( void )
  141. {
  142. CHL1_Player *pPlayer = ToHL1Player( GetOwner() );
  143. if ( !pPlayer )
  144. {
  145. return;
  146. }
  147. if ( pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 )
  148. {
  149. return;
  150. }
  151. WeaponSound( SINGLE );
  152. #if !defined(CLIENT_DLL)
  153. CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), 200, 0.2 );
  154. #endif
  155. pPlayer->DoMuzzleFlash();
  156. SendWeaponAnim( ACT_VM_PRIMARYATTACK );
  157. pPlayer->SetAnimation( PLAYER_ATTACK1 );
  158. CBaseEntity *pHornet;
  159. Vector vecSrc;
  160. Vector vForward, vRight, vUp;
  161. QAngle vecAngles;
  162. pPlayer->EyeVectors( &vForward, &vRight, &vUp );
  163. VectorAngles( vForward, vecAngles );
  164. vecSrc = pPlayer->Weapon_ShootPosition() + vForward * 16 + vRight * 8 + vUp * -12;
  165. m_iFirePhase++;
  166. switch ( m_iFirePhase )
  167. {
  168. case 1:
  169. vecSrc = vecSrc + vUp * 8;
  170. break;
  171. case 2:
  172. vecSrc = vecSrc + vUp * 8;
  173. vecSrc = vecSrc + vRight * 8;
  174. break;
  175. case 3:
  176. vecSrc = vecSrc + vRight * 8;
  177. break;
  178. case 4:
  179. vecSrc = vecSrc + vUp * -8;
  180. vecSrc = vecSrc + vRight * 8;
  181. break;
  182. case 5:
  183. vecSrc = vecSrc + vUp * -8;
  184. break;
  185. case 6:
  186. vecSrc = vecSrc + vUp * -8;
  187. vecSrc = vecSrc + vRight * -8;
  188. break;
  189. case 7:
  190. vecSrc = vecSrc + vRight * -8;
  191. break;
  192. case 8:
  193. vecSrc = vecSrc + vUp * 8;
  194. vecSrc = vecSrc + vRight * -8;
  195. m_iFirePhase = 0;
  196. break;
  197. }
  198. #ifdef CLIENT_DLL
  199. pHornet = NULL;
  200. #else
  201. pHornet = CBaseEntity::Create( "hornet", vecSrc, vecAngles, pPlayer );
  202. pHornet->SetAbsVelocity( vForward * 1200 );
  203. pHornet->SetThink( &CNPC_Hornet::StartDart );
  204. #endif
  205. m_flRechargeTime = gpGlobals->curtime + 0.5;
  206. pPlayer->ViewPunch( QAngle( -2, 0, 0 ) );
  207. pPlayer->RemoveAmmo( 1, m_iPrimaryAmmoType );
  208. m_flNextPrimaryAttack = m_flNextSecondaryAttack = gpGlobals->curtime + 0.1;
  209. SetWeaponIdleTime( random->RandomFloat( 10, 15 ) );
  210. }
  211. void CWeaponHgun::WeaponIdle( void )
  212. {
  213. if ( !HasWeaponIdleTimeElapsed() )
  214. return;
  215. int iAnim;
  216. float flRand = random->RandomFloat( 0, 1 );
  217. if ( flRand <= 0.75 )
  218. {
  219. iAnim = ACT_VM_IDLE;
  220. }
  221. else
  222. {
  223. iAnim = ACT_VM_FIDGET;
  224. }
  225. SendWeaponAnim( iAnim );
  226. }
  227. bool CWeaponHgun::Holster( CBaseCombatWeapon *pSwitchingTo )
  228. {
  229. bool bRet;
  230. bRet = BaseClass::Holster( pSwitchingTo );
  231. if ( bRet )
  232. {
  233. CHL1_Player *pPlayer = ToHL1Player( GetOwner() );
  234. if ( pPlayer )
  235. {
  236. #if !defined(CLIENT_DLL)
  237. //!!!HACKHACK - can't select hornetgun if it's empty! no way to get ammo for it, either.
  238. int iCount = pPlayer->GetAmmoCount( m_iPrimaryAmmoType );
  239. if ( iCount <= 0 )
  240. {
  241. pPlayer->GiveAmmo( iCount+1, m_iPrimaryAmmoType, true );
  242. }
  243. #endif
  244. }
  245. }
  246. return bRet;
  247. }
  248. bool CWeaponHgun::Reload( void )
  249. {
  250. if ( m_flRechargeTime >= gpGlobals->curtime )
  251. {
  252. return true;
  253. }
  254. CHL1_Player *pPlayer = ToHL1Player( GetOwner() );
  255. if ( !pPlayer )
  256. {
  257. return true;
  258. }
  259. #ifdef CLIENT_DLL
  260. #else
  261. if ( !g_pGameRules->CanHaveAmmo( pPlayer, m_iPrimaryAmmoType ) )
  262. return true;
  263. while ( ( m_flRechargeTime < gpGlobals->curtime ) && g_pGameRules->CanHaveAmmo( pPlayer, m_iPrimaryAmmoType ) )
  264. {
  265. pPlayer->GiveAmmo( 1, m_iPrimaryAmmoType, true );
  266. m_flRechargeTime += 0.5;
  267. }
  268. #endif
  269. return true;
  270. }
  271. void CWeaponHgun::ItemPostFrame( void )
  272. {
  273. Reload();
  274. BaseClass::ItemPostFrame();
  275. }