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.

719 lines
17 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Gauss
  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 "takedamageinfo.h"
  13. #ifdef CLIENT_DLL
  14. #include "hl1/hl1_c_player.h"
  15. #else
  16. #include "hl1_player.h"
  17. #endif
  18. #include "gamerules.h"
  19. #include "in_buttons.h"
  20. #ifdef CLIENT_DLL
  21. #else
  22. #include "soundent.h"
  23. #include "game.h"
  24. #endif
  25. #include "vstdlib/random.h"
  26. #include "engine/IEngineSound.h"
  27. #include "soundenvelope.h"
  28. //#include "hl1_player.h"
  29. #include "shake.h"
  30. #include "effect_dispatch_data.h"
  31. #ifdef CLIENT_DLL
  32. #include "c_te_effect_dispatch.h"
  33. #else
  34. #include "te_effect_dispatch.h"
  35. #endif
  36. #include "SoundEmitterSystem/isoundemittersystembase.h"
  37. #define GAUSS_GLOW_SPRITE "sprites/hotglow.vmt"
  38. #define GAUSS_BEAM_SPRITE "sprites/smoke.vmt"
  39. extern ConVar sk_plr_dmg_gauss;
  40. #ifdef CLIENT_DLL
  41. #define CWeaponGauss C_WeaponGauss
  42. #endif
  43. //-----------------------------------------------------------------------------
  44. // CWeaponGauss
  45. //-----------------------------------------------------------------------------
  46. class CWeaponGauss : public CBaseHL1MPCombatWeapon
  47. {
  48. DECLARE_CLASS( CWeaponGauss, CBaseHL1MPCombatWeapon );
  49. public:
  50. DECLARE_NETWORKCLASS();
  51. DECLARE_PREDICTABLE();
  52. CWeaponGauss( void );
  53. void Precache( void );
  54. void PrimaryAttack( void );
  55. void SecondaryAttack( void );
  56. void WeaponIdle( void );
  57. void AddViewKick( void );
  58. bool Deploy( void );
  59. bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL );
  60. // DECLARE_SERVERCLASS();
  61. DECLARE_DATADESC();
  62. private:
  63. void StopSpinSound( void );
  64. float GetFullChargeTime( void );
  65. void StartFire( void );
  66. void Fire( Vector vecOrigSrc, Vector vecDir, float flDamage );
  67. private:
  68. // int m_nAttackState;
  69. // bool m_bPrimaryFire;
  70. CNetworkVar( int, m_nAttackState);
  71. CNetworkVar( bool, m_bPrimaryFire);
  72. CSoundPatch *m_sndCharge;
  73. };
  74. IMPLEMENT_NETWORKCLASS_ALIASED( WeaponGauss, DT_WeaponGauss );
  75. BEGIN_NETWORK_TABLE( CWeaponGauss, DT_WeaponGauss )
  76. #ifdef CLIENT_DLL
  77. RecvPropInt( RECVINFO( m_nAttackState ) ),
  78. RecvPropBool( RECVINFO( m_bPrimaryFire ) ),
  79. #else
  80. SendPropInt( SENDINFO( m_nAttackState ) ),
  81. SendPropBool( SENDINFO( m_bPrimaryFire ) ),
  82. #endif
  83. END_NETWORK_TABLE()
  84. BEGIN_PREDICTION_DATA( CWeaponGauss )
  85. #ifdef CLIENT_DLL
  86. DEFINE_PRED_FIELD( m_nAttackState, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
  87. DEFINE_PRED_FIELD( m_bPrimaryFire, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),
  88. #endif
  89. END_PREDICTION_DATA()
  90. LINK_ENTITY_TO_CLASS( weapon_gauss, CWeaponGauss );
  91. PRECACHE_WEAPON_REGISTER( weapon_gauss );
  92. //IMPLEMENT_SERVERCLASS_ST( CWeaponGauss, DT_WeaponGauss )
  93. //END_SEND_TABLE()
  94. BEGIN_DATADESC( CWeaponGauss )
  95. DEFINE_FIELD( m_nAttackState, FIELD_INTEGER ),
  96. DEFINE_FIELD( m_bPrimaryFire, FIELD_BOOLEAN ),
  97. DEFINE_SOUNDPATCH( m_sndCharge ),
  98. END_DATADESC()
  99. //-----------------------------------------------------------------------------
  100. // Purpose: Constructor
  101. //-----------------------------------------------------------------------------
  102. CWeaponGauss::CWeaponGauss( void )
  103. {
  104. m_bReloadsSingly = false;
  105. m_bFiresUnderwater = false;
  106. m_bPrimaryFire = false;
  107. m_nAttackState = 0;
  108. m_sndCharge = NULL;
  109. }
  110. //-----------------------------------------------------------------------------
  111. // Purpose:
  112. //-----------------------------------------------------------------------------
  113. void CWeaponGauss::Precache( void )
  114. {
  115. PrecacheModel( GAUSS_GLOW_SPRITE );
  116. PrecacheModel( GAUSS_BEAM_SPRITE );
  117. PrecacheScriptSound( "Weapon_Gauss.Zap1" );
  118. PrecacheScriptSound( "Weapon_Gauss.Zap2" );
  119. PrecacheScriptSound( "Weapon_Gauss.Fire" );
  120. PrecacheScriptSound( "Weapon_Gauss.StaticDischarge" );
  121. PrecacheScriptSound( "Weapon_Gauss.Spin" );
  122. BaseClass::Precache();
  123. }
  124. float CWeaponGauss::GetFullChargeTime( void )
  125. {
  126. if ( g_pGameRules->IsMultiplayer() )
  127. {
  128. return 1.5;
  129. }
  130. else
  131. {
  132. return 4;
  133. }
  134. }
  135. //-----------------------------------------------------------------------------
  136. // Purpose:
  137. //-----------------------------------------------------------------------------
  138. void CWeaponGauss::PrimaryAttack( void )
  139. {
  140. CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
  141. if ( !pPlayer )
  142. {
  143. return;
  144. }
  145. if ( pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) < 2 )
  146. {
  147. WeaponSound( EMPTY );
  148. pPlayer->SetNextAttack( gpGlobals->curtime + 0.5 );
  149. return;
  150. }
  151. //FIXME pPlayer->m_iWeaponVolume = GAUSS_PRIMARY_FIRE_VOLUME;
  152. m_bPrimaryFire = true;
  153. pPlayer->RemoveAmmo( 2, m_iPrimaryAmmoType );
  154. StartFire();
  155. m_nAttackState = 0;
  156. SetWeaponIdleTime( gpGlobals->curtime + 1.0 );
  157. pPlayer->SetNextAttack( gpGlobals->curtime + 0.2 );
  158. }
  159. //-----------------------------------------------------------------------------
  160. // Purpose:
  161. //-----------------------------------------------------------------------------
  162. void CWeaponGauss::SecondaryAttack( void )
  163. {
  164. CHL1_Player *pPlayer = ToHL1Player( GetOwner() );
  165. if ( !pPlayer )
  166. {
  167. return;
  168. }
  169. // don't fire underwater
  170. if ( pPlayer->GetWaterLevel() == 3 )
  171. {
  172. if ( m_nAttackState != 0 )
  173. {
  174. EmitSound( "Weapon_Gauss.Zap1" );
  175. SendWeaponAnim( ACT_VM_IDLE );
  176. m_nAttackState = 0;
  177. }
  178. else
  179. {
  180. WeaponSound( EMPTY );
  181. }
  182. m_flNextSecondaryAttack = m_flNextPrimaryAttack = gpGlobals->curtime + 0.5;
  183. return;
  184. }
  185. if ( m_nAttackState == 0 )
  186. {
  187. if ( pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 )
  188. {
  189. WeaponSound( EMPTY );
  190. pPlayer->SetNextAttack( gpGlobals->curtime + 0.5 );
  191. return;
  192. }
  193. m_bPrimaryFire = false;
  194. pPlayer->RemoveAmmo( 1, m_iPrimaryAmmoType ); // take one ammo just to start the spin
  195. pPlayer->m_flNextAmmoBurn = gpGlobals->curtime;
  196. // spin up
  197. //FIXME pPlayer->m_iWeaponVolume = GAUSS_PRIMARY_CHARGE_VOLUME;
  198. SendWeaponAnim( ACT_GAUSS_SPINUP );
  199. m_nAttackState = 1;
  200. SetWeaponIdleTime( gpGlobals->curtime + 0.5 );
  201. pPlayer->m_flStartCharge = gpGlobals->curtime;
  202. pPlayer->m_flAmmoStartCharge = gpGlobals->curtime + GetFullChargeTime();
  203. //Start looping sound
  204. if ( m_sndCharge == NULL )
  205. {
  206. CPASAttenuationFilter filter( this );
  207. m_sndCharge = (CSoundEnvelopeController::GetController()).SoundCreate( filter, entindex(), CHAN_WEAPON, "Weapon_Gauss.Spin", ATTN_NORM );
  208. }
  209. if ( m_sndCharge != NULL )
  210. {
  211. (CSoundEnvelopeController::GetController()).Play( m_sndCharge, 1.0f, 110 );
  212. }
  213. }
  214. else if (m_nAttackState == 1)
  215. {
  216. if ( HasWeaponIdleTimeElapsed() )
  217. {
  218. SendWeaponAnim( ACT_GAUSS_SPINCYCLE );
  219. m_nAttackState = 2;
  220. }
  221. }
  222. else
  223. {
  224. // during the charging process, eat one bit of ammo every once in a while
  225. if ( gpGlobals->curtime >= pPlayer->m_flNextAmmoBurn && pPlayer->m_flNextAmmoBurn != 1000 )
  226. {
  227. pPlayer->RemoveAmmo( 1, m_iPrimaryAmmoType );
  228. if ( g_pGameRules->IsMultiplayer() )
  229. {
  230. pPlayer->m_flNextAmmoBurn = gpGlobals->curtime + 0.1;
  231. }
  232. else
  233. {
  234. pPlayer->m_flNextAmmoBurn = gpGlobals->curtime + 0.3;
  235. }
  236. }
  237. if ( pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 )
  238. {
  239. // out of ammo! force the gun to fire
  240. StartFire();
  241. m_nAttackState = 0;
  242. SetWeaponIdleTime( gpGlobals->curtime + 1.0 );
  243. pPlayer->SetNextAttack( gpGlobals->curtime + 1 );
  244. return;
  245. }
  246. if ( gpGlobals->curtime >= pPlayer->m_flAmmoStartCharge )
  247. {
  248. // don't eat any more ammo after gun is fully charged.
  249. pPlayer->m_flNextAmmoBurn = 1000;
  250. }
  251. int pitch = ( gpGlobals->curtime - pPlayer->m_flStartCharge ) * ( 150 / GetFullChargeTime() ) + 100;
  252. if ( pitch > 250 )
  253. pitch = 250;
  254. // ALERT( at_console, "%d %d %d\n", m_nAttackState, m_iSoundState, pitch );
  255. // if ( m_iSoundState == 0 )
  256. // ALERT( at_console, "sound state %d\n", m_iSoundState );
  257. if ( m_sndCharge != NULL )
  258. {
  259. (CSoundEnvelopeController::GetController()).SoundChangePitch( m_sndCharge, pitch, 0 );
  260. }
  261. //FIXME m_pPlayer->m_iWeaponVolume = GAUSS_PRIMARY_CHARGE_VOLUME;
  262. // m_flTimeWeaponIdle = gpGlobals->curtime + 0.1;
  263. if ( pPlayer->m_flStartCharge < gpGlobals->curtime - 10 )
  264. {
  265. // Player charged up too long. Zap him.
  266. EmitSound( "Weapon_Gauss.Zap1" );
  267. EmitSound( "Weapon_Gauss.Zap2" );
  268. m_nAttackState = 0;
  269. SetWeaponIdleTime( gpGlobals->curtime + 1.0 );
  270. pPlayer->SetNextAttack( gpGlobals->curtime + 1.0 );
  271. #if !defined(CLIENT_DLL )
  272. // Add DMG_CRUSH because we don't want any physics force
  273. pPlayer->TakeDamage( CTakeDamageInfo( this, this, 50, DMG_SHOCK | DMG_CRUSH ) );
  274. color32 gaussDamage = {255,128,0,128};
  275. UTIL_ScreenFade( pPlayer, gaussDamage, 2, 0.5, FFADE_IN );
  276. #endif
  277. SendWeaponAnim( ACT_VM_IDLE );
  278. StopSpinSound();
  279. // Player may have been killed and this weapon dropped, don't execute any more code after this!
  280. return;
  281. }
  282. }
  283. }
  284. //=========================================================
  285. // StartFire- since all of this code has to run and then
  286. // call Fire(), it was easier at this point to rip it out
  287. // of weaponidle() and make its own function then to try to
  288. // merge this into Fire(), which has some identical variable names
  289. //=========================================================
  290. void CWeaponGauss::StartFire( void )
  291. {
  292. float flDamage;
  293. CHL1_Player *pPlayer = ToHL1Player( GetOwner() );
  294. if ( !pPlayer )
  295. {
  296. return;
  297. }
  298. Vector vecAiming = pPlayer->GetAutoaimVector( 0 );
  299. Vector vecSrc = pPlayer->Weapon_ShootPosition( );
  300. if ( gpGlobals->curtime - pPlayer->m_flStartCharge > GetFullChargeTime() )
  301. {
  302. flDamage = 200;
  303. }
  304. else
  305. {
  306. flDamage = 200 * (( gpGlobals->curtime - pPlayer->m_flStartCharge) / GetFullChargeTime() );
  307. }
  308. if ( m_bPrimaryFire )
  309. {
  310. flDamage = sk_plr_dmg_gauss.GetFloat() * g_pGameRules->GetDamageMultiplier();
  311. }
  312. //ALERT ( at_console, "Time:%f Damage:%f\n", gpGlobals->curtime - m_pPlayer->m_flStartCharge, flDamage );
  313. Vector vecNewVel = pPlayer->GetAbsVelocity();
  314. float flZVel = vecNewVel.z;
  315. if ( !m_bPrimaryFire )
  316. {
  317. vecNewVel = vecNewVel - vecAiming * flDamage * 5;
  318. pPlayer->SetAbsVelocity( vecNewVel );
  319. }
  320. if ( !g_pGameRules->IsMultiplayer() )
  321. {
  322. // in deathmatch, gauss can pop you up into the air. Not in single play.
  323. vecNewVel.z = flZVel;
  324. pPlayer->SetAbsVelocity( vecNewVel );
  325. }
  326. // player "shoot" animation
  327. pPlayer->SetAnimation( PLAYER_ATTACK1 );
  328. // time until aftershock 'static discharge' sound
  329. pPlayer->m_flPlayAftershock = gpGlobals->curtime + random->RandomFloat( 0.3, 0.8 );
  330. Fire( vecSrc, vecAiming, flDamage );
  331. }
  332. void CWeaponGauss::Fire( Vector vecOrigSrc, Vector vecDir, float flDamage )
  333. {
  334. CBaseEntity *pIgnore;
  335. Vector vecSrc = vecOrigSrc;
  336. Vector vecDest = vecSrc + vecDir * MAX_TRACE_LENGTH;
  337. bool fFirstBeam = true;
  338. bool fHasPunched = false;
  339. float flMaxFrac = 1.0;
  340. int nMaxHits = 10;
  341. CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
  342. if ( !pPlayer )
  343. {
  344. return;
  345. }
  346. //FIXME pPlayer->m_iWeaponVolume = GAUSS_PRIMARY_FIRE_VOLUME;
  347. StopSpinSound();
  348. pIgnore = pPlayer;
  349. // ALERT( at_console, "%f %f\n", tr.flFraction, flMaxFrac );
  350. while ( flDamage > 10 && nMaxHits > 0 )
  351. {
  352. trace_t tr;
  353. nMaxHits--;
  354. // ALERT( at_console, "." );
  355. UTIL_TraceLine( vecSrc, vecDest, MASK_SHOT, pIgnore, COLLISION_GROUP_NONE, &tr );
  356. if ( tr.allsolid )
  357. break;
  358. CBaseEntity *pEntity = tr.m_pEnt;
  359. if (pEntity == NULL)
  360. break;
  361. CBroadcastRecipientFilter filter;
  362. CEffectData data6;
  363. if ( fFirstBeam )
  364. {
  365. pPlayer->DoMuzzleFlash();
  366. fFirstBeam = false;
  367. data6.m_vOrigin = tr.endpos;
  368. // data6.m_nEntIndex = pPlayer->GetViewModel()->entindex();
  369. #ifdef CLIENT_DLL
  370. data6.m_hEntity = pPlayer;
  371. #else
  372. data6.m_nEntIndex = pPlayer->entindex();
  373. #endif
  374. data6.m_fFlags = m_bPrimaryFire;
  375. te->DispatchEffect( filter, 0.0, data6.m_vOrigin, "HL1GaussBeam", data6 );
  376. }
  377. else
  378. {
  379. data6.m_vOrigin = tr.endpos;
  380. data6.m_vStart = vecSrc;
  381. data6.m_fFlags = m_bPrimaryFire;
  382. te->DispatchEffect( filter, 0.0, data6.m_vOrigin, "HL1GaussBeamReflect", data6 );
  383. }
  384. bool fShouldDamageEntity = ( pEntity->m_takedamage != DAMAGE_NO );
  385. if ( fShouldDamageEntity )
  386. {
  387. ClearMultiDamage();
  388. CTakeDamageInfo info( this, pPlayer, flDamage, DMG_ENERGYBEAM );
  389. CalculateMeleeDamageForce( &info, vecDir, tr.endpos );
  390. pEntity->DispatchTraceAttack( info, vecDir, &tr );
  391. ApplyMultiDamage();
  392. }
  393. if ( pEntity->IsBSPModel() && !fShouldDamageEntity )
  394. {
  395. float n;
  396. pIgnore = NULL;
  397. n = -DotProduct( tr.plane.normal, vecDir );
  398. if ( n < 0.5 ) // 60 degrees
  399. {
  400. // ALERT( at_console, "reflect %f\n", n );
  401. // reflect
  402. Vector vecReflect;
  403. vecReflect = 2.0 * tr.plane.normal * n + vecDir;
  404. flMaxFrac = flMaxFrac - tr.fraction;
  405. vecDir = vecReflect;
  406. vecSrc = tr.endpos;// + vecDir * 8;
  407. vecDest = vecSrc + vecDir * MAX_TRACE_LENGTH;
  408. #if !defined(CLIENT_DLL)
  409. // explode a bit
  410. RadiusDamage( CTakeDamageInfo( this, pPlayer, flDamage * n, DMG_BLAST ), tr.endpos, flDamage * n * 2.5, CLASS_NONE, NULL );
  411. #endif
  412. CEffectData data1;
  413. data1.m_vOrigin = tr.endpos;
  414. data1.m_vNormal = tr.plane.normal;
  415. data1.m_flMagnitude = flDamage * n;
  416. DispatchEffect( "HL1GaussReflect", data1 );
  417. // lose energy
  418. if (n == 0)
  419. n = 0.1;
  420. flDamage = flDamage * (1 - n);
  421. }
  422. else
  423. {
  424. // tunnel
  425. UTIL_ImpactTrace( &tr, DMG_ENERGYBEAM );
  426. CEffectData data4;
  427. data4.m_vOrigin = tr.endpos;
  428. data4.m_flMagnitude = flDamage;
  429. DispatchEffect( "HL1GaussWallImpact1", data4 );
  430. // limit it to one hole punch
  431. if ( fHasPunched )
  432. break;
  433. fHasPunched = true;
  434. // try punching through wall if secondary attack (primary is incapable of breaking through)
  435. if ( !m_bPrimaryFire )
  436. {
  437. trace_t punch_tr;
  438. UTIL_TraceLine( tr.endpos + vecDir * 8, vecDest, MASK_SHOT, pIgnore, COLLISION_GROUP_NONE, &punch_tr);
  439. if ( !punch_tr.allsolid )
  440. {
  441. trace_t exit_tr;
  442. // trace backwards to find exit point
  443. UTIL_TraceLine( punch_tr.endpos, tr.endpos, MASK_SHOT, pIgnore, COLLISION_GROUP_NONE, &exit_tr);
  444. float n = (exit_tr.endpos - tr.endpos).Length( );
  445. if ( n < flDamage )
  446. {
  447. if (n == 0)
  448. n = 1;
  449. flDamage -= n;
  450. CEffectData data2;
  451. data2.m_vOrigin = tr.endpos;
  452. data2.m_vNormal = vecDir;
  453. DispatchEffect( "HL1GaussWallPunchEnter", data2 );
  454. UTIL_ImpactTrace( &exit_tr, DMG_ENERGYBEAM );
  455. CEffectData data3;
  456. data3.m_vOrigin = exit_tr.endpos;
  457. data3.m_vNormal = vecDir;
  458. data3.m_flMagnitude = flDamage;
  459. DispatchEffect( "HL1GaussWallPunchExit", data3 );
  460. // ALERT( at_console, "punch %f\n", n );
  461. // exit blast damage
  462. float flDamageRadius;
  463. if ( g_pGameRules->IsMultiplayer() )
  464. {
  465. flDamageRadius = flDamage * 1.75; // Old code == 2.5
  466. }
  467. else
  468. {
  469. flDamageRadius = flDamage * 2.5;
  470. }
  471. #if !defined( CLIENT_DLL)
  472. RadiusDamage( CTakeDamageInfo( this, pPlayer, flDamage, DMG_BLAST ), exit_tr.endpos + vecDir * 8, flDamageRadius, CLASS_NONE, NULL );
  473. CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), 1024, 3.0 );
  474. #endif
  475. vecSrc = exit_tr.endpos + vecDir;
  476. }
  477. }
  478. else
  479. {
  480. //ALERT( at_console, "blocked %f\n", n );
  481. flDamage = 0;
  482. }
  483. }
  484. else
  485. {
  486. //ALERT( at_console, "blocked solid\n" );
  487. if ( m_bPrimaryFire )
  488. {
  489. // slug doesn't punch through ever with primary
  490. // fire, so leave a little glowy bit and make some balls
  491. CEffectData data5;
  492. data5.m_vOrigin = tr.endpos;
  493. data5.m_vNormal = tr.plane.normal;
  494. DispatchEffect( "HL1GaussWallImpact2", data5 );
  495. #if !defined( CLIENT_DLL)
  496. CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), 600, 0.5 );
  497. #endif
  498. }
  499. flDamage = 0;
  500. }
  501. }
  502. }
  503. else
  504. {
  505. vecSrc = tr.endpos + vecDir;
  506. pIgnore = pEntity;
  507. }
  508. }
  509. pPlayer->ViewPunch( QAngle( -2, 0, 0 ) );
  510. SendWeaponAnim( ACT_VM_PRIMARYATTACK );
  511. CPASAttenuationFilter filter( this );
  512. CSoundParameters params;
  513. if ( GetParametersForSound( "Weapon_Gauss.Fire", params, NULL ) )
  514. {
  515. EmitSound_t ep( params );
  516. ep.m_flVolume = 0.5 + flDamage * (1.0 / 400.0);
  517. EmitSound( filter, entindex(), ep );
  518. }
  519. }
  520. void CWeaponGauss::WeaponIdle( void )
  521. {
  522. CHL1_Player *pPlayer = ToHL1Player( GetOwner() );
  523. if ( !pPlayer )
  524. {
  525. return;
  526. }
  527. // play aftershock static discharge
  528. if ( pPlayer->m_flPlayAftershock && pPlayer->m_flPlayAftershock < gpGlobals->curtime )
  529. {
  530. EmitSound( "Weapon_Gauss.StaticDischarge" );
  531. pPlayer->m_flPlayAftershock = 0.0;
  532. }
  533. if ( !HasWeaponIdleTimeElapsed() )
  534. return;
  535. if ( m_nAttackState != 0 )
  536. {
  537. StartFire();
  538. m_nAttackState = 0;
  539. SetWeaponIdleTime( gpGlobals->curtime + 2.0 );
  540. }
  541. else
  542. {
  543. float flRand = random->RandomFloat( 0, 1 );
  544. if ( flRand <= 0.75 )
  545. {
  546. SendWeaponAnim( ACT_VM_IDLE );
  547. SetWeaponIdleTime( gpGlobals->curtime + random->RandomFloat( 10, 15 ) );
  548. }
  549. else
  550. {
  551. SendWeaponAnim( ACT_VM_FIDGET );
  552. SetWeaponIdleTime( gpGlobals->curtime + 3 );
  553. }
  554. }
  555. }
  556. /*
  557. ==================================================
  558. AddViewKick
  559. ==================================================
  560. */
  561. void CWeaponGauss::AddViewKick( void )
  562. {
  563. }
  564. bool CWeaponGauss::Deploy( void )
  565. {
  566. if ( DefaultDeploy( (char*)GetViewModel(), (char*)GetWorldModel(), ACT_VM_DRAW, (char*)GetAnimPrefix() ) )
  567. {
  568. CHL1_Player *pPlayer = ToHL1Player( GetOwner() );
  569. if ( pPlayer )
  570. {
  571. pPlayer->m_flPlayAftershock = 0.0;
  572. }
  573. return true;
  574. }
  575. else
  576. {
  577. return false;
  578. }
  579. }
  580. bool CWeaponGauss::Holster( CBaseCombatWeapon *pSwitchingTo )
  581. {
  582. StopSpinSound();
  583. m_nAttackState = 0;
  584. return BaseClass::Holster(pSwitchingTo);
  585. }
  586. void CWeaponGauss::StopSpinSound( void )
  587. {
  588. if ( m_sndCharge != NULL )
  589. {
  590. (CSoundEnvelopeController::GetController()).SoundDestroy( m_sndCharge );
  591. m_sndCharge = NULL;
  592. }
  593. }