From e9e50bfca2a705b079a76b4752b6af514be283c6 Mon Sep 17 00:00:00 2001 From: Shorokhov Sergey Date: Fri, 12 Jan 2024 11:40:21 +0300 Subject: [PATCH] New ConVar: `mp_defuser_allocation` --- README.md | 1 + dist/game.cfg | 8 ++++ regamedll/dlls/game.cpp | 2 + regamedll/dlls/game.h | 1 + regamedll/dlls/gamerules.h | 9 ++++ regamedll/dlls/multiplay_gamerules.cpp | 60 ++++++++++++++++++++++++++ regamedll/dlls/player.cpp | 3 ++ 7 files changed, 84 insertions(+) diff --git a/README.md b/README.md index 3150af51a..93cd795d2 100644 --- a/README.md +++ b/README.md @@ -115,6 +115,7 @@ This means that plugins that do binary code analysis (Orpheu for example) probab | mp_assist_damage_threshold | 40 | 0 | 100 | Sets the percentage of damage needed to score an assist. | | mp_freezetime_duck | 1 | 0 | 1 | Allow players to duck during freezetime.
`0` disabled
`1` enabled | | mp_freezetime_jump | 1 | 0 | 1 | Allow players to jump during freezetime.
`0` disabled
`1` enabled | +| mp_defuser_allocation | 0 | 0 | 2 | Give defuser on player spawn.
`0` disabled
`1` Random players.
`2` All players. | ## How to install zBot for CS 1.6? diff --git a/dist/game.cfg b/dist/game.cfg index 7d0775713..91009dd00 100644 --- a/dist/game.cfg +++ b/dist/game.cfg @@ -567,3 +567,11 @@ mp_freezetime_duck "1" // // Default value: "1" mp_freezetime_jump "1" + +// Give defuser on player spawn +// 0 - No free defusers (default behavior) +// 1 - Random players +// 2 - All players +// +// Default value: "0" +mp_defuser_allocation "0" diff --git a/regamedll/dlls/game.cpp b/regamedll/dlls/game.cpp index 423250ce6..4ab375d8b 100644 --- a/regamedll/dlls/game.cpp +++ b/regamedll/dlls/game.cpp @@ -177,6 +177,7 @@ cvar_t hostages_rescued_ratio = { "mp_hostages_rescued_ratio", "1.0", 0, 1.0f, n cvar_t legacy_vehicle_block = { "mp_legacy_vehicle_block", "1", 0, 0.0f, nullptr }; cvar_t dying_time = { "mp_dying_time", "3.0", 0, 3.0f, nullptr }; +cvar_t defuser_allocation = { "mp_defuser_allocation", "0", 0, 0.0f, nullptr }; void GameDLL_Version_f() { @@ -439,6 +440,7 @@ void EXT_FUNC GameDLLInit() CVAR_REGISTER(&freezetime_duck); CVAR_REGISTER(&freezetime_jump); + CVAR_REGISTER(&defuser_allocation); // print version CONSOLE_ECHO("ReGameDLL version: " APP_VERSION "\n"); diff --git a/regamedll/dlls/game.h b/regamedll/dlls/game.h index cff031fbb..706e1c2af 100644 --- a/regamedll/dlls/game.h +++ b/regamedll/dlls/game.h @@ -200,6 +200,7 @@ extern cvar_t deathmsg_flags; extern cvar_t assist_damage_threshold; extern cvar_t freezetime_duck; extern cvar_t freezetime_jump; +extern cvar_t defuser_allocation; #endif diff --git a/regamedll/dlls/gamerules.h b/regamedll/dlls/gamerules.h index e29aaba88..e7dc35085 100644 --- a/regamedll/dlls/gamerules.h +++ b/regamedll/dlls/gamerules.h @@ -255,6 +255,13 @@ enum KillRarity KILLRARITY_REVENGE = 0x100 // Revenge by the killer }; +enum +{ + DEFUSERALLOCATION_NONE = 0, + DEFUSERALLOCATION_RANDOM = 1, + DEFUSERALLOCATION_ALL = 2, +}; + class CItem; class CGameRules @@ -738,6 +745,8 @@ class CHalfLifeMultiplay: public CGameRules int GetRarityOfKill(CBaseEntity *pKiller, CBasePlayer *pVictim, CBasePlayer *pAssister, const char *killerWeaponName, bool bFlashAssist); CBasePlayer *CheckAssistsToKill(CBaseEntity *pKiller, CBasePlayer *pVictim, bool &bFlashAssist); + void GiveDefuserToRandomPlayer(); + private: void MarkLivingPlayersOnTeamAsNotReceivingMoneyNextRound(int iTeam); diff --git a/regamedll/dlls/multiplay_gamerules.cpp b/regamedll/dlls/multiplay_gamerules.cpp index c8ce28961..229da7c18 100644 --- a/regamedll/dlls/multiplay_gamerules.cpp +++ b/regamedll/dlls/multiplay_gamerules.cpp @@ -2063,6 +2063,11 @@ void EXT_FUNC CHalfLifeMultiplay::__API_HOOK(RestartRound)() GiveC4(); } +#ifdef REGAMEDLL_ADD + if (m_bMapHasBombTarget && (int)defuser_allocation.value == DEFUSERALLOCATION_RANDOM) + GiveDefuserToRandomPlayer(); +#endif + if (TheBots) { TheBots->OnEvent(EVENT_BUY_TIME_START); @@ -3837,6 +3842,10 @@ void EXT_FUNC CHalfLifeMultiplay::__API_HOOK(PlayerSpawn)(CBasePlayer *pPlayer) #ifdef REGAMEDLL_ADD if (respawn_immunitytime.value > 0) pPlayer->SetSpawnProtection(respawn_immunitytime.value); + + // remove any defusers left over from previous random if there is just one random one + if (m_bMapHasBombTarget && (int)defuser_allocation.value == DEFUSERALLOCATION_RANDOM) + pPlayer->RemoveDefuser(); #endif } @@ -5376,3 +5385,54 @@ void EXT_FUNC CHalfLifeMultiplay::__API_HOOK(SendDeathMessage)(CBaseEntity *pKil MESSAGE_END(); } + +void CHalfLifeMultiplay::GiveDefuserToRandomPlayer() +{ + int iDefusersToGive = 2; + CUtlVector candidates; + candidates.EnsureCapacity(MAX_CLIENTS); + + // add all CT candidates to a list + for (int i = 1; i <= gpGlobals->maxClients; i++) + { + CBasePlayer *pPlayer = UTIL_PlayerByIndex(i); + if (!pPlayer || FNullEnt(pPlayer->edict())) + continue; + + if (!pPlayer->IsAlive() || pPlayer->m_iTeam != CT) + continue; + + candidates.AddToTail(pPlayer); + } + + // randomly shuffle the list; this will keep the selection random in case of ties + for (int i = 0; i < candidates.Count(); i++) { + SWAP(candidates[i], candidates[RANDOM_LONG(0, candidates.Count() - 1)]); + } + + // now sort the shuffled list into subgroups + candidates.Sort([](CBasePlayer *const *left, CBasePlayer *const *right) -> int { + // should we prioritize humans over bots? + if (cv_bot_defer_to_human.value != 0.0f) + { + if ((*left)->IsBot() && !(*right)->IsBot()) + return 1; + + if (!(*left)->IsBot() && (*right)->IsBot()) + return -1; + } + + return 0; + } + ); + + // give defusers to the first N candidates + for (int i = 0; i < iDefusersToGive && i < candidates.Count(); ++i) + { + CBasePlayer *pPlayer = candidates[i]; + assert(pPlayer && pPlayer->m_iTeam == CT && pPlayer->IsAlive()); + + pPlayer->GiveDefuser(); + ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Got_defuser"); + } +} diff --git a/regamedll/dlls/player.cpp b/regamedll/dlls/player.cpp index e2770a036..0bc4e4fc0 100644 --- a/regamedll/dlls/player.cpp +++ b/regamedll/dlls/player.cpp @@ -10314,6 +10314,9 @@ void EXT_FUNC CBasePlayer::__API_HOOK(OnSpawnEquip)(bool addDefault, bool equipG case ARMOR_VESTHELM: GiveNamedItemEx("item_assaultsuit"); break; } } + + if (NeedsDefuseKit() && (int)defuser_allocation.value == DEFUSERALLOCATION_ALL) + GiveNamedItemEx("item_thighpack"); #endif }