Merge pull request #543 from TotallyNotElite/master

Autobackstab improvements volume 27
This commit is contained in:
LightCat 2018-08-10 23:09:31 +02:00 committed by GitHub
commit 4338f4ecaa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 212 additions and 202 deletions

View File

@ -11,15 +11,17 @@
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
{
int tickcount{ 0 };
Vector hitboxpos{ 0.0f, 0.0f, 0.0f };
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 };
std::array<hitboxData, 18> hitboxes;
float viewangles{ 0.0f };
float simtime{ 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;
extern circular_buf sequences;
extern BacktrackData headPositions[32][66];
extern BestTickData sorted_ticks[66];
bool isBacktrackEnabled();
float getLatency();
int getTicks();
// FIXME
int getTicks2();
bool ValidTick(BacktrackData &i, CachedEntity *ent);
}

View File

@ -91,50 +91,40 @@ AimbotCalculatedData_s calculated_data_array[2048]{};
#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 false;
return true;
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))
return false;
return true;
int iBestTarget = hacks::shared::backtrack::iBestTarget;
if (iBestTarget == -1)
return true;
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])
{
bool good_tick = false;
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)
if (hacks::shared::backtrack::ValidTick(i, tar))
continue;
if (!i.hitboxes.at(head).center.z)
continue;
if (!good_tick)
continue;
if (!IsVectorVisible(g_pLocalPlayer->v_Eye, i.hitboxpos, true))
if (!IsVectorVisible(g_pLocalPlayer->v_Eye, i.hitboxes.at(head).center, true))
continue;
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);
float &simtime = CE_FLOAT(tar, netvar.m_flSimulationTime);
angles.y = i.viewangles;
simtime = i.simtime;
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;
VectorAngles(tr, angles2);
// Clamping is important

View File

