Simplified bullet trace

This commit is contained in:
Kamay Xutax 2024-07-15 21:10:58 +02:00
parent cc3e0fcf04
commit e5ccc52ef6
10 changed files with 147 additions and 107 deletions

View file

@ -247,9 +247,7 @@ END_RECV_TABLE()
RecvPropInt ( RECVINFO( m_nWaterLevel ) ), RecvPropInt ( RECVINFO( m_nWaterLevel ) ),
RecvPropFloat ( RECVINFO( m_flLaggedMovementValue )), RecvPropFloat ( RECVINFO( m_flLaggedMovementValue )),
RecvPropArray3 ( RECVINFO_ARRAY(m_vecBulletPositions), RecvPropVector( RECVINFO(m_vecBulletPositions[0])) ), END_RECV_TABLE()
RecvPropInt(RECVINFO(m_iBulletPositionCount)),
END_RECV_TABLE()
// -------------------------------------------------------------------------------- // // -------------------------------------------------------------------------------- //
@ -416,8 +414,9 @@ C_BasePlayer::C_BasePlayer() : m_iv_vecViewOffset( "C_BasePlayer::m_iv_vecViewOf
m_pFlashlight = NULL; m_pFlashlight = NULL;
m_pCurrentVguiScreen = NULL; m_pCurrentVguiScreen = NULL;
m_pCurrentCommand = NULL; static CUserCmd nullcmd;
m_pCurrentCommand = &nullcmd;
m_flPredictionErrorTime = -100; m_flPredictionErrorTime = -100;
m_StuckLast = 0; m_StuckLast = 0;
@ -2132,34 +2131,13 @@ void C_BasePlayer::Simulate()
ResetLatched(); ResetLatched();
} }
if (m_nTickBaseFireBullet <= m_nTickBase && m_nTickBaseFireBullet != -1) bool shouldShowFireBulletHitbox = m_nTickBaseFireBullet <= m_nTickBase && m_nTickBaseFireBullet != -1;
if (shouldShowFireBulletHitbox)
{ {
DrawServerHitboxes(60.0f, true); DrawServerHitboxes(60.0f, true);
static ConVarRef cl_showimpacts("cl_showimpacts");
if (cl_showimpacts.GetInt() == 1 || cl_showimpacts.GetInt() == 3)
{
extern float g_bulletDiameter;
for (int i = 0; i < m_iBulletPositionCount; i++)
{
debugoverlay->AddBoxOverlay(m_vecBulletPositions[i],
Vector(-g_bulletDiameter,
-g_bulletDiameter,
-g_bulletDiameter),
Vector(g_bulletDiameter,
g_bulletDiameter,
g_bulletDiameter),
QAngle(0, 0, 0),
0,
0,
255,
127,
60);
}
}
m_nTickBaseFireBullet = -1; m_nTickBaseFireBullet = -1;
} }
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View file

@ -8,6 +8,7 @@
#ifndef C_BASEPLAYER_H #ifndef C_BASEPLAYER_H
#define C_BASEPLAYER_H #define C_BASEPLAYER_H
#ifdef _WIN32 #ifdef _WIN32
#pragma once #pragma once
#endif #endif
@ -434,6 +435,7 @@ public:
int m_nButtons; int m_nButtons;
CUserCmd m_LastCmd;
CUserCmd *m_pCurrentCommand; CUserCmd *m_pCurrentCommand;
// Movement constraints // Movement constraints
@ -638,8 +640,6 @@ public:
void SetOldPlayerZ( float flOld ) { m_flOldPlayerZ = flOld; } void SetOldPlayerZ( float flOld ) { m_flOldPlayerZ = flOld; }
int m_nTickBaseFireBullet; int m_nTickBaseFireBullet;
Vector m_vecBulletPositions[MAX_PLAYER_BULLET_POSITIONS];
int m_iBulletPositionCount;
}; };
EXTERN_RECV_TABLE(DT_BasePlayer); EXTERN_RECV_TABLE(DT_BasePlayer);

