mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Fix turn ending
This commit is contained in:
		| @@ -225,7 +225,8 @@ std::vector<SlotInfo> ArmyManager::getBestArmy(const IBonusBearer * armyCarrier, | ||||
|  | ||||
| 		if(weakest->count == 1)  | ||||
| 		{ | ||||
| 			assert(resultingArmy.size() > 1); | ||||
| 			if (resultingArmy.size() == 1) | ||||
| 				logAi->warn("Unexpected resulting army size!"); | ||||
|  | ||||
| 			resultingArmy.erase(weakest); | ||||
| 		} | ||||
|   | ||||
| @@ -29,7 +29,7 @@ public: | ||||
| 	using ExecHandler = Sub::ExecHandler; | ||||
|  | ||||
| 	static Sub * getRegistry(); | ||||
| 	static void defaultExecute(const EventBus * bus, PlayerColor & player); | ||||
| 	static void defaultExecute(const EventBus * bus, const PlayerColor & player); | ||||
|  | ||||
| 	virtual PlayerColor getPlayer() const = 0; | ||||
| 	virtual void setPlayer(const PlayerColor & value) = 0; | ||||
|   | ||||
| @@ -24,12 +24,11 @@ SubscriptionRegistry<PlayerGotTurn> * PlayerGotTurn::getRegistry() | ||||
| 	return Instance.get(); | ||||
| } | ||||
|  | ||||
| void PlayerGotTurn::defaultExecute(const EventBus * bus, PlayerColor & player) | ||||
| void PlayerGotTurn::defaultExecute(const EventBus * bus, const PlayerColor & player) | ||||
| { | ||||
| 	CPlayerGotTurn event; | ||||
| 	event.setPlayer(player); | ||||
| 	bus->executeEvent(event); | ||||
| 	player = event.getPlayer(); | ||||
| } | ||||
|  | ||||
| CPlayerGotTurn::CPlayerGotTurn() = default; | ||||
|   | ||||
| @@ -609,7 +609,8 @@ void CGameHandler::onPlayerTurnStarted(PlayerColor which) | ||||
|  | ||||
| void CGameHandler::onPlayerTurnEnded(PlayerColor which) | ||||
| { | ||||
|  | ||||
| 	// 7 days without castle | ||||
| 	checkVictoryLossConditionsForPlayer(which); | ||||
| } | ||||
|  | ||||
| void CGameHandler::onNewTurn() | ||||
| @@ -3550,7 +3551,7 @@ void CGameHandler::checkVictoryLossConditionsForPlayer(PlayerColor player) | ||||
| 		// If we are called before the actual game start, there might be no current player | ||||
| 		// If player making turn has lost his turn must be over as well | ||||
| 		if (playerInfo && playerInfo->status != EPlayerStatus::INGAME) | ||||
| 			turnOrder->onPlayerEndsTurn(gs->currentPlayer); | ||||
| 			turnOrder->onPlayerEndsTurn(gs->currentPlayer, PlayerTurnEndReason::GAME_END); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -40,7 +40,7 @@ void ApplyGhNetPackVisitor::visitEndTurn(EndTurn & pack) | ||||
| 	if (!gh.hasPlayerAt(pack.player, pack.c)) | ||||
| 		gh.throwAndComplain(&pack, "No such pack.player!"); | ||||
|  | ||||
| 	result = gh.turnOrder->onPlayerEndsTurn(pack.player); | ||||
| 	result = gh.turnOrder->onPlayerEndsTurn(pack.player, PlayerTurnEndReason::CLIENT_REQUEST); | ||||
| } | ||||
|  | ||||
| void ApplyGhNetPackVisitor::visitDismissHero(DismissHero & pack) | ||||
|   | ||||
| @@ -85,7 +85,7 @@ void TurnTimerHandler::onPlayerMakingTurn(PlayerState & state, int waitTime) | ||||
| 			onPlayerMakingTurn(state, waitTime); | ||||
| 		} | ||||
| 		else if(!gameHandler.queries->topQuery(state.color)) | ||||
| 			gameHandler.turnOrder->onPlayerEndsTurn(state.color); | ||||
| 			gameHandler.turnOrder->onPlayerEndsTurn(state.color, PlayerTurnEndReason::TURN_TIMEOUT); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -54,7 +54,7 @@ bool TurnOrderProcessor::canStartTurn(PlayerColor which) const | ||||
| { | ||||
| 	for (auto player : awaitingPlayers) | ||||
| 	{ | ||||
| 		if (mustActBefore(player, which)) | ||||
| 		if (player != which && mustActBefore(player, which)) | ||||
| 			return false; | ||||
| 	} | ||||
|  | ||||
| @@ -83,18 +83,19 @@ void TurnOrderProcessor::doStartNewDay() | ||||
| 		gameHandler->gameLobby()->setState(EServerState::GAMEPLAY_ENDED); | ||||
|  | ||||
| 	std::swap(actedPlayers, awaitingPlayers); | ||||
|  | ||||
| 	gameHandler->onNewTurn(); | ||||
| 	tryStartTurnsForPlayers(); | ||||
| } | ||||
|  | ||||
| void TurnOrderProcessor::doStartPlayerTurn(PlayerColor which) | ||||
| { | ||||
| 	//if player runs out of time, he shouldn't get the turn (especially AI) | ||||
| 	//pre-trigger may change anything, should check before each player | ||||
| 	//TODO: is it enough to check only one player? | ||||
| 	gameHandler->checkVictoryLossConditionsForAll(); | ||||
|  | ||||
| 	assert(gameHandler->getPlayerState(which)); | ||||
| 	assert(gameHandler->getPlayerState(which)->status == EPlayerStatus::INGAME); | ||||
|  | ||||
| 	//Note: on game load, "actingPlayer" might already contain list of players | ||||
| 	actingPlayers.insert(which); | ||||
| 	awaitingPlayers.erase(which); | ||||
| 	gameHandler->onPlayerTurnStarted(which); | ||||
|  | ||||
| 	YourTurn yt; | ||||
| @@ -102,20 +103,28 @@ void TurnOrderProcessor::doStartPlayerTurn(PlayerColor which) | ||||
| 	//Change local daysWithoutCastle counter for local interface message //TODO: needed? | ||||
| 	yt.daysWithoutCastle = gameHandler->getPlayerState(which)->daysWithoutCastle; | ||||
| 	gameHandler->sendAndApply(&yt); | ||||
|  | ||||
| 	assert(actingPlayers.size() == 1); // No simturns yet :( | ||||
| 	assert(gameHandler->getCurrentPlayer() == *actingPlayers.begin()); | ||||
| } | ||||
|  | ||||
| void TurnOrderProcessor::doEndPlayerTurn(PlayerColor which) | ||||
| void TurnOrderProcessor::doEndPlayerTurn(PlayerColor which, PlayerTurnEndReason reason) | ||||
| { | ||||
| 	assert(playerMakingTurn(which)); | ||||
|  | ||||
| 	actingPlayers.erase(which); | ||||
| 	actedPlayers.insert(which); | ||||
| 	if (reason != PlayerTurnEndReason::GAME_END) | ||||
| 		actedPlayers.insert(which); | ||||
|  | ||||
| 	if (!awaitingPlayers.empty()) | ||||
| 		tryStartTurnsForPlayers(); | ||||
|  | ||||
| 	if (actingPlayers.empty()) | ||||
| 		doStartNewDay(); | ||||
|  | ||||
| 	assert(!actingPlayers.empty()); | ||||
| 	assert(actingPlayers.size() == 1); // No simturns yet :( | ||||
| 	assert(gameHandler->getCurrentPlayer() == *actingPlayers.begin()); | ||||
| } | ||||
|  | ||||
| void TurnOrderProcessor::addPlayer(PlayerColor which) | ||||
| @@ -123,7 +132,7 @@ void TurnOrderProcessor::addPlayer(PlayerColor which) | ||||
| 	awaitingPlayers.insert(which); | ||||
| } | ||||
|  | ||||
| bool TurnOrderProcessor::onPlayerEndsTurn(PlayerColor which) | ||||
| bool TurnOrderProcessor::onPlayerEndsTurn(PlayerColor which, PlayerTurnEndReason reason) | ||||
| { | ||||
| 	if (!playerMakingTurn(which)) | ||||
| 	{ | ||||
| @@ -143,18 +152,22 @@ bool TurnOrderProcessor::onPlayerEndsTurn(PlayerColor which) | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	doEndPlayerTurn(which); | ||||
| 	if (reason != PlayerTurnEndReason::GAME_END) | ||||
| 		gameHandler->onPlayerTurnEnded(which); | ||||
|  | ||||
| 	doEndPlayerTurn(which, reason); | ||||
|  | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| void TurnOrderProcessor::onGameStarted() | ||||
| { | ||||
| 	tryStartTurnsForPlayers(); | ||||
|  | ||||
| 	// this may be game load - send notification to players that they can act | ||||
| 	auto actingPlayersCopy = actingPlayers; | ||||
| 	for (auto player : actingPlayersCopy) | ||||
| 		doStartPlayerTurn(player); | ||||
|  | ||||
| 	tryStartTurnsForPlayers(); | ||||
| } | ||||
|  | ||||
| void TurnOrderProcessor::tryStartTurnsForPlayers() | ||||
|   | ||||
| @@ -13,6 +13,13 @@ | ||||
|  | ||||
| class CGameHandler; | ||||
|  | ||||
| enum class PlayerTurnEndReason | ||||
| { | ||||
| 	CLIENT_REQUEST, // client requested end of turn (e.g. press End Turn button) | ||||
| 	TURN_TIMEOUT, // Player's turn timer has run out | ||||
| 	GAME_END // Player have won or lost the game | ||||
| }; | ||||
|  | ||||
| class TurnOrderProcessor : boost::noncopyable | ||||
| { | ||||
| 	CGameHandler * gameHandler; | ||||
| @@ -35,7 +42,7 @@ class TurnOrderProcessor : boost::noncopyable | ||||
|  | ||||
| 	void doStartNewDay(); | ||||
| 	void doStartPlayerTurn(PlayerColor which); | ||||
| 	void doEndPlayerTurn(PlayerColor which); | ||||
| 	void doEndPlayerTurn(PlayerColor which, PlayerTurnEndReason reason); | ||||
|  | ||||
| public: | ||||
| 	TurnOrderProcessor(CGameHandler * owner); | ||||
| @@ -44,7 +51,7 @@ public: | ||||
| 	void addPlayer(PlayerColor which); | ||||
|  | ||||
| 	/// NetPack call-in | ||||
| 	bool onPlayerEndsTurn(PlayerColor which); | ||||
| 	bool onPlayerEndsTurn(PlayerColor which, PlayerTurnEndReason reason); | ||||
|  | ||||
| 	/// Start game (or resume from save) and send YourTurn pack to player(s) | ||||
| 	void onGameStarted(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user