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:
BenCat07 2020-09-02 21:09:57 +02:00 committed by LightCat
parent 9a29df6262
commit 87863e495d
8 changed files with 110 additions and 20 deletions

View File

@ -99,7 +99,7 @@ void AngleVectors3(const QAngle &angles, Vector *forward, Vector *right, Vector
bool isRapidFire(IClientEntity *wep);
extern std::mutex trace_lock;
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 VisCheckEntFromEntVector(Vector startVector, CachedEntity *startEnt, CachedEntity *endEnt);
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);
// A Special function for navparser to check if a Vector is visible.
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(float distance, CachedEntity *punch_entity = nullptr);
CachedEntity *getClosestEntity(Vector vec);

View File

@ -86,7 +86,7 @@ bool CachedEntity::IsVisible()
if (m_bVisCheckComplete)
return m_bAnyHitboxVisible;
vischeck0 = IsEntityVectorVisible(this, m_vecOrigin());
vischeck0 = IsEntityVectorVisible(this, m_vecOrigin(), true);
if (vischeck0)
{

View File

@ -96,7 +96,7 @@ bool EntityHitboxCache::VisibilityCheck(int id)
hitbox = GetHitbox(id);
if (!hitbox)
return false;
m_VisCheck[id] = (IsEntityVectorVisible(parent_ref, hitbox->center));
m_VisCheck[id] = (IsEntityVectorVisible(parent_ref, hitbox->center, true));
m_VisCheckValidationFlags[id] = true;
return m_VisCheck[id];
}

View File

@ -180,7 +180,7 @@ bool aimbotTickFilter(CachedEntity *ent, hacks::tf2::backtrack::BacktrackData ti
if (g_pLocalPlayer->weapon_mode != weapon_hitscan)
return true;
// 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)
{
@ -888,8 +888,8 @@ void Aim(CachedEntity *entity)
if (CE_BAD(entity))
return;
// Get angles
Vector angles = GetAimAtAngles(g_pLocalPlayer->v_Eye, PredictEntity(entity), LOCAL_E);
// Get angles from eye to target
Vector angles = GetAimAtAngles(g_pLocalPlayer->v_Eye, PredictEntity(entity));
// Multipoint
if (multipoint && !projectile_mode)
@ -931,9 +931,9 @@ void Aim(CachedEntity *entity)
// 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 };
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;
}
}
@ -1264,17 +1264,17 @@ int BestHitbox(CachedEntity *target)
if (data)
{
// First check preferred hitbox
if (IsEntityVectorVisible(target, (*data).hitboxes[preferred].center))
if (IsEntityVectorVisible(target, (*data).hitboxes[preferred].center, false))
return preferred;
// Then check the rest
if (*backtrackVischeckAll)
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;
}
else if (IsEntityVectorVisible(target, (*data).hitboxes.at(head).center))
else if (IsEntityVectorVisible(target, (*data).hitboxes.at(head).center, false))
return 0;
}
// Nothing found, falling through to further below
@ -1341,11 +1341,11 @@ bool VischeckPredictedEntity(CachedEntity *entity)
// Update info
cd.vcheck_tick = tickcount;
if (extrapolate || projectileAimbotRequired || entity->m_Type() != ENTITY_PLAYER)
cd.visible = IsEntityVectorVisible(entity, PredictEntity(entity));
cd.visible = IsEntityVectorVisible(entity, PredictEntity(entity), true);
else
{
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)
cd.visible = false;
}
@ -1353,7 +1353,7 @@ bool VischeckPredictedEntity(CachedEntity *entity)
else
{
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;
else
cd.visible = false;

View File

@ -474,7 +474,7 @@ bool defaultTickFilter(CachedEntity *ent, BacktrackData tick)
if (g_pLocalPlayer->weapon_mode != weapon_hitscan)
return true;
// 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)

View File

@ -3,6 +3,7 @@ set(files "${CMAKE_CURRENT_LIST_DIR}/AutoJoin.cpp"
"${CMAKE_CURRENT_LIST_DIR}/Spam.cpp"
"${CMAKE_CURRENT_LIST_DIR}/Achievement.cpp"
"${CMAKE_CURRENT_LIST_DIR}/Aimbot.cpp"
"${CMAKE_CURRENT_LIST_DIR}/AutoViewmodel.cpp"
"${CMAKE_CURRENT_LIST_DIR}/MiscAimbot.cpp"
"${CMAKE_CURRENT_LIST_DIR}/Announcer.cpp"
"${CMAKE_CURRENT_LIST_DIR}/AntiAim.cpp"

View File

@ -310,7 +310,7 @@ static void SapperAimbot()
Vector angle = GetAimAtAngles(g_pLocalPlayer->v_Eye, GetBuildingPosition(target));
Vector forward = GetForwardVector(g_pLocalPlayer->v_Eye, angle, range, LOCAL_E);
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))
{
@ -540,7 +540,7 @@ static void BuildingAimbot()
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))
{

View File

@ -1005,7 +1005,7 @@ bool IsEntityVisible(CachedEntity *entity, int hb)
}
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;
if (!trace)
@ -1021,14 +1021,18 @@ bool IsEntityVectorVisible(CachedEntity *entity, Vector endpos, unsigned int mas
if (CE_BAD(entity))
return false;
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);
std::lock_guard<std::mutex> lock(trace_lock);
if (!tcm || g_Settings.is_create_move)
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
@ -1729,6 +1733,90 @@ void PrintChat(const char *fmt, ...)
#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
// does it on its own
std::unique_ptr<char[]> strfmt(const char *fmt, ...)