diff --git a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GeneralsOnline/NGMPGame.h b/GeneralsMD/Code/GameEngine/Include/GameNetwork/GeneralsOnline/NGMPGame.h index 299ac1038f9..0d11c6a51b3 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GeneralsOnline/NGMPGame.h +++ b/GeneralsMD/Code/GameEngine/Include/GameNetwork/GeneralsOnline/NGMPGame.h @@ -132,6 +132,7 @@ class NGMPGame : public GameInfo inline Bool getHasPassword(void) const { return m_requiresPassword; } inline void setAllowObservers(Bool val) { m_allowObservers = val; } inline Bool getAllowObservers(void) const { return m_allowObservers; } + Bool canKickOnObserversDisabled(); ///< Returns true when the local is defeated and observers are disabled for GO lobbies. inline void setVersion(UnsignedInt val) { m_version = val; } inline UnsignedInt getVersion(void) const { return m_version; } diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp index 890c4fa8130..143f8a380f2 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp @@ -4137,55 +4137,6 @@ void GameLogic::update() TheLocomotorStore->UPDATE(); TheVictoryConditions->UPDATE(); -#if defined(GENERALS_ONLINE) - // When observers are disabled by host on GO, remove the non host player from game after they are defeated - bool hasAllyAlive = false; - Player* localPlayer = ThePlayerList->getLocalPlayer(); - if (localPlayer) - { - Team* myTeam = localPlayer->getDefaultTeam(); - if (myTeam) - { - for (int playerIndex = 0; playerIndex < ThePlayerList->getPlayerCount(); ++playerIndex) - { - Player* other = ThePlayerList->getNthPlayer(playerIndex); - if (!other || other == localPlayer) continue; - - if (myTeam->getRelationship(other->getDefaultTeam()) == ALLIES && !TheVictoryConditions->hasSinglePlayerBeenDefeated(other)) - hasAllyAlive = true; - } - } - } - - static int observerKickCountdown = -1; - bool shouldKickObserver = TheNGMPGame && !TheNGMPGame->getAllowObservers() && TheGameLogic->getGameMode() == GAME_INTERNET && - localPlayer && !localPlayer->isPlayerObserver() && TheVictoryConditions->hasSinglePlayerBeenDefeated(localPlayer); - - if (!shouldKickObserver) - observerKickCountdown = -1; - else - { - if (hasAllyAlive) - TheGameLogic->exitGame(); - - if (TheNGMPGame->amIHost()) - observerKickCountdown = -1; - else - { - if (observerKickCountdown < 0) - observerKickCountdown = LOGICFRAMES_PER_SECOND * 10; - - if (observerKickCountdown > 0) - observerKickCountdown--; - else - { - TheGameLogic->exitGame(); - observerKickCountdown = -1; - } - } - } -#endif - { //Handle disabled statii (and re-enable objects once frame matches) for (Object* obj = m_objList; obj; obj = obj->getNextObject()) @@ -4197,9 +4148,12 @@ void GameLogic::update() } } - - - +#if defined(GENERALS_ONLINE) + if (TheNGMPGame != nullptr && TheNGMPGame->canKickOnObserversDisabled()) + { + TheGameLogic->exitGame(); + } +#endif // increment world time if (!m_startNewGame) diff --git a/GeneralsMD/Code/GameEngine/Source/GameNetwork/GeneralsOnline/NGMPGame.cpp b/GeneralsMD/Code/GameEngine/Source/GameNetwork/GeneralsOnline/NGMPGame.cpp index a723ad65a67..388e95997c3 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameNetwork/GeneralsOnline/NGMPGame.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameNetwork/GeneralsOnline/NGMPGame.cpp @@ -582,3 +582,28 @@ void NGMPGame::StartCountdown() } } +Bool NGMPGame::canKickOnObserversDisabled() +{ + if (getAllowObservers() || TheGameLogic->getGameMode() != GAME_INTERNET || TheGameLogic->getFrame() < 2) + return FALSE; + + Player *localPlayer = ThePlayerList->getLocalPlayer(); + if (!localPlayer || localPlayer->isPlayerObserver() || !TheVictoryConditions->hasSinglePlayerBeenDefeated(localPlayer)) + return FALSE; + + if (!amIHost()) + return TRUE; + + // Host is only kicked if an alive ally exists + for (Int i = 0; i < ThePlayerList->getPlayerCount(); ++i) + { + Player *otherPlayer = ThePlayerList->getNthPlayer(i); + if (!otherPlayer || otherPlayer == localPlayer) + continue; + + if (otherPlayer->getRelationship(localPlayer->getDefaultTeam()) == ALLIES && !TheVictoryConditions->hasSinglePlayerBeenDefeated(otherPlayer)) + return TRUE; + } + + return FALSE; +}