Fixed lag compensation for animations
The problem is that we still trust the client, although now we have a good base to start with; The key difference here is that we don't need to use anymore the cs player animestate client side anymore because server side values are used There are minor bugs like fire effect but they can be fixed
This commit is contained in:
parent
9d17d2252c
commit
854991ab8c
14 changed files with 52 additions and 105 deletions
|
@ -868,9 +868,9 @@ void C_BaseAnimating::UpdateRelevantInterpolatedVars()
|
|||
|
||||
void C_BaseAnimating::AddBaseAnimatingInterpolatedVars()
|
||||
{
|
||||
AddVar( m_flEncodedController, &m_iv_flEncodedController, LATCH_SIMULATION_VAR, true );
|
||||
AddVar( m_flPoseParameter, &m_iv_flPoseParameter, LATCH_SIMULATION_VAR, true );
|
||||
AddVar( &m_flCycle, &m_iv_flCycle, LATCH_SIMULATION_VAR, true );
|
||||
AddVar( m_flEncodedController, &m_iv_flEncodedController, LATCH_ANIMATION_VAR, true );
|
||||
AddVar( m_flPoseParameter, &m_iv_flPoseParameter, LATCH_ANIMATION_VAR, true );
|
||||
AddVar( &m_flCycle, &m_iv_flCycle, LATCH_ANIMATION_VAR, true );
|
||||
}
|
||||
|
||||
void C_BaseAnimating::RemoveBaseAnimatingInterpolatedVars()
|
||||
|
|
|
@ -106,7 +106,7 @@ void ResizeAnimationLayerCallback( void *pStruct, int offsetToUtlVector, int len
|
|||
{
|
||||
IInterpolatedVar *pWatcher = &pVecIV->Element( i );
|
||||
pWatcher->SetDebugName( s_m_iv_AnimOverlayNames[i] );
|
||||
pEnt->AddVar( &pVec->Element( i ), pWatcher, LATCH_SIMULATION_VAR, true );
|
||||
pEnt->AddVar( &pVec->Element( i ), pWatcher, LATCH_ANIMATION_VAR, true );
|
||||
}
|
||||
// FIXME: need to set historical values of nOrder in pVecIV to MAX_OVERLAY
|
||||
|
||||
|
|
|
@ -842,7 +842,7 @@ C_BaseEntity::C_BaseEntity() :
|
|||
// but that re-introduces a third-person hitching bug. One possible cause is the abrupt change
|
||||
// in player size/position that occurs when ducking, and how prediction tries to work through that.
|
||||
//
|
||||
// AddVar( &m_vecVelocity, &m_iv_vecVelocity, LATCH_SIMULATION_VAR );
|
||||
AddVar( &m_vecVelocity, &m_iv_vecVelocity, LATCH_SIMULATION_VAR );
|
||||
|
||||
m_DataChangeEventRef = -1;
|
||||
m_EntClientFlags = 0;
|
||||
|
|
|
@ -786,8 +786,6 @@ END_RECV_TABLE()
|
|||
C_CSPlayer::C_CSPlayer() :
|
||||
m_iv_angEyeAngles( "C_CSPlayer::m_iv_angEyeAngles" )
|
||||
{
|
||||
m_PlayerAnimState = CreatePlayerAnimState( this, this, LEGANIM_9WAY, true );
|
||||
|
||||
m_angEyeAngles.Init();
|
||||
|
||||
AddVar( &m_angEyeAngles, &m_iv_angEyeAngles, LATCH_SIMULATION_VAR );
|
||||
|
@ -822,8 +820,6 @@ C_CSPlayer::~C_CSPlayer()
|
|||
RemoveAddonModels();
|
||||
|
||||
ReleaseFlashlight();
|
||||
|
||||
m_PlayerAnimState->Release();
|
||||
}
|
||||
|
||||
|
||||
|
@ -937,10 +933,10 @@ const QAngle& C_CSPlayer::GetRenderAngles()
|
|||
if ( IsRagdoll() )
|
||||
{
|
||||
return vec3_angle;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_PlayerAnimState->GetRenderAngles();
|
||||
return GetAbsAngles();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2092,15 +2088,6 @@ void C_CSPlayer::PlayReloadEffect()
|
|||
|
||||
void C_CSPlayer::DoAnimationEvent( PlayerAnimEvent_t event, int nData )
|
||||
{
|
||||
if ( event == PLAYERANIMEVENT_THROW_GRENADE )
|
||||
{
|
||||
// Let the server handle this event. It will update m_iThrowGrenadeCounter and the client will
|
||||
// pick up the event in CCSPlayerAnimState.
|
||||
}
|
||||
else
|
||||
{
|
||||
m_PlayerAnimState->DoAnimationEvent( event, nData );
|
||||
}
|
||||
}
|
||||
|
||||
void C_CSPlayer::FireEvent( const Vector& origin, const QAngle& angles, int event, const char *options )
|
||||
|
@ -2271,12 +2258,9 @@ void C_CSPlayer::Simulate( void )
|
|||
|
||||
BaseClass::Simulate();
|
||||
|
||||
// Update the animation data. It does the local check here so this works when using
|
||||
// a third-person camera (and we don't have valid player angles).
|
||||
if ( this == C_CSPlayer::GetLocalCSPlayer() )
|
||||
m_PlayerAnimState->Update( EyeAngles()[YAW], m_angEyeAngles[PITCH] );
|
||||
else
|
||||
m_PlayerAnimState->Update( m_angEyeAngles[YAW], m_angEyeAngles[PITCH] );
|
||||
static ConVar cl_showhitboxes("cl_showhitboxes", "-1");
|
||||
if (cl_showhitboxes.GetInt() == index)
|
||||
DrawClientHitboxes(0.0f, true);
|
||||
}
|
||||
|
||||
void C_CSPlayer::ReleaseFlashlight( void )
|
||||
|
@ -2536,11 +2520,11 @@ float C_CSPlayer::GetDeathCamInterpolationTime()
|
|||
|
||||
}
|
||||
|
||||
ConVar cl_cs_player_setupbones("cl_cs_player_setupbones", "1");
|
||||
ConVar cl_server_setup_bones("cl_server_setup_bones", "1");
|
||||
|
||||
bool C_CSPlayer::SetupBones( matrix3x4_t *pBoneToWorldOut, int nMaxBones, int boneMask, float currentTime )
|
||||
{
|
||||
if (cl_cs_player_setupbones.GetBool())
|
||||
if (cl_server_setup_bones.GetBool())
|
||||
{
|
||||
AUTO_LOCK( m_BoneSetupLock );
|
||||
|
||||
|
|
|
@ -218,12 +218,8 @@ public:
|
|||
void SetActivity( Activity eActivity );
|
||||
Activity GetActivity( void ) const;
|
||||
|
||||
ICSPlayerAnimState *GetPlayerAnimState() { return m_PlayerAnimState; }
|
||||
|
||||
public:
|
||||
|
||||
ICSPlayerAnimState *m_PlayerAnimState;
|
||||
|
||||
// Used to control animation state.
|
||||
Activity m_Activity;
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include "bone_setup.h"
|
||||
#include "studio.h"
|
||||
#include "util_shared.h"
|
||||
#include "c_baseplayer.h"
|
||||
#include "c_baseentity.h"
|
||||
|
@ -1338,7 +1339,7 @@ void CInput::CreateMove ( int sequence_number, float input_sample_frametime, boo
|
|||
|
||||
cmd->has_animation[pBasePlayer->index] = true;
|
||||
cmd->animationdata[pBasePlayer->index].m_flAnimTime = pBasePlayer->m_flInterpolatedAnimTime;
|
||||
|
||||
|
||||
pBasePlayer->GetBoneControllers(cmd->animationdata[pBasePlayer->index].m_encodedControllers);
|
||||
pBasePlayer->GetPoseParameters(pBasePlayer->GetModelPtr(),
|
||||
cmd->animationdata[pBasePlayer->index].m_poseParameters);
|
||||
|
@ -1349,13 +1350,13 @@ void CInput::CreateMove ( int sequence_number, float input_sample_frametime, boo
|
|||
for (int j = 0; j < pBasePlayer->GetNumAnimOverlays(); j++)
|
||||
{
|
||||
cmd->animationdata[pBasePlayer->index].m_layerRecords[j].m_cycle =
|
||||
pBasePlayer->GetAnimOverlay(j)->m_flCycle;
|
||||
pBasePlayer->GetAnimOverlay(j)->m_flCycle.GetRaw();
|
||||
cmd->animationdata[pBasePlayer->index].m_layerRecords[j].m_sequence =
|
||||
pBasePlayer->GetAnimOverlay(j)->m_nSequence;
|
||||
pBasePlayer->GetAnimOverlay(j)->m_nSequence.GetRaw();
|
||||
cmd->animationdata[pBasePlayer->index].m_layerRecords[j].m_order =
|
||||
pBasePlayer->GetAnimOverlay(j)->m_nOrder;
|
||||
cmd->animationdata[pBasePlayer->index].m_layerRecords[j].m_weight =
|
||||
pBasePlayer->GetAnimOverlay(j)->m_flWeight;
|
||||
pBasePlayer->GetAnimOverlay(j)->m_flWeight.GetRaw();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1740,7 +1740,7 @@ void CBaseAnimating::BuildMatricesWithBoneMerge(
|
|||
}
|
||||
}
|
||||
|
||||
ConVar sv_pvsskipanimation( "sv_pvsskipanimation", "1", FCVAR_ARCHIVE, "Skips SetupBones when npc's are outside the PVS" );
|
||||
ConVar sv_pvsskipanimation( "sv_pvsskipanimation", "0", FCVAR_ARCHIVE, "Skips SetupBones when npc's are outside the PVS" );
|
||||
ConVar ai_setupbones_debug( "ai_setupbones_debug", "0", 0, "Shows that bones that are setup every think" );
|
||||
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "cbase.h"
|
||||
#include "gamestringpool.h"
|
||||
#include "ilagcompensationmanager.h"
|
||||
#include "mapentities_shared.h"
|
||||
#include "game.h"
|
||||
#include "entityapi.h"
|
||||
|
@ -235,10 +236,6 @@ static int g_nCommandClientIndex = 0;
|
|||
// The chapter number of the current
|
||||
static int g_nCurrentChapterIndex = -1;
|
||||
|
||||
#ifdef _DEBUG
|
||||
static ConVar sv_showhitboxes( "sv_showhitboxes", "-1", FCVAR_CHEAT, "Send server-side hitboxes for specified entity to client (NOTE: this uses lots of bandwidth, use on listen server only)." );
|
||||
#endif
|
||||
|
||||
void PrecachePointTemplates();
|
||||
|
||||
static ClientPutInServerOverrideFn g_pClientPutInServerOverride = NULL;
|
||||
|
@ -1291,38 +1288,6 @@ void CServerGameDLL::PreClientUpdate( bool simulating )
|
|||
//#endif
|
||||
|
||||
IGameSystem::PreClientUpdateAllSystems();
|
||||
|
||||
#ifdef _DEBUG
|
||||
if ( sv_showhitboxes.GetInt() == -1 )
|
||||
return;
|
||||
|
||||
if ( sv_showhitboxes.GetInt() == 0 )
|
||||
{
|
||||
// assume it's text
|
||||
CBaseEntity *pEntity = NULL;
|
||||
|
||||
while (1)
|
||||
{
|
||||
pEntity = gEntList.FindEntityByName( pEntity, sv_showhitboxes.GetString() );
|
||||
if ( !pEntity )
|
||||
break;
|
||||
|
||||
CBaseAnimating *anim = dynamic_cast< CBaseAnimating * >( pEntity );
|
||||
|
||||
if (anim)
|
||||
{
|
||||
anim->DrawServerHitboxes();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
CBaseAnimating *anim = dynamic_cast< CBaseAnimating * >( CBaseEntity::Instance( engine->PEntityOfEntIndex( sv_showhitboxes.GetInt() ) ) );
|
||||
if ( !anim )
|
||||
return;
|
||||
|
||||
anim->DrawServerHitboxes();
|
||||
#endif
|
||||
}
|
||||
|
||||
void CServerGameDLL::Think( bool finalTick )
|
||||
|
|
|
@ -22,7 +22,8 @@ abstract_class ILagCompensationManager
|
|||
public:
|
||||
// Called during player movement to set up/restore after lag compensation
|
||||
virtual void StartLagCompensation( CBasePlayer *player, CUserCmd *cmd ) = 0;
|
||||
virtual void FinishLagCompensation( CBasePlayer *player ) = 0;
|
||||
virtual void FinishLagCompensation(CBasePlayer * player) = 0;
|
||||
virtual void BacktrackPlayer( CBasePlayer *player, CUserCmd *cmd ) = 0;
|
||||
};
|
||||
|
||||
extern ILagCompensationManager *lagcompensation;
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "baseentity.h"
|
||||
#include "convar.h"
|
||||
#include "ilagcompensationmanager.h"
|
||||
#include "player.h"
|
||||
#include "usercmd.h"
|
||||
#include "igamemovement.h"
|
||||
|
@ -339,6 +342,14 @@ void CPlayerMove::RunCommand ( CBasePlayer *player, CUserCmd *ucmd, IMoveHelper
|
|||
gpGlobals->curtime = playerCurTime;
|
||||
gpGlobals->frametime = playerFrameTime;
|
||||
|
||||
extern ConVar sv_showhitboxes;
|
||||
|
||||
if (sv_showhitboxes.GetInt() >= 0)
|
||||
{
|
||||
lagcompensation->StartLagCompensation( player, player->GetCurrentCommand() );
|
||||
lagcompensation->FinishLagCompensation( player );
|
||||
}
|
||||
|
||||
// Prevent hacked clients from sending us invalid view angles to try to get leaf server code to crash
|
||||
if ( !ucmd->viewangles.IsValid() || !IsEntityQAngleReasonable(ucmd->viewangles) )
|
||||
{
|
||||
|
@ -457,5 +468,5 @@ void CPlayerMove::RunCommand ( CBasePlayer *player, CUserCmd *ucmd, IMoveHelper
|
|||
if ( gpGlobals->frametime > 0 )
|
||||
{
|
||||
player->m_nTickBase++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,9 +31,8 @@
|
|||
ConVar sv_unlag( "sv_unlag", "1", FCVAR_DEVELOPMENTONLY, "Enables player lag compensation" );
|
||||
ConVar sv_maxunlag( "sv_maxunlag", "1.0", FCVAR_DEVELOPMENTONLY, "Maximum lag compensation in seconds", true, 0.0f, true, 1.0f );
|
||||
ConVar sv_lagflushbonecache( "sv_lagflushbonecache", "1", FCVAR_DEVELOPMENTONLY, "Flushes entity bone cache on lag compensation" );
|
||||
ConVar sv_showlagcompensation( "sv_showlagcompensation", "0", FCVAR_CHEAT, "Show lag compensated hitboxes whenever a player is lag compensated." );
|
||||
|
||||
ConVar sv_unlag_fixstuck( "sv_unlag_fixstuck", "0", FCVAR_DEVELOPMENTONLY, "Disallow backtracking a player for lag compensation if it will cause them to become stuck" );
|
||||
ConVar sv_showhitboxes( "sv_showhitboxes", "-1");
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
|
@ -110,8 +109,6 @@ public:
|
|||
float m_masterCycle;
|
||||
float m_poseParameters[MAX_POSE_PARAMETERS];
|
||||
float m_encodedControllers[MAX_ENCODED_CONTROLLERS];
|
||||
// TODO: do proper eyeAngles lag compensation
|
||||
QAngle m_angEyeAngles;
|
||||
};
|
||||
|
||||
|
||||
|
@ -195,7 +192,7 @@ public:
|
|||
void FinishLagCompensation( CBasePlayer *player );
|
||||
|
||||
private:
|
||||
void BacktrackPlayer( CBasePlayer *player, CUserCmd *cmd );
|
||||
virtual void BacktrackPlayer( CBasePlayer *player, CUserCmd *cmd );
|
||||
|
||||
void ClearHistory()
|
||||
{
|
||||
|
@ -401,8 +398,8 @@ void CLagCompensationManager::BacktrackPlayer( CBasePlayer *pPlayer, CUserCmd *c
|
|||
int pl_index = pPlayer->entindex() - 1;
|
||||
|
||||
float flTargetSimulationTime = cmd->simulationtimes[pl_index + 1];
|
||||
auto animationData = &cmd->animationdata[pl_index + 1];
|
||||
|
||||
auto animationData = &cmd->animationdata[pl_index + 1];
|
||||
|
||||
// get track history of this player
|
||||
CUtlFixedLinkedList< LagRecord > *trackSim = &m_PlayerTrack[ pl_index ];
|
||||
|
||||
|
@ -617,7 +614,7 @@ void CLagCompensationManager::BacktrackPlayer( CBasePlayer *pPlayer, CUserCmd *c
|
|||
currentLayer->m_flCycle = animationData->m_layerRecords[layerIndex].m_cycle;
|
||||
currentLayer->m_nOrder = animationData->m_layerRecords[layerIndex].m_order;
|
||||
currentLayer->m_nSequence = animationData->m_layerRecords[layerIndex].m_sequence;
|
||||
currentLayer->m_flWeight = animationData->m_layerRecords[layerIndex].m_weight;
|
||||
currentLayer->m_flWeight = animationData->m_layerRecords[layerIndex].m_weight;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -643,7 +640,7 @@ void CLagCompensationManager::BacktrackPlayer( CBasePlayer *pPlayer, CUserCmd *c
|
|||
for( int paramIndex = 0; paramIndex < hdr->GetNumBoneControllers(); paramIndex++ )
|
||||
{
|
||||
restore->m_encodedControllers[paramIndex] = pPlayer->GetBoneController(paramIndex);
|
||||
float encodedController = animationData->m_encodedControllers[paramIndex];
|
||||
float encodedController = animationData->m_encodedControllers[paramIndex];
|
||||
|
||||
pPlayer->SetBoneControllerRaw( paramIndex, encodedController );
|
||||
}
|
||||
|
@ -657,7 +654,7 @@ void CLagCompensationManager::BacktrackPlayer( CBasePlayer *pPlayer, CUserCmd *c
|
|||
pPlayer->SetAnimTime(animationData->m_flAnimTime);
|
||||
|
||||
if ( sv_lagflushbonecache.GetBool() )
|
||||
pPlayer->InvalidateBoneCache();
|
||||
pPlayer->InvalidateBoneCache();
|
||||
|
||||
/*char text[256]; Q_snprintf( text, sizeof(text), "time %.2f", flTargetTime );
|
||||
pPlayer->DrawServerHitboxes( 10 );
|
||||
|
@ -669,17 +666,10 @@ void CLagCompensationManager::BacktrackPlayer( CBasePlayer *pPlayer, CUserCmd *c
|
|||
restore->m_fFlags = flags; // we need to restore these flags
|
||||
change->m_fFlags = flags; // we have changed these flags
|
||||
|
||||
if( sv_showlagcompensation.GetInt() == pPlayer->entindex() )
|
||||
{
|
||||
pPlayer->DrawServerHitboxes(60, true);
|
||||
}
|
||||
|
||||
static ConVar *sv_showplayerhitboxes = g_pCVar->FindVar("sv_showplayerhitboxes");
|
||||
|
||||
if ( sv_showplayerhitboxes->GetInt() == pPlayer->entindex() )
|
||||
{
|
||||
DevMsg("Server: %s => %f %f %f => %f (frac: %f)\n", pPlayer->GetPlayerName(), change->m_vecOrigin.x, change->m_vecOrigin.y, change->m_vecOrigin.z, flTargetSimulationTime, fracSim);
|
||||
}
|
||||
if (sv_showhitboxes.GetInt() == pPlayer->entindex())
|
||||
pPlayer->DrawServerHitboxes(0.0f, true);
|
||||
}
|
||||
|
||||
|
||||
|
@ -790,7 +780,7 @@ void CLagCompensationManager::FinishLagCompensation( CBasePlayer *player )
|
|||
}
|
||||
|
||||
pPlayer->SetSimulationTime( restore->m_flSimulationTime );
|
||||
pPlayer->SetAnimTime( restore->m_flAnimTime );
|
||||
pPlayer->SetAnimTime(restore->m_flAnimTime);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -75,6 +75,7 @@ END_NETWORK_TABLE()
|
|||
// During the first half-second of our life, don't draw ourselves if he's
|
||||
// still playing his throw animation.
|
||||
// (better yet, we could draw ourselves in his hand).
|
||||
#ifndef CLIENT_DLL
|
||||
if ( GetThrower() != C_BasePlayer::GetLocalPlayer() )
|
||||
{
|
||||
if ( gpGlobals->curtime - m_flSpawnTime < 0.5 )
|
||||
|
@ -86,6 +87,7 @@ END_NETWORK_TABLE()
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return BaseClass::DrawModel( flags );
|
||||
}
|
||||
|
|
|
@ -414,14 +414,15 @@ void CCSPlayer::FireBullet(
|
|||
{
|
||||
CBasePlayer *lagPlayer = UTIL_PlayerByIndex( sv_showplayerhitboxes.GetInt() );
|
||||
if( lagPlayer )
|
||||
{
|
||||
{
|
||||
#ifdef CLIENT_DLL
|
||||
DevMsg("Client:");
|
||||
lagPlayer->DrawClientHitboxes(60, true);
|
||||
DevMsg("Client: %s => %f %f %f => %f (%f)\n", lagPlayer->GetPlayerName(), lagPlayer->GetAbsOrigin().x, lagPlayer->GetAbsOrigin().y, lagPlayer->GetAbsOrigin().z,
|
||||
lagPlayer->m_flInterpolatedSimulationTime, fmod(lagPlayer->m_flInterpolatedSimulationTime, TICK_INTERVAL) / TICK_INTERVAL);
|
||||
#else
|
||||
DevMsg("Server:");
|
||||
lagPlayer->DrawServerHitboxes(60, true);
|
||||
#endif
|
||||
DevMsg("%s => %f %f %f\n", lagPlayer->GetPlayerName(), lagPlayer->GetAbsOrigin().x, lagPlayer->GetAbsOrigin().y, lagPlayer->GetAbsOrigin().z);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -174,6 +174,7 @@ void FX_FireBullets(
|
|||
|
||||
CCSWeaponInfo *pWeaponInfo = static_cast< CCSWeaponInfo* >( GetFileWeaponInfoFromHandle( hWpnInfo ) );
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
// Do the firing animation event.
|
||||
if ( pPlayer && !pPlayer->IsDormant() )
|
||||
{
|
||||
|
@ -183,7 +184,6 @@ void FX_FireBullets(
|
|||
pPlayer->GetPlayerAnimState()->DoAnimationEvent( PLAYERANIMEVENT_FIRE_GUN_SECONDARY );
|
||||
}
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
// 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(
|
||||
|
@ -311,11 +311,8 @@ void FX_FireBullets(
|
|||
// On the client, it plays the planting animation.
|
||||
void FX_PlantBomb( int iPlayerIndex, const Vector &vOrigin, PlantBombOption_t option )
|
||||
{
|
||||
#ifdef CLIENT_DLL
|
||||
C_CSPlayer *pPlayer = ToCSPlayer( ClientEntityList().GetBaseEntity( iPlayerIndex ) );
|
||||
#else
|
||||
#ifndef CLIENT_DLL
|
||||
CCSPlayer *pPlayer = ToCSPlayer( UTIL_PlayerByIndex( iPlayerIndex) );
|
||||
#endif
|
||||
|
||||
// Do the firing animation event.
|
||||
if ( pPlayer && !pPlayer->IsDormant() )
|
||||
|
@ -334,9 +331,8 @@ void FX_PlantBomb( int iPlayerIndex, const Vector &vOrigin, PlantBombOption_t op
|
|||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
// 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_PlantBomb( iPlayerIndex, vOrigin, option );
|
||||
|
|
Loading…
Reference in a new issue