From 24e166f610fdeb2d039484f2912a5d95735599b3 Mon Sep 17 00:00:00 2001 From: BenCat07 Date: Fri, 9 Oct 2020 20:22:07 +0200 Subject: [PATCH] Alot of small fixes and improvements Closes #535, #939, #894, #996, #1117 and a crash in backtrack. Additionally some projectile weapons have also been fixed --- data/menu/nullifiedcat/aimbot.xml | 4 +- data/menu/nullifiedcat/misc/collective.xml | 1 + data/menu/nullifiedcat/trigger/autoheal.xml | 1 + include/core/offsets.hpp | 4 ++ include/helpers.hpp | 2 +- include/prediction.hpp | 6 +-- src/hacks/Aimbot.cpp | 43 ++++++++++++++------- src/hacks/AutoBackstab.cpp | 11 +++++- src/hacks/AutoHeal.cpp | 3 ++ src/hacks/Backtrack.cpp | 4 +- src/hacks/Misc.cpp | 32 ++++++++++++++- src/hacks/MiscAimbot.cpp | 9 +++-- src/helpers.cpp | 31 ++++++++------- src/prediction.cpp | 15 ++++--- src/tfmm.cpp | 3 +- 15 files changed, 119 insertions(+), 50 deletions(-) diff --git a/data/menu/nullifiedcat/aimbot.xml b/data/menu/nullifiedcat/aimbot.xml index aaa1c0cd..ee75dab6 100755 --- a/data/menu/nullifiedcat/aimbot.xml +++ b/data/menu/nullifiedcat/aimbot.xml @@ -12,6 +12,7 @@ + @@ -23,7 +24,7 @@ - + @@ -99,6 +100,7 @@ + diff --git a/data/menu/nullifiedcat/misc/collective.xml b/data/menu/nullifiedcat/misc/collective.xml index 903b4ff4..68c0ecfc 100755 --- a/data/menu/nullifiedcat/misc/collective.xml +++ b/data/menu/nullifiedcat/misc/collective.xml @@ -84,6 +84,7 @@ + diff --git a/data/menu/nullifiedcat/trigger/autoheal.xml b/data/menu/nullifiedcat/trigger/autoheal.xml index 851ac1b0..28216f3d 100755 --- a/data/menu/nullifiedcat/trigger/autoheal.xml +++ b/data/menu/nullifiedcat/trigger/autoheal.xml @@ -8,6 +8,7 @@ + diff --git a/include/core/offsets.hpp b/include/core/offsets.hpp index f08c7688..9f899a33 100644 --- a/include/core/offsets.hpp +++ b/include/core/offsets.hpp @@ -224,4 +224,8 @@ struct offsets { return PlatformOffset(18, undefined, undefined); } + static constexpr uint32_t m_bUsingActionSlot() + { + return PlatformOffset(0x2fb8, undefined, undefined); + } }; diff --git a/include/helpers.hpp b/include/helpers.hpp index 98887813..d2fa93e6 100644 --- a/include/helpers.hpp +++ b/include/helpers.hpp @@ -113,7 +113,7 @@ bool LineIntersectsBox(Vector &bmin, Vector &bmax, Vector &lmin, Vector &lmax); float DistToSqr(CachedEntity *entity); void fClampAngle(Vector &qaAng); // const char* MakeInfoString(IClientEntity* player); -bool GetProjectileData(CachedEntity *weapon, float &speed, float &gravity); +bool GetProjectileData(CachedEntity *weapon, float &speed, float &gravity, float &start_velocity); bool IsVectorVisible(Vector a, Vector b, bool enviroment_only = false, CachedEntity *self = LOCAL_E, unsigned int mask = MASK_SHOT_HULL); // A Special function for navparser to check if a Vector is visible. bool IsVectorVisibleNavigation(Vector a, Vector b, unsigned int mask = MASK_SHOT_HULL); diff --git a/include/prediction.hpp b/include/prediction.hpp index 31d77743..29c9bc2f 100644 --- a/include/prediction.hpp +++ b/include/prediction.hpp @@ -18,9 +18,9 @@ Vector SimpleLatencyPrediction(CachedEntity *ent, int hb); bool PerformProjectilePrediction(CachedEntity *target, int hitbox); -Vector BuildingPrediction(CachedEntity *building, Vector vec, float speed, float gravity); -Vector ProjectilePrediction(CachedEntity *ent, int hb, float speed, float gravitymod, float entgmod); -Vector ProjectilePrediction_Engine(CachedEntity *ent, int hb, float speed, float gravitymod, float entgmod /* ignored */); +Vector BuildingPrediction(CachedEntity *building, Vector vec, float speed, float gravity, float proj_startvelocity = 0.0f); +Vector ProjectilePrediction(CachedEntity *ent, int hb, float speed, float gravitymod, float entgmod, float proj_startvelocity = 0.0f); +Vector ProjectilePrediction_Engine(CachedEntity *ent, int hb, float speed, float gravitymod, float entgmod /* ignored */, float proj_startvelocity = 0.0f); std::vector Predict(Vector pos, float offset, Vector vel, Vector acceleration, std::pair minmax, float time, int count, bool vischeck = true); float PlayerGravityMod(CachedEntity *player); diff --git a/src/hacks/Aimbot.cpp b/src/hacks/Aimbot.cpp index 861c1d43..91d87bd1 100644 --- a/src/hacks/Aimbot.cpp +++ b/src/hacks/Aimbot.cpp @@ -38,6 +38,7 @@ static settings::Float normal_fov{ "aimbot.fov", "0" }; static settings::Int priority_mode{ "aimbot.priority-mode", "0" }; static settings::Boolean wait_for_charge{ "aimbot.wait-for-charge", "0" }; +static settings::Boolean proj_silent("aimbot.projectile-silent", "1"); static settings::Boolean silent{ "aimbot.silent", "1" }; static settings::Boolean target_lock{ "aimbot.lock-target", "0" }; #if ENABLE_VISUALS @@ -54,6 +55,7 @@ static settings::Int miss_chance{ "aimbot.miss-chance", "0" }; static settings::Boolean projectile_aimbot{ "aimbot.projectile.enable", "true" }; static settings::Float proj_gravity{ "aimbot.projectile.gravity", "0" }; static settings::Float proj_speed{ "aimbot.projectile.speed", "0" }; +static settings::Float proj_start_vel{ "aimbot.projectile.initial-velocity", "0" }; static settings::Float sticky_autoshoot{ "aimbot.projectile.sticky-autoshoot", "0.5" }; @@ -153,6 +155,7 @@ settings::Boolean ignore_cloak{ "aimbot.target.ignore-cloaked-spies", "1" }; bool projectile_mode{ false }; float cur_proj_speed{ 0.0f }; float cur_proj_grav{ 0.0f }; +float cur_proj_start_vel{ 0.0f }; bool shouldBacktrack() { @@ -266,13 +269,15 @@ static void CreateMove() // Refresh projectile info if (projectileAimbotRequired) { - projectile_mode = GetProjectileData(g_pLocalPlayer->weapon(), cur_proj_speed, cur_proj_grav); + projectile_mode = GetProjectileData(g_pLocalPlayer->weapon(), cur_proj_speed, cur_proj_grav, cur_proj_start_vel); if (!projectile_mode) return; if (proj_speed) - cur_proj_speed = float(proj_speed); + cur_proj_speed = *proj_speed; if (proj_gravity) - cur_proj_grav = float(proj_gravity); + cur_proj_grav = *proj_gravity; + if (proj_start_vel) + cur_proj_start_vel = *proj_start_vel; } // Refresh our best target CachedEntity *target_entity = RetrieveBestTarget(aimkey_status); @@ -340,14 +345,14 @@ static void CreateMove() } else if (LOCAL_W->m_iClassID() == CL_CLASS(CTFPipebombLauncher)) { - float chargebegin = *((float *) ((uintptr_t) RAW_ENT(LOCAL_W) + 3152)); + float chargebegin = CE_FLOAT(LOCAL_W, netvar.flChargeBeginTime); float chargetime = g_GlobalVars->curtime - chargebegin; DoAutoshoot(); static bool currently_charging_pipe = false; // Grenade started charging - if (chargetime < 6.0f && chargetime) + if (chargetime < 6.0f && chargetime && chargebegin) currently_charging_pipe = true; // Grenade was released @@ -968,8 +973,11 @@ void DoAutoshoot(CachedEntity *target_entity) current_user_cmd->buttons &= ~IN_ATTACK; hacks::shared::antiaim::SetSafeSpace(5); begancharge = false; - // Pull string if charge isnt enough + // Projectile silent logic + if (proj_silent) + *bSendPackets = false; } + // Pull string if charge isnt enough else { current_user_cmd->buttons |= IN_ATTACK; @@ -981,16 +989,19 @@ void DoAutoshoot(CachedEntity *target_entity) begancharge = false; if (g_pLocalPlayer->weapon()->m_iClassID() == CL_CLASS(CTFPipebombLauncher)) { - float chargebegin = *((float *) ((unsigned) RAW_ENT(LOCAL_W) + 3152)); + float chargebegin = CE_FLOAT(LOCAL_W, netvar.flChargeBeginTime); float chargetime = g_GlobalVars->curtime - chargebegin; // Release Sticky if > chargetime, 3.85 is the max second chargetime, - // but we want a percent so here we go + // but we also need to consider the release time supplied by the user if ((chargetime >= 3.85f * *sticky_autoshoot) && begansticky > 3) { current_user_cmd->buttons &= ~IN_ATTACK; hacks::shared::antiaim::SetSafeSpace(5); begansticky = 0; + // Projectile silent logic + if (proj_silent) + *bSendPackets = false; } // Else just keep charging else @@ -1047,7 +1058,11 @@ void DoAutoshoot(CachedEntity *target_entity) auto hitbox = calculated_data_array[target_entity->m_IDX].hitbox; hitrate::AimbotShot(target_entity->m_IDX, hitbox != head); } - *bSendPackets = true; + // Projectile silent logic + if (projectileAimbotRequired && proj_silent) + *bSendPackets = false; + else + *bSendPackets = true; } if (LOCAL_W->m_iClassID() == CL_CLASS(CTFLaserPointer)) current_user_cmd->buttons |= IN_ATTACK2; @@ -1072,9 +1087,9 @@ const Vector &PredictEntity(CachedEntity *entity) { // Use prediction engine if user settings allow if (engine_projpred) - result = ProjectilePrediction_Engine(entity, cd.hitbox, cur_proj_speed, cur_proj_grav, 0); + result = ProjectilePrediction_Engine(entity, cd.hitbox, cur_proj_speed, cur_proj_grav, 0, cur_proj_start_vel); else - result = ProjectilePrediction(entity, cd.hitbox, cur_proj_speed, cur_proj_grav, PlayerGravityMod(entity)); + result = ProjectilePrediction(entity, cd.hitbox, cur_proj_speed, cur_proj_grav, PlayerGravityMod(entity), cur_proj_start_vel); } else { @@ -1090,7 +1105,7 @@ const Vector &PredictEntity(CachedEntity *entity) else if (entity->m_Type() == ENTITY_BUILDING || entity->m_iClassID() != CL_CLASS(CTFTankBoss)) { if (cur_proj_grav || cur_proj_grav) - result = BuildingPrediction(entity, GetBuildingPosition(entity), cur_proj_speed, cur_proj_grav); + result = BuildingPrediction(entity, GetBuildingPosition(entity), cur_proj_speed, cur_proj_grav, cur_proj_start_vel); else result = GetBuildingPosition(entity); // Other @@ -1160,12 +1175,12 @@ int BestHitbox(CachedEntity *target) // Rocket launcher } // These weapons should aim at the foot if the target is grounded - else if (ci == CL_CLASS(CTFRocketLauncher) || ci == CL_CLASS(CTFRocketLauncher_AirStrike) || ci == CL_CLASS(CTFRocketLauncher_Mortar)) + else if (ci == CL_CLASS(CTFPipebombLauncher) || ci == CL_CLASS(CTFRocketLauncher) || ci == CL_CLASS(CTFParticleCannon) || ci == CL_CLASS(CTFRocketLauncher_AirStrike) || ci == CL_CLASS(CTFRocketLauncher_Mortar)) { preferred = hitbox_t::foot_L; } // These weapons should aim at the center of mass due to little/no splash - else if (ci == CL_CLASS(CTFPipebombLauncher) || ci == CL_CLASS(CTFRocketLauncher_DirectHit) || ci == CL_CLASS(CTFGrenadeLauncher)) + else if (ci == CL_CLASS(CTFRocketLauncher_DirectHit) || ci == CL_CLASS(CTFGrenadeLauncher)) { preferred = hitbox_t::spine_3; } diff --git a/src/hacks/AutoBackstab.cpp b/src/hacks/AutoBackstab.cpp index 23d5cdcc..dd1c8aa9 100644 --- a/src/hacks/AutoBackstab.cpp +++ b/src/hacks/AutoBackstab.cpp @@ -276,7 +276,7 @@ static bool doBacktrackStab(bool legit = false) { CachedEntity *ent = ENTITY(i); // Targeting checks - if (CE_BAD(ent) || !ent->m_bAlivePlayer() || !ent->m_bEnemy() || !player_tools::shouldTarget(ent)|| IsPlayerInvulnerable(ent)) + if (CE_BAD(ent) || !ent->m_bAlivePlayer() || !ent->m_bEnemy() || !player_tools::shouldTarget(ent) || IsPlayerInvulnerable(ent)) continue; // Get the best tick for that ent @@ -304,11 +304,18 @@ static bool doBacktrackStab(bool legit = false) return false; } +inline bool HasKnife() +{ + if (re::C_TFWeaponBase::GetWeaponID(RAW_ENT(LOCAL_W)) == 7) + return true; + return false; +} + void CreateMove() { if (!enabled) return; - if (CE_BAD(LOCAL_E) || g_pLocalPlayer->life_state || g_pLocalPlayer->clazz != tf_spy || CE_BAD(LOCAL_W) || GetWeaponMode() != weapon_melee || IsPlayerInvisible(LOCAL_E) || CE_BYTE(LOCAL_E, netvar.m_bFeignDeathReady)) + if (CE_BAD(LOCAL_E) || g_pLocalPlayer->life_state || CE_BAD(LOCAL_W) || !HasKnife() || IsPlayerInvisible(LOCAL_E) || CE_BYTE(LOCAL_E, netvar.m_bFeignDeathReady)) return; if (!CanShoot()) return; diff --git a/src/hacks/AutoHeal.cpp b/src/hacks/AutoHeal.cpp index f1e0a86c..21bfd189 100644 --- a/src/hacks/AutoHeal.cpp +++ b/src/hacks/AutoHeal.cpp @@ -23,6 +23,7 @@ static settings::Boolean pop_uber_auto{ "autoheal.uber.enable", "true" }; static settings::Boolean pop_uber_voice{ "autoheal.popvoice", "true" }; static settings::Float pop_uber_percent{ "autoheal.uber.health-below-ratio", "0" }; static settings::Boolean share_uber{ "autoheal.uber.share", "false" }; +static settings::Boolean heal_disguised{ "autoheal.disguised", "false" }; static settings::Boolean auto_vacc{ "autoheal.vacc.enable", "false" }; @@ -493,6 +494,8 @@ bool CanHeal(int idx) return false; if (friendsonly && !playerlist::IsFriend(ent)) return false; + if (!heal_disguised && IsPlayerDisguised(ent)) + return false; return true; } diff --git a/src/hacks/Backtrack.cpp b/src/hacks/Backtrack.cpp index 821da505..e155fce7 100644 --- a/src/hacks/Backtrack.cpp +++ b/src/hacks/Backtrack.cpp @@ -21,7 +21,7 @@ static int lastincomingsequence{ 0 }; static float latency_rampup = 0.0f; // Which data to apply in the late CreateMove -static CachedEntity *bt_ent; +static CachedEntity *bt_ent = nullptr; static std::optional bt_data; static bool isEnabled(); @@ -51,7 +51,7 @@ void ApplyBacktrack() { if (!isBacktrackEnabled) return; - if (bt_ent) + if (bt_ent && bt_data) { current_user_cmd->tick_count = (*bt_data).tickcount; CE_FLOAT(bt_ent, netvar.m_angEyeAngles) = (*bt_data).m_vecAngles.x; diff --git a/src/hacks/Misc.cpp b/src/hacks/Misc.cpp index 100c37a1..4a259e07 100644 --- a/src/hacks/Misc.cpp +++ b/src/hacks/Misc.cpp @@ -36,8 +36,8 @@ static settings::Boolean nopush_enabled{ "misc.no-push", "false" }; static settings::Boolean dont_hide_stealth_kills{ "misc.dont-hide-stealth-kills", "true" }; static settings::Boolean unlimit_bumpercart_movement{ "misc.bumpercarthax.enable", "true" }; static settings::Boolean ping_reducer{ "misc.ping-reducer.enable", "false" }; - static settings::Int force_ping{ "misc.ping-reducer.target", "0" }; +static settings::Boolean force_wait{ "misc.force-enable-wait", "true" }; #if ENABLE_VISUALS static settings::Boolean god_mode{ "misc.god-mode", "false" }; @@ -908,8 +908,37 @@ void cyoaview_nethook(const CRecvProxyData *data, void *pPlayer, void *out) *value_out = false; } +// This function does two things. +// 1. It patches the check that's supposed to update the "isWaitCommandEnabled" on the cvar buffer to always skip +// 2. It sets the wait command to enabled +// The Former is the main logic, the latter is so you don't accidentally perma disable it either +inline void force_wait_func(bool after) +{ + static auto enable_wait_signature = gSignatures.GetEngineSignature("74 ? A2 ? ? ? ? C7 44 24 ? 01 00 00 00"); + // Jump if not overflow, aka always jump in this case + static BytePatch patch_wait(enable_wait_signature, { 0x71 }); + if (after) + { + // Enable the wait command + int **enable_wait = (int **) (enable_wait_signature + 3); + **enable_wait = true; + patch_wait.Patch(); + } + else + patch_wait.Shutdown(); +} + +void callback_force_wait(settings::VariableBase &, bool after) +{ + force_wait_func(after); +} + static InitRoutine init([]() { HookNetvar({ "DT_TFPlayer", "m_bViewingCYOAPDA" }, cyoa_anim_hook, cyoaview_nethook); + + force_wait.installChangeCallback(callback_force_wait); + force_wait_func(true); + teammatesPushaway = g_ICvar->FindVar("tf_avoidteammates_pushaway"); EC::Register(EC::Shutdown, Shutdown, "draw_local_player", EC::average); EC::Register(EC::CreateMove, CreateMove, "cm_misc_hacks", EC::average); @@ -944,6 +973,7 @@ static InitRoutine init([]() { stealth_kill.Shutdown(); cyoa_patch.Shutdown(); tryPatchLocalPlayerShouldDraw(false); + force_wait_func(false); }, "shutdown_stealthkill"); dont_hide_stealth_kills.installChangeCallback([](settings::VariableBase &, bool after) { diff --git a/src/hacks/MiscAimbot.cpp b/src/hacks/MiscAimbot.cpp index 9a978a32..98c28221 100644 --- a/src/hacks/MiscAimbot.cpp +++ b/src/hacks/MiscAimbot.cpp @@ -18,9 +18,10 @@ static settings::Boolean sandwichaim_enabled{ "sandwichaim.enable", "false" }; static settings::Button sandwichaim_aimkey{ "sandwichaim.aimkey", "" }; static settings::Int sandwichaim_aimkey_mode{ "sandwichaim.aimkey-mode", "0" }; -float sandwich_speed = 350.0f; -float grav = 0.25f; -int prevent = -1; +constexpr float sandwich_speed = 350.0f; +constexpr float grav = 0.25f; +constexpr float initial_vel = 200.0f; +int prevent = -1; static Timer previous_entity_delay{}; // TODO: Refactor this jank @@ -47,7 +48,7 @@ std::pair FindBestEnt(bool teammate, bool Predict, bool continue; Vector target{}; if (Predict) - target = ProjectilePrediction(ent, 1, sandwich_speed, grav, PlayerGravityMod(ent)); + target = ProjectilePrediction(ent, 1, sandwich_speed, grav, PlayerGravityMod(ent), initial_vel); else target = ent->hitboxes.GetHitbox(1)->center; if (!hacks::tf2::backtrack::isBacktrackEnabled && !IsEntityVectorVisible(ent, target)) diff --git a/src/helpers.cpp b/src/helpers.cpp index 6c6d4a2a..b76d8327 100644 --- a/src/helpers.cpp +++ b/src/helpers.cpp @@ -1229,16 +1229,17 @@ bool LineIntersectsBox(Vector &bmin, Vector &bmax, Vector &lmin, Vector &lmax) return true; } -bool GetProjectileData(CachedEntity *weapon, float &speed, float &gravity) +bool GetProjectileData(CachedEntity *weapon, float &speed, float &gravity, float &start_velocity) { - float rspeed, rgrav; + float rspeed, rgrav, rinitial_vel; IF_GAME(!IsTF()) return false; if (CE_BAD(weapon)) return false; - rspeed = 0.0f; - rgrav = 0.0f; + rspeed = 0.0f; + rgrav = 0.0f; + rinitial_vel = 0.0f; typedef float(GetProjectileData)(IClientEntity *); switch (weapon->m_iClassID()) @@ -1265,25 +1266,24 @@ bool GetProjectileData(CachedEntity *weapon, float &speed, float &gravity) } case CL_CLASS(CTFGrenadeLauncher): { - rspeed = 1200.0f; - rgrav = 0.4f; + rspeed = 1200.0f; + rgrav = 1.0f; + rinitial_vel = 200.0f; IF_GAME(IsTF2()) { // Loch'n Load if (CE_INT(weapon, netvar.iItemDefinitionIndex) == 308) rspeed *= 1.25f; } - IF_GAME(IsTF2C()) - { - rgrav = 0.5f; - } break; } case CL_CLASS(CTFPipebombLauncher): { float chargetime = g_GlobalVars->curtime - CE_FLOAT(weapon, netvar.flChargeBeginTime); - rspeed = RemapValClamped(chargetime, 0.0f, 4.0f, 900, 2400); - rgrav = 0.4f; + if (!CE_FLOAT(weapon, netvar.flChargeBeginTime)) + chargetime = 0.0f; + rspeed = RemapValClamped(chargetime, 0.0f, 4.0f, 900, 2400); + rgrav = 0.4f; break; } case CL_CLASS(CTFCompoundBow): @@ -1346,9 +1346,10 @@ bool GetProjectileData(CachedEntity *weapon, float &speed, float &gravity) } } - speed = rspeed; - gravity = rgrav; - return (rspeed || rgrav); + speed = rspeed; + gravity = rgrav; + start_velocity = rinitial_vel; + return (rspeed || rgrav || rinitial_vel); } constexpr unsigned developer_list[] = { 306902159 }; diff --git a/src/prediction.cpp b/src/prediction.cpp index ea3de0a2..4d216a0c 100644 --- a/src/prediction.cpp +++ b/src/prediction.cpp @@ -228,7 +228,7 @@ Vector EnginePrediction(CachedEntity *entity, float time) return result; } -Vector ProjectilePrediction_Engine(CachedEntity *ent, int hb, float speed, float gravitymod, float entgmod /* ignored */) +Vector ProjectilePrediction_Engine(CachedEntity *ent, int hb, float speed, float gravitymod, float entgmod /* ignored */, float proj_startvelocity) { Vector origin = ent->m_vecOrigin(); Vector hitbox; @@ -238,6 +238,8 @@ Vector ProjectilePrediction_Engine(CachedEntity *ent, int hb, float speed, float if (speed == 0.0f) return Vector(); + static ConVar *sv_gravity = g_ICvar->FindVar("sv_gravity"); + // TODO ProjAim float medianTime = g_pLocalPlayer->v_Eye.DistTo(hitbox) / speed; float range = 1.5f; @@ -283,14 +285,14 @@ Vector ProjectilePrediction_Engine(CachedEntity *ent, int hb, float speed, float CE_VECTOR(ent, 0x354) = origin; // Compensate for ping besttime += g_IEngine->GetNetChannelInfo()->GetLatency(FLOW_OUTGOING) + cl_interp->GetFloat(); - bestpos.z += (400 * besttime * besttime * gravitymod); + bestpos.z += (sv_gravity->GetFloat() / 2.0f * besttime * besttime * gravitymod - proj_startvelocity * besttime); // S = at^2/2 ; t = sqrt(2S/a)*/ Vector result = bestpos + hitbox_offset; /*logging::Info("[Pred][%d] delta: %.2f %.2f %.2f", result.x - origin.x, result.y - origin.y, result.z - origin.z);*/ return result; } -Vector BuildingPrediction(CachedEntity *building, Vector vec, float speed, float gravity) +Vector BuildingPrediction(CachedEntity *building, Vector vec, float speed, float gravity, float proj_startvelocity) { if (!vec.z || CE_BAD(building)) return Vector(); @@ -303,6 +305,7 @@ Vector BuildingPrediction(CachedEntity *building, Vector vec, float speed, float if (speed == 0.0f) return Vector(); + static ConVar *sv_gravity = g_ICvar->FindVar("sv_gravity"); trace::filter_no_player.SetSelf(RAW_ENT(building)); float dtg = DistanceToGround(vec, RAW_ENT(building)->GetCollideable()->OBBMins(), RAW_ENT(building)->GetCollideable()->OBBMaxs()); // TODO ProjAim @@ -335,12 +338,12 @@ Vector BuildingPrediction(CachedEntity *building, Vector vec, float speed, float } // Compensate for ping besttime += g_IEngine->GetNetChannelInfo()->GetLatency(FLOW_OUTGOING) + cl_interp->GetFloat(); - bestpos.z += (400 * besttime * besttime * gravity); + bestpos.z += (sv_gravity->GetFloat() / 2.0f * besttime * besttime * gravity - proj_startvelocity * besttime); // S = at^2/2 ; t = sqrt(2S/a)*/ return bestpos; } -Vector ProjectilePrediction(CachedEntity *ent, int hb, float speed, float gravitymod, float entgmod) +Vector ProjectilePrediction(CachedEntity *ent, int hb, float speed, float gravitymod, float entgmod, float proj_startvelocity) { Vector origin = ent->m_vecOrigin(); Vector hitbox; @@ -405,7 +408,7 @@ Vector ProjectilePrediction(CachedEntity *ent, int hb, float speed, float gravit } // Compensate for ping besttime += g_IEngine->GetNetChannelInfo()->GetLatency(FLOW_OUTGOING) + cl_interp->GetFloat(); - bestpos.z += (sv_gravity->GetFloat() / 2.0f * besttime * besttime * gravitymod); + bestpos.z += (sv_gravity->GetFloat() / 2.0f * besttime * besttime * gravitymod - proj_startvelocity * besttime); // S = at^2/2 ; t = sqrt(2S/a)*/ Vector result = bestpos + hitbox_offset; /*logging::Info("[Pred][%d] delta: %.2f %.2f %.2f", result.x - origin.x, diff --git a/src/tfmm.cpp b/src/tfmm.cpp index e69809dd..38e4303f 100644 --- a/src/tfmm.cpp +++ b/src/tfmm.cpp @@ -10,6 +10,7 @@ #include "hacks/AutoJoin.hpp" #include "hack.hpp" +static settings::Boolean auto_party{ "player-tools.set-party-state", "true" }; settings::Int queue{ "autoqueue.mode", "7" }; CatCommand cmd_queue_start("mm_queue_casual", "Start casual queue", []() { tfmm::startQueue(); }); @@ -171,7 +172,7 @@ void abandon() static Timer friend_party_t{}; void friend_party() { - if (friend_party_t.test_and_set(10000)) + if (auto_party && friend_party_t.test_and_set(10000)) { re::CTFPartyClient *pc = re::CTFPartyClient::GTFPartyClient(); if (pc)