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.

228 lines
6.5 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Crowbar - an old favorite
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "hl2mp/weapon_crowbar.h"
  9. #include "weapon_hl2mpbasehlmpcombatweapon.h"
  10. #include "gamerules.h"
  11. #include "ammodef.h"
  12. #include "mathlib/mathlib.h"
  13. #include "in_buttons.h"
  14. #include "vstdlib/random.h"
  15. #include "npcevent.h"
  16. #if defined( CLIENT_DLL )
  17. #include "c_hl2mp_player.h"
  18. #else
  19. #include "hl2mp_player.h"
  20. #include "ai_basenpc.h"
  21. #endif
  22. // memdbgon must be the last include file in a .cpp file!!!
  23. #include "tier0/memdbgon.h"
  24. #define CROWBAR_RANGE 75.0f
  25. #define CROWBAR_REFIRE 0.4f
  26. //-----------------------------------------------------------------------------
  27. // CWeaponCrowbar
  28. //-----------------------------------------------------------------------------
  29. IMPLEMENT_NETWORKCLASS_ALIASED( WeaponCrowbar, DT_WeaponCrowbar )
  30. BEGIN_NETWORK_TABLE( CWeaponCrowbar, DT_WeaponCrowbar )
  31. END_NETWORK_TABLE()
  32. BEGIN_PREDICTION_DATA( CWeaponCrowbar )
  33. END_PREDICTION_DATA()
  34. LINK_ENTITY_TO_CLASS( weapon_crowbar, CWeaponCrowbar );
  35. PRECACHE_WEAPON_REGISTER( weapon_crowbar );
  36. #ifndef CLIENT_DLL
  37. acttable_t CWeaponCrowbar::m_acttable[] =
  38. {
  39. { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SLAM, true },
  40. { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_MELEE, false },
  41. { ACT_HL2MP_RUN, ACT_HL2MP_RUN_MELEE, false },
  42. { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_MELEE, false },
  43. { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_MELEE, false },
  44. { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_MELEE, false },
  45. { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_MELEE, false },
  46. { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_MELEE, false },
  47. };
  48. IMPLEMENT_ACTTABLE(CWeaponCrowbar);
  49. #endif
  50. //-----------------------------------------------------------------------------
  51. // Constructor
  52. //-----------------------------------------------------------------------------
  53. CWeaponCrowbar::CWeaponCrowbar( void )
  54. {
  55. }
  56. //-----------------------------------------------------------------------------
  57. // Purpose: Get the damage amount for the animation we're doing
  58. // Input : hitActivity - currently played activity
  59. // Output : Damage amount
  60. //-----------------------------------------------------------------------------
  61. float CWeaponCrowbar::GetDamageForActivity( Activity hitActivity )
  62. {
  63. return 25.0f;
  64. }
  65. //-----------------------------------------------------------------------------
  66. // Purpose: Add in a view kick for this weapon
  67. //-----------------------------------------------------------------------------
  68. void CWeaponCrowbar::AddViewKick( void )
  69. {
  70. CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
  71. if ( pPlayer == NULL )
  72. return;
  73. QAngle punchAng;
  74. punchAng.x = SharedRandomFloat( "crowbarpax", 1.0f, 2.0f );
  75. punchAng.y = SharedRandomFloat( "crowbarpay", -2.0f, -1.0f );
  76. punchAng.z = 0.0f;
  77. pPlayer->ViewPunch( punchAng );
  78. }
  79. #ifndef CLIENT_DLL
  80. //-----------------------------------------------------------------------------
  81. // Animation event handlers
  82. //-----------------------------------------------------------------------------
  83. void CWeaponCrowbar::HandleAnimEventMeleeHit( animevent_t *pEvent, CBaseCombatCharacter *pOperator )
  84. {
  85. // Trace up or down based on where the enemy is...
  86. // But only if we're basically facing that direction
  87. Vector vecDirection;
  88. AngleVectors( GetAbsAngles(), &vecDirection );
  89. Vector vecEnd;
  90. VectorMA( pOperator->Weapon_ShootPosition(), 50, vecDirection, vecEnd );
  91. CBaseEntity *pHurt = pOperator->CheckTraceHullAttack( pOperator->Weapon_ShootPosition(), vecEnd,
  92. Vector(-16,-16,-16), Vector(36,36,36), GetDamageForActivity( GetActivity() ), DMG_CLUB, 0.75 );
  93. // did I hit someone?
  94. if ( pHurt )
  95. {
  96. // play sound
  97. WeaponSound( MELEE_HIT );
  98. // Fake a trace impact, so the effects work out like a player's crowbaw
  99. trace_t traceHit;
  100. UTIL_TraceLine( pOperator->Weapon_ShootPosition(), pHurt->GetAbsOrigin(), MASK_SHOT_HULL, pOperator, COLLISION_GROUP_NONE, &traceHit );
  101. ImpactEffect( traceHit );
  102. }
  103. else
  104. {
  105. WeaponSound( MELEE_MISS );
  106. }
  107. }
  108. //-----------------------------------------------------------------------------
  109. // Animation event
  110. //-----------------------------------------------------------------------------
  111. void CWeaponCrowbar::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator )
  112. {
  113. switch( pEvent->event )
  114. {
  115. case EVENT_WEAPON_MELEE_HIT:
  116. HandleAnimEventMeleeHit( pEvent, pOperator );
  117. break;
  118. default:
  119. BaseClass::Operator_HandleAnimEvent( pEvent, pOperator );
  120. break;
  121. }
  122. }
  123. //-----------------------------------------------------------------------------
  124. // Attempt to lead the target (needed because citizens can't hit manhacks with the crowbar!)
  125. //-----------------------------------------------------------------------------
  126. ConVar sk_crowbar_lead_time( "sk_crowbar_lead_time", "0.9" );
  127. int CWeaponCrowbar::WeaponMeleeAttack1Condition( float flDot, float flDist )
  128. {
  129. // Attempt to lead the target (needed because citizens can't hit manhacks with the crowbar!)
  130. CAI_BaseNPC *pNPC = GetOwner()->MyNPCPointer();
  131. CBaseEntity *pEnemy = pNPC->GetEnemy();
  132. if (!pEnemy)
  133. return COND_NONE;
  134. Vector vecVelocity;
  135. vecVelocity = pEnemy->GetSmoothedVelocity( );
  136. // Project where the enemy will be in a little while
  137. float dt = sk_crowbar_lead_time.GetFloat();
  138. dt += SharedRandomFloat( "crowbarmelee1", -0.3f, 0.2f );
  139. if ( dt < 0.0f )
  140. dt = 0.0f;
  141. Vector vecExtrapolatedPos;
  142. VectorMA( pEnemy->WorldSpaceCenter(), dt, vecVelocity, vecExtrapolatedPos );
  143. Vector vecDelta;
  144. VectorSubtract( vecExtrapolatedPos, pNPC->WorldSpaceCenter(), vecDelta );
  145. if ( fabs( vecDelta.z ) > 70 )
  146. {
  147. return COND_TOO_FAR_TO_ATTACK;
  148. }
  149. Vector vecForward = pNPC->BodyDirection2D( );
  150. vecDelta.z = 0.0f;
  151. float flExtrapolatedDist = Vector2DNormalize( vecDelta.AsVector2D() );
  152. if ((flDist > 64) && (flExtrapolatedDist > 64))
  153. {
  154. return COND_TOO_FAR_TO_ATTACK;
  155. }
  156. float flExtrapolatedDot = DotProduct2D( vecDelta.AsVector2D(), vecForward.AsVector2D() );
  157. if ((flDot < 0.7) && (flExtrapolatedDot < 0.7))
  158. {
  159. return COND_NOT_FACING_ATTACK;
  160. }
  161. return COND_CAN_MELEE_ATTACK1;
  162. }
  163. #endif
  164. //-----------------------------------------------------------------------------
  165. // Purpose:
  166. //-----------------------------------------------------------------------------
  167. void CWeaponCrowbar::Drop( const Vector &vecVelocity )
  168. {
  169. #ifndef CLIENT_DLL
  170. UTIL_Remove( this );
  171. #endif
  172. }
  173. float CWeaponCrowbar::GetRange( void )
  174. {
  175. return CROWBAR_RANGE;
  176. }
  177. float CWeaponCrowbar::GetFireRate( void )
  178. {
  179. return CROWBAR_REFIRE;
  180. }