Implement RG_CBasePlayerWeapon_CanDeploy & CBasePlayerWeapon_DefaultDeploy hooks (#420)

* Implement CBasePlayerWeapon_CanDeploy & CBasePlayerWeapon_DefaultDeploy hooks
* Implement CBasePlayerWeapon_DefaultReload hook
* Fix CBasePlayerWeapon_CanDeploy hook for grenades
* Fix CBasePlayer::CanDeploy
* ImplementRG_ CBasePlayerWeapon_DefaultShotgunReload hook
This commit is contained in:
fant1kua 2019-10-27 16:17:12 +02:00 committed by Dmitry Novikov
parent aeea713a19
commit dbf08416fd
12 changed files with 163 additions and 86 deletions

View File

@ -1,3 +1,3 @@
majorVersion=5
minorVersion=11
minorVersion=12
maintenanceVersion=0

View File

@ -162,6 +162,10 @@ GAMEHOOK_REGISTRY(CBasePlayer_RemoveSpawnProtection);
GAMEHOOK_REGISTRY(IsPenetrableEntity);
GAMEHOOK_REGISTRY(CBasePlayer_HintMessageEx);
GAMEHOOK_REGISTRY(CBasePlayer_UseEmpty);
GAMEHOOK_REGISTRY(CBasePlayerWeapon_CanDeploy);
GAMEHOOK_REGISTRY(CBasePlayerWeapon_DefaultDeploy);
GAMEHOOK_REGISTRY(CBasePlayerWeapon_DefaultReload);
GAMEHOOK_REGISTRY(CBasePlayerWeapon_DefaultShotgunReload);
int CReGameApi::GetMajorVersion() {
return REGAMEDLL_API_VERSION_MAJOR;

View File

@ -54,6 +54,11 @@
return g_ReGameHookchains.m_##className##_##functionName.callChain(&className::functionName##_OrigFunc, this);\
}
#define LINK_HOOK_CLASS_CHAIN3(ret, className, subClassName, functionName)\
ret subClassName::functionName() {\
return g_ReGameHookchains.m_##className##_##functionName.callChain(reinterpret_cast<ret (className::*)()>(&subClassName::functionName##_OrigFunc), this);\
}
#define LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN(className, customPrefix, functionName, args, ...)\
void className::functionName args {\
g_ReGameHookchains.m_##customPrefix##_##functionName.callChain(&className::functionName##_OrigFunc, this, __VA_ARGS__);\
@ -123,6 +128,7 @@
#define LINK_HOOK_CLASS_VOID_CHAIN2(...)
#define LINK_HOOK_CLASS_CHAIN(...)
#define LINK_HOOK_CLASS_CHAIN2(...)
#define LINK_HOOK_CLASS_CHAIN3(...)
#define LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN(...)
#define LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN2(...)
#define LINK_HOOK_CLASS_CUSTOM_CHAIN(...)
@ -541,6 +547,22 @@ typedef IHookChainRegistryClassImpl<bool, CBasePlayer, const char *, float, bool
typedef IHookChainClassImpl<void, CBasePlayer> CReGameHook_CBasePlayer_UseEmpty;
typedef IHookChainRegistryClassImpl<void, CBasePlayer> CReGameHookRegistry_CBasePlayer_UseEmpty;
// CBasePlayerWeapon::CanDeploy hook
typedef IHookChainClassImpl<BOOL, CBasePlayerWeapon> CReGameHook_CBasePlayerWeapon_CanDeploy;
typedef IHookChainRegistryClassImpl<BOOL, CBasePlayerWeapon> CReGameHookRegistry_CBasePlayerWeapon_CanDeploy;
// CBasePlayerWeapon::DefaultDeploy hook
typedef IHookChainClassImpl<BOOL, CBasePlayerWeapon, char *, char *, int, char *, int> CReGameHook_CBasePlayerWeapon_DefaultDeploy;
typedef IHookChainRegistryClassImpl<BOOL, CBasePlayerWeapon, char *, char *, int, char *, int> CReGameHookRegistry_CBasePlayerWeapon_DefaultDeploy;
// CBasePlayerWeapon::DefaultReload hook
typedef IHookChainClassImpl<int, CBasePlayerWeapon, int, int, float> CReGameHook_CBasePlayerWeapon_DefaultReload;
typedef IHookChainRegistryClassImpl<int, CBasePlayerWeapon, int, int, float> CReGameHookRegistry_CBasePlayerWeapon_DefaultReload;
// CBasePlayerWeapon::DefaultShotgunReload hook
typedef IHookChainClassImpl<bool, CBasePlayerWeapon, int, int, float, float, const char *, const char *> CReGameHook_CBasePlayerWeapon_DefaultShotgunReload;
typedef IHookChainRegistryClassImpl<bool, CBasePlayerWeapon, int, int, float, float, const char *, const char *> CReGameHookRegistry_CBasePlayerWeapon_DefaultShotgunReload;
class CReGameHookchains: public IReGameHookchains {
public:
// CBasePlayer virtual
@ -650,6 +672,10 @@ public:
CReGameHookRegistry_IsPenetrableEntity m_IsPenetrableEntity;
CReGameHookRegistry_CBasePlayer_HintMessageEx m_CBasePlayer_HintMessageEx;
CReGameHookRegistry_CBasePlayer_UseEmpty m_CBasePlayer_UseEmpty;
CReGameHookRegistry_CBasePlayerWeapon_CanDeploy m_CBasePlayerWeapon_CanDeploy;
CReGameHookRegistry_CBasePlayerWeapon_DefaultDeploy m_CBasePlayerWeapon_DefaultDeploy;
CReGameHookRegistry_CBasePlayerWeapon_DefaultReload m_CBasePlayerWeapon_DefaultReload;
CReGameHookRegistry_CBasePlayerWeapon_DefaultShotgunReload m_CBasePlayerWeapon_DefaultShotgunReload;
public:
virtual IReGameHookRegistry_CBasePlayer_Spawn *CBasePlayer_Spawn();
@ -758,6 +784,10 @@ public:
virtual IReGameHookRegistry_IsPenetrableEntity *IsPenetrableEntity();
virtual IReGameHookRegistry_CBasePlayer_HintMessageEx *CBasePlayer_HintMessageEx();
virtual IReGameHookRegistry_CBasePlayer_UseEmpty *CBasePlayer_UseEmpty();
virtual IReGameHookRegistry_CBasePlayerWeapon_CanDeploy *CBasePlayerWeapon_CanDeploy();
virtual IReGameHookRegistry_CBasePlayerWeapon_DefaultDeploy *CBasePlayerWeapon_DefaultDeploy();
virtual IReGameHookRegistry_CBasePlayerWeapon_DefaultReload *CBasePlayerWeapon_DefaultReload();
virtual IReGameHookRegistry_CBasePlayerWeapon_DefaultShotgunReload *CBasePlayerWeapon_DefaultShotgunReload();
};
extern CReGameHookchains g_ReGameHookchains;

View File

@ -5807,6 +5807,11 @@ void CBasePlayer::SelectItem(const char *pstr)
if (!pItem || pItem == m_pActiveItem)
return;
#ifdef REGAMEDLL_FIXES
if (!pItem->CanDeploy())
return;
#endif
ResetAutoaim();
// FIX, this needs to queue them up and delay
@ -5851,6 +5856,11 @@ void CBasePlayer::SelectLastItem()
if (!m_pLastItem || m_pLastItem == m_pActiveItem)
return;
#ifdef REGAMEDLL_FIXES
if (!m_pLastItem->CanDeploy())
return;
#endif
ResetAutoaim();
if (m_pActiveItem)

View File

@ -1295,12 +1295,16 @@ BOOL CBasePlayerWeapon::IsUseable()
return TRUE;
}
BOOL CBasePlayerWeapon::CanDeploy()
LINK_HOOK_CLASS_CHAIN2(BOOL, CBasePlayerWeapon, CanDeploy)
BOOL EXT_FUNC CBasePlayerWeapon::__API_HOOK(CanDeploy)()
{
return TRUE;
}
BOOL CBasePlayerWeapon::DefaultDeploy(char *szViewModel, char *szWeaponModel, int iAnim, char *szAnimExt, int skiplocal)
LINK_HOOK_CLASS_CHAIN(BOOL, CBasePlayerWeapon, DefaultDeploy, (char *szViewModel, char *szWeaponModel, int iAnim, char *szAnimExt, int skiplocal), szViewModel, szWeaponModel, iAnim, szAnimExt, skiplocal)
BOOL EXT_FUNC CBasePlayerWeapon::__API_HOOK(DefaultDeploy)(char *szViewModel, char *szWeaponModel, int iAnim, char *szAnimExt, int skiplocal)
{
if (!CanDeploy())
return FALSE;
@ -1350,7 +1354,9 @@ void CBasePlayerWeapon::ReloadSound()
}
}
int CBasePlayerWeapon::DefaultReload(int iClipSize, int iAnim, float fDelay)
LINK_HOOK_CLASS_CHAIN(int, CBasePlayerWeapon, DefaultReload, (int iClipSize, int iAnim, float fDelay), iClipSize, iAnim, fDelay)
int EXT_FUNC CBasePlayerWeapon::__API_HOOK(DefaultReload)(int iClipSize, int iAnim, float fDelay)
{
if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0)
return FALSE;
@ -1372,6 +1378,63 @@ int CBasePlayerWeapon::DefaultReload(int iClipSize, int iAnim, float fDelay)
return TRUE;
}
LINK_HOOK_CLASS_CHAIN(bool, CBasePlayerWeapon, DefaultShotgunReload, (int iAnim, int iStartAnim, float fDelay, float fStartDelay, const char *pszReloadSound1, const char *pszReloadSound2), iAnim, iStartAnim, fDelay, fStartDelay, pszReloadSound1, pszReloadSound2)
bool EXT_FUNC CBasePlayerWeapon::__API_HOOK(DefaultShotgunReload)(int iAnim, int iStartAnim, float fDelay, float fStartDelay, const char *pszReloadSound1, const char *pszReloadSound2)
{
if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 || m_iClip == iMaxClip())
return false;
// don't reload until recoil is done
if (m_flNextPrimaryAttack > UTIL_WeaponTimeBase())
return false;
// check to see if we're ready to reload
if (m_fInSpecialReload == 0)
{
m_pPlayer->SetAnimation(PLAYER_RELOAD);
SendWeaponAnim(iStartAnim, UseDecrement() != FALSE);
m_fInSpecialReload = 1;
m_flNextSecondaryAttack = m_flTimeWeaponIdle = m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + fStartDelay;
m_flNextPrimaryAttack = GetNextAttackDelay(fStartDelay);
}
else if (m_fInSpecialReload == 1)
{
if (m_flTimeWeaponIdle > UTIL_WeaponTimeBase())
return false;
// was waiting for gun to move to side
m_fInSpecialReload = 2;
const char *pszReloadSound = nullptr;
if (pszReloadSound1 && pszReloadSound2) pszReloadSound = RANDOM_LONG(0, 1) ? pszReloadSound1 : pszReloadSound2;
else if (pszReloadSound1) pszReloadSound = pszReloadSound1;
else if (pszReloadSound2) pszReloadSound = pszReloadSound2;
if (pszReloadSound && pszReloadSound[0] != '\0')
{
EMIT_SOUND_DYN(m_pPlayer->edict(), CHAN_ITEM, pszReloadSound, VOL_NORM, ATTN_NORM, 0, 85 + RANDOM_LONG(0, 31));
}
SendWeaponAnim(iAnim, UseDecrement());
m_flTimeWeaponIdle = m_flNextReload = UTIL_WeaponTimeBase() + fDelay;
}
else
#ifdef BUILD_LATEST_FIXES
if (m_flTimeWeaponIdle <= UTIL_WeaponTimeBase())
#endif
{
m_iClip++;
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]--;
m_pPlayer->ammo_buckshot--;
m_fInSpecialReload = 1;
}
return true;
}
BOOL CBasePlayerWeapon::PlayEmptySound()
{
if (m_iPlayEmptySound)

View File

@ -395,8 +395,14 @@ public:
bool ShieldSecondaryFire(int iUpAnim, int iDownAnim);
void HandleInfiniteAmmo();
void InstantReload(bool bCanRefillBPAmmo = false);
bool DefaultShotgunReload(int iAnim, int iStartAnim, float fDelay, float fStartDelay, const char *pszReloadSound1 = nullptr, const char *pszReloadSound2 = nullptr);
#ifdef REGAMEDLL_API
BOOL CanDeploy_OrigFunc();
BOOL DefaultDeploy_OrigFunc(char *szViewModel, char *szWeaponModel, int iAnim, char *szAnimExt, int skiplocal);
BOOL DefaultReload_OrigFunc(int iClipSize, int iAnim, float fDelay);
bool DefaultShotgunReload_OrigFunc(int iAnim, int iStartAnim, float fDelay, float fStartDelay, const char *pszReloadSound1, const char *pszReloadSound2);
CCSPlayerWeapon *CSPlayerWeapon() const;
#endif
@ -944,6 +950,10 @@ public:
#endif
}
#ifdef REGAMEDLL_API
BOOL CanDeploy_OrigFunc();
#endif
public:
bool ShieldSecondaryFire(int iUpAnim, int iDownAnim);
void SetPlayerShieldAnim();
@ -1100,6 +1110,10 @@ public:
#endif
}
#ifdef REGAMEDLL_API
BOOL CanDeploy_OrigFunc();
#endif
public:
bool ShieldSecondaryFire(int iUpAnim, int iDownAnim);
void SetPlayerShieldAnim();
@ -1575,6 +1589,10 @@ public:
#endif
}
#ifdef REGAMEDLL_API
BOOL CanDeploy_OrigFunc();
#endif
public:
bool ShieldSecondaryFire(int iUpAnim, int iDownAnim);
void SetPlayerShieldAnim();

