mirror of
https://github.com/rei-2/Amalgam
synced 2026-10-10 04:43:09 +08:00
grappling hook projectile aim support
some reorganization
This commit is contained in:
@@ -962,6 +962,7 @@
|
||||
<ClCompile Include="src\Hooks\CBaseAnimating_MaintainSequenceTransitions.cpp" />
|
||||
<ClCompile Include="src\Hooks\CBaseAnimating_SetSequence.cpp" />
|
||||
<ClCompile Include="src\Hooks\CBaseAnimating_SetupBones.cpp" />
|
||||
<ClCompile Include="src\Hooks\CTFGrapplingHook_ItemPostFrame.cpp" />
|
||||
<ClCompile Include="src\Hooks\CTFPlayer_UpdateClientSideAnimation.cpp" />
|
||||
<ClCompile Include="src\Hooks\CBaseViewModel_Interpolate.cpp" />
|
||||
<ClCompile Include="src\Hooks\CBaseEntity_EstimateAbsVelocity.cpp" />
|
||||
|
||||
@@ -208,6 +208,7 @@
|
||||
<ClCompile Include="src\Hooks\CEngineClient_GetScreenAspectRatio.cpp" />
|
||||
<ClCompile Include="src\Features\AntiCheatCompatibility\AntiCheatCompatibility.cpp" />
|
||||
<ClCompile Include="src\Features\Debug\Debug.cpp" />
|
||||
<ClCompile Include="src\Hooks\CTFGrapplingHook_ItemPostFrame.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\Utils\UtlVector\UtlVector.h" />
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#define no_inline __declspec(noinline)
|
||||
|
||||
#define VA_LIST(...) __VA_ARGS__
|
||||
|
||||
#define STRINGIFY(x) STRINGIFY2(x)
|
||||
|
||||
@@ -367,7 +367,9 @@ bool CAimbotGlobal::ShouldHoldAttack(CTFWeaponBase* pWeapon)
|
||||
break;
|
||||
[[fallthrough]];
|
||||
case Vars::Aimbot::General::AimHoldsFireEnum::Always:
|
||||
if (!F::Aimbot.m_bRunningSecondary && !G::CanPrimaryAttack && G::LastUserCmd->buttons & IN_ATTACK && Vars::Aimbot::General::AimType.Value && !pWeapon->IsInReload())
|
||||
if (!(G::LastUserCmd->buttons & IN_ATTACK) || !Vars::Aimbot::General::AimType.Value || F::Aimbot.m_bRunningSecondary)
|
||||
break;
|
||||
if (!G::CanPrimaryAttack && !pWeapon->IsInReload() || pWeapon->GetWeaponID() == TF_WEAPON_GRAPPLINGHOOK && pWeapon->As<CTFGrapplingHook>()->m_hProjectile())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -2035,12 +2035,27 @@ bool CAimbotProjectile::RunMain(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUser
|
||||
pCmd->buttons &= ~IN_ATTACK;
|
||||
}
|
||||
break;
|
||||
case TF_WEAPON_GRAPPLINGHOOK:
|
||||
break;
|
||||
default:
|
||||
pCmd->buttons |= IN_ATTACK;
|
||||
}
|
||||
}
|
||||
|
||||
F::Aimbot.m_bRan = G::Attacking = SDK::IsAttacking(pLocal, pWeapon, pCmd, true);
|
||||
if (nWeaponID != TF_WEAPON_GRAPPLINGHOOK)
|
||||
F::Aimbot.m_bRan = G::Attacking = SDK::IsAttacking(pLocal, pWeapon, pCmd, true);
|
||||
else
|
||||
{
|
||||
Vec3 vOriginalAngles = pCmd->viewangles; int iOriginalButtons = pCmd->buttons;
|
||||
pCmd->viewangles = tTarget.m_vAngleTo, pCmd->buttons |= IN_ATTACK;
|
||||
F::Aimbot.m_bRan = G::Attacking = SDK::IsAttacking(pLocal, pWeapon, pCmd, true);
|
||||
pCmd->viewangles = vOriginalAngles, pCmd->buttons = iOriginalButtons;
|
||||
if (!G::Attacking)
|
||||
continue;
|
||||
|
||||
if (Vars::Aimbot::General::AutoShoot.Value)
|
||||
pCmd->buttons |= IN_ATTACK;
|
||||
}
|
||||
DrawVisuals(iResult, tTarget, m_vPlayerPath, m_vProjectilePath, m_vBoxes);
|
||||
|
||||
Aim(pCmd, tTarget.m_vAngleTo);
|
||||
|
||||
@@ -236,7 +236,7 @@ bool CMovementSimulation::Initialize(CBaseEntity* pEntity, MoveStorage& tMoveSto
|
||||
|
||||
// setup move data
|
||||
SetupMoveData(tMoveStorage);
|
||||
if (I::GameMovement->player = pPlayer, I::GameMovement->mv = &tMoveStorage.m_MoveData; I::GameMovement->CheckStuck())
|
||||
if (CheckStuck(tMoveStorage))
|
||||
{
|
||||
tMoveStorage.m_bFailed = true;
|
||||
return true;
|
||||
@@ -319,6 +319,15 @@ void CMovementSimulation::SetupMoveData(MoveStorage& tMoveStorage)
|
||||
tMoveStorage.m_bDirectMove = tMoveStorage.m_pPlayer->IsOnGround() || tMoveStorage.m_pPlayer->IsSwimming();
|
||||
}
|
||||
|
||||
bool CMovementSimulation::CheckStuck(MoveStorage& tMoveStorage)
|
||||
{
|
||||
I::GameMovement->player = I::GameMovement->m_pTFPlayer = tMoveStorage.m_pPlayer, I::GameMovement->mv = &tMoveStorage.m_MoveData;
|
||||
SetBounds(tMoveStorage.m_pPlayer);
|
||||
bool bReturn = I::GameMovement->CheckStuck();
|
||||
RestoreBounds(tMoveStorage.m_pPlayer);
|
||||
return bReturn;
|
||||
}
|
||||
|
||||
static inline float GetFrictionScale(float flVelocityXY, float flTurn, float flVelocityZ, float flMin = 50.f, float flMax = 150.f)
|
||||
{
|
||||
if (0.f >= flVelocityZ || flVelocityZ > 250.f)
|
||||
|
||||
@@ -46,6 +46,7 @@ private:
|
||||
void Reset(MoveStorage& tMoveStorage);
|
||||
|
||||
void SetupMoveData(MoveStorage& tMoveStorage);
|
||||
bool CheckStuck(MoveStorage& tMoveStorage);
|
||||
void GetAverageYaw(MoveStorage& tMoveStorage, int iSamples);
|
||||
bool StrafePrediction(MoveStorage& tMoveStorage, bool bHitchance = false);
|
||||
|
||||
|
||||
@@ -15,9 +15,7 @@
|
||||
#include "../Features/Spectate/Spectate.h"
|
||||
#include "../Features/AntiCheatCompatibility/AntiCheatCompatibility.h"
|
||||
|
||||
MAKE_SIGNATURE(IHasGenericMeter_GetMeterMultiplier, "client.dll", "F3 0F 10 81 ? ? ? ? C3 CC CC CC CC CC CC CC 48 85 D2", 0x0);
|
||||
|
||||
static inline void UpdateInfo(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd)
|
||||
static no_inline void UpdateInfo(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCmd* pCmd)
|
||||
{
|
||||
G::PSilentAngles = G::SilentAngles = G::Attacking = G::Throwing = false;
|
||||
G::LastUserCmd = G::CurrentUserCmd ? G::CurrentUserCmd : pCmd;
|
||||
@@ -27,105 +25,7 @@ static inline void UpdateInfo(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, CUserCm
|
||||
if (!pWeapon)
|
||||
return;
|
||||
|
||||
G::CanPrimaryAttack = G::CanSecondaryAttack = G::Reloading = false;
|
||||
|
||||
if (pWeapon->GetMaxClip1() != WEAPON_NOCLIP && !pWeapon->m_bReloadsSingly())
|
||||
{ // dumb fix
|
||||
float flOldCurtime = I::GlobalVars->curtime;
|
||||
I::GlobalVars->curtime = TICKS_TO_TIME(pLocal->m_nTickBase());
|
||||
pWeapon->CheckReload();
|
||||
I::GlobalVars->curtime = flOldCurtime;
|
||||
}
|
||||
|
||||
bool bCanAttack = pLocal->CanAttack();
|
||||
{
|
||||
static int iStaticItemDefinitionIndex = 0;
|
||||
int iOldItemDefinitionIndex = iStaticItemDefinitionIndex;
|
||||
int iNewItemDefinitionIndex = iStaticItemDefinitionIndex = pWeapon->m_iItemDefinitionIndex();
|
||||
|
||||
if (iNewItemDefinitionIndex != iOldItemDefinitionIndex || !bCanAttack || !pWeapon->m_iClip1())
|
||||
F::Ticks.m_iWait = -1;
|
||||
}
|
||||
if (bCanAttack)
|
||||
{
|
||||
G::CanPrimaryAttack = pWeapon->CanPrimaryAttack();
|
||||
G::CanSecondaryAttack = pWeapon->CanSecondaryAttack();
|
||||
|
||||
switch (pWeapon->GetWeaponID())
|
||||
{
|
||||
case TF_WEAPON_FLAME_BALL:
|
||||
if (G::CanPrimaryAttack)
|
||||
{
|
||||
// do this, otherwise it will be a tick behind
|
||||
float flFrametime = TICK_INTERVAL * 100;
|
||||
float flMeterMult = S::IHasGenericMeter_GetMeterMultiplier.Call<float>(pWeapon->m_pMeter());
|
||||
float flRate = SDK::AttribHookValue(1.f, "item_meter_charge_rate", pWeapon) - 1;
|
||||
float flMult = SDK::AttribHookValue(1.f, "mult_item_meter_charge_rate", pWeapon);
|
||||
float flTankPressure = pLocal->m_flTankPressure() + flFrametime * flMeterMult / (flRate * flMult);
|
||||
|
||||
if (G::CanPrimaryAttack && flTankPressure < 100.f)
|
||||
G::CanPrimaryAttack = G::CanSecondaryAttack = false;
|
||||
}
|
||||
break;
|
||||
case TF_WEAPON_MINIGUN:
|
||||
{
|
||||
int iState = pWeapon->As<CTFMinigun>()->m_iWeaponState();
|
||||
if (iState != AC_STATE_FIRING && iState != AC_STATE_SPINNING || !pWeapon->HasPrimaryAmmoForShot())
|
||||
G::CanPrimaryAttack = false;
|
||||
break;
|
||||
}
|
||||
case TF_WEAPON_FLAREGUN_REVENGE:
|
||||
if (pCmd->buttons & IN_ATTACK2)
|
||||
G::CanPrimaryAttack = false;
|
||||
break;
|
||||
case TF_WEAPON_BAT_WOOD:
|
||||
case TF_WEAPON_BAT_GIFTWRAP:
|
||||
if (!pWeapon->HasPrimaryAmmoForShot())
|
||||
G::CanSecondaryAttack = false;
|
||||
break;
|
||||
case TF_WEAPON_MEDIGUN:
|
||||
case TF_WEAPON_BUILDER:
|
||||
case TF_WEAPON_LASER_POINTER:
|
||||
break;
|
||||
case TF_WEAPON_PARTICLE_CANNON:
|
||||
{
|
||||
float flChargeBeginTime = pWeapon->As<CTFParticleCannon>()->m_flChargeBeginTime();
|
||||
if (flChargeBeginTime > 0)
|
||||
{
|
||||
float flTotalChargeTime = TICKS_TO_TIME(pLocal->m_nTickBase()) - flChargeBeginTime;
|
||||
if (flTotalChargeTime < TF_PARTICLE_MAX_CHARGE_TIME)
|
||||
{
|
||||
G::CanPrimaryAttack = G::CanSecondaryAttack = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
[[fallthrough]];
|
||||
}
|
||||
default:
|
||||
if (pWeapon->GetSlot() != SLOT_MELEE)
|
||||
{
|
||||
bool bAmmo = pWeapon->HasPrimaryAmmoForShot();
|
||||
bool bReload = pWeapon->IsInReload();
|
||||
if (!bAmmo && pWeapon->m_iItemDefinitionIndex() != Soldier_m_TheBeggarsBazooka)
|
||||
G::CanPrimaryAttack = G::CanSecondaryAttack = false;
|
||||
if (bReload && bAmmo && !G::CanPrimaryAttack)
|
||||
G::Reloading = true;
|
||||
}
|
||||
}
|
||||
if (G::CanPrimaryAttack)
|
||||
{
|
||||
switch (pWeapon->GetWeaponID())
|
||||
{
|
||||
case TF_WEAPON_FLAMETHROWER:
|
||||
case TF_WEAPON_FLAME_BALL:
|
||||
case TF_WEAPON_FLAREGUN:
|
||||
case TF_WEAPON_FLAREGUN_REVENGE:
|
||||
if (pLocal->IsUnderwater())
|
||||
G::CanPrimaryAttack = G::CanSecondaryAttack = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SDK::CanAttack(pLocal, pWeapon, pCmd, G::CanPrimaryAttack, G::CanSecondaryAttack, G::Reloading);
|
||||
G::Attacking = SDK::IsAttacking(pLocal, pWeapon, pCmd);
|
||||
G::PrimaryWeaponType = SDK::GetWeaponType(pWeapon, &G::SecondaryWeaponType);
|
||||
G::CanHeadshot = pWeapon->CanHeadshot() || pWeapon->AmbassadorCanHeadshot(TICKS_TO_TIME(pLocal->m_nTickBase()));
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#include "../SDK/SDK.h"
|
||||
|
||||
MAKE_SIGNATURE(CTFGrapplingHook_ItemPostFrame, "client.dll", "40 53 57 48 83 EC ? 48 8B D9 E8 ? ? ? ? 48 8B F8 48 85 C0 0F 84 ? ? ? ? 8B 88", 0x0);
|
||||
MAKE_SIGNATURE(CTFGrapplingHook_PrimaryAttack, "client.dll", "48 89 5C 24 ? 48 89 7C 24 ? 55 48 8D 6C 24 ? 48 81 EC ? ? ? ? 48 8B D9 E8 ? ? ? ? 8B 93", 0x0);
|
||||
MAKE_SIGNATURE(CTFGrapplingHook_ItemPostFrame_Fired, "client.dll", "40 38 35 ? ? ? ? 75 ? 48 8B 03", 0x0);
|
||||
|
||||
static bool s_bOriginalFired = false;
|
||||
|
||||
MAKE_HOOK(CTFGrapplingHook_ItemPostFrame, S::CTFGrapplingHook_ItemPostFrame(), void,
|
||||
void* rcx)
|
||||
{
|
||||
static bool& bFired = *reinterpret_cast<bool*>(U::Memory.RelToAbs(S::CTFGrapplingHook_ItemPostFrame_Fired()));
|
||||
s_bOriginalFired = bFired;
|
||||
bFired = false; // this var breaks prediction for this weapon pretty hard otherwise
|
||||
CALL_ORIGINAL(rcx);
|
||||
}
|
||||
|
||||
MAKE_HOOK(CTFGrapplingHook_PrimaryAttack, S::CTFGrapplingHook_PrimaryAttack(), void,
|
||||
void* rcx)
|
||||
{
|
||||
bool bOriginalFirstTimePredicted = I::Prediction->m_bFirstTimePredicted;
|
||||
I::Prediction->m_bFirstTimePredicted = !s_bOriginalFired; // don't spam deny sound
|
||||
CALL_ORIGINAL(rcx);
|
||||
I::Prediction->m_bFirstTimePredicted = bOriginalFirstTimePredicted;
|
||||
}
|
||||
@@ -2,6 +2,8 @@
|
||||
#include "../Types.h"
|
||||
#include <stdint.h>
|
||||
|
||||
class CKeyValuesGrowableStringTable;
|
||||
|
||||
enum types_t
|
||||
{
|
||||
TYPE_NONE = 0,
|
||||
@@ -33,12 +35,12 @@ private:
|
||||
char m_iDataType;
|
||||
char m_bHasEscapeSequences;
|
||||
char m_bEvaluateConditionals;
|
||||
char unused[1];
|
||||
char m_bUnknown;
|
||||
|
||||
KeyValues* m_pPeer;
|
||||
KeyValues* m_pSub;
|
||||
KeyValues* m_pChain;
|
||||
void* m_pUnknown;
|
||||
CKeyValuesGrowableStringTable* m_pGrowableStringTable;
|
||||
|
||||
public:
|
||||
class AutoDelete
|
||||
|
||||
+139
-41
@@ -3,10 +3,12 @@
|
||||
#include "../Features/ImGui/Notifications/Notifications.h"
|
||||
#include "../Features/ImGui/Menu/Menu.h"
|
||||
#include "../Features/EnginePrediction/EnginePrediction.h"
|
||||
#include "../Features/Ticks/Ticks.h"
|
||||
|
||||
#pragma warning (disable : 6385)
|
||||
|
||||
MAKE_SIGNATURE(CAttributeManager_AttribHookValue_Float, "client.dll", "4C 8B DC 49 89 5B ? 49 89 6B ? 56 57 41 54 41 56 41 57 48 83 EC ? 48 8B 3D ? ? ? ? 4C 8D 35", 0x0);
|
||||
MAKE_SIGNATURE(IHasGenericMeter_GetMeterMultiplier, "client.dll", "F3 0F 10 81 ? ? ? ? C3 CC CC CC CC CC CC CC 48 85 D2", 0x0);
|
||||
|
||||
static BOOL CALLBACK TeamFortressWindow(HWND hWindow, LPARAM lParam)
|
||||
{
|
||||
@@ -418,6 +420,13 @@ bool SDK::PredictOrigin(Vec3& vOut, const Vec3& vOrigin, const Vec3& vVelocity,
|
||||
return !trace.DidHit();
|
||||
}
|
||||
|
||||
float SDK::GetGravity()
|
||||
{
|
||||
static auto sv_gravity = H::ConVars.FindVar("sv_gravity");
|
||||
|
||||
return sv_gravity->GetFloat();
|
||||
}
|
||||
|
||||
bool SDK::IsLoopback()
|
||||
{
|
||||
auto pNetChan = I::EngineClient->GetNetChannelInfo();
|
||||
@@ -437,6 +446,38 @@ int SDK::GetWinningTeam()
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* SDK::GetClassByIndex(const int nClass, bool bLower)
|
||||
{
|
||||
static const char* szClassesUpper[] = {
|
||||
"Unknown", "Scout", "Sniper", "Soldier", "Demoman", "Medic", "Heavy", "Pyro", "Spy", "Engineer"
|
||||
};
|
||||
static const char* szClassesLower[] = {
|
||||
"unknown", "scout", "sniper", "soldier", "demoman", "medic", "heavy", "pyro", "spy", "engineer"
|
||||
};
|
||||
|
||||
if (!bLower)
|
||||
return nClass < 10 && nClass > 0 ? szClassesUpper[nClass] : szClassesUpper[0];
|
||||
else
|
||||
return nClass < 10 && nClass > 0 ? szClassesLower[nClass] : szClassesLower[0];
|
||||
}
|
||||
|
||||
float SDK::AttribHookValue(float value, const char* name, void* econent, void* buffer, bool isGlobalConstString)
|
||||
{
|
||||
return S::CAttributeManager_AttribHookValue_Float.Call<float>(value, name, econent, buffer, isGlobalConstString);
|
||||
}
|
||||
|
||||
float SDK::MaxSpeed(CTFPlayer* pPlayer, bool bIncludeCrouch, bool bIgnoreSpecialAbility)
|
||||
{
|
||||
float flSpeed = pPlayer->CalculateMaxSpeed(bIgnoreSpecialAbility);
|
||||
|
||||
if (pPlayer->InCond(TF_COND_SPEED_BOOST) || pPlayer->InCond(TF_COND_HALLOWEEN_SPEED_BOOST))
|
||||
flSpeed *= 1.35f;
|
||||
if (bIncludeCrouch && pPlayer->IsDucking() && pPlayer->IsOnGround())
|
||||
flSpeed /= 3;
|
||||
|
||||
return flSpeed;
|
||||
}
|
||||
|
||||
EWeaponType SDK::GetWeaponType(CTFWeaponBase* pWeapon, EWeaponType* pSecondaryType)
|
||||
{
|
||||
if (pSecondaryType)
|
||||
@@ -478,7 +519,6 @@ EWeaponType SDK::GetWeaponType(CTFWeaponBase* pWeapon, EWeaponType* pSecondaryTy
|
||||
case TF_WEAPON_PDA_SPY_BUILD:
|
||||
case TF_WEAPON_INVIS:
|
||||
case TF_WEAPON_BUFF_ITEM:
|
||||
case TF_WEAPON_GRAPPLINGHOOK:
|
||||
case TF_WEAPON_ROCKETPACK:
|
||||
return EWeaponType::UNKNOWN;
|
||||
case TF_WEAPON_CLEAVER:
|
||||
@@ -502,25 +542,107 @@ EWeaponType SDK::GetWeaponType(CTFWeaponBase* pWeapon, EWeaponType* pSecondaryTy
|
||||
case TF_WEAPON_JAR_MILK:
|
||||
case TF_WEAPON_JAR_GAS:
|
||||
case TF_WEAPON_LUNCHBOX:
|
||||
case TF_WEAPON_GRAPPLINGHOOK:
|
||||
return EWeaponType::PROJECTILE;
|
||||
}
|
||||
|
||||
return EWeaponType::HITSCAN;
|
||||
}
|
||||
|
||||
const char* SDK::GetClassByIndex(const int nClass, bool bLower)
|
||||
void SDK::CanAttack(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, const CUserCmd* pCmd, bool& bPrimary, bool& bSecondary, bool& bReloading)
|
||||
{
|
||||
static const char* szClassesUpper[] = {
|
||||
"Unknown", "Scout", "Sniper", "Soldier", "Demoman", "Medic", "Heavy", "Pyro", "Spy", "Engineer"
|
||||
};
|
||||
static const char* szClassesLower[] = {
|
||||
"unknown", "scout", "sniper", "soldier", "demoman", "medic", "heavy", "pyro", "spy", "engineer"
|
||||
};
|
||||
bPrimary = bSecondary = bReloading = false;
|
||||
|
||||
if (!bLower)
|
||||
return nClass < 10 && nClass > 0 ? szClassesUpper[nClass] : szClassesUpper[0];
|
||||
else
|
||||
return nClass < 10 && nClass > 0 ? szClassesLower[nClass] : szClassesLower[0];
|
||||
if (pWeapon->GetMaxClip1() != WEAPON_NOCLIP && !pWeapon->m_bReloadsSingly())
|
||||
{ // dumb fix
|
||||
float flOldCurtime = I::GlobalVars->curtime;
|
||||
I::GlobalVars->curtime = TICKS_TO_TIME(pLocal->m_nTickBase());
|
||||
pWeapon->CheckReload();
|
||||
I::GlobalVars->curtime = flOldCurtime;
|
||||
}
|
||||
|
||||
bool bCanAttack = pLocal->CanAttack();
|
||||
{
|
||||
static int iStaticItemDefinitionIndex = 0;
|
||||
int iOldItemDefinitionIndex = iStaticItemDefinitionIndex;
|
||||
int iNewItemDefinitionIndex = iStaticItemDefinitionIndex = pWeapon->m_iItemDefinitionIndex();
|
||||
|
||||
if (iNewItemDefinitionIndex != iOldItemDefinitionIndex || !bCanAttack || !pWeapon->m_iClip1())
|
||||
F::Ticks.m_iWait = -1;
|
||||
}
|
||||
if (bCanAttack)
|
||||
{
|
||||
bPrimary = pWeapon->CanPrimaryAttack();
|
||||
bSecondary = pWeapon->CanSecondaryAttack();
|
||||
|
||||
switch (pWeapon->GetWeaponID())
|
||||
{
|
||||
case TF_WEAPON_FLAME_BALL:
|
||||
if (bPrimary)
|
||||
{
|
||||
// do this, otherwise it will be a tick behind
|
||||
float flFrametime = TICK_INTERVAL * 100;
|
||||
float flMeterMult = S::IHasGenericMeter_GetMeterMultiplier.Call<float>(pWeapon->m_pMeter());
|
||||
float flRate = SDK::AttribHookValue(1.f, "item_meter_charge_rate", pWeapon) - 1;
|
||||
float flMult = SDK::AttribHookValue(1.f, "mult_item_meter_charge_rate", pWeapon);
|
||||
float flTankPressure = pLocal->m_flTankPressure() + flFrametime * flMeterMult / (flRate * flMult);
|
||||
|
||||
if (bPrimary && flTankPressure < 100.f)
|
||||
bPrimary = bSecondary = false;
|
||||
}
|
||||
break;
|
||||
case TF_WEAPON_MINIGUN:
|
||||
if (int iState = pWeapon->As<CTFMinigun>()->m_iWeaponState(); iState != AC_STATE_FIRING && iState != AC_STATE_SPINNING || !pWeapon->HasPrimaryAmmoForShot())
|
||||
bPrimary = false;
|
||||
break;
|
||||
case TF_WEAPON_FLAREGUN_REVENGE:
|
||||
if (pCmd->buttons & IN_ATTACK2)
|
||||
bPrimary = false;
|
||||
break;
|
||||
case TF_WEAPON_BAT_WOOD:
|
||||
case TF_WEAPON_BAT_GIFTWRAP:
|
||||
if (!pWeapon->HasPrimaryAmmoForShot())
|
||||
bSecondary = false;
|
||||
break;
|
||||
case TF_WEAPON_MEDIGUN:
|
||||
case TF_WEAPON_BUILDER:
|
||||
case TF_WEAPON_LASER_POINTER:
|
||||
break;
|
||||
case TF_WEAPON_PARTICLE_CANNON:
|
||||
if (float flChargeBeginTime = pWeapon->As<CTFParticleCannon>()->m_flChargeBeginTime(); flChargeBeginTime > 0)
|
||||
{
|
||||
float flTotalChargeTime = TICKS_TO_TIME(pLocal->m_nTickBase()) - flChargeBeginTime;
|
||||
if (flTotalChargeTime < TF_PARTICLE_MAX_CHARGE_TIME)
|
||||
{
|
||||
bPrimary = bSecondary = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
[[fallthrough]];
|
||||
default:
|
||||
if (pWeapon->GetSlot() != SLOT_MELEE)
|
||||
{
|
||||
bool bAmmo = pWeapon->HasPrimaryAmmoForShot();
|
||||
bool bReload = pWeapon->IsInReload();
|
||||
if (!bAmmo && pWeapon->m_iItemDefinitionIndex() != Soldier_m_TheBeggarsBazooka)
|
||||
bPrimary = bSecondary = false;
|
||||
if (bReload && bAmmo && !bPrimary)
|
||||
bReloading = true;
|
||||
}
|
||||
}
|
||||
if (bPrimary)
|
||||
{
|
||||
switch (pWeapon->GetWeaponID())
|
||||
{
|
||||
case TF_WEAPON_FLAMETHROWER:
|
||||
case TF_WEAPON_FLAME_BALL:
|
||||
case TF_WEAPON_FLAREGUN:
|
||||
case TF_WEAPON_FLAREGUN_REVENGE:
|
||||
if (pLocal->IsUnderwater())
|
||||
bPrimary = bSecondary = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int SDK::IsAttacking(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, const CUserCmd* pCmd, bool bTickBase)
|
||||
@@ -621,14 +743,14 @@ int SDK::IsAttacking(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, const CUserCmd*
|
||||
if (!G::CanPrimaryAttack || !(pCmd->buttons & IN_ATTACK) || pWeapon->As<CTFGrapplingHook>()->m_hProjectile())
|
||||
return false;
|
||||
|
||||
Vec3 vPos, vAngle; GetProjectileFireSetup(pLocal, pCmd->viewangles, { 23.5f, -8.f, -3.f }, vPos, vAngle, false);
|
||||
static auto tf_grapplinghook_max_distance = H::ConVars.FindVar("tf_grapplinghook_max_distance");
|
||||
const float flGrappleDistance = tf_grapplinghook_max_distance->GetFloat();
|
||||
|
||||
Vec3 vPos, vAngle; GetProjectileFireSetup(pLocal, pCmd->viewangles, { 23.5f, -8.f, -3.f }, vPos, vAngle, 2000.f);
|
||||
Vec3 vForward; Math::AngleVectors(vAngle, &vForward);
|
||||
|
||||
CGameTrace trace = {};
|
||||
CTraceFilterHitscan filter = {};
|
||||
filter.pSkip = pLocal;
|
||||
static auto tf_grapplinghook_max_distance = H::ConVars.FindVar("tf_grapplinghook_max_distance");
|
||||
const float flGrappleDistance = tf_grapplinghook_max_distance->GetFloat();
|
||||
CTraceFilterWorldAndPropsOnly filter = {};
|
||||
Trace(vPos, vPos + vForward * flGrappleDistance, MASK_SOLID, &filter, &trace);
|
||||
return trace.DidHit() && !(trace.surface.flags & SURF_SKY);
|
||||
}
|
||||
@@ -694,30 +816,6 @@ int SDK::IsAttacking(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, const CUserCmd*
|
||||
return G::CanPrimaryAttack && pCmd->buttons & IN_ATTACK ? 1 : G::Reloading && pCmd->buttons & IN_ATTACK ? 2 : 0;
|
||||
}
|
||||
|
||||
float SDK::GetGravity()
|
||||
{
|
||||
static auto sv_gravity = H::ConVars.FindVar("sv_gravity");
|
||||
|
||||
return sv_gravity->GetFloat();
|
||||
}
|
||||
|
||||
float SDK::MaxSpeed(CTFPlayer* pPlayer, bool bIncludeCrouch, bool bIgnoreSpecialAbility)
|
||||
{
|
||||
float flSpeed = pPlayer->CalculateMaxSpeed(bIgnoreSpecialAbility);
|
||||
|
||||
if (pPlayer->InCond(TF_COND_SPEED_BOOST) || pPlayer->InCond(TF_COND_HALLOWEEN_SPEED_BOOST))
|
||||
flSpeed *= 1.35f;
|
||||
if (bIncludeCrouch && pPlayer->IsDucking() && pPlayer->IsOnGround())
|
||||
flSpeed /= 3;
|
||||
|
||||
return flSpeed;
|
||||
}
|
||||
|
||||
float SDK::AttribHookValue(float value, const char* name, void* econent, void* buffer, bool isGlobalConstString)
|
||||
{
|
||||
return S::CAttributeManager_AttribHookValue_Float.Call<float>(value, name, econent, buffer, isGlobalConstString);
|
||||
}
|
||||
|
||||
void SDK::FixMovement(CUserCmd* pCmd, const Vec3& vCurAngle, const Vec3& vTargetAngle)
|
||||
{
|
||||
bool bCurOOB = fabsf(Math::NormalizeAngle(vCurAngle.x)) > 90.f;
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
#include <intrin.h>
|
||||
#include <random>
|
||||
|
||||
#define no_inline __declspec(noinline)
|
||||
|
||||
#define VK_0 0x30
|
||||
#define VK_1 0x31
|
||||
#define VK_2 0x32
|
||||
@@ -122,16 +124,18 @@ namespace SDK
|
||||
Vec3 PredictOrigin(const Vec3& vOrigin, const Vec3& vVelocity, float flLatency, bool bTrace = true, const Vec3& vMins = {}, const Vec3& vMaxs = {}, unsigned int nMask = MASK_SOLID, float flNormal = 0.f);
|
||||
bool PredictOrigin(Vec3& vOut, const Vec3& vOrigin, const Vec3& vVelocity, float flLatency, bool bTrace = true, const Vec3& vMins = {}, const Vec3& vMaxs = {}, unsigned int nMask = MASK_SOLID, float flNormal = 0.f);
|
||||
|
||||
float GetGravity();
|
||||
bool IsLoopback();
|
||||
int GetRoundState();
|
||||
int GetWinningTeam();
|
||||
EWeaponType GetWeaponType(CTFWeaponBase* pWeapon, EWeaponType* pSecondaryType = nullptr);
|
||||
const char* GetClassByIndex(const int nClass, bool bLower = true);
|
||||
|
||||
int IsAttacking(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, const CUserCmd* pCmd, bool bTickBase = false);
|
||||
float GetGravity();
|
||||
float MaxSpeed(CTFPlayer* pPlayer, bool bIncludeCrouch = false, bool bIgnoreSpecialAbility = false);
|
||||
const char* GetClassByIndex(const int nClass, bool bLower = true);
|
||||
float AttribHookValue(float value, const char* name, void* econent, void* buffer = nullptr, bool isGlobalConstString = true);
|
||||
float MaxSpeed(CTFPlayer* pPlayer, bool bIncludeCrouch = false, bool bIgnoreSpecialAbility = false);
|
||||
|
||||
EWeaponType GetWeaponType(CTFWeaponBase* pWeapon, EWeaponType* pSecondaryType = nullptr);
|
||||
void CanAttack(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, const CUserCmd* pCmd, bool& bPrimary, bool& bSecondary, bool& bReloading);
|
||||
int IsAttacking(CTFPlayer* pLocal, CTFWeaponBase* pWeapon, const CUserCmd* pCmd, bool bTickBase = false);
|
||||
|
||||
void FixMovement(CUserCmd* pCmd, const Vec3& vCurAngle, const Vec3& vTargetAngle);
|
||||
void FixMovement(CUserCmd* pCmd, const Vec3& vTargetAngle);
|
||||
|
||||
Reference in New Issue
Block a user