Browse Source

Allow one AI and human to act simultaneously

Ivan Savenko 2 years ago
parent
commit
b2f30f78fa

+ 5 - 0
server/CGameHandler.cpp

@@ -2188,6 +2188,11 @@ bool CGameHandler::hasPlayerAt(PlayerColor player, std::shared_ptr<CConnection>
 	return connections.at(player).count(c);
 }
 
+bool CGameHandler::hasBothPlayersAtSameConnection(PlayerColor left, PlayerColor right) const
+{
+	return connections.at(left) == connections.at(right);
+}
+
 bool CGameHandler::disbandCreature(ObjectInstanceID id, SlotID pos)
 {
 	const CArmedInstance * s1 = static_cast<const CArmedInstance *>(getObjInstance(id));

+ 1 - 0
server/CGameHandler.h

@@ -176,6 +176,7 @@ public:
 	void handleClientDisconnection(std::shared_ptr<CConnection> c);
 	void handleReceivedPack(CPackForServer * pack);
 	bool hasPlayerAt(PlayerColor player, std::shared_ptr<CConnection> c) const;
+	bool hasBothPlayersAtSameConnection(PlayerColor left, PlayerColor right) const;
 
 	bool queryReply( QueryID qid, const JsonNode & answer, PlayerColor player );
 	bool buildBoat( ObjectInstanceID objid, PlayerColor player );

+ 34 - 7
server/processors/TurnOrderProcessor.cpp

@@ -24,11 +24,43 @@ TurnOrderProcessor::TurnOrderProcessor(CGameHandler * owner):
 
 }
 
-bool TurnOrderProcessor::canActSimultaneously(PlayerColor active, PlayerColor waiting) const
+int TurnOrderProcessor::simturnsTurnsLimit() const
 {
+	// TODO
+	return 7;
+}
+
+bool TurnOrderProcessor::playersInContact(PlayerColor left, PlayerColor right) const
+{
+	// TODO
 	return false;
 }
 
+bool TurnOrderProcessor::canActSimultaneously(PlayerColor active, PlayerColor waiting) const
+{
+	const auto * activeInfo = gameHandler->getPlayerState(active, false);
+	const auto * waitingInfo = gameHandler->getPlayerState(waiting, false);
+
+	assert(active != waiting);
+	assert(activeInfo);
+	assert(waitingInfo);
+
+	if (gameHandler->getDate(Date::DAY) > simturnsTurnsLimit())
+		return false;
+
+	if (gameHandler->hasBothPlayersAtSameConnection(active, waiting))
+	{
+		// only one AI and one human can play simultaneoulsy from single connection
+		if (activeInfo->human == waitingInfo->human)
+			return false;
+	}
+
+	if (playersInContact(active, waiting))
+		return false;
+
+	return true;
+}
+
 bool TurnOrderProcessor::mustActBefore(PlayerColor left, PlayerColor right) const
 {
 	const auto * leftInfo = gameHandler->getPlayerState(left, false);
@@ -107,8 +139,7 @@ void TurnOrderProcessor::doStartPlayerTurn(PlayerColor which)
 	pst.queryID = turnQuery->queryID;
 	gameHandler->sendAndApply(&pst);
 
-	assert(actingPlayers.size() == 1); // No simturns yet :(
-	assert(gameHandler->isPlayerMakingTurn(*actingPlayers.begin()));
+	assert(!actingPlayers.empty());
 }
 
 void TurnOrderProcessor::doEndPlayerTurn(PlayerColor which)
@@ -130,8 +161,6 @@ void TurnOrderProcessor::doEndPlayerTurn(PlayerColor which)
 		doStartNewDay();
 
 	assert(!actingPlayers.empty());
-	assert(actingPlayers.size() == 1); // No simturns yet :(
-	assert(gameHandler->isPlayerMakingTurn(*actingPlayers.begin()));
 }
 
 void TurnOrderProcessor::addPlayer(PlayerColor which)
@@ -152,8 +181,6 @@ void TurnOrderProcessor::onPlayerEndsGame(PlayerColor which)
 		doStartNewDay();
 
 	assert(!actingPlayers.empty());
-	assert(actingPlayers.size() == 1); // No simturns yet :(
-	assert(gameHandler->isPlayerMakingTurn(*actingPlayers.begin()));
 }
 
 bool TurnOrderProcessor::onPlayerEndsTurn(PlayerColor which)

+ 6 - 0
server/processors/TurnOrderProcessor.h

@@ -21,6 +21,12 @@ class TurnOrderProcessor : boost::noncopyable
 	std::set<PlayerColor> actingPlayers;
 	std::set<PlayerColor> actedPlayers;
 
+	/// Returns date on which simturns must end unconditionally
+	int simturnsTurnsLimit() const;
+
+	/// Returns true if players are close enough to each other for their heroes to meet on this turn
+	bool playersInContact(PlayerColor left, PlayerColor right) const;
+
 	/// Returns true if waiting player can act alongside with currently acting player
 	bool canActSimultaneously(PlayerColor active, PlayerColor waiting) const;