diff --git a/include/hacks/Aimbot.hpp b/include/hacks/Aimbot.hpp index d5acd835..d60c10ff 100644 --- a/include/hacks/Aimbot.hpp +++ b/include/hacks/Aimbot.hpp @@ -29,8 +29,7 @@ struct AimbotCalculatedData_s }; // Functions used to calculate aimbot data, and if already calculated use it -Vector PredictEntity(CachedEntity *entity, bool vischeck); -bool VischeckPredictedEntity(CachedEntity *entity); +Vector PredictEntity(CachedEntity *entity); bool BacktrackVisCheck(CachedEntity *entity); // Functions called by other functions for when certian game calls are run @@ -42,8 +41,13 @@ CachedEntity *CurrentTarget(); bool ShouldAim(); CachedEntity *RetrieveBestTarget(bool aimkey_state); bool IsTargetStateGood(CachedEntity *entity); -void Aim(CachedEntity *entity); +bool Aim(CachedEntity *entity); void DoAutoshoot(CachedEntity *target = nullptr); +bool smallBoxChecker(CachedEntity* target_entity); +int notVisibleHitbox(CachedEntity *target, int preferred); +int autoHitbox(CachedEntity* target); +bool hitscanSpecialCases(CachedEntity* target_entity, int weapon_case); +bool projectileSpecialCases(CachedEntity* target_entity, int weapon_case); int BestHitbox(CachedEntity *target); int ClosestHitbox(CachedEntity *target); void DoSlowAim(Vector &inputAngle); diff --git a/src/hacks/Aimbot.cpp b/src/hacks/Aimbot.cpp index c1492e30..2431e4de 100644 --- a/src/hacks/Aimbot.cpp +++ b/src/hacks/Aimbot.cpp @@ -13,8 +13,8 @@ #include #include #include "common.hpp" -#include "MiscTemporary.hpp" #include +#include "MiscTemporary.hpp" #include "hitrate.hpp" #include "FollowBot.hpp" #include "Warp.hpp" @@ -35,7 +35,7 @@ static settings::Int priority_mode{ "aimbot.priority-mode", "0" }; static settings::Boolean wait_for_charge{ "aimbot.wait-for-charge", "0" }; static settings::Boolean silent{ "aimbot.silent", "1" }; -static settings::Boolean target_lock{ "aimbot.lock-target", "0" }; +static settings::Boolean target_lock{ "aimbot.lock-target", "false" }; #if ENABLE_VISUALS static settings::Boolean assistance_only{ "aimbot.assistance.only", "0" }; #endif @@ -55,7 +55,6 @@ static settings::Float proj_start_vel{ "aimbot.projectile.initial-velocity", "0" static settings::Float sticky_autoshoot{ "aimbot.projectile.sticky-autoshoot", "0.5" }; static settings::Boolean aimbot_debug{ "aimbot.debug", "0" }; -settings::Boolean engine_projpred{ "aimbot.debug.engine-pp", "1" }; static settings::Boolean auto_spin_up{ "aimbot.auto.spin-up", "0" }; static settings::Boolean minigun_tapfire{ "aimbot.auto.tapfire", "false" }; @@ -88,11 +87,13 @@ static settings::Boolean specenable("aimbot.spectator.enable", "0"); static settings::Float specfov("aimbot.spectator.fov", "0"); static settings::Int specslow("aimbot.spectator.slow", "0"); +settings::Boolean engine_projpred{ "aimbot.debug.engine-pp", "1" }; + int slow_aim; float fov; bool enable; -static void spectatorUpdate() +void spectatorUpdate() { switch (*specmode) { @@ -102,6 +103,7 @@ static void spectatorUpdate() break; // Disable if being spectated in first person case 1: + { if (g_pLocalPlayer->spectator_state == g_pLocalPlayer->FIRSTPERSON) { enable = *specenable; @@ -109,8 +111,10 @@ static void spectatorUpdate() fov = *specfov; } break; + } // Disable if being spectated case 2: + { if (g_pLocalPlayer->spectator_state != g_pLocalPlayer->NONE) { enable = *specenable; @@ -118,9 +122,11 @@ static void spectatorUpdate() fov = *specfov; } }; + } } -static bool playerTeamCheck(CachedEntity *entity) +bool playerTeamCheck(CachedEntity *entity) + { return (int) teammates == 2 || (entity->m_bEnemy() && !teammates) || (!entity->m_bEnemy() && teammates) || (CE_GOOD(LOCAL_W) && LOCAL_W->m_iClassID() == CL_CLASS(CTFCrossbow) && entity->m_iHealth() < entity->m_iMaxHealth()); } @@ -128,7 +134,7 @@ static bool playerTeamCheck(CachedEntity *entity) #define GET_MIDDLE(c1, c2) (corners[c1] + corners[c2]) / 2.0f // Get all the valid aim positions -static std::vector getValidHitpoints(CachedEntity *ent, int hitbox) +std::vector getValidHitpoints(CachedEntity *ent, int hitbox) { // Recorded vischeckable points std::vector hitpoints; @@ -206,7 +212,7 @@ static std::vector getValidHitpoints(CachedEntity *ent, int hitbox) } // Get the best point to aim at for a given hitbox -static std::optional getBestHitpoint(CachedEntity *ent, int hitbox) +std::optional getBestHitpoint(CachedEntity *ent, int hitbox) { auto positions = getValidHitpoints(ent, hitbox); @@ -246,9 +252,9 @@ int GetSentry() CachedEntity *ent = ENTITY(i); if (CE_BAD(ent)) continue; - if (ent->m_Type() != ENTITY_BUILDING || ent->m_iClassID() != CL_CLASS(CObjectSentrygun)) + else if (ent->m_Type() != ENTITY_BUILDING || ent->m_iClassID() != CL_CLASS(CObjectSentrygun)) continue; - if ((CE_INT(ent, netvar.m_hBuilder) & 0xFFF) != g_pLocalPlayer->entity_idx) + else if ((CE_INT(ent, netvar.m_hBuilder) & 0xFFF) != g_pLocalPlayer->entity_idx) continue; return i; } @@ -266,7 +272,7 @@ bool shouldbacktrack_cache = false; void updateShouldBacktrack() { - if (!hacks::tf2::backtrack::backtrackEnabled() || hacks::tf2::backtrack::hasData() || projectile_mode || !(*backtrackAimbot || force_backtrack_aimbot)) + if (hacks::tf2::backtrack::hasData() || projectile_mode || !(*backtrackAimbot || force_backtrack_aimbot)) shouldbacktrack_cache = false; else shouldbacktrack_cache = true; @@ -276,9 +282,9 @@ bool shouldBacktrack(CachedEntity *ent) { if (!shouldbacktrack_cache) return false; - if (ent && ent->m_Type() != ENTITY_PLAYER) + else if (ent && ent->m_Type() != ENTITY_PLAYER) return false; - if (!tf2::backtrack::getGoodTicks(ent)) + else if (!tf2::backtrack::getGoodTicks(ent)) return false; return true; } @@ -305,12 +311,12 @@ bool validateTickFOV(tf2::backtrack::BacktrackData &tick) } // Am I holding Hitman's Heatmaker ? -static bool CarryingHeatmaker() +bool CarryingHeatmaker() { return CE_INT(LOCAL_W, netvar.iItemDefinitionIndex) == 752; } -static void doAutoZoom(bool target_found) +void doAutoZoom(bool target_found) { bool isIdle = target_found ? false : hacks::shared::followbot::isIdle(); @@ -360,209 +366,211 @@ AimbotCalculatedData_s calculated_data_array[2048]{}; // The main "loop" of the aimbot. static void CreateMove() { - enable = *normal_enable; - slow_aim = *normal_slow_aim; - fov = *normal_fov; - - spectatorUpdate(); - // Adjust for AC - if (hacks::tf2::antianticheat::enabled) - fov = std::min(fov > 0.0f ? fov : FLT_MAX, 10.0f); - - if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer() || CE_BAD(LOCAL_W)) - enable = false; - + enable = *normal_enable; + slow_aim = *normal_slow_aim; + fov = *normal_fov; aimed_this_tick = false; + bool aimkey_status = UpdateAimkey(); + + if (*specmode != 0) + spectatorUpdate(); if (!enable) { target_last = nullptr; return; } - - doAutoZoom(false); - - // TODO: Investigate this hack. Why is this necessary? - if (LOCAL_W->m_iClassID() == CL_CLASS(CTFMinigun) && CE_INT(LOCAL_E, netvar.m_iAmmo + 4) == 0) + else if (!LOCAL_E->m_bAlivePlayer()) { target_last = nullptr; return; } - // We do this as we need to pass whether the aimkey allows aiming to both - // the find target and aiming system. If we just call the func than toggle - // aimkey would break so we save it to a var to use it twice - bool aimkey_status = UpdateAimkey(); - // check if we need to run projectile Aimbot code + else if (!aimkey_status) + { + + target_last = nullptr; + return; + } + + if (hacks::tf2::antianticheat::enabled) + fov = std::min(fov > 0.0f ? fov : FLT_MAX, 10.0f); + bool should_backtrack = hacks::tf2::backtrack::backtrackEnabled(); + int get_weapon_mode = g_pLocalPlayer->weapon_mode; projectile_mode = false; projectileAimbotRequired = false; - if (projectile_aimbot && (g_pLocalPlayer->weapon_mode == weapon_projectile || g_pLocalPlayer->weapon_mode == weapon_throwable)) - projectileAimbotRequired = true; - - // Local player check + Aimkey - if (!aimkey_status || !ShouldAim()) + bool should_zoom = *auto_zoom; + switch (get_weapon_mode) { - target_last = nullptr; - return; - } - - // Refresh projectile info - if (projectileAimbotRequired) + case weapon_hitscan: { - projectile_mode = GetProjectileData(g_pLocalPlayer->weapon(), cur_proj_speed, cur_proj_grav, cur_proj_start_vel); - if (!projectile_mode) + if (should_backtrack) + updateShouldBacktrack(); + target_last = RetrieveBestTarget(aimkey_status); + if (target_last) { - target_last = nullptr; - return; + if (should_zoom) + doAutoZoom(true); + int weapon_case = LOCAL_W->m_iClassID(); + if (!hitscanSpecialCases(target_last, weapon_case)) + DoAutoshoot(target_last); } - if (proj_speed) - cur_proj_speed = *proj_speed; - if (proj_gravity) - cur_proj_grav = *proj_gravity; - if (proj_start_vel) - cur_proj_start_vel = *proj_start_vel; + break; } - - // Update backtrack status - updateShouldBacktrack(); - - // Refresh our best target - CachedEntity *target_entity = target_last = RetrieveBestTarget(aimkey_status); - if (CE_BAD(target_entity)) - return; - - // Auto-zoom - doAutoZoom(true); - - // If zoomed only is on, check if zoomed - if (zoomed_only && g_pLocalPlayer->holding_sniper_rifle) + case weapon_melee: { - if (!g_pLocalPlayer->bZoomed && !(current_user_cmd->buttons & IN_ATTACK)) - return; + if (should_backtrack) + updateShouldBacktrack(); + target_last = RetrieveBestTarget(aimkey_status); + if (target_last) + { + DoAutoshoot(target_last); + } + break; } - if (!g_IEntityList->GetClientEntity(target_entity->m_IDX)) - return; - if (!target_entity->hitboxes.GetHitbox(calculated_data_array[target_entity->m_IDX].hitbox)) - return; + case weapon_projectile: + case weapon_throwable: + { + if (projectile_aimbot) + { + projectileAimbotRequired = true; + projectile_mode = GetProjectileData(g_pLocalPlayer->weapon(), cur_proj_speed, cur_proj_grav, cur_proj_start_vel); + if (!projectile_mode) + { + target_last = nullptr; + return; + } + if (proj_speed) + cur_proj_speed = *proj_speed; + if (proj_gravity) + cur_proj_grav = *proj_gravity; + if (proj_start_vel) + cur_proj_start_vel = *proj_start_vel; + target_last = RetrieveBestTarget(aimkey_status); + if (target_last) + { + int weapon_case = g_pLocalPlayer->weapon()->m_iClassID(); + if (projectileSpecialCases(target_last, weapon_case)) + { + DoAutoshoot(target_last); + } + } + } + break; + } + } +} +bool projectileSpecialCases(CachedEntity *target_entity, int weapon_case) +{ + + switch (weapon_case) + { + case CL_CLASS(CTFCompoundBow): + { + bool release = false; + if (autoshoot) + current_user_cmd->buttons |= IN_ATTACK; + // Grab time when charge began + float begincharge = CE_FLOAT(g_pLocalPlayer->weapon(), netvar.flChargeBeginTime); + float charge = g_GlobalVars->curtime - begincharge; + if (!begincharge) + charge = 0.0f; + int damage = std::floor(50.0f + 70.0f * fminf(1.0f, charge)); + int charge_damage = std::floor(50.0f + 70.0f * fminf(1.0f, charge)) * 3.0f; + if (HasCondition(LOCAL_E) && (autoshoot || !(current_user_cmd->buttons & IN_ATTACK)) && (!wait_for_charge || (charge >= 1.0f || damage >= target_entity->m_iHealth() || charge_damage >= target_entity->m_iHealth()))) + release = true; + return release; + break; + } + case CL_CLASS(CTFCannon): + { + bool release = false; + if (autoshoot) + current_user_cmd->buttons |= IN_ATTACK; + float detonate_time = CE_FLOAT(LOCAL_W, netvar.flDetonateTime); + // Currently charging up + if (detonate_time > g_GlobalVars->curtime) + { + if (wait_for_charge) + { + // Shoot when a straight shot would result in only 100ms left on fuse upon target hit + float best_charge = PredictEntity(target_entity).DistTo(g_pLocalPlayer->v_Eye) / cur_proj_speed + 0.1; + if (detonate_time - g_GlobalVars->curtime <= best_charge) + release = true; + } + else + release = true; + } + return release; + break; + } + case CL_CLASS(CTFPipebombLauncher): + { + float chargebegin = CE_FLOAT(LOCAL_W, netvar.flChargeBeginTime); + float chargetime = g_GlobalVars->curtime - chargebegin; + + DoAutoshoot(); + bool currently_charging_pipe = false; + + // Grenade started charging + if (chargetime < 6.0f && chargetime && chargebegin) + currently_charging_pipe = true; + + // Grenade was released + if (!(current_user_cmd->buttons & IN_ATTACK) && currently_charging_pipe) + { + currently_charging_pipe = false; + Aim(target_entity); + return false; + } + break; + } + default: + return true; + } + return true; +} +int tapfire_delay = 0; +bool hitscanSpecialCases(CachedEntity *target_entity, int weapon_case) +{ + switch (weapon_case) + { + case CL_CLASS(CTFMinigun): + { + if (!minigun_tapfire) + DoAutoshoot(target_entity); + else + { + // Used to keep track of what tick we're in right now + tapfire_delay++; + + // This is the exact delay needed to hit + if (17 <= tapfire_delay || target_entity->m_flDistance() <= 1250.0f) + { + DoAutoshoot(target_entity); + tapfire_delay = 0; + } + return true; + } + return true; + break; + } + default: + return false; + } +} +bool smallBoxChecker(CachedEntity *target_entity) +{ + if (CE_BAD(target_entity) || !g_IEntityList->GetClientEntity(target_entity->m_IDX)) + return false; #if ENABLE_VISUALS if (target_entity->m_Type() == ENTITY_PLAYER) { hacks::shared::esp::SetEntityColor(target_entity, colors::target); } #endif - - // Attemt to auto-shoot - - // flNextPrimaryAttack meme - if (only_can_shoot && g_pLocalPlayer->weapon()->m_iClassID() != CL_CLASS(CTFMinigun) && g_pLocalPlayer->weapon()->m_iClassID() != CL_CLASS(CTFLaserPointer)) - { - // Handle Huntsman - if (g_pLocalPlayer->weapon()->m_iClassID() == CL_CLASS(CTFCompoundBow)) - { - bool release = false; - if (autoshoot) - current_user_cmd->buttons |= IN_ATTACK; - // Grab time when charge began - float begincharge = CE_FLOAT(g_pLocalPlayer->weapon(), netvar.flChargeBeginTime); - float charge = g_GlobalVars->curtime - begincharge; - if (!begincharge) - charge = 0.0f; - int damage = std::floor(50.0f + 70.0f * fminf(1.0f, charge)); - int charge_damage = std::floor(50.0f + 70.0f * fminf(1.0f, charge)) * 3.0f; - if (HasCondition(LOCAL_E) && (autoshoot || !(current_user_cmd->buttons & IN_ATTACK)) && (!wait_for_charge || (charge >= 1.0f || damage >= target_entity->m_iHealth() || charge_damage >= target_entity->m_iHealth()))) - release = true; - // Shoot projectile - if (release) - { - DoAutoshoot(); - Aim(target_entity); - } - } - // Loose cannon - else if (LOCAL_W->m_iClassID() == CL_CLASS(CTFCannon)) - { - // TODO: add logic for charge time - bool release = false; - if (autoshoot) - current_user_cmd->buttons |= IN_ATTACK; - float detonate_time = CE_FLOAT(LOCAL_W, netvar.flDetonateTime); - // Currently charging up - if (detonate_time > g_GlobalVars->curtime) - { - if (wait_for_charge) - { - // Shoot when a straight shot would result in only 100ms left on fuse upon target hit - float best_charge = PredictEntity(target_entity, false).DistTo(g_pLocalPlayer->v_Eye) / cur_proj_speed + 0.1; - if (detonate_time - g_GlobalVars->curtime <= best_charge) - release = true; - } - else - release = true; - } - if (release) - { - DoAutoshoot(); - Aim(target_entity); - } - } - // Not release type weapon - else if (LOCAL_W->m_iClassID() == CL_CLASS(CTFPipebombLauncher)) - { - 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 && chargebegin) - currently_charging_pipe = true; - - // Grenade was released - if (!(current_user_cmd->buttons & IN_ATTACK) && currently_charging_pipe) - { - currently_charging_pipe = false; - Aim(target_entity); - } - else - return; - - // Not release type weapon - } - else if (GetWeaponMode() == weapon_melee) - { - DoAutoshoot(); - if (g_pLocalPlayer->weapon_melee_damage_tick) - Aim(target_entity); - } - else if (CanShoot() && CE_INT(LOCAL_W, netvar.m_iClip1) != 0) - { - Aim(target_entity); - DoAutoshoot(target_entity); - } - } - else - { - Aim(target_entity); - // We should tap fire with the minigun on Bigger ranges to maximize damage, else just shoot normally - if (!minigun_tapfire || g_pLocalPlayer->weapon()->m_iClassID() != CL_CLASS(CTFMinigun)) - DoAutoshoot(target_entity); - else if (minigun_tapfire) - { - // Used to keep track of what tick we're in right now - static int tapfire_delay = 0; - tapfire_delay++; - - // This is the exact delay needed to hit - if (tapfire_delay == 17 || target_entity->m_flDistance() <= 1250.0f) - { - DoAutoshoot(target_entity); - tapfire_delay = 0; - } - } - } + return true; } - // Just hold m1 if we were aiming at something before and are in rapidfire static void CreateMoveWarp() { @@ -609,66 +617,51 @@ bool ShouldAim() if (current_user_cmd->buttons & IN_USE) return false; // Check if using action slot item - if (g_pLocalPlayer->using_action_slot_item) + else if (g_pLocalPlayer->using_action_slot_item) return false; // Using a forbidden weapon? - if (g_pLocalPlayer->weapon()->m_iClassID() == CL_CLASS(CTFKnife) || CE_INT(LOCAL_W, netvar.iItemDefinitionIndex) == 237 || CE_INT(LOCAL_W, netvar.iItemDefinitionIndex) == 265) + else if (g_pLocalPlayer->weapon()->m_iClassID() == CL_CLASS(CTFKnife) || CE_INT(LOCAL_W, netvar.iItemDefinitionIndex) == 237 || CE_INT(LOCAL_W, netvar.iItemDefinitionIndex) == 265) return false; - IF_GAME(IsTF2()) - { - // Carrying A building? - if (CE_BYTE(g_pLocalPlayer->entity, netvar.m_bCarryingObject)) - return false; - // Deadringer out? - if (CE_BYTE(g_pLocalPlayer->entity, netvar.m_bFeignDeathReady)) - return false; - // Is bonked? - if (HasCondition(g_pLocalPlayer->entity)) - return false; - // Is taunting? - if (HasCondition(g_pLocalPlayer->entity)) - return false; - // Is cloaked - if (IsPlayerInvisible(g_pLocalPlayer->entity)) - return false; - } + // Carrying A building? + else if (CE_BYTE(g_pLocalPlayer->entity, netvar.m_bCarryingObject)) + return false; + // Deadringer out? + else if (CE_BYTE(g_pLocalPlayer->entity, netvar.m_bFeignDeathReady)) + return false; + else if (g_pLocalPlayer->holding_sapper) + return false; + // Is bonked? + else if (HasCondition(g_pLocalPlayer->entity)) + return false; + // Is taunting? + else if (HasCondition(g_pLocalPlayer->entity)) + return false; + // Is cloaked + else if (IsPlayerInvisible(g_pLocalPlayer->entity)) + return false; + else if (LOCAL_W->m_iClassID() == CL_CLASS(CTFMinigun) && CE_INT(LOCAL_E, netvar.m_iAmmo + 4) == 0) + return false; #if ENABLE_VISUALS if (assistance_only && !MouseMoving()) return false; #endif - - IF_GAME(IsTF2()) + switch (GetWeaponMode()) { - switch (GetWeaponMode()) - { - case weapon_hitscan: - break; - case weapon_melee: - break; - // Check we need to run projectile Aimbot code - case weapon_projectile: - if (!projectileAimbotRequired) - return false; - break; - // Check if player doesnt have a weapon usable by aimbot - default: + case weapon_hitscan: + break; + case weapon_melee: + break; + // Check we need to run projectile Aimbot code + case weapon_projectile: + if (!projectileAimbotRequired) return false; - }; - } + break; + // Check if player doesnt have a weapon usable by aimbot + default: + return false; + }; - IF_GAME(IsTF()) - { - // Check if player is zooming - if (g_pLocalPlayer->bZoomed) - { - if (!(current_user_cmd->buttons & (IN_ATTACK | IN_ATTACK2))) - { - if (!CanHeadshot()) - return false; - } - } - } return true; } @@ -677,36 +670,35 @@ CachedEntity *RetrieveBestTarget(bool aimkey_state) { // If we have a previously chosen target, target lock is on, and the aimkey // is allowed, then attemt to keep the previous target + if (target_lock && target_last && aimkey_state) { - if (CE_GOOD(target_last)) + + if (shouldBacktrack(target_last)) { - if (shouldBacktrack(target_last)) + auto good_ticks_tmp = hacks::tf2::backtrack::getGoodTicks(target_last); + if (good_ticks_tmp) { - auto good_ticks_tmp = hacks::tf2::backtrack::getGoodTicks(target_last); - if (good_ticks_tmp) + auto good_ticks = *good_ticks_tmp; + if (backtrackLastTickOnly) { - auto good_ticks = *good_ticks_tmp; - if (backtrackLastTickOnly) - { - good_ticks.clear(); - good_ticks.push_back(good_ticks_tmp->back()); - } - for (auto &bt_tick : good_ticks) - { - if (!validateTickFOV(bt_tick)) - continue; - hacks::tf2::backtrack::MoveToTick(bt_tick); - if (IsTargetStateGood(target_last)) - return target_last; - // Restore if bad target - hacks::tf2::backtrack::RestoreEntity(target_last->m_IDX); - } + good_ticks.clear(); + good_ticks.push_back(good_ticks_tmp->back()); + } + for (auto &bt_tick : good_ticks) + { + if (!validateTickFOV(bt_tick)) + continue; + hacks::tf2::backtrack::MoveToTick(bt_tick); + if (IsTargetStateGood(target_last) && smallBoxChecker(target_last) && Aim(target_last)) + return target_last; + // Restore if bad target + hacks::tf2::backtrack::RestoreEntity(target_last->m_IDX); } } // Check if previous target is still good - else if (!shouldbacktrack_cache && IsTargetStateGood(target_last)) + else if (!shouldbacktrack_cache && IsTargetStateGood(target_last) && smallBoxChecker(target_last) && Aim(target_last)) { // If it is then return it again return target_last; @@ -718,7 +710,7 @@ CachedEntity *RetrieveBestTarget(bool aimkey_state) float target_highest_score, scr = 0.0f; CachedEntity *ent; - CachedEntity *target_highest_ent = 0; + CachedEntity *target_highest_ent = nullptr; target_highest_score = -256; std::optional bt_tick = std::nullopt; for (int i = 1; i <= HIGHEST_ENTITY; i++) @@ -746,7 +738,7 @@ CachedEntity *RetrieveBestTarget(bool aimkey_state) if (!validateTickFOV(bt_tick)) continue; hacks::tf2::backtrack::MoveToTick(bt_tick); - if (IsTargetStateGood(ent)) + if (IsTargetStateGood(ent) && smallBoxChecker(ent) && Aim(ent)) { isTargetGood = true; temp_bt_tick = bt_tick; @@ -757,7 +749,10 @@ CachedEntity *RetrieveBestTarget(bool aimkey_state) } } else - isTargetGood = IsTargetStateGood(ent); + { + if (IsTargetStateGood(ent) && smallBoxChecker(ent) && Aim(ent)) + isTargetGood = true; + } if (isTargetGood) { // Distance Priority, Uses this is melee is used @@ -768,20 +763,30 @@ CachedEntity *RetrieveBestTarget(bool aimkey_state) switch ((int) priority_mode) { case 0: // Smart Priority + { scr = GetScoreForEntity(ent); break; + } case 1: // Fov Priority + { scr = 360.0f - calculated_data_array[ent->m_IDX].fov; break; + } case 3: // Health Priority (Lowest) + { scr = 450.0f - ent->m_iHealth(); break; + } case 4: // Distance Priority (Furthest Away) + { scr = calculated_data_array[i].aim_position.DistTo(g_pLocalPlayer->v_Eye); break; + } case 5: // Health Priority (Highest) + { scr = ent->m_iHealth() * 4; break; + } default: break; } @@ -815,42 +820,32 @@ bool IsTargetStateGood(CachedEntity *entity) { PROF_SECTION(PT_aimbot_targetstatecheck); - // Checks for Players - if (entity->m_Type() == ENTITY_PLAYER) + const int current_type = entity->m_Type(); + switch (current_type) + { + + case (ENTITY_PLAYER): { // Local player check if (entity == LOCAL_E) return false; // Dead - if (!entity->m_bAlivePlayer()) + else if (!entity->m_bAlivePlayer()) return false; // Teammates - if (!playerTeamCheck(entity)) + else if (!playerTeamCheck(entity)) + return false; + else if (!player_tools::shouldTarget(entity)) + return false; + // Invulnerable players, ex: uber, bonk + else if (IsPlayerInvulnerable(entity)) return false; // Distance - if (EffectiveTargetingRange()) - { - if (g_pLocalPlayer->weapon_mode != weapon_melee) - { - if (entity->m_flDistance() > EffectiveTargetingRange() && tickcount > hacks::shared::aimbot::last_target_ignore_timer) - return false; - } - else - { - float swingrange = EffectiveTargetingRange(); - int hb = BestHitbox(entity); - if (hb == -1) - return false; - Vector newangle = GetAimAtAngles(g_pLocalPlayer->v_Eye, entity->hitboxes.GetHitbox(hb)->center, LOCAL_E); - trace_t trace; - Ray_t ray; - trace::filter_default.SetSelf(RAW_ENT(g_pLocalPlayer->entity)); - ray.Init(g_pLocalPlayer->v_Eye, GetForwardVector(g_pLocalPlayer->v_Eye, newangle, swingrange, LOCAL_E)); - g_ITrace->TraceRay(ray, MASK_SHOT_HULL, &trace::filter_default, &trace); - if ((IClientEntity *) trace.m_pEnt != RAW_ENT(entity)) - return false; - } - } + + float targeting_range = EffectiveTargetingRange(); + if (entity->m_flDistance() > targeting_range && tickcount > hacks::shared::aimbot::last_target_ignore_timer) + return false; + // Rage only check if (rageonly) { @@ -859,133 +854,106 @@ bool IsTargetStateGood(CachedEntity *entity) return false; } } - IF_GAME(IsTF()) + + // don't aim if holding sapper + + // Wait for charge + if (wait_for_charge && g_pLocalPlayer->holding_sniper_rifle) { - // don't aim if holding sapper - if (g_pLocalPlayer->holding_sapper) - return false; - - // Wait for charge - if (wait_for_charge && g_pLocalPlayer->holding_sniper_rifle) + float cdmg = CE_FLOAT(LOCAL_W, netvar.flChargedDamage) * 3; + float maxhs = 450.0f; + if (CE_INT(LOCAL_W, netvar.iItemDefinitionIndex) == 230 || HasCondition(entity)) { - float cdmg = CE_FLOAT(LOCAL_W, netvar.flChargedDamage) * 3; - float maxhs = 450.0f; - if (CE_INT(LOCAL_W, netvar.iItemDefinitionIndex) == 230 || HasCondition(entity)) - { - cdmg = int(CE_FLOAT(LOCAL_W, netvar.flChargedDamage) * 1.35f); - maxhs = 203.0f; - } - bool maxCharge = cdmg >= maxhs; - - // Darwins damage correction, Darwins protects against 15% of - // damage - // if (HasDarwins(entity)) - // cdmg = (cdmg * .85) - 1; - // Vaccinator damage correction, Vac charge protects against 75% - // of damage - if (HasCondition(entity)) - { - cdmg = (cdmg * .25) - 1; - // Passive bullet resist protects against 10% of damage - } - else if (HasCondition(entity)) - { - cdmg = (cdmg * .90) - 1; - } - // Invis damage correction, Invis spies get protection from 10% - // of damage - if (IsPlayerInvisible(entity)) - cdmg = (cdmg * .80) - 1; - - // Check if player will die from headshot or if target has more - // than 450 health and sniper has max chage - float hsdmg = 150.0f; - if (CE_INT(LOCAL_W, netvar.iItemDefinitionIndex) == 230) - hsdmg = int(50.0f * 1.35f); - if (!(entity->m_iHealth() <= hsdmg || entity->m_iHealth() <= cdmg || !g_pLocalPlayer->bZoomed || (maxCharge && entity->m_iHealth() > maxhs))) - { - return false; - } + cdmg = int(CE_FLOAT(LOCAL_W, netvar.flChargedDamage) * 1.35f); + maxhs = 203.0f; } + bool maxCharge = cdmg >= maxhs; - // Some global checks - if (!player_tools::shouldTarget(entity)) - return false; - // Invulnerable players, ex: uber, bonk - if (IsPlayerInvulnerable(entity)) - return false; - // cloaked/deadringed players - if (ignore_cloak || ignore_deadringer) + // Darwins damage correction, Darwins protects against 15% of + // damage + // if (HasDarwins(entity)) + // cdmg = (cdmg * .85) - 1; + // Vaccinator damage correction, Vac charge protects against 75% + // of damage + if (IsPlayerInvisible(entity)) + cdmg = (cdmg * .80) - 1; + + else if (HasCondition(entity)) { - if (IsPlayerInvisible(entity)) - { - // Item id for deadringer is 59 as of time of creation - if (HasWeapon(entity, 59)) - { - if (ignore_deadringer) - return false; - } - else - { - if (ignore_cloak && !(HasCondition(entity)) && !(HasCondition(entity))) - return false; - } - } + cdmg = (cdmg * .25) - 1; + // Passive bullet resist protects against 10% of damage } - // Vaccinator - if (ignore_vaccinator && IsPlayerResistantToCurrentWeapon(entity)) + else if (HasCondition(entity)) + { + cdmg = (cdmg * .90) - 1; + } + // Invis damage correction, Invis spies get protection from 10% + // of damage + + // Check if player will die from headshot or if target has more + // than 450 health and sniper has max chage + float hsdmg = 150.0f; + if (CE_INT(LOCAL_W, netvar.iItemDefinitionIndex) == 230) + hsdmg = int(50.0f * 1.35f); + + int health = entity->m_iHealth(); + if (!(health <= hsdmg || health <= cdmg || !g_pLocalPlayer->bZoomed || (maxCharge && health > maxhs))) + { return false; + } } - // Preform hitbox prediction - int hitbox = BestHitbox(entity); - // Bad hitbox - if (hitbox == -1) + // Some global checks + + // cloaked/deadringed players + if (ignore_cloak || ignore_deadringer) + { + if (IsPlayerInvisible(entity)) + { + // Item id for deadringer is 59 as of time of creation + if (HasWeapon(entity, 59)) + { + if (ignore_deadringer) + return false; + } + else + { + if (ignore_cloak && !(HasCondition(entity)) && !(HasCondition(entity))) + return false; + } + } + } + // Vaccinator + if (ignore_vaccinator && IsPlayerResistantToCurrentWeapon(entity)) return false; + AimbotCalculatedData_s &cd = calculated_data_array[entity->m_IDX]; - cd.hitbox = hitbox; - - // Vis check + fov check - if (!VischeckPredictedEntity(entity)) - return false; - if (LOCAL_W->m_iClassID() == CL_CLASS(CTFLaserPointer)) - { - int sentry = GetSentry(); - if (sentry == -1) - return false; - Vector pos = GetBuildingPosition(ENTITY(sentry)); - if (hitbox == -1 || !entity->hitboxes.GetHitbox(cd.hitbox)) - return false; - if (!IsVectorVisible(pos, entity->hitboxes.GetHitbox(cd.hitbox)->center, false, ENTITY(sentry))) - return false; - } - if (fov > 0.0f && cd.fov > fov && tickcount > hacks::shared::aimbot::last_target_ignore_timer) - return false; - + cd.hitbox = BestHitbox(entity); return true; + break; } // Check for buildings - else if (entity->m_Type() == ENTITY_BUILDING) + case (ENTITY_BUILDING): { // Don't aim if holding sapper if (g_pLocalPlayer->holding_sapper) return false; // Enabled check - if (!(buildings_other || buildings_sentry)) + else if (!(buildings_other || buildings_sentry)) return false; // Teammates, Even with friendly fire enabled, buildings can NOT be // damaged - if (!entity->m_bEnemy()) + else if (!entity->m_bEnemy()) return false; // Distance - if (EffectiveTargetingRange()) + else if (EffectiveTargetingRange()) { if (entity->m_flDistance() > (int) EffectiveTargetingRange() && tickcount > hacks::shared::aimbot::last_target_ignore_timer) return false; } // Building type - if (!(buildings_other && buildings_sentry)) + else if (!(buildings_other && buildings_sentry)) { // Check if target is a sentrygun if (entity->m_iClassID() == CL_CLASS(CObjectSentrygun)) @@ -1002,73 +970,55 @@ bool IsTargetStateGood(CachedEntity *entity) } // Grab the prediction var - AimbotCalculatedData_s &cd = calculated_data_array[entity->m_IDX]; - - // Vis and fov checks - if (!VischeckPredictedEntity(entity)) - return false; - if (LOCAL_W->m_iClassID() == CL_CLASS(CTFLaserPointer)) - { - int sentry = GetSentry(); - if (sentry == -1) - return false; - Vector pos = GetBuildingPosition(ENTITY(sentry)); - if (!IsVectorVisible(pos, GetBuildingPosition(entity), false, ENTITY(sentry))) - return false; - } - if (fov > 0.0f && cd.fov > fov && tickcount > hacks::shared::aimbot::last_target_ignore_timer) - return false; + // Vis and fov check return true; } - // NPCs (Skeletons, Merasmus, etc) - else if (entity->m_Type() == ENTITY_NPC) + case (ENTITY_NPC): { + // NPCs (Skeletons, Merasmus, etc) + // Sapper aimbot? no. if (g_pLocalPlayer->holding_sapper) return false; // NPC targeting is disabled - if (!npcs) + else if (!npcs) return false; // Cannot shoot this - if (entity->m_iTeam() == LOCAL_E->m_iTeam()) + else if (entity->m_iTeam() == LOCAL_E->m_iTeam()) return false; // Distance - if (EffectiveTargetingRange()) - { - if (entity->m_flDistance() > (int) EffectiveTargetingRange() && tickcount > hacks::shared::aimbot::last_target_ignore_timer) - return false; - } + float targeting_range = EffectiveTargetingRange(); + + if (entity->m_flDistance() > targeting_range && tickcount > hacks::shared::aimbot::last_target_ignore_timer) + return false; // Grab the prediction var - AimbotCalculatedData_s &cd = calculated_data_array[entity->m_IDX]; - if (!VischeckPredictedEntity(entity)) - return false; - if (fov > 0.0f && cd.fov > fov && tickcount > hacks::shared::aimbot::last_target_ignore_timer) - return false; return true; + break; + } + default: + break; } // Check for stickybombs - else if (entity->m_iClassID() == CL_CLASS(CTFGrenadePipebombProjectile)) + if (entity->m_iClassID() == CL_CLASS(CTFGrenadePipebombProjectile)) { // Enabled if (!stickybot) return false; // Only hitscan weapons can break stickys so check for them. - if (!(GetWeaponMode() == weapon_hitscan || GetWeaponMode() == weapon_melee)) + else if (!(GetWeaponMode() == weapon_hitscan || GetWeaponMode() == weapon_melee)) return false; // Distance - if (EffectiveTargetingRange()) - { - if (entity->m_flDistance() > (int) EffectiveTargetingRange()) - return false; - } + float targeting_range = EffectiveTargetingRange(); + if (entity->m_flDistance() > targeting_range) + return false; // Teammates, Even with friendly fire enabled, stickys can NOT be // destroied @@ -1080,50 +1030,44 @@ bool IsTargetStateGood(CachedEntity *entity) return false; // Moving Sticky? - Vector velocity; + Vector velocity; velocity::EstimateAbsVelocity(RAW_ENT(entity), velocity); if (!velocity.IsZero()) return false; // Grab the prediction var - AimbotCalculatedData_s &cd = calculated_data_array[entity->m_IDX]; // Vis and fov check - if (!VischeckPredictedEntity(entity)) - return false; - if (LOCAL_W->m_iClassID() == CL_CLASS(CTFLaserPointer)) - { - int sentry = GetSentry(); - if (sentry == -1) - return false; - Vector pos = GetBuildingPosition(ENTITY(sentry)); - if (!IsVectorVisible(pos, entity->m_vecOrigin(), false)) - return false; - } - if (fov > 0.0f && cd.fov > fov) - return false; return true; } - else - { - // Target not valid - return false; - } + + return false; } // A function to aim at a specific entitiy -void Aim(CachedEntity *entity) +bool Aim(CachedEntity *entity) { if (*miss_chance > 0 && UniformRandomInt(0, 99) < *miss_chance) - return; - - // Dont aim at a bad entity - if (CE_BAD(entity)) - return; + return true; // Get angles from eye to target - Vector angles = GetAimAtAngles(g_pLocalPlayer->v_Eye, PredictEntity(entity, false), LOCAL_E); + Vector is_it_good = PredictEntity(entity); + bool should_aim; + trace_t test_trace; + if (extrapolate || projectileAimbotRequired || entity->m_Type() != ENTITY_PLAYER) + should_aim = IsEntityVectorVisible(entity, is_it_good, true); + else + { + should_aim = IsEntityVectorVisible(entity, is_it_good, false); + } + if (!should_aim) + return false; + + AimbotCalculatedData_s &cd = calculated_data_array[entity->m_IDX]; + if (cd.fov > fov) + return false; + Vector angles = GetAimAtAngles(g_pLocalPlayer->v_Eye, is_it_good, LOCAL_E); // Slow aim if (slow_aim) @@ -1139,9 +1083,9 @@ void Aim(CachedEntity *entity) current_user_cmd->tick_count = TIME_TO_TICKS(CE_FLOAT(entity, netvar.m_flSimulationTime)); aimed_this_tick = true; viewangles_this_tick = angles; - + logging::Info("IT RAN"); // Finish function - return; + return true; } // A function to check whether player can autoshoot @@ -1152,7 +1096,7 @@ void DoAutoshoot(CachedEntity *target_entity) // Enable check if (!autoshoot) return; - if (IsPlayerDisguised(g_pLocalPlayer->entity) && !autoshoot_disguised) + else if (IsPlayerDisguised(g_pLocalPlayer->entity) && !autoshoot_disguised) return; // Handle Huntsman/Loose cannon if (g_pLocalPlayer->weapon()->m_iClassID() == CL_CLASS(CTFCompoundBow) || g_pLocalPlayer->weapon()->m_iClassID() == CL_CLASS(CTFCannon)) @@ -1199,27 +1143,23 @@ void DoAutoshoot(CachedEntity *target_entity) bool attack = true; // Rifle check - IF_GAME(IsTF()) + + if (g_pLocalPlayer->clazz == tf_class::tf_sniper) { - if (g_pLocalPlayer->clazz == tf_class::tf_sniper) + if (g_pLocalPlayer->holding_sniper_rifle) { - if (g_pLocalPlayer->holding_sniper_rifle) - { - if (zoomed_only && !CanHeadshot()) - attack = false; - } + if (zoomed_only && !CanHeadshot()) + attack = false; } } // Ambassador check - IF_GAME(IsTF2()) + + if (IsAmbassador(g_pLocalPlayer->weapon())) { - if (IsAmbassador(g_pLocalPlayer->weapon())) - { - // Check if ambasador can headshot - if (!AmbassadorCanHeadshot() && wait_for_charge) - attack = false; - } + // Check if ambasador can headshot + if (!AmbassadorCanHeadshot() && wait_for_charge) + attack = false; } // Autoshoot breaks with Slow aimbot, so use a workaround to detect when it @@ -1248,18 +1188,20 @@ void DoAutoshoot(CachedEntity *target_entity) } // Grab a vector for a specific ent -Vector PredictEntity(CachedEntity *entity, bool vischeck) +Vector PredictEntity(CachedEntity *entity) { // Pull out predicted data AimbotCalculatedData_s &cd = calculated_data_array[entity->m_IDX]; Vector &result = cd.aim_position; - if (cd.predict_tick == tickcount && cd.predict_type == vischeck && !shouldBacktrack(entity)) - return result; + const short int curr_type = entity->m_Type(); // Players - if ((entity->m_Type() == ENTITY_PLAYER)) + + // If using projectiles, predict a vector + switch (curr_type) + { + case ENTITY_PLAYER: { - // If using projectiles, predict a vector if (projectileAimbotRequired) { std::pair tmp_result; @@ -1270,10 +1212,7 @@ Vector PredictEntity(CachedEntity *entity, bool vischeck) tmp_result = ProjectilePrediction(entity, cd.hitbox, cur_proj_speed, cur_proj_grav, PlayerGravityMod(entity), cur_proj_start_vel); // Don't use the intial velocity compensated one in vischecks - if (vischeck) - result = tmp_result.first; - else - result = tmp_result.second; + result = tmp_result.second; } else { @@ -1291,9 +1230,10 @@ Vector PredictEntity(CachedEntity *entity, bool vischeck) GetHitbox(entity, cd.hitbox, result); } } + break; } - // Buildings - else if (entity->m_Type() == ENTITY_BUILDING) + // Buildings + case ENTITY_BUILDING: { if (projectileAimbotRequired) { @@ -1301,34 +1241,128 @@ Vector PredictEntity(CachedEntity *entity, bool vischeck) tmp_result = BuildingPrediction(entity, GetBuildingPosition(entity), cur_proj_speed, cur_proj_grav, cur_proj_start_vel); // Don't use the intial velocity compensated one in vischecks - if (vischeck) - result = tmp_result.first; - else - result = tmp_result.second; + result = tmp_result.second; } else + { result = GetBuildingPosition(entity); + } + break; } - // NPCs (Skeletons, merasmus, etc) - else if (entity->m_Type() == ENTITY_NPC) + // NPCs (Skeletons, merasmus, etc) + case ENTITY_NPC: { result = entity->hitboxes.GetHitbox(std::max(0, entity->hitboxes.GetNumHitboxes() / 2 - 1))->center; + break; } - // Other - else + + // Other + default: { result = entity->m_vecOrigin(); + break; + } } - cd.predict_tick = tickcount; - cd.predict_type = vischeck; - - cd.fov = GetFov(g_pLocalPlayer->v_OrigViewangles, g_pLocalPlayer->v_Eye, result); + cd.fov = GetFov(g_pLocalPlayer->v_OrigViewangles, g_pLocalPlayer->v_Eye, result); // Return the found vector return result; } +int notVisibleHitbox(CachedEntity *target, int preferred) +{ + if (target->hitboxes.VisibilityCheck(preferred)) + return preferred; + // Else attempt to find any hitbox at all + else + return hitbox_t::spine_1; +} +int auto_hitbox(CachedEntity *target) +{ + int preferred = 3; + int target_health = target->m_iHealth(); // This was used way too many times. Due to how pointers work (defrencing)+the compiler already dealing with tons of AIDS global variables it likely derefrenced it every time it was called. + int ci = LOCAL_W->m_iClassID(); + + if (CanHeadshot()) // Nothing else zooms in this game you have to be holding a rifle for this to be true. + { + float cdmg = CE_FLOAT(LOCAL_W, netvar.flChargedDamage); + float bdmg = 50; + // Vaccinator damage correction, protects against 20% of damage + if (CarryingHeatmaker()) + { + bdmg = (bdmg * .80) - 1; + cdmg = (cdmg * .80) - 1; + } + // Vaccinator damage correction, protects against 75% of damage + if (HasCondition(target)) + { + bdmg = (bdmg * .25) - 1; + cdmg = (cdmg * .25) - 1; + } + // Passive bullet resist protects against 10% of damage + else if (HasCondition(target)) + { + bdmg = (bdmg * .90) - 1; + cdmg = (cdmg * .90) - 1; + } + // Invis damage correction, Invis spies get protection from 10% + // of damage + else if (IsPlayerInvisible(target)) // You can't be invisible and under the effects of the vacc + { + bdmg = (bdmg * .80) - 1; + cdmg = (cdmg * .80) - 1; + } + // If can headshot and if bodyshot kill from charge damage, or + // if crit boosted and they have 150 health, or if player isnt + // zoomed, or if the enemy has less than 40, due to darwins, and + // only if they have less than 150 health will it try to + // bodyshot + if (std::floor(cdmg) >= target_health || IsPlayerCritBoosted(g_pLocalPlayer->entity) || (target_health <= std::floor(bdmg) && target_health <= 150)) + { + // We dont need to hit the head as a bodyshot will kill + preferred = hitbox_t::spine_1; + return preferred; + } + + return hitbox_t::head; + } + + // Hunstman + else if (ci == CL_CLASS(CTFCompoundBow)) + { + float begincharge = CE_FLOAT(g_pLocalPlayer->weapon(), netvar.flChargeBeginTime); + float charge = g_GlobalVars->curtime - begincharge; + int damage = std::floor(50.0f + 70.0f * fminf(1.0f, charge)); + if (damage >= target_health) + return hitbox_t::spine_1; + else + return hitbox_t::head; + } + + // Ambassador + else if (IsAmbassador(g_pLocalPlayer->weapon())) + { + + // 18 health is a good number to use as thats the usual minimum + // damage it can do with a bodyshot, but damage could + // potentially be higher + + if (target_health <= 18 || IsPlayerCritBoosted(g_pLocalPlayer->entity) || target->m_flDistance() > 1200) + return hitbox_t::spine_1; + else if (AmbassadorCanHeadshot()) + return hitbox_t::head; + } + + // Rockets and stickies should aim at the foot if the target is on the ground + else if (ci == CL_CLASS(CTFPipebombLauncher) || ci == CL_CLASS(CTFRocketLauncher) || ci == CL_CLASS(CTFParticleCannon) || ci == CL_CLASS(CTFRocketLauncher_AirStrike) || ci == CL_CLASS(CTFRocketLauncher_Mortar) || ci == CL_CLASS(CTFRocketLauncher_DirectHit)) + { + bool ground = CE_INT(target, netvar.iFlags) & (1 << 0); + if (ground) + preferred = notVisibleHitbox(target, hitbox_t::foot_L); // Only time it is worth the penalty + } + return preferred; +} // A function to find the best hitbox for a target int BestHitbox(CachedEntity *target) { @@ -1336,114 +1370,9 @@ int BestHitbox(CachedEntity *target) switch (*hitbox_mode) { case 0: - { // AUTO priority - int preferred = int(hitbox); - bool headonly = false; // Var to keep if we can bodyshot - - IF_GAME(IsTF()) - { - int ci = g_pLocalPlayer->weapon()->m_iClassID(); - preferred = hitbox_t::spine_3; - - // Sniper rifle - if (g_pLocalPlayer->holding_sniper_rifle) - headonly = CanHeadshot(); - - // Hunstman - else if (ci == CL_CLASS(CTFCompoundBow)) - { - float begincharge = CE_FLOAT(g_pLocalPlayer->weapon(), netvar.flChargeBeginTime); - float charge = g_GlobalVars->curtime - begincharge; - int damage = std::floor(50.0f + 70.0f * fminf(1.0f, charge)); - if (damage >= target->m_iHealth()) - preferred = hitbox_t::spine_3; - else - preferred = hitbox_t::head; - } - - // Ambassador - else if (IsAmbassador(g_pLocalPlayer->weapon())) - { - headonly = AmbassadorCanHeadshot(); - // 18 health is a good number to use as thats the usual minimum - // damage it can do with a bodyshot, but damage could - // potentially be higher - if (target->m_iHealth() <= 18 || IsPlayerCritBoosted(g_pLocalPlayer->entity) || target->m_flDistance() > 1200) - headonly = false; - } - - // Rockets and stickies should aim at the foot if the target is on the ground - else if (ci == CL_CLASS(CTFPipebombLauncher) || ci == CL_CLASS(CTFRocketLauncher) || ci == CL_CLASS(CTFParticleCannon) || ci == CL_CLASS(CTFRocketLauncher_AirStrike) || ci == CL_CLASS(CTFRocketLauncher_Mortar) || ci == CL_CLASS(CTFRocketLauncher_DirectHit)) - { - bool ground = CE_INT(target, netvar.iFlags) & (1 << 0); - if (ground) - preferred = hitbox_t::foot_L; - } - - // Bodyshot handling - if (g_pLocalPlayer->holding_sniper_rifle) - { - float cdmg = CE_FLOAT(LOCAL_W, netvar.flChargedDamage); - float bdmg = 50; - // Vaccinator damage correction, protects against 20% of damage - if (CarryingHeatmaker()) - { - bdmg = (bdmg * .80) - 1; - cdmg = (cdmg * .80) - 1; - } - // Vaccinator damage correction, protects against 75% of damage - if (HasCondition(target)) - { - bdmg = (bdmg * .25) - 1; - cdmg = (cdmg * .25) - 1; - } - // Passive bullet resist protects against 10% of damage - else if (HasCondition(target)) - { - bdmg = (bdmg * .90) - 1; - cdmg = (cdmg * .90) - 1; - } - // Invis damage correction, Invis spies get protection from 10% - // of damage - if (IsPlayerInvisible(target)) - { - bdmg = (bdmg * .80) - 1; - cdmg = (cdmg * .80) - 1; - } - // If can headshot and if bodyshot kill from charge damage, or - // if crit boosted and they have 150 health, or if player isnt - // zoomed, or if the enemy has less than 40, due to darwins, and - // only if they have less than 150 health will it try to - // bodyshot - if (CanHeadshot() && (std::floor(cdmg) >= target->m_iHealth() || IsPlayerCritBoosted(g_pLocalPlayer->entity) || !g_pLocalPlayer->bZoomed || target->m_iHealth() <= std::floor(bdmg)) && target->m_iHealth() <= 150) - { - // We dont need to hit the head as a bodyshot will kill - preferred = hitbox_t::spine_1; - headonly = false; - } - } - } - // In counter-strike source, headshots are what we want - else IF_GAME(IsCSS()) headonly = true; - - // Head only - if (headonly) - { - IF_GAME(IsTF()) - return hitbox_t::head; - IF_GAME(IsCSS()) - return 12; - } - - // preferred hitbox - if (target->hitboxes.VisibilityCheck(preferred)) - return preferred; - // Else attempt to find any hitbox at all - for (int i = 6; i > projectile_mode ? 1 : 0 && i < 6; i--) - if (target->hitboxes.VisibilityCheck(i)) - return i; - } - break; + // AUTO priority + return auto_hitbox(target); + break; case 1: { // AUTO priority, return closest hitbox to crosshair return ClosestHitbox(target); @@ -1483,27 +1412,6 @@ int ClosestHitbox(CachedEntity *target) return closest; } -// Function to get predicted visual checks -bool VischeckPredictedEntity(CachedEntity *entity) -{ - // Retrieve predicted data - AimbotCalculatedData_s &cd = calculated_data_array[entity->m_IDX]; - if (cd.vcheck_tick == tickcount && !shouldBacktrack(entity)) - return cd.visible; - // Update info - cd.vcheck_tick = tickcount; - if (extrapolate || projectileAimbotRequired || entity->m_Type() != ENTITY_PLAYER) - cd.visible = IsEntityVectorVisible(entity, PredictEntity(entity, true), true); - else - { - trace_t trace; - cd.visible = IsEntityVectorVisible(entity, PredictEntity(entity, true), false, MASK_SHOT, &trace); - if (cd.visible && cd.hitbox == head && trace.hitbox != head) - cd.visible = false; - } - return cd.visible; -} - // A helper function to find a user angle that isnt directly on the target // angle, effectively slowing the aiming process void DoSlowAim(Vector &input_angle) @@ -1589,9 +1497,9 @@ float EffectiveTargetingRange() { if (GetWeaponMode() == weapon_melee) return (float) re::C_TFWeaponBaseMelee::GetSwingRange(RAW_ENT(LOCAL_W)); - if (g_pLocalPlayer->weapon()->m_iClassID() == CL_CLASS(CTFFlameThrower)) + else if (LOCAL_W->m_iClassID() == CL_CLASS(CTFFlameThrower)) return 310.0f; // Pyros only have so much until their flames hit - if (g_pLocalPlayer->weapon()->m_iClassID() == CL_CLASS(CTFWeaponFlameBall)) + else if (LOCAL_W->m_iClassID() == CL_CLASS(CTFWeaponFlameBall)) return 512.0f; // Dragons Fury is fast but short range return (float) max_range; @@ -1683,4 +1591,4 @@ static InitRoutine EC( #endif }); -} // namespace hacks::shared::aimbot +} // namespace hacks::shared::aimbot \ No newline at end of file