Selaa lähdekoodia

finish implementing server sided quest dialog

Kolja Strohm 9 kuukautta sitten
vanhempi
commit
c5d06b0ae1

+ 1 - 1
FactoryCraft/Dimension.cpp

@@ -920,7 +920,7 @@ void Dimension::updateMap(int x, int y, int height)
             || (h1 > 0
                 && cMap->update((char)chunkLocation.x,
                     (char)chunkLocation.y,
-                    (unsigned char)(chunkLocation.z / 2) - 1,
+                    (unsigned char)(chunkLocation.z / 2 - 1),
                     color1m,
                     color2m)))
         {

+ 3 - 3
FactoryCraft/DimensionGenerator.cpp

@@ -59,7 +59,7 @@ Framework::JSON::Validator::JSONValidator* WorldHeightLayer::getValidator()
 }
 
 DimensionGenerator::DimensionGenerator(
-    Framework::JSON::JSONValue* zConfig, int worldSeed)
+    Framework::JSON::JSONValue* zConfig, int worldSeed, int dimensionId)
     : ReferenceCounter(),
       jExpressionMemory(new JExpressionMemory()),
       dimensionId(dimensionId)
@@ -100,8 +100,8 @@ int DimensionGenerator::getDimensionId() const
 }
 
 BiomedCavedDimensionGenerator::BiomedCavedDimensionGenerator(
-    Framework::JSON::JSONValue* zConfig, int worldSeed)
-    : DimensionGenerator(zConfig, worldSeed),
+    Framework::JSON::JSONValue* zConfig, int worldSeed, int dimensionId)
+    : DimensionGenerator(zConfig, worldSeed, dimensionId),
       caveGenerator(new WormCaveGenerator(75, 150, 1, 6, 0.1f, worldSeed - 1))
 {
     biomNoise = JNoise::parseNoise(

+ 3 - 2
FactoryCraft/DimensionGenerator.h

@@ -37,7 +37,8 @@ private:
     const int dimensionId;
 
 protected:
-    DimensionGenerator(Framework::JSON::JSONValue* zConfig, int worldSeed);
+    DimensionGenerator(
+        Framework::JSON::JSONValue* zConfig, int worldSeed, int dimensionId);
     ~DimensionGenerator();
 
     JExpressionMemory* zMemory() const;
@@ -89,7 +90,7 @@ protected:
 
 public:
     BiomedCavedDimensionGenerator(
-        Framework::JSON::JSONValue* zConfig, int worldSeed);
+        Framework::JSON::JSONValue* zConfig, int worldSeed, int dimensionId);
     ~BiomedCavedDimensionGenerator();
 
     Chunk* generateChunk(int centerX, int centerY);

+ 0 - 1
FactoryCraft/Entity.cpp

@@ -495,7 +495,6 @@ void Entity::notifyStatusBarObservers(NetworkMessage* msg)
 
 ItemSkill* Entity::zSkill(int itemType)
 {
-    ItemSkill* selected = 0;
     for (ItemSkill* skill : skills)
     {
         if (skill->getTypeId() == typeId)

+ 14 - 0
FactoryCraft/FactoryCraft.vcxproj

@@ -97,6 +97,9 @@
   </PropertyGroup>
   <ItemGroup>
     <ClInclude Include="BlockInfoCommand.h" />
+    <ClInclude Include="BlockInstanceGeneratorRule.h" />
+    <ClInclude Include="FactorizeNoise.h" />
+    <ClInclude Include="FlattenNoise.h" />
     <ClInclude Include="GeneratorRule.h" />
     <ClInclude Include="BlockTypeGeneratorRule.h" />
     <ClInclude Include="Chest.h" />
@@ -152,11 +155,14 @@
     <ClInclude Include="ModelInfo.h" />
     <ClInclude Include="MultiblockStructure.h" />
     <ClInclude Include="MultiblockTree.h" />
+    <ClInclude Include="MultiplyNoise.h" />
+    <ClInclude Include="NegateNoise.h" />
     <ClInclude Include="NetworkMessage.h" />
     <ClInclude Include="Noise.h" />
     <ClInclude Include="NoBlock.h" />
     <ClInclude Include="OverworldDimension.h" />
     <ClInclude Include="NoiseInterpolator.h" />
+    <ClInclude Include="OverworldDimensionGenerator.h" />
     <ClInclude Include="Player.h" />
     <ClInclude Include="PlayerHand.h" />
     <ClInclude Include="PlayerRegister.h" />
@@ -170,6 +176,7 @@
     <ClInclude Include="RecipieList.h" />
     <ClInclude Include="RecipieLoader.h" />
     <ClInclude Include="SaveCommand.h" />
+    <ClInclude Include="ScaleNoise.h" />
     <ClInclude Include="Server.h" />
     <ClInclude Include="Dimension.h" />
     <ClInclude Include="ShapedNoise.h" />
@@ -201,6 +208,7 @@
     <ClCompile Include="BiomGenerator.cpp" />
     <ClCompile Include="Block.cpp" />
     <ClCompile Include="BlockInfoCommand.cpp" />
+    <ClCompile Include="BlockInstanceGeneratorRule.cpp" />
     <ClCompile Include="BlockType.cpp" />
     <ClCompile Include="BlockTypeGeneratorRule.cpp" />
     <ClCompile Include="CaveGenerator.cpp" />
@@ -220,7 +228,9 @@
     <ClCompile Include="Entity.cpp" />
     <ClCompile Include="EntityRemovedUpdate.cpp" />
     <ClCompile Include="EntityType.cpp" />
+    <ClCompile Include="FactorizeNoise.cpp" />
     <ClCompile Include="FastNoiseWrapper.cpp" />
+    <ClCompile Include="FlattenNoise.cpp" />
     <ClCompile Include="FluidBlock.cpp" />
     <ClCompile Include="Game.cpp" />
     <ClCompile Include="GeneratedStructure.cpp" />
@@ -245,11 +255,14 @@
     <ClCompile Include="ModelInfo.cpp" />
     <ClCompile Include="MultiblockStructure.cpp" />
     <ClCompile Include="MultiblockTree.cpp" />
+    <ClCompile Include="MultiplyNoise.cpp" />
+    <ClCompile Include="NegateNoise.cpp" />
     <ClCompile Include="NetworkMessage.cpp" />
     <ClCompile Include="NoBlock.cpp" />
     <ClCompile Include="Noise.cpp" />
     <ClCompile Include="OverworldDimension.cpp" />
     <ClCompile Include="NoiseInterpolator.cpp" />
+    <ClCompile Include="OverworldDimensionGenerator.cpp" />
     <ClCompile Include="Player.cpp" />
     <ClCompile Include="PlayerHand.cpp" />
     <ClCompile Include="PlayerRegister.cpp" />
@@ -263,6 +276,7 @@
     <ClCompile Include="Recipie.cpp" />
     <ClCompile Include="RecipieLoader.cpp" />
     <ClCompile Include="SaveCommand.cpp" />
+    <ClCompile Include="ScaleNoise.cpp" />
     <ClCompile Include="Server.cpp" />
     <ClCompile Include="ShapedNoise.cpp" />
     <ClCompile Include="Shovel.cpp" />

+ 50 - 5
FactoryCraft/FactoryCraft.vcxproj.filters

@@ -25,9 +25,6 @@
     <Filter Include="world\generator\noise">
       <UniqueIdentifier>{6a594ea1-a32c-4e11-9f2c-d694f42e9076}</UniqueIdentifier>
     </Filter>
-    <Filter Include="world\generator\dimensions">
-      <UniqueIdentifier>{b04d9ff5-ad58-41e2-8e72-8de835e09c99}</UniqueIdentifier>
-    </Filter>
     <Filter Include="world\ticking">
       <UniqueIdentifier>{03a72d46-51b8-4f26-b04a-f5f4d4f5af6e}</UniqueIdentifier>
     </Filter>
@@ -100,6 +97,12 @@
     <Filter Include="UI">
       <UniqueIdentifier>{cfbafb3b-9692-4bf4-b38c-937cf0d3ddd2}</UniqueIdentifier>
     </Filter>
+    <Filter Include="world\dimensions">
+      <UniqueIdentifier>{b04d9ff5-ad58-41e2-8e72-8de835e09c99}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="world\generator\dimensions">
+      <UniqueIdentifier>{ad05d3d5-d516-4582-ba50-74f9ee112ee1}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="Chunk.h">
@@ -160,7 +163,7 @@
       <Filter>world\generator</Filter>
     </ClInclude>
     <ClInclude Include="OverworldDimension.h">
-      <Filter>world\generator\dimensions</Filter>
+      <Filter>world\dimensions</Filter>
     </ClInclude>
     <ClInclude Include="Constants.h">
       <Filter>game</Filter>
@@ -384,6 +387,27 @@
     <ClInclude Include="QuestDialog.h">
       <Filter>quests</Filter>
     </ClInclude>
+    <ClInclude Include="FactorizeNoise.h">
+      <Filter>world\generator\noise</Filter>
+    </ClInclude>
+    <ClInclude Include="FlattenNoise.h">
+      <Filter>world\generator\noise</Filter>
+    </ClInclude>
+    <ClInclude Include="MultiplyNoise.h">
+      <Filter>world\generator\noise</Filter>
+    </ClInclude>
+    <ClInclude Include="NegateNoise.h">
+      <Filter>world\generator\noise</Filter>
+    </ClInclude>
+    <ClInclude Include="ScaleNoise.h">
+      <Filter>world\generator\noise</Filter>
+    </ClInclude>
+    <ClInclude Include="BlockInstanceGeneratorRule.h">
+      <Filter>world\generator\biom\rules</Filter>
+    </ClInclude>
+    <ClInclude Include="OverworldDimensionGenerator.h">
+      <Filter>world\generator\dimensions</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Server.cpp">
@@ -414,7 +438,7 @@
       <Filter>world\generator</Filter>
     </ClCompile>
     <ClCompile Include="OverworldDimension.cpp">
-      <Filter>world\generator\dimensions</Filter>
+      <Filter>world\dimensions</Filter>
     </ClCompile>
     <ClCompile Include="TickWorker.cpp">
       <Filter>world\ticking</Filter>
@@ -656,5 +680,26 @@
     <ClCompile Include="QuestDialog.cpp">
       <Filter>quests</Filter>
     </ClCompile>
+    <ClCompile Include="FactorizeNoise.cpp">
+      <Filter>world\generator\noise</Filter>
+    </ClCompile>
+    <ClCompile Include="FlattenNoise.cpp">
+      <Filter>world\generator\noise</Filter>
+    </ClCompile>
+    <ClCompile Include="MultiplyNoise.cpp">
+      <Filter>world\generator\noise</Filter>
+    </ClCompile>
+    <ClCompile Include="NegateNoise.cpp">
+      <Filter>world\generator\noise</Filter>
+    </ClCompile>
+    <ClCompile Include="ScaleNoise.cpp">
+      <Filter>world\generator\noise</Filter>
+    </ClCompile>
+    <ClCompile Include="BlockInstanceGeneratorRule.cpp">
+      <Filter>world\generator\biom\rules</Filter>
+    </ClCompile>
+    <ClCompile Include="OverworldDimensionGenerator.cpp">
+      <Filter>world\generator\dimensions</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 2 - 2
FactoryCraft/InformationObserver.cpp

@@ -4,8 +4,8 @@
 
 InformationObserver::InformationObserver(int entityId)
     : ReferenceCounter(),
-      entityId(entityId),
-      ready(false)
+      ready(false),
+      entityId(entityId)
 {}
 
 InformationObserver::~InformationObserver()

+ 1 - 1
FactoryCraft/OverworldDimensionGenerator.cpp

@@ -12,7 +12,7 @@ OverworldDimensionGeneratorFactory::OverworldDimensionGeneratorFactory()
 DimensionGenerator* OverworldDimensionGeneratorFactory::createDimensionGenerator(
     int worldSeed, Framework::JSON::JSONValue* config)
 {
-    return new BiomedCavedDimensionGenerator(config, worldSeed);
+    return new BiomedCavedDimensionGenerator(config, worldSeed, getDimensionId());
 }
 
 Framework::JSON::Validator::JSONValidator*

+ 49 - 95
FactoryCraft/Quest.cpp

@@ -1,43 +1,16 @@
 #include "Quest.h"
 
+#include <Fenster.h>
+#include <TextFeld.h>
+
 #include "Game.h"
 
 QuestRequirementStorage::QuestRequirementStorage(Framework::Text requirementId)
     : ReferenceCounter(),
       requirementId(requirementId),
-      fulfilled(0),
-      data(new Framework::JSON::JSONObject())
+      fulfilled(0)
 {}
 
-QuestRequirementStorage::~QuestRequirementStorage()
-{
-    data->release();
-}
-
-void QuestRequirementStorage::putValue(
-    Framework::Text key, Framework::JSON::JSONValue* value)
-{
-    data->removeValue(key);
-    data->addValue(key, value);
-}
-
-Framework::JSON::JSONValue* QuestRequirementStorage::getValue(
-    Framework::Text key) const
-{
-    return data->getValue(key);
-}
-
-Framework::JSON::JSONValue* QuestRequirementStorage::zValue(
-    Framework::Text key) const
-{
-    return data->zValue(key);
-}
-
-bool QuestRequirementStorage::containsKey(Framework::Text key) const
-{
-    return data->hasValue(key);
-}
-
 void QuestRequirementStorage::setFullfilled(bool fullfilled)
 {
     this->fulfilled = fullfilled;
@@ -64,8 +37,6 @@ QuestRequirementStorage* QuestRequirementStorageType::fromJson(
         zJson->asObject()->zValue("requirementId")->asString()->getString());
     result->setFullfilled(
         zJson->asObject()->zValue("fulfilled")->asBool()->getBool());
-    result->data->release();
-    result->data = zJson->asObject()->getValue("data")->asObject();
     return result;
 }
 
@@ -77,8 +48,6 @@ Framework::JSON::JSONValue* QuestRequirementStorageType::toJson(
         new Framework::JSON::JSONString(zObject->getRequirementId()));
     result->addValue(
         "fulfilled", new Framework::JSON::JSONBool(zObject->isFullfilled()));
-    Framework::Text dataString = zObject->data->toString();
-    result->addValue("data", Framework::JSON::Parser::getValue(dataString));
     return result;
 }
 
@@ -91,17 +60,21 @@ QuestRequirementStorageType::getValidator() const
         ->withRequiredBool("fulfilled")
         ->withDefault(false)
         ->finishBool()
-        ->withRequiredObject("data")
-        ->finishObject()
         ->finishObject();
 }
 
 QuestStorage::QuestStorage(Framework::Text questId)
     : questId(questId),
       finished(0),
-      rewarded(0)
+      rewarded(0),
+      data(new Framework::JSON::JSONObject())
 {}
 
+QuestStorage::~QuestStorage()
+{
+    data->release();
+}
+
 void QuestStorage::setQuestFinished(bool finished)
 {
     this->finished = finished;
@@ -152,6 +125,28 @@ void QuestStorage::setVisible(bool visible)
     this->visible = visible;
 }
 
+void QuestStorage::putValue(
+    Framework::Text key, Framework::JSON::JSONValue* value)
+{
+    data->removeValue(key);
+    data->addValue(key, value);
+}
+
+Framework::JSON::JSONValue* QuestStorage::getValue(Framework::Text key) const
+{
+    return data->getValue(key);
+}
+
+Framework::JSON::JSONValue* QuestStorage::zValue(Framework::Text key) const
+{
+    return data->zValue(key);
+}
+
+bool QuestStorage::containsKey(Framework::Text key) const
+{
+    return data->hasValue(key);
+}
+
 QuestStorageType::QuestStorageType()
     : TypeFactory<QuestStorage>()
 {}
@@ -173,6 +168,8 @@ QuestStorage* QuestStorageType::fromJson(
             Game::INSTANCE->zTypeRegistry()->fromJson<QuestRequirementStorage>(
                 rewardsArray->zValue(i)->asObject()));
     }
