Fix crithack and nospread + clean up WeaponData usage
This commit is contained in:
parent
f84279d4e2
commit
3d2858442f
84
include/WeaponData.hpp
Normal file
84
include/WeaponData.hpp
Normal file
@ -0,0 +1,84 @@
|
||||
#include "common.hpp"
|
||||
|
||||
#pragma once
|
||||
|
||||
struct WeaponData_t
|
||||
{
|
||||
int m_nDamage;
|
||||
int m_nBulletsPerShot;
|
||||
float m_flRange;
|
||||
float m_flSpread;
|
||||
float m_flPunchAngle;
|
||||
float m_flTimeFireDelay; // Time to delay between firing
|
||||
float m_flTimeIdle; // Time to idle after firing
|
||||
float m_flTimeIdleEmpty; // Time to idle after firing last bullet in clip
|
||||
float m_flTimeReloadStart; // Time to start into a reload (ie. shotgun)
|
||||
float m_flTimeReload; // Time to reload
|
||||
bool m_bDrawCrosshair; // Should the weapon draw a crosshair
|
||||
int m_iProjectile; // The type of projectile this mode fires
|
||||
int m_iAmmoPerShot; // How much ammo each shot consumes
|
||||
float m_flProjectileSpeed; // Start speed for projectiles (nail, etc.); NOTE: union with something non-projectile
|
||||
float m_flSmackDelay; // how long after swing should damage happen for melee weapons
|
||||
bool m_bUseRapidFireCrits;
|
||||
};
|
||||
|
||||
class weapon_info
|
||||
{
|
||||
public:
|
||||
float crit_bucket{};
|
||||
unsigned int weapon_seed{};
|
||||
unsigned unknown1{};
|
||||
unsigned unknown2{};
|
||||
bool unknown3{};
|
||||
float unknown4{};
|
||||
int crit_attempts{};
|
||||
int crit_count{};
|
||||
float observed_crit_chance{};
|
||||
bool unknown7{};
|
||||
int weapon_mode{};
|
||||
int weapon_data{};
|
||||
weapon_info()
|
||||
{
|
||||
}
|
||||
void Load(IClientEntity *weapon)
|
||||
{
|
||||
crit_bucket = *(float *) ((uintptr_t) weapon + 0xa38);
|
||||
weapon_seed = *(unsigned int *) ((uintptr_t) weapon + 0xb3c);
|
||||
unknown1 = *(unsigned int *) ((uintptr_t) weapon + 0xb30);
|
||||
unknown2 = *(unsigned int *) ((uintptr_t) weapon + 0xb34);
|
||||
unknown3 = *(bool *) ((uintptr_t) weapon + 0xb17);
|
||||
unknown4 = *(float *) ((uintptr_t) weapon + 0xb40);
|
||||
crit_attempts = *(int *) ((uintptr_t) weapon + 0xa3c);
|
||||
crit_count = *(int *) ((uintptr_t) weapon + 0xa40);
|
||||
observed_crit_chance = *(float *) ((uintptr_t) weapon + 0xbfc);
|
||||
unknown7 = *(bool *) ((uintptr_t) weapon + 0xb18);
|
||||
// No need to restore
|
||||
weapon_mode = *(int *) ((uintptr_t) weapon + 0xb04);
|
||||
weapon_data = *(int *) ((uintptr_t) weapon + 0xb10);
|
||||
}
|
||||
weapon_info(IClientEntity *weapon)
|
||||
{
|
||||
Load(weapon);
|
||||
}
|
||||
void restore_data(IClientEntity *weapon)
|
||||
{
|
||||
*(float *) ((uintptr_t) weapon + 0xa38) = crit_bucket;
|
||||
*(unsigned int *) ((uintptr_t) weapon + 0xb3c) = weapon_seed;
|
||||
*(unsigned int *) ((uintptr_t) weapon + 0xb30) = unknown1;
|
||||
*(unsigned int *) ((uintptr_t) weapon + 0xb34) = unknown2;
|
||||
*(bool *) ((uintptr_t) weapon + 0xb17) = unknown3;
|
||||
*(float *) ((uintptr_t) weapon + 0xb40) = unknown4;
|
||||
*(int *) ((uintptr_t) weapon + 0xa3c) = crit_attempts;
|
||||
*(int *) ((uintptr_t) weapon + 0xa40) = crit_count;
|
||||
*(float *) ((uintptr_t) weapon + 0xbfc) = observed_crit_chance;
|
||||
*(bool *) ((uintptr_t) weapon + 0xb18) = unknown7;
|
||||
}
|
||||
};
|
||||
|
||||
inline WeaponData_t *GetWeaponData(IClientEntity *weapon)
|
||||
{
|
||||
weapon_info info(weapon);
|
||||
int WeaponData = info.weapon_data;
|
||||
int WeaponMode = info.weapon_mode;
|
||||
return (WeaponData_t *) (WeaponData + sizeof(WeaponData_t) * WeaponMode + 1784);
|
||||
}
|
@ -11,57 +11,4 @@ extern int current_index;
|
||||
extern bool isEnabled();
|
||||
extern bool force_crit_this_tick;
|
||||
void fixBucket(IClientEntity *weapon, CUserCmd *cmd);
|
||||
|
||||
class weapon_info
|
||||
{
|
||||
public:
|
||||
float crit_bucket{};
|
||||
unsigned int weapon_seed{};
|
||||
unsigned unknown1{};
|
||||
unsigned unknown2{};
|
||||
bool unknown3{};
|
||||
float unknown4{};
|
||||
int crit_attempts{};
|
||||
int crit_count{};
|
||||
float observed_crit_chance{};
|
||||
bool unknown7{};
|
||||
int weapon_mode{};
|
||||
int weapon_data{};
|
||||
weapon_info()
|
||||
{
|
||||
}
|
||||
void Load(IClientEntity *weapon)
|
||||
{
|
||||
crit_bucket = *(float *) ((uintptr_t) weapon + 0xa38);
|
||||
weapon_seed = *(unsigned int *) ((uintptr_t) weapon + 0xb3c);
|
||||
unknown1 = *(unsigned int *) ((uintptr_t) weapon + 0xb30);
|
||||
unknown2 = *(unsigned int *) ((uintptr_t) weapon + 0xb34);
|
||||
unknown3 = *(bool *) ((uintptr_t) weapon + 0xb17);
|
||||
unknown4 = *(float *) ((uintptr_t) weapon + 0xb40);
|
||||
crit_attempts = *(int *) ((uintptr_t) weapon + 0xa3c);
|
||||
crit_count = *(int *) ((uintptr_t) weapon + 0xa40);
|
||||
observed_crit_chance = *(float *) ((uintptr_t) weapon + 0xbfc);
|
||||
unknown7 = *(bool *) ((uintptr_t) weapon + 0xb18);
|
||||
// No need to restore
|
||||
weapon_mode = *(int *) ((uintptr_t) weapon + 0xb04);
|
||||
weapon_data = *(int *) ((uintptr_t) weapon + 0xb10);
|
||||
}
|
||||
weapon_info(IClientEntity *weapon)
|
||||
{
|
||||
Load(weapon);
|
||||
}
|
||||
void restore_data(IClientEntity *weapon)
|
||||
{
|
||||
*(float *) ((uintptr_t) weapon + 0xa38) = crit_bucket;
|
||||
*(unsigned int *) ((uintptr_t) weapon + 0xb3c) = weapon_seed;
|
||||
*(unsigned int *) ((uintptr_t) weapon + 0xb30) = unknown1;
|
||||
*(unsigned int *) ((uintptr_t) weapon + 0xb34) = unknown2;
|
||||
*(bool *) ((uintptr_t) weapon + 0xb17) = unknown3;
|
||||
*(float *) ((uintptr_t) weapon + 0xb40) = unknown4;
|
||||
*(int *) ((uintptr_t) weapon + 0xa3c) = crit_attempts;
|
||||
*(int *) ((uintptr_t) weapon + 0xa40) = crit_count;
|
||||
*(float *) ((uintptr_t) weapon + 0xbfc) = observed_crit_chance;
|
||||
*(bool *) ((uintptr_t) weapon + 0xb18) = unknown7;
|
||||
}
|
||||
};
|
||||
} // namespace criticals
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "common.hpp"
|
||||
#include "crits.hpp"
|
||||
#include "Backtrack.hpp"
|
||||
#include "WeaponData.hpp"
|
||||
#include "netadr.h"
|
||||
|
||||
std::unordered_map<int, int> command_number_mod{};
|
||||
@ -493,20 +494,13 @@ static void updateCmds()
|
||||
if (added_per_shot == 0.0f || previous_weapon != weapon->entindex())
|
||||
{
|
||||
weapon_info info(weapon);
|
||||
|
||||
// m_pWeaponInfo->GetWeaponData(m_iWeaponMode).m_nBulletsPerShot;
|
||||
|
||||
int WeaponData = info.weapon_data;
|
||||
int WeaponMode = info.weapon_mode;
|
||||
// Size of one WeaponMode_t is 0x40, 0x6fc is the offset to projectiles per shot
|
||||
int nProjectilesPerShot = *(int *) (WeaponData + 0x6fc + WeaponMode * 0x40);
|
||||
int nProjectilesPerShot = GetWeaponData(weapon)->m_nBulletsPerShot;
|
||||
if (nProjectilesPerShot >= 1)
|
||||
nProjectilesPerShot = ATTRIB_HOOK_FLOAT(nProjectilesPerShot, "mult_bullets_per_shot", weapon, 0x0, true);
|
||||
else
|
||||
nProjectilesPerShot = 1;
|
||||
|
||||
// Size of one WeaponMode_t is 0x40, 0x6f8 is the offset to damage
|
||||
added_per_shot = *(int *) (WeaponData + 0x6f8 + WeaponMode * 0x40);
|
||||
added_per_shot = GetWeaponData(weapon)->m_nDamage;
|
||||
added_per_shot = ATTRIB_HOOK_FLOAT(added_per_shot, "mult_dmg", weapon, 0x0, true);
|
||||
added_per_shot *= nProjectilesPerShot;
|
||||
shots_to_fill_bucket = getBucketCap() / added_per_shot;
|
||||
@ -514,8 +508,7 @@ static void updateCmds()
|
||||
if (isRapidFire(weapon))
|
||||
{
|
||||
taken_per_crit = added_per_shot;
|
||||
// Size of one WeaponMode_t is 0x40, 0x70c is the offset to Fire delay
|
||||
taken_per_crit *= 2.0f / *(float *) (WeaponData + 0x70c + WeaponMode * 0x40);
|
||||
taken_per_crit *= 2.0f / GetWeaponData(weapon)->m_flTimeFireDelay;
|
||||
|
||||
// Yes this looks dumb but i want to ensure that it matches with valve code
|
||||
int bucket_cap_recasted = (int) getBucketCap();
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "MiscTemporary.hpp"
|
||||
#include "PlayerTools.hpp"
|
||||
#include "Ragdolls.hpp"
|
||||
#include "WeaponData.hpp"
|
||||
|
||||
static settings::Boolean tcm{ "debug.tcm", "true" };
|
||||
static settings::Boolean should_correct_punch{ "debug.correct-punch", "true" };
|
||||
@ -838,9 +839,8 @@ void AngleVectors3(const QAngle &angles, Vector *forward, Vector *right, Vector
|
||||
|
||||
bool isRapidFire(IClientEntity *wep)
|
||||
{
|
||||
criticals::weapon_info info(wep);
|
||||
// Taken from game, m_pWeaponInfo->GetWeaponData( m_iWeaponMode ).m_bUseRapidFireCrits;
|
||||
bool ret = *(bool *) (info.weapon_data + 0x734 + info.weapon_mode * 0x40);
|
||||
weapon_info info(wep);
|
||||
bool ret = GetWeaponData(wep)->m_bUseRapidFireCrits;
|
||||
// Minigun changes mode once revved, so fix that
|
||||
return ret || wep->GetClientClass()->m_ClassID == CL_CLASS(CTFMinigun);
|
||||
}
|
||||
@ -1606,7 +1606,7 @@ float ATTRIB_HOOK_FLOAT(float base_value, const char *search_string, IClientEnti
|
||||
{
|
||||
typedef float (*AttribHookFloat_t)(float, const char *, IClientEntity *, void *, bool);
|
||||
|
||||
static uintptr_t AttribHookFloat = gSignatures.GetClientSignature("55 89 E5 57 56 53 83 EC 6C C7 45 ? 00 00 00 00 A1 ? ? ? ? C7 45 ? 00 00 00 00 8B 75 ? 85 C0 0F 84 ? ? ? ? 8D 55 ? 89 04 24 31 DB 89 54 24");
|
||||
static uintptr_t AttribHookFloat = e8call_direct(gSignatures.GetClientSignature("E8 ? ? ? ? 8B 96 ? ? ? ? D9 5D"));
|
||||
static auto AttribHookFloat_fn = AttribHookFloat_t(AttribHookFloat);
|
||||
|
||||
return AttribHookFloat_fn(base_value, search_string, ent, buffer, is_global_const_string);
|
||||
|
@ -28,34 +28,7 @@
|
||||
#include "usercmd.hpp"
|
||||
#include "MiscTemporary.hpp"
|
||||
#include "AntiAim.hpp"
|
||||
|
||||
struct WeaponData_t
|
||||
{
|
||||
int m_nDamage;
|
||||
int m_nBulletsPerShot;
|
||||
float m_flRange;
|
||||
float m_flSpread;
|
||||
float m_flPunchAngle;
|
||||
float m_flTimeFireDelay; // Time to delay between firing
|
||||
float m_flTimeIdle; // Time to idle after firing
|
||||
float m_flTimeIdleEmpty; // Time to idle after firing last bullet in clip
|
||||
float m_flTimeReloadStart; // Time to start into a reload (ie. shotgun)
|
||||
float m_flTimeReload; // Time to reload
|
||||
bool m_bDrawCrosshair; // Should the weapon draw a crosshair
|
||||
int m_iProjectile; // The type of projectile this mode fires
|
||||
int m_iAmmoPerShot; // How much ammo each shot consumes
|
||||
float m_flProjectileSpeed; // Start speed for projectiles (nail, etc.); NOTE: union with something non-projectile
|
||||
float m_flSmackDelay; // how long after swing should damage happen for melee weapons
|
||||
bool m_bUseRapidFireCrits;
|
||||
};
|
||||
|
||||
WeaponData_t *GetWeaponData(IClientEntity *weapon)
|
||||
{
|
||||
criticals::weapon_info info(weapon);
|
||||
int WeaponData = info.weapon_data;
|
||||
int WeaponMode = info.weapon_mode;
|
||||
return (WeaponData_t *) (WeaponData + sizeof(WeaponData_t) * WeaponMode + 1784);
|
||||
}
|
||||
#include "WeaponData.hpp"
|
||||
|
||||
namespace hacks::tf2::nospread
|
||||
{
|
||||
|
Reference in New Issue
Block a user