diff --git a/.autotools b/.autotools
new file mode 100644
index 00000000..538972ac
--- /dev/null
+++ b/.autotools
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.gitmodules b/.gitmodules
old mode 100755
new mode 100644
index 84ae995f..2a79a1e6
--- a/.gitmodules
+++ b/.gitmodules
@@ -16,3 +16,6 @@
[submodule "external/co-library"]
path = external/co-library
url = https://github.com/nullworks/co-library.git
+[submodule "external/TF2_NavFile_Reader"]
+ path = external/TF2_NavFile_Reader
+ url = https://github.com/nullworks/TF2_NavFile_Reader.git
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ce8916c5..9ba09794 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -110,7 +110,8 @@ target_include_directories(cathook SYSTEM PRIVATE
"external/source-sdk-2013-headers/mp/src/tier1"
"external/source-sdk-2013-headers/mp/src")
-target_include_directories(cathook PRIVATE "external/ucccccp")
+target_include_directories(cathook PRIVATE "external/TF2_NavFile_Reader")
+target_include_directories(cathook PRIVATE "external/PathFinder/src/")
if(EnableWarnings)
target_compile_options(cathook PRIVATE -Wall -Wextra)
diff --git a/TF2_NavFile_Reader b/TF2_NavFile_Reader
new file mode 160000
index 00000000..3bc452cb
--- /dev/null
+++ b/TF2_NavFile_Reader
@@ -0,0 +1 @@
+Subproject commit 3bc452cbca4ab3dafadbf40fa44013a31f0b159a
diff --git a/external/PathFinder b/external/PathFinder
new file mode 160000
index 00000000..03bac251
--- /dev/null
+++ b/external/PathFinder
@@ -0,0 +1 @@
+Subproject commit 03bac25118aaa65822d036ac9f3b82124b681ad9
diff --git a/include/common.hpp b/include/common.hpp
index 82e7845a..b82823c4 100755
--- a/include/common.hpp
+++ b/include/common.hpp
@@ -48,6 +48,8 @@
#include "core/macros.hpp"
#include
+#include
+#include
#if ENABLE_VISUALS
#include
diff --git a/include/core/netvars.hpp b/include/core/netvars.hpp
index b22de707..cee7796b 100755
--- a/include/core/netvars.hpp
+++ b/include/core/netvars.hpp
@@ -11,9 +11,15 @@
class IClientEntity;
+// Fix clang gay
+#if defined(__clang__)
+#define NET_VAR(entity, offset, type) \
+ (*(reinterpret_cast(reinterpret_cast(entity) + (offset))))
+#elif defined(__GNUC__) || defined(__GNUG__)
#define NET_VAR(entity, offset, type) \
(*(reinterpret_cast(reinterpret_cast(entity) + \
(offset))))
+#endif
#define NET_INT(entity, offset) NET_VAR(entity, offset, int)
diff --git a/include/hacks/Backtrack.hpp b/include/hacks/Backtrack.hpp
index 343a69ba..cfe50210 100644
--- a/include/hacks/Backtrack.hpp
+++ b/include/hacks/Backtrack.hpp
@@ -25,6 +25,7 @@ struct BacktrackData
float viewangles{ 0.0f };
float simtime{ 0.0f };
Vector entorigin{ 0.0f, 0.0f, 0.0f };
+ int index{ 0 };
};
struct BestTickData
{
@@ -40,7 +41,6 @@ void Run();
void Draw();
void AddLatencyToNetchan(INetChannel *, float);
void UpdateIncomingSequences();
-bool shouldBacktrack();
extern int lastincomingsequencenumber;
extern int BestTick;
extern int iBestTarget;
@@ -60,7 +60,7 @@ typedef boost::circular_buffer_space_optimized circular_buf;
extern circular_buf sequences;
extern BacktrackData headPositions[32][66];
-bool isBacktrackEnabled();
+extern bool isBacktrackEnabled;
float getLatency();
int getTicks();
bool ValidTick(BacktrackData &i, CachedEntity *ent);
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 0e7ab9cc..90a49c3a 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -33,7 +33,8 @@ target_sources(cathook PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/votelogger.cpp"
"${CMAKE_CURRENT_LIST_DIR}/MiscTemporary.cpp"
"${CMAKE_CURRENT_LIST_DIR}/Options.cpp"
- "${CMAKE_CURRENT_LIST_DIR}/PlayerTools.cpp")
+ "${CMAKE_CURRENT_LIST_DIR}/PlayerTools.cpp"
+ "${CMAKE_CURRENT_LIST_DIR}/pathfinder.cpp")
add_subdirectory(core)
add_subdirectory(classinfo)
@@ -47,4 +48,4 @@ add_subdirectory(settings)
if(EnableVisuals)
add_subdirectory(visual)
-endif()
\ No newline at end of file
+endif()
diff --git a/src/hacks/Aimbot.cpp b/src/hacks/Aimbot.cpp
index ebb0249c..3550c37b 100644
--- a/src/hacks/Aimbot.cpp
+++ b/src/hacks/Aimbot.cpp
@@ -93,10 +93,11 @@ Timer zoomTime{};
// This array will store calculated projectile/hitscan predictions
// for current frame, to avoid performing them again
AimbotCalculatedData_s calculated_data_array[2048]{};
+<<<<<<< Updated upstream
#define IsMelee GetWeaponMode() == weapon_melee
bool BacktrackAimbot()
{
- if (!hacks::shared::backtrack::isBacktrackEnabled() || !backtrackAimbot)
+ if (!hacks::shared::backtrack::isBacktrackEnabled || !*backtrackAimbot)
return false;
if (aimkey && !aimkey.isKeyDown())
return true;
@@ -142,6 +143,7 @@ bool BacktrackAimbot()
current_user_cmd->buttons |= IN_ATTACK;
return true;
}
+
// The main "loop" of the aimbot.
void CreateMove()
{
@@ -162,25 +164,6 @@ void CreateMove()
// 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();
- // Refresh our best target
- CachedEntity *target_entity = RetrieveBestTarget(aimkey_status);
- if (CE_BAD(target_entity) || !foundTarget)
- return;
- // Auto-zoom
- IF_GAME(IsTF())
- {
- if (auto_zoom)
- {
- if (g_pLocalPlayer->holding_sniper_rifle)
- {
- zoomTime.update();
- if (not g_pLocalPlayer->bZoomed)
- {
- current_user_cmd->buttons |= IN_ATTACK2;
- }
- }
- }
- }
// check if we need to run projectile Aimbot code
projectileAimbotRequired = false;
if (projectile_aimbot &&
@@ -204,8 +187,25 @@ void CreateMove()
if (proj_gravity)
cur_proj_grav = float(proj_gravity);
}
- if (BacktrackAimbot())
+ // Refresh our best target
+ CachedEntity *target_entity = RetrieveBestTarget(aimkey_status);
+ if (CE_BAD(target_entity) || !foundTarget)
return;
+ // Auto-zoom
+ IF_GAME(IsTF())
+ {
+ if (auto_zoom)
+ {
+ if (g_pLocalPlayer->holding_sniper_rifle)
+ {
+ zoomTime.update();
+ if (not g_pLocalPlayer->bZoomed)
+ {
+ current_user_cmd->buttons |= IN_ATTACK2;
+ }
+ }
+ }
+ }
if (!g_IEntityList->GetClientEntity(target_entity->m_IDX))
return;
@@ -413,50 +413,58 @@ CachedEntity *RetrieveBestTarget(bool aimkey_state)
CachedEntity *ent;
CachedEntity *target_highest_ent = 0;
target_highest_score = -256;
-
- for (int i = 0; i < HIGHEST_ENTITY; i++)
+ if (!hacks::shared::backtrack::isBacktrackEnabled() || projectile_mode)
{
- ent = ENTITY(i);
- if (CE_BAD(ent))
- continue; // Check for null and dormant
- // Check whether the current ent is good enough to target
- if (IsTargetStateGood(ent))
+ for (int i = 0; i < HIGHEST_ENTITY; i++)
{
+ ent = ENTITY(i);
+ if (CE_BAD(ent))
+ continue; // Check for null and dormant
+ // Check whether the current ent is good enough to target
+ if (IsTargetStateGood(ent))
+ {
- // Distance Priority, Uses this is melee is used
- if (GetWeaponMode() == weaponmode::weapon_melee ||
- (int) priority_mode == 2)
- {
- scr = 4096.0f -
- calculated_data_array[i].aim_position.DistTo(
- g_pLocalPlayer->v_Eye);
- }
- else
- {
- switch ((int) priority_mode)
+ // Distance Priority, Uses this is melee is used
+ if (GetWeaponMode() == weaponmode::weapon_melee ||
+ (int) priority_mode == 2)
{
- 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
- scr = 450.0f - ent->m_iHealth();
- break;
- default:
- break;
+ scr = 4096.0f -
+ calculated_data_array[i].aim_position.DistTo(
+ g_pLocalPlayer->v_Eye);
+ }
+ else
+ {
+ 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
+ scr = 450.0f - ent->m_iHealth();
+ break;
+ default:
+ break;
+ }
+ }
+ // Compare the top score to our current ents score
+ if (scr > target_highest_score)
+ {
+ foundTarget = true;
+ target_highest_score = scr;
+ target_highest_ent = ent;
}
- }
- // Compare the top score to our current ents score
- if (scr > target_highest_score)
- {
- foundTarget = true;
- target_highest_score = scr;
- target_highest_ent = ent;
}
}
}
+ else if (hacks::shared::backtrack::iBestTarget != -1)
+ {
+ target_highest_ent = ENTITY(hacks::shared::backtrack::iBestTarget);
+ foundTarget = true;
+ }
+
// Save the ent for future use with target lock
target_last = target_highest_ent;
@@ -471,6 +479,9 @@ bool IsTargetStateGood(CachedEntity *entity)
{
PROF_SECTION(PT_aimbot_targetstatecheck);
+ if (hacks::shared::backtrack::isBacktrackEnabled() &&
+ entity->m_Type() != ENTITY_PLAYER)
+ return false;
// Checks for Players
if (entity->m_Type() == ENTITY_PLAYER)
{
@@ -584,7 +595,7 @@ bool IsTargetStateGood(CachedEntity *entity)
// Vis check + fov check
if (!VischeckPredictedEntity(entity))
return false;
- if ((float) fov > 0.0f && cd.fov > (float) fov)
+ if (*fov > 0.0f && cd.fov > *fov)
return false;
return true;
@@ -633,7 +644,7 @@ bool IsTargetStateGood(CachedEntity *entity)
// Vis and fov checks
if (!VischeckPredictedEntity(entity))
return false;
- if ((float) fov > 0.0f && cd.fov > (float) fov)
+ if (*fov > 0.0f && cd.fov > *fov)
return false;
return true;
@@ -677,7 +688,7 @@ bool IsTargetStateGood(CachedEntity *entity)
// Vis and fov check
if (!VischeckPredictedEntity(entity))
return false;
- if ((float) fov > 0.0f && cd.fov > (float) fov)
+ if (*fov > 0.0f && cd.fov > *fov)
return false;
return true;
@@ -715,17 +726,35 @@ void Aim(CachedEntity *entity)
// Get hitbox num
AimbotCalculatedData_s &cd = calculated_data_array[entity->m_IDX];
float minx, maxx, miny, maxy, minz, maxz, centerx, centery, centerz;
- auto hitbox = entity->hitboxes.GetHitbox(cd.hitbox);
+ auto hitboxmin = entity->hitboxes.GetHitbox(cd.hitbox)->min;
+ auto hitboxmax = entity->hitboxes.GetHitbox(cd.hitbox)->max;
+ auto hitboxcenter = entity->hitboxes.GetHitbox(cd.hitbox)->center;
+ if (hacks::shared::backtrack::isBacktrackEnabled())
+ {
+ hitboxcenter =
+ hacks::shared::backtrack::headPositions
+ [entity->m_IDX][hacks::shared::backtrack::BestTick]
+ .hitboxes[cd.hitbox]
+ .center;
+ hitboxmin = hacks::shared::backtrack::headPositions
+ [entity->m_IDX][hacks::shared::backtrack::BestTick]
+ .hitboxes[cd.hitbox]
+ .min;
+ hitboxmax = hacks::shared::backtrack::headPositions
+ [entity->m_IDX][hacks::shared::backtrack::BestTick]
+ .hitboxes[cd.hitbox]
+ .max;
+ }
// get positions
- minx = hitbox->min.x;
- miny = hitbox->min.y;
- maxx = hitbox->max.x;
- maxy = hitbox->max.y;
- minz = hitbox->min.z;
- maxz = hitbox->max.z;
- centerx = hitbox->center.x;
- centery = hitbox->center.y;
- centerz = hitbox->center.z;
+ minx = hitboxmin.x;
+ miny = hitboxmin.y;
+ maxx = hitboxmax.x;
+ maxy = hitboxmax.y;
+ minz = hitboxmin.z;
+ maxz = hitboxmax.z;
+ centerx = hitboxcenter.x;
+ centery = hitboxcenter.y;
+ centerz = hitboxcenter.z;
// Shrink positions
std::vector positions;
@@ -749,7 +778,7 @@ void Aim(CachedEntity *entity)
positions.push_back({ maxx, maxy, centerz });
positions.push_back({ minx, miny, centerz });
positions.push_back({ maxx, maxy, centerz });
- positions.push_back(hitbox->center);
+ positions.push_back(hitboxcenter);
for (auto pos : positions)
if (IsVectorVisible(g_pLocalPlayer->v_Eye, pos))
{
@@ -771,7 +800,15 @@ void Aim(CachedEntity *entity)
if (silent && !slow_aim)
g_pLocalPlayer->bUseSilentAngles = true;
-
+ if (hacks::shared::backtrack::isBacktrackEnabled())
+ {
+ auto i = hacks::shared::backtrack::headPositions
+ [hacks::shared::backtrack::iBestTarget]
+ [hacks::shared::backtrack::BestTick];
+ current_user_cmd->tick_count = i.tickcount;
+ float &simtime = NET_FLOAT(RAW_ENT(entity), netvar.m_flSimulationTime);
+ simtime = i.simtime;
+ }
// Finish function
return;
}
@@ -888,45 +925,64 @@ const Vector &PredictEntity(CachedEntity *entity)
if (cd.predict_tick == tickcount)
return result;
- // Players
- if ((entity->m_Type() == ENTITY_PLAYER))
+ if (!hacks::shared::backtrack::isBacktrackEnabled() || projectile_mode)
{
- // If using projectiles, predict a vector
- if (projectileAimbotRequired)
+
+ // Players
+ if ((entity->m_Type() == ENTITY_PLAYER))
{
- // Use prediction engine if user settings allow
- if (engine_projpred)
- result = ProjectilePrediction_Engine(
- entity, cd.hitbox, cur_proj_speed, cur_proj_grav, 0);
+ // If using projectiles, predict a vector
+ if (projectileAimbotRequired)
+ {
+ // Use prediction engine if user settings allow
+ if (engine_projpred)
+ result = ProjectilePrediction_Engine(
+ entity, cd.hitbox, cur_proj_speed, cur_proj_grav, 0);
+ else
+ result = ProjectilePrediction(entity, cd.hitbox,
+ cur_proj_speed, cur_proj_grav,
+ PlayerGravityMod(entity));
+ }
else
- result = ProjectilePrediction(entity, cd.hitbox, cur_proj_speed,
- cur_proj_grav,
- PlayerGravityMod(entity));
+ {
+ // If using extrapolation, then predict a vector
+ if (extrapolate)
+ result = SimpleLatencyPrediction(entity, cd.hitbox);
+ // else just grab strait from the hitbox
+ else
+ GetHitbox(entity, cd.hitbox, result);
+ }
+ // Buildings
+ }
+ else if (entity->m_Type() == ENTITY_BUILDING)
+ {
+ result = GetBuildingPosition(entity);
+ // Other
}
else
{
- // If using extrapolation, then predict a vector
- if (extrapolate)
- result = SimpleLatencyPrediction(entity, cd.hitbox);
- // else just grab strait from the hitbox
- else
- GetHitbox(entity, cd.hitbox, result);
+ result = entity->m_vecOrigin();
}
- // Buildings
- }
- else if (entity->m_Type() == ENTITY_BUILDING)
- {
- result = GetBuildingPosition(entity);
- // Other
+
+ cd.predict_tick = tickcount;
+
+ cd.fov = GetFov(g_pLocalPlayer->v_OrigViewangles, g_pLocalPlayer->v_Eye,
+ result);
}
else
{
- result = entity->m_vecOrigin();
+ // Players only
+ if ((entity->m_Type() == ENTITY_PLAYER))
+ {
+ auto hb = hacks::shared::backtrack::headPositions
+ [entity->m_IDX]
+ [hacks::shared::backtrack::BestTick];
+ cd.predict_tick = tickcount;
+ result = hb.hitboxes[cd.hitbox].center;
+ cd.fov = GetFov(g_pLocalPlayer->v_OrigViewangles,
+ g_pLocalPlayer->v_Eye, result);
+ }
}
-
- cd.predict_tick = tickcount;
- cd.fov =
- GetFov(g_pLocalPlayer->v_OrigViewangles, g_pLocalPlayer->v_Eye, result);
// Return the found vector
return result;
}
@@ -1114,7 +1170,16 @@ bool VischeckPredictedEntity(CachedEntity *entity)
// Update info
cd.vcheck_tick = tickcount;
- cd.visible = IsEntityVectorVisible(entity, PredictEntity(entity));
+ if (!hacks::shared::backtrack::isBacktrackEnabled() || projectile_mode)
+ cd.visible = IsEntityVectorVisible(entity, PredictEntity(entity));
+ else
+ cd.visible = IsVectorVisible(
+ g_pLocalPlayer->v_Eye,
+ hacks::shared::backtrack::headPositions
+ [entity->m_IDX][hacks::shared::backtrack::BestTick]
+ .hitboxes[cd.hitbox]
+ .center,
+ true);
return cd.visible;
}
diff --git a/src/hacks/AutoBackstab.cpp b/src/hacks/AutoBackstab.cpp
index c63b3b6a..7afed9ec 100644
--- a/src/hacks/AutoBackstab.cpp
+++ b/src/hacks/AutoBackstab.cpp
@@ -45,9 +45,9 @@ int ClosestDistanceHitbox(CachedEntity *target,
{
int closest = -1;
float closest_dist = 0.0f, dist = 0.0f;
- for (int i = spine_0; i < spine_3; i++)
+ for (int i = pelvis; i < lowerArm_R; i++)
{
- if (hacks::shared::backtrack::isBacktrackEnabled())
+ if (hacks::shared::backtrack::isBacktrackEnabled)
dist = g_pLocalPlayer->v_Eye.DistTo(btd.hitboxes.at(i).center);
else
dist = g_pLocalPlayer->v_Eye.DistTo(
@@ -67,7 +67,7 @@ bool unifiedCanBackstab(Vector &vecAngle, Vector min, Vector max,
// Get melee range
float meleeRange = re::C_TFWeaponBaseMelee::GetSwingRange(RAW_ENT(LOCAL_W));
if (fabsf(vecAngle.y -
- NET_VECTOR(RAW_ENT(besttarget), netvar.m_angEyeAngles).y) >= 50)
+ NET_VECTOR(RAW_ENT(besttarget), netvar.m_angEyeAngles).y) >= 60.0f)
return false;
if (!min.x && !max.x)
return false;
@@ -122,7 +122,7 @@ void CreateMove()
if (!CanShoot())
return;
CachedEntity *besttarget = nullptr;
- if (!backtrack::isBacktrackEnabled())
+ if (!backtrack::isBacktrackEnabled)
{
for (int i = 0; i < g_IEngine->GetMaxClients(); i++)
{
@@ -173,7 +173,7 @@ void CreateMove()
{
hacks::shared::anti_anti_aim::resolveEnt(besttarget->m_IDX);
Vector angle = NET_VECTOR(RAW_ENT(LOCAL_E), netvar.m_angEyeAngles);
- if (!backtrack::isBacktrackEnabled())
+ if (!backtrack::isBacktrackEnabled)
{
for (angle.y = -180.0f; angle.y < 180.0f; angle.y += 10.0f)
{
diff --git a/src/hacks/Backtrack.cpp b/src/hacks/Backtrack.cpp
index 3ad849fa..5d444127 100644
--- a/src/hacks/Backtrack.cpp
+++ b/src/hacks/Backtrack.cpp
@@ -22,10 +22,12 @@ namespace hacks::shared::backtrack
{
void EmptyBacktrackData(BacktrackData &i);
std::pair getBestEntBestTick();
+bool shouldBacktrack();
+
BacktrackData headPositions[32][66]{};
int highesttick[32]{};
int lastincomingsequencenumber = 0;
-static bool shouldDrawBt;
+bool isBacktrackEnabled = false;
circular_buf sequences{ 2048 };
void UpdateIncomingSequences()
@@ -48,6 +50,8 @@ void UpdateIncomingSequences()
}
void AddLatencyToNetchan(INetChannel *ch, float Latency)
{
+ if (!isBacktrackEnabled)
+ return;
if (Latency > 200.0f)
Latency -= ch->GetLatency(MAX_FLOWS);
for (auto &seq : sequences)
@@ -69,21 +73,24 @@ void Init()
int BestTick = 0;
int iBestTarget = -1;
+bool istickvalid[66]{};
+bool istickinvalid[66]{};
void Run()
{
- if (!enable)
+ if (!shouldBacktrack())
+ {
+ isBacktrackEnabled = false;
return;
+ }
+ isBacktrackEnabled = true;
if (CE_BAD(LOCAL_E))
return;
- if (!shouldBacktrack())
- {
- shouldDrawBt = false;
- return;
- }
- shouldDrawBt = true;
-
+ for (auto &a : istickvalid)
+ a = false;
+ for (auto &a : istickinvalid)
+ a = false;
CUserCmd *cmd = current_user_cmd;
float bestFov = 99999;
@@ -124,7 +131,7 @@ void Run()
auto hdr = g_IModelInfo->GetStudiomodel(RAW_ENT(pEntity)->GetModel());
headPositions[i][cmd->command_number % getTicks()] =
BacktrackData{ cmd->tick_count, hbdArray, viewangles, simtime,
- ent_orig };
+ ent_orig, cmd->command_number % getTicks() };
}
if (iBestTarget != -1 && CanShoot())
{
@@ -151,12 +158,10 @@ void Run()
void Draw()
{
#if ENABLE_VISUALS
- if (!enable)
+ if (!isBacktrackEnabled)
return;
if (!draw_bt)
return;
- if (!shouldDrawBt)
- return;
for (int i = 0; i < g_IEngine->GetMaxClients(); i++)
{
CachedEntity *ent = ENTITY(i);
@@ -192,10 +197,16 @@ void Draw()
#endif
}
+// Internal only, use isBacktrackEnabled var instead
bool shouldBacktrack()
{
+ if (!*enable)
+ return false;
+ CachedEntity *wep = g_pLocalPlayer->weapon();
+ if (CE_BAD(wep))
+ return false;
int slot =
- re::C_BaseCombatWeapon::GetSlot(RAW_ENT(g_pLocalPlayer->weapon()));
+ re::C_BaseCombatWeapon::GetSlot(RAW_ENT(wep));
switch ((int) slots)
{
case 0:
@@ -229,11 +240,6 @@ bool shouldBacktrack()
return false;
}
-bool isBacktrackEnabled()
-{
- return *enable;
-}
-
float getLatency()
{
return *latency;
@@ -246,8 +252,19 @@ int getTicks()
bool ValidTick(BacktrackData &i, CachedEntity *ent)
{
- return fabsf(NET_FLOAT(RAW_ENT(ent), netvar.m_flSimulationTime) * 1000.0f -
- getLatency() - i.simtime * 1000.0f) < 200.0f;
+ if (istickvalid[i.index])
+ return true;
+ if (istickinvalid[i.index])
+ return false;
+ if (IsVectorVisible(g_pLocalPlayer->v_Eye, i.hitboxes[head].center, true))
+ if (fabsf(NET_FLOAT(RAW_ENT(ent), netvar.m_flSimulationTime) * 1000.0f -
+ getLatency() - i.simtime * 1000.0f) < 200.0f)
+ {
+ istickvalid[i.index] = true;
+ return true;
+ }
+ istickinvalid[i.index] = true;
+ return false;
}
void EmptyBacktrackData(BacktrackData &i)
diff --git a/src/hacks/Trigger.cpp b/src/hacks/Trigger.cpp
index 628e2864..9ba10f8f 100644
--- a/src/hacks/Trigger.cpp
+++ b/src/hacks/Trigger.cpp
@@ -45,7 +45,9 @@ int last_hb_traced = 0;
Vector forward;
bool CanBacktrack()
{
- CachedEntity *tar = ENTITY(hacks::shared::backtrack::iBestTarget);
+ CachedEntity *tar = (hacks::shared::backtrack::iBestTarget != -1)
+ ? ENTITY(hacks::shared::backtrack::iBestTarget)
+ : nullptr;
if (CE_BAD(tar))
return false;
for (auto i : hacks::shared::backtrack::headPositions[tar->m_IDX])
@@ -113,7 +115,7 @@ void CreateMove()
CachedEntity *ent = FindEntInSight(EffectiveTargetingRange());
// Check if can backtrack, shoot if we can
- if (!CanBacktrack() || hacks::shared::backtrack::isBacktrackEnabled())
+ if (!CanBacktrack() || hacks::shared::backtrack::isBacktrackEnabled)
return;
// Check if dormant or null to prevent crashes
diff --git a/src/pathfinder.cpp b/src/pathfinder.cpp
new file mode 100644
index 00000000..a544d620
--- /dev/null
+++ b/src/pathfinder.cpp
@@ -0,0 +1,139 @@
+#include "common.hpp"
+#include "external/TF2_NavFile_Reader/CNavFile.h"
+#include "external/PathFinder/src/PathFinder.h"
+#include "external/PathFinder/src/AStar.h"
+
+namespace hacks::shared::pathfinder
+{
+Vector loc;
+//std::vector findPath(Vector loc, Vector dest);
+//bool initiatenavfile();
+
+//CatCommand navset("nav_set", "Debug nav set",
+// [](const CCommand &args) { loc = g_pLocalPlayer->v_Origin; });
+
+//CatCommand navfind("nav_find", "Debug nav find", [](const CCommand &args) {
+// std::vector path = findPath(g_pLocalPlayer->v_Origin, loc);
+// if (path.empty())
+// {
+// logging::Info("Pathing: No path found");
+// }
+// std::string output = "Pathing: Path found! Path: ";
+// for (int i = 0; i < path.size(); i++)
+// {
+// output.append(format(path.at(i).x, ",", format(path.at(i).y)));
+// }
+// logging::Info(output.c_str());
+//});
+
+//CatCommand navinit("nav_init", "Debug nav init",
+// [](const CCommand &args) { initiatenavfile(); });
+
+class navNode : public AStarNode
+{
+// navNode()
+// {
+// }
+
+// ~navNode()
+// {
+// }
+public:
+ Vector vecLoc;
+};
+
+std::vector nodes;
+//settings::Bool enabled{ "pathing.enabled", 0 };
+
+bool initiatenavfile()
+{
+ //if (!enabled)
+ // return false;
+ logging::Info("Pathing: Initiating path...");
+
+ // This will not work, please fix
+ std::string dir =
+ "/home/elite/.steam/steam/steamapps/common/Team Fortress 2/tf/maps/";
+ std::string levelName = g_IEngine->GetLevelName();
+ int dotpos = levelName.find('.');
+ levelName = levelName.substr(0, dotpos);
+ levelName.append(".nav");
+ dir.append(levelName);
+
+ CNavFile navData(dir.c_str());
+ if (!navData.m_isOK)
+ {
+ logging::Info("Pathing: Failed to parse nav file!");
+ return false;
+ }
+ std::vector *areas = &navData.m_areas;
+ int nodeCount = areas->size();
+
+ nodes.clear();
+ nodes.reserve(nodeCount);
+
+ // register nodes
+ for (int i = 0; i < nodeCount; i++)
+ {
+ navNode *node{};
+ // node->setPosition(areas->at(i).m_center.x, areas->at(i).m_center.y);
+ node->vecLoc = areas->at(i).m_center;
+ nodes.push_back(node);
+ }
+
+ for (int i = 0; i < nodeCount; ++i)
+ {
+ std::vector *connections = &areas->at(i).m_connections;
+ int childCount = connections->size();
+ navNode *currNode = nodes.at(i);
+ for (int j = 0; j < childCount; j++)
+ {
+ currNode->addChild(nodes.at(connections->at(j).id), 1.0f);
+ }
+ }
+ logging::Info("Path init successful");
+ return true;
+}
+
+int findClosestNavSquare(Vector vec)
+{
+ float bestDist = 999999.0f;
+ int bestSquare = -1;
+ for (int i = 0; i < nodes.size(); i++)
+ {
+ float dist = nodes.at(i)->vecLoc.DistTo(vec);
+ if (dist < bestDist)
+ {
+ bestDist = dist;
+ bestSquare = i;
+ }
+ }
+ return bestSquare;
+}
+
+std::vector findPath(Vector loc, Vector dest)
+{
+ if (nodes.empty())
+ return std::vector(0);
+
+ int id_loc = findClosestNavSquare(loc);
+ int id_dest = findClosestNavSquare(dest);
+
+ navNode &node_loc = *nodes.at(id_loc);
+ navNode &node_dest = *nodes.at(id_dest);
+
+ PathFinder p;
+ std::vector pathNodes;
+
+ p.setStart(node_loc);
+ p.setGoal(node_dest);
+
+ p.findPath(pathNodes);
+
+ std::vector path;
+ for (int i = 0; i < pathNodes.size(); i++)
+ {
+ path.push_back(pathNodes.at(i)->vecLoc);
+ }
+ return path;
+}}