diff --git a/regamedll/dlls/API/CAPI_Impl.cpp b/regamedll/dlls/API/CAPI_Impl.cpp index 6175dcc0..e45e1cc8 100644 --- a/regamedll/dlls/API/CAPI_Impl.cpp +++ b/regamedll/dlls/API/CAPI_Impl.cpp @@ -176,6 +176,10 @@ GAMEHOOK_REGISTRY(CGib_Spawn); GAMEHOOK_REGISTRY(CGib_BounceGibTouch); GAMEHOOK_REGISTRY(CGib_WaitTillLand); +GAMEHOOK_REGISTRY(CBaseEntity_FireBullets); +GAMEHOOK_REGISTRY(CBaseEntity_FireBuckshots); +GAMEHOOK_REGISTRY(CBaseEntity_FireBullets3); + 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 e33b4e69..cd69b345 100644 --- a/regamedll/dlls/API/CAPI_Impl.h +++ b/regamedll/dlls/API/CAPI_Impl.h @@ -603,6 +603,18 @@ typedef IHookChainRegistryClassImpl CReGameHook typedef IHookChainClassImpl CReGameHook_CGib_WaitTillLand; typedef IHookChainRegistryClassImpl CReGameHookRegistry_CGib_WaitTillLand; +// CBaseEntity::FireBullets hook +typedef IHookChainClassImpl CReGameHook_CBaseEntity_FireBullets; +typedef IHookChainRegistryClassImpl CReGameHookRegistry_CBaseEntity_FireBullets; + +// CBaseEntity::FireBuckshots hook +typedef IHookChainClassImpl CReGameHook_CBaseEntity_FireBuckshots; +typedef IHookChainRegistryClassImpl CReGameHookRegistry_CBaseEntity_FireBuckshots; + +// CBaseEntity::FireBullets3 hook +typedef IHookChainClassImpl CReGameHook_CBaseEntity_FireBullets3; +typedef IHookChainRegistryClassImpl CReGameHookRegistry_CBaseEntity_FireBullets3; + class CReGameHookchains: public IReGameHookchains { public: // CBasePlayer virtual @@ -725,6 +737,10 @@ public: CReGameHookRegistry_CGib_BounceGibTouch m_CGib_BounceGibTouch; CReGameHookRegistry_CGib_WaitTillLand m_CGib_WaitTillLand; + CReGameHookRegistry_CBaseEntity_FireBullets m_CBaseEntity_FireBullets; + CReGameHookRegistry_CBaseEntity_FireBuckshots m_CBaseEntity_FireBuckshots; + CReGameHookRegistry_CBaseEntity_FireBullets3 m_CBaseEntity_FireBullets3; + public: virtual IReGameHookRegistry_CBasePlayer_Spawn *CBasePlayer_Spawn(); virtual IReGameHookRegistry_CBasePlayer_Precache *CBasePlayer_Precache(); @@ -844,6 +860,10 @@ public: virtual IReGameHookRegistry_CGib_Spawn *CGib_Spawn(); virtual IReGameHookRegistry_CGib_BounceGibTouch *CGib_BounceGibTouch(); virtual IReGameHookRegistry_CGib_WaitTillLand *CGib_WaitTillLand(); + + virtual IReGameHookRegistry_CBaseEntity_FireBullets *CBaseEntity_FireBullets(); + virtual IReGameHookRegistry_CBaseEntity_FireBuckshots *CBaseEntity_FireBuckshots(); + virtual IReGameHookRegistry_CBaseEntity_FireBullets3 *CBaseEntity_FireBullets3(); }; extern CReGameHookchains g_ReGameHookchains; diff --git a/regamedll/dlls/cbase.cpp b/regamedll/dlls/cbase.cpp index 1af09d1d..e1d934a3 100644 --- a/regamedll/dlls/cbase.cpp +++ b/regamedll/dlls/cbase.cpp @@ -995,7 +995,10 @@ void CBaseEntity::TraceAttack(entvars_t *pevAttacker, float flDamage, Vector vec } } -void CBaseEntity::FireBullets(ULONG cShots, Vector vecSrc, Vector vecDirShooting, Vector vecSpread, float flDistance, int iBulletType, int iTracerFreq, int iDamage, entvars_t *pevAttacker) + +LINK_HOOK_CLASS_VOID_CHAIN(CBaseEntity, FireBullets, (ULONG cShots, VectorRef vecSrc, VectorRef vecDirShooting, VectorRef vecSpread, float flDistance, int iBulletType, int iTracerFreq, int iDamage, entvars_t *pevAttacker), cShots, vecSrc, vecDirShooting, vecSpread, flDistance, iBulletType, iTracerFreq, iDamage, pevAttacker) + +void CBaseEntity::__API_HOOK(FireBullets)(ULONG cShots, VectorRef vecSrc, VectorRef vecDirShooting, VectorRef vecSpread, float flDistance, int iBulletType, int iTracerFreq, int iDamage, entvars_t *pevAttacker) { static int tracerCount; int tracer; @@ -1139,7 +1142,9 @@ void CBaseEntity::FireBullets(ULONG cShots, Vector vecSrc, Vector vecDirShooting ApplyMultiDamage(pev, pevAttacker); } -void CBaseEntity::FireBuckshots(ULONG cShots, Vector vecSrc, Vector vecDirShooting, Vector vecSpread, float flDistance, int iTracerFreq, int iDamage, entvars_t *pevAttacker) +LINK_HOOK_CLASS_VOID_CHAIN(CBaseEntity, FireBuckshots, (ULONG cShots, VectorRef vecSrc, VectorRef vecDirShooting, VectorRef vecSpread, float flDistance, int iTracerFreq, int iDamage, entvars_t *pevAttacker), cShots, vecSrc, vecDirShooting, vecSpread, flDistance, iTracerFreq, iDamage, pevAttacker) + +void CBaseEntity::__API_HOOK(FireBuckshots)(ULONG cShots, VectorRef vecSrc, VectorRef vecDirShooting, VectorRef vecSpread, float flDistance, int iTracerFreq, int iDamage, entvars_t *pevAttacker) { static int tracerCount; int tracer; @@ -1229,10 +1234,15 @@ bool EXT_FUNC IsPenetrableEntity_default(Vector &vecSrc, Vector &vecEnd, entvars return true; } + +LINK_HOOK_CLASS_CHAIN(VectorRef, CBaseEntity, FireBullets3, (VectorRef vecSrc, VectorRef vecDirShooting, float vecSpread, float flDistance, int iPenetration, int iBulletType, int iDamage, float flRangeModifier, entvars_t *pevAttacker, bool bPistol, int shared_rand), vecSrc, vecDirShooting, vecSpread, flDistance, iPenetration, iBulletType, iDamage, flRangeModifier, pevAttacker, bPistol, shared_rand) + // Go to the trouble of combining multiple pellets into a single damage call. // This version is used by Players, uses the random seed generator to sync client and server side shots. -Vector CBaseEntity::FireBullets3(Vector vecSrc, Vector vecDirShooting, float vecSpread, float flDistance, int iPenetration, int iBulletType, int iDamage, float flRangeModifier, entvars_t *pevAttacker, bool bPistol, int shared_rand) +VectorRef CBaseEntity::__API_HOOK(FireBullets3)(VectorRef vecSrc, VectorRef vecDirShooting, float vecSpread, float flDistance, int iPenetration, int iBulletType, int iDamage, float flRangeModifier, entvars_t *pevAttacker, bool bPistol, int shared_rand) { + static Vector vecRet; + int iOriginalPenetration = iPenetration; int iPenetrationPower; float flPenetrationDistance; @@ -1448,7 +1458,11 @@ Vector CBaseEntity::FireBullets3(Vector vecSrc, Vector vecDirShooting, float vec ApplyMultiDamage(pev, pevAttacker); } - return Vector(x * vecSpread, y * vecSpread, 0); + vecRet.x = x * vecSpread; + vecRet.y = y * vecSpread; + vecRet.z = 0; + + return vecRet; } void CBaseEntity::TraceBleed(float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType) diff --git a/regamedll/dlls/cbase.h b/regamedll/dlls/cbase.h index c480b11b..e0ae20c2 100644 --- a/regamedll/dlls/cbase.h +++ b/regamedll/dlls/cbase.h @@ -129,6 +129,13 @@ public: virtual BOOL FVisible(const Vector &vecOrigin); public: + +#ifdef REGAMEDLL_API + EXT_FUNC void FireBullets_OrigFunc(ULONG cShots, VectorRef vecSrc, VectorRef vecDirShooting, VectorRef vecSpread, float flDistance, int iBulletType, int iTracerFreq, int iDamage, entvars_t *pevAttacker); + EXT_FUNC void FireBuckshots_OrigFunc(ULONG cShots, VectorRef vecSrc, VectorRef vecDirShooting, VectorRef vecSpread, float flDistance, int iTracerFreq, int iDamage, entvars_t *pevAttacker); + EXT_FUNC VectorRef FireBullets3_OrigFunc(VectorRef vecSrc, VectorRef vecDirShooting, float vecSpread, float flDistance, int iPenetration, int iBulletType, int iDamage, float flRangeModifier, entvars_t *pevAttacker, bool bPistol, int shared_rand); +#endif + // allow engine to allocate instance data void *operator new(size_t stAllocateBlock, entvars_t *pevnew) { return ALLOC_PRIVATE(ENT(pevnew), stAllocateBlock); } @@ -145,9 +152,11 @@ public: void EXPORT SUB_FadeOut(); void EXPORT SUB_CallUseToggle() { Use(this, this, USE_TOGGLE, 0); } int ShouldToggle(USE_TYPE useType, BOOL currentState); - void FireBullets(ULONG cShots, Vector vecSrc, Vector vecDirShooting, Vector vecSpread, float flDistance, int iBulletType, int iTracerFreq = 4, int iDamage = 0, entvars_t *pevAttacker = nullptr); - void FireBuckshots(ULONG cShots, Vector vecSrc, Vector vecDirShooting, Vector vecSpread, float flDistance, int iTracerFreq, int iDamage, entvars_t *pevAttacker = nullptr); - Vector FireBullets3(Vector vecSrc, Vector vecDirShooting, float vecSpread, float flDistance, int iPenetration, int iBulletType, int iDamage, float flRangeModifier, entvars_t *pevAttacker, bool bPistol, int shared_rand = 0); + + EXT_FUNC void FireBullets(ULONG cShots, VectorRef vecSrc, VectorRef vecDirShooting, VectorRef vecSpread, float flDistance, int iBulletType, int iTracerFreq, int iDamage, entvars_t *pevAttacker); + EXT_FUNC void FireBuckshots(ULONG cShots, VectorRef vecSrc, VectorRef vecDirShooting, VectorRef vecSpread, float flDistance, int iTracerFreq, int iDamage, entvars_t *pevAttacker); + EXT_FUNC VectorRef FireBullets3(VectorRef vecSrc, VectorRef vecDirShooting, float vecSpread, float flDistance, int iPenetration, int iBulletType, int iDamage, float flRangeModifier, entvars_t *pevAttacker, bool bPistol, int shared_rand = 0); + void SUB_UseTargets(CBaseEntity *pActivator, USE_TYPE useType, float value); bool Intersects(CBaseEntity *pOther); bool Intersects(const Vector &mins, const Vector &maxs); diff --git a/regamedll/dlls/func_tank.cpp b/regamedll/dlls/func_tank.cpp index 606f8bfe..1ca0e966 100644 --- a/regamedll/dlls/func_tank.cpp +++ b/regamedll/dlls/func_tank.cpp @@ -659,6 +659,8 @@ void CFuncTankGun::Fire(const Vector &barrelEnd, const Vector &forward, entvars_ // FireBullets needs gpGlobals->v_up, etc. UTIL_MakeAimVectors(pev->angles); + Vector vecBarrelEnd(barrelEnd), vecForward(forward); + int bulletCount = int((gpGlobals->time - m_fireLast) * m_fireRate); if (bulletCount > 0) { @@ -667,13 +669,13 @@ void CFuncTankGun::Fire(const Vector &barrelEnd, const Vector &forward, entvars_ switch (m_bulletType) { case TANK_BULLET_9MM: - FireBullets(1, barrelEnd, forward, m_TankSpread[m_spread], 4096, BULLET_MONSTER_9MM, 1, m_iBulletDamage, pevAttacker); + FireBullets(1, vecBarrelEnd, vecForward, m_TankSpread[m_spread], 4096, BULLET_MONSTER_9MM, 1, m_iBulletDamage, pevAttacker); break; case TANK_BULLET_MP5: - FireBullets(1, barrelEnd, forward, m_TankSpread[m_spread], 4096, BULLET_MONSTER_MP5, 1, m_iBulletDamage, pevAttacker); + FireBullets(1, vecBarrelEnd, vecForward, m_TankSpread[m_spread], 4096, BULLET_MONSTER_MP5, 1, m_iBulletDamage, pevAttacker); break; case TANK_BULLET_12MM: - FireBullets(1, barrelEnd, forward, m_TankSpread[m_spread], 4096, BULLET_MONSTER_12MM, 1, m_iBulletDamage, pevAttacker); + FireBullets(1, vecBarrelEnd, vecForward, m_TankSpread[m_spread], 4096, BULLET_MONSTER_12MM, 1, m_iBulletDamage, pevAttacker); break; default: case TANK_BULLET_NONE: @@ -681,7 +683,7 @@ void CFuncTankGun::Fire(const Vector &barrelEnd, const Vector &forward, entvars_ } } - CFuncTank::Fire(barrelEnd, forward, pevAttacker); + CFuncTank::Fire(vecBarrelEnd, vecForward, pevAttacker); } } else diff --git a/regamedll/dlls/wpn_shared/wpn_elite.cpp b/regamedll/dlls/wpn_shared/wpn_elite.cpp index 9756677b..05428d8e 100644 --- a/regamedll/dlls/wpn_shared/wpn_elite.cpp +++ b/regamedll/dlls/wpn_shared/wpn_elite.cpp @@ -174,7 +174,8 @@ void CELITE::ELITEFire(float flSpread, float flCycleTime, BOOL fUseSemi) m_pPlayer->SetAnimation(PLAYER_ATTACK1); m_iWeaponState &= ~WPNSTATE_ELITE_LEFT; - vecDir = m_pPlayer->FireBullets3(vecSrc - gpGlobals->v_right * 5, vecAiming, flSpread, + vecSrc -= gpGlobals->v_right * 5; + vecDir = m_pPlayer->FireBullets3(vecSrc, vecAiming, flSpread, 8192, BULLET_PLAYER_9MM, 1, flBaseDamage, ELITE_RANGE_MODIFER, m_pPlayer->pev, true, m_pPlayer->random_seed); PLAYBACK_EVENT_FULL(flag, m_pPlayer->edict(), m_usFireELITE_LEFT, 0, (float *)&g_vecZero, (float *)&g_vecZero, flTimeDiff, vecDir.x, @@ -185,7 +186,8 @@ void CELITE::ELITEFire(float flSpread, float flCycleTime, BOOL fUseSemi) m_pPlayer->SetAnimation(PLAYER_ATTACK2); m_iWeaponState |= WPNSTATE_ELITE_LEFT; - vecDir = m_pPlayer->FireBullets3(vecSrc + gpGlobals->v_right * 5, vecAiming, flSpread, + vecSrc += gpGlobals->v_right * 5; + vecDir = m_pPlayer->FireBullets3(vecSrc, vecAiming, flSpread, 8192, BULLET_PLAYER_9MM, 1, flBaseDamage, ELITE_RANGE_MODIFER, m_pPlayer->pev, true, m_pPlayer->random_seed); PLAYBACK_EVENT_FULL(flag, m_pPlayer->edict(), m_usFireELITE_RIGHT, 0, (float *)&g_vecZero, (float *)&g_vecZero, flTimeDiff, vecDir.x, diff --git a/regamedll/dlls/wpn_shared/wpn_m3.cpp b/regamedll/dlls/wpn_shared/wpn_m3.cpp index bd27b399..69822960 100644 --- a/regamedll/dlls/wpn_shared/wpn_m3.cpp +++ b/regamedll/dlls/wpn_shared/wpn_m3.cpp @@ -132,10 +132,12 @@ void CM3::PrimaryAttack() float flBaseDamage = M3_DAMAGE; #endif + Vector vecCone(M3_CONE_VECTOR); + #ifdef REGAMEDLL_FIXES - m_pPlayer->FireBuckshots(9, vecSrc, vecAiming, M3_CONE_VECTOR, 3000, 0, flBaseDamage); + m_pPlayer->FireBuckshots(9, vecSrc, vecAiming, vecCone, 3000.0f, 0, flBaseDamage, m_pPlayer->pev); #else - m_pPlayer->FireBullets(9, vecSrc, vecAiming, M3_CONE_VECTOR, 3000, BULLET_PLAYER_BUCKSHOT, 0); + m_pPlayer->FireBullets(9, vecSrc, vecAiming, vecCone, 3000, BULLET_PLAYER_BUCKSHOT, 0, 0, NULL); #endif #ifdef CLIENT_WEAPONS diff --git a/regamedll/dlls/wpn_shared/wpn_xm1014.cpp b/regamedll/dlls/wpn_shared/wpn_xm1014.cpp index 4590e3e3..9689844f 100644 --- a/regamedll/dlls/wpn_shared/wpn_xm1014.cpp +++ b/regamedll/dlls/wpn_shared/wpn_xm1014.cpp @@ -130,10 +130,12 @@ void CXM1014::PrimaryAttack() float flBaseDamage = XM1014_DAMAGE; #endif + Vector vecCone(XM1014_CONE_VECTOR); + #ifdef REGAMEDLL_FIXES - m_pPlayer->FireBuckshots(6, vecSrc, vecAiming, XM1014_CONE_VECTOR, 3048, 0, flBaseDamage); + m_pPlayer->FireBuckshots(6, vecSrc, vecAiming, vecCone, 3048.0f, 0, flBaseDamage, m_pPlayer->pev); #else - m_pPlayer->FireBullets(6, vecSrc, vecAiming, XM1014_CONE_VECTOR, 3048, BULLET_PLAYER_BUCKSHOT, 0); + m_pPlayer->FireBullets(6, vecSrc, vecAiming, vecCone, 3048, BULLET_PLAYER_BUCKSHOT, 0, 0, NULL); #endif #ifdef CLIENT_WEAPONS diff --git a/regamedll/public/regamedll/regamedll_api.h b/regamedll/public/regamedll/regamedll_api.h index dcfe2b5b..1bb86793 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 18 +#define REGAMEDLL_API_VERSION_MINOR 19 // CBasePlayer::Spawn hook typedef IHookChainClass IReGameHook_CBasePlayer_Spawn; @@ -488,6 +488,19 @@ typedef IHookChainRegistryClass IReGameHookRegi typedef IHookChainClass IReGameHook_CGib_WaitTillLand; typedef IHookChainRegistryClass IReGameHookRegistry_CGib_WaitTillLand; +// CBaseEntity::FireBullets hook +typedef IHookChainClass IReGameHook_CBaseEntity_FireBullets; +typedef IHookChainRegistryClass IReGameHookRegistry_CBaseEntity_FireBullets; + +// CBaseEntity::FireBuckshots hook +typedef IHookChainClass IReGameHook_CBaseEntity_FireBuckshots; +typedef IHookChainRegistryClass IReGameHookRegistry_CBaseEntity_FireBuckshots; + +// CBaseEntity::FireBullets3 hook +typedef IHookChainClass IReGameHook_CBaseEntity_FireBullets3; +typedef IHookChainRegistryClass IReGameHookRegistry_CBaseEntity_FireBullets3; + + class IReGameHookchains { public: virtual ~IReGameHookchains() {} @@ -610,6 +623,10 @@ public: virtual IReGameHookRegistry_CGib_Spawn *CGib_Spawn() = 0; virtual IReGameHookRegistry_CGib_BounceGibTouch *CGib_BounceGibTouch() = 0; virtual IReGameHookRegistry_CGib_WaitTillLand *CGib_WaitTillLand() = 0; + + virtual IReGameHookRegistry_CBaseEntity_FireBullets *CBaseEntity_FireBullets() = 0; + virtual IReGameHookRegistry_CBaseEntity_FireBuckshots *CBaseEntity_FireBuckshots() = 0; + virtual IReGameHookRegistry_CBaseEntity_FireBullets3 *CBaseEntity_FireBullets3() = 0; }; struct ReGameFuncs_t { diff --git a/regamedll/regamedll/hookchains_impl.h b/regamedll/regamedll/hookchains_impl.h index 922f8844..aefd930d 100644 --- a/regamedll/regamedll/hookchains_impl.h +++ b/regamedll/regamedll/hookchains_impl.h @@ -29,6 +29,7 @@ #pragma once #include "hookchains.h" +#include #define MAX_HOOKS_IN_CHAIN 30 @@ -104,11 +105,28 @@ public: return nexthook(&nextChain, object, args...); } - return m_OriginalFunc ? (object->*m_OriginalFunc)(args...) : t_ret(); + return m_OriginalFunc ? (object->*m_OriginalFunc)(args...) : GetDefaultValue(); } - virtual t_ret callOriginal(t_class *object, t_args... args) { - return m_OriginalFunc ? (object->*m_OriginalFunc)(args...) : t_ret(); + virtual t_ret callOriginal(t_class *object, t_args... args) + { + return m_OriginalFunc ? (object->*m_OriginalFunc)(args...) : GetDefaultValue(); + } + + template + typename std::enable_if_t::value == false, T> + GetDefaultValue() + { + typedef typename std::remove_reference::type t_ret_noref; + + static t_ret_noref defaultRet = t_ret_noref{}; + return defaultRet; + } + + template + typename std::enable_if_t::value == true, T> + GetDefaultValue() + { } private: