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 isEnabled();
|
||||||
extern bool force_crit_this_tick;
|
extern bool force_crit_this_tick;
|
||||||
void fixBucket(IClientEntity *weapon, CUserCmd *cmd);
|
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
|
} // namespace criticals
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
#include "crits.hpp"
|
#include "crits.hpp"
|
||||||
#include "Backtrack.hpp"
|
#include "Backtrack.hpp"
|
||||||
|
#include "WeaponData.hpp"
|
||||||
#include "netadr.h"
|
#include "netadr.h"
|
||||||
|
|
||||||
std::unordered_map<int, int> command_number_mod{};
|
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())
|
if (added_per_shot == 0.0f || previous_weapon != weapon->entindex())
|
||||||
{
|
{
|
||||||
weapon_info info(weapon);
|
weapon_info info(weapon);
|
||||||
|
int nProjectilesPerShot = GetWeaponData(weapon)->m_nBulletsPerShot;
|
||||||
// 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);
|
|
||||||
if (nProjectilesPerShot >= 1)
|
if (nProjectilesPerShot >= 1)
|
||||||
nProjectilesPerShot = ATTRIB_HOOK_FLOAT(nProjectilesPerShot, "mult_bullets_per_shot", weapon, 0x0, true);
|
nProjectilesPerShot = ATTRIB_HOOK_FLOAT(nProjectilesPerShot, "mult_bullets_per_shot", weapon, 0x0, true);
|
||||||
else
|
else
|
||||||
nProjectilesPerShot = 1;
|
nProjectilesPerShot = 1;
|
||||||
|
|
||||||
// Size of one WeaponMode_t is 0x40, 0x6f8 is the offset to damage
|
added_per_shot = GetWeaponData(weapon)->m_nDamage;
|
||||||
added_per_shot = *(int *) (WeaponData + 0x6f8 + WeaponMode * 0x40);
|
|
||||||
added_per_shot = ATTRIB_HOOK_FLOAT(added_per_shot, "mult_dmg", weapon, 0x0, true);
|
added_per_shot = ATTRIB_HOOK_FLOAT(added_per_shot, "mult_dmg", weapon, 0x0, true);
|
||||||
added_per_shot *= nProjectilesPerShot;
|
added_per_shot *= nProjectilesPerShot;
|
||||||
shots_to_fill_bucket = getBucketCap() / added_per_shot;
|
shots_to_fill_bucket = getBucketCap() / added_per_shot;
|
||||||
@ -514,8 +508,7 @@ static void updateCmds()
|
|||||||
if (isRapidFire(weapon))
|
if (isRapidFire(weapon))
|
||||||
{
|
{
|
||||||
taken_per_crit = added_per_shot;
|
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 / GetWeaponData(weapon)->m_flTimeFireDelay;
|
||||||
taken_per_crit *= 2.0f / *(float *) (WeaponData + 0x70c + WeaponMode * 0x40);
|
|
||||||
|
|
||||||
// Yes this looks dumb but i want to ensure that it matches with valve code
|
// Yes this looks dumb but i want to ensure that it matches with valve code
|
||||||
int bucket_cap_recasted = (int) getBucketCap();
|
int bucket_cap_recasted = (int) getBucketCap();
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "MiscTemporary.hpp"
|
#include "MiscTemporary.hpp"
|
||||||
#include "PlayerTools.hpp"
|
#include "PlayerTools.hpp"
|
||||||
#include "Ragdolls.hpp"
|
#include "Ragdolls.hpp"
|
||||||
|
#include "WeaponData.hpp"
|
||||||
|
|
||||||
static settings::Boolean tcm{ "debug.tcm", "true" };
|
static settings::Boolean tcm{ "debug.tcm", "true" };
|
||||||
static settings::Boolean should_correct_punch{ "debug.correct-punch", "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)
|
bool isRapidFire(IClientEntity *wep)
|
||||||
{
|
{
|
||||||
criticals::weapon_info info(wep);
|
weapon_info info(wep);
|
||||||
// Taken from game, m_pWeaponInfo->GetWeaponData( m_iWeaponMode ).m_bUseRapidFireCrits;
|
bool ret = GetWeaponData(wep)->m_bUseRapidFireCrits;
|
||||||
bool ret = *(bool *) (info.weapon_data + 0x734 + info.weapon_mode * 0x40);
|
|
||||||
// Minigun changes mode once revved, so fix that
|
// Minigun changes mode once revved, so fix that
|
||||||
return ret || wep->GetClientClass()->m_ClassID == CL_CLASS(CTFMinigun);
|
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);
|
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);
|
static auto AttribHookFloat_fn = AttribHookFloat_t(AttribHookFloat);
|
||||||
|
|
||||||
return AttribHookFloat_fn(base_value, search_string, ent, buffer, is_global_const_string);
|
return AttribHookFloat_fn(base_value, search_string, ent, buffer, is_global_const_string);
|
||||||
|
@ -28,34 +28,7 @@
|
|||||||
#include "usercmd.hpp"
|
#include "usercmd.hpp"
|
||||||
#include "MiscTemporary.hpp"
|
#include "MiscTemporary.hpp"
|
||||||
#include "AntiAim.hpp"
|
#include "AntiAim.hpp"
|
||||||
|
#include "WeaponData.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);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace hacks::tf2::nospread
|
namespace hacks::tf2::nospread
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user