1
0
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:
beegee1
2013-12-06 19:44:11 +00:00
parent 6427827b33
commit 2d095cf20a
8 changed files with 54 additions and 54 deletions

View File

@@ -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()

View File

@@ -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)

View File

@@ -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()

View File

@@ -206,6 +206,7 @@ void CClient::endGame( bool closeConnection /*= true*/ )
}
playerint.clear();
battleints.clear();
callbacks.clear();
battleCallbacks.clear();
logNetwork->infoStream() << "Deleted playerInts.";

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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 )

View File

@@ -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)