diff --git a/addons/sourcemod/scripting/include/shavit/tas-oblivious.inc b/addons/sourcemod/scripting/include/shavit/tas-oblivious.inc new file mode 100644 index 00000000..16a61f06 --- /dev/null +++ b/addons/sourcemod/scripting/include/shavit/tas-oblivious.inc @@ -0,0 +1,248 @@ + +#if defined _shavit_tas_oblivious_included + #endinput +#endif +#define _shavit_tas_oblivious_included + + +float normalize_yaw(float _yaw) +{ + while (_yaw > 180.0) _yaw -= 360.0; + while (_yaw < -180.0) _yaw += 360.0; return _yaw; +} + +float get_length_2d(float vec[3]) +{ + return SquareRoot(vec[0] * vec[0] + vec[1] * vec[1]); +} + +float ground_delta_opt(int client, float angles[3], float move[3], float surface_friction, + float accelerate, float friction, float stopspeed) +{ + float fore[3], side[3], wishvel[3]; + float wishspeed; + + GetAngleVectors(angles, fore, side, NULL_VECTOR); + + fore[2] = 0.0; + side[2] = 0.0; + NormalizeVector(fore, fore); + NormalizeVector(side, side); + + wishvel[2] = 0.0; + for(int i = 0; i < 2; i++) + wishvel[i] = fore[i] * move[0] + side[i] * move[1]; + + wishspeed = GetVectorLength(wishvel); + + if(wishspeed > GetEntPropFloat(client, Prop_Send, "m_flMaxspeed") && GetEntPropFloat(client, Prop_Send, "m_flMaxspeed") != 0.0) wishspeed = GetEntPropFloat(client, Prop_Send, "m_flMaxspeed"); + + float velocity[3]; + GetEntPropVector(client, Prop_Data, "m_vecVelocity", velocity); + float speed = GetVectorLength(velocity); + + float interval_per_tick = GetTickInterval(); + + float accelspeed = accelerate * wishspeed * interval_per_tick * surface_friction; + + float control = speed; + if (control < stopspeed) control = stopspeed; + float drop = control * friction * interval_per_tick * surface_friction; + + float newspeed = speed - drop; + if (newspeed < 0.0) newspeed = 0.0; + + float tmp = wishspeed - accelspeed; + + if (tmp <= newspeed) + { + float gamma = RadToDeg(ArcCosine(tmp / newspeed)); + float vel_dir_ang = RadToDeg(ArcTangent2(velocity[1], velocity[0])); + + vel_dir_ang = normalize_yaw(vel_dir_ang); + + float accel_yaw = RadToDeg(ArcTangent2(wishvel[1], wishvel[0])); + + float diffm = vel_dir_ang - gamma; + float diffp = vel_dir_ang + gamma; + + diffm = normalize_yaw(diffm - accel_yaw); + diffp = normalize_yaw(diffp - accel_yaw); + + float delta_opt = 0.0; + if (FloatAbs(diffm) <= FloatAbs(diffp)) + delta_opt = -diffm; + else + delta_opt = -diffp; + delta_opt = normalize_yaw(delta_opt); + + return delta_opt; + } + + return 0.0; +} + +public Action ObliviousOnPlayerRunCmd(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 air_accelerate, float surface_friction, float flAirSpeedCap, float flMaxMove, + bool no_speed_loss) +{ + float flMaxSpeed = GetEntPropFloat(client, Prop_Send, "m_flMaxspeed"); + + bool set_back = true; + if (vel[0] != 0.0 || vel[1] != 0.0) + set_back = false; + if (set_back) + vel[1] = flMaxMove; + + float velocity[3], velocity_opt[3]; + GetEntPropVector(client, Prop_Data, "m_vecVelocity", velocity); + + velocity_opt[0] = velocity[0]; velocity_opt[1] = velocity[1]; velocity_opt[2] = velocity[2]; + + float vel_yaw = ArcTangent2(velocity[1], velocity[0]) * 180.0 / FLOAT_PI; + + float delta_opt = -normalize_yaw(angles[1] - vel_yaw); + + if (vel[0] != 0.0 && vel[1] == 0.0) + { + float sign = vel[0] > 0.0 ? -1.0 : 1.0; + delta_opt = -normalize_yaw(angles[1] - (vel_yaw + (90.0 * sign))); + } + if (vel[0] != 0.0 && vel[1] != 0.0) + { + float sign = vel[1] > 0.0 ? -1.0 : 1.0; + if (vel[0] < 0.0) + sign = -sign; + delta_opt = -normalize_yaw(angles[1] - (vel_yaw + (45.0 * sign))); + } + + float _addspeed = 0.0; + if (!set_back) + { + float _fore[3], _side[3], _wishvel[3], _wishdir[3]; + float _wishspeed, _wishspd, _currentspeed; + + GetAngleVectors(angles, _fore, _side, NULL_VECTOR); + + _fore[2] = 0.0; _side[2] = 0.0; + NormalizeVector(_fore, _fore); NormalizeVector(_side, _side); + + for(int i = 0; i < 2; i++) + _wishvel[i] = _fore[i] * vel[0] + _side[i] * vel[1]; + + _wishspeed = NormalizeVector(_wishvel, _wishdir); + + if(_wishspeed > flMaxSpeed && flMaxSpeed != 0.0) _wishspeed = flMaxSpeed; + + _wishspd = _wishspeed; + if (_wishspd > flAirSpeedCap) + _wishspd = flAirSpeedCap; + + _currentspeed = GetVectorDotProduct(velocity, _wishdir); + _addspeed = _wishspd - _currentspeed; + if (_addspeed < 0.0) + _addspeed = 0.0; + } + + float fore[3], side[3], wishvel[3], wishdir[3]; + float wishspeed, wishspd, addspeed, currentspeed; + + float tmp[3]; + tmp[0] = 0.0; tmp[2] = 0.0; + tmp[1] = normalize_yaw(angles[1] + delta_opt); + GetAngleVectors(tmp, fore, side, NULL_VECTOR); + + fore[2] = 0.0; side[2] = 0.0; + NormalizeVector(fore, fore); NormalizeVector(side, side); + + for(int i = 0; i < 2; i++) + wishvel[i] = fore[i] * vel[0] + side[i] * vel[1]; + + wishspeed = NormalizeVector(wishvel, wishdir); + + if(wishspeed > flMaxSpeed && wishspeed != 0.0) wishspeed = flMaxSpeed; + + wishspd = wishspeed; + if (wishspd > flAirSpeedCap) + wishspd = flAirSpeedCap; + + currentspeed = GetVectorDotProduct(velocity, wishdir); + addspeed = wishspd - currentspeed; + + if (no_speed_loss) + { + if (_addspeed > addspeed) + { + addspeed = _addspeed - addspeed; + } + else + { + addspeed -= _addspeed; + } + } + else + { + addspeed = addspeed - _addspeed; + + if (addspeed > 30.0) + addspeed = 30.0; + } + + if (buttons & IN_DUCK) + { + float vel2d[3]; vel2d[0] = velocity[0]; vel2d[1] = velocity[1]; + //PrintToChat(client, "%f %f\n", GetVectorLength(vel2d), addspeed); + } + + if (addspeed < 0.0) + addspeed = 0.0; + + float accelspeed = wishspeed * air_accelerate * GetTickInterval() * surface_friction; + + if (accelspeed > addspeed) + accelspeed = addspeed; + + for (int i = 0; i < 3; i++) + velocity_opt[i] += accelspeed * wishdir[i]; + + float new_vel[3]; + + float numer = velocity_opt[0] * velocity[0] + velocity_opt[1] * velocity[1]; + //float denom = SquareRoot(velocity_opt[0] * velocity_opt[0] + velocity_opt[1] * velocity_opt[1]) * SquareRoot(velocity[0] * velocity[0] + velocity[1] * velocity[1]); + float denom = get_length_2d(velocity_opt) * get_length_2d(velocity); + float ang = 0.0; + if (denom > numer) + ang = ArcCosine(numer / denom) * 180.0 / FLOAT_PI; + if (vel[1] < 0.0) ang = -ang; + + float st = Sine(ang * FLOAT_PI / 180.0); + float ct = Cosine(ang * FLOAT_PI / 180.0); + + new_vel[0] = (velocity_opt[0] * ct) - (velocity_opt[1] * st); + new_vel[1] = (velocity_opt[0] * st) + (velocity_opt[1] * ct); + new_vel[2] = velocity_opt[2]; + + float base_vel[3]; + GetEntPropVector(client, Prop_Data, "m_vecBaseVelocity", base_vel); + + //PrintToChat(client, "%.2f, %.2f, %.2f", base_vel[0], base_vel[1], base_vel[2]); + + if (GetVectorLength(new_vel) < 99999.0 && GetVectorLength(new_vel) > 0.0) + { + SetEntPropVector(client, Prop_Data, "m_vecVelocity", new_vel); + + float _new_vel[3]; + for (int i = 0; i < 3; i++) + _new_vel[i] = new_vel[i] + base_vel[i]; + + SetEntPropVector(client, Prop_Data, "m_vecAbsVelocity", _new_vel); // m_vecBaseVelocity+m_vecVelocity + SetEntPropVector(client, Prop_Data, "m_vecBaseVelocity", base_vel); + } + + SetEntPropVector(client, Prop_Data, "m_vecBaseVelocity", base_vel); + + if (set_back) + vel[1] = 0.0; + + return Plugin_Continue; +} diff --git a/addons/sourcemod/scripting/shavit-tas.sp b/addons/sourcemod/scripting/shavit-tas.sp index a227f603..61eb669c 100644 --- a/addons/sourcemod/scripting/shavit-tas.sp +++ b/addons/sourcemod/scripting/shavit-tas.sp @@ -25,6 +25,7 @@ #include #include +#include #include #undef REQUIRE_PLUGIN @@ -48,6 +49,9 @@ bool gB_ForceJump[MAXPLAYERS+1]; Convar gCV_AutoFindOffsets = null; ConVar sv_airaccelerate = null; +ConVar sv_accelerate = null; +ConVar sv_friction = null; +ConVar sv_stopspeed = null; public Plugin myinfo = { @@ -78,6 +82,9 @@ public void OnPluginStart() gEV_Type = GetEngineVersion(); sv_airaccelerate = FindConVar("sv_airaccelerate"); + sv_accelerate = FindConVar("sv_accelerate"); + sv_friction = FindConVar("sv_friction"); + sv_stopspeed = FindConVar("sv_stopspeed"); GameData gamedata = new GameData("shavit.games"); @@ -249,6 +256,11 @@ public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3 return Plugin_Continue; } + if (!IsPlayerAlive(client) || GetEntityMoveType(client) == MOVETYPE_NOCLIP || GetEntityMoveType(client) == MOVETYPE_LADDER || !(GetEntProp(client, Prop_Data, "m_nWaterLevel") <= 1)) + { + return Plugin_Continue; + } + static int s_iOnGroundCount[MAXPLAYERS+1] = {1, ...}; if (GetEntPropEnt(client, Prop_Send, "m_hGroundEntity") != -1) @@ -260,10 +272,19 @@ public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3 s_iOnGroundCount[client] = 0; } - if (IsPlayerAlive(client) - && s_iOnGroundCount[client] <= 1 - && !(GetEntityMoveType(client) & MOVETYPE_LADDER) - && (GetEntProp(client, Prop_Data, "m_nWaterLevel") <= 1)) + 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); + } + } + + if (s_iOnGroundCount[client] <= 1) { if (!!(buttons & (IN_FORWARD | IN_BACK))) { @@ -282,20 +303,32 @@ public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3 } } - float flSurfaceFriction = 1.0; - - if (g_iSurfaceFrictionOffset > 0) + if (true) { - flSurfaceFriction = GetEntDataFloat(client, g_iSurfaceFrictionOffset); + 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]); + } + else + { + ObliviousOnPlayerRunCmd(client, buttons, impulse, vel, angles, weapon, subtype, cmdnum, tickcount, seed, mouse, + sv_airaccelerate.FloatValue, flSurfaceFriction, g_flAirSpeedCap, g_fMaxMove, + false /*no_speed_loss[client]*/); + } + } + else + { + if (/*psh_enabled[client] &&*/ (vel[0] != 0.0 || vel[1] != 0.0)) + { + float _delta_opt = ground_delta_opt(client, angles, vel, flSurfaceFriction, + sv_accelerate.FloatValue, sv_friction.FloatValue, sv_stopspeed.FloatValue); - if (gCV_AutoFindOffsets.BoolValue && s_iOnGroundCount[client] == 0 && !(flSurfaceFriction == 0.25 || flSurfaceFriction == 1.0)) - { - FindNewFrictionOffset(client); - } + float _tmp[3]; _tmp[0] = angles[0]; _tmp[2] = angles[2]; + _tmp[1] = normalize_yaw(angles[1] - _delta_opt); + + angles[1] = _tmp[1]; } - 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]); + //return Plugin_Continue; // maybe?? } g_flOldYawAngle[client] = angles[1];