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
160 lines
4.3 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//=============================================================================// |
|
|
|
#include "cbase.h" |
|
|
|
#ifdef CLIENT_DLL |
|
|
|
#include "c_sdk_player.h" |
|
|
|
#else |
|
|
|
#include "sdk_player.h" |
|
|
|
#endif |
|
|
|
#include "gamevars_shared.h" |
|
#include "takedamageinfo.h" |
|
#include "effect_dispatch_data.h" |
|
#include "engine/ivdebugoverlay.h" |
|
|
|
ConVar sv_showimpacts("sv_showimpacts", "0", FCVAR_REPLICATED, "Shows client (red) and server (blue) bullet impact point" ); |
|
|
|
void DispatchEffect( const char *pName, const CEffectData &data ); |
|
|
|
CWeaponSDKBase* CSDKPlayer::SDKAnim_GetActiveWeapon() |
|
{ |
|
return GetActiveSDKWeapon(); |
|
} |
|
|
|
bool CSDKPlayer::SDKAnim_CanMove() |
|
{ |
|
return true; |
|
} |
|
|
|
void CSDKPlayer::FireBullet( |
|
Vector vecSrc, // shooting postion |
|
const QAngle &shootAngles, //shooting angle |
|
float vecSpread, // spread vector |
|
int iDamage, // base damage |
|
int iBulletType, // ammo type |
|
CBaseEntity *pevAttacker, // shooter |
|
bool bDoEffects, // create impact effect ? |
|
float x, // spread x factor |
|
float y // spread y factor |
|
) |
|
{ |
|
float fCurrentDamage = iDamage; // damage of the bullet at it's current trajectory |
|
float flCurrentDistance = 0.0; //distance that the bullet has traveled so far |
|
|
|
Vector vecDirShooting, vecRight, vecUp; |
|
AngleVectors( shootAngles, &vecDirShooting, &vecRight, &vecUp ); |
|
|
|
if ( !pevAttacker ) |
|
pevAttacker = this; // the default attacker is ourselves |
|
|
|
// add the spray |
|
Vector vecDir = vecDirShooting + |
|
x * vecSpread * vecRight + |
|
y * vecSpread * vecUp; |
|
|
|
VectorNormalize( vecDir ); |
|
|
|
float flMaxRange = 8000; |
|
|
|
Vector vecEnd = vecSrc + vecDir * flMaxRange; // max bullet range is 10000 units |
|
|
|
trace_t tr; // main enter bullet trace |
|
|
|
UTIL_TraceLine( vecSrc, vecEnd, MASK_SOLID|CONTENTS_DEBRIS|CONTENTS_HITBOX, this, COLLISION_GROUP_NONE, &tr ); |
|
|
|
if ( tr.fraction == 1.0f ) |
|
return; // we didn't hit anything, stop tracing shoot |
|
|
|
if ( sv_showimpacts.GetBool() ) |
|
{ |
|
#ifdef CLIENT_DLL |
|
// draw red client impact markers |
|
debugoverlay->AddBoxOverlay( tr.endpos, Vector(-2,-2,-2), Vector(2,2,2), QAngle( 0, 0, 0), 255,0,0,127, 4 ); |
|
|
|
if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() ) |
|
{ |
|
C_BasePlayer *player = ToBasePlayer( tr.m_pEnt ); |
|
player->DrawClientHitboxes( 4, true ); |
|
} |
|
#else |
|
// draw blue server impact markers |
|
NDebugOverlay::Box( tr.endpos, Vector(-2,-2,-2), Vector(2,2,2), 0,0,255,127, 4 ); |
|
|
|
if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() ) |
|
{ |
|
CBasePlayer *player = ToBasePlayer( tr.m_pEnt ); |
|
player->DrawServerHitboxes( 4, true ); |
|
} |
|
#endif |
|
} |
|
|
|
//calculate the damage based on the distance the bullet travelled. |
|
flCurrentDistance += tr.fraction * flMaxRange; |
|
|
|
// damage get weaker of distance |
|
fCurrentDamage *= pow ( 0.85f, (flCurrentDistance / 500)); |
|
|
|
int iDamageType = DMG_BULLET | DMG_NEVERGIB; |
|
|
|
if( bDoEffects ) |
|
{ |
|
// See if the bullet ended up underwater + started out of the water |
|
if ( enginetrace->GetPointContents( tr.endpos ) & (CONTENTS_WATER|CONTENTS_SLIME) ) |
|
{ |
|
trace_t waterTrace; |
|
UTIL_TraceLine( vecSrc, tr.endpos, (MASK_SHOT|CONTENTS_WATER|CONTENTS_SLIME), this, COLLISION_GROUP_NONE, &waterTrace ); |
|
|
|
if( waterTrace.allsolid != 1 ) |
|
{ |
|
CEffectData data; |
|
data.m_vOrigin = waterTrace.endpos; |
|
data.m_vNormal = waterTrace.plane.normal; |
|
data.m_flScale = random->RandomFloat( 8, 12 ); |
|
|
|
if ( waterTrace.contents & CONTENTS_SLIME ) |
|
{ |
|
data.m_fFlags |= FX_WATER_IN_SLIME; |
|
} |
|
|
|
DispatchEffect( "gunshotsplash", data ); |
|
} |
|
} |
|
else |
|
{ |
|
//Do Regular hit effects |
|
|
|
// Don't decal nodraw surfaces |
|
if ( !( tr.surface.flags & (SURF_SKY|SURF_NODRAW|SURF_HINT|SURF_SKIP) ) ) |
|
{ |
|
CBaseEntity *pEntity = tr.m_pEnt; |
|
if ( !( !friendlyfire.GetBool() && pEntity && pEntity->IsPlayer() && pEntity->GetTeamNumber() == GetTeamNumber() ) ) |
|
{ |
|
UTIL_ImpactTrace( &tr, iDamageType ); |
|
} |
|
} |
|
} |
|
} // bDoEffects |
|
|
|
// add damage to entity that we hit |
|
|
|
#ifdef GAME_DLL |
|
ClearMultiDamage(); |
|
|
|
CTakeDamageInfo info( pevAttacker, pevAttacker, fCurrentDamage, iDamageType ); |
|
CalculateBulletDamageForce( &info, iBulletType, vecDir, tr.endpos ); |
|
tr.m_pEnt->DispatchTraceAttack( info, vecDir, &tr ); |
|
|
|
TraceAttackToTriggers( info, tr.startpos, tr.endpos, vecDir ); |
|
|
|
ApplyMultiDamage(); |
|
#endif |
|
}
|
|
|