RandomMapTab.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. /*
  2. * RandomMapTab.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 "RandomMapTab.h"
  12. #include "CSelectionBase.h"
  13. #include "../CGameInfo.h"
  14. #include "../CServerHandler.h"
  15. #include "../gui/CAnimation.h"
  16. #include "../gui/CGuiHandler.h"
  17. #include "../widgets/CComponent.h"
  18. #include "../widgets/Buttons.h"
  19. #include "../widgets/MiscWidgets.h"
  20. #include "../widgets/ObjectLists.h"
  21. #include "../widgets/TextControls.h"
  22. #include "../windows/GUIClasses.h"
  23. #include "../windows/InfoWindows.h"
  24. #include "../../lib/CGeneralTextHandler.h"
  25. #include "../../lib/mapping/CMapInfo.h"
  26. #include "../../lib/rmg/CMapGenOptions.h"
  27. #include "../../lib/CModHandler.h"
  28. RandomMapTab::RandomMapTab():
  29. InterfaceBuilder()
  30. {
  31. recActions = 0;
  32. mapGenOptions = std::make_shared<CMapGenOptions>();
  33. const JsonNode config(ResourceID("config/windows.json"));
  34. addCallback("toggleMapSize", [&](int btnId)
  35. {
  36. auto mapSizeVal = getPossibleMapSizes();
  37. mapGenOptions->setWidth(mapSizeVal[btnId]);
  38. mapGenOptions->setHeight(mapSizeVal[btnId]);
  39. updateMapInfoByHost();
  40. });
  41. addCallback("toggleTwoLevels", [&](bool on)
  42. {
  43. mapGenOptions->setHasTwoLevels(on);
  44. updateMapInfoByHost();
  45. });
  46. addCallback("setPlayersCount", [&](int btnId)
  47. {
  48. mapGenOptions->setPlayerCount(btnId);
  49. if(auto w = dynamic_pointer_cast<CToggleGroup>(widget("groupMaxTeams")))
  50. deactivateButtonsFrom(w.get(), btnId);
  51. // deactive some CompOnlyPlayers buttons to prevent total number of players exceeds PlayerColor::PLAYER_LIMIT_I
  52. if(auto w = dynamic_pointer_cast<CToggleGroup>(widget("groupCompOnlyPlayers")))
  53. deactivateButtonsFrom(w.get(), PlayerColor::PLAYER_LIMIT_I - btnId + 1);
  54. validatePlayersCnt(btnId);
  55. updateMapInfoByHost();
  56. });
  57. addCallback("setTeamsCount", [&](int btnId)
  58. {
  59. mapGenOptions->setTeamCount(btnId);
  60. updateMapInfoByHost();
  61. });
  62. addCallback("setCompOnlyPlayers", [&](int btnId)
  63. {
  64. mapGenOptions->setCompOnlyPlayerCount(btnId);
  65. // deactive some MaxPlayers buttons to prevent total number of players exceeds PlayerColor::PLAYER_LIMIT_I
  66. if(auto w = dynamic_pointer_cast<CToggleGroup>(widget("groupMaxPlayers")))
  67. deactivateButtonsFrom(w.get(), PlayerColor::PLAYER_LIMIT_I - btnId + 1);
  68. if(auto w = dynamic_pointer_cast<CToggleGroup>(widget("groupCompOnlyTeams")))
  69. deactivateButtonsFrom(w.get(), (btnId == 0 ? 1 : btnId));
  70. validateCompOnlyPlayersCnt(btnId);
  71. updateMapInfoByHost();
  72. });
  73. addCallback("setCompOnlyTeams", [&](int btnId)
  74. {
  75. mapGenOptions->setCompOnlyTeamCount(btnId);
  76. updateMapInfoByHost();
  77. });
  78. addCallback("setWaterContent", [&](int btnId)
  79. {
  80. mapGenOptions->setWaterContent(static_cast<EWaterContent::EWaterContent>(btnId));
  81. updateMapInfoByHost();
  82. });
  83. addCallback("setMonsterStrenght", [&](int btnId)
  84. {
  85. if(btnId < 0)
  86. mapGenOptions->setMonsterStrength(EMonsterStrength::RANDOM);
  87. else
  88. mapGenOptions->setMonsterStrength(static_cast<EMonsterStrength::EMonsterStrength>(btnId)); //value 2 to 4
  89. updateMapInfoByHost();
  90. });
  91. init(config["randomMapTab"]);
  92. updateMapInfoByHost();
  93. }
  94. void RandomMapTab::updateMapInfoByHost()
  95. {
  96. if(CSH->isGuest())
  97. return;
  98. // Generate header info
  99. mapInfo = std::make_shared<CMapInfo>();
  100. mapInfo->isRandomMap = true;
  101. mapInfo->mapHeader = make_unique<CMapHeader>();
  102. mapInfo->mapHeader->version = EMapFormat::SOD;
  103. mapInfo->mapHeader->name = CGI->generaltexth->allTexts[740];
  104. mapInfo->mapHeader->description = CGI->generaltexth->allTexts[741];
  105. mapInfo->mapHeader->difficulty = 1; // Normal
  106. mapInfo->mapHeader->height = mapGenOptions->getHeight();
  107. mapInfo->mapHeader->width = mapGenOptions->getWidth();
  108. mapInfo->mapHeader->twoLevel = mapGenOptions->getHasTwoLevels();
  109. // Generate player information
  110. mapInfo->mapHeader->players.clear();
  111. int playersToGen = PlayerColor::PLAYER_LIMIT_I;
  112. if(mapGenOptions->getPlayerCount() != CMapGenOptions::RANDOM_SIZE)
  113. {
  114. if(mapGenOptions->getCompOnlyPlayerCount() != CMapGenOptions::RANDOM_SIZE)
  115. playersToGen = mapGenOptions->getPlayerCount() + mapGenOptions->getCompOnlyPlayerCount();
  116. else
  117. playersToGen = mapGenOptions->getPlayerCount();
  118. }
  119. mapInfo->mapHeader->howManyTeams = playersToGen;
  120. for(int i = 0; i < playersToGen; ++i)
  121. {
  122. PlayerInfo player;
  123. player.isFactionRandom = true;
  124. player.canComputerPlay = true;
  125. if(mapGenOptions->getCompOnlyPlayerCount() != CMapGenOptions::RANDOM_SIZE && i >= mapGenOptions->getPlayerCount())
  126. {
  127. player.canHumanPlay = false;
  128. }
  129. else
  130. {
  131. player.canHumanPlay = true;
  132. }
  133. player.team = TeamID(i);
  134. player.hasMainTown = true;
  135. player.generateHeroAtMainTown = true;
  136. mapInfo->mapHeader->players.push_back(player);
  137. }
  138. mapInfoChanged(mapInfo, mapGenOptions);
  139. }
  140. void RandomMapTab::setMapGenOptions(std::shared_ptr<CMapGenOptions> opts)
  141. {
  142. if(auto w = dynamic_pointer_cast<CToggleGroup>(widget("groupMapSize")))
  143. w->setSelected(vstd::find_pos(getPossibleMapSizes(), opts->getWidth()));
  144. if(auto w = dynamic_pointer_cast<CToggleButton>(widget("buttonTwoLevels")))
  145. w->setSelected(opts->getHasTwoLevels());
  146. if(auto w = dynamic_pointer_cast<CToggleGroup>(widget("groupMaxPlayers")))
  147. w->setSelected(opts->getPlayerCount());
  148. if(auto w = dynamic_pointer_cast<CToggleGroup>(widget("groupMaxTeams")))
  149. w->setSelected(opts->getTeamCount());
  150. if(auto w = dynamic_pointer_cast<CToggleGroup>(widget("groupCompOnlyPlayers")))
  151. w->setSelected(opts->getCompOnlyPlayerCount());
  152. if(auto w = dynamic_pointer_cast<CToggleGroup>(widget("groupCompOnlyTeams")))
  153. w->setSelected(opts->getCompOnlyTeamCount());
  154. if(auto w = dynamic_pointer_cast<CToggleGroup>(widget("groupWaterContent")))
  155. w->setSelected(opts->getWaterContent());
  156. if(auto w = dynamic_pointer_cast<CToggleGroup>(widget("groupgroupMonsterStrengthMaxTeams")))
  157. w->setSelected(opts->getMonsterStrength());
  158. }
  159. void RandomMapTab::deactivateButtonsFrom(CToggleGroup * group, int startId)
  160. {
  161. logGlobal->debug("Blocking buttons from %d", startId);
  162. for(auto toggle : group->buttons)
  163. {
  164. if(auto button = std::dynamic_pointer_cast<CToggleButton>(toggle.second))
  165. {
  166. if(startId == CMapGenOptions::RANDOM_SIZE || toggle.first < startId)
  167. {
  168. button->block(false);
  169. }
  170. else
  171. {
  172. button->block(true);
  173. }
  174. }
  175. }
  176. }
  177. void RandomMapTab::validatePlayersCnt(int playersCnt)
  178. {
  179. if(playersCnt == CMapGenOptions::RANDOM_SIZE)
  180. {
  181. return;
  182. }
  183. if(mapGenOptions->getTeamCount() >= playersCnt)
  184. {
  185. mapGenOptions->setTeamCount(playersCnt - 1);
  186. if(auto w = dynamic_pointer_cast<CToggleGroup>(widget("groupMaxTeams")))
  187. w->setSelected(mapGenOptions->getTeamCount());
  188. }
  189. // total players should not exceed PlayerColor::PLAYER_LIMIT_I (8 in homm3)
  190. if(mapGenOptions->getCompOnlyPlayerCount() + playersCnt > PlayerColor::PLAYER_LIMIT_I)
  191. {
  192. mapGenOptions->setCompOnlyPlayerCount(PlayerColor::PLAYER_LIMIT_I - playersCnt);
  193. if(auto w = dynamic_pointer_cast<CToggleGroup>(widget("groupCompOnlyPlayers")))
  194. w->setSelected(mapGenOptions->getCompOnlyPlayerCount());
  195. }
  196. validateCompOnlyPlayersCnt(mapGenOptions->getCompOnlyPlayerCount());
  197. }
  198. void RandomMapTab::validateCompOnlyPlayersCnt(int compOnlyPlayersCnt)
  199. {
  200. if(compOnlyPlayersCnt == CMapGenOptions::RANDOM_SIZE)
  201. {
  202. return;
  203. }
  204. if(mapGenOptions->getCompOnlyTeamCount() >= compOnlyPlayersCnt)
  205. {
  206. int compOnlyTeamCount = compOnlyPlayersCnt == 0 ? 0 : compOnlyPlayersCnt - 1;
  207. mapGenOptions->setCompOnlyTeamCount(compOnlyTeamCount);
  208. updateMapInfoByHost();
  209. if(auto w = dynamic_pointer_cast<CToggleGroup>(widget("groupCompOnlyTeams")))
  210. w->setSelected(compOnlyTeamCount);
  211. }
  212. }
  213. std::vector<int> RandomMapTab::getPossibleMapSizes()
  214. {
  215. return {CMapHeader::MAP_SIZE_SMALL, CMapHeader::MAP_SIZE_MIDDLE, CMapHeader::MAP_SIZE_LARGE, CMapHeader::MAP_SIZE_XLARGE, CMapHeader::MAP_SIZE_HUGE, CMapHeader::MAP_SIZE_XHUGE, CMapHeader::MAP_SIZE_GIANT};
  216. }