diff --git a/.clang-format b/.clang-format index ea8e6cf70e..26db4e14ad 100644 --- a/.clang-format +++ b/.clang-format @@ -103,22 +103,6 @@ ForEachMacros: - BOOST_FOREACH IfMacros: - KJ_IF_MAYBE -IncludeBlocks: Preserve -IncludeCategories: - - Regex: '^"(llvm|llvm-c|clang|clang-c)/' - Priority: 2 - SortPriority: 0 - CaseSensitive: false - - Regex: '^(<|"(gtest|gmock|isl|json)/)' - Priority: 3 - SortPriority: 0 - CaseSensitive: false - - Regex: '.*' - Priority: 1 - SortPriority: 0 - CaseSensitive: false -IncludeIsMainRegex: '(Test)?$' -IncludeIsMainSourceRegex: '' IndentAccessModifiers: false IndentCaseBlocks: false IndentCaseLabels: true diff --git a/game/client/c_baseanimating.cpp b/game/client/c_baseanimating.cpp index d6b2d64932..3b8f76b14e 100644 --- a/game/client/c_baseanimating.cpp +++ b/game/client/c_baseanimating.cpp @@ -5574,6 +5574,49 @@ static Vector hullcolor[8] = Vector( 1.0, 1.0, 1.0 ) }; +void C_BaseAnimating::RecordClientHitboxes() +{ + CStudioHdr *pStudioHdr = GetModelPtr(); + if ( !pStudioHdr ) + return; + + mstudiohitboxset_t *set =pStudioHdr->pHitboxSet( m_nHitboxSet ); + if ( !set ) + return; + + for ( int i = 0; i < set->numhitboxes; i++ ) + { + mstudiobbox_t *pbox = set->pHitbox( i ); + + GetBonePosition( pbox->bone, m_vecHitboxClientPositions[pbox->bone], m_angHitboxClientAngles[pbox->bone] ); + } +} + +void C_BaseAnimating::DrawClientRecordedHitboxes( float duration /*= 0.0f*/, bool monocolor /*= false*/ ) +{ + CStudioHdr *pStudioHdr = GetModelPtr(); + if ( !pStudioHdr ) + return; + + mstudiohitboxset_t *set =pStudioHdr->pHitboxSet( m_nHitboxSet ); + if ( !set ) + return; + + Vector position; + QAngle angles; + + int r = 0; + int g = 255; + int b = 0; + + for ( int i = 0; i < set->numhitboxes; i++ ) + { + mstudiobbox_t *pbox = set->pHitbox( i ); + + debugoverlay->AddBoxOverlay( m_vecHitboxClientPositions[pbox->bone], pbox->bbmin, pbox->bbmax, m_angHitboxClientAngles[pbox->bone], r, g, b, 127 ,duration ); + } +} + //----------------------------------------------------------------------------- // Purpose: Draw the current hitboxes //----------------------------------------------------------------------------- diff --git a/game/client/c_baseanimating.h b/game/client/c_baseanimating.h index 34f4c594ac..2fd3465e97 100644 --- a/game/client/c_baseanimating.h +++ b/game/client/c_baseanimating.h @@ -369,7 +369,9 @@ public: int GetHitboxSet( void ); char const *GetHitboxSetName( void ); int GetHitboxSetCount( void ); + void RecordClientHitboxes(); void DrawClientHitboxes( float duration = 0.0f, bool monocolor = false ); + void DrawClientRecordedHitboxes( float duration = 0.0f, bool monocolor = false ); void DrawServerHitboxes( float duration = 0.0f, bool monocolor = false ); C_BaseAnimating* FindFollowedEntity(); @@ -644,6 +646,8 @@ private: public: Vector m_vecHitboxServerPositions[MAXSTUDIOBONES]; QAngle m_angHitboxServerAngles[MAXSTUDIOBONES]; + Vector m_vecHitboxClientPositions[MAXSTUDIOBONES]; + QAngle m_angHitboxClientAngles[MAXSTUDIOBONES]; }; enum diff --git a/game/client/c_baseplayer.cpp b/game/client/c_baseplayer.cpp index c342baa874..32ddb896fd 100644 --- a/game/client/c_baseplayer.cpp +++ b/game/client/c_baseplayer.cpp @@ -2145,67 +2145,192 @@ void C_BasePlayer::Simulate() static ConVarRef cl_showfirebullethitboxes("cl_showfirebullethitboxes"); static ConVarRef cl_showimpacts("cl_showimpacts"); static ConVarRef cl_showhitboxes("cl_showhitboxes"); - + static ConVarRef debug_screenshot_bullet_position("debug_screenshot_bullet_position"); + + static auto DrawBullet = [&](Vector src, Vector endpos, int r, int g, int b, int a, float duration) + { + NDebugOverlay::SweptBox(src, + endpos, + Vector(-m_lastBulletDiameter, -m_lastBulletDiameter, -m_lastBulletDiameter) / 2, + Vector(m_lastBulletDiameter, m_lastBulletDiameter, m_lastBulletDiameter) / 2, + QAngle(0, 0, 0), + r, + g, + b, + a, + duration); + NDebugOverlay::Box(endpos, + Vector(-m_lastBulletDiameter, -m_lastBulletDiameter, -m_lastBulletDiameter) / 2, + Vector(m_lastBulletDiameter, m_lastBulletDiameter, m_lastBulletDiameter) / 2, + r, + g, + b, + a, + duration); + }; + + // HACK: Server var is always more delayed than client, should be safe. if (m_bDebugServerBullets && IsLocalPlayer()) { - if (cl_showimpacts.GetInt() == 1 || cl_showimpacts.GetInt() == 3) + bool shouldDrawClientBullets = cl_showimpacts.GetInt() == 1 || cl_showimpacts.GetInt() == 3; + bool shouldDrawServerBullets = cl_showimpacts.GetInt() == 1 || cl_showimpacts.GetInt() == 2; + static constexpr float flShowDuration = 60.f; + + if (shouldDrawClientBullets) { - for (int i = 0; i < m_vecServerShootPositions.Count(); i++) + for (int i = 0; i < m_vecClientShootPositions.Count(); i++) { - NDebugOverlay::SweptBox(m_vecServerShootPositions[i], - 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.f); - NDebugOverlay::Box(m_vecBulletServerPositions[i], - Vector(-m_lastBulletDiameter, -m_lastBulletDiameter, -m_lastBulletDiameter) / 2, - Vector(m_lastBulletDiameter, m_lastBulletDiameter, m_lastBulletDiameter) / 2, - 0, - 0, - 255, - 127, - 60.f); + DrawBullet(m_vecClientShootPositions[i], + m_vecBulletClientPositions[i], + 0, + 255, + 0, + 127, + flShowDuration); } } - if (cl_showfirebullethitboxes.GetBool()) + if (shouldDrawServerBullets) + { + for (int i = 0; i < m_vecServerShootPositions.Count(); i++) + { + DrawBullet(m_vecServerShootPositions[i], + m_vecBulletServerPositions[i], + 0, + 0, + 255, + 127, + flShowDuration); + } + } + + bool shouldDrawClientSS = debug_screenshot_bullet_position.GetInt() == 1 || debug_screenshot_bullet_position.GetInt() == 3; + bool shouldDrawServerSS = debug_screenshot_bullet_position.GetInt() == 1 || debug_screenshot_bullet_position.GetInt() == 2; + + if (shouldDrawClientSS) + { + for (int i = 0; i < m_vecClientShootPositions.Count(); i++) + { + DrawBullet(m_vecClientShootPositions[i], + m_vecBulletClientPositions[i], + 0, + 255, + 0, + 127, + gpGlobals->frametime); + } + } + + if (shouldDrawServerSS) + { + for (int i = 0; i < m_vecServerShootPositions.Count(); i++) + { + DrawBullet(m_vecServerShootPositions[i], + m_vecBulletServerPositions[i], + 0, + 0, + 255, + 127, + gpGlobals->frametime); + } + } + + bool shouldDrawClientBulletPlayerHitbox = cl_showfirebullethitboxes.GetInt() == 1 || cl_showfirebullethitboxes.GetInt() == 3; + bool shouldDrawServerBulletPlayerHitbox = cl_showfirebullethitboxes.GetInt() == 1 || cl_showfirebullethitboxes.GetInt() == 2; + + if (shouldDrawClientBulletPlayerHitbox || shouldDrawServerBulletPlayerHitbox) { for (int i = 1; i <= gpGlobals->maxClients; i++) { auto player = UTIL_PlayerByIndex(i); - if (player && !player->IsLocalPlayer()) + if (!player || player->IsLocalPlayer()) { - player->DrawServerHitboxes(60.0f, true); + continue; + } + + if (shouldDrawClientBulletPlayerHitbox) + { + player->DrawClientRecordedHitboxes(flShowDuration, true); + } + + if (shouldDrawServerBulletPlayerHitbox) + { + player->DrawServerHitboxes(flShowDuration, true); } } } - else + else if (shouldDrawClientBullets || shouldDrawServerBullets) { for (auto&& entityIndex : m_touchedEntitiesWithBullet) { auto player = UTIL_PlayerByIndex(entityIndex); - if (player && !player->IsLocalPlayer()) + if (!player || player->IsLocalPlayer()) { - player->DrawServerHitboxes(60.0f, true); + continue; + } + + if (shouldDrawClientBullets) + { + player->DrawClientRecordedHitboxes(flShowDuration, true); + } + + if (shouldDrawServerBullets) + { + player->DrawServerHitboxes(flShowDuration, true); } } } - + + if (shouldDrawClientSS || shouldDrawServerSS) + { + for (auto&& entityIndex : m_touchedEntitiesWithBullet) + { + auto player = UTIL_PlayerByIndex(entityIndex); + + if (!player || player->IsLocalPlayer()) + { + continue; + } + + if (shouldDrawClientSS) + { + player->DrawClientRecordedHitboxes(gpGlobals->frametime, true); + } + + if (shouldDrawServerSS) + { + player->DrawServerHitboxes(gpGlobals->frametime, true); + } + } + } + + if (shouldDrawClientSS || shouldDrawServerSS) + { + gpGlobals->client_taking_screenshot = true; + } + + // Remove accumulated client bullets. + m_vecBulletClientPositions.RemoveAll(); + m_vecClientShootPositions.RemoveAll(); m_bDebugServerBullets = false; } - if (cl_showhitboxes.GetBool() && IsPlayer() && this != GetLocalPlayer()) + bool shouldShowClientHitboxes = cl_showhitboxes.GetInt() == 1 || cl_showhitboxes.GetInt() == 3; + bool shouldShowServerHitboxes = cl_showhitboxes.GetInt() == 1 || cl_showhitboxes.GetInt() == 2; + bool shouldShowHitboxes = IsPlayer() && this != GetLocalPlayer(); + + if (shouldShowClientHitboxes && shouldShowHitboxes) + { + RecordClientHitboxes(); + DrawClientRecordedHitboxes(gpGlobals->frametime, true); + } + + if (shouldShowServerHitboxes && shouldShowHitboxes) { - DrawClientHitboxes(gpGlobals->frametime, true); DrawServerHitboxes(gpGlobals->frametime, true); - } + } } //----------------------------------------------------------------------------- diff --git a/game/client/c_baseplayer.h b/game/client/c_baseplayer.h index 9798f29853..2aceac4f04 100644 --- a/game/client/c_baseplayer.h +++ b/game/client/c_baseplayer.h @@ -645,6 +645,8 @@ public: CUtlVector m_vecBulletServerPositions; CUtlVector m_vecServerShootPositions; CUtlVector m_touchedEntitiesWithBullet; + CUtlVector m_vecBulletClientPositions; + CUtlVector m_vecClientShootPositions; }; EXTERN_RECV_TABLE(DT_BasePlayer); diff --git a/game/client/in_main.cpp b/game/client/in_main.cpp index 47d2294834..e44e544f83 100644 --- a/game/client/in_main.cpp +++ b/game/client/in_main.cpp @@ -1315,7 +1315,8 @@ void CInput::CreateMove ( int sequence_number, float input_sample_frametime, boo } static ConVarRef cl_showhitboxes("cl_showhitboxes"); - + static ConVarRef debug_screenshot_bullet_position("debug_screenshot_bullet_position"); + cmd->debug_hitboxes = CUserCmd::DEBUG_HITBOXES_OFF; if (cl_showhitboxes.GetBool()) @@ -1328,12 +1329,11 @@ void CInput::CreateMove ( int sequence_number, float input_sample_frametime, boo cmd->debug_hitboxes |= CUserCmd::DEBUG_HITBOXES_ON_FIRE; } - if (cl_showimpacts.GetInt() == 1 || cl_showimpacts.GetInt() == 3) + if (cl_showimpacts.GetBool() || debug_screenshot_bullet_position.GetBool()) { cmd->debug_hitboxes |= CUserCmd::DEBUG_HITBOXES_ON_HIT; } - pVerified->m_cmd = *cmd; pVerified->m_crc = cmd->GetChecksum(); } diff --git a/game/client/prediction.cpp b/game/client/prediction.cpp index a4e3f8a4f6..605aa9d2cc 100644 --- a/game/client/prediction.cpp +++ b/game/client/prediction.cpp @@ -22,6 +22,7 @@ #include "con_nprint.h" #include "hud_pdump.h" #include "datacache/imdlcache.h" +#include "util_shared.h" #ifdef HL2_CLIENT_DLL #include "c_basehlplayer.h" @@ -895,7 +896,9 @@ void CPrediction::RunCommand( C_BasePlayer *player, CUserCmd *ucmd, IMoveHelper { player->SetLocalViewAngles( ucmd->viewangles ); } - + + // Always record for debugging. + // Sometimes the hitbox wasn't hit by the player client side! RunPostThink( player ); // TODO diff --git a/game/shared/cstrike/cs_player_shared.cpp b/game/shared/cstrike/cs_player_shared.cpp index 7ec5cf7f68..012cb2454b 100644 --- a/game/shared/cstrike/cs_player_shared.cpp +++ b/game/shared/cstrike/cs_player_shared.cpp @@ -489,35 +489,28 @@ void CCSPlayer::FireBullet( CBasePlayer *lastPlayerHit = NULL; MDLCACHE_CRITICAL_SECTION(); -#ifdef CLIENT_DLL - static ConVarRef cl_showfirebullethitboxes("cl_showfirebullethitboxes"); + bool shouldTakeAllPlayers = m_pCurrentCommand->debug_hitboxes & CUserCmd::DEBUG_HITBOXES_ON_FIRE; + bool shouldTakeHitPlayer = m_pCurrentCommand->debug_hitboxes & CUserCmd::DEBUG_HITBOXES_ON_HIT; - if (cl_showfirebullethitboxes.GetBool() && IsLocalPlayer()) - { - for (int i = 1; i <= gpGlobals->maxClients; i++) - { - CBasePlayer* lagPlayer = UTIL_PlayerByIndex(i); - - if ( lagPlayer && !lagPlayer->IsLocalPlayer() && IsLocalPlayer()) - { - lagPlayer->DrawClientHitboxes(60, true); - } - } - } -#else - if ( m_pCurrentCommand->debug_hitboxes & CUserCmd::DEBUG_HITBOXES_ON_FIRE ) + if ( shouldTakeAllPlayers && !shouldTakeHitPlayer ) { for (int i = 1; i <= gpGlobals->maxClients; i++) { CBasePlayer* lagPlayer = UTIL_PlayerByIndex(i); if( lagPlayer ) - { - lagPlayer->RecordServerHitboxes(this); + { +#ifdef CLIENT_DLL + if (!m_pCurrentCommand->hasbeenpredicted) + { + lagPlayer->RecordClientHitboxes(); + } +#else + lagPlayer->RecordServerHitboxes(this); +#endif } } } -#endif while ( fCurrentDamage > 0 ) { @@ -563,56 +556,34 @@ void CCSPlayer::FireBullet( flDamageModifier = 0.99f; } - -#ifdef CLIENT_DLL - m_lastBulletDiameter = flBulletDiameter; - - static ConVarRef cl_showimpacts("cl_showimpacts"); - - if ((cl_showimpacts.GetInt() == 1 || cl_showimpacts.GetInt() == 2) && IsLocalPlayer()) - { - NDebugOverlay::SweptBox(vecSrc, - tr.endpos, - vecBulletRadiusMins, - vecBulletRadiusMaxs, - QAngle(0, 0, 0), - 255, - 0, - 0, - 127, - 60.0f); - NDebugOverlay::Box(tr.endpos, vecBulletRadiusMins, vecBulletRadiusMaxs, 255, 0, 0, 127, 60.f); - } - - if (tr.m_pEnt && tr.m_pEnt->IsPlayer()) - { - C_BasePlayer* player = ToBasePlayer(tr.m_pEnt); - - if ((cl_showimpacts.GetInt() == 1 || cl_showimpacts.GetInt() == 2) && IsLocalPlayer()) - { - player->DrawClientHitboxes(60.0f, true); - } - } -#else - bool shouldShowServerHitRegistration = m_pCurrentCommand->debug_hitboxes & CUserCmd::DEBUG_HITBOXES_ON_HIT; - - if (shouldShowServerHitRegistration) + if (shouldTakeHitPlayer) { +#ifndef CLIENT_DLL m_vecBulletServerPositions.AddToTail(tr.endpos); m_vecServerShootPositions.AddToTail(vecSrc); - +#else + m_vecBulletClientPositions.AddToTail(tr.endpos); + m_vecClientShootPositions.AddToTail(vecSrc); +#endif if (tr.m_pEnt) { +#ifndef CLIENT_DLL m_touchedEntitiesWithBullet.AddToTail(tr.m_pEnt->entindex()); - } - - if (tr.m_pEnt && tr.m_pEnt->IsPlayer()) - { - CBasePlayer* player = ToBasePlayer(tr.m_pEnt); - player->RecordServerHitboxes(this); +#endif + if (tr.m_pEnt->IsPlayer() && !shouldTakeAllPlayers) + { + CBasePlayer* player = ToBasePlayer(tr.m_pEnt); + #ifdef CLIENT_DLL + if (!m_pCurrentCommand->hasbeenpredicted) + { + player->RecordClientHitboxes(); + } + #else + player->RecordServerHitboxes(this); + #endif + } } } -#endif //calculate the damage based on the distance the bullet travelled. flCurrentDistance += tr.fraction * flDistance; diff --git a/game/shared/cstrike/fx_cs_shared.cpp b/game/shared/cstrike/fx_cs_shared.cpp index e15caedaa8..4ee714f987 100644 --- a/game/shared/cstrike/fx_cs_shared.cpp +++ b/game/shared/cstrike/fx_cs_shared.cpp @@ -300,11 +300,13 @@ void FX_FireBullets( for ( int iBullet=0; iBullet < pWeaponInfo->m_iBullets; iBullet++ ) { + // Still take the screenshot where we shooted, make a screenshot when we received the server bullet hits too. #ifdef CLIENT_DLL - if (debug_screenshot_bullet_position.GetBool()) + static ConVarRef debug_screenshot_bullet_position("debug_screenshot_bullet_position"); + if (pPlayer->IsLocalPlayer() && debug_screenshot_bullet_position.GetBool()) { gpGlobals->client_taking_screenshot = true; - } + } #endif pPlayer->FireBullet( iBullet,