+    result->data->release();
+    result->data = zJson->asObject()->getValue("data")->asObject();
     return result;
 }
 
@@ -193,6 +190,8 @@ Framework::JSON::JSONValue* QuestStorageType::toJson(
             Game::INSTANCE->zTypeRegistry()->toJson(storage));
     }
     result->addValue("requirements", rewardsArray);
+    Framework::Text dataString = zObject->data->toString();
+    result->addValue("data", Framework::JSON::Parser::getValue(dataString));
     return result;
 }
 
@@ -212,6 +211,9 @@ QuestStorageType::getValidator() const
         ->addAcceptedTypeInArray(Game::INSTANCE->zTypeRegistry()
                                      ->getValidator<QuestRequirementStorage>())
         ->finishArray()
+        ->withRequiredObject("data")
+        ->allowAdditionalAttriutes()
+        ->finishObject()
         ->finishObject();
 }
 
@@ -343,7 +345,7 @@ void Quest::processEvent(QuestEvent* zEvent, QuestStorage* zStorage)
             = zStorage->zStorage(requirement->getRequirementId());
         if (!zRequirementStorage->isFullfilled())
         {
-            requirement->processEvent(zEvent, zRequirementStorage);
+            requirement->processEvent(zEvent, zStorage);
             finished &= zRequirementStorage->isFullfilled();
         }
     }
