rework splash bot some for optimization purposes

+ experimental splash mode for rockets (off by default, can be turned on in debug)
misc changes and fixes
This commit is contained in:
rei-2 committed 2024-10-16 22:40:45 -04:00
1 parent 8dfc7abf06
commit ad5ac0f596
31 files changed
+690 -548

No files matched your search

+1
View File
@@ -529,6 +529,7 @@
<ClCompile Include="src\Hooks\Direct3DDevice9.cpp" />
<ClCompile Include="src\Hooks\DoEnginePostProcessing.cpp" />
<ClCompile Include="src\Hooks\DSP_Process.cpp" />
<ClCompile Include="src\Hooks\IEngineTrace_TraceRay.cpp" />
<ClCompile Include="src\Hooks\ISteamNetworkingUtils_GetDirectPingToPOP.cpp" />
<ClCompile Include="src\Hooks\IVEngineClient_ClientCmd_Unrestricted.cpp" />
<ClCompile Include="src\Hooks\IEngineVGui_Paint.cpp" />
+1
View File
@@ -172,6 +172,7 @@
<ClCompile Include="src\Hooks\CPlayerResource_GetPlayerName.cpp" />
<ClCompile Include="src\Hooks\CTFGCClientSystem_UpdateAssignedLobby.cpp" />
<ClCompile Include="src\Hooks\CTFBadgePanel_SetupBadge.cpp" />
<ClCompile Include="src\Hooks\IEngineTrace_TraceRay.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\Utils\UtlVector\UtlVector.h" />
@@ -2,7 +2,7 @@
#include "../../Players/PlayerUtils.h"
void CAimbotGlobal::SortTargets(std::vector<Target_t>* targets, const ESortMethod& method)
void CAimbotGlobal::SortTargets(std::vector<Target_t>* targets, ESortMethod method)
{ // Sort by preference
std::sort((*targets).begin(), (*targets).end(), [&](const Target_t& a, const Target_t& b) -> bool
{
@@ -23,61 +23,186 @@ void CAimbotGlobal::SortPriority(std::vector<Target_t>* targets)
});
}
bool CAimbotGlobal::ShouldIgnore(CTFPlayer* pTarget, CTFPlayer* pLocal, CTFWeaponBase* pWeapon)
// this won't prevent shooting bones outside of fov
bool CAimbotGlobal::PlayerBoneInFOV(CTFPlayer* pTarget, Vec3 vLocalPos, Vec3 vLocalAngles, float& flFOVTo, Vec3& vPos, Vec3& vAngleTo)
{
PlayerInfo_t pi{};
if (!pTarget || pTarget == pLocal || pTarget->IsDormant())
return true;
if (!I::EngineClient->GetPlayerInfo(pTarget->entindex(), &pi))
return true;
bool bReturn = false;
if (pLocal->m_iTeamNum() == pTarget->m_iTeamNum())
return false;
float flMinFOV = 180.f;
for (int nHitbox = 0; nHitbox < pTarget->GetNumOfHitboxes(); nHitbox++)
{
if (!IsHitboxValid(nHitbox))
continue;
if (Vars::Aimbot::General::Ignore.Value & INVUL && pTarget->IsInvulnerable())
{
if (pWeapon->m_iItemDefinitionIndex() != Heavy_t_TheHolidayPunch)
return true;
}
if (Vars::Aimbot::General::Ignore.Value & CLOAKED && pTarget->IsInvisible())
{
if (pTarget->GetInvisPercentage() >= Vars::Aimbot::General::IgnoreCloakPercentage.Value)
return true;
}
if (Vars::Aimbot::General::Ignore.Value & DEADRINGER && pTarget->m_bFeignDeathReady())
return true;
if (Vars::Aimbot::General::Ignore.Value & TAUNTING && pTarget->IsTaunting())
return true;
if (Vars::Aimbot::General::Ignore.Value & VACCINATOR)
{
switch (G::PrimaryWeaponType)
Vec3 vCurPos = pTarget->GetHitboxCenter(nHitbox);
Vec3 vCurAngleTo = Math::CalcAngle(vLocalPos, vCurPos);
float flCurFOVTo = Math::CalcFov(vLocalAngles, vCurAngleTo);
if (flCurFOVTo < flMinFOV && flCurFOVTo < Vars::Aimbot::General::AimFOV.Value)
{
case EWeaponType::HITSCAN:
if (pTarget->IsBulletResist() && pWeapon->m_iItemDefinitionIndex() != Spy_m_TheEnforcer)
return true;
break;
case EWeaponType::PROJECTILE:
switch (pWeapon->GetWeaponID())
{
case TF_WEAPON_FLAMETHROWER:
case TF_WEAPON_FLAREGUN:
return pTarget->IsFireResist();
case TF_WEAPON_COMPOUND_BOW:
return pTarget->IsBulletResist();
default:
return pTarget->IsBlastResist();
}
bReturn = true;
vPos = vCurPos;
vAngleTo = vCurAngleTo;
flFOVTo = flMinFOV = flCurFOVTo;
}
}
if (Vars::Aimbot::General::Ignore.Value & DISGUISED && pTarget->IsDisguised())
return true;
if (F::PlayerUtils.IsIgnored(pi.friendsID))
return true;
return bReturn;
}
bool CAimbotGlobal::IsHitboxValid(int nHitbox)
{
const int iHitboxes = Vars::Aimbot::Hitscan::Hitboxes.Value;
switch (nHitbox)
{
case -1: return true;
case HITBOX_HEAD: return iHitboxes & (1 << 0);
case HITBOX_NECK: return iHitboxes & (1 << 1);
case HITBOX_LOWER_NECK:
case HITBOX_PELVIS:
case HITBOX_BODY:
case HITBOX_THORAX: return iHitboxes & (1 << 2);
case HITBOX_CHEST:
case HITBOX_UPPER_CHEST:
case HITBOX_RIGHT_THIGH:
case HITBOX_LEFT_THIGH:
case HITBOX_RIGHT_CALF:
case HITBOX_LEFT_CALF: return iHitboxes & (1 << 3);
case HITBOX_RIGHT_FOOT:
case HITBOX_LEFT_FOOT:
case HITBOX_RIGHT_HAND:
case HITBOX_LEFT_HAND:
case HITBOX_RIGHT_UPPER_ARM:
case HITBOX_RIGHT_FOREARM:
case HITBOX_LEFT_UPPER_ARM:
case HITBOX_LEFT_FOREARM: return iHitboxes & (1 << 4);
}
return false;
}
bool CAimbotGlobal::ShouldIgnore(CBaseEntity* pEntity, CTFPlayer* pLocal, CTFWeaponBase* pWeapon)
{
if (pEntity->IsDormant())
return true;
if (auto pGameRules = I::TFGameRules->Get())
{
if (pGameRules->m_bTruceActive() && pLocal->m_iTeamNum() != pEntity->m_iTeamNum())
return true;
}
switch (pEntity->GetClassID())
{
case ETFClassID::CTFPlayer:
{
auto pPlayer = pEntity->As<CTFPlayer>();
if (pPlayer == pLocal || !pPlayer->IsAlive() || pPlayer->IsAGhost())
return true;
if (pLocal->m_iTeamNum() == pEntity->m_iTeamNum())
return false;
if (F::PlayerUtils.IsIgnored(pPlayer->entindex()))
return true;
if (Vars::Aimbot::General::Ignore.Value & INVUL && pPlayer->IsInvulnerable() && pWeapon->m_iItemDefinitionIndex() != Heavy_t_TheHolidayPunch)
return true;
if (Vars::Aimbot::General::Ignore.Value & CLOAKED && pPlayer->IsInvisible() && pPlayer->GetInvisPercentage() >= Vars::Aimbot::General::IgnoreCloakPercentage.Value)
return true;
if (Vars::Aimbot::General::Ignore.Value & DEADRINGER && pPlayer->m_bFeignDeathReady())
return true;
if (Vars::Aimbot::General::Ignore.Value & TAUNTING && pPlayer->IsTaunting())
return true;
if (Vars::Aimbot::General::Ignore.Value & VACCINATOR)
{
switch (G::PrimaryWeaponType)
{
case EWeaponType::HITSCAN:
if (pPlayer->IsBulletResist() && pWeapon->m_iItemDefinitionIndex() != Spy_m_TheEnforcer)
return true;
break;
case EWeaponType::PROJECTILE:
switch (pWeapon->GetWeaponID())
{
case TF_WEAPON_FLAMETHROWER:
case TF_WEAPON_FLAREGUN:
if (pPlayer->IsFireResist())
return true;
break;
case TF_WEAPON_COMPOUND_BOW:
if (pPlayer->IsBulletResist())
return true;
break;
default:
if (pPlayer->IsBlastResist())
return true;
}
}
}
if (Vars::Aimbot::General::Ignore.Value & DISGUISED && pPlayer->IsDisguised())
return true;
return false;
}
case ETFClassID::CObjectSentrygun:
case ETFClassID::CObjectDispenser:
case ETFClassID::CObjectTeleporter:
{
auto pBuilding = pEntity->As<CBaseObject>();
if (pLocal->m_iTeamNum() == pEntity->m_iTeamNum())
return false;
auto pOwner = pBuilding->m_hBuilder().Get();
if (pOwner && F::PlayerUtils.IsIgnored(pOwner->entindex()))
return true;
if (!(Vars::Aimbot::General::Target.Value & SENTRY) && pBuilding->IsSentrygun()
|| !(Vars::Aimbot::General::Target.Value & DISPENSER) && pBuilding->IsDispenser()
|| !(Vars::Aimbot::General::Target.Value & TELEPORTER) && pBuilding->IsTeleporter())
return true;
return false;
}
case ETFClassID::CTFGrenadePipebombProjectile:
{
auto pProjectile = pEntity->As<CTFGrenadePipebombProjectile>();
if (pLocal->m_iTeamNum() == pEntity->m_iTeamNum())
return true;
auto pOwner = pProjectile->m_hThrower().Get();
if (pOwner && F::PlayerUtils.IsIgnored(pOwner->entindex()))
return true;
if (pProjectile->m_iType() != TF_GL_MODE_REMOTE_DETONATE || !pProjectile->m_bTouched())
return true;
return false;
}
case ETFClassID::CHeadlessHatman:
case ETFClassID::CTFTankBoss:
case ETFClassID::CMerasmus:
case ETFClassID::CEyeballBoss:
{
if (pEntity->m_iTeamNum() != 5)
return true;
return false;
}
case ETFClassID::CZombie:
{
if (pLocal->m_iTeamNum() == pEntity->m_iTeamNum())
return true;
return false;
}
}
return true;
}
int CAimbotGlobal::GetPriority(int targetIdx)
{
return F::PlayerUtils.GetPriority(targetIdx);
@@ -60,10 +60,15 @@ struct Target_t
class CAimbotGlobal
{
public:
void SortTargets(std::vector<Target_t>*, const ESortMethod& method);
void SortTargets(std::vector<Target_t>*, ESortMethod method);
void SortPriority(std::vector<Target_t>*);
bool ShouldIgnore(CTFPlayer* pTarget, CTFPlayer* pLocal, CTFWeaponBase* pWeapon);
bool PlayerBoneInFOV(CTFPlayer* pTarget, Vec3 vLocalPos, Vec3 vLocalAngles, float& flFOVTo, Vec3& vPos, Vec3& vAngleTo);
bool IsHitboxValid(int nHitbox);
bool ShouldIgnore(CBaseEntity* pTarget, CTFPlayer* pLocal, CTFWeaponBase* pWeapon);
int GetPriority(int targetIdx);
bool ValidBomb(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CBaseEntity* pBomb);
};
@@ -4,40 +4,16 @@
#include "../../TickHandler/TickHandler.h"
#include "../../Visuals/Visuals.h"
bool CAimbotHitscan::PlayerBoneInFOV(CTFPlayer* pTarget, Vec3 vLocalPos, Vec3 vLocalAngles, float& flFOVTo, Vec3& vPos, Vec3& vAngleTo) // this won't prevent shooting bones outside of fov
{
bool bReturn = false;
float flMinFOV = 180.f;
for (int nHitbox = 0; nHitbox < pTarget->GetNumOfHitboxes(); nHitbox++)
{
if (!IsHitboxValid(nHitbox))
continue;
Vec3 vCurPos = pTarget->GetHitboxCenter(nHitbox);
Vec3 vCurAngleTo = Math::CalcAngle(vLocalPos, vCurPos);
float flCurFOVTo = Math::CalcFov(vLocalAngles, vCurAngleTo);
if (flCurFOVTo < flMinFOV && flCurFOVTo < Vars::Aimbot::General::AimFOV.Value)
{
bReturn = true;
vPos = vCurPos;
vAngleTo = vCurAngleTo;
flFOVTo = flMinFOV = flCurFOVTo;
}
}
return bReturn;
}
std::vector<Target_t> CAimbotHitscan::GetTargetsMedigun(CTFPlayer* pLocal, CWeaponMedigun* pWeapon)
{
if (!Vars::Aimbot::Healing::AutoHeal.Value)
return {};
std::vector<Target_t> validTargets;
const Vec3 vLocalPos = pLocal->GetShootPos();
const Vec3 vLocalAngles = I::EngineClient->GetViewAngles();
std::vector<Target_t> vTargets;
const auto sortMethod = ESortMethod(Vars::Aimbot::General::TargetSelection.Value);
Vec3 vLocalPos = pLocal->GetShootPos();
Vec3 vLocalAngles = I::EngineClient->GetViewAngles();
for (auto pEntity : H::Entities.GetGroup(EGroupType::PLAYERS_TEAMMATES))
{
@@ -49,15 +25,14 @@ std::vector<Target_t> CAimbotHitscan::GetTargetsMedigun(CTFPlayer* pLocal, CWeap
continue;
float flFOVTo; Vec3 vPos, vAngleTo;
if (!PlayerBoneInFOV(pPlayer, vLocalPos, vLocalAngles, flFOVTo, vPos, vAngleTo) && pWeapon->m_hHealingTarget().Get() != pPlayer)
if (!F::AimbotGlobal.PlayerBoneInFOV(pPlayer, vLocalPos, vLocalAngles, flFOVTo, vPos, vAngleTo) && pWeapon->m_hHealingTarget().Get() != pPlayer)
continue;
const float flDistTo = vLocalPos.DistTo(vPos);
const int priority = F::AimbotGlobal.GetPriority(pPlayer->entindex());
validTargets.push_back({ pPlayer, ETargetType::PLAYER, vPos, vAngleTo, flFOVTo, flDistTo, priority });
float flDistTo = sortMethod == ESortMethod::DISTANCE ? vLocalPos.DistTo(vPos) : 0.f;
vTargets.push_back({ pPlayer, ETargetType::PLAYER, vPos, vAngleTo, flFOVTo, flDistTo });
}
return validTargets;
return vTargets;
}
std::vector<Target_t> CAimbotHitscan::GetTargets(CTFPlayer* pLocal, CTFWeaponBase* pWeapon)
@@ -65,39 +40,30 @@ std::vector<Target_t> CAimbotHitscan::GetTargets(CTFPlayer* pLocal, CTFWeaponBas
if (pWeapon->GetWeaponID() == TF_WEAPON_MEDIGUN)
return GetTargetsMedigun(pLocal, pWeapon->As<CWeaponMedigun>());
std::vector<Target_t> validTargets;
const Vec3 vLocalPos = pLocal->GetShootPos();
const Vec3 vLocalAngles = I::EngineClient->GetViewAngles();
std::vector<Target_t> vTargets;
const auto sortMethod = ESortMethod(Vars::Aimbot::General::TargetSelection.Value);
Vec3 vLocalPos = pLocal->GetShootPos();
Vec3 vLocalAngles = I::EngineClient->GetViewAngles();
if (Vars::Aimbot::General::Target.Value & PLAYER)
{
const bool bPissRifle = pWeapon->m_iItemDefinitionIndex() == Sniper_m_TheSydneySleeper;
EGroupType groupType = bPissRifle ? EGroupType::PLAYERS_ALL : EGroupType::PLAYERS_ENEMIES;
for (auto pEntity : H::Entities.GetGroup(groupType))
bool bPissRifle = pWeapon->m_iItemDefinitionIndex() == Sniper_m_TheSydneySleeper;
for (auto pEntity : H::Entities.GetGroup(bPissRifle ? EGroupType::PLAYERS_ALL : EGroupType::PLAYERS_ENEMIES))
{
auto pPlayer = pEntity->As<CTFPlayer>();
if (pPlayer == pLocal || !pPlayer->IsAlive() || pPlayer->IsAGhost())
if (F::AimbotGlobal.ShouldIgnore(pEntity, pLocal, pWeapon))
continue;
if (bPissRifle && (pPlayer->m_iTeamNum() == pLocal->m_iTeamNum()))
{
if (!(Vars::Aimbot::Hitscan::Modifiers.Value & (1 << 6)) || !pPlayer->IsOnFire())
continue;
}
if (F::AimbotGlobal.ShouldIgnore(pPlayer, pLocal, pWeapon))
if (pWeapon->m_iItemDefinitionIndex() == Sniper_m_TheSydneySleeper && pEntity->m_iTeamNum() == pLocal->m_iTeamNum()
&& (!(Vars::Aimbot::Hitscan::Modifiers.Value & (1 << 6)) || !pEntity->As<CTFPlayer>()->IsOnFire()))
continue;
float flFOVTo; Vec3 vPos, vAngleTo;
if (!PlayerBoneInFOV(pPlayer, vLocalPos, vLocalAngles, flFOVTo, vPos, vAngleTo))
if (!F::AimbotGlobal.PlayerBoneInFOV(pEntity->As<CTFPlayer>(), vLocalPos, vLocalAngles, flFOVTo, vPos, vAngleTo))
continue;
const float flDistTo = vLocalPos.DistTo(vPos);
const int priority = F::AimbotGlobal.GetPriority(pPlayer->entindex());
validTargets.push_back({ pPlayer, ETargetType::PLAYER, vPos, vAngleTo, flFOVTo, flDistTo, priority });
float flDistTo = sortMethod == ESortMethod::DISTANCE ? vLocalPos.DistTo(vPos) : 0.f;
vTargets.push_back({ pEntity, ETargetType::PLAYER, vPos, vAngleTo, flFOVTo, flDistTo, F::AimbotGlobal.GetPriority(pEntity->entindex()) });
}
}
@@ -105,23 +71,17 @@ std::vector<Target_t> CAimbotHitscan::GetTargets(CTFPlayer* pLocal, CTFWeaponBas
{
for (auto pEntity : H::Entities.GetGroup(EGroupType::BUILDINGS_ENEMIES))
{
auto pBuilding = pEntity->As<CBaseObject>();
bool bSentry = pBuilding->IsSentrygun(), bDispenser = pBuilding->IsDispenser(), bTeleporter = pBuilding->IsTeleporter();
if (bSentry && !(Vars::Aimbot::General::Target.Value & SENTRY)
|| bDispenser && !(Vars::Aimbot::General::Target.Value & DISPENSER)
|| bTeleporter && !(Vars::Aimbot::General::Target.Value & TELEPORTER))
if (F::AimbotGlobal.ShouldIgnore(pEntity, pLocal, pWeapon))
continue;
Vec3 vPos = pBuilding->GetCenter();
Vec3 vPos = pEntity->GetCenter();
Vec3 vAngleTo = Math::CalcAngle(vLocalPos, vPos);
const float flFOVTo = Math::CalcFov(vLocalAngles, vAngleTo);
float flFOVTo = Math::CalcFov(vLocalAngles, vAngleTo);
if (flFOVTo > Vars::Aimbot::General::AimFOV.Value)
continue;
const float flDistTo = vLocalPos.DistTo(vPos);
validTargets.push_back({ pBuilding, bSentry ? ETargetType::SENTRY : bDispenser ? ETargetType::DISPENSER : ETargetType::TELEPORTER, vPos, vAngleTo, flFOVTo, flDistTo });
float flDistTo = sortMethod == ESortMethod::DISTANCE ? vLocalPos.DistTo(vPos) : 0.f;
vTargets.push_back({ pEntity, pEntity->IsSentrygun() ? ETargetType::SENTRY : pEntity->IsDispenser() ? ETargetType::DISPENSER : ETargetType::TELEPORTER, vPos, vAngleTo, flFOVTo, flDistTo });
}
}
@@ -129,121 +89,71 @@ std::vector<Target_t> CAimbotHitscan::GetTargets(CTFPlayer* pLocal, CTFWeaponBas
{
for (auto pEntity : H::Entities.GetGroup(EGroupType::WORLD_PROJECTILES))
{
if (pEntity->GetClassID() != ETFClassID::CTFGrenadePipebombProjectile)
if (F::AimbotGlobal.ShouldIgnore(pEntity, pLocal, pWeapon))
continue;
auto pProjectile = pEntity->As<CTFGrenadePipebombProjectile>();
if (pProjectile->m_iType() != TF_GL_MODE_REMOTE_DETONATE || !pProjectile->m_bTouched())
continue;
auto pOwner = pProjectile->m_hThrower().Get();
if (!pOwner || pOwner->m_iTeamNum() == pLocal->m_iTeamNum())
continue;
Vec3 vPos = pProjectile->GetCenter();
Vec3 vPos = pEntity->GetCenter();
Vec3 vAngleTo = Math::CalcAngle(vLocalPos, vPos);
const float flFOVTo = Math::CalcFov(vLocalAngles, vAngleTo);
float flFOVTo = Math::CalcFov(vLocalAngles, vAngleTo);
if (flFOVTo > Vars::Aimbot::General::AimFOV.Value)
continue;
const float flDistTo = vLocalPos.DistTo(vPos);
validTargets.push_back({ pProjectile, ETargetType::STICKY, vPos, vAngleTo, flFOVTo, flDistTo });
float flDistTo = sortMethod == ESortMethod::DISTANCE ? vLocalPos.DistTo(vPos) : 0.f;
vTargets.push_back({ pEntity, ETargetType::STICKY, vPos, vAngleTo, flFOVTo, flDistTo });
}
}
if (Vars::Aimbot::General::Target.Value & NPC)
{
for (auto pNPC : H::Entities.GetGroup(EGroupType::WORLD_NPC))
for (auto pEntity : H::Entities.GetGroup(EGroupType::WORLD_NPC))
{
Vec3 vPos = pNPC->GetCenter();
Vec3 vAngleTo = Math::CalcAngle(vLocalPos, vPos);
const float flFOVTo = Math::CalcFov(vLocalAngles, vAngleTo);
if (F::AimbotGlobal.ShouldIgnore(pEntity, pLocal, pWeapon))
continue;
Vec3 vPos = pEntity->GetCenter();
Vec3 vAngleTo = Math::CalcAngle(vLocalPos, vPos);
float flFOVTo = Math::CalcFov(vLocalAngles, vAngleTo);
if (flFOVTo > Vars::Aimbot::General::AimFOV.Value)
continue;
const float flDistTo = vLocalPos.DistTo(vPos);
validTargets.push_back({ pNPC, ETargetType::NPC, vPos, vAngleTo, flFOVTo, flDistTo });
float flDistTo = sortMethod == ESortMethod::DISTANCE ? vLocalPos.DistTo(vPos) : 0.f;
vTargets.push_back({ pEntity, ETargetType::NPC, vPos, vAngleTo, flFOVTo, flDistTo });
}
}
if (Vars::Aimbot::General::Target.Value & BOMB)
{
for (auto pBomb : H::Entities.GetGroup(EGroupType::WORLD_BOMBS))
for (auto pEntity : H::Entities.GetGroup(EGroupType::WORLD_BOMBS))
{
Vec3 vPos = pBomb->GetCenter();
Vec3 vPos = pEntity->GetCenter();
Vec3 vAngleTo = Math::CalcAngle(vLocalPos, vPos);
const float flFOVTo = Math::CalcFov(vLocalAngles, vAngleTo);
const float flDistTo = sortMethod == ESortMethod::DISTANCE ? vLocalPos.DistTo(vPos) : 0.0f;
float flFOVTo = Math::CalcFov(vLocalAngles, vAngleTo);
if (flFOVTo > Vars::Aimbot::General::AimFOV.Value)
continue;
if (!F::AimbotGlobal.ValidBomb(pLocal, pWeapon, pBomb))
if (!F::AimbotGlobal.ValidBomb(pLocal, pWeapon, pEntity))
continue;
validTargets.push_back({ pBomb, ETargetType::BOMBS, vPos, vAngleTo, flFOVTo, flDistTo });
float flDistTo = sortMethod == ESortMethod::DISTANCE ? vLocalPos.DistTo(vPos) : 0.f;
vTargets.push_back({ pEntity, ETargetType::BOMBS, vPos, vAngleTo, flFOVTo, flDistTo });
}
}
return validTargets;
return vTargets;
}
std::vector<Target_t> CAimbotHitscan::SortTargets(CTFPlayer* pLocal, CTFWeaponBase* pWeapon)
{
auto validTargets = GetTargets(pLocal, pWeapon);
auto vTargets = GetTargets(pLocal, pWeapon);
const auto sortMethod = ESortMethod(Vars::Aimbot::General::TargetSelection.Value);
F::AimbotGlobal.SortTargets(&validTargets, sortMethod);
std::vector<Target_t> sortedTargets = {};
int i = 0; for (auto& target : validTargets)
{
i++; if (i > Vars::Aimbot::General::MaxTargets.Value) break;
sortedTargets.push_back(target);
}
F::AimbotGlobal.SortPriority(&sortedTargets);
return sortedTargets;
F::AimbotGlobal.SortTargets(&vTargets, ESortMethod(Vars::Aimbot::General::TargetSelection.Value));
vTargets.resize(std::min(size_t(Vars::Aimbot::General::MaxTargets.Value), vTargets.size()));
F::AimbotGlobal.SortPriority(&vTargets);
return vTargets;
}
bool CAimbotHitscan::IsHitboxValid(int nHitbox) // check that this & all other uses are right
{
const int iHitboxes = Vars::Aimbot::Hitscan::Hitboxes.Value;
switch (nHitbox)
{
case -1: return true;
case HITBOX_HEAD: return iHitboxes & (1 << 0);
case HITBOX_NECK: return iHitboxes & (1 << 1);
case HITBOX_LOWER_NECK:
case HITBOX_PELVIS:
case HITBOX_BODY:
case HITBOX_THORAX: return iHitboxes & (1 << 2);
case HITBOX_CHEST:
case HITBOX_UPPER_CHEST:
case HITBOX_RIGHT_THIGH:
case HITBOX_LEFT_THIGH:
case HITBOX_RIGHT_CALF:
case HITBOX_LEFT_CALF: return iHitboxes & (1 << 3);
case HITBOX_RIGHT_FOOT:
case HITBOX_LEFT_FOOT:
case HITBOX_RIGHT_HAND:
case HITBOX_LEFT_HAND:
case HITBOX_RIGHT_UPPER_ARM:
case HITBOX_RIGHT_FOREARM:
case HITBOX_LEFT_UPPER_ARM:
case HITBOX_LEFT_FOREARM: return iHitboxes & (1 << 4);
}
return false;
}
int CAimbotHitscan::GetHitboxPriority(int nHitbox, CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CBaseEntity* pTarget)
{
bool bHeadshot = false;
@@ -414,7 +324,7 @@ int CAimbotHitscan::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* p
std::vector<std::pair<const mstudiobbox_t*, int>> primary, secondary, tertiary; // dumb
for (int nHitbox = 0; nHitbox < target.m_pEntity->As<CTFPlayer>()->GetNumOfHitboxes(); nHitbox++)
{
if (!IsHitboxValid(nHitbox))
if (!F::AimbotGlobal.IsHitboxValid(nHitbox))
continue;
auto pBox = pSet->pHitbox(nHitbox);
@@ -5,12 +5,10 @@
class CAimbotHitscan
{
bool PlayerBoneInFOV(CTFPlayer* pTarget, Vec3 vLocalPos, Vec3 vLocalAngles, float& flFOVTo, Vec3& vPos, Vec3& vAngleTo);
std::vector<Target_t> GetTargets(CTFPlayer* pLocal, CTFWeaponBase* pWeapon);
std::vector<Target_t> GetTargetsMedigun(CTFPlayer* pLocal, CWeaponMedigun* pWeapon);
std::vector<Target_t> SortTargets(CTFPlayer* pLocal, CTFWeaponBase* pWeapon);
bool IsHitboxValid(int nHitbox);
int GetHitboxPriority(int nHitbox, CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CBaseEntity* pTarget);
float GetMaxRange(CTFWeaponBase* pWeapon);
int CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* pWeapon);
@@ -6,91 +6,78 @@
std::vector<Target_t> CAimbotMelee::GetTargets(CTFPlayer* pLocal, CTFWeaponBase* pWeapon)
{
std::vector<Target_t> validTargets;
std::vector<Target_t> vTargets;
const Vec3 vLocalPos = pLocal->GetShootPos();
const Vec3 vLocalAngles = I::EngineClient->GetViewAngles();
if (Vars::Aimbot::General::Target.Value & PLAYER)
{
const bool bDisciplinary = Vars::Aimbot::Melee::WhipTeam.Value && pWeapon->m_iItemDefinitionIndex() == Soldier_t_TheDisciplinaryAction;
bool bDisciplinary = Vars::Aimbot::Melee::WhipTeam.Value && pWeapon->m_iItemDefinitionIndex() == Soldier_t_TheDisciplinaryAction;
for (auto pEntity : H::Entities.GetGroup(bDisciplinary ? EGroupType::PLAYERS_ALL : EGroupType::PLAYERS_ENEMIES))
{
auto pPlayer = pEntity->As<CTFPlayer>();
if (pPlayer == pLocal || !pPlayer->IsAlive() || pPlayer->IsAGhost())
if (F::AimbotGlobal.ShouldIgnore(pEntity, pLocal, pWeapon))
continue;
if (F::AimbotGlobal.ShouldIgnore(pPlayer, pLocal, pWeapon))
float flFOVTo; Vec3 vPos, vAngleTo;
if (!F::AimbotGlobal.PlayerBoneInFOV(pEntity->As<CTFPlayer>(), vLocalPos, vLocalAngles, flFOVTo, vPos, vAngleTo))
continue;
Vec3 vPos = pPlayer->GetCenter();
Vec3 vAngleTo = Math::CalcAngle(vLocalPos, vPos);
const float flFOVTo = Math::CalcFov(vLocalAngles, vAngleTo);
if (flFOVTo > Vars::Aimbot::General::AimFOV.Value)
continue;
const float flDistTo = vLocalPos.DistTo(vPos);
const int priority = F::AimbotGlobal.GetPriority(pPlayer->entindex());
validTargets.push_back({ pPlayer, ETargetType::PLAYER, vPos, vAngleTo, flFOVTo, flDistTo, priority });
float flDistTo = vLocalPos.DistTo(vPos);
vTargets.push_back({ pEntity, ETargetType::PLAYER, vPos, vAngleTo, flFOVTo, flDistTo, F::AimbotGlobal.GetPriority(pEntity->entindex()) });
}
}
if (Vars::Aimbot::General::Target.Value)
{
bool bHasWrench = pWeapon->GetWeaponID() == TF_WEAPON_WRENCH, bCanDestroySapper = false;
bool bWrench = pWeapon->GetWeaponID() == TF_WEAPON_WRENCH, bDestroySapper = false;
switch (pWeapon->m_iItemDefinitionIndex())
{
case Pyro_t_Homewrecker:
case Pyro_t_TheMaul:
case Pyro_t_NeonAnnihilator:
case Pyro_t_NeonAnnihilatorG:
bCanDestroySapper = true;
bDestroySapper = true;
}
for (auto pEntity : H::Entities.GetGroup(bHasWrench || bCanDestroySapper ? EGroupType::BUILDINGS_ALL : EGroupType::BUILDINGS_ENEMIES))
for (auto pEntity : H::Entities.GetGroup(bWrench || bDestroySapper ? EGroupType::BUILDINGS_ALL : EGroupType::BUILDINGS_ENEMIES))
{
auto pBuilding = pEntity->As<CBaseObject>();
bool bSentry = pBuilding->IsSentrygun(), bDispenser = pBuilding->IsDispenser(), bTeleporter = pBuilding->IsTeleporter();
if (bSentry && !(Vars::Aimbot::General::Target.Value & SENTRY)
|| bDispenser && !(Vars::Aimbot::General::Target.Value & DISPENSER)
|| bTeleporter && !(Vars::Aimbot::General::Target.Value & TELEPORTER))
if (F::AimbotGlobal.ShouldIgnore(pEntity, pLocal, pWeapon))
continue;
if (pBuilding->m_iTeamNum() == pLocal->m_iTeamNum() && (bHasWrench && !AimFriendlyBuilding(pBuilding) || bCanDestroySapper && !pBuilding->m_bHasSapper()))
if (pEntity->m_iTeamNum() == pLocal->m_iTeamNum() && (bWrench && !AimFriendlyBuilding(pEntity->As<CBaseObject>()) || bDestroySapper && !pEntity->As<CBaseObject>()->m_bHasSapper()))
continue;
Vec3 vPos = pBuilding->GetCenter();
Vec3 vPos = pEntity->GetCenter();
Vec3 vAngleTo = Math::CalcAngle(vLocalPos, vPos);
const float flFOVTo = Math::CalcFov(vLocalAngles, vAngleTo);
const float flDistTo = vLocalPos.DistTo(vPos);
float flFOVTo = Math::CalcFov(vLocalAngles, vAngleTo);
if (flFOVTo > Vars::Aimbot::General::AimFOV.Value)
continue;
validTargets.push_back({ pBuilding, bSentry ? ETargetType::SENTRY : bDispenser ? ETargetType::DISPENSER : ETargetType::TELEPORTER, vPos, vAngleTo, flFOVTo, flDistTo });
float flDistTo = vLocalPos.DistTo(vPos);
vTargets.push_back({ pEntity, pEntity->IsSentrygun() ? ETargetType::SENTRY : pEntity->IsDispenser() ? ETargetType::DISPENSER : ETargetType::TELEPORTER, vPos, vAngleTo, flFOVTo, flDistTo });
}
}
if (Vars::Aimbot::General::Target.Value & NPC)
{
for (auto pNPC : H::Entities.GetGroup(EGroupType::WORLD_NPC))
for (auto pEntity : H::Entities.GetGroup(EGroupType::WORLD_NPC))
{
Vec3 vPos = pNPC->GetCenter();
if (F::AimbotGlobal.ShouldIgnore(pEntity, pLocal, pWeapon))
continue;
Vec3 vPos = pEntity->GetCenter();
Vec3 vAngleTo = Math::CalcAngle(vLocalPos, vPos);
const float flFOVTo = Math::CalcFov(vLocalAngles, vAngleTo);
const float flDistTo = vLocalPos.DistTo(vPos);
float flFOVTo = Math::CalcFov(vLocalAngles, vAngleTo);
if (flFOVTo > Vars::Aimbot::General::AimFOV.Value)
continue;
validTargets.push_back({ pNPC, ETargetType::NPC, vPos, vAngleTo, flFOVTo, flDistTo });
float flDistTo = vLocalPos.DistTo(vPos);
vTargets.push_back({ pEntity, ETargetType::NPC, vPos, vAngleTo, flFOVTo, flDistTo });
}
}
return validTargets;
return vTargets;
}
bool CAimbotMelee::AimFriendlyBuilding(CBaseObject* pBuilding)
@@ -110,22 +97,12 @@ bool CAimbotMelee::AimFriendlyBuilding(CBaseObject* pBuilding)
std::vector<Target_t> CAimbotMelee::SortTargets(CTFPlayer* pLocal, CTFWeaponBase* pWeapon)
{
auto validTargets = GetTargets(pLocal, pWeapon);
auto vTargets = GetTargets(pLocal, pWeapon);
const auto& sortMethod = ESortMethod::DISTANCE; //static_cast<ESortMethod>(Vars::Aimbot::Melee::SortMethod.Value);
F::AimbotGlobal.SortTargets(&validTargets, sortMethod);
std::vector<Target_t> sortedTargets = {};
int i = 0; for (auto& target : validTargets)
{
i++; if (i > Vars::Aimbot::General::MaxTargets.Value) break;
sortedTargets.push_back(target);
}
F::AimbotGlobal.SortPriority(&sortedTargets);
return sortedTargets;
F::AimbotGlobal.SortTargets(&vTargets, ESortMethod::DISTANCE);
vTargets.resize(std::min(size_t(Vars::Aimbot::General::MaxTargets.Value), vTargets.size()));
F::AimbotGlobal.SortPriority(&vTargets);
return vTargets;
}
@@ -7,7 +7,7 @@
std::vector<Target_t> CAimbotProjectile::GetTargets(CTFPlayer* pLocal, CTFWeaponBase* pWeapon)
{
std::vector<Target_t> validTargets;
std::vector<Target_t> vTargets;
const auto sortMethod = static_cast<ESortMethod>(Vars::Aimbot::General::TargetSelection.Value);
const Vec3 vLocalPos = pLocal->GetShootPos();
@@ -24,96 +24,99 @@ std::vector<Target_t> CAimbotProjectile::GetTargets(CTFPlayer* pLocal, CTFWeapon
for (auto pEntity : H::Entities.GetGroup(groupType))
{
auto pPlayer = pEntity->As<CTFPlayer>();
if (pPlayer == pLocal || !pPlayer->IsAlive() || pPlayer->IsAGhost())
if (F::AimbotGlobal.ShouldIgnore(pEntity, pLocal, pWeapon))
continue;
// Check if weapon should shoot at friendly players
if ((groupType == EGroupType::PLAYERS_ALL || groupType == EGroupType::PLAYERS_TEAMMATES) &&
pPlayer->m_iTeamNum() == pLocal->m_iTeamNum())
{
if (pPlayer->m_iHealth() >= pPlayer->GetMaxHealth())
continue;
}
if (F::AimbotGlobal.ShouldIgnore(pPlayer, pLocal, pWeapon))
if (pEntity->m_iTeamNum() == pLocal->m_iTeamNum() && pEntity->As<CTFPlayer>()->m_iHealth() >= pEntity->As<CTFPlayer>()->GetMaxHealth())
continue;
Vec3 vPos = pPlayer->GetCenter();
Vec3 vAngleTo = Math::CalcAngle(vLocalPos, vPos);
const float flFOVTo = Math::CalcFov(vLocalAngles, vAngleTo);
if (flFOVTo > Vars::Aimbot::General::AimFOV.Value)
float flFOVTo; Vec3 vPos, vAngleTo;
if (!F::AimbotGlobal.PlayerBoneInFOV(pEntity->As<CTFPlayer>(), vLocalPos, vLocalAngles, flFOVTo, vPos, vAngleTo))
continue;
const float flDistTo = (sortMethod == ESortMethod::DISTANCE) ? vLocalPos.DistTo(vPos) : 0.0f;
const int priority = F::AimbotGlobal.GetPriority(pPlayer->entindex());
validTargets.push_back({ pPlayer, ETargetType::PLAYER, vPos, vAngleTo, flFOVTo, flDistTo, priority });
float flDistTo = sortMethod == ESortMethod::DISTANCE ? vLocalPos.DistTo(vPos) : 0.f;
vTargets.push_back({ pEntity, ETargetType::PLAYER, vPos, vAngleTo, flFOVTo, flDistTo, F::AimbotGlobal.GetPriority(pEntity->entindex()) });
}
}
const bool bIsRescueRanger = pWeapon->GetWeaponID() == TF_WEAPON_SHOTGUN_BUILDING_RESCUE;
for (auto pEntity : H::Entities.GetGroup(bIsRescueRanger ? EGroupType::BUILDINGS_ALL : EGroupType::BUILDINGS_ENEMIES))
if (Vars::Aimbot::General::Target.Value)
{
auto pBuilding = pEntity->As<CBaseObject>();
bool bSentry = pBuilding->IsSentrygun(), bDispenser = pBuilding->IsDispenser(), bTeleporter = pBuilding->IsTeleporter();
if (bSentry && !(Vars::Aimbot::General::Target.Value & SENTRY)
|| bDispenser && !(Vars::Aimbot::General::Target.Value & DISPENSER)
|| bTeleporter && !(Vars::Aimbot::General::Target.Value & TELEPORTER))
continue;
if (pBuilding->m_iTeamNum() == pLocal->m_iTeamNum() && bIsRescueRanger && pBuilding->m_iHealth() >= pBuilding->m_iMaxHealth())
continue;
Vec3 vPos = pBuilding->GetCenter();
Vec3 vAngleTo = Math::CalcAngle(vLocalPos, vPos);
const float flFOVTo = Math::CalcFov(vLocalAngles, vAngleTo);
if (flFOVTo > Vars::Aimbot::General::AimFOV.Value)
continue;
const float flDistTo = sortMethod == ESortMethod::DISTANCE ? vLocalPos.DistTo(vPos) : 0.0f;
validTargets.push_back({ pBuilding, bSentry ? ETargetType::SENTRY : bDispenser ? ETargetType::DISPENSER : ETargetType::TELEPORTER, vPos, vAngleTo, flFOVTo, flDistTo });
}
if (Vars::Aimbot::General::Target.Value & NPC)
{
for (auto pNPC : H::Entities.GetGroup(EGroupType::WORLD_NPC))
bool bIsRescueRanger = pWeapon->GetWeaponID() == TF_WEAPON_SHOTGUN_BUILDING_RESCUE;
for (auto pEntity : H::Entities.GetGroup(bIsRescueRanger ? EGroupType::BUILDINGS_ALL : EGroupType::BUILDINGS_ENEMIES))
{
Vec3 vPos = pNPC->GetCenter();
if (F::AimbotGlobal.ShouldIgnore(pEntity, pLocal, pWeapon))
continue;
if (pEntity->m_iTeamNum() == pLocal->m_iTeamNum() && pEntity->As<CBaseObject>()->m_iHealth() >= pEntity->As<CBaseObject>()->m_iMaxHealth())
continue;
Vec3 vPos = pEntity->GetCenter();
Vec3 vAngleTo = Math::CalcAngle(vLocalPos, vPos);
const float flFOVTo = Math::CalcFov(vLocalAngles, vAngleTo);
const float flDistTo = sortMethod == ESortMethod::DISTANCE ? vLocalPos.DistTo(vPos) : 0.0f;
float flFOVTo = Math::CalcFov(vLocalAngles, vAngleTo);
if (flFOVTo > Vars::Aimbot::General::AimFOV.Value)
continue;
validTargets.push_back({ pNPC, ETargetType::NPC, vPos, vAngleTo, flFOVTo, flDistTo });
float flDistTo = sortMethod == ESortMethod::DISTANCE ? vLocalPos.DistTo(vPos) : 0.f;
vTargets.push_back({ pEntity, pEntity->IsSentrygun() ? ETargetType::SENTRY : pEntity->IsDispenser() ? ETargetType::DISPENSER : ETargetType::TELEPORTER, vPos, vAngleTo, flFOVTo, flDistTo });
}
}
return validTargets;
if (Vars::Aimbot::General::Target.Value & STICKY)
{
bool bShouldAim = false;
switch (pWeapon->m_iItemDefinitionIndex())
{
case Demoman_s_TheQuickiebombLauncher:
case Demoman_s_TheScottishResistance:
case Pyro_s_TheScorchShot:
bShouldAim = true;
}
if (bShouldAim)
{
for (auto pEntity : H::Entities.GetGroup(EGroupType::WORLD_PROJECTILES))
{
if (F::AimbotGlobal.ShouldIgnore(pEntity, pLocal, pWeapon))
continue;
Vec3 vPos = pEntity->GetCenter();
Vec3 vAngleTo = Math::CalcAngle(vLocalPos, vPos);
float flFOVTo = Math::CalcFov(vLocalAngles, vAngleTo);
if (flFOVTo > Vars::Aimbot::General::AimFOV.Value)
continue;
float flDistTo = sortMethod == ESortMethod::DISTANCE ? vLocalPos.DistTo(vPos) : 0.f;
vTargets.push_back({ pEntity, ETargetType::STICKY, vPos, vAngleTo, flFOVTo, flDistTo });
}
}
}
if (Vars::Aimbot::General::Target.Value & NPC) // does not predict movement
{
for (auto pEntity : H::Entities.GetGroup(EGroupType::WORLD_NPC))
{
Vec3 vPos = pEntity->GetCenter();
Vec3 vAngleTo = Math::CalcAngle(vLocalPos, vPos);
float flFOVTo = Math::CalcFov(vLocalAngles, vAngleTo);
if (flFOVTo > Vars::Aimbot::General::AimFOV.Value)
continue;
float flDistTo = sortMethod == ESortMethod::DISTANCE ? vLocalPos.DistTo(vPos) : 0.f;
vTargets.push_back({ pEntity, ETargetType::NPC, vPos, vAngleTo, flFOVTo, flDistTo });
}
}
return vTargets;
}
std::vector<Target_t> CAimbotProjectile::SortTargets(CTFPlayer* pLocal, CTFWeaponBase* pWeapon)
{
auto validTargets = GetTargets(pLocal, pWeapon);
auto vTargets = GetTargets(pLocal, pWeapon);
const auto& sortMethod = static_cast<ESortMethod>(Vars::Aimbot::General::TargetSelection.Value);
F::AimbotGlobal.SortTargets(&validTargets, sortMethod);
std::vector<Target_t> sortedTargets = {};
int i = 0; for (auto& target : validTargets)
{
i++; if (i > Vars::Aimbot::General::MaxTargets.Value) break;
sortedTargets.push_back(target);
}
F::AimbotGlobal.SortPriority(&sortedTargets);
return sortedTargets;
F::AimbotGlobal.SortTargets(&vTargets, ESortMethod(Vars::Aimbot::General::TargetSelection.Value));
vTargets.resize(std::min(size_t(Vars::Aimbot::General::MaxTargets.Value), vTargets.size()));
F::AimbotGlobal.SortPriority(&vTargets);
return vTargets;
}
@@ -133,7 +136,7 @@ float GetSplashRadius(CTFWeaponBase* pWeapon, CTFPlayer* pLocal = nullptr)
flRadius = 110.f;
if (!flRadius)
return 0.f;
flRadius = SDK::AttribHookValue(flRadius, "mult_explosion_radius", pWeapon);
switch (pWeapon->GetWeaponID())
{
@@ -158,22 +161,22 @@ float PrimeTime(CTFWeaponBase* pWeapon)
return 0.f;
}
int CAimbotProjectile::GetHitboxPriority(int nHitbox, CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Target_t& target, Info_t& tInfo)
int CAimbotProjectile::GetHitboxPriority(int nHitbox, Target_t& target, Info_t& tInfo)
{
bool bHeadshot = target.m_TargetType == ETargetType::PLAYER && pWeapon->GetWeaponID() == TF_WEAPON_COMPOUND_BOW;
bool bHeadshot = target.m_TargetType == ETargetType::PLAYER && tInfo.m_pWeapon->GetWeaponID() == TF_WEAPON_COMPOUND_BOW;
if (Vars::Aimbot::Projectile::Modifiers.Value & (1 << 2) && bHeadshot)
{
float charge = I::GlobalVars->curtime - pWeapon->As<CTFPipebombLauncher>()->m_flChargeBeginTime();
float charge = I::GlobalVars->curtime - tInfo.m_pWeapon->As<CTFPipebombLauncher>()->m_flChargeBeginTime();
float damage = Math::RemapValClamped(charge, 0.f, 1.f, 50.f, 120.f);
if (pLocal->IsMiniCritBoosted())
if (tInfo.m_pLocal->IsMiniCritBoosted())
damage *= 1.36f;
if (damage >= target.m_pEntity->As<CTFPlayer>()->m_iHealth())
bHeadshot = false;
if (pLocal->IsCritBoosted()) // for reliability
if (tInfo.m_pLocal->IsCritBoosted()) // for reliability
bHeadshot = false;
}
const bool bLower = target.m_TargetType == ETargetType::PLAYER && target.m_pEntity->As<CTFPlayer>()->IsOnGround() && tInfo.flRadius;
const bool bLower = target.m_TargetType == ETargetType::PLAYER && target.m_pEntity->As<CTFPlayer>()->IsOnGround() && tInfo.m_flRadius;
if (bHeadshot)
target.m_nAimedHitbox = HITBOX_HEAD;
@@ -188,14 +191,14 @@ int CAimbotProjectile::GetHitboxPriority(int nHitbox, CTFPlayer* pLocal, CTFWeap
return 3;
};
std::unordered_map<int, Vec3> CAimbotProjectile::GetDirectPoints(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Info_t& tInfo)
std::unordered_map<int, Vec3> CAimbotProjectile::GetDirectPoints(Target_t& target, Info_t& tInfo)
{
std::unordered_map<int, Vec3> mPoints = {};
const Vec3 vMins = target.m_pEntity->m_vecMins(), vMaxs = target.m_pEntity->m_vecMaxs();
for (int i = 0; i < 3; i++)
{
const int iPriority = GetHitboxPriority(i, pLocal, pWeapon, target, tInfo);
const int iPriority = GetHitboxPriority(i, target, tInfo);
if (iPriority == 3)
continue;
@@ -228,9 +231,9 @@ std::unordered_map<int, Vec3> CAimbotProjectile::GetDirectPoints(Target_t& targe
}
// seode
std::vector<Vec3> ComputeSphere(float flRadius, int iSamples)
std::vector<std::pair<Vec3, int>> ComputeSphere(float flRadius, int iSamples)
{
std::vector<Vec3> vPoints;
std::vector<std::pair<Vec3, int>> vPoints;
vPoints.reserve(iSamples);
for (int n = 0; n < iSamples; n++)
@@ -240,75 +243,124 @@ std::vector<Vec3> ComputeSphere(float flRadius, int iSamples)
Vec3 point = Vec3(sinf(a1) * cosf(a2), sinf(a1) * sinf(a2), -cosf(a1)) * flRadius;
vPoints.push_back(point);
vPoints.push_back({ point, Vars::Aimbot::Projectile::SplashGrates.Value ? PointType_Regular | PointType_Obscured : PointType_Regular });
}
return vPoints;
};
std::vector<Point_t> CAimbotProjectile::GetSplashPoints(Target_t& target, std::vector<Vec3>& vSpherePoints, CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Info_t& tInfo, int iSimTime) // possibly add air splash for autodet weapons
// possibly add air splash for autodet weapons
std::vector<Point_t> CAimbotProjectile::GetSplashPoints(Target_t& target, std::vector<std::pair<Vec3, int>>& vSpherePoints, Info_t& tInfo, int iSimTime)
{
std::vector<Point_t> vPoints = {};
std::vector<std::pair<Point_t, float>> vPointDistances = {};
const Vec3 vLocalEye = pLocal->GetShootPos(), vTargetEye = target.m_vPos + target.m_pEntity->As<CTFPlayer>()->GetViewOffset();
Vec3 vTargetEye = target.m_vPos + tInfo.m_vTargetEye;
auto checkPoint = [&](CGameTrace& trace, Vec3 vNormal, bool& bErase)
auto checkPoint = [&](CGameTrace& trace, bool& bErase, bool& bNormal)
{
bErase = true;
if (!trace.DidHit() || !trace.m_pEnt || !trace.m_pEnt->GetAbsVelocity().IsZero() || trace.surface.flags & 0x0004 /*SURF_SKY*/)
bErase = trace.fraction == 1.f || !trace.m_pEnt || !trace.m_pEnt->GetAbsVelocity().IsZero() || trace.surface.flags & 0x0004 /*SURF_SKY*/;
if (bErase)
return false;
Point_t tPoint = { trace.endpos, {} };
CalculateAngle(vLocalEye, tPoint.m_vPoint, tInfo, iSimTime, pLocal, pWeapon, tPoint.m_Solution);
CalculateAngle(tInfo.m_vLocalEye, tPoint.m_vPoint, tInfo, iSimTime, tPoint.m_Solution);
Vec3 vForward; Math::AngleVectors({ tPoint.m_Solution.m_flPitch, tPoint.m_Solution.m_flYaw, 0.f }, &vForward);
if (vForward.Dot(vNormal) > 0)
return bErase = true;
bNormal = vForward.Dot(trace.plane.normal) >= 0;
if (bNormal)
return false;
bErase = tPoint.m_Solution.m_iCalculated == 1;
if (bErase && int(tPoint.m_Solution.m_flTime / TICK_INTERVAL) + 1 == iSimTime)
{
vPoints.push_back(tPoint);
if (!bErase || int(tPoint.m_Solution.m_flTime / TICK_INTERVAL) + 1 != iSimTime)
return false;
}
vPointDistances.push_back({ tPoint, tPoint.m_vPoint.DistTo(target.m_vPos) });
return true;
};
for (auto it = vSpherePoints.begin(); it != vSpherePoints.end();)
{
bool bErase = false;
Vec3 vPoint = it->first + vTargetEye;
int& iType = it->second;
Vec3 vPoint = *it + vTargetEye;
Solution_t solution; CalculateAngle(pLocal->GetShootPos(), vPoint, tInfo, iSimTime, pLocal, pWeapon, solution, false);
if (solution.m_iCalculated != 3 && abs(solution.m_flTime - TICKS_TO_TIME(iSimTime)) < tInfo.flRadius / tInfo.flVelocity)
Solution_t solution; CalculateAngle(tInfo.m_vLocalEye, vPoint, tInfo, iSimTime, solution, false);
if (solution.m_iCalculated == 3)
iType = 0;
else if (abs(solution.m_flTime - TICKS_TO_TIME(iSimTime)) < tInfo.m_flRadiusTime)
{
bErase = true;
CGameTrace trace = {};
CTraceFilterWorldAndPropsOnly filter = {};
SDK::Trace(vTargetEye, vPoint, MASK_SOLID, &filter, &trace);
if (checkPoint(trace, trace.plane.normal, bErase)) // regular
if (iType & PointType_Regular)
{
SDK::Trace(vPoint, vTargetEye, MASK_SHOT, &filter, &trace);
if (!trace.DidHit())
bool bErase = false, bNormal = false;
SDK::Trace(vTargetEye, vPoint, MASK_SOLID, &filter, &trace);
checkPoint(trace, bErase, bNormal);
if (bErase)
iType = 0;
else if (bNormal)
iType &= ~PointType_Regular;
else
iType &= ~PointType_Obscured;
}
if (iType & PointType_Obscured)
{
bool bErase = false, bNormal = false;
if (!tInfo.m_bRocket) // just do this, it's less expensive
{
SDK::Trace(vPoint, vTargetEye, MASK_SHOT, &filter, &trace);
bNormal = trace.DidHit();
if (!bNormal)
{
SDK::Trace(vPoint, vTargetEye, MASK_SOLID, &filter, &trace);
checkPoint(trace, bErase, bNormal);
}
}
else // currently experimental, there may be a more efficient way to do this?
{
SDK::Trace(vPoint, vTargetEye, MASK_SOLID, &filter, &trace);
checkPoint(trace, trace.plane.normal, bErase); // grate
bNormal = trace.fraction == 1.f /*|| trace.startsolid*/;
if (!bNormal)
{
/*
CGameTrace checkTrace = {};
SDK::Trace(trace.endpos + trace.plane.normal, MASK_SHOT, &filter, &checkTrace);
if (checkTrace.fraction == 1.f)
checkPoint(trace, bErase, bNormal);
*/
if (checkPoint(trace, bErase, bNormal))
{
SDK::Trace(trace.endpos + trace.plane.normal, vTargetEye, MASK_SHOT, &filter, &trace);
if (trace.fraction < 1.f)
vPointDistances.pop_back();
}
}
}
if (bErase)
iType = 0;
else if (bNormal)
iType &= ~PointType_Obscured;
else
iType &= ~PointType_Regular;
}
}
if (bErase)
if (!iType)
it = vSpherePoints.erase(it);
else
++it;
}
std::sort(vPoints.begin(), vPoints.end(), [&](const Point_t& a, const Point_t& b) -> bool
std::sort(vPointDistances.begin(), vPointDistances.end(), [&](const auto& a, const auto& b) -> bool
{
return a.m_vPoint.DistTo(target.m_vPos) < b.m_vPoint.DistTo(target.m_vPos);
return a.second < b.second;
});
vPoints.resize(Vars::Aimbot::Projectile::SplashCount.Value);
std::vector<Point_t> vPoints = {};
for (int i = 0; i < std::min(tInfo.m_iSplashCount, int(vPointDistances.size())); i++)
vPoints.push_back(vPointDistances[i].first);
const Vec3 vOriginal = target.m_pEntity->GetAbsOrigin();
target.m_pEntity->SetAbsOrigin(target.m_vPos);
@@ -319,7 +371,7 @@ std::vector<Point_t> CAimbotProjectile::GetSplashPoints(Target_t& target, std::v
if (bValid)
{
Vec3 vPos = {}; reinterpret_cast<CCollisionProperty*>(target.m_pEntity->GetCollideable())->CalcNearestPoint(vPoint.m_vPoint, &vPos);
bValid = vPoint.m_vPoint.DistTo(vPos) < tInfo.flRadius;
bValid = vPoint.m_vPoint.DistTo(vPos) < tInfo.m_flRadius;
}
if (bValid)
@@ -355,25 +407,25 @@ Vec3 PullPoint(Vec3 vPoint, Vec3 vLocalPos, Info_t& tInfo, Vec3 vMins, Vec3 vMax
{
auto HeightenLocalPos = [&]()
{ // basic trajectory pass
const float flGrav = tInfo.flGravity * 800.f;
const float flGrav = tInfo.m_flGravity * 800.f;
if (!flGrav)
return vPoint;
const Vec3 vDelta = vTargetPos - vLocalPos;
const float flDist = vDelta.Length2D();
const float flRoot = pow(tInfo.flVelocity, 4) - flGrav * (flGrav * pow(flDist, 2) + 2.f * vDelta.z * pow(tInfo.flVelocity, 2));
const float flRoot = pow(tInfo.m_flVelocity, 4) - flGrav * (flGrav * pow(flDist, 2) + 2.f * vDelta.z * pow(tInfo.m_flVelocity, 2));
if (flRoot < 0.f)
return vPoint;
float flPitch = atan((pow(tInfo.flVelocity, 2) - sqrt(flRoot)) / (flGrav * flDist));
float flPitch = atan((pow(tInfo.m_flVelocity, 2) - sqrt(flRoot)) / (flGrav * flDist));
float flTime = flDist / (cos(flPitch) * tInfo.flVelocity) - tInfo.flOffset;
float flTime = flDist / (cos(flPitch) * tInfo.m_flVelocity) - tInfo.m_flOffsetTime;
return vLocalPos + Vec3(0, 0, (flGrav * pow(flTime, 2)) / 2);
};
vLocalPos = HeightenLocalPos();
Vec3 vForward, vRight, vUp; Math::AngleVectors(Math::CalcAngle(vLocalPos, vPoint), &vForward, &vRight, &vUp);
Vec3 vStart = vLocalPos + (vForward * tInfo.vOffset.x) + (vRight * tInfo.vOffset.y) + (vUp * tInfo.vOffset.z);
Vec3 vStart = vLocalPos + (vForward * tInfo.m_vOffset.x) + (vRight * tInfo.m_vOffset.y) + (vUp * tInfo.m_vOffset.z);
return vStart + (vPoint - vStart) * fabsf(AABBLine(vMins + vTargetPos, vMaxs + vTargetPos, vStart, vPoint - vStart));
}
@@ -430,12 +482,12 @@ void SolveProjectileSpeed(CTFWeaponBase* pWeapon, const Vec3& vLocalPos, const V
if (Vars::Aimbot::Projectile::TimeOverride.Value)
flDragTime = Vars::Aimbot::Projectile::TimeOverride.Value;
}
void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTargetPos, Info_t& tInfo, int iSimTime, CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Solution_t& out, bool bAccuracy)
void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTargetPos, Info_t& tInfo, int iSimTime, Solution_t& out, bool bAccuracy)
{
if (out.m_iCalculated)
return;
const float flGrav = tInfo.flGravity * 800.f;
const float flGrav = tInfo.m_flGravity * 800.f;
float flPitch, flYaw;
{ // basic trajectory pass
@@ -450,16 +502,16 @@ void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTarge
}
else
{ // arch
const float flRoot = pow(tInfo.flVelocity, 4) - flGrav * (flGrav * pow(flDist, 2) + 2.f * vDelta.z * pow(tInfo.flVelocity, 2));
const float flRoot = pow(tInfo.m_flVelocity, 4) - flGrav * (flGrav * pow(flDist, 2) + 2.f * vDelta.z * pow(tInfo.m_flVelocity, 2));
if (flRoot < 0.f)
{
out.m_iCalculated = 3; return;
}
flPitch = atan((pow(tInfo.flVelocity, 2) - sqrt(flRoot)) / (flGrav * flDist));
flPitch = atan((pow(tInfo.m_flVelocity, 2) - sqrt(flRoot)) / (flGrav * flDist));
flYaw = atan2(vDelta.y, vDelta.x);
}
out.m_flTime = flDist / (cos(flPitch) * tInfo.flVelocity) - tInfo.flOffset;
flPitch = -RAD2DEG(flPitch) - tInfo.flUpFix, flYaw = RAD2DEG(flYaw);
out.m_flTime = flDist / (cos(flPitch) * tInfo.m_flVelocity) - tInfo.m_flOffsetTime;
out.m_flPitch = flPitch = -RAD2DEG(flPitch) - tInfo.m_flUpFix, out.m_flYaw = flYaw = RAD2DEG(flYaw);
}
int iTimeTo = int(out.m_flTime / TICK_INTERVAL) + 1;
@@ -469,7 +521,7 @@ void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTarge
}
ProjectileInfo projInfo = {};
if (!F::ProjSim.GetInfo(pLocal, pWeapon, { flPitch, flYaw, 0 }, projInfo, bAccuracy))
if (!F::ProjSim.GetInfo(tInfo.m_pLocal, tInfo.m_pWeapon, { flPitch, flYaw, 0 }, projInfo, bAccuracy ? ProjSim_Trace : ProjSim_None))
{
out.m_iCalculated = 3; return;
}
@@ -481,8 +533,8 @@ void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTarge
}
{ // calculate trajectory from projectile origin
float flNewVel = tInfo.flVelocity, flDragTime = 0.f;
SolveProjectileSpeed(pWeapon, projInfo.m_vPos, vTargetPos, flNewVel, flDragTime, tInfo.flGravity);
float flNewVel = tInfo.m_flVelocity, flDragTime = 0.f;
SolveProjectileSpeed(tInfo.m_pWeapon, projInfo.m_vPos, vTargetPos, flNewVel, flDragTime, tInfo.m_flGravity);
const Vec3 vDelta = vTargetPos - projInfo.m_vPos;
const float flDist = vDelta.Length2D();
@@ -502,14 +554,14 @@ void CAimbotProjectile::CalculateAngle(const Vec3& vLocalPos, const Vec3& vTarge
out.m_flPitch = atan((pow(flNewVel, 2) - sqrt(flRoot)) / (flGrav * flDist));
}
out.m_flTime = flDist / (cos(out.m_flPitch) * flNewVel) + flDragTime;
out.m_flPitch = -RAD2DEG(out.m_flPitch) + flPitch - tInfo.flUpFix;
out.m_flPitch = -RAD2DEG(out.m_flPitch) + flPitch - tInfo.m_flUpFix;
}
iTimeTo = int(out.m_flTime / TICK_INTERVAL) + 1;
out.m_iCalculated = iTimeTo > iSimTime ? 2 : 1;
}
bool CAimbotProjectile::TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Target_t& target, Vec3& vPoint, Vec3& vAngles, int iSimTime, bool bSplash, std::deque<Vec3>* pProjLines)
bool CAimbotProjectile::TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Target_t& target, Vec3& vPoint, Vec3& vAngles, int iSimTime, bool bSplash, std::deque<Vec3>* pProjectilePath)
{
ProjectileInfo projInfo = {};
if (!F::ProjSim.GetInfo(pLocal, pWeapon, vAngles, projInfo) || !F::ProjSim.Initialize(projInfo))
@@ -653,7 +705,8 @@ bool CAimbotProjectile::TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Tar
int CAimbotProjectile::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* pWeapon, std::deque<Vec3>* pPlayerPath, std::deque<Vec3>* pProjectilePath, std::vector<DrawBox>* pBoxes, float* pTimeTo)
int CAimbotProjectile::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* pWeapon,
std::deque<Vec3>* pPlayerPath, std::deque<Vec3>* pProjectilePath, std::vector<DrawBox>* pBoxes, float* pTimeTo)
{
if (Vars::Aimbot::General::Ignore.Value & UNSIMULATED && H::Entities.GetChoke(target.m_pEntity) > Vars::Aimbot::General::TickTolerance.Value)
return false;
@@ -663,43 +716,58 @@ int CAimbotProjectile::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase
target.m_vPos = target.m_pEntity->m_vecOrigin();
const float flSize = target.m_pEntity->m_vecMins().DistTo(target.m_pEntity->m_vecMaxs());
int iMaxTime; Info_t tInfo = {};
int iMaxTime, iSplash; Info_t tInfo = { pLocal, pWeapon };
ProjectileInfo projInfo = {};
{
if (!F::ProjSim.GetInfo(pLocal, pWeapon, {}, projInfo, false) || !F::ProjSim.Initialize(projInfo, false))
if (!F::ProjSim.GetInfo(pLocal, pWeapon, {}, projInfo, ProjSim_None) || !F::ProjSim.Initialize(projInfo, false))
{
F::MoveSim.Restore(storage);
return false;
}
tInfo.m_vLocalEye = pLocal->GetShootPos();
tInfo.m_vTargetEye = target.m_pEntity->As<CTFPlayer>()->GetViewOffset();
tInfo.m_flLatency = F::Backtrack.GetReal() + TICKS_TO_TIME(G::AnticipatedChoke + Vars::Aimbot::Projectile::LatencyOffset.Value);
tInfo.m_iLatency = TIME_TO_TICKS(tInfo.m_flLatency);
iMaxTime = TIME_TO_TICKS(std::min(projInfo.m_flLifetime, Vars::Aimbot::Projectile::PredictionTime.Value));
Vec3 vVelocity = F::ProjSim.GetVelocity();
tInfo.flVelocity = vVelocity.Length(); // account for up velocity & capped velocity
Vec3 vBadAngle = {}; Math::VectorAngles(vVelocity, vBadAngle); tInfo.flUpFix = vBadAngle.x; // account for up velocity
tInfo.m_flVelocity = vVelocity.Length(); // account for up velocity & capped velocity
Vec3 vBadAngle = {}; Math::VectorAngles(vVelocity, vBadAngle); tInfo.m_flUpFix = vBadAngle.x; // account for up velocity
tInfo.vOffset = projInfo.m_vPos - pLocal->GetShootPos(); tInfo.vOffset.y *= -1;
tInfo.flOffset = tInfo.vOffset.Length() / tInfo.flVelocity; // silly
tInfo.m_vOffset = projInfo.m_vPos - tInfo.m_vLocalEye; tInfo.m_vOffset.y *= -1;
tInfo.m_flOffsetTime = tInfo.m_vOffset.Length() / tInfo.m_flVelocity; // silly
tInfo.flGravity = projInfo.m_flGravity;
tInfo.flRadius = GetSplashRadius(pWeapon, pLocal);
tInfo.flSphere = (tInfo.flRadius + flSize) / tInfo.flVelocity;
tInfo.m_flGravity = projInfo.m_flGravity;
tInfo.m_flRadius = GetSplashRadius(pWeapon, pLocal); tInfo.m_flRadiusTime = tInfo.m_flRadius / tInfo.m_flVelocity;
tInfo.m_flBoundingRadius = (tInfo.m_flRadius + flSize) / tInfo.m_flVelocity;
tInfo.iPrimeTime = TIME_TO_TICKS(PrimeTime(pWeapon));
iSplash = Vars::Aimbot::Projectile::SplashPrediction.Value && tInfo.m_flRadius ? Vars::Aimbot::Projectile::SplashPrediction.Value : 0;
tInfo.m_iSplashCount = !projInfo.m_flGravity ? Vars::Aimbot::Projectile::SplashCountDirect.Value : Vars::Aimbot::Projectile::SplashCountArc.Value;
if (Vars::Aimbot::Projectile::SplashRocket.Value)
{
switch (pWeapon->GetWeaponID())
{
case TF_WEAPON_ROCKETLAUNCHER:
case TF_WEAPON_ROCKETLAUNCHER_DIRECTHIT:
case TF_WEAPON_PARTICLE_CANNON:
tInfo.m_bRocket = true;
}
}
tInfo.m_iPrimeTime = TIME_TO_TICKS(PrimeTime(pWeapon));
}
const float flLatency = F::Backtrack.GetReal() + TICKS_TO_TIME(G::AnticipatedChoke + Vars::Aimbot::Projectile::LatencyOffset.Value);
const bool bCanSplash = Vars::Aimbot::Projectile::SplashPrediction.Value && tInfo.flRadius;
const int iSplash = bCanSplash ? Vars::Aimbot::Projectile::SplashPrediction.Value : 0;
auto mDirectPoints = iSplash == 3 ? std::unordered_map<int, Vec3> {} : GetDirectPoints(target, pLocal, pWeapon, tInfo);
auto vSpherePoints = !iSplash ? std::vector<Vec3> {} : ComputeSphere(tInfo.flRadius + flSize, Vars::Aimbot::Projectile::SplashPoints.Value);
auto mDirectPoints = iSplash == 3 ? std::unordered_map<int, Vec3>() : GetDirectPoints(target, tInfo);
auto vSpherePoints = !iSplash ? std::vector<std::pair<Vec3, int>>() : ComputeSphere(tInfo.m_flRadius + flSize, Vars::Aimbot::Projectile::SplashPoints.Value);
Vec3 vAngleTo, vPredicted, vTarget;
int iLowestPriority = std::numeric_limits<int>::max(); float flLowestDist = std::numeric_limits<float>::max();
for (int i = 1; i < iMaxTime; i++)
{
const int iSimTime = i - TIME_TO_TICKS(flLatency);
const int iSimTime = i - tInfo.m_iLatency;
if (!storage.m_bFailed)
{
F::MoveSim.RunTick(storage);
@@ -709,14 +777,14 @@ int CAimbotProjectile::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase
std::vector<Point_t> vSplashPoints = {};
if (iSplash)
{
Solution_t solution; CalculateAngle(pLocal->GetShootPos(), target.m_vPos, tInfo, iSimTime, pLocal, pWeapon, solution, false);
Solution_t solution; CalculateAngle(tInfo.m_vLocalEye, target.m_vPos, tInfo, iSimTime, solution, false);
if (solution.m_iCalculated != 3)
{
const float flTimeTo = solution.m_flTime - TICKS_TO_TIME(iSimTime);
if (flTimeTo < -tInfo.flSphere || vSpherePoints.empty())
if (flTimeTo < -tInfo.m_flBoundingRadius || vSpherePoints.empty())
break;
else if (abs(flTimeTo) < tInfo.flSphere)
vSplashPoints = GetSplashPoints(target, vSpherePoints, pLocal, pWeapon, tInfo, iSimTime);
else if (abs(flTimeTo) < tInfo.m_flBoundingRadius)
vSplashPoints = GetSplashPoints(target, vSpherePoints, tInfo, iSimTime);
}
}
else if (mDirectPoints.empty())
@@ -724,7 +792,7 @@ int CAimbotProjectile::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase
std::vector<std::tuple<Point_t, int, int>> vPoints = {};
for (auto& [iIndex, vPoint] : mDirectPoints)
vPoints.push_back({ { target.m_vPos + vPoint, {}}, iIndex + (iSplash == 2 ? Vars::Aimbot::Projectile::SplashCount.Value : 0), iIndex });
vPoints.push_back({ { target.m_vPos + vPoint, {}}, iIndex + (iSplash == 2 ? tInfo.m_iSplashCount : 0), iIndex });
for (auto& vPoint : vSplashPoints)
vPoints.push_back({ vPoint, iSplash == 1 ? 3 : 0, -1 });
@@ -734,18 +802,18 @@ int CAimbotProjectile::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase
Vec3 vOriginalPoint = vPoint.m_vPoint;
if (target.m_nAimedHitbox == HITBOX_HEAD)
vPoint.m_vPoint = PullPoint(vPoint.m_vPoint, pLocal->GetShootPos(), tInfo, target.m_pEntity->m_vecMins(), target.m_pEntity->m_vecMaxs(), target.m_vPos);
vPoint.m_vPoint = PullPoint(vPoint.m_vPoint, tInfo.m_vLocalEye, tInfo, target.m_pEntity->m_vecMins(), target.m_pEntity->m_vecMaxs(), target.m_vPos);
float flDist = bSplash ? target.m_vPos.DistTo(vPoint.m_vPoint) : flLowestDist;
bool bPriority = bSplash ? iPriority <= iLowestPriority : iPriority < iLowestPriority;
bool bTime = bSplash || tInfo.iPrimeTime < iSimTime || storage.m_MoveData.m_vecVelocity.IsZero();
bool bTime = bSplash || tInfo.m_iPrimeTime < iSimTime || storage.m_MoveData.m_vecVelocity.IsZero();
bool bDist = !bSplash || flDist < flLowestDist;
if (!bSplash && !bPriority)
mDirectPoints.erase(iIndex);
if (!bPriority || !bTime || !bDist)
continue;
CalculateAngle(pLocal->GetShootPos(), vPoint.m_vPoint, tInfo, iSimTime, pLocal, pWeapon, vPoint.m_Solution);
CalculateAngle(tInfo.m_vLocalEye, vPoint.m_vPoint, tInfo, iSimTime, vPoint.m_Solution);
if (!bSplash && (vPoint.m_Solution.m_iCalculated == 1 || vPoint.m_Solution.m_iCalculated == 3))
mDirectPoints.erase(iIndex);
if (vPoint.m_Solution.m_iCalculated != 1)
@@ -757,7 +825,7 @@ int CAimbotProjectile::CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase
{
iLowestPriority = iPriority; flLowestDist = flDist;
vAngleTo = vAngles, vPredicted = target.m_vPos, vTarget = vOriginalPoint;
*pTimeTo = vPoint.m_Solution.m_flTime + flLatency;
*pTimeTo = vPoint.m_Solution.m_flTime + tInfo.m_flLatency;
*pPlayerPath = storage.m_vPath;
if (!pPlayerPath->empty())
pPlayerPath->push_back(storage.m_MoveData.m_vecAbsOrigin);
@@ -983,7 +1051,7 @@ bool CAimbotProjectile::RunMain(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUser
}
if (!pWeapon->IsInReload())
Aim(pCmd, target.m_vAngleTo);
Aim(pCmd, target.m_vAngleTo);
if (G::PSilentAngles)
{
switch (pWeapon->GetWeaponID())
@@ -1026,7 +1094,7 @@ void CAimbotProjectile::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd*
pCmd->buttons &= ~IN_ATTACK;
else if (G::CanPrimaryAttack && Vars::Aimbot::Projectile::Modifiers.Value & (1 << 1))
{
if (bLastTickHeld && (G::LastUserCmd->buttons & IN_ATTACK && !(pCmd->buttons & IN_ATTACK) && bEarly || flAmount > 0.95f))
if (m_bLastTickHeld && (G::LastUserCmd->buttons & IN_ATTACK && !(pCmd->buttons & IN_ATTACK) && bEarly || flAmount > 0.95f))
{
switch (pWeapon->GetWeaponID())
{
@@ -1038,18 +1106,18 @@ void CAimbotProjectile::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd*
if (auto pSwap = pLocal->GetWeaponFromSlot(SLOT_SECONDARY))
{
pCmd->weaponselect = pSwap->entindex();
bLastTickCancel = pWeapon->entindex();
m_bLastTickCancel = pWeapon->entindex();
}
break;
case TF_WEAPON_PIPEBOMBLAUNCHER:
if (auto pSwap = pLocal->GetWeaponFromSlot(SLOT_PRIMARY))
{
pCmd->weaponselect = pSwap->entindex();
bLastTickCancel = pWeapon->entindex();
m_bLastTickCancel = pWeapon->entindex();
}
}
}
}
bLastTickHeld = Vars::Aimbot::General::AimType.Value;
m_bLastTickHeld = Vars::Aimbot::General::AimType.Value;
}
@@ -3,6 +3,13 @@
#include "../AimbotGlobal/AimbotGlobal.h"
enum PointType_
{
PointType_None = 0,
PointType_Regular = (1 << 0),
PointType_Obscured = (1 << 1)
};
struct Solution_t
{
float m_flPitch = 0.f;
@@ -17,14 +24,26 @@ struct Point_t
};
struct Info_t
{
Vec3 vOffset = {};
float flVelocity = 0.f;
float flGravity = 0.f;
float flRadius = 0.f;
float flSphere = 0.f;
float flUpFix = 0.f;
float flOffset = 0.f;
int iPrimeTime = 0;
CTFPlayer* m_pLocal = nullptr;
CTFWeaponBase* m_pWeapon = nullptr;
Vec3 m_vLocalEye = {};
Vec3 m_vTargetEye = {};
float m_flLatency = 0.f;
int m_iLatency = 0;
Vec3 m_vOffset = {};
float m_flVelocity = 0.f;
float m_flGravity = 0.f;
float m_flRadius = 0.f;
float m_flRadiusTime = 0.f;
float m_flBoundingRadius = 0.f;
float m_flUpFix = 0.f;
float m_flOffsetTime = 0.f;
int m_iSplashCount = 0;
bool m_bRocket = false;
int m_iPrimeTime = 0;
};
class CAimbotProjectile
@@ -32,11 +51,11 @@ class CAimbotProjectile
std::vector<Target_t> GetTargets(CTFPlayer* pLocal, CTFWeaponBase* pWeapon);
std::vector<Target_t> SortTargets(CTFPlayer* pLocal, CTFWeaponBase* pWeapon);
int GetHitboxPriority(int nHitbox, CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Target_t& target, Info_t& tInfo);
std::unordered_map<int, Vec3> GetDirectPoints(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Info_t& tInfo);
std::vector<Point_t> GetSplashPoints(Target_t& target, std::vector<Vec3>& vSpherePoints, CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Info_t& tInfo, int iSimTime);
int GetHitboxPriority(int nHitbox, Target_t& target, Info_t& tInfo);
std::unordered_map<int, Vec3> GetDirectPoints(Target_t& target, Info_t& tInfo);
std::vector<Point_t> GetSplashPoints(Target_t& target, std::vector<std::pair<Vec3, int>>& vSpherePoints, Info_t& tInfo, int iSimTime);
void CalculateAngle(const Vec3& vLocalPos, const Vec3& vTargetPos, Info_t& tInfo, int iSimTime, CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Solution_t& out, bool bAccuracy = true);
void CalculateAngle(const Vec3& vLocalPos, const Vec3& vTargetPos, Info_t& tInfo, int iSimTime, Solution_t& out, bool bAccuracy = true);
bool TestAngle(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, Target_t& target, Vec3& vPoint, Vec3& vAngles, int iSimTime, bool bSplash, std::deque<Vec3>* pProjectilePath);
int CanHit(Target_t& target, CTFPlayer* pLocal, CTFWeaponBase* pWeapon, std::deque<Vec3>* pPlayerPath, std::deque<Vec3>* pProjectilePath, std::vector<DrawBox>* pBoxes, float* pTimeTo);
@@ -1,8 +1,6 @@
#pragma once
#include "../../../SDK/SDK.h"
#include "../AimbotGlobal/AimbotGlobal.h"
class CAutoHeal
{
bool ActivateOnVoice(CTFPlayer* pLocal, CWeaponMedigun* pWeapon, CUserCmd* pCmd);
@@ -90,10 +90,10 @@ void CAutoRocketJump::Run(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* p
Vec3 vPos = {}; reinterpret_cast<CCollisionProperty*>(pLocal->GetCollideable())->CalcNearestPoint(vPoint, &vPos);
pLocal->SetAbsOrigin(vOriginal);
return vPoint.DistTo(vPos) < 120.f && SDK::VisPos(pLocal, pLocal, vPoint, vOrigin + pLocal->m_vecViewOffset(), MASK_SHOT);
return vPoint.DistTo(vPos) < 120.f && SDK::VisPosWorld(pLocal, pLocal, vPoint, vOrigin + pLocal->m_vecViewOffset(), MASK_SHOT);
};
bWillHit = WillHit(pLocal, localStorage.m_MoveData.m_vecAbsOrigin, trace.endpos);
bWillHit = WillHit(pLocal, localStorage.m_MoveData.m_vecAbsOrigin, trace.endpos + trace.plane.normal);
iDelay = std::max(n + (n > Vars::Misc::Movement::ApplyAbove.Value ? Vars::Misc::Movement::TimingOffset.Value : 0), 0);
if (bWillHit)
+15 -8
View File
@@ -132,7 +132,7 @@ void CMenu::MenuAimbot()
FDropdown("Aim type", Vars::Aimbot::General::AimType, { "Off", "Plain", "Smooth", "Silent" }, {}, FDropdown_Left);
FDropdown("Target selection", Vars::Aimbot::General::TargetSelection, { "FOV", "Distance" }, {}, FDropdown_Right);
FDropdown("Target", Vars::Aimbot::General::Target, { "Players", "Sentries", "Dispensers", "Teleporters", "Stickies", "NPCs", "Bombs" }, {}, FDropdown_Multi | FDropdown_Left);
FDropdown("Ignore", Vars::Aimbot::General::Ignore, { "Invulnerable", "Cloaked", "Dead Ringer", "Vaccinator", "Unsimulated Players", "Disguised", "Taunting" }, {}, FDropdown_Multi | FDropdown_Right);
FDropdown("Ignore", Vars::Aimbot::General::Ignore, { "Invulnerable", "Cloaked", "Dead Ringer", "Vaccinator", "Unsimulated players", "Disguised", "Taunting" }, {}, FDropdown_Multi | FDropdown_Right);
FSlider("Aim FOV", Vars::Aimbot::General::AimFOV, 0.f, 180.f, 1.f, "%g", FSlider_Clamp | FSlider_Precision);
PushTransparent(FGet(Vars::Aimbot::General::AimType) != 2);
FSlider("Smoothing## Hitscan", Vars::Aimbot::General::Smoothing, 0.f, 100.f, 1.f, "%g%%", FSlider_Clamp | FSlider_Precision);
@@ -157,7 +157,8 @@ void CMenu::MenuAimbot()
if (Section("debug## aimbot"))
{
FSlider("hitscan peek", Vars::Aimbot::General::HitscanPeek, 0, 5);
FToggle("peek dt only", Vars::Aimbot::General::PeekDTOnly); // this should probably stay on if you want to be able to target hitboxes other than the highest priority one
FToggle("peek dt only", Vars::Aimbot::General::PeekDTOnly);
FTooltip("this should probably stay on if you want to be able to\ntarget hitboxes other than the highest priority one");
FSlider("offset## nospread", Vars::Aimbot::General::NoSpreadOffset, -1.f, 1.f, 0.5f, "%g", FSlider_Precision);
FSlider("average", Vars::Aimbot::General::NoSpreadAverage, 1, 25);
FDropdown("aim holds fire", Vars::Aimbot::General::AimHoldsFire, { "false", "minigun only", "true" });
@@ -217,7 +218,7 @@ void CMenu::MenuAimbot()
{
if (Section("debug## projectile"))
{
FText("ground");
FText("\nground");
FSlider("samples##ground", Vars::Aimbot::Projectile::GroundSamples, 3, 66, 1, "%i", FSlider_Left);
FSlider("straight fuzzy value##ground", Vars::Aimbot::Projectile::GroundStraightFuzzyValue, 0.f, 500.f, 25.f, "%g", FSlider_Right | FSlider_Min | FSlider_Precision);
FSlider("low min samples##ground", Vars::Aimbot::Projectile::GroundLowMinimumSamples, 3, 66, 1, "%i", FSlider_Left);
@@ -241,10 +242,14 @@ void CMenu::MenuAimbot()
FSlider("hull increase", Vars::Aimbot::Projectile::HullIncrease, 0.f, 3.f, 0.5f, "%g", FSlider_Left | FSlider_Min | FSlider_Precision);
FSlider("drag override", Vars::Aimbot::Projectile::DragOverride, 0.f, 1.f, 0.01f, "%g", FSlider_Right | FSlider_Min | FSlider_Precision);
FSlider("time override", Vars::Aimbot::Projectile::TimeOverride, 0.f, 1.f, 0.01f, "%g", FSlider_Left | FSlider_Min | FSlider_Precision);
FSlider("splash points", Vars::Aimbot::Projectile::SplashPoints, 0, 100, 1, "%i", FSlider_Right);
FSlider("splash count", Vars::Aimbot::Projectile::SplashCount, 1, 5, 1, "%i", FSlider_Left);
FSlider("delta count", Vars::Aimbot::Projectile::DeltaCount, 1, 5, 1, "%i", FSlider_Right);
FDropdown("delta mode", Vars::Aimbot::Projectile::DeltaMode, { "average", "max" });
FToggle("splash grates", Vars::Aimbot::Projectile::SplashGrates);
FToggle("splash rocket", Vars::Aimbot::Projectile::SplashRocket, FToggle_Middle);
FTooltip("special splash type for rockets, more expensive");
FSlider("splash points", Vars::Aimbot::Projectile::SplashPoints, 1, 400, 5, "%i", FSlider_Min);
FSlider("direct splash count", Vars::Aimbot::Projectile::SplashCountDirect, 1, 100, 1, "%i", FSlider_Left | FSlider_Min);
FSlider("arc splash count", Vars::Aimbot::Projectile::SplashCountArc, 1, 100, 1, "%i", FSlider_Right | FSlider_Min);
FSlider("delta count", Vars::Aimbot::Projectile::DeltaCount, 1, 5, 1, "%i", FSlider_Left);
FDropdown("delta mode", Vars::Aimbot::Projectile::DeltaMode, { "average", "max" }, {}, FDropdown_Right);
} EndSection();
}
if (Section("Melee"))
@@ -968,7 +973,7 @@ void CMenu::MenuMisc()
TableNextColumn();
if (Section("Sound"))
{
FDropdown("Block", Vars::Misc::Sound::Block, { "Footsteps", "Noisemaker" }, {}, FDropdown_Multi);
FDropdown("Block", Vars::Misc::Sound::Block, { "Footsteps", "Noisemaker", "Frying pan" }, {}, FDropdown_Multi);
FToggle("Giant weapon sounds", Vars::Misc::Sound::GiantWeaponSounds);
FToggle("Hitsound always", Vars::Misc::Sound::HitsoundAlways, FToggle_Middle);
} EndSection();
@@ -1282,8 +1287,10 @@ void CMenu::MenuSettings()
FToggle("Debug logging", Vars::Debug::Logging, FToggle_Middle);
FToggle("Show server hitboxes", Vars::Debug::ServerHitbox); FTooltip("Only localhost servers");
FToggle("Anti aim lines", Vars::Debug::AntiAimLines, FToggle_Middle);
#ifdef DEBUG_TRACES
FToggle("Visualize traces", Vars::Debug::VisualizeTraces);
FToggle("Visualize trace hits", Vars::Debug::VisualizeTraceHits, FToggle_Middle);
#endif
} EndSection();
if (Section("Extra"))
{
+1 -1
View File
@@ -334,7 +334,7 @@ void CMisc::TauntKartControl(CTFPlayer* pLocal, CUserCmd* pCmd)
}
else if (pCmd->buttons & (IN_FORWARD | IN_BACK | IN_MOVELEFT | IN_MOVERIGHT))
{
if (flipVar)
if (flipVar || G::ShiftedTicks == G::MaxShift)
{ // you could just do this if you didn't care about viewangles
const Vec3 vecMove(pCmd->forwardmove, pCmd->sidemove, 0.f);
const float flLength = vecMove.Length();
@@ -178,16 +178,25 @@ bool CProjectileSimulation::GetInfoMain(CTFPlayer* pPlayer, CTFWeaponBase* pWeap
return false;
}
bool CProjectileSimulation::GetInfo(CTFPlayer* pPlayer, CTFWeaponBase* pWeapon, const Vec3& vAngles, ProjectileInfo& out, bool bTrace, bool bQuick, float flAutoCharge)
bool CProjectileSimulation::GetInfo(CTFPlayer* pPlayer, CTFWeaponBase* pWeapon, const Vec3& vAngles, ProjectileInfo& out, int iFlags, float flAutoCharge)
{
const float flOldCurrentTime = I::GlobalVars->curtime;
if (bQuick)
I::GlobalVars->curtime = TICKS_TO_TIME(pPlayer->m_nTickBase());
const bool bReturn = GetInfoMain(pPlayer, pWeapon, vAngles, out, bTrace, bQuick, flAutoCharge);
I::GlobalVars->curtime = flOldCurrentTime;
bool bTrace = iFlags & ProjSim_Trace;
bool InitCheck = iFlags & ProjSim_InitCheck;
bool bQuick = iFlags & ProjSim_Quick;
if (!bReturn)
return false;
bool bReturn;
if (bQuick)
{
const float flOldCurrentTime = I::GlobalVars->curtime;
I::GlobalVars->curtime = TICKS_TO_TIME(pPlayer->m_nTickBase());
bReturn = GetInfoMain(pPlayer, pWeapon, vAngles, out, bTrace, true, flAutoCharge);
I::GlobalVars->curtime = flOldCurrentTime;
}
else
bReturn = GetInfoMain(pPlayer, pWeapon, vAngles, out, bTrace, false, flAutoCharge);
if (!bReturn || !InitCheck)
return bReturn;
const Vec3 vStart = bQuick ? pPlayer->GetEyePosition() : pPlayer->GetShootPos();
const Vec3 vEnd = out.m_vPos;
@@ -1,6 +1,14 @@
#pragma once
#include "../../../SDK/SDK.h"
enum ProjSim_
{
ProjSim_None = 0,
ProjSim_Trace = 1 << 0,
ProjSim_InitCheck = 1 << 2,
ProjSim_Quick = 1 << 1
};
struct ProjectileInfo
{
ProjectileType_t m_iType{};
@@ -39,7 +47,7 @@ class CProjectileSimulation
};
public:
bool GetInfo(CTFPlayer* pPlayer, CTFWeaponBase* pWeapon, const Vec3& vAngles, ProjectileInfo& out, bool bTrace = true, bool bQuick = false, float flAutoCharge = -1.f);
bool GetInfo(CTFPlayer* pPlayer, CTFWeaponBase* pWeapon, const Vec3& vAngles, ProjectileInfo& out, int iFlags = ProjSim_Trace | ProjSim_InitCheck, float flAutoCharge = -1.f);
bool Initialize(ProjectileInfo& info, bool bSimulate = true);
void RunTick(ProjectileInfo& info, bool bPath = true);
Vec3 GetOrigin();
+2 -2
View File
@@ -117,7 +117,7 @@ bool CChams::GetChams(CTFPlayer* pLocal, CBaseEntity* pEntity, Chams_t* pChams)
case ETFClassID::CTFProjectile_Flare:
{
auto pWeapon = pEntity->As<CTFBaseRocket>()->m_hLauncher().Get();
auto pOwner = pWeapon ? pWeapon->As<CTFWeaponBase>()->m_hOwner().Get() : nullptr;
auto pOwner = pWeapon ? pWeapon->As<CTFWeaponBase>()->m_hOwner().Get() : pEntity;
if (!pOwner) pOwner = pEntity;
return GetPlayerChams(pOwner, pLocal, pChams, Vars::Chams::Friendly::Projectiles.Value, Vars::Chams::Enemy::Projectiles.Value);
@@ -127,7 +127,7 @@ bool CChams::GetChams(CTFPlayer* pLocal, CBaseEntity* pEntity, Chams_t* pChams)
//case ETFClassID::CTFProjectile_Syringe: // not drawn
{
auto pWeapon = pEntity->As<CTFBaseRocket>()->m_hLauncher().Get();
auto pOwner = pWeapon ? pWeapon->As<CTFWeaponBase>()->m_hOwner().Get() : nullptr;
auto pOwner = pWeapon ? pWeapon->As<CTFWeaponBase>()->m_hOwner().Get() : pEntity;
if (!pOwner) pOwner = pEntity;
return GetPlayerChams(pOwner, pLocal, pChams, Vars::Chams::Friendly::Projectiles.Value, Vars::Chams::Enemy::Projectiles.Value);
+2 -2
View File
@@ -109,7 +109,7 @@ bool CGlow::GetGlow(CTFPlayer* pLocal, CBaseEntity* pEntity, Glow_t* pGlow, Colo
case ETFClassID::CTFProjectile_Flare:
{
auto pWeapon = pEntity->As<CTFBaseRocket>()->m_hLauncher().Get();
auto pOwner = pWeapon ? pWeapon->As<CTFWeaponBase>()->m_hOwner().Get() : nullptr;
auto pOwner = pWeapon ? pWeapon->As<CTFWeaponBase>()->m_hOwner().Get() : pEntity;
if (!pOwner) pOwner = pEntity;
return GetPlayerGlow(pOwner, pLocal, pGlow, pColor, Vars::Glow::Friendly::Projectiles.Value, Vars::Glow::Enemy::Projectiles.Value);
@@ -119,7 +119,7 @@ bool CGlow::GetGlow(CTFPlayer* pLocal, CBaseEntity* pEntity, Glow_t* pGlow, Colo
//case ETFClassID::CTFProjectile_Syringe: // not drawn
{
auto pWeapon = pEntity->As<CTFBaseRocket>()->m_hLauncher().Get();
auto pOwner = pWeapon ? pWeapon->As<CTFWeaponBase>()->m_hOwner().Get() : nullptr;
auto pOwner = pWeapon ? pWeapon->As<CTFWeaponBase>()->m_hOwner().Get() : pEntity;
if (!pOwner) pOwner = pEntity;
return GetPlayerGlow(pOwner, pLocal, pGlow, pColor, Vars::Glow::Friendly::Projectiles.Value, Vars::Glow::Enemy::Projectiles.Value);
+11 -9
View File
@@ -24,12 +24,15 @@ void CVisuals::DrawAimbotFOV(CTFPlayer* pLocal)
if (!Vars::Aimbot::General::FOVCircle.Value || !Vars::Colors::FOVCircle.Value.a || !pLocal->IsAlive() || pLocal->IsAGhost() || pLocal->IsTaunting() || pLocal->IsStunned() || pLocal->IsInBumperKart())
return;
const float flR = tanf(DEG2RAD(Vars::Aimbot::General::AimFOV.Value) / 2.0f) / tanf(DEG2RAD(pLocal->m_iFOV()) / 2.0f) * H::Draw.m_nScreenW;
const Color_t clr = Vars::Colors::FOVCircle.Value;
H::Draw.LineCircle(H::Draw.m_nScreenW / 2, H::Draw.m_nScreenH / 2, flR, 68, clr);
if (Vars::Aimbot::General::AimFOV.Value >= 90.f)
return;
float flW = H::Draw.m_nScreenW, flH = H::Draw.m_nScreenH;
float flRadius = tanf(DEG2RAD(Vars::Aimbot::General::AimFOV.Value)) / tanf(DEG2RAD(pLocal->m_iFOV()) / 2) * flW * (4.f / 6.f) / (flW / flH);
H::Draw.LineCircle(H::Draw.m_nScreenW / 2, H::Draw.m_nScreenH / 2, flRadius, 68, Vars::Colors::FOVCircle.Value);
}
void CVisuals::DrawTickbaseText(CTFPlayer* pLocal)
void CVisuals::DrawTicks(CTFPlayer* pLocal)
{
if (!(Vars::Menu::Indicators.Value & (1 << 0)))
return;
@@ -37,20 +40,18 @@ void CVisuals::DrawTickbaseText(CTFPlayer* pLocal)
if (!pLocal->IsAlive())
return;
const int iTicks = std::clamp(G::ShiftedTicks + G::ChokeAmount, 0, G::MaxShift);
const DragBox_t dtPos = Vars::Menu::TicksDisplay.Value;
const auto& fFont = H::Fonts.GetFont(FONT_INDICATORS);
const int offset = 7 + 12 * Vars::Menu::DPI.Value;
H::Draw.String(fFont, dtPos.x, dtPos.y + 2, Vars::Menu::Theme::Active.Value, ALIGN_TOP, "Ticks %d / %d", iTicks, G::MaxShift);
H::Draw.String(fFont, dtPos.x, dtPos.y + 2, Vars::Menu::Theme::Active.Value, ALIGN_TOP, "Ticks %d / %d", G::ShiftedTicks, G::MaxShift);
if (G::WaitForShift)
H::Draw.String(fFont, dtPos.x, dtPos.y + fFont.m_nTall + offset, Vars::Menu::Theme::Active.Value, ALIGN_TOP, "Not Ready");
const float ratioCurrent = (float)iTicks / (float)G::MaxShift;
const float ratioCurrent = float(std::clamp(G::ShiftedTicks, 0, G::MaxShift)) / G::MaxShift;
float sizeX = 100 * Vars::Menu::DPI.Value, sizeY = 12 * Vars::Menu::DPI.Value, posX = dtPos.x - sizeX / 2, posY = dtPos.y + 5 + fFont.m_nTall;
H::Draw.LineRect(posX, dtPos.y + 5 + fFont.m_nTall, sizeX, sizeY, Vars::Menu::Theme::Accent.Value);
if (iTicks)
if (ratioCurrent)
{
sizeX -= 4, sizeY -= 4, posX = dtPos.x - sizeX / 2;
H::Draw.StartClipping(posX, posY, sizeX * ratioCurrent, sizeY + 2 /*?*/);
@@ -481,6 +482,7 @@ void CVisuals::DrawDebugInfo(CTFPlayer* pLocal)
}
H::Draw.String(fFont, x, y += fFont.m_nTall + 1, {}, ALIGN_TOPLEFT, "Round state: %i", SDK::GetRoundState());
H::Draw.String(fFont, x, y += fFont.m_nTall + 1, {}, ALIGN_TOPLEFT, "Tickcount: %i", pLocal->m_nTickBase());
H::Draw.String(fFont, x, y += fFont.m_nTall + 1, {}, ALIGN_TOPLEFT, "Entities: %i (%i, %i)", I::ClientEntityList->GetMaxEntities(), I::ClientEntityList->GetHighestEntityIndex(), I::ClientEntityList->NumberOfEntities(false));
}
}
+1 -1
View File
@@ -26,7 +26,7 @@ private:
public:
void DrawAimbotFOV(CTFPlayer* pLocal);
void DrawTickbaseText(CTFPlayer* pLocal);
void DrawTicks(CTFPlayer* pLocal);
void DrawOnScreenPing(CTFPlayer* pLocal);
void DrawOnScreenConditions(CTFPlayer* pLocal);
void DrawSeedPrediction(CTFPlayer* pLocal);
@@ -9,7 +9,5 @@ MAKE_HOOK(CBaseAnimating_UpdateClientSideAnimation, S::CBaseAnimating_UpdateClie
if (!G::UpdatingAnims && (rcx && rcx == pLocal ? !pLocal->IsInBumperKart() : true))
return;
G::AnimateKart = true;
CALL_ORIGINAL(rcx);
G::AnimateKart = false;
}
@@ -11,59 +11,35 @@ MAKE_HOOK(CBaseHudChatLine_InsertAndColorizeText, S::CBaseHudChatLine_InsertAndC
if (!clientIndex || !I::EngineClient->GetPlayerInfo(clientIndex, &pi))
return CALL_ORIGINAL(rcx, buf, clientIndex);
bool bLocal = false, bFriend = false, bEnemy = false;
PriorityLabel_t* pTag = nullptr;
if (Vars::Visuals::UI::ChatTags.Value || Vars::Visuals::UI::StreamerMode.Value)
{
if (clientIndex == I::EngineClient->GetLocalPlayer())
bLocal = true;
else if (H::Entities.IsFriend(clientIndex))
bFriend = true;
else
{
auto pTag = F::PlayerUtils.GetSignificantTag(clientIndex, 0);
if (!pTag)
{
auto pResource = H::Entities.GetPR();
bEnemy = !pResource || pResource->GetTeam(I::EngineClient->GetLocalPlayer()) != pResource->GetTeam(clientIndex);
}
}
}
std::string sMessage = SDK::ConvertWideToUTF8(buf);
std::string sName = pi.name;
auto iFind = sMessage.find(pi.name);
bool bFound = iFind != std::string::npos;
if (bFound)
int iType = 0;
if (const char* sReplace = F::PlayerUtils.GetPlayerName(clientIndex, nullptr, &iType))
{
int iType = 0;
if (const char* sReplace = F::PlayerUtils.GetPlayerName(clientIndex, nullptr, &iType))
{
if (bFound)
sMessage = sMessage.replace(std::max(iFind - 1, 0ui64), sName.length() + 1, std::format("\x3{}\x1", sReplace));
if (iType == 1)
return CALL_ORIGINAL(rcx, const_cast<wchar_t*>(SDK::ConvertUtf8ToWide(sMessage).c_str()), clientIndex);
else
sName = sReplace;
}
if (iType == 1)
return CALL_ORIGINAL(rcx, const_cast<wchar_t*>(SDK::ConvertUtf8ToWide(sMessage).c_str()), clientIndex);
else
sName = sReplace;
}
if (Vars::Visuals::UI::ChatTags.Value)
{
std::string sTag, cColor;
if (bLocal)
if (clientIndex == I::EngineClient->GetLocalPlayer())
{
if (Vars::Visuals::UI::ChatTags.Value & (1 << 0))
sTag = "You", cColor = Vars::Colors::Local.Value.ToHexA();
}
else if (bFriend)
else if (Vars::Visuals::UI::ChatTags.Value & (1 << 1) && H::Entities.IsFriend(clientIndex))
sTag = "Friend", cColor = F::PlayerUtils.m_vTags[FRIEND_TAG].Color.ToHexA();
else if (Vars::Visuals::UI::ChatTags.Value & (1 << 2))
{
if (Vars::Visuals::UI::ChatTags.Value & (1 << 1))
sTag = "Friend", cColor = F::PlayerUtils.m_vTags[FRIEND_TAG].Color.ToHexA();
}
else if (pTag)
{
if (Vars::Visuals::UI::ChatTags.Value & (1 << 2))
if (auto pTag = F::PlayerUtils.GetSignificantTag(clientIndex, 0))
sTag = pTag->Name, cColor = pTag->Color.ToHexA();
}
+11 -5
View File
@@ -4,6 +4,8 @@ MAKE_SIGNATURE(CTFPlayerShared_InCond, "client.dll", "48 89 5C 24 ? 57 48 83 EC
MAKE_SIGNATURE(CTFPlayer_ShouldDraw_InCond_Call, "client.dll", "E8 ? ? ? ? 84 C0 74 ? 32 C0 48 8B 74 24", 0x5);
MAKE_SIGNATURE(CTFWearable_ShouldDraw_InCond_Call, "client.dll", "E8 ? ? ? ? 84 C0 0F 85 ? ? ? ? 41 BF", 0x5);
MAKE_SIGNATURE(CHudScope_ShouldDraw_InCond_Call, "client.dll", "84 C0 74 ? 48 8B CB E8 ? ? ? ? 48 85 C0 74 ? 48 8B CB E8 ? ? ? ? 48 8B C8 48 8B 10 FF 92 ? ? ? ? 83 F8 ? 0F 94 C0", 0x0);
MAKE_SIGNATURE(CTFPlayer_CreateMove_InCond_Call, "client.dll", "84 C0 74 ? 4C 8B C3", 0x0);
MAKE_SIGNATURE(CTFInput_ApplyMouse_InCond_Call, "client.dll", "84 C0 74 ? F3 0F 10 9B", 0x0);
MAKE_HOOK(CTFPlayerShared_InCond, S::CTFPlayerShared_InCond(), bool, __fastcall,
void* rcx, ETFCond nCond)
@@ -11,6 +13,8 @@ MAKE_HOOK(CTFPlayerShared_InCond, S::CTFPlayerShared_InCond(), bool, __fastcall,
static const auto dwPlayer = S::CTFPlayer_ShouldDraw_InCond_Call();
static const auto dwWearable = S::CTFWearable_ShouldDraw_InCond_Call();
static const auto dwHudScope = S::CHudScope_ShouldDraw_InCond_Call();
static const auto dwKart1 = S::CTFPlayer_CreateMove_InCond_Call();
static const auto dwKart2 = S::CTFInput_ApplyMouse_InCond_Call();
const auto dwRetAddr = uintptr_t(_ReturnAddress());
auto GetOuter = [&rcx]() -> CBaseEntity*
@@ -33,18 +37,20 @@ MAKE_HOOK(CTFPlayerShared_InCond, S::CTFPlayerShared_InCond(), bool, __fastcall,
auto pLocal = H::Entities.GetLocal();
auto pEntity = GetOuter();
// Compare team's, removing team's taunt is useless
if (pLocal && pEntity && pEntity->m_iTeamNum() != pLocal->m_iTeamNum())
return false;
}
break;
case TF_COND_HALLOWEEN_KART:
if (Vars::Misc::Automation::KartControl.Value && H::Entities.GetLocal() == GetOuter() && !G::AnimateKart)
return false;
break;
case TF_COND_DISGUISED:
if (Vars::Visuals::Removals::Disguises.Value && H::Entities.GetLocal() != GetOuter())
return false;
break;
case TF_COND_HALLOWEEN_KART:
if (Vars::Misc::Automation::KartControl.Value && (dwRetAddr == dwKart1 || dwRetAddr == dwKart2))
return false;
break;
case TF_COND_FREEZE_INPUT:
return false;
}
return CALL_ORIGINAL(rcx, nCond);
@@ -0,0 +1,20 @@
#include "../SDK/SDK.h"
#ifdef DEBUG_TRACES
MAKE_HOOK(IEngineTrace_TraceRay, U::Memory.GetVFunc(I::EngineTrace, 4), void, __fastcall,
void* rcx, const Ray_t& ray, unsigned int fMask, ITraceFilter* pTraceFilter, trace_t* pTrace)
{
CALL_ORIGINAL(rcx, ray, fMask, pTraceFilter, pTrace);
if (Vars::Debug::VisualizeTraces.Value)
{
Vec3 vStart = ray.m_Start + ray.m_StartOffset;
Vec3 vEnd = Vars::Debug::VisualizeTraceHits.Value ? pTrace->endpos : ray.m_Delta + vStart;
G::LineStorage.push_back({ { vStart, vEnd }, I::GlobalVars->curtime + 0.015f, { 0, 0, 255, 255 }, bool(GetAsyncKeyState(VK_MENU) & 0x8000) });
if (!ray.m_IsRay)
{
G::BoxStorage.push_back({ ray.m_Start, ray.m_Extents * -1, ray.m_Extents, {}, I::GlobalVars->curtime + 0.015f, { 0, 0, 255, 255 }, { 0, 0, 0, 0 }, bool(GetAsyncKeyState(VK_MENU) & 0x8000) });
G::BoxStorage.push_back({ vEnd - ray.m_StartOffset, ray.m_Extents * -1, ray.m_Extents, {}, I::GlobalVars->curtime + 0.015f, { 0, 0, 255, 255 }, { 0, 0, 0, 0 }, bool(GetAsyncKeyState(VK_MENU) & 0x8000) });
}
}
}
#endif
+1 -1
View File
@@ -44,7 +44,7 @@ void Paint()
F::Visuals.DrawOnScreenPing(pLocal);
F::SpectatorList.Run(pLocal);
F::CritHack.Draw(pLocal);
F::Visuals.DrawTickbaseText(pLocal);
F::Visuals.DrawTicks(pLocal);
F::Visuals.DrawDebugInfo(pLocal);
}
I::MatSystemSurface->FinishDrawing();
@@ -96,7 +96,7 @@ public:
inline Vec3 GetCenter()
{
return m_vecOrigin() + Vec3(0, 0, (m_vecMins().z + m_vecMaxs().z) / 2);
return m_vecOrigin() + (m_vecMins() + m_vecMaxs()) / 2;
}
inline Vec3 GetRenderCenter()
@@ -241,6 +241,9 @@ public:
inline Vec3 GetViewOffset() // use on nonlocal players
{
if (!IsPlayer())
return (m_vecMins() + m_vecMaxs()) / 2;
auto getMainOffset = [this]() -> Vec3
{
if (IsDucking())
-1
View File
@@ -80,7 +80,6 @@ namespace G
inline bool Choking = false;
inline bool UpdatingAnims = false;
inline bool AnimateKart = false;
inline bool DrawingProps = false;
inline bool FlipViewmodels = false;
+40 -40
View File
@@ -13,8 +13,7 @@ void CEntities::Store()
return;
m_pLocal = pLocal->As<CTFPlayer>();
if (auto pEntity = m_pLocal->m_hActiveWeapon().Get())
m_pLocalWeapon = pEntity->As<CTFWeaponBase>();
m_pLocalWeapon = m_pLocal->m_hActiveWeapon().Get()->As<CTFWeaponBase>();
switch (m_pLocal->m_iObserverMode())
{
@@ -28,53 +27,18 @@ void CEntities::Store()
default: break;
}
for (int n = 1; n <= I::ClientEntityList->GetHighestEntityIndex(); n++)
for (int n = I::EngineClient->GetMaxClients() + 1; n <= I::ClientEntityList->GetHighestEntityIndex(); n++)
{
auto pClientEntity = I::ClientEntityList->GetClientEntity(n);
if (!pClientEntity)
auto pEntity = I::ClientEntityList->GetClientEntity(n)->As<CBaseEntity>();
if (!pEntity || pEntity->IsDormant())
continue;
auto pEntity = pClientEntity->As<CBaseEntity>();
if (pEntity->IsDormant())
{
if (!pEntity->IsPlayer() || !m_mDormancy.contains(pEntity))
continue;
auto pPlayer = pEntity->As<CTFPlayer>();
auto& dormantData = m_mDormancy[pEntity];
float lastUpdate = dormantData.LastUpdate;
if (I::EngineClient->Time() - lastUpdate > Vars::ESP::DormantTime.Value)
continue;
pPlayer->SetAbsOrigin(dormantData.Location);
pPlayer->m_vecOrigin() = dormantData.Location;
pPlayer->m_lifeState() = LIFE_ALIVE;
auto playerResource = GetPR();
if (playerResource && playerResource->GetValid(n))
pPlayer->m_iHealth() = playerResource->GetHealth(n);
}
else if (pEntity->IsPlayer())
m_mDormancy[pEntity] = { pEntity->m_vecOrigin(), I::EngineClient->Time() };
auto nClassID = pEntity->GetClassID();
switch (nClassID)
{
case ETFClassID::CTFPlayerResource:
m_pPlayerResource = pEntity->As<CTFPlayerResource>();
break;
case ETFClassID::CTFPlayer:
{
m_mGroups[EGroupType::PLAYERS_ALL].push_back(pEntity);
m_mGroups[pEntity->m_iTeamNum() != m_pLocal->m_iTeamNum() ? EGroupType::PLAYERS_ENEMIES : EGroupType::PLAYERS_TEAMMATES].push_back(pEntity);
PlayerInfo_t pi{};
if (I::EngineClient->GetPlayerInfo(n, &pi) && !pi.fakeplayer)
m_mIFriends[n] = m_mUFriends[pi.friendsID] = I::SteamFriends->HasFriend({ pi.friendsID, 1, k_EUniversePublic, k_EAccountTypeIndividual }, k_EFriendFlagImmediate);
break;
}
case ETFClassID::CObjectSentrygun:
case ETFClassID::CObjectDispenser:
case ETFClassID::CObjectTeleporter:
@@ -182,6 +146,42 @@ void CEntities::Store()
break;
}
}
for (int n = 1; n <= I::EngineClient->GetMaxClients(); n++)
{
auto pEntity = I::ClientEntityList->GetClientEntity(n)->As<CBaseEntity>();
if (!pEntity || !pEntity->IsPlayer())
continue;
if (pEntity->IsDormant())
{
if (!m_mDormancy.contains(pEntity))
continue;
auto& dormantData = m_mDormancy[pEntity];
if (I::EngineClient->Time() - dormantData.LastUpdate > Vars::ESP::DormantTime.Value)
continue;
auto pPlayer = pEntity->As<CTFPlayer>();
pPlayer->SetAbsOrigin(dormantData.Location);
pPlayer->m_vecOrigin() = dormantData.Location;
pPlayer->m_lifeState() = LIFE_ALIVE;
auto playerResource = GetPR();
if (playerResource && playerResource->GetValid(n))
pPlayer->m_iHealth() = playerResource->GetHealth(n);
}
else
m_mDormancy[pEntity] = { pEntity->m_vecOrigin(), I::EngineClient->Time() };
m_mGroups[EGroupType::PLAYERS_ALL].push_back(pEntity);
m_mGroups[pEntity->m_iTeamNum() != m_pLocal->m_iTeamNum() ? EGroupType::PLAYERS_ENEMIES : EGroupType::PLAYERS_TEAMMATES].push_back(pEntity);
PlayerInfo_t pi{};
if (I::EngineClient->GetPlayerInfo(n, &pi) && !pi.fakeplayer)
m_mIFriends[n] = m_mUFriends[pi.friendsID] = I::SteamFriends->HasFriend({ pi.friendsID, 1, k_EUniversePublic, k_EAccountTypeIndividual }, k_EFriendFlagImmediate);
}
int iLag;
{
@@ -1,4 +1,5 @@
#include "TraceFilters.h"
#include "../../SDK.h"
bool CTraceFilterHitscan::ShouldHitEntity(IHandleEntity* pServerEntity, int nContentsMask)
+14 -8
View File
@@ -66,15 +66,17 @@ bool SDK::IsGameWindowInFocus()
std::wstring SDK::ConvertUtf8ToWide(const std::string& source)
{
std::wstring result(source.length(), 0);
MultiByteToWideChar(CP_UTF8, 0, source.c_str(), -1, result.data(), int(source.length()));
int size = MultiByteToWideChar(CP_UTF8, 0, source.data(), -1, nullptr, 0);
std::wstring result(size, 0);
MultiByteToWideChar(CP_UTF8, 0, source.data(), -1, result.data(), size);
return result;
}
std::string SDK::ConvertWideToUTF8(const std::wstring& source)
{
std::string result(source.length(), 0);
WideCharToMultiByte(CP_UTF8, 0, source.c_str(), -1, result.data(), int(source.length()), NULL, NULL);
int size = WideCharToMultiByte(CP_UTF8, 0, source.data(), -1, nullptr, 0, nullptr, nullptr);
std::string result(size, 0);
WideCharToMultiByte(CP_UTF8, 0, source.data(), -1, result.data(), size, nullptr, nullptr);
return result;
}
@@ -254,8 +256,10 @@ void SDK::Trace(const Vec3& vecStart, const Vec3& vecEnd, unsigned int nMask, IT
ray.Init(vecStart, vecEnd);
I::EngineTrace->TraceRay(ray, nMask, pFilter, pTrace);
#ifdef DEBUG_TRACES
if (Vars::Debug::VisualizeTraces.Value)
G::LineStorage.push_back({ { vecStart, Vars::Debug::VisualizeTraceHits.Value ? pTrace->endpos : vecEnd }, I::GlobalVars->curtime + 0.015f });
G::LineStorage.push_back({ { vecStart, Vars::Debug::VisualizeTraceHits.Value ? pTrace->endpos : vecEnd }, I::GlobalVars->curtime + 0.015f, {}, bool(GetAsyncKeyState(VK_MENU) & 0x8000) });
#endif
}
void SDK::TraceHull(const Vec3& vecStart, const Vec3& vecEnd, const Vec3& vecHullMin, const Vec3& vecHullMax, unsigned int nMask, ITraceFilter* pFilter, CGameTrace* pTrace)
@@ -264,15 +268,17 @@ void SDK::TraceHull(const Vec3& vecStart, const Vec3& vecEnd, const Vec3& vecHul
ray.Init(vecStart, vecEnd, vecHullMin, vecHullMax);
I::EngineTrace->TraceRay(ray, nMask, pFilter, pTrace);
#ifdef DEBUG_TRACES
if (Vars::Debug::VisualizeTraces.Value)
{
G::LineStorage.push_back({ { vecStart, Vars::Debug::VisualizeTraceHits.Value ? pTrace->endpos : vecEnd }, I::GlobalVars->curtime + 0.015f });
G::LineStorage.push_back({ { vecStart, Vars::Debug::VisualizeTraceHits.Value ? pTrace->endpos : vecEnd }, I::GlobalVars->curtime + 0.015f, {}, bool(GetAsyncKeyState(VK_MENU) & 0x8000) });
if (!(vecHullMax - vecHullMin).IsZero())
{
G::BoxStorage.push_back({ vecStart, vecHullMin, vecHullMax, {}, I::GlobalVars->curtime + 0.015f, {}, { 0, 0, 0, 0 } });
G::BoxStorage.push_back({ Vars::Debug::VisualizeTraceHits.Value ? pTrace->endpos : vecEnd, vecHullMin, vecHullMax, {}, I::GlobalVars->curtime + 0.015f, {}, { 0, 0, 0, 0 } });
G::BoxStorage.push_back({ vecStart, vecHullMin, vecHullMax, {}, I::GlobalVars->curtime + 0.015f, {}, { 0, 0, 0, 0 }, bool(GetAsyncKeyState(VK_MENU) & 0x8000) });
G::BoxStorage.push_back({ Vars::Debug::VisualizeTraceHits.Value ? pTrace->endpos : vecEnd, vecHullMin, vecHullMax, {}, I::GlobalVars->curtime + 0.015f, {}, { 0, 0, 0, 0 }, bool(GetAsyncKeyState(VK_MENU) & 0x8000) });
}
}
#endif
}
bool SDK::VisPos(CBaseEntity* pSkip, const CBaseEntity* pEntity, const Vec3& from, const Vec3& to, unsigned int nMask)
+7 -2
View File
@@ -170,8 +170,11 @@ namespace Vars
CVar(DragOverride, 0.f, NOSAVE) // debug
CVar(TimeOverride, 0.f, NOSAVE) // debug
CVar(HuntsmanLerp, 100.f, NOSAVE) // debug
CVar(SplashPoints, 80, NOSAVE) // debug
CVar(SplashCount, 5, NOSAVE) // debug
CVar(SplashGrates, true, NOSAVE) // debug
CVar(SplashRocket, false, NOSAVE) // debug
CVar(SplashPoints, 100, NOSAVE) // debug
CVar(SplashCountDirect, 100, NOSAVE) // debug
CVar(SplashCountArc, 5, NOSAVE) // debug
CVar(DeltaCount, 5, NOSAVE) // debug
CVar(DeltaMode, 0, NOSAVE) // debug
SUBNAMESPACE_END(Projectile)
@@ -747,7 +750,9 @@ namespace Vars
CVar(Logging, false, NOSAVE)
CVar(ServerHitbox, false, NOSAVE)
CVar(AntiAimLines, false)
#ifdef DEBUG_TRACES
CVar(VisualizeTraces, false, NOSAVE)
CVar(VisualizeTraceHits, false, NOSAVE)
#endif
NAMESPACE_END(Debug)
}