QuestDialog.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. #include "QuestDialog.h"
  2. #include <Fenster.h>
  3. #include <TextFeld.h>
  4. #include "Game.h"
  5. #include "Quest.h"
  6. QuestDialog::QuestDialog(int playerId)
  7. : UIDialog("quests", playerId, 0)
  8. {
  9. QuestManager* zManager = Game::INSTANCE->zQuestManager();
  10. Framework::Text uiml = "<dialog id=\"quests\" title=\"Quests\" "
  11. "width=\"1200\" height=\"800\">";
  12. uiml.append()
  13. << "<listView id=\"collectionList\" width=\"200\" height=\"100%\" "
  14. "member-height=\"40\" align-top=\"start\" "
  15. "align-left=\"start\" onSelectMessage=\"quests;0\">";
  16. QuestParty* party = zManager->zParty(playerId);
  17. int index = 0;
  18. for (QuestCollection* questCollection : zManager->questCollections)
  19. {
  20. if (questCollection->isVisible(party, zManager))
  21. {
  22. uiml.append() << "<listItem id=\"quest_collection_" << index++
  23. << "\" collectionName=\""
  24. << questCollection->getName() << "\">"
  25. << questCollection->getName() << "</listItem>";
  26. }
  27. }
  28. uiml.append()
  29. << "</listView><questGraph id=\"visible_quest_graph\" width=\"1000\" "
  30. "align-left=\"collectionList\" "
  31. "height=\"100%\"/><frame id=\"questDetailView\" width=\"100%\" "
  32. "height=\"0%\" style=\""
  33. << (Framework::Fenster::Style::Titel
  34. | Framework::Fenster::Style::Erlaubt
  35. | Framework::Fenster::Style::Sichtbar)
  36. << "\" title-height=\"30\" title-font-size=\"20\"/></dialog>";
  37. this->uiml = new Framework::XML::Element(uiml);
  38. }
  39. void QuestDialog::api(
  40. Framework::StreamReader* zRequest, NetworkMessage* zResponse)
  41. {
  42. char typ;
  43. zRequest->lese(&typ, 1);
  44. switch (typ)
  45. {
  46. case 0: // onSelect Message of listView
  47. { // open quest graph
  48. int selection;
  49. zRequest->lese((char*)&selection, 4);
  50. auto questGraph = this->uiml->selectChildsByName("questGraph");
  51. questGraph.selectChildren().remove();
  52. auto listItems
  53. = uiml->selectChildsByName("listView").selectChildren();
  54. listItems.removeAttribute("selected");
  55. listItems
  56. .whereAttributeEquals(
  57. "id", Framework::Text("quest_collection_") + selection)
  58. .forEach([this, &questGraph](
  59. Framework::XML::Element* zElement) {
  60. zElement->setAttribute("selected", "");
  61. auto collectionName
  62. = zElement->getAttributeValue("collectionName");
  63. QuestManager* zManager = Game::INSTANCE->zQuestManager();
  64. auto questCollection
  65. = zManager->zCollection(collectionName);
  66. QuestParty* zParty = zManager->zParty(getPlayerId());
  67. for (Quest* quest : questCollection->quests)
  68. {
  69. if (quest->isVisible(zParty, zManager))
  70. {
  71. questGraph.addChild(
  72. getQuestGraphItem(quest, zParty));
  73. }
  74. }
  75. });
  76. update();
  77. break;
  78. }
  79. case 1: // onClick Message of questGraphItem
  80. { // open quest detail view
  81. unsigned char len;
  82. zRequest->lese((char*)&len, 1);
  83. char* id = new char[len + 1];
  84. zRequest->lese(id, len);
  85. id[len] = 0;
  86. Framework::Text collectionName
  87. = uiml->selectChildsByName("listView")
  88. .selectChildren()
  89. .whereAttributeExists("selected")
  90. .getFirstElement()
  91. .map<Framework::Text>([](auto element) {
  92. return element->getAttributeValue("collectionName");
  93. })
  94. .orElse("");
  95. QuestManager* zManager = Game::INSTANCE->zQuestManager();
  96. QuestCollection* questCollection
  97. = zManager->zCollection(collectionName);
  98. QuestParty* zParty = zManager->zParty(getPlayerId());
  99. for (Quest* quest : questCollection->quests)
  100. {
  101. if (quest->isActive(zParty)
  102. && quest->getQuestId().istGleich(id))
  103. {
  104. QuestStorage* zStorage
  105. = zParty->zQuestStorage(quest->questId);
  106. uiml->selectChildsByAttribute("id", "collectionList")
  107. .setAttribute("height", "0");
  108. uiml->selectChildsByAttribute("id", "visible_quest_graph")
  109. .setAttribute("height", "0");
  110. auto questView
  111. = uiml->selectChildsByAttribute("id", "questDetailView")
  112. .getFirstElement();
  113. questView->setAttribute("height", "100%");
  114. questView->setAttribute("questId", quest->questId);
  115. questView->removeAllChilds();
  116. showQuestDetails(quest,
  117. zStorage,
  118. (Framework::RCPointer<Framework::XML::Element>)
  119. questView);
  120. break;
  121. }
  122. }
  123. delete[] id;
  124. break;
  125. }
  126. case 2: // onClick Message of back_to_graph
  127. {
  128. auto detailView
  129. = uiml->selectChildsByAttribute("id", "questDetailView");
  130. detailView.removeAllChilds();
  131. detailView.setAttribute("height", "0");
  132. uiml->selectChildsByAttribute("id", "collectionList")
  133. .setAttribute("height", "100%");
  134. uiml->selectChildsByAttribute("id", "visible_quest_graph")
  135. .setAttribute("height", "100%");
  136. update();
  137. break;
  138. }
  139. case 3: // onClick Message of give_rewards
  140. {
  141. Framework::Text collectionName
  142. = uiml->selectChildsByName("listView")
  143. .selectChildren()
  144. .whereAttributeExists("selected")
  145. .getFirstElement()
  146. .map<Framework::Text>([](auto element) {
  147. return element->getAttributeValue("collectionName");
  148. })
  149. .orElse("");
  150. QuestManager* zManager = Game::INSTANCE->zQuestManager();
  151. QuestCollection* questCollection
  152. = zManager->zCollection(collectionName);
  153. QuestParty* zParty = zManager->zParty(getPlayerId());
  154. Framework::Text questId
  155. = uiml->selectChildsByAttribute("id", "questDetailView")
  156. .getFirstElement()
  157. ->getAttributeValue("questId");
  158. for (Quest* quest : questCollection->quests)
  159. {
  160. if (quest->getQuestId().istGleich(questId))
  161. {
  162. QuestStorage* zStorage
  163. = zParty->zQuestStorage(quest->questId);
  164. if (zStorage->isQuestFinished()
  165. && !zStorage->isQuestRewarded())
  166. {
  167. Framework::XML::Element* rewardContainer
  168. = (Framework::RCPointer<Framework::XML::Element>)
  169. uiml->selectChildren()
  170. .selectAllElements()
  171. .whereAttributeEquals(
  172. "id", "quest_rewards")
  173. .getFirstElement();
  174. bool valid = 1;
  175. for (auto reward : quest->rewards)
  176. {
  177. valid &= reward->validateSettings(
  178. rewardContainer, zStorage);
  179. }
  180. if (valid)
  181. {
  182. zStorage->setQuestRewarded(1);
  183. for (auto reward : quest->rewards)
  184. {
  185. reward->giveReward(rewardContainer,
  186. zStorage,
  187. Game::INSTANCE->zEntity(getPlayerId()));
  188. }
  189. auto questView = uiml->selectChildsByAttribute(
  190. "id", "questDetailView")
  191. .getFirstElement();
  192. questView->removeAllChilds();
  193. showQuestDetails(quest,
  194. zStorage,
  195. (Framework::RCPointer<Framework::XML::Element>)
  196. questView);
  197. }
  198. break;
  199. }
  200. }
  201. }
  202. break;
  203. }
  204. case 4: // requirement message
  205. {
  206. Framework::Text collectionName
  207. = uiml->selectChildsByName("listView")
  208. .selectChildren()
  209. .whereAttributeExists("selected")
  210. .getFirstElement()
  211. .map<Framework::Text>([](auto element) {
  212. return element->getAttributeValue("collectionName");
  213. })
  214. .orElse("");
  215. QuestManager* zManager = Game::INSTANCE->zQuestManager();
  216. QuestCollection* questCollection
  217. = zManager->zCollection(collectionName);
  218. QuestParty* zParty = zManager->zParty(getPlayerId());
  219. Framework::Text questId
  220. = uiml->selectChildsByAttribute("id", "questDetailView")
  221. .getFirstElement()
  222. ->getAttributeValue("questId");
  223. unsigned char len;
  224. zRequest->lese((char*)&len, 1);
  225. char* requirementId = new char[len + 1];
  226. requirementId[len] = 0;
  227. auto requirementsContainer
  228. = uiml->selectChildsByAttribute("id", "quest_requirements");
  229. if (requirementsContainer.exists())
  230. {
  231. for (Quest* quest : questCollection->quests)
  232. {
  233. if (quest->getQuestId().istGleich(questId))
  234. {
  235. for (QuestRequirement* requirement :
  236. quest->requirements)
  237. {
  238. if (requirement->getRequirementId().istGleich(
  239. requirementId))
  240. {
  241. requirement->api(zRequest,
  242. (Framework::RCPointer<
  243. Framework::XML::Element>)
  244. requirementsContainer.getFirstElement(),
  245. zParty->zQuestStorage(questId));
  246. }
  247. }
  248. }
  249. }
  250. }
  251. delete[] requirementId;
  252. break;
  253. }
  254. case 5: // reward message
  255. {
  256. Framework::Text collectionName
  257. = uiml->selectChildsByName("listView")
  258. .selectChildren()
  259. .whereAttributeExists("selected")
  260. .getFirstElement()
  261. .map<Framework::Text>([](auto element) {
  262. return element->getAttributeValue("collectionName");
  263. })
  264. .orElse("");
  265. QuestManager* zManager = Game::INSTANCE->zQuestManager();
  266. QuestCollection* questCollection
  267. = zManager->zCollection(collectionName);
  268. QuestParty* zParty = zManager->zParty(getPlayerId());
  269. Framework::Text questId
  270. = uiml->selectChildsByAttribute("id", "questDetailView")
  271. .getFirstElement()
  272. ->getAttributeValue("questId");
  273. unsigned char len;
  274. zRequest->lese((char*)&len, 1);
  275. char* reqardId = new char[len + 1];
  276. reqardId[len] = 0;
  277. auto requirementsContainer
  278. = uiml->selectChildsByAttribute("id", "quest_rewards");
  279. if (requirementsContainer.exists())
  280. {
  281. for (Quest* quest : questCollection->quests)
  282. {
  283. if (quest->getQuestId().istGleich(questId))
  284. {
  285. for (QuestReward* reward : quest->rewards)
  286. {
  287. if (reward->getRewardId().istGleich(reqardId))
  288. {
  289. reward->api(zRequest,
  290. (Framework::RCPointer<
  291. Framework::XML::Element>)
  292. requirementsContainer.getFirstElement(),
  293. zParty->zQuestStorage(questId));
  294. }
  295. }
  296. }
  297. }
  298. }
  299. delete[] reqardId;
  300. break;
  301. }
  302. }
  303. }
  304. Framework::XML::Element* QuestDialog::getQuestGraphItem(
  305. Quest* zQuest, QuestParty* zParty)
  306. {
  307. Framework::Text requirements = "";
  308. int index = 0;
  309. int currentGroup = 0;
  310. for (Framework::Text* requiredQuest : zQuest->requiredQuestsIds)
  311. {
  312. int group = zQuest->requiredQuestsGroups.get(index);
  313. if (index != 0)
  314. { // disjunctive normal form
  315. if (group != currentGroup)
  316. {
  317. requirements += "||";
  318. currentGroup = group;
  319. }
  320. else
  321. {
  322. requirements += "&&";
  323. }
  324. }
  325. else
  326. {
  327. currentGroup = group;
  328. }
  329. requirements += Framework::Text("quest_") + *requiredQuest;
  330. index++;
  331. }
  332. if (!zQuest->isActive(zParty))
  333. {
  334. Framework::Text result = "<questGraphItem id=\"quest_";
  335. result.append()
  336. << zQuest->questId << "\" name=\"Unknown Quest\" image=\""
  337. << zQuest->imagePath
  338. << "\" description=\"You have to finish other quests befor this "
  339. "quest will be available.\" finished=\"false\" "
  340. "rewarded=\"false\" mainQuest=\""
  341. << zQuest->mainQuest << "\" requirements=\"" << requirements
  342. << "\" width=\"" << (zQuest->mainQuest ? "50" : "30")
  343. << "\" height=\"" << (zQuest->mainQuest ? "50" : "30") << "\"/>";
  344. return new Framework::XML::Element(result);
  345. }
  346. else
  347. {
  348. QuestStorage* zStorage = zParty->zQuestStorage(zQuest->questId);
  349. Framework::Text result = "<questGraphItem id=\"quest_";
  350. result.append() << zQuest->questId << "\" name=\""
  351. << zQuest->questName + "\" image=\""
  352. << zQuest->imagePath << "\" description=\""
  353. << zQuest->description << "\" finished=\""
  354. << zStorage->isQuestFinished() << "\" rewarded=\""
  355. << zStorage->isQuestRewarded() << "\" mainQuest=\""
  356. << zQuest->mainQuest << "\" requirements=\""
  357. << requirements << "\" width=\""
  358. << (zQuest->mainQuest ? "50" : "30") << "\" height=\""
  359. << (zQuest->mainQuest ? "50" : "30")
  360. << "\" onClick=\"quests;(char)1;" << zQuest->questId
  361. << "\"/>";
  362. return new Framework::XML::Element(result);
  363. }
  364. }
  365. void QuestDialog::showQuestDetails(
  366. Quest* zQuest, QuestStorage* zStorage, Framework::XML::Element* zParent)
  367. {
  368. zParent->setAttribute("title", zQuest->questName);
  369. zParent->addChild(new Framework::XML::Element(
  370. (((Framework::Text("<text id=\"quest_description\" width=\"50% - 15\" "
  371. "height=\"50% - 10\" "
  372. "align-left=\"start\" margin-left=\"10\" "
  373. "align-top=\"start\" margin-top=\"10\" border=\"1\" "
  374. "border-color=\"0xFF52525E\" vScroll=\"auto\" "
  375. "style=\"")
  376. += Framework::TextFeld::Style::Text
  377. | Framework::TextFeld::Style::Mehrzeilig
  378. | Framework::TextFeld::Style::AutoLineBreak)
  379. += "\">")
  380. += zQuest->description)
  381. += "</text>"));
  382. Framework::XML::Element* requirementsContainer
  383. = new Framework::XML::Element(
  384. "<frame id=\"quest_requirements\" align-left=\"quest_description\" "
  385. "margin-left=\"10\" "
  386. "align-top=\"start\" margin-top=\"10\" width=\"50% - 15\" "
  387. "height=\"100% - "
  388. "50\" vScroll=\"auto\" display=\"column\" gap=\"10\" border=\"1\" "
  389. "border-color=\"0xFF52525E\"/>");
  390. requirementsContainer->addChild(new Framework::XML::Element(
  391. "<text id=\"quest_requirements_title\" width=\"100%\" "
  392. "height=\"30\" text-align-horizontal=\"center\" "
  393. "text-align-vertical=\"center\" "
  394. "font-size=\"20\">Requirements</text>"));
  395. requirementsContainer->setAttribute("style",
  396. Framework::Text() += (Framework::Fenster::Style::Sichtbar
  397. | Framework::Fenster::Style::Erlaubt
  398. | Framework::Fenster::Style::Rahmen));
  399. for (QuestRequirement* requirement : zQuest->requirements)
  400. {
  401. requirement->addRequirementUIML(zStorage,
  402. requirementsContainer,
  403. Framework::Text("quests;(char)4;")
  404. += requirement->getRequirementId());
  405. }
  406. zParent->addChild(requirementsContainer);
  407. Framework::XML::Element* rewardsContainer = new Framework::XML::Element(
  408. "<frame id=\"quest_rewards\" align-left=\"start\" margin-left=\"10\" "
  409. "margin-top=\"10\" "
  410. "align-top=\"quest_description\" width=\"50% - 15\" height=\"50% - "
  411. "20\" vScroll=\"auto\" display=\"column\" gap=\"10\" border=\"1\" "
  412. "border-color=\"0xFF52525E\"/>");
  413. rewardsContainer->addChild(new Framework::XML::Element(
  414. "<text id=\"quest_rewards_title\" width=\"100%\" height=\"30\" "
  415. "text-align-horizontal=\"center\" text-align-vertical=\"center\" "
  416. "font-size=\"20\">Rewards</text>"));
  417. rewardsContainer->setAttribute("style",
  418. Framework::Text() += (Framework::Fenster::Style::Sichtbar
  419. | Framework::Fenster::Style::Erlaubt
  420. | Framework::Fenster::Style::Rahmen));
  421. for (QuestReward* reward : zQuest->rewards)
  422. {
  423. reward->addRewardUIML(rewardsContainer,
  424. zStorage,
  425. Framework::Text("quests;(char)5;") += reward->getRewardId());
  426. }
  427. zParent->addChild(rewardsContainer);
  428. zParent->addChild(new Framework::XML::Element(
  429. "<button id=\"back_to_graph\" width=\"100\" height=\"20\" "
  430. "align-right=\"end\" align-top=\"quest_requirements\" "
  431. "margin-right=\"10\" margin-top=\"10\" "
  432. "onClick=\"quests;(char)2\">Back</button>"));
  433. if (zStorage->isQuestFinished() && !zStorage->isQuestRewarded())
  434. {
  435. zParent->addChild(new Framework::XML::Element(
  436. "<button id=\"give_rewards\" width=\"100\" height=\"20\" "
  437. "align-left=\"quest_rewards\" align-top=\"quest_requirements\" "
  438. "margin-left=\"10\" margin-top=\"10\" "
  439. "onClick=\"quests;(char)3\">Give rewards</button>"));
  440. }
  441. update();
  442. }