ArtifactsUIController.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /*
  2. * ArtifactsUIController.cpp, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #include "StdInc.h"
  11. #include "ArtifactsUIController.h"
  12. #include "CGameInfo.h"
  13. #include "CPlayerInterface.h"
  14. #include "../CCallback.h"
  15. #include "../lib/ArtifactUtils.h"
  16. #include "../lib/CGeneralTextHandler.h"
  17. #include "../lib/mapObjects/CGHeroInstance.h"
  18. #include "gui/CGuiHandler.h"
  19. #include "gui/WindowHandler.h"
  20. #include "widgets/CComponent.h"
  21. #include "windows/CWindowWithArtifacts.h"
  22. ArtifactsUIController::ArtifactsUIController()
  23. {
  24. numOfMovedArts = 0;
  25. }
  26. bool ArtifactsUIController::askToAssemble(const ArtifactLocation & al, const bool onlyEquipped, const bool checkIgnored)
  27. {
  28. if(auto hero = LOCPLINT->cb->getHero(al.artHolder))
  29. {
  30. if(hero->getArt(al.slot) == nullptr)
  31. {
  32. logGlobal->error("artifact location %d points to nothing", al.slot.num);
  33. return false;
  34. }
  35. return askToAssemble(hero, al.slot, onlyEquipped, checkIgnored);
  36. }
  37. return false;
  38. }
  39. bool ArtifactsUIController::askToAssemble(const CGHeroInstance * hero, const ArtifactPosition & slot,
  40. const bool onlyEquipped, const bool checkIgnored)
  41. {
  42. assert(hero);
  43. const auto art = hero->getArt(slot);
  44. assert(art);
  45. if(hero->tempOwner != LOCPLINT->playerID)
  46. return false;
  47. if(numOfArtsAskAssembleSession != 0)
  48. numOfArtsAskAssembleSession--;
  49. auto assemblyPossibilities = ArtifactUtils::assemblyPossibilities(hero, art->getTypeId(), onlyEquipped);
  50. if(!assemblyPossibilities.empty())
  51. {
  52. auto askThread = new boost::thread([this, hero, art, slot, assemblyPossibilities, checkIgnored]() -> void
  53. {
  54. boost::mutex::scoped_lock askLock(askAssembleArtifactMutex);
  55. for(const auto combinedArt : assemblyPossibilities)
  56. {
  57. boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
  58. if(checkIgnored)
  59. {
  60. if(vstd::contains(ignoredArtifacts, combinedArt->getId()))
  61. continue;
  62. ignoredArtifacts.emplace(combinedArt->getId());
  63. }
  64. bool assembleConfirmed = false;
  65. MetaString message = MetaString::createFromTextID(art->artType->getDescriptionTextID());
  66. message.appendEOL();
  67. message.appendEOL();
  68. message.appendRawString(CGI->generaltexth->allTexts[732]); // You possess all of the components needed to assemble the
  69. message.replaceName(ArtifactID(combinedArt->getId()));
  70. LOCPLINT->showYesNoDialog(message.toString(), [&assembleConfirmed, hero, slot, combinedArt]()
  71. {
  72. assembleConfirmed = true;
  73. LOCPLINT->cb.get()->assembleArtifacts(hero->id, slot, true, combinedArt->getId());
  74. }, nullptr, {std::make_shared<CComponent>(ComponentType::ARTIFACT, combinedArt->getId())});
  75. LOCPLINT->waitWhileDialog();
  76. if(assembleConfirmed)
  77. break;
  78. }
  79. });
  80. askThread->detach();
  81. return true;
  82. }
  83. return false;
  84. }
  85. bool ArtifactsUIController::askToDisassemble(const CGHeroInstance * hero, const ArtifactPosition & slot)
  86. {
  87. assert(hero);
  88. const auto art = hero->getArt(slot);
  89. assert(art);
  90. if(hero->tempOwner != LOCPLINT->playerID)
  91. return false;
  92. if(art->isCombined())
  93. {
  94. if(ArtifactUtils::isSlotBackpack(slot) && !ArtifactUtils::isBackpackFreeSlots(hero, art->artType->getConstituents().size() - 1))
  95. return false;
  96. MetaString message = MetaString::createFromTextID(art->artType->getDescriptionTextID());
  97. message.appendEOL();
  98. message.appendEOL();
  99. message.appendRawString(CGI->generaltexth->allTexts[733]); // Do you wish to disassemble this artifact?
  100. LOCPLINT->showYesNoDialog(message.toString(), [hero, slot]()
  101. {
  102. LOCPLINT->cb->assembleArtifacts(hero->id, slot, false, ArtifactID());
  103. }, nullptr);
  104. return true;
  105. }
  106. return false;
  107. }
  108. void ArtifactsUIController::artifactRemoved()
  109. {
  110. for(const auto & artWin : GH.windows().findWindows<CWindowWithArtifacts>())
  111. artWin->update();
  112. LOCPLINT->waitWhileDialog();
  113. }
  114. void ArtifactsUIController::artifactMoved()
  115. {
  116. // If a bulk transfer has arrived, then redrawing only the last art movement.
  117. if(numOfMovedArts != 0)
  118. numOfMovedArts--;
  119. if(numOfMovedArts == 0)
  120. for(const auto & artWin : GH.windows().findWindows<CWindowWithArtifacts>())
  121. {
  122. artWin->update();
  123. }
  124. LOCPLINT->waitWhileDialog();
  125. }
  126. void ArtifactsUIController::bulkArtMovementStart(size_t totalNumOfArts, size_t possibleAssemblyNumOfArts)
  127. {
  128. assert(totalNumOfArts >= possibleAssemblyNumOfArts);
  129. numOfMovedArts = totalNumOfArts;
  130. if(numOfArtsAskAssembleSession == 0)
  131. {
  132. // Do not start the next session until the previous one is finished
  133. numOfArtsAskAssembleSession = possibleAssemblyNumOfArts;
  134. ignoredArtifacts.clear();
  135. }
  136. }
  137. void ArtifactsUIController::artifactAssembled()
  138. {
  139. for(const auto & artWin : GH.windows().findWindows<CWindowWithArtifacts>())
  140. artWin->update();
  141. }
  142. void ArtifactsUIController::artifactDisassembled()
  143. {
  144. for(const auto & artWin : GH.windows().findWindows<CWindowWithArtifacts>())
  145. artWin->update();
  146. }