mirror of
https://github.com/vcmi/vcmi.git
synced 2025-09-16 09:26:28 +02:00
- Fixed days without castle counter
- Fixed 'you have only 0 days...' message - Checks victory/loss conditions every player turn instead of every day - Fixed mantis #1463
This commit is contained in:
@@ -348,20 +348,10 @@ void CCallback::castSpell(const CGHeroInstance *hero, SpellID spellID, const int
|
||||
sendRequest(&cas);
|
||||
}
|
||||
|
||||
void CCallback::unregisterMyInterface()
|
||||
void CCallback::unregisterAllInterfaces()
|
||||
{
|
||||
ASSERT_IF_CALLED_WITH_PLAYER
|
||||
auto playerInt = cl->playerint[*player];
|
||||
|
||||
cl->playerint.erase(*player);
|
||||
cl->battleints.erase(*player);
|
||||
//TODO? should callback be disabled as well?
|
||||
|
||||
//Disabled interface will be deleted very soon, so switch LOCPLINT to next player available
|
||||
if(playerInt.get() == LOCPLINT && cl->playerint.size())
|
||||
{
|
||||
LOCPLINT = dynamic_cast<CPlayerInterface*>(cl->playerint.begin()->second.get());
|
||||
}
|
||||
cl->playerint.clear();
|
||||
cl->battleints.clear();
|
||||
}
|
||||
|
||||
void CCallback::validatePaths()
|
||||
|
@@ -119,7 +119,7 @@ public:
|
||||
void unregisterGameInterface(shared_ptr<IGameEventsReceiver> gameEvents);
|
||||
void unregisterBattleInterface(shared_ptr<IBattleEventsReceiver> battleEvents);
|
||||
|
||||
void unregisterMyInterface(); //stops delivering information about game events to that player's interface -> can be called ONLY after victory/loss
|
||||
void unregisterAllInterfaces(); //stops delivering information about game events to player interfaces -> can be called ONLY after victory/loss
|
||||
|
||||
//commands
|
||||
bool moveHero(const CGHeroInstance *h, int3 dst); //dst must be free, neighbouring tile (this function can move hero only by one tile)
|
||||
|
@@ -2107,37 +2107,40 @@ void CPlayerInterface::gameOver(PlayerColor player, const EVictoryLossCheckResul
|
||||
|
||||
if(player == playerID)
|
||||
{
|
||||
if(victoryLossCheckResult.loss())
|
||||
showInfoDialog(CGI->generaltexth->allTexts[95]);
|
||||
// else
|
||||
// showInfoDialog("Placeholder message: you won!");
|
||||
if(victoryLossCheckResult.loss()) showInfoDialog(CGI->generaltexth->allTexts[95]);
|
||||
|
||||
if(LOCPLINT == this)
|
||||
{
|
||||
GH.curInt = this; //waiting for dialogs requires this to get events
|
||||
waitForAllDialogs(); //wait till all dialogs are displayed and closed
|
||||
}
|
||||
|
||||
howManyPeople--;
|
||||
if(!howManyPeople //all human players eliminated
|
||||
&& cb->getStartInfo()->mode != StartInfo::CAMPAIGN) //campaigns are handled in proposeNextMission
|
||||
--howManyPeople;
|
||||
|
||||
if(cb->getStartInfo()->mode != StartInfo::CAMPAIGN) //campaigns are handled in proposeNextMission
|
||||
{
|
||||
if(adventureInt)
|
||||
if(howManyPeople == 0) //all human players eliminated
|
||||
{
|
||||
terminate_cond.setn(true);
|
||||
adventureInt->deactivate();
|
||||
if(GH.topInt() == adventureInt)
|
||||
GH.popInt(adventureInt);
|
||||
delete adventureInt;
|
||||
adventureInt = nullptr;
|
||||
if(adventureInt)
|
||||
{
|
||||
terminate_cond.setn(true);
|
||||
adventureInt->deactivate();
|
||||
if(GH.topInt() == adventureInt)
|
||||
GH.popInt(adventureInt);
|
||||
delete adventureInt;
|
||||
adventureInt = nullptr;
|
||||
}
|
||||
|
||||
requestReturningToMainMenu();
|
||||
}
|
||||
else if(victoryLossCheckResult.victory() && LOCPLINT == this) // end game if current human player has won
|
||||
{
|
||||
requestReturningToMainMenu();
|
||||
}
|
||||
requestReturningToMainMenu();
|
||||
}
|
||||
if(GH.curInt == this)
|
||||
GH.curInt = nullptr;
|
||||
|
||||
cb->unregisterMyInterface(); //we already won/lost, nothing else matters
|
||||
if(GH.curInt == this) GH.curInt = nullptr;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if(victoryLossCheckResult.loss() && cb->getPlayerStatus(playerID) == EPlayerStatus::INGAME) //enemy has lost
|
||||
@@ -2293,18 +2296,18 @@ void CPlayerInterface::acceptTurn()
|
||||
components.push_back(Component(Component::FLAG, playerColor.getNum(), 0, 0));
|
||||
MetaString text;
|
||||
|
||||
auto daysWithoutCastle = cb->getPlayer(playerColor)->daysWithoutCastle;
|
||||
if(daysWithoutCastle == 6)
|
||||
{
|
||||
text.addTxt(MetaString::ARRAY_TXT,129); //%s, this is your last day to capture a town or you will be banished from this land.
|
||||
text.addReplacement(MetaString::COLOR, playerColor.getNum());
|
||||
}
|
||||
else
|
||||
auto daysWithoutCastle = *cb->getPlayer(playerColor)->daysWithoutCastle;
|
||||
if (daysWithoutCastle < 6)
|
||||
{
|
||||
text.addTxt(MetaString::ARRAY_TXT,128); //%s, you only have %d days left to capture a town or you will be banished from this land.
|
||||
text.addReplacement(MetaString::COLOR, playerColor.getNum());
|
||||
text.addReplacement(7 - daysWithoutCastle);
|
||||
}
|
||||
else if(daysWithoutCastle == 6)
|
||||
{
|
||||
text.addTxt(MetaString::ARRAY_TXT,129); //%s, this is your last day to capture a town or you will be banished from this land.
|
||||
text.addReplacement(MetaString::COLOR, playerColor.getNum());
|
||||
}
|
||||
|
||||
showInfoDialogAndWait(components, text);
|
||||
}
|
||||
@@ -2434,6 +2437,7 @@ void CPlayerInterface::showShipyardDialogOrProblemPopup(const IShipyard *obj)
|
||||
void CPlayerInterface::requestReturningToMainMenu()
|
||||
{
|
||||
sendCustomEvent(RETURN_TO_MAIN_MENU);
|
||||
cb->unregisterAllInterfaces();
|
||||
}
|
||||
|
||||
void CPlayerInterface::requestStoppingClient()
|
||||
|
@@ -206,6 +206,7 @@ void CClient::endGame( bool closeConnection /*= true*/ )
|
||||
}
|
||||
|
||||
playerint.clear();
|
||||
battleints.clear();
|
||||
callbacks.clear();
|
||||
battleCallbacks.clear();
|
||||
logNetwork->infoStream() << "Deleted playerInts.";
|
||||
|
@@ -2438,8 +2438,10 @@ EVictoryLossCheckResult CGameState::checkForLoss( PlayerColor player ) const
|
||||
}
|
||||
}
|
||||
|
||||
if(!p->towns.size() && p->daysWithoutCastle >= 7)
|
||||
if(p->towns.empty() && p->daysWithoutCastle && *p->daysWithoutCastle >= 6 && currentPlayer != player)
|
||||
{
|
||||
return EVictoryLossCheckResult::LOSS_STANDARD_TOWNS_AND_TIME_OVER;
|
||||
}
|
||||
|
||||
return EVictoryLossCheckResult::NO_VICTORY_OR_LOSS;
|
||||
}
|
||||
@@ -2752,7 +2754,7 @@ void CGPath::convert( ui8 mode )
|
||||
|
||||
PlayerState::PlayerState()
|
||||
: color(-1), currentSelection(0xffffffff), enteredWinningCheatCode(0),
|
||||
enteredLosingCheatCode(0), status(EPlayerStatus::INGAME), daysWithoutCastle(0)
|
||||
enteredLosingCheatCode(0), status(EPlayerStatus::INGAME)
|
||||
{
|
||||
setNodeType(PLAYER);
|
||||
}
|
||||
|
@@ -176,7 +176,7 @@ public:
|
||||
|
||||
bool enteredWinningCheatCode, enteredLosingCheatCode; //if true, this player has entered cheat codes for loss / victory
|
||||
EPlayerStatus::EStatus status;
|
||||
ui8 daysWithoutCastle;
|
||||
boost::optional<ui8> daysWithoutCastle;
|
||||
|
||||
PlayerState();
|
||||
std::string nodeName() const override;
|
||||
|
@@ -966,15 +966,6 @@ DLL_LINKAGE void NewTurn::applyGs( CGameState *gs )
|
||||
|
||||
//TODO not really a single root hierarchy, what about bonuses placed elsewhere? [not an issue with H3 mechanics but in the future...]
|
||||
|
||||
//count days without town
|
||||
for( auto i=gs->players.begin() ; i!=gs->players.end(); i++)
|
||||
{
|
||||
if(i->second.towns.size() || gs->day == 1)
|
||||
i->second.daysWithoutCastle = 0;
|
||||
else
|
||||
i->second.daysWithoutCastle++;
|
||||
}
|
||||
|
||||
for(CGTownInstance* t : gs->map->towns)
|
||||
t->builded = 0;
|
||||
}
|
||||
@@ -1595,6 +1586,18 @@ DLL_LINKAGE void BattleSetStackProperty::applyGs(CGameState *gs)
|
||||
DLL_LINKAGE void YourTurn::applyGs( CGameState *gs )
|
||||
{
|
||||
gs->currentPlayer = player;
|
||||
|
||||
//count days without town
|
||||
auto & playerState = gs->players[player];
|
||||
if(playerState.towns.empty())
|
||||
{
|
||||
if(playerState.daysWithoutCastle) ++(*playerState.daysWithoutCastle);
|
||||
else playerState.daysWithoutCastle = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
playerState.daysWithoutCastle = boost::none;
|
||||
}
|
||||
}
|
||||
|
||||
DLL_LINKAGE void SetSelection::applyGs( CGameState *gs )
|
||||
|
@@ -1413,8 +1413,6 @@ void CGameHandler::newTurn()
|
||||
elem->newTurn();
|
||||
}
|
||||
|
||||
checkVictoryLossConditionsForAll();
|
||||
|
||||
synchronizeArtifactHandlerLists(); //new day events may have changed them. TODO better of managing that
|
||||
}
|
||||
void CGameHandler::run(bool resume)
|
||||
@@ -1493,6 +1491,8 @@ void CGameHandler::run(bool resume)
|
||||
yt.player = i->first;
|
||||
applyAndSend(&yt);
|
||||
|
||||
checkVictoryLossConditionsForAll();
|
||||
|
||||
//wait till turn is done
|
||||
boost::unique_lock<boost::mutex> lock(states.mx);
|
||||
while(states.players.at(i->first).makingTurn && !end2)
|
||||
|
Reference in New Issue
Block a user