View file

@ -168,10 +168,12 @@ public:
public: public:
virtual float GetPlayerMaxSpeed(); virtual float GetPlayerMaxSpeed();
void GetBulletTypeParameters( float GetBulletDiameter(int iBulletType);
int iBulletType, void GetBulletTypeParameters(
float &fPenetrationPower, int iBulletType,
float &flPenetrationDistance ); float &fPenetrationPower,
float &flPenetrationDistance,
float &flBulletDiameter );
void FireBullet( void FireBullet(
Vector vecSrc, Vector vecSrc,

View file

@ -763,9 +763,9 @@ void CPrediction::FinishCommand( C_BasePlayer *player )
#if !defined( NO_ENTITY_PREDICTION ) #if !defined( NO_ENTITY_PREDICTION )
VPROF( "CPrediction::FinishCommand" ); VPROF( "CPrediction::FinishCommand" );
player->m_pCurrentCommand = NULL; // player->m_pCurrentCommand = NULL;
C_BaseEntity::SetPredictionRandomSeed( NULL ); //C_BaseEntity::SetPredictionRandomSeed( NULL );
C_BaseEntity::SetPredictionPlayer( NULL ); //C_BaseEntity::SetPredictionPlayer( NULL );
#endif #endif
} }

View file

@ -50,6 +50,7 @@ public:
ListenForGameEvent( "hostage_killed" ); ListenForGameEvent( "hostage_killed" );
ListenForGameEvent( "hostage_follows" ); ListenForGameEvent( "hostage_follows" );
ListenForGameEvent( "player_hurt" ); ListenForGameEvent( "player_hurt" );
ListenForGameEvent( "bullet_impact" );
return true; return true;
} }
@ -299,7 +300,35 @@ protected:
); );
return true; return true;
} }
else if ( !Q_strncmp( eventName, "bullet_impact", Q_strlen("bullet_impact") ) )
{
static ConVarRef cl_showimpacts("cl_showimpacts");
if (cl_showimpacts.GetInt() == 1
|| cl_showimpacts.GetInt() == 3)
{
auto x = event->GetFloat("x");
auto y = event->GetFloat("y");
auto z = event->GetFloat("z");
auto flBulletDiameter = event->GetFloat("diameter");
debugoverlay->AddBoxOverlay(Vector(x, y, z),
Vector(-flBulletDiameter,
-flBulletDiameter,
-flBulletDiameter),
Vector(flBulletDiameter,
flBulletDiameter,
flBulletDiameter),
QAngle(0, 0, 0),
0,
0,
255,
127,
60.0f);
}
return true;
}
// unused events: // unused events:
//hostage_hurt //hostage_hurt
//bomb_exploded //bomb_exploded

View file

@ -317,10 +317,12 @@ public:
float lateral_max, float lateral_max,
int direction_change ); int direction_change );
float GetBulletDiameter(int iBulletType);
void GetBulletTypeParameters( void GetBulletTypeParameters(
int iBulletType, int iBulletType,
float &fPenetrationPower, float &fPenetrationPower,
float &flPenetrationDistance ); float &flPenetrationDistance,
float &flBulletDiameter );
// Returns true if the player is allowed to move. // Returns true if the player is allowed to move.
bool CanMove() const; bool CanMove() const;

View file

