mirror of
https://github.com/shavitush/bhoptimer.git
synced 2025-12-07 02:18:26 +00:00
shape into shavit-tas
This commit is contained in:
parent
1ce6acc5f4
commit
2fa06031de
@ -21,48 +21,8 @@
|
|||||||
#endif
|
#endif
|
||||||
#define _shavit_tas_xutax_included
|
#define _shavit_tas_xutax_included
|
||||||
|
|
||||||
|
// reference code for CGameMovement::AirAccelerate & CGameMovement::AirMove at:
|
||||||
// taken from shavit's oryx
|
// https://github.com/ValveSoftware/source-sdk-2013/blob/0d8dceea4310fde5706b3ce1c70609d72a38efdf/mp/src/game/shared/gamemovement.cpp#L1707-L1799
|
||||||
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<int>(data) || (entity < 1 || entity > MaxClients));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
float AngleNormalize(float flAngle)
|
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).
|
* 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[0] = foward[0] * forwardmove + right[0] * sidemove;
|
||||||
// wishdir[1] = foward[1] * forwardmove + right[1] * 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);
|
float flDivide = (c * e - a * f);
|
||||||
if(flDivide == 0.0)
|
if(flDivide == 0.0)
|
||||||
{
|
{
|
||||||
flForwardMove = g_fMaxMove;
|
flForwardMove = flMaxMove;
|
||||||
flSideMove = 0.0;
|
flSideMove = 0.0;
|
||||||
}
|
}
|
||||||
else
|
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
|
// In order to solve this, we must check that accelspeed < 30
|
||||||
// so it applies the correct strafing method.
|
// 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 flAccelSpeed = flAirAccelerate * flMaxSpeed * flSurfaceFriction * flFrametime;
|
||||||
|
|
||||||
float flWantedDotProduct = g_flAirSpeedCap - flAccelSpeed;
|
float flWantedDotProduct = flAirSpeedCap - flAccelSpeed;
|
||||||
|
|
||||||
if (flWantedDotProduct > 0.0)
|
if (flWantedDotProduct > 0.0)
|
||||||
{
|
{
|
||||||
@ -208,13 +168,13 @@ float GetThetaAngleInAir(float flVelocity[2], float flAirAccelerate, float flMax
|
|||||||
return flMaxDelta;
|
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;
|
float flWishSpeedCapped = flMaxSpeed;
|
||||||
|
|
||||||
// Cap speed
|
// Cap speed
|
||||||
if( flWishSpeedCapped > g_flAirSpeedCap )
|
if( flWishSpeedCapped > flAirSpeedCap )
|
||||||
flWishSpeedCapped = g_flAirSpeedCap;
|
flWishSpeedCapped = flAirSpeedCap;
|
||||||
|
|
||||||
// Determine veer amount
|
// Determine veer amount
|
||||||
float flCurrentSpeed = flVelocity[0] * flWishDir[0] + flVelocity[1] * flWishDir[1];
|
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
|
// 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 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.
|
// Convert velocity 2D to angle.
|
||||||
float flYawVelocity = Vec2DToYaw(flVelocity);
|
float flYawVelocity = Vec2DToYaw(flVelocity);
|
||||||
@ -283,8 +242,8 @@ float GetMaxDeltaInAir(float flVelocity[2], float flMaxSpeed, float flSurfaceFri
|
|||||||
float flCalcVelocityLeft[2], flCalcVelocityRight[2];
|
float flCalcVelocityLeft[2], flCalcVelocityRight[2];
|
||||||
|
|
||||||
// Simulate air accelerate function in order to get the new max gain possible on both side.
|
// 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, vecBestLeft, flAirAccelerate, flMaxSpeed, flFrametime, flSurfaceFriction, flCalcVelocityLeft, flAirSpeedCap);
|
||||||
SimulateAirAccelerate(flVelocity, vecBestRight, flAirAccelerate, flMaxSpeed, flFrametime, flSurfaceFriction, flCalcVelocityRight);
|
SimulateAirAccelerate(flVelocity, vecBestRight, flAirAccelerate, flMaxSpeed, flFrametime, flSurfaceFriction, flCalcVelocityRight, flAirSpeedCap);
|
||||||
|
|
||||||
float flNewBestYawLeft = Vec2DToYaw(flCalcVelocityLeft);
|
float flNewBestYawLeft = Vec2DToYaw(flCalcVelocityLeft);
|
||||||
float flNewBestYawRight = Vec2DToYaw(flCalcVelocityRight);
|
float flNewBestYawRight = Vec2DToYaw(flCalcVelocityRight);
|
||||||
@ -303,14 +262,13 @@ float GetMaxDeltaInAir(float flVelocity[2], float flMaxSpeed, float flSurfaceFri
|
|||||||
// return FloatAbs(AngleNormalize(flNewBestYawLeft - flNewBestYawRight) / 2.0);
|
// 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 flFrametime = GetTickInterval();
|
||||||
float flYawVelocity = Vec2DToYaw(flVelocity);
|
float flYawVelocity = Vec2DToYaw(flVelocity);
|
||||||
|
|
||||||
// Get theta angle
|
// 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.
|
// Get the best yaw direction on the right.
|
||||||
float flBestYawRight = AngleNormalize(flYawVelocity + flTheta);
|
float flBestYawRight = AngleNormalize(flYawVelocity + flTheta);
|
||||||
@ -381,7 +339,7 @@ void GetIdealMovementsInAir(float flYawWantedDir, float flVelocity[2], float flM
|
|||||||
vecRightWantedDir[1] = vecRightWantedDir3D[1];
|
vecRightWantedDir[1] = vecRightWantedDir3D[1];
|
||||||
|
|
||||||
// Solve the movement variables from our wanted direction and the best gain direction.
|
// 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);
|
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 flFowardMove, flSideMove;
|
||||||
float flMaxSpeed = GetEntPropFloat(client, Prop_Data, "m_flMaxspeed");
|
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];
|
float flVelocity[3], flVelocity2D[2];
|
||||||
|
|
||||||
GetEntPropVector(client, Prop_Data, "m_vecVelocity", flVelocity);
|
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]));
|
// 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);
|
float flCurrentAngles = FloatAbs(flAngleDifference);
|
||||||
|
|
||||||
|
|
||||||
// Right
|
// Right
|
||||||
if (flAngleDifference < 0.0)
|
if (flAngleDifference < 0.0)
|
||||||
{
|
{
|
||||||
float flMaxDelta = GetMaxDeltaInAir(flVelocity2D, flMaxSpeed, flSurfaceFriction, true);
|
float flMaxDelta = GetMaxDeltaInAir(flVelocity2D, flMaxSpeed, flSurfaceFriction, true, flAirAccelerate, flAirSpeedCap);
|
||||||
vel[1] = g_fMaxMove;
|
vel[1] = flMaxMove;
|
||||||
|
|
||||||
if (flCurrentAngles <= flMaxDelta * g_fPower[client])
|
if (flCurrentAngles <= flMaxDelta * fPower)
|
||||||
{
|
{
|
||||||
vel[0] = flFowardMove * g_fMaxMove;
|
vel[0] = flFowardMove * flMaxMove;
|
||||||
vel[1] = flSideMove * g_fMaxMove;
|
vel[1] = flSideMove * flMaxMove;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (flAngleDifference > 0.0)
|
else if (flAngleDifference > 0.0)
|
||||||
{
|
{
|
||||||
float flMaxDelta = GetMaxDeltaInAir(flVelocity2D, flMaxSpeed, flSurfaceFriction, false);
|
float flMaxDelta = GetMaxDeltaInAir(flVelocity2D, flMaxSpeed, flSurfaceFriction, false, flAirAccelerate, flAirSpeedCap);
|
||||||
vel[1] = -g_fMaxMove;
|
vel[1] = -flMaxMove;
|
||||||
|
|
||||||
if (flCurrentAngles <= flMaxDelta * g_fPower[client])
|
if (flCurrentAngles <= flMaxDelta * fPower)
|
||||||
{
|
{
|
||||||
vel[0] = flFowardMove * g_fMaxMove;
|
vel[0] = flFowardMove * flMaxMove;
|
||||||
vel[1] = flSideMove * g_fMaxMove;
|
vel[1] = flSideMove * flMaxMove;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vel[0] = flFowardMove * g_fMaxMove;
|
vel[0] = flFowardMove * flMaxMove;
|
||||||
vel[1] = flSideMove * g_fMaxMove;
|
vel[1] = flSideMove * flMaxMove;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Plugin_Continue;
|
return Plugin_Continue;
|
||||||
|
|||||||
77
addons/sourcemod/scripting/include/shavit/tas.inc
Normal file
77
addons/sourcemod/scripting/include/shavit/tas.inc
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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<int>(data) || (entity < 1 || entity > MaxClients));
|
||||||
|
}
|
||||||
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
#include <sourcemod>
|
#include <sourcemod>
|
||||||
#include <sdktools>
|
#include <sdktools>
|
||||||
#include <cstrike>
|
#include <cstrike>
|
||||||
#include <convar_class>
|
#include <convar_class>
|
||||||
|
|
||||||
|
#include <shavit/core>
|
||||||
|
#include <shavit/tas>
|
||||||
|
#include <shavit/tas-xutax>
|
||||||
|
|
||||||
|
#undef REQUIRE_PLUGIN
|
||||||
|
#include <shavit/checkpoints>
|
||||||
|
#include <shavit/zones>
|
||||||
|
|
||||||
#pragma newdecls required
|
#pragma newdecls required
|
||||||
#pragma semicolon 1
|
#pragma semicolon 1
|
||||||
|
|
||||||
|
EngineVersion gEV_Type = Engine_Unknown;
|
||||||
|
|
||||||
float g_flAirSpeedCap = 30.0;
|
float g_flAirSpeedCap = 30.0;
|
||||||
float g_flOldYawAngle[MAXPLAYERS + 1];
|
float g_flOldYawAngle[MAXPLAYERS + 1];
|
||||||
ConVar g_ConVar_sv_airaccelerate;
|
|
||||||
int g_iSurfaceFrictionOffset;
|
int g_iSurfaceFrictionOffset;
|
||||||
float g_fMaxMove = 400.0;
|
float g_fMaxMove = 400.0;
|
||||||
EngineVersion g_Game;
|
|
||||||
bool g_bEnabled[MAXPLAYERS + 1];
|
bool g_bEnabled[MAXPLAYERS + 1];
|
||||||
int g_iType[MAXPLAYERS + 1];
|
int g_iType[MAXPLAYERS + 1];
|
||||||
float g_fPower[MAXPLAYERS + 1] = {1.0, ...};
|
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 =
|
public Plugin myinfo =
|
||||||
{
|
{
|
||||||
name = "Perfect autostrafe",
|
name = "[shavit] TAS (XutaxKamay)",
|
||||||
author = "xutaxkamay",
|
author = "xutaxkamay, KiD Fearless, rtldg",
|
||||||
description = "",
|
description = "TAS module for shavit's bhop timer featuring xutaxkamay's autostrafer.",
|
||||||
version = "1.2",
|
version = SHAVIT_VERSION,
|
||||||
url = "https://steamcommunity.com/id/xutaxkamay/"
|
url = "https://github.com/shavitush/bhoptimer"
|
||||||
};
|
};
|
||||||
|
|
||||||
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
|
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("SetXutaxPower", Native_SetPower);
|
||||||
CreateNative("GetXutaxPower", Native_GetPower);
|
CreateNative("GetXutaxPower", Native_GetPower);
|
||||||
|
|
||||||
RegPluginLibrary("xutax-strafe");
|
RegPluginLibrary("shavit-tas");
|
||||||
return APLRes_Success;
|
return APLRes_Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnPluginStart()
|
public void OnPluginStart()
|
||||||
{
|
{
|
||||||
g_Game = GetEngineVersion();
|
LoadTranslations("shavit-common.phrases");
|
||||||
g_ConVar_sv_airaccelerate = FindConVar("sv_airaccelerate");
|
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");
|
GameData gamedata = new GameData("shavit.games");
|
||||||
delete gamedata;
|
|
||||||
|
|
||||||
if(g_iSurfaceFrictionOffset == -1)
|
if ((g_iSurfaceFrictionOffset = gamedata.GetOffset("m_surfaceFriction")) == -1)
|
||||||
{
|
{
|
||||||
LogError("[XUTAX] Invalid offset supplied, defaulting friction values");
|
LogError("[XUTAX] Invalid offset supplied, defaulting friction values");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(g_Game == Engine_CSGO)
|
delete gamedata;
|
||||||
|
|
||||||
|
if (gEV_Type == Engine_CSGO)
|
||||||
{
|
{
|
||||||
g_fMaxMove = 450.0;
|
g_fMaxMove = 450.0;
|
||||||
ConVar sv_air_max_wishspeed = FindConVar("sv_air_max_wishspeed");
|
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;
|
g_iSurfaceFrictionOffset = FindSendPropInfo("CBasePlayer", "m_ubEFNoInterpParity") - g_iSurfaceFrictionOffset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(g_Game == Engine_CSS)
|
else
|
||||||
{
|
{
|
||||||
if (g_iSurfaceFrictionOffset != -1)
|
if (g_iSurfaceFrictionOffset != -1)
|
||||||
{
|
{
|
||||||
g_iSurfaceFrictionOffset += FindSendPropInfo("CBasePlayer", "m_szLastPlaceName");
|
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");
|
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();
|
Convar.AutoExecConfig();
|
||||||
}
|
}
|
||||||
@ -103,12 +128,121 @@ public void OnClientConnected(int client)
|
|||||||
g_fPower[client] = 1.0;
|
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])
|
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])
|
if (!g_bEnabled[client])
|
||||||
{
|
{
|
||||||
return Plugin_Continue;
|
return Plugin_Continue;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!Shavit_ShouldProcessFrame(client))
|
if (!Shavit_ShouldProcessFrame(client))
|
||||||
{
|
{
|
||||||
@ -147,6 +281,21 @@ public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3
|
|||||||
return Plugin_Continue;
|
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];
|
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)
|
stock void FindNewFrictionOffset(int client, bool logOnly = false)
|
||||||
{
|
{
|
||||||
if(g_Game == Engine_CSGO)
|
if (gEV_Type == Engine_CSGO)
|
||||||
{
|
{
|
||||||
int startingOffset = FindSendPropInfo("CBasePlayer", "m_ubEFNoInterpParity");
|
int startingOffset = FindSendPropInfo("CBasePlayer", "m_ubEFNoInterpParity");
|
||||||
for (int i = 16; i >= -128; --i)
|
for (int i = 16; i >= -128; --i)
|
||||||
|
|||||||
@ -188,6 +188,10 @@
|
|||||||
{
|
{
|
||||||
"en" "Use velocity"
|
"en" "Use velocity"
|
||||||
}
|
}
|
||||||
|
"TasSettings"
|
||||||
|
{
|
||||||
|
"en" "TAS Settings"
|
||||||
|
}
|
||||||
// ---------- Misc ---------- //
|
// ---------- Misc ---------- //
|
||||||
"BHStartZoneDisallowed"
|
"BHStartZoneDisallowed"
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user