diff --git a/AI/EmptyAI/CEmptyAI.cpp b/AI/EmptyAI/CEmptyAI.cpp index 0ca26e8c4..4291663e7 100644 --- a/AI/EmptyAI/CEmptyAI.cpp +++ b/AI/EmptyAI/CEmptyAI.cpp @@ -56,7 +56,7 @@ void CEmptyAI::commanderGotLevel(const CCommanderInstance * commander, std::vect cb->selectionMade(CRandomGenerator::getDefault().nextInt((int)skills.size() - 1), queryID); } -void CEmptyAI::showBlockingDialog(const std::string &text, const std::vector &components, QueryID askID, const int soundID, bool selection, bool cancel) +void CEmptyAI::showBlockingDialog(const std::string &text, const std::vector &components, QueryID askID, const int soundID, bool selection, bool cancel, bool safeToAutoaccept) { cb->selectionMade(0, askID); } diff --git a/AI/EmptyAI/CEmptyAI.h b/AI/EmptyAI/CEmptyAI.h index eb2935f83..78b0353f4 100644 --- a/AI/EmptyAI/CEmptyAI.h +++ b/AI/EmptyAI/CEmptyAI.h @@ -28,7 +28,7 @@ public: void activeStack(const BattleID & battleID, const CStack * stack) override; void heroGotLevel(const CGHeroInstance *hero, PrimarySkill pskill, std::vector &skills, QueryID queryID) override; void commanderGotLevel (const CCommanderInstance * commander, std::vector skills, QueryID queryID) override; - void showBlockingDialog(const std::string &text, const std::vector &components, QueryID askID, const int soundID, bool selection, bool cancel) override; + void showBlockingDialog(const std::string &text, const std::vector &components, QueryID askID, const int soundID, bool selection, bool cancel, bool safeToAutoaccept) override; void showTeleportDialog(const CGHeroInstance * hero, TeleportChannelID channel, TTeleportExitsList exits, bool impassable, QueryID askID) override; void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, QueryID queryID) override; void showMapObjectSelectDialog(QueryID askID, const Component & icon, const MetaString & title, const MetaString & description, const std::vector & objects) override; diff --git a/AI/Nullkiller/AIGateway.cpp b/AI/Nullkiller/AIGateway.cpp index 1ce6b6fd4..b7fe81b85 100644 --- a/AI/Nullkiller/AIGateway.cpp +++ b/AI/Nullkiller/AIGateway.cpp @@ -614,9 +614,9 @@ void AIGateway::commanderGotLevel(const CCommanderInstance * commander, std::vec requestActionASAP([=](){ answerQuery(queryID, 0); }); } -void AIGateway::showBlockingDialog(const std::string & text, const std::vector & components, QueryID askID, const int soundID, bool selection, bool cancel) +void AIGateway::showBlockingDialog(const std::string & text, const std::vector & components, QueryID askID, const int soundID, bool selection, bool cancel, bool safeToAutoaccept) { - LOG_TRACE_PARAMS(logAi, "text '%s', askID '%i', soundID '%i', selection '%i', cancel '%i'", text % askID % soundID % selection % cancel); + LOG_TRACE_PARAMS(logAi, "text '%s', askID '%i', soundID '%i', selection '%i', cancel '%i'", text % askID % soundID % selection % cancel % safeToAutoaccept); NET_EVENT_HANDLER; status.addQuery(askID, boost::str(boost::format("Blocking dialog query with %d components - %s") % components.size() % text)); diff --git a/AI/Nullkiller/AIGateway.h b/AI/Nullkiller/AIGateway.h index e4aa16ab5..2c157d0a0 100644 --- a/AI/Nullkiller/AIGateway.h +++ b/AI/Nullkiller/AIGateway.h @@ -115,7 +115,7 @@ public: void heroGotLevel(const CGHeroInstance * hero, PrimarySkill pskill, std::vector & skills, QueryID queryID) override; //pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id void commanderGotLevel(const CCommanderInstance * commander, std::vector skills, QueryID queryID) override; //TODO - void showBlockingDialog(const std::string & text, const std::vector & components, QueryID askID, const int soundID, bool selection, bool cancel) override; //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID. + void showBlockingDialog(const std::string & text, const std::vector & components, QueryID askID, const int soundID, bool selection, bool cancel, bool safeToAutoaccept) override; //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID. void showGarrisonDialog(const CArmedInstance * up, const CGHeroInstance * down, bool removableUnits, QueryID queryID) override; //all stacks operations between these objects become allowed, interface has to call onEnd when done void showTeleportDialog(const CGHeroInstance * hero, TeleportChannelID channel, TTeleportExitsList exits, bool impassable, QueryID askID) override; void showMapObjectSelectDialog(QueryID askID, const Component & icon, const MetaString & title, const MetaString & description, const std::vector & objects) override; diff --git a/AI/VCAI/VCAI.cpp b/AI/VCAI/VCAI.cpp index 2cfb7cd10..fa4091f9b 100644 --- a/AI/VCAI/VCAI.cpp +++ b/AI/VCAI/VCAI.cpp @@ -654,9 +654,9 @@ void VCAI::commanderGotLevel(const CCommanderInstance * commander, std::vector & components, QueryID askID, const int soundID, bool selection, bool cancel) +void VCAI::showBlockingDialog(const std::string & text, const std::vector & components, QueryID askID, const int soundID, bool selection, bool cancel, bool safeToAutoaccept) { - LOG_TRACE_PARAMS(logAi, "text '%s', askID '%i', soundID '%i', selection '%i', cancel '%i'", text % askID % soundID % selection % cancel); + LOG_TRACE_PARAMS(logAi, "text '%s', askID '%i', soundID '%i', selection '%i', cancel '%i'", text % askID % soundID % selection % cancel % safeToAutoaccept); NET_EVENT_HANDLER; int sel = 0; status.addQuery(askID, boost::str(boost::format("Blocking dialog query with %d components - %s") diff --git a/AI/VCAI/VCAI.h b/AI/VCAI/VCAI.h index 4db3f89f0..b5625c164 100644 --- a/AI/VCAI/VCAI.h +++ b/AI/VCAI/VCAI.h @@ -148,7 +148,7 @@ public: void heroGotLevel(const CGHeroInstance * hero, PrimarySkill pskill, std::vector & skills, QueryID queryID) override; //pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id void commanderGotLevel(const CCommanderInstance * commander, std::vector skills, QueryID queryID) override; //TODO - void showBlockingDialog(const std::string & text, const std::vector & components, QueryID askID, const int soundID, bool selection, bool cancel) override; //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID. + void showBlockingDialog(const std::string & text, const std::vector & components, QueryID askID, const int soundID, bool selection, bool cancel, bool safeToAutoaccept) override; //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID. void showGarrisonDialog(const CArmedInstance * up, const CGHeroInstance * down, bool removableUnits, QueryID queryID) override; //all stacks operations between these objects become allowed, interface has to call onEnd when done void showTeleportDialog(const CGHeroInstance * hero, TeleportChannelID channel, TTeleportExitsList exits, bool impassable, QueryID askID) override; void showMapObjectSelectDialog(QueryID askID, const Component & icon, const MetaString & title, const MetaString & description, const std::vector & objects) override; diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index 086eebe92..ded74dfc2 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -1024,7 +1024,7 @@ void CPlayerInterface::showYesNoDialog(const std::string &text, CFunctionList &components, QueryID askID, const int soundID, bool selection, bool cancel ) +void CPlayerInterface::showBlockingDialog(const std::string &text, const std::vector &components, QueryID askID, const int soundID, bool selection, bool cancel, bool safeToAutoaccept) { EVENT_HANDLER_CALLED_BY_CLIENT; waitWhileDialog(); @@ -1034,6 +1034,12 @@ void CPlayerInterface::showBlockingDialog( const std::string &text, const std::v if (!selection && cancel) //simple yes/no dialog { + if(settings["general"]["enableUiEnhancements"].Bool() && safeToAutoaccept) + { + cb->selectionMade(1, askID); //as in HD mod, we try to skip dialogs that server considers visual fluff which does not affect gamestate + return; + } + std::vector> intComps; for (auto & component : components) intComps.push_back(std::make_shared(component)); //will be deleted by close in window diff --git a/client/CPlayerInterface.h b/client/CPlayerInterface.h index de41ed1a9..11f9388b6 100644 --- a/client/CPlayerInterface.h +++ b/client/CPlayerInterface.h @@ -119,7 +119,7 @@ protected: // Call-ins from server, should not be called directly, but only via void receivedResource() override; void showInfoDialog(EInfoWindowMode type, const std::string & text, const std::vector & components, int soundID) override; void showRecruitmentDialog(const CGDwelling *dwelling, const CArmedInstance *dst, int level, QueryID queryID) override; - void showBlockingDialog(const std::string &text, const std::vector &components, QueryID askID, const int soundID, bool selection, bool cancel) override; //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID. + void showBlockingDialog(const std::string &text, const std::vector &components, QueryID askID, const int soundID, bool selection, bool cancel, bool safeToAutoaccept) override; //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID. void showTeleportDialog(const CGHeroInstance * hero, TeleportChannelID channel, TTeleportExitsList exits, bool impassable, QueryID askID) override; void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, QueryID queryID) override; void showMapObjectSelectDialog(QueryID askID, const Component & icon, const MetaString & title, const MetaString & description, const std::vector & objects) override; diff --git a/client/NetPacksClient.cpp b/client/NetPacksClient.cpp index 34f5cd8ca..53d4304d2 100644 --- a/client/NetPacksClient.cpp +++ b/client/NetPacksClient.cpp @@ -738,7 +738,7 @@ void ApplyClientNetPackVisitor::visitBlockingDialog(BlockingDialog & pack) { std::string str = pack.text.toString(); - if(!callOnlyThatInterface(cl, pack.player, &CGameInterface::showBlockingDialog, str, pack.components, pack.queryID, (soundBase::soundID)pack.soundID, pack.selection(), pack.cancel())) + if(!callOnlyThatInterface(cl, pack.player, &CGameInterface::showBlockingDialog, str, pack.components, pack.queryID, (soundBase::soundID)pack.soundID, pack.selection(), pack.cancel(), pack.safeToAutoaccept())) logNetwork->warn("We received YesNoDialog for not our player..."); } diff --git a/lib/CGameInterface.h b/lib/CGameInterface.h index ee99645d7..5804a2478 100644 --- a/lib/CGameInterface.h +++ b/lib/CGameInterface.h @@ -99,7 +99,7 @@ public: // Show a dialog, player must take decision. If selection then he has to choose between one of given components, // if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called // with number of selected component (1 - n) or 0 for cancel (if allowed) and askID. - virtual void showBlockingDialog(const std::string &text, const std::vector &components, QueryID askID, const int soundID, bool selection, bool cancel) = 0; + virtual void showBlockingDialog(const std::string &text, const std::vector &components, QueryID askID, const int soundID, bool selection, bool cancel, bool safeToAutoaccept) = 0; // all stacks operations between these objects become allowed, interface has to call onEnd when done virtual void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, QueryID queryID) = 0; diff --git a/lib/mapObjects/CGDwelling.cpp b/lib/mapObjects/CGDwelling.cpp index dafcc8819..ce357cba9 100644 --- a/lib/mapObjects/CGDwelling.cpp +++ b/lib/mapObjects/CGDwelling.cpp @@ -290,6 +290,11 @@ void CGDwelling::onHeroVisit( const CGHeroInstance * h ) const else throw std::runtime_error("Illegal dwelling!"); + if(ID == Obj::REFUGEE_CAMP || (ID == Obj::CREATURE_GENERATOR1 && VLC->creatures()->getById(creatures[0].second[0])->getLevel() != 1)) + { + bd.flags |= BlockingDialog::SAFE_TO_AUTOACCEPT; + } + cb->showBlockingDialog(&bd); } diff --git a/lib/networkPacks/PacksForClient.h b/lib/networkPacks/PacksForClient.h index e0be8f2e4..a287af945 100644 --- a/lib/networkPacks/PacksForClient.h +++ b/lib/networkPacks/PacksForClient.h @@ -1335,7 +1335,7 @@ struct DLL_LINKAGE CommanderLevelUp : public Query //Until sending reply player won't be allowed to take any actions struct DLL_LINKAGE BlockingDialog : public Query { - enum { ALLOW_CANCEL = 1, SELECTION = 2 }; + enum { ALLOW_CANCEL = 1, SELECTION = 2, SAFE_TO_AUTOACCEPT = 4 }; MetaString text; std::vector components; PlayerColor player; @@ -1351,6 +1351,11 @@ struct DLL_LINKAGE BlockingDialog : public Query return flags & SELECTION; } + bool safeToAutoaccept() const + { + return flags & SAFE_TO_AUTOACCEPT; + } + BlockingDialog(bool yesno, bool Selection) { if(yesno) flags |= ALLOW_CANCEL; diff --git a/test/vcai/mock_VCAI.h b/test/vcai/mock_VCAI.h index c67d2f1dc..0ab80be4e 100644 --- a/test/vcai/mock_VCAI.h +++ b/test/vcai/mock_VCAI.h @@ -32,7 +32,7 @@ public: MOCK_METHOD4(heroGotLevel, void(const CGHeroInstance * hero, PrimarySkill::PrimarySkill pskill, std::vector & skills, QueryID queryID)); MOCK_METHOD3(commanderGotLevel, void(const CCommanderInstance * commander, std::vector skills, QueryID queryID)); - MOCK_METHOD6(showBlockingDialog, void(const std::string & text, const std::vector & components, QueryID askID, const int soundID, bool selection, bool cancel)); + MOCK_METHOD6(showBlockingDialog, void(const std::string & text, const std::vector & components, QueryID askID, const int soundID, bool selection, bool cancel, bool safeToAutoaccept)); MOCK_METHOD4(showGarrisonDialog, void(const CArmedInstance * up, const CGHeroInstance * down, bool removableUnits, QueryID queryID)); MOCK_METHOD4(showTeleportDialog, void(TeleportChannelID channel, TTeleportExitsList exits, bool impassable, QueryID askID)); MOCK_METHOD5(showMapObjectSelectDialog, void(QueryID askID, const Component & icon, const MetaString & title, const MetaString & description, const std::vector & objects));