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.

197 lines
5.8 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. //
  4. //=============================================================================
  5. #include "cbase.h"
  6. #include "tf_weapon_smg.h"
  7. static const float DAMAGE_TO_FILL_MINICRIT_METER = 100.0f;
  8. // Client specific.
  9. #ifdef CLIENT_DLL
  10. #include "c_tf_player.h"
  11. // Server specific.
  12. #else
  13. #include "tf_player.h"
  14. #endif
  15. //=============================================================================
  16. //
  17. // Weapon tables.
  18. //
  19. // ---------- Regular SMG -------------
  20. CREATE_SIMPLE_WEAPON_TABLE( TFSMG, tf_weapon_smg )
  21. // Server specific.
  22. #ifndef CLIENT_DLL
  23. BEGIN_DATADESC( CTFSMG )
  24. END_DATADESC()
  25. #endif
  26. // ---------- Charged SMG -------------
  27. IMPLEMENT_NETWORKCLASS_ALIASED( TFChargedSMG, DT_WeaponChargedSMG )
  28. BEGIN_NETWORK_TABLE( CTFChargedSMG, DT_WeaponChargedSMG )
  29. // Client specific.
  30. #ifdef CLIENT_DLL
  31. RecvPropFloat( RECVINFO( m_flMinicritCharge ) ),
  32. // Server specific.
  33. #else
  34. SendPropFloat( SENDINFO( m_flMinicritCharge ), 4, SPROP_NOSCALE, 0.0f, DAMAGE_TO_FILL_MINICRIT_METER ),
  35. #endif
  36. END_NETWORK_TABLE()
  37. // Server specific
  38. #ifndef CLIENT_DLL
  39. BEGIN_DATADESC( CTFChargedSMG )
  40. END_DATADESC()
  41. #endif
  42. // Client specific
  43. #ifdef CLIENT_DLL
  44. BEGIN_PREDICTION_DATA( CTFChargedSMG )
  45. DEFINE_FIELD( m_flMinicritCharge, FIELD_FLOAT )
  46. END_PREDICTION_DATA()
  47. #endif
  48. LINK_ENTITY_TO_CLASS( tf_weapon_charged_smg, CTFChargedSMG );
  49. PRECACHE_WEAPON_REGISTER( tf_weapon_charged_smg );
  50. //=============================================================================
  51. //
  52. // Weapon SMG functions.
  53. //-----------------------------------------------------------------------------
  54. // Purpose:
  55. //-----------------------------------------------------------------------------
  56. int CTFSMG::GetDamageType( void ) const
  57. {
  58. if ( CanHeadshot() )
  59. {
  60. int iDamageType = BaseClass::GetDamageType() | DMG_USE_HITLOCATIONS;
  61. return iDamageType;
  62. }
  63. return BaseClass::GetDamageType();
  64. }
  65. //-----------------------------------------------------------------------------
  66. // Purpose:
  67. //-----------------------------------------------------------------------------
  68. bool CTFSMG::CanFireCriticalShot( bool bIsHeadshot )
  69. {
  70. if ( !BaseClass::CanFireCriticalShot( bIsHeadshot ) )
  71. return false;
  72. CTFPlayer *pPlayer = GetTFPlayerOwner();
  73. if ( pPlayer && pPlayer->m_Shared.IsCritBoosted() )
  74. return true;
  75. if ( !bIsHeadshot )
  76. return !CanHeadshot();
  77. return true;
  78. }
  79. //-----------------------------------------------------------------------------
  80. // Purpose: Determine if secondary fire is available.
  81. //-----------------------------------------------------------------------------
  82. bool CTFChargedSMG::CanPerformSecondaryAttack() const
  83. {
  84. return ( m_flMinicritCharge >= DAMAGE_TO_FILL_MINICRIT_METER && BaseClass::CanPerformSecondaryAttack() );
  85. }
  86. //-----------------------------------------------------------------------------
  87. // Purpose: Determine whether to flash the HUD element showing the charge bar
  88. //-----------------------------------------------------------------------------
  89. bool CTFChargedSMG::ShouldFlashChargeBar()
  90. {
  91. return m_flMinicritCharge >= DAMAGE_TO_FILL_MINICRIT_METER;
  92. }
  93. //-----------------------------------------------------------------------------
  94. // Purpose: Get HUD charge bar progress amount
  95. //-----------------------------------------------------------------------------
  96. float CTFChargedSMG::GetProgress( void )
  97. {
  98. // Progress bar shows charge amount if we're charging up, otherwise drains over time if we're mini-crit boosted.
  99. CTFPlayer *pPlayer = ToTFPlayer( GetOwner() );
  100. if ( pPlayer && pPlayer->m_Shared.InCond( TF_COND_ENERGY_BUFF ) )
  101. {
  102. int flBuffDuration = 0;
  103. CALL_ATTRIB_HOOK_FLOAT( flBuffDuration, minicrit_boost_when_charged );
  104. if ( flBuffDuration > 0 )
  105. {
  106. float flElapsed = gpGlobals->curtime - m_flMinicritStartTime;
  107. float flRemainingPortion = Clamp( (flBuffDuration - flElapsed) / flBuffDuration, 0.0f, 1.0f );
  108. return flRemainingPortion;
  109. }
  110. else
  111. {
  112. return 0.0f;
  113. }
  114. }
  115. else
  116. {
  117. return m_flMinicritCharge / DAMAGE_TO_FILL_MINICRIT_METER;
  118. }
  119. }
  120. //-----------------------------------------------------------------------------
  121. // Purpose: Reset weapon state
  122. //-----------------------------------------------------------------------------
  123. void CTFChargedSMG::WeaponReset()
  124. {
  125. BaseClass::WeaponReset();
  126. m_flMinicritCharge = 0.0f;
  127. m_flMinicritStartTime = 0.0f;
  128. }
  129. //-----------------------------------------------------------------------------
  130. // Purpose: Perform secondary attack
  131. //-----------------------------------------------------------------------------
  132. void CTFChargedSMG::SecondaryAttack()
  133. {
  134. BaseClass::SecondaryAttack();
  135. m_flMinicritCharge = 0.0f;
  136. CTFPlayer *pPlayer = ToTFPlayer( GetOwner() );
  137. if ( pPlayer )
  138. {
  139. float flBuffDuration = 0;
  140. CALL_ATTRIB_HOOK_FLOAT( flBuffDuration, minicrit_boost_when_charged );
  141. if ( flBuffDuration > 0 )
  142. {
  143. pPlayer->m_Shared.AddCond( TF_COND_ENERGY_BUFF, flBuffDuration );
  144. m_flMinicritStartTime = gpGlobals->curtime;
  145. }
  146. }
  147. }
  148. #ifdef GAME_DLL
  149. //-----------------------------------------------------------------------------
  150. // Purpose: Update state when we score a hit with this weapon
  151. //-----------------------------------------------------------------------------
  152. void CTFChargedSMG::ApplyOnHitAttributes( CBaseEntity *pVictimBaseEntity, CTFPlayer *pAttacker, const CTakeDamageInfo &info )
  153. {
  154. BaseClass::ApplyOnHitAttributes( pVictimBaseEntity, pAttacker, info );
  155. if ( pAttacker )
  156. {
  157. CTFPlayer *pPlayer = ToTFPlayer( GetOwner() );
  158. if ( pPlayer && !pPlayer->m_Shared.InCond( TF_COND_ENERGY_BUFF ) )
  159. {
  160. float damage = info.GetDamage();
  161. float flChargeRate = 0.0f;
  162. CALL_ATTRIB_HOOK_FLOAT( flChargeRate, minicrit_boost_charge_rate );
  163. m_flMinicritCharge += damage * flChargeRate;
  164. if ( m_flMinicritCharge > DAMAGE_TO_FILL_MINICRIT_METER )
  165. {
  166. m_flMinicritCharge = DAMAGE_TO_FILL_MINICRIT_METER;
  167. }
  168. }
  169. }
  170. }
  171. #endif