diff --git a/core/PlayerManager.cpp b/core/PlayerManager.cpp index 813783c7..26e5f98c 100644 --- a/core/PlayerManager.cpp +++ b/core/PlayerManager.cpp @@ -321,6 +321,18 @@ void PlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playername m_clputinserver->Execute(&res, NULL); } +void PlayerManager::OnSourceModLevelEnd() +{ + /* Disconnect all bots still in game */ + for (int i=1; i<=m_maxClients; i++) + { + if (m_Players[i].IsConnected() && m_Players[i].IsFakeClient()) + { + OnClientDisconnect(m_Players[i].GetEdict()); + } + } +} + void PlayerManager::OnClientDisconnect(edict_t *pEntity) { cell_t res; diff --git a/core/PlayerManager.h b/core/PlayerManager.h index 18240adf..912d23ad 100644 --- a/core/PlayerManager.h +++ b/core/PlayerManager.h @@ -75,6 +75,7 @@ public: public: //SMGlobalClass void OnSourceModAllInitialized(); void OnSourceModShutdown(); + void OnSourceModLevelEnd(); public: CPlayer *GetPlayerByIndex(int client) const; void RunAuthChecks(); diff --git a/core/sm_globals.h b/core/sm_globals.h index cf3efc55..b01e9be3 100644 --- a/core/sm_globals.h +++ b/core/sm_globals.h @@ -108,6 +108,13 @@ public: { } + /** + * @brief Called when the level ends. + */ + virtual void OnSourceModLevelEnd() + { + } + /** * @brief Called after plugins are loaded on mapchange. */ diff --git a/core/sourcemod.cpp b/core/sourcemod.cpp index 75f05692..d21467a5 100644 --- a/core/sourcemod.cpp +++ b/core/sourcemod.cpp @@ -256,6 +256,7 @@ void SourceModBase::StartSourceMod(bool late) g_Loaded = true; } +static bool g_LevelEndBarrier = false; bool SourceModBase::LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background) { /* If we're not loaded... */ @@ -306,6 +307,8 @@ bool SourceModBase::LevelInit(char const *pMapName, char const *pMapEntities, ch g_pOnMapEnd = g_Forwards.CreateForward("OnMapEnd", ET_Ignore, 0, NULL); } + g_LevelEndBarrier = true; + RETURN_META_VALUE(MRES_IGNORED, true); } @@ -405,6 +408,17 @@ void SourceModBase::GameFrame(bool simulating) void SourceModBase::LevelShutdown() { + if (g_LevelEndBarrier) + { + SMGlobalClass *next = SMGlobalClass::head; + while (next) + { + next->OnSourceModLevelEnd(); + next = next->m_pGlobalClassNext; + } + g_LevelEndBarrier = false; + } + if (g_pOnMapEnd && m_ExecOnMapEnd) { g_pOnMapEnd->Execute(NULL);