@@ -401,27 +403,6 @@ const Framework::Text& Quest::getQuestId() const
     return questId;
 }
 
-Framework::Text Quest::getQuestViewUIML(QuestStorage* zStorage)
-{
-    Framework::Text result = "<questView id=\"";
-    result.append() << questId << "\" name=\""
-                    << questName + "\" description=\"" << description
-                    << "\" finished=\"" << zStorage->isQuestFinished()
-                    << "\" rewarded=\"" << zStorage->isQuestRewarded() << "\">";
-    for (QuestRequirement* requirement : requirements)
-    {
-        result += requirement->getRequirementUIML(
-            zStorage->zStorage(requirement->getRequirementId()));
-    }
-    for (QuestReward* reward : rewards)
-    {
-        result += reward->getRewardUIML();
-    }
-
-    result += "</questView>";
-    return result;
-}
-
 void Quest::setVisible(bool visible, QuestParty* zParty, QuestManager* zManager)
 {
     if (zParty->zQuestStorage(questId)->isVisible() == visible)
@@ -574,8 +555,7 @@ QuestCollection::QuestCollection(Framework::Text name)
       name(name)
 {}
 
-void QuestCollection::processEvent(
-    QuestEvent* zEvent, QuestParty* zParty)
+void QuestCollection::processEvent(QuestEvent* zEvent, QuestParty* zParty)
 {
     for (Quest* quest : quests)
     {
@@ -627,20 +607,6 @@ const Framework::Text& QuestCollection::getName() const
     return name;
 }
 
-Framework::Text QuestCollection::getQuestViewUIML(
-    QuestParty* zParty, Framework::Text questId)
-{
-    for (Quest* quest : quests)
-    {
-        if (quest->getQuestId().istGleich(questId))
-        {
-            QuestStorage* zStorage = zParty->zQuestStorage(quest->getQuestId());
-            return quest->getQuestViewUIML(zStorage);
-        }
-    }
-    return "";
-}
-
 void QuestCollection::setQuestVisible(bool visible,
     Framework::Text questId,
     QuestParty* zParty,
@@ -724,13 +690,13 @@ QuestParty* QuestManager::zParty(int entityId)
 QuestCollection* QuestManager::zCollection(Framework::Text collectionName)
 {
     for (QuestCollection* collection : questCollections)
-	{
-		if (collection->getName().istGleich(collectionName))
-		{
-			return collection;
-		}
-	}
-	return 0;
+    {
+        if (collection->getName().istGleich(collectionName))
+        {
+            return collection;
+        }
+    }
+    return 0;
 }
 
 void QuestManager::loadQuests()
@@ -883,18 +849,6 @@ void QuestManager::giveReward(
     }
 }
 
-Framework::Text QuestManager::getQuestViewUIML(
-    Entity* zTargetEntity, Framework::Text questId)
-{
-    Framework::Text result = "";
-    QuestParty* party = zParty(zTargetEntity->getId());
-    for (QuestCollection* questCollection : questCollections)
-    {
-        result += questCollection->getQuestViewUIML(party, questId);
-    }
-    return result;
-}
-
 void QuestManager::setQuestVisible(
     bool visible, Framework::Text questId, QuestParty* zParty)
 {

+ 6 - 11
FactoryCraft/Quest.h

@@ -14,16 +14,10 @@ class QuestRequirementStorage : public virtual Framework::ReferenceCounter
 private:
     Framework::Text requirementId;
     bool fulfilled;
-    Framework::JSON::JSONObject* data;
 
 public:
     QuestRequirementStorage(Framework::Text requirementId);
-    ~QuestRequirementStorage();
 
-    void putValue(Framework::Text key, Framework::JSON::JSONValue* value);
-    Framework::JSON::JSONValue* getValue(Framework::Text key) const;
-    Framework::JSON::JSONValue* zValue(Framework::Text key) const;
-    bool containsKey(Framework::Text key) const;
     void setFullfilled(bool fullfilled);
     bool isFullfilled() const;
     const Framework::Text& getRequirementId() const;
@@ -52,9 +46,11 @@ private:
     bool rewarded;
     bool visible;
     Framework::RCArray<QuestRequirementStorage> requirements;
+    Framework::JSON::JSONObject* data;
 
 public:
     QuestStorage(Framework::Text questId);
+    ~QuestStorage();
 
     void setQuestFinished(bool finished);
     void setQuestRewarded(bool rewarded);
@@ -64,6 +60,10 @@ public:
     const Framework::Text& getQuestId() const;
     bool isVisible() const;
     void setVisible(bool visible);
+    void putValue(Framework::Text key, Framework::JSON::JSONValue* value);
+    Framework::JSON::JSONValue* getValue(Framework::Text key) const;
+    Framework::JSON::JSONValue* zValue(Framework::Text key) const;
+    bool containsKey(Framework::Text key) const;
 
     friend QuestStorageType;
 };
@@ -132,7 +132,6 @@ public:
     bool isActive(QuestParty* zParty);
     void giveReward(int choice, Entity* zTargetEntity, QuestStorage* zStorage);
     const Framework::Text& getQuestId() const;
-    Framework::Text getQuestViewUIML(QuestStorage* zStorage);
     void setVisible(bool visible, QuestParty* zParty, QuestManager* zManager);
 
     friend QuestType;
@@ -168,8 +167,6 @@ public:
     void addQuest(Quest* zQuest);
 
     const Framework::Text& getName() const;
-    Framework::Text getQuestViewUIML(
-        QuestParty* zParty, Framework::Text questId);
     void setQuestVisible(bool visible,
         Framework::Text questId,
         QuestParty* zParty,
@@ -205,8 +202,6 @@ public:
 
     void processEvent(QuestEvent* event);
     void giveReward(Framework::Text questId, int choice, Entity* zTargetEntity);
-    Framework::Text getQuestViewUIML(
-        Entity* zTargetEntity, Framework::Text questId);
     void setQuestVisible(
         bool visible, Framework::Text questId, QuestParty* zParty);
 

+ 294 - 11
FactoryCraft/QuestDialog.cpp

@@ -1,11 +1,13 @@
 #include "QuestDialog.h"
 
+#include <Fenster.h>
+#include <TextFeld.h>
+
 #include "Game.h"
 
 QuestDialog::QuestDialog(int playerId)
     : UIDialog("quests", playerId, 0)
 {
-
     QuestManager* zManager = Game::INSTANCE->zQuestManager();
     Framework::Text uiml = "<dialog id=\"quests\" title=\"Quests\" "
                            "width=\"1200\" height=\"800\">";
@@ -22,14 +24,18 @@ QuestDialog::QuestDialog(int playerId)
             uiml.append() << "<listItem id=\"quest_collection_" << index++
                           << "\" collectionName=\""
                           << questCollection->getName() << "\">"
-                          << questCollection->getName()
-                          << "</listItem>";
+                          << questCollection->getName() << "</listItem>";
         }
     }
     uiml.append()
         << "</listView><questGraph id=\"visible_quest_graph\" width=\"1000\" "
            "align-left=\"collectionList\" "
-           "height=\"100%\"/></dialog>";
+           "height=\"100%\"/><frame id=\"questDetailView\" width=\"100%\" "
+           "height=\"0%\" style=\""
+        << (Framework::Fenster::Style::Titel
+               | Framework::Fenster::Style::Erlaubt
+               | Framework::Fenster::Style::Sichtbar)
+        << "\" title-height=\"20\"/></dialog>";
     this->uiml = new Framework::XML::Element(uiml);
 }
 
@@ -41,7 +47,7 @@ void QuestDialog::api(
     switch (typ)
     {
     case 0: // onSelect Message of listView
-        {
+        {   // open quest graph
             int selection;
             zRequest->lese((char*)&selection, 4);
             auto questGraph = this->uiml->selectChildsByName("questGraph");
@@ -65,13 +71,216 @@ void QuestDialog::api(
                     {
                         if (quest->isVisible(zParty, zManager))
                         {
-                            questGraph.addChild(getQuestGraphItem(quest, zParty));
+                            questGraph.addChild(
+                                getQuestGraphItem(quest, zParty));
                         }
                     }
                 });
             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 collectionName
+                = uiml->selectChildsByName("listView")
+                      .selectChildren()
+                      .whereAttributeExists("selected")
+                      .getFirstElement()
+                      .map<Framework::Text>([](auto element) {
+                          return element->getAttributeValue("collectionName");
+                      })
+                      .orElse("");
+            QuestManager* zManager = Game::INSTANCE->zQuestManager();
+            QuestCollection* questCollection
+                = zManager->zCollection(collectionName);
+            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<Framework::XML::Element>)
+                            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 collectionName
+                = uiml->selectChildsByName("listView")
+                      .selectChildren()
+                      .whereAttributeExists("selected")
+                      .getFirstElement()
+                      .map<Framework::Text>([](auto element) {
+                          return element->getAttributeValue("collectionName");
+                      })
+                      .orElse("");
+            QuestManager* zManager = Game::INSTANCE->zQuestManager();
+            QuestCollection* questCollection
+                = zManager->zCollection(collectionName);
+            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())
+                    {
+                        auto questView = uiml->selectChildsByAttribute(
+                                                 "id", "questDetailView")
+                                             .getFirstElement();
+                        questView->removeAllChilds();
+
+                        // TODO: give rewards
+
+                        showQuestDetails(quest,
+                            zStorage,
+                            (Framework::RCPointer<Framework::XML::Element>)
+                                questView);
+                        break;
+                    }
+                }
+            }
+            break;
+        }
+    case 4: // requirement message
+        {
+            Framework::Text collectionName
+                = uiml->selectChildsByName("listView")
+                      .selectChildren()
+                      .whereAttributeExists("selected")
+                      .getFirstElement()
+                      .map<Framework::Text>([](auto element) {
+                          return element->getAttributeValue("collectionName");
+                      })
+                      .orElse("");
+            QuestManager* zManager = Game::INSTANCE->zQuestManager();
+            QuestCollection* questCollection
+                = zManager->zCollection(collectionName);
+            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,
+                                    (RCPointer<Framework::XML::Element>)
+                                        requirementsContainer.getFirstElement(),
+                                    zParty->zQuestStorage(questId));
+                            }
+                        }
+                    }
+                }
+            }
+            delete[] requirementId;
+            break;
+        }
+    case 5: // reward message
+        {
+            Framework::Text collectionName
+                = uiml->selectChildsByName("listView")
+                      .selectChildren()
+                      .whereAttributeExists("selected")
+                      .getFirstElement()
+                      .map<Framework::Text>([](auto element) {
+                          return element->getAttributeValue("collectionName");
+                      })
+                      .orElse("");
+            QuestManager* zManager = Game::INSTANCE->zQuestManager();
+            QuestCollection* questCollection
+                = zManager->zCollection(collectionName);
+            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,
+                                    (RCPointer<Framework::XML::Element>)
+                                        requirementsContainer.getFirstElement(),
+                                    zParty->zQuestStorage(questId));
+                            }
+                        }
+                    }
+                }
+            }
+            delete[] reqardId;
+            break;
+        }
     }
 }
 
