diff --git a/addons/sourcemod/scripting/include/shavit/tas-xutax.inc b/addons/sourcemod/scripting/include/shavit/tas-xutax.inc index 6d6f0cf2f..d93c37832 100644 --- a/addons/sourcemod/scripting/include/shavit/tas-xutax.inc +++ b/addons/sourcemod/scripting/include/shavit/tas-xutax.inc @@ -21,48 +21,8 @@ #endif #define _shavit_tas_xutax_included - -// taken from shavit's oryx -stock bool IsSurfing(int client) -{ - float fPosition[3]; - GetClientAbsOrigin(client, fPosition); - - float fEnd[3]; - fEnd = fPosition; - fEnd[2] -= 64.0; - - float fMins[3]; - GetEntPropVector(client, Prop_Send, "m_vecMins", fMins); - - float fMaxs[3]; - GetEntPropVector(client, Prop_Send, "m_vecMaxs", fMaxs); - - Handle hTR = TR_TraceHullFilterEx(fPosition, fEnd, fMins, fMaxs, MASK_PLAYERSOLID, TRFilter_NoPlayers, client); - - if(TR_DidHit(hTR)) - { - float fNormal[3]; - TR_GetPlaneNormal(hTR, fNormal); - - delete hTR; - - // If the plane normal's Z axis is 0.7 or below (alternatively, -0.7 when upside-down) then it's a surf ramp. - // https://github.com/alliedmodders/hl2sdk/blob/92dcf04225a278b75170cc84917f04e98f5d08ec/game/server/physics_main.cpp#L1059 - // https://github.com/ValveSoftware/source-sdk-2013/blob/0d8dceea4310fde5706b3ce1c70609d72a38efdf/mp/src/game/server/physics_main.cpp#L1065 - - return (-0.7 <= fNormal[2] <= 0.7); - } - - delete hTR; - - return false; -} - -public bool TRFilter_NoPlayers(int entity, int mask, any data) -{ - return (entity != view_as(data) || (entity < 1 || entity > MaxClients)); -} +// reference code for CGameMovement::AirAccelerate & CGameMovement::AirMove at: +// https://github.com/ValveSoftware/source-sdk-2013/blob/0d8dceea4310fde5706b3ce1c70609d72a38efdf/mp/src/game/shared/gamemovement.cpp#L1707-L1799 float AngleNormalize(float flAngle) @@ -108,7 +68,7 @@ float Vec2DToYaw(float vec[2]) * But, for noclip (3D) it's a different story that I will let you discover, same method, but 3 equations and 3 unknown variables (forwardmove, sidemove, upmove). */ -void Solve2DMovementsVars(float vecWishDir[2], float vecForward[2], float vecRight[2], float &flForwardMove, float &flSideMove) +void Solve2DMovementsVars(float vecWishDir[2], float vecForward[2], float vecRight[2], float &flForwardMove, float &flSideMove, float flMaxMove) { // wishdir[0] = foward[0] * forwardmove + right[0] * sidemove; // wishdir[1] = foward[1] * forwardmove + right[1] * sidemove; @@ -131,7 +91,7 @@ void Solve2DMovementsVars(float vecWishDir[2], float vecForward[2], float vecRig float flDivide = (c * e - a * f); if(flDivide == 0.0) { - flForwardMove = g_fMaxMove; + flForwardMove = flMaxMove; flSideMove = 0.0; } else @@ -141,7 +101,7 @@ void Solve2DMovementsVars(float vecWishDir[2], float vecForward[2], float vecRig } } -float GetThetaAngleInAir(float flVelocity[2], float flAirAccelerate, float flMaxSpeed, float flSurfaceFriction, float flFrametime) +float GetThetaAngleInAir(float flVelocity[2], float flAirAccelerate, float flMaxSpeed, float flSurfaceFriction, float flFrametime, float flAirSpeedCap) { // In order to solve this, we must check that accelspeed < 30 // so it applies the correct strafing method. @@ -158,7 +118,7 @@ float GetThetaAngleInAir(float flVelocity[2], float flAirAccelerate, float flMax float flAccelSpeed = flAirAccelerate * flMaxSpeed * flSurfaceFriction * flFrametime; - float flWantedDotProduct = g_flAirSpeedCap - flAccelSpeed; + float flWantedDotProduct = flAirSpeedCap - flAccelSpeed; if (flWantedDotProduct > 0.0) { @@ -208,13 +168,13 @@ float GetThetaAngleInAir(float flVelocity[2], float flAirAccelerate, float flMax return flMaxDelta; }*/ -float SimulateAirAccelerate(float flVelocity[2], float flWishDir[2], float flAirAccelerate, float flMaxSpeed, float flSurfaceFriction, float flFrametime, float flVelocityOutput[2]) +float SimulateAirAccelerate(float flVelocity[2], float flWishDir[2], float flAirAccelerate, float flMaxSpeed, float flSurfaceFriction, float flFrametime, float flVelocityOutput[2], float flAirSpeedCap) { float flWishSpeedCapped = flMaxSpeed; // Cap speed - if( flWishSpeedCapped > g_flAirSpeedCap ) - flWishSpeedCapped = g_flAirSpeedCap; + if( flWishSpeedCapped > flAirSpeedCap ) + flWishSpeedCapped = flAirSpeedCap; // Determine veer amount float flCurrentSpeed = flVelocity[0] * flWishDir[0] + flVelocity[1] * flWishDir[1]; @@ -242,12 +202,11 @@ float SimulateAirAccelerate(float flVelocity[2], float flWishDir[2], float flAir } // The idea is to get the maximum angle -float GetMaxDeltaInAir(float flVelocity[2], float flMaxSpeed, float flSurfaceFriction, bool bLeft) +float GetMaxDeltaInAir(float flVelocity[2], float flMaxSpeed, float flSurfaceFriction, bool bLeft, float flAirAccelerate, float flAirSpeedCap) { float flFrametime = GetTickInterval(); - float flAirAccelerate = g_ConVar_sv_airaccelerate.FloatValue; - float flTheta = GetThetaAngleInAir(flVelocity, flAirAccelerate, flMaxSpeed, flSurfaceFriction, flFrametime); + float flTheta = GetThetaAngleInAir(flVelocity, flAirAccelerate, flMaxSpeed, flSurfaceFriction, flFrametime, flAirSpeedCap); // Convert velocity 2D to angle. float flYawVelocity = Vec2DToYaw(flVelocity); @@ -283,8 +242,8 @@ float GetMaxDeltaInAir(float flVelocity[2], float flMaxSpeed, float flSurfaceFri float flCalcVelocityLeft[2], flCalcVelocityRight[2]; // Simulate air accelerate function in order to get the new max gain possible on both side. - SimulateAirAccelerate(flVelocity, vecBestLeft, flAirAccelerate, flMaxSpeed, flFrametime, flSurfaceFriction, flCalcVelocityLeft); - SimulateAirAccelerate(flVelocity, vecBestRight, flAirAccelerate, flMaxSpeed, flFrametime, flSurfaceFriction, flCalcVelocityRight); + SimulateAirAccelerate(flVelocity, vecBestLeft, flAirAccelerate, flMaxSpeed, flFrametime, flSurfaceFriction, flCalcVelocityLeft, flAirSpeedCap); + SimulateAirAccelerate(flVelocity, vecBestRight, flAirAccelerate, flMaxSpeed, flFrametime, flSurfaceFriction, flCalcVelocityRight, flAirSpeedCap); float flNewBestYawLeft = Vec2DToYaw(flCalcVelocityLeft); float flNewBestYawRight = Vec2DToYaw(flCalcVelocityRight); @@ -303,14 +262,13 @@ float GetMaxDeltaInAir(float flVelocity[2], float flMaxSpeed, float flSurfaceFri // return FloatAbs(AngleNormalize(flNewBestYawLeft - flNewBestYawRight) / 2.0); } -void GetIdealMovementsInAir(float flYawWantedDir, float flVelocity[2], float flMaxSpeed, float flSurfaceFriction, float &flForwardMove, float &flSideMove, bool bPreferRight = true) +void GetIdealMovementsInAir(float flYawWantedDir, float flVelocity[2], float flMaxSpeed, float flSurfaceFriction, float &flForwardMove, float &flSideMove, bool bPreferRight, float flAirAccelerate, float flMaxMove, float flAirSpeedCap) { - float flAirAccelerate = g_ConVar_sv_airaccelerate.FloatValue; float flFrametime = GetTickInterval(); float flYawVelocity = Vec2DToYaw(flVelocity); // Get theta angle - float flTheta = GetThetaAngleInAir(flVelocity, flAirAccelerate, flMaxSpeed, flSurfaceFriction, flFrametime); + float flTheta = GetThetaAngleInAir(flVelocity, flAirAccelerate, flMaxSpeed, flSurfaceFriction, flFrametime, flAirSpeedCap); // Get the best yaw direction on the right. float flBestYawRight = AngleNormalize(flYawVelocity + flTheta); @@ -381,7 +339,7 @@ void GetIdealMovementsInAir(float flYawWantedDir, float flVelocity[2], float flM vecRightWantedDir[1] = vecRightWantedDir3D[1]; // Solve the movement variables from our wanted direction and the best gain direction. - Solve2DMovementsVars(vecBestDir, vecForwardWantedDir, vecRightWantedDir, flForwardMove, flSideMove); + Solve2DMovementsVars(vecBestDir, vecForwardWantedDir, vecRightWantedDir, flForwardMove, flSideMove, flMaxMove); float flLengthMovements = SquareRoot(flForwardMove * flForwardMove + flSideMove * flSideMove); @@ -392,21 +350,11 @@ void GetIdealMovementsInAir(float flYawWantedDir, float flVelocity[2], float flM } } -public Action XutaxOnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3], float angles[3], int& weapon, int& subtype, int& cmdnum, int& tickcount, int& seed, int mouse[2]) +public Action XutaxOnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3], float angles[3], int& weapon, int& subtype, int& cmdnum, int& tickcount, int& seed, int mouse[2], + float flAirAccelerate, float flSurfaceFriction, float flAirSpeedCap, float flMaxMove, float flOldYawAngle, float fPower) { float flFowardMove, flSideMove; float flMaxSpeed = GetEntPropFloat(client, Prop_Data, "m_flMaxspeed"); - float flSurfaceFriction = 1.0; - if (g_iSurfaceFrictionOffset > 0) - { - flSurfaceFriction = GetEntDataFloat(client, g_iSurfaceFrictionOffset); - if (g_ConVar_AutoFind_Offset.BoolValue && s_iOnGroundCount[client] == 0 && !(flSurfaceFriction == 0.25 || flSurfaceFriction == 1.0)) - { - FindNewFrictionOffset(client); - } - } - - float flVelocity[3], flVelocity2D[2]; GetEntPropVector(client, Prop_Data, "m_vecVelocity", flVelocity); @@ -416,39 +364,39 @@ public Action XutaxOnPlayerRunCmd(int client, int& buttons, int& impulse, float // PrintToChat(client, "%f", SquareRoot(flVelocity2D[0] * flVelocity2D[0] + flVelocity2D[1] * flVelocity2D[1])); - GetIdealMovementsInAir(angles[1], flVelocity2D, flMaxSpeed, flSurfaceFriction, flFowardMove, flSideMove); + GetIdealMovementsInAir(angles[1], flVelocity2D, flMaxSpeed, flSurfaceFriction, flFowardMove, flSideMove, true, flAirAccelerate, flMaxMove, flAirSpeedCap); - float flAngleDifference = AngleNormalize(angles[1] - g_flOldYawAngle[client]); + float flAngleDifference = AngleNormalize(angles[1] - flOldYawAngle); float flCurrentAngles = FloatAbs(flAngleDifference); // Right if (flAngleDifference < 0.0) { - float flMaxDelta = GetMaxDeltaInAir(flVelocity2D, flMaxSpeed, flSurfaceFriction, true); - vel[1] = g_fMaxMove; + float flMaxDelta = GetMaxDeltaInAir(flVelocity2D, flMaxSpeed, flSurfaceFriction, true, flAirAccelerate, flAirSpeedCap); + vel[1] = flMaxMove; - if (flCurrentAngles <= flMaxDelta * g_fPower[client]) + if (flCurrentAngles <= flMaxDelta * fPower) { - vel[0] = flFowardMove * g_fMaxMove; - vel[1] = flSideMove * g_fMaxMove; + vel[0] = flFowardMove * flMaxMove; + vel[1] = flSideMove * flMaxMove; } } else if (flAngleDifference > 0.0) { - float flMaxDelta = GetMaxDeltaInAir(flVelocity2D, flMaxSpeed, flSurfaceFriction, false); - vel[1] = -g_fMaxMove; + float flMaxDelta = GetMaxDeltaInAir(flVelocity2D, flMaxSpeed, flSurfaceFriction, false, flAirAccelerate, flAirSpeedCap); + vel[1] = -flMaxMove; - if (flCurrentAngles <= flMaxDelta * g_fPower[client]) + if (flCurrentAngles <= flMaxDelta * fPower) { - vel[0] = flFowardMove * g_fMaxMove; - vel[1] = flSideMove * g_fMaxMove; + vel[0] = flFowardMove * flMaxMove; + vel[1] = flSideMove * flMaxMove; } } else { - vel[0] = flFowardMove * g_fMaxMove; - vel[1] = flSideMove * g_fMaxMove; + vel[0] = flFowardMove * flMaxMove; + vel[1] = flSideMove * flMaxMove; } return Plugin_Continue; diff --git a/addons/sourcemod/scripting/include/shavit/tas.inc b/addons/sourcemod/scripting/include/shavit/tas.inc new file mode 100644 index 000000000..5d83eeda1 --- /dev/null +++ b/addons/sourcemod/scripting/include/shavit/tas.inc @@ -0,0 +1,77 @@ +/* + * shavit's Timer - tas.inc file + * by: xutaxkamay, shavit + * + * This file is part of shavit's Timer. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, version 3.0, as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + * + */ + +#if defined _shavit_tas_included + #endinput +#endif +#define _shavit_tas_included + + +#define TAS_STYLE_SETTING "tas" + +enum +{ + Type_Normal, // only w/s disables autostrafe + Type_SurfOverride, // w/s always disables, a/d only over surf ramps + Type_Override, // all keys disable + Type_Size // size +}; + +// taken from shavit's oryx +stock bool IsSurfing(int client) +{ + float fPosition[3]; + GetClientAbsOrigin(client, fPosition); + + float fEnd[3]; + fEnd = fPosition; + fEnd[2] -= 64.0; + + float fMins[3]; + GetEntPropVector(client, Prop_Send, "m_vecMins", fMins); + + float fMaxs[3]; + GetEntPropVector(client, Prop_Send, "m_vecMaxs", fMaxs); + + Handle hTR = TR_TraceHullFilterEx(fPosition, fEnd, fMins, fMaxs, MASK_PLAYERSOLID, TRFilter_NoPlayers, client); + + if(TR_DidHit(hTR)) + { + float fNormal[3]; + TR_GetPlaneNormal(hTR, fNormal); + + delete hTR; + + // If the plane normal's Z axis is 0.7 or below (alternatively, -0.7 when upside-down) then it's a surf ramp. + // https://github.com/alliedmodders/hl2sdk/blob/92dcf04225a278b75170cc84917f04e98f5d08ec/game/server/physics_main.cpp#L1059 + // https://github.com/ValveSoftware/source-sdk-2013/blob/0d8dceea4310fde5706b3ce1c70609d72a38efdf/mp/src/game/server/physics_main.cpp#L1065 + + return (-0.7 <= fNormal[2] <= 0.7); + } + + delete hTR; + + return false; +} + +public bool TRFilter_NoPlayers(int entity, int mask, any data) +{ + return (entity != view_as(data) || (entity < 1 || entity > MaxClients)); +} diff --git a/addons/sourcemod/scripting/shavit-tas.sp b/addons/sourcemod/scripting/shavit-tas.sp index a98861117..a227f603d 100644 --- a/addons/sourcemod/scripting/shavit-tas.sp +++ b/addons/sourcemod/scripting/shavit-tas.sp @@ -1,34 +1,61 @@ - +/* + * shavit's Timer - TAS + * by: xutaxkamay, KiD Fearless, rtldg + * + * This file is part of shavit's Timer. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, version 3.0, as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + * + */ #include #include #include #include +#include +#include +#include + +#undef REQUIRE_PLUGIN +#include +#include + #pragma newdecls required #pragma semicolon 1 +EngineVersion gEV_Type = Engine_Unknown; + float g_flAirSpeedCap = 30.0; float g_flOldYawAngle[MAXPLAYERS + 1]; -ConVar g_ConVar_sv_airaccelerate; int g_iSurfaceFrictionOffset; float g_fMaxMove = 400.0; -EngineVersion g_Game; bool g_bEnabled[MAXPLAYERS + 1]; int g_iType[MAXPLAYERS + 1]; float g_fPower[MAXPLAYERS + 1] = {1.0, ...}; -bool g_bTASEnabled; -Convar g_ConVar_AutoFind_Offset; +bool gB_ForceJump[MAXPLAYERS+1]; +Convar gCV_AutoFindOffsets = null; +ConVar sv_airaccelerate = null; public Plugin myinfo = { - name = "Perfect autostrafe", - author = "xutaxkamay", - description = "", - version = "1.2", - url = "https://steamcommunity.com/id/xutaxkamay/" + name = "[shavit] TAS (XutaxKamay)", + author = "xutaxkamay, KiD Fearless, rtldg", + description = "TAS module for shavit's bhop timer featuring xutaxkamay's autostrafer.", + version = SHAVIT_VERSION, + url = "https://github.com/shavitush/bhoptimer" }; public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max) @@ -40,26 +67,28 @@ public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max CreateNative("SetXutaxPower", Native_SetPower); CreateNative("GetXutaxPower", Native_GetPower); - RegPluginLibrary("xutax-strafe"); + RegPluginLibrary("shavit-tas"); return APLRes_Success; } public void OnPluginStart() { - g_Game = GetEngineVersion(); - g_ConVar_sv_airaccelerate = FindConVar("sv_airaccelerate"); + LoadTranslations("shavit-common.phrases"); + LoadTranslations("shavit-misc.phrases"); - GameData gamedata = new GameData("KiD-TAS.games"); + gEV_Type = GetEngineVersion(); + sv_airaccelerate = FindConVar("sv_airaccelerate"); - g_iSurfaceFrictionOffset = gamedata.GetOffset("m_surfaceFriction"); - delete gamedata; + GameData gamedata = new GameData("shavit.games"); - if(g_iSurfaceFrictionOffset == -1) + if ((g_iSurfaceFrictionOffset = gamedata.GetOffset("m_surfaceFriction")) == -1) { LogError("[XUTAX] Invalid offset supplied, defaulting friction values"); } - if(g_Game == Engine_CSGO) + delete gamedata; + + if (gEV_Type == Engine_CSGO) { g_fMaxMove = 450.0; ConVar sv_air_max_wishspeed = FindConVar("sv_air_max_wishspeed"); @@ -71,21 +100,17 @@ public void OnPluginStart() g_iSurfaceFrictionOffset = FindSendPropInfo("CBasePlayer", "m_ubEFNoInterpParity") - g_iSurfaceFrictionOffset; } } - else if(g_Game == Engine_CSS) + else { if (g_iSurfaceFrictionOffset != -1) { g_iSurfaceFrictionOffset += FindSendPropInfo("CBasePlayer", "m_szLastPlaceName"); } } - else - { - SetFailState("This plugin is for CSGO/CSS only."); - } RegAdminCmd("sm_xutax_scan", Command_ScanOffsets, ADMFLAG_CHEATS, "Scan for possible offset locations"); - g_ConVar_AutoFind_Offset = new Convar("xutax_find_offsets", "1", "Attempt to autofind offsets", _, true, 0.0, true, 1.0); + gCV_AutoFindOffsets = new Convar("xutax_find_offsets", "1", "Attempt to autofind offsets", _, true, 0.0, true, 1.0); Convar.AutoExecConfig(); } @@ -103,12 +128,121 @@ public void OnClientConnected(int client) g_fPower[client] = 1.0; } +public void Shavit_OnLeaveZone(int client, int type, int track, int id, int entity, int data) +{ + if (!IsValidClient(client, true) || IsFakeClient(client)) + { + return; + } + + if (!Shavit_GetStyleSettingBool(Shavit_GetBhopStyle(client), TAS_STYLE_SETTING)) + { + return; + } + + if (Shavit_GetTimerStatus(client) != Timer_Running) + { + return; + } + + if (type == Zone_Start) + { + if (GetEntityFlags(client) & FL_ONGROUND) + { + gB_ForceJump[client] = true; + } + } +} + +int FindMenuItem(Menu menu, const char[] info) +{ + for (int i = 0; i < menu.ItemCount; i++) + { + char sInfo[64]; + menu.GetItem(i, sInfo, sizeof(sInfo)); + + if (StrEqual(info, sInfo)) + { + return i; + } + } + + return -1; +} + +public Action Shavit_OnCheckpointMenuMade(int client, bool segmented, Menu menu) +{ + if (!Shavit_GetStyleSettingBool(Shavit_GetBhopStyle(client), TAS_STYLE_SETTING)) + { + return Plugin_Continue; + } + + char sDisplay[64]; + bool tas_timescale = (Shavit_GetStyleSettingFloat(Shavit_GetBhopStyle(client), "tas_timescale") == -1.0); + int delcurrentcheckpoint = -1; + + if (tas_timescale) + { + if ((delcurrentcheckpoint = FindMenuItem(menu, "del")) != -1) + { + menu.RemoveItem(delcurrentcheckpoint); + } + } + + FormatEx(sDisplay, 64, "%T\n ", "TasSettings", client); + menu.AddItem("tassettings", sDisplay); + //menu.ExitButton = false; + + if (delcurrentcheckpoint != -1) + { + FormatEx(sDisplay, 64, "%T", "MiscCheckpointDeleteCurrent", client); + menu.AddItem("del", sDisplay, (Shavit_GetTotalCheckpoints(client) > 0) ? ITEMDRAW_DEFAULT:ITEMDRAW_DISABLED); + } + + return Plugin_Changed; +} + +public Action Shavit_OnCheckpointMenuSelect(int client, int param2, char[] info, int maxlength, int currentCheckpoint, int maxCPs) +{ + if (!Shavit_GetStyleSettingBool(Shavit_GetBhopStyle(client), TAS_STYLE_SETTING)) + { + return Plugin_Continue; + } + + if (StrEqual(info, "tassettings")) + { + // OpenTasSettings(client); + return Plugin_Handled; + } + + return Plugin_Continue; +} + +// TODO: Not good enough. Need to jump earlier to get 0.0 offset... +public Action Shavit_OnUserCmdPre(int client, int &buttons, int &impulse, float vel[3], float angles[3], TimerStatus status, int track, int style, int mouse[2]) +{ + if (!Shavit_ShouldProcessFrame(client)) + { + return Plugin_Continue; + } + + if (gB_ForceJump[client] && status == Timer_Running && Shavit_GetStyleSettingBool(style, TAS_STYLE_SETTING)) + { + buttons |= IN_JUMP; + } + + gB_ForceJump[client] = false; + return Plugin_Changed; +} + public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3], float angles[3], int& weapon, int& subtype, int& cmdnum, int& tickcount, int& seed, int mouse[2]) { +#if 0 if (!g_bEnabled[client]) { return Plugin_Continue; } +#endif if (!Shavit_ShouldProcessFrame(client)) { @@ -147,6 +281,21 @@ public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3 return Plugin_Continue; } } + + float flSurfaceFriction = 1.0; + + if (g_iSurfaceFrictionOffset > 0) + { + flSurfaceFriction = GetEntDataFloat(client, g_iSurfaceFrictionOffset); + + if (gCV_AutoFindOffsets.BoolValue && s_iOnGroundCount[client] == 0 && !(flSurfaceFriction == 0.25 || flSurfaceFriction == 1.0)) + { + FindNewFrictionOffset(client); + } + } + + XutaxOnPlayerRunCmd(client, buttons, impulse, vel, angles, weapon, subtype, cmdnum, tickcount, seed, mouse, + sv_airaccelerate.FloatValue, flSurfaceFriction, g_flAirSpeedCap, g_fMaxMove, g_flOldYawAngle[client], g_fPower[client]); } g_flOldYawAngle[client] = angles[1]; @@ -156,7 +305,7 @@ public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3 stock void FindNewFrictionOffset(int client, bool logOnly = false) { - if(g_Game == Engine_CSGO) + if (gEV_Type == Engine_CSGO) { int startingOffset = FindSendPropInfo("CBasePlayer", "m_ubEFNoInterpParity"); for (int i = 16; i >= -128; --i) diff --git a/addons/sourcemod/translations/shavit-misc.phrases.txt b/addons/sourcemod/translations/shavit-misc.phrases.txt index b8f44c419..dccdd93ab 100644 --- a/addons/sourcemod/translations/shavit-misc.phrases.txt +++ b/addons/sourcemod/translations/shavit-misc.phrases.txt @@ -188,6 +188,10 @@ { "en" "Use velocity" } + "TasSettings" + { + "en" "TAS Settings" + } // ---------- Misc ---------- // "BHStartZoneDisallowed" {