#include "QuestDialog.h" #include #include #include "Game.h" #include "Quest.h" #include "UIMLBuilder.h" QuestDialog::QuestDialog(int playerId) : UIDialog("quests", playerId, 0) { QuestManager* zManager = Game::INSTANCE->zQuestManager(); UIMLListSelectionBuilder* listBuilder = UIMLBuilder::createListSelection() ->setID("collectionList") ->setWidth(200) ->setHeightPercentage(100) ->setItemHeight(40) ->setAlignTopStart() ->setAlignLeftStart() ->setOnSelectNotification("quests", 0); QuestParty* party = zManager->zParty(playerId); int index = 0; for (QuestCollection* questCollection : zManager->questCollections) { if (questCollection->isVisible(party, zManager)) { listBuilder->addItem( Framework::Text("quest_collection_") += index++, questCollection->getName(), false); } } this->uiml = UIMLBuilder::createDialog("quests") ->setTitle("Quests") ->setWidth(1200) ->setHeight(800) ->addElement(listBuilder->build()) ->addElement(UIMLBuilder::createQuestGraph() ->setID("visible_quest_graph") ->setWidth(1000) ->setHeightPercentage(100) ->setAlignLeftToElement("collectionList") ->build()) ->addElement(UIMLBuilder::createContainer() ->setID("questDetailView") ->setWidthPercentage(100) ->setHeightPercentage(0) ->setStyle(Framework::Fenster::Style::Titel | Framework::Fenster::Style::Erlaubt | Framework::Fenster::Style::Sichtbar) ->setTitleHeight(30) ->setTitleFontSize(20) ->build()) ->build(); } void QuestDialog::api( Framework::StreamReader* zRequest, NetworkMessage* zResponse) { char typ; zRequest->lese(&typ, 1); switch (typ) { case 0: // onSelect Message of listView { // open quest graph int selection; zRequest->lese((char*)&selection, 4); auto questGraph = this->uiml->selectChildsByName("questGraph"); questGraph.selectChildren().remove(); auto listItems = uiml->selectChildsByName("listView").selectChildren(); listItems.removeAttribute("selected"); QuestManager* zManager = Game::INSTANCE->zQuestManager(); auto questCollection = zManager->zCollection(selection); QuestParty* zParty = zManager->zParty(getPlayerId()); for (Quest* quest : questCollection->quests) { if (quest->isVisible(zParty, zManager)) { questGraph.addChild(getQuestGraphItem(quest, zParty)); } } listItems .whereAttributeEquals( "id", Framework::Text("quest_collection_") + selection) .forEach( [this, &questGraph](Framework::XML::Element* zElement) { zElement->setAttribute("selected", ""); }); update(); break; } case 1: // onClick Message of questGraphItem { // open quest detail view unsigned char len; zRequest->lese((char*)&len, 1); char* id = new char[len + 1]; zRequest->lese(id, len); id[len] = 0; Framework::Text selectedId = uiml->selectChildsByName("listView") .selectChildren() .whereAttributeExists("selected") .getFirstElement() .map( [](Framework::XML::Element* element) { return element->getAttributeValue("id"); }) .orElse(""); QuestManager* zManager = Game::INSTANCE->zQuestManager(); QuestCollection* questCollection = zManager->zCollection(Framework::TextZuInt( selectedId.getText() + strlen("quest_collection_"), 10)); QuestParty* zParty = zManager->zParty(getPlayerId()); for (Quest* quest : questCollection->quests) { if (quest->isActive(zParty) && quest->getQuestId().istGleich(id)) { QuestStorage* zStorage = zParty->zQuestStorage(quest->questId); uiml->selectChildsByAttribute("id", "collectionList") .setAttribute("height", "0"); uiml->selectChildsByAttribute("id", "visible_quest_graph") .setAttribute("height", "0"); auto questView = uiml->selectChildsByAttribute("id", "questDetailView") .getFirstElement(); questView->setAttribute("height", "100%"); questView->setAttribute("questId", quest->questId); questView->removeAllChilds(); showQuestDetails(quest, zStorage, (Framework::RCPointer) questView); break; } } delete[] id; break; } case 2: // onClick Message of back_to_graph { auto detailView = uiml->selectChildsByAttribute("id", "questDetailView"); detailView.removeAllChilds(); detailView.setAttribute("height", "0"); uiml->selectChildsByAttribute("id", "collectionList") .setAttribute("height", "100%"); uiml->selectChildsByAttribute("id", "visible_quest_graph") .setAttribute("height", "100%"); update(); break; } case 3: // onClick Message of give_rewards { Framework::Text selectedId = uiml->selectChildsByName("listView") .selectChildren() .whereAttributeExists("selected") .getFirstElement() .map([](auto element) { return element->getAttributeValue("id"); }) .orElse(""); QuestManager* zManager = Game::INSTANCE->zQuestManager(); QuestCollection* questCollection = zManager->zCollection(Framework::TextZuInt( selectedId.getText() + strlen("quest_collection_"), 10)); QuestParty* zParty = zManager->zParty(getPlayerId()); Framework::Text questId = uiml->selectChildsByAttribute("id", "questDetailView") .getFirstElement() ->getAttributeValue("questId"); for (Quest* quest : questCollection->quests) { if (quest->getQuestId().istGleich(questId)) { QuestStorage* zStorage = zParty->zQuestStorage(quest->questId); if (zStorage->isQuestFinished() && !zStorage->isQuestRewarded()) { Framework::XML::Element* rewardContainer = (Framework::RCPointer) uiml->selectChildren() .selectAllElements() .whereAttributeEquals( "id", "quest_rewards") .getFirstElement(); bool valid = 1; for (auto reward : quest->rewards) { valid &= reward->validateSettings( rewardContainer, zStorage); } if (valid) { zStorage->setQuestRewarded(1); for (auto reward : quest->rewards) { reward->giveReward(rewardContainer, zStorage, Game::INSTANCE->zEntity(getPlayerId())); } auto questView = uiml->selectChildsByAttribute( "id", "questDetailView") .getFirstElement(); questView->removeAllChilds(); showQuestDetails(quest, zStorage, (Framework::RCPointer) questView); } break; } } } break; } case 4: // requirement message { Framework::Text selectedId = uiml->selectChildsByName("listView") .selectChildren() .whereAttributeExists("selected") .getFirstElement() .map([](auto element) { return element->getAttributeValue("id"); }) .orElse(""); QuestManager* zManager = Game::INSTANCE->zQuestManager(); QuestCollection* questCollection = zManager->zCollection(Framework::TextZuInt( selectedId.getText() + strlen("quest_collection_"), 10)); QuestParty* zParty = zManager->zParty(getPlayerId()); Framework::Text questId = uiml->selectChildsByAttribute("id", "questDetailView") .getFirstElement() ->getAttributeValue("questId"); unsigned char len; zRequest->lese((char*)&len, 1); char* requirementId = new char[len + 1]; requirementId[len] = 0; auto requirementsContainer = uiml->selectChildsByAttribute("id", "quest_requirements"); if (requirementsContainer.exists()) { for (Quest* quest : questCollection->quests) { if (quest->getQuestId().istGleich(questId)) { for (QuestRequirement* requirement : quest->requirements) { if (requirement->getRequirementId().istGleich( requirementId)) { requirement->api(zRequest, (Framework::RCPointer< Framework::XML::Element>) requirementsContainer.getFirstElement(), zParty->zQuestStorage(questId)); } } } } } delete[] requirementId; break; } case 5: // reward message { Framework::Text selectedId = uiml->selectChildsByName("listView") .selectChildren() .whereAttributeExists("selected") .getFirstElement() .map([](auto element) { return element->getAttributeValue("id"); }) .orElse(""); QuestManager* zManager = Game::INSTANCE->zQuestManager(); QuestCollection* questCollection = zManager->zCollection(Framework::TextZuInt( selectedId.getText() + strlen("quest_collection_"), 10)); QuestParty* zParty = zManager->zParty(getPlayerId()); Framework::Text questId = uiml->selectChildsByAttribute("id", "questDetailView") .getFirstElement() ->getAttributeValue("questId"); unsigned char len; zRequest->lese((char*)&len, 1); char* reqardId = new char[len + 1]; reqardId[len] = 0; auto requirementsContainer = uiml->selectChildsByAttribute("id", "quest_rewards"); if (requirementsContainer.exists()) { for (Quest* quest : questCollection->quests) { if (quest->getQuestId().istGleich(questId)) { for (QuestReward* reward : quest->rewards) { if (reward->getRewardId().istGleich(reqardId)) { reward->api(zRequest, (Framework::RCPointer< Framework::XML::Element>) requirementsContainer.getFirstElement(), zParty->zQuestStorage(questId)); } } } } } delete[] reqardId; break; } } } Framework::XML::Element* QuestDialog::getQuestGraphItem( Quest* zQuest, QuestParty* zParty) { Framework::Text requirements = ""; int index = 0; int currentGroup = 0; for (Framework::Text* requiredQuest : zQuest->requiredQuestsIds) { int group = zQuest->requiredQuestsGroups.get(index); if (index != 0) { // disjunctive normal form if (group != currentGroup) { requirements += "||"; currentGroup = group; } else { requirements += "&&"; } } else { currentGroup = group; } requirements += Framework::Text("quest_") + *requiredQuest; index++; } if (!zQuest->isActive(zParty)) { return UIMLBuilder::createQuestNode() ->setID(Framework::Text("quest_") += zQuest->questId) ->setQuestName("Unknown Quest") ->setImagePath(zQuest->imagePath) ->setDescription("You have to finish other quests befor this " "quest will be available.") ->setFinished(0) ->setRewarded(0) ->setMainQuest(zQuest->mainQuest) ->setRequirements(requirements) ->setWidth(zQuest->mainQuest ? 50 : 30) ->setHeight(zQuest->mainQuest ? 50 : 30) ->build(); } else { QuestStorage* zStorage = zParty->zQuestStorage(zQuest->questId); return UIMLBuilder::createQuestNode() ->setID(Framework::Text("quest_") += zQuest->questId) ->setQuestName(zQuest->questName) ->setImagePath(zQuest->imagePath) ->setDescription(zQuest->description) ->setFinished(zStorage->isQuestFinished()) ->setRewarded(zStorage->isQuestRewarded()) ->setMainQuest(zQuest->mainQuest) ->setRequirements(requirements) ->setWidth(zQuest->mainQuest ? 50 : 30) ->setHeight(zQuest->mainQuest ? 50 : 30) ->setOnClickMessage("quests", {1}) ->build(); } } void QuestDialog::showQuestDetails( Quest* zQuest, QuestStorage* zStorage, Framework::XML::Element* zParent) { zParent->setAttribute("title", zQuest->questName); zParent->addChild(UIMLBuilder::createText(zQuest->description) ->setID("quest_description") ->setWidth(50, -15) ->setHeight(50, -10) ->setAlignLeftStart() ->setMarginLeft(10) ->setAlignTopStart() ->setMarginTop(10) ->setBorder(1, 0xFF52525E) ->enableVerticalScrollbar() ->setStyle(Framework::TextFeld::Style::Text | Framework::TextFeld::Style::Mehrzeilig | Framework::TextFeld::Style::AutoLineBreak) ->build()); UIMLContainerBuilder* requirementsContainerBuilder = UIMLBuilder::createContainer() ->setID("quest_requirements") ->setAlignLeftToElement("quest_description") ->setMarginLeft(10) ->setAlignTopStart() ->setMarginTop(10) ->setWidth(50, -15) ->setHeight(100, -50) ->setDisplayAsColumn(0, 10) ->setBorder(1, 0xFF52525E) ->setStyle(Framework::Fenster::Style::Sichtbar | Framework::Fenster::Style::Erlaubt | Framework::Fenster::Style::Rahmen) ->enableVerticalScrollbar() ->addChild(UIMLBuilder::createText("Requirements") ->setID("quest_requirements_title") ->setWidthPercentage(100) ->setHeight(30) ->setStyle(Framework::TextFeld::Style::Text | Framework::TextFeld::Style::Center) ->setFontSize(20) ->build()); for (QuestRequirement* requirement : zQuest->requirements) { requirement->addRequirementUIML(zStorage, requirementsContainerBuilder); } zParent->addChild(requirementsContainerBuilder->build()); UIMLContainerBuilder* rewardsContainerBuilder = UIMLBuilder::createContainer() ->setID("quest_rewards") ->setAlignLeftStart() ->setMarginLeft(10) ->setAlignTopToElement("quest_description") ->setMarginTop(10) ->setWidth(50, -15) ->setHeight(50, -20) ->setDisplayAsColumn(0, 10) ->setBorder(1, 0xFF52525E) ->setStyle(Framework::Fenster::Style::Sichtbar | Framework::Fenster::Style::Erlaubt | Framework::Fenster::Style::Rahmen) ->enableVerticalScrollbar() ->addChild(UIMLBuilder::createText("Rewards") ->setID("quest_rewards_title") ->setWidthPercentage(100) ->setHeight(30) ->setStyle(Framework::TextFeld::Style::Text | Framework::TextFeld::Style::Center) ->setFontSize(20) ->build()); for (QuestReward* reward : zQuest->rewards) { reward->addRewardUIML(rewardsContainerBuilder, zStorage); } zParent->addChild(rewardsContainerBuilder->build()); zParent->addChild(UIMLBuilder::createButton("Back") ->setID("back_to_graph") ->setWidth(100) ->setHeight(20) ->setAlignRightEnd() ->setMarginRight(10) ->setAlignTopToElement("quest_requirements") ->setMarginTop(10) ->setOnClickMessage("quests", {2}) ->build()); if (zStorage->isQuestFinished() && !zStorage->isQuestRewarded()) { zParent->addChild(UIMLBuilder::createButton("Give rewards") ->setID("give_rewards") ->setWidth(100) ->setHeight(20) ->setAlignLeftToElement("quest_rewards") ->setMarginLeft(10) ->setAlignTopToElement("quest_requirements") ->setMarginTop(10) ->setOnClickMessage("quests", {3}) ->build()); } update(); }