LagCompensation: optimize
This commit is contained in:
parent
1eb3f52992
commit
d9ea3bbf33
@ -92,7 +92,9 @@ Handle g_hRestartRound;
|
||||
Handle g_hSetTarget;
|
||||
Handle g_hSetTargetPost;
|
||||
Handle g_hFrameUpdatePostEntityThink;
|
||||
Handle g_hActivate;
|
||||
|
||||
int g_iParent;
|
||||
int g_iTouchStamp;
|
||||
int g_iCollision;
|
||||
int g_iSolidFlags;
|
||||
@ -106,6 +108,7 @@ int g_iAngAbsRotation;
|
||||
int g_iSimulationTime;
|
||||
int g_iCoordinateFrame;
|
||||
|
||||
int g_aLagCompensated[MAX_EDICTS] = {-1, ...};
|
||||
char g_aBlockTriggerTouch[MAX_EDICTS];
|
||||
char g_aaBlockTouch[(MAXPLAYERS + 1) * MAX_EDICTS];
|
||||
|
||||
@ -206,6 +209,23 @@ public void OnPluginStart()
|
||||
|
||||
delete hGameData;
|
||||
|
||||
|
||||
hGameData = LoadGameConfigFile("sdktools.games");
|
||||
if(!hGameData)
|
||||
SetFailState("Failed to load sdktools gamedata.");
|
||||
|
||||
int offset = GameConfGetOffset(hGameData, "Activate");
|
||||
if (offset == -1)
|
||||
SetFailState("Failed to find Activate offset");
|
||||
|
||||
// CPhysForce::Activate
|
||||
g_hActivate = DHookCreate(offset, HookType_Entity, ReturnType_Void, ThisPointer_CBaseEntity, Hook_CPhysForce_Activate);
|
||||
if(g_hActivate == INVALID_HANDLE)
|
||||
SetFailState("Failed to DHookCreate Activate");
|
||||
|
||||
delete hGameData;
|
||||
|
||||
|
||||
RegAdminCmd("sm_unlag", Command_AddLagCompensation, ADMFLAG_RCON, "sm_unlag <entidx>");
|
||||
RegAdminCmd("sm_lagged", Command_CheckLagCompensated, ADMFLAG_GENERIC, "sm_lagged");
|
||||
|
||||
@ -245,6 +265,7 @@ public void OnMapStart()
|
||||
|
||||
g_bCleaningUp = false;
|
||||
|
||||
g_iParent = FindDataMapInfo(0, "m_pParent");
|
||||
g_iTouchStamp = FindDataMapInfo(0, "touchStamp");
|
||||
g_iCollision = FindDataMapInfo(0, "m_Collision");
|
||||
g_iSolidFlags = FindDataMapInfo(0, "m_usSolidFlags");
|
||||
@ -267,31 +288,57 @@ public void OnMapStart()
|
||||
{
|
||||
char sClassname[64];
|
||||
if(GetEntityClassname(entity, sClassname, sizeof(sClassname)))
|
||||
{
|
||||
OnEntityCreated(entity, sClassname);
|
||||
OnEntitySpawned(entity, sClassname);
|
||||
|
||||
if(StrEqual(sClassname, "phys_thruster", false))
|
||||
{
|
||||
Hook_CPhysForce_Activate(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnEntityCreated(int entity, const char[] classname)
|
||||
{
|
||||
if(g_bCleaningUp)
|
||||
return;
|
||||
|
||||
if(StrEqual(classname, "phys_thruster", false))
|
||||
{
|
||||
DHookEntity(g_hActivate, true, entity);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnEntitySpawned(int entity, const char[] classname)
|
||||
{
|
||||
if(g_bCleaningUp)
|
||||
return;
|
||||
|
||||
CheckEntityForLagComp(entity, classname);
|
||||
}
|
||||
|
||||
bool CheckEntityForLagComp(int entity, const char[] classname, bool bRecursive=false, bool bGoodParents=false)
|
||||
{
|
||||
if(entity < 0 || entity > MAX_EDICTS)
|
||||
return;
|
||||
return false;
|
||||
|
||||
if(!IsValidEntity(entity))
|
||||
return;
|
||||
return false;
|
||||
|
||||
if(g_aLagCompensated[entity] != -1)
|
||||
return false;
|
||||
|
||||
bool bTrigger = StrEqual(classname, "trigger_hurt", false) ||
|
||||
StrEqual(classname, "trigger_push", false) ||
|
||||
StrEqual(classname, "trigger_teleport", false);
|
||||
//StrEqual(classname, "trigger_multiple", false);
|
||||
|
||||
bool bMoving = !strncmp(classname, "func_physbox", 12, false);
|
||||
bool bPhysbox = !strncmp(classname, "func_physbox", 12, false);
|
||||
|
||||
if(!bTrigger && !bMoving)
|
||||
return;
|
||||
if(!bTrigger && !bPhysbox)
|
||||
return false;
|
||||
|
||||
// Don't lag compensate anything that could be parented to a player
|
||||
// The player simulation would usually move the entity,
|
||||
@ -300,7 +347,7 @@ public void OnEntitySpawned(int entity, const char[] classname)
|
||||
char sParentClassname[64];
|
||||
for(int iTmp = entity;;)
|
||||
{
|
||||
iTmp = GetEntPropEnt(iTmp, Prop_Data, "m_pParent");
|
||||
iTmp = GetEntDataEnt2(iTmp, g_iParent);
|
||||
if(iTmp == INVALID_ENT_REFERENCE)
|
||||
break;
|
||||
|
||||
@ -310,24 +357,56 @@ public void OnEntitySpawned(int entity, const char[] classname)
|
||||
if(StrEqual(sParentClassname, "player") ||
|
||||
!strncmp(sParentClassname, "weapon_", 7))
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(g_aLagCompensated[iParent] != -1)
|
||||
{
|
||||
bGoodParents = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if(strncmp(sParentClassname, "func_", 5))
|
||||
continue;
|
||||
|
||||
if(StrEqual(sParentClassname[5], "movelinear") ||
|
||||
StrEqual(sParentClassname[5], "door") ||
|
||||
StrEqual(sParentClassname[5], "rotating") ||
|
||||
StrEqual(sParentClassname[5], "tracktrain"))
|
||||
{
|
||||
bGoodParents = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Lag compensate all moving stuff
|
||||
if(bMoving)
|
||||
if(!bGoodParents)
|
||||
return false;
|
||||
|
||||
if(AddEntityForLagCompensation(entity, bTrigger))
|
||||
{
|
||||
AddEntityForLagCompensation(entity, false);
|
||||
return;
|
||||
if(bRecursive)
|
||||
{
|
||||
CheckEntityChildrenForLagComp(entity);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Lag compensate all (non player-) parented hurt triggers
|
||||
if(bTrigger && iParent > MaxClients && iParent < MAX_EDICTS)
|
||||
return false;
|
||||
}
|
||||
|
||||
void CheckEntityChildrenForLagComp(int parent)
|
||||
{
|
||||
if(AddEntityForLagCompensation(entity, true))
|
||||
int entity = INVALID_ENT_REFERENCE;
|
||||
while((entity = FindEntityByClassname(entity, "*")) != INVALID_ENT_REFERENCE)
|
||||
{
|
||||
// Filter the trigger from being touched outside of the lag compensation
|
||||
g_aBlockTriggerTouch[entity] = 1;
|
||||
if(GetEntDataEnt2(entity, g_iParent) != parent)
|
||||
continue;
|
||||
|
||||
char sClassname[64];
|
||||
if(GetEntityClassname(entity, sClassname, sizeof(sClassname)))
|
||||
{
|
||||
CheckEntityForLagComp(entity, sClassname, _, true);
|
||||
CheckEntityChildrenForLagComp(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -340,17 +419,11 @@ public void OnEntityDestroyed(int entity)
|
||||
if(entity < 0 || entity > MAX_EDICTS)
|
||||
return;
|
||||
|
||||
if(!IsValidEntity(entity))
|
||||
int iIndex = g_aLagCompensated[entity];
|
||||
if(iIndex == -1)
|
||||
return;
|
||||
|
||||
for(int i = 0; i < g_iNumEntities; i++)
|
||||
{
|
||||
if(g_aEntityLagData[i].iEntity != entity)
|
||||
continue;
|
||||
|
||||
RemoveRecord(i);
|
||||
return;
|
||||
}
|
||||
RemoveRecord(iIndex);
|
||||
}
|
||||
|
||||
|
||||
@ -363,30 +436,26 @@ public MRESReturn Detour_OnUTIL_Remove(Handle hParams)
|
||||
if(entity < 0 || entity > MAX_EDICTS)
|
||||
return MRES_Ignored;
|
||||
|
||||
for(int i = 0; i < g_iNumEntities; i++)
|
||||
{
|
||||
if(g_aEntityLagData[i].iEntity != entity)
|
||||
continue;
|
||||
int iIndex = g_aLagCompensated[entity];
|
||||
if(iIndex == -1)
|
||||
return MRES_Ignored;
|
||||
|
||||
// let it die
|
||||
if(!g_aEntityLagData[i].bLateKill)
|
||||
break;
|
||||
if(!g_aEntityLagData[iIndex].bLateKill)
|
||||
return MRES_Ignored;
|
||||
|
||||
// ignore sleeping entities
|
||||
if(g_aEntityLagData[i].iNotMoving >= MAX_RECORDS)
|
||||
break;
|
||||
if(g_aEntityLagData[iIndex].iNotMoving >= MAX_RECORDS)
|
||||
return MRES_Ignored;
|
||||
|
||||
if(!g_aEntityLagData[i].iDeleted)
|
||||
if(!g_aEntityLagData[iIndex].iDeleted)
|
||||
{
|
||||
g_aEntityLagData[i].iDeleted = GetGameTickCount();
|
||||
g_aEntityLagData[iIndex].iDeleted = GetGameTickCount();
|
||||
}
|
||||
|
||||
return MRES_Supercede;
|
||||
}
|
||||
|
||||
return MRES_Ignored;
|
||||
}
|
||||
|
||||
public MRESReturn Detour_OnRestartRound()
|
||||
{
|
||||
g_bCleaningUp = true;
|
||||
@ -395,6 +464,7 @@ public MRESReturn Detour_OnRestartRound()
|
||||
{
|
||||
int iEntity = g_aEntityLagData[i].iEntity;
|
||||
|
||||
g_aLagCompensated[iEntity] = -1;
|
||||
g_aBlockTriggerTouch[iEntity] = 0;
|
||||
|
||||
for(int client = 1; client <= MaxClients; client++)
|
||||
@ -434,18 +504,22 @@ public MRESReturn Detour_OnSetTargetPost(Handle hParams)
|
||||
if(!GetEntityClassname(entity, sClassname, sizeof(sClassname)))
|
||||
return MRES_Ignored;
|
||||
|
||||
if(!(StrEqual(sClassname, "trigger_hurt", false) ||
|
||||
StrEqual(sClassname, "trigger_push", false) ||
|
||||
StrEqual(sClassname, "trigger_teleport", false)))
|
||||
{
|
||||
CheckEntityForLagComp(entity, sClassname, true, true);
|
||||
|
||||
return MRES_Ignored;
|
||||
}
|
||||
|
||||
if(AddEntityForLagCompensation(entity, true))
|
||||
public MRESReturn Hook_CPhysForce_Activate(int entity)
|
||||
{
|
||||
// Filter the trigger from being touched outside of the lag compensation
|
||||
g_aBlockTriggerTouch[entity] = 1;
|
||||
}
|
||||
int attachedObject = GetEntPropEnt(entity, Prop_Data, "m_attachedObject");
|
||||
if(!IsValidEntity(attachedObject))
|
||||
return MRES_Ignored;
|
||||
|
||||
char sClassname[64];
|
||||
if(!GetEntityClassname(attachedObject, sClassname, sizeof(sClassname)))
|
||||
return MRES_Ignored;
|
||||
|
||||
CheckEntityForLagComp(attachedObject, sClassname, true, true);
|
||||
|
||||
return MRES_Ignored;
|
||||
}
|
||||
@ -752,15 +826,14 @@ bool AddEntityForLagCompensation(int iEntity, bool bLateKill)
|
||||
return false;
|
||||
}
|
||||
|
||||
for(int i = 0; i < g_iNumEntities; i++)
|
||||
{
|
||||
if(g_aEntityLagData[i].iEntity == iEntity)
|
||||
return true;
|
||||
}
|
||||
if(g_aLagCompensated[iEntity] != -1)
|
||||
return false;
|
||||
|
||||
int i = g_iNumEntities;
|
||||
g_iNumEntities++;
|
||||
|
||||
g_aLagCompensated[iEntity] = i;
|
||||
|
||||
g_aEntityLagData[i].iEntity = iEntity;
|
||||
g_aEntityLagData[i].iRecordIndex = 0;
|
||||
g_aEntityLagData[i].iNumRecords = 1;
|
||||
@ -772,6 +845,9 @@ bool AddEntityForLagCompensation(int iEntity, bool bLateKill)
|
||||
g_aEntityLagData[i].bLateKill = bLateKill;
|
||||
g_aEntityLagData[i].iTouchStamp = GetEntData(iEntity, g_iTouchStamp);
|
||||
|
||||
if(bLateKill)
|
||||
g_aBlockTriggerTouch[iEntity] = 1;
|
||||
|
||||
RecordDataIntoRecord(iEntity, g_aaLagRecords[i][0]);
|
||||
|
||||
{
|
||||
@ -796,6 +872,7 @@ void RemoveRecord(int index)
|
||||
|
||||
int iEntity = g_aEntityLagData[index].iEntity;
|
||||
|
||||
if(IsValidEntity(iEntity))
|
||||
{
|
||||
char sClassname[64];
|
||||
GetEntityClassname(g_aEntityLagData[index].iEntity, sClassname, sizeof(sClassname));
|
||||
@ -808,6 +885,7 @@ void RemoveRecord(int index)
|
||||
PrintToBoth("[%d] RemoveRecord %d / %d (%s)\"%s\"(#%d), num: %d", GetGameTickCount(), index, g_aEntityLagData[index].iEntity, sClassname, sTargetname, iHammerID, g_iNumEntities);
|
||||
}
|
||||
|
||||
g_aLagCompensated[iEntity] = -1;
|
||||
g_aBlockTriggerTouch[iEntity] = 0;
|
||||
|
||||
for(int client = 1; client <= MaxClients; client++)
|
||||
@ -823,6 +901,7 @@ void RemoveRecord(int index)
|
||||
|
||||
EntityLagData_Copy(g_aEntityLagData[dest], g_aEntityLagData[src]);
|
||||
g_aEntityLagData[src].iEntity = INVALID_ENT_REFERENCE;
|
||||
g_aLagCompensated[g_aEntityLagData[dest].iEntity] = dest;
|
||||
|
||||
int iNumRecords = g_aEntityLagData[dest].iNumRecords;
|
||||
for(int i = 0; i < iNumRecords; i++)
|
||||
@ -895,7 +974,6 @@ public Action Command_AddLagCompensation(int client, int argc)
|
||||
}
|
||||
|
||||
AddEntityForLagCompensation(entity, late);
|
||||
g_aBlockTriggerTouch[entity] = 1;
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user