Add Multidirectional Airstrafe and fix some projectile nospread issues

This commit is contained in:
BenCat07 2021-08-14 21:43:48 +02:00 committed by LightCat
parent 7bd167f43e
commit 3fc68c9c5c
5 changed files with 286 additions and 171 deletions

View File

@ -1,9 +1,15 @@
<Tab name="Movement" padding="6 6 6 6">
<Box padding="12 6 6 6" width="content" height="content" name="Bunny hop">
<Box padding="12 6 6 6" width="content" height="content" name="General">
<List width="150">
<AutoVariable width="fill" target="bunnyhop.enable" label="Enable bunny hop"/>
<AutoVariable width="fill" target="bunnyhop.chance" label="Bhop chance" tooltip="% chance of a successful bunnyhop."/>
<AutoVariable width="fill" target="misc.autostrafe" label="Enable auto strafe"/>
<LabeledObject width="fill" label="Auto strafe">
<Select target="misc.autostrafe">
<Option name="Off" value="0"/>
<Option name="Regular" value="1"/>
<Option name="Multidir" value="2"/>
</Select>
</LabeledObject>
</List>
</Box>
<Box padding="12 6 6 6" width="content" height="content" name="FollowBot" x="170">

View File

@ -28,7 +28,7 @@ namespace hacks::shared::misc
static settings::Boolean render_zoomed{ "visual.render-local-zoomed", "true" };
#endif
static settings::Boolean anti_afk{ "misc.anti-afk", "false" };
static settings::Boolean auto_strafe{ "misc.autostrafe", "false" };
static settings::Int auto_strafe{ "misc.autostrafe", "0" };
static settings::Boolean tauntslide{ "misc.tauntslide-tf2c", "false" };
static settings::Boolean tauntslide_tf2{ "misc.tauntslide", "false" };
static settings::Boolean flashlight_spam{ "misc.flashlight-spam", "false" };
@ -182,6 +182,29 @@ void DrawWireframeHitbox(wireframe_data data)
}
#endif
static float normalizeRad(float a) noexcept
{
return std::isfinite(a) ? std::remainder(a, PI * 2) : 0.0f;
}
static float angleDiffRad(float a1, float a2) noexcept
{
float delta;
delta = normalizeRad(a1 - a2);
if (a1 > a2)
{
if (delta >= PI)
delta -= PI * 2;
}
else
{
if (delta <= -PI)
delta += PI * 2;
}
return delta;
}
void CreateMove()
{
#if ENABLE_VISUALS
@ -206,18 +229,85 @@ void CreateMove()
// Automatically strafes in the air
if (auto_strafe && CE_GOOD(LOCAL_E) && !g_pLocalPlayer->life_state)
{
static bool was_jumping = false;
auto flags = CE_INT(LOCAL_E, netvar.iFlags);
auto movetype = (unsigned) CE_VAR(LOCAL_E, 0x194, unsigned char);
// Noclip
if (movetype != 8)
{
switch (*auto_strafe)
{
case 0: // Off
return;
break;
case 1: // Regular strafe
{
static bool was_jumping = false;
bool is_jumping = current_user_cmd->buttons & IN_JUMP;
if (!(flags & FL_ONGROUND) && !(flags & FL_INWATER) && (!is_jumping || was_jumping))
{
if (!(flags & FL_ONGROUND) || !(flags & FL_INWATER) && (!is_jumping || was_jumping))
if (current_user_cmd->mousedx)
{
current_user_cmd->sidemove = current_user_cmd->mousedx > 1 ? 450.f : -450.f;
}
}
was_jumping = is_jumping;
break;
}
case 2: // Multidirectional Airstrafe,
// Huge Credits to https://github.com/degeneratehyperbola/NEPS, as their airstrafe
// Apparently just works for tf2
// Also credits to "zelta" for porting it to tf2,
// And "Cyanide" for making it work with cathook.
{
static bool lastHeldJump = current_user_cmd->buttons & IN_JUMP;
const float speed = CE_VECTOR(LOCAL_E, netvar.vVelocity).Length2D();
auto vel = CE_VECTOR(LOCAL_E, netvar.vVelocity);
if (flags & FL_ONGROUND || flags & FL_INWATER)
return;
if (current_user_cmd->buttons & IN_JUMP)
return;
if (~current_user_cmd->buttons & current_user_cmd->buttons & IN_JUMP && !lastHeldJump)
return;
if (speed < 2.0f)
return;
constexpr auto perfectDelta = [](float speed) noexcept
{
static auto speedVar = CE_FLOAT(LOCAL_E, netvar.m_flMaxspeed);
static auto airVar = g_ICvar->FindVar("sv_airaccelerate");
// This is hardcoded for tf2, unless you run sourcemod
static auto wishSpeed = 30.0f;
const auto term = wishSpeed / airVar->GetFloat() / speedVar * 100.0f / speed;
if (term < 1.0f && term > -1.0f)
return acosf(term);
return 0.0f;
};
const float pDelta = perfectDelta(speed);
if (pDelta)
{
const float yaw = DEG2RAD(g_pLocalPlayer->v_OrigViewangles.y);
const float velDir = atan2f(vel.y, vel.x) - yaw;
const float wishAng = atan2f(-current_user_cmd->sidemove, current_user_cmd->forwardmove);
const float delta = angleDiffRad(velDir, wishAng); // Helpers::angleDiffRad(velDir, wishAng);
float moveDir = delta < 0.0f ? velDir + pDelta : velDir - pDelta;
current_user_cmd->forwardmove = cosf(moveDir) * 450.0f;
current_user_cmd->sidemove = -sinf(moveDir) * 450.0f;
}
lastHeldJump = current_user_cmd->buttons & current_user_cmd->buttons & IN_JUMP;
break;
}
default:
break;
}
}
}
// TF2c Tauntslide
@ -386,6 +476,7 @@ void Draw()
if (local->m_iClassID() == CL_CLASS(CTFMinigun))
AddSideString(format("Weapon state: ", CE_INT(local, netvar.iWeaponState)));
AddSideString(format("ItemDefinitionIndex: ", CE_INT(local, netvar.iItemDefinitionIndex)));
AddSideString(format("Maxspeed: ", CE_FLOAT(LOCAL_E, netvar.m_flMaxspeed)));
/*AddSideString(colors::white, "Weapon: %s [%i]",
RAW_ENT(g_pLocalPlayer->weapon())->GetClientClass()->GetName(),
g_pLocalPlayer->weapon()->m_iClassID());
@ -563,6 +654,16 @@ CatCommand set_value("set", "Set value",
var->SetValue(value.c_str());
logging::Info("Set '%s' to '%s'", args.Arg(1), value.c_str());
});
CatCommand get_value("get", "Set value",
[](const CCommand &args)
{
if (args.ArgC() < 2)
return;
ConVar *var = g_ICvar->FindVar(args.Arg(1));
if (!var)
return;
logging::Info("'%s': '%s'", args.Arg(1), var->GetString());
});
CatCommand say_lines("say_lines", "Say with newlines (\\n)",
[](const CCommand &args)
{

View File

@ -1349,7 +1349,7 @@ bool GetProjectileData(CachedEntity *weapon, float &speed, float &gravity, float
}
case CL_CLASS(CTFSyringeGun):
{
rgrav = 0.2f;
rgrav = 0.3f;
rspeed = 1000.0f;
break;
}

View File

@ -29,7 +29,7 @@ static bool update_override_textures = false;
std::vector<std::string> world_strings = { "World" };
std::vector<std::string> skybox_strings = { "SkyBox" };
std::vector<std::string> gui_strings = { "Other", "VGUI" };
std::vector<std::string> dont_override_strings = { "glass", "door", "water", "tools", "player" };
std::vector<std::string> dont_override_strings = { "glass", "door", "water", "tools", "player", "wall28", "wall26" };
std::vector<std::string> nodraw_strings = { "decal", "overlay", "hay" };
namespace hooked_methods
@ -58,6 +58,8 @@ DEFINE_HOOKED_METHOD(FrameStageNotify, void, void *this_, ClientFrameStage_t sta
// Ensure world mat
if (name.find("World") == std::string::npos)
continue;
if (pMaterial->IsErrorMaterial() || !pMaterial->IsPrecached() || pMaterial->IsTranslucent() || pMaterial->IsSpriteCard())
continue;
// Don't override this stuff
bool good = true;
for (auto &entry : dont_override_strings)
@ -77,9 +79,9 @@ DEFINE_HOOKED_METHOD(FrameStageNotify, void, void *this_, ClientFrameStage_t sta
if (!pMaterial->GetMaterialVarFlag(MATERIAL_VAR_NO_DRAW))
{
auto *kv = new KeyValues(pMaterial->GetShaderName());
auto *kv = new KeyValues("LightmappedGeneric" /*pMaterial->GetShaderName()*/);
kv->SetString("$basetexture", (*override_textures_texture).c_str());
kv->SetString("$basetexturetransform", "center .5 .5 scale 6 6 rotate 0 translate 0 0");
//kv->SetString("$basetexturetransform", "center .5 .5 scale 6 6 rotate 0 translate 0 0");
kv->SetString("$surfaceprop", "concrete");
pMaterial->SetShaderAndParams(kv);
}

