From 8d5aa54cebe8ab08ad345d9146c85b30dbc2bde6 Mon Sep 17 00:00:00 2001 From: GLoOoccK <155241167+GLoOoccK@users.noreply.github.com> Date: Sun, 20 Apr 2025 11:32:49 -0300 Subject: [PATCH] API: Knockback (#1069) --- README.md | 1 + dist/game.cfg | 7 +++++++ regamedll/dlls/API/CAPI_Impl.cpp | 1 + regamedll/dlls/API/CAPI_Impl.h | 6 ++++++ regamedll/dlls/API/CSPlayer.cpp | 5 +++++ regamedll/dlls/game.cpp | 4 ++++ regamedll/dlls/game.h | 1 + regamedll/dlls/player.cpp | 22 ++++++++++++++++++---- regamedll/dlls/player.h | 2 ++ regamedll/public/regamedll/API/CSPlayer.h | 1 + regamedll/public/regamedll/regamedll_api.h | 7 ++++++- regamedll/version/version.h | 2 +- 12 files changed, 53 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index b39c0f19..a1198f08 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,7 @@ This means that plugins that do binary code analysis (Orpheu for example) probab | mp_randomspawn | 0 | 0 | 1 | Random player spawns
`0` disabled
`1` enabled
`NOTE`: Navigation `maps/.nav` file required | | mp_playerid_showhealth | 1 | 0 | 2 | Player ID display mode.
`0` don't show health
`1` show health for teammates only (default CS behaviour)
`2` show health for all players | | mp_playerid_field | 3 | 0 | 3 | Player ID field display mode.
`0` don't show additional information
`1` show team name
`2` show health percentage
`3` show both team name and health percentage | +| mp_knockback | 170 | - | - | Knockback force applied to the victim when damaged by strong weapons (e.g. `AWP`, `AK47`).
Works only if not crouching, and not hit in the legs.
Set to `0` to disable. | diff --git a/dist/game.cfg b/dist/game.cfg index 70bd646b..f566ee9b 100644 --- a/dist/game.cfg +++ b/dist/game.cfg @@ -680,3 +680,10 @@ mp_playerid_showhealth "1" // // Default value: "3" mp_playerid_field "3" + +// Knockback force applied to the victim when damaged by strong weapons (e.g. AWP, AK47). +// Works only if not crouching, and not hit in the legs. +// Set to "0" to disable. +// +// Default: "170" +mp_knockback "170" diff --git a/regamedll/dlls/API/CAPI_Impl.cpp b/regamedll/dlls/API/CAPI_Impl.cpp index aebde38a..55da8ae3 100644 --- a/regamedll/dlls/API/CAPI_Impl.cpp +++ b/regamedll/dlls/API/CAPI_Impl.cpp @@ -337,6 +337,7 @@ GAMEHOOK_REGISTRY(CBasePlayer_PlayerDeathThink); GAMEHOOK_REGISTRY(CBasePlayer_Observer_Think); GAMEHOOK_REGISTRY(CBasePlayer_RemoveAllItems); GAMEHOOK_REGISTRY(CBasePlayer_UpdateStatusBar); +GAMEHOOK_REGISTRY(CBasePlayer_TakeDamageImpulse); 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 a9c89e99..727fdf9e 100644 --- a/regamedll/dlls/API/CAPI_Impl.h +++ b/regamedll/dlls/API/CAPI_Impl.h @@ -753,6 +753,10 @@ typedef IHookChainRegistryClassImpl CReGameHookRegistry typedef IHookChainClassImpl CReGameHook_CBasePlayer_UpdateStatusBar; typedef IHookChainRegistryClassImpl CReGameHookRegistry_CBasePlayer_UpdateStatusBar; +// CBasePlayer::TakeDamageImpulse hook +typedef IHookChainClassImpl CReGameHook_CBasePlayer_TakeDamageImpulse; +typedef IHookChainRegistryClassImpl CReGameHookRegistry_CBasePlayer_TakeDamageImpulse; + class CReGameHookchains: public IReGameHookchains { public: // CBasePlayer virtual @@ -915,6 +919,7 @@ public: CReGameHookRegistry_CBasePlayer_Observer_Think m_CBasePlayer_Observer_Think; CReGameHookRegistry_CBasePlayer_RemoveAllItems m_CBasePlayer_RemoveAllItems; CReGameHookRegistry_CBasePlayer_UpdateStatusBar m_CBasePlayer_UpdateStatusBar; + CReGameHookRegistry_CBasePlayer_TakeDamageImpulse m_CBasePlayer_TakeDamageImpulse; public: virtual IReGameHookRegistry_CBasePlayer_Spawn *CBasePlayer_Spawn(); @@ -1076,6 +1081,7 @@ public: virtual IReGameHookRegistry_CBasePlayer_Observer_Think *CBasePlayer_Observer_Think(); virtual IReGameHookRegistry_CBasePlayer_RemoveAllItems *CBasePlayer_RemoveAllItems(); virtual IReGameHookRegistry_CBasePlayer_UpdateStatusBar *CBasePlayer_UpdateStatusBar(); + virtual IReGameHookRegistry_CBasePlayer_TakeDamageImpulse *CBasePlayer_TakeDamageImpulse(); }; extern CReGameHookchains g_ReGameHookchains; diff --git a/regamedll/dlls/API/CSPlayer.cpp b/regamedll/dlls/API/CSPlayer.cpp index 2252b416..cab27a47 100644 --- a/regamedll/dlls/API/CSPlayer.cpp +++ b/regamedll/dlls/API/CSPlayer.cpp @@ -539,6 +539,11 @@ EXT_FUNC bool CCSPlayer::CheckActivityInGame() return (fabs(deltaYaw) >= 0.1f && fabs(deltaPitch) >= 0.1f); } +EXT_FUNC void CCSPlayer::TakeDamageImpulse(CBasePlayer *pAttacker, float flKnockbackForce, float flVelModifier) +{ + BasePlayer()->TakeDamageImpulse(pAttacker, flKnockbackForce, flVelModifier); +} + void CCSPlayer::ResetVars() { m_szModel[0] = '\0'; diff --git a/regamedll/dlls/game.cpp b/regamedll/dlls/game.cpp index a022348e..2c6d9fbf 100644 --- a/regamedll/dlls/game.cpp +++ b/regamedll/dlls/game.cpp @@ -199,6 +199,8 @@ cvar_t randomspawn = { "mp_randomspawn", "0", FCVAR_SERVER, 0.0f, nu cvar_t playerid_showhealth = { "mp_playerid_showhealth", "1", 0, 1.0f, nullptr }; cvar_t playerid_field = { "mp_playerid_field", "3", 0, 3.0f, nullptr }; +cvar_t knockback = { "mp_knockback", "170", 0, 170.0f, nullptr }; + void GameDLL_Version_f() { if (Q_stricmp(CMD_ARGV(1), "version") != 0) @@ -485,6 +487,8 @@ void EXT_FUNC GameDLLInit() CVAR_REGISTER(&flymove_method); + CVAR_REGISTER(&knockback); + // print version CONSOLE_ECHO("ReGameDLL version: " APP_VERSION "\n"); diff --git a/regamedll/dlls/game.h b/regamedll/dlls/game.h index 95609f12..ecf1001c 100644 --- a/regamedll/dlls/game.h +++ b/regamedll/dlls/game.h @@ -216,6 +216,7 @@ extern cvar_t logkills; extern cvar_t randomspawn; extern cvar_t playerid_showhealth; extern cvar_t playerid_field; +extern cvar_t knockback; #endif diff --git a/regamedll/dlls/player.cpp b/regamedll/dlls/player.cpp index 34b48223..67aa43e4 100644 --- a/regamedll/dlls/player.cpp +++ b/regamedll/dlls/player.cpp @@ -1233,7 +1233,7 @@ BOOL EXT_FUNC CBasePlayer::__API_HOOK(TakeDamage)(entvars_t *pevInflictor, entva if (!ShouldDoLargeFlinch(m_LastHitGroup, iGunType)) { - m_flVelocityModifier = 0.5f; + TakeDamageImpulse(pAttack, 0.0f, 0.5f); if (m_LastHitGroup == HITGROUP_HEAD) m_bHighDamage = (flDamage > 60); @@ -1246,10 +1246,13 @@ BOOL EXT_FUNC CBasePlayer::__API_HOOK(TakeDamage)(entvars_t *pevInflictor, entva { if (pev->velocity.Length() < 300) { - Vector attack_velocity = (pev->origin - pAttack->pev->origin).Normalize() * 170; - pev->velocity = pev->velocity + attack_velocity; +#ifdef REGAMEDLL_ADD + float knockbackValue = knockback.value; +#else + float knockbackValue = 170; +#endif - m_flVelocityModifier = 0.65f; + TakeDamageImpulse(pAttack, knockbackValue, 0.65f); } SetAnimation(PLAYER_LARGE_FLINCH); @@ -10867,6 +10870,17 @@ bool CBasePlayer::Kill() return true; } +LINK_HOOK_CLASS_VOID_CHAIN(CBasePlayer, TakeDamageImpulse, (CBasePlayer *pAttacker, float flKnockbackForce, float flVelModifier), pAttacker, flKnockbackForce, flVelModifier) + +void EXT_FUNC CBasePlayer::__API_HOOK(TakeDamageImpulse)(CBasePlayer *pAttacker, float flKnockbackForce, float flVelModifier) +{ + if (flKnockbackForce != 0.0f) + pev->velocity += (pev->origin - pAttacker->pev->origin).Normalize() * flKnockbackForce; + + if (flVelModifier != 0.0f) + m_flVelocityModifier = flVelModifier; +} + const usercmd_t *CBasePlayer::GetLastUserCommand() const { #ifdef REGAMEDLL_API diff --git a/regamedll/dlls/player.h b/regamedll/dlls/player.h index 78293ed9..f3ec649c 100644 --- a/regamedll/dlls/player.h +++ b/regamedll/dlls/player.h @@ -451,6 +451,7 @@ public: void Observer_Think_OrigFunc(); void RemoveAllItems_OrigFunc(BOOL removeSuit); void UpdateStatusBar_OrigFunc(); + void TakeDamageImpulse_OrigFunc(CBasePlayer *pAttacker, float flKnockbackForce, float flVelModifier); CCSPlayer *CSPlayer() const; #endif // REGAMEDLL_API @@ -659,6 +660,7 @@ public: void UseEmpty(); void DropIdlePlayer(const char *reason); bool Kill(); + void TakeDamageImpulse(CBasePlayer *pAttacker, float flKnockbackForce, float flVelModifier); // templates template diff --git a/regamedll/public/regamedll/API/CSPlayer.h b/regamedll/public/regamedll/API/CSPlayer.h index 251cd6f5..3ead37a2 100644 --- a/regamedll/public/regamedll/API/CSPlayer.h +++ b/regamedll/public/regamedll/API/CSPlayer.h @@ -118,6 +118,7 @@ public: virtual void OnSpawnEquip(bool addDefault = true, bool equipGame = true); virtual void SetScoreboardAttributes(CBasePlayer *destination = nullptr); virtual void Observer_FindNextPlayer(bool bReverse, const char *name = nullptr); + virtual void TakeDamageImpulse(CBasePlayer *pAttacker, float flKnockbackForce, float flVelModifier); bool IsPlayerDominated(int iPlayerIndex) const; void SetPlayerDominated(CBasePlayer *pPlayer, bool bDominated); diff --git a/regamedll/public/regamedll/regamedll_api.h b/regamedll/public/regamedll/regamedll_api.h index 6b9aadd7..fda245bc 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 29 +#define REGAMEDLL_API_VERSION_MINOR 30 // CBasePlayer::Spawn hook typedef IHookChainClass IReGameHook_CBasePlayer_Spawn; @@ -632,6 +632,10 @@ typedef IHookChainRegistryClass IReGameHookRegist typedef IHookChainClass IReGameHook_CBasePlayer_UpdateStatusBar; typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayer_UpdateStatusBar; +// CBasePlayer::TakeDamageImpulse hook +typedef IHookChainClass IReGameHook_CBasePlayer_TakeDamageImpulse; +typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayer_TakeDamageImpulse; + class IReGameHookchains { public: virtual ~IReGameHookchains() {} @@ -795,6 +799,7 @@ public: virtual IReGameHookRegistry_CBasePlayer_Observer_Think *CBasePlayer_Observer_Think() = 0; virtual IReGameHookRegistry_CBasePlayer_RemoveAllItems *CBasePlayer_RemoveAllItems() = 0; virtual IReGameHookRegistry_CBasePlayer_UpdateStatusBar *CBasePlayer_UpdateStatusBar() = 0; + virtual IReGameHookRegistry_CBasePlayer_TakeDamageImpulse *CBasePlayer_TakeDamageImpulse() = 0; }; struct ReGameFuncs_t { diff --git a/regamedll/version/version.h b/regamedll/version/version.h index d3e8b9db..3838a2f8 100644 --- a/regamedll/version/version.h +++ b/regamedll/version/version.h @@ -6,5 +6,5 @@ #pragma once #define VERSION_MAJOR 5 -#define VERSION_MINOR 29 +#define VERSION_MINOR 30 #define VERSION_MAINTENANCE 0