diff --git a/inc/manager.h b/inc/manager.h index d27bb0a..8d1eee5 100644 --- a/inc/manager.h +++ b/inc/manager.h @@ -82,6 +82,7 @@ private: Array m_activeGrenades; // holds currently active grenades on the map Array m_intrestingEntities; // holds currently intresting entities on the map + Deque m_saveBotNames; // bots names that persist upon changelevel Deque m_addRequests; // bot creation tab SmallArray m_filters; // task filters SmallArray m_bots; // all available bots diff --git a/inc/yapb.h b/inc/yapb.h index e4ccad1..f1a610d 100644 --- a/inc/yapb.h +++ b/inc/yapb.h @@ -1175,6 +1175,7 @@ extern ConVar cv_economics_rounds; extern ConVar cv_shoots_thru_walls; extern ConVar cv_debug; extern ConVar cv_debug_goal; +extern ConVar cv_save_bots_names; extern ConVar mp_freezetime; extern ConVar mp_roundtime; diff --git a/src/linkage.cpp b/src/linkage.cpp index 4913838..a8c698a 100644 --- a/src/linkage.cpp +++ b/src/linkage.cpp @@ -339,10 +339,6 @@ CR_EXPORT int GetEntityAPI (gamefuncs_t *table, int) { // send message on new map util.setNeedForWelcome (false); - // xash is not kicking fakeclients on changelevel - if (game.is (GameFlags::Xash3D)) { - bots.kickEveryone (true, false); - } graph.reset (); // clear all the bots @@ -509,25 +505,6 @@ CR_LINKAGE_C int GetEngineFunctions (enginefuncs_t *table, int *) { }; } - table->pfnChangeLevel = [] (char *s1, char *s2) { - // the purpose of this function is to ask the engine to shutdown the server and restart a - // new one running the map whose name is s1. It is used ONLY IN SINGLE PLAYER MODE and is - // transparent to the user, because it saves the player state and equipment and restores it - // back in the new level. The "changelevel trigger point" in the old level is linked to the - // new level's spawn point using the s2 string, which is formatted as follows: "trigger_name - // to spawnpoint_name", without spaces (for example, "tr_1atotr_2lm" would tell the engine - // the player has reached the trigger point "tr_1a" and has to spawn in the next level on the - // spawn point named "tr_2lm". - - // save collected experience on map change - graph.savePractice (); - - if (game.is (GameFlags::Metamod)) { - RETURN_META (MRES_IGNORED); - } - engfuncs.pfnChangeLevel (s1, s2); - }; - table->pfnLightStyle = [] (int style, char *val) { // ths function update lightstyle for the bots diff --git a/src/manager.cpp b/src/manager.cpp index c5aeaec..1b0780a 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -28,6 +28,7 @@ ConVar cv_difficulty_auto ("yb_difficulty_auto", "0", "Enables each bot balances ConVar cv_show_avatars ("yb_show_avatars", "1", "Enables or disabels displaying bot avatars in front of their names in scoreboard. Note, that is currently you can see only avatars of your steam friends."); ConVar cv_show_latency ("yb_show_latency", "2", "Enables latency display in scoreboard.\nAllowed values: '0', '1', '2'.\nIf '0', there is nothing displayed.\nIf '1', there is a 'BOT' is displayed.\nIf '2' fake ping is displayed.", true, 0.0f, 2.0f); +ConVar cv_save_bots_names ("yb_save_bots_names", "1", "Allows to save bot names upon changelevel, so bot names will be the same after a map change", true, 0.0f, 1.0f); ConVar cv_botskin_t ("yb_botskin_t", "0", "Specifies the bots wanted skin for Terrorist team.", true, 0.0f, 5.0f); ConVar cv_botskin_ct ("yb_botskin_ct", "0", "Specifies the bots wanted skin for CT team.", true, 0.0f, 5.0f); @@ -289,6 +290,11 @@ void BotManager::addbot (StringRef name, int difficulty, int personality, int te request.skin = skin; request.manual = manual; + // restore the bot name + if (cv_save_bots_names.bool_ () && name.empty () && !m_saveBotNames.empty ()) { + request.name = m_saveBotNames.popFront (); + } + // put to queue m_addRequests.emplaceLast (cr::move (request)); } @@ -412,6 +418,12 @@ void BotManager::maintainQuota () { kickRandom (false, Team::Unassigned); } } + else { + // clear the saved names when quota balancing ended + if (cv_save_bots_names.bool_ () && !m_saveBotNames.empty ()) { + m_saveBotNames.clear (); + } + } m_quotaMaintainTime = game.time () + 0.40f; } @@ -546,8 +558,7 @@ void BotManager::serverFill (int selection, int personality, int difficulty, int selection = 5; } char teams[6][12] = {"", {"Terrorists"}, {"CTs"}, "", "", {"Random"}, }; - - int toAdd = numToAdd == -1 ? maxClients - (getHumansCount () + getBotCount ()) : numToAdd; + auto toAdd = numToAdd == -1 ? maxClients - (getHumansCount () + getBotCount ()) : numToAdd; for (int i = 0; i <= toAdd; ++i) { addbot ("", difficulty, personality, selection, -1, true); @@ -558,7 +569,7 @@ void BotManager::serverFill (int selection, int personality, int difficulty, int void BotManager::kickEveryone (bool instant, bool zeroQuota) { // this function drops all bot clients from server (this function removes only yapb's) - if (cv_quota.bool_ () && getBotCount () > 0) { + if (cv_quota.bool_ () && hasBotsOnline ()) { ctrl.msg ("Bots are removed from server."); } @@ -566,6 +577,11 @@ void BotManager::kickEveryone (bool instant, bool zeroQuota) { decrementQuota (0); } + // if everyone is kicked, clear the saved bot names + if (cv_save_bots_names.bool_ () && !m_saveBotNames.empty ()) { + m_saveBotNames.clear (); + } + if (instant) { for (const auto &bot : m_bots) { bot->kick (); @@ -1109,6 +1125,10 @@ void BotManager::erase (Bot *bot) { if (e.get () != bot) { continue; } + + if (cv_save_bots_names.bool_ ()) { + m_saveBotNames.emplaceLast (bot->pev->netname.chars ()); + } bot->markStale (); auto index = m_bots.index (e);