From 1cc538ab108505e52bc52b5b6c5788dbbff2e2c4 Mon Sep 17 00:00:00 2001 From: jeefo Date: Tue, 18 Oct 2016 20:34:02 +0300 Subject: [PATCH] Workaround for regamedll mp_auto_join_team & humans_join_team bug, that was introduced for thirdparty bots (partially fixes s1lentq/ReGameDLL_CS#62) Changed remove all menu now will not popup again after execing command. Verify that team isn't stacked before adding bot when sets bot team manually on adding the bot. --- include/core.h | 6 +++- project/yapb.vcxproj | 4 +-- source/interface.cpp | 1 - source/manager.cpp | 79 +++++++++++++++++++++++++++++++++++--------- 4 files changed, 70 insertions(+), 20 deletions(-) diff --git a/include/core.h b/include/core.h index 01075e6..745a516 100644 --- a/include/core.h +++ b/include/core.h @@ -157,7 +157,8 @@ enum BotCreationResult { BOT_RESULT_CREATED, BOT_RESULT_MAX_PLAYERS_REACHED, - BOT_RESULT_NAV_ERROR + BOT_RESULT_NAV_ERROR, + BOT_RESULT_TEAM_STACKED }; // radio messages @@ -1098,7 +1099,9 @@ public: int m_numEnemiesLeft; // number of enemies alive left on map int m_numFriendsLeft; // number of friend alive left on map + int m_retryJoin; // retry count for chosing team/class int m_startAction; // team/class selection state + bool m_notKilled; // has the player been killed or has he just respawned bool m_notStarted; // team/class not chosen yet @@ -1294,6 +1297,7 @@ public: ~BotManager (void); bool IsEcoValid (int team) { return m_economicsGood[team]; } + bool IsTeamStacked (int team); int GetLastWinner (void) const { return m_lastWinner; } void SetLastWinner (int winner) { m_lastWinner = winner; } diff --git a/project/yapb.vcxproj b/project/yapb.vcxproj index b8162b2..d3ba282 100644 --- a/project/yapb.vcxproj +++ b/project/yapb.vcxproj @@ -193,7 +193,7 @@ .\release\inf\ Level4 true - None + ProgramDatabase CompileAsCpp SingleFile true @@ -225,7 +225,7 @@ .\release\yapb.dll true user32.dll;ws2_32.dll;%(DelayLoadDLLs) - No + true false Windows false diff --git a/source/interface.cpp b/source/interface.cpp index f3c8efa..a707cd6 100644 --- a/source/interface.cpp +++ b/source/interface.cpp @@ -1548,7 +1548,6 @@ void ClientCommand (edict_t *ent) case 4: bots.RemoveAll (); - DisplayMenuToClient (ent, BOT_MENU_CONTROL); break; case 5: diff --git a/source/manager.cpp b/source/manager.cpp index 6ff1d79..1859895 100644 --- a/source/manager.cpp +++ b/source/manager.cpp @@ -24,6 +24,8 @@ ConVar yb_difficulty ("yb_difficulty", "4"); ConVar yb_latency_display ("yb_latency_display", "2"); ConVar yb_avatar_display ("yb_avatar_display", "1"); +ConVar mp_limitteams ("mp_limitteams", nullptr, VT_NOREGISTER); + BotManager::BotManager (void) { // this is a bot manager class constructor @@ -128,17 +130,24 @@ BotCreationResult BotManager::CreateBot (const String &name, int difficulty, int engine.CenterPrintf ("Waypoints have been changed. Load waypoints again..."); return BOT_RESULT_NAV_ERROR; } - - if (difficulty < 0 || difficulty > 4) - difficulty = yb_difficulty.GetInt (); + else if (team != -1 && IsTeamStacked (team - 1)) + { + engine.CenterPrintf ("Desired team is stacked. Unable to proceed with bot creation"); + return BOT_RESULT_TEAM_STACKED; + } if (difficulty < 0 || difficulty > 4) { - difficulty = Random.Int (3, 4); - yb_difficulty.SetInt (difficulty); + difficulty = yb_difficulty.GetInt (); + + if (difficulty < 0 || difficulty > 4) + { + difficulty = Random.Int (3, 4); + yb_difficulty.SetInt (difficulty); + } } - if (personality < 0 || personality > 2) + if (personality < PERSONALITY_NORMAL || personality > PERSONALITY_CAREFUL) { if (Random.Int (0, 100) < 50) personality = PERSONALITY_NORMAL; @@ -438,6 +447,10 @@ void BotManager::MaintainBotQuota (void) m_creationTab.RemoveAll (); // maximum players reached, so set quota to maximum players yb_quota.SetInt (GetBotsNum ()); } + else if (callResult == BOT_RESULT_TEAM_STACKED) + { + engine.Printf ("Could not add bot to the game: Team is stacked (to disable this check, set mp_limitteams and mp_autoteambalance to zero and restart the round)"); + } m_maintainTime = engine.Time () + 0.20f; } @@ -934,6 +947,7 @@ Bot::Bot (edict_t *bot, int difficulty, int personality, int team, int member, c m_forceRadio = false; m_startAction = GSM_IDLE; + m_retryJoin = 0; m_moneyAmount = 0; m_logotypeIndex = Random.Int (0, 9); @@ -1069,6 +1083,26 @@ int BotManager::GetHumansJoinedTeam (void) return count; } +bool BotManager::IsTeamStacked (int team) +{ + int teamLimit = mp_limitteams.GetInt (); + + if (!teamLimit) + return false; + + int teamCount[SPECTATOR] = { 0, }; + + for (int i = 0; i < engine.MaxClients (); i++) + { + const Client &client = g_clients[i]; + + if ((client.flags & CF_USED) && ((client.team == TERRORIST) || client.team == CT)) + teamCount[client.team]++; + } + return teamCount[team] + 1 > teamCount[team == CT ? TERRORIST : CT] + teamLimit; +} + + void Bot::NewRound (void) { // this function initializes a bot after creation & at the start of each round @@ -1326,6 +1360,24 @@ void Bot::StartGame (void) if (g_gameFlags & GAME_LEGACY) pev->button |= IN_ATTACK; + // check if something has assigned team to us + else if (m_team == TERRORIST || m_team == CT) + m_notStarted = false; + + // if bot was unable to join team, and no menus popups, check for stacked team + if (m_startAction == GSM_IDLE && ++m_retryJoin > 2) + { + if (bots.IsTeamStacked (m_wantedTeam - 1)) + { + m_retryJoin = 0; + + engine.Printf ("Could not add bot to the game: Team is stacked (to disable this check, set mp_limitteams and mp_autoteambalance to zero and restart the round)."); + Kick (); + + return; + } + } + // handle counter-strike stuff here... if (m_startAction == GSM_TEAM_SELECT) { @@ -1348,16 +1400,11 @@ void Bot::StartGame (void) { m_startAction = GSM_IDLE; // switch back to idle - if (g_gameFlags & GAME_CZERO) // czero has spetsnaz and militia skins - { - if (m_wantedClass < 1 || m_wantedClass > 5) - m_wantedClass = Random.Int (1, 5); // use random if invalid - } - else - { - if (m_wantedClass < 1 || m_wantedClass > 4) - m_wantedClass = Random.Int (1, 4); // use random if invalid - } + // czero has additional models + int maxChoice = (g_gameFlags & GAME_CZERO) ? 5 : 4; + + if (m_wantedClass < 1 || m_wantedClass > maxChoice) + m_wantedClass = Random.Int (1, maxChoice); // use random if invalid // select the class the bot wishes to use... engine.IssueBotCommand (GetEntity (), "menuselect %d", m_wantedClass);