From dedbf8ab824817f27cb8e6f0f1bebb9a9c7a7de3 Mon Sep 17 00:00:00 2001 From: jeefo Date: Wed, 15 May 2024 22:56:35 +0300 Subject: [PATCH] bot: add more support for zombie mod scenario (ref #563) added multiple items to custom.cfg, so game delay timer cvar is now configurable, the infected team is configurable as well. creature (well, just zombies) now correctly detects their "creature" status even with custom model names (assumes that bot is on an infected team = zombie) Co-Authored-By: Max <161382234+dyspose@users.noreply.github.com> --- cfg/addons/yapb/conf/custom.cfg | 22 ++++++++++++++++++++++ inc/engine.h | 3 ++- inc/manager.h | 1 + inc/yapb.h | 3 ++- src/botlib.cpp | 26 +++++++++++++++++++++++--- src/config.cpp | 4 ++++ src/engine.cpp | 28 ++++++++++++++++++++++------ src/manager.cpp | 18 +++++++++++++++--- 8 files changed, 91 insertions(+), 14 deletions(-) diff --git a/cfg/addons/yapb/conf/custom.cfg b/cfg/addons/yapb/conf/custom.cfg index 6ad83ae..89fc9ef 100644 --- a/cfg/addons/yapb/conf/custom.cfg +++ b/cfg/addons/yapb/conf/custom.cfg @@ -6,6 +6,8 @@ ; ; Custom configuration file, allow to change some hardcoded stuff in bot code. ; +; NOTE: All changes to this file takes effect only on server restart. +; ; ; Custom name for C4 model, for servers that replacing C4 model with it's own. @@ -28,3 +30,23 @@ AMXParachuteCvar = sv_parachute ; CustomCSDMSpawnPoint = view_spawn +; +; Primary cvar for detection if CSDM mod is activated in game. +; +CSDMDetectCvar = csdm_active + +; +; Primary cvar to detect if bot is running on Zombie Mod. +; +ZMDetectCvar = zp_delay + +; +; For Zombie Mod, the cvars that deals with time before any game mode starts. +; +ZMDelayCvar = zp_delay + +; +; For Zombie Mod, determines the team on which infected players are on. +; Valid values: T, CT. +; +ZMInfectedTeam = T diff --git a/inc/engine.h b/inc/engine.h index 878ef10..1398541 100644 --- a/inc/engine.h +++ b/inc/engine.h @@ -47,7 +47,8 @@ CR_DECLARE_SCOPED_ENUM (GameFlags, HasFakePings = cr::bit (10), // on that game version we can fake bots pings HasBotVoice = cr::bit (11), // on that game version we can use chatter AnniversaryHL25 = cr::bit (12), // half-life 25th anniversary engine - Xash3DLegacy = cr::bit (13) // old xash3d-branch + Xash3DLegacy = cr::bit (13), // old xash3d-branch + ZombieMod = cr::bit (14) // zombie mod is active ) // defines map type diff --git a/inc/manager.h b/inc/manager.h index 2ff470f..abcde90 100644 --- a/inc/manager.h +++ b/inc/manager.h @@ -122,6 +122,7 @@ public: void setLastWinner (int winner); void checkBotModel (edict_t *ent, char *infobuffer); void checkNeedsToBeKicked (); + void refreshCreatureStatus (); bool isTeamStacked (int team); bool kickRandom (bool decQuota = true, Team fromTeam = Team::Unassigned); diff --git a/inc/yapb.h b/inc/yapb.h index e27d9c9..c6bd94d 100644 --- a/inc/yapb.h +++ b/inc/yapb.h @@ -306,6 +306,7 @@ private: bool m_moveToC4 {}; // ct is moving to bomb bool m_needToSendWelcomeChat {}; // bot needs to greet people on server? bool m_isCreature {}; // bot is not a player, but something else ? zombie ? + bool m_isOnInfectedTeam {}; // bot is zombie (this assumes bot is a creature) bool m_defuseNotified {}; // bot is notified about bomb defusion bool m_jumpSequence {}; // next path link will be jump link bool m_checkFall {}; // check bot fall @@ -500,7 +501,7 @@ private: void selectWeaponByIndex (int index); void syncUpdatePredictedIndex (); void updatePredictedIndex (); - void refreshModelName (char *infobuffer); + void refreshCreatureStatus (char *infobuffer); void updateRightRef (); void completeTask (); diff --git a/src/botlib.cpp b/src/botlib.cpp index 54563e5..5032380 100644 --- a/src/botlib.cpp +++ b/src/botlib.cpp @@ -3244,7 +3244,7 @@ void Bot::logic () { } void Bot::spawned () { - if (game.is (GameFlags::CSDM)) { + if (game.is (GameFlags::CSDM | GameFlags::ZombieMod)) { newRound (); clearTasks (); } @@ -4089,7 +4089,27 @@ float Bot::getShiftSpeed () { return pev->maxspeed * 0.4f; } -void Bot::refreshModelName (char *infobuffer) { +void Bot::refreshCreatureStatus (char *infobuffer) { + // if bot is on infected team, assume he is a creature + if (game.is (GameFlags::ZombieMod)) { + static StringRef zmInfectedTeam (conf.fetchCustom ("ZMInfectedTeam")); + + // by default infected team is terrorists + Team infectedTeam = Team::Terrorist; + + if (zmInfectedTeam == "CT") { + infectedTeam = Team::CT; + } + + // if bot is on infected team, and zombie mode is active, assume bot is a creature/zombie + m_isOnInfectedTeam = game.getRealTeam (ent ()) == infectedTeam; + + // do not process next if already infected + if (m_isOnInfectedTeam) { + return; + } + } + if (infobuffer == nullptr) { infobuffer = engfuncs.pfnGetInfoKeyBuffer (ent ()); } @@ -4115,5 +4135,5 @@ bool Bot::isCreature () { constexpr auto modelMaskZombie = (('o' << 8) + 'z'); constexpr auto modelMaskChicken = (('h' << 8) + 'c'); - return m_modelMask == modelMaskZombie || m_modelMask == modelMaskChicken; + return m_isOnInfectedTeam || m_modelMask == modelMaskZombie || m_modelMask == modelMaskChicken; } diff --git a/src/config.cpp b/src/config.cpp index 8bc93ad..87b84b1 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -661,6 +661,10 @@ void BotConfig::loadCustomConfig () { m_custom["C4ModelName"] = "c4.mdl"; m_custom["AMXParachuteCvar"] = "sv_parachute"; m_custom["CustomCSDMSpawnPoint"] = "view_spawn"; + m_custom["CSDMDetectCvar"] = "csdm_active"; + m_custom["ZMDetectCvar"] = "zp_delay"; + m_custom["ZMDelayCvar"] = "zp_delay"; + m_custom["ZMInfectedTeam"] = "T"; }; setDefaults (); diff --git a/src/engine.cpp b/src/engine.cpp index 2f72752..ea9fb0b 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -951,7 +951,11 @@ void Game::applyGameModes () { return; } - static ConVarRef csdm_active ("csdm_active"); + static StringRef csdmActiveCvarName = conf.fetchCustom ("CSDMDetectCvar"); + static StringRef zmActiveCvarName = conf.fetchCustom ("ZMDetectCvar"); + static StringRef zmDelayCvarName = conf.fetchCustom ("ZMDelayCvar"); + + static ConVarRef csdm_active (csdmActiveCvarName); static ConVarRef csdm_version ("csdm_version"); static ConVarRef redm_active ("redm_active"); static ConVarRef mp_freeforall ("mp_freeforall"); @@ -976,12 +980,21 @@ void Game::applyGameModes () { } } - // some little support for zombie plague - static ConVarRef zp_delay ("zp_delay"); + // does zombie mod is in use + static ConVarRef zm_active (zmActiveCvarName); - // update our ignore timer if zp_elay exists - if (zp_delay.exists () && zp_delay.value () > 0.0f) { - cv_ignore_enemies_after_spawn_time.set (zp_delay.value () + 3.0f); + // do a some little support for zombie plague + if (zm_active.exists ()) { + static ConVarRef zm_delay (zmDelayCvarName); + + // update our ignore timer if zp_delay exists + if (zm_delay.exists () && zm_delay.value () > 0.0f) { + cv_ignore_enemies_after_spawn_time.set (zm_delay.value () + 3.5f); + } + m_gameFlags |= GameFlags::ZombieMod; + } + else { + m_gameFlags &= ~GameFlags::ZombieMod; } } @@ -1033,6 +1046,9 @@ void Game::slowFrame () { // kick failed bots bots.checkNeedsToBeKicked (); + // refresh bot infection (creature) status + bots.refreshCreatureStatus (); + // update next update time m_oneSecondFrame = nextUpdate + time (); } diff --git a/src/manager.cpp b/src/manager.cpp index af7a605..5d2f38f 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -814,7 +814,7 @@ void BotManager::setLastWinner (int winner) { void BotManager::checkBotModel (edict_t *ent, char *infobuffer) { for (const auto &bot : bots) { if (bot->ent () == ent) { - bot->refreshModelName (infobuffer); + bot->refreshCreatureStatus (infobuffer); break; } } @@ -829,6 +829,18 @@ void BotManager::checkNeedsToBeKicked () { } } +void BotManager::refreshCreatureStatus () { + if (!game.is (GameFlags::ZombieMod)) { + return; + } + + for (const auto &bot : bots) { + if (bot->m_isAlive) { + bot->refreshCreatureStatus (nullptr); + } + } +} + void BotManager::setWeaponMode (int selection) { // this function sets bots weapon mode @@ -1370,7 +1382,7 @@ void BotManager::handleDeath (edict_t *killer, edict_t *victim) { } } - // mark bot as "spawned", and reset it to new-round state when it dead (for csdm only) + // mark bot as "spawned", and reset it to new-round state when it dead (for csdm/zombie only) if (victimBot != nullptr) { victimBot->spawned (); } @@ -1519,7 +1531,7 @@ void Bot::newRound () { for (auto &timer : m_chatterTimes) { timer = kMaxChatterRepeatInterval; } - refreshModelName (nullptr); + refreshCreatureStatus (nullptr); m_isReloading = false; m_reloadState = Reload::None;