@@ -123,12 +332,86 @@ Framework::XML::Element* QuestDialog::getQuestGraphItem(
         result.append() << zQuest->questId << "\" name=\""
                         << zQuest->questName + "\" image=\""
                         << zQuest->imagePath << "\" description=\""
-                        << zQuest->description
-                        << "\" finished=\"" << zStorage->isQuestFinished() << "\" mainQuest=\""
-                        << zQuest->mainQuest
-                        << "\" requirements=\"" << requirements << "\" width=\""
+                        << zQuest->description << "\" finished=\""
+                        << zStorage->isQuestFinished() << "\" mainQuest=\""
+                        << zQuest->mainQuest << "\" requirements=\""
+                        << requirements << "\" width=\""
                         << (zQuest->mainQuest ? "50" : "30") << "\" height=\""
-                        << (zQuest->mainQuest ? "50" : "30") << "\"/>";
+                        << (zQuest->mainQuest ? "50" : "30")
+                        << "\" onClick=\"quests;(char)1;" << zQuest->questId
+                        << "\"/>";
         return new Framework::XML::Element(result);
     }
 }
+
+void QuestDialog::showQuestDetails(
+    Quest* zQuest, QuestStorage* zStorage, Framework::XML::Element* zParent)
+{
+    zParent->setAttribute("title", zQuest->questName);
+    zParent->addChild(new Framework::XML::Element(
+        (((Framework::Text(
+               "<text id=\"quest_description\" width=\"50%\" height=\"50%\" "
+               "align-left=\"start\" align-top=\"start\" vScroll=\"auto\" "
+               "style=\"")
+              += Framework::TextFeld::Style::Text
+               | Framework::TextFeld::Style::Mehrzeilig
+               | Framework::TextFeld::Style::AutoLineBreak)
+             += "\">")
+            += zQuest->description)
+        += "</text>"));
+    zParent->addChild(new Framework::XML::Element(
+        "<text id=\"quest_requirements_title\" width=\"50%\" height=\"30\" "
+        "align-left=\"quest_description\" align-top=\"start\" "
+        "text-align-horizontal=\"center\"  text-align-vertical=\"center\" "
+        "font-size\"20\">Requirements</text>"));
+    zParent->addChild(new Framework::XML::Element(
+        "<text id=\"quest_rewards_title\" width=\"50%\" height=\"30\" "
+        "align-left=\"start\" align-top=\"quest_description\" "
+        "text-align-horizontal=\"center\"  text-align-vertical=\"center\" "
+        "font-size\"20\">Rewards</text>"));
+    Framework::XML::Element* requirementsContainer
+        = new Framework::XML::Element(
+            "<frame id=\"quest_requirements\" align-left=\"start\" "
+            "align-top=\"quest_requirements_title\" width=\"50%\" "
+            "height=\"100% - "
+            "70\" vScroll=\"auto\" display=\"column\" gap=\"10\"/>");
+    requirementsContainer->setAttribute("style",
+        Framework::Text() += (Framework::Fenster::Style::Sichtbar
+                              | Framework::Fenster::Style::Erlaubt));
+    for (QuestRequirement* requirement : zQuest->requirements)
+    {
+        requirement->addRequirementUIML(zStorage,
+            requirementsContainer,
+            Framework::Text("quests;(char)4;")
+            += requirement->getRequirementId());
+    }
+    zParent->addChild(requirementsContainer);
+    Framework::XML::Element* rewardsContainer = new Framework::XML::Element(
+        "<frame id=\"quest_rewards\" align-left=\"start\" "
+        "align-top=\"quest_rewards_title\" width=\"50%\" height=\"50% - "
+        "30\" vScroll=\"auto\" display=\"column\" gap=\"10\"/>");
+    rewardsContainer->setAttribute("style",
+        Framework::Text() += (Framework::Fenster::Style::Sichtbar
+                              | Framework::Fenster::Style::Erlaubt));
+    for (QuestReward* reward : zQuest->rewards)
+    {
+        reward->addRewardUIML(rewardsContainer,
+            zStorage,
+            Framework::Text("quests;(char)5;") += reward->getRewardId());
+    }
+    zParent->addChild(rewardsContainer);
+    zParent->addChild(new XML::Element(
+        "<button id=\"back_to_graph\" width=\"100\" height=\"20\" "
+        "align-right=\"end\" align-top=\"quest_requirements\" "
+        "margin-right=\"10\" margin-top=\"10\" "
+        "onClick=\"quests;(char)2\">Back</button>"));
+    if (zStorage->isQuestFinished() && !zStorage->isQuestRewarded())
+    {
+        zParent->addChild(new XML::Element(
+            "<button id=\"give_rewards\" width=\"100\" height=\"20\" "
+            "align-left=\"quest_rewards\" align-top=\"quest_requirements\" "
+            "margin-left=\"10\" margin-top=\"10\" "
+            "onClick=\"quests;(char)3\">Give rewards</button>"));
+    }
+    update();
+}