View File

@ -82,16 +82,7 @@ void CreateMove()
// Credits to https://www.unknowncheats.me/forum/team-fortress-2-a/139094-projectile-nospread.html
// Set up Random Seed
int cmd_num = current_user_cmd->command_number;
// Crithack uses different things
if (criticals::isEnabled() && g_pLocalPlayer->weapon_mode != weapon_melee && criticals::crit_cmds.find(LOCAL_W->m_IDX) != criticals::crit_cmds.end() && criticals::crit_cmds.find(LOCAL_W->m_IDX)->second.size())
{
int array_index = criticals::current_index;
if (array_index >= criticals::crit_cmds.at(LOCAL_W->m_IDX).size())
array_index = 0;
// Adjust for nospread
cmd_num = criticals::crit_cmds.at(LOCAL_W->m_IDX).at(array_index);
}
int cmd_num = current_late_user_cmd->command_number;
RandomSeed(MD5_PseudoRandom(cmd_num) & 0x7FFFFFFF);
SharedRandomInt(MD5_PseudoRandom(cmd_num) & 0x7FFFFFFF, "SelectWeightedSequence", 0, 0, 0);
for (int i = 0; i < 6; ++i)
@ -106,7 +97,7 @@ void CreateMove()
{
// Check if we released the barrage by releasing m1, also lock bool so people don't just release m1 and tap it again
if (!should_nospread)
should_nospread = !(current_user_cmd->buttons & IN_ATTACK) && g_pLocalPlayer->bAttackLastTick;
should_nospread = !(current_late_user_cmd->buttons & IN_ATTACK) && g_pLocalPlayer->bAttackLastTick;
if (!CE_INT(LOCAL_W, netvar.m_iClip1) && CE_INT(LOCAL_W, netvar.iReloadMode) == 0)
{
@ -121,29 +112,29 @@ void CreateMove()
// Huntsman check
else if (LOCAL_W->m_iClassID() == CL_CLASS(CTFCompoundBow))
{
if (!g_pLocalPlayer->bAttackLastTick || (current_user_cmd->buttons & IN_ATTACK))
if (!g_pLocalPlayer->bAttackLastTick || (current_late_user_cmd->buttons & IN_ATTACK))
return;
}
// Rest of weapons
else if (!(current_user_cmd->buttons & IN_ATTACK))
else if (!(current_late_user_cmd->buttons & IN_ATTACK))
return;
switch (LOCAL_W->m_iClassID())
{
case CL_CLASS(CTFSyringeGun):
{
if (g_pLocalPlayer->v_OrigViewangles == current_user_cmd->viewangles)
if (g_pLocalPlayer->v_OrigViewangles == current_late_user_cmd->viewangles)
g_pLocalPlayer->bUseSilentAngles = true;
float spread = 1.5f;
current_user_cmd->viewangles.x -= RandomFloat(-spread, spread);
current_user_cmd->viewangles.y -= RandomFloat(-spread, spread);
fClampAngle(current_user_cmd->viewangles);
current_late_user_cmd->viewangles.x -= RandomFloat(-spread, spread);
current_late_user_cmd->viewangles.y -= RandomFloat(-spread, spread);
fClampAngle(current_late_user_cmd->viewangles);
break;
}
case CL_CLASS(CTFCompoundBow):
{
Vector view = re::C_BasePlayer::GetLocalEyeAngles(RAW_ENT(LOCAL_E));
if (g_pLocalPlayer->v_OrigViewangles == current_user_cmd->viewangles)
if (g_pLocalPlayer->v_OrigViewangles == current_late_user_cmd->viewangles)
g_pLocalPlayer->bUseSilentAngles = true;
Vector spread;
@ -152,25 +143,25 @@ void CreateMove()
re::C_TFWeaponBase::GetProjectileFireSetupHuntsman(RAW_ENT(LOCAL_W), RAW_ENT(LOCAL_E), Vector(23.5f, -8.f, 8.f), &src, &spread, false, 2000.0f);
spread -= view;
current_user_cmd->viewangles -= spread;
fClampAngle(current_user_cmd->viewangles);
current_late_user_cmd->viewangles -= spread;
fClampAngle(current_late_user_cmd->viewangles);
break;
}
default:
Vector view = re::C_BasePlayer::GetLocalEyeAngles(RAW_ENT(LOCAL_E));
if (g_pLocalPlayer->v_OrigViewangles == current_user_cmd->viewangles)
if (g_pLocalPlayer->v_OrigViewangles == current_late_user_cmd->viewangles)
g_pLocalPlayer->bUseSilentAngles = true;
Vector spread = re::C_TFWeaponBase::GetSpreadAngles(RAW_ENT(LOCAL_W));
spread -= view;
current_user_cmd->viewangles -= spread;
fClampAngle(current_user_cmd->viewangles);
current_late_user_cmd->viewangles -= spread;
fClampAngle(current_late_user_cmd->viewangles);
break;
}
}
static InitRoutine init([]() { EC::Register(EC::CreateMove, CreateMove, "nospread_cm", EC::very_late); });
static InitRoutine init([]() { EC::Register(EC::CreateMoveLate, CreateMove, "nospread_cm", EC::very_late); });
enum nospread_sync_state
{
@ -306,7 +297,9 @@ void ApplySpreadCorrection(Vector &angles, int seed, float spread)
fClampAngle(angles);
}
CatCommand debug_mantissa("test_mantissa", "For debug purposes", [](const CCommand &rCmd) {
CatCommand debug_mantissa("test_mantissa", "For debug purposes",
[](const CCommand &rCmd)
{
if (rCmd.ArgC() < 2)
{
g_ICvar->ConsoleColorPrintf(MENU_COLOR, "You must provide float to test.\n");
@ -327,7 +320,9 @@ CatCommand debug_mantissa("test_mantissa", "For debug purposes", [](const CComma
return;
});
static CatCommand nospread_sync("nospread_sync", "Try to sync client and server time", []() {
static CatCommand nospread_sync("nospread_sync", "Try to sync client and server time",
[]()
{
if (!bullet)
{
g_ICvar->ConsoleColorPrintf(MENU_COLOR, "Set nospread.enable to true first.\n");
@ -338,7 +333,9 @@ static CatCommand nospread_sync("nospread_sync", "Try to sync client and server
g_ICvar->ConsoleColorPrintf(MENU_COLOR, "Trying to sync Seed...\n");
});
static CatCommand nospread_resync("nospread_resync", "Try to sync client and server time", []() {
static CatCommand nospread_resync("nospread_resync", "Try to sync client and server time",
[]()
{
if (!bullet)
{
g_ICvar->ConsoleColorPrintf(MENU_COLOR, "Set nospread.enable to true first.\n");
@ -627,7 +624,8 @@ void CL_SendMove_hook()
int new_packets = 1 + *choked_packets;
auto RecheckIfresync_needed = [&new_packets](double asumed_time) -> void {
auto RecheckIfresync_needed = [&new_packets](double asumed_time) -> void
{
static Timer s_NextCheck;
// we use it as 1 sec delay
if (s_NextCheck.check(1000) && new_packets == 1 && (no_spread_synced != SYNCED || !LOCAL_E->m_bAlivePlayer()) && !waiting_perf_data)
@ -879,7 +877,9 @@ void CreateMove2()
}
}
static InitRoutine init_bulletnospread([]() {
static InitRoutine init_bulletnospread(
[]()
{
// Get our detour hooks running
static auto writeusercmd_addr = gSignatures.GetClientSignature("55 89 E5 57 56 53 83 EC 2C 8B 45 ? 8B 7D ? 8B 5D ? 89 45 ? 8B 40");
cl_writeusercmd_detour.Init(writeusercmd_addr, (void *) WriteUserCmd_hook);
@ -892,7 +892,9 @@ static InitRoutine init_bulletnospread([]() {
EC::Register(EC::CreateMove, CreateMove2, "nospread_createmove2");
EC::Register(EC::CreateMoveWarp, CreateMove2, "nospread_createmove2w");
bullet.installChangeCallback([](settings::VariableBase<bool> &, bool after) {
bullet.installChangeCallback(
[](settings::VariableBase<bool> &, bool after)
{
if (!after)
{
is_syncing = false;
@ -902,7 +904,8 @@ static InitRoutine init_bulletnospread([]() {
#if ENABLE_VISUALS
EC::Register(
EC::Draw,
[]() {
[]()
{
if (bullet && (draw || draw_mantissa) && CE_GOOD(LOCAL_E) && LOCAL_E->m_bAlivePlayer())
{
std::string draw_string = "";
@ -949,7 +952,8 @@ static InitRoutine init_bulletnospread([]() {
#endif
EC::Register(
EC::LevelInit,
[]() {
[]()
{
no_spread_synced = NOT_SYNCED;
last_was_player_perf = false;
bad_mantissa = false;
@ -959,7 +963,8 @@ static InitRoutine init_bulletnospread([]() {
EC::Register(
EC::LevelShutdown,
[]() {
[]()
{
no_spread_synced = NOT_SYNCED;
last_was_player_perf = false;
bad_mantissa = false;
@ -968,7 +973,8 @@ static InitRoutine init_bulletnospread([]() {
"nospread_levelshutdown");
EC::Register(
EC::Shutdown,
[]() {
[]()
{
cl_writeusercmd_detour.Shutdown();
fx_firebullets_detour.Shutdown();
// net_sendpacket_detour.Shutdown();