@ -583,8 +583,9 @@ CBasePlayer::CBasePlayer( )
m_bitsDamageType = 0; m_bitsDamageType = 0;
m_bForceOrigin = false; m_bForceOrigin = false;
m_hVehicle = NULL; m_hVehicle = NULL;
m_pCurrentCommand = NULL; static CUserCmd nullcmd;
m_pCurrentCommand = &nullcmd;
// Setup our default FOV // Setup our default FOV
m_iDefaultFOV = g_pGameRules->DefaultFOV(); m_iDefaultFOV = g_pGameRules->DefaultFOV();
@ -634,7 +635,6 @@ CBasePlayer::CBasePlayer( )
m_flLastUserCommandTime = 0.f; m_flLastUserCommandTime = 0.f;
m_flMovementTimeForUserCmdProcessingRemaining = 0.0f; m_flMovementTimeForUserCmdProcessingRemaining = 0.0f;
m_iBulletPositionCount.Set(0);
} }
CBasePlayer::~CBasePlayer( ) CBasePlayer::~CBasePlayer( )
@ -7970,8 +7970,6 @@ void CMovementSpeedMod::InputSpeedMod(inputdata_t &data)
SendPropInt ( SENDINFO( m_nWaterLevel ), 2, SPROP_UNSIGNED ), SendPropInt ( SENDINFO( m_nWaterLevel ), 2, SPROP_UNSIGNED ),
SendPropFloat ( SENDINFO( m_flLaggedMovementValue ), 0, SPROP_NOSCALE ), SendPropFloat ( SENDINFO( m_flLaggedMovementValue ), 0, SPROP_NOSCALE ),
SendPropArray3( SENDINFO_ARRAY3(m_vecBulletPositions), SendPropVector(SENDINFO_ARRAY(m_vecBulletPositions))),
SendPropInt(SENDINFO(m_iBulletPositionCount)),
END_SEND_TABLE() END_SEND_TABLE()

View file

@ -1210,8 +1210,6 @@ private:
public: public:
virtual unsigned int PlayerSolidMask( bool brushOnly = false ) const; // returns the solid mask for the given player, so bots can have a more-restrictive set virtual unsigned int PlayerSolidMask( bool brushOnly = false ) const; // returns the solid mask for the given player, so bots can have a more-restrictive set
CNetworkArray(Vector, m_vecBulletPositions, MAX_PLAYER_BULLET_POSITIONS);
CNetworkVar(int, m_iBulletPositionCount);
}; };
typedef CHandle<CBasePlayer> CBasePlayerHandle; typedef CHandle<CBasePlayer> CBasePlayerHandle;

View file