+ 6 - 1
FactoryCraft/QuestDialog.h

@@ -4,6 +4,7 @@
 
 class Quest;
 class QuestParty;
+class QuestStorage;
 
 class QuestDialog : public UIDialog
 {
@@ -14,5 +15,9 @@ public:
         Framework::StreamReader* zRequest, NetworkMessage* zResponse) override;
 
 private:
-    Framework::XML::Element *getQuestGraphItem(Quest *zQuest, QuestParty *zParty);
+    Framework::XML::Element* getQuestGraphItem(
+        Quest* zQuest, QuestParty* zParty);
+    void showQuestDetails(Quest* zQuest,
+        QuestStorage* zStorage,
+        Framework::XML::Element* zParent);
 };

+ 41 - 9
FactoryCraft/QuestRequirement.cpp

@@ -1,5 +1,7 @@
 #include "QuestRequirement.h"
 
+#include <Fenster.h>
+
 #include "Quest.h"
 
 QuestRequirement::QuestRequirement(
@@ -9,6 +11,11 @@ QuestRequirement::QuestRequirement(
       description(description)
 {}
 
+void QuestRequirement::api(Framework::StreamReader* message,
+    Framework::XML::Element* zParent,
+    QuestStorage* zStorage)
+{}
+
 const Framework::Text& QuestRequirement::getRequirementId() const
 {
     return id;
@@ -26,26 +33,51 @@ QuestRequirementOpenDialog::QuestRequirementOpenDialog(
 {}
 
 void QuestRequirementOpenDialog::processEvent(
-    QuestEvent* zEvent, QuestRequirementStorage* zStorage)
+    QuestEvent* zEvent, QuestStorage* zStorage)
 {
+    QuestRequirementStorage* zRequirementStorage
+        = zStorage->zStorage(getRequirementId());
     QuestEventOpenDialog* event = dynamic_cast<QuestEventOpenDialog*>(zEvent);
     if (event)
     {
         if (event->getDialogId() == dialogId)
         {
-            zStorage->setFullfilled(true);
+            zRequirementStorage->setFullfilled(true);
         }
     }
 }
 
-Framework::Text QuestRequirementOpenDialog::getRequirementUIML(
-    QuestRequirementStorage* zStorage)
+void QuestRequirementOpenDialog::addRequirementUIML(QuestStorage* zStorage,
+    Framework::XML::Element* zParent,
+    Framework::Text onClickPrefix)
 {
-    Framework::Text result = "<questRequirement id=\"";
-    result.append() << id << "\" fullfilled=\"" << zStorage->isFullfilled()
-                    << "\"><text>" << description
-                    << "</text></questRequirement>";
-    return result;
+    Framework::XML::Element* container = new Framework::XML::Element(
+        "<frame width=\"100%\" height=\"50\" display=\"row\" gap=\"10\"/>");
+    container->setAttribute("style",
+        Framework::Text() += (Framework::Fenster::Style::Sichtbar
+                              | Framework::Fenster::Style::Erlaubt));
+    container->setAttribute(
+        "id", Framework::Text("requirement_") += getRequirementId());
+    // TODO: add icon of dialog
+    auto text = new Framework::XML::Element("<text width=\"auto\" height=\"auto\"/>");
+    text->setAttribute("id",
+        Framework::Text("requirement_description_") += getRequirementId());
+    text->setText(description);
+    container->addChild(text);
+    auto status = new Framework::XML::Element("<text margin-top=\"10\" width=\"auto\" height=\"auto\"/>");
+    status->setAttribute("align-top", text->getAttributeValue("id"));
+    if (zStorage->zStorage(getRequirementId())->isFullfilled())
+    {
+        status->setText("Completed");
+        status->setAttribute("color", "0xFF00FF00");
+    }
+    else
+    {
+        status->setText("Not completed");
+        status->setAttribute("color", "0xFFFF0000");
+    }
+    container->addChild(status);
+    zParent->addChild(container);
 }
 
 QuestRequirementOpenDialogType::QuestRequirementOpenDialogType()

+ 12 - 10
FactoryCraft/QuestRequirement.h

@@ -3,7 +3,7 @@
 #include "QuestEvent.h"
 #include "TypeRegistry.h"
 
-class QuestRequirementStorage;
+class QuestStorage;
 
 class QuestRequirement : public virtual Framework::ReferenceCounter
 {
@@ -13,12 +13,14 @@ protected:
 
 public:
     QuestRequirement(Framework::Text id, Framework::Text description);
-    virtual void processEvent(
-        QuestEvent* zEvent, QuestRequirementStorage* zStorage)
-        = 0;
-    virtual Framework::Text getRequirementUIML(
-        QuestRequirementStorage* zStorage)
+    virtual void processEvent(QuestEvent* zEvent, QuestStorage* zStorage) = 0;
+    virtual void addRequirementUIML(QuestStorage* zStorage,
+        Framework::XML::Element* zParent,
+        Framework::Text onClickPrefix)
         = 0;
+    virtual void api(Framework::StreamReader* message,
+        Framework::XML::Element* zParent,
+        QuestStorage* zStorage);
     const Framework::Text& getRequirementId() const;
     const Framework::Text& getDescription() const;
 };
@@ -34,10 +36,10 @@ public:
     QuestRequirementOpenDialog(Framework::Text id,
         Framework::Text description,
         Framework::Text dialogId);
-    void processEvent(
-        QuestEvent* zEvent, QuestRequirementStorage* zStorage) override;
-    Framework::Text getRequirementUIML(
-        QuestRequirementStorage* zStorage) override;
+    void processEvent(QuestEvent* zEvent, QuestStorage* zStorage) override;
+    void addRequirementUIML(QuestStorage* zStorage,
+        Framework::XML::Element* zParent,
+        Framework::Text onClickPrefix) override;
 
     friend QuestRequirementOpenDialogType;
 };

+ 36 - 9
FactoryCraft/QuestReward.cpp

@@ -1,5 +1,7 @@
 #include "QuestReward.h"
 
+#include <Fenster.h>
+
 #include "Entity.h"
 #include "Game.h"
 
@@ -8,6 +10,17 @@ QuestReward::QuestReward(Framework::Text rewardId)
       rewardId(rewardId)
 {}
 
+bool QuestReward::validateSettings(
+    Framework::XML::Element* zParent, QuestStorage* zStorage)
+{
+    return true;
+}
+
+void QuestReward::api(Framework::StreamReader* message,
+    Framework::XML::Element* zParent,
+    QuestStorage* zStorage)
+{}
+
 const Framework::Text& QuestReward::getRewardId() const
 {
     return rewardId;
@@ -94,19 +107,33 @@ void QuestRewardGiveItems::giveReward(Entity* zTargetEntity)
     }
 }
 
-Framework::Text QuestRewardGiveItems::getRewardUIML()
+void QuestRewardGiveItems::addRewardUIML(Framework::XML::Element* zParent,
+    QuestStorage* zStorage,
+    Framework::Text onClickPrefix)
 {
-    Framework::Text result = "<questReward>";
+    Framework::XML::Element* container = new Framework::XML::Element(
+        "<frame width=\"100%\" height=\"50\" display=\"column\" gap=\"10\"/>");
+    container->setAttribute("style",
+        Framework::Text() += (Framework::Fenster::Style::Sichtbar
+                              | Framework::Fenster::Style::Erlaubt));
+    container->setAttribute("id", Framework::Text("reward_") += rewardId);
+    container->addChild(
+        new Framework::XML::Element("<text>Item Reward:</text>"));
     for (ItemStackInfo* info : items)
     {
-        result.append() << "<itemStack count=\"" << info->getCount()
-                        << "\" itemImage=\""
-                        << info->zItem()->zItemType()->getId() << "\"><text>"
-                        << info->zItem()->getName() << "</text>"
-                        << info->zItem()->getTooltipUIML() << "</itemStack>";
+        auto stack = new Framework::XML::Element(
+            "<itemStack width=\"50\" height=\"50\"/>");
+        stack->setAttribute(
+            "id", (Framework::Text("reward_") += rewardId) += "_item_stack");
+        stack->setAttribute("count", info->getCount());
+        stack->addChild(
+            new Framework::XML::Element(info->zItem()->getTooltipUIML()));
+        auto text = new Framework::XML::Element("<text margin-left=\"10\"/>");
+        text->setText(info->zItem()->getName());
+        text->setAttribute("align-left", stack->getAttributeValue("id"));
+        container->addChild(stack);
     }
-    result += "</questReward>";
-    return result;
+    zParent->addChild(container);
 }
 
 QuestRewardGiveItemsType::QuestRewardGiveItemsType()

+ 11 - 2
FactoryCraft/QuestReward.h

@@ -4,6 +4,7 @@
 
 class Entity;
 class Item;
+class QuestStorage;
 
 class QuestReward : public virtual Framework::ReferenceCounter
 {
@@ -14,7 +15,13 @@ public:
     QuestReward(Framework::Text rewardId);
 
     virtual void giveReward(Entity* zTargetEntity) = 0;
-    virtual Framework::Text getRewardUIML() = 0;
+    virtual void addRewardUIML(
+        Framework::XML::Element* zParent, QuestStorage* zStorage, Framework::Text onClickPrefix)
+        = 0;
+    virtual bool validateSettings(
+        Framework::XML::Element* zParent, QuestStorage *zStorage);
+    virtual void api(Framework::StreamReader* message,
+        Framework::XML::Element* zParent, QuestStorage* zStorage);
 
     const Framework::Text& getRewardId() const;
 };
@@ -52,7 +59,9 @@ public:
     QuestRewardGiveItems(Framework::Text rewardId);
 
     void giveReward(Entity* zTargetEntity) override;
-    Framework::Text getRewardUIML() override;
+    void addRewardUIML(Framework::XML::Element* zParent,
+        QuestStorage* zStorage,
+        Framework::Text onClickPrefix) override;
 
     friend QuestRewardGiveItemsType;
 };

+ 5 - 3
FactoryCraft/Start.cpp

@@ -55,6 +55,7 @@ public:
           infoLength(0)
     {}
 
+    #ifdef WIN32
     void __CLR_OR_THIS_CALL _Lock() override
     {
         cs.lock();
@@ -64,14 +65,15 @@ public:
     {
         cs.unlock();
     }
+    #endif
 
     int sync() override
     {
-        _Lock();
+        cs.lock();
         std::string value = str();
         if (value.length() == 0 && !Game::INSTANCE)
         {
-            _Unlock();
+            cs.unlock();
             return 0;
         }
         str("");
@@ -131,7 +133,7 @@ public:
             infoLength = 0;
         }
         if (hasFile) file << value << std::flush;
-        _Unlock();
+        cs.unlock();
         return 0;
     }
 };

+ 1 - 1
FactoryCraft/TypeRegistry.h

@@ -334,7 +334,7 @@ public:
             throw Framework::Text("Type not registered as Polymorphic type: ")
                 + typeId;
         }
-        polymorphFactory->addFactory<S>(factory);
+        polymorphFactory->template addFactory<S>(factory);
     }
 
     template<typename T> void registerType(TypeFactory<T>* factory)