get the shavit_misc_prespeed 1&&>=3 working again with the on-ground timer

This commit is contained in:
rtldg 2023-06-21 01:41:07 +00:00
parent ca60971410
commit 309aa7a189
4 changed files with 158 additions and 43 deletions

View File

@ -551,6 +551,15 @@ stock void TrimDisplayString(const char[] str, char[] outstr, int outstrlen, int
Format(outstr, outstrlen, "%s...", outstr); Format(outstr, outstrlen, "%s...", outstr);
} }
// TODO: surfacefriction
stock float MaxPrestrafe(float runspeed, float accelerate, float friction, float tickinterval)
{
return runspeed * SquareRoot(
(accelerate / friction) *
((2.0 - accelerate * tickinterval) / (2.0 - friction * tickinterval))
);
}
/** /**
* Called before shavit-core processes the client's usercmd. * Called before shavit-core processes the client's usercmd.
* Before this is called, safety checks (fake/dead clients) happen. * Before this is called, safety checks (fake/dead clients) happen.
@ -599,9 +608,10 @@ forward void Shavit_OnTimeIncrementPost(int client, float time);
* *
* @param client Client index. * @param client Client index.
* @param track Timer track. * @param track Timer track.
* @param skipGroundTimer Whether shavit-core can skip the on-ground-for-half-a-second check. shavit-misc uses this for some prespeed settings...
* @return Plugin_Continue to do nothing or anything else to not start the timer. * @return Plugin_Continue to do nothing or anything else to not start the timer.
*/ */
forward Action Shavit_OnStartPre(int client, int track); forward Action Shavit_OnStartPre(int client, int track, bool& skipGroundTimer);
/** /**
* Called when a player's timer starts. * Called when a player's timer starts.
@ -862,9 +872,10 @@ native Database Shavit_GetDatabase(int& outdriver=0);
* *
* @param client Client index. * @param client Client index.
* @param track Timer track. * @param track Timer track.
* @param skipGroundCheck Whether to skip checking if the player is on the ground. This is used in shavit-zones for when teleporting/!restarting players to a floating zone...
* @noreturn * @noreturn
*/ */
native void Shavit_StartTimer(int client, int track); native void Shavit_StartTimer(int client, int track, bool skipGroundCheck=false);
/** /**
* Restarts the timer for a player. * Restarts the timer for a player.

View File

@ -256,7 +256,7 @@ public void OnPluginStart()
{ {
// forwards // forwards
gH_Forwards_Start = CreateGlobalForward("Shavit_OnStart", ET_Ignore, Param_Cell, Param_Cell); gH_Forwards_Start = CreateGlobalForward("Shavit_OnStart", ET_Ignore, Param_Cell, Param_Cell);
gH_Forwards_StartPre = CreateGlobalForward("Shavit_OnStartPre", ET_Event, Param_Cell, Param_Cell); gH_Forwards_StartPre = CreateGlobalForward("Shavit_OnStartPre", ET_Event, Param_Cell, Param_Cell, Param_CellByRef);
gH_Forwards_Stop = CreateGlobalForward("Shavit_OnStop", ET_Event, Param_Cell, Param_Cell); gH_Forwards_Stop = CreateGlobalForward("Shavit_OnStop", ET_Event, Param_Cell, Param_Cell);
gH_Forwards_StopPre = CreateGlobalForward("Shavit_OnStopPre", ET_Event, Param_Cell, Param_Cell); gH_Forwards_StopPre = CreateGlobalForward("Shavit_OnStopPre", ET_Event, Param_Cell, Param_Cell);
gH_Forwards_FinishPre = CreateGlobalForward("Shavit_OnFinishPre", ET_Hook, Param_Cell, Param_Array); gH_Forwards_FinishPre = CreateGlobalForward("Shavit_OnFinishPre", ET_Hook, Param_Cell, Param_Array);
@ -1777,7 +1777,7 @@ public int Native_IsKZMap(Handle handler, int numParams)
public int Native_StartTimer(Handle handler, int numParams) public int Native_StartTimer(Handle handler, int numParams)
{ {
StartTimer(GetNativeCell(1), GetNativeCell(2)); StartTimer(GetNativeCell(1), GetNativeCell(2), numParams >= 3 ? GetNativeCell(3) : false);
return 0; return 0;
} }
@ -2440,58 +2440,88 @@ TimerStatus GetTimerStatus(int client)
return Timer_Running; return Timer_Running;
} }
// TODO: surfacefriction float StyleMaxPrestrafe(int style)
float MaxPrestrafe(float runspeed, float accelerate, float friction, float tickinterval)
{ {
return runspeed * SquareRoot( float runspeed = GetStyleSettingFloat(style, "runspeed");
(accelerate / friction) *
((2.0 - accelerate * tickinterval) / (2.0 - friction * tickinterval))
);
}
float ClientMaxPrestrafe(int client)
{
float runspeed = GetStyleSettingFloat(gA_Timers[client].bsStyle, "runspeed");
return MaxPrestrafe(runspeed, sv_accelerate.FloatValue, sv_friction.FloatValue, GetTickInterval()); return MaxPrestrafe(runspeed, sv_accelerate.FloatValue, sv_friction.FloatValue, GetTickInterval());
} }
void StartTimer(int client, int track) bool CanStartTimer(int client, int track, bool skipGroundCheck)
{ {
if(!IsValidClient(client, true) || GetClientTeam(client) < 2 || IsFakeClient(client) || !gB_CookiesRetrieved[client]) if(!IsValidClient(client, true) || GetClientTeam(client) < 2 || IsFakeClient(client) || !gB_CookiesRetrieved[client])
{ {
return; return false;
} }
int style = gA_Timers[client].bsStyle;
int prespeed = GetStyleSettingInt(style, "prespeed");
if (prespeed == 1)
return true;
float fSpeed[3]; float fSpeed[3];
GetEntPropVector(client, Prop_Data, "m_vecVelocity", fSpeed); GetEntPropVector(client, Prop_Data, "m_vecVelocity", fSpeed);
int nozaxisspeed = GetStyleSettingInt(style, "nozaxisspeed");
if (nozaxisspeed < 0) nozaxisspeed = gCV_NoZAxisSpeed.IntValue;
if (nozaxisspeed && fSpeed[2] != 0.0)
return false;
if (prespeed == 2)
return true;
bool skipGroundTimer = false;
Action result = Plugin_Continue;
Call_StartForward(gH_Forwards_StartPre);
Call_PushCell(client);
Call_PushCell(track);
Call_PushCellRef(skipGroundTimer);
Call_Finish(result);
if (result != Plugin_Continue)
return false;
// re-grab velocity in case shavit-misc capped it
GetEntPropVector(client, Prop_Data, "m_vecVelocity", fSpeed);
float curVel = SquareRoot(Pow(fSpeed[0], 2.0) + Pow(fSpeed[1], 2.0)); float curVel = SquareRoot(Pow(fSpeed[0], 2.0) + Pow(fSpeed[1], 2.0));
int nozaxisspeed = GetStyleSettingInt(gA_Timers[client].bsStyle, "nozaxisspeed"); // This helps with zones that are floating in the air (commonly for bonuses).
// Since you teleport into the air with 0-velocity...
if (curVel <= 50.0)
return true;
if (nozaxisspeed < 0) float prestrafe = StyleMaxPrestrafe(style);
if (curVel > prestrafe)
return false;
if (skipGroundCheck || GetStyleSettingBool(style, "startinair"))
return true;
#if 0
MoveType mtMoveType = GetEntityMoveType(client);
bool bInWater = (GetEntProp(client, Prop_Send, "m_nWaterLevel") >= 2);
int iGroundEntity = GetEntPropEnt(client, Prop_Send, "m_hGroundEntity");
// gA_Timers[client].bOnGround isn't updated/correct when zones->touchpost->starttimer happens... frustrating...
bool bOnGround = (!bInWater && mtMoveType == MOVETYPE_WALK && iGroundEntity != -1);
if (!bOnGround) return false;
#endif
if (skipGroundTimer) return true;
int halfSecOfTicks = RoundFloat(0.5 / GetTickInterval());
int onGroundTicks = gI_LastTickcount[client] - gI_FirstTouchedGround[client];
return onGroundTicks >= halfSecOfTicks;
}
void StartTimer(int client, int track, bool skipGroundCheck)
{
if (CanStartTimer(client, track, skipGroundCheck))
{ {
nozaxisspeed = gCV_NoZAxisSpeed.BoolValue; if (true) // fucking shit
}
if (!nozaxisspeed ||
GetStyleSettingInt(gA_Timers[client].bsStyle, "prespeed") == 1 ||
(fSpeed[2] == 0.0 && (GetStyleSettingInt(gA_Timers[client].bsStyle, "prespeed") == 2 || curVel <= 50.0 ||
((curVel <= ClientMaxPrestrafe(client) && gA_Timers[client].bOnGround &&
(gI_LastTickcount[client]-gI_FirstTouchedGround[client] > RoundFloat(0.5/GetTickInterval()))))))) // beautiful
{
Action result = Plugin_Continue;
Call_StartForward(gH_Forwards_StartPre);
Call_PushCell(client);
Call_PushCell(track);
Call_Finish(result);
if(result == Plugin_Continue)
{ {
Call_StartForward(gH_Forwards_Start);
Call_PushCell(client);
Call_PushCell(track);
Call_Finish(result);
if (gA_Timers[client].bClientPaused) if (gA_Timers[client].bClientPaused)
{ {
//SetEntityMoveType(client, MOVETYPE_WALK); //SetEntityMoveType(client, MOVETYPE_WALK);
@ -2523,6 +2553,11 @@ void StartTimer(int client, int track)
gA_Timers[client].fZoneOffset[Zone_End] = 0.0; gA_Timers[client].fZoneOffset[Zone_End] = 0.0;
gA_Timers[client].fDistanceOffset[Zone_Start] = 0.0; gA_Timers[client].fDistanceOffset[Zone_Start] = 0.0;
gA_Timers[client].fDistanceOffset[Zone_End] = 0.0; gA_Timers[client].fDistanceOffset[Zone_End] = 0.0;
float fSpeed[3];
GetEntPropVector(client, Prop_Data, "m_vecVelocity", fSpeed);
float curVel = SquareRoot(Pow(fSpeed[0], 2.0) + Pow(fSpeed[1], 2.0));
gA_Timers[client].fAvgVelocity = curVel; gA_Timers[client].fAvgVelocity = curVel;
gA_Timers[client].fMaxVelocity = curVel; gA_Timers[client].fMaxVelocity = curVel;
@ -2533,6 +2568,11 @@ void StartTimer(int client, int track)
UpdateLaggedMovement(client, true); UpdateLaggedMovement(client, true);
SetEntityGravity(client, GetStyleSettingFloat(gA_Timers[client].bsStyle, "gravity")); SetEntityGravity(client, GetStyleSettingFloat(gA_Timers[client].bsStyle, "gravity"));
Call_StartForward(gH_Forwards_Start);
Call_PushCell(client);
Call_PushCell(track);
Call_Finish();
} }
#if 0 #if 0
else if(result == Plugin_Handled || result == Plugin_Stop) else if(result == Plugin_Handled || result == Plugin_Stop)

View File

@ -117,6 +117,8 @@ ConVar gCV_PauseMovement = null;
Convar gCV_RestartWithFullHP = null; Convar gCV_RestartWithFullHP = null;
// external cvars // external cvars
ConVar sv_accelerate = null;
ConVar sv_friction = null;
ConVar sv_cheats = null; ConVar sv_cheats = null;
ConVar sv_disable_immunity_alpha = null; ConVar sv_disable_immunity_alpha = null;
ConVar mp_humanteam = null; ConVar mp_humanteam = null;
@ -312,6 +314,9 @@ public void OnPluginStart()
sv_disable_radar = FindConVar("sv_disable_radar"); sv_disable_radar = FindConVar("sv_disable_radar");
tf_dropped_weapon_lifetime = FindConVar("tf_dropped_weapon_lifetime"); tf_dropped_weapon_lifetime = FindConVar("tf_dropped_weapon_lifetime");
sv_accelerate = FindConVar("sv_accelerate");
sv_friction = FindConVar("sv_friction");
// crons // crons
CreateTimer(10.0, Timer_Cron, 0, TIMER_REPEAT); CreateTimer(10.0, Timer_Cron, 0, TIMER_REPEAT);
@ -2253,13 +2258,69 @@ public Action Command_Specs(int client, int args)
return Plugin_Handled; return Plugin_Handled;
} }
public Action Shavit_OnStartPre(int client) float StyleMaxPrestrafe(int style)
{ {
if (Shavit_GetStyleSettingInt(gI_Style[client], "prespeed") == 0 && GetEntityMoveType(client) == MOVETYPE_NOCLIP) float runspeed = Shavit_GetStyleSettingFloat(style, "runspeed");
return MaxPrestrafe(runspeed, sv_accelerate.FloatValue, sv_friction.FloatValue, GetTickInterval());
}
public Action Shavit_OnStartPre(int client, int track, bool& skipGroundTimer)
{
if (GetEntityMoveType(client) == MOVETYPE_NOCLIP)
{ {
return Plugin_Stop; return Plugin_Stop;
} }
if (Shavit_GetStyleSettingInt(gI_Style[client], "prespeed") == 0)
{
int prespeed_type = Shavit_GetStyleSettingInt(gI_Style[client], "prespeed_type");
if (prespeed_type == -1)
{
prespeed_type = gCV_PreSpeed.IntValue;
}
if (prespeed_type == 1 || prespeed_type >= 3)
{
float fSpeed[3];
GetEntPropVector(client, Prop_Data, "m_vecAbsVelocity", fSpeed);
float fLimit = (Shavit_GetStyleSettingFloat(gI_Style[client], "runspeed") + gCV_PrestrafeLimit.FloatValue);
float maxPrestrafe = StyleMaxPrestrafe(gI_Style[client]);
if (fLimit > maxPrestrafe) fLimit = maxPrestrafe;
// if trying to jump, add a very low limit to stop prespeeding in an elegant way
// otherwise, make sure nothing weird is happening (such as sliding at ridiculous speeds, at zone enter)
if (prespeed_type < 4 && fSpeed[2] > 0.0)
{
fLimit /= 3.0;
}
float fSpeedXY = (SquareRoot(Pow(fSpeed[0], 2.0) + Pow(fSpeed[1], 2.0)));
float fScale = (fLimit / fSpeedXY);
if(fScale < 1.0)
{
if (prespeed_type == 5)
{
float zSpeed = fSpeed[2];
fSpeed[2] = 0.0;
ScaleVector(fSpeed, fScale);
fSpeed[2] = zSpeed;
}
else
{
ScaleVector(fSpeed, fScale);
}
DumbSetVelocity(client, fSpeed);
}
skipGroundTimer = true;
}
}
return Plugin_Continue; return Plugin_Continue;
} }

View File

@ -4991,7 +4991,8 @@ public void Shavit_OnRestart(int client, int track)
{ {
ResetClientTargetNameAndClassName(client, track); ResetClientTargetNameAndClassName(client, track);
// normally StartTimer will happen on zone-touch BUT we have this here for zones that are in the air // normally StartTimer will happen on zone-touch BUT we have this here for zones that are in the air
Shavit_StartTimer(client, track); bool skipGroundCheck = true;
Shavit_StartTimer(client, track, skipGroundCheck);
} }
} }
// kz buttons // kz buttons
@ -5416,10 +5417,12 @@ public void TouchPost(int entity, int other)
} }
} }
#if 0
if (GetEntPropEnt(other, Prop_Send, "m_hGroundEntity") == -1 && !Shavit_GetStyleSettingBool(Shavit_GetBhopStyle(other), "startinair")) if (GetEntPropEnt(other, Prop_Send, "m_hGroundEntity") == -1 && !Shavit_GetStyleSettingBool(Shavit_GetBhopStyle(other), "startinair"))
{ {
return; return;
} }
#endif
// start timer instantly for main track, but require bonuses to have the current timer stopped // start timer instantly for main track, but require bonuses to have the current timer stopped
// so you don't accidentally step on those while running // so you don't accidentally step on those while running