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);
|
||||
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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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];
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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"
|
||||
|
@ -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))
|
||||
{
|
||||
|
@ -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, ...)
|
||||
|
Reference in New Issue
Block a user