Added fast ent lookups for server dll

This commit is contained in:
Kamay Xutax 2024-09-05 15:31:51 +02:00
parent d8598a8d22
commit 8376d865cf
7 changed files with 115 additions and 75 deletions

View file

@ -518,18 +518,22 @@ CFastEntityLookUp::CFastEntityLookUp()
cl_entitylist->AddListenerEntity( this );
}
void CFastEntityLookUp::OnEntityCreated( C_BaseEntity* pEntity )
void CFastEntityLookUp::OnEntityCreated( CBaseEntity* pEntity )
{
if ( pEntity->index > 0 && pEntity->index < MAX_EDICTS )
auto index = pEntity->entindex();
if ( index >= 0 && index < NUM_ENT_ENTRIES )
{
entities[pEntity->index] = pEntity;
entities[index] = pEntity;
}
}
void CFastEntityLookUp::OnEntityDeleted( C_BaseEntity* pEntity )
void CFastEntityLookUp::OnEntityDeleted( CBaseEntity* pEntity )
{
if ( pEntity->index > 0 && pEntity->index < MAX_EDICTS )
auto index = pEntity->entindex();
if ( index >= 0 && index < NUM_ENT_ENTRIES )
{
entities[pEntity->index] = NULL;
entities[index] = NULL;
}
}

View file

@ -312,8 +312,8 @@ class CFastEntityLookUp : public IClientEntityListener
virtual void OnEntityCreated( C_BaseEntity* pEntity );
virtual void OnEntityDeleted( C_BaseEntity* pEntity );
// Let have a chance to let the CPU autovectorize these!
CBaseEntity* entities[MAX_EDICTS];
// Let have a chance to the CPU in order to autovectorize these!
CBaseEntity* entities[NUM_ENT_ENTRIES];
};
extern CFastEntityLookUp* g_pFastEntityLookUp;

View file

@ -33,6 +33,9 @@ static CUtlVector<IServerNetworkable*> g_DeleteList;
CGlobalEntityList gEntList;
CBaseEntityList *g_pEntityList = &gEntList;
static CFastEntityLookUp g_FastEntityLookUp;
CFastEntityLookUp* g_pFastEntityLookUp = &g_FastEntityLookUp;
class CAimTargetManager : public IEntityListener
{
public:
@ -1634,3 +1637,32 @@ CON_COMMAND(report_simthinklist, "Lists all simulating/thinking entities")
list.ReportEntityList();
}
CFastEntityLookUp::CFastEntityLookUp()
{
for ( int i = 0; i < MAX_EDICTS; i++ )
{
entities[i] = NULL;
}
gEntList.AddListenerEntity( this );
}
void CFastEntityLookUp::OnEntityCreated( CBaseEntity* pEntity )
{
auto index = pEntity->entindex();
if ( index >= 0 && index < NUM_ENT_ENTRIES )
{
entities[index] = pEntity;
}
}
void CFastEntityLookUp::OnEntityDeleted( CBaseEntity* pEntity )
{
auto index = pEntity->entindex();
if ( index >= 0 && index < NUM_ENT_ENTRIES )
{
entities[index] = NULL;
}
}

View file

@ -9,6 +9,7 @@
#ifndef ENTITYLIST_H
#define ENTITYLIST_H
#include "const.h"
#ifdef _WIN32
#pragma once
#endif
@ -349,6 +350,20 @@ public:
virtual void OnEntityDeleted( CBaseEntity *pEntity ) {};
};
class CFastEntityLookUp : public IEntityListener
{
public:
CFastEntityLookUp();
virtual void OnEntityCreated( CBaseEntity* pEntity );
virtual void OnEntityDeleted( CBaseEntity* pEntity );
// Let have a chance to the CPU in order to autovectorize these!
CBaseEntity* entities[NUM_ENT_ENTRIES];
};
extern CFastEntityLookUp* g_pFastEntityLookUp;
// singleton
extern INotify *g_pNotify;

View file

