From bc2c3176e46e2c32ebc0110e7df879ea7ddbfafa Mon Sep 17 00:00:00 2001 From: Shorohov Sergey Date: Sun, 18 Feb 2018 14:31:24 +0300 Subject: [PATCH] Spawn protection API and cvar (mp_respawn_immunitytime). (#266) --- README.md | 1 + dist/game.cfg | 7 ++++++ regamedll/dlls/API/CAPI_Impl.cpp | 2 ++ regamedll/dlls/API/CAPI_Impl.h | 12 ++++++++++ regamedll/dlls/API/CSPlayer.cpp | 10 ++++++++ regamedll/dlls/game.cpp | 2 ++ regamedll/dlls/game.h | 1 + regamedll/dlls/multiplay_gamerules.cpp | 5 ++++ regamedll/dlls/player.cpp | 28 ++++++++++++++++++++++ regamedll/dlls/player.h | 6 ++++- regamedll/public/regamedll/API/CSPlayer.h | 5 +++- regamedll/public/regamedll/regamedll_api.h | 10 ++++++++ 12 files changed, 87 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 13fd5cbd..c6921c4e 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ Archive's bin directory contains 2 subdirectories, 'bugfixed' and 'pure' | bot_quota_mode | normal | - | - | Determines the type of quota.
`normal` default behaviour
`fill` the server will adjust bots to keep `N` players in the game, where `N` is bot_quota | | mp_item_staytime | 300 | - | - | Time to remove item that have been dropped from the players. | | mp_legacy_bombtarget_touch | 1 | 0 | 1 | Legacy func_bomb_target touch. New one is more strict.
`0` New behavior
`1` Legacy behavior| +| mp_respawn_immunitytime | 0 | 0 | - | Specifies the players defense time after respawn. (in seconds).
`0` disabled
`>0.00001` time delay to remove protection | ## How to install zBot for CS 1.6? * Extract all the files from an [archive](regamedll/extra/zBot/bot_profiles.zip?raw=true) diff --git a/dist/game.cfg b/dist/game.cfg index 769adb43..be842906 100644 --- a/dist/game.cfg +++ b/dist/game.cfg @@ -186,3 +186,10 @@ mp_item_staytime 300 // // Default value: "1" mp_legacy_bombtarget_touch "1" + +// Specifies the players defense time after respawn. (in seconds). +// 0 - disabled +// >0.00001 - time delay to remove protection +// +// Default value: "0" +mp_respawn_immunitytime "0" diff --git a/regamedll/dlls/API/CAPI_Impl.cpp b/regamedll/dlls/API/CAPI_Impl.cpp index e5e260cb..dd13c263 100644 --- a/regamedll/dlls/API/CAPI_Impl.cpp +++ b/regamedll/dlls/API/CAPI_Impl.cpp @@ -157,6 +157,8 @@ GAMEHOOK_REGISTRY(ThrowHeGrenade); GAMEHOOK_REGISTRY(ThrowFlashbang); GAMEHOOK_REGISTRY(ThrowSmokeGrenade); GAMEHOOK_REGISTRY(PlantBomb); +GAMEHOOK_REGISTRY(CBasePlayer_SetSpawnProtection); +GAMEHOOK_REGISTRY(CBasePlayer_RemoveSpawnProtection); 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 84f61195..6f958171 100644 --- a/regamedll/dlls/API/CAPI_Impl.h +++ b/regamedll/dlls/API/CAPI_Impl.h @@ -521,6 +521,14 @@ typedef IHookChainRegistryImpl CReGameHook_PlantBomb; typedef IHookChainRegistryImpl CReGameHookRegistry_PlantBomb; +// CBasePlayer::SetSpawnProtection hook +typedef IHookChainClassImpl CReGameHook_CBasePlayer_SetSpawnProtection; +typedef IHookChainRegistryClassImpl CReGameHookRegistry_CBasePlayer_SetSpawnProtection; + +// CBasePlayer::RemoveSpawnProtection hook +typedef IHookChainImpl CReGameHook_CBasePlayer_RemoveSpawnProtection; +typedef IHookChainRegistryClassImpl CReGameHookRegistry_CBasePlayer_RemoveSpawnProtection; + class CReGameHookchains: public IReGameHookchains { public: // CBasePlayer virtual @@ -625,6 +633,8 @@ public: CReGameHookRegistry_ThrowFlashbang m_ThrowFlashbang; CReGameHookRegistry_ThrowSmokeGrenade m_ThrowSmokeGrenade; CReGameHookRegistry_PlantBomb m_PlantBomb; + CReGameHookRegistry_CBasePlayer_SetSpawnProtection m_CBasePlayer_SetSpawnProtection; + CReGameHookRegistry_CBasePlayer_RemoveSpawnProtection m_CBasePlayer_RemoveSpawnProtection; public: virtual IReGameHookRegistry_CBasePlayer_Spawn *CBasePlayer_Spawn(); virtual IReGameHookRegistry_CBasePlayer_Precache *CBasePlayer_Precache(); @@ -727,6 +737,8 @@ public: virtual IReGameHookRegistry_ThrowFlashbang *ThrowFlashbang(); virtual IReGameHookRegistry_ThrowSmokeGrenade *ThrowSmokeGrenade(); virtual IReGameHookRegistry_PlantBomb *PlantBomb(); + virtual IReGameHookRegistry_CBasePlayer_SetSpawnProtection *CBasePlayer_SetSpawnProtection(); + virtual IReGameHookRegistry_CBasePlayer_RemoveSpawnProtection *CBasePlayer_RemoveSpawnProtection(); }; extern CReGameHookchains g_ReGameHookchains; diff --git a/regamedll/dlls/API/CSPlayer.cpp b/regamedll/dlls/API/CSPlayer.cpp index e3a62a72..84533b7f 100644 --- a/regamedll/dlls/API/CSPlayer.cpp +++ b/regamedll/dlls/API/CSPlayer.cpp @@ -489,3 +489,13 @@ EXT_FUNC void CCSPlayer::StartDeathCam() { BasePlayer()->StartDeathCam(); } + +EXT_FUNC void CCSPlayer::SetSpawnProtection(float flProtectionTime) +{ + BasePlayer()->SetSpawnProtection(flProtectionTime); +} + +EXT_FUNC void CCSPlayer::RemoveSpawnProtection() +{ + BasePlayer()->RemoveSpawnProtection(); +} diff --git a/regamedll/dlls/game.cpp b/regamedll/dlls/game.cpp index 0260905e..dc98895c 100644 --- a/regamedll/dlls/game.cpp +++ b/regamedll/dlls/game.cpp @@ -116,6 +116,7 @@ cvar_t show_radioicon = { "mp_show_radioicon", "1", FCVAR_SERVER, 1.0f, cvar_t old_bomb_defused_sound = { "mp_old_bomb_defused_sound", "1", FCVAR_SERVER, 1.0f, nullptr }; cvar_t item_staytime = { "mp_item_staytime", "300", FCVAR_SERVER, 300.0f, nullptr }; cvar_t legacy_bombtarget_touch = { "mp_legacy_bombtarget_touch", "1", FCVAR_SERVER, 1.0f, nullptr }; +cvar_t respawn_immunitytime = { "mp_respawn_immunitytime", "0", FCVAR_SERVER, 0.0f, nullptr }; void GameDLL_Version_f() { @@ -270,6 +271,7 @@ void EXT_FUNC GameDLLInit() CVAR_REGISTER(&old_bomb_defused_sound); CVAR_REGISTER(&item_staytime); CVAR_REGISTER(&legacy_bombtarget_touch); + CVAR_REGISTER(&respawn_immunitytime); // print version CONSOLE_ECHO("ReGameDLL version: " APP_VERSION "\n"); diff --git a/regamedll/dlls/game.h b/regamedll/dlls/game.h index f8e45aa0..1c3fd654 100644 --- a/regamedll/dlls/game.h +++ b/regamedll/dlls/game.h @@ -153,6 +153,7 @@ extern cvar_t show_radioicon; extern cvar_t old_bomb_defused_sound; extern cvar_t item_staytime; extern cvar_t legacy_bombtarget_touch; +extern cvar_t respawn_immunitytime; #endif diff --git a/regamedll/dlls/multiplay_gamerules.cpp b/regamedll/dlls/multiplay_gamerules.cpp index 9e93e121..2e5db3b1 100644 --- a/regamedll/dlls/multiplay_gamerules.cpp +++ b/regamedll/dlls/multiplay_gamerules.cpp @@ -3635,6 +3635,11 @@ void EXT_FUNC CHalfLifeMultiplay::__API_HOOK(PlayerSpawn)(CBasePlayer *pPlayer) pPlayer->pev->weapons |= (1 << WEAPON_SUIT); pPlayer->OnSpawnEquip(); pPlayer->SetPlayerModel(false); + +#ifdef REGAMEDLL_ADD + if (respawn_immunitytime.value > 0) + pPlayer->SetSpawnProtection(respawn_immunitytime.value); +#endif } LINK_HOOK_CLASS_CUSTOM_CHAIN(BOOL, CHalfLifeMultiplay, CSGameRules, FPlayerCanRespawn, (CBasePlayer *pPlayer), pPlayer) diff --git a/regamedll/dlls/player.cpp b/regamedll/dlls/player.cpp index ab3cad3a..e4325422 100644 --- a/regamedll/dlls/player.cpp +++ b/regamedll/dlls/player.cpp @@ -4376,6 +4376,13 @@ void EXT_FUNC CBasePlayer::__API_HOOK(PreThink)() } UpdateLocation(); + +#ifdef REGAMEDLL_ADD + if (CSPlayer()->m_flSpawnProtectionEndTime > 0 && gpGlobals->time > CSPlayer()->m_flSpawnProtectionEndTime) + { + RemoveSpawnProtection(); + } +#endif } // If player is taking time based damage, continue doing damage to player - @@ -9516,3 +9523,24 @@ bool CBasePlayer::__API_HOOK(CanSwitchTeam)(TeamName teamToSwap) return true; } + +LINK_HOOK_CLASS_VOID_CHAIN(CBasePlayer, SetSpawnProtection, (float flProtectionTime), flProtectionTime) + +void EXT_FUNC CBasePlayer::__API_HOOK(SetSpawnProtection)(float flProtectionTime) +{ + pev->takedamage = DAMAGE_NO; + pev->rendermode = kRenderTransAdd; + pev->renderamt = 100.0; + + CSPlayer()->m_flSpawnProtectionEndTime = gpGlobals->time + flProtectionTime; +} + +LINK_HOOK_CLASS_VOID_CHAIN2(CBasePlayer, RemoveSpawnProtection) + +void CBasePlayer::__API_HOOK(RemoveSpawnProtection)() +{ + pev->takedamage = DAMAGE_AIM; + pev->rendermode = kRenderNormal; + + CSPlayer()->m_flSpawnProtectionEndTime = 0.0f; +} diff --git a/regamedll/dlls/player.h b/regamedll/dlls/player.h index d1c02976..9a926f4d 100644 --- a/regamedll/dlls/player.h +++ b/regamedll/dlls/player.h @@ -343,7 +343,6 @@ public: virtual BOOL AddPlayerItem(CBasePlayerItem *pItem); virtual BOOL RemovePlayerItem(CBasePlayerItem *pItem); virtual int GiveAmmo(int iAmount, const char *szName, int iMax = -1); - #ifndef REGAMEDLL_API virtual void StartSneaking() { m_tSneaking = gpGlobals->time - 1; } virtual void StopSneaking() { m_tSneaking = gpGlobals->time + 30; } @@ -420,6 +419,8 @@ public: CGrenade *ThrowGrenade_OrigFunc(CBasePlayerWeapon *pWeapon, VectorRef vecSrc, VectorRef vecThrow, float time, unsigned short usEvent = 0); void SwitchTeam_OrigFunc(); bool CanSwitchTeam_OrigFunc(TeamName teamToSwap); + void SetSpawnProtection_OrigFunc(float flProtectionTime); + void RemoveSpawnProtection_OrigFunc(); CCSPlayer *CSPlayer() const; #endif // REGAMEDLL_API @@ -609,6 +610,9 @@ public: CBasePlayerItem *GetItemByName(const char *itemName); CBasePlayerItem *GetItemById(WeaponIdType weaponID); + void SetSpawnProtection(float flProtectionTime); + void RemoveSpawnProtection(); + // templates template T *ForEachItem(int slot, const Functor &func) const diff --git a/regamedll/public/regamedll/API/CSPlayer.h b/regamedll/public/regamedll/API/CSPlayer.h index 5fbc2963..fc31c512 100644 --- a/regamedll/public/regamedll/API/CSPlayer.h +++ b/regamedll/public/regamedll/API/CSPlayer.h @@ -33,7 +33,7 @@ class CCSPlayer: public CCSMonster { public: - CCSPlayer() : m_bForceShowMenu(false), m_flRespawnPending(0) + CCSPlayer() : m_bForceShowMenu(false), m_flRespawnPending(0), m_flSpawnProtectionEndTime(0) { m_szModel[0] = '\0'; } @@ -80,6 +80,8 @@ public: virtual void ResetSequenceInfo(); virtual void StartDeathCam(); virtual bool RemovePlayerItemEx(const char* pszItemName, bool bRemoveAmmo); + virtual void SetSpawnProtection(float flProtectionTime); + virtual void RemoveSpawnProtection(); CBasePlayer *BasePlayer() const; @@ -87,6 +89,7 @@ public: char m_szModel[32]; bool m_bForceShowMenu; float m_flRespawnPending; + float m_flSpawnProtectionEndTime; }; // Inlines diff --git a/regamedll/public/regamedll/regamedll_api.h b/regamedll/public/regamedll/regamedll_api.h index 34e47699..fcab3161 100644 --- a/regamedll/public/regamedll/regamedll_api.h +++ b/regamedll/public/regamedll/regamedll_api.h @@ -424,6 +424,14 @@ typedef IHookChainRegistry IReGameHook_PlantBomb; typedef IHookChainRegistry IReGameHookRegistry_PlantBomb; +// CBasePlayer::SetSpawnProtection hook +typedef IHookChainClass IReGameHook_CBasePlayer_SetSpawnProtection; +typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayer_SetSpawnProtection; + +// CBasePlayer::RemoveSpawnProtection hook +typedef IHookChainClass IReGameHook_CBasePlayer_RemoveSpawnProtection; +typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayer_RemoveSpawnProtection; + class IReGameHookchains { public: virtual ~IReGameHookchains() {} @@ -529,6 +537,8 @@ public: virtual IReGameHookRegistry_ThrowFlashbang *ThrowFlashbang() = 0; virtual IReGameHookRegistry_ThrowSmokeGrenade *ThrowSmokeGrenade() = 0; virtual IReGameHookRegistry_PlantBomb *PlantBomb() = 0; + virtual IReGameHookRegistry_CBasePlayer_RemoveSpawnProtection *CBasePlayer_RemoveSpawnProtection() = 0; + virtual IReGameHookRegistry_CBasePlayer_SetSpawnProtection *CBasePlayer_SetSpawnProtection() = 0; }; struct ReGameFuncs_t {