Skip to content

Commit

Permalink
API: Add "CBaseEntity::Fire<Bullets[3]|Buckshots>" hooks. (#587)
Browse files Browse the repository at this point in the history
  • Loading branch information
StevenKal authored Nov 27, 2020
1 parent 519b7db commit 7721348
Show file tree
Hide file tree
Showing 10 changed files with 111 additions and 21 deletions.
4 changes: 4 additions & 0 deletions regamedll/dlls/API/CAPI_Impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
20 changes: 20 additions & 0 deletions regamedll/dlls/API/CAPI_Impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -725,6 +737,10 @@ class CReGameHookchains: public IReGameHookchains {
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();
Expand Down Expand Up @@ -844,6 +860,10 @@ class CReGameHookchains: public IReGameHookchains {
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;
Expand Down
22 changes: 18 additions & 4 deletions regamedll/dlls/cbase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
15 changes: 12 additions & 3 deletions regamedll/dlls/cbase.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,13 @@ class CBaseEntity {
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); }

Expand All @@ -145,9 +152,11 @@ class CBaseEntity {
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);
Expand Down
10 changes: 6 additions & 4 deletions regamedll/dlls/func_tank.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -667,21 +669,21 @@ 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:
break;
}
}

CFuncTank::Fire(barrelEnd, forward, pevAttacker);
CFuncTank::Fire(vecBarrelEnd, vecForward, pevAttacker);
}
}
else
Expand Down
6 changes: 4 additions & 2 deletions regamedll/dlls/wpn_shared/wpn_elite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand Down
6 changes: 4 additions & 2 deletions regamedll/dlls/wpn_shared/wpn_m3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 4 additions & 2 deletions regamedll/dlls/wpn_shared/wpn_xm1014.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
19 changes: 18 additions & 1 deletion regamedll/public/regamedll/regamedll_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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() {}
Expand Down Expand Up @@ -610,6 +623,10 @@ class IReGameHookchains {
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 {
Expand Down
24 changes: 21 additions & 3 deletions regamedll/regamedll/hookchains_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#pragma once

#include "hookchains.h"
#include <type_traits>

#define MAX_HOOKS_IN_CHAIN 30

Expand Down Expand Up @@ -104,11 +105,28 @@ class IHookChainClassImpl : public IHookChainClass<t_ret, t_class, t_args...> {
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:
Expand Down

1 comment on commit 7721348

@StevenKal
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@s1lentq + @"the original author of the PR": Thank you very much for such quick addition to the public version!

Please sign in to comment.