View File

@ -264,7 +264,9 @@ void CFlashbang::WeaponIdle()
}
}
BOOL CFlashbang::CanDeploy()
LINK_HOOK_CLASS_CHAIN3(BOOL, CBasePlayerWeapon, CFlashbang, CanDeploy)
BOOL EXT_FUNC CFlashbang::__API_HOOK(CanDeploy)()
{
return m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] != 0;
}

View File

@ -260,7 +260,9 @@ void CHEGrenade::WeaponIdle()
}
}
BOOL CHEGrenade::CanDeploy()
LINK_HOOK_CLASS_CHAIN3(BOOL, CBasePlayerWeapon, CHEGrenade, CanDeploy)
BOOL EXT_FUNC CHEGrenade::__API_HOOK(CanDeploy)()
{
return m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] != 0;
}

View File

@ -177,43 +177,9 @@ void CM3::PrimaryAttack()
void CM3::Reload()
{
if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 || m_iClip == iMaxClip())
return;
// don't reload until recoil is done
if (m_flNextPrimaryAttack > UTIL_WeaponTimeBase())
return;
// check to see if we're ready to reload
if (m_fInSpecialReload == 0)
if (!DefaultShotgunReload(M3_RELOAD, M3_START_RELOAD, 0.45f, 0.55f))
{
m_pPlayer->SetAnimation(PLAYER_RELOAD);
SendWeaponAnim(M3_START_RELOAD, UseDecrement() != FALSE);
m_fInSpecialReload = 1;
m_flNextSecondaryAttack = m_flTimeWeaponIdle = m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.55f;
m_flNextPrimaryAttack = GetNextAttackDelay(0.55);
}
else if (m_fInSpecialReload == 1)
{
if (m_flTimeWeaponIdle > UTIL_WeaponTimeBase())
return;
// was waiting for gun to move to side
m_fInSpecialReload = 2;
SendWeaponAnim(M3_RELOAD, UseDecrement());
m_flTimeWeaponIdle = m_flNextReload = UTIL_WeaponTimeBase() + 0.45f;
}
else
#ifdef BUILD_LATEST_FIXES
if (m_flTimeWeaponIdle <= UTIL_WeaponTimeBase())
#endif
{
m_iClip++;
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]--;
m_pPlayer->ammo_buckshot--;
m_fInSpecialReload = 1;
/* do nothing */
}
}

