diff --git a/game/client/c_baseplayer.cpp b/game/client/c_baseplayer.cpp index a22d300df2..a233ea4f6b 100644 --- a/game/client/c_baseplayer.cpp +++ b/game/client/c_baseplayer.cpp @@ -247,7 +247,9 @@ END_RECV_TABLE() RecvPropInt ( RECVINFO( m_nWaterLevel ) ), RecvPropFloat ( RECVINFO( m_flLaggedMovementValue )), -END_RECV_TABLE() + RecvPropArray3 ( RECVINFO_ARRAY(m_vecBulletServerPositions), RecvPropVector( RECVINFO(m_vecBulletServerPositions[0])) ), + RecvPropInt(RECVINFO(m_iBulletServerPositionCount)), + END_RECV_TABLE() // -------------------------------------------------------------------------------- // @@ -443,6 +445,7 @@ C_BasePlayer::C_BasePlayer() : m_iv_vecViewOffset( "C_BasePlayer::m_iv_vecViewOf ListenForGameEvent( "base_player_teleported" ); m_nTickBaseFireBullet = -1; + m_iBulletServerPositionCount = 0; } //----------------------------------------------------------------------------- diff --git a/game/client/c_baseplayer.h b/game/client/c_baseplayer.h index b9933d11c9..0b6b86d7b1 100644 --- a/game/client/c_baseplayer.h +++ b/game/client/c_baseplayer.h @@ -640,6 +640,8 @@ public: void SetOldPlayerZ( float flOld ) { m_flOldPlayerZ = flOld; } int m_nTickBaseFireBullet; + Vector m_vecBulletServerPositions[MAX_PLAYER_BULLET_SERVER_POSITIONS]; + int m_iBulletServerPositionCount; }; EXTERN_RECV_TABLE(DT_BasePlayer); diff --git a/game/client/cstrike/c_cs_player.cpp b/game/client/cstrike/c_cs_player.cpp index 5831224c9c..0981e3c22d 100644 --- a/game/client/cstrike/c_cs_player.cpp +++ b/game/client/cstrike/c_cs_player.cpp @@ -52,6 +52,7 @@ #include "steam/steam_api.h" #include "cs_blackmarket.h" // for vest/helmet prices +#include "weapon_csbase.h" #if defined( CCSPlayer ) #undef CCSPlayer @@ -2226,6 +2227,38 @@ void C_CSPlayer::Simulate( void ) } BaseClass::Simulate(); + + static ConVarRef cl_showimpacts("cl_showimpacts"); + + if ((cl_showimpacts.GetInt() == 1 || cl_showimpacts.GetInt() == 3) && m_lastBulletDiameter != -1.0f && m_iBulletServerPositionCount > 0) + { + auto weaponInfo = GetActiveWeapon(); + + if (!weaponInfo) + { + return; + } + + for (int i = 0; i < m_iBulletServerPositionCount; i++) + { + debugoverlay->AddBoxOverlay( + m_vecBulletServerPositions[i], + Vector(-m_lastBulletDiameter, + -m_lastBulletDiameter, + -m_lastBulletDiameter) + / 2, + Vector(m_lastBulletDiameter, m_lastBulletDiameter, m_lastBulletDiameter) + / 2, + QAngle(0, 0, 0), + 0, + 0, + 255, + 127, + 60); + } + + m_lastBulletDiameter = -1.0f; + } } void C_CSPlayer::PostThink() diff --git a/game/client/cstrike/c_cs_player.h b/game/client/cstrike/c_cs_player.h index 6a820d2785..37851061ad 100644 --- a/game/client/cstrike/c_cs_player.h +++ b/game/client/cstrike/c_cs_player.h @@ -168,6 +168,7 @@ public: public: virtual float GetPlayerMaxSpeed(); + float m_lastBulletDiameter; float GetBulletDiameter(int iBulletType); void GetBulletTypeParameters( int iBulletType, diff --git a/game/server/cstrike/cs_eventlog.cpp b/game/server/cstrike/cs_eventlog.cpp index d1a90a1c3d..6ad09f4119 100644 --- a/game/server/cstrike/cs_eventlog.cpp +++ b/game/server/cstrike/cs_eventlog.cpp @@ -299,36 +299,7 @@ protected: pPlayer->GetNetworkIDString() ); 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: //hostage_hurt //bomb_exploded diff --git a/game/server/player.cpp b/game/server/player.cpp index 049b001e09..d561c9a366 100644 --- a/game/server/player.cpp +++ b/game/server/player.cpp @@ -635,6 +635,7 @@ CBasePlayer::CBasePlayer( ) m_flLastUserCommandTime = 0.f; m_flMovementTimeForUserCmdProcessingRemaining = 0.0f; + m_iBulletServerPositionCount.Set(0); } CBasePlayer::~CBasePlayer( ) @@ -7970,6 +7971,8 @@ void CMovementSpeedMod::InputSpeedMod(inputdata_t &data) SendPropInt ( SENDINFO( m_nWaterLevel ), 2, SPROP_UNSIGNED ), SendPropFloat ( SENDINFO( m_flLaggedMovementValue ), 0, SPROP_NOSCALE ), + SendPropArray3( SENDINFO_ARRAY3(m_vecBulletServerPositions), SendPropVector(SENDINFO_ARRAY(m_vecBulletServerPositions))), + SendPropInt(SENDINFO(m_iBulletServerPositionCount)), END_SEND_TABLE() diff --git a/game/server/player.h b/game/server/player.h index 407a59e001..089085d3a9 100644 --- a/game/server/player.h +++ b/game/server/player.h @@ -1210,6 +1210,8 @@ private: 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 + CNetworkArray(Vector, m_vecBulletServerPositions, MAX_PLAYER_BULLET_SERVER_POSITIONS); + CNetworkVar(int, m_iBulletServerPositionCount); }; typedef CHandle CBasePlayerHandle; diff --git a/game/shared/cstrike/cs_player_shared.cpp b/game/shared/cstrike/cs_player_shared.cpp index c10fe32147..417b3cb9c2 100644 --- a/game/shared/cstrike/cs_player_shared.cpp +++ b/game/shared/cstrike/cs_player_shared.cpp @@ -190,7 +190,12 @@ void UTIL_ClipTraceToPlayersHull( float flBulletDiameter, const Vector& vecAbsSt float smallestFraction = tr->fraction; const float maxRange = 60.0f; - ray.Init( vecAbsStart, vecAbsEnd , Vector(-flBulletDiameter, -flBulletDiameter, -flBulletDiameter), Vector(flBulletDiameter, flBulletDiameter, flBulletDiameter) ); + Vector vecBulletDiameterMaxs(flBulletDiameter, flBulletDiameter, flBulletDiameter); + vecBulletDiameterMaxs /= 2.0f; + Vector vecBulletDiameterMins(-flBulletDiameter, -flBulletDiameter, -flBulletDiameter); + vecBulletDiameterMins /= 2.0f; + + ray.Init( vecAbsStart, vecAbsEnd , vecBulletDiameterMins, vecBulletDiameterMaxs ); for ( int k = 1; k <= gpGlobals->maxClients; ++k ) { @@ -407,13 +412,18 @@ static bool TraceToExit(Vector &start, Vector &dir, Vector &end, float flStepSiz 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 ) { + Vector vecBulletDiameterMaxs(flBulletDiameter, flBulletDiameter, flBulletDiameter); + vecBulletDiameterMaxs /= 2.0f; + Vector vecBulletDiameterMins(-flBulletDiameter, -flBulletDiameter, -flBulletDiameter); + vecBulletDiameterMins /= 2.0f; + Ray_t ray; - ray.Init( vecAbsStart, vecAbsEnd, Vector(-flBulletDiameter, -flBulletDiameter, -flBulletDiameter), Vector(flBulletDiameter, flBulletDiameter, flBulletDiameter) ); + ray.Init( vecAbsStart, vecAbsEnd, vecBulletDiameterMins, vecBulletDiameterMaxs ); CTraceFilterSkipTwoEntities traceFilter( ignore, ignore2, collisionGroup ); enginetrace->TraceRay( ray, mask, &traceFilter, ptr ); if( r_visualizetraces.GetBool() ) { - NDebugOverlay::SweptBox( ptr->startpos, ptr->endpos, Vector(-flBulletDiameter, -flBulletDiameter, -flBulletDiameter), Vector(flBulletDiameter, flBulletDiameter, flBulletDiameter), QAngle(), 255, 0, 0, true, 100.0f ); + NDebugOverlay::SweptBox( ptr->startpos, ptr->endpos, vecBulletDiameterMins, vecBulletDiameterMaxs, QAngle(), 255, 0, 0, true, 100.0f ); } } @@ -442,9 +452,19 @@ void CCSPlayer::FireBullet( float flDamageModifier = 0.5; // default modification of bullets power after they go through a wall. float flPenetrationModifier = 1.f; float flBulletDiameter = 0.0f; - + int iPenetrationCount = 0; + GetBulletTypeParameters( iBulletType, flPenetrationPower, flPenetrationDistance, flBulletDiameter ); +#ifdef CLIENT_DLL + m_lastBulletDiameter = flBulletDiameter; +#endif + + Vector vecBulletDiameterMaxs(flBulletDiameter, flBulletDiameter, flBulletDiameter); + vecBulletDiameterMaxs /= 2.0f; + Vector vecBulletDiameterMins(-flBulletDiameter, -flBulletDiameter, -flBulletDiameter); + vecBulletDiameterMins /= 2.0f; + if ( !pevAttacker ) pevAttacker = this; // the default attacker is ourselves @@ -572,7 +592,7 @@ void CCSPlayer::FireBullet( { #ifdef CLIENT_DLL // draw red client impact markers - debugoverlay->AddBoxOverlay( tr.endpos, Vector(-flBulletDiameter,-flBulletDiameter,-flBulletDiameter), Vector(flBulletDiameter,flBulletDiameter,flBulletDiameter), QAngle( 0, 0, 0), 255,0,0,127, 60 ); + debugoverlay->AddBoxOverlay( tr.endpos, vecBulletDiameterMins, vecBulletDiameterMaxs, QAngle( 0, 0, 0), 255,0,0,127, 60 ); if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() ) { @@ -588,18 +608,11 @@ void CCSPlayer::FireBullet( 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 ); + if (iPenetrationCount < MAX_PLAYER_BULLET_SERVER_POSITIONS) + { + m_vecBulletServerPositions.Set(iPenetrationCount, tr.endpos); + iPenetrationCount++; + m_iBulletServerPositionCount.Set(iPenetrationCount); } #endif } @@ -625,7 +638,7 @@ void CCSPlayer::FireBullet( if ( enginetrace->GetPointContents( tr.endpos ) & (CONTENTS_WATER|CONTENTS_SLIME) ) { trace_t 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 ); + UTIL_TraceHull( vecSrc, tr.endpos, vecBulletDiameterMins, vecBulletDiameterMaxs, (MASK_SHOT|CONTENTS_WATER|CONTENTS_SLIME), this, COLLISION_GROUP_NONE, &waterTrace ); if( waterTrace.allsolid != 1 ) { @@ -708,12 +721,12 @@ void CCSPlayer::FireBullet( // find exact penetration exit trace_t exitTr; - UTIL_TraceHull( penetrationEnd, tr.endpos, Vector(-flBulletDiameter, -flBulletDiameter, -flBulletDiameter), Vector(flBulletDiameter, flBulletDiameter, flBulletDiameter), CS_MASK_SHOOT|CONTENTS_HITBOX, NULL, &exitTr ); + UTIL_TraceHull( penetrationEnd, tr.endpos, vecBulletDiameterMins, vecBulletDiameterMaxs, CS_MASK_SHOOT|CONTENTS_HITBOX, NULL, &exitTr ); if( exitTr.m_pEnt != tr.m_pEnt && exitTr.m_pEnt != NULL ) { // something was blocking, trace again - 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 ); + UTIL_TraceHull( penetrationEnd, tr.endpos, vecBulletDiameterMins, vecBulletDiameterMaxs, CS_MASK_SHOOT|CONTENTS_HITBOX, exitTr.m_pEnt, COLLISION_GROUP_NONE, &exitTr ); } // get material at exit point diff --git a/game/shared/util_shared.h b/game/shared/util_shared.h index ad0059703e..a975529c8e 100644 --- a/game/shared/util_shared.h +++ b/game/shared/util_shared.h @@ -26,7 +26,7 @@ #include "portal_util_shared.h" #endif -#define MAX_PLAYER_BULLET_POSITIONS 128 +#define MAX_PLAYER_BULLET_SERVER_POSITIONS 128 //----------------------------------------------------------------------------- // Forward declarations