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.

160 lines
4.3 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #ifdef CLIENT_DLL
  8. #include "c_sdk_player.h"
  9. #else
  10. #include "sdk_player.h"
  11. #endif
  12. #include "gamevars_shared.h"
  13. #include "takedamageinfo.h"
  14. #include "effect_dispatch_data.h"
  15. #include "engine/ivdebugoverlay.h"
  16. ConVar sv_showimpacts("sv_showimpacts", "0", FCVAR_REPLICATED, "Shows client (red) and server (blue) bullet impact point" );
  17. void DispatchEffect( const char *pName, const CEffectData &data );
  18. CWeaponSDKBase* CSDKPlayer::SDKAnim_GetActiveWeapon()
  19. {
  20. return GetActiveSDKWeapon();
  21. }
  22. bool CSDKPlayer::SDKAnim_CanMove()
  23. {
  24. return true;
  25. }
  26. void CSDKPlayer::FireBullet(
  27. Vector vecSrc, // shooting postion
  28. const QAngle &shootAngles, //shooting angle
  29. float vecSpread, // spread vector
  30. int iDamage, // base damage
  31. int iBulletType, // ammo type
  32. CBaseEntity *pevAttacker, // shooter
  33. bool bDoEffects, // create impact effect ?
  34. float x, // spread x factor
  35. float y // spread y factor
  36. )
  37. {
  38. float fCurrentDamage = iDamage; // damage of the bullet at it's current trajectory
  39. float flCurrentDistance = 0.0; //distance that the bullet has traveled so far
  40. Vector vecDirShooting, vecRight, vecUp;
  41. AngleVectors( shootAngles, &vecDirShooting, &vecRight, &vecUp );
  42. if ( !pevAttacker )
  43. pevAttacker = this; // the default attacker is ourselves
  44. // add the spray
  45. Vector vecDir = vecDirShooting +
  46. x * vecSpread * vecRight +
  47. y * vecSpread * vecUp;
  48. VectorNormalize( vecDir );
  49. float flMaxRange = 8000;
  50. Vector vecEnd = vecSrc + vecDir * flMaxRange; // max bullet range is 10000 units
  51. trace_t tr; // main enter bullet trace
  52. UTIL_TraceLine( vecSrc, vecEnd, MASK_SOLID|CONTENTS_DEBRIS|CONTENTS_HITBOX, this, COLLISION_GROUP_NONE, &tr );
  53. if ( tr.fraction == 1.0f )
  54. return; // we didn't hit anything, stop tracing shoot
  55. if ( sv_showimpacts.GetBool() )
  56. {
  57. #ifdef CLIENT_DLL
  58. // draw red client impact markers
  59. debugoverlay->AddBoxOverlay( tr.endpos, Vector(-2,-2,-2), Vector(2,2,2), QAngle( 0, 0, 0), 255,0,0,127, 4 );
  60. if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() )
  61. {
  62. C_BasePlayer *player = ToBasePlayer( tr.m_pEnt );
  63. player->DrawClientHitboxes( 4, true );
  64. }
  65. #else
  66. // draw blue server impact markers
  67. NDebugOverlay::Box( tr.endpos, Vector(-2,-2,-2), Vector(2,2,2), 0,0,255,127, 4 );
  68. if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() )
  69. {
  70. CBasePlayer *player = ToBasePlayer( tr.m_pEnt );
  71. player->DrawServerHitboxes( 4, true );
  72. }
  73. #endif
  74. }
  75. //calculate the damage based on the distance the bullet travelled.
  76. flCurrentDistance += tr.fraction * flMaxRange;
  77. // damage get weaker of distance
  78. fCurrentDamage *= pow ( 0.85f, (flCurrentDistance / 500));
  79. int iDamageType = DMG_BULLET | DMG_NEVERGIB;
  80. if( bDoEffects )
  81. {
  82. // See if the bullet ended up underwater + started out of the water
  83. if ( enginetrace->GetPointContents( tr.endpos ) & (CONTENTS_WATER|CONTENTS_SLIME) )
  84. {
  85. trace_t waterTrace;
  86. UTIL_TraceLine( vecSrc, tr.endpos, (MASK_SHOT|CONTENTS_WATER|CONTENTS_SLIME), this, COLLISION_GROUP_NONE, &waterTrace );
  87. if( waterTrace.allsolid != 1 )
  88. {
  89. CEffectData data;
  90. data.m_vOrigin = waterTrace.endpos;
  91. data.m_vNormal = waterTrace.plane.normal;
  92. data.m_flScale = random->RandomFloat( 8, 12 );
  93. if ( waterTrace.contents & CONTENTS_SLIME )
  94. {
  95. data.m_fFlags |= FX_WATER_IN_SLIME;
  96. }
  97. DispatchEffect( "gunshotsplash", data );
  98. }
  99. }
  100. else
  101. {
  102. //Do Regular hit effects
  103. // Don't decal nodraw surfaces
  104. if ( !( tr.surface.flags & (SURF_SKY|SURF_NODRAW|SURF_HINT|SURF_SKIP) ) )
  105. {
  106. CBaseEntity *pEntity = tr.m_pEnt;
  107. if ( !( !friendlyfire.GetBool() && pEntity && pEntity->IsPlayer() && pEntity->GetTeamNumber() == GetTeamNumber() ) )
  108. {
  109. UTIL_ImpactTrace( &tr, iDamageType );
  110. }
  111. }
  112. }
  113. } // bDoEffects
  114. // add damage to entity that we hit
  115. #ifdef GAME_DLL
  116. ClearMultiDamage();
  117. CTakeDamageInfo info( pevAttacker, pevAttacker, fCurrentDamage, iDamageType );
  118. CalculateBulletDamageForce( &info, iBulletType, vecDir, tr.endpos );
  119. tr.m_pEnt->DispatchTraceAttack( info, vecDir, &tr );
  120. TraceAttackToTriggers( info, tr.startpos, tr.endpos, vecDir );
  121. ApplyMultiDamage();
  122. #endif
  123. }