Compensate for weapon shot offsets
Some weapons do not shoot centered and in some cases need to have their vischecks done from that offset
This commit is contained in:
parent
9a29df6262
commit
87863e495d
@ -99,7 +99,7 @@ void AngleVectors3(const QAngle &angles, Vector *forward, Vector *right, Vector
|
|||||||
bool isRapidFire(IClientEntity *wep);
|
bool isRapidFire(IClientEntity *wep);
|
||||||
extern std::mutex trace_lock;
|
extern std::mutex trace_lock;
|
||||||
bool IsEntityVisible(CachedEntity *entity, int hb);
|
bool IsEntityVisible(CachedEntity *entity, int hb);
|
||||||
bool IsEntityVectorVisible(CachedEntity *entity, Vector endpos, unsigned int mask = MASK_SHOT_HULL, trace_t *trace = nullptr);
|
bool IsEntityVectorVisible(CachedEntity *entity, Vector endpos, bool use_weapon_offset = false, unsigned int mask = MASK_SHOT_HULL, trace_t *trace = nullptr);
|
||||||
bool VisCheckEntFromEnt(CachedEntity *startEnt, CachedEntity *endEnt);
|
bool VisCheckEntFromEnt(CachedEntity *startEnt, CachedEntity *endEnt);
|
||||||
bool VisCheckEntFromEntVector(Vector startVector, CachedEntity *startEnt, CachedEntity *endEnt);
|
bool VisCheckEntFromEntVector(Vector startVector, CachedEntity *startEnt, CachedEntity *endEnt);
|
||||||
Vector VischeckCorner(CachedEntity *player, CachedEntity *target, float maxdist, bool checkWalkable);
|
Vector VischeckCorner(CachedEntity *player, CachedEntity *target, float maxdist, bool checkWalkable);
|
||||||
@ -117,6 +117,7 @@ bool GetProjectileData(CachedEntity *weapon, float &speed, float &gravity);
|
|||||||
bool IsVectorVisible(Vector a, Vector b, bool enviroment_only = false, CachedEntity *self = LOCAL_E, unsigned int mask = MASK_SHOT_HULL);
|
bool IsVectorVisible(Vector a, Vector b, bool enviroment_only = false, CachedEntity *self = LOCAL_E, unsigned int mask = MASK_SHOT_HULL);
|
||||||
// A Special function for navparser to check if a Vector is visible.
|
// A Special function for navparser to check if a Vector is visible.
|
||||||
bool IsVectorVisibleNavigation(Vector a, Vector b, unsigned int mask = MASK_SHOT_HULL);
|
bool IsVectorVisibleNavigation(Vector a, Vector b, unsigned int mask = MASK_SHOT_HULL);
|
||||||
|
Vector getShootPos(Vector angle);
|
||||||
Vector GetForwardVector(Vector origin, Vector viewangles, float distance, CachedEntity *punch_entity = nullptr);
|
Vector GetForwardVector(Vector origin, Vector viewangles, float distance, CachedEntity *punch_entity = nullptr);
|
||||||
Vector GetForwardVector(float distance, CachedEntity *punch_entity = nullptr);
|
Vector GetForwardVector(float distance, CachedEntity *punch_entity = nullptr);
|
||||||
CachedEntity *getClosestEntity(Vector vec);
|
CachedEntity *getClosestEntity(Vector vec);
|
||||||
|
@ -86,7 +86,7 @@ bool CachedEntity::IsVisible()
|
|||||||
if (m_bVisCheckComplete)
|
if (m_bVisCheckComplete)
|
||||||
return m_bAnyHitboxVisible;
|
return m_bAnyHitboxVisible;
|
||||||
|
|
||||||
vischeck0 = IsEntityVectorVisible(this, m_vecOrigin());
|
vischeck0 = IsEntityVectorVisible(this, m_vecOrigin(), true);
|
||||||
|
|
||||||
if (vischeck0)
|
if (vischeck0)
|
||||||
{
|
{
|
||||||
|
@ -96,7 +96,7 @@ bool EntityHitboxCache::VisibilityCheck(int id)
|
|||||||
hitbox = GetHitbox(id);
|
hitbox = GetHitbox(id);
|
||||||
if (!hitbox)
|
if (!hitbox)
|
||||||
return false;
|
return false;
|
||||||
m_VisCheck[id] = (IsEntityVectorVisible(parent_ref, hitbox->center));
|
m_VisCheck[id] = (IsEntityVectorVisible(parent_ref, hitbox->center, true));
|
||||||
m_VisCheckValidationFlags[id] = true;
|
m_VisCheckValidationFlags[id] = true;
|
||||||
return m_VisCheck[id];
|
return m_VisCheck[id];
|
||||||
}
|
}
|
||||||
|
@ -180,7 +180,7 @@ bool aimbotTickFilter(CachedEntity *ent, hacks::tf2::backtrack::BacktrackData ti
|
|||||||
if (g_pLocalPlayer->weapon_mode != weapon_hitscan)
|
if (g_pLocalPlayer->weapon_mode != weapon_hitscan)
|
||||||
return true;
|
return true;
|
||||||
// Return visibility
|
// Return visibility
|
||||||
return IsEntityVectorVisible(ent, tick.hitboxes.at(head).center, MASK_SHOT);
|
return IsEntityVectorVisible(ent, tick.hitboxes.at(head).center, true, MASK_SHOT);
|
||||||
}
|
}
|
||||||
static void doAutoZoom(bool target_found)
|
static void doAutoZoom(bool target_found)
|
||||||
{
|
{
|
||||||
@ -888,8 +888,8 @@ void Aim(CachedEntity *entity)
|
|||||||
if (CE_BAD(entity))
|
if (CE_BAD(entity))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Get angles
|
// Get angles from eye to target
|
||||||
Vector angles = GetAimAtAngles(g_pLocalPlayer->v_Eye, PredictEntity(entity), LOCAL_E);
|
Vector angles = GetAimAtAngles(g_pLocalPlayer->v_Eye, PredictEntity(entity));
|
||||||
|
|
||||||
// Multipoint
|
// Multipoint
|
||||||
if (multipoint && !projectile_mode)
|
if (multipoint && !projectile_mode)
|
||||||
@ -931,9 +931,9 @@ void Aim(CachedEntity *entity)
|
|||||||
// Create Vectors
|
// Create Vectors
|
||||||
const Vector positions[13] = { { minx, centery, minz }, { maxx, centery, minz }, { minx, centery, maxz }, { maxx, centery, maxz }, { centerx, miny, minz }, { centerx, maxy, minz }, { centerx, miny, maxz }, { centerx, maxy, maxz }, { minx, miny, centerz }, { maxx, maxy, centerz }, { minx, miny, centerz }, { maxx, maxy, centerz }, hitboxcenter };
|
const Vector positions[13] = { { minx, centery, minz }, { maxx, centery, minz }, { minx, centery, maxz }, { maxx, centery, maxz }, { centerx, miny, minz }, { centerx, maxy, minz }, { centerx, miny, maxz }, { centerx, maxy, maxz }, { minx, miny, centerz }, { maxx, maxy, centerz }, { minx, miny, centerz }, { maxx, maxy, centerz }, hitboxcenter };
|
||||||
for (int i = 0; i < 13; ++i)
|
for (int i = 0; i < 13; ++i)
|
||||||
if (IsEntityVectorVisible(entity, positions[i]))
|
if (IsEntityVectorVisible(entity, positions[i], true))
|
||||||
{
|
{
|
||||||
angles = GetAimAtAngles(g_pLocalPlayer->v_Eye, positions[i], LOCAL_E);
|
angles = GetAimAtAngles(g_pLocalPlayer->v_Eye, positions[i]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1264,17 +1264,17 @@ int BestHitbox(CachedEntity *target)
|
|||||||
if (data)
|
if (data)
|
||||||
{
|
{
|
||||||
// First check preferred hitbox
|
// First check preferred hitbox
|
||||||
if (IsEntityVectorVisible(target, (*data).hitboxes[preferred].center))
|
if (IsEntityVectorVisible(target, (*data).hitboxes[preferred].center, false))
|
||||||
return preferred;
|
return preferred;
|
||||||
|
|
||||||
// Then check the rest
|
// Then check the rest
|
||||||
if (*backtrackVischeckAll)
|
if (*backtrackVischeckAll)
|
||||||
for (int j = head; j < foot_R; j++)
|
for (int j = head; j < foot_R; j++)
|
||||||
{
|
{
|
||||||
if (IsEntityVectorVisible(target, (*data).hitboxes[j].center))
|
if (IsEntityVectorVisible(target, (*data).hitboxes[j].center, false))
|
||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
else if (IsEntityVectorVisible(target, (*data).hitboxes.at(head).center))
|
else if (IsEntityVectorVisible(target, (*data).hitboxes.at(head).center, false))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// Nothing found, falling through to further below
|
// Nothing found, falling through to further below
|
||||||
@ -1341,11 +1341,11 @@ bool VischeckPredictedEntity(CachedEntity *entity)
|
|||||||
// Update info
|
// Update info
|
||||||
cd.vcheck_tick = tickcount;
|
cd.vcheck_tick = tickcount;
|
||||||
if (extrapolate || projectileAimbotRequired || entity->m_Type() != ENTITY_PLAYER)
|
if (extrapolate || projectileAimbotRequired || entity->m_Type() != ENTITY_PLAYER)
|
||||||
cd.visible = IsEntityVectorVisible(entity, PredictEntity(entity));
|
cd.visible = IsEntityVectorVisible(entity, PredictEntity(entity), true);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
trace_t trace;
|
trace_t trace;
|
||||||
cd.visible = IsEntityVectorVisible(entity, PredictEntity(entity), MASK_SHOT, &trace);
|
cd.visible = IsEntityVectorVisible(entity, PredictEntity(entity), false, MASK_SHOT, &trace);
|
||||||
if (cd.visible && cd.hitbox == head && trace.hitbox != head)
|
if (cd.visible && cd.hitbox == head && trace.hitbox != head)
|
||||||
cd.visible = false;
|
cd.visible = false;
|
||||||
}
|
}
|
||||||
@ -1353,7 +1353,7 @@ bool VischeckPredictedEntity(CachedEntity *entity)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto data = hacks::tf2::backtrack::getClosestEntTick(entity, LOCAL_E->m_vecOrigin(), aimbotTickFilter);
|
auto data = hacks::tf2::backtrack::getClosestEntTick(entity, LOCAL_E->m_vecOrigin(), aimbotTickFilter);
|
||||||
if (data && IsEntityVectorVisible(entity, data->hitboxes.at((cd.hitbox == -1 || cd.hitbox >= 18) ? 0 : cd.hitbox).center, MASK_SHOT))
|
if (data && IsEntityVectorVisible(entity, data->hitboxes.at((cd.hitbox == -1 || cd.hitbox >= 18) ? 0 : cd.hitbox).center, false, MASK_SHOT))
|
||||||
cd.visible = true;
|
cd.visible = true;
|
||||||
else
|
else
|
||||||
cd.visible = false;
|
cd.visible = false;
|
||||||
|
@ -474,7 +474,7 @@ bool defaultTickFilter(CachedEntity *ent, BacktrackData tick)
|
|||||||
if (g_pLocalPlayer->weapon_mode != weapon_hitscan)
|
if (g_pLocalPlayer->weapon_mode != weapon_hitscan)
|
||||||
return true;
|
return true;
|
||||||
// Return visibility
|
// Return visibility
|
||||||
return IsEntityVectorVisible(ent, tick.hitboxes.at(head).center, MASK_SHOT);
|
return IsEntityVectorVisible(ent, tick.hitboxes.at(head).center, true, MASK_SHOT);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool defaultEntFilter(CachedEntity *ent)
|
bool defaultEntFilter(CachedEntity *ent)
|
||||||
|
@ -3,6 +3,7 @@ set(files "${CMAKE_CURRENT_LIST_DIR}/AutoJoin.cpp"
|
|||||||
"${CMAKE_CURRENT_LIST_DIR}/Spam.cpp"
|
"${CMAKE_CURRENT_LIST_DIR}/Spam.cpp"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/Achievement.cpp"
|
"${CMAKE_CURRENT_LIST_DIR}/Achievement.cpp"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/Aimbot.cpp"
|
"${CMAKE_CURRENT_LIST_DIR}/Aimbot.cpp"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/AutoViewmodel.cpp"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/MiscAimbot.cpp"
|
"${CMAKE_CURRENT_LIST_DIR}/MiscAimbot.cpp"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/Announcer.cpp"
|
"${CMAKE_CURRENT_LIST_DIR}/Announcer.cpp"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/AntiAim.cpp"
|
"${CMAKE_CURRENT_LIST_DIR}/AntiAim.cpp"
|
||||||
|
@ -310,7 +310,7 @@ static void SapperAimbot()
|
|||||||
Vector angle = GetAimAtAngles(g_pLocalPlayer->v_Eye, GetBuildingPosition(target));
|
Vector angle = GetAimAtAngles(g_pLocalPlayer->v_Eye, GetBuildingPosition(target));
|
||||||
Vector forward = GetForwardVector(g_pLocalPlayer->v_Eye, angle, range, LOCAL_E);
|
Vector forward = GetForwardVector(g_pLocalPlayer->v_Eye, angle, range, LOCAL_E);
|
||||||
trace_t trace;
|
trace_t trace;
|
||||||
if (IsEntityVectorVisible(target, forward, MASK_SHOT, &trace))
|
if (IsEntityVectorVisible(target, forward, false, MASK_SHOT, &trace))
|
||||||
{
|
{
|
||||||
if (trace.DidHit() && (IClientEntity *) trace.m_pEnt == RAW_ENT(target))
|
if (trace.DidHit() && (IClientEntity *) trace.m_pEnt == RAW_ENT(target))
|
||||||
{
|
{
|
||||||
@ -540,7 +540,7 @@ static void BuildingAimbot()
|
|||||||
|
|
||||||
trace_t trace;
|
trace_t trace;
|
||||||
|
|
||||||
if (IsEntityVectorVisible(target, forward, MASK_SHOT, &trace))
|
if (IsEntityVectorVisible(target, forward, false, MASK_SHOT, &trace))
|
||||||
{
|
{
|
||||||
if (trace.DidHit() && (IClientEntity *) trace.m_pEnt == RAW_ENT(target))
|
if (trace.DidHit() && (IClientEntity *) trace.m_pEnt == RAW_ENT(target))
|
||||||
{
|
{
|
||||||
|
@ -1005,7 +1005,7 @@ bool IsEntityVisible(CachedEntity *entity, int hb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::mutex trace_lock;
|
std::mutex trace_lock;
|
||||||
bool IsEntityVectorVisible(CachedEntity *entity, Vector endpos, unsigned int mask, trace_t *trace)
|
bool IsEntityVectorVisible(CachedEntity *entity, Vector endpos, bool use_weapon_offset, unsigned int mask, trace_t *trace)
|
||||||
{
|
{
|
||||||
trace_t trace_object;
|
trace_t trace_object;
|
||||||
if (!trace)
|
if (!trace)
|
||||||
@ -1021,14 +1021,18 @@ bool IsEntityVectorVisible(CachedEntity *entity, Vector endpos, unsigned int mas
|
|||||||
if (CE_BAD(entity))
|
if (CE_BAD(entity))
|
||||||
return false;
|
return false;
|
||||||
trace::filter_default.SetSelf(RAW_ENT(g_pLocalPlayer->entity));
|
trace::filter_default.SetSelf(RAW_ENT(g_pLocalPlayer->entity));
|
||||||
ray.Init(g_pLocalPlayer->v_Eye, endpos);
|
Vector eye = g_pLocalPlayer->v_Eye;
|
||||||
|
// Adjust for weapon offsets if needed
|
||||||
|
if (use_weapon_offset)
|
||||||
|
eye = getShootPos(GetAimAtAngles(eye, endpos, LOCAL_E));
|
||||||
|
ray.Init(eye, endpos);
|
||||||
{
|
{
|
||||||
PROF_SECTION(IEVV_TraceRay);
|
PROF_SECTION(IEVV_TraceRay);
|
||||||
std::lock_guard<std::mutex> lock(trace_lock);
|
std::lock_guard<std::mutex> lock(trace_lock);
|
||||||
if (!tcm || g_Settings.is_create_move)
|
if (!tcm || g_Settings.is_create_move)
|
||||||
g_ITrace->TraceRay(ray, mask, &trace::filter_default, trace);
|
g_ITrace->TraceRay(ray, mask, &trace::filter_default, trace);
|
||||||
}
|
}
|
||||||
return (((IClientEntity *) trace->m_pEnt) == RAW_ENT(entity) || trace->fraction >= 0.99f);
|
return (((IClientEntity *) trace->m_pEnt) == RAW_ENT(entity) || !trace->DidHit());
|
||||||
}
|
}
|
||||||
|
|
||||||
// For when you need to vis check something that isnt the local player
|
// For when you need to vis check something that isnt the local player
|
||||||
@ -1729,6 +1733,90 @@ void PrintChat(const char *fmt, ...)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the point Your shots originate from
|
||||||
|
Vector getShootPos(Vector angle)
|
||||||
|
{
|
||||||
|
Vector eye = g_pLocalPlayer->v_Eye;
|
||||||
|
if (g_pLocalPlayer->weapon_mode != weapon_projectile || CE_BAD(LOCAL_W))
|
||||||
|
return eye;
|
||||||
|
|
||||||
|
Vector forward, right, up;
|
||||||
|
AngleVectors3(VectorToQAngle(angle), &forward, &right, &up);
|
||||||
|
|
||||||
|
std::optional<Vector> vecOffset(0.0f);
|
||||||
|
switch (LOCAL_W->m_iClassID())
|
||||||
|
{
|
||||||
|
// Rocket launchers and flare guns/Pomson
|
||||||
|
case CL_CLASS(CTFRocketLauncher):
|
||||||
|
case CL_CLASS(CTFRocketLauncher_Mortar):
|
||||||
|
case CL_CLASS(CTFRocketLauncher_AirStrike):
|
||||||
|
case CL_CLASS(CTFRocketLauncher_DirectHit):
|
||||||
|
case CL_CLASS(CTFFlareGun):
|
||||||
|
case CL_CLASS(CTFFlareGun_Revenge):
|
||||||
|
case CL_CLASS(CTFDRGPomson):
|
||||||
|
// The original shoots centered, rest doesn't
|
||||||
|
if (CE_INT(LOCAL_W, netvar.iItemDefinitionIndex) != 513)
|
||||||
|
{
|
||||||
|
vecOffset = Vector(23.5f, 12.0f, -3.0f);
|
||||||
|
// Ducking changes offset
|
||||||
|
if (CE_INT(LOCAL_E, netvar.iFlags) & FL_DUCKING)
|
||||||
|
vecOffset->z = 8.0f;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Pill/Pipebomb launchers
|
||||||
|
case CL_CLASS(CTFPipebombLauncher):
|
||||||
|
case CL_CLASS(CTFGrenadeLauncher):
|
||||||
|
case CL_CLASS(CTFCannon):
|
||||||
|
vecOffset = Vector(16.0f, 8.0f, -6.0f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CL_CLASS(CTFSyringeGun):
|
||||||
|
vecOffset = Vector(16.0f, 6.0f, -8.0f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Huntsman
|
||||||
|
case CL_CLASS(CTFCompoundBow):
|
||||||
|
vecOffset = Vector(23.5f, -8.0f, -3.0f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have an offset for the weapon that may or may not need to be applied
|
||||||
|
if (vecOffset)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Game checks 2000 HU infront of eye for a hit
|
||||||
|
static const float distance = 2000.0f;
|
||||||
|
|
||||||
|
Vector endpos = eye + (forward * distance);
|
||||||
|
|
||||||
|
trace_t tr;
|
||||||
|
Ray_t ray;
|
||||||
|
|
||||||
|
trace::filter_default.SetSelf(RAW_ENT(g_pLocalPlayer->entity));
|
||||||
|
ray.Init(eye, endpos);
|
||||||
|
if (!tcm || g_Settings.is_create_move)
|
||||||
|
g_ITrace->TraceRay(ray, MASK_SOLID, &trace::filter_default, &tr);
|
||||||
|
|
||||||
|
// Replicate game behaviour, only use the offset if our trace has a big enough fraction
|
||||||
|
if (tr.fraction <= 0.1)
|
||||||
|
{
|
||||||
|
// Flipped viewmodels flip the y
|
||||||
|
if (re::C_TFWeaponBase::IsViewModelFlipped(RAW_ENT(LOCAL_W)))
|
||||||
|
vecOffset->y *= -1.0f;
|
||||||
|
eye = eye + (forward * vecOffset->x) + (right * vecOffset->y) + (up * vecOffset->z);
|
||||||
|
// They decided to do this weird stuff for the pomson instead of fixing their offset
|
||||||
|
if (LOCAL_W->m_iClassID() == CL_CLASS(CTFDRGPomson))
|
||||||
|
eye.z -= 13.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return eye;
|
||||||
|
}
|
||||||
|
|
||||||
// You shouldn't delete[] this unique_ptr since it
|
// You shouldn't delete[] this unique_ptr since it
|
||||||
// does it on its own
|
// does it on its own
|
||||||
std::unique_ptr<char[]> strfmt(const char *fmt, ...)
|
std::unique_ptr<char[]> strfmt(const char *fmt, ...)
|
||||||
|
Reference in New Issue
Block a user