API: Add "CBaseEntity::Fire<Bullets[3]|Buckshots>" hooks. (#587)

This commit is contained in:
StevenKal 2020-11-27 23:55:14 +01:00 committed by GitHub
parent 519b7db38d
commit 7721348199
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 111 additions and 21 deletions

View File

@ -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;
}

View File

@ -603,6 +603,18 @@ typedef IHookChainRegistryClassImpl<void, class CGib, CBaseEntity *> CReGameHook
typedef IHookChainClassImpl<void, class CGib> CReGameHook_CGib_WaitTillLand;
typedef IHookChainRegistryClassImpl<void, class CGib> CReGameHookRegistry_CGib_WaitTillLand;
// CBaseEntity::FireBullets hook
typedef IHookChainClassImpl<void, class CBaseEntity, ULONG, Vector &, Vector &, Vector &, float, int, int, int, entvars_t *> CReGameHook_CBaseEntity_FireBullets;
typedef IHookChainRegistryClassImpl<void, class CBaseEntity, ULONG, Vector &, Vector &, Vector &, float, int, int, int, entvars_t *> CReGameHookRegistry_CBaseEntity_FireBullets;
// CBaseEntity::FireBuckshots hook
typedef IHookChainClassImpl<void, class CBaseEntity, ULONG, Vector &, Vector &, Vector &, float, int, int, entvars_t *> CReGameHook_CBaseEntity_FireBuckshots;
typedef IHookChainRegistryClassImpl<void, class CBaseEntity, ULONG, Vector &, Vector &, Vector &, float, int, int, entvars_t *> CReGameHookRegistry_CBaseEntity_FireBuckshots;
// CBaseEntity::FireBullets3 hook
typedef IHookChainClassImpl<Vector &, class CBaseEntity, Vector &, Vector &, float, float, int, int, int, float, entvars_t *, bool, int> CReGameHook_CBaseEntity_FireBullets3;
typedef IHookChainRegistryClassImpl<Vector &, class CBaseEntity, Vector &, Vector &, float, float, int, int, int, float, entvars_t *, bool, int> 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;

View File

@ -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)

View File

@ -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);

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -38,7 +38,7 @@
#include <API/CSInterfaces.h>
#define REGAMEDLL_API_VERSION_MAJOR 5
#define REGAMEDLL_API_VERSION_MINOR 18
#define REGAMEDLL_API_VERSION_MINOR 19
// CBasePlayer::Spawn hook
typedef IHookChainClass<void, class CBasePlayer> IReGameHook_CBasePlayer_Spawn;
@ -488,6 +488,19 @@ typedef IHookChainRegistryClass<void, class CGib, CBaseEntity *> IReGameHookRegi
typedef IHookChainClass<void, class CGib> IReGameHook_CGib_WaitTillLand;
typedef IHookChainRegistryClass<void, class CGib> IReGameHookRegistry_CGib_WaitTillLand;
// CBaseEntity::FireBullets hook
typedef IHookChainClass<void, class CBaseEntity, ULONG, Vector &, Vector &, Vector &, float, int, int, int, entvars_t *> IReGameHook_CBaseEntity_FireBullets;
typedef IHookChainRegistryClass<void, class CBaseEntity, ULONG, Vector &, Vector &, Vector &, float, int, int, int, entvars_t *> IReGameHookRegistry_CBaseEntity_FireBullets;
// CBaseEntity::FireBuckshots hook
typedef IHookChainClass<void, class CBaseEntity, ULONG, Vector &, Vector &, Vector &, float, int, int, entvars_t *> IReGameHook_CBaseEntity_FireBuckshots;
typedef IHookChainRegistryClass<void, class CBaseEntity, ULONG, Vector &, Vector &, Vector &, float, int, int, entvars_t *> IReGameHookRegistry_CBaseEntity_FireBuckshots;
// CBaseEntity::FireBullets3 hook
typedef IHookChainClass<Vector &, class CBaseEntity, Vector &, Vector &, float, float, int, int, int, float, entvars_t *, bool, int> IReGameHook_CBaseEntity_FireBullets3;
typedef IHookChainRegistryClass<Vector &, class CBaseEntity, Vector &, Vector &, float, float, int, int, int, float, entvars_t *, bool, int> 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 {

View File

@ -29,6 +29,7 @@
#pragma once
#include "hookchains.h"
#include <type_traits>
#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<t_ret>();
}
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<t_ret>();
}
template <typename T>
typename std::enable_if_t<std::is_void<T>::value == false, T>
GetDefaultValue()
{
typedef typename std::remove_reference<T>::type t_ret_noref;
static t_ret_noref defaultRet = t_ret_noref{};
return defaultRet;
}
template <typename T>
typename std::enable_if_t<std::is_void<T>::value == true, T>
GetDefaultValue()
{
}
private: