Added more infos to debug out hitboxes
This commit is contained in:
parent
ece2f9a81f
commit
f4ded28fe0
8 changed files with 283 additions and 53 deletions
|
@ -149,24 +149,8 @@ const unsigned int FCLIENTANIM_SEQUENCE_CYCLE = 0x00000001;
|
|||
|
||||
static CUtlVector< clientanimating_t > g_ClientSideAnimationList;
|
||||
|
||||
void RecvProxy_Sequence( const CRecvProxyData *pData, void *pStruct, void *pOut )
|
||||
{
|
||||
// Have the regular proxy store the data.
|
||||
RecvProxy_Int32ToInt32( pData, pStruct, pOut );
|
||||
|
||||
C_BaseAnimating *pAnimating = (C_BaseAnimating *)pStruct;
|
||||
|
||||
if ( !pAnimating )
|
||||
return;
|
||||
|
||||
pAnimating->SetReceivedSequence();
|
||||
|
||||
// render bounds may have changed
|
||||
pAnimating->UpdateVisibility();
|
||||
}
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_BaseAnimating, DT_BaseAnimating, CBaseAnimating)
|
||||
RecvPropInt(RECVINFO(m_nSequence), 0, RecvProxy_Sequence),
|
||||
RecvPropInt(RECVINFO(m_nSequence)),
|
||||
RecvPropInt(RECVINFO(m_nForceBone)),
|
||||
RecvPropVector(RECVINFO(m_vecForce)),
|
||||
RecvPropInt(RECVINFO(m_nSkin)),
|
||||
|
|
|
@ -521,9 +521,12 @@ private:
|
|||
bool m_bWasFrozen;
|
||||
int m_flPhysics;
|
||||
|
||||
public:
|
||||
int m_nTickBase;
|
||||
int m_nFinalPredictedTick;
|
||||
|
||||
public:
|
||||
|
||||
EHANDLE m_pCurrentVguiScreen;
|
||||
|
||||
bool m_bFiredWeapon;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "interpolatedvar.h"
|
||||
#include "mathlib/vector.h"
|
||||
#include "shareddefs.h"
|
||||
#include "strtools.h"
|
||||
#include "studio.h"
|
||||
#include "util_shared.h"
|
||||
#include "view.h"
|
||||
|
@ -2145,10 +2146,14 @@ void C_CSPlayer::FireGameEvent( IGameEvent* event )
|
|||
|
||||
if ( player && !player->IsLocalPlayer() )
|
||||
{
|
||||
const auto nAttackerTickBase = event->GetInt( "tickbase" );
|
||||
|
||||
const auto numhitboxes = event->GetInt( "num_hitboxes" );
|
||||
QAngle angles[MAXSTUDIOBONES];
|
||||
Vector positions[MAXSTUDIOBONES];
|
||||
|
||||
Assert( numhitboxes == player->GetModelPtr()->numbones() );
|
||||
|
||||
for ( int i = 0; i < numhitboxes; i++ )
|
||||
{
|
||||
char buffer[256];
|
||||
|
@ -2175,11 +2180,12 @@ void C_CSPlayer::FireGameEvent( IGameEvent* event )
|
|||
// Let's see what the client thinks to check if there's any problems with hitboxes
|
||||
float flBackupPoseParams[MAXSTUDIOPOSEPARAM];
|
||||
float flBackupBoneControllers[MAXSTUDIOBONECTRLS];
|
||||
|
||||
C_AnimationLayer backupAnimLayers[C_BaseAnimatingOverlay::MAX_OVERLAYS];
|
||||
Vector vecBackupPosition = player->GetAbsOrigin();
|
||||
QAngle angBackupAngles = player->GetRenderAngles();
|
||||
auto flOldCycle = GetCycle();
|
||||
auto iOldSequence = GetSequence();
|
||||
auto flOldCycle = player->GetCycle();
|
||||
auto iOldSequence = player->GetSequence();
|
||||
|
||||
for ( int i = 0; i < MAXSTUDIOPOSEPARAM; i++ )
|
||||
{
|
||||
|
@ -2191,13 +2197,13 @@ void C_CSPlayer::FireGameEvent( IGameEvent* event )
|
|||
flBackupBoneControllers[i] = player->m_flEncodedController[i];
|
||||
}
|
||||
|
||||
for ( int i = 0; i < GetNumAnimOverlays(); i++ )
|
||||
for ( int i = 0; i < player->GetNumAnimOverlays(); i++ )
|
||||
{
|
||||
backupAnimLayers[i] = *player->GetAnimOverlay(i);
|
||||
}
|
||||
|
||||
player->SetSequence( event->GetInt( "sequence" ) );
|
||||
player->SetCycle( event->GetFloat( "cycle" ) );
|
||||
player->m_nSequence = event->GetInt( "sequence" );
|
||||
player->m_flCycle = event->GetFloat( "cycle" );
|
||||
player->SetAbsOrigin( Vector( event->GetFloat( "position_x" ),
|
||||
event->GetFloat( "position_y" ),
|
||||
event->GetFloat( "position_z" ) ) );
|
||||
|
@ -2207,7 +2213,7 @@ void C_CSPlayer::FireGameEvent( IGameEvent* event )
|
|||
event->GetFloat( "angle_z" ) );
|
||||
|
||||
const auto numposeparams = event->GetInt( "num_poseparams" );
|
||||
Assert( numposeparams == pStudioHdr->GetNumPoseParameters() );
|
||||
Assert( numposeparams == player->GetModelPtr()->GetNumPoseParameters() );
|
||||
|
||||
for ( int i = 0; i < numposeparams; i++ )
|
||||
{
|
||||
|
@ -2218,7 +2224,7 @@ void C_CSPlayer::FireGameEvent( IGameEvent* event )
|
|||
}
|
||||
|
||||
const auto numbonecontrollers = event->GetInt( "num_bonecontrollers" );
|
||||
Assert( numbonecontrollers == pStudioHdr->GetNumBoneControllers() );
|
||||
Assert( numbonecontrollers == player->GetModelPtr()->GetNumBoneControllers() );
|
||||
|
||||
for ( int i = 0; i < numbonecontrollers; i++ )
|
||||
{
|
||||
|
@ -2252,17 +2258,168 @@ void C_CSPlayer::FireGameEvent( IGameEvent* event )
|
|||
animOverlay->m_fFlags = event->GetInt( buffer );
|
||||
}
|
||||
|
||||
player->PushAllowBoneAccess( true, false, "Lag compensation context" );
|
||||
// Let's see if anything wrong has happened, print some infos.
|
||||
HitboxRecord* pRecord = nullptr;
|
||||
|
||||
for ( int i = 0; i < MAX_HISTORY_HITBOX_RECORDS; i++ )
|
||||
{
|
||||
pRecord = m_HitboxTrack[player->index].Get( i );
|
||||
|
||||
if ( pRecord && ( pRecord->m_nAttackerTickBase == nAttackerTickBase ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( pRecord )
|
||||
{
|
||||
// Let's check what went wrong.
|
||||
int pos = 0;
|
||||
|
||||
auto newOrigin = player->GetAbsOrigin();
|
||||
|
||||
if ( pRecord->m_vecAbsOrigin != newOrigin )
|
||||
{
|
||||
char buffer[256];
|
||||
V_sprintf_safe( buffer,
|
||||
"pos: %f != %f, %f != %f, %f != %f",
|
||||
newOrigin.x,
|
||||
pRecord->m_vecAbsOrigin.x,
|
||||
newOrigin.y,
|
||||
pRecord->m_vecAbsOrigin.y,
|
||||
newOrigin.z,
|
||||
pRecord->m_vecAbsOrigin.z );
|
||||
|
||||
NDebugOverlay::EntityTextAtPosition( pRecord->m_vecAbsOrigin, pos, buffer, flDuration );
|
||||
pos++;
|
||||
}
|
||||
|
||||
if ( pRecord->m_angRenderAngles != player->m_angRenderAngles )
|
||||
{
|
||||
char buffer[256];
|
||||
V_sprintf_safe( buffer,
|
||||
"angles: %f != %f, %f != %f, %f != %f",
|
||||
player->m_angRenderAngles.x,
|
||||
pRecord->m_angRenderAngles.x,
|
||||
player->m_angRenderAngles.y,
|
||||
pRecord->m_angRenderAngles.y,
|
||||
player->m_angRenderAngles.z,
|
||||
pRecord->m_angRenderAngles.z );
|
||||
|
||||
NDebugOverlay::EntityTextAtPosition( pRecord->m_vecAbsOrigin, pos, buffer, flDuration );
|
||||
pos++;
|
||||
}
|
||||
|
||||
if ( pRecord->m_flCycle != player->m_flCycle )
|
||||
{
|
||||
char buffer[256];
|
||||
V_sprintf_safe( buffer, "cycle: %f != %f", player->m_flCycle, pRecord->m_flCycle );
|
||||
|
||||
NDebugOverlay::EntityTextAtPosition( pRecord->m_vecAbsOrigin, pos, buffer, flDuration );
|
||||
pos++;
|
||||
}
|
||||
|
||||
if ( pRecord->m_nSequence != player->m_nSequence )
|
||||
{
|
||||
char buffer[256];
|
||||
V_sprintf_safe( buffer,
|
||||
"sequence: %s(%i) != %s(%i)",
|
||||
player->GetSequenceName( player->m_nSequence ),
|
||||
player->m_nSequence,
|
||||
player->GetSequenceName( pRecord->m_nSequence ),
|
||||
pRecord->m_nSequence );
|
||||
|
||||
NDebugOverlay::EntityTextAtPosition( pRecord->m_vecAbsOrigin, pos, buffer, flDuration );
|
||||
pos++;
|
||||
}
|
||||
|
||||
auto mdl = player->GetModelPtr();
|
||||
|
||||
for ( int i = 0; i < mdl->GetNumPoseParameters(); i++ )
|
||||
{
|
||||
if ( pRecord->m_flPoseParameters[i] != player->m_flPoseParameter[i] )
|
||||
{
|
||||
char buffer[256];
|
||||
V_sprintf_safe( buffer,
|
||||
"pose parameter %s (%i): %f != %f",
|
||||
mdl->pPoseParameter( i ).pszName(),
|
||||
i,
|
||||
player->m_flPoseParameter[i],
|
||||
pRecord->m_flPoseParameters[i] );
|
||||
|
||||
NDebugOverlay::EntityTextAtPosition( pRecord->m_vecAbsOrigin, pos, buffer, flDuration );
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
for ( int i = 0; i < mdl->GetNumBoneControllers(); i++ )
|
||||
{
|
||||
if ( pRecord->m_flEncodedControllers[i] != player->m_flEncodedController[i] )
|
||||
{
|
||||
char buffer[256];
|
||||
V_sprintf_safe( buffer,
|
||||
"bone controller %i (%i): %f != %f",
|
||||
mdl->pBonecontroller( i )->bone,
|
||||
i,
|
||||
player->m_flEncodedController[i],
|
||||
pRecord->m_flEncodedControllers[i] );
|
||||
|
||||
NDebugOverlay::EntityTextAtPosition( pRecord->m_vecAbsOrigin, pos, buffer, flDuration );
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
for ( int i = 0; i < player->GetNumAnimOverlays(); i++ )
|
||||
{
|
||||
auto animOverlay = player->GetAnimOverlay( i );
|
||||
|
||||
if ( animOverlay->m_flCycle != pRecord->m_AnimationLayer[i].m_flCycle
|
||||
|| animOverlay->m_flWeight != pRecord->m_AnimationLayer[i].m_flWeight
|
||||
|| animOverlay->m_nSequence != pRecord->m_AnimationLayer[i].m_nSequence
|
||||
|| animOverlay->m_nOrder != pRecord->m_AnimationLayer[i].m_nOrder
|
||||
|| animOverlay->m_fFlags != pRecord->m_AnimationLayer[i].m_fFlags )
|
||||
{
|
||||
char buffer[256];
|
||||
V_sprintf_safe( buffer,
|
||||
"anim overlay %i: sequence: %s != %s ( %i != %i ), cycle: %f != %f, "
|
||||
"weight: %f != %f, order %i != %i, flags: %i != %i",
|
||||
i,
|
||||
GetSequenceName( animOverlay->m_nSequence ),
|
||||
GetSequenceName( pRecord->m_AnimationLayer[i].m_nSequence ),
|
||||
animOverlay->m_nSequence,
|
||||
pRecord->m_AnimationLayer[i].m_nSequence,
|
||||
animOverlay->m_flCycle,
|
||||
pRecord->m_AnimationLayer[i].m_flCycle,
|
||||
animOverlay->m_flWeight,
|
||||
pRecord->m_AnimationLayer[i].m_flWeight,
|
||||
animOverlay->m_nOrder,
|
||||
pRecord->m_AnimationLayer[i].m_nOrder,
|
||||
animOverlay->m_fFlags,
|
||||
pRecord->m_AnimationLayer[i].m_fFlags );
|
||||
|
||||
NDebugOverlay::EntityTextAtPosition( pRecord->m_vecAbsOrigin, pos, buffer, flDuration );
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DevMsg( "Could not get record info for player %s (%i) with tickbase %i\n",
|
||||
player->GetPlayerName(),
|
||||
player->index,
|
||||
nAttackerTickBase );
|
||||
}
|
||||
|
||||
player->PushAllowBoneAccess( true, false, "Lag compensation context" );
|
||||
// Be sure we setup the bones again.
|
||||
player->InvalidateBoneCache();
|
||||
player->SetupBones( NULL, -1, BONE_USED_BY_ANYTHING, gpGlobals->curtime );
|
||||
player->DrawClientHitboxes( cl_debug_duration.GetFloat(), false );
|
||||
player->DrawClientHitboxes( flDuration, false );
|
||||
player->PopBoneAccess( "Lag compensation context" );
|
||||
|
||||
// Set back original stuff.
|
||||
player->SetSequence( iOldSequence );
|
||||
player->SetCycle( flOldCycle );
|
||||
player->m_nSequence = iOldSequence;
|
||||
player->m_flCycle = flOldCycle;
|
||||
player->SetAbsOrigin( vecBackupPosition );
|
||||
player->m_angRenderAngles = angBackupAngles;
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "cs_playeranimstate.h"
|
||||
#include "c_baseplayer.h"
|
||||
#include "cs_shareddefs.h"
|
||||
|
@ -31,8 +30,6 @@ public:
|
|||
int m_iAttachmentPoint; // Which attachment point on the player model this guy is on.
|
||||
};
|
||||
|
||||
|
||||
|
||||
class C_CSPlayer : public C_BasePlayer, public ICSPlayerAnimStateHelpers
|
||||
{
|
||||
public:
|
||||
|
@ -328,8 +325,10 @@ private:
|
|||
bool m_bHasHelmet;
|
||||
int m_iClass;
|
||||
int m_ArmorValue;
|
||||
public:
|
||||
QAngle m_angEyeAngles;
|
||||
QAngle m_angRenderAngles;
|
||||
private:
|
||||
bool m_bHasDefuser;
|
||||
float m_fNextThinkPushAway;
|
||||
|
||||
|
@ -393,7 +392,36 @@ private:
|
|||
int a,
|
||||
float duration);
|
||||
|
||||
C_CSPlayer( const C_CSPlayer & );
|
||||
C_CSPlayer( const C_CSPlayer& );
|
||||
|
||||
public:
|
||||
// Around 256 bullets, should be way enough to debug out what happned...
|
||||
static constexpr auto MAX_HISTORY_HITBOX_RECORDS = 256;
|
||||
|
||||
struct AnimLayerRecord
|
||||
{
|
||||
int m_nSequence;
|
||||
float m_flCycle;
|
||||
float m_flWeight;
|
||||
int m_nOrder;
|
||||
int m_fFlags;
|
||||
};
|
||||
|
||||
struct HitboxRecord
|
||||
{
|
||||
int m_nAttackerTickBase;
|
||||
Vector m_vecAbsOrigin;
|
||||
QAngle m_angRenderAngles;
|
||||
float m_flSimulationTime;
|
||||
int m_nSequence;
|
||||
float m_flCycle;
|
||||
float m_flAnimTime;
|
||||
AnimLayerRecord m_AnimationLayer[MAX_LAYER_RECORDS];
|
||||
float m_flPoseParameters[MAXSTUDIOPOSEPARAM];
|
||||
float m_flEncodedControllers[MAXSTUDIOBONECTRLS];
|
||||
};
|
||||
|
||||
CUtlCircularBuffer< HitboxRecord, MAX_HISTORY_HITBOX_RECORDS > m_HitboxTrack[MAX_PLAYERS + 1];
|
||||
};
|
||||
|
||||
C_CSPlayer* GetLocalOrInEyeCSPlayer( void );
|
||||
|
|
|
@ -683,8 +683,9 @@ void CBasePlayer::SetupVisibility( CBaseEntity *pViewEntity, unsigned char *pvs,
|
|||
|
||||
int CBasePlayer::UpdateTransmitState()
|
||||
{
|
||||
// TODO_ENHANCED: this fucks up animations.
|
||||
// always call ShouldTransmit() for players
|
||||
return SetTransmitState( FL_EDICT_FULLCHECK );
|
||||
return SetTransmitState( FL_EDICT_ALWAYS );
|
||||
}
|
||||
|
||||
int CBasePlayer::ShouldTransmit( const CCheckTransmitInfo *pInfo )
|
||||
|
|
|
@ -159,7 +159,7 @@ struct LagRecord
|
|||
// If it can't get there, leave the player where he is.
|
||||
//
|
||||
|
||||
ConVar sv_unlag_debug( "sv_unlag_debug", "0", FCVAR_GAMEDLL | FCVAR_DEVELOPMENTONLY );
|
||||
ConVar sv_unlag_debug( "sv_unlag_debug", "0" );
|
||||
|
||||
float g_flFractionScale = 0.95;
|
||||
|
||||
|
@ -426,6 +426,8 @@ void CLagCompensationManager::BacktrackPlayer( CBasePlayer* pPlayer, CUserCmd* c
|
|||
|
||||
// get track history of this player
|
||||
auto track = &m_EntityTrack[pl_index];
|
||||
bool foundSim = false;
|
||||
bool foundAnim = false;
|
||||
|
||||
for ( int i = 0; i < MAX_TICKS_SAVED; i++ )
|
||||
{
|
||||
|
@ -443,11 +445,13 @@ void CLagCompensationManager::BacktrackPlayer( CBasePlayer* pPlayer, CUserCmd* c
|
|||
|
||||
if ( flTargetSimTime == recordSim->m_flSimulationTime )
|
||||
{
|
||||
foundSim = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( recordSim->m_flSimulationTime < flTargetSimTime )
|
||||
{
|
||||
foundSim = true;
|
||||
prevRecordSim = track->Get( i - 1 );
|
||||
break;
|
||||
}
|
||||
|
@ -464,6 +468,7 @@ void CLagCompensationManager::BacktrackPlayer( CBasePlayer* pPlayer, CUserCmd* c
|
|||
|
||||
if ( recordAnim->m_flAnimTime == flTargetAnimTime )
|
||||
{
|
||||
foundAnim = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -471,7 +476,7 @@ void CLagCompensationManager::BacktrackPlayer( CBasePlayer* pPlayer, CUserCmd* c
|
|||
Assert( recordAnim );
|
||||
Assert( recordSim );
|
||||
|
||||
if ( !recordSim || !recordAnim )
|
||||
if ( !foundAnim || !foundSim )
|
||||
{
|
||||
if ( sv_unlag_debug.GetBool() )
|
||||
{
|
||||
|
@ -489,7 +494,7 @@ void CLagCompensationManager::BacktrackPlayer( CBasePlayer* pPlayer, CUserCmd* c
|
|||
// so interpolate between these two records;
|
||||
|
||||
Assert( prevRecordSim->m_flSimulationTime > recordSim->m_flSimulationTime );
|
||||
Assert( flTargetLerpSimTime < prevRecordSim->m_flSimulationTime );
|
||||
Assert( flTargetSimTime < prevRecordSim->m_flSimulationTime );
|
||||
|
||||
// calc fraction between both records
|
||||
fracSim = float( ( double( flTargetSimTime ) - double( recordSim->m_flSimulationTime ) )
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "cbase.h"
|
||||
#include "const.h"
|
||||
#include "debugoverlay_shared.h"
|
||||
#include "shareddefs.h"
|
||||
#include "strtools.h"
|
||||
#ifndef CLIENT_DLL
|
||||
#include "player.h"
|
||||
|
@ -526,16 +527,16 @@ void CCSPlayer::FireBullet(
|
|||
#ifndef CLIENT_DLL
|
||||
auto WritePlayerHitboxEvent = [&]( CBasePlayer* lagPlayer )
|
||||
{
|
||||
if ( IsBot() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IGameEvent* event = gameeventmanager->CreateEvent( "bullet_player_hitboxes" );
|
||||
if ( event )
|
||||
{
|
||||
event->SetInt( "userid", GetUserID() );
|
||||
event->SetInt( "player_index", lagPlayer->entindex() );
|
||||
event->SetInt( "tickbase", TIME_TO_TICKS( GetTimeBase() ) );
|
||||
event->SetInt( "bullet", iBullet );
|
||||
|
||||
event->SetFloat( "simtime", lagPlayer->GetSimulationTime() );
|
||||
event->SetFloat( "animtime", lagPlayer->GetAnimTime() );
|
||||
|
||||
Vector positions[MAXSTUDIOBONES];
|
||||
QAngle angles[MAXSTUDIOBONES];
|
||||
|
@ -718,6 +719,8 @@ void CCSPlayer::FireBullet(
|
|||
event->SetFloat( "dst_y", tr.endpos.y );
|
||||
event->SetFloat( "dst_z", tr.endpos.z );
|
||||
event->SetFloat( "radius", flBulletRadius );
|
||||
event->SetInt( "tickbase", TIME_TO_TICKS( GetTimeBase() ) );
|
||||
event->SetInt( "bullet", iBullet );
|
||||
gameeventmanager->FireEvent( event );
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
|||
#include "convar.h"
|
||||
#include "mathlib/vector.h"
|
||||
#include "usercmd.h"
|
||||
#include "util_shared.h"
|
||||
#include "weapon_csbase.h"
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
|
@ -31,15 +32,15 @@ ConVar debug_screenshot_bullet_position("debug_screenshot_bullet_position", "0")
|
|||
{
|
||||
|
||||
// If we have some sounds from the weapon classname.txt file, play a random one of them
|
||||
const char *shootsound = pWeaponInfo->aShootSounds[ sound_type ];
|
||||
const char *shootsound = pWeaponInfo->aShootSounds[ sound_type ];
|
||||
if ( !shootsound || !shootsound[0] )
|
||||
return;
|
||||
|
||||
CBroadcastRecipientFilter filter; // this is client side only
|
||||
if ( !te->CanPredict() )
|
||||
return;
|
||||
|
||||
CBaseEntity::EmitSound( filter, iPlayerIndex, shootsound, &vOrigin, flSoundTime );
|
||||
|
||||
CBaseEntity::EmitSound( filter, iPlayerIndex, shootsound, &vOrigin, flSoundTime );
|
||||
}
|
||||
|
||||
class CGroupedSound
|
||||
|
@ -51,7 +52,7 @@ ConVar debug_screenshot_bullet_position("debug_screenshot_bullet_position", "0")
|
|||
|
||||
CUtlVector<CGroupedSound> g_GroupedSounds;
|
||||
|
||||
|
||||
|
||||
// Called by the ImpactSound function.
|
||||
void ShotgunImpactSoundGroup( const char *pSoundName, const Vector &vEndPos )
|
||||
{
|
||||
|
@ -109,7 +110,7 @@ ConVar debug_screenshot_bullet_position("debug_screenshot_bullet_position", "0")
|
|||
// This runs on both the client and the server.
|
||||
// On the server, it only does the damage calculations.
|
||||
// On the client, it does all the effects.
|
||||
void FX_FireBullets(
|
||||
void FX_FireBullets(
|
||||
int iPlayerIndex,
|
||||
const Vector &vOrigin,
|
||||
const QAngle &vAngles,
|
||||
|
@ -183,7 +184,7 @@ void FX_FireBullets(
|
|||
// #else
|
||||
// V_strcat(szFlags, "SERVER ", sizeof(szFlags));
|
||||
// #endif
|
||||
//
|
||||
//
|
||||
if ( pPlayer->GetMoveType() == MOVETYPE_LADDER )
|
||||
V_strcat(szFlags, "LADDER ", sizeof(szFlags));
|
||||
|
||||
|
@ -195,7 +196,7 @@ void FX_FireBullets(
|
|||
|
||||
float fVelocity = pPlayer->GetAbsVelocity().Length2D();
|
||||
|
||||
Msg("FireBullets @ %10f [ %s ]: inaccuracy=%f spread=%f max dispersion=%f mode=%2i vel=%10f seed=%3i %s\n",
|
||||
Msg("FireBullets @ %10f [ %s ]: inaccuracy=%f spread=%f max dispersion=%f mode=%2i vel=%10f seed=%3i %s\n",
|
||||
gpGlobals->curtime, weaponAlias, fInaccuracy, fSpread, fInaccuracy + fSpread, iMode, fVelocity, iSeed, szFlags);
|
||||
}
|
||||
#endif
|
||||
|
@ -224,10 +225,10 @@ void FX_FireBullets(
|
|||
|
||||
// if this is server code, send the effect over to client as temp entity
|
||||
// Dispatch one message for all the bullet impacts and sounds.
|
||||
TE_FireBullets(
|
||||
TE_FireBullets(
|
||||
iPlayerIndex,
|
||||
vHookedOrigin,
|
||||
vAngles,
|
||||
vHookedOrigin,
|
||||
vAngles,
|
||||
iWeaponID,
|
||||
iMode,
|
||||
iSeed,
|
||||
|
@ -289,7 +290,7 @@ void FX_FireBullets(
|
|||
|
||||
if ( !pPlayer )
|
||||
return;
|
||||
|
||||
|
||||
StartGroupingSounds();
|
||||
|
||||
#ifdef GAME_DLL
|
||||
|
@ -322,6 +323,54 @@ void FX_FireBullets(
|
|||
y1[iBullet] = fRadius1 * sinf(fTheta1);
|
||||
}
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
static ConVarRef cl_showfirebullethitboxes("cl_showfirebullethitboxes");
|
||||
static ConVarRef cl_showimpacts( "cl_showimpacts" );
|
||||
|
||||
if ( playerCmd && !playerCmd->hasbeenpredicted && ( cl_showfirebullethitboxes.GetBool() || cl_showimpacts.GetBool() ) )
|
||||
{
|
||||
for ( int i = 1; i <= gpGlobals->maxClients; i++ )
|
||||
{
|
||||
auto lagPlayer = ( C_CSPlayer* )UTIL_PlayerByIndex( i );
|
||||
|
||||
if ( !lagPlayer )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
C_CSPlayer::HitboxRecord record;
|
||||
|
||||
record.m_vecAbsOrigin = lagPlayer->GetRenderOrigin();
|
||||
record.m_angRenderAngles = lagPlayer->m_angRenderAngles;
|
||||
|
||||
record.m_nAttackerTickBase = pPlayer->m_nTickBase;
|
||||
record.m_flSimulationTime = lagPlayer->GetSimulationTime();
|
||||
record.m_flAnimTime = lagPlayer->GetAnimTime();
|
||||
record.m_flCycle = lagPlayer->GetCycle();
|
||||
record.m_nSequence = lagPlayer->GetSequence();
|
||||
|
||||
lagPlayer->GetPoseParameters( lagPlayer->GetModelPtr(), record.m_flPoseParameters );
|
||||
lagPlayer->GetBoneControllers( record.m_flEncodedControllers );
|
||||
|
||||
for ( int i = 0; i < lagPlayer->GetNumAnimOverlays(); i++ )
|
||||
{
|
||||
CAnimationLayer* layer = lagPlayer->GetAnimOverlay( i );
|
||||
|
||||
if ( layer )
|
||||
{
|
||||
record.m_AnimationLayer[i].m_flCycle = layer->m_flCycle;
|
||||
record.m_AnimationLayer[i].m_nOrder = layer->m_nOrder;
|
||||
record.m_AnimationLayer[i].m_nSequence = layer->m_nSequence;
|
||||
record.m_AnimationLayer[i].m_flWeight = layer->m_flWeight;
|
||||
record.m_AnimationLayer[i].m_fFlags = layer->m_fFlags;
|
||||
}
|
||||
}
|
||||
|
||||
pPlayer->m_HitboxTrack[lagPlayer->index].Push( record );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for ( int iBullet=0; iBullet < pWeaponInfo->m_iBullets; iBullet++ )
|
||||
{
|
||||
#ifdef CLIENT_DLL
|
||||
|
|
Loading…
Reference in a new issue