1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Fix handling of turn order in case of player defeat

This commit is contained in:
Ivan Savenko 2023-08-24 13:36:35 +03:00
parent f451c15932
commit a19cdb57ba
5 changed files with 30 additions and 25 deletions

View File

@ -3480,6 +3480,8 @@ void CGameHandler::checkVictoryLossConditionsForPlayer(PlayerColor player)
peg.victoryLossCheckResult = victoryLossCheckResult; peg.victoryLossCheckResult = victoryLossCheckResult;
sendAndApply(&peg); sendAndApply(&peg);
turnOrder->onPlayerEndsGame(player);
if (victoryLossCheckResult.victory()) if (victoryLossCheckResult.victory())
{ {
//one player won -> all enemies lost //one player won -> all enemies lost
@ -3545,13 +3547,6 @@ void CGameHandler::checkVictoryLossConditionsForPlayer(PlayerColor player)
} }
checkVictoryLossConditions(playerColors); checkVictoryLossConditions(playerColors);
} }
auto playerInfo = getPlayerState(gs->currentPlayer, false);
// 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, PlayerTurnEndReason::GAME_END);
} }
} }

View File

@ -40,7 +40,7 @@ void ApplyGhNetPackVisitor::visitEndTurn(EndTurn & pack)
if (!gh.hasPlayerAt(pack.player, pack.c)) if (!gh.hasPlayerAt(pack.player, pack.c))
gh.throwAndComplain(&pack, "No such pack.player!"); gh.throwAndComplain(&pack, "No such pack.player!");
result = gh.turnOrder->onPlayerEndsTurn(pack.player, PlayerTurnEndReason::CLIENT_REQUEST); result = gh.turnOrder->onPlayerEndsTurn(pack.player);
} }
void ApplyGhNetPackVisitor::visitDismissHero(DismissHero & pack) void ApplyGhNetPackVisitor::visitDismissHero(DismissHero & pack)

View File

@ -85,7 +85,7 @@ void TurnTimerHandler::onPlayerMakingTurn(PlayerState & state, int waitTime)
onPlayerMakingTurn(state, waitTime); onPlayerMakingTurn(state, waitTime);
} }
else if(!gameHandler.queries->topQuery(state.color)) else if(!gameHandler.queries->topQuery(state.color))
gameHandler.turnOrder->onPlayerEndsTurn(state.color, PlayerTurnEndReason::TURN_TIMEOUT); gameHandler.turnOrder->onPlayerEndsTurn(state.color);
} }
} }

View File

@ -108,12 +108,11 @@ void TurnOrderProcessor::doStartPlayerTurn(PlayerColor which)
assert(gameHandler->getCurrentPlayer() == *actingPlayers.begin()); assert(gameHandler->getCurrentPlayer() == *actingPlayers.begin());
} }
void TurnOrderProcessor::doEndPlayerTurn(PlayerColor which, PlayerTurnEndReason reason) void TurnOrderProcessor::doEndPlayerTurn(PlayerColor which)
{ {
assert(playerMakingTurn(which)); assert(playerMakingTurn(which));
actingPlayers.erase(which); actingPlayers.erase(which);
if (reason != PlayerTurnEndReason::GAME_END)
actedPlayers.insert(which); actedPlayers.insert(which);
if (!awaitingPlayers.empty()) if (!awaitingPlayers.empty())
@ -132,7 +131,24 @@ void TurnOrderProcessor::addPlayer(PlayerColor which)
awaitingPlayers.insert(which); awaitingPlayers.insert(which);
} }
bool TurnOrderProcessor::onPlayerEndsTurn(PlayerColor which, PlayerTurnEndReason reason) void TurnOrderProcessor::onPlayerEndsGame(PlayerColor which)
{
awaitingPlayers.erase(which);
actingPlayers.erase(which);
actedPlayers.erase(which);
if (!awaitingPlayers.empty())
tryStartTurnsForPlayers();
if (actingPlayers.empty())
doStartNewDay();
assert(!actingPlayers.empty());
assert(actingPlayers.size() == 1); // No simturns yet :(
assert(gameHandler->getCurrentPlayer() == *actingPlayers.begin());
}
bool TurnOrderProcessor::onPlayerEndsTurn(PlayerColor which)
{ {
if (!playerMakingTurn(which)) if (!playerMakingTurn(which))
{ {
@ -152,10 +168,9 @@ bool TurnOrderProcessor::onPlayerEndsTurn(PlayerColor which, PlayerTurnEndReason
return false; return false;
} }
if (reason != PlayerTurnEndReason::GAME_END)
gameHandler->onPlayerTurnEnded(which); gameHandler->onPlayerTurnEnded(which);
doEndPlayerTurn(which, reason); doEndPlayerTurn(which);
return true; return true;
} }

View File

@ -13,13 +13,6 @@
class CGameHandler; 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 class TurnOrderProcessor : boost::noncopyable
{ {
CGameHandler * gameHandler; CGameHandler * gameHandler;
@ -42,7 +35,7 @@ class TurnOrderProcessor : boost::noncopyable
void doStartNewDay(); void doStartNewDay();
void doStartPlayerTurn(PlayerColor which); void doStartPlayerTurn(PlayerColor which);
void doEndPlayerTurn(PlayerColor which, PlayerTurnEndReason reason); void doEndPlayerTurn(PlayerColor which);
public: public:
TurnOrderProcessor(CGameHandler * owner); TurnOrderProcessor(CGameHandler * owner);
@ -51,7 +44,9 @@ public:
void addPlayer(PlayerColor which); void addPlayer(PlayerColor which);
/// NetPack call-in /// NetPack call-in
bool onPlayerEndsTurn(PlayerColor which, PlayerTurnEndReason reason); bool onPlayerEndsTurn(PlayerColor which);
void onPlayerEndsGame(PlayerColor which);
/// Start game (or resume from save) and send YourTurn pack to player(s) /// Start game (or resume from save) and send YourTurn pack to player(s)
void onGameStarted(); void onGameStarted();