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>
This commit is contained in:
jeefo 2024-05-15 22:56:35 +03:00
commit dedbf8ab82
No known key found for this signature in database
GPG key ID: D696786B81B667C8
8 changed files with 91 additions and 14 deletions

View file

@ -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;
}

View file

@ -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 ();

View file

@ -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 ();
}

View file

@ -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;