@ -14,6 +14,7 @@
namespace hacks::tf2::autobackstab
{
namespace backtrack = hacks::shared::backtrack;
static settings::Bool enable{ "autobackstab.enable", "0" };
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
int ClosestDistanceHitbox(CachedEntity *target)
int ClosestDistanceHitbox(CachedEntity *target,
backtrack::BacktrackData btd = {})
{
int closest = -1;
float closest_dist = 0.0f, dist = 0.0f;
for (int i = spine_0; i < spine_3; i++)
{
dist =
g_pLocalPlayer->v_Eye.DistTo(target->hitboxes.GetHitbox(i)->center);
if (hacks::shared::backtrack::isBacktrackEnabled())
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)
{
closest = i;
@ -62,7 +66,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) >= 45)
NET_VECTOR(RAW_ENT(besttarget), netvar.m_angEyeAngles).y) >= 50)
return false;
if (!min.x && !max.x)
return false;
@ -124,36 +128,58 @@ void CreateMove()
if (!CanShoot())
return;
CachedEntity *besttarget = nullptr;
for (int i = 0; i < g_IEngine->GetMaxClients(); i++)
if (!backtrack::isBacktrackEnabled())
{
CachedEntity *target = ENTITY(i);
if (CE_BAD(target))
continue;
if (target == LOCAL_E || target->m_iTeam() == LOCAL_E->m_iTeam() ||
!target->m_bAlivePlayer() || target->m_Type() != ENTITY_PLAYER)
continue;
if (target->hitboxes.GetHitbox(spine_3)->center.DistTo(
g_pLocalPlayer->v_Eye) <= 300.0f)
for (int i = 0; i < g_IEngine->GetMaxClients(); i++)
{
if (CE_GOOD(besttarget))
CachedEntity *target = ENTITY(i);
if (CE_BAD(target))
continue;
if (target == LOCAL_E || target->m_iTeam() == LOCAL_E->m_iTeam() ||
!target->m_bAlivePlayer() || target->m_Type() != ENTITY_PLAYER)
continue;
if (target->hitboxes.GetHitbox(spine_3)->center.DistTo(
g_pLocalPlayer->v_Eye) <= 200.0f)
{
if (target->hitboxes.GetHitbox(spine_3)->center.DistTo(
g_pLocalPlayer->v_Eye) <
besttarget->hitboxes.GetHitbox(spine_3)->center.DistTo(
g_pLocalPlayer->v_Eye))
if (CE_GOOD(besttarget))
{
if (target->hitboxes.GetHitbox(spine_3)->center.DistTo(
g_pLocalPlayer->v_Eye) <
besttarget->hitboxes.GetHitbox(spine_3)->center.DistTo(
g_pLocalPlayer->v_Eye))
besttarget = target;
}
else
{
besttarget = target;
}
else
{
besttarget = target;
}
}
}
}
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))
{
hacks::shared::anti_anti_aim::resolveEnt(besttarget->m_IDX);
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)
{
@ -182,20 +208,13 @@ void CreateMove()
}
else
{
int idx = besttarget->m_IDX;
int tickcnt = 0;
for (auto i : hacks::shared::backtrack::headPositions[idx])
int idx = besttarget->m_IDX;
for (auto i : backtrack::headPositions[idx])
{
bool good_tick = false;
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)
if (!backtrack::ValidTick(i, besttarget))
continue;
backtrack::hitboxData &hitbox =
i.hitboxes.at(ClosestDistanceHitbox(besttarget, i));
// Check if we are inside the target (which will in most cases
// result in a failstab)
@ -206,17 +225,18 @@ void CreateMove()
g_pLocalPlayer->v_Origin);
// Get dist Z to Z
float halfHeight =
(i.spineMin.DistTo(
Vector{ i.spineMin.x, i.spineMin.y, i.spineMax.z })) /
(hitbox.min.DistTo(
Vector{ hitbox.min.x, hitbox.min.y, hitbox.max.z })) /
2;
// Make our first diagonal line
std::pair<Vector, Vector> line1(
{ i.spineMin.x, i.spineMin.y, i.spineMin.z + halfHeight },
{ i.spineMax.x, i.spineMax.y, i.spineMax.z - halfHeight });
{ hitbox.min.x, hitbox.min.y, hitbox.min.z + halfHeight },
{ hitbox.max.x, hitbox.max.y, hitbox.max.z - halfHeight });
// Make our second diagonal line
std::pair<Vector, Vector> line2(
{ line1.second.x, line1.first.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,
collidableMinMax.second, line1.first,
line1.second) ||
@ -224,10 +244,11 @@ void CreateMove()
collidableMinMax.second, line2.first,
line2.second))
continue;
for (angle.y = -180.0f; angle.y < 180.0f; angle.y += 20.0f)
{
if (unifiedCanBackstab(angle, i.spineMin, i.spineMax,
i.spine, besttarget))
if (unifiedCanBackstab(angle, hitbox.min, hitbox.max,
hitbox.center, besttarget))
{
current_user_cmd->tick_count = i.tickcount;
current_user_cmd->viewangles = angle;

View File

@ -12,7 +12,6 @@
#include <settings/Bool.hpp>
#include <hacks/Backtrack.hpp>
static settings::Bool enable{ "backtrack.enable", "false" };
static settings::Bool draw_bt{ "backtrack.draw", "false" };
static settings::Int latency{ "backtrack.latency", "0" };
@ -21,9 +20,9 @@ static settings::Int slots{ "backtrack.slots", "0" };
namespace hacks::shared::backtrack
{
void EmptyBacktrackData(BacktrackData &i);
std::pair<int, int> getBestEntBestTick();
BacktrackData headPositions[32][66]{};
BestTickData sorted_ticks[66]{};
int highesttick[32]{};
int lastincomingsequencenumber = 0;
static bool shouldDrawBt;
@ -65,10 +64,7 @@ void Init()
{
for (int i = 0; i < 32; i++)
for (int j = 0; j < 66; j++)
headPositions[i][j] = BacktrackData{
0, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
{ 0, 0, 0 }, { 0, 0, 0 }, 0, 0, { 0, 0, 0 }
};
EmptyBacktrackData(headPositions[i][j]);
}
int BestTick = 0;
@ -90,12 +86,13 @@ void Run()
CUserCmd *cmd = current_user_cmd;
float bestFov = 99999;
BestTick = 0;
iBestTarget = -1;
bool IsMelee = GetWeaponMode() == weapon_melee;
float prev_distance = 9999;
auto bestEntBestTick = getBestEntBestTick();
BestTick = bestEntBestTick.second;
iBestTarget = bestEntBestTick.first;
for (int i = 1; i < g_IEngine->GetMaxClients(); i++)
{
CachedEntity *pEntity = ENTITY(i);
@ -103,10 +100,7 @@ void Run()
if (CE_BAD(pEntity) || !pEntity->m_bAlivePlayer())
{
for (BacktrackData &btd : headPositions[i])
btd = BacktrackData{ 0, { 0, 0, 0 }, { 0, 0, 0 },
{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
{ 0, 0, 0 }, 0, 0,
{ 0, 0, 0 } };
EmptyBacktrackData(btd);
continue;
}
if (pEntity->m_iTeam() == LOCAL_E->m_iTeam())
@ -115,97 +109,42 @@ void Run()
continue;
if (!pEntity->hitboxes.GetHitbox(0))
continue;
Vector hitboxpos = pEntity->hitboxes.GetHitbox(0)->center;
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 = CE_VECTOR(pEntity, netvar.m_angEyeAngles).y;
float viewangles =
(_viewangles > 180) ? _viewangles - 360 : _viewangles;
float simtime = CE_FLOAT(pEntity, netvar.m_flSimulationTime);
Vector hitbox_spine = pEntity->hitboxes.GetHitbox(spine_3)->center;
Vector hitbox_min = pEntity->hitboxes.GetHitbox(spine_3)->min;
Vector hitbox_max = pEntity->hitboxes.GetHitbox(spine_3)->max;
Vector ent_orig = pEntity->InternalEntity()->GetAbsOrigin();
float simtime = CE_FLOAT(pEntity, netvar.m_flSimulationTime);
std::array<hitboxData, 18> hbdArray;
for (size_t i = 0; i < hbdArray.max_size(); i++)
{
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();
auto hdr = g_IModelInfo->GetStudiomodel(RAW_ENT(pEntity)->GetModel());
headPositions[i][cmd->command_number % getTicks()] =
BacktrackData{ cmd->tick_count, hitboxpos, min, max,
hitbox_spine, hitbox_min, hitbox_max, viewangles,
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;
}
BacktrackData{ cmd->tick_count, hbdArray, viewangles, simtime,
ent_orig };
}
if (iBestTarget != -1 && CanShoot())
{
int bestTick = 0;
float tempFOV = 9999;
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)
CachedEntity *tar = ENTITY(iBestTarget);
if (CE_GOOD(tar))
{
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)
if (cmd->buttons & IN_ATTACK)
{
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;
// ok just in case
if (CE_BAD(tar))
return;
auto i = headPositions[iBestTarget][BestTick];
cmd->tick_count = i.tickcount;
Vector &angles =
NET_VECTOR(RAW_ENT(tar), netvar.m_angEyeAngles);
float &simtime =
NET_FLOAT(RAW_ENT(tar), netvar.m_flSimulationTime);
angles.y = i.viewangles;
simtime = i.simtime;
}
else
{
if (bestFOV > tempFOV)
bestTick = t, bestFOV = tempFOV;
}
}
BestTick = bestTick;
if (cmd->buttons & IN_ATTACK)
{
CachedEntity *tar = ENTITY(iBestTarget);
// ok just in case
if (CE_BAD(tar))
return;
auto i = headPositions[iBestTarget][bestTick];
cmd->tick_count = i.tickcount;
Vector &angles = NET_VECTOR(RAW_ENT(tar), netvar.m_angEyeAngles);
float &simtime = NET_FLOAT(RAW_ENT(tar), netvar.m_flSimulationTime);
angles.y = i.viewangles;
simtime = i.simtime;
}
}
}
@ -218,22 +157,18 @@ void Draw()
return;
if (!shouldDrawBt)
return;
int tickus = getTicks2();
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++)
{
bool good_tick = false;
for (int i = 0; i < tickus; ++i)
if (j == sorted_ticks[i].tick)
good_tick = true;
if (!good_tick)
if (!ValidTick(headPositions[i][j], ent))
continue;
auto hbpos = headPositions[i][j].hitboxpos;
auto tickount = headPositions[i][j].tickcount;
auto min = headPositions[i][j].min;
auto max = headPositions[i][j].max;
auto hbpos = headPositions[i][j].hitboxes.at(head).center;
auto min = headPositions[i][j].hitboxes.at(head).min;
auto max = headPositions[i][j].hitboxes.at(head).max;
if (!hbpos.x && !hbpos.y && !hbpos.z)
continue;
Vector out;
@ -306,13 +241,87 @@ float getLatency()
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 (*latency > 800 || *latency < 200) ? 12 : 24;
return 12;
return fabsf(NET_FLOAT(RAW_ENT(ent), netvar.m_flSimulationTime) * 1000.0f -
getLatency() - i.simtime * 1000.0f) < 200.0f;
}
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

View File

@ -41,21 +41,15 @@ int last_hb_traced = 0;
Vector forward;
bool CanBacktrack()
{
int target = hacks::shared::backtrack::iBestTarget;
int tickcnt = 0;
int tickus = hacks::shared::backtrack::getTicks2();
for (auto i : hacks::shared::backtrack::headPositions[target])
CachedEntity *tar = ENTITY(hacks::shared::backtrack::iBestTarget);
if (CE_BAD(tar))
return false;
for (auto i : hacks::shared::backtrack::headPositions[tar->m_IDX])
{
bool good_tick = false;
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)
if(!hacks::shared::backtrack::ValidTick(i, tar))
continue;
auto min = i.min;
auto max = i.max;
auto min = i.hitboxes.at(head).min;
auto max = i.hitboxes.at(head).max;
if (!min.x && !max.x)
continue;
@ -83,10 +77,6 @@ bool CanBacktrack()
continue;
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);
float &simtime = NET_FLOAT(RAW_ENT(tar), netvar.m_flSimulationTime);
angles.y = i.viewangles;