From e843af24bf4524b971825d7691b1b07276ab941b Mon Sep 17 00:00:00 2001 From: Dydzio Date: Wed, 11 Sep 2024 23:00:06 +0200 Subject: [PATCH 1/4] Fix broken popping of top interfaces when town was opened during multiplayer game --- client/CPlayerInterface.cpp | 13 +++---------- client/gui/CIntObject.cpp | 2 +- client/gui/CIntObject.h | 1 - 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index 9a690d502..e88caf65d 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -172,10 +172,11 @@ void CPlayerInterface::initGameInterface(std::shared_ptr ENV, std:: void CPlayerInterface::closeAllDialogs() { // remove all active dialogs that do not expect query answer - for (;;) + while(true) { auto adventureWindow = GH.windows().topWindow(); auto infoWindow = GH.windows().topWindow(); + auto topWindow = GH.windows().topWindow(); if(adventureWindow != nullptr) break; @@ -183,16 +184,8 @@ void CPlayerInterface::closeAllDialogs() if(infoWindow && infoWindow->ID != QueryID::NONE) break; - if (infoWindow) - infoWindow->close(); - else - GH.windows().popWindows(1); + topWindow->close(); } - - if(castleInt) - castleInt->close(); - - castleInt = nullptr; } void CPlayerInterface::playerEndsTurn(PlayerColor player) diff --git a/client/gui/CIntObject.cpp b/client/gui/CIntObject.cpp index 3f136151e..e2fa75409 100644 --- a/client/gui/CIntObject.cpp +++ b/client/gui/CIntObject.cpp @@ -341,6 +341,6 @@ WindowBase::WindowBase(int used_, Point pos_) void WindowBase::close() { if(!GH.windows().isTopWindow(this)) - logGlobal->error("Only top interface must be closed"); + throw std::runtime_error("Only top interface can be closed"); GH.windows().popWindows(1); } diff --git a/client/gui/CIntObject.h b/client/gui/CIntObject.h index bde3c1f81..336297227 100644 --- a/client/gui/CIntObject.h +++ b/client/gui/CIntObject.h @@ -146,7 +146,6 @@ class WindowBase : public CIntObject { public: WindowBase(int used_ = 0, Point pos_ = Point()); -protected: virtual void close(); }; From 7979f62f823400a8459354ecdd5a27dc503c9100 Mon Sep 17 00:00:00 2001 From: Dydzio Date: Tue, 17 Sep 2024 21:38:28 +0200 Subject: [PATCH 2/4] Add status bar movement points info for own hero on adventure map or hero list --- Mods/vcmi/config/vcmi/english.json | 1 + Mods/vcmi/config/vcmi/polish.json | 1 + client/adventureMap/CList.cpp | 2 +- lib/mapObjects/CGHeroInstance.cpp | 19 +++++++++++++++++++ lib/mapObjects/CGHeroInstance.h | 2 ++ 5 files changed, 24 insertions(+), 1 deletion(-) diff --git a/Mods/vcmi/config/vcmi/english.json b/Mods/vcmi/config/vcmi/english.json index 47f490262..8274126a8 100644 --- a/Mods/vcmi/config/vcmi/english.json +++ b/Mods/vcmi/config/vcmi/english.json @@ -20,6 +20,7 @@ "vcmi.adventureMap.playerAttacked" : "Player has been attacked: %s", "vcmi.adventureMap.moveCostDetails" : "Movement points - Cost: %TURNS turns + %POINTS points, Remaining points: %REMAINING", "vcmi.adventureMap.moveCostDetailsNoTurns" : "Movement points - Cost: %POINTS points, Remaining points: %REMAINING", + "vcmi.adventureMap.movementPointsHeroInfo" : "(Movement points: %REMAINING / %POINTS)", "vcmi.adventureMap.replayOpponentTurnNotImplemented" : "Sorry, replay opponent turn is not implemented yet!", "vcmi.capitalColors.0" : "Red", diff --git a/Mods/vcmi/config/vcmi/polish.json b/Mods/vcmi/config/vcmi/polish.json index ceac0bd9a..bc1b81dc9 100644 --- a/Mods/vcmi/config/vcmi/polish.json +++ b/Mods/vcmi/config/vcmi/polish.json @@ -20,6 +20,7 @@ "vcmi.adventureMap.playerAttacked" : "Gracz został zaatakowany: %s", "vcmi.adventureMap.moveCostDetails" : "Punkty ruchu - Koszt: %TURNS tury + %POINTS punkty, Pozostałe punkty: %REMAINING", "vcmi.adventureMap.moveCostDetailsNoTurns" : "Punkty ruchu - Koszt: %POINTS punkty, Pozostałe punkty: %REMAINING", + "vcmi.adventureMap.movementPointsHeroInfo" : "(Punkty ruchu: %REMAINING / %POINTS)", "vcmi.adventureMap.replayOpponentTurnNotImplemented" : "Wybacz, powtórka ruchu wroga nie została jeszcze zaimplementowana!", "vcmi.capitalColors.0" : "Czerwony", diff --git a/client/adventureMap/CList.cpp b/client/adventureMap/CList.cpp index c535e80cf..0b97f1a63 100644 --- a/client/adventureMap/CList.cpp +++ b/client/adventureMap/CList.cpp @@ -263,7 +263,7 @@ void CHeroList::CHeroItem::showTooltip() std::string CHeroList::CHeroItem::getHoverText() { - return boost::str(boost::format(CGI->generaltexth->allTexts[15]) % hero->getNameTranslated() % hero->getClassNameTranslated()); + return boost::str(boost::format(CGI->generaltexth->allTexts[15]) % hero->getNameTranslated() % hero->getClassNameTranslated()) + hero->getMovementPointsTextIfOwner(hero->getOwner()); } void CHeroList::CHeroItem::gesture(bool on, const Point & initialPosition, const Point & finalPosition) diff --git a/lib/mapObjects/CGHeroInstance.cpp b/lib/mapObjects/CGHeroInstance.cpp index 0a9a127c7..49720b1b5 100644 --- a/lib/mapObjects/CGHeroInstance.cpp +++ b/lib/mapObjects/CGHeroInstance.cpp @@ -566,6 +566,25 @@ std::string CGHeroInstance::getObjectName() const return VLC->objtypeh->getObjectName(ID, 0); } +std::string CGHeroInstance::getHoverText(PlayerColor player) const +{ + std::string hoverText = CArmedInstance::getHoverText(player) + getMovementPointsTextIfOwner(player); + return hoverText; +} + +std::string CGHeroInstance::getMovementPointsTextIfOwner(PlayerColor player) const +{ + std::string output = ""; + if(player == getOwner()) + { + output += " " + VLC->generaltexth->translate("vcmi.adventureMap.movementPointsHeroInfo"); + boost::replace_first(output, "%POINTS", std::to_string(movementPointsLimit(!boat))); + boost::replace_first(output, "%REMAINING", std::to_string(movementPointsRemaining())); + } + + return output; +} + ui8 CGHeroInstance::maxlevelsToMagicSchool() const { return type->heroClass->isMagicHero() ? 3 : 4; diff --git a/lib/mapObjects/CGHeroInstance.h b/lib/mapObjects/CGHeroInstance.h index b929ef7e0..33a8cf7bd 100644 --- a/lib/mapObjects/CGHeroInstance.h +++ b/lib/mapObjects/CGHeroInstance.h @@ -297,6 +297,8 @@ public: void pickRandomObject(CRandomGenerator & rand) override; void onHeroVisit(const CGHeroInstance * h) const override; std::string getObjectName() const override; + std::string getHoverText(PlayerColor player) const override; + std::string getMovementPointsTextIfOwner(PlayerColor player) const; void afterAddToMap(CMap * map) override; void afterRemoveFromMap(CMap * map) override; From c6edd615acfff0406eac16a2a1e93f2235268b69 Mon Sep 17 00:00:00 2001 From: Dydzio Date: Tue, 17 Sep 2024 21:49:21 +0200 Subject: [PATCH 3/4] Block possibility to move hero if shift-clicking on path end --- client/adventureMap/AdventureMapInterface.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/adventureMap/AdventureMapInterface.cpp b/client/adventureMap/AdventureMapInterface.cpp index 381e26c86..a781bc869 100644 --- a/client/adventureMap/AdventureMapInterface.cpp +++ b/client/adventureMap/AdventureMapInterface.cpp @@ -555,7 +555,8 @@ void AdventureMapInterface::onTileLeftClicked(const int3 &targetPosition) else //still here? we need to move hero if we clicked end of already selected path or calculate a new path otherwise { if(LOCPLINT->localState->hasPath(currentHero) && - LOCPLINT->localState->getPath(currentHero).endPos() == targetPosition)//we'll be moving + LOCPLINT->localState->getPath(currentHero).endPos() == targetPosition && + !GH.isKeyboardShiftDown())//we'll be moving { assert(!CGI->mh->hasOngoingAnimations()); if(!CGI->mh->hasOngoingAnimations() && LOCPLINT->localState->getPath(currentHero).nextNode().turns == 0) From 3e1968c20146b8d9850cc48261ecf953ab572aa9 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Thu, 19 Sep 2024 15:30:51 +0000 Subject: [PATCH 4/4] Wait for inactive player in hotseat to answer dialog before starting battle --- client/CPlayerInterface.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index e88caf65d..7aa374fd8 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -1489,6 +1489,7 @@ void CPlayerInterface::playerBlocked(int reason, bool start) cmp.push_back(std::make_shared(ComponentType::FLAG, playerID)); makingTurn = true; //workaround for stiff showInfoDialog implementation showInfoDialog(msg, cmp); + waitWhileDialog(); makingTurn = false; } }