From 05e10bae6ee425f26ae27065f776274cf47730e7 Mon Sep 17 00:00:00 2001 From: jeefo Date: Sun, 21 Jan 2024 00:59:15 +0300 Subject: [PATCH] feat: allow bots to be added into the game even if no default spawn points (ref #511) --- cfg/addons/yapb/conf/custom.cfg | 8 ++++++++ inc/engine.h | 3 +++ inc/manager.h | 7 ++++--- src/config.cpp | 1 + src/engine.cpp | 4 ++++ src/manager.cpp | 17 ++++++++++++++++- 6 files changed, 36 insertions(+), 4 deletions(-) diff --git a/cfg/addons/yapb/conf/custom.cfg b/cfg/addons/yapb/conf/custom.cfg index fbffc17..5978cb9 100644 --- a/cfg/addons/yapb/conf/custom.cfg +++ b/cfg/addons/yapb/conf/custom.cfg @@ -20,3 +20,11 @@ C4ModelName = c4.mdl ; cvar here. ; AMXParachuteCvar = sv_parachute + +; +; For CSDM mods that add custom spawn points other than info_player_start and +; In info_player_deathmatch, you can specify the class name of this spawn point. +; So bot's will be able to join the game without default spawn entities. +; +CustomCSDMSpawnPoint = view_spawn + diff --git a/inc/engine.h b/inc/engine.h index c870cdf..494989a 100644 --- a/inc/engine.h +++ b/inc/engine.h @@ -220,6 +220,9 @@ public: // search entities in sphere void searchEntities (const Vector &position, float radius, EntitySearch functor); + // check if map has entity + bool hasEntityInGame (StringRef classname); + // print the version to server console on startup void printBotVersion (); diff --git a/inc/manager.h b/inc/manager.h index 2e00f81..6e902a8 100644 --- a/inc/manager.h +++ b/inc/manager.h @@ -46,9 +46,9 @@ private: bool m_leaderChoosen[kGameTeamNum] {}; // is team leader choose thees round bool m_economicsGood[kGameTeamNum] {}; // is team able to buy anything - bool m_bombPlanted {}; - bool m_botsCanPause {}; - bool m_roundOver {}; + bool m_bombPlanted {}; // is bomb planted ? + bool m_botsCanPause {}; // bots can do a little pause ? + bool m_roundOver {}; // well, round is over> Array m_activeGrenades {}; // holds currently active grenades on the map Array m_interestingEntities {}; // holds currently interesting entities on the map @@ -124,6 +124,7 @@ public: bool isTeamStacked (int team); bool kickRandom (bool decQuota = true, Team fromTeam = Team::Unassigned); + bool hasCustomCSDMSpawnEntities (); public: const Array &getActiveGrenades () { diff --git a/src/config.cpp b/src/config.cpp index fb724af..2b0b32b 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -651,6 +651,7 @@ void BotConfig::loadCustomConfig () { m_custom["C4ModelName"] = "c4.mdl"; m_custom["AMXParachuteCvar"] = "sv_parachute"; + m_custom["CustomCSDMSpawnPoint"] = "view_spawn"; // custom initialization if (openConfig ("custom", "Custom config file not found. Loading defaults.", &file)) { diff --git a/src/engine.cpp b/src/engine.cpp index 490c6cf..0c6e7c9 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -1054,6 +1054,10 @@ void Game::searchEntities (const Vector &position, float radius, EntitySearch fu } } +bool Game::hasEntityInGame (StringRef classname) { + return !isNullEntity (engfuncs.pfnFindEntityByString (nullptr, "classname", classname.chars ())); +} + void Game::printBotVersion () { String gameVersionStr; StringArray botRuntimeFlags; diff --git a/src/manager.cpp b/src/manager.cpp index 2a4c5b7..ad47639 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -441,7 +441,12 @@ void BotManager::maintainQuota () { else { desiredBotCount = cr::min (desiredBotCount, maxClients - humanPlayersInGame); } - int maxSpawnCount = game.getSpawnCount (Team::Terrorist) + game.getSpawnCount (Team::CT) - humanPlayersInGame; + auto maxSpawnCount = game.getSpawnCount (Team::Terrorist) + game.getSpawnCount (Team::CT) - humanPlayersInGame; + + // if has some custom spawn points, max out spawn point counter + if (desiredBotCount > botsInGame && hasCustomCSDMSpawnEntities ()) { + maxSpawnCount = game.maxClients () + 1; + } // sent message only to console from here ctrl.setFromConsole (true); @@ -760,6 +765,16 @@ bool BotManager::kickRandom (bool decQuota, Team fromTeam) { return false; } +bool BotManager::hasCustomCSDMSpawnEntities () { + if (!game.is (GameFlags::CSDM | GameFlags::FreeForAll)) { + return false; + } + auto customSpawnClass = conf.fetchCustom ("CustomCSDMSpawnPoint"); + + // check for custom entity + return game.hasEntityInGame (customSpawnClass); +} + void BotManager::setLastWinner (int winner) { m_lastWinner = winner; m_roundOver = true;