@ -84,9 +84,9 @@ void CPlayerMove::FinishCommand( CBasePlayer *player )
{ {
VPROF( "CPlayerMove::FinishCommand" ); VPROF( "CPlayerMove::FinishCommand" );
player->m_pCurrentCommand = NULL; // player->m_pCurrentCommand = NULL;
CBaseEntity::SetPredictionRandomSeed( NULL ); // CBaseEntity::SetPredictionRandomSeed( NULL );
CBaseEntity::SetPredictionPlayer( NULL ); // CBaseEntity::SetPredictionPlayer( NULL );
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View file

@ -183,20 +183,14 @@ float CCSPlayer::GetPlayerMaxSpeed()
return speed; return speed;
} }
float g_bulletDiameter = 0.0f; void UTIL_ClipTraceToPlayersHull( float flBulletDiameter, const Vector& vecAbsStart, const Vector& vecAbsEnd, unsigned int mask, ITraceFilter *filter, trace_t *tr )
static constexpr float MMToUnits(float mm)
{
return (mm / 10.f) / 1.905f;
}
void UTIL_ClipTraceToPlayersHull( const Vector& vecAbsStart, const Vector& vecAbsEnd, unsigned int mask, ITraceFilter *filter, trace_t *tr )
{ {
trace_t playerTrace; trace_t playerTrace;
Ray_t ray; Ray_t ray;
float smallestFraction = tr->fraction; float smallestFraction = tr->fraction;
const float maxRange = 60.0f; const float maxRange = 60.0f;
ray.Init( vecAbsStart, vecAbsEnd , Vector(-g_bulletDiameter, -g_bulletDiameter, -g_bulletDiameter), Vector(g_bulletDiameter, g_bulletDiameter, g_bulletDiameter) ); ray.Init( vecAbsStart, vecAbsEnd , Vector(-flBulletDiameter, -flBulletDiameter, -flBulletDiameter), Vector(flBulletDiameter, flBulletDiameter, flBulletDiameter) );
for ( int k = 1; k <= gpGlobals->maxClients; ++k ) for ( int k = 1; k <= gpGlobals->maxClients; ++k )
{ {
@ -227,66 +221,109 @@ void UTIL_ClipTraceToPlayersHull( const Vector& vecAbsStart, const Vector& vecAb
} }
} }
float CCSPlayer::GetBulletDiameter(int iBulletType)
{
auto MMToUnits = [] (float&& mm)
{
return (mm / 10.f) / 1.905f;
};
if (IsAmmoType(iBulletType, BULLET_PLAYER_50AE))
{
return MMToUnits(13.8f);
}
else if (IsAmmoType(iBulletType, BULLET_PLAYER_762MM))
{
return MMToUnits(7.62f);
}
else if (IsAmmoType(iBulletType, BULLET_PLAYER_556MM)
|| IsAmmoType(iBulletType, BULLET_PLAYER_556MM_BOX))
{
return MMToUnits(5.56f);
}
else if (IsAmmoType(iBulletType, BULLET_PLAYER_338MAG))
{
return MMToUnits(8.6f);
}
else if (IsAmmoType(iBulletType, BULLET_PLAYER_9MM))
{
return MMToUnits(9.f);
}
else if (IsAmmoType(iBulletType, BULLET_PLAYER_BUCKSHOT))
{
return MMToUnits(9.9f);
}
else if (IsAmmoType(iBulletType, BULLET_PLAYER_45ACP))
{
return MMToUnits(11.43f);
}
else if (IsAmmoType(iBulletType, BULLET_PLAYER_357SIG))
{
return MMToUnits(9.f);
}
else if (IsAmmoType(iBulletType, BULLET_PLAYER_57MM))
{
return MMToUnits(5.7f);
}
else
{
Assert(false);
return 0.0f;
}
}
void CCSPlayer::GetBulletTypeParameters( void CCSPlayer::GetBulletTypeParameters(
int iBulletType, int iBulletType,
float &fPenetrationPower, float &fPenetrationPower,
float &flPenetrationDistance ) float &flPenetrationDistance,
float &flBulletDiameter )
{ {
//MIKETODO: make ammo types come from a script file. //MIKETODO: make ammo types come from a script file.
if ( IsAmmoType( iBulletType, BULLET_PLAYER_50AE ) ) if ( IsAmmoType( iBulletType, BULLET_PLAYER_50AE ) )
{ {
fPenetrationPower = 30; fPenetrationPower = 30;
flPenetrationDistance = 1000.0; flPenetrationDistance = 1000.0;
g_bulletDiameter = MMToUnits(13.8f);
} }
else if ( IsAmmoType( iBulletType, BULLET_PLAYER_762MM ) ) else if ( IsAmmoType( iBulletType, BULLET_PLAYER_762MM ) )
{ {
fPenetrationPower = 39; fPenetrationPower = 39;
flPenetrationDistance = 5000.0; flPenetrationDistance = 5000.0;
g_bulletDiameter = MMToUnits(7.62f);
} }
else if ( IsAmmoType( iBulletType, BULLET_PLAYER_556MM ) || else if ( IsAmmoType( iBulletType, BULLET_PLAYER_556MM ) ||
IsAmmoType( iBulletType, BULLET_PLAYER_556MM_BOX ) ) IsAmmoType( iBulletType, BULLET_PLAYER_556MM_BOX ) )
{ {
fPenetrationPower = 35; fPenetrationPower = 35;
flPenetrationDistance = 4000.0; flPenetrationDistance = 4000.0;
g_bulletDiameter = MMToUnits(5.56f);
} }
else if ( IsAmmoType( iBulletType, BULLET_PLAYER_338MAG ) ) else if ( IsAmmoType( iBulletType, BULLET_PLAYER_338MAG ) )
{ {
fPenetrationPower = 45; fPenetrationPower = 45;
flPenetrationDistance = 8000.0; flPenetrationDistance = 8000.0;
g_bulletDiameter = MMToUnits(8.6f);
} }
else if ( IsAmmoType( iBulletType, BULLET_PLAYER_9MM ) ) else if ( IsAmmoType( iBulletType, BULLET_PLAYER_9MM ) )
{ {
fPenetrationPower = 21; fPenetrationPower = 21;
flPenetrationDistance = 800.0; flPenetrationDistance = 800.0;
g_bulletDiameter = MMToUnits(9.f);
} }
else if ( IsAmmoType( iBulletType, BULLET_PLAYER_BUCKSHOT ) ) else if ( IsAmmoType( iBulletType, BULLET_PLAYER_BUCKSHOT ) )
{ {
fPenetrationPower = 0; fPenetrationPower = 0;
flPenetrationDistance = 0.0; flPenetrationDistance = 0.0;
g_bulletDiameter = MMToUnits(9.9f);
} }
else if ( IsAmmoType( iBulletType, BULLET_PLAYER_45ACP ) ) else if ( IsAmmoType( iBulletType, BULLET_PLAYER_45ACP ) )
{ {
fPenetrationPower = 15; fPenetrationPower = 15;
flPenetrationDistance = 500.0; flPenetrationDistance = 500.0;
g_bulletDiameter = MMToUnits(11.43f);
} }
else if ( IsAmmoType( iBulletType, BULLET_PLAYER_357SIG ) ) else if ( IsAmmoType( iBulletType, BULLET_PLAYER_357SIG ) )
{ {
fPenetrationPower = 25; fPenetrationPower = 25;
flPenetrationDistance = 800.0; flPenetrationDistance = 800.0;
g_bulletDiameter = MMToUnits(9.f);
} }
else if ( IsAmmoType( iBulletType, BULLET_PLAYER_57MM ) ) else if ( IsAmmoType( iBulletType, BULLET_PLAYER_57MM ) )
{ {
fPenetrationPower = 30; fPenetrationPower = 30;
flPenetrationDistance = 2000.0; flPenetrationDistance = 2000.0;
g_bulletDiameter = MMToUnits(5.7f);
} }
else else
{ {
@ -294,7 +331,9 @@ void CCSPlayer::GetBulletTypeParameters(
Assert( false ); Assert( false );
fPenetrationPower = 0; fPenetrationPower = 0;
flPenetrationDistance = 0.0; flPenetrationDistance = 0.0;
} }
flBulletDiameter = GetBulletDiameter(iBulletType);
} }
static void GetMaterialParameters( int iMaterial, float &flPenetrationModifier, float &flDamageModifier ) static void GetMaterialParameters( int iMaterial, float &flPenetrationModifier, float &flDamageModifier )
@ -365,16 +404,16 @@ static bool TraceToExit(Vector &start, Vector &dir, Vector &end, float flStepSiz
return false; return false;
} }
inline void UTIL_TraceLineIgnoreTwoEntities( const Vector& vecAbsStart, const Vector& vecAbsEnd, unsigned int mask, inline void UTIL_TraceLineIgnoreTwoEntities(float flBulletDiameter, const Vector& vecAbsStart, const Vector& vecAbsEnd, unsigned int mask,
const IHandleEntity *ignore, const IHandleEntity *ignore2, int collisionGroup, trace_t *ptr ) const IHandleEntity *ignore, const IHandleEntity *ignore2, int collisionGroup, trace_t *ptr )
{ {
Ray_t ray; Ray_t ray;
ray.Init( vecAbsStart, vecAbsEnd, Vector(-g_bulletDiameter, -g_bulletDiameter, -g_bulletDiameter), Vector(g_bulletDiameter, g_bulletDiameter, g_bulletDiameter) ); ray.Init( vecAbsStart, vecAbsEnd, Vector(-flBulletDiameter, -flBulletDiameter, -flBulletDiameter), Vector(flBulletDiameter, flBulletDiameter, flBulletDiameter) );
CTraceFilterSkipTwoEntities traceFilter( ignore, ignore2, collisionGroup ); CTraceFilterSkipTwoEntities traceFilter( ignore, ignore2, collisionGroup );
enginetrace->TraceRay( ray, mask, &traceFilter, ptr ); enginetrace->TraceRay( ray, mask, &traceFilter, ptr );
if( r_visualizetraces.GetBool() ) if( r_visualizetraces.GetBool() )
{ {
NDebugOverlay::SweptBox( ptr->startpos, ptr->endpos, Vector(-g_bulletDiameter, -g_bulletDiameter, -g_bulletDiameter), Vector(g_bulletDiameter, g_bulletDiameter, g_bulletDiameter), QAngle(), 255, 0, 0, true, 100.0f ); NDebugOverlay::SweptBox( ptr->startpos, ptr->endpos, Vector(-flBulletDiameter, -flBulletDiameter, -flBulletDiameter), Vector(flBulletDiameter, flBulletDiameter, flBulletDiameter), QAngle(), 255, 0, 0, true, 100.0f );
} }
} }
@ -401,15 +440,14 @@ void CCSPlayer::FireBullet(
float flPenetrationPower = 0; // thickness of a wall that this bullet can penetrate float flPenetrationPower = 0; // thickness of a wall that this bullet can penetrate
float flPenetrationDistance = 0; // distance at which the bullet is capable of penetrating a wall float flPenetrationDistance = 0; // distance at which the bullet is capable of penetrating a wall
float flDamageModifier = 0.5; // default modification of bullets power after they go through a wall. float flDamageModifier = 0.5; // default modification of bullets power after they go through a wall.
float flPenetrationModifier = 1.f; float flPenetrationModifier = 1.f;
float flBulletDiameter = 0.0f;
GetBulletTypeParameters( iBulletType, flPenetrationPower, flPenetrationDistance );
GetBulletTypeParameters( iBulletType, flPenetrationPower, flPenetrationDistance, flBulletDiameter );
if ( !pevAttacker ) if ( !pevAttacker )
pevAttacker = this; // the default attacker is ourselves pevAttacker = this; // the default attacker is ourselves
int iPenetrationCount = 0;
if ( weapon_accuracy_nospread.GetBool() ) if ( weapon_accuracy_nospread.GetBool() )
{ {
xSpread = 0.0f; xSpread = 0.0f;
@ -464,6 +502,7 @@ void CCSPlayer::FireBullet(
bool bFirstHit = true; bool bFirstHit = true;
CBasePlayer *lastPlayerHit = NULL; CBasePlayer *lastPlayerHit = NULL;
MDLCACHE_CRITICAL_SECTION();
if ( m_pCurrentCommand->debug_hitboxes == CUserCmd::DEBUG_HITBOXES_ON_BULLET ) if ( m_pCurrentCommand->debug_hitboxes == CUserCmd::DEBUG_HITBOXES_ON_BULLET )
{ {
@ -483,21 +522,21 @@ void CCSPlayer::FireBullet(
} }
#endif #endif
} }
} }
MDLCACHE_CRITICAL_SECTION();
while ( fCurrentDamage > 0 ) while ( fCurrentDamage > 0 )
{ {
Vector vecEnd = vecSrc + vecDir * flDistance; Vector vecEnd = vecSrc + vecDir * flDistance;
trace_t tr; // main enter bullet trace trace_t tr; // main enter bullet trace
UTIL_TraceLineIgnoreTwoEntities( vecSrc, vecEnd, CS_MASK_SHOOT|CONTENTS_HITBOX, this, lastPlayerHit, COLLISION_GROUP_NONE, &tr ); UTIL_TraceLineIgnoreTwoEntities(flBulletDiameter, vecSrc, vecEnd, CS_MASK_SHOOT|CONTENTS_HITBOX, this, lastPlayerHit, COLLISION_GROUP_NONE, &tr );
{ {
CTraceFilterSkipTwoEntities filter( this, lastPlayerHit, COLLISION_GROUP_NONE ); CTraceFilterSkipTwoEntities filter( this, lastPlayerHit, COLLISION_GROUP_NONE );
// Check for player hitboxes extending outside their collision bounds // Check for player hitboxes extending outside their collision bounds
const float rayExtension = 40.0f; const float rayExtension = 40.0f;
UTIL_ClipTraceToPlayersHull( vecSrc, vecEnd + vecDir * rayExtension, CS_MASK_SHOOT|CONTENTS_HITBOX, &filter, &tr ); UTIL_ClipTraceToPlayersHull(flBulletDiameter, vecSrc, vecEnd + vecDir * rayExtension, CS_MASK_SHOOT|CONTENTS_HITBOX, &filter, &tr );
} }
lastPlayerHit = ToBasePlayer(tr.m_pEnt); lastPlayerHit = ToBasePlayer(tr.m_pEnt);
@ -512,22 +551,6 @@ void CCSPlayer::FireBullet(
bFirstHit = false; bFirstHit = false;
#ifndef CLIENT_DLL
//
// Propogate a bullet impact event
// @todo Add this for shotgun pellets (which dont go thru here)
//
IGameEvent * event = gameeventmanager->CreateEvent( "bullet_impact" );
if ( event )
{
event->SetInt( "userid", GetUserID() );
event->SetFloat( "x", tr.endpos.x );
event->SetFloat( "y", tr.endpos.y );
event->SetFloat( "z", tr.endpos.z );
gameeventmanager->FireEvent( event );
}
#endif
/************* MATERIAL DETECTION ***********/ /************* MATERIAL DETECTION ***********/
surfacedata_t *pSurfaceData = physprops->GetSurfaceData( tr.surface.surfaceProps ); surfacedata_t *pSurfaceData = physprops->GetSurfaceData( tr.surface.surfaceProps );
int iEnterMaterial = pSurfaceData->game.material; int iEnterMaterial = pSurfaceData->game.material;
@ -549,24 +572,34 @@ void CCSPlayer::FireBullet(
{ {
#ifdef CLIENT_DLL #ifdef CLIENT_DLL
// draw red client impact markers // draw red client impact markers
debugoverlay->AddBoxOverlay( tr.endpos, Vector(-g_bulletDiameter,-g_bulletDiameter,-g_bulletDiameter), Vector(g_bulletDiameter,g_bulletDiameter,g_bulletDiameter), QAngle( 0, 0, 0), 255,0,0,127, 60 ); debugoverlay->AddBoxOverlay( tr.endpos, Vector(-flBulletDiameter,-flBulletDiameter,-flBulletDiameter), Vector(flBulletDiameter,flBulletDiameter,flBulletDiameter), QAngle( 0, 0, 0), 255,0,0,127, 60 );
if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() ) if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() )
{ {
C_BasePlayer *player = ToBasePlayer( tr.m_pEnt ); C_BasePlayer *player = ToBasePlayer( tr.m_pEnt );
player->DrawClientHitboxes( 60, true ); player->DrawClientHitboxes( 60, true );
player->m_nTickBaseFireBullet = int(player->GetTimeBase() / TICK_INTERVAL); player->m_nTickBaseFireBullet = int(player->GetTimeBase() / TICK_INTERVAL);
} }
#else #else
m_vecBulletPositions.Set(iPenetrationCount, tr.endpos);
iPenetrationCount++;
m_iBulletPositionCount.Set(iPenetrationCount);
if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() ) if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() )
{ {
CBasePlayer *player = ToBasePlayer( tr.m_pEnt ); CBasePlayer *player = ToBasePlayer( tr.m_pEnt );
player->RecordServerHitboxes( this ); player->RecordServerHitboxes( this );
}
//
// Propogate a bullet impact event
// @todo Add this for shotgun pellets (which dont go thru here)
//
IGameEvent * event = gameeventmanager->CreateEvent( "bullet_impact" );
if ( event )
{
event->SetFloat( "x", tr.endpos.x );
event->SetFloat( "y", tr.endpos.y );
event->SetFloat("z", tr.endpos.z);
event->SetFloat( "diameter", flBulletDiameter );
gameeventmanager->FireEvent( event );
} }
#endif #endif
} }
@ -592,7 +625,7 @@ void CCSPlayer::FireBullet(
if ( enginetrace->GetPointContents( tr.endpos ) & (CONTENTS_WATER|CONTENTS_SLIME) ) if ( enginetrace->GetPointContents( tr.endpos ) & (CONTENTS_WATER|CONTENTS_SLIME) )
{ {
trace_t waterTrace; trace_t waterTrace;
UTIL_TraceHull( vecSrc, tr.endpos, Vector(-g_bulletDiameter, -g_bulletDiameter, -g_bulletDiameter), Vector(g_bulletDiameter, g_bulletDiameter, g_bulletDiameter), (MASK_SHOT|CONTENTS_WATER|CONTENTS_SLIME), this, COLLISION_GROUP_NONE, &waterTrace ); UTIL_TraceHull( vecSrc, tr.endpos, Vector(-flBulletDiameter, -flBulletDiameter, -flBulletDiameter), Vector(flBulletDiameter, flBulletDiameter, flBulletDiameter), (MASK_SHOT|CONTENTS_WATER|CONTENTS_SLIME), this, COLLISION_GROUP_NONE, &waterTrace );
if( waterTrace.allsolid != 1 ) if( waterTrace.allsolid != 1 )
{ {
@ -675,12 +708,12 @@ void CCSPlayer::FireBullet(
// find exact penetration exit // find exact penetration exit
trace_t exitTr; trace_t exitTr;
UTIL_TraceHull( penetrationEnd, tr.endpos, Vector(-g_bulletDiameter, -g_bulletDiameter, -g_bulletDiameter), Vector(g_bulletDiameter, g_bulletDiameter, g_bulletDiameter), CS_MASK_SHOOT|CONTENTS_HITBOX, NULL, &exitTr ); UTIL_TraceHull( penetrationEnd, tr.endpos, Vector(-flBulletDiameter, -flBulletDiameter, -flBulletDiameter), Vector(flBulletDiameter, flBulletDiameter, flBulletDiameter), CS_MASK_SHOOT|CONTENTS_HITBOX, NULL, &exitTr );
if( exitTr.m_pEnt != tr.m_pEnt && exitTr.m_pEnt != NULL ) if( exitTr.m_pEnt != tr.m_pEnt && exitTr.m_pEnt != NULL )
{ {
// something was blocking, trace again // something was blocking, trace again
UTIL_TraceHull( penetrationEnd, tr.endpos, Vector(-g_bulletDiameter, -g_bulletDiameter, -g_bulletDiameter), Vector(g_bulletDiameter, g_bulletDiameter, g_bulletDiameter), CS_MASK_SHOOT|CONTENTS_HITBOX, exitTr.m_pEnt, COLLISION_GROUP_NONE, &exitTr ); UTIL_TraceHull( penetrationEnd, tr.endpos, Vector(-flBulletDiameter, -flBulletDiameter, -flBulletDiameter), Vector(flBulletDiameter, flBulletDiameter, flBulletDiameter), CS_MASK_SHOOT|CONTENTS_HITBOX, exitTr.m_pEnt, COLLISION_GROUP_NONE, &exitTr );
} }
// get material at exit point // get material at exit point