From 87863e495d5a8174e4509761578707d7abbcd176 Mon Sep 17 00:00:00 2001 From: BenCat07 Date: Wed, 2 Sep 2020 21:09:57 +0200 Subject: [PATCH] Compensate for weapon shot offsets Some weapons do not shoot centered and in some cases need to have their vischecks done from that offset --- include/helpers.hpp | 3 +- src/entitycache.cpp | 2 +- src/entityhitboxcache.cpp | 2 +- src/hacks/Aimbot.cpp | 22 ++++----- src/hacks/Backtrack.cpp | 2 +- src/hacks/CMakeLists.txt | 1 + src/hacks/MiscAimbot.cpp | 4 +- src/helpers.cpp | 94 +++++++++++++++++++++++++++++++++++++-- 8 files changed, 110 insertions(+), 20 deletions(-) diff --git a/include/helpers.hpp b/include/helpers.hpp index 5a286075..98887813 100644 --- a/include/helpers.hpp +++ b/include/helpers.hpp @@ -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); diff --git a/src/entitycache.cpp b/src/entitycache.cpp index 4d8d1128..b3601fb2 100644 --- a/src/entitycache.cpp +++ b/src/entitycache.cpp @@ -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) { diff --git a/src/entityhitboxcache.cpp b/src/entityhitboxcache.cpp index d1025445..1791ca25 100644 --- a/src/entityhitboxcache.cpp +++ b/src/entityhitboxcache.cpp @@ -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]; } diff --git a/src/hacks/Aimbot.cpp b/src/hacks/Aimbot.cpp index 5c100f74..7d866e4e 100644 --- a/src/hacks/Aimbot.cpp +++ b/src/hacks/Aimbot.cpp @@ -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; diff --git a/src/hacks/Backtrack.cpp b/src/hacks/Backtrack.cpp index 6e9c5bab..821da505 100644 --- a/src/hacks/Backtrack.cpp +++ b/src/hacks/Backtrack.cpp @@ -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) diff --git a/src/hacks/CMakeLists.txt b/src/hacks/CMakeLists.txt index c97a0128..4ed45a94 100755 --- a/src/hacks/CMakeLists.txt +++ b/src/hacks/CMakeLists.txt @@ -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" diff --git a/src/hacks/MiscAimbot.cpp b/src/hacks/MiscAimbot.cpp index c3ac6abe..aee624e5 100644 --- a/src/hacks/MiscAimbot.cpp +++ b/src/hacks/MiscAimbot.cpp @@ -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)) { diff --git a/src/helpers.cpp b/src/helpers.cpp index e9ce8819..cffaea2c 100644 --- a/src/helpers.cpp +++ b/src/helpers.cpp @@ -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 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 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 strfmt(const char *fmt, ...)