2
0

CMarketWindow.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. /*
  2. * CMarketWindow.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 "CMarketWindow.h"
  12. #include "../GameEngine.h"
  13. #include "../GameInstance.h"
  14. #include "../gui/Shortcut.h"
  15. #include "../widgets/Buttons.h"
  16. #include "../widgets/TextControls.h"
  17. #include "../widgets/markets/CAltarArtifacts.h"
  18. #include "../widgets/markets/CAltarCreatures.h"
  19. #include "../widgets/markets/CArtifactsBuying.h"
  20. #include "../widgets/markets/CArtifactsSelling.h"
  21. #include "../widgets/markets/CFreelancerGuild.h"
  22. #include "../widgets/markets/CMarketResources.h"
  23. #include "../widgets/markets/CTransferResources.h"
  24. #include "../CPlayerInterface.h"
  25. #include "../../lib/GameLibrary.h"
  26. #include "../../lib/callback/CCallback.h"
  27. #include "../../lib/entities/building/CBuilding.h"
  28. #include "../../lib/entities/ResourceTypeHandler.h"
  29. #include "../../lib/mapObjects/CGHeroInstance.h"
  30. #include "../../lib/mapObjects/CGMarket.h"
  31. #include "../../lib/mapObjects/CGTownInstance.h"
  32. #include "../../lib/texts/CGeneralTextHandler.h"
  33. CMarketWindow::CMarketWindow(const IMarket * market, const CGHeroInstance * hero, const std::function<void()> & onWindowClosed, EMarketMode mode)
  34. : CWindowObject(PLAYER_COLORED)
  35. , windowClosedCallback(onWindowClosed)
  36. {
  37. assert(mode == EMarketMode::RESOURCE_RESOURCE || mode == EMarketMode::RESOURCE_PLAYER || mode == EMarketMode::CREATURE_RESOURCE ||
  38. mode == EMarketMode::RESOURCE_ARTIFACT || mode == EMarketMode::ARTIFACT_RESOURCE || mode == EMarketMode::ARTIFACT_EXP ||
  39. mode == EMarketMode::CREATURE_EXP);
  40. OBJECT_CONSTRUCTION;
  41. if(mode == EMarketMode::RESOURCE_RESOURCE)
  42. createMarketResources(market, hero);
  43. else if(mode == EMarketMode::RESOURCE_PLAYER)
  44. createTransferResources(market, hero);
  45. else if(mode == EMarketMode::CREATURE_RESOURCE)
  46. createFreelancersGuild(market, hero);
  47. else if(mode == EMarketMode::RESOURCE_ARTIFACT)
  48. createArtifactsBuying(market, hero);
  49. else if(mode == EMarketMode::ARTIFACT_RESOURCE)
  50. createArtifactsSelling(market, hero);
  51. else if(mode == EMarketMode::ARTIFACT_EXP)
  52. createAltarArtifacts(market, hero);
  53. else if(mode == EMarketMode::CREATURE_EXP)
  54. createAltarCreatures(market, hero);
  55. statusbar = CGStatusBar::create(std::make_shared<CPicture>(background->getSurface(), Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
  56. }
  57. void CMarketWindow::updateArtifacts()
  58. {
  59. update();
  60. }
  61. void CMarketWindow::updateGarrisons()
  62. {
  63. update();
  64. }
  65. void CMarketWindow::updateResources()
  66. {
  67. update();
  68. }
  69. void CMarketWindow::updateExperience()
  70. {
  71. update();
  72. }
  73. void CMarketWindow::update()
  74. {
  75. CWindowWithArtifacts::updateArtifacts();
  76. assert(marketWidget);
  77. marketWidget->update();
  78. }
  79. void CMarketWindow::close()
  80. {
  81. if(windowClosedCallback)
  82. windowClosedCallback();
  83. CWindowObject::close();
  84. }
  85. bool CMarketWindow::holdsGarrison(const CArmedInstance * army)
  86. {
  87. assert(marketWidget);
  88. return marketWidget->hero == army;
  89. }
  90. void CMarketWindow::createChangeModeButtons(EMarketMode currentMode, const IMarket * market, const CGHeroInstance * hero)
  91. {
  92. auto isButtonVisible = [currentMode, market, hero](EMarketMode modeButton) -> bool
  93. {
  94. if(currentMode == modeButton)
  95. return false;
  96. if(!market->allowsTrade(modeButton))
  97. return false;
  98. if(currentMode == EMarketMode::ARTIFACT_EXP && modeButton != EMarketMode::CREATURE_EXP)
  99. return false;
  100. if(currentMode == EMarketMode::CREATURE_EXP && modeButton != EMarketMode::ARTIFACT_EXP)
  101. return false;
  102. if(modeButton == EMarketMode::RESOURCE_RESOURCE || modeButton == EMarketMode::RESOURCE_PLAYER)
  103. {
  104. if(const auto town = dynamic_cast<const CGTownInstance*>(market))
  105. return town->getOwner() == GAME->interface()->playerID;
  106. else
  107. return true;
  108. }
  109. else
  110. {
  111. return hero != nullptr;
  112. }
  113. };
  114. changeModeButtons.clear();
  115. auto buttonPos = Point(18, 520);
  116. auto addButton = [this, &buttonPos](const AnimationPath & picPath, const std::pair<std::string, std::string> & buttonHelpContainer,
  117. const std::function<void()> & pressButtonFunctor, EShortcut shortcut)
  118. {
  119. changeModeButtons.emplace_back(std::make_shared<CButton>(buttonPos, picPath, buttonHelpContainer, pressButtonFunctor, shortcut));
  120. buttonPos -= Point(0, buttonHeightWithMargin);
  121. };
  122. if(isButtonVisible(EMarketMode::RESOURCE_PLAYER))
  123. addButton(AnimationPath::builtin("TPMRKBU1.DEF"), LIBRARY->generaltexth->zelp[612], std::bind(&CMarketWindow::createTransferResources, this, market, hero), EShortcut::MARKET_RESOURCE_PLAYER);
  124. if(isButtonVisible(EMarketMode::ARTIFACT_RESOURCE))
  125. addButton(AnimationPath::builtin("TPMRKBU3.DEF"), LIBRARY->generaltexth->zelp[613], std::bind(&CMarketWindow::createArtifactsSelling, this, market, hero), EShortcut::MARKET_ARTIFACT_RESOURCE);
  126. if(isButtonVisible(EMarketMode::RESOURCE_ARTIFACT))
  127. addButton(AnimationPath::builtin("TPMRKBU2.DEF"), LIBRARY->generaltexth->zelp[598], std::bind(&CMarketWindow::createArtifactsBuying, this, market, hero), EShortcut::MARKET_RESOURCE_ARTIFACT);
  128. buttonPos = Point(516, 520 - buttonHeightWithMargin);
  129. if(isButtonVisible(EMarketMode::CREATURE_RESOURCE))
  130. addButton(AnimationPath::builtin("TPMRKBU4.DEF"), LIBRARY->generaltexth->zelp[599], std::bind(&CMarketWindow::createFreelancersGuild, this, market, hero), EShortcut::MARKET_CREATURE_RESOURCE);
  131. if(isButtonVisible(EMarketMode::RESOURCE_RESOURCE))
  132. addButton(AnimationPath::builtin("TPMRKBU5.DEF"), LIBRARY->generaltexth->zelp[605], std::bind(&CMarketWindow::createMarketResources, this, market, hero), EShortcut::MARKET_RESOURCE_RESOURCE);
  133. buttonPos = Point(516, 421);
  134. if(isButtonVisible(EMarketMode::CREATURE_EXP))
  135. {
  136. addButton(AnimationPath::builtin("ALTSACC.DEF"), LIBRARY->generaltexth->zelp[572], std::bind(&CMarketWindow::createAltarCreatures, this, market, hero), EShortcut::MARKET_CREATURE_EXPERIENCE);
  137. if(marketWidget->hero->getAlignment() == EAlignment::GOOD)
  138. changeModeButtons.back()->block(true);
  139. }
  140. if(isButtonVisible(EMarketMode::ARTIFACT_EXP))
  141. {
  142. addButton(AnimationPath::builtin("ALTART.DEF"), LIBRARY->generaltexth->zelp[580], std::bind(&CMarketWindow::createAltarArtifacts, this, market, hero), EShortcut::MARKET_ARTIFACT_EXPERIENCE);
  143. if(marketWidget->hero->getAlignment() == EAlignment::EVIL)
  144. changeModeButtons.back()->block(true);
  145. }
  146. }
  147. void CMarketWindow::initWidgetInternals(const EMarketMode mode, const std::pair<std::string, std::string> & quitButtonHelpContainer)
  148. {
  149. background->center();
  150. pos = background->pos;
  151. marketWidget->setRedrawParent(true);
  152. marketWidget->moveTo(pos.topLeft());
  153. createChangeModeButtons(mode, marketWidget->market, marketWidget->hero);
  154. quitButton = std::make_shared<CButton>(quitButtonPos, AnimationPath::builtin("IOK6432.DEF"),
  155. quitButtonHelpContainer, [this](){close();}, EShortcut::GLOBAL_RETURN);
  156. redraw();
  157. }
  158. std::string CMarketWindow::getMarketTitle(const ObjectInstanceID marketId, const EMarketMode mode) const
  159. {
  160. assert(GAME->interface()->cb->getMarket(marketId));
  161. assert(vstd::contains(GAME->interface()->cb->getMarket(marketId)->availableModes(), mode));
  162. if(const auto town = GAME->interface()->cb->getTown(marketId))
  163. {
  164. for(const auto & buildingId : town->getBuildings())
  165. {
  166. const auto & building = town->getTown()->buildings.at(buildingId);
  167. if(vstd::contains(building->marketModes, mode))
  168. return building->getNameTranslated();
  169. }
  170. }
  171. return GAME->interface()->cb->getObj(marketId)->getObjectName();
  172. }
  173. ImagePath CMarketWindow::getImagePathBasedOnResources(std::string name)
  174. {
  175. int res = LIBRARY->resourceTypeHandler->getAllObjects().size();
  176. if(res == 8)
  177. name += "-R8";
  178. else if(res > 8)
  179. name += "-R9";
  180. return ImagePath::builtin(name);
  181. }
  182. void CMarketWindow::createArtifactsBuying(const IMarket * market, const CGHeroInstance * hero)
  183. {
  184. OBJECT_CONSTRUCTION;
  185. auto image = getImagePathBasedOnResources("TPMRKABS");
  186. background = createBg(image, PLAYER_COLORED);
  187. marketWidget = std::make_shared<CArtifactsBuying>(market, hero, getMarketTitle(market->getObjInstanceID(), EMarketMode::RESOURCE_ARTIFACT));
  188. initWidgetInternals(EMarketMode::RESOURCE_ARTIFACT, LIBRARY->generaltexth->zelp[600]);
  189. }
  190. void CMarketWindow::createArtifactsSelling(const IMarket * market, const CGHeroInstance * hero)
  191. {
  192. OBJECT_CONSTRUCTION;
  193. auto image = getImagePathBasedOnResources("TPMRKASS");
  194. background = createBg(image, PLAYER_COLORED);
  195. // Create image that copies part of background containing slot MISC_1 into position of slot MISC_5
  196. artSlotBack = std::make_shared<CPicture>(background->getSurface(), Rect(20, 187, 47, 47), 0, 0);
  197. artSlotBack->moveTo(pos.topLeft() + Point(18, 339));
  198. auto artsSellingMarket = std::make_shared<CArtifactsSelling>(market, hero, getMarketTitle(market->getObjInstanceID(), EMarketMode::ARTIFACT_RESOURCE));
  199. artSets.clear();
  200. const auto heroArts = artsSellingMarket->getAOHset();
  201. addSet(heroArts);
  202. marketWidget = artsSellingMarket;
  203. initWidgetInternals(EMarketMode::ARTIFACT_RESOURCE, LIBRARY->generaltexth->zelp[600]);
  204. }
  205. void CMarketWindow::createMarketResources(const IMarket * market, const CGHeroInstance * hero)
  206. {
  207. OBJECT_CONSTRUCTION;
  208. auto image = getImagePathBasedOnResources("TPMRKRES");
  209. background = createBg(image, PLAYER_COLORED);
  210. marketWidget = std::make_shared<CMarketResources>(market, hero);
  211. initWidgetInternals(EMarketMode::RESOURCE_RESOURCE, LIBRARY->generaltexth->zelp[600]);
  212. }
  213. void CMarketWindow::createFreelancersGuild(const IMarket * market, const CGHeroInstance * hero)
  214. {
  215. OBJECT_CONSTRUCTION;
  216. auto image = getImagePathBasedOnResources("TPMRKCRS");
  217. background = createBg(image, PLAYER_COLORED);
  218. marketWidget = std::make_shared<CFreelancerGuild>(market, hero);
  219. initWidgetInternals(EMarketMode::CREATURE_RESOURCE, LIBRARY->generaltexth->zelp[600]);
  220. }
  221. void CMarketWindow::createTransferResources(const IMarket * market, const CGHeroInstance * hero)
  222. {
  223. OBJECT_CONSTRUCTION;
  224. auto image = getImagePathBasedOnResources("TPMRKPTS");
  225. background = createBg(image, PLAYER_COLORED);
  226. marketWidget = std::make_shared<CTransferResources>(market, hero);
  227. initWidgetInternals(EMarketMode::RESOURCE_PLAYER, LIBRARY->generaltexth->zelp[600]);
  228. }
  229. void CMarketWindow::createAltarArtifacts(const IMarket * market, const CGHeroInstance * hero)
  230. {
  231. OBJECT_CONSTRUCTION;
  232. background = createBg(ImagePath::builtin("ALTRART2.bmp"), PLAYER_COLORED);
  233. auto altarArtifactsStorage = std::make_shared<CAltarArtifacts>(market, hero);
  234. marketWidget = altarArtifactsStorage;
  235. artSets.clear();
  236. const auto heroArts = altarArtifactsStorage->getAOHset();
  237. heroArts->clickPressedCallback = [this, heroArts](const CArtPlace & artPlace, const Point & cursorPosition)
  238. {
  239. clickPressedOnArtPlace(heroArts->getHero(), artPlace.slot, true, true, false, cursorPosition);
  240. };
  241. heroArts->showPopupCallback = [this, heroArts](CArtPlace & artPlace, const Point & cursorPosition)
  242. {
  243. showArtifactPopup(*heroArts, artPlace, cursorPosition);
  244. };
  245. heroArts->gestureCallback = [this, heroArts](const CArtPlace & artPlace, const Point & cursorPosition)
  246. {
  247. showQuickBackpackWindow(heroArts->getHero(), artPlace.slot, cursorPosition);
  248. };
  249. addSet(heroArts);
  250. initWidgetInternals(EMarketMode::ARTIFACT_EXP, LIBRARY->generaltexth->zelp[568]);
  251. updateExperience();
  252. quitButton->addCallback([altarArtifactsStorage](){altarArtifactsStorage->putBackArtifacts();});
  253. }
  254. void CMarketWindow::createAltarCreatures(const IMarket * market, const CGHeroInstance * hero)
  255. {
  256. OBJECT_CONSTRUCTION;
  257. background = createBg(ImagePath::builtin("ALTARMON.bmp"), PLAYER_COLORED);
  258. marketWidget = std::make_shared<CAltarCreatures>(market, hero);
  259. initWidgetInternals(EMarketMode::CREATURE_EXP, LIBRARY->generaltexth->zelp[568]);
  260. updateExperience();
  261. }