@ -6,6 +6,7 @@
//=============================================================================//
#include "cbase.h"
#include "entitylist.h"
#include "icvar.h"
#include "player.h"
#include "shareddefs.h"
@ -155,9 +156,12 @@ void CLagCompensationManager::TrackEntities()
VPROF_BUDGET( "TrackEntities", "CLagCompensationManager" );
auto entities = g_pFastEntityLookUp->entities;
// Iterate all active entities
for ( int i = 0; i < MAX_EDICTS; i++ )
{
CBaseEntity* pEntity = UTIL_EntityByIndex( i );
CBaseEntity* pEntity = entities[i];
if ( !pEntity )
{
@ -248,9 +252,12 @@ void CLagCompensationManager::StartLagCompensation( CBasePlayer* player, CUserCm
// Iterate all active entities
const CBitVec< MAX_EDICTS >* pEntityTransmitBits = engine->GetEntityTransmitBitsForClient( player->entindex() - 1 );
auto entities = g_pFastEntityLookUp->entities;
// Iterate all active entities
for ( int i = 0; i < MAX_EDICTS; i++ )
{
CBaseEntity* pEntity = UTIL_EntityByIndex( i );
CBaseEntity* pEntity = entities[i];
if ( !pEntity )
{
@ -287,10 +294,8 @@ inline void CLagCompensationManager::BacktrackEntity( CBaseEntity* pEntity, int
LagRecord* recordSim;
LagRecord* recordAnim;
int pl_index = loopindex;
float flTargetSimTime = cmd->simulationdata[pl_index].sim_time;
float flTargetAnimTime = cmd->simulationdata[pl_index].anim_time;
float flTargetSimTime = cmd->simulationdata[loopindex].sim_time;
float flTargetAnimTime = cmd->simulationdata[loopindex].anim_time;
// Somehow the client didn't care.
if ( flTargetSimTime == 0 )
@ -305,7 +310,7 @@ inline void CLagCompensationManager::BacktrackEntity( CBaseEntity* pEntity, int
}
// get track history of this entity
auto track = &m_EntityTrack[pl_index];
auto track = &m_EntityTrack[loopindex];
bool foundSim = false;
bool foundAnim = false;
@ -375,8 +380,8 @@ inline void CLagCompensationManager::BacktrackEntity( CBaseEntity* pEntity, int
// See if this represents a change for the entity
int flags = 0;
LagRecord* restore = &m_RestoreData[pl_index];
LagRecord* change = &m_ChangeData[pl_index];
LagRecord* restore = &m_RestoreData[loopindex];
LagRecord* change = &m_ChangeData[loopindex];
QAngle angdiff = pEntity->GetLocalAngles() - ang;
Vector orgdiff = pEntity->GetLocalOrigin() - org;
@ -438,10 +443,10 @@ inline void CLagCompensationManager::BacktrackEntity( CBaseEntity* pEntity, int
}
}
m_RestoreEntity.Set( pl_index ); // remember that we changed this entity
m_bNeedToRestore = true; // we changed at least one entity
restore->m_fFlags = flags; // we need to restore these flags
change->m_fFlags = flags; // we have changed these flags
m_RestoreEntity.Set( loopindex ); // remember that we changed this entity
m_bNeedToRestore = true; // we changed at least one entity
restore->m_fFlags = flags; // we need to restore these flags
change->m_fFlags = flags; // we have changed these flags
};
// Somehow the client didn't care.
@ -486,8 +491,6 @@ inline void CLagCompensationManager::BacktrackEntity( CBaseEntity* pEntity, int
return;
}
auto pAnimOverlay = dynamic_cast< CBaseAnimatingOverlay* >( pEntity );
if ( pAnim && foundAnim )
{
// Sorry for the loss of the optimization for the case of people
@ -527,6 +530,8 @@ inline void CLagCompensationManager::BacktrackEntity( CBaseEntity* pEntity, int
}
}
auto pAnimOverlay = dynamic_cast< CBaseAnimatingOverlay* >( pEntity );
if ( pAnimOverlay && foundAnim )
{
////////////////////////
@ -569,6 +574,8 @@ void CLagCompensationManager::FinishLagCompensation( CBasePlayer* player )
return; // no entities was changed at all
}
auto entities = g_pFastEntityLookUp->entities;
// Iterate all active entities
for ( int i = 0; i < MAX_EDICTS; i++ )
{
@ -578,7 +585,8 @@ void CLagCompensationManager::FinishLagCompensation( CBasePlayer* player )
continue;
}
CBaseEntity* pEntity = UTIL_EntityByIndex( i );
CBaseEntity* pEntity = entities[i];
if ( !pEntity )
{
continue;
@ -602,8 +610,7 @@ void CLagCompensationManager::FinishLagCompensation( CBasePlayer* player )
pEntity->SetLocalOrigin( restore->m_vecOrigin );
}
auto pAnim = dynamic_cast< CBaseAnimating* >( pEntity );
auto pAnimOverlay = dynamic_cast< CBaseAnimatingOverlay* >( pEntity );
auto pAnim = dynamic_cast< CBaseAnimating* >( pEntity );
if ( pAnim )
{
@ -635,7 +642,9 @@ void CLagCompensationManager::FinishLagCompensation( CBasePlayer* player )
}
}
if ( restore->m_fFlags & LC_ANIM_OVERS_CHANGED && pAnimOverlay )
auto pAnimOverlay = dynamic_cast< CBaseAnimatingOverlay* >( pEntity );
if ( pAnimOverlay && restore->m_fFlags & LC_ANIM_OVERS_CHANGED )
{
int layerCount = pAnimOverlay->GetNumAnimOverlays();

View file

@ -557,20 +557,14 @@ void UTIL_RemoveImmediate( CBaseEntity *oldObj )
// returns a CBaseEntity pointer to a player by index. Only returns if the player is spawned and connected
// otherwise returns NULL
// Index is 1 based
CBasePlayer *UTIL_PlayerByIndex( int playerIndex )
CBasePlayer* UTIL_PlayerByIndex( int playerIndex )
{
CBasePlayer *pPlayer = NULL;
if ( playerIndex > 0 && playerIndex <= gpGlobals->maxClients )
{
edict_t *pPlayerEdict = INDEXENT( playerIndex );
if ( pPlayerEdict && !pPlayerEdict->IsFree() )
{
pPlayer = (CBasePlayer*)GetContainingEntity( pPlayerEdict );
}
return ( CBasePlayer* )( g_pFastEntityLookUp->entities[playerIndex] );
}
return pPlayer;
return NULL;
}
CBasePlayer* UTIL_PlayerByName( const char *name )
@ -698,18 +692,12 @@ bool UTIL_IsCommandIssuedByServerAdmin( void )
*/
CBaseEntity *UTIL_EntityByIndex( int entityIndex )
{
CBaseEntity *entity = NULL;
if ( entityIndex > 0 )
{
edict_t *edict = INDEXENT( entityIndex );
if ( edict && !edict->IsFree() )
{
entity = GetContainingEntity( edict );
}
return g_pFastEntityLookUp->entities[entityIndex];
}
return entity;
return NULL;
}

View file

@ -122,9 +122,6 @@ void FX_FireBullets(
float flSoundTime
)
{
// Fallback if failed to find the interpolated shoot position.
Vector vHookedOrigin = vOrigin;
if (weapon_accuracy_noinaccuracy.GetBool())
{
fInaccuracy = 0.0f;
@ -227,7 +224,7 @@ void FX_FireBullets(
// Dispatch one message for all the bullet impacts and sounds.
TE_FireBullets(
iPlayerIndex,
vHookedOrigin,
vOrigin,
vAngles,
iWeaponID,
iMode,
@ -282,7 +279,7 @@ void FX_FireBullets(
if ( bDoEffects)
{
FX_WeaponSound( iPlayerIndex, sound_type, vHookedOrigin, pWeaponInfo, flSoundTime );
FX_WeaponSound( iPlayerIndex, sound_type, vOrigin, pWeaponInfo, flSoundTime );
}
@ -305,19 +302,8 @@ void FX_FireBullets(
float x0 = fRadius0 * cosf(fTheta0);
float y0 = fRadius0 * sinf(fTheta0);
const int kMaxBullets = 16;
float x1[kMaxBullets], y1[kMaxBullets];
Assert(pWeaponInfo->m_iBullets <= kMaxBullets);
// the RNG can be desynchronized by FireBullet(), so pre-generate all spread offsets
for ( int iBullet=0; iBullet < pWeaponInfo->m_iBullets; iBullet++ )
{
float fTheta1 = RandomFloat(0.0f, 2.0f * M_PI);
float fRadius1 = RandomFloat(0.0f, fSpread);
x1[iBullet] = fRadius1 * cosf(fTheta1);
y1[iBullet] = fRadius1 * sinf(fTheta1);
}
#ifdef CLIENT_DLL
static ConVarRef cl_showfirebullethitboxes("cl_showfirebullethitboxes");
static ConVarRef cl_showimpacts( "cl_showimpacts" );
@ -374,19 +360,25 @@ void FX_FireBullets(
gpGlobals->client_taking_screenshot = true;
}
#endif
pPlayer->FireBullet(
iBullet,
vHookedOrigin,
vAngles,
flRange,
iPenetration,
iAmmoType,
iDamage,
flRangeModifier,
pPlayer,
bDoEffects,
x0 + x1[iBullet], y0 + y1[iBullet] );
}
float fTheta1 = RandomFloat( 0.0f, 2.0f * M_PI );
float fRadius1 = RandomFloat( 0.0f, fSpread );
float x1 = fRadius1 * cosf( fTheta1 );
float y1 = fRadius1 * sinf( fTheta1 );
pPlayer->FireBullet( iBullet,
vOrigin,
vAngles,
flRange,
iPenetration,
iAmmoType,
iDamage,
flRangeModifier,
pPlayer,
bDoEffects,
x0 + x1,
y0 + y1 );
}
EndGroupingSounds();
}