diff --git a/dist/game.cfg b/dist/game.cfg index 6e293e1e..7244c421 100644 --- a/dist/game.cfg +++ b/dist/game.cfg @@ -43,3 +43,9 @@ mp_hegrenade_penetration 0 // 2 - drop a everyone // Default value: "0" mp_nadedrops 0 + +// Player cannot respawn until next round +// if more than N seconds has elapsed since the beginning round +// +// Default value: "20" +mp_roundrespawn_time 20 diff --git a/regamedll/dlls/client.cpp b/regamedll/dlls/client.cpp index d481d122..34505c1c 100644 --- a/regamedll/dlls/client.cpp +++ b/regamedll/dlls/client.cpp @@ -910,7 +910,9 @@ void DropPrimary(CBasePlayer *pPlayer) } } -bool CanBuyThis(CBasePlayer *pPlayer, int iWeapon) +LINK_HOOK_CHAIN(bool, CanBuyThis, (CBasePlayer *pPlayer, int iWeapon), pPlayer, iWeapon); + +bool __API_HOOK(CanBuyThis)(CBasePlayer *pPlayer, int iWeapon) { if (pPlayer->HasShield() && iWeapon == WEAPON_ELITE) { diff --git a/regamedll/dlls/client.h b/regamedll/dlls/client.h index acfeb394..77098243 100644 --- a/regamedll/dlls/client.h +++ b/regamedll/dlls/client.h @@ -132,6 +132,7 @@ void Host_Say(edict_t *pEntity, int teamonly); void DropSecondary(CBasePlayer *pPlayer); void DropPrimary(CBasePlayer *pPlayer); bool CanBuyThis(CBasePlayer *pPlayer, int iWeapon); +bool CanBuyThis_(CBasePlayer *pPlayer, int iWeapon); void BuyPistol(CBasePlayer *pPlayer, int iSlot); void BuyShotgun(CBasePlayer *pPlayer, int iSlot); void BuySubMachineGun(CBasePlayer *pPlayer, int iSlot); diff --git a/regamedll/dlls/game.cpp b/regamedll/dlls/game.cpp index 5bc5eb03..7c6995cc 100644 --- a/regamedll/dlls/game.cpp +++ b/regamedll/dlls/game.cpp @@ -100,6 +100,7 @@ cvar_t maxmoney = { "mp_maxmoney", "16000", FCVAR_SERVER, 0.0f, nullptr }; cvar_t round_infinite = { "mp_round_infinite", "0", FCVAR_SERVER, 0.0f, nullptr }; cvar_t hegrenade_penetration = { "mp_hegrenade_penetration", "0", 0, 0.0f, nullptr }; cvar_t nadedrops = { "mp_nadedrops", "0", 0, 0.0f, nullptr }; +cvar_t roundrespawn_time = { "mp_roundrespawn_time", "20", 0, 20.0f, nullptr }; void GameDLL_Version_f() { @@ -226,6 +227,7 @@ void EXT_FUNC GameDLLInit() CVAR_REGISTER(&round_infinite); CVAR_REGISTER(&hegrenade_penetration); CVAR_REGISTER(&nadedrops); + CVAR_REGISTER(&roundrespawn_time); // print version CONSOLE_ECHO("ReGameDLL build: " __TIME__ " " __DATE__ " (" APP_VERSION_STRD ")\n"); diff --git a/regamedll/dlls/game.h b/regamedll/dlls/game.h index be8f75e7..9dcdbb44 100644 --- a/regamedll/dlls/game.h +++ b/regamedll/dlls/game.h @@ -137,6 +137,7 @@ extern cvar_t maxmoney; extern cvar_t round_infinite; extern cvar_t hegrenade_penetration; extern cvar_t nadedrops; +extern cvar_t roundrespawn_time; #endif diff --git a/regamedll/dlls/gamerules.h b/regamedll/dlls/gamerules.h index e893ecd8..0cea73cf 100644 --- a/regamedll/dlls/gamerules.h +++ b/regamedll/dlls/gamerules.h @@ -50,6 +50,7 @@ #define ITEM_RESPAWN_TIME 30 #define WEAPON_RESPAWN_TIME 20 #define AMMO_RESPAWN_TIME 20 +#define ROUND_RESPAWN_TIME 20 // longest the intermission can last, in seconds #define MAX_INTERMISSION_TIME 120 @@ -592,6 +593,15 @@ public: m_bRoundTerminating = true; } + inline float GetRoundRespawnTime() const + { +#ifdef REGAMEDLL_ADD + return roundrespawn_time.value; +#else + return ROUND_RESPAWN_TIME; +#endif + } + // allow the mode of fire on a friendly player (FFA) inline bool IsFriendlyFireAttack() const { diff --git a/regamedll/dlls/multiplay_gamerules.cpp b/regamedll/dlls/multiplay_gamerules.cpp index fa305f5e..d8f0d8bc 100644 --- a/regamedll/dlls/multiplay_gamerules.cpp +++ b/regamedll/dlls/multiplay_gamerules.cpp @@ -3546,10 +3546,10 @@ BOOL CHalfLifeMultiplay::__MAKE_VHOOK(FPlayerCanRespawn)(CBasePlayer *pPlayer) if (m_iNumTerrorist > 0 && m_iNumCT > 0) { - // If this player just connected and fadetoblack is on, then maybe - // the server admin doesn't want him peeking around. - if (gpGlobals->time > m_fRoundCount + 20.0f) + if (gpGlobals->time > m_fRoundCount + GetRoundRespawnTime()) { + // If this player just connected and fadetoblack is on, then maybe + // the server admin doesn't want him peeking around. if (fadetoblack.value != 0.0f) { UTIL_ScreenFade(pPlayer, Vector(0, 0, 0), 3, 3, 255, (FFADE_OUT | FFADE_STAYOUT)); diff --git a/regamedll/dlls/player.cpp b/regamedll/dlls/player.cpp index ad77ff58..75700a60 100644 --- a/regamedll/dlls/player.cpp +++ b/regamedll/dlls/player.cpp @@ -1343,8 +1343,10 @@ void packPlayerItem(CBasePlayer *pPlayer, CBasePlayerItem *pItem, bool packAmmo) const char *modelName = GetCSModelName(pItem->m_iId); if (modelName != NULL) { + // create a box to pack the stuff into. CWeaponBox *pWeaponBox = (CWeaponBox *)CBaseEntity::Create("weaponbox", pPlayer->pev->origin, pPlayer->pev->angles, ENT(pPlayer->pev)); + // don't let weaponbox tilt. pWeaponBox->pev->angles.x = 0; pWeaponBox->pev->angles.z = 0; @@ -1352,8 +1354,9 @@ void packPlayerItem(CBasePlayer *pPlayer, CBasePlayerItem *pItem, bool packAmmo) pWeaponBox->SetThink(&CWeaponBox::Kill); pWeaponBox->pev->nextthink = gpGlobals->time + 300.0f; - pWeaponBox->PackWeapon(pItem); + pWeaponBox->PackWeapon(pItem); // now pack all of the items in the lists + // pack the ammo if (packAmmo) { pWeaponBox->PackAmmo(MAKE_STRING(IMPL_CLASS(CBasePlayerItem, ItemInfoArray)[pItem->m_iId].pszAmmo1), pPlayer->m_rgAmmo[pItem->PrimaryAmmoIndex()]); @@ -1391,8 +1394,10 @@ void packPlayerNade(CBasePlayer *pPlayer, CBasePlayerItem *pItem, bool packAmmo) vecAngles.x = 0.0f; vecAngles.y += 45.0f; + // create a box to pack the stuff into. CWeaponBox *pWeaponBox = (CWeaponBox *)CBaseEntity::Create("weaponbox", pPlayer->pev->origin + dir, vecAngles, ENT(pPlayer->pev)); + // don't let weaponbox tilt. pWeaponBox->pev->angles.x = 0; pWeaponBox->pev->angles.z = 0; @@ -1400,8 +1405,9 @@ void packPlayerNade(CBasePlayer *pPlayer, CBasePlayerItem *pItem, bool packAmmo) pWeaponBox->SetThink(&CWeaponBox::Kill); pWeaponBox->pev->nextthink = gpGlobals->time + 300.0f; - pWeaponBox->PackWeapon(pItem); + pWeaponBox->PackWeapon(pItem); // now pack all of the items in the lists + // pack the ammo if (packAmmo) { pWeaponBox->PackAmmo(MAKE_STRING(IMPL_CLASS(CBasePlayerItem, ItemInfoArray)[pItem->m_iId].pszAmmo1), pPlayer->m_rgAmmo[pItem->PrimaryAmmoIndex()]); @@ -1411,8 +1417,12 @@ void packPlayerNade(CBasePlayer *pPlayer, CBasePlayerItem *pItem, bool packAmmo) } #endif +// PackDeadPlayerItems - call this when a player dies to +// pack up the appropriate weapons and ammo items, and to +// destroy anything that shouldn't be packed. void CBasePlayer::PackDeadPlayerItems() { + // get the game rules bool bPackGun = (g_pGameRules->DeadPlayerWeapons(this) != GR_PLR_DROP_GUN_NO); bool bPackAmmo = (g_pGameRules->DeadPlayerAmmo(this) != GR_PLR_DROP_AMMO_NO); @@ -1430,6 +1440,7 @@ void CBasePlayer::PackDeadPlayerItems() for (int n = 0; n < MAX_ITEM_TYPES; ++n) { + // there's a weapon here. Should I pack it? CBasePlayerItem *pPlayerItem = m_rgpPlayerItems[ n ]; while (pPlayerItem != NULL) @@ -1461,14 +1472,10 @@ void CBasePlayer::PackDeadPlayerItems() break; case 2: { - CBasePlayerItem *pNade = pPlayerItem; - while (pNade != nullptr) - { - CBasePlayerItem *pTemp = pNade->m_pNext; - packPlayerNade(this, pNade, true); - pNade = pTemp; - } - break; + CBasePlayerItem *pNext = pPlayerItem->m_pNext; + packPlayerNade(this, pPlayerItem, true); + pPlayerItem = pNext; + continue; } } } diff --git a/regamedll/dlls/util.cpp b/regamedll/dlls/util.cpp index adcb3e7f..c96bd90c 100644 --- a/regamedll/dlls/util.cpp +++ b/regamedll/dlls/util.cpp @@ -409,7 +409,7 @@ CBaseEntity *UTIL_FindEntityByString_Old(CBaseEntity *pStartEntity, const char * return NULL; } -CBaseEntity *UTIL_FindEntityByString(CBaseEntity *pStartEntity, const char *szKeyword, const char *szValue) +CBaseEntity *EXT_FUNC UTIL_FindEntityByString(CBaseEntity *pStartEntity, const char *szKeyword, const char *szValue) { edict_t *pentEntity; int startEntityIndex; diff --git a/regamedll/dlls/weapons.cpp b/regamedll/dlls/weapons.cpp index 6002c893..00d5f2eb 100644 --- a/regamedll/dlls/weapons.cpp +++ b/regamedll/dlls/weapons.cpp @@ -1930,9 +1930,9 @@ int CWeaponBox::GiveAmmo(int iCount, char *szName, int iMax, int *pIndex) if (iCount == 0 || iAdd > 0) { m_rgAmmo[i] += iAdd; - return i; } + return -1; } } diff --git a/regamedll/dlls/weapontype.cpp b/regamedll/dlls/weapontype.cpp index 5b8960bb..b5a286ae 100644 --- a/regamedll/dlls/weapontype.cpp +++ b/regamedll/dlls/weapontype.cpp @@ -372,7 +372,7 @@ bool IsSecondaryWeapon(int id) return false; } -WeaponInfoStruct *GetWeaponInfo(int weaponID) +WeaponInfoStruct *EXT_FUNC GetWeaponInfo(int weaponID) { for (int i = 0; weaponInfo[i].id != 0; ++i) { diff --git a/regamedll/extra/cssdk/dlls/regamedll_api.h b/regamedll/extra/cssdk/dlls/regamedll_api.h index 1f6ea12d..8e7e72a7 100644 --- a/regamedll/extra/cssdk/dlls/regamedll_api.h +++ b/regamedll/extra/cssdk/dlls/regamedll_api.h @@ -174,6 +174,10 @@ typedef IVoidHookChainRegistry IReGameHook_RoundEnd; typedef IHookChainRegistryClassEmpty IReGameHookRegistry_RoundEnd; +// CanBuyThis hook +typedef IHookChain IReGameHook_CanBuyThis; +typedef IHookChainRegistry IReGameHookRegistry_CanBuyThis; + class IReGameHookchains { public: virtual ~IReGameHookchains() {} @@ -216,6 +220,7 @@ public: virtual IReGameHookRegistry_PlayerBlind* PlayerBlind() = 0; virtual IReGameHookRegistry_RadiusFlash_TraceLine* RadiusFlash_TraceLine() = 0; virtual IReGameHookRegistry_RoundEnd* RoundEnd() = 0; + virtual IReGameHookRegistry_CanBuyThis* CanBuyThis() = 0; }; @@ -235,7 +240,8 @@ struct ReGameFuncs_t { void (*AddMultiDamage)(entvars_t *pevInflictor, CBaseEntity *pEntity, float flDamage, int bitsDamageType); void (*EndRoundMessage)(const char *sentence, int event); - + class CBaseEntity *(*UTIL_FindEntityByString)(class CBaseEntity *pStartEntity, const char *szKeyword, const char *szValue); + struct WeaponInfoStruct *(*GetWeaponInfo)(int weaponID); }; class IReGameApi { diff --git a/regamedll/extra/cssdk/dlls/regamedll_interfaces.h b/regamedll/extra/cssdk/dlls/regamedll_interfaces.h index e2d3fd08..8abddd42 100644 --- a/regamedll/extra/cssdk/dlls/regamedll_interfaces.h +++ b/regamedll/extra/cssdk/dlls/regamedll_interfaces.h @@ -301,6 +301,7 @@ public: virtual void GiveNamedItem(const char *pszName) = 0; virtual void GiveDefaultItems() = 0; virtual void GiveShield(bool bDeploy = true) = 0; + virtual void RemoveAllItems(bool bRemoveSuit) = 0; }; class IAPI_Bot: public ICSPlayer { diff --git a/regamedll/public/regamedll/regamedll_api.h b/regamedll/public/regamedll/regamedll_api.h index 1f6ea12d..8e7e72a7 100644 --- a/regamedll/public/regamedll/regamedll_api.h +++ b/regamedll/public/regamedll/regamedll_api.h @@ -174,6 +174,10 @@ typedef IVoidHookChainRegistry IReGameHook_RoundEnd; typedef IHookChainRegistryClassEmpty IReGameHookRegistry_RoundEnd; +// CanBuyThis hook +typedef IHookChain IReGameHook_CanBuyThis; +typedef IHookChainRegistry IReGameHookRegistry_CanBuyThis; + class IReGameHookchains { public: virtual ~IReGameHookchains() {} @@ -216,6 +220,7 @@ public: virtual IReGameHookRegistry_PlayerBlind* PlayerBlind() = 0; virtual IReGameHookRegistry_RadiusFlash_TraceLine* RadiusFlash_TraceLine() = 0; virtual IReGameHookRegistry_RoundEnd* RoundEnd() = 0; + virtual IReGameHookRegistry_CanBuyThis* CanBuyThis() = 0; }; @@ -235,7 +240,8 @@ struct ReGameFuncs_t { void (*AddMultiDamage)(entvars_t *pevInflictor, CBaseEntity *pEntity, float flDamage, int bitsDamageType); void (*EndRoundMessage)(const char *sentence, int event); - + class CBaseEntity *(*UTIL_FindEntityByString)(class CBaseEntity *pStartEntity, const char *szKeyword, const char *szValue); + struct WeaponInfoStruct *(*GetWeaponInfo)(int weaponID); }; class IReGameApi { diff --git a/regamedll/public/regamedll/regamedll_interfaces.h b/regamedll/public/regamedll/regamedll_interfaces.h index e2d3fd08..8abddd42 100644 --- a/regamedll/public/regamedll/regamedll_interfaces.h +++ b/regamedll/public/regamedll/regamedll_interfaces.h @@ -301,6 +301,7 @@ public: virtual void GiveNamedItem(const char *pszName) = 0; virtual void GiveDefaultItems() = 0; virtual void GiveShield(bool bDeploy = true) = 0; + virtual void RemoveAllItems(bool bRemoveSuit) = 0; }; class IAPI_Bot: public ICSPlayer { diff --git a/regamedll/regamedll/regamedll_api_impl.cpp b/regamedll/regamedll/regamedll_api_impl.cpp index 027084c7..171cb0d5 100644 --- a/regamedll/regamedll/regamedll_api_impl.cpp +++ b/regamedll/regamedll/regamedll_api_impl.cpp @@ -45,7 +45,10 @@ ReGameFuncs_t g_ReGameApiFuncs = { &ApplyMultiDamage_api, &AddMultiDamage_api, - &EndRoundMessage + &EndRoundMessage, + &UTIL_FindEntityByString, + &GetWeaponInfo, + }; IReGameHookRegistry_CBasePlayer_Spawn* CReGameHookchains::CBasePlayer_Spawn() { return &m_CBasePlayer_Spawn; } @@ -85,6 +88,7 @@ IReGameHookRegistry_GetForceCamera* CReGameHookchains::GetForceCamera() { return IReGameHookRegistry_PlayerBlind* CReGameHookchains::PlayerBlind() { return &m_PlayerBlind; } IReGameHookRegistry_RadiusFlash_TraceLine* CReGameHookchains::RadiusFlash_TraceLine() { return &m_RadiusFlash_TraceLine; } IReGameHookRegistry_RoundEnd* CReGameHookchains::RoundEnd() { return &m_RoundEnd; } +IReGameHookRegistry_CanBuyThis* CReGameHookchains::CanBuyThis() { return &m_CanBuyThis; } int CReGameApi::GetMajorVersion() { diff --git a/regamedll/regamedll/regamedll_api_impl.h b/regamedll/regamedll/regamedll_api_impl.h index 3c64bf14..b267a935 100644 --- a/regamedll/regamedll/regamedll_api_impl.h +++ b/regamedll/regamedll/regamedll_api_impl.h @@ -164,9 +164,14 @@ typedef IVoidHookChainRegistryImpl CReGameHook_RadiusFlash_TraceLine; typedef IVoidHookChainRegistryImpl CReGameHookRegistry_RadiusFlash_TraceLine; +// RoundEnd hook typedef IHookChainClassImpl CReGameHook_RoundEnd; typedef IHookChainRegistryClassEmptyImpl CReGameHookRegistry_RoundEnd; +// CanBuyThis hook +typedef IHookChainImpl CReGameHook_CanBuyThis; +typedef IHookChainRegistryImpl CReGameHookRegistry_CanBuyThis; + class CReGameHookchains: public IReGameHookchains { public: // CBasePlayer virtual @@ -207,6 +212,7 @@ public: CReGameHookRegistry_PlayerBlind m_PlayerBlind; CReGameHookRegistry_RadiusFlash_TraceLine m_RadiusFlash_TraceLine; CReGameHookRegistry_RoundEnd m_RoundEnd; + CReGameHookRegistry_CanBuyThis m_CanBuyThis; public: virtual IReGameHookRegistry_CBasePlayer_Spawn* CBasePlayer_Spawn(); @@ -246,6 +252,7 @@ public: virtual IReGameHookRegistry_PlayerBlind* PlayerBlind(); virtual IReGameHookRegistry_RadiusFlash_TraceLine* RadiusFlash_TraceLine(); virtual IReGameHookRegistry_RoundEnd* RoundEnd(); + virtual IReGameHookRegistry_CanBuyThis* CanBuyThis(); }; diff --git a/regamedll/regamedll/regamedll_interfaces_impl.h b/regamedll/regamedll/regamedll_interfaces_impl.h index 65f6c6f9..972c3cbc 100644 --- a/regamedll/regamedll/regamedll_interfaces_impl.h +++ b/regamedll/regamedll/regamedll_interfaces_impl.h @@ -317,7 +317,7 @@ public: virtual void GiveNamedItem(const char *pszName) { ((CBasePlayer *)m_pEntity)->GiveNamedItem(pszName); } virtual void GiveDefaultItems() { ((CBasePlayer *)m_pEntity)->GiveDefaultItems(); } virtual void GiveShield(bool bDeploy = true) { ((CBasePlayer *)m_pEntity)->GiveShield(bDeploy); } - + virtual void RemoveAllItems(bool bRemoveSuit) { ((CBasePlayer *)m_pEntity)->RemoveAllItems(bRemoveSuit ? TRUE : FALSE); } }; class CAPI_Bot: public CCSPlayer {