Pārlūkot izejas kodu

Make console available during other players' turn

nordsoft 3 gadi atpakaļ
vecāks
revīzija
895ec2d302

+ 2 - 0
CCallback.cpp

@@ -284,6 +284,8 @@ void CCallback::sendMessage(const std::string &mess, const CGObjectInstance * cu
 {
 	ASSERT_IF_CALLED_WITH_PLAYER
 	PlayerMessage pm(mess, currentObject? currentObject->id : ObjectInstanceID(-1));
+	if(player)
+		pm.player = *player;
 	sendRequest(&pm);
 }
 

+ 9 - 0
client/Client.cpp

@@ -404,6 +404,15 @@ void CClient::endGame()
 	logNetwork->info("Client stopped.");
 }
 
+void CClient::processDisconnectedPlayers()
+{
+	if(!gs || !disconnectedPlayers.count(gs->currentPlayer))
+		return;
+	
+	LOCPLINT->showYesNoDialog("Waiting for player. Press Ok to save & end, cancel to kick that player",
+							  [](){}, [](){});
+}
+
 void CClient::initMapHandler()
 {
 	// TODO: CMapHandler initialization can probably go somewhere else

+ 4 - 0
client/Client.h

@@ -138,6 +138,8 @@ public:
 	std::map<PlayerColor, std::shared_ptr<CBattleGameInterface>> battleints;
 
 	std::map<PlayerColor, std::vector<std::shared_ptr<IBattleEventsReceiver>>> additionalBattleInts;
+	
+	std::set<PlayerColor> disconnectedPlayers;
 
 	boost::optional<BattleAction> curbaction;
 
@@ -157,6 +159,8 @@ public:
 
 	void save(const std::string & fname);
 	void endGame();
+	
+	void processDisconnectedPlayers();
 
 	void initMapHandler();
 	void initPlayerEnvironments();

+ 2 - 0
client/NetPacksClient.cpp

@@ -811,6 +811,8 @@ void YourTurn::applyCl(CClient *cl)
 
 	callAllInterfaces(cl, &IGameEventsReceiver::playerStartsTurn, player);
 	callOnlyThatInterface(cl, player, &CGameInterface::yourTurn);
+	
+	cl->processDisconnectedPlayers();
 }
 
 void SaveGameClient::applyCl(CClient *cl)

+ 4 - 6
client/windows/CAdvmapInterface.cpp

@@ -934,6 +934,10 @@ void CAdvMapInt::activate()
 
 	screenBuf = screen;
 	GH.statusbar = statusbar;
+	
+	if(LOCPLINT)
+		LOCPLINT->cingconsole->activate();
+	
 	if(!duringAITurn)
 	{
 		activeMapPanel->activate();
@@ -945,8 +949,6 @@ void CAdvMapInt::activate()
 		}
 		minimap.activate();
 		terrain.activate();
-		if(LOCPLINT)
-			LOCPLINT->cingconsole->activate();
 
 		GH.fakeMouseMove(); //to restore the cursor
 	}
@@ -970,8 +972,6 @@ void CAdvMapInt::deactivate()
 		}
 		minimap.deactivate();
 		terrain.deactivate();
-		if(LOCPLINT)
-			LOCPLINT->cingconsole->deactivate();
 	}
 }
 
@@ -1532,8 +1532,6 @@ void CAdvMapInt::endingTurn()
 	if(settings["session"]["spectate"].Bool())
 		return;
 
-	if(LOCPLINT->cingconsole->active)
-		LOCPLINT->cingconsole->deactivate();
 	LOCPLINT->makingTurn = false;
 	LOCPLINT->cb->endTurn();
 	CCS->soundh->ambientStopAllChannels();

+ 10 - 2
server/CGameHandler.cpp

@@ -1330,12 +1330,15 @@ void CGameHandler::handleClientDisconnection(std::shared_ptr<CConnection> c)
 	for(auto & playerConnections : connections)
 	{
 		PlayerColor playerId = playerConnections.first;
-		auto & playerSettings = gs->scenarioOps->getIthPlayersSettings(playerId);
+		auto * playerSettings = gs->scenarioOps->getPlayersSettings(playerId.getNum());
+		if(!playerSettings)
+			continue;
+		
 		for(auto & playerConnection : playerConnections.second)
 		{
 			if(playerConnection == c)
 			{
-				std::string messageText = boost::str(boost::format("%s (cid %d) was disconnected") % playerSettings.name % c->connectionID);
+				std::string messageText = boost::str(boost::format("%s (cid %d) was disconnected") % playerSettings->name % c->connectionID);
 				playerMessage(playerId, messageText, ObjectInstanceID{});
 			}
 		}
@@ -3393,6 +3396,11 @@ bool CGameHandler::arrangeStacks(ObjectInstanceID id1, ObjectInstanceID id2, ui8
 	return true;
 }
 
+bool CGameHandler::hasPlayerAt(PlayerColor player, std::shared_ptr<CConnection> c) const
+{
+	return connections.at(player).count(c);
+}
+
 PlayerColor CGameHandler::getPlayerAt(std::shared_ptr<CConnection> c) const
 {
 	std::set<PlayerColor> all;

+ 1 - 0
server/CGameHandler.h

@@ -223,6 +223,7 @@ public:
 	void handleClientDisconnection(std::shared_ptr<CConnection> c);
 	void handleReceivedPack(CPackForServer * pack);
 	PlayerColor getPlayerAt(std::shared_ptr<CConnection> c) const;
+	bool hasPlayerAt(PlayerColor player, std::shared_ptr<CConnection> c) const;
 
 	void playerMessage(PlayerColor player, const std::string &message, ObjectInstanceID currObj);
 	void updateGateState();

+ 2 - 5
server/NetPacksServer.cpp

@@ -61,7 +61,7 @@ void CPackForServer::throwOnWrongOwner(CGameHandler * gh, ObjectInstanceID id)
 
 void CPackForServer::throwOnWrongPlayer(CGameHandler * gh, PlayerColor player)
 {
-	if(player != gh->getPlayerAt(c))
+	if(!gh->hasPlayerAt(player, c) && player != gh->getPlayerAt(c))
 	{
 		wrongPlayerMessage(gh, player);
 		throwNotAllowedAction();
@@ -381,11 +381,8 @@ bool CastAdvSpell::applyGh(CGameHandler * gh)
 bool PlayerMessage::applyGh(CGameHandler * gh)
 {
 	if(!player.isSpectator()) // TODO: clearly not a great way to verify permissions
-	{
 		throwOnWrongPlayer(gh, player);
-		if(gh->getPlayerAt(this->c) != player)
-			throwNotAllowedAction();
-	}
+	
 	gh->playerMessage(player, text, currObj);
 	return true;
 }