View File

@ -274,7 +274,9 @@ void CSmokeGrenade::WeaponIdle()
}
}
BOOL CSmokeGrenade::CanDeploy()
LINK_HOOK_CLASS_CHAIN3(BOOL, CBasePlayerWeapon, CSmokeGrenade, CanDeploy)
BOOL EXT_FUNC CSmokeGrenade::__API_HOOK(CanDeploy)()
{
return m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] != 0;
}

View File

@ -174,49 +174,9 @@ void CXM1014::PrimaryAttack()
void CXM1014::Reload()
{
if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 || m_iClip == iMaxClip())
return;
// don't reload until recoil is done
if (m_flNextPrimaryAttack > UTIL_WeaponTimeBase())
return;
// check to see if we're ready to reload
if (m_fInSpecialReload == 0)
if (!DefaultShotgunReload(XM1014_RELOAD, XM1014_START_RELOAD, 0.3f, 0.55f, "weapons/reload1.wav", "weapons/reload3.wav"))
{
m_pPlayer->SetAnimation(PLAYER_RELOAD);
SendWeaponAnim(XM1014_START_RELOAD, UseDecrement() != FALSE);
m_fInSpecialReload = 1;
m_flNextSecondaryAttack = m_flTimeWeaponIdle = m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.55f;
m_flNextPrimaryAttack = GetNextAttackDelay(0.55);
}
else if (m_fInSpecialReload == 1)
{
if (m_flTimeWeaponIdle > UTIL_WeaponTimeBase())
return;
// was waiting for gun to move to side
m_fInSpecialReload = 2;
if (RANDOM_LONG(0, 1))
EMIT_SOUND_DYN(m_pPlayer->edict(), CHAN_ITEM, "weapons/reload1.wav", VOL_NORM, ATTN_NORM, 0, 85 + RANDOM_LONG(0, 31));
else
EMIT_SOUND_DYN(m_pPlayer->edict(), CHAN_ITEM, "weapons/reload3.wav", VOL_NORM, ATTN_NORM, 0, 85 + RANDOM_LONG(0, 31));
SendWeaponAnim(XM1014_RELOAD, UseDecrement());
m_flTimeWeaponIdle = m_flNextReload = UTIL_WeaponTimeBase() + 0.3f;
}
else
#ifdef BUILD_LATEST_FIXES
if (m_flTimeWeaponIdle <= UTIL_WeaponTimeBase())
#endif
{
m_iClip++;
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]--;
m_pPlayer->ammo_buckshot--;
m_fInSpecialReload = 1;
/* do nothing */
}
}

