mirror of
https://github.com/jason-e/rngfix.git
synced 2025-12-07 10:28:32 +00:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
31eb8e3b5b | ||
|
|
1df7099bbc | ||
|
|
c233d0bcc3 | ||
|
|
ad6a3d5379 | ||
|
|
bdd2f7fda5 | ||
|
|
ba2e9d22a5 | ||
|
|
1c85683a7e | ||
|
|
0e06cb0c81 | ||
|
|
46cabbe2d6 | ||
|
|
3aea927d8a |
@ -36,15 +36,15 @@
|
|||||||
// applies to trigger_vphysics_motion and trigger_wind
|
// applies to trigger_vphysics_motion and trigger_wind
|
||||||
"CBaseVPhysicsTrigger::PassesTriggerFilters"
|
"CBaseVPhysicsTrigger::PassesTriggerFilters"
|
||||||
{
|
{
|
||||||
"windows" "196"
|
"windows" "200"
|
||||||
"linux" "197"
|
"linux" "201"
|
||||||
}
|
}
|
||||||
|
|
||||||
// applies to all other triggers
|
// applies to all other triggers
|
||||||
"CBaseTrigger::PassesTriggerFilters"
|
"CBaseTrigger::PassesTriggerFilters"
|
||||||
{
|
{
|
||||||
"windows" "206"
|
"windows" "210"
|
||||||
"linux" "207"
|
"linux" "211"
|
||||||
}
|
}
|
||||||
|
|
||||||
"IServerGameEnts::MarkEntitiesAsTouching"
|
"IServerGameEnts::MarkEntitiesAsTouching"
|
||||||
@ -52,6 +52,36 @@
|
|||||||
"windows" "1"
|
"windows" "1"
|
||||||
"linux" "2"
|
"linux" "2"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"CMoveData::m_flForwardMove"
|
||||||
|
{
|
||||||
|
"windows" "44"
|
||||||
|
"linux" "44"
|
||||||
|
}
|
||||||
|
|
||||||
|
"CMoveData::m_flSideMove"
|
||||||
|
{
|
||||||
|
"windows" "48"
|
||||||
|
"linux" "48"
|
||||||
|
}
|
||||||
|
|
||||||
|
"CMoveData::m_flMaxSpeed"
|
||||||
|
{
|
||||||
|
"windows" "56"
|
||||||
|
"linux" "56"
|
||||||
|
}
|
||||||
|
|
||||||
|
"CMoveData::m_vecVelocity"
|
||||||
|
{
|
||||||
|
"windows" "64"
|
||||||
|
"linux" "64"
|
||||||
|
}
|
||||||
|
|
||||||
|
"CMoveData::m_vecAbsOrigin"
|
||||||
|
{
|
||||||
|
"windows" "172"
|
||||||
|
"linux" "172"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,24 +89,70 @@
|
|||||||
{
|
{
|
||||||
"Offsets"
|
"Offsets"
|
||||||
{
|
{
|
||||||
|
"CMoveData::m_flForwardMove"
|
||||||
|
{
|
||||||
|
"windows" "44"
|
||||||
|
"windows64" "44"
|
||||||
|
"linux" "44"
|
||||||
|
"linux64" "44"
|
||||||
|
}
|
||||||
|
|
||||||
|
"CMoveData::m_flSideMove"
|
||||||
|
{
|
||||||
|
"windows" "52"
|
||||||
|
"windows64" "52"
|
||||||
|
"linux" "52"
|
||||||
|
"linux64" "52"
|
||||||
|
}
|
||||||
|
|
||||||
|
"CMoveData::m_flMaxSpeed"
|
||||||
|
{
|
||||||
|
"windows" "60"
|
||||||
|
"windows64" "60"
|
||||||
|
"linux" "60"
|
||||||
|
"linux64" "60"
|
||||||
|
}
|
||||||
|
|
||||||
|
"CMoveData::m_vecVelocity"
|
||||||
|
{
|
||||||
|
"windows" "68"
|
||||||
|
"windows64" "68"
|
||||||
|
"linux" "68"
|
||||||
|
"linux64" "68"
|
||||||
|
}
|
||||||
|
|
||||||
|
"CMoveData::m_vecAbsOrigin"
|
||||||
|
{
|
||||||
|
"windows" "156"
|
||||||
|
"windows64" "156"
|
||||||
|
"linux" "156"
|
||||||
|
"linux64" "156"
|
||||||
|
}
|
||||||
|
|
||||||
// applies to trigger_vphysics_motion and trigger_wind
|
// applies to trigger_vphysics_motion and trigger_wind
|
||||||
"CBaseVPhysicsTrigger::PassesTriggerFilters"
|
"CBaseVPhysicsTrigger::PassesTriggerFilters"
|
||||||
{
|
{
|
||||||
"windows" "188"
|
"windows" "194"
|
||||||
"linux" "189"
|
"windows64" "194"
|
||||||
|
"linux" "195"
|
||||||
|
"linux64" "195"
|
||||||
}
|
}
|
||||||
|
|
||||||
// applies to all other triggers
|
// applies to all other triggers
|
||||||
"CBaseTrigger::PassesTriggerFilters"
|
"CBaseTrigger::PassesTriggerFilters"
|
||||||
{
|
{
|
||||||
"windows" "197"
|
"windows" "203"
|
||||||
"linux" "198"
|
"windows64" "203"
|
||||||
|
"linux" "204"
|
||||||
|
"linux64" "204"
|
||||||
}
|
}
|
||||||
|
|
||||||
"IServerGameEnts::MarkEntitiesAsTouching"
|
"IServerGameEnts::MarkEntitiesAsTouching"
|
||||||
{
|
{
|
||||||
"windows" "2"
|
"windows" "2"
|
||||||
|
"windows64" "2"
|
||||||
"linux" "3"
|
"linux" "3"
|
||||||
|
"linux64" "3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
#pragma semicolon 1
|
#pragma semicolon 1
|
||||||
#pragma newdecls required
|
#pragma newdecls required
|
||||||
|
|
||||||
#define PLUGIN_VERSION "1.1.1"
|
#define PLUGIN_VERSION "1.1.3"
|
||||||
|
|
||||||
public Plugin myinfo =
|
public Plugin myinfo =
|
||||||
{
|
{
|
||||||
@ -48,7 +48,7 @@ int g_iLastGroundEnt[MAXPLAYERS+1];
|
|||||||
int g_iLastLandTick[MAXPLAYERS+1];
|
int g_iLastLandTick[MAXPLAYERS+1];
|
||||||
int g_iLastCollisionTick[MAXPLAYERS+1];
|
int g_iLastCollisionTick[MAXPLAYERS+1];
|
||||||
int g_iLastMapTeleportTick[MAXPLAYERS+1];
|
int g_iLastMapTeleportTick[MAXPLAYERS+1];
|
||||||
int g_bMapTeleportedSequentialTicks[MAXPLAYERS+1];
|
bool g_bMapTeleportedSequentialTicks[MAXPLAYERS+1];
|
||||||
float g_vCollisionPoint[MAXPLAYERS+1][3];
|
float g_vCollisionPoint[MAXPLAYERS+1][3];
|
||||||
float g_vCollisionNormal[MAXPLAYERS+1][3];
|
float g_vCollisionNormal[MAXPLAYERS+1][3];
|
||||||
|
|
||||||
@ -86,6 +86,12 @@ Handle g_hProcessMovementHookPre;
|
|||||||
Address g_IServerGameEnts;
|
Address g_IServerGameEnts;
|
||||||
Handle g_hMarkEntitiesAsTouching;
|
Handle g_hMarkEntitiesAsTouching;
|
||||||
|
|
||||||
|
int g_iCMoveData_ForwardMove;
|
||||||
|
int g_iCMoveData_SideMove;
|
||||||
|
int g_iCMoveData_MaxSpeed;
|
||||||
|
int g_iCMoveData_Velocity;
|
||||||
|
int g_iCMoveData_Origin;
|
||||||
|
|
||||||
bool g_bIsSurfMap;
|
bool g_bIsSurfMap;
|
||||||
|
|
||||||
bool g_bLateLoad;
|
bool g_bLateLoad;
|
||||||
@ -223,6 +229,27 @@ public void OnPluginStart()
|
|||||||
DHookAddParam(g_hProcessMovementHookPre, HookParamType_ObjectPtr);
|
DHookAddParam(g_hProcessMovementHookPre, HookParamType_ObjectPtr);
|
||||||
DHookRaw(g_hProcessMovementHookPre, false, IGameMovement);
|
DHookRaw(g_hProcessMovementHookPre, false, IGameMovement);
|
||||||
|
|
||||||
|
if ((g_iCMoveData_ForwardMove = GameConfGetOffset(gamedataConf, "CMoveData::m_flForwardMove")) == -1)
|
||||||
|
{
|
||||||
|
SetFailState("Failed to get CMoveData::m_flForwardMove");
|
||||||
|
}
|
||||||
|
if ((g_iCMoveData_SideMove = GameConfGetOffset(gamedataConf, "CMoveData::m_flSideMove")) == -1)
|
||||||
|
{
|
||||||
|
SetFailState("Failed to get CMoveData::m_flSideMove");
|
||||||
|
}
|
||||||
|
if ((g_iCMoveData_MaxSpeed = GameConfGetOffset(gamedataConf, "CMoveData::m_flMaxSpeed")) == -1)
|
||||||
|
{
|
||||||
|
SetFailState("Failed to get CMoveData::m_flMaxSpeed");
|
||||||
|
}
|
||||||
|
if ((g_iCMoveData_Velocity = GameConfGetOffset(gamedataConf, "CMoveData::m_vecVelocity")) == -1)
|
||||||
|
{
|
||||||
|
SetFailState("Failed to get CMoveData::m_vecVelocity");
|
||||||
|
}
|
||||||
|
if ((g_iCMoveData_Origin = GameConfGetOffset(gamedataConf, "CMoveData::m_vecAbsOrigin")) == -1)
|
||||||
|
{
|
||||||
|
SetFailState("Failed to get CMoveData::m_vecAbsOrigin");
|
||||||
|
}
|
||||||
|
|
||||||
// MarkEntitiesAsTouching
|
// MarkEntitiesAsTouching
|
||||||
if (!GameConfGetKeyValue(gamedataConf, "IServerGameEnts", interfaceName, sizeof(interfaceName)))
|
if (!GameConfGetKeyValue(gamedataConf, "IServerGameEnts", interfaceName, sizeof(interfaceName)))
|
||||||
{
|
{
|
||||||
@ -486,7 +513,7 @@ void AirAccelerate(int client, float velocity[3], Handle hParams)
|
|||||||
for (int i = 0; i < 2; i++) wishvel[i] = fore[i] * g_vVel[client][0] + side[i] * g_vVel[client][1];
|
for (int i = 0; i < 2; i++) wishvel[i] = fore[i] * g_vVel[client][0] + side[i] * g_vVel[client][1];
|
||||||
|
|
||||||
float wishspeed = NormalizeVector(wishvel, wishdir);
|
float wishspeed = NormalizeVector(wishvel, wishdir);
|
||||||
float m_flMaxSpeed = DHookGetParamObjectPtrVar(hParams, 2, 56, ObjectValueType_Float);
|
float m_flMaxSpeed = DHookGetParamObjectPtrVar(hParams, 2, g_iCMoveData_MaxSpeed, ObjectValueType_Float);
|
||||||
if (wishspeed > m_flMaxSpeed && m_flMaxSpeed != 0.0) wishspeed = m_flMaxSpeed;
|
if (wishspeed > m_flMaxSpeed && m_flMaxSpeed != 0.0) wishspeed = m_flMaxSpeed;
|
||||||
|
|
||||||
if (wishspeed)
|
if (wishspeed)
|
||||||
@ -565,7 +592,7 @@ void PreventCollision(int client, Handle hParams, const float origin[3], const f
|
|||||||
|
|
||||||
// Since the MoveData for this tick has already been filled and is about to be used, we need
|
// Since the MoveData for this tick has already been filled and is about to be used, we need
|
||||||
// to modify it directly instead of changing the player entity's actual position (such as with TeleportEntity).
|
// to modify it directly instead of changing the player entity's actual position (such as with TeleportEntity).
|
||||||
DHookSetParamObjectPtrVarVector(hParams, 2, GetEngineVersion() == Engine_CSGO ? 172 : 152, ObjectValueType_Vector, newOrigin);
|
DHookSetParamObjectPtrVarVector(hParams, 2, g_iCMoveData_Origin, ObjectValueType_Vector, newOrigin);
|
||||||
|
|
||||||
DebugLaser(client, origin, newOrigin, 15.0, 0.5, g_color2);
|
DebugLaser(client, origin, newOrigin, 15.0, 0.5, g_color2);
|
||||||
|
|
||||||
@ -589,20 +616,28 @@ void ClipVelocity(const float velocity[3], const float nrm[3], float out[3])
|
|||||||
// The adjust step only matters with overbounce which doesnt apply to walkable surfaces.
|
// The adjust step only matters with overbounce which doesnt apply to walkable surfaces.
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetVelocity(int client, float velocity[3])
|
void SetVelocity(int client, float velocity[3], bool dontUseTeleportEntity = false)
|
||||||
{
|
{
|
||||||
// Pull out basevelocity from desired true velocity
|
// Pull out basevelocity from desired true velocity
|
||||||
// Use the pre-tick basevelocity because that is what influenced this tick's movement and the desired new velocity.
|
// Use the pre-tick basevelocity because that is what influenced this tick's movement and the desired new velocity.
|
||||||
SubtractVectors(velocity, g_vLastBaseVelocity[client], velocity);
|
SubtractVectors(velocity, g_vLastBaseVelocity[client], velocity);
|
||||||
|
|
||||||
float baseVelocity[3];
|
if (dontUseTeleportEntity && GetEntPropEnt(client, Prop_Data, "m_hMoveParent") == -1)
|
||||||
GetEntPropVector(client, Prop_Data, "m_vecBaseVelocity", baseVelocity);
|
{
|
||||||
|
SetEntPropVector(client, Prop_Data, "m_vecAbsVelocity", velocity);
|
||||||
|
SetEntPropVector(client, Prop_Data, "m_vecVelocity", velocity);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float baseVelocity[3];
|
||||||
|
GetEntPropVector(client, Prop_Data, "m_vecBaseVelocity", baseVelocity);
|
||||||
|
|
||||||
TeleportEntity(client, NULL_VECTOR, NULL_VECTOR, velocity);
|
TeleportEntity(client, NULL_VECTOR, NULL_VECTOR, velocity);
|
||||||
|
|
||||||
// TeleportEntity with non-null velocity wipes out basevelocity, so restore it after.
|
// TeleportEntity with non-null velocity wipes out basevelocity, so restore it after.
|
||||||
// Since we didn't change position, nothing should change regarding influences on basevelocity.
|
// Since we didn't change position, nothing should change regarding influences on basevelocity.
|
||||||
SetEntPropVector(client, Prop_Data, "m_vecBaseVelocity", baseVelocity);
|
SetEntPropVector(client, Prop_Data, "m_vecBaseVelocity", baseVelocity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public MRESReturn DHook_ProcessMovementPre(Handle hParams)
|
public MRESReturn DHook_ProcessMovementPre(Handle hParams)
|
||||||
@ -642,18 +677,20 @@ void RunPreTickChecks(int client, Handle hParams)
|
|||||||
|
|
||||||
g_iButtons[client] = DHookGetParamObjectPtrVar(hParams, 2, 36, ObjectValueType_Int);
|
g_iButtons[client] = DHookGetParamObjectPtrVar(hParams, 2, 36, ObjectValueType_Int);
|
||||||
g_iOldButtons[client] = DHookGetParamObjectPtrVar(hParams, 2, 40, ObjectValueType_Int);
|
g_iOldButtons[client] = DHookGetParamObjectPtrVar(hParams, 2, 40, ObjectValueType_Int);
|
||||||
DHookGetParamObjectPtrVarVector(hParams, 2, 44, ObjectValueType_Vector, g_vVel[client]);
|
g_vVel[client][0] = DHookGetParamObjectPtrVar(hParams, 2, g_iCMoveData_ForwardMove, ObjectValueType_Float);
|
||||||
|
g_vVel[client][1] = DHookGetParamObjectPtrVar(hParams, 2, g_iCMoveData_SideMove, ObjectValueType_Float);
|
||||||
|
g_vVel[client][2] = 0.0;
|
||||||
DHookGetParamObjectPtrVarVector(hParams, 2, 12, ObjectValueType_Vector, g_vAngles[client]);
|
DHookGetParamObjectPtrVarVector(hParams, 2, 12, ObjectValueType_Vector, g_vAngles[client]);
|
||||||
|
|
||||||
float velocity[3];
|
float velocity[3];
|
||||||
DHookGetParamObjectPtrVarVector(hParams, 2, 64, ObjectValueType_Vector, velocity);
|
DHookGetParamObjectPtrVarVector(hParams, 2, g_iCMoveData_Velocity, ObjectValueType_Vector, velocity);
|
||||||
|
|
||||||
float baseVelocity[3];
|
float baseVelocity[3];
|
||||||
// basevelocity is not stored in MoveData
|
// basevelocity is not stored in MoveData
|
||||||
GetEntPropVector(client, Prop_Data, "m_vecBaseVelocity", baseVelocity);
|
GetEntPropVector(client, Prop_Data, "m_vecBaseVelocity", baseVelocity);
|
||||||
|
|
||||||
float origin[3];
|
float origin[3];
|
||||||
DHookGetParamObjectPtrVarVector(hParams, 2, GetEngineVersion() == Engine_CSGO ? 172 : 152, ObjectValueType_Vector, origin);
|
DHookGetParamObjectPtrVarVector(hParams, 2, g_iCMoveData_Origin, ObjectValueType_Vector, origin);
|
||||||
|
|
||||||
float nextOrigin[3], mins[3], maxs[3];
|
float nextOrigin[3], mins[3], maxs[3];
|
||||||
|
|
||||||
@ -998,7 +1035,9 @@ bool DoInclineCollisionFixes(int client, const float nrm[3])
|
|||||||
|
|
||||||
// If a collision was predicted this tick (and wasn't prevented by another fix alrady), no fix is needed.
|
// If a collision was predicted this tick (and wasn't prevented by another fix alrady), no fix is needed.
|
||||||
// It's possible we actually have to run the edge bug fix and an incline fix in the same tick.
|
// It's possible we actually have to run the edge bug fix and an incline fix in the same tick.
|
||||||
if (g_iLastCollisionTick[client] == g_iTick[client]) return false;
|
// If using the old Slopefix logic, do the fix regardless of necessity just like Slopefix
|
||||||
|
// so we can be sure to trigger a double boost if applicable.
|
||||||
|
if (g_iLastCollisionTick[client] == g_iTick[client] && !g_cvUseOldSlopefixLogic.BoolValue) return false;
|
||||||
|
|
||||||
// Make sure the ground is not level, otherwise a collision would do nothing important anyway.
|
// Make sure the ground is not level, otherwise a collision would do nothing important anyway.
|
||||||
if (nrm[2] == 1.0) return false;
|
if (nrm[2] == 1.0) return false;
|
||||||
@ -1094,9 +1133,24 @@ bool DoTelehopFix(int client)
|
|||||||
// Don't forget to add the second half-tick of gravity ourselves.
|
// Don't forget to add the second half-tick of gravity ourselves.
|
||||||
FinishGravity(client, newVelocity);
|
FinishGravity(client, newVelocity);
|
||||||
|
|
||||||
DebugMsg(client, "DO FIX: Telehop");
|
float origin[3];
|
||||||
|
GetEntPropVector(client, Prop_Data, "m_vecAbsOrigin", origin);
|
||||||
|
|
||||||
SetVelocity(client, newVelocity);
|
float mins[3], maxs[3];
|
||||||
|
GetEntPropVector(client, Prop_Data, "m_vecMins", mins);
|
||||||
|
GetEntPropVector(client, Prop_Data, "m_vecMaxs", maxs);
|
||||||
|
|
||||||
|
TR_TraceHullFilter(origin, origin, mins, maxs, MASK_PLAYERSOLID, PlayerFilter);
|
||||||
|
|
||||||
|
// If we appear to be "stuck" after teleporting (likely because the teleport destination
|
||||||
|
// was exactly on the ground), set velocity directly to avoid side-effects of
|
||||||
|
// TeleportEntity that can cause the player to really get stuck in the ground.
|
||||||
|
// This might only be an issue in CSS, but do it on CSGO too just to be safe.
|
||||||
|
bool dontUseTeleportEntity = TR_DidHit();
|
||||||
|
|
||||||
|
DebugMsg(client, "DO FIX: Telehop%s", dontUseTeleportEntity ? " (no TeleportEntity)" : "");
|
||||||
|
|
||||||
|
SetVelocity(client, newVelocity, dontUseTeleportEntity);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
4
tech.md
4
tech.md
@ -68,7 +68,7 @@ The rationale behind this is that, if the player is "landed" on the ground, then
|
|||||||
---
|
---
|
||||||
**Telehops** [Post-tick]
|
**Telehops** [Post-tick]
|
||||||
|
|
||||||
If the plugin detects that a `trigger_teleport` was activated during this tick, and either:
|
If the plugin detects that a `trigger_teleport` was activated during this tick, the player did *not* activate one the previous tick, and either:
|
||||||
* The plugin predicted right before the tick that a collision would occur during this tick (resulting in a change / loss of velocity)
|
* The plugin predicted right before the tick that a collision would occur during this tick (resulting in a change / loss of velocity)
|
||||||
*or*
|
*or*
|
||||||
* The plugin detected that the client landed during the simulation of the tick (resulting in an instant removal of Z velocity)
|
* The plugin detected that the client landed during the simulation of the tick (resulting in an instant removal of Z velocity)
|
||||||
@ -77,6 +77,8 @@ Then the player's velocity is restored to the velocity they would have had after
|
|||||||
|
|
||||||
The engine simulates each tick in a sequence of discrete steps, which to put it simply starts with a complete simulation of player movement including collisions with any solids, and only *after* this has finished does the engine check to see if the client is touching any triggers and activates them. This means it is not all that unlikely that a player will collide with something inside of or behind a thin `trigger_teleport` before triggering it, despite passing through it to even reach the point of collision. Occurrences of this issue are more prevalent on **lower** tickrates.
|
The engine simulates each tick in a sequence of discrete steps, which to put it simply starts with a complete simulation of player movement including collisions with any solids, and only *after* this has finished does the engine check to see if the client is touching any triggers and activates them. This means it is not all that unlikely that a player will collide with something inside of or behind a thin `trigger_teleport` before triggering it, despite passing through it to even reach the point of collision. Occurrences of this issue are more prevalent on **lower** tickrates.
|
||||||
|
|
||||||
|
This fix is not applied if the player also activated a `trigger_teleport` on the previous tick to account for the speed-stopping teleport hubs some mappers use, especially on surf maps. These hubs typically teleport the player into a tiny box (or even inside a clip brush), and then at that location the player activates another `trigger_teleport` -- or sometimes one of several based on their `targetname` or `classname`. These are explicitly set up to stop the player's speed, and thus the fix should not be applied.
|
||||||
|
|
||||||
---
|
---
|
||||||
**Stair Sliding** [Post-tick]
|
**Stair Sliding** [Post-tick]
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user