Browse Source

basic multiplayer support

Laserlicht 1 month ago
parent
commit
134017a7cd

+ 1 - 1
client/CPlayerInterface.cpp

@@ -1483,7 +1483,7 @@ void CPlayerInterface::playerBlocked(int reason, bool start)
 {
 	if(reason == PlayerBlocked::EReason::UPCOMING_BATTLE)
 	{
-		if(GAME->server().howManyPlayerInterfaces() > 1 && GAME->interface() != this && GAME->interface()->makingTurn == false)
+		if(GAME->server().howManyPlayerInterfaces() > 1 && GAME->interface() != this && GAME->interface()->makingTurn == false && !GAME->map().getMap()->battleOnly)
 		{
 			//one of our players who isn't last in order got attacked not by our another player (happens for example in hotseat mode)
 			GAME->setInterfaceInstance(this);

+ 1 - 1
client/NetPacksClient.cpp

@@ -401,7 +401,7 @@ void ApplyClientNetPackVisitor::visitPlayerEndsGame(PlayerEndsGame & pack)
 	bool localHumanWinsGame = vstd::contains(cl.playerint, pack.player) && cl.gameInfo().getPlayerState(pack.player)->human && pack.victoryLossCheckResult.victory();
 	bool lastHumanEndsGame = GAME->server().howManyPlayerInterfaces() == 1 && vstd::contains(cl.playerint, pack.player) && cl.gameInfo().getPlayerState(pack.player)->human && !settings["session"]["spectate"].Bool();
 
-	if(lastHumanEndsGame || localHumanWinsGame)
+	if(lastHumanEndsGame || localHumanWinsGame || pack.silentEnd)
 	{
 		assert(adventureInt);
 		if(adventureInt)

+ 7 - 4
server/CGameHandler.cpp

@@ -3480,10 +3480,13 @@ void CGameHandler::checkVictoryLossConditionsForPlayer(PlayerColor player)
 
 	if(gameState().getMap().battleOnly)
 	{
-		PlayerEndsGame peg;
-		peg.player = player;
-		peg.silentEnd = true;
-		sendAndApply(peg);
+		for(const auto & playerIt : gameState().players)
+		{
+			PlayerEndsGame peg;
+			peg.player = playerIt.first;
+			peg.silentEnd = true;
+			sendAndApply(peg);
+		}
 		gameServer().setState(EServerState::SHUTDOWN);
 		return;
 	}

+ 1 - 1
server/CVCMIServer.cpp

@@ -1021,7 +1021,7 @@ void CVCMIServer::multiplayerWelcomeMessage()
 		if(pi.second.isControlledByHuman())
 			humanPlayer++;
 
-	if(humanPlayer < 2) // Singleplayer
+	if(humanPlayer < 2 || mi->mapHeader->battleOnly) // Singleplayer or Battle only mode
 		return;
 
 	gh->playerMessages->broadcastSystemMessage(MetaString::createFromTextID("vcmi.broadcast.command"));

+ 2 - 1
server/battles/BattleResultProcessor.cpp

@@ -26,6 +26,7 @@
 #include "../../lib/entities/artifact/CArtifact.h"
 #include "../../lib/entities/artifact/CArtifactFittingSet.h"
 #include "../../lib/gameState/CGameState.h"
+#include "../../lib/mapping/CMap.h"
 #include "../../lib/mapObjects/CGTownInstance.h"
 #include "../../lib/networkPacks/PacksForClientBattle.h"
 #include "../../lib/spells/CSpellHandler.h"
@@ -275,7 +276,7 @@ void BattleResultProcessor::endBattle(const CBattleInfoCallback & battle)
 	bool isDefenderHuman = defenderPlayer && defenderPlayer->isHuman();
 	bool onlyOnePlayerHuman = isAttackerHuman != isDefenderHuman;
 	// in battles against neutrals attacker can ask to replay battle manually, additionally in battles against AI player human side can also ask for replay
-	if(onlyOnePlayerHuman)
+	if(onlyOnePlayerHuman || gameHandler->gameState().getMap().battleOnly)
 	{
 		auto battleDialogQuery = std::make_shared<CBattleDialogQuery>(gameHandler, battle.getBattle(), battleQuery->result);
 		battleResult->queryID = battleDialogQuery->queryID;