diff --git a/gradle.properties b/gradle.properties index 8b095261..9c1255b4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ majorVersion=5 -minorVersion=11 +minorVersion=12 maintenanceVersion=0 diff --git a/regamedll/dlls/API/CAPI_Impl.cpp b/regamedll/dlls/API/CAPI_Impl.cpp index 17ddcb35..98e11fc2 100644 --- a/regamedll/dlls/API/CAPI_Impl.cpp +++ b/regamedll/dlls/API/CAPI_Impl.cpp @@ -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; diff --git a/regamedll/dlls/API/CAPI_Impl.h b/regamedll/dlls/API/CAPI_Impl.h index 3e8b6a55..cd7df97b 100644 --- a/regamedll/dlls/API/CAPI_Impl.h +++ b/regamedll/dlls/API/CAPI_Impl.h @@ -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(&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 CReGameHook_CBasePlayer_UseEmpty; typedef IHookChainRegistryClassImpl CReGameHookRegistry_CBasePlayer_UseEmpty; +// CBasePlayerWeapon::CanDeploy hook +typedef IHookChainClassImpl CReGameHook_CBasePlayerWeapon_CanDeploy; +typedef IHookChainRegistryClassImpl CReGameHookRegistry_CBasePlayerWeapon_CanDeploy; + +// CBasePlayerWeapon::DefaultDeploy hook +typedef IHookChainClassImpl CReGameHook_CBasePlayerWeapon_DefaultDeploy; +typedef IHookChainRegistryClassImpl CReGameHookRegistry_CBasePlayerWeapon_DefaultDeploy; + +// CBasePlayerWeapon::DefaultReload hook +typedef IHookChainClassImpl CReGameHook_CBasePlayerWeapon_DefaultReload; +typedef IHookChainRegistryClassImpl CReGameHookRegistry_CBasePlayerWeapon_DefaultReload; + +// CBasePlayerWeapon::DefaultShotgunReload hook +typedef IHookChainClassImpl CReGameHook_CBasePlayerWeapon_DefaultShotgunReload; +typedef IHookChainRegistryClassImpl 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; diff --git a/regamedll/dlls/player.cpp b/regamedll/dlls/player.cpp index aa231dd9..becb4ca9 100644 --- a/regamedll/dlls/player.cpp +++ b/regamedll/dlls/player.cpp @@ -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) diff --git a/regamedll/dlls/weapons.cpp b/regamedll/dlls/weapons.cpp index 7d4b0d02..2eff9fb0 100644 --- a/regamedll/dlls/weapons.cpp +++ b/regamedll/dlls/weapons.cpp @@ -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) diff --git a/regamedll/dlls/weapons.h b/regamedll/dlls/weapons.h index 859d7ec2..f3d90ebb 100644 --- a/regamedll/dlls/weapons.h +++ b/regamedll/dlls/weapons.h @@ -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(); diff --git a/regamedll/dlls/wpn_shared/wpn_flashbang.cpp b/regamedll/dlls/wpn_shared/wpn_flashbang.cpp index f749fc4b..c5462e49 100644 --- a/regamedll/dlls/wpn_shared/wpn_flashbang.cpp +++ b/regamedll/dlls/wpn_shared/wpn_flashbang.cpp @@ -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; } diff --git a/regamedll/dlls/wpn_shared/wpn_hegrenade.cpp b/regamedll/dlls/wpn_shared/wpn_hegrenade.cpp index 864e36cd..3f17e725 100644 --- a/regamedll/dlls/wpn_shared/wpn_hegrenade.cpp +++ b/regamedll/dlls/wpn_shared/wpn_hegrenade.cpp @@ -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; } diff --git a/regamedll/dlls/wpn_shared/wpn_m3.cpp b/regamedll/dlls/wpn_shared/wpn_m3.cpp index 810008e2..bd27b399 100644 --- a/regamedll/dlls/wpn_shared/wpn_m3.cpp +++ b/regamedll/dlls/wpn_shared/wpn_m3.cpp @@ -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 */ } } diff --git a/regamedll/dlls/wpn_shared/wpn_smokegrenade.cpp b/regamedll/dlls/wpn_shared/wpn_smokegrenade.cpp index 6496c498..d63fe3a6 100644 --- a/regamedll/dlls/wpn_shared/wpn_smokegrenade.cpp +++ b/regamedll/dlls/wpn_shared/wpn_smokegrenade.cpp @@ -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; } diff --git a/regamedll/dlls/wpn_shared/wpn_xm1014.cpp b/regamedll/dlls/wpn_shared/wpn_xm1014.cpp index b123f8c3..4590e3e3 100644 --- a/regamedll/dlls/wpn_shared/wpn_xm1014.cpp +++ b/regamedll/dlls/wpn_shared/wpn_xm1014.cpp @@ -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 */ } } diff --git a/regamedll/public/regamedll/regamedll_api.h b/regamedll/public/regamedll/regamedll_api.h index 20041468..e05bab42 100644 --- a/regamedll/public/regamedll/regamedll_api.h +++ b/regamedll/public/regamedll/regamedll_api.h @@ -38,7 +38,7 @@ #include #define REGAMEDLL_API_VERSION_MAJOR 5 -#define REGAMEDLL_API_VERSION_MINOR 11 +#define REGAMEDLL_API_VERSION_MINOR 12 // CBasePlayer::Spawn hook typedef IHookChainClass IReGameHook_CBasePlayer_Spawn; @@ -444,6 +444,22 @@ typedef IHookChainRegistryClass IReGameHook_CBasePlayer_UseEmpty; typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayer_UseEmpty; +// CBasePlayerWeapon::CanDeploy hook +typedef IHookChainClass IReGameHook_CBasePlayerWeapon_CanDeploy; +typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayerWeapon_CanDeploy; + +// CBasePlayerWeapon::DefaultDeploy hook +typedef IHookChainClass IReGameHook_CBasePlayerWeapon_DefaultDeploy; +typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayerWeapon_DefaultDeploy; + +// CBasePlayerWeapon::DefaultReload hook +typedef IHookChainClass IReGameHook_CBasePlayerWeapon_DefaultReload; +typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayerWeapon_DefaultReload; + +// CBasePlayerWeapon::DefaultShotgunReload hook +typedef IHookChainClass IReGameHook_CBasePlayerWeapon_DefaultShotgunReload; +typedef IHookChainRegistryClass 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 {