From 86f854dac62731e2e4bc916c24fdc2a3096174af Mon Sep 17 00:00:00 2001 From: LightCat Date: Sat, 15 Sep 2018 16:52:09 +0200 Subject: [PATCH] Start Converting CreateMove's --- include/hacks/AutoJoin.hpp | 1 - include/hacks/ESP.hpp | 1 - include/hacks/FollowBot.hpp | 1 - include/hacks/NavBot.hpp | 1 - include/hacks/Walkbot.hpp | 1 - include/hoovy.hpp | 1 - include/navparser.hpp | 1 - src/hacks/AutoJoin.cpp | 33 +- src/hacks/ESP.cpp | 102 ++--- src/hacks/FollowBot.cpp | 605 ++++++++++++------------- src/hacks/NavBot.cpp | 862 ++++++++++++++++++------------------ src/hacks/Walkbot.cpp | 127 +++--- src/hooks/CreateMove.cpp | 45 +- src/hoovy.cpp | 37 +- src/navparser.cpp | 142 +++--- 15 files changed, 974 insertions(+), 986 deletions(-) mode change 100755 => 100644 src/hoovy.cpp diff --git a/include/hacks/AutoJoin.hpp b/include/hacks/AutoJoin.hpp index dbe5a360..9d1ab82e 100644 --- a/include/hacks/AutoJoin.hpp +++ b/include/hacks/AutoJoin.hpp @@ -9,7 +9,6 @@ #include "common.hpp" namespace hacks::shared::autojoin { -void update(); void updateSearch(); void onShutdown(); } // namespace hacks::shared::autojoin diff --git a/include/hacks/ESP.hpp b/include/hacks/ESP.hpp index 2f42f43c..f759e4a9 100644 --- a/include/hacks/ESP.hpp +++ b/include/hacks/ESP.hpp @@ -38,7 +38,6 @@ public: void Init(); extern std::array data; -void CreateMove(); void Draw(); // Entity Processing diff --git a/include/hacks/FollowBot.hpp b/include/hacks/FollowBot.hpp index d2dd196c..000dc7c0 100644 --- a/include/hacks/FollowBot.hpp +++ b/include/hacks/FollowBot.hpp @@ -11,7 +11,6 @@ namespace hacks::shared::followbot { void DrawTick(); -void WorldTick(); int ClassPriority(CachedEntity *ent); bool isEnabled(); diff --git a/include/hacks/NavBot.hpp b/include/hacks/NavBot.hpp index ce4ade47..5536157f 100644 --- a/include/hacks/NavBot.hpp +++ b/include/hacks/NavBot.hpp @@ -9,5 +9,4 @@ namespace hacks::tf2::NavBot { void Init(); void initonce(); -void CreateMove(); } // namespace hacks::tf2::NavBot \ No newline at end of file diff --git a/include/hacks/Walkbot.hpp b/include/hacks/Walkbot.hpp index ff75b245..e5dc3eee 100644 --- a/include/hacks/Walkbot.hpp +++ b/include/hacks/Walkbot.hpp @@ -16,6 +16,5 @@ void Initialize(); #if ENABLE_VISUALS void Draw(); #endif -void Move(); void OnLevelInit(); } // namespace hacks::shared::walkbot diff --git a/include/hoovy.hpp b/include/hoovy.hpp index b9b52259..b33343ed 100755 --- a/include/hoovy.hpp +++ b/include/hoovy.hpp @@ -9,5 +9,4 @@ class CachedEntity; -void UpdateHoovyList(); bool IsHoovy(CachedEntity *entity); diff --git a/include/navparser.hpp b/include/navparser.hpp index 2e45065f..04efb3f7 100644 --- a/include/navparser.hpp +++ b/include/navparser.hpp @@ -22,7 +22,6 @@ bool NavTo(Vector dest, bool navToLocalCenter = true, bool persistent = true, void clearInstructions(); int findClosestNavSquare(Vector vec); bool Prepare(); -void CreateMove(); void Draw(); int FindInVector(size_t id); diff --git a/src/hacks/AutoJoin.cpp b/src/hacks/AutoJoin.cpp index 8804d14e..8f69c9bc 100644 --- a/src/hacks/AutoJoin.cpp +++ b/src/hacks/AutoJoin.cpp @@ -6,6 +6,7 @@ */ #include +#include "HookTools.hpp" #include #include "common.hpp" @@ -157,26 +158,26 @@ void updateSearch() } #endif } - -void update() -{ +static HookedFunction + update(HookedFunctions_types::HF_CreateMove, "Autojoin", 1, []() { #if !LAGBOT_MODE - if (autoteam_timer.test_and_set(500)) - { - if (autojoin_team and UnassignedTeam()) + if (autoteam_timer.test_and_set(500)) { - hack::ExecuteCommand("autoteam"); + if (autojoin_team and UnassignedTeam()) + { + hack::ExecuteCommand("autoteam"); + } + else if (autojoin_class and UnassignedClass()) + { + if (int(autojoin_class) < 10) + g_IEngine->ExecuteClientCmd( + format("join_class ", + classnames[int(autojoin_class) - 1]) + .c_str()); + } } - else if (autojoin_class and UnassignedClass()) - { - if (int(autojoin_class) < 10) - g_IEngine->ExecuteClientCmd( - format("join_class ", classnames[int(autojoin_class) - 1]) - .c_str()); - } - } #endif -} + }); void onShutdown() { diff --git a/src/hacks/ESP.cpp b/src/hacks/ESP.cpp index 9c865ea6..2f158a28 100644 --- a/src/hacks/ESP.cpp +++ b/src/hacks/ESP.cpp @@ -247,64 +247,66 @@ void Draw() } // Function called on create move -void CreateMove() -{ +static HookedFunction + CreateMove(HookedFunctions_types::HF_CreateMove, "ESP", 18, []() { + // Check usersettings if enabled + if (!*enable) + return; + if (CE_BAD(LOCAL_E)) + return; + // Something + std::lock_guard esp_lock(threadsafe_mutex); - // Check usersettings if enabled - if (!*enable) - return; + ResetEntityStrings(); // Clear any strings entities have + entities_need_repaint + .clear(); // Clear data on entities that need redraw + int max_clients = g_IEngine->GetMaxClients(); + int limit = HIGHEST_ENTITY; - // Something - std::lock_guard esp_lock(threadsafe_mutex); + // If not using any other special esp, we lower the min to the max + // clients + if (!buildings && !proj_esp && !item_esp) + limit = std::min(max_clients, HIGHEST_ENTITY); - ResetEntityStrings(); // Clear any strings entities have - entities_need_repaint.clear(); // Clear data on entities that need redraw - int max_clients = g_IEngine->GetMaxClients(); - int limit = HIGHEST_ENTITY; - - // If not using any other special esp, we lower the min to the max clients - if (!buildings && !proj_esp && !item_esp) - limit = std::min(max_clients, HIGHEST_ENTITY); - - { // Prof section ends when out of scope, these brackets here. - PROF_SECTION(CM_ESP_EntityLoop); - // Loop through entities - for (int i = 0; i < limit; i++) - { - // Get an entity from the loop tick and process it - CachedEntity *ent = ENTITY(i); - if (CE_BAD(ent)) - continue; - ProcessEntity(ent); - // Update Bones - if (i <= 32) - ent->hitboxes.GetHitbox(0); - // Dont know what this check is for - if (data[i].string_count) + { // Prof section ends when out of scope, these brackets here. + PROF_SECTION(CM_ESP_EntityLoop); + // Loop through entities + for (int i = 0; i < limit; i++) { - - // Set entity color - SetEntityColor(ent, colors::EntityF(ent)); - - // If snow distance, add string here - if (show_distance) + // Get an entity from the loop tick and process it + CachedEntity *ent = ENTITY(i); + if (CE_BAD(ent)) + continue; + ProcessEntity(ent); + // Update Bones + if (i <= 32) + ent->hitboxes.GetHitbox(0); + // Dont know what this check is for + if (data[i].string_count) { - AddEntityString( - ent, - format((int) (ENTITY(i)->m_flDistance() / 64 * 1.22f), - 'm')); + + // Set entity color + SetEntityColor(ent, colors::EntityF(ent)); + + // If snow distance, add string here + if (show_distance) + { + AddEntityString( + ent, format((int) (ENTITY(i)->m_flDistance() / 64 * + 1.22f), + 'm')); + } + } + // No idea, this is confusing + if (data[ent->m_IDX].needs_paint) + { + if (vischeck) + data[ent->m_IDX].transparent = !ent->IsVisible(); + entities_need_repaint.push_back(ent->m_IDX); } } - // No idea, this is confusing - if (data[ent->m_IDX].needs_paint) - { - if (vischeck) - data[ent->m_IDX].transparent = !ent->IsVisible(); - entities_need_repaint.push_back(ent->m_IDX); - } } - } -} + }); static glez::texture atlas{ DATA_PATH "/textures/atlas.png" }; static glez::texture idspec{ DATA_PATH "/textures/idspec.png" }; diff --git a/src/hacks/FollowBot.cpp b/src/hacks/FollowBot.cpp index 0664ebd3..4782efe2 100644 --- a/src/hacks/FollowBot.cpp +++ b/src/hacks/FollowBot.cpp @@ -168,347 +168,350 @@ int ClassPriority(CachedEntity *ent) } Timer waittime{}; int lastent = 0; -void WorldTick() -{ - if (!enable) - { - follow_target = 0; - return; - } - if (!inited) - init(); - - // We need a local player to control - if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer()) - { - follow_target = 0; - return; - } - - if (afk) - checkAFK(); - - // Still good check - if (follow_target) - { - // Overflow protection - if (breadcrumbs.size() > crumb_limit) - follow_target = 0; - // Still good check - else if (CE_BAD(ENTITY(follow_target))) - follow_target = 0; - } - - if (!follow_target) - breadcrumbs.clear(); // no target == no path - // Target Selection - if (steamid) - { - // Find a target with the steam id, as it is prioritized - auto ent_count = HIGHEST_ENTITY; - for (int i = 0; i < ent_count; i++) +#if ENABLE_IPC +static HookedFunction + WorldTick(HookedFunctions_types::HF_CreateMove, "followbot", 20, []() { + if (!enable) { - auto entity = ENTITY(i); - if (CE_BAD(entity)) // Exist + dormant - continue; - if (i == follow_target) - break; - if (entity->m_Type() != ENTITY_PLAYER) - continue; - if (steamid != entity->player_info.friendsID) // steamid check - continue; - - if (!entity->m_bAlivePlayer()) // Dont follow dead players - continue; - if (corneractivate) - { - Vector indirectOrigin = - VischeckCorner(LOCAL_E, entity, *follow_activation / 2, - true); // get the corner location that the - // future target is visible from - std::pair corners; - if (!indirectOrigin.z && - entity->m_IDX == lastent) // if we couldn't find it, run - // wallcheck instead - { - corners = VischeckWall(LOCAL_E, entity, - float(follow_activation) / 2, true); - if (!corners.first.z || !corners.second.z) - continue; - // addCrumbs(LOCAL_E, corners.first); - // addCrumbs(entity, corners.second); - addCrumbPair(LOCAL_E, entity, corners); - } - if (indirectOrigin.z) - addCrumbs(entity, indirectOrigin); - else if (!indirectOrigin.z && !corners.first.z) - continue; - } - else - { - if (!VisCheckEntFromEnt(LOCAL_E, entity)) - continue; - } - follow_target = entity->m_IDX; - break; + follow_target = 0; + return; } - } - // If we dont have a follow target from that, we look again for someone - // else who is suitable - if ((!follow_target || change || - (ClassPriority(ENTITY(follow_target)) < 6 && - ENTITY(follow_target)->player_info.friendsID != steamid)) && - roambot) - { - // Try to get a new target - auto ent_count = - followcart ? HIGHEST_ENTITY : g_IEngine->GetMaxClients(); - for (int i = 0; i < ent_count; i++) + if (!inited) + init(); + + // We need a local player to control + if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer()) { - auto entity = ENTITY(i); - if (CE_BAD(entity)) // Exist + dormant - continue; - if (!followcart) + follow_target = 0; + return; + } + + if (afk) + checkAFK(); + + // Still good check + if (follow_target) + { + // Overflow protection + if (breadcrumbs.size() > crumb_limit) + follow_target = 0; + // Still good check + else if (CE_BAD(ENTITY(follow_target))) + follow_target = 0; + } + + if (!follow_target) + breadcrumbs.clear(); // no target == no path + // Target Selection + if (steamid) + { + // Find a target with the steam id, as it is prioritized + auto ent_count = HIGHEST_ENTITY; + for (int i = 0; i < ent_count; i++) + { + auto entity = ENTITY(i); + if (CE_BAD(entity)) // Exist + dormant + continue; + if (i == follow_target) + break; if (entity->m_Type() != ENTITY_PLAYER) continue; - if (entity == LOCAL_E) // Follow self lol - continue; - if (entity->m_bEnemy()) - continue; - if (afk && - afkTicks[i].check(int( - afktime))) // don't follow target that was determined afk - continue; - if (IsPlayerDisguised(entity) || IsPlayerInvisible(entity)) - continue; - if (!entity->m_bAlivePlayer()) // Dont follow dead players - continue; - if (follow_activation && - entity->m_flDistance() > (float) follow_activation) - continue; - const model_t *model = - ENTITY(follow_target)->InternalEntity()->GetModel(); - // FIXME follow cart/point - /*if (followcart && model && - (lagexploit::pointarr[0] || lagexploit::pointarr[1] || - lagexploit::pointarr[2] || lagexploit::pointarr[3] || - lagexploit::pointarr[4]) && - (model == lagexploit::pointarr[0] || - model == lagexploit::pointarr[1] || - model == lagexploit::pointarr[2] || - model == lagexploit::pointarr[3] || - model == lagexploit::pointarr[4])) - follow_target = entity->m_IDX;*/ - if (entity->m_Type() != ENTITY_PLAYER) - continue; - // favor closer entitys - if (follow_target && - ENTITY(follow_target)->m_flDistance() < - entity->m_flDistance()) // favor closer entitys - continue; - // check if new target has a higher priority than current target - if (ClassPriority(ENTITY(follow_target)) >= - ClassPriority(ENTITY(i))) - continue; + if (steamid != entity->player_info.friendsID) // steamid check + continue; - if (corneractivate) - { - Vector indirectOrigin = - VischeckCorner(LOCAL_E, entity, 250, - true); // get the corner location that the - // future target is visible from - std::pair corners; - corners.first.z = 0; - corners.second.z = 0; - if (!indirectOrigin.z && - entity->m_IDX == lastent) // if we couldn't find it, run - // wallcheck instead + if (!entity->m_bAlivePlayer()) // Dont follow dead players + continue; + if (corneractivate) { - corners = VischeckWall(LOCAL_E, entity, 250, true); - if (!corners.first.z || !corners.second.z) + Vector indirectOrigin = VischeckCorner( + LOCAL_E, entity, *follow_activation / 2, + true); // get the corner location that the + // future target is visible from + std::pair corners; + if (!indirectOrigin.z && + entity->m_IDX == lastent) // if we couldn't find it, run + // wallcheck instead + { + corners = + VischeckWall(LOCAL_E, entity, + float(follow_activation) / 2, true); + if (!corners.first.z || !corners.second.z) + continue; + // addCrumbs(LOCAL_E, corners.first); + // addCrumbs(entity, corners.second); + addCrumbPair(LOCAL_E, entity, corners); + } + if (indirectOrigin.z) + addCrumbs(entity, indirectOrigin); + else if (!indirectOrigin.z && !corners.first.z) continue; - addCrumbPair(LOCAL_E, entity, corners); } - if (indirectOrigin.z) - addCrumbs(entity, indirectOrigin); - else if (!indirectOrigin.z && !corners.first.z) - continue; + else + { + if (!VisCheckEntFromEnt(LOCAL_E, entity)) + continue; + } + follow_target = entity->m_IDX; + break; } - else - { - if (!VisCheckEntFromEnt(LOCAL_E, entity)) - continue; - } - - // ooooo, a target - follow_target = i; - afkTicks[i].update(); // set afk time to 0 } - } - lastent++; - if (lastent > g_IEngine->GetMaxClients()) - lastent = 0; - // last check for entity before we continue - if (!follow_target) - return; + // If we dont have a follow target from that, we look again for someone + // else who is suitable + if ((!follow_target || change || + (ClassPriority(ENTITY(follow_target)) < 6 && + ENTITY(follow_target)->player_info.friendsID != steamid)) && + roambot) + { + // Try to get a new target + auto ent_count = + followcart ? HIGHEST_ENTITY : g_IEngine->GetMaxClients(); + for (int i = 0; i < ent_count; i++) + { + auto entity = ENTITY(i); + if (CE_BAD(entity)) // Exist + dormant + continue; + if (!followcart) + if (entity->m_Type() != ENTITY_PLAYER) + continue; + if (entity == LOCAL_E) // Follow self lol + continue; + if (entity->m_bEnemy()) + continue; + if (afk && + afkTicks[i].check(int(afktime))) // don't follow target that + // was determined afk + continue; + if (IsPlayerDisguised(entity) || IsPlayerInvisible(entity)) + continue; + if (!entity->m_bAlivePlayer()) // Dont follow dead players + continue; + if (follow_activation && + entity->m_flDistance() > (float) follow_activation) + continue; + const model_t *model = + ENTITY(follow_target)->InternalEntity()->GetModel(); + // FIXME follow cart/point + /*if (followcart && model && + (lagexploit::pointarr[0] || lagexploit::pointarr[1] || + lagexploit::pointarr[2] || lagexploit::pointarr[3] || + lagexploit::pointarr[4]) && + (model == lagexploit::pointarr[0] || + model == lagexploit::pointarr[1] || + model == lagexploit::pointarr[2] || + model == lagexploit::pointarr[3] || + model == lagexploit::pointarr[4])) + follow_target = entity->m_IDX;*/ + if (entity->m_Type() != ENTITY_PLAYER) + continue; + // favor closer entitys + if (follow_target && + ENTITY(follow_target)->m_flDistance() < + entity->m_flDistance()) // favor closer entitys + continue; + // check if new target has a higher priority than current target + if (ClassPriority(ENTITY(follow_target)) >= + ClassPriority(ENTITY(i))) + continue; - CachedEntity *followtar = ENTITY(follow_target); - // wtf is this needed - if (CE_BAD(followtar) || !followtar->m_bAlivePlayer()) - { - follow_target = 0; - return; - } - // Check if we are following a disguised/spy - if (IsPlayerDisguised(followtar) || IsPlayerInvisible(followtar)) - { - follow_target = 0; - return; - } - // check if target is afk - if (afk) - { - if (afkTicks[follow_target].check(int(afktime))) + if (corneractivate) + { + Vector indirectOrigin = VischeckCorner( + LOCAL_E, entity, 250, + true); // get the corner location that the + // future target is visible from + std::pair corners; + corners.first.z = 0; + corners.second.z = 0; + if (!indirectOrigin.z && + entity->m_IDX == lastent) // if we couldn't find it, run + // wallcheck instead + { + corners = VischeckWall(LOCAL_E, entity, 250, true); + if (!corners.first.z || !corners.second.z) + continue; + addCrumbPair(LOCAL_E, entity, corners); + } + if (indirectOrigin.z) + addCrumbs(entity, indirectOrigin); + else if (!indirectOrigin.z && !corners.first.z) + continue; + } + else + { + if (!VisCheckEntFromEnt(LOCAL_E, entity)) + continue; + } + + // ooooo, a target + follow_target = i; + afkTicks[i].update(); // set afk time to 0 + } + } + lastent++; + if (lastent > g_IEngine->GetMaxClients()) + lastent = 0; + // last check for entity before we continue + if (!follow_target) + return; + + CachedEntity *followtar = ENTITY(follow_target); + // wtf is this needed + if (CE_BAD(followtar) || !followtar->m_bAlivePlayer()) { follow_target = 0; return; } - } + // Check if we are following a disguised/spy + if (IsPlayerDisguised(followtar) || IsPlayerInvisible(followtar)) + { + follow_target = 0; + return; + } + // check if target is afk + if (afk) + { + if (afkTicks[follow_target].check(int(afktime))) + { + follow_target = 0; + return; + } + } - // Update timer on new target - static Timer idle_time{}; - if (breadcrumbs.empty()) - idle_time.update(); + // Update timer on new target + static Timer idle_time{}; + if (breadcrumbs.empty()) + idle_time.update(); - // If the player is close enough, we dont need to follow the path - auto tar_orig = followtar->m_vecOrigin(); - auto loc_orig = LOCAL_E->m_vecOrigin(); - auto dist_to_target = loc_orig.DistTo(tar_orig); + // If the player is close enough, we dont need to follow the path + auto tar_orig = followtar->m_vecOrigin(); + auto loc_orig = LOCAL_E->m_vecOrigin(); + auto dist_to_target = loc_orig.DistTo(tar_orig); - if ((dist_to_target < (float) follow_distance) && - VisCheckEntFromEnt(LOCAL_E, followtar)) - { - idle_time.update(); - } - - // New crumbs, we add one if its empty so we have something to follow - if ((breadcrumbs.empty() || - tar_orig.DistTo(breadcrumbs.at(breadcrumbs.size() - 1)) > 40.0F) && - DistanceToGround(ENTITY(follow_target)) < 45) - breadcrumbs.push_back(tar_orig); - - // Prune old and close crumbs that we wont need anymore, update idle timer - // too - for (int i = 0; i < breadcrumbs.size(); i++) - { - if (loc_orig.DistTo(breadcrumbs.at(i)) < 60.f) + if ((dist_to_target < (float) follow_distance) && + VisCheckEntFromEnt(LOCAL_E, followtar)) { idle_time.update(); - for (int j = 0; j <= i; j++) - breadcrumbs.erase(breadcrumbs.begin()); - } - } - - // Tauntsync - if (sync_taunt && HasCondition(followtar) && - lastTaunt.test_and_set(1000)) - { - g_IEngine->ClientCmd("taunt"); - } - - // Follow the crumbs when too far away, or just starting to follow - if (dist_to_target > (float) follow_distance) - { - // Check for jump - if (autojump && lastJump.check(1000) && - (idle_time.check(2000) || - DistanceToGround({ breadcrumbs[0].x, breadcrumbs[0].y, - breadcrumbs[0].z + 5 }) > 47)) - { - current_user_cmd->buttons |= IN_JUMP; - lastJump.update(); - } - // Check if still moving. 70 HU = Sniper Zoomed Speed - if (idle_time.check(3000) && - CE_VECTOR(g_pLocalPlayer->entity, netvar.vVelocity).IsZero(60.0f)) - { - follow_target = 0; - return; - } - // Basic idle check - if (idle_time.test_and_set(5000)) - { - follow_target = 0; - return; } - static float last_slot_check = 0.0f; - if (g_GlobalVars->curtime < last_slot_check) - last_slot_check = 0.0f; - if (follow_target && (always_medigun || mimic_slot) && - (g_GlobalVars->curtime - last_slot_check > 1.0f) && - !g_pLocalPlayer->life_state && - !CE_BYTE(ENTITY(follow_target), netvar.iLifeState)) + // New crumbs, we add one if its empty so we have something to follow + if ((breadcrumbs.empty() || + tar_orig.DistTo(breadcrumbs.at(breadcrumbs.size() - 1)) > 40.0F) && + DistanceToGround(ENTITY(follow_target)) < 45) + breadcrumbs.push_back(tar_orig); + + // Prune old and close crumbs that we wont need anymore, update idle + // timer too + for (int i = 0; i < breadcrumbs.size(); i++) { + if (loc_orig.DistTo(breadcrumbs.at(i)) < 60.f) + { + idle_time.update(); + for (int j = 0; j <= i; j++) + breadcrumbs.erase(breadcrumbs.begin()); + } + } - // We are checking our slot so reset the timer - last_slot_check = g_GlobalVars->curtime; + // Tauntsync + if (sync_taunt && HasCondition(followtar) && + lastTaunt.test_and_set(1000)) + { + g_IEngine->ClientCmd("taunt"); + } - // Get the follow targets active weapon - int owner_weapon_eid = - (CE_INT(ENTITY(follow_target), netvar.hActiveWeapon) & 0xFFF); - IClientEntity *owner_weapon = - g_IEntityList->GetClientEntity(owner_weapon_eid); + // Follow the crumbs when too far away, or just starting to follow + if (dist_to_target > (float) follow_distance) + { + // Check for jump + if (autojump && lastJump.check(1000) && + (idle_time.check(2000) || + DistanceToGround({ breadcrumbs[0].x, breadcrumbs[0].y, + breadcrumbs[0].z + 5 }) > 47)) + { + current_user_cmd->buttons |= IN_JUMP; + lastJump.update(); + } + // Check if still moving. 70 HU = Sniper Zoomed Speed + if (idle_time.check(3000) && + CE_VECTOR(g_pLocalPlayer->entity, netvar.vVelocity) + .IsZero(60.0f)) + { + follow_target = 0; + return; + } + // Basic idle check + if (idle_time.test_and_set(5000)) + { + follow_target = 0; + return; + } - // If both the follow targets and the local players weapons arnt - // null or - // dormant - if (owner_weapon && CE_GOOD(g_pLocalPlayer->weapon())) + static float last_slot_check = 0.0f; + if (g_GlobalVars->curtime < last_slot_check) + last_slot_check = 0.0f; + if (follow_target && (always_medigun || mimic_slot) && + (g_GlobalVars->curtime - last_slot_check > 1.0f) && + !g_pLocalPlayer->life_state && + !CE_BYTE(ENTITY(follow_target), netvar.iLifeState)) { - // IsBaseCombatWeapon() - if (re::C_BaseCombatWeapon::IsBaseCombatWeapon( - RAW_ENT(g_pLocalPlayer->weapon())) && - re::C_BaseCombatWeapon::IsBaseCombatWeapon(owner_weapon)) + // We are checking our slot so reset the timer + last_slot_check = g_GlobalVars->curtime; + + // Get the follow targets active weapon + int owner_weapon_eid = + (CE_INT(ENTITY(follow_target), netvar.hActiveWeapon) & + 0xFFF); + IClientEntity *owner_weapon = + g_IEntityList->GetClientEntity(owner_weapon_eid); + + // If both the follow targets and the local players weapons arnt + // null or + // dormant + if (owner_weapon && CE_GOOD(g_pLocalPlayer->weapon())) { - // Get the players slot numbers and store in some vars - int my_slot = re::C_BaseCombatWeapon::GetSlot( - RAW_ENT(g_pLocalPlayer->weapon())); - int owner_slot = - re::C_BaseCombatWeapon::GetSlot(owner_weapon); - - // If the local player is a medic and user settings allow, - // then - // keep the medigun out - if (g_pLocalPlayer->clazz == tf_medic && always_medigun) + // IsBaseCombatWeapon() + if (re::C_BaseCombatWeapon::IsBaseCombatWeapon( + RAW_ENT(g_pLocalPlayer->weapon())) && + re::C_BaseCombatWeapon::IsBaseCombatWeapon( + owner_weapon)) { - if (my_slot != 1) + + // Get the players slot numbers and store in some vars + int my_slot = re::C_BaseCombatWeapon::GetSlot( + RAW_ENT(g_pLocalPlayer->weapon())); + int owner_slot = + re::C_BaseCombatWeapon::GetSlot(owner_weapon); + + // If the local player is a medic and user settings + // allow, then keep the medigun out + if (g_pLocalPlayer->clazz == tf_medic && always_medigun) { - g_IEngine->ExecuteClientCmd("slot2"); + if (my_slot != 1) + { + g_IEngine->ExecuteClientCmd("slot2"); + } + + // Else we attemt to keep our weapon mimiced with + // our follow target } - - // Else we attemt to keep our weapon mimiced with our - // follow - // target - } - else - { - if (my_slot != owner_slot) + else { - g_IEngine->ExecuteClientCmd( - format("slot", owner_slot + 1).c_str()); + if (my_slot != owner_slot) + { + g_IEngine->ExecuteClientCmd( + format("slot", owner_slot + 1).c_str()); + } } } } } + WalkTo(breadcrumbs[0]); } - WalkTo(breadcrumbs[0]); - } - else - idle_time.update(); -} - + else + idle_time.update(); + }); +#endif void DrawTick() { #if ENABLE_VISUALS diff --git a/src/hacks/NavBot.cpp b/src/hacks/NavBot.cpp index 1be325d0..b75bcbe1 100644 --- a/src/hacks/NavBot.cpp +++ b/src/hacks/NavBot.cpp @@ -436,222 +436,155 @@ CatCommand debug_tele("navbot_debug", "debug", []() { CE_FLOAT(ent, netvar.m_flTeleYawToExit), g_GlobalVars->curtime, g_GlobalVars->curtime * g_GlobalVars->interval_per_tick); }); + int follow_target = 0; -void CreateMove() -{ - if ((!enable && !enable_fb) || !nav::Prepare()) - return; - if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer()) - return; - if (primary_only && enable) - UpdateSlot(); - if (*stay_near && nav_enemy_cd.test_and_set(1000) && - (!HasLowAmmo()) & (!HasLowHealth())) - NavToEnemy(); - if (HasLowHealth() && cdr.test_and_set(5000)) - { - CachedEntity *med = nearestHealth(); - if (CE_GOOD(med)) - { - if (nav::priority == 1337) - nav::clearInstructions(); - nav::NavTo(med->m_vecOrigin(), true, true, 7); - } - } - if (HasLowAmmo() && cdr.test_and_set(5000)) - { - CachedEntity *ammo = nearestAmmo(); - if (CE_GOOD(ammo)) - { - if (nav::priority == 1337) - nav::clearInstructions(); - nav::NavTo(ammo->m_vecOrigin(), true, true, 6); - } - } - if ((!HasLowHealth() && nav::priority == 7) || - (!HasLowAmmo() && nav::priority == 6)) - nav::clearInstructions(); - static int waittime = (spy_mode || heavy_mode || engi_mode) ? 100 : 2000; - if (*take_tele) - { - int idx = GetClosestTeleporter(); - if (idx != -1) - { - CachedEntity *ent = ENTITY(idx); - if (CE_GOOD(ent) && ent->m_flDistance() < 300.0f) - if (CE_FLOAT(ent, netvar.m_flTeleYawToExit) && - CE_FLOAT(ent, netvar.m_flTeleRechargeTime) < - g_GlobalVars->curtime) - { - waittime = 1000; - cd3.update(); - if (nav::priority == 1337) - nav::clearInstructions(); - nav::NavTo(GetBuildingPosition(ent), false, false); - } - } - } - if (enable) - { - if (!nav::ReadyForCommands && !spy_mode && !heavy_mode && !engi_mode) - cd3.update(); - if (target_sentry && NavToSentry(3)) +static HookedFunction + CreateMove(HookedFunctions_types::HF_CreateMove, "NavBot", 16, []() { + if ((!enable && !enable_fb) || !nav::Prepare()) return; - bool isready = (spy_mode || heavy_mode || engi_mode) - ? true - : nav::ReadyForCommands; - if (isready && cd3.test_and_set(waittime)) + if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer()) + return; + if (primary_only && enable) + UpdateSlot(); + if (*stay_near && nav_enemy_cd.test_and_set(1000) && + (!HasLowAmmo()) & (!HasLowHealth())) + NavToEnemy(); + if (HasLowHealth() && cdr.test_and_set(5000)) { - waittime = (spy_mode || heavy_mode || engi_mode) ? 100 : 2000; - if (!spy_mode && !heavy_mode && !engi_mode) + CachedEntity *med = nearestHealth(); + if (CE_GOOD(med)) { - cd3.update(); - if (cd2.test_and_set(5000)) - Init(); - if (!NavToSniperSpot(5)) - waittime = 1; + if (nav::priority == 1337) + nav::clearInstructions(); + nav::NavTo(med->m_vecOrigin(), true, true, 7); } - else if (!engi_mode) + } + if (HasLowAmmo() && cdr.test_and_set(5000)) + { + CachedEntity *ammo = nearestAmmo(); + if (CE_GOOD(ammo)) { - CachedEntity *tar = NearestEnemy(); - if (CE_BAD(tar) && last_tar == -1 && nav::ReadyForCommands) + if (nav::priority == 1337) + nav::clearInstructions(); + nav::NavTo(ammo->m_vecOrigin(), true, true, 6); + } + } + if ((!HasLowHealth() && nav::priority == 7) || + (!HasLowAmmo() && nav::priority == 6)) + nav::clearInstructions(); + static int waittime = + (spy_mode || heavy_mode || engi_mode) ? 100 : 2000; + if (*take_tele) + { + int idx = GetClosestTeleporter(); + if (idx != -1) + { + CachedEntity *ent = ENTITY(idx); + if (CE_GOOD(ent) && ent->m_flDistance() < 300.0f) + if (CE_FLOAT(ent, netvar.m_flTeleYawToExit) && + CE_FLOAT(ent, netvar.m_flTeleRechargeTime) < + g_GlobalVars->curtime) + { + waittime = 1000; + cd3.update(); + if (nav::priority == 1337) + nav::clearInstructions(); + nav::NavTo(GetBuildingPosition(ent), false, false); + } + } + } + if (enable) + { + if (!nav::ReadyForCommands && !spy_mode && !heavy_mode && + !engi_mode) + cd3.update(); + if (target_sentry && NavToSentry(3)) + return; + bool isready = (spy_mode || heavy_mode || engi_mode) + ? true + : nav::ReadyForCommands; + if (isready && cd3.test_and_set(waittime)) + { + waittime = (spy_mode || heavy_mode || engi_mode) ? 100 : 2000; + if (!spy_mode && !heavy_mode && !engi_mode) { + cd3.update(); if (cd2.test_and_set(5000)) Init(); - if (!NavToSniperSpot(4)) + if (!NavToSniperSpot(5)) waittime = 1; } - if (CE_GOOD(tar)) + else if (!engi_mode) { - if (!spy_mode || - !hacks::shared::backtrack::isBacktrackEnabled) + CachedEntity *tar = NearestEnemy(); + if (CE_BAD(tar) && last_tar == -1 && nav::ReadyForCommands) { - if (!nav::NavTo(tar->m_vecOrigin(), false)) - last_tar = -1; + if (cd2.test_and_set(5000)) + Init(); + if (!NavToSniperSpot(4)) + waittime = 1; } - else + if (CE_GOOD(tar)) { - int bestscr = INT_MAX; - hacks::shared::backtrack::BacktrackData besttick{}; - for (auto i : hacks::shared::backtrack::headPositions - [tar->m_IDX]) + if (!spy_mode || + !hacks::shared::backtrack::isBacktrackEnabled) { - if (!hacks::shared::backtrack::ValidTick(i, tar)) + if (!nav::NavTo(tar->m_vecOrigin(), false)) + last_tar = -1; + } + else + { + int bestscr = INT_MAX; + hacks::shared::backtrack::BacktrackData besttick{}; + for (auto i : hacks::shared::backtrack:: + headPositions[tar->m_IDX]) { - int scr = i.tickcount; - if (scr < bestscr) + if (!hacks::shared::backtrack::ValidTick(i, + tar)) { - bestscr = scr; - besttick = i; + int scr = i.tickcount; + if (scr < bestscr) + { + bestscr = scr; + besttick = i; + } } } - } - if (besttick.tickcount) - nav::NavTo(besttick.entorigin, false, false); - else if (!nav::NavTo(tar->m_vecOrigin(), false)) - last_tar = -1; - } - } - } - // Engi Mode - else - { - // Init things - if (cd2.test_and_set(5000)) - Init(); - // If No spots set just return - if (nest_spots.empty()) - return; - // Get Metal (offset of MAX metal is +8 and current metal +12) - int metal = CE_INT(LOCAL_E, netvar.m_iAmmo + 12); - // Best spot storage - static Vector best_spot{}; - // Get Best spot based on distance - if (engi_spot_cd.test_and_set(10000)) - { - float bestscr = FLT_MAX; - for (auto spot : nest_spots) - { - if (spot.DistTo(LOCAL_E->m_vecOrigin()) < bestscr) - { - bestscr = spot.DistTo(LOCAL_E->m_vecOrigin()); - best_spot = spot; + if (besttick.tickcount) + nav::NavTo(besttick.entorigin, false, false); + else if (!nav::NavTo(tar->m_vecOrigin(), false)) + last_tar = -1; } } } - if (nav::priority == 1) + // Engi Mode + else { - CachedEntity *ammo = nearestAmmo(); - if (CE_GOOD(ammo)) - { - nav::NavTo(ammo->m_vecOrigin(), false, true); + // Init things + if (cd2.test_and_set(5000)) + Init(); + // If No spots set just return + if (nest_spots.empty()) return; - } - } - // If Near The best spot and ready for commands - if (best_spot.DistTo(LOCAL_E->m_vecOrigin()) < 200.0f && - (nav::ReadyForCommands || nav::priority == 1)) - { - // Get the closest Building - int ClosestBuilding = GetClosestBuilding(); - // If A Building was found - if (ClosestBuilding != -1) + // Get Metal (offset of MAX metal is +8 and current metal + // +12) + int metal = CE_INT(LOCAL_E, netvar.m_iAmmo + 12); + // Best spot storage + static Vector best_spot{}; + // Get Best spot based on distance + if (engi_spot_cd.test_and_set(10000)) { - CachedEntity *ent = ENTITY(ClosestBuilding); - // If we have more than 25 metal and the building is - // damaged or not fully upgraded hit it with the wrench - if (metal > 25 && - (CE_INT(ent, netvar.iUpgradeLevel) < 3 || - CE_INT(ent, netvar.iBuildingHealth) < - CE_INT(ent, netvar.iBuildingMaxHealth))) + float bestscr = FLT_MAX; + for (auto spot : nest_spots) { - auto collide = RAW_ENT(ent)->GetCollideable(); - Vector min = - ent->m_vecOrigin() + collide->OBBMins(); - Vector max = - ent->m_vecOrigin() + collide->OBBMaxs(); - // Distance check - if (min.DistTo(g_pLocalPlayer->v_Eye) > - re::C_TFWeaponBaseMelee::GetSwingRange( - RAW_ENT(LOCAL_W)) && - max.DistTo(g_pLocalPlayer->v_Eye) > - re::C_TFWeaponBaseMelee::GetSwingRange( - RAW_ENT(LOCAL_W)) && - GetBuildingPosition(ent).DistTo( - g_pLocalPlayer->v_Eye) > - re::C_TFWeaponBaseMelee::GetSwingRange( - RAW_ENT(LOCAL_W))) + if (spot.DistTo(LOCAL_E->m_vecOrigin()) < bestscr) { - float minf = min.DistTo(g_pLocalPlayer->v_Eye); - float maxf = max.DistTo(g_pLocalPlayer->v_Eye); - float center = GetBuildingPosition(ent).DistTo( - g_pLocalPlayer->v_Eye); - float closest = - fminf(minf, fminf(maxf, center)); - Vector tonav = - (minf == closest) - ? min - : (maxf == closest) - ? max - : GetBuildingPosition(ent); - nav::NavTo(tonav, false, false); + bestscr = spot.DistTo(LOCAL_E->m_vecOrigin()); + best_spot = spot; } - Vector tr = GetBuildingPosition(ent) - - g_pLocalPlayer->v_Eye; - Vector angles; - VectorAngles(tr, angles); - // Clamping is important - fClampAngle(angles); - current_user_cmd->viewangles = angles; - current_user_cmd->buttons |= IN_ATTACK; - g_pLocalPlayer->bUseSilentAngles = true; - return; } } - // Get A building, Sentry > Dispenser - int tobuild = GetBestBuilding(metal); - // If not enough metal then Find ammo - if (tobuild == -1) + if (nav::priority == 1) { CachedEntity *ammo = nearestAmmo(); if (CE_GOOD(ammo)) @@ -659,276 +592,357 @@ void CreateMove() nav::NavTo(ammo->m_vecOrigin(), false, true); return; } - // Ammo is dormant, go and find it! - else if (sniper_spots.size() && nav::ReadyForCommands) + } + // If Near The best spot and ready for commands + if (best_spot.DistTo(LOCAL_E->m_vecOrigin()) < 200.0f && + (nav::ReadyForCommands || nav::priority == 1)) + { + // Get the closest Building + int ClosestBuilding = GetClosestBuilding(); + // If A Building was found + if (ClosestBuilding != -1) { - if (cd2.test_and_set(5000)) - Init(); - if (!NavToSniperSpot(1)) - waittime = 1; - return; + CachedEntity *ent = ENTITY(ClosestBuilding); + // If we have more than 25 metal and the building is + // damaged or not fully upgraded hit it with the + // wrench + if (metal > 25 && + (CE_INT(ent, netvar.iUpgradeLevel) < 3 || + CE_INT(ent, netvar.iBuildingHealth) < + CE_INT(ent, netvar.iBuildingMaxHealth))) + { + auto collide = RAW_ENT(ent)->GetCollideable(); + Vector min = + ent->m_vecOrigin() + collide->OBBMins(); + Vector max = + ent->m_vecOrigin() + collide->OBBMaxs(); + // Distance check + if (min.DistTo(g_pLocalPlayer->v_Eye) > + re::C_TFWeaponBaseMelee::GetSwingRange( + RAW_ENT(LOCAL_W)) && + max.DistTo(g_pLocalPlayer->v_Eye) > + re::C_TFWeaponBaseMelee::GetSwingRange( + RAW_ENT(LOCAL_W)) && + GetBuildingPosition(ent).DistTo( + g_pLocalPlayer->v_Eye) > + re::C_TFWeaponBaseMelee::GetSwingRange( + RAW_ENT(LOCAL_W))) + { + float minf = + min.DistTo(g_pLocalPlayer->v_Eye); + float maxf = + max.DistTo(g_pLocalPlayer->v_Eye); + float center = + GetBuildingPosition(ent).DistTo( + g_pLocalPlayer->v_Eye); + float closest = + fminf(minf, fminf(maxf, center)); + Vector tonav = + (minf == closest) + ? min + : (maxf == closest) + ? max + : GetBuildingPosition(ent); + nav::NavTo(tonav, false, false); + } + Vector tr = GetBuildingPosition(ent) - + g_pLocalPlayer->v_Eye; + Vector angles; + VectorAngles(tr, angles); + // Clamping is important + fClampAngle(angles); + current_user_cmd->viewangles = angles; + current_user_cmd->buttons |= IN_ATTACK; + g_pLocalPlayer->bUseSilentAngles = true; + return; + } + } + // Get A building, Sentry > Dispenser + int tobuild = GetBestBuilding(metal); + // If not enough metal then Find ammo + if (tobuild == -1) + { + CachedEntity *ammo = nearestAmmo(); + if (CE_GOOD(ammo)) + { + nav::NavTo(ammo->m_vecOrigin(), false, true); + return; + } + // Ammo is dormant, go and find it! + else if (sniper_spots.size() && + nav::ReadyForCommands) + { + if (cd2.test_and_set(5000)) + Init(); + if (!NavToSniperSpot(1)) + waittime = 1; + return; + } + } + // Build Building + else if (tobuild != 3) + { + // Make ENgi look slightly down + current_user_cmd->viewangles.x = 20.0f; + // Build buildings in a 360° angle around player + current_user_cmd->viewangles.y = + 90.0f * (tobuild + 1); + // Build new one + g_IEngine->ServerCmd( + format("build ", tobuild).c_str(), true); + current_user_cmd->buttons |= IN_ATTACK; + g_pLocalPlayer->bUseSilentAngles = true; } } - // Build Building - else if (tobuild != 3) - { - // Make ENgi look slightly down - current_user_cmd->viewangles.x = 20.0f; - // Build buildings in a 360° angle around player - current_user_cmd->viewangles.y = 90.0f * (tobuild + 1); - // Build new one - g_IEngine->ServerCmd(format("build ", tobuild).c_str(), - true); - current_user_cmd->buttons |= IN_ATTACK; - g_pLocalPlayer->bUseSilentAngles = true; - } + // If not near best spot then navigate to it + else if (nav::ReadyForCommands) + nav::NavTo(best_spot, false, true); } - // If not near best spot then navigate to it - else if (nav::ReadyForCommands) - nav::NavTo(best_spot, false, true); } } - } - else if (enable_fb) - { - // We need a local player to control - if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer()) + else if (enable_fb) { - follow_target = 0; - nav::NavTo(LOCAL_E->m_vecOrigin(), true, false, 4); - return; - } - - if (afk) - checkAFK(); - - // Still good check - if (follow_target) - if (CE_BAD(ENTITY(follow_target))) - follow_target = 0; - - if (!follow_target) - nav::NavTo(LOCAL_E->m_vecOrigin(), true, - false); // no target == no path - // Target Selection - if (steamid) - { - // Find a target with the steam id, as it is prioritized - auto ent_count = HIGHEST_ENTITY; - for (int i = 0; i < ent_count; i++) - { - auto entity = ENTITY(i); - if (CE_BAD(entity)) // Exist + dormant - continue; - if (i == follow_target) - break; - if (entity->m_Type() != ENTITY_PLAYER) - continue; - if (steamid != entity->player_info.friendsID) // steamid check - continue; - - if (!entity->m_bAlivePlayer()) // Dont follow dead players - continue; - follow_target = entity->m_IDX; - break; - } - } - // If we dont have a follow target from that, we look again for someone - // else who is suitable - if ((!follow_target || change_tar || - (hacks::shared::followbot::ClassPriority(ENTITY(follow_target)) < - 6 && - ENTITY(follow_target)->player_info.friendsID != steamid)) && - roambot) - { - // Try to get a new target - auto ent_count = g_IEngine->GetMaxClients(); - for (int i = 0; i < ent_count; i++) - { - auto entity = ENTITY(i); - if (CE_BAD(entity)) // Exist + dormant - continue; - if (entity->m_Type() != ENTITY_PLAYER) - continue; - if (entity == LOCAL_E) // Follow self lol - continue; - if (entity->m_bEnemy()) - continue; - if (afk && - afkTicks[i].check(int(afktime))) // don't follow target that - // was determined afk - continue; - if (IsPlayerDisguised(entity) || IsPlayerInvisible(entity)) - continue; - if (!entity->m_bAlivePlayer()) // Dont follow dead players - continue; - if (follow_activation && - entity->m_flDistance() > (float) follow_activation) - continue; - const model_t *model = - ENTITY(follow_target)->InternalEntity()->GetModel(); - // FIXME follow cart/point - /*if (followcart && model && - (lagexploit::pointarr[0] || lagexploit::pointarr[1] || - lagexploit::pointarr[2] || lagexploit::pointarr[3] || - lagexploit::pointarr[4]) && - (model == lagexploit::pointarr[0] || - model == lagexploit::pointarr[1] || - model == lagexploit::pointarr[2] || - model == lagexploit::pointarr[3] || - model == lagexploit::pointarr[4])) - follow_target = entity->m_IDX;*/ - if (entity->m_Type() != ENTITY_PLAYER) - continue; - // favor closer entitys - if (follow_target && - ENTITY(follow_target)->m_flDistance() < - entity->m_flDistance()) // favor closer entitys - continue; - // check if new target has a higher priority than current target - if (hacks::shared::followbot::ClassPriority( - ENTITY(follow_target)) >= - hacks::shared::followbot::ClassPriority(ENTITY(i))) - continue; - // ooooo, a target - follow_target = i; - afkTicks[i].update(); // set afk time to 0 - } - } - // last check for entity before we continue - if (!follow_target) - { - nav::NavTo(LOCAL_E->m_vecOrigin(), true, false, 4); - return; - } - - CachedEntity *followtar = ENTITY(follow_target); - // wtf is this needed - if (CE_BAD(followtar) || !followtar->m_bAlivePlayer()) - { - follow_target = 0; - nav::NavTo(LOCAL_E->m_vecOrigin(), true, false, 4); - return; - } - // Check if we are following a disguised/spy - if (IsPlayerDisguised(followtar) || IsPlayerInvisible(followtar)) - { - follow_target = 0; - nav::NavTo(LOCAL_E->m_vecOrigin(), true, false, 4); - return; - } - // check if target is afk - if (afk) - { - if (afkTicks[follow_target].check(int(afktime))) + // We need a local player to control + if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer()) { follow_target = 0; nav::NavTo(LOCAL_E->m_vecOrigin(), true, false, 4); return; } - } - // Update timer on new target - static Timer idle_time{}; - if (nav::ReadyForCommands) - idle_time.update(); + if (afk) + checkAFK(); - // If the player is close enough, we dont need to follow the path - auto tar_orig = followtar->m_vecOrigin(); - auto loc_orig = LOCAL_E->m_vecOrigin(); - auto dist_to_target = loc_orig.DistTo(tar_orig); - if (!CE_VECTOR(followtar, netvar.vVelocity).IsZero(20.0f)) - idle_time.update(); + // Still good check + if (follow_target) + if (CE_BAD(ENTITY(follow_target))) + follow_target = 0; - // Tauntsync - if (sync_taunt && HasCondition(followtar) && - lastTaunt.test_and_set(1000)) - g_IEngine->ClientCmd("taunt"); + if (!follow_target) + nav::NavTo(LOCAL_E->m_vecOrigin(), true, + false); // no target == no path + // Target Selection + if (steamid) + { + // Find a target with the steam id, as it is prioritized + auto ent_count = HIGHEST_ENTITY; + for (int i = 0; i < ent_count; i++) + { + auto entity = ENTITY(i); + if (CE_BAD(entity)) // Exist + dormant + continue; + if (i == follow_target) + break; + if (entity->m_Type() != ENTITY_PLAYER) + continue; + if (steamid != + entity->player_info.friendsID) // steamid check + continue; - // Check for jump - if (autojump && lastJump.check(1000) && idle_time.check(2000)) - { - current_user_cmd->buttons |= IN_JUMP; - lastJump.update(); - } - // Check if still moving. 70 HU = Sniper Zoomed Speed - if (idle_time.check(3000) && - CE_VECTOR(g_pLocalPlayer->entity, netvar.vVelocity).IsZero(60.0f)) - { - follow_target = 0; - nav::NavTo(LOCAL_E->m_vecOrigin(), true, false, 4); - return; - } - // Basic idle check - if (idle_time.test_and_set(5000)) - { - follow_target = 0; - nav::NavTo(LOCAL_E->m_vecOrigin(), true, false, 4); - return; - } + if (!entity->m_bAlivePlayer()) // Dont follow dead players + continue; + follow_target = entity->m_IDX; + break; + } + } + // If we dont have a follow target from that, we look again for + // someone else who is suitable + if ((!follow_target || change_tar || + (hacks::shared::followbot::ClassPriority( + ENTITY(follow_target)) < 6 && + ENTITY(follow_target)->player_info.friendsID != steamid)) && + roambot) + { + // Try to get a new target + auto ent_count = g_IEngine->GetMaxClients(); + for (int i = 0; i < ent_count; i++) + { + auto entity = ENTITY(i); + if (CE_BAD(entity)) // Exist + dormant + continue; + if (entity->m_Type() != ENTITY_PLAYER) + continue; + if (entity == LOCAL_E) // Follow self lol + continue; + if (entity->m_bEnemy()) + continue; + if (afk && afkTicks[i].check( + int(afktime))) // don't follow target that + // was determined afk + continue; + if (IsPlayerDisguised(entity) || IsPlayerInvisible(entity)) + continue; + if (!entity->m_bAlivePlayer()) // Dont follow dead players + continue; + if (follow_activation && + entity->m_flDistance() > (float) follow_activation) + continue; + const model_t *model = + ENTITY(follow_target)->InternalEntity()->GetModel(); + // FIXME follow cart/point + /*if (followcart && model && + (lagexploit::pointarr[0] || lagexploit::pointarr[1] || + lagexploit::pointarr[2] || lagexploit::pointarr[3] || + lagexploit::pointarr[4]) && + (model == lagexploit::pointarr[0] || + model == lagexploit::pointarr[1] || + model == lagexploit::pointarr[2] || + model == lagexploit::pointarr[3] || + model == lagexploit::pointarr[4])) + follow_target = entity->m_IDX;*/ + if (entity->m_Type() != ENTITY_PLAYER) + continue; + // favor closer entitys + if (follow_target && + ENTITY(follow_target)->m_flDistance() < + entity->m_flDistance()) // favor closer entitys + continue; + // check if new target has a higher priority than current + // target + if (hacks::shared::followbot::ClassPriority( + ENTITY(follow_target)) >= + hacks::shared::followbot::ClassPriority(ENTITY(i))) + continue; + // ooooo, a target + follow_target = i; + afkTicks[i].update(); // set afk time to 0 + } + } + // last check for entity before we continue + if (!follow_target) + { + nav::NavTo(LOCAL_E->m_vecOrigin(), true, false, 4); + return; + } - static float last_slot_check = 0.0f; - if (g_GlobalVars->curtime < last_slot_check) - last_slot_check = 0.0f; - if (follow_target && (always_medigun || mimic_slot) && - (g_GlobalVars->curtime - last_slot_check > 1.0f) && - !g_pLocalPlayer->life_state && - !CE_BYTE(ENTITY(follow_target), netvar.iLifeState)) - { + CachedEntity *followtar = ENTITY(follow_target); + // wtf is this needed + if (CE_BAD(followtar) || !followtar->m_bAlivePlayer()) + { + follow_target = 0; + nav::NavTo(LOCAL_E->m_vecOrigin(), true, false, 4); + return; + } + // Check if we are following a disguised/spy + if (IsPlayerDisguised(followtar) || IsPlayerInvisible(followtar)) + { + follow_target = 0; + nav::NavTo(LOCAL_E->m_vecOrigin(), true, false, 4); + return; + } + // check if target is afk + if (afk) + { + if (afkTicks[follow_target].check(int(afktime))) + { + follow_target = 0; + nav::NavTo(LOCAL_E->m_vecOrigin(), true, false, 4); + return; + } + } - // We are checking our slot so reset the timer - last_slot_check = g_GlobalVars->curtime; + // Update timer on new target + static Timer idle_time{}; + if (nav::ReadyForCommands) + idle_time.update(); - // Get the follow targets active weapon - int owner_weapon_eid = - (CE_INT(ENTITY(follow_target), netvar.hActiveWeapon) & 0xFFF); - IClientEntity *owner_weapon = - g_IEntityList->GetClientEntity(owner_weapon_eid); + // If the player is close enough, we dont need to follow the path + auto tar_orig = followtar->m_vecOrigin(); + auto loc_orig = LOCAL_E->m_vecOrigin(); + auto dist_to_target = loc_orig.DistTo(tar_orig); + if (!CE_VECTOR(followtar, netvar.vVelocity).IsZero(20.0f)) + idle_time.update(); - // If both the follow targets and the local players weapons arnt - // null or - // dormant - if (owner_weapon && CE_GOOD(g_pLocalPlayer->weapon())) + // Tauntsync + if (sync_taunt && HasCondition(followtar) && + lastTaunt.test_and_set(1000)) + g_IEngine->ClientCmd("taunt"); + + // Check for jump + if (autojump && lastJump.check(1000) && idle_time.check(2000)) + { + current_user_cmd->buttons |= IN_JUMP; + lastJump.update(); + } + // Check if still moving. 70 HU = Sniper Zoomed Speed + if (idle_time.check(3000) && + CE_VECTOR(g_pLocalPlayer->entity, netvar.vVelocity) + .IsZero(60.0f)) + { + follow_target = 0; + nav::NavTo(LOCAL_E->m_vecOrigin(), true, false, 4); + return; + } + // Basic idle check + if (idle_time.test_and_set(5000)) + { + follow_target = 0; + nav::NavTo(LOCAL_E->m_vecOrigin(), true, false, 4); + return; + } + + static float last_slot_check = 0.0f; + if (g_GlobalVars->curtime < last_slot_check) + last_slot_check = 0.0f; + if (follow_target && (always_medigun || mimic_slot) && + (g_GlobalVars->curtime - last_slot_check > 1.0f) && + !g_pLocalPlayer->life_state && + !CE_BYTE(ENTITY(follow_target), netvar.iLifeState)) { - // IsBaseCombatWeapon() - if (re::C_BaseCombatWeapon::IsBaseCombatWeapon( - RAW_ENT(g_pLocalPlayer->weapon())) && - re::C_BaseCombatWeapon::IsBaseCombatWeapon(owner_weapon)) + // We are checking our slot so reset the timer + last_slot_check = g_GlobalVars->curtime; + + // Get the follow targets active weapon + int owner_weapon_eid = + (CE_INT(ENTITY(follow_target), netvar.hActiveWeapon) & + 0xFFF); + IClientEntity *owner_weapon = + g_IEntityList->GetClientEntity(owner_weapon_eid); + + // If both the follow targets and the local players weapons arnt + // null or + // dormant + if (owner_weapon && CE_GOOD(g_pLocalPlayer->weapon())) { - // Get the players slot numbers and store in some vars - int my_slot = re::C_BaseCombatWeapon::GetSlot( - RAW_ENT(g_pLocalPlayer->weapon())); - int owner_slot = - re::C_BaseCombatWeapon::GetSlot(owner_weapon); - - // If the local player is a medic and user settings allow, - // then - // keep the medigun out - if (g_pLocalPlayer->clazz == tf_medic && always_medigun) + // IsBaseCombatWeapon() + if (re::C_BaseCombatWeapon::IsBaseCombatWeapon( + RAW_ENT(g_pLocalPlayer->weapon())) && + re::C_BaseCombatWeapon::IsBaseCombatWeapon( + owner_weapon)) { - if (my_slot != 1) + + // Get the players slot numbers and store in some vars + int my_slot = re::C_BaseCombatWeapon::GetSlot( + RAW_ENT(g_pLocalPlayer->weapon())); + int owner_slot = + re::C_BaseCombatWeapon::GetSlot(owner_weapon); + + // If the local player is a medic and user settings + // allow, then keep the medigun out + if (g_pLocalPlayer->clazz == tf_medic && always_medigun) { - g_IEngine->ExecuteClientCmd("slot2"); + if (my_slot != 1) + { + g_IEngine->ExecuteClientCmd("slot2"); + } + + // Else we attemt to keep our weapon mimiced with + // our follow target } - - // Else we attemt to keep our weapon mimiced with our - // follow - // target - } - else - { - if (my_slot != owner_slot) + else { - g_IEngine->ExecuteClientCmd( - format("slot", owner_slot + 1).c_str()); + if (my_slot != owner_slot) + { + g_IEngine->ExecuteClientCmd( + format("slot", owner_slot + 1).c_str()); + } } } } } + nav::NavTo(tar_orig, false, true, 5); } - nav::NavTo(tar_orig, false, true, 5); - } -} + }); } // namespace hacks::tf2::NavBot diff --git a/src/hacks/Walkbot.cpp b/src/hacks/Walkbot.cpp index 053beba4..0ba05f22 100644 --- a/src/hacks/Walkbot.cpp +++ b/src/hacks/Walkbot.cpp @@ -1216,75 +1216,78 @@ void OnLevelInit() Timer quit_timer{}; Timer map_check{}; int erasedelay = 0; -void Move() -{ - if (state::state == WB_DISABLED) - return; - switch (state::state) - { - case WB_RECORDING: - { - UpdateClosestNode(); - if (recording_key.isKeyDown() and ShouldSpawnNode()) +static HookedFunction + Move(HookedFunctions_types::HF_CreateMove, "Walkbot", 16, []() { + if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer()) + return; + if (state::state == WB_DISABLED) + return; + switch (state::state) { - RecordNode(); - } - } - break; - case WB_EDITING: - { - UpdateClosestNode(); - } - break; - case WB_REPLAYING: - { - if (leave_if_empty) + case WB_RECORDING: { - if (nodes.size() == 0 || g_IEngine->GetLevelName() != prevlvlname) + UpdateClosestNode(); + if (recording_key.isKeyDown() and ShouldSpawnNode()) { - prevlvlname = g_IEngine->GetLevelName(); - if (!boost::contains(prevlvlname, "pl_")) + RecordNode(); + } + } + break; + case WB_EDITING: + { + UpdateClosestNode(); + } + break; + case WB_REPLAYING: + { + if (leave_if_empty) + { + if (nodes.size() == 0 || + g_IEngine->GetLevelName() != prevlvlname) { - Load("default"); - if (leave_if_empty && nodes.size() == 0 && - quit_timer.test_and_set(5000)) + prevlvlname = g_IEngine->GetLevelName(); + if (!boost::contains(prevlvlname, "pl_")) { - logging::Info("No map file, abandon"); - tfmm::abandon(); - return; + Load("default"); + if (leave_if_empty && nodes.size() == 0 && + quit_timer.test_and_set(5000)) + { + logging::Info("No map file, abandon"); + tfmm::abandon(); + return; + } } } } + /*prevlvlname = g_IEngine->GetLevelName(); + std::string prvlvlname(prevlvlname); + if (boost::contains(prvlvlname, "pl_") || + boost::contains(prvlvlname, "cp_")) + { + logging::Info("1"); + bool ret = false; + if (lagexploit::pointarr[0] || lagexploit::pointarr[1] || + lagexploit::pointarr[2] || lagexploit::pointarr[3] || + lagexploit::pointarr[4]) + { + hacks::shared::followbot::followbot = 1; + hacks::shared::followbot::roambot = 1; + hacks::shared::followbot::followcart = true; + } + else + { + hacks::shared::followbot::followbot = 0; + hacks::shared::followbot::roambot = 0; + hacks::shared::followbot::followcart = false; + } + }*/ + if (nodes.size() == 0) + return; + if (force_slot) + UpdateSlot(); + UpdateWalker(); } - /*prevlvlname = g_IEngine->GetLevelName(); - std::string prvlvlname(prevlvlname); - if (boost::contains(prvlvlname, "pl_") || - boost::contains(prvlvlname, "cp_")) - { - logging::Info("1"); - bool ret = false; - if (lagexploit::pointarr[0] || lagexploit::pointarr[1] || - lagexploit::pointarr[2] || lagexploit::pointarr[3] || - lagexploit::pointarr[4]) - { - hacks::shared::followbot::followbot = 1; - hacks::shared::followbot::roambot = 1; - hacks::shared::followbot::followcart = true; - } - else - { - hacks::shared::followbot::followbot = 0; - hacks::shared::followbot::roambot = 0; - hacks::shared::followbot::followcart = false; - } - }*/ - if (nodes.size() == 0) - return; - if (force_slot) - UpdateSlot(); - UpdateWalker(); - } - break; - } -} + break; + } + }); } // namespace hacks::shared::walkbot diff --git a/src/hooks/CreateMove.cpp b/src/hooks/CreateMove.cpp index 268eb3bd..c25e1a81 100644 --- a/src/hooks/CreateMove.cpp +++ b/src/hooks/CreateMove.cpp @@ -109,7 +109,13 @@ static int attackticks = 0; namespace hooked_methods { - +static HookedFunction viewangs(HookedFunctions_types::HF_CreateMove, "set_ang", + 21, []() { + if (CE_BAD(LOCAL_E)) + return; + g_pLocalPlayer->v_OrigViewangles = + current_user_cmd->viewangles; + }); DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time, CUserCmd *cmd) { @@ -249,9 +255,6 @@ DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time, g_pLocalPlayer->Update(); } g_Settings.bInvalid = false; - - hacks::shared::autojoin::update(); - { PROF_SECTION(CM_AAA); hacks::shared::anti_anti_aim::createMove(); @@ -261,45 +264,11 @@ DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time, PROF_SECTION(CM_WRAPPER); HookTools::CM(); } - -#if ENABLE_IPC -#if !LAGBOT_MODE - if (hacks::shared::followbot::isEnabled()) - { - hacks::shared::followbot::WorldTick(); - } -#endif -#endif if (CE_GOOD(g_pLocalPlayer->entity)) { -#if !LAGBOT_MODE - IF_GAME(IsTF2()) - { - UpdateHoovyList(); - } - g_pLocalPlayer->v_OrigViewangles = cmd->viewangles; -#if ENABLE_VISUALS - { - PROF_SECTION(CM_esp); - hacks::shared::esp::CreateMove(); - } -#endif -#endif if (!g_pLocalPlayer->life_state && CE_GOOD(g_pLocalPlayer->weapon())) { #if !LAGBOT_MODE - { - PROF_SECTION(CM_walkbot); - hacks::shared::walkbot::Move(); - } - { - PROF_SECTION(CM_navparse); - nav::CreateMove(); - } - { - PROF_SECTION(CM_navbot); - hacks::tf2::NavBot::CreateMove(); - } // Walkbot can leave game. if (!g_IEngine->IsInGame()) { diff --git a/src/hoovy.cpp b/src/hoovy.cpp old mode 100755 new mode 100644 index 5b7faa90..89b2b74b --- a/src/hoovy.cpp +++ b/src/hoovy.cpp @@ -37,28 +37,31 @@ bool IsHoovyHelper(CachedEntity *entity) return false; } -void UpdateHoovyList() -{ - static CachedEntity *ent; +static HookedFunction UpdateHoovyList( + HookedFunctions_types::HF_CreateMove, "HoovyList", 19, []() { + if (CE_BAD(LOCAL_E)) + return; - for (int i = 1; i < 32 && i < g_IEntityList->GetHighestEntityIndex(); i++) - { - ent = ENTITY(i); - if (CE_GOOD(ent) && CE_BYTE(ent, netvar.iLifeState) == LIFE_ALIVE) + static CachedEntity *ent; + for (int i = 1; i < 32 && i < g_IEntityList->GetHighestEntityIndex(); + i++) { - if (!hoovy_list[i - 1]) + ent = ENTITY(i); + if (CE_GOOD(ent) && CE_BYTE(ent, netvar.iLifeState) == LIFE_ALIVE) { - if (IsHoovyHelper(ent)) - hoovy_list[i - 1] = true; - } - else - { - if (!HasSandvichOut(ent)) - hoovy_list[i - 1] = false; + if (!hoovy_list[i - 1]) + { + if (IsHoovyHelper(ent)) + hoovy_list[i - 1] = true; + } + else + { + if (!HasSandvichOut(ent)) + hoovy_list[i - 1] = false; + } } } - } -} + }); bool IsHoovy(CachedEntity *entity) { diff --git a/src/navparser.cpp b/src/navparser.cpp index 7f966aad..2a038645 100644 --- a/src/navparser.cpp +++ b/src/navparser.cpp @@ -367,78 +367,78 @@ void Repath() } // Main movement function, gets path from NavTo -void CreateMove() -{ - if (!enabled || !threadingFinished.load()) - return; - if (CE_BAD(LOCAL_E)) - return; - if (!LOCAL_E->m_bAlivePlayer()) - { - // Clear path if player dead - crumbs.clear(); - return; - } - ignoreManagerCM(); - // Crumbs empty, prepare for next instruction - if (crumbs.empty()) - { - priority = 0; - ReadyForCommands = true; - ensureArrival = false; - return; - } - ReadyForCommands = false; - // Remove old crumbs - if (g_pLocalPlayer->v_Origin.DistTo(Vector{ crumbs.at(0).x, crumbs.at(0).y, - g_pLocalPlayer->v_Origin.z }) < - 30.0f) - { - lastArea = crumbs.at(0); - crumbs.erase(crumbs.begin()); - inactivity.update(); - } - if (crumbs.empty()) - return; - // Detect when jumping is necessary - if (crumbs.at(0).z - g_pLocalPlayer->v_Origin.z > 18 && - lastJump.test_and_set(200)) - current_user_cmd->buttons |= IN_JUMP; - // Check if were dealing with a type 2 connection - if (inactivity.check(3000) && - TF2MAP->inactiveTracker.CheckType2({ lastArea, crumbs.at(0) })) - { - logging::Info("Pathing: Type 2 connection detected!"); - TF2MAP->pather->Reset(); - Repath(); - inactivity.update(); - return; - } - // Check for new sentries - if (sentryCheck.test_and_set(1000) && - TF2MAP->inactiveTracker.ShouldCancelPath(crumbs)) - { - logging::Info("Pathing: New Sentry found!"); - TF2MAP->pather->Reset(); - Repath(); - return; - } - // If inactive for too long - if (inactivity.check(5000)) - { - // Ignore connection - bool resetPather = false; - TF2MAP->inactiveTracker.AddTime({ lastArea, crumbs.at(0) }, inactivity, - resetPather); - if (resetPather) +static HookedFunction + CreateMove(HookedFunctions_types::HF_CreateMove, "NavParser", 17, []() { + if (!enabled || !threadingFinished.load()) + return; + if (CE_BAD(LOCAL_E)) + return; + if (!LOCAL_E->m_bAlivePlayer()) + { + // Clear path if player dead + crumbs.clear(); + return; + } + ignoreManagerCM(); + // Crumbs empty, prepare for next instruction + if (crumbs.empty()) + { + priority = 0; + ReadyForCommands = true; + ensureArrival = false; + return; + } + ReadyForCommands = false; + // Remove old crumbs + if (g_pLocalPlayer->v_Origin.DistTo(Vector{ + crumbs.at(0).x, crumbs.at(0).y, g_pLocalPlayer->v_Origin.z }) < + 30.0f) + { + lastArea = crumbs.at(0); + crumbs.erase(crumbs.begin()); + inactivity.update(); + } + if (crumbs.empty()) + return; + // Detect when jumping is necessary + if (crumbs.at(0).z - g_pLocalPlayer->v_Origin.z > 18 && + lastJump.test_and_set(200)) + current_user_cmd->buttons |= IN_JUMP; + // Check if were dealing with a type 2 connection + if (inactivity.check(3000) && + TF2MAP->inactiveTracker.CheckType2({ lastArea, crumbs.at(0) })) + { + logging::Info("Pathing: Type 2 connection detected!"); TF2MAP->pather->Reset(); - Repath(); - inactivity.update(); - return; - } - // Walk to next crumb - WalkTo(crumbs.at(0)); -} + Repath(); + inactivity.update(); + return; + } + // Check for new sentries + if (sentryCheck.test_and_set(1000) && + TF2MAP->inactiveTracker.ShouldCancelPath(crumbs)) + { + logging::Info("Pathing: New Sentry found!"); + TF2MAP->pather->Reset(); + Repath(); + return; + } + // If inactive for too long + if (inactivity.check(5000)) + { + // Ignore connection + bool resetPather = false; + TF2MAP->inactiveTracker.AddTime({ lastArea, crumbs.at(0) }, + inactivity, resetPather); + if (resetPather) + TF2MAP->pather->Reset(); + Repath(); + inactivity.update(); + return; + } + // Walk to next crumb + WalkTo(crumbs.at(0)); + }); void Draw() {