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.

259 lines
7.5 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. //
  4. //=============================================================================
  5. #include "cbase.h"
  6. #include "tf_weapon_pistol.h"
  7. #include "tf_fx_shared.h"
  8. #include "in_buttons.h"
  9. #include "tf_gamerules.h"
  10. // Client specific.
  11. #ifdef CLIENT_DLL
  12. #include "c_tf_player.h"
  13. #include "c_tf_gamestats.h"
  14. // Server specific.
  15. #else
  16. #include "tf_player.h"
  17. #include "tf_gamestats.h"
  18. #include "ilagcompensationmanager.h"
  19. #endif
  20. //=============================================================================
  21. //
  22. // Weapon Pistol tables.
  23. //
  24. IMPLEMENT_NETWORKCLASS_ALIASED( TFPistol, DT_WeaponPistol )
  25. BEGIN_NETWORK_TABLE( CTFPistol, DT_WeaponPistol )
  26. END_NETWORK_TABLE()
  27. BEGIN_PREDICTION_DATA( CTFPistol )
  28. END_PREDICTION_DATA()
  29. LINK_ENTITY_TO_CLASS( tf_weapon_pistol, CTFPistol );
  30. PRECACHE_WEAPON_REGISTER( tf_weapon_pistol );
  31. // Server specific.
  32. #ifndef CLIENT_DLL
  33. BEGIN_DATADESC( CTFPistol )
  34. END_DATADESC()
  35. #endif
  36. //============================
  37. IMPLEMENT_NETWORKCLASS_ALIASED( TFPistol_Scout, DT_WeaponPistol_Scout )
  38. BEGIN_NETWORK_TABLE( CTFPistol_Scout, DT_WeaponPistol_Scout )
  39. END_NETWORK_TABLE()
  40. BEGIN_PREDICTION_DATA( CTFPistol_Scout )
  41. END_PREDICTION_DATA()
  42. LINK_ENTITY_TO_CLASS( tf_weapon_pistol_scout, CTFPistol_Scout );
  43. PRECACHE_WEAPON_REGISTER( tf_weapon_pistol_scout );
  44. //============================
  45. IMPLEMENT_NETWORKCLASS_ALIASED( TFPistol_ScoutPrimary, DT_WeaponPistol_ScoutPrimary )
  46. BEGIN_NETWORK_TABLE( CTFPistol_ScoutPrimary, DT_WeaponPistol_ScoutPrimary )
  47. END_NETWORK_TABLE()
  48. BEGIN_PREDICTION_DATA( CTFPistol_ScoutPrimary )
  49. END_PREDICTION_DATA()
  50. LINK_ENTITY_TO_CLASS( tf_weapon_handgun_scout_primary, CTFPistol_ScoutPrimary );
  51. PRECACHE_WEAPON_REGISTER( tf_weapon_handgun_scout_primary );
  52. //-----------------------------------------------------------------------------
  53. // Purpose:
  54. //-----------------------------------------------------------------------------
  55. CTFPistol_ScoutPrimary::CTFPistol_ScoutPrimary()
  56. {
  57. m_flPushTime = -1.f;
  58. }
  59. //-----------------------------------------------------------------------------
  60. // Purpose:
  61. //-----------------------------------------------------------------------------
  62. void CTFPistol_ScoutPrimary::PlayWeaponShootSound( void )
  63. {
  64. BaseClass::PlayWeaponShootSound();
  65. if ( TFGameRules()->GameModeUsesUpgrades() )
  66. {
  67. PlayUpgradedShootSound( "Weapon_Upgrade.DamageBonus" );
  68. }
  69. }
  70. //-----------------------------------------------------------------------------
  71. // Purpose:
  72. //-----------------------------------------------------------------------------
  73. void CTFPistol_ScoutPrimary::SecondaryAttack( void )
  74. {
  75. CTFPlayer *pOwner = ToTFPlayer( GetPlayerOwner() );
  76. if ( !pOwner )
  77. return;
  78. if ( !CanAttack() )
  79. return;
  80. if ( m_flNextSecondaryAttack > gpGlobals->curtime )
  81. return;
  82. pOwner->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_SECONDARY );
  83. SendWeaponAnim( ACT_SECONDARY_VM_ALTATTACK );
  84. m_flNextPrimaryAttack = gpGlobals->curtime + 0.6f;
  85. m_flNextSecondaryAttack = gpGlobals->curtime + 1.5f;
  86. m_flPushTime = gpGlobals->curtime + 0.2f; // Anim delay
  87. EmitSound( "Weapon_Hands.Push" );
  88. }
  89. //-----------------------------------------------------------------------------
  90. // Purpose:
  91. //-----------------------------------------------------------------------------
  92. void CTFPistol_ScoutPrimary::Push( void )
  93. {
  94. CTFPlayer *pOwner = ToTFPlayer( GetPlayerOwner() );
  95. if ( !pOwner )
  96. return;
  97. #ifdef GAME_DLL
  98. lagcompensation->StartLagCompensation( pOwner, pOwner->GetCurrentCommand() );
  99. CUtlVector< CTFPlayer* > enemyVector;
  100. CollectPlayers( &enemyVector, GetEnemyTeam( pOwner->GetTeamNumber() ), COLLECT_ONLY_LIVING_PLAYERS );
  101. for ( int i = 0; i < enemyVector.Count(); ++i )
  102. {
  103. CTFPlayer *pVictim = enemyVector[i];
  104. if ( !pVictim->IsAlive() )
  105. continue;
  106. if ( pVictim == pOwner )
  107. continue;
  108. if ( pVictim->InSameTeam( pOwner ) )
  109. continue;
  110. if ( TFGameRules() && TFGameRules()->IsTruceActive() && pOwner->IsTruceValidForEnt() )
  111. continue;
  112. if ( ( pOwner->GetAbsOrigin()- pVictim->GetAbsOrigin() ).LengthSqr() > ( 128.f * 128.f ) )
  113. continue;
  114. if ( !pOwner->FVisible( pVictim, MASK_SOLID ) )
  115. continue;
  116. Vector vecEyes = pOwner->EyePosition();
  117. Vector vecForward;
  118. AngleVectors( pOwner->EyeAngles(), &vecForward );
  119. CTraceFilterSimple traceFilter( this, COLLISION_GROUP_NONE );
  120. const Vector vHull = Vector( 16.f, 16.f, 16.f );
  121. trace_t trace;
  122. float flDist = 50.f;
  123. UTIL_TraceHull( vecEyes, vecEyes + vecForward * flDist, -vHull, vHull, MASK_SOLID, &traceFilter, &trace );
  124. bool bDebug = false;
  125. if ( bDebug )
  126. {
  127. NDebugOverlay::SweptBox( vecEyes, vecEyes + vecForward * flDist, -vHull, vHull, pOwner->EyeAngles(), 255, 0, 0, 40, 5 );
  128. }
  129. if ( trace.m_pEnt && trace.m_pEnt == pVictim && trace.fraction < 1.f )
  130. {
  131. Vector vecToVictim = pVictim->GetAbsOrigin() - pOwner->GetAbsOrigin();
  132. VectorNormalize( vecToVictim );
  133. pVictim->ApplyAirBlastImpulse( vecToVictim * 400.f );
  134. float flDamage = 1.f;
  135. CTakeDamageInfo info( pOwner, pVictim, this, flDamage, DMG_MELEE | DMG_NEVERGIB | DMG_CLUB, TF_DMG_CUSTOM_NONE );
  136. CalculateMeleeDamageForce( &info, vecForward, GetAbsOrigin() + vecForward * flDist, 1.f / flDamage * 80.f );
  137. pVictim->DispatchTraceAttack( info, vecForward, &trace );
  138. ApplyMultiDamage();
  139. CPVSFilter filter( vecToVictim );
  140. EmitSound( "Weapon_Hands.PushImpact" );
  141. // Make sure we get credit for the push if the target falls to its death
  142. pVictim->m_AchievementData.AddDamagerToHistory( pOwner );
  143. break;
  144. }
  145. }
  146. pOwner->SpeakWeaponFire();
  147. CTF_GameStats.Event_PlayerFiredWeapon( pOwner, IsCurrentAttackACrit() );
  148. lagcompensation->FinishLagCompensation( pOwner );
  149. #else
  150. C_CTF_GameStats.Event_PlayerFiredWeapon( pOwner, IsCurrentAttackACrit() );
  151. #endif
  152. }
  153. //-----------------------------------------------------------------------------
  154. // Purpose:
  155. // Input : -
  156. //-----------------------------------------------------------------------------
  157. void CTFPistol_ScoutPrimary::ItemPostFrame()
  158. {
  159. // Check for smack.
  160. if ( m_flPushTime > -1.f && gpGlobals->curtime > m_flPushTime )
  161. {
  162. Push();
  163. m_flPushTime = -1.f;
  164. }
  165. BaseClass::ItemPostFrame();
  166. }
  167. //-----------------------------------------------------------------------------
  168. // Purpose:
  169. //-----------------------------------------------------------------------------
  170. bool CTFPistol_ScoutPrimary::Holster( CBaseCombatWeapon *pSwitchingTo )
  171. {
  172. m_flPushTime = -1.f;
  173. return BaseClass::Holster( pSwitchingTo );
  174. }
  175. //-----------------------------------------------------------------------------
  176. // Purpose:
  177. //-----------------------------------------------------------------------------
  178. void CTFPistol_ScoutPrimary::Precache( void )
  179. {
  180. PrecacheScriptSound( "Weapon_Hands.Push" );
  181. PrecacheScriptSound( "Weapon_Hands.PushImpact" );
  182. BaseClass::Precache();
  183. }
  184. //============================
  185. IMPLEMENT_NETWORKCLASS_ALIASED( TFPistol_ScoutSecondary, DT_WeaponPistol_ScoutSecondary )
  186. BEGIN_NETWORK_TABLE( CTFPistol_ScoutSecondary, DT_WeaponPistol_ScoutSecondary )
  187. END_NETWORK_TABLE()
  188. BEGIN_PREDICTION_DATA( CTFPistol_ScoutSecondary )
  189. END_PREDICTION_DATA()
  190. LINK_ENTITY_TO_CLASS( tf_weapon_handgun_scout_secondary, CTFPistol_ScoutSecondary );
  191. PRECACHE_WEAPON_REGISTER( tf_weapon_handgun_scout_secondary );
  192. //-----------------------------------------------------------------------------
  193. int CTFPistol_ScoutSecondary::GetDamageType( void ) const
  194. {
  195. int iBackheadshot = 0;
  196. CALL_ATTRIB_HOOK_INT( iBackheadshot, back_headshot );
  197. if ( iBackheadshot )
  198. {
  199. return BaseClass::GetDamageType() | DMG_USE_HITLOCATIONS;
  200. }
  201. return BaseClass::GetDamageType();
  202. }