Merge pull request #543 from TotallyNotElite/master
Autobackstab improvements volume 27
This commit is contained in:
commit
4338f4ecaa
@ -11,15 +11,17 @@
|
|||||||
|
|
||||||
namespace hacks::shared::backtrack
|
namespace hacks::shared::backtrack
|
||||||
{
|
{
|
||||||
|
struct hitboxData
|
||||||
|
{
|
||||||
|
Vector center{ 0.0f, 0.0f, 0.0f };
|
||||||
|
Vector min{ 0.0f, 0.0f, 0.0f };
|
||||||
|
Vector max{ 0.0f, 0.0f, 0.0f };
|
||||||
|
};
|
||||||
|
|
||||||
struct BacktrackData
|
struct BacktrackData
|
||||||
{
|
{
|
||||||
int tickcount{ 0 };
|
int tickcount{ 0 };
|
||||||
Vector hitboxpos{ 0.0f, 0.0f, 0.0f };
|
std::array<hitboxData, 18> hitboxes;
|
||||||
Vector min{ 0.0f, 0.0f, 0.0f };
|
|
||||||
Vector max{ 0.0f, 0.0f, 0.0f };
|
|
||||||
Vector spine{ 0.0f, 0.0f, 0.0f };
|
|
||||||
Vector spineMin{ 0.0f, 0.0f, 0.0f };
|
|
||||||
Vector spineMax{ 0.0f, 0.0f, 0.0f };
|
|
||||||
float viewangles{ 0.0f };
|
float viewangles{ 0.0f };
|
||||||
float simtime{ 0.0f };
|
float simtime{ 0.0f };
|
||||||
Vector entorigin{ 0.0f, 0.0f, 0.0f };
|
Vector entorigin{ 0.0f, 0.0f, 0.0f };
|
||||||
@ -57,11 +59,9 @@ struct CIncomingSequence
|
|||||||
typedef boost::circular_buffer_space_optimized<CIncomingSequence> circular_buf;
|
typedef boost::circular_buffer_space_optimized<CIncomingSequence> circular_buf;
|
||||||
extern circular_buf sequences;
|
extern circular_buf sequences;
|
||||||
extern BacktrackData headPositions[32][66];
|
extern BacktrackData headPositions[32][66];
|
||||||
extern BestTickData sorted_ticks[66];
|
|
||||||
|
|
||||||
bool isBacktrackEnabled();
|
bool isBacktrackEnabled();
|
||||||
float getLatency();
|
float getLatency();
|
||||||
int getTicks();
|
int getTicks();
|
||||||
// FIXME
|
bool ValidTick(BacktrackData &i, CachedEntity *ent);
|
||||||
int getTicks2();
|
|
||||||
}
|
}
|
||||||
|
@ -91,50 +91,40 @@ AimbotCalculatedData_s calculated_data_array[2048]{};
|
|||||||
#define IsMelee GetWeaponMode() == weapon_melee
|
#define IsMelee GetWeaponMode() == weapon_melee
|
||||||
bool BacktrackAimbot()
|
bool BacktrackAimbot()
|
||||||
{
|
{
|
||||||
if (!hacks::shared::backtrack::isBacktrackEnabled() || !backtrackAimbot)
|
if (!hacks::shared::backtrack::isBacktrackEnabled() || !*backtrackAimbot)
|
||||||
return false;
|
return false;
|
||||||
if (aimkey && !aimkey.isKeyDown())
|
if (aimkey && !aimkey.isKeyDown())
|
||||||
return false;
|
return true;
|
||||||
|
|
||||||
if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer() || !CanShoot())
|
if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer() || !CanShoot())
|
||||||
return false;
|
return true;
|
||||||
|
|
||||||
if (zoomed_only && !g_pLocalPlayer->bZoomed &&
|
if (*zoomed_only && !g_pLocalPlayer->bZoomed &&
|
||||||
!(current_user_cmd->buttons & IN_ATTACK))
|
!(current_user_cmd->buttons & IN_ATTACK))
|
||||||
return false;
|
return true;
|
||||||
|
|
||||||
int iBestTarget = hacks::shared::backtrack::iBestTarget;
|
int iBestTarget = hacks::shared::backtrack::iBestTarget;
|
||||||
if (iBestTarget == -1)
|
if (iBestTarget == -1)
|
||||||
return true;
|
return true;
|
||||||
int tickcnt = 0;
|
int tickcnt = 0;
|
||||||
int tickus = (float(hacks::shared::backtrack::getLatency()) > 800.0f || float(hacks::shared::backtrack::getLatency()) < 200.0f) ? 12 : 24;
|
CachedEntity *tar = ENTITY(iBestTarget);
|
||||||
|
if (CE_BAD(tar))
|
||||||
|
return false;
|
||||||
for (auto i : hacks::shared::backtrack::headPositions[iBestTarget])
|
for (auto i : hacks::shared::backtrack::headPositions[iBestTarget])
|
||||||
{
|
{
|
||||||
bool good_tick = false;
|
if (hacks::shared::backtrack::ValidTick(i, tar))
|
||||||
for (int j = 0; j < tickus; ++j)
|
|
||||||
if (tickcnt == hacks::shared::backtrack::sorted_ticks[j].tick &&
|
|
||||||
hacks::shared::backtrack::sorted_ticks[j].tickcount != INT_MAX)
|
|
||||||
good_tick = true;
|
|
||||||
tickcnt++;
|
|
||||||
if (!i.hitboxpos.z)
|
|
||||||
continue;
|
continue;
|
||||||
if (!good_tick)
|
if (!i.hitboxes.at(head).center.z)
|
||||||
continue;
|
continue;
|
||||||
if (!IsVectorVisible(g_pLocalPlayer->v_Eye, i.hitboxpos, true))
|
if (!IsVectorVisible(g_pLocalPlayer->v_Eye, i.hitboxes.at(head).center, true))
|
||||||
continue;
|
continue;
|
||||||
float scr = abs(g_pLocalPlayer->v_OrigViewangles.y - i.viewangles);
|
float scr = abs(g_pLocalPlayer->v_OrigViewangles.y - i.viewangles);
|
||||||
|
|
||||||
CachedEntity *tar = ENTITY(iBestTarget);
|
|
||||||
// ok just in case
|
|
||||||
if (CE_BAD(tar))
|
|
||||||
continue;
|
|
||||||
// target_eid = tar->m_IDX;
|
|
||||||
Vector &angles = NET_VECTOR(RAW_ENT(tar), netvar.m_angEyeAngles);
|
Vector &angles = NET_VECTOR(RAW_ENT(tar), netvar.m_angEyeAngles);
|
||||||
float &simtime = CE_FLOAT(tar, netvar.m_flSimulationTime);
|
float &simtime = CE_FLOAT(tar, netvar.m_flSimulationTime);
|
||||||
angles.y = i.viewangles;
|
angles.y = i.viewangles;
|
||||||
simtime = i.simtime;
|
simtime = i.simtime;
|
||||||
current_user_cmd->tick_count = i.tickcount;
|
current_user_cmd->tick_count = i.tickcount;
|
||||||
Vector tr = (i.hitboxpos - g_pLocalPlayer->v_Eye);
|
Vector tr = (i.hitboxes.at(head).center - g_pLocalPlayer->v_Eye);
|
||||||
Vector angles2;
|
Vector angles2;
|
||||||
VectorAngles(tr, angles2);
|
VectorAngles(tr, angles2);
|
||||||
// Clamping is important
|
// Clamping is important
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
namespace hacks::tf2::autobackstab
|
namespace hacks::tf2::autobackstab
|
||||||
{
|
{
|
||||||
|
namespace backtrack = hacks::shared::backtrack;
|
||||||
static settings::Bool enable{ "autobackstab.enable", "0" };
|
static settings::Bool enable{ "autobackstab.enable", "0" };
|
||||||
static settings::Bool silent{ "autobackstab.silent", "1" };
|
static settings::Bool silent{ "autobackstab.silent", "1" };
|
||||||
|
|
||||||
@ -38,15 +39,18 @@ Vector rotateVector(Vector center, float radianAngle, Vector p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Function to find the closest hitbox to the v_Eye for a given ent
|
// Function to find the closest hitbox to the v_Eye for a given ent
|
||||||
int ClosestDistanceHitbox(CachedEntity *target)
|
int ClosestDistanceHitbox(CachedEntity *target,
|
||||||
|
backtrack::BacktrackData btd = {})
|
||||||
{
|
{
|
||||||
int closest = -1;
|
int closest = -1;
|
||||||
float closest_dist = 0.0f, dist = 0.0f;
|
float closest_dist = 0.0f, dist = 0.0f;
|
||||||
|
|
||||||
for (int i = spine_0; i < spine_3; i++)
|
for (int i = spine_0; i < spine_3; i++)
|
||||||
{
|
{
|
||||||
dist =
|
if (hacks::shared::backtrack::isBacktrackEnabled())
|
||||||
g_pLocalPlayer->v_Eye.DistTo(target->hitboxes.GetHitbox(i)->center);
|
dist = g_pLocalPlayer->v_Eye.DistTo(btd.hitboxes.at(i).center);
|
||||||
|
else
|
||||||
|
dist = g_pLocalPlayer->v_Eye.DistTo(
|
||||||
|
target->hitboxes.GetHitbox(i)->center);
|
||||||
if (dist < closest_dist || closest == -1)
|
if (dist < closest_dist || closest == -1)
|
||||||
{
|
{
|
||||||
closest = i;
|
closest = i;
|
||||||
@ -62,7 +66,7 @@ bool unifiedCanBackstab(Vector &vecAngle, Vector min, Vector max,
|
|||||||
// Get melee range
|
// Get melee range
|
||||||
float meleeRange = re::C_TFWeaponBaseMelee::GetSwingRange(RAW_ENT(LOCAL_W));
|
float meleeRange = re::C_TFWeaponBaseMelee::GetSwingRange(RAW_ENT(LOCAL_W));
|
||||||
if (fabsf(vecAngle.y -
|
if (fabsf(vecAngle.y -
|
||||||
NET_VECTOR(RAW_ENT(besttarget), netvar.m_angEyeAngles).y) >= 45)
|
NET_VECTOR(RAW_ENT(besttarget), netvar.m_angEyeAngles).y) >= 50)
|
||||||
return false;
|
return false;
|
||||||
if (!min.x && !max.x)
|
if (!min.x && !max.x)
|
||||||
return false;
|
return false;
|
||||||
@ -124,6 +128,8 @@ void CreateMove()
|
|||||||
if (!CanShoot())
|
if (!CanShoot())
|
||||||
return;
|
return;
|
||||||
CachedEntity *besttarget = nullptr;
|
CachedEntity *besttarget = nullptr;
|
||||||
|
if (!backtrack::isBacktrackEnabled())
|
||||||
|
{
|
||||||
for (int i = 0; i < g_IEngine->GetMaxClients(); i++)
|
for (int i = 0; i < g_IEngine->GetMaxClients(); i++)
|
||||||
{
|
{
|
||||||
CachedEntity *target = ENTITY(i);
|
CachedEntity *target = ENTITY(i);
|
||||||
@ -133,7 +139,7 @@ void CreateMove()
|
|||||||
!target->m_bAlivePlayer() || target->m_Type() != ENTITY_PLAYER)
|
!target->m_bAlivePlayer() || target->m_Type() != ENTITY_PLAYER)
|
||||||
continue;
|
continue;
|
||||||
if (target->hitboxes.GetHitbox(spine_3)->center.DistTo(
|
if (target->hitboxes.GetHitbox(spine_3)->center.DistTo(
|
||||||
g_pLocalPlayer->v_Eye) <= 300.0f)
|
g_pLocalPlayer->v_Eye) <= 200.0f)
|
||||||
{
|
{
|
||||||
if (CE_GOOD(besttarget))
|
if (CE_GOOD(besttarget))
|
||||||
{
|
{
|
||||||
@ -149,11 +155,31 @@ void CreateMove()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Run if backtrack is enabled
|
||||||
|
if (backtrack::iBestTarget == -1)
|
||||||
|
return;
|
||||||
|
CachedEntity *target = ENTITY(backtrack::iBestTarget);
|
||||||
|
// Various valid entity checks
|
||||||
|
if (CE_BAD(target))
|
||||||
|
return;
|
||||||
|
if (target == LOCAL_E || target->m_iTeam() == LOCAL_E->m_iTeam() ||
|
||||||
|
!target->m_bAlivePlayer() || target->m_Type() != ENTITY_PLAYER)
|
||||||
|
return;
|
||||||
|
// Check if besttick distance is < 200.0f
|
||||||
|
if (backtrack::headPositions[target->m_IDX][backtrack::BestTick]
|
||||||
|
.hitboxes.at(spine_3)
|
||||||
|
.center.DistTo(g_pLocalPlayer->v_Eye) < 200.0f)
|
||||||
|
besttarget = target;
|
||||||
|
}
|
||||||
|
|
||||||
if (CE_GOOD(besttarget))
|
if (CE_GOOD(besttarget))
|
||||||
{
|
{
|
||||||
hacks::shared::anti_anti_aim::resolveEnt(besttarget->m_IDX);
|
hacks::shared::anti_anti_aim::resolveEnt(besttarget->m_IDX);
|
||||||
Vector angle = NET_VECTOR(RAW_ENT(LOCAL_E), netvar.m_angEyeAngles);
|
Vector angle = NET_VECTOR(RAW_ENT(LOCAL_E), netvar.m_angEyeAngles);
|
||||||
if (!hacks::shared::backtrack::isBacktrackEnabled())
|
if (!backtrack::isBacktrackEnabled())
|
||||||
{
|
{
|
||||||
for (angle.y = -180.0f; angle.y < 180.0f; angle.y += 10.0f)
|
for (angle.y = -180.0f; angle.y < 180.0f; angle.y += 10.0f)
|
||||||
{
|
{
|
||||||
@ -183,19 +209,12 @@ void CreateMove()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
int idx = besttarget->m_IDX;
|
int idx = besttarget->m_IDX;
|
||||||
int tickcnt = 0;
|
for (auto i : backtrack::headPositions[idx])
|
||||||
for (auto i : hacks::shared::backtrack::headPositions[idx])
|
|
||||||
{
|
{
|
||||||
bool good_tick = false;
|
if (!backtrack::ValidTick(i, besttarget))
|
||||||
for (int j = 0; j < hacks::shared::backtrack::getTicks2(); ++j)
|
|
||||||
if (tickcnt ==
|
|
||||||
hacks::shared::backtrack::sorted_ticks[j].tick &&
|
|
||||||
hacks::shared::backtrack::sorted_ticks[j].tickcount !=
|
|
||||||
INT_MAX)
|
|
||||||
good_tick = true;
|
|
||||||
tickcnt++;
|
|
||||||
if (!good_tick)
|
|
||||||
continue;
|
continue;
|
||||||
|
backtrack::hitboxData &hitbox =
|
||||||
|
i.hitboxes.at(ClosestDistanceHitbox(besttarget, i));
|
||||||
|
|
||||||
// Check if we are inside the target (which will in most cases
|
// Check if we are inside the target (which will in most cases
|
||||||
// result in a failstab)
|
// result in a failstab)
|
||||||
@ -206,17 +225,18 @@ void CreateMove()
|
|||||||
g_pLocalPlayer->v_Origin);
|
g_pLocalPlayer->v_Origin);
|
||||||
// Get dist Z to Z
|
// Get dist Z to Z
|
||||||
float halfHeight =
|
float halfHeight =
|
||||||
(i.spineMin.DistTo(
|
(hitbox.min.DistTo(
|
||||||
Vector{ i.spineMin.x, i.spineMin.y, i.spineMax.z })) /
|
Vector{ hitbox.min.x, hitbox.min.y, hitbox.max.z })) /
|
||||||
2;
|
2;
|
||||||
// Make our first diagonal line
|
// Make our first diagonal line
|
||||||
std::pair<Vector, Vector> line1(
|
std::pair<Vector, Vector> line1(
|
||||||
{ i.spineMin.x, i.spineMin.y, i.spineMin.z + halfHeight },
|
{ hitbox.min.x, hitbox.min.y, hitbox.min.z + halfHeight },
|
||||||
{ i.spineMax.x, i.spineMax.y, i.spineMax.z - halfHeight });
|
{ hitbox.max.x, hitbox.max.y, hitbox.max.z - halfHeight });
|
||||||
// Make our second diagonal line
|
// Make our second diagonal line
|
||||||
std::pair<Vector, Vector> line2(
|
std::pair<Vector, Vector> line2(
|
||||||
{ line1.second.x, line1.first.y, line1.first.z },
|
{ line1.second.x, line1.first.y, line1.first.z },
|
||||||
{ line1.first.x, line1.second.y, line1.first.z });
|
{ line1.first.x, line1.second.y, line1.first.z });
|
||||||
|
// Check if one of the lines intersects with our collidable
|
||||||
if (LineIntersectsBox(collidableMinMax.first,
|
if (LineIntersectsBox(collidableMinMax.first,
|
||||||
collidableMinMax.second, line1.first,
|
collidableMinMax.second, line1.first,
|
||||||
line1.second) ||
|
line1.second) ||
|
||||||
@ -224,10 +244,11 @@ void CreateMove()
|
|||||||
collidableMinMax.second, line2.first,
|
collidableMinMax.second, line2.first,
|
||||||
line2.second))
|
line2.second))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (angle.y = -180.0f; angle.y < 180.0f; angle.y += 20.0f)
|
for (angle.y = -180.0f; angle.y < 180.0f; angle.y += 20.0f)
|
||||||
{
|
{
|
||||||
if (unifiedCanBackstab(angle, i.spineMin, i.spineMax,
|
if (unifiedCanBackstab(angle, hitbox.min, hitbox.max,
|
||||||
i.spine, besttarget))
|
hitbox.center, besttarget))
|
||||||
{
|
{
|
||||||
current_user_cmd->tick_count = i.tickcount;
|
current_user_cmd->tick_count = i.tickcount;
|
||||||
current_user_cmd->viewangles = angle;
|
current_user_cmd->viewangles = angle;
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
#include <settings/Bool.hpp>
|
#include <settings/Bool.hpp>
|
||||||
#include <hacks/Backtrack.hpp>
|
#include <hacks/Backtrack.hpp>
|
||||||
|
|
||||||
|
|
||||||
static settings::Bool enable{ "backtrack.enable", "false" };
|
static settings::Bool enable{ "backtrack.enable", "false" };
|
||||||
static settings::Bool draw_bt{ "backtrack.draw", "false" };
|
static settings::Bool draw_bt{ "backtrack.draw", "false" };
|
||||||
static settings::Int latency{ "backtrack.latency", "0" };
|
static settings::Int latency{ "backtrack.latency", "0" };
|
||||||
@ -21,9 +20,9 @@ static settings::Int slots{ "backtrack.slots", "0" };
|
|||||||
|
|
||||||
namespace hacks::shared::backtrack
|
namespace hacks::shared::backtrack
|
||||||
{
|
{
|
||||||
|
void EmptyBacktrackData(BacktrackData &i);
|
||||||
|
std::pair<int, int> getBestEntBestTick();
|
||||||
BacktrackData headPositions[32][66]{};
|
BacktrackData headPositions[32][66]{};
|
||||||
BestTickData sorted_ticks[66]{};
|
|
||||||
int highesttick[32]{};
|
int highesttick[32]{};
|
||||||
int lastincomingsequencenumber = 0;
|
int lastincomingsequencenumber = 0;
|
||||||
static bool shouldDrawBt;
|
static bool shouldDrawBt;
|
||||||
@ -65,10 +64,7 @@ void Init()
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < 32; i++)
|
for (int i = 0; i < 32; i++)
|
||||||
for (int j = 0; j < 66; j++)
|
for (int j = 0; j < 66; j++)
|
||||||
headPositions[i][j] = BacktrackData{
|
EmptyBacktrackData(headPositions[i][j]);
|
||||||
0, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
|
|
||||||
{ 0, 0, 0 }, { 0, 0, 0 }, 0, 0, { 0, 0, 0 }
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int BestTick = 0;
|
int BestTick = 0;
|
||||||
@ -90,12 +86,13 @@ void Run()
|
|||||||
|
|
||||||
CUserCmd *cmd = current_user_cmd;
|
CUserCmd *cmd = current_user_cmd;
|
||||||
float bestFov = 99999;
|
float bestFov = 99999;
|
||||||
BestTick = 0;
|
|
||||||
iBestTarget = -1;
|
|
||||||
bool IsMelee = GetWeaponMode() == weapon_melee;
|
|
||||||
|
|
||||||
float prev_distance = 9999;
|
float prev_distance = 9999;
|
||||||
|
|
||||||
|
auto bestEntBestTick = getBestEntBestTick();
|
||||||
|
BestTick = bestEntBestTick.second;
|
||||||
|
iBestTarget = bestEntBestTick.first;
|
||||||
|
|
||||||
for (int i = 1; i < g_IEngine->GetMaxClients(); i++)
|
for (int i = 1; i < g_IEngine->GetMaxClients(); i++)
|
||||||
{
|
{
|
||||||
CachedEntity *pEntity = ENTITY(i);
|
CachedEntity *pEntity = ENTITY(i);
|
||||||
@ -103,10 +100,7 @@ void Run()
|
|||||||
if (CE_BAD(pEntity) || !pEntity->m_bAlivePlayer())
|
if (CE_BAD(pEntity) || !pEntity->m_bAlivePlayer())
|
||||||
{
|
{
|
||||||
for (BacktrackData &btd : headPositions[i])
|
for (BacktrackData &btd : headPositions[i])
|
||||||
btd = BacktrackData{ 0, { 0, 0, 0 }, { 0, 0, 0 },
|
EmptyBacktrackData(btd);
|
||||||
{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
|
|
||||||
{ 0, 0, 0 }, 0, 0,
|
|
||||||
{ 0, 0, 0 } };
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (pEntity->m_iTeam() == LOCAL_E->m_iTeam())
|
if (pEntity->m_iTeam() == LOCAL_E->m_iTeam())
|
||||||
@ -115,99 +109,44 @@ void Run()
|
|||||||
continue;
|
continue;
|
||||||
if (!pEntity->hitboxes.GetHitbox(0))
|
if (!pEntity->hitboxes.GetHitbox(0))
|
||||||
continue;
|
continue;
|
||||||
Vector hitboxpos = pEntity->hitboxes.GetHitbox(0)->center;
|
float _viewangles = CE_VECTOR(pEntity, netvar.m_angEyeAngles).y;
|
||||||
Vector min = pEntity->hitboxes.GetHitbox(0)->min;
|
|
||||||
Vector max = pEntity->hitboxes.GetHitbox(0)->max;
|
|
||||||
float _viewangles =
|
|
||||||
NET_VECTOR(RAW_ENT(pEntity), netvar.m_angEyeAngles).y;
|
|
||||||
float viewangles =
|
float viewangles =
|
||||||
(_viewangles > 180) ? _viewangles - 360 : _viewangles;
|
(_viewangles > 180) ? _viewangles - 360 : _viewangles;
|
||||||
float simtime = CE_FLOAT(pEntity, netvar.m_flSimulationTime);
|
float simtime = CE_FLOAT(pEntity, netvar.m_flSimulationTime);
|
||||||
Vector hitbox_spine = pEntity->hitboxes.GetHitbox(spine_3)->center;
|
std::array<hitboxData, 18> hbdArray;
|
||||||
Vector hitbox_min = pEntity->hitboxes.GetHitbox(spine_3)->min;
|
for (size_t i = 0; i < hbdArray.max_size(); i++)
|
||||||
Vector hitbox_max = pEntity->hitboxes.GetHitbox(spine_3)->max;
|
{
|
||||||
|
hbdArray.at(i).center = pEntity->hitboxes.GetHitbox(i)->center;
|
||||||
|
hbdArray.at(i).min = pEntity->hitboxes.GetHitbox(i)->min;
|
||||||
|
hbdArray.at(i).max = pEntity->hitboxes.GetHitbox(i)->max;
|
||||||
|
}
|
||||||
Vector ent_orig = pEntity->InternalEntity()->GetAbsOrigin();
|
Vector ent_orig = pEntity->InternalEntity()->GetAbsOrigin();
|
||||||
auto hdr = g_IModelInfo->GetStudiomodel(RAW_ENT(pEntity)->GetModel());
|
auto hdr = g_IModelInfo->GetStudiomodel(RAW_ENT(pEntity)->GetModel());
|
||||||
headPositions[i][cmd->command_number % getTicks()] =
|
headPositions[i][cmd->command_number % getTicks()] =
|
||||||
BacktrackData{ cmd->tick_count, hitboxpos, min, max,
|
BacktrackData{ cmd->tick_count, hbdArray, viewangles, simtime,
|
||||||
hitbox_spine, hitbox_min, hitbox_max, viewangles,
|
ent_orig };
|
||||||
simtime, ent_orig };
|
|
||||||
float FOVDistance = GetFov(g_pLocalPlayer->v_OrigViewangles,
|
|
||||||
g_pLocalPlayer->v_Eye, hitboxpos);
|
|
||||||
float distance = g_pLocalPlayer->v_Eye.DistTo(hitbox_spine);
|
|
||||||
if (!IsMelee && bestFov > FOVDistance && FOVDistance < 60.0f)
|
|
||||||
{
|
|
||||||
bestFov = FOVDistance;
|
|
||||||
iBestTarget = i;
|
|
||||||
}
|
|
||||||
if (IsMelee && distance < prev_distance)
|
|
||||||
{
|
|
||||||
prev_distance = distance;
|
|
||||||
iBestTarget = i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (iBestTarget != -1 && CanShoot())
|
if (iBestTarget != -1 && CanShoot())
|
||||||
{
|
{
|
||||||
int bestTick = 0;
|
CachedEntity *tar = ENTITY(iBestTarget);
|
||||||
float tempFOV = 9999;
|
if (CE_GOOD(tar))
|
||||||
float bestFOV = 180.0f;
|
|
||||||
float distance, prev_distance_ticks = 9999;
|
|
||||||
|
|
||||||
for (int i = 0; i < getTicks(); ++i)
|
|
||||||
sorted_ticks[i] = BestTickData{ INT_MAX, i };
|
|
||||||
for (int t = 0; t < getTicks(); ++t)
|
|
||||||
{
|
{
|
||||||
if (headPositions[iBestTarget][t].tickcount)
|
|
||||||
sorted_ticks[t] =
|
|
||||||
BestTickData{ headPositions[iBestTarget][t].tickcount, t };
|
|
||||||
}
|
|
||||||
std::sort(sorted_ticks, sorted_ticks + getTicks());
|
|
||||||
int tickus = getTicks2();
|
|
||||||
for (int t = 0; t < getTicks(); ++t)
|
|
||||||
{
|
|
||||||
bool good_tick = false;
|
|
||||||
|
|
||||||
for (int i = 0; i < tickus; ++i)
|
|
||||||
if (t == sorted_ticks[i].tick &&
|
|
||||||
sorted_ticks[i].tickcount != INT_MAX &&
|
|
||||||
sorted_ticks[i].tickcount)
|
|
||||||
good_tick = true;
|
|
||||||
if (!good_tick)
|
|
||||||
continue;
|
|
||||||
tempFOV =
|
|
||||||
GetFov(g_pLocalPlayer->v_OrigViewangles, g_pLocalPlayer->v_Eye,
|
|
||||||
headPositions[iBestTarget][t].hitboxpos);
|
|
||||||
if (IsMelee)
|
|
||||||
{
|
|
||||||
distance = g_pLocalPlayer->v_Eye.DistTo(
|
|
||||||
headPositions[iBestTarget][t].spine);
|
|
||||||
if (distance < (float) mindistance)
|
|
||||||
continue;
|
|
||||||
if (distance < prev_distance_ticks && tempFOV < 90.0f)
|
|
||||||
prev_distance_ticks = distance, bestTick = t;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (bestFOV > tempFOV)
|
|
||||||
bestTick = t, bestFOV = tempFOV;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BestTick = bestTick;
|
|
||||||
if (cmd->buttons & IN_ATTACK)
|
if (cmd->buttons & IN_ATTACK)
|
||||||
{
|
{
|
||||||
CachedEntity *tar = ENTITY(iBestTarget);
|
|
||||||
// ok just in case
|
// ok just in case
|
||||||
if (CE_BAD(tar))
|
if (CE_BAD(tar))
|
||||||
return;
|
return;
|
||||||
auto i = headPositions[iBestTarget][bestTick];
|
auto i = headPositions[iBestTarget][BestTick];
|
||||||
cmd->tick_count = i.tickcount;
|
cmd->tick_count = i.tickcount;
|
||||||
Vector &angles = NET_VECTOR(RAW_ENT(tar), netvar.m_angEyeAngles);
|
Vector &angles =
|
||||||
float &simtime = NET_FLOAT(RAW_ENT(tar), netvar.m_flSimulationTime);
|
NET_VECTOR(RAW_ENT(tar), netvar.m_angEyeAngles);
|
||||||
|
float &simtime =
|
||||||
|
NET_FLOAT(RAW_ENT(tar), netvar.m_flSimulationTime);
|
||||||
angles.y = i.viewangles;
|
angles.y = i.viewangles;
|
||||||
simtime = i.simtime;
|
simtime = i.simtime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void Draw()
|
void Draw()
|
||||||
{
|
{
|
||||||
@ -218,22 +157,18 @@ void Draw()
|
|||||||
return;
|
return;
|
||||||
if (!shouldDrawBt)
|
if (!shouldDrawBt)
|
||||||
return;
|
return;
|
||||||
int tickus = getTicks2();
|
|
||||||
for (int i = 0; i < g_IEngine->GetMaxClients(); i++)
|
for (int i = 0; i < g_IEngine->GetMaxClients(); i++)
|
||||||
{
|
{
|
||||||
|
CachedEntity *ent = ENTITY(i);
|
||||||
|
if (CE_BAD(ent))
|
||||||
|
continue;
|
||||||
for (int j = 0; j < getTicks(); j++)
|
for (int j = 0; j < getTicks(); j++)
|
||||||
{
|
{
|
||||||
bool good_tick = false;
|
if (!ValidTick(headPositions[i][j], ent))
|
||||||
|
|
||||||
for (int i = 0; i < tickus; ++i)
|
|
||||||
if (j == sorted_ticks[i].tick)
|
|
||||||
good_tick = true;
|
|
||||||
if (!good_tick)
|
|
||||||
continue;
|
continue;
|
||||||
auto hbpos = headPositions[i][j].hitboxpos;
|
auto hbpos = headPositions[i][j].hitboxes.at(head).center;
|
||||||
auto tickount = headPositions[i][j].tickcount;
|
auto min = headPositions[i][j].hitboxes.at(head).min;
|
||||||
auto min = headPositions[i][j].min;
|
auto max = headPositions[i][j].hitboxes.at(head).max;
|
||||||
auto max = headPositions[i][j].max;
|
|
||||||
if (!hbpos.x && !hbpos.y && !hbpos.z)
|
if (!hbpos.x && !hbpos.y && !hbpos.z)
|
||||||
continue;
|
continue;
|
||||||
Vector out;
|
Vector out;
|
||||||
@ -306,13 +241,87 @@ float getLatency()
|
|||||||
|
|
||||||
int getTicks()
|
int getTicks()
|
||||||
{
|
{
|
||||||
return max(min(int(*latency / 200.0f * 13.0f), 65), 12);
|
return max(min(int(*latency / 200.0f * 13.0f) + 12, 65), 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
int getTicks2()
|
bool ValidTick(BacktrackData &i, CachedEntity *ent)
|
||||||
{
|
{
|
||||||
// Removed for now
|
return fabsf(NET_FLOAT(RAW_ENT(ent), netvar.m_flSimulationTime) * 1000.0f -
|
||||||
//return (*latency > 800 || *latency < 200) ? 12 : 24;
|
getLatency() - i.simtime * 1000.0f) < 200.0f;
|
||||||
return 12;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EmptyBacktrackData(BacktrackData &i)
|
||||||
|
{
|
||||||
|
i = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This func is internal only
|
||||||
|
std::pair<int, int> getBestEntBestTick()
|
||||||
|
{
|
||||||
|
int bestEnt = -1;
|
||||||
|
int bestTick = -1;
|
||||||
|
if (GetWeaponMode() == weapon_melee)
|
||||||
|
{
|
||||||
|
float bestDist = 9999.0f;
|
||||||
|
for (int i = 0; i < g_IEngine->GetMaxClients(); i++)
|
||||||
|
{
|
||||||
|
CachedEntity *tar = ENTITY(i);
|
||||||
|
if (CE_GOOD(tar))
|
||||||
|
{
|
||||||
|
if (tar != LOCAL_E && tar->m_bEnemy())
|
||||||
|
{
|
||||||
|
|
||||||
|
for (int j = 0; j < getTicks(); j++)
|
||||||
|
{
|
||||||
|
if (ValidTick(headPositions[i][j], ENTITY(i)))
|
||||||
|
{
|
||||||
|
float dist =
|
||||||
|
headPositions[i][j]
|
||||||
|
.hitboxes.at(spine_3)
|
||||||
|
.center.DistTo(g_pLocalPlayer->v_Eye);
|
||||||
|
if (dist < bestDist && dist > *mindistance)
|
||||||
|
{
|
||||||
|
bestEnt = i;
|
||||||
|
bestTick = j;
|
||||||
|
bestDist = dist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float bestFov = 0.0f;
|
||||||
|
for (int i = 0; i < g_IEngine->GetMaxClients(); i++)
|
||||||
|
{
|
||||||
|
CachedEntity *tar = ENTITY(i);
|
||||||
|
if (CE_GOOD(tar))
|
||||||
|
{
|
||||||
|
if (tar != LOCAL_E && tar->m_bEnemy())
|
||||||
|
{
|
||||||
|
for (int j = 0; j < getTicks(); j++)
|
||||||
|
{
|
||||||
|
if (ValidTick(headPositions[i][j], tar))
|
||||||
|
{
|
||||||
|
float FOVDistance = GetFov(
|
||||||
|
g_pLocalPlayer->v_OrigViewangles,
|
||||||
|
g_pLocalPlayer->v_Eye,
|
||||||
|
headPositions[i][j].hitboxes.at(head).center);
|
||||||
|
if (bestFov > FOVDistance)
|
||||||
|
{
|
||||||
|
bestFov = FOVDistance;
|
||||||
|
bestEnt = i;
|
||||||
|
bestTick = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::make_pair(bestEnt, bestTick);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace hacks::shared::backtrack
|
||||||
|
@ -41,21 +41,15 @@ int last_hb_traced = 0;
|
|||||||
Vector forward;
|
Vector forward;
|
||||||
bool CanBacktrack()
|
bool CanBacktrack()
|
||||||
{
|
{
|
||||||
int target = hacks::shared::backtrack::iBestTarget;
|
CachedEntity *tar = ENTITY(hacks::shared::backtrack::iBestTarget);
|
||||||
int tickcnt = 0;
|
if (CE_BAD(tar))
|
||||||
int tickus = hacks::shared::backtrack::getTicks2();
|
return false;
|
||||||
for (auto i : hacks::shared::backtrack::headPositions[target])
|
for (auto i : hacks::shared::backtrack::headPositions[tar->m_IDX])
|
||||||
{
|
{
|
||||||
bool good_tick = false;
|
if(!hacks::shared::backtrack::ValidTick(i, tar))
|
||||||
for (int j = 0; j < tickus; ++j)
|
|
||||||
if (tickcnt == hacks::shared::backtrack::sorted_ticks[j].tick &&
|
|
||||||
hacks::shared::backtrack::sorted_ticks[j].tickcount != INT_MAX)
|
|
||||||
good_tick = true;
|
|
||||||
tickcnt++;
|
|
||||||
if (!good_tick)
|
|
||||||
continue;
|
continue;
|
||||||
auto min = i.min;
|
auto min = i.hitboxes.at(head).min;
|
||||||
auto max = i.max;
|
auto max = i.hitboxes.at(head).max;
|
||||||
if (!min.x && !max.x)
|
if (!min.x && !max.x)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -83,10 +77,6 @@ bool CanBacktrack()
|
|||||||
continue;
|
continue;
|
||||||
if (CheckLineBox(minz, maxz, g_pLocalPlayer->v_Eye, forward, hit))
|
if (CheckLineBox(minz, maxz, g_pLocalPlayer->v_Eye, forward, hit))
|
||||||
{
|
{
|
||||||
CachedEntity *tar = ENTITY(target);
|
|
||||||
// ok just in case
|
|
||||||
if (CE_BAD(tar))
|
|
||||||
continue;
|
|
||||||
Vector &angles = NET_VECTOR(RAW_ENT(tar), netvar.m_angEyeAngles);
|
Vector &angles = NET_VECTOR(RAW_ENT(tar), netvar.m_angEyeAngles);
|
||||||
float &simtime = NET_FLOAT(RAW_ENT(tar), netvar.m_flSimulationTime);
|
float &simtime = NET_FLOAT(RAW_ENT(tar), netvar.m_flSimulationTime);
|
||||||
angles.y = i.viewangles;
|
angles.y = i.viewangles;
|
||||||
|
Reference in New Issue
Block a user