LagCompensation: more optimizations

This commit is contained in:
BotoX 2019-11-17 20:46:38 +01:00
parent d9ea3bbf33
commit 5979f48610

View File

@ -4,6 +4,10 @@
#include <CSSFixes> #include <CSSFixes>
#include <dhooks> #include <dhooks>
#define SetBit(%1,%2) ((%1)[(%2) >> 5] |= (1 << ((%2) & 31)))
#define ClearBit(%1,%2) ((%1)[(%2) >> 5] &= ~(1 << ((%2) & 31)))
#define CheckBit(%1,%2) !!((%1)[(%2) >> 5] & (1 << ((%2) & 31)))
#pragma semicolon 1 #pragma semicolon 1
#pragma newdecls required #pragma newdecls required
@ -50,6 +54,22 @@ enum
SOLID_LAST, SOLID_LAST,
}; };
enum
{
SF_TRIGGER_ALLOW_CLIENTS = 0x01, // Players can fire this trigger
SF_TRIGGER_ALLOW_NPCS = 0x02, // NPCS can fire this trigger
SF_TRIGGER_ALLOW_PUSHABLES = 0x04, // Pushables can fire this trigger
SF_TRIGGER_ALLOW_PHYSICS = 0x08, // Physics objects can fire this trigger
SF_TRIGGER_ONLY_PLAYER_ALLY_NPCS = 0x10, // *if* NPCs can fire this trigger, this flag means only player allies do so
SF_TRIGGER_ONLY_CLIENTS_IN_VEHICLES = 0x20, // *if* Players can fire this trigger, this flag means only players inside vehicles can
SF_TRIGGER_ALLOW_ALL = 0x40, // Everything can fire this trigger EXCEPT DEBRIS!
SF_TRIGGER_ONLY_CLIENTS_OUT_OF_VEHICLES = 0x200, // *if* Players can fire this trigger, this flag means only players outside vehicles can
SF_TRIG_PUSH_ONCE = 0x80, // trigger_push removes itself after firing once
SF_TRIG_PUSH_AFFECT_PLAYER_ON_LADDER = 0x100, // if pushed object is player on a ladder, then this disengages them from the ladder (HL2only)
SF_TRIG_TOUCH_DEBRIS = 0x400, // Will touch physics debris objects
SF_TRIGGER_ONLY_NPCS_IN_VEHICLES = 0x800, // *if* NPCs can fire this trigger, only NPCs in vehicles do so (respects player ally flag too)
};
#define MAX_RECORDS 32 #define MAX_RECORDS 32
#define MAX_ENTITIES 256 #define MAX_ENTITIES 256
//#define DEBUG //#define DEBUG
@ -95,6 +115,7 @@ Handle g_hFrameUpdatePostEntityThink;
Handle g_hActivate; Handle g_hActivate;
int g_iParent; int g_iParent;
int g_iSpawnFlags;
int g_iTouchStamp; int g_iTouchStamp;
int g_iCollision; int g_iCollision;
int g_iSolidFlags; int g_iSolidFlags;
@ -109,8 +130,9 @@ int g_iSimulationTime;
int g_iCoordinateFrame; int g_iCoordinateFrame;
int g_aLagCompensated[MAX_EDICTS] = {-1, ...}; int g_aLagCompensated[MAX_EDICTS] = {-1, ...};
char g_aBlockTriggerTouch[MAX_EDICTS]; int g_aFilterTriggerTouch[MAX_EDICTS / 32];
char g_aaBlockTouch[(MAXPLAYERS + 1) * MAX_EDICTS]; int g_aaFilterClientEntity[((MAXPLAYERS + 1) * MAX_EDICTS) / 32];
int g_aBlockTriggerMoved[MAX_EDICTS / 32];
public void OnPluginStart() public void OnPluginStart()
{ {
@ -229,7 +251,8 @@ public void OnPluginStart()
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");
FilterClientEntityMap(g_aaBlockTouch, true); FilterClientEntityMap(g_aaFilterClientEntity, true);
BlockTriggerMoved(g_aBlockTriggerMoved, true);
} }
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max) public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
@ -241,8 +264,9 @@ public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max
public void OnPluginEnd() public void OnPluginEnd()
{ {
g_bCleaningUp = true; g_bCleaningUp = true;
FilterClientEntityMap(g_aaBlockTouch, false); FilterClientEntityMap(g_aaFilterClientEntity, false);
FilterTriggerTouchPlayers(g_aBlockTriggerTouch, false); BlockTriggerMoved(g_aBlockTriggerMoved, false);
FilterTriggerTouchPlayers(g_aFilterTriggerTouch, false);
DHookDisableDetour(g_hUTIL_Remove, false, Detour_OnUTIL_Remove); DHookDisableDetour(g_hUTIL_Remove, false, Detour_OnUTIL_Remove);
@ -266,6 +290,7 @@ public void OnMapStart()
g_bCleaningUp = false; g_bCleaningUp = false;
g_iParent = FindDataMapInfo(0, "m_pParent"); g_iParent = FindDataMapInfo(0, "m_pParent");
g_iSpawnFlags = FindDataMapInfo(0, "m_spawnflags");
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");
@ -384,10 +409,18 @@ bool CheckEntityForLagComp(int entity, const char[] classname, bool bRecursive=f
if(AddEntityForLagCompensation(entity, bTrigger)) if(AddEntityForLagCompensation(entity, bTrigger))
{ {
if(bTrigger)
{
int Flags = GetEntData(entity, g_iSpawnFlags);
if(!(Flags & (SF_TRIGGER_ALLOW_PUSHABLES | SF_TRIGGER_ALLOW_PHYSICS | SF_TRIGGER_ALLOW_ALL | SF_TRIG_TOUCH_DEBRIS)))
SetBit(g_aBlockTriggerMoved, entity);
}
if(bRecursive) if(bRecursive)
{ {
CheckEntityChildrenForLagComp(entity); CheckEntityChildrenForLagComp(entity);
} }
return true; return true;
} }
@ -465,11 +498,12 @@ public MRESReturn Detour_OnRestartRound()
int iEntity = g_aEntityLagData[i].iEntity; int iEntity = g_aEntityLagData[i].iEntity;
g_aLagCompensated[iEntity] = -1; g_aLagCompensated[iEntity] = -1;
g_aBlockTriggerTouch[iEntity] = 0; ClearBit(g_aFilterTriggerTouch, iEntity);
ClearBit(g_aBlockTriggerMoved, iEntity);
for(int client = 1; client <= MaxClients; client++) for(int client = 1; client <= MaxClients; client++)
{ {
g_aaBlockTouch[client * MAX_EDICTS + iEntity] = 0; ClearBit(g_aaFilterClientEntity, client * MAX_EDICTS + iEntity);
} }
if(g_aEntityLagData[i].iDeleted) if(g_aEntityLagData[i].iDeleted)
@ -541,7 +575,7 @@ public MRESReturn Detour_OnFrameUpdatePostEntityThink()
public void OnRunThinkFunctions(bool simulating) public void OnRunThinkFunctions(bool simulating)
{ {
FilterTriggerTouchPlayers(g_aBlockTriggerTouch, false); FilterTriggerTouchPlayers(g_aFilterTriggerTouch, false);
for(int i = 0; i < g_iNumEntities; i++) for(int i = 0; i < g_iNumEntities; i++)
{ {
@ -614,19 +648,19 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3
// Entity too new, the client couldn't even see it yet. // Entity too new, the client couldn't even see it yet.
if(g_aEntityLagData[i].iSpawned > iPlayerSimTick) if(g_aEntityLagData[i].iSpawned > iPlayerSimTick)
{ {
g_aaBlockTouch[client * MAX_EDICTS + iEntity] = 1; SetBit(g_aaFilterClientEntity, client * MAX_EDICTS + iEntity);
continue; continue;
} }
else if(g_aEntityLagData[i].iSpawned == iPlayerSimTick) else if(g_aEntityLagData[i].iSpawned == iPlayerSimTick)
{ {
g_aaBlockTouch[client * MAX_EDICTS + iEntity] = 0; ClearBit(g_aaFilterClientEntity, client * MAX_EDICTS + iEntity);
} }
if(g_aEntityLagData[i].iDeleted) if(g_aEntityLagData[i].iDeleted)
{ {
if(g_aEntityLagData[i].iDeleted <= iPlayerSimTick) if(g_aEntityLagData[i].iDeleted <= iPlayerSimTick)
{ {
g_aaBlockTouch[client * MAX_EDICTS + iEntity] = 1; SetBit(g_aaFilterClientEntity, client * MAX_EDICTS + iEntity);
continue; continue;
} }
} }
@ -663,7 +697,7 @@ public void OnPostPlayerThinkFunctions()
g_aEntityLagData[i].bRestore = false; g_aEntityLagData[i].bRestore = false;
} }
FilterTriggerTouchPlayers(g_aBlockTriggerTouch, true); FilterTriggerTouchPlayers(g_aFilterTriggerTouch, true);
} }
public void OnRunThinkFunctionsPost(bool simulating) public void OnRunThinkFunctionsPost(bool simulating)
@ -846,7 +880,9 @@ bool AddEntityForLagCompensation(int iEntity, bool bLateKill)
g_aEntityLagData[i].iTouchStamp = GetEntData(iEntity, g_iTouchStamp); g_aEntityLagData[i].iTouchStamp = GetEntData(iEntity, g_iTouchStamp);
if(bLateKill) if(bLateKill)
g_aBlockTriggerTouch[iEntity] = 1; {
SetBit(g_aFilterTriggerTouch, iEntity);
}
RecordDataIntoRecord(iEntity, g_aaLagRecords[i][0]); RecordDataIntoRecord(iEntity, g_aaLagRecords[i][0]);
@ -886,11 +922,12 @@ void RemoveRecord(int index)
} }
g_aLagCompensated[iEntity] = -1; g_aLagCompensated[iEntity] = -1;
g_aBlockTriggerTouch[iEntity] = 0; ClearBit(g_aFilterTriggerTouch, iEntity);
ClearBit(g_aBlockTriggerMoved, iEntity);
for(int client = 1; client <= MaxClients; client++) for(int client = 1; client <= MaxClients; client++)
{ {
g_aaBlockTouch[client * MAX_EDICTS + iEntity] = 0; ClearBit(g_aaFilterClientEntity, client * MAX_EDICTS + iEntity);
} }
g_aEntityLagData[index].iEntity = INVALID_ENT_REFERENCE; g_aEntityLagData[index].iEntity = INVALID_ENT_REFERENCE;
@ -998,14 +1035,14 @@ public Action Command_CheckLagCompensated(int client, int argc)
bool bDeleted = false; bool bDeleted = false;
for(int j = 1; j <= MaxClients; j++) for(int j = 1; j <= MaxClients; j++)
{ {
if(g_aaBlockTouch[j * MAX_EDICTS + i]) if(CheckBit(g_aaFilterClientEntity, j * MAX_EDICTS + i))
{ {
bDeleted = true; bDeleted = true;
break; break;
} }
} }
if(g_aBlockTriggerTouch[i] || bDeleted) if(CheckBit(g_aFilterTriggerTouch, i) || bDeleted)
{ {
int index = -1; int index = -1;
for(int j = 0; j < g_iNumEntities; j++) for(int j = 0; j < g_iNumEntities; j++)
@ -1028,7 +1065,7 @@ public Action Command_CheckLagCompensated(int client, int argc)
iHammerID = GetEntProp(i, Prop_Data, "m_iHammerID"); iHammerID = GetEntProp(i, Prop_Data, "m_iHammerID");
} }
bool bBlockPhysics = g_aBlockTriggerTouch[i]; bool bBlockPhysics = CheckBit(g_aFilterTriggerTouch, i);
PrintToConsole(client, "%2d. #%d %s \"%s\" (#%d) -> BlockPhysics: %d / Deleted: %d", index, i, sClassname, sTargetname, iHammerID, bBlockPhysics, bDeleted); PrintToConsole(client, "%2d. #%d %s \"%s\" (#%d) -> BlockPhysics: %d / Deleted: %d", index, i, sClassname, sTargetname, iHammerID, bBlockPhysics, bDeleted);
} }
} }