mirror of
https://github.com/vcmi/vcmi.git
synced 2026-06-19 22:57:37 +02:00
Fix handling of "7 days without town" loss condition
This commit is contained in:
@@ -471,7 +471,6 @@ void ClientCommandManager::giveTurn(const PlayerColor &colorIdentifier)
|
||||
{
|
||||
YourTurn yt;
|
||||
yt.player = colorIdentifier;
|
||||
yt.daysWithoutCastle = CSH->client->getPlayerState(colorIdentifier)->daysWithoutCastle;
|
||||
|
||||
ApplyClientNetPackVisitor visitor(*CSH->client, *CSH->client->gameState());
|
||||
yt.visit(visitor);
|
||||
|
||||
@@ -27,6 +27,7 @@ public:
|
||||
virtual void visitPlayerBlocked(PlayerBlocked & pack) {}
|
||||
virtual void visitPlayerCheated(PlayerCheated & pack) {}
|
||||
virtual void visitYourTurn(YourTurn & pack) {}
|
||||
virtual void visitYourTurn(DaysWithoutTown & pack) {}
|
||||
virtual void visitTurnTimeUpdate(TurnTimeUpdate & pack) {}
|
||||
virtual void visitEntitiesChanged(EntitiesChanged & pack) {}
|
||||
virtual void visitSetResources(SetResources & pack) {}
|
||||
|
||||
+15
-1
@@ -167,7 +167,21 @@ struct DLL_LINKAGE YourTurn : public CPackForClient
|
||||
void applyGs(CGameState * gs) const;
|
||||
|
||||
PlayerColor player;
|
||||
std::optional<ui8> daysWithoutCastle;
|
||||
|
||||
virtual void visitTyped(ICPackVisitor & visitor) override;
|
||||
|
||||
template <typename Handler> void serialize(Handler & h, const int version)
|
||||
{
|
||||
h & player;
|
||||
}
|
||||
};
|
||||
|
||||
struct DLL_LINKAGE DaysWithoutTown : public CPackForClient
|
||||
{
|
||||
void applyGs(CGameState * gs) const;
|
||||
|
||||
PlayerColor player;
|
||||
std::optional<int32_t> daysWithoutCastle;
|
||||
|
||||
virtual void visitTyped(ICPackVisitor & visitor) override;
|
||||
|
||||
|
||||
+18
-22
@@ -108,6 +108,11 @@ void YourTurn::visitTyped(ICPackVisitor & visitor)
|
||||
visitor.visitYourTurn(*this);
|
||||
}
|
||||
|
||||
void DaysWithoutTown::visitTyped(ICPackVisitor & visitor)
|
||||
{
|
||||
visitor.visitYourTurn(*this);
|
||||
}
|
||||
|
||||
void EntitiesChanged::visitTyped(ICPackVisitor & visitor)
|
||||
{
|
||||
visitor.visitEntitiesChanged(*this);
|
||||
@@ -2025,26 +2030,6 @@ void NewTurn::applyGs(CGameState *gs)
|
||||
|
||||
if(gs->getDate(Date::DAY_OF_WEEK) == 1)
|
||||
gs->updateRumor();
|
||||
|
||||
//count days without town for all players, regardless of their turn order
|
||||
for (auto &p : gs->players)
|
||||
{
|
||||
PlayerState & playerState = p.second;
|
||||
if (playerState.status == EPlayerStatus::INGAME)
|
||||
{
|
||||
if (playerState.towns.empty())
|
||||
{
|
||||
if (playerState.daysWithoutCastle)
|
||||
++(*playerState.daysWithoutCastle);
|
||||
else
|
||||
playerState.daysWithoutCastle = std::make_optional(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
playerState.daysWithoutCastle = std::nullopt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetObjectProperty::applyGs(CGameState * gs) const
|
||||
@@ -2063,8 +2048,16 @@ void SetObjectProperty::applyGs(CGameState * gs) const
|
||||
{
|
||||
auto * t = dynamic_cast<CGTownInstance *>(obj);
|
||||
assert(t);
|
||||
if(t->tempOwner < PlayerColor::PLAYER_LIMIT)
|
||||
gs->getPlayerState(t->tempOwner)->towns -= t;
|
||||
|
||||
PlayerColor oldOwner = t->tempOwner;
|
||||
if(oldOwner.isValidPlayer())
|
||||
{
|
||||
auto * state = gs->getPlayerState(oldOwner);
|
||||
state->towns -= t;
|
||||
|
||||
if(state->towns.empty())
|
||||
*state->daysWithoutCastle = 0;
|
||||
}
|
||||
if(val < PlayerColor::PLAYER_LIMIT_I)
|
||||
{
|
||||
PlayerState * p = gs->getPlayerState(PlayerColor(val));
|
||||
@@ -2509,7 +2502,10 @@ void PlayerCheated::applyGs(CGameState * gs) const
|
||||
void YourTurn::applyGs(CGameState * gs) const
|
||||
{
|
||||
gs->currentPlayer = player;
|
||||
}
|
||||
|
||||
void DaysWithoutTown::applyGs(CGameState * gs) const
|
||||
{
|
||||
auto & playerState = gs->players[player];
|
||||
playerState.daysWithoutCastle = daysWithoutCastle;
|
||||
}
|
||||
|
||||
@@ -232,6 +232,7 @@ void registerTypesClientPacks1(Serializer &s)
|
||||
s.template registerType<CPackForClient, PlayerBlocked>();
|
||||
s.template registerType<CPackForClient, PlayerCheated>();
|
||||
s.template registerType<CPackForClient, YourTurn>();
|
||||
s.template registerType<CPackForClient, DaysWithoutTown>();
|
||||
s.template registerType<CPackForClient, TurnTimeUpdate>();
|
||||
s.template registerType<CPackForClient, SetResources>();
|
||||
s.template registerType<CPackForClient, SetPrimSkill>();
|
||||
|
||||
+22
-1
@@ -609,7 +609,28 @@ void CGameHandler::onPlayerTurnStarted(PlayerColor which)
|
||||
|
||||
void CGameHandler::onPlayerTurnEnded(PlayerColor which)
|
||||
{
|
||||
// 7 days without castle
|
||||
const auto * playerState = gs->getPlayerState(which);
|
||||
assert(playerState->status == EPlayerStatus::INGAME);
|
||||
|
||||
if (playerState->towns.empty())
|
||||
{
|
||||
DaysWithoutTown pack;
|
||||
pack.player = which;
|
||||
pack.daysWithoutCastle = playerState->daysWithoutCastle.value_or(0) + 1;
|
||||
sendAndApply(&pack);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (playerState->daysWithoutCastle.has_value())
|
||||
{
|
||||
DaysWithoutTown pack;
|
||||
pack.player = which;
|
||||
pack.daysWithoutCastle = std::nullopt;
|
||||
sendAndApply(&pack);
|
||||
}
|
||||
}
|
||||
|
||||
// check for 7 days without castle
|
||||
checkVictoryLossConditionsForPlayer(which);
|
||||
|
||||
bool newWeek = getDate(Date::DAY_OF_WEEK) == 7; // end of 7th day
|
||||
|
||||
@@ -84,7 +84,7 @@ void TurnTimerHandler::onPlayerMakingTurn(PlayerState & state, int waitTime)
|
||||
state.turnTimer.baseTimer = 0;
|
||||
onPlayerMakingTurn(state, waitTime);
|
||||
}
|
||||
else if(!gameHandler.queries->topQuery(state.color))
|
||||
else if(!gameHandler.queries->topQuery(state.color)) //wait for replies to avoid pending queries
|
||||
gameHandler.turnOrder->onPlayerEndsTurn(state.color);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,8 +100,6 @@ void TurnOrderProcessor::doStartPlayerTurn(PlayerColor which)
|
||||
|
||||
YourTurn yt;
|
||||
yt.player = 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 :(
|
||||
@@ -111,6 +109,7 @@ void TurnOrderProcessor::doStartPlayerTurn(PlayerColor which)
|
||||
void TurnOrderProcessor::doEndPlayerTurn(PlayerColor which)
|
||||
{
|
||||
assert(playerMakingTurn(which));
|
||||
assert(gameHandler->getPlayerStatus(which) == EPlayerStatus::INGAME);
|
||||
|
||||
actingPlayers.erase(which);
|
||||
actedPlayers.insert(which);
|
||||
@@ -170,7 +169,10 @@ bool TurnOrderProcessor::onPlayerEndsTurn(PlayerColor which)
|
||||
|
||||
gameHandler->onPlayerTurnEnded(which);
|
||||
|
||||
doEndPlayerTurn(which);
|
||||
// it is possible that player have lost - e.g. spent 7 days without town
|
||||
// in this case - don't call doEndPlayerTurn - turn transfer was already handled by onPlayerEndsGame
|
||||
if(gameHandler->getPlayerStatus(which) == EPlayerStatus::INGAME)
|
||||
doEndPlayerTurn(which);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -37,6 +37,10 @@ class TurnOrderProcessor : boost::noncopyable
|
||||
void doStartPlayerTurn(PlayerColor which);
|
||||
void doEndPlayerTurn(PlayerColor which);
|
||||
|
||||
bool playerAwaitsTurn(PlayerColor which) const;
|
||||
bool playerMakingTurn(PlayerColor which) const;
|
||||
bool playerAwaitsNewDay(PlayerColor which) const;
|
||||
|
||||
public:
|
||||
TurnOrderProcessor(CGameHandler * owner);
|
||||
|
||||
@@ -46,21 +50,14 @@ public:
|
||||
/// NetPack call-in
|
||||
bool onPlayerEndsTurn(PlayerColor which);
|
||||
|
||||
/// Ends player turn and removes this player from turn order
|
||||
void onPlayerEndsGame(PlayerColor which);
|
||||
|
||||
/// Start game (or resume from save) and send YourTurn pack to player(s)
|
||||
void onGameStarted();
|
||||
|
||||
/// Returns true if player turn has not started today
|
||||
bool playerAwaitsTurn(PlayerColor which) const;
|
||||
|
||||
/// Returns true if player is currently making his turn
|
||||
bool playerMakingTurn(PlayerColor which) const;
|
||||
|
||||
/// Returns true if player has finished his turn and is waiting for new day
|
||||
bool playerAwaitsNewDay(PlayerColor which) const;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
template<typename Handler>
|
||||
void serialize(Handler & h, const int version)
|
||||
{
|
||||
h & awaitingPlayers;
|
||||
h & actingPlayers;
|
||||
|
||||
Reference in New Issue
Block a user