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