View File

@ -38,7 +38,7 @@
#include <API/CSInterfaces.h>
#define REGAMEDLL_API_VERSION_MAJOR 5
#define REGAMEDLL_API_VERSION_MINOR 11
#define REGAMEDLL_API_VERSION_MINOR 12
// CBasePlayer::Spawn hook
typedef IHookChainClass<void, class CBasePlayer> IReGameHook_CBasePlayer_Spawn;
@ -444,6 +444,22 @@ typedef IHookChainRegistryClass<bool, class CBasePlayer, const char *, float, bo
typedef IHookChainClass<void, class CBasePlayer> IReGameHook_CBasePlayer_UseEmpty;
typedef IHookChainRegistryClass<void, class CBasePlayer> IReGameHookRegistry_CBasePlayer_UseEmpty;
// CBasePlayerWeapon::CanDeploy hook
typedef IHookChainClass<BOOL, class CBasePlayerWeapon> IReGameHook_CBasePlayerWeapon_CanDeploy;
typedef IHookChainRegistryClass<BOOL, class CBasePlayerWeapon> IReGameHookRegistry_CBasePlayerWeapon_CanDeploy;
// CBasePlayerWeapon::DefaultDeploy hook
typedef IHookChainClass<BOOL, class CBasePlayerWeapon, char *, char *, int, char *, int> IReGameHook_CBasePlayerWeapon_DefaultDeploy;
typedef IHookChainRegistryClass<BOOL, class CBasePlayerWeapon, char *, char *, int, char *, int> IReGameHookRegistry_CBasePlayerWeapon_DefaultDeploy;
// CBasePlayerWeapon::DefaultReload hook
typedef IHookChainClass<int, class CBasePlayerWeapon, int, int, float> IReGameHook_CBasePlayerWeapon_DefaultReload;
typedef IHookChainRegistryClass<int, class CBasePlayerWeapon, int, int, float> IReGameHookRegistry_CBasePlayerWeapon_DefaultReload;
// CBasePlayerWeapon::DefaultShotgunReload hook
typedef IHookChainClass<bool, class CBasePlayerWeapon, int, int, float, float, const char *, const char *> IReGameHook_CBasePlayerWeapon_DefaultShotgunReload;
typedef IHookChainRegistryClass<bool, class CBasePlayerWeapon, int, int, float, float, const char *, const char *> IReGameHookRegistry_CBasePlayerWeapon_DefaultShotgunReload;
class IReGameHookchains {
public:
virtual ~IReGameHookchains() {}
@ -554,6 +570,10 @@ public:
virtual IReGameHookRegistry_IsPenetrableEntity *IsPenetrableEntity() = 0;
virtual IReGameHookRegistry_CBasePlayer_HintMessageEx *CBasePlayer_HintMessageEx() = 0;
virtual IReGameHookRegistry_CBasePlayer_UseEmpty *CBasePlayer_UseEmpty() = 0;
virtual IReGameHookRegistry_CBasePlayerWeapon_CanDeploy *CBasePlayerWeapon_CanDeploy() = 0;
virtual IReGameHookRegistry_CBasePlayerWeapon_DefaultDeploy *CBasePlayerWeapon_DefaultDeploy() = 0;
virtual IReGameHookRegistry_CBasePlayerWeapon_DefaultReload *CBasePlayerWeapon_DefaultReload() = 0;
virtual IReGameHookRegistry_CBasePlayerWeapon_DefaultShotgunReload *CBasePlayerWeapon_DefaultShotgunReload() = 0;
};
struct ReGameFuncs_t {