windownewmap.cpp 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. /*
  2. * windownewmap.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 "../lib/mapping/CMap.h"
  12. #include "../lib/rmg/CRmgTemplateStorage.h"
  13. #include "../lib/rmg/CRmgTemplate.h"
  14. #include "../lib/rmg/CMapGenerator.h"
  15. #include "../lib/VCMI_Lib.h"
  16. #include "../lib/mapping/CMapEditManager.h"
  17. #include "../lib/CGeneralTextHandler.h"
  18. #include "windownewmap.h"
  19. #include "ui_windownewmap.h"
  20. #include "mainwindow.h"
  21. #include "generatorprogress.h"
  22. WindowNewMap::WindowNewMap(QWidget *parent) :
  23. QDialog(parent),
  24. ui(new Ui::WindowNewMap)
  25. {
  26. ui->setupUi(this);
  27. setAttribute(Qt::WA_DeleteOnClose);
  28. setWindowModality(Qt::ApplicationModal);
  29. loadUserSettings();
  30. show();
  31. //setup initial parameters
  32. mapGenOptions.setWidth(ui->widthTxt->text().toInt());
  33. mapGenOptions.setHeight(ui->heightTxt->text().toInt());
  34. bool twoLevel = ui->twoLevelCheck->isChecked();
  35. mapGenOptions.setHasTwoLevels(twoLevel);
  36. updateTemplateList();
  37. }
  38. WindowNewMap::~WindowNewMap()
  39. {
  40. saveUserSettings();
  41. delete ui;
  42. }
  43. void WindowNewMap::loadUserSettings()
  44. {
  45. //load window settings
  46. QSettings s(Ui::teamName, Ui::appName);
  47. auto width = s.value(newMapWidth);
  48. if (width.isValid())
  49. {
  50. ui->widthTxt->setText(width.toString());
  51. }
  52. auto height = s.value(newMapHeight);
  53. if (height.isValid())
  54. {
  55. ui->heightTxt->setText(height.toString());
  56. }
  57. auto twoLevel = s.value(newMapTwoLevel);
  58. if (twoLevel.isValid())
  59. {
  60. ui->twoLevelCheck->setChecked(twoLevel.toBool());
  61. }
  62. auto generateRandom = s.value(newMapGenerateRandom);
  63. if (generateRandom.isValid())
  64. {
  65. ui->randomMapCheck->setChecked(generateRandom.toBool());
  66. }
  67. auto players = s.value(newMapPlayers);
  68. if (players.isValid())
  69. {
  70. ui->humanCombo->setCurrentIndex(players.toInt());
  71. }
  72. auto cpuPlayers = s.value(newMapCpuPlayers);
  73. if (cpuPlayers.isValid())
  74. {
  75. ui->cpuCombo->setCurrentIndex(cpuPlayers.toInt());
  76. }
  77. //TODO: teams when implemented
  78. auto waterContent = s.value(newMapWaterContent);
  79. if (waterContent.isValid())
  80. {
  81. switch (waterContent.toInt())
  82. {
  83. case EWaterContent::RANDOM:
  84. ui->waterOpt1->setChecked(true); break;
  85. case EWaterContent::NONE:
  86. ui->waterOpt2->setChecked(true); break;
  87. case EWaterContent::NORMAL:
  88. ui->waterOpt3->setChecked(true); break;
  89. case EWaterContent::ISLANDS:
  90. ui->waterOpt4->setChecked(true); break;
  91. }
  92. }
  93. auto monsterStrength = s.value(newMapMonsterStrength);
  94. if (monsterStrength.isValid())
  95. {
  96. switch (monsterStrength.toInt())
  97. {
  98. case EMonsterStrength::RANDOM:
  99. ui->monsterOpt1->setChecked(true); break;
  100. case EMonsterStrength::GLOBAL_WEAK:
  101. ui->monsterOpt2->setChecked(true); break;
  102. case EMonsterStrength::GLOBAL_NORMAL:
  103. ui->monsterOpt3->setChecked(true); break;
  104. case EMonsterStrength::GLOBAL_STRONG:
  105. ui->monsterOpt4->setChecked(true); break;
  106. }
  107. }
  108. auto templateName = s.value(newMapTemplate);
  109. if (templateName.isValid())
  110. {
  111. updateTemplateList();
  112. auto* templ = VLC->tplh->getTemplate(templateName.toString().toStdString());
  113. if (templ)
  114. {
  115. ui->templateCombo->setCurrentText(templateName.toString());
  116. //TODO: validate inside this method
  117. mapGenOptions.setMapTemplate(templ);
  118. }
  119. else
  120. {
  121. //Display problem on status bar
  122. }
  123. }
  124. }
  125. void WindowNewMap::saveUserSettings()
  126. {
  127. QSettings s(Ui::teamName, Ui::appName);
  128. s.setValue(newMapWidth, ui->widthTxt->text().toInt());
  129. s.setValue(newMapHeight, ui->heightTxt->text().toInt());
  130. s.setValue(newMapTwoLevel, ui->twoLevelCheck->isChecked());
  131. s.setValue(newMapGenerateRandom, ui->randomMapCheck->isChecked());
  132. s.setValue(newMapPlayers,ui->humanCombo->currentIndex());
  133. s.setValue(newMapCpuPlayers,ui->cpuCombo->currentIndex());
  134. //TODO: teams when implemented
  135. EWaterContent::EWaterContent water = EWaterContent::RANDOM;
  136. if(ui->waterOpt1->isChecked())
  137. water = EWaterContent::RANDOM;
  138. else if(ui->waterOpt2->isChecked())
  139. water = EWaterContent::NONE;
  140. else if(ui->waterOpt3->isChecked())
  141. water = EWaterContent::NORMAL;
  142. else if(ui->waterOpt4->isChecked())
  143. water = EWaterContent::ISLANDS;
  144. s.setValue(newMapWaterContent, static_cast<int>(water));
  145. EMonsterStrength::EMonsterStrength monster = EMonsterStrength::RANDOM;
  146. if(ui->monsterOpt1->isChecked())
  147. monster = EMonsterStrength::RANDOM;
  148. else if(ui->monsterOpt2->isChecked())
  149. monster = EMonsterStrength::GLOBAL_WEAK;
  150. else if(ui->monsterOpt3->isChecked())
  151. monster = EMonsterStrength::GLOBAL_NORMAL;
  152. else if(ui->monsterOpt4->isChecked())
  153. monster = EMonsterStrength::GLOBAL_STRONG;
  154. s.setValue(newMapMonsterStrength, static_cast<int>(monster));
  155. auto templateName = ui->templateCombo->currentText();
  156. if (templateName.size())
  157. {
  158. s.setValue(newMapTemplate, templateName);
  159. }
  160. }
  161. void WindowNewMap::on_cancelButton_clicked()
  162. {
  163. close();
  164. }
  165. void generateRandomMap(CMapGenerator & gen, MainWindow * window)
  166. {
  167. window->controller.setMap(gen.generate());
  168. }
  169. std::unique_ptr<CMap> generateEmptyMap(CMapGenOptions & options)
  170. {
  171. std::unique_ptr<CMap> map(new CMap);
  172. map->version = EMapFormat::VCMI;
  173. map->width = options.getWidth();
  174. map->height = options.getHeight();
  175. map->twoLevel = options.getHasTwoLevels();
  176. map->initTerrain();
  177. map->getEditManager()->clearTerrain(&CRandomGenerator::getDefault());
  178. return std::move(map);
  179. }
  180. void WindowNewMap::on_okButton_clicked()
  181. {
  182. EWaterContent::EWaterContent water = EWaterContent::RANDOM;
  183. EMonsterStrength::EMonsterStrength monster = EMonsterStrength::RANDOM;
  184. if(ui->waterOpt1->isChecked())
  185. water = EWaterContent::RANDOM;
  186. if(ui->waterOpt2->isChecked())
  187. water = EWaterContent::NONE;
  188. if(ui->waterOpt3->isChecked())
  189. water = EWaterContent::NORMAL;
  190. if(ui->waterOpt4->isChecked())
  191. water = EWaterContent::ISLANDS;
  192. if(ui->monsterOpt1->isChecked())
  193. monster = EMonsterStrength::RANDOM;
  194. if(ui->monsterOpt2->isChecked())
  195. monster = EMonsterStrength::GLOBAL_WEAK;
  196. if(ui->monsterOpt3->isChecked())
  197. monster = EMonsterStrength::GLOBAL_NORMAL;
  198. if(ui->monsterOpt4->isChecked())
  199. monster = EMonsterStrength::GLOBAL_STRONG;
  200. mapGenOptions.setWaterContent(water);
  201. mapGenOptions.setMonsterStrength(monster);
  202. std::unique_ptr<CMap> nmap;
  203. if(ui->randomMapCheck->isChecked())
  204. {
  205. //verify map template
  206. if(mapGenOptions.getPossibleTemplates().empty())
  207. {
  208. QMessageBox::warning(this, "No template", "No template for parameters scecified. Random map cannot be generated.");
  209. return;
  210. }
  211. int seed = std::time(nullptr);
  212. if(ui->checkSeed->isChecked() && !ui->lineSeed->text().isEmpty())
  213. seed = ui->lineSeed->text().toInt();
  214. CMapGenerator generator(mapGenOptions, seed);
  215. auto progressBarWnd = new GeneratorProgress(generator, this);
  216. progressBarWnd->show();
  217. try
  218. {
  219. auto f = std::async(std::launch::async, &CMapGenerator::generate, &generator);
  220. progressBarWnd->update();
  221. nmap = f.get();
  222. }
  223. catch(const std::exception & e)
  224. {
  225. QMessageBox::critical(this, "RMG failure", e.what());
  226. }
  227. }
  228. else
  229. {
  230. auto f = std::async(std::launch::async, &::generateEmptyMap, std::ref(mapGenOptions));
  231. nmap = f.get();
  232. }
  233. static_cast<MainWindow*>(parent())->controller.setMap(std::move(nmap));
  234. static_cast<MainWindow*>(parent())->initializeMap(true);
  235. close();
  236. }
  237. void WindowNewMap::on_sizeCombo_activated(int index)
  238. {
  239. std::map<int, std::pair<int, int>> sizes
  240. {
  241. {0, {36, 36}},
  242. {1, {72, 72}},
  243. {2, {108, 108}},
  244. {3, {144, 144}},
  245. };
  246. ui->widthTxt->setText(QString::number(sizes[index].first));
  247. ui->heightTxt->setText(QString::number(sizes[index].second));
  248. }
  249. void WindowNewMap::on_twoLevelCheck_stateChanged(int arg1)
  250. {
  251. bool twoLevel = ui->twoLevelCheck->isChecked();
  252. mapGenOptions.setHasTwoLevels(twoLevel);
  253. updateTemplateList();
  254. }
  255. void WindowNewMap::on_humanCombo_activated(int index)
  256. {
  257. int humans = players.at(index);
  258. if(humans > playerLimit)
  259. {
  260. humans = playerLimit;
  261. ui->humanCombo->setCurrentIndex(humans);
  262. return;
  263. }
  264. mapGenOptions.setPlayerCount(humans);
  265. int teams = mapGenOptions.getTeamCount();
  266. if(teams > humans - 1)
  267. {
  268. teams = humans - 1;
  269. //TBD
  270. }
  271. int cpu = mapGenOptions.getCompOnlyPlayerCount();
  272. if(cpu > playerLimit - humans)
  273. {
  274. cpu = playerLimit - humans;
  275. ui->cpuCombo->setCurrentIndex(cpu + 1);
  276. }
  277. int cpuTeams = mapGenOptions.getCompOnlyTeamCount(); //comp only players - 1
  278. if(cpuTeams > cpu - 1)
  279. {
  280. cpuTeams = cpu - 1;
  281. //TBD
  282. }
  283. //void setMapTemplate(const CRmgTemplate * value);
  284. updateTemplateList();
  285. }
  286. void WindowNewMap::on_cpuCombo_activated(int index)
  287. {
  288. int humans = mapGenOptions.getPlayerCount();
  289. int cpu = cpuPlayers.at(index);
  290. if(cpu > playerLimit - humans)
  291. {
  292. cpu = playerLimit - humans;
  293. ui->cpuCombo->setCurrentIndex(cpu + 1);
  294. return;
  295. }
  296. mapGenOptions.setCompOnlyPlayerCount(cpu);
  297. updateTemplateList();
  298. }
  299. void WindowNewMap::on_randomMapCheck_stateChanged(int arg1)
  300. {
  301. randomMap = ui->randomMapCheck->isChecked();
  302. ui->templateCombo->setEnabled(randomMap);
  303. updateTemplateList();
  304. }
  305. void WindowNewMap::on_templateCombo_activated(int index)
  306. {
  307. if(index == 0)
  308. {
  309. mapGenOptions.setMapTemplate(nullptr);
  310. return;
  311. }
  312. auto * templ = data_cast<const CRmgTemplate>(ui->templateCombo->currentData().toLongLong());
  313. mapGenOptions.setMapTemplate(templ);
  314. }
  315. void WindowNewMap::on_widthTxt_textChanged(const QString &arg1)
  316. {
  317. int sz = arg1.toInt();
  318. if(sz > 1)
  319. {
  320. mapGenOptions.setWidth(arg1.toInt());
  321. updateTemplateList();
  322. }
  323. }
  324. void WindowNewMap::on_heightTxt_textChanged(const QString &arg1)
  325. {
  326. int sz = arg1.toInt();
  327. if(sz > 1)
  328. {
  329. mapGenOptions.setHeight(arg1.toInt());
  330. updateTemplateList();
  331. }
  332. }
  333. void WindowNewMap::updateTemplateList()
  334. {
  335. ui->templateCombo->clear();
  336. ui->templateCombo->setCurrentIndex(-1);
  337. if(!randomMap)
  338. return;
  339. mapGenOptions.setMapTemplate(nullptr);
  340. auto templates = mapGenOptions.getPossibleTemplates();
  341. if(templates.empty())
  342. return;
  343. ui->templateCombo->addItem("[default]", 0);
  344. for(auto * templ : templates)
  345. {
  346. ui->templateCombo->addItem(QString::fromStdString(templ->getName()), data_cast(templ));
  347. }
  348. ui->templateCombo->setCurrentIndex(0);
  349. }
  350. void WindowNewMap::on_checkSeed_toggled(bool checked)
  351. {
  352. ui->lineSeed->setEnabled(checked);
  353. }