Przeglądaj źródła

improve json config loading

Kolja Strohm 8 miesięcy temu
rodzic
commit
7820a034c7
108 zmienionych plików z 6724 dodań i 5134 usunięć
  1. 126 191
      FactoryCraft/BasicBlocks.cpp
  2. 29 31
      FactoryCraft/BasicBlocks.h
  3. 95 97
      FactoryCraft/BasicItems.cpp
  4. 16 16
      FactoryCraft/BasicItems.h
  5. 903 643
      FactoryCraft/BasicTool.cpp
  6. 119 109
      FactoryCraft/BasicTool.h
  7. 144 43
      FactoryCraft/BiomGenerator.cpp
  8. 26 3
      FactoryCraft/BiomGenerator.h
  9. 108 87
      FactoryCraft/Block.cpp
  10. 24 15
      FactoryCraft/Block.h
  11. 176 135
      FactoryCraft/BlockFilter.cpp
  12. 76 53
      FactoryCraft/BlockFilter.h
  13. 8 3
      FactoryCraft/BlockInfoCommand.cpp
  14. 47 21
      FactoryCraft/BlockInstanceGeneratorRule.cpp
  15. 15 6
      FactoryCraft/BlockInstanceGeneratorRule.h
  16. 113 75
      FactoryCraft/BlockType.cpp
  17. 125 22
      FactoryCraft/BlockType.h
  18. 45 21
      FactoryCraft/BlockTypeGeneratorRule.cpp
  19. 14 6
      FactoryCraft/BlockTypeGeneratorRule.h
  20. 4 2
      FactoryCraft/Chat.cpp
  21. 2 2
      FactoryCraft/ChatCommand.cpp
  22. 2 1
      FactoryCraft/ChatCommandExecutor.cpp
  23. 7 5
      FactoryCraft/ChatObserver.cpp
  24. 38 87
      FactoryCraft/Chest.cpp
  25. 11 12
      FactoryCraft/Chest.h
  26. 37 26
      FactoryCraft/Chunk.cpp
  27. 3 1
      FactoryCraft/CraftingStorage.cpp
  28. 7 13
      FactoryCraft/Dimension.cpp
  29. 265 81
      FactoryCraft/DimensionGenerator.cpp
  30. 124 32
      FactoryCraft/DimensionGenerator.h
  31. 9 5
      FactoryCraft/DimensionMap.cpp
  32. 14 12
      FactoryCraft/Entity.cpp
  33. 1 0
      FactoryCraft/EntityType.cpp
  34. 0 4
      FactoryCraft/FactoryCraft.vcxproj
  35. 0 18
      FactoryCraft/FactoryCraft.vcxproj.filters
  36. 110 115
      FactoryCraft/FluidBlock.cpp
  37. 17 17
      FactoryCraft/FluidBlock.h
  38. 209 191
      FactoryCraft/FluidContainer.cpp
  39. 39 40
      FactoryCraft/FluidContainer.h
  40. 18 8
      FactoryCraft/Game.cpp
  41. 38 31
      FactoryCraft/Game.h
  42. 44 22
      FactoryCraft/GeneratorRule.cpp
  43. 60 8
      FactoryCraft/GeneratorRule.h
  44. 17 6
      FactoryCraft/GeneratorTemplate.cpp
  45. 36 3
      FactoryCraft/GeneratorTemplate.h
  46. 3 1
      FactoryCraft/GrantCommand.cpp
  47. 16 93
      FactoryCraft/Grass.cpp
  48. 12 11
      FactoryCraft/Grass.h
  49. 132 93
      FactoryCraft/GrowingPlant.cpp
  50. 23 18
      FactoryCraft/GrowingPlant.h
  51. 3 2
      FactoryCraft/Inventory.cpp
  52. 21 16
      FactoryCraft/Item.cpp
  53. 7 4
      FactoryCraft/Item.h
  54. 3 1
      FactoryCraft/ItemEntity.cpp
  55. 94 63
      FactoryCraft/ItemFilter.cpp
  56. 37 24
      FactoryCraft/ItemFilter.h
  57. 66 64
      FactoryCraft/ItemModifier.cpp
  58. 32 27
      FactoryCraft/ItemModifier.h
  59. 4 4
      FactoryCraft/ItemSkill.cpp
  60. 42 2
      FactoryCraft/ItemSkill.h
  61. 71 44
      FactoryCraft/ItemType.cpp
  62. 96 14
      FactoryCraft/ItemType.h
  63. 10 8
      FactoryCraft/JNoise.cpp
  64. 720 403
      FactoryCraft/JsonExpression.cpp
  65. 207 33
      FactoryCraft/JsonExpression.h
  66. 100 81
      FactoryCraft/LightSources.cpp
  67. 20 16
      FactoryCraft/LightSources.h
  68. 64 28
      FactoryCraft/ModelInfo.cpp
  69. 13 4
      FactoryCraft/ModelInfo.h
  70. 1 0
      FactoryCraft/MultiblockStructure.cpp
  71. 12 7
      FactoryCraft/NetworkMessage.cpp
  72. 11 10
      FactoryCraft/NoBlock.cpp
  73. 0 11
      FactoryCraft/OverworldDimension.cpp
  74. 0 11
      FactoryCraft/OverworldDimension.h
  75. 0 479
      FactoryCraft/OverworldDimensionGenerator.cpp
  76. 0 14
      FactoryCraft/OverworldDimensionGenerator.h
  77. 101 74
      FactoryCraft/PlaceableProof.cpp
  78. 38 29
      FactoryCraft/PlaceableProof.h
  79. 10 7
      FactoryCraft/Player.cpp
  80. 11 4
      FactoryCraft/PlayerHand.cpp
  81. 140 113
      FactoryCraft/Quest.cpp
  82. 47 21
      FactoryCraft/Quest.h
  83. 7 4
      FactoryCraft/QuestDialog.cpp
  84. 48 35
      FactoryCraft/QuestRequirement.cpp
  85. 52 11
      FactoryCraft/QuestRequirement.h
  86. 84 59
      FactoryCraft/QuestReward.cpp
  87. 56 18
      FactoryCraft/QuestReward.h
  88. 198 178
      FactoryCraft/Recipie.cpp
  89. 95 31
      FactoryCraft/Recipie.h
  90. 1 0
      FactoryCraft/SaveCommand.cpp
  91. 6 5
      FactoryCraft/Server.cpp
  92. 1 0
      FactoryCraft/Start.cpp
  93. 147 49
      FactoryCraft/StructureCollection.cpp
  94. 28 3
      FactoryCraft/StructureCollection.h
  95. 123 83
      FactoryCraft/TreeSeblingBlock.cpp
  96. 22 16
      FactoryCraft/TreeSeblingBlock.h
  97. 90 67
      FactoryCraft/TreeTemplate.cpp
  98. 18 16
      FactoryCraft/TreeTemplate.h
  99. 20 102
      FactoryCraft/TypeRegistry.cpp
  100. 168 141
      FactoryCraft/TypeRegistry.h
  101. 1 0
      FactoryCraft/UIDialog.cpp
  102. 29 104
      FactoryCraft/WorldGenerator.cpp
  103. 1 5
      FactoryCraft/WorldGenerator.h
  104. 9 4
      FactoryCraft/WorldLoader.cpp
  105. 15 13
      FactoryCraft/WormCaveGenerator.cpp
  106. 0 4
      Windows Version/Windows Version.vcxproj
  107. 0 18
      Windows Version/Windows Version.vcxproj.filters
  108. 17 15
      Windows Version/data/generator/overworld.json

+ 126 - 191
FactoryCraft/BasicBlocks.cpp

@@ -5,6 +5,7 @@
 #include "ItemEntity.h"
 #include "ModelInfo.h"
 #include "TreeSeblingBlock.h"
+#include "ItemStack.h"
 
 BasicBlock::BasicBlock(int typeId, Framework::Vec3<int> pos, int dimensionId)
     : BasicBlock(typeId, pos, dimensionId, false)
@@ -22,24 +23,9 @@ bool BasicBlock::onTick(TickQueue* zQueue, int numTicks, bool& blocked)
 
 void BasicBlock::onPostTick() {}
 
-BasicBlockType::BasicBlockType(Framework::Text itemTypeName,
-    ModelInfo* model,
-    Framework::Text name,
-    int mapColor,
-    bool modelSubscription,
-    float hardness,
-    Framework::RCArray<Framework::Text> groupNames)
-    : BlockType(0,
-        model,
-        1,
-        100,
-        0,
-        name,
-        modelSubscription,
-        mapColor,
-        groupNames,
-        hardness),
-      itemTypeName(itemTypeName),
+BasicBlockType::BasicBlockType()
+    : BlockType(),
+      itemTypeName(),
       transparent(0),
       passable(0),
       speedModifier(1.f),
@@ -91,13 +77,23 @@ Framework::Text BasicBlockType::getItemTypeName() const
 ItemType* BasicBlockType::createItemType() const
 {
     return new BasicBlockItemType(getItemTypeName(),
-        new ModelInfo(zModel()->getModelPath(), zModel()->getTexturePaths(), zModel()->isTransparent(), zModel()->getSize() / 2.f),
+        new ModelInfo(zModel()->getModelPath(),
+            zModel()->getTexturePaths(),
+            zModel()->isTransparent(),
+            zModel()->getSize() / 2.f),
         transparent,
         passable,
         getHardness(),
         speedModifier,
         getItemTypeName(),
-        0, 50, getGroupNames());
+        0,
+        50,
+        getGroupNames());
+}
+
+void BasicBlockType::setItemTypeName(Framework::Text itemTypeName)
+{
+    this->itemTypeName = itemTypeName;
 }
 
 int BasicBlockType::getItemTypeId() const
@@ -105,8 +101,9 @@ int BasicBlockType::getItemTypeId() const
     return itemTypeId;
 }
 
-void BasicBlockType::setTransparent(bool transparent) {
-	this->transparent = transparent;
+void BasicBlockType::setTransparent(bool transparent)
+{
+    this->transparent = transparent;
 }
 
 bool BasicBlockType::isTransparent() const
@@ -114,8 +111,9 @@ bool BasicBlockType::isTransparent() const
     return transparent;
 }
 
-void BasicBlockType::setPassable(bool passable) {
-	this->passable = passable;
+void BasicBlockType::setPassable(bool passable)
+{
+    this->passable = passable;
 }
 
 bool BasicBlockType::isPassable() const
@@ -123,8 +121,9 @@ bool BasicBlockType::isPassable() const
     return passable;
 }
 
-void BasicBlockType::setSpeedModifier(float speedModifier) {
-	this->speedModifier = speedModifier;
+void BasicBlockType::setSpeedModifier(float speedModifier)
+{
+    this->speedModifier = speedModifier;
 }
 
 float BasicBlockType::getSpeedModifier() const
@@ -132,83 +131,75 @@ float BasicBlockType::getSpeedModifier() const
     return speedModifier;
 }
 
-void BasicBlockType::setInteractable(bool interactable) {
-	this->interactable = interactable;
+void BasicBlockType::setInteractable(bool interactable)
+{
+    this->interactable = interactable;
+}
+
+bool BasicBlockType::isInteractable() const
+{
+    return interactable;
 }
 
 BasicBlockTypeFactory::BasicBlockTypeFactory()
-    : SubTypeFactory()
+    : BlockTypeFactoryBase()
 {}
 
-BasicBlockType* BasicBlockTypeFactory::fromJson(
+BasicBlockType* BasicBlockTypeFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
-    Framework::RCArray<Framework::Text> groupNames;
-    for (Framework::JSON::JSONValue* value :
-        *zJson->zValue("groupNames")->asArray())
-    {
-        groupNames.add(new Framework::Text(value->asString()->getString()));
-    }
-    return new BasicBlockType(
-        zJson->zValue("itemType")->asString()->getString(),
-        Game::INSTANCE->zTypeRegistry()->fromJson<ModelInfo>(
-            zJson->zValue("model")),
-        zJson->zValue("name")->asString()->getString(),
-        (int)zJson->zValue("mapColor")->asString()->getString(),
-        zJson->zValue("modelSubscription")->asBool()->getBool(),
-        (float)zJson->zValue("hardness")->asNumber()->getNumber(),
-        groupNames);
-}
-
-Framework::JSON::JSONObject* BasicBlockTypeFactory::toJson(
-    BasicBlockType* zObject) const
-{
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue("itemType",
+    return new BasicBlockType();
+}
+
+void BasicBlockTypeFactory::fromJson(
+    BasicBlockType* zResult, Framework::JSON::JSONObject* zJson) const
+{
+    zResult->setItemTypeName(
+        zJson->zValue("itemType")->asString()->getString());
+    zResult->setTransparent(zJson->zValue("transparent")->asBool()->getBool());
+    zResult->setPassable(zJson->zValue("passable")->asBool()->getBool());
+    zResult->setSpeedModifier(
+        (float)zJson->zValue("speedModifier")->asNumber()->getNumber());
+    zResult->setInteractable(
+        (float)zJson->zValue("interactable")->asBool()->getBool());
+    BlockTypeFactoryBase::fromJson(zResult, zJson);
+}
+
+void BasicBlockTypeFactory::toJson(
+    BasicBlockType* zObject, Framework::JSON::JSONObject* zResult) const
+{
+    zResult->addValue("itemType",
         new Framework::JSON::JSONString(zObject->getItemTypeName()));
-    result->addValue(
-        "model", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zModel()));
-    result->addValue(
-        "name", new Framework::JSON::JSONString(zObject->getName()));
-    result->addValue(
-        "mapColor", new Framework::JSON::JSONString(zObject->getMapColor()));
-    result->addValue("modelSubscription",
-        new Framework::JSON::JSONBool(zObject->doesNeedModelSubscription()));
-    result->addValue(
-        "hardness", new Framework::JSON::JSONNumber(zObject->getHardness()));
-    Framework::JSON::JSONArray* groupNames = new Framework::JSON::JSONArray();
-    for (Framework::Text* groupName : zObject->getGroupNames())
-    {
-        groupNames->addValue(new Framework::JSON::JSONString(*groupName));
-    }
-    result->addValue("groupNames", groupNames);
-    return result;
-}
-
-Framework::JSON::Validator::JSONValidator* BasicBlockTypeFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
-{
-    return builder->withRequiredString("itemType")
-        ->finishString()
-        ->withRequiredAttribute(
-            "model", Game::INSTANCE->zTypeRegistry()->getValidator<ModelInfo>())
-        ->withRequiredString("name")
-        ->finishString()
-        ->withRequiredString("mapColor")
-        ->finishString()
-        ->withRequiredBool("modelSubscription")
-        ->withDefault(false)
-        ->finishBool()
-        ->withRequiredNumber("hardness")
-        ->withDefault(1.0)
-        ->finishNumber()
-        ->withRequiredArray("groupNames")
-        ->withDefault(new Framework::JSON::JSONArray())
-        ->addAcceptedStringInArray()
-        ->finishString()
-        ->finishArray()
-        ->finishObject();
+    zResult->addValue(
+        "transparent", new Framework::JSON::JSONBool(zObject->isTransparent()));
+    zResult->addValue(
+        "passable", new Framework::JSON::JSONBool(zObject->isPassable()));
+    zResult->addValue("speedModifier",
+        new Framework::JSON::JSONNumber(zObject->getSpeedModifier()));
+    zResult->addValue("interactable",
+        new Framework::JSON::JSONBool(zObject->isInteractable()));
+    BlockTypeFactoryBase::toJson(zObject, zResult);
+}
+
+JSONObjectValidationBuilder* BasicBlockTypeFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return BlockTypeFactoryBase::addToValidator(
+        builder->withRequiredString("itemType")
+            ->withDefault("")
+            ->finishString()
+            ->withRequiredBool("transparent")
+            ->withDefault(false)
+            ->finishBool()
+            ->withRequiredBool("passable")
+            ->withDefault(false)
+            ->finishBool()
+            ->withRequiredNumber("speedModifier")
+            ->withDefault(1.0)
+            ->finishNumber()
+            ->withRequiredBool("interactable")
+            ->withDefault(true)
+            ->finishBool());
 }
 
 Framework::Text BasicBlockTypeFactory::getTypeToken() const
@@ -261,11 +252,16 @@ void AdditionalItemSpawningBlock::onDestroy()
     BasicBlock::onDestroy();
 }
 
+AdditionalItemSpawningBlockType::AdditionalItemSpawningBlockType()
+    : BasicBlockType(),
+      spawns()
+{}
+
 void AdditionalItemSpawningBlockType::createSuperBlock(
     Block* zBlock, Item* zItem) const
 {
     AdditionalItemSpawningBlock* block
-		= dynamic_cast<AdditionalItemSpawningBlock*>(zBlock);
+        = dynamic_cast<AdditionalItemSpawningBlock*>(zBlock);
     if (block)
     {
         for (const SpawnConfig& config : spawns)
@@ -276,25 +272,6 @@ void AdditionalItemSpawningBlockType::createSuperBlock(
     BasicBlockType::createSuperBlock(zBlock, zItem);
 }
 
-AdditionalItemSpawningBlockType::AdditionalItemSpawningBlockType(
-    Framework::Text itemTypeName,
-    ModelInfo* model,
-    Framework::Text name,
-    int mapColor,
-    bool modelSubscription,
-    float hardness,
-    Framework::Array<SpawnConfig> spawns,
-    Framework::RCArray<Framework::Text> groupNames)
-    : BasicBlockType(itemTypeName,
-        model,
-        name,
-        mapColor,
-        modelSubscription,
-        hardness,
-        groupNames),
-      spawns(spawns)
-{}
-
 bool AdditionalItemSpawningBlockType::initialize(Game* zGame)
 {
     for (auto iterator = spawns.begin(); iterator; iterator++)
@@ -322,6 +299,11 @@ Block* AdditionalItemSpawningBlockType::createBlock(
     return block;
 }
 
+void AdditionalItemSpawningBlockType::addSpawn(SpawnConfig config)
+{
+    spawns.add(config);
+}
+
 const Framework::Array<SpawnConfig>&
 AdditionalItemSpawningBlockType::getSpawns() const
 {
@@ -329,26 +311,26 @@ AdditionalItemSpawningBlockType::getSpawns() const
 }
 
 AdditionalItemSpawningBlockTypeFactory::AdditionalItemSpawningBlockTypeFactory()
-    : SubTypeFactory()
+    : BlockTypeFactoryBase()
 {}
 
 AdditionalItemSpawningBlockType*
-AdditionalItemSpawningBlockTypeFactory::fromJson(
+AdditionalItemSpawningBlockTypeFactory::createValue(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new AdditionalItemSpawningBlockType();
+}
+
+void AdditionalItemSpawningBlockTypeFactory::fromJson(
+    AdditionalItemSpawningBlockType* zResult,
     Framework::JSON::JSONObject* zJson) const
 {
-    Framework::RCArray<Framework::Text> groupNames;
-    for (Framework::JSON::JSONValue* value :
-        *zJson->zValue("groupNames")->asArray())
-    {
-        groupNames.add(new Framework::Text(value->asString()->getString()));
-    }
-    Framework::Array<SpawnConfig> spawns;
     Framework::JSON::JSONArray* spawnsJson = zJson->zValue("spawns")->asArray();
     for (int i = 0; i < spawnsJson->getLength(); i++)
     {
         Framework::JSON::JSONObject* spawnJson
             = spawnsJson->zValue(i)->asObject();
-        spawns.add(SpawnConfig{
+        zResult->addSpawn(SpawnConfig{
             (int)spawnJson->zValue("min")->asNumber()->getNumber(),
             (int)spawnJson->zValue("max")->asNumber()->getNumber(),
             (float)spawnJson->zValue("chance")->asNumber()->getNumber(),
@@ -356,34 +338,13 @@ AdditionalItemSpawningBlockTypeFactory::fromJson(
             0,
         });
     }
-    return new AdditionalItemSpawningBlockType(
-        zJson->zValue("itemType")->asString()->getString(),
-        Game::INSTANCE->zTypeRegistry()->fromJson<ModelInfo>(
-            zJson->zValue("model")),
-        zJson->zValue("name")->asString()->getString(),
-        (int)zJson->zValue("mapColor")->asString()->getString(),
-        zJson->zValue("modelSubscription")->asBool()->getBool(),
-        (float)zJson->zValue("hardness")->asNumber()->getNumber(),
-        spawns,
-        groupNames);
-}
-
-Framework::JSON::JSONObject* AdditionalItemSpawningBlockTypeFactory::toJson(
-    AdditionalItemSpawningBlockType* zObject) const
-{
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue("itemType",
-        new Framework::JSON::JSONString(zObject->getItemTypeName()));
-    result->addValue(
-        "model", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zModel()));
-    result->addValue(
-        "name", new Framework::JSON::JSONString(zObject->getName()));
-    result->addValue(
-        "mapColor", new Framework::JSON::JSONString(zObject->getMapColor()));
-    result->addValue("modelSubscription",
-        new Framework::JSON::JSONBool(zObject->doesNeedModelSubscription()));
-    result->addValue(
-        "hardness", new Framework::JSON::JSONNumber(zObject->getHardness()));
+    super.fromJson(zResult, zJson);
+}
+
+void AdditionalItemSpawningBlockTypeFactory::toJson(
+    AdditionalItemSpawningBlockType* zObject,
+    Framework::JSON::JSONObject* zResult) const
+{
     Framework::JSON::JSONArray* spawns = new Framework::JSON::JSONArray();
     for (const SpawnConfig& config : zObject->getSpawns())
     {
@@ -396,37 +357,17 @@ Framework::JSON::JSONObject* AdditionalItemSpawningBlockTypeFactory::toJson(
         spawn->addValue("max", new Framework::JSON::JSONNumber(config.max));
         spawns->addValue(spawn);
     }
-    result->addValue("spawns", spawns);
-    Framework::JSON::JSONArray* groupNames = new Framework::JSON::JSONArray();
-    for (Framework::Text* groupName : zObject->getGroupNames())
-    {
-        groupNames->addValue(new Framework::JSON::JSONString(*groupName));
-    }
-    result->addValue("groupNames", groupNames);
-    return result;
-}
-
-Framework::JSON::Validator::JSONValidator*
-AdditionalItemSpawningBlockTypeFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
-{
-    return builder->withRequiredString("itemType")
-        ->finishString()
-        ->withRequiredAttribute(
-            "model", Game::INSTANCE->zTypeRegistry()->getValidator<ModelInfo>())
-        ->withRequiredString("name")
-        ->finishString()
-        ->withRequiredString("mapColor")
-        ->finishString()
-        ->withRequiredBool("modelSubscription")
-        ->withDefault(false)
-        ->finishBool()
-        ->withRequiredNumber("hardness")
-        ->withDefault(1.0)
-        ->finishNumber()
-        ->withRequiredAttribute("spawns",
-            JSON::Validator::JSONValidator::buildForArray()
+    zResult->addValue("spawns", spawns);
+    return super.toJson(zObject, zResult);
+}
+
+JSONObjectValidationBuilder*
+AdditionalItemSpawningBlockTypeFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return super.addToValidator(
+        builder->withRequiredAttribute("spawns",
+            Framework::JSON::Validator::JSONValidator::buildForArray()
                 ->addAcceptedObjectInArray()
                 ->withRequiredString("itemType")
                 ->finishString()
@@ -437,13 +378,7 @@ AdditionalItemSpawningBlockTypeFactory::getValidator(
                 ->withRequiredNumber("max")
                 ->finishNumber()
                 ->finishObject()
-                ->finishArray())
-        ->withRequiredArray("groupNames")
-        ->withDefault(new Framework::JSON::JSONArray())
-        ->addAcceptedStringInArray()
-        ->finishString()
-        ->finishArray()
-        ->finishObject();
+                ->finishArray()));
 }
 
 Framework::Text AdditionalItemSpawningBlockTypeFactory::getTypeToken() const

+ 29 - 31
FactoryCraft/BasicBlocks.h

@@ -47,19 +47,14 @@ protected:
     virtual void createSuperBlock(Block* zBlock, Item* zItem) const override;
 
 public:
-    BasicBlockType(Framework::Text itemTypeName,
-        ModelInfo* model,
-        Framework::Text name,
-        int mapColor,
-        bool modelSubscription,
-        float hardness,
-        Framework::RCArray<Framework::Text> groupNames);
+    BasicBlockType();
     virtual bool initialize(Game* zGame) override;
     virtual Block* createBlock(
         Framework::Vec3<int> position, int dimensionId) const override;
     virtual Item* createItem() const override;
     Framework::Text getItemTypeName() const;
     virtual ItemType* createItemType() const override;
+    void setItemTypeName(Framework::Text itemTypeName);
     int getItemTypeId() const;
     void setTransparent(bool transparent);
     bool isTransparent() const;
@@ -68,17 +63,21 @@ public:
     void setSpeedModifier(float speedModifier);
     float getSpeedModifier() const;
     void setInteractable(bool interactable);
+    bool isInteractable() const;
 };
 
-class BasicBlockTypeFactory : public SubTypeFactory<BlockType, BasicBlockType>
+class BasicBlockTypeFactory : public BlockTypeFactoryBase<BasicBlockType>
 {
 public:
     BasicBlockTypeFactory();
-    BasicBlockType* fromJson(Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(BasicBlockType* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    BasicBlockType* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(BasicBlockType* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(BasicBlockType* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };
 
@@ -88,9 +87,8 @@ private:
     Framework::Array<SpawnConfig> spawns;
 
 public:
-    AdditionalItemSpawningBlock(int typeId,
-        Framework::Vec3<int> pos,
-        int dimensionId);
+    AdditionalItemSpawningBlock(
+        int typeId, Framework::Vec3<int> pos, int dimensionId);
     void addSpawn(SpawnConfig config);
     virtual void onDestroy() override;
 };
@@ -100,35 +98,35 @@ class AdditionalItemSpawningBlockType : public BasicBlockType
 private:
     Framework::Array<SpawnConfig> spawns;
 
+public:
+    AdditionalItemSpawningBlockType();
+
 protected:
     virtual void createSuperBlock(Block* zBlock, Item* zItem) const override;
 
 public:
-    AdditionalItemSpawningBlockType(Framework::Text itemTypeName,
-        ModelInfo* model,
-        Framework::Text name,
-        int mapColor,
-        bool modelSubscription,
-        float hardness,
-        Framework::Array<SpawnConfig> spawns,
-        Framework::RCArray<Framework::Text> groupNames);
     virtual bool initialize(Game* zGame) override;
     virtual Block* createBlock(
         Framework::Vec3<int> position, int dimensionId) const override;
+    void addSpawn(SpawnConfig config);
     const Framework::Array<SpawnConfig>& getSpawns() const;
 };
 
 class AdditionalItemSpawningBlockTypeFactory
-    : public SubTypeFactory<BlockType, AdditionalItemSpawningBlockType>
+    : public BlockTypeFactoryBase<AdditionalItemSpawningBlockType>
 {
+private:
+    BasicBlockTypeFactory super;
+
 public:
     AdditionalItemSpawningBlockTypeFactory();
-    AdditionalItemSpawningBlockType* fromJson(
+    AdditionalItemSpawningBlockType* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(AdditionalItemSpawningBlockType* zResult,
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(
-        AdditionalItemSpawningBlockType* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    void toJson(AdditionalItemSpawningBlockType* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };

+ 95 - 97
FactoryCraft/BasicItems.cpp

@@ -2,24 +2,17 @@
 
 #include "Game.h"
 #include "ModelInfo.h"
+#include "Item.h"
+#include "Entity.h"
 
-BasicItemType::BasicItemType(Framework::Text name,
-    ModelInfo* model,
-    Framework::Text itemName,
-    float hp,
-    float durability,
-    int maxStack,
-    bool solid,
-    float hungerRecoveryPerHp,
-    float thirstRecoveryPerHp,
-    Framework::RCArray<Framework::Text> groups)
-    : ItemType(name, model, maxStack, groups),
-      itemName(itemName),
-      hp(hp),
-      durability(durability),
-      solid(solid),
-      hungerRecoveryPerHp(hungerRecoveryPerHp),
-      thirstRecoveryPerHp(thirstRecoveryPerHp)
+BasicItemType::BasicItemType()
+    : ItemType(),
+      itemName(),
+      hp(1.f),
+      durability(1.f),
+      solid(true),
+      hungerRecoveryPerHp(0.f),
+      thirstRecoveryPerHp(0.f)
 {}
 
 Item* BasicItemType::createItem() const
@@ -76,128 +69,133 @@ Item* BasicItemType::createItem() const
     return result;
 }
 
+void BasicItemType::setItemName(Framework::Text itemName)
+{
+    this->itemName = itemName;
+}
+
 Framework::Text BasicItemType::getItemName() const
 {
     return itemName;
 }
 
+void BasicItemType::setHp(float hp)
+{
+    this->hp = hp;
+}
+
 float BasicItemType::getHp() const
 {
     return hp;
 }
 
+void BasicItemType::setDurability(float durability)
+{
+    this->durability = durability;
+}
+
 float BasicItemType::getDurability() const
 {
     return durability;
 }
 
+void BasicItemType::setSolid(bool solid)
+{
+    this->solid = solid;
+}
+
 bool BasicItemType::isSolid() const
 {
     return solid;
 }
 
+void BasicItemType::setHungerRecoveryPerHp(float hungerRecoveryPerHp)
+{
+    this->hungerRecoveryPerHp = hungerRecoveryPerHp;
+}
+
 float BasicItemType::getHungerRecoveryPerHp() const
 {
     return hungerRecoveryPerHp;
 }
 
+void BasicItemType::setThirstRecoveryPerHp(float thirstRecoveryPerHp)
+{
+    this->thirstRecoveryPerHp = thirstRecoveryPerHp;
+}
+
 float BasicItemType::getThirstRecoveryPerHp() const
 {
     return thirstRecoveryPerHp;
 }
 
 BasicItemTypeFactory::BasicItemTypeFactory()
-    : SubTypeFactory()
+    : ItemTypeFactoryBase()
 {}
 
-BasicItemType* BasicItemTypeFactory::fromJson(
+BasicItemType* BasicItemTypeFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
-    Framework::RCArray<Framework::Text> groups;
-    for (Framework::JSON::JSONValue* group :
-        *zJson->zValue("groupNames")->asArray())
-    {
-        groups.add(new Framework::Text(group->asString()->getString()));
-    }
-    return new BasicItemType(zJson->zValue("name")->asString()->getString(),
-        Game::INSTANCE->zTypeRegistry()->fromJson<ModelInfo>(
-            zJson->zValue("model")),
-        zJson->zValue("itemName")->asString()->getString(),
-        (float)zJson->zValue("hp")->asNumber()->getNumber(),
-        (float)zJson->zValue("durability")->asNumber()->getNumber(),
-        (int)zJson->zValue("maxStack")->asNumber()->getNumber(),
-        zJson->zValue("solid")->asBool()->getBool(),
-        (float)zJson->zValue("hungerRecoveryPerHp")->asNumber()->getNumber(),
-        (float)zJson->zValue("thirstRecoveryPerHp")->asNumber()->getNumber(), groups);
-}
-
-Framework::JSON::JSONObject* BasicItemTypeFactory::toJson(
-    BasicItemType* zObject) const
-{
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue(
-        "name", new Framework::JSON::JSONString(zObject->getName()));
-    result->addValue(
-        "model", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zModel()));
-    result->addValue(
+    return new BasicItemType();
+}
+
+void BasicItemTypeFactory::fromJson(
+    BasicItemType* zResult, Framework::JSON::JSONObject* zJson) const
+{
+    zResult->setItemName(
+        Framework::Text(zJson->zValue("itemName")->asString()->getString()));
+    zResult->setHp((float)zJson->zValue("hp")->asNumber()->getNumber());
+    zResult->setDurability(
+        (float)zJson->zValue("durability")->asNumber()->getNumber());
+    zResult->setSolid(zJson->zValue("solid")->asBool()->getBool());
+    zResult->setHungerRecoveryPerHp(
+        (float)zJson->zValue("hungerRecoveryPerHp")->asNumber()->getNumber());
+    zResult->setThirstRecoveryPerHp(
+        (float)zJson->zValue("thirstRecoveryPerHp")->asNumber()->getNumber());
+    ItemTypeFactoryBase::fromJson(zResult, zJson);
+}
+
+void BasicItemTypeFactory::toJson(
+    BasicItemType* zObject, Framework::JSON::JSONObject* zResult) const
+{
+    zResult->addValue(
         "itemName", new Framework::JSON::JSONString(zObject->getItemName()));
-    result->addValue("hp", new Framework::JSON::JSONNumber(zObject->getHp()));
-    result->addValue("durability",
+    zResult->addValue("hp", new Framework::JSON::JSONNumber(zObject->getHp()));
+    zResult->addValue("durability",
         new Framework::JSON::JSONNumber(zObject->getDurability()));
-    result->addValue("maxStack",
-        new Framework::JSON::JSONNumber(zObject->getMaxStackSize()));
-    result->addValue(
+    zResult->addValue(
         "solid", new Framework::JSON::JSONBool(zObject->isSolid()));
-    result->addValue("hungerRecoveryPerHp",
+    zResult->addValue("hungerRecoveryPerHp",
         new Framework::JSON::JSONNumber(zObject->getHungerRecoveryPerHp()));
-    result->addValue("thirstRecoveryPerHp",
+    zResult->addValue("thirstRecoveryPerHp",
         new Framework::JSON::JSONNumber(zObject->getThirstRecoveryPerHp()));
-    Framework::JSON::JSONArray* groups = new Framework::JSON::JSONArray();
-    for (Framework::Text* group : zObject->getGroups())
-    {
-        groups->addValue(new Framework::JSON::JSONString(group->getText()));
-    }
-    result->addValue("groupNames", groups);
-    return result;
 }
 
-Framework::JSON::Validator::JSONValidator* BasicItemTypeFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
-{
-    return builder->withRequiredString("name")
-        ->finishString()
-        ->withRequiredAttribute(
-            "model", Game::INSTANCE->zTypeRegistry()->getValidator<ModelInfo>())
-        ->withRequiredString("itemName")
-        ->finishString()
-        ->withRequiredNumber("hp")
-        ->whichIsGreaterThen(0.0)
-        ->finishNumber()
-        ->withRequiredNumber("durability")
-        ->whichIsGreaterThen(0.0)
-        ->finishNumber()
-        ->withRequiredNumber("maxStack")
-        ->whichIsGreaterThen(0.0)
-        ->withDefault(50.0)
-        ->finishNumber()
-        ->withRequiredBool("solid")
-        ->withDefault(true)
-        ->finishBool()
-        ->withRequiredNumber("hungerRecoveryPerHp")
-        ->whichIsGreaterOrEqual(0.0)
-        ->withDefault(0.0)
-        ->finishNumber()
-        ->withRequiredNumber("thirstRecoveryPerHp")
-        ->whichIsGreaterOrEqual(0.0)
-        ->withDefault(0.0)
-        ->finishNumber()
-        ->withRequiredArray("groupNames")
-        ->addAcceptedStringInArray()
-        ->finishString()
-        ->withDefault(new Framework::JSON::JSONArray())
-        ->finishArray()
-        ->finishObject();
+JSONObjectValidationBuilder* BasicItemTypeFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return ItemTypeFactoryBase::addToValidator(
+        builder->withRequiredString("itemName")
+            ->finishString()
+            ->withRequiredNumber("hp")
+            ->whichIsGreaterThen(0.0)
+            ->withDefault(1.0)
+            ->finishNumber()
+            ->withRequiredNumber("durability")
+            ->whichIsGreaterThen(0.0)
+            ->withDefault(1.0)
+            ->finishNumber()
+            ->withRequiredBool("solid")
+            ->withDefault(true)
+            ->finishBool()
+            ->withRequiredNumber("hungerRecoveryPerHp")
+            ->whichIsGreaterOrEqual(0.0)
+            ->withDefault(0.0)
+            ->finishNumber()
+            ->withRequiredNumber("thirstRecoveryPerHp")
+            ->whichIsGreaterOrEqual(0.0)
+            ->withDefault(0.0)
+            ->finishNumber());
 }
 
 Framework::Text BasicItemTypeFactory::getTypeToken() const

+ 16 - 16
FactoryCraft/BasicItems.h

@@ -13,33 +13,33 @@ private:
     float thirstRecoveryPerHp;
 
 public:
-    BasicItemType(Framework::Text name,
-        ModelInfo* model,
-        Framework::Text itemName,
-        float hp,
-        float durability,
-        int maxStack,
-        bool solid,
-        float hungerRecoveryPerHp,
-        float thirstRecoveryPerHp,
-        Framework::RCArray<Framework::Text> groups);
+    BasicItemType();
     Item* createItem() const override;
+    void setItemName(Framework::Text itemName);
     Framework::Text getItemName() const;
+    void setHp(float hp);
     float getHp() const;
+    void setDurability(float durability);
     float getDurability() const;
+    void setSolid(bool solid);
     bool isSolid() const;
+    void setHungerRecoveryPerHp(float hungerRecoveryPerHp);
     float getHungerRecoveryPerHp() const;
+    void setThirstRecoveryPerHp(float thirstRecoveryPerHp);
     float getThirstRecoveryPerHp() const;
 };
 
-class BasicItemTypeFactory : public SubTypeFactory<ItemType, BasicItemType>
+class BasicItemTypeFactory : public ItemTypeFactoryBase<BasicItemType>
 {
 public:
     BasicItemTypeFactory();
-    BasicItemType* fromJson(Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(BasicItemType* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    BasicItemType* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(BasicItemType* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(BasicItemType* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };

+ 903 - 643
FactoryCraft/BasicTool.cpp

@@ -1,18 +1,21 @@
 #include "BasicTool.h"
 
+#include <numeric>
+
+#include "Block.h"
+#include "Dimension.h"
+#include "Entity.h"
 #include "Game.h"
 
-XPBasedLevelUpRule::XPBasedLevelUpRule(float xpIncrease,
-    float xpMultiplier,
-    float levelIncrease,
-    float levelMultiplier,
-    float maxLevel)
+#undef max
+
+XPBasedLevelUpRule::XPBasedLevelUpRule()
     : ItemSkillLevelUpRule(),
-      xpIncrease(xpIncrease),
-      xpMultiplier(xpMultiplier),
-      levelIncrease(levelIncrease),
-      levelMultiplier(levelMultiplier),
-      maxLevel(maxLevel)
+      xpIncrease(0.0),
+      xpMultiplier(2.0),
+      levelIncrease(1.0),
+      levelMultiplier(1.0),
+      maxLevel(std::numeric_limits<float>::max())
 {}
 
 void XPBasedLevelUpRule::applyOn(ItemSkill* zSkill)
@@ -26,26 +29,51 @@ void XPBasedLevelUpRule::applyOn(ItemSkill* zSkill)
     }
 }
 
+void XPBasedLevelUpRule::setXpIncrease(float xpIncrease)
+{
+    this->xpIncrease = xpIncrease;
+}
+
 float XPBasedLevelUpRule::getXpIncrease() const
 {
     return xpIncrease;
 }
 
+void XPBasedLevelUpRule::setXpMultiplier(float xpMultiplier)
+{
+    this->xpMultiplier = xpMultiplier;
+}
+
 float XPBasedLevelUpRule::getXpMultiplier() const
 {
     return xpMultiplier;
 }
 
+void XPBasedLevelUpRule::setLevelIncrease(float levelIncrease)
+{
+    this->levelIncrease = levelIncrease;
+}
+
 float XPBasedLevelUpRule::getLevelIncrease() const
 {
     return levelIncrease;
 }
 
+void XPBasedLevelUpRule::setLevelMultiplier(float levelMultiplier)
+{
+    this->levelMultiplier = levelMultiplier;
+}
+
 float XPBasedLevelUpRule::getLevelMultiplier() const
 {
     return levelMultiplier;
 }
 
+void XPBasedLevelUpRule::setMaxLevel(float maxLevel)
+{
+    this->maxLevel = maxLevel;
+}
+
 float XPBasedLevelUpRule::getMaxLevel() const
 {
     return maxLevel;
@@ -55,55 +83,47 @@ XPBasedLevelUpRuleFactory::XPBasedLevelUpRuleFactory()
     : SubTypeFactory()
 {}
 
-XPBasedLevelUpRule* XPBasedLevelUpRuleFactory::fromJson(
+XPBasedLevelUpRule* XPBasedLevelUpRuleFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
-    float maxLevel;
-    if (zJson->zValue("maxLevel")->getType()
-        == Framework::JSON::JSONType::NULL_)
-    {
-        maxLevel = -1;
-    }
-    else
+    return new XPBasedLevelUpRule();
+}
+
+void XPBasedLevelUpRuleFactory::fromJson(
+    XPBasedLevelUpRule* zResult, Framework::JSON::JSONObject* zJson) const
+{
+    if (zJson->hasValue("maxLevel"))
     {
-        maxLevel = (float)zJson->zValue("maxLevel")->asNumber()->getNumber();
+        zResult->setMaxLevel(
+            (float)zJson->zValue("maxLevel")->asNumber()->getNumber());
     }
-    return new XPBasedLevelUpRule(
-        (float)zJson->zValue("xpIncrease")->asNumber()->getNumber(),
-        (float)zJson->zValue("xpMultiplier")->asNumber()->getNumber(),
-        (float)zJson->zValue("levelIncrease")->asNumber()->getNumber(),
-        (float)zJson->zValue("levelMultiplier")->asNumber()->getNumber(),
-        maxLevel);
+    zResult->setXpIncrease(
+        (float)zJson->zValue("xpIncrease")->asNumber()->getNumber());
+    zResult->setXpMultiplier(
+        (float)zJson->zValue("xpMultiplier")->asNumber()->getNumber());
+    zResult->setLevelIncrease(
+        (float)zJson->zValue("levelIncrease")->asNumber()->getNumber());
+    zResult->setLevelMultiplier(
+        (float)zJson->zValue("levelMultiplier")->asNumber()->getNumber());
 }
 
-Framework::JSON::JSONObject* XPBasedLevelUpRuleFactory::toJson(
-    XPBasedLevelUpRule* zObject) const
+void XPBasedLevelUpRuleFactory::toJson(
+    XPBasedLevelUpRule* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue("xpIncrease",
+    zResult->addValue("xpIncrease",
         new Framework::JSON::JSONNumber(zObject->getXpIncrease()));
-    result->addValue("xpMultiplier",
+    zResult->addValue("xpMultiplier",
         new Framework::JSON::JSONNumber(zObject->getXpMultiplier()));
-    result->addValue("levelIncrease",
+    zResult->addValue("levelIncrease",
         new Framework::JSON::JSONNumber(zObject->getLevelIncrease()));
-    result->addValue("levelMultiplier",
+    zResult->addValue("levelMultiplier",
         new Framework::JSON::JSONNumber(zObject->getLevelMultiplier()));
-    if (zObject->getMaxLevel() < 0)
-    {
-        result->addValue("maxLevel",
-            new Framework::JSON::JSONNumber(zObject->getMaxLevel()));
-    }
-    else
-    {
-        result->addValue("maxLevel", new Framework::JSON::JSONValue());
-    }
-    return result;
+    zResult->addValue(
+        "maxLevel", new Framework::JSON::JSONNumber(zObject->getMaxLevel()));
 }
 
-Framework::JSON::Validator::JSONValidator*
-XPBasedLevelUpRuleFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
+JSONObjectValidationBuilder* XPBasedLevelUpRuleFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
     return builder->withRequiredNumber("xpIncrease")
         ->whichIsGreaterOrEqual(0.0)
@@ -122,10 +142,8 @@ XPBasedLevelUpRuleFactory::getValidator(
         ->withDefault(1.0)
         ->finishNumber()
         ->withRequiredNumber("maxLevel")
-        ->withDefaultNull()
-        ->whichCanBeNull()
-        ->finishNumber()
-        ->finishObject();
+        ->whichIsOptional()
+        ->finishNumber();
 }
 
 Framework::Text XPBasedLevelUpRuleFactory::getTypeToken() const
@@ -133,9 +151,8 @@ Framework::Text XPBasedLevelUpRuleFactory::getTypeToken() const
     return "xpBased";
 }
 
-BasicToolItem::BasicToolItem(int itemTypeId, Framework::Text name,
-    float maxHp,
-    float maxDurability)
+BasicToolItem::BasicToolItem(
+    int itemTypeId, Framework::Text name, float maxHp, float maxDurability)
     : Item(itemTypeId, name),
       headMaterialHardness(0.0),
       rodMaterialHardness(0.0),
@@ -182,46 +199,29 @@ float BasicToolItem::getHandleMaterialHardness() const
     return handleMaterialHardness;
 }
 
-BasicToolItemType::BasicToolItemType(Framework::Text name,
-    ModelInfo* model,
-    float headMaterialHardness,
-    float rodMaterialHardness,
-    float handleMaterialHardness,
-    float baseDurability,
-    float baseDurabilityMultiplier,
-    float headMaterialDurability,
-    float headMaterialDurabilityMultiplier,
-    float rodMaterialDurability,
-    float rodMaterialDurabilityMultiplier,
-    float handleMaterialDurability,
-    float handleMaterialDurabilityMultiplier,
-    ItemSkillLevelUpRule* levelUpRule,
-    Framework::Text brokenItemTypeName,
-    Framework::JSON::JSONObject* itemSkillConfigJson,
-    int maxStackSize,
-    Framework::RCArray<Framework::Text> groups)
-    : ItemType(name, model, maxStackSize, groups),
-      headMaterialHardness(headMaterialHardness),
-      rodMaterialHardness(rodMaterialHardness),
-      handleMaterialHardness(handleMaterialHardness),
-      baseDurability(baseDurability),
-      baseDurabilityMultiplier(baseDurabilityMultiplier),
-      headMaterialDurability(headMaterialDurability),
-      headMaterialDurabilityMultiplier(headMaterialDurabilityMultiplier),
-      rodMaterialDurability(rodMaterialDurability),
-      rodMaterialDurabilityMultiplier(rodMaterialDurabilityMultiplier),
-      handleMaterialDurability(handleMaterialDurability),
-      handleMaterialDurabilityMultiplier(handleMaterialDurabilityMultiplier),
-      levelUpRule(levelUpRule),
-      brokenItemTypeName(brokenItemTypeName),
-      itemSkillConfigJson(itemSkillConfigJson),
+BasicToolItemType::BasicToolItemType()
+    : ItemType(),
+      headMaterialHardness(1.f),
+      rodMaterialHardness(1.f),
+      handleMaterialHardness(1.f),
+      baseDurability(10.f),
+      baseDurabilityMultiplier(1.f),
+      headMaterialDurability(10.f),
+      headMaterialDurabilityMultiplier(0.f),
+      rodMaterialDurability(10.f),
+      rodMaterialDurabilityMultiplier(0.f),
+      handleMaterialDurability(10.f),
+      handleMaterialDurabilityMultiplier(0.0),
+      levelUpRule(0),
+      brokenItemTypeName(),
+      itemSkillConfigJson(0),
       brokenItemTypeId(-1)
 {}
 
 BasicToolItemType::~BasicToolItemType()
 {
-    levelUpRule->release();
-    itemSkillConfigJson->release();
+    if (levelUpRule) levelUpRule->release();
+    if (itemSkillConfigJson) itemSkillConfigJson->release();
 }
 
 void BasicToolItemType::loadSuperItem(
@@ -333,241 +333,308 @@ void BasicToolItemType::addItemAttributes(
     ItemType::addItemAttributes(item, zItemObjet);
 }
 
+ItemSkill* BasicToolItemType::createDefaultItemSkill() const
+{
+    return Game::INSTANCE->zTypeRegistry()->fromJson<ItemSkill>(
+        itemSkillConfigJson);
+}
+
+void BasicToolItemType::setBrokenItemTypeName(
+    Framework::Text brokenItemTypeName)
+{
+    this->brokenItemTypeName = brokenItemTypeName;
+}
+
+Framework::Text BasicToolItemType::getBrokenItemTypeName() const
+{
+    return brokenItemTypeName;
+}
+
+void BasicToolItemType::setHeadMaterialHardness(float hardness)
+{
+    headMaterialHardness = hardness;
+}
+
 float BasicToolItemType::getHeadMaterialHardness() const
 {
     return headMaterialHardness;
 }
 
+void BasicToolItemType::setRodMaterialHardness(float hardness)
+{
+    rodMaterialHardness = hardness;
+}
+
 float BasicToolItemType::getRodMaterialHardness() const
 {
     return rodMaterialHardness;
 }
 
+void BasicToolItemType::setHandleMaterialHardness(float hardness)
+{
+    handleMaterialHardness = hardness;
+}
+
 float BasicToolItemType::getHandleMaterialHardness() const
 {
     return handleMaterialHardness;
 }
 
+void BasicToolItemType::setBaseDurability(float durability)
+{
+    baseDurability = durability;
+}
+
 float BasicToolItemType::getBaseDurablility() const
 {
     return baseDurability;
 }
 
+void BasicToolItemType::setBaseDurabilityMultiplier(float multiplier)
+{
+    baseDurabilityMultiplier = multiplier;
+}
+
 float BasicToolItemType::getBaseDurabilityMultiplier() const
 {
     return baseDurabilityMultiplier;
 }
 
+void BasicToolItemType::setHeadMaterialDurability(float durability)
+{
+    headMaterialDurability = durability;
+}
+
 float BasicToolItemType::getHeadMaterialDurability() const
 {
     return headMaterialDurability;
 }
 
+void BasicToolItemType::setHeadMaterialDurabilityMultiplier(float multiplier)
+{
+    headMaterialDurabilityMultiplier = multiplier;
+}
+
 float BasicToolItemType::getHeadMaterialDurabilityMultiplier() const
 {
     return headMaterialDurabilityMultiplier;
 }
 
+void BasicToolItemType::setRodMaterialDurability(float durability)
+{
+    rodMaterialDurability = durability;
+}
+
 float BasicToolItemType::getRodMaterialDurability() const
 {
     return rodMaterialDurability;
 }
 
+void BasicToolItemType::setRodMaterialDurabilityMultiplier(float multiplier)
+{
+    rodMaterialDurabilityMultiplier = multiplier;
+}
+
 float BasicToolItemType::getRodMaterialDurabilityMultiplier() const
 {
     return rodMaterialDurabilityMultiplier;
 }
 
+void BasicToolItemType::setHandleMaterialDurability(float durability)
+{
+    handleMaterialDurability = durability;
+}
+
 float BasicToolItemType::getHandleMaterialDurability() const
 {
     return handleMaterialDurability;
 }
 
+void BasicToolItemType::setHandleMaterialDurabilityMultiplier(float multiplier)
+{
+    handleMaterialDurabilityMultiplier = multiplier;
+}
+
 float BasicToolItemType::getHandleMaterialDurabilityMultiplier() const
 {
     return handleMaterialDurabilityMultiplier;
 }
 
+void BasicToolItemType::setLevelUpRule(ItemSkillLevelUpRule* rule)
+{
+    if (levelUpRule) levelUpRule->release();
+    levelUpRule = rule;
+}
+
 ItemSkillLevelUpRule* BasicToolItemType::zLevelUpRule() const
 {
     return levelUpRule;
 }
 
+void BasicToolItemType::setItemSkillConfigJson(
+    Framework::JSON::JSONObject* zJson)
+{
+    if (itemSkillConfigJson) itemSkillConfigJson->release();
+    itemSkillConfigJson = zJson;
+}
+
 Framework::JSON::JSONObject* BasicToolItemType::getItemSkillConfigJson() const
 {
     return dynamic_cast<Framework::JSON::JSONObject*>(
         itemSkillConfigJson->getThis());
 }
 
-ItemSkill* BasicToolItemType::createDefaultItemSkill() const
+BasicToolItemTypeFactory::BasicToolItemTypeFactory()
+    : ItemTypeFactoryBase()
+{}
+
+BasicToolItemType* BasicToolItemTypeFactory::createValue(
+    Framework::JSON::JSONObject* zJson) const
 {
-    return Game::INSTANCE->zTypeRegistry()->fromJson<ItemSkill>(
-        itemSkillConfigJson);
+    return new BasicToolItemType();
 }
 
-BasicToolItemTypeFactory::BasicToolItemTypeFactory() {}
-
-BasicToolItemType* BasicToolItemTypeFactory::fromJson(
-    Framework::JSON::JSONObject* zJson) const
+void BasicToolItemTypeFactory::fromJson(
+    BasicToolItemType* zResult, Framework::JSON::JSONObject* zJson) const
 {
-    Framework::RCArray<Framework::Text> groups;
-    for (Framework::JSON::JSONValue* group :
-        *zJson->zValue("groupNames")->asArray())
-    {
-        groups.add(new Framework::Text(group->asString()->getString()));
-    }
-    return new BasicToolItemType(zJson->zValue("name")->asString()->getString(),
-        Game::INSTANCE->zTypeRegistry()->fromJson<ModelInfo>(
-            zJson->zValue("model")),
-        (float)zJson->zValue("headMaterialHardness")->asNumber()->getNumber(),
-        (float)zJson->zValue("rodMaterialHardness")->asNumber()->getNumber(),
-        (float)zJson->zValue("handleMaterialHardness")->asNumber()->getNumber(),
-        (float)zJson->zValue("baseDurability")->asNumber()->getNumber(),
+    zResult->setHandleMaterialHardness(
+        (float)zJson->zValue("headMaterialHardness")->asNumber()->getNumber());
+    zResult->setRodMaterialHardness(
+        (float)zJson->zValue("rodMaterialHardness")->asNumber()->getNumber());
+    zResult->setHandleMaterialHardness(
+        (float)zJson->zValue("handleMaterialHardness")
+            ->asNumber()
+            ->getNumber());
+    zResult->setBaseDurability(
+        (float)zJson->zValue("baseDurability")->asNumber()->getNumber());
+    zResult->setBaseDurabilityMultiplier(
         (float)zJson->zValue("baseDurabilityMultiplier")
             ->asNumber()
-            ->getNumber(),
-        (float)zJson->zValue("headMaterialDurability")->asNumber()->getNumber(),
+            ->getNumber());
+    zResult->setHeadMaterialDurability(
+        (float)zJson->zValue("headMaterialDurability")
+            ->asNumber()
+            ->getNumber());
+    zResult->setHeadMaterialDurabilityMultiplier(
         (float)zJson->zValue("headMaterialDurabilityMultiplier")
             ->asNumber()
-            ->getNumber(),
-        (float)zJson->zValue("rodMaterialDurability")->asNumber()->getNumber(),
+            ->getNumber());
+    zResult->setRodMaterialDurability(
+        (float)zJson->zValue("rodMaterialDurability")->asNumber()->getNumber());
+    zResult->setRodMaterialDurabilityMultiplier(
         (float)zJson->zValue("rodMaterialDurabilityMultiplier")
             ->asNumber()
-            ->getNumber(),
+            ->getNumber());
+    zResult->setHandleMaterialDurability(
         (float)zJson->zValue("handleMaterialDurability")
             ->asNumber()
-            ->getNumber(),
+            ->getNumber());
+    zResult->setHandleMaterialDurabilityMultiplier(
         (float)zJson->zValue("handleMaterialDurabilityMultiplier")
             ->asNumber()
-            ->getNumber(),
+            ->getNumber());
+    zResult->setLevelUpRule(
         Game::INSTANCE->zTypeRegistry()->fromJson<ItemSkillLevelUpRule>(
-            zJson->zValue("levelUpRule")),
-        zJson->zValue("brokenItemTypeName")->asString()->getString(),
-        zJson->getValue("itemSkill")->asObject(),
-        (int)zJson->zValue("maxStack")->asNumber()->getNumber(), groups);
+            zJson->zValue("levelUpRule")));
+    zResult->setBrokenItemTypeName(
+        zJson->zValue("brokenItemTypeName")->asString()->getString());
+    zResult->setItemSkillConfigJson(zJson->getValue("itemSkill")->asObject());
+    ItemTypeFactoryBase::fromJson(zResult, zJson);
 }
 
-Framework::JSON::JSONObject* BasicToolItemTypeFactory::toJson(
-    BasicToolItemType* zObject) const
+void BasicToolItemTypeFactory::toJson(
+    BasicToolItemType* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* json = new Framework::JSON::JSONObject();
-    json->addValue("name", new Framework::JSON::JSONString(zObject->getName()));
-    json->addValue(
-        "model", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zModel()));
-    json->addValue("headMaterialHardness",
+    zResult->addValue("headMaterialHardness",
         new Framework::JSON::JSONNumber(zObject->getHeadMaterialHardness()));
-    json->addValue("rodMaterialHardness",
+    zResult->addValue("rodMaterialHardness",
         new Framework::JSON::JSONNumber(zObject->getRodMaterialHardness()));
-    json->addValue("handleMaterialHardness",
+    zResult->addValue("handleMaterialHardness",
         new Framework::JSON::JSONNumber(zObject->getHandleMaterialHardness()));
-    json->addValue("baseDurability",
+    zResult->addValue("baseDurability",
         new Framework::JSON::JSONNumber(zObject->getBaseDurablility()));
-    json->addValue("baseDurabilityMultiplier",
+    zResult->addValue("baseDurabilityMultiplier",
         new Framework::JSON::JSONNumber(
             zObject->getBaseDurabilityMultiplier()));
-    json->addValue("headMaterialDurability",
+    zResult->addValue("headMaterialDurability",
         new Framework::JSON::JSONNumber(zObject->getHeadMaterialDurability()));
-
-    json->addValue("headMaterialDurabilityMultiplier",
+    zResult->addValue("headMaterialDurabilityMultiplier",
         new Framework::JSON::JSONNumber(
             zObject->getHeadMaterialDurabilityMultiplier()));
-    json->addValue("rodMaterialDurability",
+    zResult->addValue("rodMaterialDurability",
         new Framework::JSON::JSONNumber(zObject->getRodMaterialDurability()));
-    json->addValue("rodMaterialDurabilityMultiplier",
+    zResult->addValue("rodMaterialDurabilityMultiplier",
         new Framework::JSON::JSONNumber(
             zObject->getRodMaterialDurabilityMultiplier()));
-    json->addValue("handleMaterialDurability",
+    zResult->addValue("handleMaterialDurability",
         new Framework::JSON::JSONNumber(
             zObject->getHandleMaterialDurability()));
-    json->addValue("handleMaterialDurabilityMultiplier",
+    zResult->addValue("handleMaterialDurabilityMultiplier",
         new Framework::JSON::JSONNumber(
             zObject->getHandleMaterialDurabilityMultiplier()));
-    json->addValue("levelUpRule",
+    zResult->addValue("levelUpRule",
         Game::INSTANCE->zTypeRegistry()->toJson(zObject->zLevelUpRule()));
-    json->addValue("brokenItemTypeName",
+    zResult->addValue("brokenItemTypeName",
         new Framework::JSON::JSONString(zObject->zBrokenItemType()->getName()));
-    json->addValue("itemSkill", zObject->getItemSkillConfigJson());
-    json->addValue("maxStack",
-        new Framework::JSON::JSONNumber(zObject->getMaxStackSize()));
-    Framework::JSON::JSONArray* groups = new Framework::JSON::JSONArray();
-    for (Framework::Text* group : zObject->getGroups())
-    {
-        groups->addValue(new Framework::JSON::JSONString(group->getText()));
-    }
-    json->addValue("groupNames", groups);
-    return json;
-}
-
-Framework::JSON::Validator::JSONValidator*
-BasicToolItemTypeFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
-{
-    return builder->withRequiredString("name")
-        ->finishString()
-        ->withRequiredAttribute(
-            "model", Game::INSTANCE->zTypeRegistry()->getValidator<ModelInfo>())
-        ->withRequiredNumber("headMaterialHardness")
-        ->withDefault(1.0)
-        ->whichIsGreaterOrEqual(0.0)
-        ->finishNumber()
-        ->withRequiredNumber("rodMaterialHardness")
-        ->withDefault(1.0)
-        ->whichIsGreaterOrEqual(0.0)
-        ->finishNumber()
-        ->withRequiredNumber("handleMaterialHardness")
-        ->withDefault(1.0)
-        ->whichIsGreaterOrEqual(0.0)
-        ->finishNumber()
-        ->withRequiredNumber("baseDurability")
-        ->withDefault(10.0)
-        ->whichIsGreaterOrEqual(0.0)
-        ->finishNumber()
-        ->withRequiredNumber("baseDurabilityMultiplier")
-        ->withDefault(1.0)
-        ->whichIsGreaterOrEqual(0.0)
-        ->finishNumber()
-        ->withRequiredNumber("headMaterialDurability")
-        ->withDefault(10.0)
-        ->whichIsGreaterOrEqual(0.0)
-        ->finishNumber()
-        ->withRequiredNumber("headMaterialDurabilityMultiplier")
-        ->withDefault(0.0)
-        ->whichIsGreaterOrEqual(0.0)
-        ->finishNumber()
-        ->withRequiredNumber("rodMaterialDurability")
-        ->withDefault(10.0)
-        ->whichIsGreaterOrEqual(0.0)
-        ->finishNumber()
-        ->withRequiredNumber("rodMaterialDurabilityMultiplier")
-        ->withDefault(0.0)
-        ->whichIsGreaterOrEqual(0.0)
-        ->finishNumber()
-        ->withRequiredNumber("handleMaterialDurability")
-        ->withDefault(10.0)
-        ->whichIsGreaterOrEqual(0.0)
-        ->finishNumber()
-        ->withRequiredNumber("handleMaterialDurabilityMultiplier")
-        ->withDefault(0.0)
-        ->whichIsGreaterOrEqual(0.0)
-        ->finishNumber()
-        ->withRequiredNumber("maxStack")
-        ->withDefault(10)
-        ->whichIsGreaterOrEqual(1)
-        ->finishNumber()
-        ->withRequiredString("brokenItemTypeName")
-        ->finishString()
-        ->withRequiredAttribute("levelUpRule",
-            Game::INSTANCE->zTypeRegistry()
-                ->getValidator<ItemSkillLevelUpRule>())
-        ->withRequiredAttribute("itemSkill",
-            Game::INSTANCE->zTypeRegistry()->getValidator<ItemSkill>())
-        ->withRequiredArray("groupNames")
-        ->addAcceptedStringInArray()
-        ->finishString()
-        ->withDefault(new Framework::JSON::JSONArray())
-        ->finishArray()
-        ->finishObject();
+    zResult->addValue("itemSkill", zObject->getItemSkillConfigJson());
+    ItemTypeFactoryBase::toJson(zObject, zResult);
+}
+
+JSONObjectValidationBuilder* BasicToolItemTypeFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return ItemTypeFactoryBase::addToValidator(
+        builder->withRequiredNumber("headMaterialHardness")
+            ->withDefault(1.0)
+            ->whichIsGreaterOrEqual(0.0)
+            ->finishNumber()
+            ->withRequiredNumber("rodMaterialHardness")
+            ->withDefault(1.0)
+            ->whichIsGreaterOrEqual(0.0)
+            ->finishNumber()
+            ->withRequiredNumber("handleMaterialHardness")
+            ->withDefault(1.0)
+            ->whichIsGreaterOrEqual(0.0)
+            ->finishNumber()
+            ->withRequiredNumber("baseDurability")
+            ->withDefault(10.0)
+            ->whichIsGreaterOrEqual(0.0)
+            ->finishNumber()
+            ->withRequiredNumber("baseDurabilityMultiplier")
+            ->withDefault(1.0)
+            ->whichIsGreaterOrEqual(0.0)
+            ->finishNumber()
+            ->withRequiredNumber("headMaterialDurability")
+            ->withDefault(10.0)
+            ->whichIsGreaterOrEqual(0.0)
+            ->finishNumber()
+            ->withRequiredNumber("headMaterialDurabilityMultiplier")
+            ->withDefault(0.0)
+            ->whichIsGreaterOrEqual(0.0)
+            ->finishNumber()
+            ->withRequiredNumber("rodMaterialDurability")
+            ->withDefault(10.0)
+            ->whichIsGreaterOrEqual(0.0)
+            ->finishNumber()
+            ->withRequiredNumber("rodMaterialDurabilityMultiplier")
+            ->withDefault(0.0)
+            ->whichIsGreaterOrEqual(0.0)
+            ->finishNumber()
+            ->withRequiredNumber("handleMaterialDurability")
+            ->withDefault(10.0)
+            ->whichIsGreaterOrEqual(0.0)
+            ->finishNumber()
+            ->withRequiredNumber("handleMaterialDurabilityMultiplier")
+            ->withDefault(0.0)
+            ->whichIsGreaterOrEqual(0.0)
+            ->finishNumber()
+            ->withRequiredString("brokenItemTypeName")
+            ->finishString()
+            ->withRequiredAttribute("levelUpRule",
+                Game::INSTANCE->zTypeRegistry()
+                    ->getValidator<ItemSkillLevelUpRule>())
+            ->withRequiredAttribute("itemSkill",
+                Game::INSTANCE->zTypeRegistry()->getValidator<ItemSkill>()));
 }
 
 Framework::Text BasicToolItemTypeFactory::getTypeToken() const
@@ -575,30 +642,18 @@ Framework::Text BasicToolItemTypeFactory::getTypeToken() const
     return "tool";
 }
 
-BlockReplaceItemSkillConfig::BlockReplaceItemSkillConfig(
-    BlockFilter* targetBlockFilter,
-    int replacementBlockTypeId,
-    int cooldownTicks,
-    float staminaCost,
-    float staminaCostDevider,
-    float additionalStaminaCostDeviderPerLevel,
-    float durabilityCost,
-    float durabilityCostDevider,
-    float additionalDurabilityCostDeviderPerLevel,
-    float xpGain)
+BlockReplaceItemSkillConfig::BlockReplaceItemSkillConfig()
     : ReferenceCounter(),
-      targetBlockFilter(targetBlockFilter),
-      replacementBlockTypeId(replacementBlockTypeId),
-      cooldownTicks(cooldownTicks),
-      staminaCost(staminaCost),
-      staminaCostDevider(staminaCostDevider),
-      additionalStaminaCostDeviderPerLevel(
-          additionalStaminaCostDeviderPerLevel),
-      durabilityCost(durabilityCost),
-      durabilityCostDevider(durabilityCostDevider),
-      additionalDurabilityCostDeviderPerLevel(
-          additionalDurabilityCostDeviderPerLevel),
-      xpGain(xpGain)
+      targetBlockFilter(0),
+      replacementBlockTypeId(-1),
+      cooldownTicks(20),
+      staminaCost(0.5f),
+      staminaCostDevider(0.8f),
+      additionalStaminaCostDeviderPerLevel(0.2f),
+      durabilityCost(0.5f),
+      durabilityCostDevider(0.89f),
+      additionalDurabilityCostDeviderPerLevel(0.02f),
+      xpGain(0.5f)
 {}
 
 BlockReplaceItemSkillConfig::~BlockReplaceItemSkillConfig()
@@ -606,53 +661,111 @@ BlockReplaceItemSkillConfig::~BlockReplaceItemSkillConfig()
     if (targetBlockFilter) targetBlockFilter->release();
 }
 
+void BlockReplaceItemSkillConfig::setTargetBlockFilter(
+    BlockFilter* targetBlockFilter)
+{
+    this->targetBlockFilter = targetBlockFilter;
+}
+
 BlockFilter* BlockReplaceItemSkillConfig::zTargetBlockFilter() const
 {
     return targetBlockFilter;
 }
 
+void BlockReplaceItemSkillConfig::setReplacementBlockTypeId(
+    int replacementBlockTypeId)
+{
+    this->replacementBlockTypeId = replacementBlockTypeId;
+}
+
 int BlockReplaceItemSkillConfig::getReplacementBlockTypeId() const
 {
     return replacementBlockTypeId;
 }
 
+void BlockReplaceItemSkillConfig::setCooldownTicks(int cooldownTicks)
+{
+    this->cooldownTicks = cooldownTicks;
+}
+
 int BlockReplaceItemSkillConfig::getCooldownTicks() const
 {
     return cooldownTicks;
 }
 
+void BlockReplaceItemSkillConfig::setStaminaCost(float staminaCost)
+{
+    this->staminaCost = staminaCost;
+}
+
 float BlockReplaceItemSkillConfig::getStaminaCost() const
 {
     return staminaCost;
 }
 
+void BlockReplaceItemSkillConfig::setStaminaCostDevider(
+    float staminaCostDevider)
+{
+    this->staminaCostDevider = staminaCostDevider;
+}
+
 float BlockReplaceItemSkillConfig::getStaminaCostDevider() const
 {
     return staminaCostDevider;
 }
 
+void BlockReplaceItemSkillConfig::setAdditionalStaminaCostDeviderPerLevel(
+    float additionalStaminaCostDeviderPerLevel)
+{
+    this->additionalStaminaCostDeviderPerLevel
+        = additionalStaminaCostDeviderPerLevel;
+}
+
 float BlockReplaceItemSkillConfig::getAdditionalStaminaCostDeviderPerLevel()
     const
 {
     return additionalStaminaCostDeviderPerLevel;
 }
 
+void BlockReplaceItemSkillConfig::setDurabilityCost(float durabilityCost)
+{
+    this->durabilityCost = durabilityCost;
+}
+
 float BlockReplaceItemSkillConfig::getDurabilityCost() const
 {
     return durabilityCost;
 }
 
+void BlockReplaceItemSkillConfig::setDurabilityCostDevider(
+    float durabilityCostDevider)
+{
+    this->durabilityCostDevider = durabilityCostDevider;
+}
+
 float BlockReplaceItemSkillConfig::getDurabilityCostDevider() const
 {
     return durabilityCostDevider;
 }
 
+void BlockReplaceItemSkillConfig::setAdditionalDurabilityCostDeviderPerLevel(
+    float additionalDurabilityCostDeviderPerLevel)
+{
+    this->additionalDurabilityCostDeviderPerLevel
+        = additionalDurabilityCostDeviderPerLevel;
+}
+
 float BlockReplaceItemSkillConfig::getAdditionalDurabilityCostDeviderPerLevel()
     const
 {
     return additionalDurabilityCostDeviderPerLevel;
 }
 
+void BlockReplaceItemSkillConfig::setXpGain(float xpGain)
+{
+    this->xpGain = xpGain;
+}
+
 float BlockReplaceItemSkillConfig::getXpGain() const
 {
     return xpGain;
@@ -662,82 +775,96 @@ BlockReplaceItemSkillConfigFactory::BlockReplaceItemSkillConfigFactory()
     : TypeFactory()
 {}
 
-BlockReplaceItemSkillConfig* BlockReplaceItemSkillConfigFactory::fromJson(
-    Framework::JSON::JSONValue* zJson) const
+BlockReplaceItemSkillConfig* BlockReplaceItemSkillConfigFactory::createValue(
+    Framework::JSON::JSONObject* zJson) const
 {
-    return new BlockReplaceItemSkillConfig(
+    return new BlockReplaceItemSkillConfig();
+}
+
+void BlockReplaceItemSkillConfigFactory::fromJson(
+    BlockReplaceItemSkillConfig* zResult,
+    Framework::JSON::JSONObject* zJson) const
+{
+    zResult->setTargetBlockFilter(
         Game::INSTANCE->zTypeRegistry()->fromJson<BlockFilter>(
-            zJson->asObject()->zValue("targetFilter")),
+            zJson->asObject()->zValue("targetFilter")));
+    zResult->setCooldownTicks((int)zJson->asObject()
+                                  ->zValue("cooldownTicks")
+                                  ->asNumber()
+                                  ->getNumber());
+    zResult->setReplacementBlockTypeId(
         Game::INSTANCE->getBlockTypeId(zJson->asObject()
                                            ->zValue("replacementBlockType")
                                            ->asString()
-                                           ->getString()),
-        (int)zJson->asObject()
-            ->zValue("cooldownTicks")
-            ->asNumber()
-            ->getNumber(),
-        (float)zJson->asObject()
-            ->zValue("staminaCost")
-            ->asNumber()
-            ->getNumber(),
-        (float)zJson->asObject()
-            ->zValue("staminaCostDevider")
-            ->asNumber()
-            ->getNumber(),
+                                           ->getString()));
+    zResult->setCooldownTicks((int)zJson->asObject()
+                                  ->zValue("cooldownTicks")
+                                  ->asNumber()
+                                  ->getNumber());
+    zResult->setStaminaCost((float)zJson->asObject()
+                                ->zValue("staminaCost")
+                                ->asNumber()
+                                ->getNumber());
+    zResult->setStaminaCostDevider((float)zJson->asObject()
+                                       ->zValue("staminaCostDevider")
+                                       ->asNumber()
+                                       ->getNumber());
+    zResult->setAdditionalStaminaCostDeviderPerLevel(
         (float)zJson->asObject()
             ->zValue("additionalStaminaCostDeviderPerLevel")
             ->asNumber()
-            ->getNumber(),
-        (float)zJson->asObject()
-            ->zValue("durabilityCost")
-            ->asNumber()
-            ->getNumber(),
-        (float)zJson->asObject()
-            ->zValue("durabilityCostDevider")
-            ->asNumber()
-            ->getNumber(),
+            ->getNumber());
+    zResult->setDurabilityCost((float)zJson->asObject()
+                                   ->zValue("durabilityCost")
+                                   ->asNumber()
+                                   ->getNumber());
+    zResult->setDurabilityCostDevider((float)zJson->asObject()
+                                          ->zValue("durabilityCostDevider")
+                                          ->asNumber()
+                                          ->getNumber());
+    zResult->setAdditionalDurabilityCostDeviderPerLevel(
         (float)zJson->asObject()
             ->zValue("additionalDurabilityCostDeviderPerLevel")
             ->asNumber()
-            ->getNumber(),
+            ->getNumber());
+    zResult->setXpGain(
         (float)zJson->asObject()->zValue("xpGain")->asNumber()->getNumber());
 }
 
-Framework::JSON::JSONValue* BlockReplaceItemSkillConfigFactory::toJson(
-    BlockReplaceItemSkillConfig* zObject) const
+void BlockReplaceItemSkillConfigFactory::toJson(
+    BlockReplaceItemSkillConfig* zObject,
+    Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue("targetFilter",
+    zResult->addValue("targetFilter",
         Game::INSTANCE->zTypeRegistry()->toJson(zObject->zTargetBlockFilter()));
-    result->addValue("replacementBlockType",
+    zResult->addValue("replacementBlockType",
         new Framework::JSON::JSONString(
             Game::INSTANCE->zBlockType(zObject->getReplacementBlockTypeId())
                 ->getName()));
-    result->addValue("cooldownTicks",
+    zResult->addValue("cooldownTicks",
         new Framework::JSON::JSONNumber(zObject->getCooldownTicks()));
-    result->addValue("staminaCost",
+    zResult->addValue("staminaCost",
         new Framework::JSON::JSONNumber(zObject->getStaminaCost()));
-    result->addValue("staminaCostDevider",
+    zResult->addValue("staminaCostDevider",
         new Framework::JSON::JSONNumber(zObject->getStaminaCostDevider()));
-    result->addValue("additionalStaminaCostDeviderPerLevel",
+    zResult->addValue("additionalStaminaCostDeviderPerLevel",
         new Framework::JSON::JSONNumber(
             zObject->getAdditionalStaminaCostDeviderPerLevel()));
-    result->addValue("durabilityCost",
+    zResult->addValue("durabilityCost",
         new Framework::JSON::JSONNumber(zObject->getDurabilityCost()));
-    result->addValue("durabilityCostDevider",
+    zResult->addValue("durabilityCostDevider",
         new Framework::JSON::JSONNumber(zObject->getDurabilityCostDevider()));
-    result->addValue("additionalDurabilityCostDeviderPerLevel",
+    zResult->addValue("additionalDurabilityCostDeviderPerLevel",
         new Framework::JSON::JSONNumber(
             zObject->getAdditionalDurabilityCostDeviderPerLevel()));
-    result->addValue(
+    zResult->addValue(
         "xpGain", new Framework::JSON::JSONNumber(zObject->getXpGain()));
-    return result;
 }
 
-Framework::JSON::Validator::JSONValidator*
-BlockReplaceItemSkillConfigFactory::getValidator() const
+JSONObjectValidationBuilder* BlockReplaceItemSkillConfigFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
-    return Framework::JSON::Validator::JSONValidator::buildForObject()
+    return builder
         ->withRequiredAttribute("targetFilter",
             Game::INSTANCE->zTypeRegistry()->getValidator<BlockFilter>())
         ->withRequiredString("replacementBlockType")
@@ -773,22 +900,21 @@ BlockReplaceItemSkillConfigFactory::getValidator() const
         ->withRequiredNumber("xpGain")
         ->whichIsGreaterOrEqual(0)
         ->withDefault(0.5)
-        ->finishNumber()
-        ->finishObject();
-}
-
-BlockReplaceItemSkill::BlockReplaceItemSkill(float xp,
-    float maxXp,
-    float level,
-    BlockReplaceItemSkillConfig* invalidUseConfig,
-    Framework::RCArray<BlockReplaceItemSkillConfig> configs,
-    int cooldownTicks)
-    : ItemSkill(xp, maxXp, level),
-      invalidUseConfig(invalidUseConfig),
-      configs(configs),
-      cooldownTicks(cooldownTicks)
+        ->finishNumber();
+}
+
+BlockReplaceItemSkill::BlockReplaceItemSkill()
+    : ItemSkill(),
+      invalidUseConfig(0),
+      configs(),
+      cooldownTicks(20)
 {}
 
+BlockReplaceItemSkill::~BlockReplaceItemSkill()
+{
+    if (invalidUseConfig) invalidUseConfig->release();
+}
+
 void BlockReplaceItemSkill::load(Framework::StreamReader* zReader)
 {
     zReader->lese((char*)&cooldownTicks, 4);
@@ -849,7 +975,7 @@ bool BlockReplaceItemSkill::use(Entity* zActor, Item* zUsedItem, Block* zTarget)
     setXp(getXp() + usedConfig->getXpGain());
     if (!invalid)
     {
-        Vec3<int> pos = zTarget->getPos();
+        Framework::Vec3<int> pos = zTarget->getPos();
         int dimension = zTarget->getDimensionId();
         Game::INSTANCE->doLater([pos, dimension, usedConfig]() {
             Game::INSTANCE->zDimension(dimension)->placeBlock(
@@ -865,94 +991,112 @@ bool BlockReplaceItemSkill::use(
     return false;
 }
 
+void BlockReplaceItemSkill::setInvalidUseConfig(
+    BlockReplaceItemSkillConfig* config)
+{
+    if (invalidUseConfig) invalidUseConfig->release();
+    invalidUseConfig = config;
+}
+
 BlockReplaceItemSkillConfig* BlockReplaceItemSkill::zInvalidUseConfig() const
 {
     return invalidUseConfig;
 }
 
+void BlockReplaceItemSkill::addConfig(BlockReplaceItemSkillConfig* config)
+{
+    configs.add(config);
+}
+
 const Framework::RCArray<BlockReplaceItemSkillConfig>&
 BlockReplaceItemSkill::getConfigs() const
 {
     return configs;
 }
 
+void BlockReplaceItemSkill::setCooldownTicks(int cooldownTicks)
+{
+    this->cooldownTicks = cooldownTicks;
+}
+
 int BlockReplaceItemSkill::getCooldownTicks() const
 {
     return cooldownTicks;
 }
 
 BlockReplaceItemSkillFactory::BlockReplaceItemSkillFactory()
-    : SubTypeFactory()
+    : ItemSkillFactoryBase()
 {}
 
-BlockReplaceItemSkill* BlockReplaceItemSkillFactory::fromJson(
+BlockReplaceItemSkill* BlockReplaceItemSkillFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
+    return new BlockReplaceItemSkill();
+}
+
+void BlockReplaceItemSkillFactory::fromJson(
+    BlockReplaceItemSkill* zResult, Framework::JSON::JSONObject* zJson) const
+{
+    BlockReplaceItemSkillConfig* invalidUseConfig
+        = new BlockReplaceItemSkillConfig();
+    invalidUseConfig->setStaminaCost(
+        (float)zJson->zValue("invalidStaminaCost")->asNumber()->getNumber());
+    invalidUseConfig->setStaminaCostDevider(
+        (float)zJson->zValue("invalidStaminaCostDevider")
+            ->asNumber()
+            ->getNumber());
+    invalidUseConfig->setAdditionalStaminaCostDeviderPerLevel(
+        (float)zJson->zValue("invalidAdditionalStaminaCostDeviderPerLevel")
+            ->asNumber()
+            ->getNumber());
+    invalidUseConfig->setDurabilityCost(
+        (float)zJson->zValue("invalidDurabilityCost")->asNumber()->getNumber());
+    invalidUseConfig->setDurabilityCostDevider(
+        (float)zJson->zValue("invalidDurabilityCostDevider")
+            ->asNumber()
+            ->getNumber());
+    invalidUseConfig->setAdditionalDurabilityCostDeviderPerLevel(
+        (float)zJson->zValue("invalidAdditionalDurabilityCostDeviderPerLevel")
+            ->asNumber()
+            ->getNumber());
+    invalidUseConfig->setCooldownTicks(
+        (int)zJson->zValue("invalidCooldownTicks")->asNumber()->getNumber());
+    invalidUseConfig->setXpGain(0.f);
+    zResult->setInvalidUseConfig(invalidUseConfig);
     Framework::RCArray<BlockReplaceItemSkillConfig> configs;
     for (Framework::JSON::JSONValue* value :
         *zJson->zValue("configs")->asArray())
     {
-        configs.add(Game::INSTANCE->zTypeRegistry()
-                        ->fromJson<BlockReplaceItemSkillConfig>(value));
+        zResult->addConfig(Game::INSTANCE->zTypeRegistry()
+                               ->fromJson<BlockReplaceItemSkillConfig>(value));
     }
-    return new BlockReplaceItemSkill(0,
-        (float)zJson->zValue("maxXp")->asNumber()->getNumber(),
-        1,
-        new BlockReplaceItemSkillConfig(0,
-            0,
-            0,
-            (float)zJson->zValue("invalidStaminaCost")->asNumber()->getNumber(),
-            (float)zJson->zValue("invalidStaminaCostDevider")
-                ->asNumber()
-                ->getNumber(),
-            (float)zJson->zValue("invalidAdditionalStaminaCostDeviderPerLevel")
-                ->asNumber()
-                ->getNumber(),
-            (float)zJson->zValue("invalidDurabilityCost")
-                ->asNumber()
-                ->getNumber(),
-            (float)zJson->zValue("invalidDurabilityCostDevider")
-                ->asNumber()
-                ->getNumber(),
-            (float)zJson
-                ->zValue("invalidAdditionalDurabilityCostDeviderPerLevel")
-                ->asNumber()
-                ->getNumber(),
-            0.f),
-        configs,
-        (int)zJson->zValue("cooldownTicks")->asNumber()->getNumber());
-}
-
-Framework::JSON::JSONObject* BlockReplaceItemSkillFactory::toJson(
-    BlockReplaceItemSkill* zObject) const
-{
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue(
-        "maxXp", new Framework::JSON::JSONNumber(zObject->getMaxXp()));
-    result->addValue("invalidStaminaCost",
+    ItemSkillFactoryBase::fromJson(zResult, zJson);
+}
+
+void BlockReplaceItemSkillFactory::toJson(
+    BlockReplaceItemSkill* zObject, Framework::JSON::JSONObject* zResult) const
+{
+    zResult->addValue("invalidStaminaCost",
         new Framework::JSON::JSONNumber(
             zObject->zInvalidUseConfig()->getStaminaCost()));
-    result->addValue("invalidStaminaCostDevider",
+    zResult->addValue("invalidStaminaCostDevider",
         new Framework::JSON::JSONNumber(
             zObject->zInvalidUseConfig()->getStaminaCostDevider()));
-    result->addValue("invalidAdditionalStaminaCostDeviderPerLevel",
+    zResult->addValue("invalidAdditionalStaminaCostDeviderPerLevel",
         new Framework::JSON::JSONNumber(
             zObject->zInvalidUseConfig()
                 ->getAdditionalStaminaCostDeviderPerLevel()));
-    result->addValue("invalidDurabilityCost",
+    zResult->addValue("invalidDurabilityCost",
         new Framework::JSON::JSONNumber(
             zObject->zInvalidUseConfig()->getDurabilityCost()));
-    result->addValue("invalidDurabilityCostDevider",
+    zResult->addValue("invalidDurabilityCostDevider",
         new Framework::JSON::JSONNumber(
             zObject->zInvalidUseConfig()->getDurabilityCostDevider()));
-    result->addValue("invalidAdditionalDurabilityCostDeviderPerLevel",
+    zResult->addValue("invalidAdditionalDurabilityCostDeviderPerLevel",
         new Framework::JSON::JSONNumber(
             zObject->zInvalidUseConfig()
                 ->getAdditionalDurabilityCostDeviderPerLevel()));
-    result->addValue("invalidXpGain",
-        new Framework::JSON::JSONNumber(
-            zObject->zInvalidUseConfig()->getXpGain()));
-    result->addValue("invalidCooldownTicks",
+    zResult->addValue("invalidCooldownTicks",
         new Framework::JSON::JSONNumber(
             zObject->zInvalidUseConfig()->getCooldownTicks()));
     Framework::JSON::JSONArray* configs = new Framework::JSON::JSONArray();
@@ -960,51 +1104,47 @@ Framework::JSON::JSONObject* BlockReplaceItemSkillFactory::toJson(
     {
         configs->addValue(Game::INSTANCE->zTypeRegistry()->toJson(config));
     }
-    result->addValue("configs", configs);
-    result->addValue("cooldownTicks",
-        new Framework::JSON::JSONNumber(zObject->getCooldownTicks()));
-    return result;
-}
-
-Framework::JSON::Validator::JSONValidator*
-BlockReplaceItemSkillFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
-{
-    return builder->withRequiredNumber("maxXp")
-        ->whichIsGreaterThen(0.0)
-        ->withDefault(10.0)
-        ->finishNumber()
-        ->withRequiredNumber("invalidStaminaCost")
-        ->whichIsGreaterOrEqual(0.0)
-        ->withDefault(0.5)
-        ->finishNumber()
-        ->withRequiredNumber("invalidStaminaCostDevider")
-        ->whichIsGreaterOrEqual(0.0)
-        ->withDefault(0.8)
-        ->finishNumber()
-        ->withRequiredNumber("invalidAdditionalStaminaCostDeviderPerLevel")
-        ->whichIsGreaterOrEqual(0.0)
-        ->withDefault(0.2)
-        ->finishNumber()
-        ->withRequiredNumber("invalidDurabilityCost")
-        ->whichIsGreaterOrEqual(0.0)
-        ->withDefault(0.5)
-        ->finishNumber()
-        ->withRequiredNumber("invalidDurabilityCostDevider")
-        ->whichIsGreaterOrEqual(0.0)
-        ->withDefault(0.98)
-        ->finishNumber()
-        ->withRequiredNumber("invalidAdditionalDurabilityCostDeviderPerLevel")
-        ->whichIsGreaterOrEqual(0.0)
-        ->withDefault(0.02)
-        ->finishNumber()
-        ->withRequiredArray("configs")
-        ->addAcceptedTypeInArray(
-            Game::INSTANCE->zTypeRegistry()
-                ->getValidator<BlockReplaceItemSkillConfig>())
-        ->finishArray()
-        ->finishObject();
+    zResult->addValue("configs", configs);
+    ItemSkillFactoryBase::toJson(zObject, zResult);
+}
+
+JSONObjectValidationBuilder* BlockReplaceItemSkillFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return ItemSkillFactoryBase::addToValidator(
+        builder->withRequiredNumber("invalidStaminaCost")
+            ->whichIsGreaterOrEqual(0.0)
+            ->withDefault(0.5)
+            ->finishNumber()
+            ->withRequiredNumber("invalidStaminaCostDevider")
+            ->whichIsGreaterOrEqual(0.0)
+            ->withDefault(0.8)
+            ->finishNumber()
+            ->withRequiredNumber("invalidAdditionalStaminaCostDeviderPerLevel")
+            ->whichIsGreaterOrEqual(0.0)
+            ->withDefault(0.2)
+            ->finishNumber()
+            ->withRequiredNumber("invalidDurabilityCost")
+            ->whichIsGreaterOrEqual(0.0)
+            ->withDefault(0.5)
+            ->finishNumber()
+            ->withRequiredNumber("invalidDurabilityCostDevider")
+            ->whichIsGreaterOrEqual(0.0)
+            ->withDefault(0.98)
+            ->finishNumber()
+            ->withRequiredNumber(
+                "invalidAdditionalDurabilityCostDeviderPerLevel")
+            ->whichIsGreaterOrEqual(0.0)
+            ->withDefault(0.02)
+            ->finishNumber()
+            ->withRequiredNumber("invalidCooldownTicks")
+            ->withDefault(20)
+            ->finishNumber()
+            ->withRequiredArray("configs")
+            ->addAcceptedTypeInArray(
+                Game::INSTANCE->zTypeRegistry()
+                    ->getValidator<BlockReplaceItemSkillConfig>())
+            ->finishArray());
 }
 
 Framework::Text BlockReplaceItemSkillFactory::getTypeToken() const
@@ -1012,48 +1152,28 @@ Framework::Text BlockReplaceItemSkillFactory::getTypeToken() const
     return "replaceBlock";
 }
 
-DamagingItemSkillConfig::DamagingItemSkillConfig(BlockFilter* targetBlockFilter,
-    float damage,
-    float damagePerHeadHardness,
-    float baseDamageMultiplier,
-    float damageMupliplierPerHeadHardness,
-    float damagePerLevel,
-    float damageMultiplierPerLevel,
-    float damageDevider,
-    float damageDeviderPerHardness,
-    float staminaCost,
-    float staminaCostPerDamage,
-    float staminaCostPerHardness,
-    float staminaCostDevider,
-    float staminaCostDeviderPerLevel,
-    float durabilityCost,
-    float durabilityCostPerDamage,
-    float durabilityCostPerHardness,
-    float durabilityCostDevider,
-    float additionalDurabilityCostDeviderPerLevel,
-    float xpGainPerDamage)
+DamagingItemSkillConfig::DamagingItemSkillConfig()
     : ReferenceCounter(),
-      targetBlockFilter(targetBlockFilter),
-      damage(damage),
-      damagePerHeadHardness(damagePerHeadHardness),
-      baseDamageMultiplier(baseDamageMultiplier),
-      damageMupliplierPerHeadHardness(damageMupliplierPerHeadHardness),
-      damagePerLevel(damagePerLevel),
-      damageMultiplierPerLevel(damageMultiplierPerLevel),
-      damageDevider(damageDevider),
-      damageDeviderPerHardness(damageDeviderPerHardness),
-      staminaCost(staminaCost),
-      staminaCostPerDamage(staminaCostPerDamage),
-      staminaCostPerHardness(staminaCostPerHardness),
-      staminaCostDevider(staminaCostDevider),
-      staminaCostDeviderPerLevel(staminaCostDeviderPerLevel),
-      durabilityCost(durabilityCost),
-      durabilityCostPerDamage(durabilityCostPerDamage),
-      durabilityCostPerHardness(durabilityCostPerHardness),
-      durabilityCostDevider(durabilityCostDevider),
-      additionalDurabilityCostDeviderPerLevel(
-          additionalDurabilityCostDeviderPerLevel),
-      xpGainPerDamage(xpGainPerDamage)
+      targetBlockFilter(0),
+      damage(2.f),
+      damagePerHeadHardness(1.f),
+      baseDamageMultiplier(1.f),
+      damageMultiplierPerHeadHardness(0.f),
+      damagePerLevel(0.3f),
+      damageMultiplierPerLevel(0.0f),
+      damageDevider(1.0f),
+      damageDeviderPerHardness(1.0f),
+      staminaCost(0.00001f),
+      staminaCostPerDamage(0.00001f),
+      staminaCostPerHardness(0.001f),
+      staminaCostDevider(0.9f),
+      staminaCostDeviderPerLevel(0.1f),
+      durabilityCost(0.1f),
+      durabilityCostPerDamage(0.01f),
+      durabilityCostPerHardness(0.01f),
+      durabilityCostDevider(0.8f),
+      additionalDurabilityCostDeviderPerLevel(0.2f),
+      xpGainPerDamage(0.05f)
 {}
 
 DamagingItemSkillConfig::~DamagingItemSkillConfig()
@@ -1061,29 +1181,64 @@ DamagingItemSkillConfig::~DamagingItemSkillConfig()
     if (targetBlockFilter) targetBlockFilter->release();
 }
 
+void DamagingItemSkillConfig::setTargetBlockFilter(
+    BlockFilter* targetBlockFilter)
+{
+    if (this->targetBlockFilter) this->targetBlockFilter->release();
+    this->targetBlockFilter = targetBlockFilter;
+}
+
 BlockFilter* DamagingItemSkillConfig::zTargetBlockFilter() const
 {
     return targetBlockFilter;
 }
 
+void DamagingItemSkillConfig::setDamage(float damage)
+{
+    this->damage = damage;
+}
+
 float DamagingItemSkillConfig::getDamage() const
 {
     return damage;
 }
 
+void DamagingItemSkillConfig::setDamagePerHeadHardness(
+    float damagePerHeadHardness)
+{
+    this->damagePerHeadHardness = damagePerHeadHardness;
+}
+
 float DamagingItemSkillConfig::getDamagePerHeadHardness() const
 {
     return damageDeviderPerHardness;
 }
 
+void DamagingItemSkillConfig::setBaseDamageMultiplier(
+    float baseDamageMultiplier)
+{
+    this->baseDamageMultiplier = baseDamageMultiplier;
+}
+
 float DamagingItemSkillConfig::getBaseDamageMultiplier() const
 {
     return baseDamageMultiplier;
 }
 
-float DamagingItemSkillConfig::getDamageMupliplierPerHeadHardness() const
+void DamagingItemSkillConfig::setDamageMultiplierPerHeadHardness(
+    float damageMupliplierPerHeadHardness)
+{
+    this->damageMultiplierPerHeadHardness = damageMupliplierPerHeadHardness;
+}
+
+float DamagingItemSkillConfig::getDamageMultiplierPerHeadHardness() const
+{
+    return damageMultiplierPerHeadHardness;
+}
+
+void DamagingItemSkillConfig::setDamagePerLevel(float damagePerLevel)
 {
-    return damageMupliplierPerHeadHardness;
+    this->damagePerLevel = damagePerLevel;
 }
 
 float DamagingItemSkillConfig::getDamagePerLevel() const
@@ -1091,72 +1246,152 @@ float DamagingItemSkillConfig::getDamagePerLevel() const
     return damagePerLevel;
 }
 
+void DamagingItemSkillConfig::setDamageMultiplierPerLevel(
+    float damageMultiplierPerLevel)
+{
+    this->damageMultiplierPerLevel = damageMultiplierPerLevel;
+}
+
 float DamagingItemSkillConfig::getDamageMultiplierPerLevel() const
 {
     return damageMultiplierPerLevel;
 }
 
+void DamagingItemSkillConfig::setDamageDevider(float damageDevider)
+{
+    this->damageDevider = damageDevider;
+}
+
 float DamagingItemSkillConfig::getDamageDevider() const
 {
     return damageDevider;
 }
 
+void DamagingItemSkillConfig::setDamageDeviderPerHardness(
+    float damageDeviderPerHardness)
+{
+    this->damageDeviderPerHardness = damageDeviderPerHardness;
+}
+
 float DamagingItemSkillConfig::getDamageDeviderPerHardness() const
 {
     return damageDeviderPerHardness;
 }
 
+void DamagingItemSkillConfig::setStaminaCost(float staminaCost)
+{
+    this->staminaCost = staminaCost;
+}
+
 float DamagingItemSkillConfig::getStaminaCost() const
 {
     return staminaCost;
 }
 
+void DamagingItemSkillConfig::setStaminaCostPerDamage(
+    float staminaCostPerDamage)
+{
+    this->staminaCostPerDamage = staminaCostPerDamage;
+}
+
 float DamagingItemSkillConfig::getStaminaCostPerDamage() const
 {
     return staminaCostPerDamage;
 }
 
+void DamagingItemSkillConfig::setStaminaCostPerHardness(
+    float staminaCostPerHardness)
+{
+    this->staminaCostPerHardness = staminaCostPerHardness;
+}
+
 float DamagingItemSkillConfig::getStaminaCostPerHardness() const
 {
     return staminaCostPerHardness;
 }
 
+void DamagingItemSkillConfig::setStaminaCostDevider(float staminaCostDevider)
+{
+    this->staminaCostDevider = staminaCostDevider;
+}
+
 float DamagingItemSkillConfig::getStaminaCostDevider() const
 {
     return staminaCostDevider;
 }
 
+void DamagingItemSkillConfig::setStaminaCostDeviderPerLevel(
+    float staminaCostDeviderPerLevel)
+{
+    this->staminaCostDeviderPerLevel = staminaCostDeviderPerLevel;
+}
+
 float DamagingItemSkillConfig::getStaminaCostDeviderPerLevel() const
 {
     return staminaCostDeviderPerLevel;
 }
 
+void DamagingItemSkillConfig::setDurabilityCost(float durabilityCost)
+{
+    this->durabilityCost = durabilityCost;
+}
+
 float DamagingItemSkillConfig::getDurabilityCost() const
 {
     return durabilityCost;
 }
 
+void DamagingItemSkillConfig::setDurabilityCostPerDamage(
+    float durabilityCostPerDamage)
+{
+    this->durabilityCostPerDamage = durabilityCostPerDamage;
+}
+
 float DamagingItemSkillConfig::getDurabilityCostPerDamage() const
 {
     return durabilityCostPerDamage;
 }
 
+void DamagingItemSkillConfig::setDurabilityCostPerHardness(
+    float durabilityCostPerHardness)
+{
+    this->durabilityCostPerHardness = durabilityCostPerHardness;
+}
+
 float DamagingItemSkillConfig::getDurabilityCostPerHardness() const
 {
     return durabilityCostPerHardness;
 }
 
+void DamagingItemSkillConfig::setDurabilityCostDevider(
+    float durabilityCostDevider)
+{
+    this->durabilityCostDevider = durabilityCostDevider;
+}
+
 float DamagingItemSkillConfig::getDurabilityCostDevider() const
 {
     return durabilityCostDevider;
 }
 
+void DamagingItemSkillConfig::setAdditionalDurabilityCostDeviderPerLevel(
+    float additionalDurabilityCostDeviderPerLevel)
+{
+    this->additionalDurabilityCostDeviderPerLevel
+        = additionalDurabilityCostDeviderPerLevel;
+}
+
 float DamagingItemSkillConfig::getAdditionalDurabilityCostDeviderPerLevel()
     const
 {
     return additionalDurabilityCostDeviderPerLevel;
 }
 
+void DamagingItemSkillConfig::setXpGainPerDamage(float xpGainPerDamage)
+{
+    this->xpGainPerDamage = xpGainPerDamage;
+}
+
 float DamagingItemSkillConfig::getXpGainPerDamage() const
 {
     return xpGainPerDamage;
@@ -1166,144 +1401,155 @@ DamagingItemSkillConfigFactory::DamagingItemSkillConfigFactory()
     : TypeFactory()
 {}
 
-DamagingItemSkillConfig* DamagingItemSkillConfigFactory::fromJson(
-    Framework::JSON::JSONValue* zJson) const
+DamagingItemSkillConfig* DamagingItemSkillConfigFactory::createValue(
+    Framework::JSON::JSONObject* zJson) const
 {
-    return new DamagingItemSkillConfig(
+    return new DamagingItemSkillConfig();
+}
+
+void DamagingItemSkillConfigFactory::fromJson(
+    DamagingItemSkillConfig* zResult, Framework::JSON::JSONObject* zJson) const
+{
+    zResult->setTargetBlockFilter(
         Game::INSTANCE->zTypeRegistry()->fromJson<BlockFilter>(
-            zJson->asObject()->zValue("targetFilter")),
-        (float)zJson->asObject()->zValue("damage")->asNumber()->getNumber(),
+            zJson->zValue("targetFilter")));
+    zResult->setDamage(
+        (float)zJson->asObject()->zValue("damage")->asNumber()->getNumber());
+    zResult->setDamagePerHeadHardness((float)zJson->asObject()
+                                          ->zValue("damagePerHeadHardness")
+                                          ->asNumber()
+                                          ->getNumber());
+    zResult->setBaseDamageMultiplier((float)zJson->asObject()
+                                         ->zValue("baseDamageMultiplier")
+                                         ->asNumber()
+                                         ->getNumber());
+    zResult->setDamageMultiplierPerHeadHardness(
         (float)zJson->asObject()
-            ->zValue("damagePerHeadHardness")
+            ->zValue("damageMultiplierPerHeadHardness")
             ->asNumber()
-            ->getNumber(),
-        (float)zJson->asObject()
-            ->zValue("baseDamageMultiplier")
-            ->asNumber()
-            ->getNumber(),
-        (float)zJson->asObject()
-            ->zValue("damageMupliplierPerHeadHardness")
-            ->asNumber()
-            ->getNumber(),
-        (float)zJson->asObject()
-            ->zValue("damagePerLevel")
-            ->asNumber()
-            ->getNumber(),
+            ->getNumber());
+    zResult->setDamagePerLevel((float)zJson->asObject()
+                                   ->zValue("damagePerLevel")
+                                   ->asNumber()
+                                   ->getNumber());
+    zResult->setDamageMultiplierPerLevel(
         (float)zJson->asObject()
             ->zValue("damageMultiplierPerLevel")
             ->asNumber()
-            ->getNumber(),
-        (float)zJson->asObject()
-            ->zValue("damageDevider")
-            ->asNumber()
-            ->getNumber(),
+            ->getNumber());
+    zResult->setDamageDevider((float)zJson->asObject()
+                                  ->zValue("damageDevider")
+                                  ->asNumber()
+                                  ->getNumber());
+    zResult->setDamageDeviderPerHardness(
         (float)zJson->asObject()
             ->zValue("damageDeviderPerHardness")
             ->asNumber()
-            ->getNumber(),
-        (float)zJson->asObject()
-            ->zValue("staminaCost")
-            ->asNumber()
-            ->getNumber(),
-        (float)zJson->asObject()
-            ->zValue("staminaCostPerDamage")
-            ->asNumber()
-            ->getNumber(),
-        (float)zJson->asObject()
-            ->zValue("staminaCostPerHardness")
-            ->asNumber()
-            ->getNumber(),
-        (float)zJson->asObject()
-            ->zValue("staminaCostDevider")
-            ->asNumber()
-            ->getNumber(),
+            ->getNumber());
+    zResult->setStaminaCost((float)zJson->asObject()
+                                ->zValue("staminaCost")
+                                ->asNumber()
+                                ->getNumber());
+    zResult->setStaminaCostPerDamage((float)zJson->asObject()
+                                         ->zValue("staminaCostPerDamage")
+                                         ->asNumber()
+                                         ->getNumber());
+    zResult->setStaminaCostPerHardness((float)zJson->asObject()
+                                           ->zValue("staminaCostPerHardness")
+                                           ->asNumber()
+                                           ->getNumber());
+    zResult->setStaminaCostDevider((float)zJson->asObject()
+                                       ->zValue("staminaCostDevider")
+                                       ->asNumber()
+                                       ->getNumber());
+    zResult->setStaminaCostDeviderPerLevel(
         (float)zJson->asObject()
             ->zValue("staminaCostDeviderPerLevel")
             ->asNumber()
-            ->getNumber(),
-        (float)zJson->asObject()
-            ->zValue("durabilityCost")
-            ->asNumber()
-            ->getNumber(),
-        (float)zJson->asObject()
-            ->zValue("durabilityCostPerDamage")
-            ->asNumber()
-            ->getNumber(),
+            ->getNumber());
+    zResult->setDurabilityCost((float)zJson->asObject()
+                                   ->zValue("durabilityCost")
+                                   ->asNumber()
+                                   ->getNumber());
+    zResult->setDurabilityCostPerDamage((float)zJson->asObject()
+                                            ->zValue("durabilityCostPerDamage")
+                                            ->asNumber()
+                                            ->getNumber());
+    zResult->setDurabilityCostPerHardness(
         (float)zJson->asObject()
             ->zValue("durabilityCostPerHardness")
             ->asNumber()
-            ->getNumber(),
-        (float)zJson->asObject()
-            ->zValue("durabilityCostDevider")
-            ->asNumber()
-            ->getNumber(),
+            ->getNumber());
+    zResult->setDurabilityCostDevider((float)zJson->asObject()
+                                          ->zValue("durabilityCostDevider")
+                                          ->asNumber()
+                                          ->getNumber());
+    zResult->setAdditionalDurabilityCostDeviderPerLevel(
         (float)zJson->asObject()
             ->zValue("additionalDurabilityCostDeviderPerLevel")
             ->asNumber()
-            ->getNumber(),
-        (float)zJson->asObject()
-            ->zValue("xpGainPerDamage")
-            ->asNumber()
             ->getNumber());
+    zResult->setXpGainPerDamage((float)zJson->asObject()
+                                    ->zValue("xpGainPerDamage")
+                                    ->asNumber()
+                                    ->getNumber());
 }
 
-Framework::JSON::JSONValue* DamagingItemSkillConfigFactory::toJson(
-    DamagingItemSkillConfig* zObject) const
+void DamagingItemSkillConfigFactory::toJson(DamagingItemSkillConfig* zObject,
+    Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue("targetFilter",
+    zResult->addValue("targetFilter",
         Game::INSTANCE->zTypeRegistry()->toJson(zObject->zTargetBlockFilter()));
-    result->addValue(
+    zResult->addValue(
         "damage", new Framework::JSON::JSONNumber(zObject->getDamage()));
-    result->addValue("damagePerHeadHardness",
+    zResult->addValue("damagePerHeadHardness",
         new Framework::JSON::JSONNumber(zObject->getDamagePerHeadHardness()));
-    result->addValue("baseDamageMultiplier",
+    zResult->addValue("baseDamageMultiplier",
         new Framework::JSON::JSONNumber(zObject->getBaseDamageMultiplier()));
-    result->addValue("damageMupliplierPerHeadHardness",
+    zResult->addValue("damageMultiplierPerHeadHardness",
         new Framework::JSON::JSONNumber(
-            zObject->getDamageMupliplierPerHeadHardness()));
-    result->addValue("damagePerLevel",
+            zObject->getDamageMultiplierPerHeadHardness()));
+    zResult->addValue("damagePerLevel",
         new Framework::JSON::JSONNumber(zObject->getDamagePerLevel()));
-    result->addValue("damageMultiplierPerLevel",
+    zResult->addValue("damageMultiplierPerLevel",
         new Framework::JSON::JSONNumber(
             zObject->getDamageMultiplierPerLevel()));
-    result->addValue("damageDevider",
+    zResult->addValue("damageDevider",
         new Framework::JSON::JSONNumber(zObject->getDamageDevider()));
-    result->addValue("damageDeviderPerHardness",
+    zResult->addValue("damageDeviderPerHardness",
         new Framework::JSON::JSONNumber(
             zObject->getDamageDeviderPerHardness()));
-    result->addValue("staminaCost",
+    zResult->addValue("staminaCost",
         new Framework::JSON::JSONNumber(zObject->getStaminaCost()));
-    result->addValue("staminaCostPerDamage",
+    zResult->addValue("staminaCostPerDamage",
         new Framework::JSON::JSONNumber(zObject->getStaminaCostPerDamage()));
-    result->addValue("staminaCostPerHardness",
+    zResult->addValue("staminaCostPerHardness",
         new Framework::JSON::JSONNumber(zObject->getStaminaCostPerHardness()));
-    result->addValue("staminaCostDevider",
+    zResult->addValue("staminaCostDevider",
         new Framework::JSON::JSONNumber(zObject->getStaminaCostDevider()));
-    result->addValue("staminaCostDeviderPerLevel",
+    zResult->addValue("staminaCostDeviderPerLevel",
         new Framework::JSON::JSONNumber(
             zObject->getStaminaCostDeviderPerLevel()));
-    result->addValue("durabilityCost",
+    zResult->addValue("durabilityCost",
         new Framework::JSON::JSONNumber(zObject->getDurabilityCost()));
-    result->addValue("durabilityCostPerDamage",
+    zResult->addValue("durabilityCostPerDamage",
         new Framework::JSON::JSONNumber(zObject->getDurabilityCostPerDamage()));
-    result->addValue("durabilityCostPerHardness",
+    zResult->addValue("durabilityCostPerHardness",
         new Framework::JSON::JSONNumber(
             zObject->getDurabilityCostPerHardness()));
-    result->addValue("durabilityCostDevider",
+    zResult->addValue("durabilityCostDevider",
         new Framework::JSON::JSONNumber(zObject->getDurabilityCostDevider()));
-    result->addValue("additionalDurabilityCostDeviderPerLevel",
+    zResult->addValue("additionalDurabilityCostDeviderPerLevel",
         new Framework::JSON::JSONNumber(
             zObject->getAdditionalDurabilityCostDeviderPerLevel()));
-    result->addValue("xpGainPerDamage",
+    zResult->addValue("xpGainPerDamage",
         new Framework::JSON::JSONNumber(zObject->getXpGainPerDamage()));
-    return result;
 }
 
-Framework::JSON::Validator::JSONValidator*
-DamagingItemSkillConfigFactory::getValidator() const
+JSONObjectValidationBuilder* DamagingItemSkillConfigFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
-    return Framework::JSON::Validator::JSONValidator::buildForObject()
+    return builder
         ->withRequiredAttribute("targetFilter",
             Game::INSTANCE->zTypeRegistry()->getValidator<BlockFilter>())
         ->withRequiredNumber("damage")
@@ -1318,7 +1564,7 @@ DamagingItemSkillConfigFactory::getValidator() const
         ->whichIsGreaterOrEqual(0.0)
         ->withDefault(1.0)
         ->finishNumber()
-        ->withRequiredNumber("damageMupliplierPerHeadHardness")
+        ->withRequiredNumber("damageMultiplierPerHeadHardness")
         ->whichIsGreaterOrEqual(0.0)
         ->withDefault(0.0)
         ->finishNumber()
@@ -1381,18 +1627,19 @@ DamagingItemSkillConfigFactory::getValidator() const
         ->withRequiredNumber("xpGainPerDamage")
         ->whichIsGreaterOrEqual(0.0)
         ->withDefault(0.05)
-        ->finishNumber()
-        ->finishObject();
+        ->finishNumber();
 }
 
-DamagingItemSkill::DamagingItemSkill(float xp,
-    float maxXp,
-    float level,
-    DamagingItemSkillConfig* invalidUseConfig,
-    Framework::RCArray<DamagingItemSkillConfig> configs)
-    : ItemSkill(xp, maxXp, level)
+DamagingItemSkill::DamagingItemSkill()
+    : ItemSkill(),
+      invalidUseConfig(0)
 {}
 
+DamagingItemSkill::~DamagingItemSkill()
+{
+    if (invalidUseConfig) invalidUseConfig->release();
+}
+
 bool DamagingItemSkill::use(Entity* zActor, Item* zUsedItem, Block* zTarget)
 {
     BasicToolItem* tool = dynamic_cast<BasicToolItem*>(zUsedItem);
@@ -1418,7 +1665,7 @@ bool DamagingItemSkill::use(Entity* zActor, Item* zUsedItem, Block* zTarget)
     float damageMultiplier
         = usedConfig->getBaseDamageMultiplier()
         + usedConfig->getDamageMultiplierPerLevel() * getLevel()
-        + usedConfig->getDamageMupliplierPerHeadHardness()
+        + usedConfig->getDamageMultiplierPerHeadHardness()
               * (tool ? tool->getHeadMaterialHardness() : 0);
     if (damageMultiplier != 0)
     {
@@ -1469,11 +1716,22 @@ bool DamagingItemSkill::use(Entity* zActor, Item* zUsedItem, Entity* zTarget)
     return false;
 }
 
+void DamagingItemSkill::setInvalidUseConfig(DamagingItemSkillConfig* config)
+{
+    if (invalidUseConfig) invalidUseConfig->release();
+    invalidUseConfig = config;
+}
+
 DamagingItemSkillConfig* DamagingItemSkill::zInvalidUseConfig() const
 {
     return invalidUseConfig;
 }
 
+void DamagingItemSkill::addConfig(DamagingItemSkillConfig* config)
+{
+    configs.add(config);
+}
+
 const Framework::RCArray<DamagingItemSkillConfig>&
 DamagingItemSkill::getConfigs() const
 {
@@ -1481,88 +1739,94 @@ DamagingItemSkill::getConfigs() const
 }
 
 DamagingItemSkillFactory::DamagingItemSkillFactory()
-    : SubTypeFactory()
+    : ItemSkillFactoryBase()
 {}
 
-DamagingItemSkill* DamagingItemSkillFactory::fromJson(
+DamagingItemSkill* DamagingItemSkillFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
-    Framework::RCArray<DamagingItemSkillConfig> configs;
+    return new DamagingItemSkill();
+}
+
+void DamagingItemSkillFactory::fromJson(
+    DamagingItemSkill* zResult, Framework::JSON::JSONObject* zJson) const
+{
     for (Framework::JSON::JSONValue* configValue :
         *zJson->zValue("configs")->asArray())
     {
-        configs.add(
+        zResult->addConfig(
             Game::INSTANCE->zTypeRegistry()->fromJson<DamagingItemSkillConfig>(
                 configValue));
     }
-    return new DamagingItemSkill(0.f,
-        (float)zJson->zValue("maxXp")->asNumber()->getNumber(),
-        1.f,
-        new DamagingItemSkillConfig(0,
-            0.f,
-            0.f,
-            0.f,
-            0.f,
-            0.f,
-            0.f,
-            1.f,
-            0.f,
-            (float)zJson->zValue("invalidStaminaCost")->asNumber()->getNumber(),
-            0.f,
-            (float)zJson->zValue("invalidStaminaCostPerHardness")
-                ->asNumber()
-                ->getNumber(),
-            (float)zJson->zValue("invalidStaminaCostDevider")
-                ->asNumber()
-                ->getNumber(),
-            (float)zJson->zValue("invalidStaminaCostDeviderPerLevel")
-                ->asNumber()
-                ->getNumber(),
-            (float)zJson->zValue("invalidDurabilityCost")
-                ->asNumber()
-                ->getNumber(),
-            0.f,
-            (float)zJson->zValue("invalidDurabilityCostPerHardness")
-                ->asNumber()
-                ->getNumber(),
-            (float)zJson->zValue("invalidDurabilityCostDevider")
-                ->asNumber()
-                ->getNumber(),
-            (float)zJson->zValue("invalidDurabilityCostDeviderPerLevel")
-                ->asNumber()
-                ->getNumber(),
-            0.f),
-        configs);
-}
-
-Framework::JSON::JSONObject* DamagingItemSkillFactory::toJson(
-    DamagingItemSkill* zObject) const
-{
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue(
+    DamagingItemSkillConfig* invalidUseConfig = new DamagingItemSkillConfig();
+    invalidUseConfig->setDamage(0.f);
+    invalidUseConfig->setDamageDeviderPerHardness(0.f);
+    invalidUseConfig->setBaseDamageMultiplier(0.f);
+    invalidUseConfig->setDamageMultiplierPerHeadHardness(0.f);
+    invalidUseConfig->setDamagePerLevel(0.f);
+    invalidUseConfig->setDamageMultiplierPerLevel(0.f);
+    invalidUseConfig->setDamageDevider(1.f);
+    invalidUseConfig->setDamageDeviderPerHardness(0.f);
+    invalidUseConfig->setStaminaCost(
+        (float)zJson->zValue("invalidStaminaCost")->asNumber()->getNumber());
+    invalidUseConfig->setStaminaCostPerDamage(0.f);
+    invalidUseConfig->setStaminaCostPerHardness(
+        (float)zJson->zValue("invalidStaminaCostPerHardness")
+            ->asNumber()
+            ->getNumber());
+    invalidUseConfig->setStaminaCostDevider(
+        (float)zJson->zValue("invalidStaminaCostDevider")
+            ->asNumber()
+            ->getNumber());
+    invalidUseConfig->setStaminaCostDeviderPerLevel(
+        (float)zJson->zValue("invalidStaminaCostDeviderPerLevel")
+            ->asNumber()
+            ->getNumber());
+    invalidUseConfig->setDurabilityCost(
+        (float)zJson->zValue("invalidDurabilityCost")->asNumber()->getNumber());
+    invalidUseConfig->setDurabilityCostPerHardness(
+        (float)zJson->zValue("invalidDurabilityCostPerHardness")
+            ->asNumber()
+            ->getNumber());
+    invalidUseConfig->setDurabilityCostDevider(
+        (float)zJson->zValue("invalidDurabilityCostDevider")
+            ->asNumber()
+            ->getNumber());
+    invalidUseConfig->setAdditionalDurabilityCostDeviderPerLevel(
+        (float)zJson->zValue("invalidDurabilityCostDeviderPerLevel")
+            ->asNumber()
+            ->getNumber());
+    zResult->setInvalidUseConfig(invalidUseConfig);
+    ItemSkillFactoryBase::fromJson(zResult, zJson);
+}
+
+void DamagingItemSkillFactory::toJson(
+    DamagingItemSkill* zObject, Framework::JSON::JSONObject* zResult) const
+{
+    zResult->addValue(
         "maxXp", new Framework::JSON::JSONNumber(zObject->getMaxXp()));
-    result->addValue("invalidStaminaCost",
+    zResult->addValue("invalidStaminaCost",
         new Framework::JSON::JSONNumber(
             zObject->zInvalidUseConfig()->getStaminaCost()));
-    result->addValue("invalidStaminaCostPerHardness",
+    zResult->addValue("invalidStaminaCostPerHardness",
         new Framework::JSON::JSONNumber(
             zObject->zInvalidUseConfig()->getStaminaCostPerHardness()));
-    result->addValue("invalidStaminaCostDevider",
+    zResult->addValue("invalidStaminaCostDevider",
         new Framework::JSON::JSONNumber(
             zObject->zInvalidUseConfig()->getStaminaCostDevider()));
-    result->addValue("invalidStaminaCostDeviderPerLevel",
+    zResult->addValue("invalidStaminaCostDeviderPerLevel",
         new Framework::JSON::JSONNumber(
             zObject->zInvalidUseConfig()->getStaminaCostDeviderPerLevel()));
-    result->addValue("invalidDurabilityCost",
+    zResult->addValue("invalidDurabilityCost",
         new Framework::JSON::JSONNumber(
             zObject->zInvalidUseConfig()->getDurabilityCost()));
-    result->addValue("invalidDurabilityCostPerHardness",
+    zResult->addValue("invalidDurabilityCostPerHardness",
         new Framework::JSON::JSONNumber(
             zObject->zInvalidUseConfig()->getDurabilityCostPerHardness()));
-    result->addValue("invalidDurabilityCostDevider",
+    zResult->addValue("invalidDurabilityCostDevider",
         new Framework::JSON::JSONNumber(
             zObject->zInvalidUseConfig()->getDurabilityCostDevider()));
-    result->addValue("invalidDurabilityCostDeviderPerLevel",
+    zResult->addValue("invalidDurabilityCostDeviderPerLevel",
         new Framework::JSON::JSONNumber(
             zObject->zInvalidUseConfig()
                 ->getAdditionalDurabilityCostDeviderPerLevel()));
@@ -1571,56 +1835,52 @@ Framework::JSON::JSONObject* DamagingItemSkillFactory::toJson(
     {
         configs->addValue(Game::INSTANCE->zTypeRegistry()->toJson(config));
     }
-    result->addValue("configs", configs);
-    return nullptr;
-}
-
-Framework::JSON::Validator::JSONValidator*
-DamagingItemSkillFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
-{
-    return builder->withRequiredNumber("maxXp")
-        ->whichIsGreaterThen(0.0)
-        ->withDefault(10.0)
-        ->finishNumber()
-        ->withRequiredNumber("invalidStaminaCost")
-        ->whichIsGreaterOrEqual(0.0)
-        ->withDefault(0.5)
-        ->finishNumber()
-        ->withRequiredNumber("invalidStaminaCostPerHardness")
-        ->whichIsGreaterOrEqual(0.0)
-        ->withDefault(0.001)
-        ->finishNumber()
-        ->withRequiredNumber("invalidStaminaCostDevider")
-        ->whichIsGreaterOrEqual(0.0)
-        ->withDefault(0.8)
-        ->finishNumber()
-        ->withRequiredNumber("invalidAdditionalStaminaCostDeviderPerLevel")
-        ->whichIsGreaterOrEqual(0.0)
-        ->withDefault(0.2)
-        ->finishNumber()
-        ->withRequiredNumber("invalidDurabilityCost")
-        ->whichIsGreaterOrEqual(0.0)
-        ->withDefault(0.5)
-        ->finishNumber()
-        ->withRequiredNumber("invalidDurabilityCostPerHardness")
-        ->whichIsGreaterOrEqual(0.0)
-        ->withDefault(0.01)
-        ->finishNumber()
-        ->withRequiredNumber("invalidDurabilityCostDevider")
-        ->whichIsGreaterOrEqual(0.0)
-        ->withDefault(0.98)
-        ->finishNumber()
-        ->withRequiredNumber("invalidAdditionalDurabilityCostDeviderPerLevel")
-        ->whichIsGreaterOrEqual(0.0)
-        ->withDefault(0.02)
-        ->finishNumber()
-        ->withRequiredArray("configs")
-        ->addAcceptedTypeInArray(Game::INSTANCE->zTypeRegistry()
-                                     ->getValidator<DamagingItemSkillConfig>())
-        ->finishArray()
-        ->finishObject();
+    zResult->addValue("configs", configs);
+    ItemSkillFactoryBase::toJson(zObject, zResult);
+}
+
+JSONObjectValidationBuilder* DamagingItemSkillFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return ItemSkillFactoryBase::addToValidator(
+        builder->withRequiredNumber("invalidStaminaCost")
+            ->whichIsGreaterOrEqual(0.0)
+            ->withDefault(0.5)
+            ->finishNumber()
+            ->withRequiredNumber("invalidStaminaCostPerHardness")
+            ->whichIsGreaterOrEqual(0.0)
+            ->withDefault(0.001)
+            ->finishNumber()
+            ->withRequiredNumber("invalidStaminaCostDevider")
+            ->whichIsGreaterOrEqual(0.0)
+            ->withDefault(0.8)
+            ->finishNumber()
+            ->withRequiredNumber("invalidAdditionalStaminaCostDeviderPerLevel")
+            ->whichIsGreaterOrEqual(0.0)
+            ->withDefault(0.2)
+            ->finishNumber()
+            ->withRequiredNumber("invalidDurabilityCost")
+            ->whichIsGreaterOrEqual(0.0)
+            ->withDefault(0.5)
+            ->finishNumber()
+            ->withRequiredNumber("invalidDurabilityCostPerHardness")
+            ->whichIsGreaterOrEqual(0.0)
+            ->withDefault(0.01)
+            ->finishNumber()
+            ->withRequiredNumber("invalidDurabilityCostDevider")
+            ->whichIsGreaterOrEqual(0.0)
+            ->withDefault(0.98)
+            ->finishNumber()
+            ->withRequiredNumber(
+                "invalidAdditionalDurabilityCostDeviderPerLevel")
+            ->whichIsGreaterOrEqual(0.0)
+            ->withDefault(0.02)
+            ->finishNumber()
+            ->withRequiredArray("configs")
+            ->addAcceptedTypeInArray(
+                Game::INSTANCE->zTypeRegistry()
+                    ->getValidator<DamagingItemSkillConfig>())
+            ->finishArray());
 }
 
 Framework::Text DamagingItemSkillFactory::getTypeToken() const

+ 119 - 109
FactoryCraft/BasicTool.h

@@ -17,16 +17,17 @@ private:
     float maxLevel;
 
 public:
-    XPBasedLevelUpRule(float xpIncrease,
-        float xpMultiplier,
-        float levelIncrease,
-        float levelMultiplier,
-        float maxLevel);
+    XPBasedLevelUpRule();
     virtual void applyOn(ItemSkill* zSkill) override;
+    void setXpIncrease(float xpIncrease);
     float getXpIncrease() const;
+    void setXpMultiplier(float xpMultiplier);
     float getXpMultiplier() const;
+    void setLevelIncrease(float levelIncrease);
     float getLevelIncrease() const;
+    void setLevelMultiplier(float levelMultiplier);
     float getLevelMultiplier() const;
+    void setMaxLevel(float maxLevel);
     float getMaxLevel() const;
 };
 
@@ -35,13 +36,14 @@ class XPBasedLevelUpRuleFactory
 {
 public:
     XPBasedLevelUpRuleFactory();
-    XPBasedLevelUpRule* fromJson(
+    XPBasedLevelUpRule* createValue(
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(
-        XPBasedLevelUpRule* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    void fromJson(XPBasedLevelUpRule* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(XPBasedLevelUpRule* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };
 
@@ -53,10 +55,8 @@ private:
     float handleMaterialHardness;
 
 public:
-    BasicToolItem(int itemTypeId,
-        Framework::Text name,
-        float maxHp,
-        float maxDurability);
+    BasicToolItem(
+        int itemTypeId, Framework::Text name, float maxHp, float maxDurability);
     void setHeadMaterialHardness(float hardness);
     void setRodMaterialHardness(float hardness);
     void setHandleMaterialHardness(float hardness);
@@ -85,24 +85,7 @@ private:
     Framework::JSON::JSONObject* itemSkillConfigJson;
 
 public:
-    BasicToolItemType(Framework::Text name,
-        ModelInfo* model,
-        float headMaterialHardness,
-        float rodMaterialHardness,
-        float handleMaterialHardness,
-        float baseDurability,
-        float baseDurabilityMultiplier,
-        float headMaterialDurability,
-        float headMaterialDurabilityMultiplier,
-        float rodMaterialDurability,
-        float rodMaterialDurabilityMultiplier,
-        float handleMaterialDurability,
-        float handleMaterialDurabilityMultiplier,
-        ItemSkillLevelUpRule* levelUpRule,
-        Framework::Text brokenItemTypeName,
-        Framework::JSON::JSONObject* itemSkillConfigJson,
-        int maxStackSize,
-        Framework::RCArray<Framework::Text> groups);
+    BasicToolItemType();
     ~BasicToolItemType();
 
 protected:
@@ -121,34 +104,49 @@ public:
         Framework::JSON::JSONValue* zValue) const override;
     virtual void addItemAttributes(
         Item* zItem, Framework::JSON::JSONObject* zItemObjet) const override;
+    virtual ItemSkill* createDefaultItemSkill() const override;
+    void setBrokenItemTypeName(Framework::Text brokenItemTypeName);
+    Framework::Text getBrokenItemTypeName() const;
+    void setHeadMaterialHardness(float hardness);
     float getHeadMaterialHardness() const;
+    void setRodMaterialHardness(float hardness);
     float getRodMaterialHardness() const;
+    void setHandleMaterialHardness(float hardness);
     float getHandleMaterialHardness() const;
+    void setBaseDurability(float durability);
     float getBaseDurablility() const;
+    void setBaseDurabilityMultiplier(float multiplier);
     float getBaseDurabilityMultiplier() const;
+    void setHeadMaterialDurability(float durability);
     float getHeadMaterialDurability() const;
+    void setHeadMaterialDurabilityMultiplier(float multiplier);
     float getHeadMaterialDurabilityMultiplier() const;
+    void setRodMaterialDurability(float durability);
     float getRodMaterialDurability() const;
+    void setRodMaterialDurabilityMultiplier(float multiplier);
     float getRodMaterialDurabilityMultiplier() const;
+    void setHandleMaterialDurability(float durability);
     float getHandleMaterialDurability() const;
+    void setHandleMaterialDurabilityMultiplier(float multiplier);
     float getHandleMaterialDurabilityMultiplier() const;
+    void setLevelUpRule(ItemSkillLevelUpRule* rule);
     ItemSkillLevelUpRule* zLevelUpRule() const;
+    void setItemSkillConfigJson(Framework::JSON::JSONObject* zJson);
     Framework::JSON::JSONObject* getItemSkillConfigJson() const;
-    virtual ItemSkill* createDefaultItemSkill() const override;
 };
 
-class BasicToolItemTypeFactory
-    : public SubTypeFactory<ItemType, BasicToolItemType>
+class BasicToolItemTypeFactory : public ItemTypeFactoryBase<BasicToolItemType>
 {
 public:
     BasicToolItemTypeFactory();
-    BasicToolItemType* fromJson(
+    BasicToolItemType* createValue(
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(
-        BasicToolItemType* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    void fromJson(BasicToolItemType* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(BasicToolItemType* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };
 
@@ -167,26 +165,29 @@ private:
     float xpGain;
 
 public:
-    BlockReplaceItemSkillConfig(BlockFilter* targetBlockFilter,
-        int replacementBlockTypeId,
-        int cooldownTicks,
-        float staminaCost,
-        float staminaCostDevider,
-        float additionalStaminaCostDeviderPerLevel,
-        float durabilityCost,
-        float durabilityCostDevider,
-        float additionalDurabilityCostDeviderPerLevel,
-        float xpGain);
+    BlockReplaceItemSkillConfig();
     ~BlockReplaceItemSkillConfig();
+    void setTargetBlockFilter(BlockFilter* targetBlockFilter);
     BlockFilter* zTargetBlockFilter() const;
+    void setReplacementBlockTypeId(int replacementBlockTypeId);
     int getReplacementBlockTypeId() const;
+    void setCooldownTicks(int cooldownTicks);
     int getCooldownTicks() const;
+    void setStaminaCost(float staminaCost);
     float getStaminaCost() const;
+    void setStaminaCostDevider(float staminaCostDevider);
     float getStaminaCostDevider() const;
+    void setAdditionalStaminaCostDeviderPerLevel(
+        float additionalStaminaCostDeviderPerLevel);
     float getAdditionalStaminaCostDeviderPerLevel() const;
+    void setDurabilityCost(float durabilityCost);
     float getDurabilityCost() const;
+    void setDurabilityCostDevider(float durabilityCostDevider);
     float getDurabilityCostDevider() const;
+    void setAdditionalDurabilityCostDeviderPerLevel(
+        float additionalDurabilityCostDeviderPerLevel);
     float getAdditionalDurabilityCostDeviderPerLevel() const;
+    void setXpGain(float xpGain);
     float getXpGain() const;
 };
 
@@ -195,11 +196,14 @@ class BlockReplaceItemSkillConfigFactory
 {
 public:
     BlockReplaceItemSkillConfigFactory();
-    BlockReplaceItemSkillConfig* fromJson(
-        Framework::JSON::JSONValue* zJson) const override;
-    Framework::JSON::JSONValue* toJson(
-        BlockReplaceItemSkillConfig* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator() const override;
+    BlockReplaceItemSkillConfig* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(BlockReplaceItemSkillConfig* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(BlockReplaceItemSkillConfig* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
 };
 
 class BlockReplaceItemSkill : public ItemSkill
@@ -210,33 +214,33 @@ private:
     int cooldownTicks;
 
 public:
-    BlockReplaceItemSkill(float xp,
-        float maxXp,
-        float level,
-        BlockReplaceItemSkillConfig* invalidUseConfig,
-        Framework::RCArray<BlockReplaceItemSkillConfig> configs,
-        int cooldownTicks);
+    BlockReplaceItemSkill();
+    ~BlockReplaceItemSkill();
     virtual void load(Framework::StreamReader* zReader) override;
     virtual void save(Framework::StreamWriter* zWriter) override;
     virtual bool use(Entity* zActor, Item* zUsedItem, Block* zTarget) override;
     virtual bool use(Entity* zActor, Item* zUsedItem, Entity* zTarget) override;
+    void setInvalidUseConfig(BlockReplaceItemSkillConfig* config);
     BlockReplaceItemSkillConfig* zInvalidUseConfig() const;
+    void addConfig(BlockReplaceItemSkillConfig* config);
     const Framework::RCArray<BlockReplaceItemSkillConfig>& getConfigs() const;
+    void setCooldownTicks(int cooldownTicks);
     int getCooldownTicks() const;
 };
 
 class BlockReplaceItemSkillFactory
-    : public SubTypeFactory<ItemSkill, BlockReplaceItemSkill>
+    : public ItemSkillFactoryBase<BlockReplaceItemSkill>
 {
 public:
     BlockReplaceItemSkillFactory();
-    BlockReplaceItemSkill* fromJson(
+    BlockReplaceItemSkill* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(BlockReplaceItemSkill* zResult,
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(
-        BlockReplaceItemSkill* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    void toJson(BlockReplaceItemSkill* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };
 
@@ -247,7 +251,7 @@ private:
     float damage;
     float damagePerHeadHardness;
     float baseDamageMultiplier;
-    float damageMupliplierPerHeadHardness;
+    float damageMultiplierPerHeadHardness;
     float damagePerLevel;
     float damageMultiplierPerLevel;
     float damageDevider;
@@ -265,46 +269,49 @@ private:
     float xpGainPerDamage;
 
 public:
-    DamagingItemSkillConfig(BlockFilter* targetBlockFilter,
-        float damage,
-        float damagePerHeadHardness,
-        float baseDamageMultiplier,
-        float damageMupliplierPerHeadHardness,
-        float damagePerLevel,
-        float damageMultiplierPerLevel,
-        float damageDevider,
-        float damageDeviderPerHardness,
-        float staminaCost,
-        float staminaCostPerDamage,
-        float staminaCostPerHardness,
-        float staminaCostDevider,
-        float staminaCostDeviderPerLevel,
-        float durabilityCost,
-        float durabilityCostPerDamage,
-        float durabilityCostPerHardness,
-        float durabilityCostDevider,
-        float additionalDurabilityCostDeviderPerLevel,
-        float xpGainPerDamage);
+    DamagingItemSkillConfig();
     ~DamagingItemSkillConfig();
+    void setTargetBlockFilter(BlockFilter* targetBlockFilter);
     BlockFilter* zTargetBlockFilter() const;
+    void setDamage(float damage);
     float getDamage() const;
+    void setDamagePerHeadHardness(float damagePerHeadHardness);
     float getDamagePerHeadHardness() const;
+    void setBaseDamageMultiplier(float baseDamageMultiplier);
     float getBaseDamageMultiplier() const;
-    float getDamageMupliplierPerHeadHardness() const;
+    void setDamageMultiplierPerHeadHardness(
+        float damageMupliplierPerHeadHardness);
+    float getDamageMultiplierPerHeadHardness() const;
+    void setDamagePerLevel(float damagePerLevel);
     float getDamagePerLevel() const;
+    void setDamageMultiplierPerLevel(float damageMultiplierPerLevel);
     float getDamageMultiplierPerLevel() const;
+    void setDamageDevider(float damageDevider);
     float getDamageDevider() const;
+    void setDamageDeviderPerHardness(float damageDeviderPerHardness);
     float getDamageDeviderPerHardness() const;
+    void setStaminaCost(float staminaCost);
     float getStaminaCost() const;
+    void setStaminaCostPerDamage(float staminaCostPerDamage);
     float getStaminaCostPerDamage() const;
+    void setStaminaCostPerHardness(float staminaCostPerHardness);
     float getStaminaCostPerHardness() const;
+    void setStaminaCostDevider(float staminaCostDevider);
     float getStaminaCostDevider() const;
+    void setStaminaCostDeviderPerLevel(float staminaCostDeviderPerLevel);
     float getStaminaCostDeviderPerLevel() const;
+    void setDurabilityCost(float durabilityCost);
     float getDurabilityCost() const;
+    void setDurabilityCostPerDamage(float durabilityCostPerDamage);
     float getDurabilityCostPerDamage() const;
+    void setDurabilityCostPerHardness(float durabilityCostPerHardness);
     float getDurabilityCostPerHardness() const;
+    void setDurabilityCostDevider(float durabilityCostDevider);
     float getDurabilityCostDevider() const;
+    void setAdditionalDurabilityCostDeviderPerLevel(
+        float additionalDurabilityCostDeviderPerLevel);
     float getAdditionalDurabilityCostDeviderPerLevel() const;
+    void setXpGainPerDamage(float xpGainPerDamage);
     float getXpGainPerDamage() const;
 };
 
@@ -313,11 +320,14 @@ class DamagingItemSkillConfigFactory
 {
 public:
     DamagingItemSkillConfigFactory();
-    DamagingItemSkillConfig* fromJson(
-        Framework::JSON::JSONValue* zJson) const override;
-    Framework::JSON::JSONValue* toJson(
-        DamagingItemSkillConfig* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator() const override;
+    DamagingItemSkillConfig* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(DamagingItemSkillConfig* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(DamagingItemSkillConfig* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
 };
 
 class DamagingItemSkill : public ItemSkill
@@ -327,28 +337,28 @@ private:
     Framework::RCArray<DamagingItemSkillConfig> configs;
 
 public:
-    DamagingItemSkill(float xp,
-        float maxXp,
-        float level,
-        DamagingItemSkillConfig* invalidUseConfig,
-        Framework::RCArray<DamagingItemSkillConfig> configs);
+    DamagingItemSkill();
+    ~DamagingItemSkill();
     virtual bool use(Entity* zActor, Item* zUsedItem, Block* zTarget) override;
     virtual bool use(Entity* zActor, Item* zUsedItem, Entity* zTarget) override;
+    void setInvalidUseConfig(DamagingItemSkillConfig* config);
     DamagingItemSkillConfig* zInvalidUseConfig() const;
+    void addConfig(DamagingItemSkillConfig* config);
     const Framework::RCArray<DamagingItemSkillConfig>& getConfigs() const;
 };
 
 class DamagingItemSkillFactory
-    : public SubTypeFactory<ItemSkill, DamagingItemSkill>
+    : public ItemSkillFactoryBase<DamagingItemSkill>
 {
 public:
     DamagingItemSkillFactory();
-    DamagingItemSkill* fromJson(
+    DamagingItemSkill* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(DamagingItemSkill* zResult,
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(
-        DamagingItemSkill* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    void toJson(DamagingItemSkill* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };

+ 144 - 43
FactoryCraft/BiomGenerator.cpp

@@ -1,45 +1,28 @@
 #include "BiomGenerator.h"
 
+#include "Constants.h"
 #include "Game.h"
 #include "JNoise.h"
 
-BiomGenerator::BiomGenerator(
-    Framework::JSON::JSONValue* zConfig, JExpressionMemory* zMemory)
-    : ReferenceCounter()
+BiomGenerator::BiomGenerator()
+    : ReferenceCounter(),
+      condition(0)
+{}
+
+BiomGenerator::~BiomGenerator()
 {
-    name = zConfig->asObject()->zValue("name")->asString()->getString();
-    condition = JExpressionParser::parseBoolExpression(
-        zConfig->asObject()->zValue("condition"));
-    bool first = 1;
-    for (Framework::JSON::JSONValue* value :
-        *zConfig->asObject()->zValue("structurCollections")->asArray())
+    if (condition) condition->release();
+}
+
+void BiomGenerator::initialize(JExpressionMemory* zMemory)
+{
+    for (GeneratorRule* rule : rules)
     {
-        StructureTemplateCollection* collection
-            = new StructureTemplateCollection(value, zMemory);
-        templates.add(collection);
-        if (first)
-        {
-            minStructureOffset = collection->getMinAffected();
-            maxStructureOffset = collection->getMaxAffected();
-            first = 0;
-        }
-        else
-        {
-            Framework::Vec3<int> min = collection->getMinAffected();
-            Framework::Vec3<int> max = collection->getMaxAffected();
-            if (minStructureOffset.x > min.x) minStructureOffset.x = min.x;
-            if (minStructureOffset.y > min.y) minStructureOffset.y = min.y;
-            if (minStructureOffset.z > min.z) minStructureOffset.z = min.z;
-            if (maxStructureOffset.x < max.x) maxStructureOffset.x = max.x;
-            if (maxStructureOffset.y < max.y) maxStructureOffset.y = max.y;
-            if (maxStructureOffset.z < max.z) maxStructureOffset.z = max.z;
-        }
+        rule->initialize(zMemory);
     }
-    for (Framework::JSON::JSONValue* value :
-        *zConfig->asObject()->zValue("blocks")->asArray())
+    for (StructureTemplateCollection* collection : templates)
     {
-        rules.add(Game::INSTANCE->zTypeRegistry()->createGeneratorRule(
-            value, zMemory));
+        collection->initialize(zMemory);
     }
 }
 
@@ -112,20 +95,138 @@ Framework::Vec3<int> BiomGenerator::getMaxStructureOffset() const
     return maxStructureOffset;
 }
 
-Framework::JSON::Validator::JSONValidator* BiomGenerator::getConfigValidator()
+void BiomGenerator::setName(Framework::Text name)
+{
+    this->name = name;
+}
+
+Framework::Text BiomGenerator::getName() const
+{
+    return name;
+}
+
+void BiomGenerator::setCondition(JBoolExpression* condition)
+{
+    if (this->condition) this->condition->release();
+    this->condition = condition;
+}
+
+JBoolExpression* BiomGenerator::getCondition() const
 {
-    return Framework::JSON::Validator::JSONValidator::buildForObject()
-        ->withRequiredString("name")
+    return condition;
+}
+
+void BiomGenerator::addTemplate(StructureTemplateCollection* collection)
+{
+    templates.add(collection);
+    Framework::Vec3<int> min = collection->getMinAffected();
+    Framework::Vec3<int> max = collection->getMaxAffected();
+    if (templates.getEintragAnzahl())
+    {
+        minStructureOffset = min;
+        maxStructureOffset = max;
+    }
+    else
+    {
+        if (minStructureOffset.x > min.x) minStructureOffset.x = min.x;
+        if (minStructureOffset.y > min.y) minStructureOffset.y = min.y;
+        if (minStructureOffset.z > min.z) minStructureOffset.z = min.z;
+        if (maxStructureOffset.x < max.x) maxStructureOffset.x = max.x;
+        if (maxStructureOffset.y < max.y) maxStructureOffset.y = max.y;
+        if (maxStructureOffset.z < max.z) maxStructureOffset.z = max.z;
+    }
+}
+
+const Framework::RCArray<StructureTemplateCollection>&
+BiomGenerator::getTemplates()
+{
+    return templates;
+}
+
+void BiomGenerator::addGeneratorRule(GeneratorRule* rule)
+{
+    rules.add(rule);
+}
+
+const Framework::RCArray<GeneratorRule>&
+BiomGenerator::getGeneratorRules() const
+{
+    return rules;
+}
+
+BiomGeneratorFactory::BiomGeneratorFactory()
+    : TypeFactory()
+{}
+
+BiomGenerator* BiomGeneratorFactory::createValue(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new BiomGenerator();
+}
+
+void BiomGeneratorFactory::fromJson(
+    BiomGenerator* zResult, Framework::JSON::JSONObject* zJson) const
+{
+    zResult->setName(zJson->zValue("name")->asString()->getString());
+    zResult->setCondition(
+        Game::INSTANCE->zTypeRegistry()->fromJson<JBoolExpression>(
+            zJson->zValue("condition")));
+    bool first = 1;
+    for (Framework::JSON::JSONValue* value :
+        *zJson->zValue("structurCollections")->asArray())
+    {
+        StructureTemplateCollection* collection
+            = Game::INSTANCE->zTypeRegistry()
+                  ->fromJson<StructureTemplateCollection>(value);
+        zResult->addTemplate(collection);
+    }
+    for (Framework::JSON::JSONValue* value :
+        *zJson->asObject()->zValue("blocks")->asArray())
+    {
+        zResult->addGeneratorRule(
+            Game::INSTANCE->zTypeRegistry()->fromJson<GeneratorRule>(value));
+    }
+}
+
+void BiomGeneratorFactory::toJson(
+    BiomGenerator* zObject, Framework::JSON::JSONObject* zResult) const
+{
+    zResult->addValue(
+        "name", new Framework::JSON::JSONString(zObject->getName()));
+    zResult->addValue("condition",
+        Game::INSTANCE->zTypeRegistry()->toJson<JBoolExpression>(
+            zObject->getCondition()));
+    Framework::JSON::JSONArray* collections = new Framework::JSON::JSONArray();
+    for (StructureTemplateCollection* collection : zObject->getTemplates())
+    {
+        collections->addValue(
+            Game::INSTANCE->zTypeRegistry()
+                ->toJson<StructureTemplateCollection>(collection));
+    }
+    zResult->addValue("structurCollections", collections);
+    Framework::JSON::JSONArray* rules = new Framework::JSON::JSONArray();
+    for (GeneratorRule* rule : zObject->getGeneratorRules())
+    {
+        rules->addValue(
+            Game::INSTANCE->zTypeRegistry()->toJson<GeneratorRule>(rule));
+    }
+    zResult->addValue("blocks", rules);
+}
+
+JSONObjectValidationBuilder* BiomGeneratorFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return builder->withRequiredString("name")
         ->finishString()
-        ->withRequiredAttribute(
-            "condition", JExpressionParser::getBoolValidator())
+        ->withRequiredAttribute("condition",
+            Game::INSTANCE->zTypeRegistry()->getValidator<JBoolExpression>())
         ->withRequiredArray("structurCollections")
         ->addAcceptedTypeInArray(
-            StructureTemplateCollection::getConfigValidator())
+            Game::INSTANCE->zTypeRegistry()
+                ->getValidator<StructureTemplateCollection>())
         ->finishArray()
         ->withRequiredArray("blocks")
         ->addAcceptedTypeInArray(
-            Game::INSTANCE->zTypeRegistry()->getGeneratorRuleValidator())
-        ->finishArray()
-        ->finishObject();
-}
+            Game::INSTANCE->zTypeRegistry()->getValidator<GeneratorRule>())
+        ->finishArray();
+}

+ 26 - 3
FactoryCraft/BiomGenerator.h

@@ -26,8 +26,10 @@ protected:
     int seed;
 
 public:
-    BiomGenerator(
-        Framework::JSON::JSONValue* zConfig, JExpressionMemory* zMemory);
+    BiomGenerator();
+    ~BiomGenerator();
+
+    void initialize(JExpressionMemory* zMemory);
     Framework::Either<Block*, int> generateBlock(int x,
         int y,
         int z,
@@ -48,5 +50,26 @@ public:
     Framework::Vec3<int> getMinStructureOffset() const;
     Framework::Vec3<int> getMaxStructureOffset() const;
 
-    static Framework::JSON::Validator::JSONValidator* getConfigValidator();
+    void setName(Framework::Text name);
+    Framework::Text getName() const;
+    void setCondition(JBoolExpression* condition);
+    JBoolExpression* getCondition() const;
+    void addTemplate(StructureTemplateCollection* collection);
+    const Framework::RCArray<StructureTemplateCollection>& getTemplates();
+    void addGeneratorRule(GeneratorRule* rule);
+    const Framework::RCArray<GeneratorRule>& getGeneratorRules() const;
+};
+
+class BiomGeneratorFactory : public TypeFactory<BiomGenerator>
+{
+public:
+    BiomGeneratorFactory();
+    BiomGenerator* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(BiomGenerator* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(BiomGenerator* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
 };

+ 108 - 87
FactoryCraft/Block.cpp

@@ -1,12 +1,15 @@
 #include "Block.h"
 
 #include "AddEntityUpdate.h"
+#include "Dimension.h"
 #include "Game.h"
 #include "Inventory.h"
 #include "ItemEntity.h"
 #include "MultiblockStructure.h"
 #include "NoBlock.h"
 #include "PlaceableProof.h"
+#include "TickQueue.h"
+#include "WorldGenerator.h"
 
 Block::Block(
     int typeId, Framework::Vec3<int> pos, int dimensionId, bool hasInventory)
@@ -72,7 +75,7 @@ void Block::onDestroy()
     }
 }
 
-void Block::onDialogClosed(Text dialogId) {}
+void Block::onDialogClosed(Framework::Text dialogId) {}
 
 void Block::broadcastModelInfoChange()
 {
@@ -359,7 +362,7 @@ void Block::updateModel(ModelInfo* zInfo) const
         {
             NetworkMessage* changeMsg = new NetworkMessage();
             changeMsg->addressBlock(this);
-            InMemoryBuffer buffer;
+            Framework::InMemoryBuffer buffer;
             zInfo->writeTo(&buffer);
             char* msg = new char[(int)buffer.getSize() + 1];
             msg[0] = 1; // hmodel change
@@ -417,6 +420,16 @@ bool BasicBlockItem::canBePlacedAt(
             || placeableProof->isPlacable(this, worldPos, dimensionId));
 }
 
+BasicBlockItemType::BasicBlockItemType()
+    : ItemType(),
+      transparent(0),
+      passable(0),
+      hardness(1.f),
+      speedModifier(1.f),
+      blockTypeName(""),
+      placeableProof(0)
+{}
+
 BasicBlockItemType::BasicBlockItemType(Framework::Text name,
     ModelInfo* model,
     bool transparent,
@@ -427,14 +440,20 @@ BasicBlockItemType::BasicBlockItemType(Framework::Text name,
     PlaceableProof* placeableProof,
     int maxStackSize,
     Framework::RCArray<Framework::Text> groups)
-    : ItemType(name, model, maxStackSize, groups),
+    : ItemType(),
       transparent(transparent),
       passable(passable),
       hardness(hardness),
       speedModifier(speedModifier),
       blockTypeName(blockTypeName),
       placeableProof(placeableProof)
-{}
+{
+    setName(name);
+    setModel(model);
+    setMaxStackSize(maxStackSize);
+    for (Framework::Text* group : groups)
+        addGroup(*group);
+}
 
 BasicBlockItemType::~BasicBlockItemType()
 {
@@ -452,31 +471,62 @@ int BasicBlockItemType::getBlockTypeId() const
     return blockTypeId;
 }
 
+void BasicBlockItemType::setTransparent(bool transparent)
+{
+    this->transparent = transparent;
+}
+
 bool BasicBlockItemType::isTransparent() const
 {
     return transparent;
 }
 
+void BasicBlockItemType::setPassable(bool passable)
+{
+    this->passable = passable;
+}
+
 bool BasicBlockItemType::isPassable() const
 {
     return passable;
 }
 
+void BasicBlockItemType::setHardness(float hardness)
+{
+    this->hardness = hardness;
+}
+
 float BasicBlockItemType::getHardness() const
 {
     return hardness;
 }
 
+void BasicBlockItemType::setSpeedModifier(float speedModifier)
+{
+    this->speedModifier = speedModifier;
+}
+
 float BasicBlockItemType::getSpeedModifier() const
 {
     return speedModifier;
 }
 
+void BasicBlockItemType::setBlockTypeName(Framework::Text blockTypeName)
+{
+    this->blockTypeName = blockTypeName;
+}
+
 Framework::Text BasicBlockItemType::getBlockTypeName() const
 {
     return blockTypeName;
 }
 
+void BasicBlockItemType::setPlaceableProof(PlaceableProof* placeableProof)
+{
+    if (this->placeableProof) this->placeableProof->release();
+    this->placeableProof = placeableProof;
+}
+
 PlaceableProof* BasicBlockItemType::zPlaceableProof() const
 {
     return placeableProof;
@@ -529,108 +579,79 @@ Item* BasicBlockItemType::createItem() const
 }
 
 BasicBlockItemTypeFactory::BasicBlockItemTypeFactory()
-    : SubTypeFactory()
+    : ItemTypeFactoryBase()
 {}
 
-BasicBlockItemType* BasicBlockItemTypeFactory::fromJson(
+BasicBlockItemType* BasicBlockItemTypeFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
-    Framework::RCArray<Framework::Text> groups;
-    for (Framework::JSON::JSONValue* group :
-        *zJson->zValue("groupNames")->asArray())
-    {
-        groups.add(new Framework::Text(group->asString()->getString()));
-    }
-    return new BasicBlockItemType(
-        zJson->zValue("name")->asString()->getString(),
-        Game::INSTANCE->zTypeRegistry()->fromJson<ModelInfo>(
-            zJson->zValue("model")),
-        zJson->zValue("transparent")->asBool()->getBool(),
-        zJson->zValue("passable")->asBool()->getBool(),
-        (float)zJson->zValue("hardness")->asNumber()->getNumber(),
-        (float)zJson->zValue("speedModifier")->asNumber()->getNumber(),
-        zJson->zValue("blockType")->asString()->getString(),
+    return new BasicBlockItemType();
+}
+
+void BasicBlockItemTypeFactory::fromJson(
+    BasicBlockItemType* zResult, Framework::JSON::JSONObject* zJson) const
+{
+    zResult->setTransparent(zJson->zValue("transparent")->asBool()->getBool());
+    zResult->setPassable(zJson->zValue("passable")->asBool()->getBool());
+    zResult->setHardness(
+        (float)zJson->zValue("hardness")->asNumber()->getNumber());
+    zResult->setSpeedModifier(
+        (float)zJson->zValue("speedModifier")->asNumber()->getNumber());
+    zResult->setBlockTypeName(
+        zJson->zValue("blockType")->asString()->getString());
+    zResult->setPlaceableProof(
         zJson->zValue("placeableProof")->getType()
                 == Framework::JSON::JSONType::OBJECT
             ? Game::INSTANCE->zTypeRegistry()->fromJson<PlaceableProof>(
                 zJson->zValue("placeableProof"))
-            : 0,
-        (int)zJson->zValue("maxStack")->asNumber()->getNumber(),
-        groups);
+            : 0);
+    ItemTypeFactoryBase::fromJson(zResult, zJson);
 }
 
-Framework::JSON::JSONObject* BasicBlockItemTypeFactory::toJson(
-    BasicBlockItemType* zObject) const
+void BasicBlockItemTypeFactory::toJson(
+    BasicBlockItemType* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* zJson = new Framework::JSON::JSONObject();
-    zJson->addValue(
-        "name", new Framework::JSON::JSONString(zObject->getName()));
-    zJson->addValue(
-        "model", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zModel()));
-    zJson->addValue(
+    zResult->addValue(
         "transparent", new Framework::JSON::JSONBool(zObject->isTransparent()));
-    zJson->addValue(
+    zResult->addValue(
         "passable", new Framework::JSON::JSONBool(zObject->isPassable()));
-    zJson->addValue(
+    zResult->addValue(
         "hardness", new Framework::JSON::JSONNumber(zObject->getHardness()));
-    zJson->addValue("speedModifier",
+    zResult->addValue("speedModifier",
         new Framework::JSON::JSONNumber(zObject->getSpeedModifier()));
-    zJson->addValue("blockType",
+    zResult->addValue("blockType",
         new Framework::JSON::JSONString(zObject->getBlockTypeName()));
-    zJson->addValue("placeableProof",
+    zResult->addValue("placeableProof",
         zObject->zPlaceableProof() ? Game::INSTANCE->zTypeRegistry()->toJson(
             zObject->zPlaceableProof())
                                    : new Framework::JSON::JSONValue());
-    zJson->addValue("maxStack",
-        new Framework::JSON::JSONNumber(zObject->getMaxStackSize()));
-    Framework::JSON::JSONArray* groups = new Framework::JSON::JSONArray();
-    for (Framework::Text* group : zObject->getGroups())
-    {
-        groups->addValue(new Framework::JSON::JSONString(group->getText()));
-    }
-    zJson->addValue("groupNames", groups);
-    return zJson;
-}
-
-Framework::JSON::Validator::JSONValidator*
-BasicBlockItemTypeFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
-{
-    return builder->withRequiredString("name")
-        ->finishString()
-        ->withRequiredAttribute(
-            "model", Game::INSTANCE->zTypeRegistry()->getValidator<ModelInfo>())
-        ->withRequiredBool("transparent")
-        ->withDefault(false)
-        ->finishBool()
-        ->withRequiredBool("passable")
-        ->withDefault(false)
-        ->finishBool()
-        ->withRequiredNumber("hardness")
-        ->withDefault(1.f)
-        ->finishNumber()
-        ->withRequiredNumber("speedModifier")
-        ->withDefault(1.f)
-        ->finishNumber()
-        ->withRequiredString("blockType")
-        ->finishString()
-        ->withRequiredAttribute("placeableProof",
-            Game::INSTANCE->zTypeRegistry()->getValidator<PlaceableProof>())
-        ->withRequiredObject("placeableProof")
-        ->withDefaultNull()
-        ->whichCanBeNull()
-        ->finishObject()
-        ->withRequiredNumber("maxStack")
-        ->withDefault(50.0)
-        ->whichIsGreaterOrEqual(1.0)
-        ->finishNumber()
-        ->withRequiredArray("groupNames")
-        ->addAcceptedStringInArray()
-        ->finishString()
-        ->withDefault(new Framework::JSON::JSONArray())
-        ->finishArray()
-        ->finishObject();
+    ItemTypeFactoryBase::toJson(zObject, zResult);
+}
+
+JSONObjectValidationBuilder* BasicBlockItemTypeFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return ItemTypeFactoryBase::addToValidator(
+        builder->withRequiredBool("transparent")
+            ->withDefault(false)
+            ->finishBool()
+            ->withRequiredBool("passable")
+            ->withDefault(false)
+            ->finishBool()
+            ->withRequiredNumber("hardness")
+            ->withDefault(1.f)
+            ->finishNumber()
+            ->withRequiredNumber("speedModifier")
+            ->withDefault(1.f)
+            ->finishNumber()
+            ->withRequiredString("blockType")
+            ->finishString()
+            ->withRequiredAttribute("placeableProof",
+                Game::INSTANCE->zTypeRegistry()->getValidator<PlaceableProof>())
+            ->withRequiredObject("placeableProof")
+            ->withDefaultNull()
+            ->whichCanBeNull()
+            ->finishObject());
 }
 
 Framework::Text BasicBlockItemTypeFactory::getTypeToken() const

+ 24 - 15
FactoryCraft/Block.h

@@ -153,14 +153,8 @@ private:
     int blockTypeId;
     PlaceableProof* placeableProof;
 
-protected:
-    virtual void loadSuperItem(
-        Item* zItem, Framework::StreamReader* zReader) const override;
-    virtual void saveSuperItem(
-        const Item* zItem, Framework::StreamWriter* zWriter) const override;
-    virtual Item* createItem() const override;
-
 public:
+    BasicBlockItemType();
     BasicBlockItemType(Framework::Text name,
         ModelInfo* model,
         bool transparent,
@@ -172,27 +166,42 @@ public:
         int maxStackSize,
         Framework::RCArray<Framework::Text> groups);
     ~BasicBlockItemType();
+
+protected:
+    virtual void loadSuperItem(
+        Item* zItem, Framework::StreamReader* zReader) const override;
+    virtual void saveSuperItem(
+        const Item* zItem, Framework::StreamWriter* zWriter) const override;
+    virtual Item* createItem() const override;
+
+public:
     virtual bool initialize(Game* zGame) override;
     int getBlockTypeId() const;
+    void setTransparent(bool transparent);
     bool isTransparent() const;
+    void setPassable(bool passable);
     bool isPassable() const;
+    void setHardness(float hardness);
     float getHardness() const;
+    void setSpeedModifier(float speedModifier);
     float getSpeedModifier() const;
+    void setBlockTypeName(Framework::Text blockTypeName);
     Framework::Text getBlockTypeName() const;
+    void setPlaceableProof(PlaceableProof* placeableProof);
     PlaceableProof* zPlaceableProof() const;
 };
 
-class BasicBlockItemTypeFactory
-    : public SubTypeFactory<ItemType, BasicBlockItemType>
+class BasicBlockItemTypeFactory : public ItemTypeFactoryBase<BasicBlockItemType>
 {
 public:
     BasicBlockItemTypeFactory();
-    BasicBlockItemType* fromJson(
+    BasicBlockItemType* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(BasicBlockItemType* zResult,
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(
-        BasicBlockItemType* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    void toJson(BasicBlockItemType* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };

+ 176 - 135
FactoryCraft/BlockFilter.cpp

@@ -8,9 +8,8 @@ BlockFilter::BlockFilter()
     : ReferenceCounter()
 {}
 
-BlockFilterAnd::BlockFilterAnd(Framework::RCArray<BlockFilter> filters)
-    : BlockFilter(),
-      filters(filters)
+BlockFilterAnd::BlockFilterAnd()
+    : BlockFilter()
 {}
 
 bool BlockFilterAnd::test(const Block* zBlock)
@@ -25,6 +24,11 @@ bool BlockFilterAnd::test(const Block* zBlock)
     return true;
 }
 
+void BlockFilterAnd::addFilter(BlockFilter* filter)
+{
+    filters.add(filter);
+}
+
 Framework::RCArray<BlockFilter> BlockFilterAnd::getFilters() const
 {
     return filters;
@@ -34,41 +38,41 @@ BlockFilterAndFactory::BlockFilterAndFactory()
     : SubTypeFactory()
 {}
 
-BlockFilterAnd* BlockFilterAndFactory::fromJson(
+BlockFilterAnd* BlockFilterAndFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
-    Framework::RCArray<BlockFilter> filters;
+    return new BlockFilterAnd();
+}
+
+void BlockFilterAndFactory::fromJson(
+    BlockFilterAnd* zResult, Framework::JSON::JSONObject* zJson) const
+{
     for (Framework::JSON::JSONValue* value :
         *zJson->zValue("filters")->asArray())
     {
-        filters.add(
+        zResult->addFilter(
             Game::INSTANCE->zTypeRegistry()->fromJson<BlockFilter>(value));
     }
-    return new BlockFilterAnd(filters);
 }
 
-Framework::JSON::JSONObject* BlockFilterAndFactory::toJson(
-    BlockFilterAnd* zObject) const
+void BlockFilterAndFactory::toJson(
+    BlockFilterAnd* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
     Framework::JSON::JSONArray* filters = new Framework::JSON::JSONArray();
     for (BlockFilter* filter : zObject->getFilters())
     {
         filters->addValue(Game::INSTANCE->zTypeRegistry()->toJson(filter));
     }
-    result->addValue("filters", filters);
-    return result;
+    zResult->addValue("filters", filters);
 }
 
-Framework::JSON::Validator::JSONValidator* BlockFilterAndFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
+JSONObjectValidationBuilder* BlockFilterAndFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
     return builder->withRequiredArray("filters")
         ->addAcceptedTypeInArray(
             Game::INSTANCE->zTypeRegistry()->getValidator<BlockFilter>())
-        ->finishArray()
-        ->finishObject();
+        ->finishArray();
 }
 
 Framework::Text BlockFilterAndFactory::getTypeToken() const
@@ -76,9 +80,8 @@ Framework::Text BlockFilterAndFactory::getTypeToken() const
     return "and";
 }
 
-BlockFilterOr::BlockFilterOr(Framework::RCArray<BlockFilter> filters)
-    : BlockFilter(),
-      filters(filters)
+BlockFilterOr::BlockFilterOr()
+    : BlockFilter()
 {}
 
 bool BlockFilterOr::test(const Block* zBlock)
@@ -93,6 +96,11 @@ bool BlockFilterOr::test(const Block* zBlock)
     return false;
 }
 
+void BlockFilterOr::addFilter(BlockFilter* filter)
+{
+    filters.add(filter);
+}
+
 Framework::RCArray<BlockFilter> BlockFilterOr::getFilters() const
 {
     return filters;
@@ -102,41 +110,41 @@ BlockFilterOrFactory::BlockFilterOrFactory()
     : SubTypeFactory()
 {}
 
-BlockFilterOr* BlockFilterOrFactory::fromJson(
+BlockFilterOr* BlockFilterOrFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
-    Framework::RCArray<BlockFilter> filters;
+    return new BlockFilterOr();
+}
+
+void BlockFilterOrFactory::fromJson(
+    BlockFilterOr* zResult, Framework::JSON::JSONObject* zJson) const
+{
     for (Framework::JSON::JSONValue* value :
         *zJson->zValue("filters")->asArray())
     {
-        filters.add(
+        zResult->addFilter(
             Game::INSTANCE->zTypeRegistry()->fromJson<BlockFilter>(value));
     }
-    return new BlockFilterOr(filters);
 }
 
-Framework::JSON::JSONObject* BlockFilterOrFactory::toJson(
-    BlockFilterOr* zObject) const
+void BlockFilterOrFactory::toJson(
+    BlockFilterOr* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
     Framework::JSON::JSONArray* filters = new Framework::JSON::JSONArray();
     for (BlockFilter* filter : zObject->getFilters())
     {
         filters->addValue(Game::INSTANCE->zTypeRegistry()->toJson(filter));
     }
-    result->addValue("filters", filters);
-    return result;
+    zResult->addValue("filters", filters);
 }
 
-Framework::JSON::Validator::JSONValidator* BlockFilterOrFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
+JSONObjectValidationBuilder* BlockFilterOrFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
     return builder->withRequiredArray("filters")
         ->addAcceptedTypeInArray(
             Game::INSTANCE->zTypeRegistry()->getValidator<BlockFilter>())
-        ->finishArray()
-        ->finishObject();
+        ->finishArray();
 }
 
 Framework::Text BlockFilterOrFactory::getTypeToken() const
@@ -144,16 +152,27 @@ Framework::Text BlockFilterOrFactory::getTypeToken() const
     return "or";
 }
 
-BlockFilterNot::BlockFilterNot(BlockFilter* filter)
+BlockFilterNot::BlockFilterNot()
     : BlockFilter(),
-      filter(filter)
+      filter(0)
 {}
 
+BlockFilterNot::~BlockFilterNot()
+{
+    if (filter) filter->release();
+}
+
 bool BlockFilterNot::test(const Block* zBlock)
 {
     return !filter->test(zBlock);
 }
 
+void BlockFilterNot::setFilter(BlockFilter* filter)
+{
+    if (this->filter) this->filter->release();
+    this->filter = filter;
+}
+
 BlockFilter* BlockFilterNot::zFilter() const
 {
     return filter;
@@ -163,31 +182,31 @@ BlockFilterNotFactory::BlockFilterNotFactory()
     : SubTypeFactory()
 {}
 
-BlockFilterNot* BlockFilterNotFactory::fromJson(
+BlockFilterNot* BlockFilterNotFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
-    return new BlockFilterNot(
-        Game::INSTANCE->zTypeRegistry()->fromJson<BlockFilter>(
-            zJson->zValue("filter")));
+    return new BlockFilterNot();
+}
+
+void BlockFilterNotFactory::fromJson(
+    BlockFilterNot* zResult, Framework::JSON::JSONObject* zJson) const
+{
+    zResult->setFilter(Game::INSTANCE->zTypeRegistry()->fromJson<BlockFilter>(
+        zJson->zValue("filter")));
 }
 
-Framework::JSON::JSONObject* BlockFilterNotFactory::toJson(
-    BlockFilterNot* zObject) const
+void BlockFilterNotFactory::toJson(
+    BlockFilterNot* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue(
+    zResult->addValue(
         "filter", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zFilter()));
-    return result;
 }
 
-Framework::JSON::Validator::JSONValidator* BlockFilterNotFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
+JSONObjectValidationBuilder* BlockFilterNotFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
-    return builder
-        ->withRequiredAttribute("filter",
-            Game::INSTANCE->zTypeRegistry()->getValidator<BlockFilter>())
-        ->finishObject();
+    return builder->withRequiredAttribute(
+        "filter", Game::INSTANCE->zTypeRegistry()->getValidator<BlockFilter>());
 }
 
 Framework::Text BlockFilterNotFactory::getTypeToken() const
@@ -195,9 +214,8 @@ Framework::Text BlockFilterNotFactory::getTypeToken() const
     return "not";
 }
 
-BlockFilterBlockType::BlockFilterBlockType(Framework::Array<int> blockTypeIds)
-    : BlockFilter(),
-      blockTypeIds(blockTypeIds)
+BlockFilterBlockType::BlockFilterBlockType()
+    : BlockFilter()
 {}
 
 bool BlockFilterBlockType::test(const Block* zBlock)
@@ -212,6 +230,11 @@ bool BlockFilterBlockType::test(const Block* zBlock)
     return false;
 }
 
+void BlockFilterBlockType::addBlockTypeId(int blockTypeId)
+{
+    blockTypeIds.add(blockTypeId);
+}
+
 const Framework::Array<int>& BlockFilterBlockType::getBlockTypeIds() const
 {
     return blockTypeIds;
@@ -221,43 +244,42 @@ BlockFilterBlockTypeFactory::BlockFilterBlockTypeFactory()
     : SubTypeFactory()
 {}
 
-BlockFilterBlockType* BlockFilterBlockTypeFactory::fromJson(
+BlockFilterBlockType* BlockFilterBlockTypeFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
-    Framework::Array<int> blockTypeIds;
+    return new BlockFilterBlockType();
+}
+
+void BlockFilterBlockTypeFactory::fromJson(
+    BlockFilterBlockType* zResult, Framework::JSON::JSONObject* zJson) const
+{
     for (Framework::JSON::JSONValue* value :
         *zJson->zValue("typeNames")->asArray())
     {
-        blockTypeIds.add(
+        zResult->addBlockTypeId(
             Game::INSTANCE->getBlockTypeId(value->asString()->getString()));
     }
-    return new BlockFilterBlockType(blockTypeIds);
 }
 
-Framework::JSON::JSONObject* BlockFilterBlockTypeFactory::toJson(
-    BlockFilterBlockType* zObject) const
+void BlockFilterBlockTypeFactory::toJson(
+    BlockFilterBlockType* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
     Framework::JSON::JSONArray* typeNames = new Framework::JSON::JSONArray();
     for (int typeId : zObject->getBlockTypeIds())
     {
         typeNames->addValue(new Framework::JSON::JSONString(
             Game::INSTANCE->zBlockType(typeId)->getName()));
     }
-    result->addValue("typeNames", typeNames);
-    return result;
+    zResult->addValue("typeNames", typeNames);
 }
 
-Framework::JSON::Validator::JSONValidator*
-BlockFilterBlockTypeFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
+JSONObjectValidationBuilder* BlockFilterBlockTypeFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
     return builder->withRequiredArray("typeNames")
         ->addAcceptedStringInArray()
         ->finishString()
-        ->finishArray()
-        ->finishObject();
+        ->finishArray();
 }
 
 Framework::Text BlockFilterBlockTypeFactory::getTypeToken() const
@@ -265,10 +287,8 @@ Framework::Text BlockFilterBlockTypeFactory::getTypeToken() const
     return "types";
 }
 
-BlockFilterTypeGroup::BlockFilterTypeGroup(
-    Framework::RCArray<Framework::Text> groupNames)
-    : BlockFilter(),
-      groupNames(groupNames)
+BlockFilterTypeGroup::BlockFilterTypeGroup()
+    : BlockFilter()
 {}
 
 bool BlockFilterTypeGroup::test(const Block* zBlock)
@@ -287,6 +307,11 @@ bool BlockFilterTypeGroup::test(const Block* zBlock)
     return false;
 }
 
+void BlockFilterTypeGroup::addGroupName(const Framework::Text groupName)
+{
+    groupNames.add(new Framework::Text(groupName));
+}
+
 const Framework::RCArray<Framework::Text>&
 BlockFilterTypeGroup::getGroupNames() const
 {
@@ -297,41 +322,40 @@ BlockFilterTypeGroupFactory::BlockFilterTypeGroupFactory()
     : SubTypeFactory()
 {}
 
-BlockFilterTypeGroup* BlockFilterTypeGroupFactory::fromJson(
+BlockFilterTypeGroup* BlockFilterTypeGroupFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
-    Framework::RCArray<Framework::Text> groupNames;
+    return new BlockFilterTypeGroup();
+}
+
+void BlockFilterTypeGroupFactory::fromJson(
+    BlockFilterTypeGroup* zResult, Framework::JSON::JSONObject* zJson) const
+{
     for (Framework::JSON::JSONValue* value :
         *zJson->zValue("groupNames")->asArray())
     {
-        groupNames.add(new Framework::Text(value->asString()->getString()));
+        zResult->addGroupName(value->asString()->getString());
     }
-    return new BlockFilterTypeGroup(groupNames);
 }
 
-Framework::JSON::JSONObject* BlockFilterTypeGroupFactory::toJson(
-    BlockFilterTypeGroup* zObject) const
+void BlockFilterTypeGroupFactory::toJson(
+    BlockFilterTypeGroup* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
     Framework::JSON::JSONArray* groupNames = new Framework::JSON::JSONArray();
     for (Framework::Text* groupName : zObject->getGroupNames())
     {
         groupNames->addValue(new Framework::JSON::JSONString(*groupName));
     }
-    result->addValue("groupNames", groupNames);
-    return result;
+    zResult->addValue("groupNames", groupNames);
 }
 
-Framework::JSON::Validator::JSONValidator*
-BlockFilterTypeGroupFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
+JSONObjectValidationBuilder* BlockFilterTypeGroupFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
     return builder->withRequiredArray("groupNames")
         ->addAcceptedStringInArray()
         ->finishString()
-        ->finishArray()
-        ->finishObject();
+        ->finishArray();
 }
 
 Framework::Text BlockFilterTypeGroupFactory::getTypeToken() const
@@ -339,9 +363,8 @@ Framework::Text BlockFilterTypeGroupFactory::getTypeToken() const
     return "groups";
 }
 
-BlockFilterMaxHardness::BlockFilterMaxHardness(float maxHardness)
-    : BlockFilter(),
-      maxHardness(maxHardness)
+BlockFilterMaxHardness::BlockFilterMaxHardness()
+    : BlockFilter()
 {}
 
 bool BlockFilterMaxHardness::test(const Block* zBlock)
@@ -349,6 +372,11 @@ bool BlockFilterMaxHardness::test(const Block* zBlock)
     return zBlock->zBlockType()->getHardness() <= maxHardness;
 }
 
+void BlockFilterMaxHardness::setMaxHardness(float maxHardness)
+{
+    this->maxHardness = maxHardness;
+}
+
 float BlockFilterMaxHardness::getMaxHardness() const
 {
     return maxHardness;
@@ -358,31 +386,32 @@ BlockFilterMaxHardnessFactory::BlockFilterMaxHardnessFactory()
     : SubTypeFactory()
 {}
 
-BlockFilterMaxHardness* BlockFilterMaxHardnessFactory::fromJson(
+BlockFilterMaxHardness* BlockFilterMaxHardnessFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
-    return new BlockFilterMaxHardness(
+    return new BlockFilterMaxHardness();
+}
+
+void BlockFilterMaxHardnessFactory::fromJson(
+    BlockFilterMaxHardness* zResult, Framework::JSON::JSONObject* zJson) const
+{
+    zResult->setMaxHardness(
         (float)zJson->zValue("maxHardness")->asNumber()->getNumber());
 }
 
-Framework::JSON::JSONObject* BlockFilterMaxHardnessFactory::toJson(
-    BlockFilterMaxHardness* zObject) const
+void BlockFilterMaxHardnessFactory::toJson(
+    BlockFilterMaxHardness* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue("maxHardness",
+    zResult->addValue("maxHardness",
         new Framework::JSON::JSONNumber(zObject->getMaxHardness()));
-    return result;
 }
 
-Framework::JSON::Validator::JSONValidator*
-BlockFilterMaxHardnessFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
+JSONObjectValidationBuilder* BlockFilterMaxHardnessFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
     return builder->withRequiredNumber("maxHardness")
         ->whichIsGreaterOrEqual(0.0)
-        ->finishNumber()
-        ->finishObject();
+        ->finishNumber();
 }
 
 Framework::Text BlockFilterMaxHardnessFactory::getTypeToken() const
@@ -390,9 +419,9 @@ Framework::Text BlockFilterMaxHardnessFactory::getTypeToken() const
     return "maxHardness";
 }
 
-BlockFilterMinHardness::BlockFilterMinHardness(float minHardness)
+BlockFilterMinHardness::BlockFilterMinHardness()
     : BlockFilter(),
-      minHardness(minHardness)
+      minHardness(0.f)
 {}
 
 bool BlockFilterMinHardness::test(const Block* zBlock)
@@ -400,6 +429,11 @@ bool BlockFilterMinHardness::test(const Block* zBlock)
     return zBlock->zBlockType()->getHardness() >= minHardness;
 }
 
+void BlockFilterMinHardness::setMinHardness(float minHardness)
+{
+    this->minHardness = minHardness;
+}
+
 float BlockFilterMinHardness::getMinHardness() const
 {
     return minHardness;
@@ -409,31 +443,32 @@ BlockFilterMinHardnessFactory::BlockFilterMinHardnessFactory()
     : SubTypeFactory()
 {}
 
-BlockFilterMinHardness* BlockFilterMinHardnessFactory::fromJson(
+BlockFilterMinHardness* BlockFilterMinHardnessFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
-    return new BlockFilterMinHardness(
+    return new BlockFilterMinHardness();
+}
+
+void BlockFilterMinHardnessFactory::fromJson(
+    BlockFilterMinHardness* zResult, Framework::JSON::JSONObject* zJson) const
+{
+    zResult->setMinHardness(
         (float)zJson->zValue("minHardness")->asNumber()->getNumber());
 }
 
-Framework::JSON::JSONObject* BlockFilterMinHardnessFactory::toJson(
-    BlockFilterMinHardness* zObject) const
+void BlockFilterMinHardnessFactory::toJson(
+    BlockFilterMinHardness* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue("minHardness",
+    zResult->addValue("minHardness",
         new Framework::JSON::JSONNumber(zObject->getMinHardness()));
-    return result;
 }
 
-Framework::JSON::Validator::JSONValidator*
-BlockFilterMinHardnessFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
+JSONObjectValidationBuilder* BlockFilterMinHardnessFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
     return builder->withRequiredNumber("minHardness")
         ->whichIsGreaterOrEqual(0.0)
-        ->finishNumber()
-        ->finishObject();
+        ->finishNumber();
 }
 
 Framework::Text BlockFilterMinHardnessFactory::getTypeToken() const
@@ -441,9 +476,9 @@ Framework::Text BlockFilterMinHardnessFactory::getTypeToken() const
     return "minHardness";
 }
 
-BlockFilterMaxHeat::BlockFilterMaxHeat(float maxHeat)
+BlockFilterMaxHeat::BlockFilterMaxHeat()
     : BlockFilter(),
-      maxHeat(maxHeat)
+      maxHeat(0.f)
 {}
 
 bool BlockFilterMaxHeat::test(const Block* zBlock)
@@ -453,6 +488,11 @@ bool BlockFilterMaxHeat::test(const Block* zBlock)
     return type && type->getHeat() <= maxHeat;
 }
 
+void BlockFilterMaxHeat::setMaxHeat(float maxHeat)
+{
+    this->maxHeat = maxHeat;
+}
+
 float BlockFilterMaxHeat::getMaxHeat() const
 {
     return maxHeat;
@@ -462,28 +502,29 @@ BlockFilterMaxHeatFactory::BlockFilterMaxHeatFactory()
     : SubTypeFactory()
 {}
 
-BlockFilterMaxHeat* BlockFilterMaxHeatFactory::fromJson(
+BlockFilterMaxHeat* BlockFilterMaxHeatFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
-    return new BlockFilterMaxHeat(
-        (float)zJson->zValue("heat")->asNumber()->getNumber());
+    return new BlockFilterMaxHeat();
+}
+
+void BlockFilterMaxHeatFactory::fromJson(
+    BlockFilterMaxHeat* zResult, Framework::JSON::JSONObject* zJson) const
+{
+    zResult->setMaxHeat((float)zJson->zValue("heat")->asNumber()->getNumber());
 }
 
-Framework::JSON::JSONObject* BlockFilterMaxHeatFactory::toJson(
-    BlockFilterMaxHeat* zObject) const
+void BlockFilterMaxHeatFactory::toJson(
+    BlockFilterMaxHeat* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue(
+    zResult->addValue(
         "heat", new Framework::JSON::JSONNumber(zObject->getMaxHeat()));
-    return result;
 }
 
-Framework::JSON::Validator::JSONValidator*
-BlockFilterMaxHeatFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
+JSONObjectValidationBuilder* BlockFilterMaxHeatFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
-    return builder->withRequiredNumber("heat")->finishNumber()->finishObject();
+    return builder->withRequiredNumber("heat")->finishNumber();
 }
 
 Framework::Text BlockFilterMaxHeatFactory::getTypeToken() const

+ 76 - 53
FactoryCraft/BlockFilter.h

@@ -19,8 +19,9 @@ private:
     Framework::RCArray<BlockFilter> filters;
 
 public:
-    BlockFilterAnd(Framework::RCArray<BlockFilter> filters);
+    BlockFilterAnd();
     bool test(const Block* zBlock) override;
+    void addFilter(BlockFilter* filter);
     Framework::RCArray<BlockFilter> getFilters() const;
 };
 
@@ -28,11 +29,14 @@ class BlockFilterAndFactory : public SubTypeFactory<BlockFilter, BlockFilterAnd>
 {
 public:
     BlockFilterAndFactory();
-    BlockFilterAnd* fromJson(Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(BlockFilterAnd* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    BlockFilterAnd* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(BlockFilterAnd* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(BlockFilterAnd* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };
 
@@ -42,8 +46,9 @@ private:
     Framework::RCArray<BlockFilter> filters;
 
 public:
-    BlockFilterOr(Framework::RCArray<BlockFilter> filters);
+    BlockFilterOr();
     bool test(const Block* zBlock) override;
+    void addFilter(BlockFilter* filter);
     Framework::RCArray<BlockFilter> getFilters() const;
 };
 
@@ -51,11 +56,14 @@ class BlockFilterOrFactory : public SubTypeFactory<BlockFilter, BlockFilterOr>
 {
 public:
     BlockFilterOrFactory();
-    BlockFilterOr* fromJson(Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(BlockFilterOr* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    BlockFilterOr* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(BlockFilterOr* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(BlockFilterOr* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };
 
@@ -65,8 +73,10 @@ private:
     BlockFilter* filter;
 
 public:
-    BlockFilterNot(BlockFilter* filter);
+    BlockFilterNot();
+    ~BlockFilterNot();
     bool test(const Block* zBlock) override;
+    void setFilter(BlockFilter* filter);
     BlockFilter* zFilter() const;
 };
 
@@ -74,11 +84,14 @@ class BlockFilterNotFactory : public SubTypeFactory<BlockFilter, BlockFilterNot>
 {
 public:
     BlockFilterNotFactory();
-    BlockFilterNot* fromJson(Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(BlockFilterNot* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    BlockFilterNot* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(BlockFilterNot* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(BlockFilterNot* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };
 
@@ -88,8 +101,9 @@ private:
     Framework::Array<int> blockTypeIds;
 
 public:
-    BlockFilterBlockType(Framework::Array<int> blockTypeIds);
+    BlockFilterBlockType();
     bool test(const Block* zBlock) override;
+    void addBlockTypeId(int blockTypeId);
     const Framework::Array<int>& getBlockTypeIds() const;
 };
 
@@ -98,13 +112,14 @@ class BlockFilterBlockTypeFactory
 {
 public:
     BlockFilterBlockTypeFactory();
-    BlockFilterBlockType* fromJson(
+    BlockFilterBlockType* createValue(
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(
-        BlockFilterBlockType* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    void fromJson(BlockFilterBlockType* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(BlockFilterBlockType* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };
 
@@ -114,8 +129,9 @@ private:
     Framework::RCArray<Framework::Text> groupNames;
 
 public:
-    BlockFilterTypeGroup(Framework::RCArray<Framework::Text> groupNames);
+    BlockFilterTypeGroup();
     bool test(const Block* zBlock) override;
+    void addGroupName(const Framework::Text groupName);
     const Framework::RCArray<Framework::Text>& getGroupNames() const;
 };
 
@@ -124,13 +140,14 @@ class BlockFilterTypeGroupFactory
 {
 public:
     BlockFilterTypeGroupFactory();
-    BlockFilterTypeGroup* fromJson(
+    BlockFilterTypeGroup* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(BlockFilterTypeGroup* zResult,
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(
-        BlockFilterTypeGroup* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    void toJson(BlockFilterTypeGroup* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };
 
@@ -140,8 +157,9 @@ private:
     float maxHardness;
 
 public:
-    BlockFilterMaxHardness(float maxHardness);
+    BlockFilterMaxHardness();
     bool test(const Block* zBlock) override;
+    void setMaxHardness(float maxHardness);
     float getMaxHardness() const;
 };
 
@@ -150,13 +168,14 @@ class BlockFilterMaxHardnessFactory
 {
 public:
     BlockFilterMaxHardnessFactory();
-    BlockFilterMaxHardness* fromJson(
+    BlockFilterMaxHardness* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(BlockFilterMaxHardness* zResult,
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(
-        BlockFilterMaxHardness* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    void toJson(BlockFilterMaxHardness* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };
 
@@ -166,8 +185,9 @@ private:
     float minHardness;
 
 public:
-    BlockFilterMinHardness(float minHardness);
+    BlockFilterMinHardness();
     bool test(const Block* zBlock) override;
+    void setMinHardness(float minHardness);
     float getMinHardness() const;
 };
 
@@ -176,13 +196,14 @@ class BlockFilterMinHardnessFactory
 {
 public:
     BlockFilterMinHardnessFactory();
-    BlockFilterMinHardness* fromJson(
+    BlockFilterMinHardness* createValue(
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(
-        BlockFilterMinHardness* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    void fromJson(BlockFilterMinHardness* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(BlockFilterMinHardness* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };
 
@@ -192,8 +213,9 @@ private:
     float maxHeat;
 
 public:
-    BlockFilterMaxHeat(float maxHeat);
+    BlockFilterMaxHeat();
     bool test(const Block* zBlock) override;
+    void setMaxHeat(float maxHeat);
     float getMaxHeat() const;
 };
 
@@ -202,12 +224,13 @@ class BlockFilterMaxHeatFactory
 {
 public:
     BlockFilterMaxHeatFactory();
-    BlockFilterMaxHeat* fromJson(
+    BlockFilterMaxHeat* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(BlockFilterMaxHeat* zResult,
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(
-        BlockFilterMaxHeat* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    void toJson(BlockFilterMaxHeat* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };

+ 8 - 3
FactoryCraft/BlockInfoCommand.cpp

@@ -1,5 +1,9 @@
 #include "BlockInfoCommand.h"
 
+#include "Block.h"
+#include "BlockType.h"
+#include "Chat.h"
+#include "Dimension.h"
 #include "Game.h"
 
 BlockInfoCommand::BlockInfoCommand()
@@ -25,8 +29,8 @@ void BlockInfoCommand::execute(
     int y = (int)*params.z(1);
     int z = (int)*params.z(2);
     int dimension = (int)*params.z(3);
-    Vec3<int> location = {x, y, z};
-    Text result = "";
+    Framework::Vec3<int> location = {x, y, z};
+    Framework::Text result = "";
     if (Game::INSTANCE->zDimension(dimension))
     {
         auto block = Game::INSTANCE->zBlockAt(location, dimension);
@@ -86,7 +90,8 @@ void BlockInfoCommand::execute(
         result += "\n";
         for (int i = 0; i < 6; i++)
         {
-            Vec3<int> pos = location + getDirection(getDirectionFromIndex(i));
+            Framework::Vec3<int> pos
+                = location + getDirection(getDirectionFromIndex(i));
             if (pos.z >= 0 && pos.z < WORLD_HEIGHT)
             {
                 switch (i)

+ 47 - 21
FactoryCraft/BlockInstanceGeneratorRule.cpp

@@ -2,13 +2,10 @@
 
 #include "Game.h"
 
-BlockInstanceGeneratorRule::BlockInstanceGeneratorRule(
-    Framework::JSON::JSONValue* zConfig, JExpressionMemory* zMemory)
-    : GeneratorRule(zConfig, zMemory)
-{
-    blockType = BlockType::getTypeId(
-        zConfig->asObject()->zValue("blockType")->asString()->getString());
-}
+BlockInstanceGeneratorRule::BlockInstanceGeneratorRule()
+    : GeneratorRule(),
+      blockType(0)
+{}
 
 Framework::Either<Block*, int> BlockInstanceGeneratorRule::createBlock(
     int x, int y, int z, int dimensionId)
@@ -17,18 +14,47 @@ Framework::Either<Block*, int> BlockInstanceGeneratorRule::createBlock(
         Framework::Vec3<int>(x, y, z), dimensionId, 0);
 }
 
+void BlockInstanceGeneratorRule::setBlockTypeId(int blockType)
+{
+    this->blockType = blockType;
+}
+
+int BlockInstanceGeneratorRule::getBlockTypeId() const
+{
+    return blockType;
+}
+
 BlockInstanceGeneratorRuleFactory::BlockInstanceGeneratorRuleFactory()
-    : ReferenceCounter()
+    : GeneratorRuleFactory()
 {}
 
-GeneratorRule* BlockInstanceGeneratorRuleFactory::createRule(
-    Framework::JSON::JSONValue* zConfig, JExpressionMemory* zMemory)
+BlockInstanceGeneratorRule* BlockInstanceGeneratorRuleFactory::createValue(
+    Framework::JSON::JSONObject* zJson) const
 {
-    return new BlockInstanceGeneratorRule(zConfig, zMemory);
+    return new BlockInstanceGeneratorRule();
 }
 
-Framework::JSON::Validator::JSONValidator*
-BlockInstanceGeneratorRuleFactory::getValidator()
+void BlockInstanceGeneratorRuleFactory::fromJson(
+    BlockInstanceGeneratorRule* zResult,
+    Framework::JSON::JSONObject* zJson) const
+{
+    zResult->setBlockTypeId(Game::INSTANCE->getBlockTypeId(
+        zJson->zValue("blockType")->asString()->getString()));
+    GeneratorRuleFactory::fromJson(zResult, zJson);
+}
+
+void BlockInstanceGeneratorRuleFactory::toJson(
+    BlockInstanceGeneratorRule* zObject,
+    Framework::JSON::JSONObject* zResult) const
+{
+    zResult->addValue("blockType",
+        new Framework::JSON::JSONString(
+            Game::INSTANCE->zBlockType(zObject->getBlockTypeId())->getName()));
+    GeneratorRuleFactory::toJson(zObject, zResult);
+}
+
+JSONObjectValidationBuilder* BlockInstanceGeneratorRuleFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
     Framework::RCArray<Framework::Text> blockTypeNames;
     for (int i = 0; i < Game::INSTANCE->getBlockTypeCount(); i++)
@@ -39,13 +65,13 @@ BlockInstanceGeneratorRuleFactory::getValidator()
                 new Framework::Text(Game::INSTANCE->zBlockType(i)->getName()));
         }
     }
-    return GeneratorRule::addToValidator(
-        Framework::JSON::Validator::JSONValidator::buildForObject()
-            ->withRequiredString("type")
-            ->withExactMatch("blockInstance")
-            ->finishString()
-            ->withRequiredString("blockType")
+    return GeneratorRuleFactory::addToValidator(
+        builder->withRequiredString("blockType")
             ->whichIsOneOf(blockTypeNames)
-            ->finishString())
-        ->finishObject();
+            ->finishString());
+}
+
+Framework::Text BlockInstanceGeneratorRuleFactory::getTypeToken() const
+{
+    return "blockInstance";
 }

+ 15 - 6
FactoryCraft/BlockInstanceGeneratorRule.h

@@ -7,17 +7,26 @@ private:
     int blockType;
 
 public:
-    BlockInstanceGeneratorRule(
-        Framework::JSON::JSONValue* zConfig, JExpressionMemory* zMemory);
+    BlockInstanceGeneratorRule();
     Framework::Either<Block*, int> createBlock(
         int x, int y, int z, int dimensionId) override;
+
+    void setBlockTypeId(int blockType);
+    int getBlockTypeId() const;
 };
 
-class BlockInstanceGeneratorRuleFactory : public GeneratorRuleFactory
+class BlockInstanceGeneratorRuleFactory
+    : public GeneratorRuleFactory<BlockInstanceGeneratorRule>
 {
 public:
     BlockInstanceGeneratorRuleFactory();
-    GeneratorRule* createRule(Framework::JSON::JSONValue* zConfig,
-        JExpressionMemory* zMemory) override;
-    Framework::JSON::Validator::JSONValidator* getValidator() override;
+    BlockInstanceGeneratorRule* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(BlockInstanceGeneratorRule* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(BlockInstanceGeneratorRule* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
+    Framework::Text getTypeToken() const override;
 };

+ 113 - 75
FactoryCraft/BlockType.cpp

@@ -5,35 +5,28 @@
 #include "Game.h"
 #include "ItemType.h"
 #include "MultiblockStructure.h"
+#include "Dimension.h"
 
 using namespace Framework;
 
-BlockType::BlockType(Block* defaultBlock,
-    ModelInfo* model,
-    bool needsClientInstance,
-    int initialMaxHP,
-    bool lightSource,
-    Framework::Text name,
-    bool needModelSubscription,
-    int initialMapColor,
-    Framework::RCArray<Framework::Text> groupNames,
-    float hardness)
+BlockType::BlockType()
     : ReferenceCounter(),
-      id(id),
-      model(model),
-      initialMaxHP(initialMaxHP),
-      needsClientInstance(needsClientInstance),
-      lightSource(lightSource),
-      name(name),
-      needModelSubscription(needModelSubscription),
-      initialMapColor(initialMapColor),
-      defaultBlock(defaultBlock),
-      groupNames(groupNames),
-      hardness(hardness)
+      id(0),
+      model(0),
+      initialMaxHP(0),
+      needsClientInstance(true),
+      lightSource(false),
+      name(),
+      needModelSubscription(false),
+      initialMapColor(0),
+      defaultBlock(0),
+      groupNames(),
+      hardness(1.f)
 {}
 
 BlockType::~BlockType()
 {
+    if (model) model->release();
     if (defaultBlock) defaultBlock->release();
 }
 
@@ -121,6 +114,40 @@ bool BlockType::initialize(Game* zGame)
     return true;
 }
 
+BlockType* BlockType::initializeDefault()
+{
+    if (!defaultBlock)
+    {
+        defaultBlock = createBlockAt({0, 0, 0}, 0, 0);
+    }
+    return this;
+}
+
+const Block* BlockType::zDefault() const
+{
+    return defaultBlock;
+}
+
+void BlockType::writeTypeInfo(StreamWriter* zWriter) const
+{
+    int id = getId();
+    zWriter->schreibe((char*)&id, 4);
+    bool inst = doesNeedClientInstance();
+    zWriter->schreibe((char*)&inst, 1);
+    bool sub = doesNeedModelSubscription();
+    zWriter->schreibe((char*)&sub, 1);
+    bool fluid = isFluid();
+    zWriter->schreibe((char*)&fluid, 1);
+    if (fluid)
+    {
+        char flowDist = getFlowDistance();
+        zWriter->schreibe(&flowDist, 1);
+    }
+    int maxHp = getInitialMaxHP();
+    zWriter->schreibe((char*)&maxHp, 4);
+    zModel()->writeTo(zWriter);
+}
+
 Framework::Text BlockType::getTargetUIML() const
 {
     return Text("<targetInfo><text width=\"auto\" height=\"auto\">") + name
@@ -159,39 +186,39 @@ Block* BlockType::createBlockAt(
     return result;
 }
 
-bool BlockType::doesNeedClientInstance() const
+int BlockType::getId() const
 {
-    return needsClientInstance;
+    return id;
 }
 
-ModelInfo* BlockType::zModel() const
+bool BlockType::isFluid() const
 {
-    return model;
+    return false;
 }
 
-int BlockType::getMapColor() const
+unsigned char BlockType::getFlowDistance() const
 {
-    return initialMapColor;
+    return 0;
 }
 
-const Framework::RCArray<Framework::Text>& BlockType::getGroupNames() const
+void BlockType::setTypeId(int id)
 {
-    return groupNames;
+    this->id = id;
 }
 
-float BlockType::getHardness() const
+void BlockType::setModel(ModelInfo* model)
 {
-    return hardness;
+    this->model = model;
 }
 
-int BlockType::getId() const
+ModelInfo* BlockType::zModel() const
 {
-    return id;
+    return model;
 }
 
-const Block* BlockType::zDefault() const
+void BlockType::setInitialMaxHP(int initialMaxHP)
 {
-    return defaultBlock;
+    this->initialMaxHP = initialMaxHP;
 }
 
 int BlockType::getInitialMaxHP() const
@@ -199,26 +226,29 @@ int BlockType::getInitialMaxHP() const
     return initialMaxHP;
 }
 
-bool BlockType::isLightSource() const
+void BlockType::setNeedsClientInstance(bool needsClientInstance)
 {
-    return lightSource;
+    this->needsClientInstance = needsClientInstance;
 }
 
-const Block* getDefaultBlock(Either<Block*, int> b)
+bool BlockType::doesNeedClientInstance() const
 {
-    if (b.isA())
-        return b;
-    else
-        return Game::INSTANCE->zBlockType(b)->zDefault();
+    return needsClientInstance;
 }
 
-BlockType* BlockType::initializeDefault()
+void BlockType::setLightSource(bool lightSource)
 {
-    if (!defaultBlock)
-    {
-        defaultBlock = createBlockAt({0, 0, 0}, 0, 0);
-    }
-    return this;
+    this->lightSource = lightSource;
+}
+
+bool BlockType::isLightSource() const
+{
+    return lightSource;
+}
+
+void BlockType::setName(Framework::Text name)
+{
+    this->name = name;
 }
 
 const char* BlockType::getName() const
@@ -226,34 +256,44 @@ const char* BlockType::getName() const
     return name;
 }
 
+void BlockType::setNeedModelSubscription(bool needModelSubscription)
+{
+    this->needModelSubscription = needModelSubscription;
+}
+
 const bool BlockType::doesNeedModelSubscription() const
 {
     return needModelSubscription;
 }
 
-void BlockType::writeTypeInfo(StreamWriter* zWriter) const
+void BlockType::setMapColor(int mapColor)
 {
-    int id = getId();
-    zWriter->schreibe((char*)&id, 4);
-    bool inst = doesNeedClientInstance();
-    zWriter->schreibe((char*)&inst, 1);
-    bool sub = doesNeedModelSubscription();
-    zWriter->schreibe((char*)&sub, 1);
-    bool fluid = isFluid();
-    zWriter->schreibe((char*)&fluid, 1);
-    if (fluid)
-    {
-        char flowDist = getFlowDistance();
-        zWriter->schreibe(&flowDist, 1);
-    }
-    int maxHp = getInitialMaxHP();
-    zWriter->schreibe((char*)&maxHp, 4);
-    zModel()->writeTo(zWriter);
+    this->initialMapColor = mapColor;
 }
 
-bool BlockType::isFluid() const
+int BlockType::getMapColor() const
 {
-    return false;
+    return initialMapColor;
+}
+
+void BlockType::setGroupNames(Framework::RCArray<Framework::Text> groupNames)
+{
+    this->groupNames = groupNames;
+}
+
+const Framework::RCArray<Framework::Text>& BlockType::getGroupNames() const
+{
+    return groupNames;
+}
+
+void BlockType::setHardness(float hardness)
+{
+    this->hardness = hardness;
+}
+
+float BlockType::getHardness() const
+{
+    return hardness;
 }
 
 int BlockType::getTypeId(const char* name)
@@ -279,12 +319,10 @@ Framework::Text BlockType::getTypeName(int id)
     return 0;
 }
 
-unsigned char BlockType::getFlowDistance() const
-{
-    return 0;
-}
-
-void BlockType::setTypeId(int id)
+const Block* getDefaultBlock(Either<Block*, int> b)
 {
-    this->id = id;
-}
+    if (b.isA())
+        return b;
+    else
+        return Game::INSTANCE->zBlockType(b)->zDefault();
+}

+ 125 - 22
FactoryCraft/BlockType.h

@@ -25,26 +25,17 @@ private:
     int id;
     ModelInfo* model;
     int initialMaxHP;
-    const bool needsClientInstance;
+    bool needsClientInstance;
     bool lightSource;
     Framework::Text name;
-    const bool needModelSubscription;
+    bool needModelSubscription;
     int initialMapColor;
     Block* defaultBlock;
     Framework::RCArray<Framework::Text> groupNames;
     float hardness;
 
 protected:
-    BlockType(Block* defaultBlock,
-        ModelInfo* model,
-        bool needsClientInstance,
-        int initialMaxHP,
-        bool lightSource,
-        Framework::Text name,
-        bool needModelSubscription,
-        int initialMapColor,
-        Framework::RCArray<Framework::Text> groupNames,
-        float hardness);
+    BlockType();
     virtual ~BlockType();
 
     virtual void loadSuperBlock(
@@ -60,6 +51,12 @@ protected:
 
 public:
     virtual bool initialize(Game* zGame);
+    BlockType* initializeDefault();
+    virtual const Block* zDefault() const;
+
+    virtual ItemType* createItemType() const = 0;
+
+    void writeTypeInfo(Framework::StreamWriter* zWriter) const;
     virtual Framework::Text getTargetUIML() const;
     virtual Block* loadBlock(Framework::Vec3<int> position,
         Framework::StreamReader* zReader,
@@ -69,26 +66,132 @@ public:
     virtual Item* getItemFromBlock(Block* zBlock) const;
     virtual Block* createBlockAt(
         Framework::Vec3<int> position, int dimensionId, Item* zUsedItem) const;
-    virtual const Block* zDefault() const;
-    bool doesNeedClientInstance() const;
+
     int getId() const;
-    int getInitialMaxHP() const;
-    bool isLightSource() const;
-    BlockType* initializeDefault();
-    const char* getName() const;
-    const bool doesNeedModelSubscription() const;
-    void writeTypeInfo(Framework::StreamWriter* zWriter) const;
     virtual bool isFluid() const;
     virtual unsigned char getFlowDistance() const;
     void setTypeId(int id);
+    void setModel(ModelInfo* model);
     ModelInfo* zModel() const;
+    void setInitialMaxHP(int initialMaxHP);
+    int getInitialMaxHP() const;
+    void setNeedsClientInstance(bool needsClientInstance);
+    bool doesNeedClientInstance() const;
+    void setLightSource(bool lightSource);
+    bool isLightSource() const;
+    void setName(Framework::Text name);
+    const char* getName() const;
+    void setNeedModelSubscription(bool needModelSubscription);
+    const bool doesNeedModelSubscription() const;
+    void setMapColor(int mapColor);
     int getMapColor() const;
-    virtual ItemType* createItemType() const = 0;
+    void setGroupNames(Framework::RCArray<Framework::Text> groupNames);
     const Framework::RCArray<Framework::Text>& getGroupNames() const;
+    void setHardness(float hardness);
     float getHardness() const;
 
     static int getTypeId(const char* name);
     static Framework::Text getTypeName(int id);
 };
 
-const Block* getDefaultBlock(Framework::Either<Block*, int> b);
+const Block* getDefaultBlock(Framework::Either<Block*, int> b);
+
+template<typename S> class BlockTypeFactoryBase
+    : public SubTypeFactory<BlockType, S>
+{
+public:
+    BlockTypeFactoryBase()
+        : SubTypeFactory<BlockType, S>()
+    {}
+
+    virtual void fromJson(
+        S* zResult, Framework::JSON::JSONObject* zJson) const override
+    {
+        BlockType* zType = dynamic_cast<BlockType*>(zResult);
+        zType->setModel(Game::INSTANCE->zTypeRegistry()->fromJson<ModelInfo>(
+            zJson->zValue("model")->asObject()));
+        zType->setInitialMaxHP(
+            (int)zJson->zValue("maxHp")->asNumber()->getNumber());
+        zType->setNeedsClientInstance(
+            zJson->zValue("needsClientInstance")->asBool()->getBool());
+        zType->setLightSource(
+            zJson->zValue("lightSource")->asNumber()->getNumber());
+        zType->setName(zJson->zValue("name")->asString()->getString());
+        zType->setNeedModelSubscription(
+            zJson->zValue("needModelSubscription")->asBool()->getBool());
+        zType->setMapColor(
+            (int)zJson->zValue("mapColor")->asString()->getString());
+        Framework::RCArray<Framework::Text> groupNames;
+        for (Framework::JSON::JSONValue* value :
+            *zJson->zValue("groupNames")->asArray())
+        {
+            groupNames.add(new Framework::Text(value->asString()->getString()));
+        }
+        zType->setGroupNames(groupNames);
+        zType->setHardness(
+            (float)zJson->zValue("hardness")->asNumber()->getNumber());
+    }
+
+    virtual void toJson(
+        S* zObject, Framework::JSON::JSONObject* zResult) const override
+    {
+        BlockType* zType = dynamic_cast<BlockType*>(zResult);
+        zResult->addValue("model",
+            Game::INSTANCE->zTypeRegistry()->toJson<ModelInfo>(
+                zType->zModel()));
+        zResult->addValue("maxHp",
+            new Framework::JSON::JSONNumber((double)zType->getInitialMaxHP()));
+        zResult->addValue("needsClientInstance",
+            new Framework::JSON::JSONBool(zType->doesNeedClientInstance()));
+        zResult->addValue("lightSource",
+            new Framework::JSON::JSONBool(zType->isLightSource()));
+        zResult->addValue(
+            "name", new Framework::JSON::JSONString(zType->getName()));
+        zResult->addValue("needModelSubscription",
+            new Framework::JSON::JSONBool(zType->doesNeedModelSubscription()));
+        zResult->addValue("mapColor",
+            new Framework::JSON::JSONString(
+                Framework::Text(zType->getMapColor())));
+        Framework::JSON::JSONArray* groupNames
+            = new Framework::JSON::JSONArray();
+        for (Framework::Text* groupName : zType->getGroupNames())
+        {
+            groupNames->addValue(new Framework::JSON::JSONString(*groupName));
+        }
+        zResult->addValue("groupNames", groupNames);
+        zResult->addValue(
+            "hardness", new Framework::JSON::JSONNumber(zType->getHardness()));
+    }
+
+    virtual JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override
+    {
+        return builder
+            ->withRequiredAttribute("model",
+                Game::INSTANCE->zTypeRegistry()->getValidator<ModelInfo>())
+            ->withRequiredNumber("maxHp")
+            ->withDefault(100.0)
+            ->finishNumber()
+            ->withRequiredBool("needsClientInstance")
+            ->withDefault(true)
+            ->finishBool()
+            ->withRequiredBool("lightSource")
+            ->withDefault(false)
+            ->finishBool()
+            ->withRequiredString("name")
+            ->finishString()
+            ->withRequiredBool("needModelSubscription")
+            ->withDefault(true)
+            ->finishBool()
+            ->withRequiredString("mapColor")
+            ->finishString()
+            ->withRequiredArray("groupNames")
+            ->withDefault(new Framework::JSON::JSONArray())
+            ->addAcceptedStringInArray()
+            ->finishString()
+            ->finishArray()
+            ->withRequiredNumber("hardness")
+            ->withDefault(1.0)
+            ->finishNumber();
+    }
+};

+ 45 - 21
FactoryCraft/BlockTypeGeneratorRule.cpp

@@ -2,13 +2,10 @@
 
 #include "Game.h"
 
-BlockTypeGeneratorRule::BlockTypeGeneratorRule(
-    Framework::JSON::JSONValue* zConfig, JExpressionMemory* zMemory)
-    : GeneratorRule(zConfig, zMemory)
-{
-    blockType = BlockType::getTypeId(
-        zConfig->asObject()->zValue("blockType")->asString()->getString());
-}
+BlockTypeGeneratorRule::BlockTypeGeneratorRule()
+    : GeneratorRule(),
+      blockType(0)
+{}
 
 Framework::Either<Block*, int> BlockTypeGeneratorRule::createBlock(
     int x, int y, int z, int dimensionId)
@@ -16,18 +13,45 @@ Framework::Either<Block*, int> BlockTypeGeneratorRule::createBlock(
     return blockType;
 }
 
+void BlockTypeGeneratorRule::setBlockTypeId(int blockType)
+{
+    this->blockType = blockType;
+}
+
+int BlockTypeGeneratorRule::getBlockTypeId() const
+{
+    return blockType;
+}
+
 BlockTypeGeneratorRuleFactory::BlockTypeGeneratorRuleFactory()
-    : ReferenceCounter()
+    : GeneratorRuleFactory()
 {}
 
-GeneratorRule* BlockTypeGeneratorRuleFactory::createRule(
-    Framework::JSON::JSONValue* zConfig, JExpressionMemory* zMemory)
+BlockTypeGeneratorRule* BlockTypeGeneratorRuleFactory::createValue(
+    Framework::JSON::JSONObject* zJson) const
 {
-    return new BlockTypeGeneratorRule(zConfig, zMemory);
+    return new BlockTypeGeneratorRule();
 }
 
-Framework::JSON::Validator::JSONValidator*
-BlockTypeGeneratorRuleFactory::getValidator()
+void BlockTypeGeneratorRuleFactory::fromJson(
+    BlockTypeGeneratorRule* zResult, Framework::JSON::JSONObject* zJson) const
+{
+    zResult->setBlockTypeId(Game::INSTANCE->getBlockTypeId(
+        zJson->zValue("blockType")->asString()->getString()));
+    GeneratorRuleFactory::fromJson(zResult, zJson);
+}
+
+void BlockTypeGeneratorRuleFactory::toJson(
+    BlockTypeGeneratorRule* zObject, Framework::JSON::JSONObject* zResult) const
+{
+    zResult->addValue("blockType",
+        new Framework::JSON::JSONString(
+            Game::INSTANCE->zBlockType(zObject->getBlockTypeId())->getName()));
+    GeneratorRuleFactory::toJson(zObject, zResult);
+}
+
+JSONObjectValidationBuilder* BlockTypeGeneratorRuleFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
     Framework::RCArray<Framework::Text> blockTypeNames;
     for (int i = 0; i < Game::INSTANCE->getBlockTypeCount(); i++)
@@ -38,13 +62,13 @@ BlockTypeGeneratorRuleFactory::getValidator()
                 new Framework::Text(Game::INSTANCE->zBlockType(i)->getName()));
         }
     }
-    return GeneratorRule::addToValidator(
-        Framework::JSON::Validator::JSONValidator::buildForObject()
-            ->withRequiredString("type")
-            ->withExactMatch("blockType")
-            ->finishString()
-            ->withRequiredString("blockType")
+    return GeneratorRuleFactory::addToValidator(
+        builder->withRequiredString("blockType")
             ->whichIsOneOf(blockTypeNames)
-            ->finishString())
-        ->finishObject();
+            ->finishString());
+}
+
+Framework::Text BlockTypeGeneratorRuleFactory::getTypeToken() const
+{
+    return "blockType";
 }

+ 14 - 6
FactoryCraft/BlockTypeGeneratorRule.h

@@ -8,17 +8,25 @@ private:
     int blockType;
 
 public:
-    BlockTypeGeneratorRule(
-        Framework::JSON::JSONValue* zConfig, JExpressionMemory* zMemory);
+    BlockTypeGeneratorRule();
     Framework::Either<Block*, int> createBlock(
         int x, int y, int z, int dimensionId) override;
+    void setBlockTypeId(int blockType);
+    int getBlockTypeId() const;
 };
 
-class BlockTypeGeneratorRuleFactory : public GeneratorRuleFactory
+class BlockTypeGeneratorRuleFactory
+    : public GeneratorRuleFactory<BlockTypeGeneratorRule>
 {
 public:
     BlockTypeGeneratorRuleFactory();
-    GeneratorRule* createRule(
-	    Framework::JSON::JSONValue* zConfig, JExpressionMemory* zMemory) override;
-    Framework::JSON::Validator::JSONValidator* getValidator() override;
+    BlockTypeGeneratorRule* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(BlockTypeGeneratorRule* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(BlockTypeGeneratorRule* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
+    Framework::Text getTypeToken() const override;
 };

+ 4 - 2
FactoryCraft/Chat.cpp

@@ -3,6 +3,7 @@
 #include <Datei.h>
 
 #include "Game.h"
+#include "Player.h"
 
 const Framework::Text Chat::CHANNEL_INFO = "system:INFO";
 const Framework::Text Chat::CHANNEL_WARNING = "system:WARNING";
@@ -15,7 +16,8 @@ Chat::Chat()
     Framework::Datei messageData;
     messageData.setDatei(
         Game::INSTANCE->getWorldDirectory() + "/chat/history.chat");
-    if (messageData.existiert() && messageData.open(Datei::Style::lesen))
+    if (messageData.existiert()
+        && messageData.open(Framework::Datei::Style::lesen))
     {
         std::cout << "loading chat history from "
                   << messageData.zPfad()->getText() << std::endl
@@ -257,7 +259,7 @@ void Chat::save()
     messageData.setDatei(
         Game::INSTANCE->getWorldDirectory() + "/chat/history.chat");
     if (!messageData.existiert()) messageData.erstellen();
-    messageData.open(Datei::Style::schreiben);
+    messageData.open(Framework::Datei::Style::schreiben);
     for (ChatMessage* msg : history)
     {
         msg->writeTo(&messageData);

+ 2 - 2
FactoryCraft/ChatCommand.cpp

@@ -122,10 +122,10 @@ IntegerParameter::IntegerParameter(Framework::Text name,
 
 bool IntegerParameter::isLegalValue(Framework::Text value) const
 {
-    return Text((int)value).istGleich(value);
+    return Framework::Text((int)value).istGleich(value);
 }
 
 Framework::Text IntegerParameter::getDefaultValue(Entity* zActor) const
 {
-    return Text(calculateDefault(zActor));
+    return Framework::Text(calculateDefault(zActor));
 }

+ 2 - 1
FactoryCraft/ChatCommandExecutor.cpp

@@ -1,9 +1,10 @@
 #include "ChatCommandExecutor.h"
 
+#include "BlockInfoCommand.h"
+#include "Chat.h"
 #include "Game.h"
 #include "GrantCommand.h"
 #include "SaveCommand.h"
-#include "BlockInfoCommand.h"
 
 ChatCommandExecutor::ChatCommandExecutor()
     : ReferenceCounter()

+ 7 - 5
FactoryCraft/ChatObserver.cpp

@@ -2,7 +2,9 @@
 
 #include <Datei.h>
 
+#include "Chat.h"
 #include "Game.h"
+#include "Player.h"
 
 ChatObserver::ChatObserver(int entityId)
     : ReferenceCounter(),
@@ -11,7 +13,7 @@ ChatObserver::ChatObserver(int entityId)
     Framework::Datei config;
     config.setDatei(Game::INSTANCE->getWorldDirectory() + "/chat/observer/"
                     + entityId + ".observer");
-    if (config.existiert() && config.open(Datei::Style::lesen))
+    if (config.existiert() && config.open(Framework::Datei::Style::lesen))
     {
         int count;
         config.lese((char*)&count, sizeof(int));
@@ -38,9 +40,9 @@ ChatObserver::ChatObserver(int entityId)
     }
     else
     {
-        channel.add(new Text(Chat::CHANNEL_INFO));
-        channel.add(new Text(Chat::CHANNEL_WARNING));
-        channel.add(new Text(Chat::CHANNEL_ERROR));
+        channel.add(new Framework::Text(Chat::CHANNEL_INFO));
+        channel.add(new Framework::Text(Chat::CHANNEL_WARNING));
+        channel.add(new Framework::Text(Chat::CHANNEL_ERROR));
     }
 }
 
@@ -112,7 +114,7 @@ void ChatObserver::save() const
     config.setDatei(Game::INSTANCE->getWorldDirectory() + "/chat/observer/"
                     + entityId + ".observer");
     config.erstellen();
-    if (config.open(Datei::Style::schreiben))
+    if (config.open(Framework::Datei::Style::schreiben))
     {
         writeTo(&config);
         config.close();

+ 38 - 87
FactoryCraft/Chest.cpp

@@ -2,7 +2,13 @@
 
 #include <TextFeld.h>
 
+#include "Chunk.h"
+#include "Dimension.h"
+#include "Entity.h"
 #include "Game.h"
+#include "ItemSlot.h"
+#include "UIController.h"
+#include "UIDialog.h"
 
 Chest::Chest(int typeId, Framework::Vec3<int> pos, int dimensionId)
     : BasicBlock(typeId, pos, dimensionId, 1),
@@ -23,7 +29,8 @@ void Chest::onDestroy()
     {
         if (!slot->isEmpty())
         {
-            Game::INSTANCE->spawnItem(location + Vec3<float>(0.5f, 0.5f, 0.5f),
+            Game::INSTANCE->spawnItem(
+                location + Framework::Vec3<float>(0.5f, 0.5f, 0.5f),
                 getDimensionId(),
                 slot->takeItemsOut(slot->getNumberOfItems(), NO_DIRECTION));
         }
@@ -43,15 +50,16 @@ void Chest::onDialogClosed(Framework::Text dialogId)
             Chunk::index(Dimension::chunkCoordinates(getPos())),
             1,
             1.0,
-            Vec3<float>(0.5f, 0.f, 0.45f),
-            Vec3<float>(0.0f, 0.f, 0.f)); // close the chest over one second
+            Framework::Vec3<float>(0.5f, 0.f, 0.45f),
+            Framework::Vec3<float>(
+                0.0f, 0.f, 0.f)); // close the chest over one second
         broadcastMessage(msg);
     }
 }
 
 Framework::Text Chest::getDialogId() const
 {
-    Text dialogId = "chest_inventory_";
+    Framework::Text dialogId = "chest_inventory_";
     dialogId.append() << getDimensionId() << "," << getPos().x << ","
                       << getPos().y << "," << getPos().z;
     return dialogId;
@@ -80,7 +88,7 @@ bool Chest::interact(Item* zItem, Entity* zActor)
     {
         userEntityId = zActor->getId();
         open = 1;
-        Text uiml = "";
+        Framework::Text uiml = "";
         uiml.append()
             << "<dialog id=\"" << getDialogId()
             << "\" title=\"Chest\" "
@@ -99,8 +107,9 @@ bool Chest::interact(Item* zItem, Entity* zActor)
             << "<text id=\"player_label\" width=\"100%\" height=\"auto\" "
                "style=\""
             << std::uppercase << std::hex
-            << (TextFeld::Style::Text | TextFeld::Style::Center) << std::dec
-            << std::nouppercase
+            << (Framework::TextFeld::Style::Text
+                   | Framework::TextFeld::Style::Center)
+            << std::dec << std::nouppercase
             << "\" margin-bottom=\"9\" "
                "align-bottom=\"player_inventory\">Player "
                "Inventory</text>"
@@ -123,8 +132,8 @@ bool Chest::interact(Item* zItem, Entity* zActor)
             Chunk::index(Dimension::chunkCoordinates(getPos())),
             1,
             1.0,
-            Vec3<float>(0.5f, 0.f, 0.45f),
-            Vec3<float>(
+            Framework::Vec3<float>(0.5f, 0.f, 0.45f),
+            Framework::Vec3<float>(
                 0.0f, (float)(PI / 2.0), 0.f)); // open the chest over 1 second
         broadcastMessage(msg);
     }
@@ -141,26 +150,14 @@ void Chest::sendModelInfo(NetworkMessage* zMessage)
             Chunk::index(Dimension::chunkCoordinates(getPos())),
             1,
             0.0,
-            Vec3<float>(0.5f, 0.f, 0.45f),
-            Vec3<float>(
+            Framework::Vec3<float>(0.5f, 0.f, 0.45f),
+            Framework::Vec3<float>(
                 0.0f, (float)(PI / 2.0), 0.f)); // open the chest instantly
     }
 }
 
-ChestBlockType::ChestBlockType(Framework::Text itemTypeName,
-    ModelInfo* model,
-    Framework::Text name,
-    int mapColor,
-    bool modelSubscription,
-    float hardness,
-    Framework::RCArray<Framework::Text> groupNames)
-    : BasicBlockType(itemTypeName,
-        model,
-        name,
-        mapColor,
-        modelSubscription,
-        hardness,
-        groupNames)
+ChestBlockType::ChestBlockType()
+    : BasicBlockType()
 {}
 
 Block* ChestBlockType::createBlock(
@@ -170,78 +167,32 @@ Block* ChestBlockType::createBlock(
 }
 
 ChestBlockTypeFactory::ChestBlockTypeFactory()
-    : SubTypeFactory()
+    : SubTypeFactory(),
+      super()
 {}
 
-ChestBlockType* ChestBlockTypeFactory::fromJson(
+ChestBlockType* ChestBlockTypeFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
-    Framework::RCArray<Framework::Text> groupNames;
-    for (Framework::JSON::JSONValue* value :
-        *zJson->zValue("groupNames")->asArray())
-    {
-        groupNames.add(new Framework::Text(value->asString()->getString()));
-    }
-    return new ChestBlockType(
-        zJson->zValue("itemType")->asString()->getString(),
-        Game::INSTANCE->zTypeRegistry()->fromJson<ModelInfo>(
-            zJson->zValue("model")),
-        zJson->zValue("name")->asString()->getString(),
-        (int)zJson->zValue("mapColor")->asString()->getString(),
-        zJson->zValue("modelSubscription")->asBool()->getBool(),
-        (float)zJson->zValue("hardness")->asNumber()->getNumber(),
-        groupNames);
+    return new ChestBlockType();
 }
 
-Framework::JSON::JSONObject* ChestBlockTypeFactory::toJson(
-    ChestBlockType* zObject) const
+void ChestBlockTypeFactory::fromJson(
+    ChestBlockType* zResult, Framework::JSON::JSONObject* zJson) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue("itemType",
-        new Framework::JSON::JSONString(zObject->getItemTypeName()));
-    result->addValue(
-        "model", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zModel()));
-    result->addValue(
-        "name", new Framework::JSON::JSONString(zObject->getName()));
-    result->addValue(
-        "mapColor", new Framework::JSON::JSONString(zObject->getMapColor()));
-    result->addValue("modelSubscription",
-        new Framework::JSON::JSONBool(zObject->doesNeedModelSubscription()));
-    result->addValue(
-        "hardness", new Framework::JSON::JSONNumber(zObject->getHardness()));
-    Framework::JSON::JSONArray* groupNames = new Framework::JSON::JSONArray();
-    for (Framework::Text* groupName : zObject->getGroupNames())
-    {
-        groupNames->addValue(new Framework::JSON::JSONString(*groupName));
-    }
-    result->addValue("groupNames", groupNames);
-    return result;
+    super.fromJson(zResult, zJson);
+}
+
+void ChestBlockTypeFactory::toJson(
+    ChestBlockType* zObject, Framework::JSON::JSONObject* zResult) const
+{
+    super.toJson(zObject, zResult);
 }
 
-Framework::JSON::Validator::JSONValidator* ChestBlockTypeFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
+JSONObjectValidationBuilder* ChestBlockTypeFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
-    return builder->withRequiredString("itemType")
-        ->finishString()
-        ->withRequiredAttribute(
-            "model", Game::INSTANCE->zTypeRegistry()->getValidator<ModelInfo>())
-        ->withRequiredString("name")
-        ->finishString()
-        ->withRequiredString("mapColor")
-        ->finishString()
-        ->withRequiredBool("modelSubscription")
-        ->withDefault(false)
-        ->finishBool()
-        ->withRequiredNumber("hardness")
-        ->withDefault(1.0)
-        ->finishNumber()
-        ->withRequiredArray("groupNames")
-        ->withDefault(new Framework::JSON::JSONArray())
-        ->addAcceptedStringInArray()
-        ->finishString()
-        ->finishArray()
-        ->finishObject();
+    return super.addToValidator(builder);
 }
 
 Framework::Text ChestBlockTypeFactory::getTypeToken() const

+ 11 - 12
FactoryCraft/Chest.h

@@ -25,25 +25,24 @@ public:
 class ChestBlockType : public BasicBlockType
 {
 public:
-    ChestBlockType(Framework::Text itemTypeName,
-        ModelInfo* model,
-        Framework::Text name,
-        int mapColor,
-        bool modelSubscription,
-        float hardness,
-        Framework::RCArray<Framework::Text> groupNames);
+    ChestBlockType();
     virtual Block* createBlock(
         Framework::Vec3<int> position, int dimensionId) const override;
 };
 
 class ChestBlockTypeFactory : public SubTypeFactory<BlockType, ChestBlockType>
 {
+    BasicBlockTypeFactory super;
+
 public:
     ChestBlockTypeFactory();
-    ChestBlockType* fromJson(Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(ChestBlockType* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    ChestBlockType* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(ChestBlockType* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(ChestBlockType* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };

+ 37 - 26
FactoryCraft/Chunk.cpp

@@ -4,9 +4,12 @@
 #include <InMemoryBuffer.h>
 
 #include "Constants.h"
+#include "Dimension.h"
+#include "Entity.h"
 #include "FluidBlock.h"
 #include "Game.h"
 #include "NoBlock.h"
+#include "WorldGenerator.h"
 
 Chunk::Chunk(Framework::Punkt location, int dimensionId)
     : ReferenceCounter(),
@@ -102,8 +105,9 @@ void Chunk::sendLightToClient(Framework::StreamWriter* zWriter)
                 bool needSend = 0;
                 for (int i = 0; i < 6; i++)
                 {
-                    Vec3<int> pos = Vec3<int>(x, y, z)
-                                  + getDirection(getDirectionFromIndex(i));
+                    Framework::Vec3<int> pos
+                        = Framework::Vec3<int>(x, y, z)
+                        + getDirection(getDirectionFromIndex(i));
                     if (pos.z >= 0 && pos.z < WORLD_HEIGHT)
                     {
                         if (pos.x >= 0 && pos.x < CHUNK_SIZE && pos.y >= 0
@@ -124,7 +128,7 @@ void Chunk::sendLightToClient(Framework::StreamWriter* zWriter)
                                 cs.lock();
                                 if (i < 4 && zNeighbours[i])
                                 {
-                                    Vec3<int> offset
+                                    Framework::Vec3<int> offset
                                         = getDirection(getDirectionFromIndex(i))
                                         * 16;
                                     int bi = ((pos.x - offset.x) * CHUNK_SIZE
@@ -216,13 +220,14 @@ bool Chunk::isVisible(int index) const
                 return 1;
             else
             {
-                Vec3<int> indexPos = {(index / WORLD_HEIGHT) / CHUNK_SIZE,
-                    (index / WORLD_HEIGHT) % CHUNK_SIZE,
-                    index % WORLD_HEIGHT};
+                Framework::Vec3<int> indexPos
+                    = {(index / WORLD_HEIGHT) / CHUNK_SIZE,
+                        (index / WORLD_HEIGHT) % CHUNK_SIZE,
+                        index % WORLD_HEIGHT};
                 for (int d = 0; d < 6; d++)
                 {
-                    Either<Block*, int> n = BlockTypeEnum::NO_BLOCK;
-                    Vec3<int> pos
+                    Framework::Either<Block*, int> n = BlockTypeEnum::NO_BLOCK;
+                    Framework::Vec3<int> pos
                         = getDirection((Directions)getDirectionFromIndex(d))
                         + indexPos;
                     if (pos.x >= 0 && pos.x < CHUNK_SIZE && pos.y >= 0
@@ -305,7 +310,7 @@ Framework::Either<Block*, int> Chunk::zBlockNeighbor(
 
 void Chunk::notifyObservers(NetworkMessage* msg)
 {
-    Array<int> remove;
+    Framework::Array<int> remove;
     int index = 0;
     for (InformationObserver* observer : observers)
     {
@@ -330,7 +335,7 @@ void Chunk::addObserver(Entity* zEntity, DoLaterHandler& laterHandler)
     int id = zEntity->getId();
     observers.add(new InformationObserver(id));
     laterHandler.addTodo([this, id]() {
-        InMemoryBuffer buffer;
+        Framework::InMemoryBuffer buffer;
         buffer.schreibe("\4", 1);
         buffer.schreibe((char*)&location.x, 4);
         buffer.schreibe((char*)&location.y, 4);
@@ -409,13 +414,14 @@ void Chunk::initializeLightning()
                 for (int y = 0; y < CHUNK_SIZE; y++)
                 {
                     int index = (x * CHUNK_SIZE + y) * WORLD_HEIGHT + z;
-                    unsigned char* light = getLightData(Vec3<int>(x, y, z));
+                    unsigned char* light
+                        = getLightData(Framework::Vec3<int>(x, y, z));
                     unsigned char newLight[6] = {0, 0, 0, 0, 0, 0};
                     for (int i = 0; i < 6; i++)
                     {
                         unsigned char* neighborLeight;
-                        Vec3<int> neighborPos
-                            = Vec3<int>(x, y, z)
+                        Framework::Vec3<int> neighborPos
+                            = Framework::Vec3<int>(x, y, z)
                             + getDirection(getDirectionFromIndex(i));
                         if (neighborPos.z < 0 || neighborPos.x < 0
                             || neighborPos.y < 0 || neighborPos.x >= CHUNK_SIZE
@@ -566,7 +572,7 @@ void Chunk::putBlockAt(Framework::Vec3<int> location, Block* block)
     for (int i = 0; i < 6; i++)
     {
         Direction d = getDirectionFromIndex(i);
-        Either<Block*, int> neighbor
+        Framework::Either<Block*, int> neighbor
             = zBlockNeighbor(location + getDirection(d));
         if (neighbor.isA())
         {
@@ -603,7 +609,8 @@ void Chunk::putBlockAt(Framework::Vec3<int> location, Block* block)
             if (block)
             {
                 Game::INSTANCE->updateLightningWithoutWait(getDimensionId(),
-                    Vec3<int>(location.x + this->location.x - CHUNK_SIZE / 2,
+                    Framework::Vec3<int>(
+                        location.x + this->location.x - CHUNK_SIZE / 2,
                         location.y + this->location.y - CHUNK_SIZE / 2,
                         location.z));
             }
@@ -631,7 +638,7 @@ void Chunk::putBlockTypeAt(Framework::Vec3<int> location, int type)
         for (int i = 0; i < 6; i++)
         {
             Direction d = getDirectionFromIndex(i);
-            Either<Block*, int> neighbor
+            Framework::Either<Block*, int> neighbor
                 = zBlockNeighbor(location + getDirection(d));
             if (neighbor.isA())
                 ((Block*)neighbor)
@@ -648,7 +655,8 @@ void Chunk::putBlockTypeAt(Framework::Vec3<int> location, int type)
         {
             sendBlockInfo(location);
             Game::INSTANCE->updateLightningWithoutWait(getDimensionId(),
-                Vec3<int>(location.x + this->location.x - CHUNK_SIZE / 2,
+                Framework::Vec3<int>(
+                    location.x + this->location.x - CHUNK_SIZE / 2,
                     location.y + this->location.y - CHUNK_SIZE / 2,
                     location.z));
             Game::INSTANCE->zDimension(dimensionId)
@@ -777,18 +785,19 @@ void Chunk::setNeighbor(Direction dir, Chunk* zChunk)
                     if (zChunk->zBlockConst(j)->isTransparent()
                         && !blockIds[index])
                     {
-                        generateBlock(
-                            Vec3<int>((index / WORLD_HEIGHT) / CHUNK_SIZE,
-                                (index / WORLD_HEIGHT) % CHUNK_SIZE,
-                                index % WORLD_HEIGHT));
+                        generateBlock(Framework::Vec3<int>(
+                            (index / WORLD_HEIGHT) / CHUNK_SIZE,
+                            (index / WORLD_HEIGHT) % CHUNK_SIZE,
+                            index % WORLD_HEIGHT));
                     }
                 }
             }
             if (needsTransmission && added)
             {
-                sendBlockInfo(Vec3<int>((index / WORLD_HEIGHT) / CHUNK_SIZE,
-                    (index / WORLD_HEIGHT) % CHUNK_SIZE,
-                    index % WORLD_HEIGHT));
+                sendBlockInfo(
+                    Framework::Vec3<int>((index / WORLD_HEIGHT) / CHUNK_SIZE,
+                        (index / WORLD_HEIGHT) % CHUNK_SIZE,
+                        index % WORLD_HEIGHT));
             }
         }
     }
@@ -1020,7 +1029,8 @@ void Chunk::setLightData(
     bool needSend = 0;
     for (int i = 0; i < 6; i++)
     {
-        Vec3<int> pos = location + getDirection(getDirectionFromIndex(i));
+        Framework::Vec3<int> pos
+            = location + getDirection(getDirectionFromIndex(i));
         if (pos.z >= 0 && pos.z < WORLD_HEIGHT)
         {
             if (pos.x >= 0 && pos.x < CHUNK_SIZE && pos.y >= 0
@@ -1036,7 +1046,8 @@ void Chunk::setLightData(
             {
                 int type = Game::INSTANCE->getBlockType(
                     pos
-                        + Vec3<int>(this->location.x - CHUNK_SIZE / 2,
+                        + Framework::Vec3<int>(
+                            this->location.x - CHUNK_SIZE / 2,
                             this->location.y - CHUNK_SIZE / 2,
                             0),
                     dimensionId);

+ 3 - 1
FactoryCraft/CraftingStorage.cpp

@@ -5,6 +5,8 @@
 #include "Game.h"
 #include "Inventory.h"
 #include "Item.h"
+#include "RecipieList.h"
+#include "RecipieLoader.h"
 
 #undef min
 #undef max
@@ -427,7 +429,7 @@ void BasicShapedCrafter::applyCurrentRecipie()
 void BasicShapedCrafter::calculateOutputPreview()
 {
     RecipieList* recipies
-        = Game::INSTANCE->getRecipies().zRecipieList(recipieList);
+        = Game::INSTANCE->zRecipies()->zRecipieList(recipieList);
     if (recipies)
     {
         Recipie* recipie = recipies->zFirstRecipie(this);

+ 7 - 13
FactoryCraft/Dimension.cpp

@@ -4,8 +4,12 @@
 #include "Constants.h"
 #include "Datei.h"
 #include "DimensionMap.h"
+#include "Entity.h"
+#include "EntityType.h"
 #include "Game.h"
 #include "NoBlock.h"
+#include "Player.h"
+#include "TickOrganizer.h"
 
 using namespace Framework;
 
@@ -19,9 +23,9 @@ Dimension::Dimension(int id)
       map(new DimensionMap(id)),
       stop(0),
       currentDayTime(0.0),
-      nightDuration(0.0),
-      nightTransitionDuration(0.0),
-      dayDuration(1000.0)
+      nightDuration(300.0),
+      nightTransitionDuration(30.0),
+      dayDuration(600.0)
 {
     Datei d;
     d.setDatei(
@@ -950,14 +954,4 @@ double Dimension::getNightTransitionDuration() const
 double Dimension::getDayDuration() const
 {
     return dayDuration;
-}
-
-DimensionFactory::DimensionFactory(int dimensionId)
-    : ReferenceCounter(),
-      dimensionId(dimensionId)
-{}
-
-int DimensionFactory::getDimensionId() const
-{
-    return dimensionId;
 }

+ 265 - 81
FactoryCraft/DimensionGenerator.cpp

@@ -1,84 +1,124 @@
 #include "DimensionGenerator.h"
 
 #include <iostream>
+#include <Zeit.h>
 
 #include "Constants.h"
+#include "Dimension.h"
 #include "Game.h"
 #include "NoBlock.h"
 #include "Noise.h"
 #include "RandNoise.h"
 #include "WormCaveGenerator.h"
 
-DimensionGeneratorFactory::DimensionGeneratorFactory(
-    Framework::Text name, int dimensionId)
+WorldHeightLayer::WorldHeightLayer()
     : ReferenceCounter(),
-      name(name),
-      dimensionId(dimensionId)
+      noiseConfig(0),
+      noise(0),
+      value(0)
 {}
 
-Framework::Text DimensionGeneratorFactory::getName() const
+WorldHeightLayer::~WorldHeightLayer()
+{
+    if (noiseConfig) noiseConfig->release();
+    if (noise) noise->release();
+    if (value) value->release();
+}
+
+void WorldHeightLayer::initialize(JExpressionMemory* zMemory)
+{
+    if (noise) noise->release();
+    noise = JNoise::parseNoise(noiseConfig, zMemory);
+    zMemory->setNoise(name, dynamic_cast<Noise*>(noise->getThis()));
+}
+
+void WorldHeightLayer::calculateValue(JExpressionMemory* zMemory)
+{
+    zMemory->setFloatVariable(name, value->getValue(zMemory));
+}
+
+void WorldHeightLayer::setNoiseConfig(Framework::JSON::JSONObject* noiseConfig)
+{
+    if (this->noiseConfig) this->noiseConfig->release();
+    this->noiseConfig = noiseConfig;
+}
+
+Framework::JSON::JSONObject* WorldHeightLayer::zNoiseConfig() const
+{
+    return noiseConfig;
+}
+
+void WorldHeightLayer::setName(Framework::Text name)
+{
+    this->name = name;
+}
+
+Framework::Text WorldHeightLayer::getName() const
 {
     return name;
 }
 
-int DimensionGeneratorFactory::getDimensionId() const
+void WorldHeightLayer::setValue(JFloatExpression* value)
 {
-    return dimensionId;
+    if (this->value) this->value->release();
+    this->value = value;
 }
 
-WorldHeightLayer::WorldHeightLayer(
-    Framework::JSON::JSONValue* zConfig, JExpressionMemory* zMemory)
-    : ReferenceCounter()
+JFloatExpression* WorldHeightLayer::zValue() const
 {
-    noise = JNoise::parseNoise(zConfig->asObject()->zValue("noise"), zMemory);
-    name = zConfig->asObject()->zValue("name")->asString()->getString();
-    value = JExpressionParser::parseFloatExpression(
-        zConfig->asObject()->zValue("value"));
-    zMemory->setNoise(name, dynamic_cast<Noise*>(noise->getThis()));
+    return value;
 }
 
-WorldHeightLayer::~WorldHeightLayer()
+WorldHeightLayerFactory::WorldHeightLayerFactory() {}
+
+WorldHeightLayer* WorldHeightLayerFactory::createValue(
+    Framework::JSON::JSONObject* zJson) const
 {
-    noise->release();
-    value->release();
+    return new WorldHeightLayer();
 }
 
-void WorldHeightLayer::calculateValue(JExpressionMemory* zMemory)
+void WorldHeightLayerFactory::fromJson(
+    WorldHeightLayer* zResult, Framework::JSON::JSONObject* zJson) const
 {
-    zMemory->setFloatVariable(name, value->getValue(zMemory));
+    zResult->setName(zJson->zValue("name")->asString()->getString());
+    zResult->setNoiseConfig(zJson->getValue("noise")->asObject());
+    zResult->setValue(
+        Game::INSTANCE->zTypeRegistry()->fromJson<JFloatExpression>(
+            zJson->zValue("value")));
+}
+
+void WorldHeightLayerFactory::toJson(
+    WorldHeightLayer* zObject, Framework::JSON::JSONObject* zResult) const
+{
+    zResult->addValue(
+        "name", new Framework::JSON::JSONString(zObject->getName()));
+    zResult->addValue("noise", zObject->zNoiseConfig());
+    zResult->addValue("value",
+        Game::INSTANCE->zTypeRegistry()->toJson<JFloatExpression>(
+            zObject->zValue()));
 }
 
-Framework::JSON::Validator::JSONValidator* WorldHeightLayer::getValidator()
+JSONObjectValidationBuilder* WorldHeightLayerFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
-    return JSON::Validator::JSONValidator::buildForObject()
-        ->withRequiredString("name")
+    return builder->withRequiredString("name")
         ->finishString()
         ->withRequiredAttribute("noise", JNoise::getValidator(false))
-        ->withRequiredAttribute("value", JExpressionParser::getFloatValidator())
-        ->finishObject();
+        ->withRequiredAttribute("value",
+            Game::INSTANCE->zTypeRegistry()->getValidator<JFloatExpression>());
 }
 
-DimensionGenerator::DimensionGenerator(
-    Framework::JSON::JSONValue* zConfig, int worldSeed, int dimensionId)
+DimensionGenerator::DimensionGenerator()
     : ReferenceCounter(),
       jExpressionMemory(new JExpressionMemory()),
-      dimensionId(dimensionId)
-{
-    jExpressionMemory->setFloatVariable("worldSeed", (float)worldSeed);
-    JFloatExpression* expr = JExpressionParser::parseFloatExpression(
-        zConfig->asObject()->zValue("dimensionSeed"));
-    jExpressionMemory->setFloatVariable(
-        "dimensionSeed", expr->getValue(jExpressionMemory));
-    for (Framework::JSON::JSONValue* value :
-        *zConfig->asObject()->zValue("heightLayers")->asArray())
-    {
-        heightLayers.add(new WorldHeightLayer(value, jExpressionMemory));
-    }
-}
+      seedExpression(0),
+      dimensionId(0)
+{}
 
 DimensionGenerator::~DimensionGenerator()
 {
     jExpressionMemory->release();
+    if (seedExpression) seedExpression->release();
 }
 
 JExpressionMemory* DimensionGenerator::zMemory() const
@@ -94,48 +134,94 @@ void DimensionGenerator::calculateHeightLayers()
     }
 }
 
-int DimensionGenerator::getDimensionId() const
+Dimension* DimensionGenerator::createDimension()
 {
-    return dimensionId;
+    return new Dimension(getId());
 }
 
-BiomedCavedDimensionGenerator::BiomedCavedDimensionGenerator(
-    Framework::JSON::JSONValue* zConfig, int worldSeed, int dimensionId)
-    : DimensionGenerator(zConfig, worldSeed, dimensionId),
-      caveGenerator(new WormCaveGenerator(75, 150, 1, 6, 0.1f, worldSeed - 1))
+void DimensionGenerator::initialize(int worldSeed)
 {
-    biomNoise = JNoise::parseNoise(
-        zConfig->asObject()->zValue("biomNoise"), zMemory());
-    bool first = 1;
-    for (Framework::JSON::JSONValue* value :
-        *zConfig->asObject()->zValue("bioms")->asArray())
+    jExpressionMemory->setFloatVariable("worldSeed", (float)worldSeed);
+    jExpressionMemory->setFloatVariable(
+        "dimensionSeed", seedExpression->getValue(jExpressionMemory));
+    for (WorldHeightLayer* layer : heightLayers)
     {
-        BiomGenerator* gen = new BiomGenerator(value, zMemory());
-        biomGenerators.add(gen);
-        if (first)
-        {
-            minStructureOffset = gen->getMinStructureOffset();
-            maxStructureOffset = gen->getMaxStructureOffset();
-            first = 0;
-        }
-        else
-        {
-            Framework::Vec3<int> min = gen->getMinStructureOffset();
-            Framework::Vec3<int> max = gen->getMaxStructureOffset();
-            if (minStructureOffset.x > min.x) minStructureOffset.x = min.x;
-            if (minStructureOffset.y > min.y) minStructureOffset.y = min.y;
-            if (minStructureOffset.z > min.z) minStructureOffset.z = min.z;
-            if (maxStructureOffset.x < max.x) maxStructureOffset.x = max.x;
-            if (maxStructureOffset.y < max.y) maxStructureOffset.y = max.y;
-            if (maxStructureOffset.z < max.z) maxStructureOffset.z = max.z;
-        }
+        layer->initialize(jExpressionMemory);
     }
 }
 
+int DimensionGenerator::getDimensionId() const
+{
+    return dimensionId;
+}
+
+void DimensionGenerator::addHeightLayer(WorldHeightLayer* layer)
+{
+    heightLayers.add(layer);
+}
+
+const Framework::RCArray<WorldHeightLayer>&
+DimensionGenerator::getHeightLayers() const
+{
+    return heightLayers;
+}
+
+void DimensionGenerator::setName(Framework::Text name)
+{
+    this->name = name;
+}
+
+Framework::Text DimensionGenerator::getName() const
+{
+    return name;
+}
+
+void DimensionGenerator::setId(int id)
+{
+    dimensionId = id;
+}
+
+int DimensionGenerator::getId() const
+{
+    return dimensionId;
+}
+
+void DimensionGenerator::setSeed(JFloatExpression* seed)
+{
+    if (seedExpression) seedExpression->release();
+    seedExpression = seed;
+}
+
+JFloatExpression* DimensionGenerator::zSeed() const
+{
+    return seedExpression;
+}
+
+BiomedCavedDimensionGenerator::BiomedCavedDimensionGenerator()
+    : DimensionGenerator(),
+      caveGenerator(0),
+      noiseConfig(0),
+      biomNoise(0)
+{}
+
 BiomedCavedDimensionGenerator::~BiomedCavedDimensionGenerator()
 {
-    biomNoise->release();
-    caveGenerator->release();
+    if (noiseConfig) noiseConfig->release();
+    if (biomNoise) biomNoise->release();
+    if (caveGenerator) caveGenerator->release();
+}
+
+void BiomedCavedDimensionGenerator::initialize(int worldSeed)
+{
+    if (biomNoise) biomNoise->release();
+    if (caveGenerator) caveGenerator->release();
+    DimensionGenerator::initialize(worldSeed);
+    biomNoise = JNoise::parseNoise(noiseConfig, zMemory());
+    for (BiomGenerator* gen : biomGenerators)
+    {
+        gen->initialize(zMemory());
+    }
+    caveGenerator = new WormCaveGenerator(75, 150, 1, 6, 0.1f, worldSeed - 1);
 }
 
 BiomGenerator* BiomedCavedDimensionGenerator::zBiomGenerator()
@@ -196,8 +282,8 @@ Chunk* BiomedCavedDimensionGenerator::generateChunk(int centerX, int centerY)
     double blockGenTime = 0;
     double biomTime = 0;
     double layerTime = 0;
-    ZeitMesser zm;
-    ZeitMesser zmGlobal;
+    Framework::ZeitMesser zm;
+    Framework::ZeitMesser zmGlobal;
     zm.messungStart();
     zmGlobal.messungStart();
     Framework::RCArray<GeneratedStructure>* structures
@@ -214,7 +300,8 @@ Chunk* BiomedCavedDimensionGenerator::generateChunk(int centerX, int centerY)
         = caveGenerator->getGeneratorForChunk(centerX, centerY);
     zm.messungEnde();
     caveTime += zm.getSekunden();
-    Chunk* chunk = new Chunk(Framework::Punkt(centerX, centerY), getDimensionId());
+    Chunk* chunk
+        = new Chunk(Framework::Punkt(centerX, centerY), getDimensionId());
     zMemory()->setCurrentChunk(dynamic_cast<Chunk*>(chunk->getThis()));
     for (int x = -CHUNK_SIZE / 2; x < CHUNK_SIZE / 2; x++)
     {
@@ -235,8 +322,7 @@ Chunk* BiomedCavedDimensionGenerator::generateChunk(int centerX, int centerY)
             // generate blocks
             for (int z = 0; z < WORLD_HEIGHT; z++)
             {
-                zMemory()->setFloatVariable(
-                    "z", (float)z);
+                zMemory()->setFloatVariable("z", (float)z);
                 Framework::Either<Block*, int> generated = BlockTypeEnum::AIR;
                 bool structureAffected = 0;
                 // check if the block is inside of a structure
@@ -340,7 +426,8 @@ Framework::Either<Block*, int> BiomedCavedDimensionGenerator::generateBlock(
     {
         if (structure->isBlockAffected(location))
         {
-            auto generated = structure->generateBlockAt(location, getDimensionId());
+            auto generated
+                = structure->generateBlockAt(location, getDimensionId());
             structures->release();
             zMemory()->unlock();
             return generated;
@@ -348,7 +435,7 @@ Framework::Either<Block*, int> BiomedCavedDimensionGenerator::generateBlock(
     }
     structures->release();
 
-    Punkt chunkCenter = Game::getChunkCenter(location.x, location.y);
+    Framework::Punkt chunkCenter = Game::getChunkCenter(location.x, location.y);
     CaveChunkGenerator* caveGen
         = caveGenerator->getGeneratorForChunk(chunkCenter.x, chunkCenter.y);
     if (caveGen->isInCave(location.x, location.y, location.z))
@@ -379,7 +466,7 @@ bool BiomedCavedDimensionGenerator::spawnStructure(
 
     BiomGenerator* biom = zBiomGenerator();
     zMemory()->unlock();
-    for (StructureTemplateCollection *tc : biom->getTemplates())
+    for (StructureTemplateCollection* tc : biom->getTemplates())
     {
         for (GeneratorTemplate* t : tc->getStructures())
         {
@@ -427,4 +514,101 @@ bool BiomedCavedDimensionGenerator::spawnStructure(
         }
     }
     return 0;
-}
+}
+
+void BiomedCavedDimensionGenerator::addBiomGenerator(
+    BiomGenerator* biomGenerator)
+{
+    biomGenerators.add(biomGenerator);
+    if (biomGenerators.getEintragAnzahl() == 1)
+    {
+        minStructureOffset = biomGenerator->getMinStructureOffset();
+        maxStructureOffset = biomGenerator->getMaxStructureOffset();
+    }
+    else
+    {
+        Framework::Vec3<int> min = biomGenerator->getMinStructureOffset();
+        Framework::Vec3<int> max = biomGenerator->getMaxStructureOffset();
+        if (minStructureOffset.x > min.x) minStructureOffset.x = min.x;
+        if (minStructureOffset.y > min.y) minStructureOffset.y = min.y;
+        if (minStructureOffset.z > min.z) minStructureOffset.z = min.z;
+        if (maxStructureOffset.x < max.x) maxStructureOffset.x = max.x;
+        if (maxStructureOffset.y < max.y) maxStructureOffset.y = max.y;
+        if (maxStructureOffset.z < max.z) maxStructureOffset.z = max.z;
+    }
+}
+
+const Framework::RCArray<BiomGenerator>&
+BiomedCavedDimensionGenerator::getBiomGenerators() const
+{
+    return biomGenerators;
+}
+
+void BiomedCavedDimensionGenerator::setBiomNoiseConfig(
+    Framework::JSON::JSONObject* biomNoiseConfig)
+{
+    if (noiseConfig) noiseConfig->release();
+    noiseConfig = biomNoiseConfig;
+}
+
+Framework::JSON::JSONObject*
+BiomedCavedDimensionGenerator::zBiomNoiseConfig() const
+{
+    return noiseConfig;
+}
+
+BiomedCavedDimensionGeneratorFactory::BiomedCavedDimensionGeneratorFactory() {}
+
+BiomedCavedDimensionGenerator*
+BiomedCavedDimensionGeneratorFactory::createValue(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new BiomedCavedDimensionGenerator();
+}
+
+void BiomedCavedDimensionGeneratorFactory::fromJson(
+    BiomedCavedDimensionGenerator* zResult,
+    Framework::JSON::JSONObject* zJson) const
+{
+    zResult->setBiomNoiseConfig(zJson->getValue("biomNoise")->asObject());
+    for (Framework::JSON::JSONValue* value : *zJson->zValue("bioms")->asArray())
+    {
+        zResult->addBiomGenerator(
+            Game::INSTANCE->zTypeRegistry()->fromJson<BiomGenerator>(value));
+    }
+    DimensionGeneratorFactory::fromJson(zResult, zJson);
+}
+
+void BiomedCavedDimensionGeneratorFactory::toJson(
+    BiomedCavedDimensionGenerator* zObject,
+    Framework::JSON::JSONObject* zResult) const
+{
+    Framework::JSON::JSONArray* bioms = new Framework::JSON::JSONArray();
+    for (BiomGenerator* biom : zObject->getBiomGenerators())
+    {
+        bioms->addValue(
+            Game::INSTANCE->zTypeRegistry()->toJson<BiomGenerator>(biom));
+    }
+    zResult->addValue("bioms", bioms);
+    zResult->addValue("biomNoise",
+        dynamic_cast<Framework::JSON::JSONValue*>(
+            zObject->zBiomNoiseConfig()->getThis()));
+    DimensionGeneratorFactory::toJson(zObject, zResult);
+}
+
+JSONObjectValidationBuilder*
+BiomedCavedDimensionGeneratorFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return DimensionGeneratorFactory::addToValidator(
+        builder->withRequiredArray("bioms")
+            ->addAcceptedTypeInArray(
+                Game::INSTANCE->zTypeRegistry()->getValidator<BiomGenerator>())
+            ->finishArray()
+            ->withRequiredAttribute("biomNoise", JNoise::getValidator(false)));
+}
+
+Framework::Text BiomedCavedDimensionGeneratorFactory::getTypeToken() const
+{
+    return "cavedBioms";
+}

+ 124 - 32
FactoryCraft/DimensionGenerator.h

@@ -15,36 +15,60 @@ class DimensionGenerator;
 class WorldHeightLayer : public virtual Framework::ReferenceCounter
 {
 private:
+    Framework::JSON::JSONObject* noiseConfig;
     Noise* noise;
     Framework::Text name;
     JFloatExpression* value;
 
 public:
-    WorldHeightLayer(
-        Framework::JSON::JSONValue* zConfig, JExpressionMemory* zMemory);
+    WorldHeightLayer();
     ~WorldHeightLayer();
 
+    void initialize(JExpressionMemory* zMemory);
+
     void calculateValue(JExpressionMemory* zMemory);
 
-    static Framework::JSON::Validator::JSONValidator* getValidator();
+    void setNoiseConfig(Framework::JSON::JSONObject* noiseConfig);
+    Framework::JSON::JSONObject* zNoiseConfig() const;
+    void setName(Framework::Text name);
+    Framework::Text getName() const;
+    void setValue(JFloatExpression* value);
+    JFloatExpression* zValue() const;
+};
+
+class WorldHeightLayerFactory : public TypeFactory<WorldHeightLayer>
+{
+public:
+    WorldHeightLayerFactory();
+    WorldHeightLayer* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(WorldHeightLayer* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(WorldHeightLayer* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
 };
 
 class DimensionGenerator : public virtual Framework::ReferenceCounter
 {
 private:
     JExpressionMemory* jExpressionMemory;
+    JFloatExpression* seedExpression;
     Framework::RCArray<WorldHeightLayer> heightLayers;
-    const int dimensionId;
+    Framework::Text name;
+    int dimensionId;
 
 protected:
-    DimensionGenerator(
-        Framework::JSON::JSONValue* zConfig, int worldSeed, int dimensionId);
+    DimensionGenerator();
     ~DimensionGenerator();
 
     JExpressionMemory* zMemory() const;
     void calculateHeightLayers();
 
 public:
+    Dimension *createDimension();
+    virtual void initialize(int worldSeed);
     virtual Chunk* generateChunk(int centerX, int centerY) = 0;
     virtual Framework::Either<Block*, int> generateBlock(
         Framework::Vec3<int> location)
@@ -53,21 +77,78 @@ public:
         std::function<bool(GeneratorTemplate* tmpl)> filter)
         = 0;
     int getDimensionId() const;
+    void addHeightLayer(WorldHeightLayer* layer);
+    const Framework::RCArray<WorldHeightLayer>& getHeightLayers() const;
+    void setName(Framework::Text name);
+    Framework::Text getName() const;
+    void setId(int id);
+    int getId() const;
+    void setSeed(JFloatExpression* seed);
+    JFloatExpression* zSeed() const;
+};
+
+template<typename S> class DimensionGeneratorFactory
+    : public SubTypeFactory<DimensionGenerator, S>
+{
+public:
+    DimensionGeneratorFactory()
+        : SubTypeFactory<DimensionGenerator, S>()
+    {}
+
+    void fromJson(S* zResult, Framework::JSON::JSONObject* zJson) const override
+    {
+        DimensionGenerator* zGenerator
+            = dynamic_cast<DimensionGenerator*>(zResult);
+        zGenerator->setName(zJson->zValue("name")->asString()->getString());
+        zGenerator->setId((int)zJson->zValue("id")->asNumber()->getNumber());
+        zGenerator->setSeed(
+            Game::INSTANCE->zTypeRegistry()->fromJson<JFloatExpression>(
+                zJson->zValue("dimensionSeed")));
+        for (Framework::JSON::JSONValue* layer :
+            *zJson->zValue("heightLayers")->asArray())
+        {
+            zGenerator->addHeightLayer(
+                Game::INSTANCE->zTypeRegistry()->fromJson<WorldHeightLayer>(
+                    layer));
+        }
+    }
 
-    template<typename T>
-    static Framework::JSON::Validator::ObjectValidationBuilder<T>*
-    addConfigAttributes(
-        Framework::JSON::Validator::ObjectValidationBuilder<T>* zBuilder)
+    void toJson(S* zObject, Framework::JSON::JSONObject* zResult) const override
     {
-        return zBuilder
-            ->withRequiredAttribute(
-                "dimensionSeed", JExpressionParser::getFloatValidator())
-            ->withRequiredAttribute("heightLayers",
-                Framework::JSON::Validator::JSONValidator::buildForArray()
-                    ->withDefault(new Framework::JSON::JSONArray())
-                    ->removeInvalidEntries()
-                    ->addAcceptedTypeInArray(WorldHeightLayer::getValidator())
-                    ->finishArray());
+        DimensionGenerator* zGenerator
+            = dynamic_cast<DimensionGenerator*>(zObject);
+        zResult->addValue(
+            "name", new Framework::JSON::JSONString(zGenerator->getName()));
+        zResult->addValue(
+            "id", new Framework::JSON::JSONNumber(zGenerator->getId()));
+        zResult->addValue("dimensionSeed",
+            Game::INSTANCE->zTypeRegistry()->toJson<JFloatExpression>(
+                zGenerator->zSeed()));
+        Framework::JSON::JSONArray* hightLayers
+            = new Framework::JSON::JSONArray();
+        for (WorldHeightLayer* layer : zGenerator->getHeightLayers())
+        {
+            hightLayers->addValue(
+                Game::INSTANCE->zTypeRegistry()->toJson(layer));
+        }
+        zResult->addValue("heightLayers", hightLayers);
+    }
+
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override
+    {
+        return builder
+            ->withRequiredAttribute("dimensionSeed",
+                Game::INSTANCE->zTypeRegistry()
+                    ->getValidator<JFloatExpression>())
+            ->withRequiredArray("heightLayers")
+            ->addAcceptedTypeInArray(Game::INSTANCE->zTypeRegistry()
+                                         ->getValidator<WorldHeightLayer>())
+            ->finishArray()
+            ->withRequiredString("name")
+            ->finishString()
+            ->withRequiredNumber("id")
+            ->finishNumber();
     }
 };
 
@@ -78,6 +159,7 @@ class BiomedCavedDimensionGenerator : public DimensionGenerator
 private:
     Framework::RCArray<BiomGenerator> biomGenerators;
     CaveGenerator* caveGenerator;
+    Framework::JSON::JSONObject* noiseConfig;
     Noise* biomNoise;
     Framework::Vec3<int> minStructureOffset;
     Framework::Vec3<int> maxStructureOffset;
@@ -89,24 +171,34 @@ protected:
         Framework::Vec3<int> minPos, Framework::Vec3<int> maxPos);
 
 public:
-    BiomedCavedDimensionGenerator(
-        Framework::JSON::JSONValue* zConfig, int worldSeed, int dimensionId);
+    BiomedCavedDimensionGenerator();
     ~BiomedCavedDimensionGenerator();
 
+    virtual void initialize(int worldSeed) override;
+
     Chunk* generateChunk(int centerX, int centerY);
     Framework::Either<Block*, int> generateBlock(Framework::Vec3<int> location);
     bool spawnStructure(Framework::Vec3<int> location,
         std::function<bool(GeneratorTemplate* tmpl)> filter);
 
-    template<typename T>
-    static Framework::JSON::Validator::ObjectValidationBuilder<T>*
-    addConfigAttributes(
-        Framework::JSON::Validator::ObjectValidationBuilder<T>* zBuilder)
-    {
-        return DimensionGenerator::addConfigAttributes(zBuilder
-            ->withRequiredArray("bioms")
-            ->addAcceptedTypeInArray(BiomGenerator::getConfigValidator())
-            ->finishArray()
-            ->withRequiredAttribute("biomNoise", JNoise::getValidator(false)));
-    }
+    void addBiomGenerator(BiomGenerator* biomGenerator);
+    const Framework::RCArray<BiomGenerator>& getBiomGenerators() const;
+    void setBiomNoiseConfig(Framework::JSON::JSONObject* biomNoiseConfig);
+    Framework::JSON::JSONObject* zBiomNoiseConfig() const;
+};
+
+class BiomedCavedDimensionGeneratorFactory
+    : public DimensionGeneratorFactory<BiomedCavedDimensionGenerator>
+{
+public:
+    BiomedCavedDimensionGeneratorFactory();
+    BiomedCavedDimensionGenerator* createValue(
+		Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(BiomedCavedDimensionGenerator* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(BiomedCavedDimensionGenerator* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
+    Framework::Text getTypeToken() const override;
 };

+ 9 - 5
FactoryCraft/DimensionMap.cpp

@@ -2,8 +2,12 @@
 
 #include <Datei.h>
 
+#include "Chat.h"
 #include "ChunkMap.h"
+#include "Dimension.h"
+#include "Entity.h"
 #include "Game.h"
+#include "Player.h"
 
 DimensionMap::DimensionMap(int dimensionId)
     : ReferenceCounter(),
@@ -58,17 +62,17 @@ void DimensionMap::api(Framework::InMemoryBuffer* zRequest,
         }
     case 3: // player list request
         {
-            InMemoryBuffer buff;
+            Framework::InMemoryBuffer buff;
             int count = 0;
             for (Entity* entity : *zDimension->entities)
             {
                 if (entity->zType()->getId() == EntityTypeEnum::PLAYER)
                 {
                     Player* p = dynamic_cast<Player*>(entity);
-                    char len = (char)textLength(p->getName());
+                    char len = (char)Framework::textLength(p->getName());
                     buff.schreibe(&len, 1);
                     buff.schreibe(p->getName(), len);
-                    Vec3<float> pos = p->getPosition();
+                    Framework::Vec3<float> pos = p->getPosition();
                     buff.schreibe((char*)&pos.x, 4);
                     buff.schreibe((char*)&pos.y, 4);
                     buff.schreibe((char*)&pos.z, 4);
@@ -94,7 +98,7 @@ ChunkMap* DimensionMap::load(Framework::Punkt chunkCenter)
     filePath.appendHex(chunkCenter.y);
     filePath += ".map";
     file.setDatei(filePath);
-    if (file.open(Datei::Style::lesen))
+    if (file.open(Framework::Datei::Style::lesen))
     {
         ChunkMap* map = new ChunkMap(&file);
         file.close();
@@ -179,7 +183,7 @@ void DimensionMap::saveMap(char* addr, int addrLen)
         filePath += ".map";
         file.setDatei(filePath);
         file.erstellen();
-        if (file.open(Datei::Style::schreiben))
+        if (file.open(Framework::Datei::Style::schreiben))
         {
             map->writeTo(&file);
             file.close();

+ 14 - 12
FactoryCraft/Entity.cpp

@@ -7,9 +7,10 @@
 #include "EntityRemovedUpdate.h"
 #include "Game.h"
 #include "ItemSkill.h"
+#include "ItemStack.h"
 #include "NoBlock.h"
 
-ActionTarget::ActionTarget(Vec3<int> blockPos, Direction blockSide)
+ActionTarget::ActionTarget(Framework::Vec3<int> blockPos, Direction blockSide)
     : blockPos(blockPos),
       targetBlockSide(blockSide),
       entityId(-1)
@@ -409,7 +410,7 @@ void Entity::calculateTarget(Framework::Vec3<float> basePos,
     Framework::Vec3<float> direction,
     const Item* zItem)
 {
-    Vec3<float> headPosition = basePos + faceOffset;
+    Framework::Vec3<float> headPosition = basePos + faceOffset;
     int px = (int)floor(headPosition.x);
     int py = (int)floor(headPosition.y);
     int pz = (int)floor(headPosition.z);
@@ -417,8 +418,8 @@ void Entity::calculateTarget(Framework::Vec3<float> basePos,
     Direction dir = BOTTOM;
     while (true)
     {
-        if (getDefaultBlock(
-                Game::INSTANCE->zBlockAt(Vec3<int>{px, py, pz}, dimensionId))
+        if (getDefaultBlock(Game::INSTANCE->zBlockAt(
+                                Framework::Vec3<int>{px, py, pz}, dimensionId))
                 ->isInteractable(zItem))
         {
             if (!target || !target->isBlock({px, py, pz}, dir))
@@ -435,7 +436,7 @@ void Entity::calculateTarget(Framework::Vec3<float> basePos,
         if (direction.x > 0)
         {
             float xt = ((float)px + 1.f - headPosition.x) / direction.x;
-            Vec3<float> tmp = headPosition + direction * xt;
+            Framework::Vec3<float> tmp = headPosition + direction * xt;
             if (xt <= targetDistanceLimit && tmp.y >= (float)py
                 && tmp.y < (float)py + 1.f && tmp.z >= (float)pz
                 && tmp.z < (float)pz + 1.f)
@@ -448,7 +449,7 @@ void Entity::calculateTarget(Framework::Vec3<float> basePos,
         if (direction.x < 0)
         {
             float xt = ((float)px - headPosition.x) / direction.x;
-            Vec3<float> tmp = headPosition + direction * xt;
+            Framework::Vec3<float> tmp = headPosition + direction * xt;
             if (xt <= targetDistanceLimit && tmp.y >= (float)py
                 && tmp.y < (float)py + 1.f && tmp.z >= (float)pz
                 && tmp.z < (float)pz + 1.f)
@@ -461,7 +462,7 @@ void Entity::calculateTarget(Framework::Vec3<float> basePos,
         if (direction.y > 0)
         {
             float yt = ((float)py + 1.f - headPosition.y) / direction.y;
-            Vec3<float> tmp = headPosition + direction * yt;
+            Framework::Vec3<float> tmp = headPosition + direction * yt;
             if (yt <= targetDistanceLimit && tmp.x >= (float)px
                 && tmp.x < (float)px + 1.f && tmp.z >= (float)pz
                 && tmp.z < (float)pz + 1.f)
@@ -474,7 +475,7 @@ void Entity::calculateTarget(Framework::Vec3<float> basePos,
         if (direction.y < 0)
         {
             float yt = ((float)py - headPosition.y) / direction.y;
-            Vec3<float> tmp = headPosition + direction * yt;
+            Framework::Vec3<float> tmp = headPosition + direction * yt;
             if (yt <= targetDistanceLimit && tmp.x >= (float)px
                 && tmp.x < (float)px + 1.f && tmp.z >= (float)pz
                 && tmp.z < (float)pz + 1.f)
@@ -487,7 +488,7 @@ void Entity::calculateTarget(Framework::Vec3<float> basePos,
         if (direction.z > 0)
         {
             float zt = ((float)pz + 1.f - headPosition.z) / direction.z;
-            Vec3<float> tmp = headPosition + direction * zt;
+            Framework::Vec3<float> tmp = headPosition + direction * zt;
             if (zt <= targetDistanceLimit && tmp.x >= (float)px
                 && tmp.x < (float)px + 1.f && tmp.y >= (float)py
                 && tmp.y < (float)py + 1.f)
@@ -500,7 +501,7 @@ void Entity::calculateTarget(Framework::Vec3<float> basePos,
         if (direction.z < 0)
         {
             float zt = ((float)pz - headPosition.z) / direction.z;
-            Vec3<float> tmp = headPosition + direction * zt;
+            Framework::Vec3<float> tmp = headPosition + direction * zt;
             if (zt <= targetDistanceLimit && tmp.x >= (float)px
                 && tmp.x < (float)px + 1.f && tmp.y >= (float)py
                 && tmp.y < (float)py + 1)
@@ -551,7 +552,8 @@ void Entity::addStatusBarObserver(Entity* zSource, Framework::Text id)
             return;
         }
     }
-    statusBarObservers.add(ImmutablePair<int, Text>(zSource->getId(), id));
+    statusBarObservers.add(
+        Framework::ImmutablePair<int, Framework::Text>(zSource->getId(), id));
     cs.unlock();
 }
 
@@ -559,7 +561,7 @@ void Entity::notifyStatusBarObservers(NetworkMessage* msg)
 {
     cs.lock();
     int index = 0;
-    Array<int> toDelete;
+    Framework::Array<int> toDelete;
     for (auto observer : statusBarObservers)
     {
         Entity* e = Game::INSTANCE->zEntity(observer.getFirst());

+ 1 - 0
FactoryCraft/EntityType.cpp

@@ -2,6 +2,7 @@
 
 #include "Entity.h"
 #include "Game.h"
+#include "ItemType.h"
 
 EntityType::EntityType(Framework::Text name, ModelInfo* model)
     : ReferenceCounter(),

+ 0 - 4
FactoryCraft/FactoryCraft.vcxproj

@@ -162,9 +162,7 @@
     <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="PlaceableProof.h" />
     <ClInclude Include="Player.h" />
     <ClInclude Include="PlayerHand.h" />
@@ -263,9 +261,7 @@
     <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="PlaceableProof.cpp" />
     <ClCompile Include="Player.cpp" />
     <ClCompile Include="PlayerHand.cpp" />

+ 0 - 18
FactoryCraft/FactoryCraft.vcxproj.filters

@@ -97,12 +97,6 @@
     <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>
     <Filter Include="inventory\items\fluidContainer">
       <UniqueIdentifier>{59a5d9f2-a3fb-45a5-92c8-c641f2891b01}</UniqueIdentifier>
     </Filter>
@@ -165,9 +159,6 @@
     <ClInclude Include="DimensionGenerator.h">
       <Filter>world\generator</Filter>
     </ClInclude>
-    <ClInclude Include="OverworldDimension.h">
-      <Filter>world\dimensions</Filter>
-    </ClInclude>
     <ClInclude Include="Constants.h">
       <Filter>game</Filter>
     </ClInclude>
@@ -399,9 +390,6 @@
     <ClInclude Include="BlockInstanceGeneratorRule.h">
       <Filter>world\generator\biom\rules</Filter>
     </ClInclude>
-    <ClInclude Include="OverworldDimensionGenerator.h">
-      <Filter>world\generator\dimensions</Filter>
-    </ClInclude>
     <ClInclude Include="FluidContainer.h">
       <Filter>inventory\items\fluidContainer</Filter>
     </ClInclude>
@@ -443,9 +431,6 @@
     <ClCompile Include="WorldGenerator.cpp">
       <Filter>world\generator</Filter>
     </ClCompile>
-    <ClCompile Include="OverworldDimension.cpp">
-      <Filter>world\dimensions</Filter>
-    </ClCompile>
     <ClCompile Include="TickWorker.cpp">
       <Filter>world\ticking</Filter>
     </ClCompile>
@@ -695,9 +680,6 @@
     <ClCompile Include="BlockInstanceGeneratorRule.cpp">
       <Filter>world\generator\biom\rules</Filter>
     </ClCompile>
-    <ClCompile Include="OverworldDimensionGenerator.cpp">
-      <Filter>world\generator\dimensions</Filter>
-    </ClCompile>
     <ClCompile Include="FluidContainer.cpp">
       <Filter>inventory\items\fluidContainer</Filter>
     </ClCompile>

+ 110 - 115
FactoryCraft/FluidBlock.cpp

@@ -1,12 +1,13 @@
 #include "FluidBlock.h"
 
+#include "Dimension.h"
 #include "FluidContainer.h"
 #include "Game.h"
 
 FluidBlock::FluidBlock(int typeId,
     Framework::Vec3<int> pos,
     int dimensionId,
-    Vec3<float> lightWeights)
+    Framework::Vec3<float> lightWeights)
     : Block(typeId, pos, dimensionId, 0),
       lightWeights(lightWeights),
       neighborChanged(1),
@@ -218,23 +219,14 @@ char FluidBlock::getFlowOptions() const
     return flowOptions;
 }
 
-FluidBlockType::FluidBlockType(ModelInfo* model,
-    Framework::Text name,
-    int mapColor,
-    Vec3<float> lightWeights,
-    int ticktsToFlow,
-    unsigned char flowDistance,
-    float hpRecoveryPerL,
-    float thirstRecoveryPerL,
-    float heat,
-    Framework::RCArray<Framework::Text> groupNames)
-    : BlockType(0, model, 1, 10, 0, name, true, mapColor, groupNames, 0.f),
-      lightWeights(lightWeights),
-      ticktsToFlow(ticktsToFlow),
-      flowDistance(flowDistance),
-      hungerRecoveryPerL(hungerRecoveryPerL),
-      thirstRecoveryPerL(thirstRecoveryPerL),
-    heat(heat)
+FluidBlockType::FluidBlockType()
+    : BlockType(),
+      lightWeights(1.f, 1.f, 1.f),
+      ticktsToFlow(20),
+      flowDistance(8),
+      hungerRecoveryPerL(0.f),
+      thirstRecoveryPerL(0.f),
+      heat(10.f)
 {}
 
 void FluidBlockType::loadSuperBlock(
@@ -277,34 +269,64 @@ bool FluidBlockType::isFluid() const
     return true;
 }
 
+ItemType* FluidBlockType::createItemType() const
+{
+    return 0;
+}
+
+void FluidBlockType::setTicktsToFlow(int ticksToFlow)
+{
+    this->ticktsToFlow = ticksToFlow;
+}
+
 int FluidBlockType::getTicktsToFlow() const
 {
     return ticktsToFlow;
 }
 
+void FluidBlockType::setFlowDistance(unsigned char flowDistance)
+{
+    this->flowDistance = flowDistance;
+}
+
 unsigned char FluidBlockType::getFlowDistance() const
 {
     return flowDistance;
 }
 
+void FluidBlockType::setLightWeights(Framework::Vec3<float> lightWeights)
+{
+    this->lightWeights = lightWeights;
+}
+
 Framework::Vec3<float> FluidBlockType::getLightWeights() const
 {
     return lightWeights;
 }
 
+void FluidBlockType::setHungerRecoveryPerL(float hungerRecoveryPerL)
+{
+    this->hungerRecoveryPerL = hungerRecoveryPerL;
+}
+
 float FluidBlockType::getHungerRecoveryPerL() const
 {
     return hungerRecoveryPerL;
 }
 
+void FluidBlockType::setThirstRecoveryPerL(float thirstRecoveryPerL)
+{
+    this->thirstRecoveryPerL = thirstRecoveryPerL;
+}
+
 float FluidBlockType::getThirstRecoveryPerL() const
 {
     return thirstRecoveryPerL;
 }
 
-ItemType* FluidBlockType::createItemType() const
+void FluidBlockType::setHeat(float heat)
 {
-    return 0;
+    this->heat = heat;
 }
 
 float FluidBlockType::getHeat() const
@@ -313,23 +335,19 @@ float FluidBlockType::getHeat() const
 }
 
 FluidBlockTypeFactory::FluidBlockTypeFactory()
-    : SubTypeFactory()
+    : BlockTypeFactoryBase()
 {}
 
-FluidBlockType* FluidBlockTypeFactory::fromJson(
+FluidBlockType* FluidBlockTypeFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
-    Framework::RCArray<Framework::Text> groupNames;
-    for (Framework::JSON::JSONValue* value :
-        *zJson->zValue("groupNames")->asArray())
-    {
-        groupNames.add(new Framework::Text(value->asString()->getString()));
-    }
-    return new FluidBlockType(
-        Game::INSTANCE->zTypeRegistry()->fromJson<ModelInfo>(
-            zJson->zValue("model")),
-        zJson->zValue("name")->asString()->getString(),
-        (int)zJson->zValue("mapColor")->asString()->getString(),
+    return new FluidBlockType();
+}
+
+void FluidBlockTypeFactory::fromJson(
+    FluidBlockType* zResult, Framework::JSON::JSONObject* zJson) const
+{
+    zResult->setLightWeights(
         Framework::Vec3<float>((float)zJson->zValue("lightWeight")
                                    ->asObject()
                                    ->zValue("red")
@@ -344,25 +362,22 @@ FluidBlockType* FluidBlockTypeFactory::fromJson(
                 ->asObject()
                 ->zValue("blue")
                 ->asNumber()
-                ->getNumber()),
-        (int)zJson->zValue("ticksToFlow")->asNumber()->getNumber(),
-        (char)zJson->zValue("flowDistance")->asNumber()->getNumber(),
-        (float)zJson->zValue("hungerRecoveryPerL")->asNumber()->getNumber(),
-        (float)zJson->zValue("thirstRecoveryPerL")->asNumber()->getNumber(),
-        (float)zJson->zValue("heat")->asNumber()->getNumber(),
-        groupNames);
-}
-
-Framework::JSON::JSONObject* FluidBlockTypeFactory::toJson(
-    FluidBlockType* zObject) const
-{
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue(
-        "model", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zModel()));
-    result->addValue(
-        "name", new Framework::JSON::JSONString(zObject->getName()));
-    result->addValue(
-        "mapColor", new Framework::JSON::JSONString(zObject->getMapColor()));
+                ->getNumber()));
+    zResult->setTicktsToFlow(
+        (int)zJson->zValue("ticksToFlow")->asNumber()->getNumber());
+    zResult->setFlowDistance(
+        (char)zJson->zValue("flowDistance")->asNumber()->getNumber());
+    zResult->setHungerRecoveryPerL(
+        (float)zJson->zValue("hungerRecoveryPerL")->asNumber()->getNumber());
+    zResult->setThirstRecoveryPerL(
+        (float)zJson->zValue("thirstRecoveryPerL")->asNumber()->getNumber());
+    zResult->setHeat((float)zJson->zValue("heat")->asNumber()->getNumber());
+    BlockTypeFactoryBase::fromJson(zResult, zJson);
+}
+
+void FluidBlockTypeFactory::toJson(
+    FluidBlockType* zObject, Framework::JSON::JSONObject* zResult) const
+{
     Framework::JSON::JSONObject* lightWeight
         = new Framework::JSON::JSONObject();
     lightWeight->addValue(
@@ -371,77 +386,57 @@ Framework::JSON::JSONObject* FluidBlockTypeFactory::toJson(
         "green", new Framework::JSON::JSONNumber(zObject->getLightWeights().y));
     lightWeight->addValue(
         "blue", new Framework::JSON::JSONNumber(zObject->getLightWeights().z));
-    result->addValue("lightWeight", lightWeight);
-    result->addValue("ticksToFlow",
+    zResult->addValue("lightWeight", lightWeight);
+    zResult->addValue("ticksToFlow",
         new Framework::JSON::JSONNumber((double)zObject->getTicktsToFlow()));
-    result->addValue("flowDistance",
+    zResult->addValue("flowDistance",
         new Framework::JSON::JSONNumber((double)zObject->getFlowDistance()));
-    result->addValue("hungerRecoveryPerL",
+    zResult->addValue("hungerRecoveryPerL",
         new Framework::JSON::JSONNumber(
             (double)zObject->getHungerRecoveryPerL()));
-    result->addValue("thirstRecoveryPerL",
+    zResult->addValue("thirstRecoveryPerL",
         new Framework::JSON::JSONNumber(
             (double)zObject->getThirstRecoveryPerL()));
-    result->addValue("heat",
-        new Framework::JSON::JSONNumber(
-            (double)zObject->getHeat()));
-    Framework::JSON::JSONArray* groupNames = new Framework::JSON::JSONArray();
-    for (Framework::Text* groupName : zObject->getGroupNames())
-    {
-        groupNames->addValue(new Framework::JSON::JSONString(*groupName));
-    }
-    result->addValue("groupNames", groupNames);
-    return result;
+    zResult->addValue(
+        "heat", new Framework::JSON::JSONNumber((double)zObject->getHeat()));
+    BlockTypeFactoryBase::toJson(zObject, zResult);
 }
 
-Framework::JSON::Validator::JSONValidator* FluidBlockTypeFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
-{
-    return builder
-        ->withRequiredAttribute(
-            "model", Game::INSTANCE->zTypeRegistry()->getValidator<ModelInfo>())
-        ->withRequiredString("name")
-        ->finishString()
-        ->withRequiredString("mapColor")
-        ->finishString()
-        ->withRequiredObject("lightWeight")
-        ->withRequiredNumber("red")
-        ->whichIsGreaterOrEqual(0.0)
-        ->whichIsLessOrEqual(1.0)
-        ->finishNumber()
-        ->withRequiredNumber("green")
-        ->whichIsGreaterOrEqual(0.0)
-        ->whichIsLessOrEqual(1.0)
-        ->finishNumber()
-        ->withRequiredNumber("blue")
-        ->whichIsGreaterOrEqual(0.0)
-        ->whichIsLessOrEqual(1.0)
-        ->finishNumber()
-        ->finishObject()
-        ->withRequiredNumber("ticksToFlow")
-        ->whichIsGreaterOrEqual(1.0)
-        ->finishNumber()
-        ->withRequiredNumber("flowDistance")
-        ->whichIsGreaterOrEqual(0.0)
-        ->finishNumber()
-        ->withRequiredNumber("hungerRecoveryPerL")
-        ->whichIsGreaterOrEqual(0.0)
-        ->withDefault(0.0)
-        ->finishNumber()
-        ->withRequiredNumber("thirstRecoveryPerL")
-        ->whichIsGreaterOrEqual(0.0)
-        ->withDefault(0.0)
-        ->finishNumber()
-        ->withRequiredNumber("heat")
-        ->withDefault(10.0)
-        ->finishNumber()
-        ->withRequiredArray("groupNames")
-        ->withDefault(new Framework::JSON::JSONArray())
-        ->addAcceptedStringInArray()
-        ->finishString()
-        ->finishArray()
-        ->finishObject();
+JSONObjectValidationBuilder* FluidBlockTypeFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return BlockTypeFactoryBase::addToValidator(
+        builder->withRequiredObject("lightWeight")
+            ->withRequiredNumber("red")
+            ->whichIsGreaterOrEqual(0.0)
+            ->whichIsLessOrEqual(1.0)
+            ->finishNumber()
+            ->withRequiredNumber("green")
+            ->whichIsGreaterOrEqual(0.0)
+            ->whichIsLessOrEqual(1.0)
+            ->finishNumber()
+            ->withRequiredNumber("blue")
+            ->whichIsGreaterOrEqual(0.0)
+            ->whichIsLessOrEqual(1.0)
+            ->finishNumber()
+            ->finishObject()
+            ->withRequiredNumber("ticksToFlow")
+            ->whichIsGreaterOrEqual(1.0)
+            ->finishNumber()
+            ->withRequiredNumber("flowDistance")
+            ->whichIsGreaterOrEqual(0.0)
+            ->finishNumber()
+            ->withRequiredNumber("hungerRecoveryPerL")
+            ->whichIsGreaterOrEqual(0.0)
+            ->withDefault(0.0)
+            ->finishNumber()
+            ->withRequiredNumber("thirstRecoveryPerL")
+            ->whichIsGreaterOrEqual(0.0)
+            ->withDefault(0.0)
+            ->finishNumber()
+            ->withRequiredNumber("heat")
+            ->withDefault(10.0)
+            ->finishNumber());
 }
 
 Framework::Text FluidBlockTypeFactory::getTypeToken() const

+ 17 - 17
FactoryCraft/FluidBlock.h

@@ -52,16 +52,7 @@ private:
     float heat;
 
 public:
-    FluidBlockType(ModelInfo* model,
-        Framework::Text name,
-        int mapColor,
-        Framework::Vec3<float> lightWeights,
-        int ticktsToFlow,
-        unsigned char flowDistance,
-        float hungerRecoveryPerL,
-        float thirstRecoveryPerL,
-        float heat,
-        Framework::RCArray<Framework::Text> groupNames);
+    FluidBlockType();
 
 protected:
     virtual void loadSuperBlock(Block* zBlock,
@@ -75,23 +66,32 @@ protected:
 
 public:
     bool isFluid() const override;
+    virtual ItemType* createItemType() const override;
+    void setTicktsToFlow(int ticksToFlow);
     int getTicktsToFlow() const;
+    void setFlowDistance(unsigned char flowDistance);
     unsigned char getFlowDistance() const override;
+    void setLightWeights(Framework::Vec3<float> lightWeights);
     Framework::Vec3<float> getLightWeights() const;
+    void setHungerRecoveryPerL(float hungerRecoveryPerL);
     float getHungerRecoveryPerL() const;
+    void setThirstRecoveryPerL(float thirstRecoveryPerL);
     float getThirstRecoveryPerL() const;
-    virtual ItemType* createItemType() const override;
+    void setHeat(float heat);
     float getHeat() const;
 };
 
-class FluidBlockTypeFactory : public SubTypeFactory<BlockType, FluidBlockType>
+class FluidBlockTypeFactory : public BlockTypeFactoryBase<FluidBlockType>
 {
 public:
     FluidBlockTypeFactory();
-    FluidBlockType* fromJson(Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(FluidBlockType* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    FluidBlockType* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(FluidBlockType* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(FluidBlockType* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };

+ 209 - 191
FactoryCraft/FluidContainer.cpp

@@ -2,6 +2,8 @@
 
 #include <TextFeld.h>
 
+#include "Dimension.h"
+#include "Entity.h"
 #include "FluidBlock.h"
 #include "Game.h"
 
@@ -151,19 +153,14 @@ void FluidContainerItem::setFluidTypeId(int fluidTypeId)
     }
 }
 
-FluidContainerItemSkillConfig::FluidContainerItemSkillConfig(
-    BlockFilter* targetFilter,
-    float staminaCost,
-    float staminaCostDevider,
-    float staminaCostDeviderPerLevel,
-    int cooldownTicks,
-    float xpGain)
-    : targetFilter(targetFilter),
-      staminaCost(staminaCost),
-      staminaCostDevider(staminaCostDevider),
-      staminaCostDeviderPerLevel(staminaCostDeviderPerLevel),
-      cooldownTicks(cooldownTicks),
-      xpGain(xpGain)
+FluidContainerItemSkillConfig::FluidContainerItemSkillConfig()
+    : ReferenceCounter(),
+      targetFilter(0),
+      staminaCost(0.5f),
+      staminaCostDevider(0.9f),
+      staminaCostDeviderPerLevel(1.f),
+      cooldownTicks(10),
+      xpGain(0.5f)
 {}
 
 FluidContainerItemSkillConfig::~FluidContainerItemSkillConfig()
@@ -171,31 +168,63 @@ FluidContainerItemSkillConfig::~FluidContainerItemSkillConfig()
     if (targetFilter) targetFilter->release();
 }
 
+void FluidContainerItemSkillConfig::setTargetFilter(BlockFilter* targetFilter)
+{
+    this->targetFilter = targetFilter;
+}
+
 BlockFilter* FluidContainerItemSkillConfig::zTargetFilter() const
 {
     return targetFilter;
 }
 
+void FluidContainerItemSkillConfig::setStaminaCost(float staminaCost)
+{
+    this->staminaCost = staminaCost;
+}
+
 float FluidContainerItemSkillConfig::getStaminaCost() const
 {
     return staminaCost;
 }
 
+void FluidContainerItemSkillConfig::setStaminaCostDevider(
+    float staminaCostDevider)
+{
+    this->staminaCostDevider = staminaCostDevider;
+}
+
 float FluidContainerItemSkillConfig::getStaminaCostDevider() const
 {
     return staminaCostDevider;
 }
 
+void FluidContainerItemSkillConfig::setStaminaCostDeviderPerLevel(
+    float staminaCostDeviderPerLevel)
+{
+    this->staminaCostDeviderPerLevel = staminaCostDeviderPerLevel;
+}
+
 float FluidContainerItemSkillConfig::getStaminaCostDeviderPerLevel() const
 {
     return staminaCostDeviderPerLevel;
 }
 
+void FluidContainerItemSkillConfig::setCooldownTicks(int cooldownTicks)
+{
+    this->cooldownTicks = cooldownTicks;
+}
+
 int FluidContainerItemSkillConfig::getCooldownTicks() const
 {
     return cooldownTicks;
 }
 
+void FluidContainerItemSkillConfig::setXpGain(float xpGain)
+{
+    this->xpGain = xpGain;
+}
+
 float FluidContainerItemSkillConfig::getXpGain() const
 {
     return xpGain;
@@ -205,55 +234,65 @@ FluidContainerItemSkillConfigFactory::FluidContainerItemSkillConfigFactory()
     : TypeFactory()
 {}
 
-FluidContainerItemSkillConfig* FluidContainerItemSkillConfigFactory::fromJson(
-    Framework::JSON::JSONValue* zJson) const
+FluidContainerItemSkillConfig*
+FluidContainerItemSkillConfigFactory::createValue(
+    Framework::JSON::JSONObject* zJson) const
 {
-    return new FluidContainerItemSkillConfig(
+    return new FluidContainerItemSkillConfig();
+}
+
+void FluidContainerItemSkillConfigFactory::fromJson(
+    FluidContainerItemSkillConfig* zResult,
+    Framework::JSON::JSONObject* zJson) const
+{
+    zResult->setTargetFilter(
         Game::INSTANCE->zTypeRegistry()->fromJson<BlockFilter>(
-            zJson->asObject()->zValue("targetFilter")),
-        (float)zJson->asObject()
-            ->zValue("staminaCost")
-            ->asNumber()
-            ->getNumber(),
-        (float)zJson->asObject()
-            ->zValue("staminaCostDevider")
-            ->asNumber()
-            ->getNumber(),
+            zJson->asObject()->zValue("targetFilter")));
+    zResult->setStaminaCost((float)zJson->asObject()
+                                ->zValue("staminaCost")
+                                ->asNumber()
+                                ->getNumber());
+    zResult->setStaminaCostDevider((float)zJson->asObject()
+                                       ->zValue("staminaCostDevider")
+                                       ->asNumber()
+                                       ->getNumber());
+    zResult->setStaminaCostDeviderPerLevel(
         (float)zJson->asObject()
             ->zValue("staminaCostDeviderPerLevel")
             ->asNumber()
-            ->getNumber(),
-        (int)zJson->asObject()
-            ->zValue("cooldownTicks")
-            ->asNumber()
-            ->getNumber(),
+            ->getNumber());
+    zResult->setCooldownTicks((int)zJson->asObject()
+                                  ->zValue("cooldownTicks")
+                                  ->asNumber()
+                                  ->getNumber());
+    zResult->setXpGain(
         (float)zJson->asObject()->zValue("xpGain")->asNumber()->getNumber());
 }
 
-Framework::JSON::JSONValue* FluidContainerItemSkillConfigFactory::toJson(
-    FluidContainerItemSkillConfig* zObject) const
+void FluidContainerItemSkillConfigFactory::toJson(
+    FluidContainerItemSkillConfig* zObject,
+    Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue("targetFilter",
+    zResult->addValue("targetFilter",
         Game::INSTANCE->zTypeRegistry()->toJson(zObject->zTargetFilter()));
-    result->addValue("staminaCost",
+    zResult->addValue("staminaCost",
         new Framework::JSON::JSONNumber(zObject->getStaminaCost()));
-    result->addValue("staminaCostDevider",
+    zResult->addValue("staminaCostDevider",
         new Framework::JSON::JSONNumber(zObject->getStaminaCostDevider()));
-    result->addValue("staminaCostDeviderPerLevel",
+    zResult->addValue("staminaCostDeviderPerLevel",
         new Framework::JSON::JSONNumber(
             zObject->getStaminaCostDeviderPerLevel()));
-    result->addValue("cooldownTicks",
+    zResult->addValue("cooldownTicks",
         new Framework::JSON::JSONNumber(zObject->getCooldownTicks()));
-    result->addValue(
+    zResult->addValue(
         "xpGain", new Framework::JSON::JSONNumber(zObject->getXpGain()));
-    return result;
 }
 
-Framework::JSON::Validator::JSONValidator*
-FluidContainerItemSkillConfigFactory::getValidator() const
+JSONObjectValidationBuilder*
+FluidContainerItemSkillConfigFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
-    return Framework::JSON::Validator::JSONValidator::buildForObject()
+    return builder
         ->withRequiredAttribute("targetFilter",
             Game::INSTANCE->zTypeRegistry()->getValidator<BlockFilter>())
         ->withRequiredNumber("staminaCost")
@@ -275,22 +314,20 @@ FluidContainerItemSkillConfigFactory::getValidator() const
         ->withRequiredNumber("xpGain")
         ->whichIsGreaterOrEqual(0.0)
         ->withDefault(0.5)
-        ->finishNumber()
-        ->finishObject();
-}
-
-FluidContainerItemSkill::FluidContainerItemSkill(float xp,
-    float maxXp,
-    float level,
-    int cooldownTicks,
-    FluidContainerItemSkillConfig* invalidUseConfig,
-    Framework::RCArray<FluidContainerItemSkillConfig> configs)
-    : ItemSkill(xp, maxXp, level),
-      cooldownTicks(cooldownTicks),
-      invalidUseConfig(invalidUseConfig),
-      configs(configs)
+        ->finishNumber();
+}
+
+FluidContainerItemSkill::FluidContainerItemSkill()
+    : ItemSkill(),
+      cooldownTicks(0),
+      invalidUseConfig(0)
 {}
 
+FluidContainerItemSkill::~FluidContainerItemSkill()
+{
+    if (invalidUseConfig) invalidUseConfig->release();
+}
+
 bool FluidContainerItemSkill::use(
     Entity* zActor, Item* zUsedItem, Block* zTarget)
 {
@@ -384,68 +421,81 @@ bool FluidContainerItemSkill::use(
     return false;
 }
 
+void FluidContainerItemSkill::setInvalidUseConfig(
+    FluidContainerItemSkillConfig* invalidUseConfig)
+{
+    if (this->invalidUseConfig) this->invalidUseConfig->release();
+    this->invalidUseConfig = invalidUseConfig;
+}
+
 FluidContainerItemSkillConfig*
 FluidContainerItemSkill::zInvalidUseConfig() const
 {
     return invalidUseConfig;
 }
 
+void FluidContainerItemSkill::addConfig(FluidContainerItemSkillConfig* config)
+{
+    configs.add(config);
+}
+
 const Framework::RCArray<FluidContainerItemSkillConfig>&
 FluidContainerItemSkill::zConfigs() const
 {
     return configs;
 }
 
-FluidContainerItemSkillFactory::FluidContainerItemSkillFactory() {}
+FluidContainerItemSkillFactory::FluidContainerItemSkillFactory()
+    : ItemSkillFactoryBase()
+{}
 
-FluidContainerItemSkill* FluidContainerItemSkillFactory::fromJson(
+FluidContainerItemSkill* FluidContainerItemSkillFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
-    Framework::RCArray<FluidContainerItemSkillConfig> configs;
+    return new FluidContainerItemSkill();
+}
+
+void FluidContainerItemSkillFactory::fromJson(
+    FluidContainerItemSkill* zResult, Framework::JSON::JSONObject* zJson) const
+{
     for (Framework::JSON::JSONValue* configValue :
         *zJson->zValue("configs")->asArray())
     {
-        configs.add(Game::INSTANCE->zTypeRegistry()
-                        ->fromJson<FluidContainerItemSkillConfig>(
-                            configValue->asObject()));
+        zResult->addConfig(Game::INSTANCE->zTypeRegistry()
+                               ->fromJson<FluidContainerItemSkillConfig>(
+                                   configValue->asObject()));
     }
-    return new FluidContainerItemSkill(0,
-        (float)zJson->zValue("maxXp")->asNumber()->getNumber(),
-        1,
-        0,
-        new FluidContainerItemSkillConfig(0,
-            (float)zJson->zValue("invalidUseStaminaCost")
-                ->asNumber()
-                ->getNumber(),
-            (float)zJson->zValue("invalidUseStaminaCostDevider")
-                ->asNumber()
-                ->getNumber(),
-            (float)zJson->zValue("invalidUseStaminaCostDeviderPerLevel")
-                ->asNumber()
-                ->getNumber(),
-            (int)zJson->zValue("invalidUseCooldownTicks")
-                ->asNumber()
-                ->getNumber(),
-            0),
-        configs);
-}
-
-Framework::JSON::JSONObject* FluidContainerItemSkillFactory::toJson(
-    FluidContainerItemSkill* zObject) const
-{
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue(
-        "maxXp", new Framework::JSON::JSONNumber(zObject->getMaxXp()));
-    result->addValue("invalidUseStaminaCost",
+    FluidContainerItemSkillConfig* invalidConfig
+        = new FluidContainerItemSkillConfig();
+    invalidConfig->setStaminaCost(
+        (float)zJson->zValue("invalidUseStaminaCost")->asNumber()->getNumber());
+    invalidConfig->setStaminaCostDevider(
+        (float)zJson->zValue("invalidUseStaminaCostDevider")
+            ->asNumber()
+            ->getNumber());
+    invalidConfig->setStaminaCostDeviderPerLevel(
+        (float)zJson->zValue("invalidUseStaminaCostDeviderPerLevel")
+            ->asNumber()
+            ->getNumber());
+    invalidConfig->setCooldownTicks(
+        (int)zJson->zValue("invalidUseCooldownTicks")->asNumber()->getNumber());
+    zResult->setInvalidUseConfig(invalidConfig);
+    ItemSkillFactoryBase::fromJson(zResult, zJson);
+}
+
+void FluidContainerItemSkillFactory::toJson(FluidContainerItemSkill* zObject,
+    Framework::JSON::JSONObject* zResult) const
+{
+    zResult->addValue("invalidUseStaminaCost",
         new Framework::JSON::JSONNumber(
             zObject->zInvalidUseConfig()->getStaminaCost()));
-    result->addValue("invalidUseStaminaCostDevider",
+    zResult->addValue("invalidUseStaminaCostDevider",
         new Framework::JSON::JSONNumber(
             zObject->zInvalidUseConfig()->getStaminaCostDevider()));
-    result->addValue("invalidUseStaminaCostDeviderPerLevel",
+    zResult->addValue("invalidUseStaminaCostDeviderPerLevel",
         new Framework::JSON::JSONNumber(
             zObject->zInvalidUseConfig()->getStaminaCostDeviderPerLevel()));
-    result->addValue("invalidUseCooldownTicks",
+    zResult->addValue("invalidUseCooldownTicks",
         new Framework::JSON::JSONNumber(
             zObject->zInvalidUseConfig()->getCooldownTicks()));
     Framework::JSON::JSONArray* configs = new Framework::JSON::JSONArray();
@@ -453,14 +503,12 @@ Framework::JSON::JSONObject* FluidContainerItemSkillFactory::toJson(
     {
         configs->addValue(Game::INSTANCE->zTypeRegistry()->toJson(config));
     }
-    result->addValue("configs", configs);
-    return result;
+    zResult->addValue("configs", configs);
+    ItemSkillFactoryBase::toJson(zObject, zResult);
 }
 
-Framework::JSON::Validator::JSONValidator*
-FluidContainerItemSkillFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
+JSONObjectValidationBuilder* FluidContainerItemSkillFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
     return builder->withRequiredNumber("invalidUseStaminaCost")
         ->whichIsGreaterOrEqual(0.0)
@@ -478,16 +526,11 @@ FluidContainerItemSkillFactory::getValidator(
         ->whichIsGreaterOrEqual(0)
         ->withDefault(10)
         ->finishNumber()
-        ->withRequiredNumber("maxXp")
-        ->whichIsGreaterOrEqual(0)
-        ->withDefault(10)
-        ->finishNumber()
         ->withRequiredArray("configs")
         ->addAcceptedTypeInArray(
             Game::INSTANCE->zTypeRegistry()
                 ->getValidator<FluidContainerItemSkillConfig>())
-        ->finishArray()
-        ->finishObject();
+        ->finishArray();
 }
 
 Framework::Text FluidContainerItemSkillFactory::getTypeToken() const
@@ -495,23 +538,17 @@ Framework::Text FluidContainerItemSkillFactory::getTypeToken() const
     return "fluidGathering";
 }
 
-FluidContainerItemType::FluidContainerItemType(Framework::Text name,
-    ModelInfo* model,
-    Framework::JSON::JSONObject* itemSkillConfig,
-    ItemSkillLevelUpRule* levelUpRule,
-    int maxFluidAmount,
-    int maxStackSize,
-    Framework::RCArray<Framework::Text> groups)
-    : ItemType(name, model, maxStackSize, groups),
-      itemSkillConfig(itemSkillConfig),
-      levelUpRule(levelUpRule),
-      maxFluidAmount(maxFluidAmount)
+FluidContainerItemType::FluidContainerItemType()
+    : ItemType(),
+      maxFluidAmount(1000),
+      itemSkillConfig(0),
+      levelUpRule(0)
 {}
 
 FluidContainerItemType::~FluidContainerItemType()
 {
-    itemSkillConfig->release();
-    levelUpRule->release();
+    if (itemSkillConfig) itemSkillConfig->release();
+    if (levelUpRule) levelUpRule->release();
 }
 
 void FluidContainerItemType::loadSuperItem(
@@ -636,107 +673,88 @@ void FluidContainerItemType::addItemAttributes(
     }
 }
 
+void FluidContainerItemType::setItemSkillConfig(
+    Framework::JSON::JSONObject* itemSkillConfig)
+{
+    if (this->itemSkillConfig) this->itemSkillConfig->release();
+    this->itemSkillConfig = itemSkillConfig;
+}
+
 Framework::JSON::JSONObject* FluidContainerItemType::zItemSkillConfig() const
 {
     return itemSkillConfig;
 }
 
+void FluidContainerItemType::setLevelUpRule(ItemSkillLevelUpRule* levelUpRule)
+{
+    if (this->levelUpRule) this->levelUpRule->release();
+    this->levelUpRule = levelUpRule;
+}
+
 ItemSkillLevelUpRule* FluidContainerItemType::zLevelUpRule() const
 {
     return levelUpRule;
 }
 
-int FluidContainerItemType::getMaxFluidAmount() const
+void FluidContainerItemType::setMaxFluidAmount(int maxFluidAmount)
 {
-    return maxFluidAmount;
+    this->maxFluidAmount = maxFluidAmount;
 }
 
-FluidContainerItemType* FluidContainerItemType::setMaxFluidAmount(
-    int maxFluidAmount)
+int FluidContainerItemType::getMaxFluidAmount() const
 {
-    this->maxFluidAmount = maxFluidAmount;
-    return this;
+    return maxFluidAmount;
 }
 
 FluidContainerItemTypeFactory::FluidContainerItemTypeFactory()
-    : SubTypeFactory()
+    : ItemTypeFactoryBase()
 {}
 
-FluidContainerItemType* FluidContainerItemTypeFactory::fromJson(
+FluidContainerItemType* FluidContainerItemTypeFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
-    Framework::RCArray<Framework::Text> groups;
-    for (Framework::JSON::JSONValue* group :
-        *zJson->zValue("groupNames")->asArray())
-    {
-        groups.add(new Framework::Text(group->asString()->getString()));
-    }
-    return new FluidContainerItemType(
-        zJson->zValue("name")->asString()->getString(),
-        Game::INSTANCE->zTypeRegistry()->fromJson<ModelInfo>(
-            zJson->zValue("model")),
-        zJson->getValue("itemSkill")->asObject(),
+    return new FluidContainerItemType();
+}
+
+void FluidContainerItemTypeFactory::fromJson(
+    FluidContainerItemType* zResult, Framework::JSON::JSONObject* zJson) const
+{
+    zResult->setItemSkillConfig(zJson->getValue("itemSkill")->asObject());
+    zResult->setLevelUpRule(
         Game::INSTANCE->zTypeRegistry()->fromJson<ItemSkillLevelUpRule>(
-            zJson->zValue("levelUpRule")),
-        (int)zJson->zValue("maxFluidAmount")->asNumber()->getNumber(),
-        (int)zJson->zValue("maxStack")->asNumber()->getNumber(),
-        groups);
+            zJson->zValue("levelUpRule")));
+    zResult->setMaxFluidAmount(
+        (int)zJson->zValue("maxFluidAmount")->asNumber()->getNumber());
+    ItemTypeFactoryBase::fromJson(zResult, zJson);
 }
 
-Framework::JSON::JSONObject* FluidContainerItemTypeFactory::toJson(
-    FluidContainerItemType* zObject) const
+void FluidContainerItemTypeFactory::toJson(
+    FluidContainerItemType* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue(
-        "name", new Framework::JSON::JSONString(zObject->getName()));
-    result->addValue(
-        "model", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zModel()));
-    result->addValue("levelUpRule",
+    zResult->addValue("levelUpRule",
         Game::INSTANCE->zTypeRegistry()->toJson(zObject->zLevelUpRule()));
-    result->addValue("itemSkill",
+    zResult->addValue("itemSkill",
         dynamic_cast<Framework::JSON::JSONObject*>(
             zObject->zItemSkillConfig()->getThis()));
-    result->addValue("maxFluidAmount",
+    zResult->addValue("maxFluidAmount",
         new Framework::JSON::JSONNumber(zObject->getMaxFluidAmount()));
-    result->addValue("maxStack",
-        new Framework::JSON::JSONNumber(zObject->getMaxStackSize()));
-    Framework::JSON::JSONArray* groups = new Framework::JSON::JSONArray();
-    for (Framework::Text* group : zObject->getGroups())
-    {
-        groups->addValue(new Framework::JSON::JSONString(group->getText()));
-    }
-    result->addValue("groupNames", groups);
-    return result;
-}
-
-Framework::JSON::Validator::JSONValidator*
-FluidContainerItemTypeFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
-{
-    return builder->withRequiredString("name")
-        ->finishString()
-        ->withRequiredAttribute(
-            "model", Game::INSTANCE->zTypeRegistry()->getValidator<ModelInfo>())
-        ->withRequiredAttribute("levelUpRule",
-            Game::INSTANCE->zTypeRegistry()
-                ->getValidator<ItemSkillLevelUpRule>())
-        ->withRequiredAttribute("itemSkill",
-            Game::INSTANCE->zTypeRegistry()->getValidator<ItemSkill>())
-        ->withRequiredNumber("maxFluidAmount")
-        ->whichIsGreaterThen(0)
-        ->withDefault(1000.0)
-        ->finishNumber()
-        ->withRequiredNumber("maxStack")
-        ->withDefault(50.0)
-        ->whichIsGreaterOrEqual(1.0)
-        ->finishNumber()
-        ->withRequiredArray("groupNames")
-        ->addAcceptedStringInArray()
-        ->finishString()
-        ->withDefault(new Framework::JSON::JSONArray())
-        ->finishArray()
-        ->finishObject();
+    ItemTypeFactoryBase::toJson(zObject, zResult);
+}
+
+JSONObjectValidationBuilder* FluidContainerItemTypeFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return ItemTypeFactoryBase::addToValidator(
+        builder
+            ->withRequiredAttribute("levelUpRule",
+                Game::INSTANCE->zTypeRegistry()
+                    ->getValidator<ItemSkillLevelUpRule>())
+            ->withRequiredAttribute("itemSkill",
+                Game::INSTANCE->zTypeRegistry()->getValidator<ItemSkill>())
+            ->withRequiredNumber("maxFluidAmount")
+            ->whichIsGreaterThen(0)
+            ->withDefault(1000.0)
+            ->finishNumber());
 }
 
 Framework::Text FluidContainerItemTypeFactory::getTypeToken() const

+ 39 - 40
FactoryCraft/FluidContainer.h

@@ -44,18 +44,19 @@ private:
     float xpGain;
 
 public:
-    FluidContainerItemSkillConfig(BlockFilter* targetFilter,
-        float staminaCost,
-        float staminaCostDevider,
-        float staminaCostDeviderPerLevel,
-        int cooldownTicks,
-        float xpGain);
+    FluidContainerItemSkillConfig();
     ~FluidContainerItemSkillConfig();
+    void setTargetFilter(BlockFilter* targetFilter);
     BlockFilter* zTargetFilter() const;
+    void setStaminaCost(float staminaCost);
     float getStaminaCost() const;
+    void setStaminaCostDevider(float staminaCostDevider);
     float getStaminaCostDevider() const;
+    void setStaminaCostDeviderPerLevel(float staminaCostDeviderPerLevel);
     float getStaminaCostDeviderPerLevel() const;
+    void setCooldownTicks(int cooldownTicks);
     int getCooldownTicks() const;
+    void setXpGain(float xpGain);
     float getXpGain() const;
 };
 
@@ -64,11 +65,14 @@ class FluidContainerItemSkillConfigFactory
 {
 public:
     FluidContainerItemSkillConfigFactory();
-    FluidContainerItemSkillConfig* fromJson(
-        Framework::JSON::JSONValue* zJson) const override;
-    Framework::JSON::JSONValue* toJson(
-        FluidContainerItemSkillConfig* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator() const override;
+    FluidContainerItemSkillConfig* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(FluidContainerItemSkillConfig* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(FluidContainerItemSkillConfig* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
 };
 
 class FluidContainerItemSkill : public ItemSkill
@@ -79,30 +83,29 @@ private:
     Framework::RCArray<FluidContainerItemSkillConfig> configs;
 
 public:
-    FluidContainerItemSkill(float xp,
-        float maxXp,
-        float level,
-        int cooldownTicks,
-        FluidContainerItemSkillConfig* invalidUseConfig,
-        Framework::RCArray<FluidContainerItemSkillConfig> configs);
+    FluidContainerItemSkill();
+    ~FluidContainerItemSkill();
     virtual bool use(Entity* zActor, Item* zUsedItem, Block* zTarget) override;
     virtual bool use(Entity* zActor, Item* zUsedItem, Entity* zTarget) override;
+    void setInvalidUseConfig(FluidContainerItemSkillConfig* invalidUseConfig);
     FluidContainerItemSkillConfig* zInvalidUseConfig() const;
+    void addConfig(FluidContainerItemSkillConfig* config);
     const Framework::RCArray<FluidContainerItemSkillConfig>& zConfigs() const;
 };
 
 class FluidContainerItemSkillFactory
-    : public SubTypeFactory<ItemSkill, FluidContainerItemSkill>
+    : public ItemSkillFactoryBase<FluidContainerItemSkill>
 {
 public:
     FluidContainerItemSkillFactory();
-    FluidContainerItemSkill* fromJson(
+    FluidContainerItemSkill* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(FluidContainerItemSkill* zResult,
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(
-        FluidContainerItemSkill* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    void toJson(FluidContainerItemSkill* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };
 
@@ -114,13 +117,7 @@ private:
     ItemSkillLevelUpRule* levelUpRule;
 
 public:
-    FluidContainerItemType(Framework::Text name,
-        ModelInfo* model,
-        Framework::JSON::JSONObject* itemSkillConfig,
-        ItemSkillLevelUpRule* levelUpRule,
-        int maxFluidAmount,
-        int maxStackSize,
-        Framework::RCArray<Framework::Text> groups);
+    FluidContainerItemType();
     ~FluidContainerItemType();
 
 protected:
@@ -138,24 +135,26 @@ public:
         Framework::JSON::JSONValue* zValue) const override;
     virtual void addItemAttributes(
         Item* zItem, Framework::JSON::JSONObject* zItemObjet) const override;
+    void setItemSkillConfig(Framework::JSON::JSONObject* itemSkillConfig);
     Framework::JSON::JSONObject* zItemSkillConfig() const;
+    void setLevelUpRule(ItemSkillLevelUpRule* levelUpRule);
     ItemSkillLevelUpRule* zLevelUpRule() const;
+    void setMaxFluidAmount(int maxFluidAmount);
     int getMaxFluidAmount() const;
-
-    FluidContainerItemType* setMaxFluidAmount(int maxFluidAmount);
 };
 
 class FluidContainerItemTypeFactory
-    : public SubTypeFactory<ItemType, FluidContainerItemType>
+    : public ItemTypeFactoryBase<FluidContainerItemType>
 {
 public:
     FluidContainerItemTypeFactory();
-    FluidContainerItemType* fromJson(
+    FluidContainerItemType* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(FluidContainerItemType* zResult,
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(
-        FluidContainerItemType* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    void toJson(FluidContainerItemType* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };

+ 18 - 8
FactoryCraft/Game.cpp

@@ -2,6 +2,8 @@
 
 #include "AddEntityUpdate.h"
 #include "AsynchronCall.h"
+#include "Chat.h"
+#include "Dimension.h"
 #include "Entity.h"
 #include "EntityRemovedUpdate.h"
 #include "ItemEntity.h"
@@ -9,9 +11,16 @@
 #include "MultiblockTree.h"
 #include "NetworkMessage.h"
 #include "NoBlock.h"
-#include "OverworldDimension.h"
 #include "Player.h"
 #include "PlayerHand.h"
+#include "PlayerRegister.h"
+#include "Quest.h"
+#include "RecipieLoader.h"
+#include "Server.h"
+#include "TickOrganizer.h"
+#include "UIController.h"
+#include "WorldGenerator.h"
+#include "WorldLoader.h"
 #include "Zeit.h"
 
 using namespace Framework;
@@ -325,6 +334,7 @@ Game::Game(Framework::Text name, Framework::Text worldsDir)
       nextEntityId(0),
       generator(0),
       loader(0),
+      recipies(new RecipieLoader()),
       chat(0),
       playerRegister(new PlayerRegister(path)),
       uiController(new UIController()),
@@ -365,6 +375,7 @@ Game::~Game()
     playerRegister->release();
     typeRegistry->release();
     uiController->release();
+    recipies->release();
     for (int i = 0; i < blockTypeCount; i++)
     {
         if (blockTypes[i]) blockTypes[i]->release();
@@ -614,7 +625,7 @@ void Game::initialize()
     generator = new WorldGenerator(seed);
     loader = new WorldLoader();
     // load recipies
-    recipies.loadRecipies("data/recipies");
+    recipies->loadRecipies("data/recipies");
     // initialize chat
     chat = new Chat();
     // load quests
@@ -726,7 +737,7 @@ void Game::thread()
                     dynamic_cast<WorldUpdate*>(update->getThis()));
             if (!zDimension(update->getAffectedDimension()))
             {
-                Dimension* dim = typeRegistry->createDimension(
+                Dimension* dim = generator->createDimension(
                     update->getAffectedDimension());
                 if (dim)
                     addDimension(dim);
@@ -812,7 +823,7 @@ void Game::api(Framework::InMemoryBuffer* zRequest, GameClient* zOrigin)
             Dimension* dim = zDimension(zOrigin->zEntity()->getDimensionId());
             if (!dim)
             {
-                dim = typeRegistry->createDimension(
+                dim = generator->createDimension(
                     zOrigin->zEntity()->getDimensionId());
                 if (!dim)
                 {
@@ -873,7 +884,7 @@ void Game::api(Framework::InMemoryBuffer* zRequest, GameClient* zOrigin)
         { // crafting uiml request
             int id;
             zRequest->lese((char*)&id, 4);
-            Text uiml = recipies.getCrafingUIML(id);
+            Text uiml = recipies->getCrafingUIML(id);
             Text dialogId = "crafting_";
             dialogId += id;
             uiController->addDialog(new UIDialog(dialogId,
@@ -1013,8 +1024,7 @@ GameClient* Game::addPlayer(FCKlient* client, Framework::Text name)
     clients->add(gameClient);
     if (!zDimension(player->getDimensionId()))
     {
-        Dimension* dim
-            = typeRegistry->createDimension(player->getDimensionId());
+        Dimension* dim = generator->createDimension(player->getDimensionId());
         if (!dim)
         {
             std::cout << "ERROR: could not create dimension "
@@ -1271,7 +1281,7 @@ Entity* Game::zNearestEntity(int dimensionId,
     return d->zNearestEntity(pos, filter);
 }
 
-const RecipieLoader& Game::getRecipies() const
+RecipieLoader* Game::zRecipies() const
 {
     return recipies;
 }

+ 38 - 31
FactoryCraft/Game.h

@@ -1,45 +1,51 @@
 #pragma once
 
 #include <Critical.h>
+#include <Either.h>
+#include <InMemoryBuffer.h>
 #include <Network.h>
 #include <Punkt.h>
 #include <Text.h>
 #include <Thread.h>
 
-#include "Chat.h"
-#include "Constants.h"
-#include "Dimension.h"
-#include "InMemoryBuffer.h"
-#include "Player.h"
-#include "PlayerRegister.h"
-#include "Quest.h"
-#include "RecipieLoader.h"
-#include "Server.h"
-#include "TickOrganizer.h"
+#include "Area.h"
+#include "NetworkMessage.h"
 #include "TypeRegistry.h"
-#include "UIController.h"
-#include "WorldGenerator.h"
-#include "WorldLoader.h"
 #include "WorldUpdate.h"
 
 class FCKlient;
+class Player;
+class QuestManager;
+class TickOrganizer;
+class WorldGenerator;
+class WorldLoader;
+class RecipieLoader;
+class Chat;
+class PlayerRegister;
+class UIController;
+class EntityType;
+class MultiblockStructureType;
+class ItemStack;
+class BlockType;
+class ItemType;
+class Item;
 
 class GameClient : public Framework::Thread
 {
 private:
     Player* zPlayer;
     FCKlient* client;
-    Critical background;
-    Critical foreground;
-    Critical other;
+    Framework::Critical background;
+    Framework::Critical foreground;
+    Framework::Critical other;
     Framework::Synchronizer updateSync;
-    RCArray<InMemoryBuffer> requests;
-    RCArray<WorldUpdate> updateQueue;
-    RCArray<NetworkMessage> backgroundQueue;
-    RCArray<NetworkMessage> foregroundQueue;
+    Framework::RCArray<Framework::InMemoryBuffer> requests;
+    Framework::RCArray<WorldUpdate> updateQueue;
+    Framework::RCArray<NetworkMessage> backgroundQueue;
+    Framework::RCArray<NetworkMessage> foregroundQueue;
     Framework::Synchronizer foregroundQueueSync;
     Framework::Synchronizer backgroundQueueSync;
-    Critical queueCs;
+    Framework::Critical queueCs;
     Framework::Synchronizer emptyForegroundQueueSync;
     Framework::Synchronizer emptyBackgroundQueueSync;
     int viewDistance;
@@ -57,7 +63,7 @@ public:
     void sendWorldUpdate(WorldUpdate* update);
     void reply();
     void logout();
-    void addMessage(StreamReader* reader);
+    void addMessage(Framework::StreamReader* reader);
     bool isOnline() const;
     void sendResponse(NetworkMessage* response);
     Player* zEntity() const;
@@ -83,16 +89,16 @@ private:
     Framework::RCArray<GameClient>* clients;
     Framework::Array<std::function<void()>> actions;
     QuestManager* questManager;
-    Critical actionsCs;
+    Framework::Critical actionsCs;
     TickOrganizer* ticker;
     Framework::Text path;
     bool stop;
     __int64 tickId;
-    Critical cs;
+    Framework::Critical cs;
     int nextEntityId;
     WorldGenerator* generator;
     WorldLoader* loader;
-    RecipieLoader recipies;
+    RecipieLoader* recipies;
     Chat* chat;
     PlayerRegister* playerRegister;
     UIController* uiController;
@@ -107,7 +113,7 @@ private:
     int itemTypeCount;
     EntityType** entityTypes;
     int entityTypeCount;
-    MultiblockStructureType **multiblockStructureTypes;
+    MultiblockStructureType** multiblockStructureTypes;
     int multiblockStructureTypeCount;
 
     void thread() override;
@@ -118,8 +124,9 @@ public:
     ~Game();
     void initialize();
     void api(Framework::InMemoryBuffer* zRequest, GameClient* zOrigin);
-    void updateLightning(int dimensionId, Vec3<int> location);
-    void updateLightningWithoutWait(int dimensionId, Vec3<int> location);
+    void updateLightning(int dimensionId, Framework::Vec3<int> location);
+    void updateLightningWithoutWait(
+        int dimensionId, Framework::Vec3<int> location);
     void broadcastMessage(NetworkMessage* response);
     void sendMessage(NetworkMessage* response, Entity* zTargetPlayer);
     bool requestWorldUpdate(WorldUpdate* update);
@@ -141,7 +148,7 @@ public:
     int getBlockType(Framework::Vec3<int> location, int dimension);
     Dimension* zDimension(int id) const;
     static Framework::Punkt getChunkCenter(int x, int y);
-    Area getChunckArea(Punkt center) const;
+    Area getChunckArea(Framework::Punkt center) const;
     Framework::Text getWorldDirectory() const;
     void requestArea(Area area);
     void save() const;
@@ -154,7 +161,7 @@ public:
     Entity* zNearestEntity(int dimensionId,
         Framework::Vec3<float> pos,
         std::function<bool(Entity*)> filter);
-    const RecipieLoader& getRecipies() const;
+    RecipieLoader* zRecipies() const;
     void doLater(std::function<void()> action);
     TickOrganizer* zTickOrganizer() const;
     Chat* zChat() const;
@@ -181,6 +188,6 @@ public:
     int getMultiblockStructureTypeCount() const;
 
     static Game* INSTANCE;
-    static Critical INSTANCE_CS;
+    static Framework::Critical INSTANCE_CS;
     static void initialize(Framework::Text name, Framework::Text worldsDir);
 };

+ 44 - 22
FactoryCraft/GeneratorRule.cpp

@@ -2,33 +2,30 @@
 
 #include "JNoise.h"
 
-GeneratorRule::GeneratorRule(
-    Framework::JSON::JSONValue* zConfig, JExpressionMemory* zMemory)
+GeneratorRule::GeneratorRule()
     : ReferenceCounter(),
-      noise(0)
-{
-    if (zConfig->asObject()->hasValue("noise"))
-    {
-        noise = JNoise::parseNoise(
-            zConfig->asObject()->zValue("noise"), zMemory);
-    }
-    condition = JExpressionParser::parseBoolExpression(
-        zConfig->asObject()->zValue("condition"));
-    if (zConfig->asObject()->hasValue("threshold"))
-    {
-        threshold = (float)zConfig->asObject()
-                        ->zValue("threshold")
-                        ->asNumber()
-                        ->getNumber();
-    }
-}
+      noiseConfig(0),
+      noise(0),
+      threshold(0.f),
+      condition(0)
+{}
 
 GeneratorRule::~GeneratorRule()
 {
+    if (noiseConfig) noiseConfig->release();
     if (noise) noise->release();
     if (condition) condition->release();
 }
 
+void GeneratorRule::initialize(JExpressionMemory* zMemory)
+{
+    if (noiseConfig)
+    {
+        if (noise) noise->release();
+        noise = JNoise::parseNoise(noiseConfig, zMemory);
+    }
+}
+
 bool GeneratorRule::checkCondition(
     int x, int y, int z, JExpressionMemory* zMemory)
 {
@@ -43,6 +40,31 @@ Framework::Either<Block*, int> GeneratorRule::generateBlock(
     return createBlock(x, y, z, dimensionId);
 }
 
-GeneratorRuleFactory::GeneratorRuleFactory()
-    : ReferenceCounter()
-{}
+void GeneratorRule::setNoiseConfig(Framework::JSON::JSONObject* noiseConfig) {
+    if (this->noiseConfig) this->noiseConfig->release();
+	this->noiseConfig = noiseConfig;
+}
+
+Framework::JSON::JSONObject* GeneratorRule::zNoiseConfig() const
+{
+    return noiseConfig;
+}
+
+void GeneratorRule::setThreshold(float threshold) {
+    this->threshold = threshold;
+}
+
+float GeneratorRule::getThreshold() const
+{
+    return threshold;
+}
+
+void GeneratorRule::setCondition(JBoolExpression* condition) {
+	if (this->condition) this->condition->release();
+	this->condition = condition;
+}
+
+JBoolExpression* GeneratorRule::zCondition() const
+{
+    return condition;
+}

+ 60 - 8
FactoryCraft/GeneratorRule.h

@@ -6,10 +6,12 @@
 #include "Block.h"
 #include "JNoise.h"
 #include "JsonExpression.h"
+#include "TypeRegistry.h"
 
 class GeneratorRule : public virtual Framework::ReferenceCounter
 {
 private:
+    Framework::JSON::JSONObject* noiseConfig;
     Noise* noise;
     float threshold;
     JBoolExpression* condition;
@@ -20,23 +22,73 @@ protected:
         = 0;
 
 public:
-    GeneratorRule(
-        Framework::JSON::JSONValue* zConfig, JExpressionMemory* zMemory);
+    GeneratorRule();
     ~GeneratorRule();
 
+    void initialize(JExpressionMemory* zMemory);
+
     bool checkCondition(int x, int y, int z, JExpressionMemory* zMemory);
     Framework::Either<Block*, int> generateBlock(
         int x, int y, int z, int dimensionId);
 
-    template<class T>
-    static Framework::JSON::Validator::ObjectValidationBuilder<T>*
-    addToValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<T>* builder)
+    void setNoiseConfig(Framework::JSON::JSONObject* noiseConfig);
+    Framework::JSON::JSONObject* zNoiseConfig() const;
+    void setThreshold(float threshold);
+    float getThreshold() const;
+    void setCondition(JBoolExpression* condition);
+    JBoolExpression* zCondition() const;
+};
+
+template<typename S> class GeneratorRuleFactory
+    : public SubTypeFactory<GeneratorRule, S>
+{
+public:
+    GeneratorRuleFactory()
+        : SubTypeFactory<GeneratorRule, S>()
+    {}
+
+    void fromJson(S* zResult, Framework::JSON::JSONObject* zJson) const override
+    {
+        GeneratorRule* zRule = dynamic_cast<GeneratorRule*>(zResult);
+        if (zJson->hasValue("noise"))
+        {
+            zRule->setNoiseConfig(zJson->getValue("noise")->asObject());
+        }
+        if (zJson->hasValue("threshold"))
+        {
+            zRule->setThreshold(
+                (float)zJson->zValue("threshold")->asNumber()->getNumber());
+        }
+        zRule->setCondition(
+            Game::INSTANCE->zTypeRegistry()->fromJson<JBoolExpression>(
+                zJson->zValue("condition")));
+    }
+
+    void toJson(S* zObject, Framework::JSON::JSONObject* zResult) const override
+    {
+        GeneratorRule* zRule = dynamic_cast<GeneratorRule*>(zObject);
+        if (zRule->zNoiseConfig())
+        {
+            zResult->addValue("noise",
+                dynamic_cast<Framework::JSON::JSONValue*>(
+                    zRule->zNoiseConfig()->getThis()));
+        }
+        zResult->addValue("threshold",
+            new Framework::JSON::JSONNumber(zRule->getThreshold()));
+        zResult->addValue("condition",
+            Game::INSTANCE->zTypeRegistry()->toJson(
+                dynamic_cast<Framework::JSON::JSONValue*>(
+                    zRule->zCondition()->getThis())));
+    }
+
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override
     {
         return builder
             ->withRequiredAttribute("noise", JNoise::getValidator(true))
-            ->withRequiredAttribute(
-                "condition", JExpressionParser::getBoolValidator())
+            ->withRequiredAttribute("condition",
+                Game::INSTANCE->zTypeRegistry()
+                    ->getValidator<JBoolExpression>())
             ->withRequiredNumber("threshold")
             ->whichIsOptional()
             ->whichIsGreaterOrEqual(0.0)

+ 17 - 6
FactoryCraft/GeneratorTemplate.cpp

@@ -1,14 +1,25 @@
 #include "GeneratorTemplate.h"
 
-GeneratorTemplate::GeneratorTemplate(float propability,
-    Framework::Vec3<int> minPosOffset,
-    Framework::Vec3<int> maxSize)
+GeneratorTemplate::GeneratorTemplate()
     : ReferenceCounter(),
-      propability(propability),
-      minPosOffset(minPosOffset),
-      maxSize(maxSize)
+      propability(0.f)
 {}
 
+void GeneratorTemplate::setMinPosOffset(Framework::Vec3<int> minPosOffset)
+{
+    this->minPosOffset = minPosOffset;
+}
+
+void GeneratorTemplate::setMaxSize(Framework::Vec3<int> maxSize)
+{
+    this->maxSize = maxSize;
+}
+
+void GeneratorTemplate::setPropability(float propability)
+{
+    this->propability = propability;
+}
+
 bool GeneratorTemplate::canEffect(
     Framework::Vec3<int> location, Framework::Vec3<int> affectedLocation) const
 {

+ 36 - 3
FactoryCraft/GeneratorTemplate.h

@@ -14,10 +14,14 @@ private:
     Framework::Vec3<int> maxSize;
 
 public:
-    GeneratorTemplate(float propability,
-        Framework::Vec3<int> minPosOffset,
-        Framework::Vec3<int> maxSize);
+    GeneratorTemplate();
 
+protected:
+    void setMinPosOffset(Framework::Vec3<int> minPosOffset);
+    void setMaxSize(Framework::Vec3<int> maxSize);
+
+public:
+    void setPropability(float propability);
     virtual bool canEffect(Framework::Vec3<int> location,
         Framework::Vec3<int> affectedLocation) const;
     virtual GeneratedStructure* generateAt(
@@ -27,4 +31,33 @@ public:
     float getPropability() const;
     Framework::Vec3<int> getMinAffectedOffset() const;
     Framework::Vec3<int> getMaxAffectedOffset() const;
+};
+
+template<typename S> class GeneratorTemplateFactory
+    : public SubTypeFactory<GeneratorTemplate, S>
+{
+public:
+    GeneratorTemplateFactory()
+        : SubTypeFactory<GeneratorTemplate, S>()
+    {}
+
+    void fromJson(S* zResult, Framework::JSON::JSONObject* zJson) const override
+    {
+        GeneratorTemplate* zRecipie = dynamic_cast<GeneratorTemplate*>(zResult);
+        zRecipie->setPropability(
+            (float)zJson->zValue("propability")->asNumber()->getNumber());
+    }
+
+    void toJson(S* zObject, Framework::JSON::JSONObject* zResult) const override
+    {
+        GeneratorTemplate* zRecipie = dynamic_cast<GeneratorTemplate*>(zResult);
+        zResult->addValue("propability",
+            new Framework::JSON::JSONNumber(zRecipie->getPropability()));
+    };
+
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override
+    {
+        return builder->withRequiredNumber("propability")->finishNumber();
+    }
 };

+ 3 - 1
FactoryCraft/GrantCommand.cpp

@@ -1,6 +1,8 @@
 #include "GrantCommand.h"
 
+#include "Chat.h"
 #include "Game.h"
+#include "Player.h"
 
 CrantCommand::CrantCommand()
     : ChatCommand("grant", "Grants a player a permission", 0)
@@ -23,7 +25,7 @@ void CrantCommand::execute(
     if (zTarget)
     {
         zTarget->setChatSecurityLevel(securityLevel);
-        Text message = "The security level of player ";
+        Framework::Text message = "The security level of player ";
         message.append() << *params.z(0) << " is now set to " << securityLevel;
         Game::INSTANCE->zChat()->sendMessageTo(
             message, zActor, Chat::CHANNEL_INFO);

+ 16 - 93
FactoryCraft/Grass.cpp

@@ -26,13 +26,8 @@ void GrassBlock::filterPassingLight(unsigned char rgb[3]) const
     rgb[2] = (unsigned char)(rgb[2] * 0.7);
 }
 
-GrassBlockType::GrassBlockType(ModelInfo* model,
-    Framework::Text name,
-    int mapColor,
-    Framework::Array<SpawnConfig> spawns,
-    Framework::RCArray<Framework::Text> groupNames)
-    : AdditionalItemSpawningBlockType(
-        "", model, name, mapColor, false, 0.1f, spawns, groupNames)
+GrassBlockType::GrassBlockType()
+    : AdditionalItemSpawningBlockType()
 {
     setTransparent(true);
     setPassable(true);
@@ -77,100 +72,28 @@ GrassBlockTypeFactory::GrassBlockTypeFactory()
     : SubTypeFactory()
 {}
 
-GrassBlockType* GrassBlockTypeFactory::fromJson(
+GrassBlockType* GrassBlockTypeFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
-    Framework::RCArray<Framework::Text> groupNames;
-    for (Framework::JSON::JSONValue* value :
-        *zJson->zValue("groupNames")->asArray())
-    {
-        groupNames.add(new Framework::Text(value->asString()->getString()));
-    }
-    Framework::Array<SpawnConfig> spawns;
-    Framework::JSON::JSONArray* spawnsJson = zJson->zValue("spawns")->asArray();
-    for (int i = 0; i < spawnsJson->getLength(); i++)
-    {
-        Framework::JSON::JSONObject* spawnJson
-            = spawnsJson->zValue(i)->asObject();
-        spawns.add(SpawnConfig{
-            (int)spawnJson->zValue("min")->asNumber()->getNumber(),
-            (int)spawnJson->zValue("max")->asNumber()->getNumber(),
-            (float)spawnJson->zValue("chance")->asNumber()->getNumber(),
-            spawnJson->zValue("itemType")->asString()->getString(),
-            0,
-        });
-    }
-    return new GrassBlockType(
-        Game::INSTANCE->zTypeRegistry()->fromJson<ModelInfo>(
-            zJson->zValue("model")),
-        zJson->zValue("name")->asString()->getString(),
-        (int)zJson->zValue("mapColor")->asString()->getString(),
-        spawns,
-        groupNames);
+    return new GrassBlockType();
 }
 
-Framework::JSON::JSONObject* GrassBlockTypeFactory::toJson(
-    GrassBlockType* zObject) const
+void GrassBlockTypeFactory::fromJson(
+    GrassBlockType* zResult, Framework::JSON::JSONObject* zJson) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue(
-        "model", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zModel()));
-    result->addValue(
-        "name", new Framework::JSON::JSONString(zObject->getName()));
-    result->addValue(
-        "mapColor", new Framework::JSON::JSONString(zObject->getMapColor()));
-    Framework::JSON::JSONArray* groupNames = new Framework::JSON::JSONArray();
-    for (Framework::Text* groupName : zObject->getGroupNames())
-    {
-        groupNames->addValue(new Framework::JSON::JSONString(*groupName));
-    }
-    result->addValue("groupNames", groupNames);
-    Framework::JSON::JSONArray* spawns = new Framework::JSON::JSONArray();
-    for (const SpawnConfig& config : zObject->getSpawns())
-    {
-        Framework::JSON::JSONObject* spawn = new Framework::JSON::JSONObject();
-        spawn->addValue(
-            "itemType", new Framework::JSON::JSONString(config.itemTypeName));
-        spawn->addValue(
-            "chance", new Framework::JSON::JSONNumber(config.chance));
-        spawn->addValue("min", new Framework::JSON::JSONNumber(config.min));
-        spawn->addValue("max", new Framework::JSON::JSONNumber(config.max));
-        spawns->addValue(spawn);
-    }
-    result->addValue("spawns", spawns);
-    return result;
+    super.fromJson(zResult, zJson);
 }
 
-Framework::JSON::Validator::JSONValidator* GrassBlockTypeFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
+void GrassBlockTypeFactory::toJson(
+    GrassBlockType* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    return builder
-        ->withRequiredAttribute(
-            "model", Game::INSTANCE->zTypeRegistry()->getValidator<ModelInfo>())
-        ->withRequiredString("name")
-        ->finishString()
-        ->withRequiredString("mapColor")
-        ->finishString()
-        ->withRequiredAttribute("spawns",
-            JSON::Validator::JSONValidator::buildForArray()
-                ->addAcceptedObjectInArray()
-                ->withRequiredString("itemType")
-                ->finishString()
-                ->withRequiredNumber("chance")
-                ->finishNumber()
-                ->withRequiredNumber("min")
-                ->finishNumber()
-                ->withRequiredNumber("max")
-                ->finishNumber()
-                ->finishObject()
-                ->finishArray())
-        ->withRequiredArray("groupNames")
-        ->withDefault(new Framework::JSON::JSONArray())
-        ->addAcceptedStringInArray()
-        ->finishString()
-        ->finishArray()
-        ->finishObject();
+    super.toJson(zObject, zResult);
+}
+
+JSONObjectValidationBuilder* GrassBlockTypeFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return super.addToValidator(builder);
 }
 
 Framework::Text GrassBlockTypeFactory::getTypeToken() const

+ 12 - 11
FactoryCraft/Grass.h

@@ -20,11 +20,7 @@ public:
 class GrassBlockType : public AdditionalItemSpawningBlockType
 {
 public:
-    GrassBlockType(ModelInfo* model,
-        Framework::Text name,
-        int mapColor,
-        Framework::Array<SpawnConfig> spawns,
-        Framework::RCArray<Framework::Text> groupNames);
+    GrassBlockType();
 
 protected:
     virtual void createSuperBlock(Block* zBlock, Item* zItem) const override;
@@ -38,18 +34,23 @@ protected:
         Framework::Vec3<int> position, int dimensionId) const override;
 
 public:
-    Framework::Text getItemTypeName() const;
     virtual ItemType* createItemType() const override;
 };
 
 class GrassBlockTypeFactory : public SubTypeFactory<BlockType, GrassBlockType>
 {
+private:
+    AdditionalItemSpawningBlockTypeFactory super;
+
 public:
     GrassBlockTypeFactory();
-    GrassBlockType* fromJson(Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(GrassBlockType* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    GrassBlockType* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(GrassBlockType* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(GrassBlockType* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };

+ 132 - 93
FactoryCraft/GrowingPlant.cpp

@@ -1,5 +1,6 @@
 #include "GrowingPlant.h"
 
+#include "Dimension.h"
 #include "Game.h"
 
 GrowthState::GrowthState(float percentage, ModelInfo* model)
@@ -97,7 +98,7 @@ void GrowingPlantBlock::sendModelInfo(NetworkMessage* zMessage)
     if (current)
     {
         zMessage->addressBlock(this);
-        InMemoryBuffer buffer;
+        Framework::InMemoryBuffer buffer;
         current->zModel()->writeTo(&buffer);
         char* msg = new char[(int)buffer.getSize() + 1];
         msg[0] = 1; // hmodel change
@@ -108,9 +109,9 @@ void GrowingPlantBlock::sendModelInfo(NetworkMessage* zMessage)
 
 Framework::Text GrowingPlantBlock::getTargetUIML()
 {
-    return Text("<targetInfo><text width=\"auto\" height=\"auto\">") + name
-         + "\n" + "Growth: "
-         + Text((int)(seblingTicks / (float)seblingTicksMax * 100.f))
+    return Framework::Text("<targetInfo><text width=\"auto\" height=\"auto\">")
+         + name + "\n" + "Growth: "
+         + Framework::Text((int)(seblingTicks / (float)seblingTicksMax * 100.f))
          + "%</text></targetInfo>";
 }
 
@@ -130,24 +131,13 @@ GrowingPlantBlock* GrowingPlantBlock::addGrowthState(GrowthState* state)
     return this;
 }
 
-GrowingPlantBlockType::GrowingPlantBlockType(ModelInfo* model,
-    Framework::Text name,
-    Framework::Text blockTypeNameAfterGrowth,
-    const char* readableName,
-    int ticksNeeded,
-    int mapColor,
-    float hardness,
-    Framework::RCArray<Framework::Text> groupNames)
-    : BlockType(
-        0, model, true, 10, false, name, true, mapColor, groupNames, hardness),
+GrowingPlantBlockType::GrowingPlantBlockType()
+    : BlockType(),
       transparent(1),
       passable(1),
       speedModifier(0.3f),
       interactable(1),
-      states(),
-      blockTypeNameAfterGrowth(blockTypeNameAfterGrowth),
-      readableName(readableName),
-      ticksNeeded(ticksNeeded)
+      ticksNeeded(0)
 {}
 
 void GrowingPlantBlockType::createSuperBlock(Block* zBlock, Item* zItem) const
@@ -210,80 +200,135 @@ Framework::Text GrowingPlantBlockType::getBlockTypeNameAfterGrowth() const
     return blockTypeNameAfterGrowth;
 }
 
+void GrowingPlantBlockType::setReadableName(const char* readableName)
+{
+    this->readableName = readableName;
+}
+
 const char* GrowingPlantBlockType::getReadableName() const
 {
     return readableName;
 }
 
+void GrowingPlantBlockType::setTicksNeeded(int ticksNeeded)
+{
+    this->ticksNeeded = ticksNeeded;
+}
+
 int GrowingPlantBlockType::getTicksNeeded() const
 {
     return ticksNeeded;
 }
 
+void GrowingPlantBlockType::setTransparent(bool transparent)
+{
+    this->transparent = transparent;
+}
+
+bool GrowingPlantBlockType::isTransparent() const
+{
+    return transparent;
+}
+
+void GrowingPlantBlockType::setPassable(bool passable)
+{
+    this->passable = passable;
+}
+
+bool GrowingPlantBlockType::isPassable() const
+{
+    return passable;
+}
+
+void GrowingPlantBlockType::setSpeedModifier(float speedModifier)
+{
+    this->speedModifier = speedModifier;
+}
+
+float GrowingPlantBlockType::getSpeedModifier() const
+{
+    return speedModifier;
+}
+
+void GrowingPlantBlockType::setInteractable(bool interactable)
+{
+    this->interactable = interactable;
+}
+
+bool GrowingPlantBlockType::isInteractable() const
+{
+    return interactable;
+}
+
 const Framework::RCArray<GrowthState>& GrowingPlantBlockType::getStates() const
 {
     return states;
 }
 
+void GrowingPlantBlockType::setBlockTypeNameAfterGrowth(
+    Framework::Text blockTypeIdAfterGrowth)
+{}
+
 ItemType* GrowingPlantBlockType::createItemType() const
 {
     return 0;
 }
 
 GrowingPlantBlockTypeFactory::GrowingPlantBlockTypeFactory()
-    : SubTypeFactory()
+    : BlockTypeFactoryBase()
 {}
 
-GrowingPlantBlockType* GrowingPlantBlockTypeFactory::fromJson(
+GrowingPlantBlockType* GrowingPlantBlockTypeFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
-    Framework::RCArray<Framework::Text> groupNames;
-    for (Framework::JSON::JSONValue* value :
-        *zJson->zValue("groupNames")->asArray())
-    {
-        groupNames.add(new Framework::Text(value->asString()->getString()));
-    }
-    GrowingPlantBlockType* result = new GrowingPlantBlockType(
-        Game::INSTANCE->zTypeRegistry()->fromJson<ModelInfo>(
-            zJson->zValue("model")),
-        zJson->zValue("name")->asString()->getString(),
-        zJson->zValue("blockTypeAfterGrowth")->asString()->getString(),
-        zJson->zValue("readableName")->asString()->getString(),
-        (int)zJson->zValue("ticksNeeded")->asNumber()->getNumber(),
-        (int)zJson->zValue("mapColor")->asString()->getString(),
-        (float)zJson->zValue("hardness")->asNumber()->getNumber(),
-        groupNames);
+    return new GrowingPlantBlockType();
+}
+
+void GrowingPlantBlockTypeFactory::fromJson(
+    GrowingPlantBlockType* zResult, Framework::JSON::JSONObject* zJson) const
+{
+    zResult->setBlockTypeNameAfterGrowth(
+        zJson->zValue("blockTypeAfterGrowth")->asString()->getString());
+    zResult->setReadableName(
+        zJson->zValue("readableName")->asString()->getString());
+    zResult->setTicksNeeded(
+        (int)zJson->zValue("ticksNeeded")->asNumber()->getNumber());
+    zResult->setTransparent(zJson->zValue("transparent")->asBool()->getBool());
+    zResult->setPassable(zJson->zValue("passable")->asBool()->getBool());
+    zResult->setSpeedModifier(
+        (float)zJson->zValue("speedModifier")->asNumber()->getNumber());
+    zResult->setInteractable(
+        zJson->zValue("interactable")->asBool()->getBool());
     for (Framework::JSON::JSONValue* state :
         *zJson->zValue("states")->asArray())
     {
-        result->addGrowthState((float)state->asObject()
-                                   ->zValue("percentage")
-                                   ->asNumber()
-                                   ->getNumber(),
+        zResult->addGrowthState((float)state->asObject()
+                                    ->zValue("percentage")
+                                    ->asNumber()
+                                    ->getNumber(),
             Game::INSTANCE->zTypeRegistry()->fromJson<ModelInfo>(
                 state->asObject()->zValue("model")));
     }
-    return result;
+    BlockTypeFactoryBase::fromJson(zResult, zJson);
 }
 
-Framework::JSON::JSONObject* GrowingPlantBlockTypeFactory::toJson(
-    GrowingPlantBlockType* zObject) const
+void GrowingPlantBlockTypeFactory::toJson(
+    GrowingPlantBlockType* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue("readableName",
+    zResult->addValue("readableName",
         new Framework::JSON::JSONString(zObject->getReadableName()));
-    result->addValue(
+    zResult->addValue(
         "model", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zModel()));
-    result->addValue(
+    zResult->addValue(
         "name", new Framework::JSON::JSONString(zObject->getName()));
-    result->addValue(
+    zResult->addValue(
         "hardness", new Framework::JSON::JSONNumber(zObject->getHardness()));
-    result->addValue(
+    zResult->addValue(
         "mapColor", new Framework::JSON::JSONString(zObject->getMapColor()));
-    result->addValue("blockTypeAfterGrowth",
+    zResult->addValue("blockTypeAfterGrowth",
         new Framework::JSON::JSONString(
             zObject->getBlockTypeNameAfterGrowth()));
-    result->addValue("ticksNeeded",
+    zResult->addValue("ticksNeeded",
         new Framework::JSON::JSONNumber((double)zObject->getTicksNeeded()));
     Framework::JSON::JSONArray* states = new Framework::JSON::JSONArray();
     for (GrowthState* state : zObject->getStates())
@@ -296,53 +341,47 @@ Framework::JSON::JSONObject* GrowingPlantBlockTypeFactory::toJson(
             new Framework::JSON::JSONNumber(state->getPercentage()));
         states->addValue(stateObj);
     }
-    result->addValue("states", states);
+    zResult->addValue("states", states);
     Framework::JSON::JSONArray* groupNames = new Framework::JSON::JSONArray();
     for (Framework::Text* groupName : zObject->getGroupNames())
     {
         groupNames->addValue(new Framework::JSON::JSONString(*groupName));
     }
-    result->addValue("groupNames", groupNames);
-    return result;
-}
-
-Framework::JSON::Validator::JSONValidator*
-GrowingPlantBlockTypeFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
-{
-    return builder
-        ->withRequiredAttribute(
-            "model", Game::INSTANCE->zTypeRegistry()->getValidator<ModelInfo>())
-        ->withRequiredString("name")
-        ->finishString()
-        ->withRequiredNumber("hardness")
-        ->withDefault(1.0)
-        ->finishNumber()
-        ->withRequiredString("mapColor")
-        ->finishString()
-        ->withRequiredString("readableName")
-        ->finishString()
-        ->withRequiredNumber("ticksNeeded")
-        ->finishNumber()
-        ->withRequiredString("blockTypeAfterGrowth")
-        ->finishString()
-        ->withRequiredArray("states")
-        ->addAcceptedObjectInArray()
-        ->withRequiredNumber("percentage")
-        ->whichIsGreaterOrEqual(0.0)
-        ->whichIsLessOrEqual(1.0)
-        ->finishNumber()
-        ->withRequiredAttribute(
-            "model", Game::INSTANCE->zTypeRegistry()->getValidator<ModelInfo>())
-        ->finishObject()
-        ->finishArray()
-        ->withRequiredArray("groupNames")
-        ->withDefault(new Framework::JSON::JSONArray())
-        ->addAcceptedStringInArray()
-        ->finishString()
-        ->finishArray()
-        ->finishObject();
+    zResult->addValue("groupNames", groupNames);
+}
+
+JSONObjectValidationBuilder* GrowingPlantBlockTypeFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return BlockTypeFactoryBase::addToValidator(
+        builder->withRequiredString("readableName")
+            ->finishString()
+            ->withRequiredNumber("ticksNeeded")
+            ->finishNumber()
+            ->withRequiredString("blockTypeAfterGrowth")
+            ->finishString()
+            ->withRequiredArray("states")
+            ->addAcceptedObjectInArray()
+            ->withRequiredNumber("percentage")
+            ->whichIsGreaterOrEqual(0.0)
+            ->whichIsLessOrEqual(1.0)
+            ->finishNumber()
+            ->withRequiredAttribute("model",
+                Game::INSTANCE->zTypeRegistry()->getValidator<ModelInfo>())
+            ->finishObject()
+            ->finishArray()
+            ->withRequiredBool("transparent")
+            ->withDefault(true)
+            ->finishBool()
+            ->withRequiredBool("passable")
+            ->withDefault(true)
+            ->finishBool()
+            ->withRequiredNumber("speedModifier")
+            ->withDefault(0.5)
+            ->finishNumber()
+            ->withRequiredBool("interactable")
+            ->withDefault(true)
+            ->finishBool());
 }
 
 Framework::Text GrowingPlantBlockTypeFactory::getTypeToken() const

+ 23 - 18
FactoryCraft/GrowingPlant.h

@@ -60,14 +60,7 @@ private:
     int ticksNeeded;
 
 public:
-    GrowingPlantBlockType(ModelInfo* model,
-        Framework::Text name,
-        Framework::Text blockTypeNameAfterGrowth,
-        const char* readableName,
-        int ticksNeeded,
-        int mapColor,
-        float hardness,
-        Framework::RCArray<Framework::Text> groupNames);
+    GrowingPlantBlockType();
 
 protected:
     virtual void loadSuperBlock(Block* zBlock,
@@ -81,27 +74,39 @@ protected:
         Framework::Vec3<int> position, int dimensionId) const override;
 
 public:
+    virtual ItemType* createItemType() const override;
+
     GrowingPlantBlockType* addGrowthState(
         float growthPercentage, ModelInfo* model);
-
+    const Framework::RCArray<GrowthState>& getStates() const;
+    void setBlockTypeNameAfterGrowth(Framework::Text blockTypeIdAfterGrowth);
     Framework::Text getBlockTypeNameAfterGrowth() const;
+    void setReadableName(const char* readableName);
     const char* getReadableName() const;
+    void setTicksNeeded(int ticksNeeded);
     int getTicksNeeded() const;
-    const Framework::RCArray<GrowthState>& getStates() const;
-    virtual ItemType* createItemType() const override;
+    void setTransparent(bool transparent);
+    bool isTransparent() const;
+    void setPassable(bool passable);
+    bool isPassable() const;
+    void setSpeedModifier(float speedModifier);
+    float getSpeedModifier() const;
+    void setInteractable(bool interactable);
+    bool isInteractable() const;
 };
 
 class GrowingPlantBlockTypeFactory
-    : public SubTypeFactory<BlockType, GrowingPlantBlockType>
+    : public BlockTypeFactoryBase<GrowingPlantBlockType>
 {
 public:
     GrowingPlantBlockTypeFactory();
-    GrowingPlantBlockType* fromJson(
+    GrowingPlantBlockType* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(GrowingPlantBlockType* zResult,
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(
-        GrowingPlantBlockType* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    void toJson(GrowingPlantBlockType* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };

+ 3 - 2
FactoryCraft/Inventory.cpp

@@ -7,6 +7,8 @@
 #include "Entity.h"
 #include "Game.h"
 #include "ItemFilter.h"
+#include "ItemSlot.h"
+#include "ItemStack.h"
 #include "NetworkMessage.h"
 
 using namespace Framework;
@@ -400,8 +402,7 @@ void Inventory::loadInventory(Framework::StreamReader* zReader)
             {
                 int id = 0;
                 zReader->lese((char*)&id, 4);
-                Item* item = Game::INSTANCE->zItemType(id)->loadItem(
-                        zReader);
+                Item* item = Game::INSTANCE->zItemType(id)->loadItem(zReader);
                 stack->addItems(new ItemStack(item, size), NO_DIRECTION);
             }
         }

+ 21 - 16
FactoryCraft/Item.cpp

@@ -2,6 +2,7 @@
 
 #include <Text.h>
 
+#include "Block.h"
 #include "Game.h"
 
 Item::Item(int itemTypeId, Framework::Text name)
@@ -128,11 +129,10 @@ bool Item::canBeStackedWith(const Item* zItem) const
         && zItem->durability == zItem->durability && maxHp == zItem->maxHp
         && eatable == zItem->eatable && placeable == zItem->placeable
         && equippable == zItem->eatable && solid == zItem->solid
-        && usable == zItem->usable
-        && name.istGleich(zItem->name);
+        && usable == zItem->usable && name.istGleich(zItem->name);
 }
 
-bool Item::canBePlacedAt(int dimensionId, Vec3<int> worldPos) const
+bool Item::canBePlacedAt(int dimensionId, Framework::Vec3<int> worldPos) const
 {
     auto b = Game::INSTANCE->zBlockAt(worldPos, dimensionId);
     return (b.isA()
@@ -174,31 +174,37 @@ ItemJsonType::ItemJsonType()
     : TypeFactory()
 {}
 
-Item* ItemJsonType::fromJson(Framework::JSON::JSONValue* zJson) const
+Item* ItemJsonType::createValue(Framework::JSON::JSONObject* zJson) const
+{
+    const ItemType* type = ItemType::zByName(
+        zJson->asObject()->zValue("type")->asString()->getString());
+    return type->createItem();
+}
+
+void ItemJsonType::fromJson(
+    Item* zResult, Framework::JSON::JSONObject* zJson) const
 {
     const ItemType* type = ItemType::zByName(
         zJson->asObject()->zValue("type")->asString()->getString());
-    Item* result = type->createItem();
     for (auto attribute = zJson->asObject()->getFields(); attribute;
          attribute++)
     {
         if (attribute.val().istGleich("type")) continue;
         type->setItemAttribute(
-            result, attribute, zJson->asObject()->zValue(attribute));
+            zResult, attribute, zJson->asObject()->zValue(attribute));
     }
-    return result;
 }
 
-Framework::JSON::JSONValue* ItemJsonType::toJson(Item* zObject) const
+void ItemJsonType::toJson(
+    Item* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue("type",
+    zResult->addValue("type",
         new Framework::JSON::JSONString(zObject->zItemType()->getName()));
-    zObject->zItemType()->addItemAttributes(zObject, result);
-    return result;
+    zObject->zItemType()->addItemAttributes(zObject, zResult);
 }
 
-Framework::JSON::Validator::JSONValidator* ItemJsonType::getValidator() const
+JSONObjectValidationBuilder* ItemJsonType::addToValidator(
+    JSONObjectValidationBuilder *builder) const
 {
     Framework::RCArray<Framework::Text> itemTypes;
     for (int index = 0; index < Game::INSTANCE->getItemTypeCount(); index++)
@@ -209,10 +215,9 @@ Framework::JSON::Validator::JSONValidator* ItemJsonType::getValidator() const
                 Game::INSTANCE->zItemType(index)->getName()));
         }
     }
-    return Framework::JSON::Validator::JSONValidator::buildForObject()
+    return builder
         ->withRequiredString("type")
         ->whichIsOneOf(itemTypes)
         ->finishString()
-        ->allowAdditionalAttriutes()
-        ->finishObject();
+        ->allowAdditionalAttriutes();
 }

+ 7 - 4
FactoryCraft/Item.h

@@ -70,8 +70,11 @@ class ItemJsonType : public TypeFactory<Item>
 {
 public:
     ItemJsonType();
-    Item* fromJson(Framework::JSON::JSONValue* zJson) const override;
-    Framework::JSON::JSONValue* toJson(Item* zObject) const override;
-    Framework::JSON::Validator::JSONValidator*
-    getValidator() const override;
+    Item* createValue(Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(
+        Item* zResult, Framework::JSON::JSONObject* zJson) const override;
+    void toJson(
+        Item* zObject, Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
 };

+ 3 - 1
FactoryCraft/ItemEntity.cpp

@@ -1,6 +1,8 @@
 #include "ItemEntity.h"
 
 #include "Game.h"
+#include "ItemSlot.h"
+#include "ItemStack.h"
 
 #ifdef _WINDOWS
 #    define __INT32_MAX__ 0x7FFFFFFF
@@ -85,7 +87,7 @@ bool ItemEntity::hasDefaultModel() const
     return 0;
 }
 
-ModelInfo *ItemEntity::zSpecialModel() const
+ModelInfo* ItemEntity::zSpecialModel() const
 {
     const ItemType* zItemType = 0;
     if (!slot->isEmpty()) zItemType = slot->zStack()->zItem()->zItemType();

+ 94 - 63
FactoryCraft/ItemFilter.cpp

@@ -25,6 +25,11 @@ bool ItemFilter::matchTargetSlot(ItemSlot* zSlot) const
     return 1;
 }
 
+CombinedItemFilter::CombinedItemFilter()
+    : ItemFilter(),
+      op([](bool a, bool b) { return false; })
+{}
+
 CombinedItemFilter::CombinedItemFilter(
     Framework::RCArray<ItemFilter> filters, std::function<bool(bool, bool)> op)
     : ItemFilter(),
@@ -108,11 +113,21 @@ Framework::Text CombinedItemFilter::getLogicUIML() const
     }
 }
 
+void CombinedItemFilter::addFilter(ItemFilter* filter)
+{
+    filters.add(filter);
+}
+
 const Framework::RCArray<ItemFilter>& CombinedItemFilter::getFilters() const
 {
     return filters;
 }
 
+void CombinedItemFilter::setOp(std::function<bool(bool, bool)> op)
+{
+    this->op = op;
+}
+
 std::function<bool(bool, bool)> CombinedItemFilter::getOp() const
 {
     return op;
@@ -122,8 +137,14 @@ CombinedItemFilterFactory::CombinedItemFilterFactory()
     : SubTypeFactory()
 {}
 
-CombinedItemFilter* CombinedItemFilterFactory::fromJson(
+CombinedItemFilter* CombinedItemFilterFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
+{
+    return new CombinedItemFilter();
+}
+
+void CombinedItemFilterFactory::fromJson(
+    CombinedItemFilter* zResult, Framework::JSON::JSONObject* zJson) const
 {
     std::function<bool(bool, bool)> func;
     Framework::Text op = zJson->zValue("operator")->asString()->getString();
@@ -191,18 +212,18 @@ CombinedItemFilter* CombinedItemFilterFactory::fromJson(
     {
         func = [](bool a, bool b) { return false; };
     }
+    zResult->setOp(func);
     Framework::RCArray<ItemFilter> filters;
     for (Framework::JSON::JSONValue* value :
         *zJson->zValue("filters")->asArray())
     {
-        filters.add(
+        zResult->addFilter(
             Game::INSTANCE->zTypeRegistry()->fromJson<ItemFilter>(value));
     }
-    return new CombinedItemFilter(filters, func);
 }
 
-Framework::JSON::JSONObject* CombinedItemFilterFactory::toJson(
-    CombinedItemFilter* zObject) const
+void CombinedItemFilterFactory::toJson(
+    CombinedItemFilter* zObject, Framework::JSON::JSONObject* zResult) const
 {
     Framework::Text op;
     std::function<bool(bool, bool)> func = zObject->getOp();
@@ -313,20 +334,17 @@ Framework::JSON::JSONObject* CombinedItemFilterFactory::toJson(
         }
     }
     Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue("operator", new Framework::JSON::JSONString(op));
+    zResult->addValue("operator", new Framework::JSON::JSONString(op));
     Framework::JSON::JSONArray* filters = new Framework::JSON::JSONArray();
     for (ItemFilter* filter : zObject->getFilters())
     {
         filters->addValue(Game::INSTANCE->zTypeRegistry()->toJson(filter));
     }
-    result->addValue("filters", filters);
-    return result;
+    zResult->addValue("filters", filters);
 }
 
-Framework::JSON::Validator::JSONValidator*
-CombinedItemFilterFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
+JSONObjectValidationBuilder* CombinedItemFilterFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
     return builder->withRequiredString("operator")
         ->whichIsOneOf({"or",
@@ -349,8 +367,7 @@ CombinedItemFilterFactory::getValidator(
         ->withRequiredArray("filters")
         ->addAcceptedTypeInArray(
             Game::INSTANCE->zTypeRegistry()->getValidator<ItemFilter>())
-        ->finishArray()
-        ->finishObject();
+        ->finishArray();
 }
 
 Framework::Text CombinedItemFilterFactory::getTypeToken() const
@@ -376,23 +393,24 @@ AnyItemFilterFactory::AnyItemFilterFactory()
     : SubTypeFactory()
 {}
 
-AnyItemFilter* AnyItemFilterFactory::fromJson(
+AnyItemFilter* AnyItemFilterFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
     return new AnyItemFilter();
 }
 
-Framework::JSON::JSONObject* AnyItemFilterFactory::toJson(
-    AnyItemFilter* zObject) const
-{
-    return new Framework::JSON::JSONObject();
-}
+void AnyItemFilterFactory::fromJson(
+    AnyItemFilter* zResult, Framework::JSON::JSONObject* zJson) const
+{}
+
+void AnyItemFilterFactory::toJson(
+    AnyItemFilter* zObject, Framework::JSON::JSONObject* zResult) const
+{}
 
-Framework::JSON::Validator::JSONValidator* AnyItemFilterFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
+JSONObjectValidationBuilder* AnyItemFilterFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
-    return builder->finishObject();
+    return builder;
 }
 
 Framework::Text AnyItemFilterFactory::getTypeToken() const
@@ -400,9 +418,9 @@ Framework::Text AnyItemFilterFactory::getTypeToken() const
     return "anyItem";
 }
 
-TypeItemFilter::TypeItemFilter(const ItemType* zType)
+TypeItemFilter::TypeItemFilter()
     : ItemFilter(),
-      type(zType)
+      type(0)
 {}
 
 bool TypeItemFilter::matchItem(const Item* zItem) const
@@ -417,6 +435,11 @@ Framework::Text TypeItemFilter::getLogicUIML() const
     return result;
 }
 
+void TypeItemFilter::setType(const ItemType* type)
+{
+    this->type = type;
+}
+
 const ItemType* TypeItemFilter::zType() const
 {
     return type;
@@ -426,28 +449,30 @@ TypeItemFilterFactory::TypeItemFilterFactory()
     : SubTypeFactory()
 {}
 
-TypeItemFilter* TypeItemFilterFactory::fromJson(
+TypeItemFilter* TypeItemFilterFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
-    return new TypeItemFilter(
-        Game::INSTANCE->zItemType(Game::INSTANCE->getItemTypeId(
-            zJson->zValue("itemType")->asString()->getString())));
+    return new TypeItemFilter();
 }
 
-Framework::JSON::JSONObject* TypeItemFilterFactory::toJson(
-    TypeItemFilter* zObject) const
+void TypeItemFilterFactory::fromJson(
+    TypeItemFilter* zResult, Framework::JSON::JSONObject* zJson) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue("itemType",
+    zResult->setType(Game::INSTANCE->zItemType(Game::INSTANCE->getItemTypeId(
+        zJson->zValue("itemType")->asString()->getString())));
+}
+
+void TypeItemFilterFactory::toJson(
+    TypeItemFilter* zObject, Framework::JSON::JSONObject* zResult) const
+{
+    zResult->addValue("itemType",
         new Framework::JSON::JSONString(zObject->zType()->getName()));
-    return result;
 }
 
-Framework::JSON::Validator::JSONValidator* TypeItemFilterFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
+JSONObjectValidationBuilder* TypeItemFilterFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
-    Framework::RCArray<Text> types;
+    Framework::RCArray<Framework::Text> types;
     for (int i = 0; i < Game::INSTANCE->getItemTypeCount(); i++)
     {
         if (Game::INSTANCE->zItemType(i))
@@ -458,8 +483,7 @@ Framework::JSON::Validator::JSONValidator* TypeItemFilterFactory::getValidator(
     }
     return builder->withRequiredString("itemType")
         ->whichIsOneOf(types)
-        ->finishString()
-        ->finishObject();
+        ->finishString();
 }
 
 Framework::Text TypeItemFilterFactory::getTypeToken() const
@@ -544,9 +568,8 @@ Framework::Text TargetSlotBlacklistFilter::getLogicUIML() const
     return "<anyItem/>";
 }
 
-GroupItemFilter::GroupItemFilter(Framework::RCArray<Framework::Text> groups)
-    : ItemFilter(),
-      groups(groups)
+GroupItemFilter::GroupItemFilter()
+    : ItemFilter()
 {}
 
 bool GroupItemFilter::matchItem(const Item* zItem) const
@@ -563,7 +586,7 @@ bool GroupItemFilter::matchItem(const Item* zItem) const
 
 Framework::Text GroupItemFilter::getLogicUIML() const
 {
-    Framework::RCArray<ItemFilter> filters;
+    CombinedItemFilter filter;
     for (int i = 0; i < Game::INSTANCE->getItemTypeCount(); i++)
     {
         if (Game::INSTANCE->zItemType(i))
@@ -583,12 +606,20 @@ Framework::Text GroupItemFilter::getLogicUIML() const
                 if (found) break;
             }
             if (found)
-                filters.add(new TypeItemFilter(Game::INSTANCE->zItemType(i)));
+            {
+                TypeItemFilter* f = new TypeItemFilter();
+                f->setType(Game::INSTANCE->zItemType(i));
+                filter.addFilter(f);
+            }
         }
     }
-    return CombinedItemFilter(filters, [](bool a, bool b) {
-        return a || b;
-    }).getLogicUIML();
+    filter.setOp([](bool a, bool b) { return a || b; });
+    return filter.getLogicUIML();
+}
+
+void GroupItemFilter::addGroup(const Framework::Text group)
+{
+    groups.add(new Framework::Text(group));
 }
 
 const Framework::RCArray<Framework::Text>& GroupItemFilter::getGroups() const
@@ -600,40 +631,40 @@ GroupItemFilterFactory::GroupItemFilterFactory()
     : SubTypeFactory()
 {}
 
-GroupItemFilter* GroupItemFilterFactory::fromJson(
+GroupItemFilter* GroupItemFilterFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
-    Framework::RCArray<Framework::Text> groups;
+    return new GroupItemFilter();
+}
+
+void GroupItemFilterFactory::fromJson(
+    GroupItemFilter* zResult, Framework::JSON::JSONObject* zJson) const
+{
     for (Framework::JSON::JSONValue* group :
         *zJson->zValue("groupNames")->asArray())
     {
-        groups.add(new Framework::Text(group->asString()->getString()));
+        zResult->addGroup(group->asString()->getString());
     }
-    return new GroupItemFilter(groups);
 }
 
-Framework::JSON::JSONObject* GroupItemFilterFactory::toJson(
-    GroupItemFilter* zObject) const
+void GroupItemFilterFactory::toJson(
+    GroupItemFilter* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
     Framework::JSON::JSONArray* groups = new Framework::JSON::JSONArray();
     for (Framework::Text* group : zObject->getGroups())
     {
         groups->addValue(new Framework::JSON::JSONString(group->getText()));
     }
-    result->addValue("groupNames", groups);
-    return result;
+    zResult->addValue("groupNames", groups);
 }
 
-Framework::JSON::Validator::JSONValidator* GroupItemFilterFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
+JSONObjectValidationBuilder* GroupItemFilterFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
     return builder->withRequiredArray("groupNames")
         ->addAcceptedStringInArray()
         ->finishString()
-        ->finishArray()
-        ->finishObject();
+        ->finishArray();
 }
 
 Framework::Text GroupItemFilterFactory::getTypeToken() const

+ 37 - 24
FactoryCraft/ItemFilter.h

@@ -26,13 +26,16 @@ private:
     std::function<bool(bool, bool)> op;
 
 public:
+    CombinedItemFilter();
     CombinedItemFilter(Framework::RCArray<ItemFilter> filters,
         std::function<bool(bool, bool)> op);
     bool matchItem(const Item* zItem) const override;
     bool matchSourceSlot(ItemSlot* zSlot) const override;
     bool matchTargetSlot(ItemSlot* zSlot) const override;
     Framework::Text getLogicUIML() const override;
+    void addFilter(ItemFilter* filter);
     const Framework::RCArray<ItemFilter>& getFilters() const;
+    void setOp(std::function<bool(bool, bool)> op);
     std::function<bool(bool, bool)> getOp() const;
 };
 
@@ -41,13 +44,14 @@ class CombinedItemFilterFactory
 {
 public:
     CombinedItemFilterFactory();
-    CombinedItemFilter* fromJson(
+    CombinedItemFilter* createValue(
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(
-        CombinedItemFilter* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    void fromJson(CombinedItemFilter* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(CombinedItemFilter* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };
 
@@ -63,11 +67,14 @@ class AnyItemFilterFactory : public SubTypeFactory<ItemFilter, AnyItemFilter>
 {
 public:
     AnyItemFilterFactory();
-    AnyItemFilter* fromJson(Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(AnyItemFilter* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    AnyItemFilter* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(AnyItemFilter* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(AnyItemFilter* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };
 
@@ -77,9 +84,10 @@ private:
     const ItemType* type;
 
 public:
-    TypeItemFilter(const ItemType* zType);
+    TypeItemFilter();
     bool matchItem(const Item* zItem) const override;
     Framework::Text getLogicUIML() const override;
+    void setType(const ItemType* type);
     const ItemType* zType() const;
 };
 
@@ -87,11 +95,14 @@ class TypeItemFilterFactory : public SubTypeFactory<ItemFilter, TypeItemFilter>
 {
 public:
     TypeItemFilterFactory();
-    TypeItemFilter* fromJson(Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(TypeItemFilter* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    TypeItemFilter* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(TypeItemFilter* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(TypeItemFilter* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };
 
@@ -140,9 +151,10 @@ private:
     Framework::RCArray<Framework::Text> groups;
 
 public:
-    GroupItemFilter(Framework::RCArray<Framework::Text> groups);
+    GroupItemFilter();
     bool matchItem(const Item* zItem) const override;
     Framework::Text getLogicUIML() const override;
+    void addGroup(const Framework::Text group);
     const Framework::RCArray<Framework::Text>& getGroups() const;
 };
 
@@ -151,12 +163,13 @@ class GroupItemFilterFactory
 {
 public:
     GroupItemFilterFactory();
-    GroupItemFilter* fromJson(
+    GroupItemFilter* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(GroupItemFilter* zResult,
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(
-        GroupItemFilter* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    void toJson(GroupItemFilter* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };

+ 66 - 64
FactoryCraft/ItemModifier.cpp

@@ -21,24 +21,24 @@ ConsumeItemModifierFactory::ConsumeItemModifierFactory()
     : SubTypeFactory()
 {}
 
-ConsumeItemModifier* ConsumeItemModifierFactory::fromJson(
+ConsumeItemModifier* ConsumeItemModifierFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
     return new ConsumeItemModifier();
 }
 
-Framework::JSON::JSONObject* ConsumeItemModifierFactory::toJson(
-    ConsumeItemModifier* zObject) const
-{
-    return new Framework::JSON::JSONObject();
-}
+void ConsumeItemModifierFactory::fromJson(
+    ConsumeItemModifier* zResult, Framework::JSON::JSONObject* zJson) const
+{}
 
-Framework::JSON::Validator::JSONValidator*
-ConsumeItemModifierFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
+void ConsumeItemModifierFactory::toJson(
+    ConsumeItemModifier* zObject, Framework::JSON::JSONObject* zResult) const
+{}
+
+JSONObjectValidationBuilder* ConsumeItemModifierFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
-    return builder->finishObject();
+    return builder;
 }
 
 Framework::Text ConsumeItemModifierFactory::getTypeToken() const
@@ -59,24 +59,24 @@ DoNothingModifierFactory::DoNothingModifierFactory()
     : SubTypeFactory()
 {}
 
-DoNothingModifier* DoNothingModifierFactory::fromJson(
+DoNothingModifier* DoNothingModifierFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
     return new DoNothingModifier();
 }
 
-Framework::JSON::JSONObject* DoNothingModifierFactory::toJson(
-    DoNothingModifier* zObject) const
-{
-    return new Framework::JSON::JSONObject();
-}
+void DoNothingModifierFactory::fromJson(
+    DoNothingModifier* zResult, Framework::JSON::JSONObject* zJson) const
+{}
+
+void DoNothingModifierFactory::toJson(
+    DoNothingModifier* zObject, Framework::JSON::JSONObject* zResult) const
+{}
 
-Framework::JSON::Validator::JSONValidator*
-DoNothingModifierFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
+JSONObjectValidationBuilder* DoNothingModifierFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
-    return builder->finishObject();
+    return builder;
 }
 
 Framework::Text DoNothingModifierFactory::getTypeToken() const
@@ -84,12 +84,8 @@ Framework::Text DoNothingModifierFactory::getTypeToken() const
     return "doNothing";
 }
 
-AttributeItemModifier::AttributeItemModifier(
-    Framework::RCArray<Framework::Text> attribute,
-    Framework::RCArray<Framework::JSON::JSONValue> value)
-    : ItemModifier(),
-      attributes(attribute),
-      values(value)
+AttributeItemModifier::AttributeItemModifier()
+    : ItemModifier()
 {}
 
 void AttributeItemModifier::applyOn(Item* zItem)
@@ -105,6 +101,13 @@ void AttributeItemModifier::applyOn(Item* zItem)
     }
 }
 
+void AttributeItemModifier::addAttribute(
+    Framework::Text name, Framework::JSON::JSONValue* value)
+{
+    attributes.add(new Framework::Text(name));
+    values.add(value);
+}
+
 const Framework::RCArray<Framework::Text>&
 AttributeItemModifier::getAttributes() const
 {
@@ -121,49 +124,46 @@ AttributeItemModifierFactory::AttributeItemModifierFactory()
     : SubTypeFactory()
 {}
 
-AttributeItemModifier* AttributeItemModifierFactory::fromJson(
+AttributeItemModifier* AttributeItemModifierFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
-    Framework::RCArray<Framework::Text> attributes;
-    Framework::RCArray<Framework::JSON::JSONValue> values;
+    return new AttributeItemModifier();
+}
+
+void AttributeItemModifierFactory::fromJson(
+    AttributeItemModifier* zResult, Framework::JSON::JSONObject* zJson) const
+{
     auto attribute = zJson->getFields();
     auto value = zJson->getValues();
     while (attribute, value)
     {
         if (!attribute.val().istGleich("type"))
         {
-            attributes.add(new Framework::Text(attribute.val()));
-            values.add(
-                dynamic_cast<Framework::JSON::JSONValue*>(value->getThis()));
+            zResult->addAttribute(attribute.val(), value);
         }
         attribute++;
         value++;
     }
-    return new AttributeItemModifier(attributes, values);
 }
 
-Framework::JSON::JSONObject* AttributeItemModifierFactory::toJson(
-    AttributeItemModifier* zObject) const
+void AttributeItemModifierFactory::toJson(
+    AttributeItemModifier* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
     auto attribute = zObject->getAttributes().begin();
     auto value = zObject->getValues().begin();
     while (attribute && value)
     {
-        result->addValue(attribute->getText(),
+        zResult->addValue(attribute->getText(),
             dynamic_cast<Framework::JSON::JSONObject*>(value->getThis()));
         attribute++;
         value++;
     }
-    return result;
 }
 
-Framework::JSON::Validator::JSONValidator*
-AttributeItemModifierFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
+JSONObjectValidationBuilder* AttributeItemModifierFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
-    return builder->allowAdditionalAttriutes()->finishObject();
+    return builder->allowAdditionalAttriutes();
 }
 
 Framework::Text AttributeItemModifierFactory::getTypeToken() const
@@ -171,10 +171,8 @@ Framework::Text AttributeItemModifierFactory::getTypeToken() const
     return "attributes";
 }
 
-CombinedItemModifier::CombinedItemModifier(
-    Framework::RCArray<ItemModifier> modifiers)
-    : ItemModifier(),
-      modifiers()
+CombinedItemModifier::CombinedItemModifier()
+    : ItemModifier()
 {}
 
 void CombinedItemModifier::applyOn(Item* zItem)
@@ -185,6 +183,11 @@ void CombinedItemModifier::applyOn(Item* zItem)
     }
 }
 
+void CombinedItemModifier::addModifier(ItemModifier* zModifier)
+{
+    modifiers.add(zModifier);
+}
+
 const Framework::RCArray<ItemModifier>&
 CombinedItemModifier::getModifiers() const
 {
@@ -195,42 +198,41 @@ CombinedItemModifierFactory::CombinedItemModifierFactory()
     : SubTypeFactory()
 {}
 
-CombinedItemModifier* CombinedItemModifierFactory::fromJson(
+CombinedItemModifier* CombinedItemModifierFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
-    Framework::RCArray<ItemModifier> modifiers;
+    return new CombinedItemModifier();
+}
+
+void CombinedItemModifierFactory::fromJson(
+    CombinedItemModifier* zResult, Framework::JSON::JSONObject* zJson) const
+{
     for (Framework::JSON::JSONValue* value :
         *zJson->zValue("modifiers")->asArray())
     {
-        modifiers.add(
+        zResult->addModifier(
             Game::INSTANCE->zTypeRegistry()->fromJson<ItemModifier>(value));
     }
-    return new CombinedItemModifier(modifiers);
 }
 
-Framework::JSON::JSONObject* CombinedItemModifierFactory::toJson(
-    CombinedItemModifier* zObject) const
+void CombinedItemModifierFactory::toJson(
+    CombinedItemModifier* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
     Framework::JSON::JSONArray* modifiers = new Framework::JSON::JSONArray();
     for (ItemModifier* modifier : zObject->getModifiers())
     {
         modifiers->addValue(Game::INSTANCE->zTypeRegistry()->toJson(modifier));
     }
-    result->addValue("modifiers", modifiers);
-    return result;
+    zResult->addValue("modifiers", modifiers);
 }
 
-Framework::JSON::Validator::JSONValidator*
-CombinedItemModifierFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
+JSONObjectValidationBuilder* CombinedItemModifierFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
     return builder->withRequiredArray("modifiers")
         ->addAcceptedTypeInArray(
             Game::INSTANCE->zTypeRegistry()->getValidator<ItemModifier>())
-        ->finishArray()
-        ->finishObject();
+        ->finishArray();
 }
 
 Framework::Text CombinedItemModifierFactory::getTypeToken() const

+ 32 - 27
FactoryCraft/ItemModifier.h

@@ -24,13 +24,14 @@ class ConsumeItemModifierFactory
 {
 public:
     ConsumeItemModifierFactory();
-    ConsumeItemModifier* fromJson(
+    ConsumeItemModifier* createValue(
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(
-        ConsumeItemModifier* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    void fromJson(ConsumeItemModifier* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(ConsumeItemModifier* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };
 
@@ -46,13 +47,14 @@ class DoNothingModifierFactory
 {
 public:
     DoNothingModifierFactory();
-    DoNothingModifier* fromJson(
+    DoNothingModifier* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(DoNothingModifier* zResult,
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(
-        DoNothingModifier* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    void toJson(DoNothingModifier* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };
 
@@ -63,9 +65,9 @@ private:
     Framework::RCArray<Framework::JSON::JSONValue> values;
 
 public:
-    AttributeItemModifier(Framework::RCArray<Framework::Text> attribute,
-        Framework::RCArray<Framework::JSON::JSONValue> value);
+    AttributeItemModifier();
     void applyOn(Item* zItem) override;
+    void addAttribute(Framework::Text name, Framework::JSON::JSONValue* value);
     const Framework::RCArray<Framework::Text>& getAttributes() const;
     const Framework::RCArray<Framework::JSON::JSONValue>& getValues() const;
 };
@@ -75,13 +77,14 @@ class AttributeItemModifierFactory
 {
 public:
     AttributeItemModifierFactory();
-    AttributeItemModifier* fromJson(
+    AttributeItemModifier* createValue(
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(
-        AttributeItemModifier* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    void fromJson(AttributeItemModifier* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(AttributeItemModifier* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };
 
@@ -90,8 +93,9 @@ class CombinedItemModifier : public ItemModifier
     Framework::RCArray<ItemModifier> modifiers;
 
 public:
-    CombinedItemModifier(Framework::RCArray<ItemModifier> modifiers);
+    CombinedItemModifier();
     void applyOn(Item* zItem) override;
+    void addModifier(ItemModifier* zModifier);
     const Framework::RCArray<ItemModifier>& getModifiers() const;
 };
 
@@ -100,12 +104,13 @@ class CombinedItemModifierFactory
 {
 public:
     CombinedItemModifierFactory();
-    CombinedItemModifier* fromJson(
+    CombinedItemModifier* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(CombinedItemModifier* zResult,
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(
-        CombinedItemModifier* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    void toJson(CombinedItemModifier* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };

+ 4 - 4
FactoryCraft/ItemSkill.cpp

@@ -4,11 +4,11 @@
 #include "Entity.h"
 #include "ItemType.h"
 
-ItemSkill::ItemSkill(float xp, float maxXp, float level)
+ItemSkill::ItemSkill()
     : Framework::ReferenceCounter(),
-      xp(xp),
-      maxXP(maxXp),
-      level(level),
+      xp(10.f),
+      maxXP(10.f),
+      level(1.f),
       itemTypeId(-1)
 {}
 

+ 42 - 2
FactoryCraft/ItemSkill.h

@@ -1,9 +1,10 @@
 #pragma once
 
 #include <JSON.h>
+#include <Reader.h>
 #include <ReferenceCounter.h>
 
-#include "Reader.h"
+#include "TypeRegistry.h"
 
 class ItemType;
 class ItemSkill;
@@ -27,7 +28,7 @@ private:
     int itemTypeId;
 
 public:
-    ItemSkill(float xp, float maxXp, float level);
+    ItemSkill();
     virtual void load(Framework::StreamReader* zReader);
     virtual void save(Framework::StreamWriter* zWriter);
     virtual bool use(Entity* zActor, Item* zUsedItem, Block* zTarget) = 0;
@@ -42,4 +43,43 @@ public:
     float getLevel() const;
     void setItemTypeId(int itemTypeId);
     int getItemTypeId() const;
+};
+
+template<typename S> class ItemSkillFactoryBase
+    : public SubTypeFactory<ItemSkill, S>
+{
+public:
+    ItemSkillFactoryBase()
+        : SubTypeFactory<ItemSkill, S>(){};
+
+    virtual void fromJson(
+        S* zResult, Framework::JSON::JSONObject* zJson) const override
+    {
+        ItemSkill* zSkill = dynamic_cast<ItemSkill*>(zResult);
+        zSkill->setMaxXp(
+            (float)zJson->zValue("maxXp")->asNumber()->getNumber());
+        zSkill->setLevel(
+            (float)zJson->zValue("level")->asNumber()->getNumber());
+    }
+
+    virtual void toJson(
+        S* zObject, Framework::JSON::JSONObject* zResult) const override
+    {
+        ItemSkill* zSkill = dynamic_cast<ItemSkill*>(zObject);
+        zResult->addValue(
+            "maxXp", new Framework::JSON::JSONNumber(zSkill->getMaxXp()));
+        zResult->addValue(
+            "level", new Framework::JSON::JSONNumber(zSkill->getLevel()));
+    }
+
+    virtual JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override
+    {
+        return builder->withRequiredNumber("maxXp")
+            ->withDefault(10.f)
+            ->finishNumber()
+            ->withRequiredNumber("level")
+            ->withDefault(1.f)
+            ->finishNumber();
+    }
 };

+ 71 - 44
FactoryCraft/ItemType.cpp

@@ -7,30 +7,20 @@
 #include "ItemSkill.h"
 #include "ItemStack.h"
 
-ItemType::ItemType(Framework::Text name,
-    ModelInfo* model,
-    int maxStackSize,
-    Framework::RCArray<Framework::Text> groups)
+ItemType::ItemType()
     : ReferenceCounter(),
-      name(name),
-      model(model),
-      maxStackSize(maxStackSize),
-      groups(groups)
-{
-    tooltipUIML = Framework::Text("<tip><text width=\"auto\" height=\"auto\">")
-                + name + "</text></tip>";
-}
+      name(""),
+      tooltipUIML(""),
+      model(0),
+      maxStackSize(0),
+      groups()
+{}
 
 ItemType::~ItemType()
 {
     if (model) model->release();
 }
 
-bool ItemType::initialize(Game* zGame)
-{
-    return true;
-}
-
 void ItemType::loadSuperItem(
     Item* zItem, Framework::StreamReader* zReader) const
 {
@@ -68,19 +58,9 @@ void ItemType::saveSuperItem(
     zWriter->schreibe(zItem->name, len);
 }
 
-int ItemType::getId() const
-{
-    return id;
-}
-
-const Framework::Text& ItemType::getName() const
-{
-    return name;
-}
-
-const Framework::Text& ItemType::getTooltipUIML() const
+bool ItemType::initialize(Game* zGame)
 {
-    return tooltipUIML;
+    return true;
 }
 
 const ItemType* ItemType::zBrokenItemType() const
@@ -102,19 +82,6 @@ ItemSkill* ItemType::createDefaultItemSkill() const
 
 void ItemType::levelUpItemSkill(ItemSkill* zSkill) const {}
 
-Item* ItemType::loadItem(Framework::StreamReader* zReader) const
-{
-    Item* item = createItem();
-    loadSuperItem(item, zReader);
-    return item;
-}
-
-void ItemType::saveItem(
-    const Item* zItem, Framework::StreamWriter* zWriter) const
-{
-    saveSuperItem(zItem, zWriter);
-}
-
 Item* ItemType::cloneItem(const Item* zItem) const
 {
     Framework::InMemoryBuffer buffer;
@@ -127,9 +94,17 @@ Item* ItemType::breakItem(const Item* zItem) const
     return 0;
 }
 
-ModelInfo* ItemType::zModel() const
+Item* ItemType::loadItem(Framework::StreamReader* zReader) const
 {
-    return model;
+    Item* item = createItem();
+    loadSuperItem(item, zReader);
+    return item;
+}
+
+void ItemType::saveItem(
+    const Item* zItem, Framework::StreamWriter* zWriter) const
+{
+    saveSuperItem(zItem, zWriter);
 }
 
 void ItemType::setItemAttribute(
@@ -182,11 +157,63 @@ void ItemType::setTypeId(int id)
     this->id = id;
 }
 
+int ItemType::getId() const
+{
+    return id;
+}
+
+void ItemType::setName(Framework::Text name)
+{
+    this->name = name;
+    if (!tooltipUIML.getLength())
+    {
+        tooltipUIML
+            = Framework::Text("<tip><text width=\"auto\" height=\"auto\">")
+            + name + "</text></tip>";
+    }
+}
+
+const Framework::Text& ItemType::getName() const
+{
+    return name;
+}
+
+void ItemType::setTooltipUIML(Framework::Text tooltipUIML)
+{
+    this->tooltipUIML = tooltipUIML;
+}
+
+const Framework::Text& ItemType::getTooltipUIML() const
+{
+    return tooltipUIML;
+}
+
+void ItemType::setModel(ModelInfo* model)
+{
+    if (this->model) this->model->release();
+    this->model = model;
+}
+
+ModelInfo* ItemType::zModel() const
+{
+    return model;
+}
+
+void ItemType::setMaxStackSize(int maxStackSize)
+{
+    this->maxStackSize = maxStackSize;
+}
+
 int ItemType::getMaxStackSize() const
 {
     return maxStackSize;
 }
 
+void ItemType::addGroup(Framework::Text group)
+{
+    groups.add(new Framework::Text(group));
+}
+
 const Framework::RCArray<Framework::Text>& ItemType::getGroups() const
 {
     return groups;

+ 96 - 14
FactoryCraft/ItemType.h

@@ -7,6 +7,7 @@
 
 #include "BlockType.h"
 #include "Effect.h"
+#include "Game.h"
 #include "ModelInfo.h"
 
 class Item;
@@ -24,47 +25,55 @@ class ItemType : public virtual Framework::ReferenceCounter
 {
 protected:
     int id;
-    const Framework::Text name;
+    Framework::Text name;
     Framework::Text tooltipUIML;
-    ModelInfo *model;
+    ModelInfo* model;
     int maxStackSize;
     Framework::RCArray<Framework::Text> groups;
 
-    ItemType(Framework::Text name,
-        ModelInfo* model,
-        int maxStackSize,
-        Framework::RCArray<Framework::Text> groups);
+public:
+    ItemType();
+    ~ItemType();
 
+protected:
     virtual void loadSuperItem(
         Item* zItem, Framework::StreamReader* zReader) const;
     virtual void saveSuperItem(
         const Item* zItem, Framework::StreamWriter* zWriter) const;
 
 public:
-    ~ItemType();
     virtual bool initialize(Game* zGame);
-
-    int getId() const;
-    const Framework::Text& getName() const;
-    const Framework::Text& getTooltipUIML() const;
     virtual const ItemType* zBrokenItemType() const;
+
     virtual Item* createItem() const = 0;
+
     virtual ItemStack* createItemStack(int size) const;
     virtual ItemSkill* createDefaultItemSkill() const;
     virtual void levelUpItemSkill(ItemSkill* zSkill) const;
+    virtual Item* cloneItem(const Item* zItem) const;
+    virtual Item* breakItem(const Item* zItem) const;
+
     virtual Item* loadItem(Framework::StreamReader* zReader) const;
     virtual void saveItem(
         const Item* zItem, Framework::StreamWriter* zWriter) const;
-    virtual Item* cloneItem(const Item* zItem) const;
-    virtual Item* breakItem(const Item* zItem) const;
-    ModelInfo* zModel() const;
+
     virtual void setItemAttribute(Item* zItem,
         Framework::Text name,
         Framework::JSON::JSONValue* zValue) const;
     virtual void addItemAttributes(
         Item* zItem, Framework::JSON::JSONObject* zItemObjet) const;
+
     void setTypeId(int id);
+    int getId() const;
+    void setName(Framework::Text name);
+    const Framework::Text& getName() const;
+    void setTooltipUIML(Framework::Text tooltipUIML);
+    const Framework::Text& getTooltipUIML() const;
+    void setModel(ModelInfo* model);
+    ModelInfo* zModel() const;
+    void setMaxStackSize(int maxStackSize);
     int getMaxStackSize() const;
+    void addGroup(Framework::Text group);
     const Framework::RCArray<Framework::Text>& getGroups() const;
 
     static Item* createBasicItem(int id,
@@ -80,4 +89,77 @@ public:
         bool usable);
     static int getTypeId(const char* name);
     static const ItemType* zByName(const char* name);
+};
+
+template<typename S> class ItemTypeFactoryBase
+    : public SubTypeFactory<ItemType, S>
+{
+public:
+    ItemTypeFactoryBase()
+        : SubTypeFactory<ItemType, S>()
+    {}
+
+    virtual void fromJson(
+        S* zResult, Framework::JSON::JSONObject* zJson) const override
+    {
+        ItemType* zType = dynamic_cast<ItemType*>(zResult);
+        zType->setModel(Game::INSTANCE->zTypeRegistry()->fromJson<ModelInfo>(
+            zJson->zValue("model")->asObject()));
+        zType->setName(zJson->zValue("name")->asString()->getString());
+        if (zJson->hasValue("tooltipUIML"))
+        {
+            zType->setTooltipUIML(
+                zJson->zValue("tooltipUIML")->asString()->getString());
+        }
+        zType->setMaxStackSize(
+            (int)zJson->zValue("maxStack")->asNumber()->getNumber());
+        for (Framework::JSON::JSONValue* value :
+            *zJson->zValue("groupNames")->asArray())
+        {
+            zType->addGroup(value->asString()->getString());
+        }
+    }
+
+    virtual void toJson(
+        S* zObject, Framework::JSON::JSONObject* zResult) const override
+    {
+        ItemType* zType = dynamic_cast<ItemType*>(zResult);
+        zResult->addValue("model",
+            Game::INSTANCE->zTypeRegistry()->toJson<ModelInfo>(
+                zType->zModel()));
+        zResult->addValue(
+            "name", new Framework::JSON::JSONString(zType->getName()));
+        zResult->addValue("tooltipUIML",
+            new Framework::JSON::JSONString(zType->getTooltipUIML()));
+        zResult->addValue("maxStack",
+            new Framework::JSON::JSONNumber(zType->getMaxStackSize()));
+        Framework::JSON::JSONArray* groupNames
+            = new Framework::JSON::JSONArray();
+        for (Framework::Text* groupName : zType->getGroups())
+        {
+            groupNames->addValue(new Framework::JSON::JSONString(*groupName));
+        }
+        zResult->addValue("groupNames", groupNames);
+    }
+
+    virtual JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override
+    {
+        return builder
+            ->withRequiredAttribute("model",
+                Game::INSTANCE->zTypeRegistry()->getValidator<ModelInfo>())
+            ->withRequiredString("name")
+            ->finishString()
+            ->withRequiredString("tooltipUIML")
+            ->whichIsOptional()
+            ->finishString()
+            ->withRequiredNumber("maxStack")
+            ->withDefault(50)
+            ->finishNumber()
+            ->withRequiredArray("groupNames")
+            ->withDefault(new Framework::JSON::JSONArray())
+            ->addAcceptedStringInArray()
+            ->finishString()
+            ->finishArray();
+    }
 };

+ 10 - 8
FactoryCraft/JNoise.cpp

@@ -2,13 +2,13 @@
 
 #include "FactorizeNoise.h"
 #include "FastNoiseWrapper.h"
+#include "FlattenNoise.h"
+#include "Game.h"
 #include "MultiplyNoise.h"
-#include "RandNoise.h"
 #include "NegateNoise.h"
-#include "FlattenNoise.h"
+#include "RandNoise.h"
 #include "ScaleNoise.h"
 
-
 using namespace Framework;
 
 Noise* JNoise::parseNoise(JSON::JSONValue* zConfig, JExpressionMemory* zMemory)
@@ -17,7 +17,7 @@ Noise* JNoise::parseNoise(JSON::JSONValue* zConfig, JExpressionMemory* zMemory)
     if (type.istGleich("random"))
     {
         JFloatExpression* seedExpression
-            = JExpressionParser::parseFloatExpression(
+            = Game::INSTANCE->zTypeRegistry()->fromJson<JFloatExpression>(
                 zConfig->asObject()->zValue("seed"));
         float seed = seedExpression->getValue(zMemory);
         return new RandNoise((int)(round(seed)));
@@ -61,7 +61,7 @@ Noise* JNoise::parseNoise(JSON::JSONValue* zConfig, JExpressionMemory* zMemory)
     else
     {
         JFloatExpression* seedExpression
-            = JExpressionParser::parseFloatExpression(
+            = Game::INSTANCE->zTypeRegistry()->fromJson<JFloatExpression>(
                 zConfig->asObject()->zValue("seed"));
         float seed = seedExpression->getValue(zMemory);
         FastNoiseLite* noise = new FastNoiseLite((int)(round(seed)));
@@ -340,7 +340,8 @@ JSON::Validator::JSONValidator* JNoise::getValidator(bool optional)
                               ->withExactMatch("random")
                               ->finishString()
                               ->withRequiredAttribute("seed",
-                                  JExpressionParser::getFloatValidator())
+                                  Game::INSTANCE->zTypeRegistry()
+                                      ->getValidator<JFloatExpression>())
                               ->finishObject())
         ->addAcceptedType(validator2->setObjectReferenceId("jn_factorize")
                               ->withRequiredString("type")
@@ -410,8 +411,9 @@ JSON::Validator::JSONValidator* JNoise::getValidator(bool optional)
                     "OpenSimplex2",
                     "Value"})
                 ->finishString()
-                ->withRequiredAttribute(
-                    "seed", JExpressionParser::getFloatValidator())
+                ->withRequiredAttribute("seed",
+                    Game::INSTANCE->zTypeRegistry()
+                        ->getValidator<JFloatExpression>())
                 ->withRequiredString("rotationType3D")
                 ->whichIsOptional()
                 ->whichIsOneOf({"None", "ImproveXYPlanes", "ImproveXZPlanes"})

+ 720 - 403
FactoryCraft/JsonExpression.cpp

@@ -1,5 +1,6 @@
 #include "JsonExpression.h"
 
+#include "Dimension.h"
 #include "DimensionGenerator.h"
 #include "Game.h"
 
@@ -76,9 +77,8 @@ JBoolExpression::JBoolExpression()
     : ReferenceCounter()
 {}
 
-JVariableFloatExpression::JVariableFloatExpression(Framework::Text name)
-    : JFloatExpression(),
-      name(name)
+JVariableFloatExpression::JVariableFloatExpression()
+    : JFloatExpression()
 {}
 
 float JVariableFloatExpression::getValue(JExpressionMemory* zMemory)
@@ -86,9 +86,52 @@ float JVariableFloatExpression::getValue(JExpressionMemory* zMemory)
     return zMemory->getFloatVariable(name);
 }
 
-JVariableBoolExpression::JVariableBoolExpression(Framework::Text name)
-    : JBoolExpression(),
-      name(name)
+void JVariableFloatExpression::setName(Framework::Text name)
+{
+    this->name = name;
+}
+
+Framework::Text JVariableFloatExpression::getName() const
+{
+    return name;
+}
+
+JVariableFloatExpressionFactory::JVariableFloatExpressionFactory()
+    : SubTypeFactory()
+{}
+
+JVariableFloatExpression* JVariableFloatExpressionFactory::createValue(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new JVariableFloatExpression();
+}
+
+void JVariableFloatExpressionFactory::fromJson(
+    JVariableFloatExpression* zResult, Framework::JSON::JSONObject* zJson) const
+{
+    zResult->setName(zJson->zValue("name")->asString()->getString());
+}
+
+void JVariableFloatExpressionFactory::toJson(JVariableFloatExpression* zObject,
+    Framework::JSON::JSONObject* zResult) const
+{
+    zResult->addValue(
+        "name", new Framework::JSON::JSONString(zObject->getName()));
+}
+
+JSONObjectValidationBuilder* JVariableFloatExpressionFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return builder->withRequiredString("name")->finishString();
+}
+
+Framework::Text JVariableFloatExpressionFactory::getTypeToken() const
+{
+    return "variable";
+}
+
+JVariableBoolExpression::JVariableBoolExpression()
+    : JBoolExpression()
 {}
 
 bool JVariableBoolExpression::getValue(JExpressionMemory* zMemory)
@@ -96,9 +139,53 @@ bool JVariableBoolExpression::getValue(JExpressionMemory* zMemory)
     return zMemory->getBoolVariable(name);
 }
 
-JConstantFloatExpression::JConstantFloatExpression(float value)
+void JVariableBoolExpression::setName(Framework::Text name)
+{
+    this->name = name;
+}
+
+Framework::Text JVariableBoolExpression::getName() const
+{
+    return name;
+}
+
+JVariableBoolExpressionFactory::JVariableBoolExpressionFactory()
+    : SubTypeFactory()
+{}
+
+JVariableBoolExpression* JVariableBoolExpressionFactory::createValue(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new JVariableBoolExpression();
+}
+
+void JVariableBoolExpressionFactory::fromJson(
+    JVariableBoolExpression* zResult, Framework::JSON::JSONObject* zJson) const
+{
+    zResult->setName(zJson->zValue("name")->asString()->getString());
+}
+
+void JVariableBoolExpressionFactory::toJson(JVariableBoolExpression* zObject,
+    Framework::JSON::JSONObject* zResult) const
+{
+    zResult->addValue(
+        "name", new Framework::JSON::JSONString(zObject->getName()));
+}
+
+JSONObjectValidationBuilder* JVariableBoolExpressionFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return builder->withRequiredString("name")->finishString();
+}
+
+Framework::Text JVariableBoolExpressionFactory::getTypeToken() const
+{
+    return "variable";
+}
+
+JConstantFloatExpression::JConstantFloatExpression()
     : JFloatExpression(),
-      value(value)
+      value(0)
 {}
 
 float JConstantFloatExpression::getValue(JExpressionMemory* zMemory)
@@ -106,9 +193,52 @@ float JConstantFloatExpression::getValue(JExpressionMemory* zMemory)
     return value;
 }
 
-JConstantBoolExpression::JConstantBoolExpression(bool value)
-    : JBoolExpression(),
-      value(value)
+void JConstantFloatExpression::setValue(float value)
+{
+    this->value = value;
+}
+
+float JConstantFloatExpression::getValue() const
+{
+    return value;
+}
+
+JConstantFloatExpressionFactory::JConstantFloatExpressionFactory()
+    : SubTypeFactory()
+{}
+
+JConstantFloatExpression* JConstantFloatExpressionFactory::createValue(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new JConstantFloatExpression();
+}
+
+void JConstantFloatExpressionFactory::fromJson(
+    JConstantFloatExpression* zResult, Framework::JSON::JSONObject* zJson) const
+{
+    zResult->setValue((float)zJson->zValue("value")->asNumber()->getNumber());
+}
+
+void JConstantFloatExpressionFactory::toJson(JConstantFloatExpression* zObject,
+    Framework::JSON::JSONObject* zResult) const
+{
+    zResult->addValue(
+        "value", new Framework::JSON::JSONNumber(zObject->getValue()));
+}
+
+JSONObjectValidationBuilder* JConstantFloatExpressionFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return builder->withRequiredNumber("value")->finishNumber();
+}
+
+Framework::Text JConstantFloatExpressionFactory::getTypeToken() const
+{
+    return "constant";
+}
+
+JConstantBoolExpression::JConstantBoolExpression()
+    : JBoolExpression()
 {}
 
 bool JConstantBoolExpression::getValue(JExpressionMemory* zMemory)
@@ -116,22 +246,62 @@ bool JConstantBoolExpression::getValue(JExpressionMemory* zMemory)
     return value;
 }
 
-JNoiseFloatExpression::JNoiseFloatExpression(Framework::Text name,
-    JFloatExpression* x,
-    JFloatExpression* y,
-    JFloatExpression* z)
+void JConstantBoolExpression::setValue(bool value)
+{
+    this->value = value;
+}
+
+bool JConstantBoolExpression::getValue() const
+{
+    return value;
+}
+
+JConstantBoolExpressionFactory::JConstantBoolExpressionFactory()
+    : SubTypeFactory()
+{}
+
+JConstantBoolExpression* JConstantBoolExpressionFactory::createValue(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new JConstantBoolExpression();
+}
+
+void JConstantBoolExpressionFactory::fromJson(
+    JConstantBoolExpression* zResult, Framework::JSON::JSONObject* zJson) const
+{
+    zResult->setValue(zJson->zValue("value")->asBool()->getBool());
+}
+
+void JConstantBoolExpressionFactory::toJson(JConstantBoolExpression* zObject,
+    Framework::JSON::JSONObject* zResult) const
+{
+    zResult->addValue(
+        "value", new Framework::JSON::JSONBool(zObject->getValue()));
+}
+
+JSONObjectValidationBuilder* JConstantBoolExpressionFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return builder->withRequiredBool("value")->finishBool();
+}
+
+Framework::Text JConstantBoolExpressionFactory::getTypeToken() const
+{
+    return "constant";
+}
+
+JNoiseFloatExpression::JNoiseFloatExpression()
     : JFloatExpression(),
-      name(name),
-      x(x),
-      y(y),
-      z(z)
+      x(0),
+      y(0),
+      z(0)
 {}
 
 JNoiseFloatExpression::~JNoiseFloatExpression()
 {
-    x->release();
-    y->release();
-    z->release();
+    if (x) x->release();
+    if (y) y->release();
+    if (z) z->release();
 }
 
 float JNoiseFloatExpression::getValue(JExpressionMemory* zMemory)
@@ -140,24 +310,112 @@ float JNoiseFloatExpression::getValue(JExpressionMemory* zMemory)
         name, x->getValue(zMemory), y->getValue(zMemory), z->getValue(zMemory));
 }
 
-JOperatorFloatExpression::JOperatorFloatExpression(
-    std::function<float(float a, float b)> accumulator,
-    Framework::RCArray<JFloatExpression>* values)
-    : JFloatExpression(),
-      accumulator(accumulator),
-      values(values)
+void JNoiseFloatExpression::setName(Framework::Text name)
+{
+    this->name = name;
+}
+
+Framework::Text JNoiseFloatExpression::getName() const
+{
+    return name;
+}
+
+void JNoiseFloatExpression::setX(JFloatExpression* x)
+{
+    if (this->x) this->x->release();
+    this->x = x;
+}
+
+JFloatExpression* JNoiseFloatExpression::zX() const
+{
+    return x;
+}
+
+void JNoiseFloatExpression::setY(JFloatExpression* y)
+{
+    if (this->y) this->y->release();
+    this->y = y;
+}
+
+JFloatExpression* JNoiseFloatExpression::zY() const
+{
+    return y;
+}
+
+void JNoiseFloatExpression::setZ(JFloatExpression* z)
+{
+    if (this->z) this->z->release();
+    this->z = z;
+}
+
+JFloatExpression* JNoiseFloatExpression::zZ() const
+{
+    return z;
+}
+
+JNoiseFloatExpressionFactory::JNoiseFloatExpressionFactory()
+    : SubTypeFactory()
 {}
 
-JOperatorFloatExpression::~JOperatorFloatExpression()
+JNoiseFloatExpression* JNoiseFloatExpressionFactory::createValue(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new JNoiseFloatExpression();
+}
+
+void JNoiseFloatExpressionFactory::fromJson(
+    JNoiseFloatExpression* zResult, Framework::JSON::JSONObject* zJson) const
 {
-    values->release();
+    zResult->setName(zJson->zValue("name")->asString()->getString());
+    zResult->setX(Game::INSTANCE->zTypeRegistry()->fromJson<JFloatExpression>(
+        zJson->zValue("x")));
+    zResult->setY(Game::INSTANCE->zTypeRegistry()->fromJson<JFloatExpression>(
+        zJson->zValue("y")));
+    zResult->setZ(Game::INSTANCE->zTypeRegistry()->fromJson<JFloatExpression>(
+        zJson->zValue("z")));
 }
 
+void JNoiseFloatExpressionFactory::toJson(
+    JNoiseFloatExpression* zObject, Framework::JSON::JSONObject* zResult) const
+{
+    zResult->addValue(
+        "name", new Framework::JSON::JSONString(zObject->getName()));
+    zResult->addValue(
+        "x", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zX()));
+    zResult->addValue(
+        "y", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zY()));
+    zResult->addValue(
+        "z", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zZ()));
+}
+
+JSONObjectValidationBuilder* JNoiseFloatExpressionFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return builder->withRequiredString("name")
+        ->finishString()
+        ->withRequiredAttribute("x",
+            Game::INSTANCE->zTypeRegistry()->getValidator<JFloatExpression>())
+        ->withRequiredAttribute("y",
+            Game::INSTANCE->zTypeRegistry()->getValidator<JFloatExpression>())
+        ->withRequiredAttribute("z",
+            Game::INSTANCE->zTypeRegistry()->getValidator<JFloatExpression>());
+}
+
+Framework::Text JNoiseFloatExpressionFactory::getTypeToken() const
+{
+    return "noise";
+}
+
+JOperatorFloatExpression::JOperatorFloatExpression()
+    : JFloatExpression(),
+      accumulator([](float a, float b) { return 0.f; })
+{}
+
 float JOperatorFloatExpression::getValue(JExpressionMemory* zMemory)
 {
     bool first = 1;
     float val = 0.f;
-    for (JFloatExpression* expression : *values)
+    for (JFloatExpression* expression : values)
     {
         if (first)
         {
@@ -172,24 +430,108 @@ float JOperatorFloatExpression::getValue(JExpressionMemory* zMemory)
     return val;
 }
 
-JBoolOperatorBoolExpression::JBoolOperatorBoolExpression(
-    std::function<bool(bool a, bool b)> accumulator,
-    Framework::RCArray<JBoolExpression>* values)
-    : JBoolExpression(),
-      accumulator(accumulator),
-      values(values)
+void JOperatorFloatExpression::setOperator(
+    Framework::Text op, std::function<float(float a, float b)> accumulator)
+{
+    this->op = op;
+    this->accumulator = accumulator;
+}
+
+Framework::Text JOperatorFloatExpression::getOperator()
+{
+    return op;
+}
+
+void JOperatorFloatExpression::addValue(JFloatExpression* value)
+{
+    values.add(value);
+}
+
+const Framework::RCArray<JFloatExpression>&
+JOperatorFloatExpression::getValues() const
+{
+    return values;
+}
+
+JOperatorFloatExpressionFactory::JOperatorFloatExpressionFactory()
+    : SubTypeFactory()
 {}
 
-JBoolOperatorBoolExpression::~JBoolOperatorBoolExpression()
+JOperatorFloatExpression* JOperatorFloatExpressionFactory::createValue(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new JOperatorFloatExpression();
+}
+
+void JOperatorFloatExpressionFactory::fromJson(
+    JOperatorFloatExpression* zResult, Framework::JSON::JSONObject* zJson) const
+{
+    Framework::Text op = zJson->zValue("operator")->asString()->getString();
+    if (op.istGleich("+"))
+    {
+        zResult->setOperator("+", [](float a, float b) { return a + b; });
+    }
+    else if (op.istGleich("-"))
+    {
+        zResult->setOperator("-", [](float a, float b) { return a - b; });
+    }
+    else if (op.istGleich("*"))
+    {
+        zResult->setOperator("*", [](float a, float b) { return a * b; });
+    }
+    else if (op.istGleich("/"))
+    {
+        zResult->setOperator("/", [](float a, float b) { return a / b; });
+    }
+    for (Framework::JSON::JSONValue* value :
+        *zJson->zValue("values")->asArray())
+    {
+        zResult->addValue(
+            Game::INSTANCE->zTypeRegistry()->fromJson<JFloatExpression>(value));
+    }
+}
+
+void JOperatorFloatExpressionFactory::toJson(JOperatorFloatExpression* zObject,
+    Framework::JSON::JSONObject* zResult) const
 {
-    values->release();
+    zResult->addValue(
+        "operator", new Framework::JSON::JSONString(zObject->getOperator()));
+    Framework::JSON::JSONArray* values = new Framework::JSON::JSONArray();
+    for (JFloatExpression* expression : zObject->getValues())
+    {
+        values->addValue(
+            Game::INSTANCE->zTypeRegistry()->toJson<JFloatExpression>(
+                expression));
+    }
+    zResult->addValue("values", values);
+}
+
+JSONObjectValidationBuilder* JOperatorFloatExpressionFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return builder->withRequiredString("operator")
+        ->whichIsOneOf({"+", "-", "*", "/"})
+        ->finishString()
+        ->withRequiredArray("values")
+        ->addAcceptedTypeInArray(
+            Game::INSTANCE->zTypeRegistry()->getValidator<JFloatExpression>())
+        ->finishArray();
 }
 
+Framework::Text JOperatorFloatExpressionFactory::getTypeToken() const
+{
+    return "operator";
+}
+
+JBoolOperatorBoolExpression::JBoolOperatorBoolExpression()
+    : JBoolExpression()
+{}
+
 bool JBoolOperatorBoolExpression::getValue(JExpressionMemory* zMemory)
 {
     bool first = 1;
     bool val = 0;
-    for (JBoolExpression* expression : *values)
+    for (JBoolExpression* expression : values)
     {
         if (first)
         {
@@ -204,25 +546,102 @@ bool JBoolOperatorBoolExpression::getValue(JExpressionMemory* zMemory)
     return val;
 }
 
-JFloatOperatorBoolExpression::JFloatOperatorBoolExpression(
-    std::function<bool(float a, float b)> accumulator,
-    Framework::RCArray<JFloatExpression>* values)
-    : JBoolExpression(),
-      accumulator(accumulator),
-      values(values)
+void JBoolOperatorBoolExpression::setOperator(
+    Framework::Text op, std::function<float(float a, float b)> accumulator)
+{
+    this->op = op;
+    this->accumulator = accumulator;
+}
+
+Framework::Text JBoolOperatorBoolExpression::getOperator()
+{
+    return op;
+}
+
+void JBoolOperatorBoolExpression::addValue(JBoolExpression* value)
+{
+    values.add(value);
+}
+
+const Framework::RCArray<JBoolExpression>&
+JBoolOperatorBoolExpression::getValues() const
+{
+    return values;
+}
+
+JBoolOperatorBoolExpressionFactory::JBoolOperatorBoolExpressionFactory()
+    : SubTypeFactory()
 {}
 
-JFloatOperatorBoolExpression::~JFloatOperatorBoolExpression()
+JBoolOperatorBoolExpression* JBoolOperatorBoolExpressionFactory::createValue(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new JBoolOperatorBoolExpression();
+}
+
+void JBoolOperatorBoolExpressionFactory::fromJson(
+    JBoolOperatorBoolExpression* zResult,
+    Framework::JSON::JSONObject* zJson) const
 {
-    values->release();
+    for (Framework::JSON::JSONValue* value : *zJson->zValue("values")->asArray())
+    {
+        zResult->addValue(
+            Game::INSTANCE->zTypeRegistry()->fromJson<JBoolExpression>(value));
+    }
+    Framework::Text op = zJson->zValue("operator")->asString()->getString();
+    if (op.istGleich("&&"))
+    {
+        zResult->setOperator("&&", [](bool a, bool b) { return a && b; });
+    }
+    else if (op.istGleich("||"))
+    {
+        zResult->setOperator("||", [](bool a, bool b) { return a || b; });
+    }
 }
 
+void JBoolOperatorBoolExpressionFactory::toJson(
+    JBoolOperatorBoolExpression* zObject,
+    Framework::JSON::JSONObject* zResult) const
+{
+    Framework::JSON::JSONArray* values = new Framework::JSON::JSONArray();
+    for (JBoolExpression* expression : zObject->getValues())
+    {
+        values->addValue(
+            Game::INSTANCE->zTypeRegistry()->toJson<JBoolExpression>(
+                expression));
+    }
+    zResult->addValue("values", values);
+    zResult->addValue(
+        "operator", new Framework::JSON::JSONString(zObject->getOperator()));
+}
+
+JSONObjectValidationBuilder* JBoolOperatorBoolExpressionFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return builder->withRequiredString("operator")
+        ->whichIsOneOf({"&&", "||"})
+        ->finishString()
+        ->withRequiredArray("values")
+        ->addAcceptedTypeInArray(
+            Game::INSTANCE->zTypeRegistry()->getValidator<JBoolExpression>())
+        ->finishArray();
+}
+
+Framework::Text JBoolOperatorBoolExpressionFactory::getTypeToken() const
+{
+    return "operator";
+}
+
+JFloatOperatorBoolExpression::JFloatOperatorBoolExpression()
+    : JBoolExpression()
+{}
+
 bool JFloatOperatorBoolExpression::getValue(JExpressionMemory* zMemory)
 {
     bool first = 1;
     bool val = 1;
     float last = 0.f;
-    for (JFloatExpression* expression : *values)
+    for (JFloatExpression* expression : values)
     {
         float current = expression->getValue(zMemory);
         if (!first) val &= accumulator(last, current);
@@ -232,393 +651,291 @@ bool JFloatOperatorBoolExpression::getValue(JExpressionMemory* zMemory)
     return val;
 }
 
-JBlockTypeBoolExpression::JBlockTypeBoolExpression(
-    int typeId, JFloatExpression* x, JFloatExpression* y, JFloatExpression* z)
-    : JBoolExpression(),
-      typeId(typeId),
-      x(x),
-      y(y),
-      z(z)
-{}
+void JFloatOperatorBoolExpression::setOperator(
+    Framework::Text op, std::function<bool(float a, float b)> accumulator)
+{
+    this->op = op;
+    this->accumulator = accumulator;
+}
 
-JBlockTypeBoolExpression ::~JBlockTypeBoolExpression()
+Framework::Text JFloatOperatorBoolExpression::getOperator()
 {
-    x->release();
-    y->release();
-    z->release();
+    return op;
 }
 
-bool JBlockTypeBoolExpression::getValue(JExpressionMemory* zMemory)
+void JFloatOperatorBoolExpression::addValue(JFloatExpression* value)
 {
-    int x = (int)(round(this->x->getValue(zMemory)));
-    int y = (int)(round(this->y->getValue(zMemory)));
-    int z = (int)(round(this->z->getValue(zMemory)));
-    if (z < 0 || z >= WORLD_HEIGHT
-        || !zMemory->zCurrentChunk()
-        || Game::getChunkCenter(x, y) != zMemory->zCurrentChunk()->getCenter())
-    {
-        return 0;
-    }
-    return zMemory->zCurrentChunk()->getBlockTypeAt(
-               Dimension::chunkCoordinates({x, y, z}))
-        == typeId;
+    values.add(value);
 }
 
-using namespace Framework::JSON;
-using namespace Framework::JSON::Validator;
+const Framework::RCArray<JFloatExpression>&
+JFloatOperatorBoolExpression::getValues() const
+{
+    return values;
+}
 
-JFloatExpression* JExpressionParser::parseFloatExpression(
-    Framework::JSON::JSONValue* zValue)
+JFloatOperatorBoolExpressionFactory::JFloatOperatorBoolExpressionFactory()
+    : SubTypeFactory()
+{}
+
+JFloatOperatorBoolExpression* JFloatOperatorBoolExpressionFactory::createValue(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new JFloatOperatorBoolExpression();
+}
+
+void JFloatOperatorBoolExpressionFactory::fromJson(
+    JFloatOperatorBoolExpression* zResult,
+    Framework::JSON::JSONObject* zJson) const
 {
-    JSONObject* obj = zValue->asObject();
-    Framework::Text type = obj->zValue("type")->asString()->getString();
-    if (type.istGleich("variable"))
+    Framework::Text op = zJson->zValue("operator")->asString()->getString();
+    if (op.istGleich(">"))
     {
-        return new JVariableFloatExpression(
-            obj->zValue("name")->asString()->getString());
+        return zResult->setOperator(
+            ">", [](float a, float b) { return a > b; });
     }
-    else if (type.istGleich("constant"))
+    else if (op.istGleich("<"))
     {
-        return new JConstantFloatExpression(
-            (float)obj->zValue("value")->asNumber()->getNumber());
+        return zResult->setOperator(
+            "<", [](float a, float b) { return a < b; });
     }
-    else if (type.istGleich("noise"))
+    else if (op.istGleich(">="))
     {
-        return new JNoiseFloatExpression(
-            obj->zValue("name")->asString()->getString(),
-            parseFloatExpression(obj->zValue("x")),
-            parseFloatExpression(obj->zValue("y")),
-            parseFloatExpression(obj->zValue("z")));
+        return zResult->setOperator(
+            ">=", [](float a, float b) { return a >= b; });
     }
-    else if (type.istGleich("operator"))
+    else if (op.istGleich("<="))
     {
-        Framework::RCArray<JFloatExpression>* values
-            = new Framework::RCArray<JFloatExpression>();
-        JSONArray* valuesArray = obj->zValue("values")->asArray();
-        for (JSONValue* value : *valuesArray)
-        {
-            values->add(parseFloatExpression(value));
-        }
-        Framework::Text op = obj->zValue("operator")->asString()->getString();
-        if (op.istGleich("+"))
-        {
-            return new JOperatorFloatExpression(
-                [](float a, float b) { return a + b; }, values);
-        }
-        else if (op.istGleich("-"))
-        {
-            return new JOperatorFloatExpression(
-                [](float a, float b) { return a - b; }, values);
-        }
-        else if (op.istGleich("*"))
-        {
-            return new JOperatorFloatExpression(
-                [](float a, float b) { return a * b; }, values);
-        }
-        else if (op.istGleich("/"))
-        {
-            return new JOperatorFloatExpression(
-                [](float a, float b) { return a / b; }, values);
-        }
-        else
-        {
-            values->release();
-        }
+        return zResult->setOperator(
+            "<=", [](float a, float b) { return a <= b; });
     }
-    return 0;
-}
-
-Framework::JSON::Validator::JSONValidator*
-JExpressionParser::getFloatValidator()
-{
-    JSONValidator* refs
-        = JSONValidator::buildForOneOf()
-              ->typeSpecifiedByAttribute("type")
-              ->addAcceptedType(
-                  JSONValidator::buildForObjectReference("jef_variable"))
-              ->addAcceptedType(
-                  JSONValidator::buildForObjectReference("jef_constant"))
-              ->addAcceptedType(
-                  JSONValidator::buildForObjectReference("jef_noise"))
-              ->addAcceptedType(
-                  JSONValidator::buildForObjectReference("jef_operator"))
-              ->finishOneOf();
-    JSONValidator* validator
-        = JSONValidator::buildForOneOf()
-              ->typeSpecifiedByAttribute("type")
-              ->addAcceptedType(JSONValidator::buildForObject()
-                                    ->setObjectReferenceId("jef_variable")
-                                    ->withRequiredString("type")
-                                    ->whichIs("variable")
-                                    ->finishString()
-                                    ->withRequiredString("name")
-                                    ->finishString()
-                                    ->finishObject())
-              ->addAcceptedType(JSONValidator::buildForObject()
-                                    ->setObjectReferenceId("jef_constant")
-                                    ->withRequiredString("type")
-                                    ->whichIs("constant")
-                                    ->finishString()
-                                    ->withRequiredNumber("value")
-                                    ->finishNumber()
-                                    ->finishObject())
-              ->addAcceptedType(
-                  JSONValidator::buildForObject()
-                      ->setObjectReferenceId("jef_noise")
-                      ->withRequiredString("type")
-                      ->whichIs("noise")
-                      ->finishString()
-                      ->withRequiredString("name")
-                      ->withDefault("noise")
-                      ->finishString()
-                      ->withRequiredAttribute(
-                          "x", dynamic_cast<JSONValidator*>(refs->getThis()))
-                      ->withRequiredAttribute(
-                          "y", dynamic_cast<JSONValidator*>(refs->getThis()))
-                      ->withRequiredAttribute(
-                          "z", dynamic_cast<JSONValidator*>(refs->getThis()))
-                      ->finishObject())
-              ->addAcceptedType(
-                  JSONValidator::buildForObject()
-                      ->setObjectReferenceId("jef_operator")
-                      ->withRequiredString("type")
-                      ->whichIs("operator")
-                      ->finishString()
-                      ->withRequiredString("operator")
-                      ->whichIsOneOf({"+", "-", "*", "/"})
-                      ->finishString()
-                      ->withRequiredArray("values")
-                      ->addAcceptedTypeInArray(
-                          dynamic_cast<JSONValidator*>(refs->getThis()))
-                      ->finishArray()
-                      ->finishObject())
-              ->finishOneOf();
-    return validator;
-}
-
-JBoolExpression* JExpressionParser::parseBoolExpression(
-    Framework::JSON::JSONValue* zValue)
-{
-    JSONObject* obj = zValue->asObject();
-    Framework::Text type = obj->zValue("type")->asString()->getString();
-    if (type.istGleich("variable"))
+    else if (op.istGleich("=="))
     {
-        return new JVariableBoolExpression(
-            obj->zValue("name")->asString()->getString());
+        return zResult->setOperator(
+            "==", [](float a, float b) { return a == b; });
     }
-    else if (type.istGleich("constant"))
+    else if (op.istGleich("!="))
     {
-        return new JConstantBoolExpression(
-            (float)obj->zValue("value")->asBool()->getBool());
+        return zResult->setOperator(
+            "!=", [](float a, float b) { return a != b; });
     }
-    else if (type.istGleich("blockType"))
+    else if (op.istGleich(">i"))
     {
-        return new JBlockTypeBoolExpression(
-            BlockType::getTypeId(
-                obj->zValue("blockType")->asString()->getString()),
-            parseFloatExpression(obj->zValue("x")),
-            parseFloatExpression(obj->zValue("y")),
-            parseFloatExpression(obj->zValue("z")));
+        return zResult->setOperator(
+            ">i", [](float a, float b) { return (int)a > (int)b; });
     }
-    else if (type.istGleich("operator"))
+    else if (op.istGleich("<i"))
     {
-        Framework::Text op = obj->zValue("operator")->asString()->getString();
-        if (op.istGleich("&&") || op.istGleich("||"))
-        {
-            Framework::RCArray<JBoolExpression>* values
-                = new Framework::RCArray<JBoolExpression>();
-            JSONArray* valuesArray = obj->zValue("values")->asArray();
-            for (JSONValue* value : *valuesArray)
-            {
-                values->add(parseBoolExpression(value));
-            }
-            if (op.istGleich("&&"))
-            {
-                return new JBoolOperatorBoolExpression(
-                    [](bool a, bool b) { return a && b; }, values);
-            }
-            else if (op.istGleich("||"))
-            {
-                return new JBoolOperatorBoolExpression(
-                    [](bool a, bool b) { return a || b; }, values);
-            }
-            else
-            {
-                values->release();
-            }
-        }
-        else
-        {
-            Framework::RCArray<JFloatExpression>* values
-                = new Framework::RCArray<JFloatExpression>();
-            JSONArray* valuesArray = obj->zValue("values")->asArray();
-            for (JSONValue* value : *valuesArray)
-            {
-                values->add(parseFloatExpression(value));
-            }
-            if (op.istGleich(">"))
-            {
-                return new JFloatOperatorBoolExpression(
-                    [](float a, float b) { return a > b; }, values);
-            }
-            else if (op.istGleich("<"))
-            {
-                return new JFloatOperatorBoolExpression(
-                    [](float a, float b) { return a < b; }, values);
-            }
-            else if (op.istGleich(">="))
-            {
-                return new JFloatOperatorBoolExpression(
-                    [](float a, float b) { return a >= b; }, values);
-            }
-            else if (op.istGleich("<="))
-            {
-                return new JFloatOperatorBoolExpression(
-                    [](float a, float b) { return a <= b; }, values);
-            }
-            else if (op.istGleich("=="))
-            {
-                return new JFloatOperatorBoolExpression(
-                    [](float a, float b) { return a == b; }, values);
-            }
-            else if (op.istGleich("!="))
-            {
-                return new JFloatOperatorBoolExpression(
-                    [](float a, float b) { return a != b; }, values);
-            }
-            else if (op.istGleich(">i"))
-            {
-                return new JFloatOperatorBoolExpression(
-                    [](float a, float b) { return (int)a > (int)b; }, values);
-            }
-            else if (op.istGleich("<i"))
-            {
-                return new JFloatOperatorBoolExpression(
-                    [](float a, float b) { return (int)a < (int)b; }, values);
-            }
-            else if (op.istGleich(">=i"))
-            {
-                return new JFloatOperatorBoolExpression(
-                    [](float a, float b) { return (int)a >= (int)b; }, values);
-            }
-            else if (op.istGleich("<=i"))
-            {
-                return new JFloatOperatorBoolExpression(
-                    [](float a, float b) { return (int)a <= (int)b; }, values);
-            }
-            else if (op.istGleich("==i"))
-            {
-                return new JFloatOperatorBoolExpression(
-                    [](float a, float b) { return (int)a == (int)b; }, values);
-            }
-            else if (op.istGleich("!=i"))
-            {
-                return new JFloatOperatorBoolExpression(
-                    [](float a, float b) { return (int)a != (int)b; }, values);
-            }
-            else
-            {
-                values->release();
-            }
-        }
+        return zResult->setOperator(
+            "<i", [](float a, float b) { return (int)a < (int)b; });
+    }
+    else if (op.istGleich(">=i"))
+    {
+        return zResult->setOperator(
+            ">=i", [](float a, float b) { return (int)a >= (int)b; });
+    }
+    else if (op.istGleich("<=i"))
+    {
+        return zResult->setOperator(
+            "<=i", [](float a, float b) { return (int)a <= (int)b; });
+    }
+    else if (op.istGleich("==i"))
+    {
+        return zResult->setOperator(
+            "==i", [](float a, float b) { return (int)a == (int)b; });
+    }
+    else if (op.istGleich("!=i"))
+    {
+        return zResult->setOperator(
+            "!=i", [](float a, float b) { return (int)a != (int)b; });
     }
-    return 0;
+    for (Framework::JSON::JSONValue* value :
+        *zJson->zValue("values")->asArray())
+    {
+        zResult->addValue(
+            Game::INSTANCE->zTypeRegistry()->fromJson<JFloatExpression>(value));
+    }
+}
+
+void JFloatOperatorBoolExpressionFactory::toJson(
+    JFloatOperatorBoolExpression* zObject,
+    Framework::JSON::JSONObject* zResult) const
+{
+    zResult->addValue(
+        "operator", new Framework::JSON::JSONString(zObject->getOperator()));
+    Framework::JSON::JSONArray* values = new Framework::JSON::JSONArray();
+    for (JFloatExpression* expression : zObject->getValues())
+    {
+        values->addValue(
+            Game::INSTANCE->zTypeRegistry()->toJson<JFloatExpression>(
+                expression));
+    }
+    zResult->addValue("values", values);
+}
+
+JSONObjectValidationBuilder*
+JFloatOperatorBoolExpressionFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return builder->withRequiredString("operator")
+        ->whichIsOneOf({">",
+            "<",
+            ">=",
+            "<=",
+            "==",
+            "!=",
+            "<i",
+            ">i",
+            ">=i",
+            "<=i",
+            "==i",
+            "!=i"})
+        ->finishString()
+        ->withRequiredArray("values")
+        ->addAcceptedTypeInArray(
+            Game::INSTANCE->zTypeRegistry()->getValidator<JFloatExpression>())
+        ->finishArray();
 }
 
-Framework::JSON::Validator::JSONValidator* JExpressionParser::getBoolValidator()
+Framework::Text JFloatOperatorBoolExpressionFactory::getTypeToken() const
+{
+    return "comparsion";
+}
+
+JBlockTypeBoolExpression::JBlockTypeBoolExpression()
+    : JBoolExpression(),
+      typeId(0),
+      x(0),
+      y(0),
+      z(0)
+{}
+
+JBlockTypeBoolExpression ::~JBlockTypeBoolExpression()
+{
+    if (x) x->release();
+    if (y) y->release();
+    if (z) z->release();
+}
+
+bool JBlockTypeBoolExpression::getValue(JExpressionMemory* zMemory)
+{
+    int x = (int)(round(this->x->getValue(zMemory)));
+    int y = (int)(round(this->y->getValue(zMemory)));
+    int z = (int)(round(this->z->getValue(zMemory)));
+    if (z < 0 || z >= WORLD_HEIGHT || !zMemory->zCurrentChunk()
+        || Game::getChunkCenter(x, y) != zMemory->zCurrentChunk()->getCenter())
+    {
+        return 0;
+    }
+    return zMemory->zCurrentChunk()->getBlockTypeAt(
+               Dimension::chunkCoordinates({x, y, z}))
+        == typeId;
+}
+
+void JBlockTypeBoolExpression::setTypeId(int typeId)
+{
+    this->typeId = typeId;
+}
+
+int JBlockTypeBoolExpression::getTypeId() const
+{
+    return typeId;
+}
+
+void JBlockTypeBoolExpression::setX(JFloatExpression* x)
+{
+    if (this->x) this->x->release();
+    this->x = x;
+}
+
+JFloatExpression* JBlockTypeBoolExpression::zX() const
+{
+    return x;
+}
+
+void JBlockTypeBoolExpression::setY(JFloatExpression* y)
+{
+    if (this->y) this->y->release();
+    this->y = y;
+}
+
+JFloatExpression* JBlockTypeBoolExpression::zY() const
+{
+    return y;
+}
+
+void JBlockTypeBoolExpression::setZ(JFloatExpression* z)
+{
+    if (this->z) this->z->release();
+    this->z = z;
+}
+
+JFloatExpression* JBlockTypeBoolExpression::zZ() const
+{
+    return z;
+}
+
+JBlockTypeBoolExpressionFactory::JBlockTypeBoolExpressionFactory()
+    : SubTypeFactory()
+{}
+
+JBlockTypeBoolExpression* JBlockTypeBoolExpressionFactory::createValue(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new JBlockTypeBoolExpression();
+}
+
+void JBlockTypeBoolExpressionFactory::fromJson(
+    JBlockTypeBoolExpression* zResult, Framework::JSON::JSONObject* zJson) const
+{
+    zResult->setTypeId(Game::INSTANCE->getBlockTypeId(
+        zJson->zValue("blockType")->asString()->getString()));
+    zResult->setX(Game::INSTANCE->zTypeRegistry()->fromJson<JFloatExpression>(
+        zJson->zValue("x")));
+    zResult->setY(Game::INSTANCE->zTypeRegistry()->fromJson<JFloatExpression>(
+        zJson->zValue("y")));
+    zResult->setZ(Game::INSTANCE->zTypeRegistry()->fromJson<JFloatExpression>(
+        zJson->zValue("z")));
+}
+
+void JBlockTypeBoolExpressionFactory::toJson(JBlockTypeBoolExpression* zObject,
+    Framework::JSON::JSONObject* zResult) const
+{
+    zResult->addValue("blockType",
+        new Framework::JSON::JSONString(
+            Game::INSTANCE->zBlockType(zObject->getTypeId())->getName()));
+    zResult->addValue(
+        "x", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zX()));
+    zResult->addValue(
+        "y", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zY()));
+    zResult->addValue(
+        "z", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zZ()));
+}
+
+JSONObjectValidationBuilder* JBlockTypeBoolExpressionFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
     Framework::RCArray<Framework::Text> blockTypeNames;
     for (int i = 0; i < Game::INSTANCE->getBlockTypeCount(); i++)
     {
         if (Game::INSTANCE->zBlockType(i))
         {
-            blockTypeNames.add(new Framework::Text(Game::INSTANCE->zBlockType(i)->getName()));
+            blockTypeNames.add(
+                new Framework::Text(Game::INSTANCE->zBlockType(i)->getName()));
         }
     }
-    JSONValidator* refs
-        = JSONValidator::buildForOneOf()
-              ->typeSpecifiedByAttribute("type")
-              ->addAcceptedType(
-                  JSONValidator::buildForObjectReference("jeb_variable"))
-              ->addAcceptedType(
-                  JSONValidator::buildForObjectReference("jeb_constant"))
-              ->addAcceptedType(
-                  JSONValidator::buildForObjectReference("jeb_blockType"))
-              ->addAcceptedType(
-                  JSONValidator::buildForObjectReference("jeb_bool_operator"))
-              ->addAcceptedType(
-                  JSONValidator::buildForObjectReference("jeb_float_operator"))
-              ->finishOneOf();
-    JSONValidator* validator
-        = JSONValidator::buildForOneOf()
-              ->typeSpecifiedByAttribute("type")
-              ->addAcceptedType(JSONValidator::buildForObject()
-                                    ->setObjectReferenceId("jeb_variable")
-                                    ->withRequiredString("type")
-                                    ->whichIs("variable")
-                                    ->finishString()
-                                    ->withRequiredString("name")
-                                    ->finishString()
-                                    ->finishObject())
-              ->addAcceptedType(JSONValidator::buildForObject()
-                                    ->setObjectReferenceId("jeb_constant")
-                                    ->withRequiredString("type")
-                                    ->whichIs("constant")
-                                    ->finishString()
-                                    ->withRequiredBool("value")
-                                    ->finishBool()
-                                    ->finishObject())
-              ->addAcceptedType(
-                  JSONValidator::buildForObject()
-                      ->setObjectReferenceId("jeb_blockType")
-                      ->withRequiredString("type")
-                      ->whichIs("blockType")
-                      ->finishString()
-                      ->withRequiredString("blockType")
-                      ->whichIsOneOf(blockTypeNames)
-                      ->finishString()
-                      ->withRequiredAttribute("x", getFloatValidator())
-                      ->withRequiredAttribute("y", getFloatValidator())
-                      ->withRequiredAttribute("z", getFloatValidator())
-                      ->finishObject())
-              ->addAcceptedType(
-                  JSONValidator::buildForObject()
-                      ->setObjectReferenceId("jeb_bool_operator")
-                      ->withRequiredString("type")
-                      ->whichIs("operator")
-                      ->finishString()
-                      ->withRequiredString("operator")
-                      ->whichIsOneOf({"&&", "||"})
-                      ->finishString()
-                      ->withRequiredArray("values")
-                      ->addAcceptedTypeInArray(
-                          dynamic_cast<JSONValidator*>(refs->getThis()))
-                      ->finishArray()
-                      ->finishObject())
-              ->addAcceptedType(
-                  JSONValidator::buildForObject()
-                      ->setObjectReferenceId("jeb_float_operator")
-                      ->withRequiredString("type")
-                      ->whichIs("operator")
-                      ->finishString()
-                      ->withRequiredString("operator")
-                      ->whichIsOneOf({">",
-                          "<",
-                          ">=",
-                          "<=",
-                          "==",
-                          "!=",
-                          ">i",
-                          "<i",
-                          ">=i",
-                          "<=i",
-                          "==i",
-                          "!=i"})
-                      ->finishString()
-                      ->withRequiredArray("values")
-                      ->addAcceptedTypeInArray(getFloatValidator())
-                      ->finishArray()
-                      ->finishObject())
-              ->finishOneOf();
-    return validator;
+    return builder->withRequiredString("blockType")
+        ->whichIsOneOf(blockTypeNames)
+        ->finishString()
+        ->withRequiredAttribute("x",
+            Game::INSTANCE->zTypeRegistry()->getValidator<JFloatExpression>())
+        ->withRequiredAttribute("y",
+            Game::INSTANCE->zTypeRegistry()->getValidator<JFloatExpression>())
+        ->withRequiredAttribute("z",
+            Game::INSTANCE->zTypeRegistry()->getValidator<JFloatExpression>());
+}
+
+Framework::Text JBlockTypeBoolExpressionFactory::getTypeToken() const
+{
+    return "blockType";
 }

+ 207 - 33
FactoryCraft/JsonExpression.h

@@ -1,13 +1,14 @@
 #pragma once
 
 #include <Array.h>
+#include <Critical.h>
 #include <functional>
 #include <JSON.h>
 #include <Text.h>
 #include <Trie.h>
-#include <Critical.h>
 
 #include "Noise.h"
+#include "TypeRegistry.h"
 
 class Chunk;
 
@@ -64,8 +65,27 @@ private:
     Framework::Text name;
 
 public:
-    JVariableFloatExpression(Framework::Text name);
+    JVariableFloatExpression();
     float getValue(JExpressionMemory* zMemory) override;
+
+    void setName(Framework::Text name);
+    Framework::Text getName() const;
+};
+
+class JVariableFloatExpressionFactory
+    : public SubTypeFactory<JFloatExpression, JVariableFloatExpression>
+{
+public:
+    JVariableFloatExpressionFactory();
+    JVariableFloatExpression* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(JVariableFloatExpression* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(JVariableFloatExpression* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
+    Framework::Text getTypeToken() const override;
 };
 
 class JVariableBoolExpression : public JBoolExpression
@@ -74,8 +94,27 @@ private:
     Framework::Text name;
 
 public:
-    JVariableBoolExpression(Framework::Text name);
+    JVariableBoolExpression();
     bool getValue(JExpressionMemory* zMemory) override;
+
+    void setName(Framework::Text name);
+    Framework::Text getName() const;
+};
+
+class JVariableBoolExpressionFactory
+    : public SubTypeFactory<JBoolExpression, JVariableBoolExpression>
+{
+public:
+    JVariableBoolExpressionFactory();
+    JVariableBoolExpression* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(JVariableBoolExpression* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(JVariableBoolExpression* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
+    Framework::Text getTypeToken() const override;
 };
 
 class JConstantFloatExpression : public JFloatExpression
@@ -84,8 +123,27 @@ private:
     float value;
 
 public:
-    JConstantFloatExpression(float value);
+    JConstantFloatExpression();
     float getValue(JExpressionMemory* zMemory) override;
+
+    void setValue(float value);
+    float getValue() const;
+};
+
+class JConstantFloatExpressionFactory
+    : public SubTypeFactory<JFloatExpression, JConstantFloatExpression>
+{
+public:
+    JConstantFloatExpressionFactory();
+    JConstantFloatExpression* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(JConstantFloatExpression* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(JConstantFloatExpression* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
+    Framework::Text getTypeToken() const override;
 };
 
 class JConstantBoolExpression : public JBoolExpression
@@ -94,8 +152,27 @@ private:
     bool value;
 
 public:
-    JConstantBoolExpression(bool value);
+    JConstantBoolExpression();
     bool getValue(JExpressionMemory* zMemory) override;
+
+    void setValue(bool value);
+    bool getValue() const;
+};
+
+class JConstantBoolExpressionFactory
+    : public SubTypeFactory<JBoolExpression, JConstantBoolExpression>
+{
+public:
+    JConstantBoolExpressionFactory();
+    JConstantBoolExpression* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(JConstantBoolExpression* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(JConstantBoolExpression* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
+    Framework::Text getTypeToken() const override;
 };
 
 class JNoiseFloatExpression : public JFloatExpression
@@ -107,52 +184,136 @@ private:
     JFloatExpression* z;
 
 public:
-    JNoiseFloatExpression(Framework::Text name,
-        JFloatExpression* x,
-        JFloatExpression* y,
-        JFloatExpression* z);
+    JNoiseFloatExpression();
     ~JNoiseFloatExpression();
     float getValue(JExpressionMemory* zMemory) override;
+
+    void setName(Framework::Text name);
+    Framework::Text getName() const;
+    void setX(JFloatExpression* x);
+    JFloatExpression* zX() const;
+    void setY(JFloatExpression* y);
+    JFloatExpression* zY() const;
+    void setZ(JFloatExpression* z);
+    JFloatExpression* zZ() const;
+};
+
+class JNoiseFloatExpressionFactory
+    : public SubTypeFactory<JFloatExpression, JNoiseFloatExpression>
+{
+public:
+    JNoiseFloatExpressionFactory();
+    JNoiseFloatExpression* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(JNoiseFloatExpression* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(JNoiseFloatExpression* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
+    Framework::Text getTypeToken() const override;
 };
 
 class JOperatorFloatExpression : public JFloatExpression
 {
 private:
+    Framework::Text op;
     std::function<float(float a, float b)> accumulator;
-    Framework::RCArray<JFloatExpression>* values;
+    Framework::RCArray<JFloatExpression> values;
 
 public:
-    JOperatorFloatExpression(std::function<float(float a, float b)> accumulator,
-        Framework::RCArray<JFloatExpression>* values);
-    ~JOperatorFloatExpression();
+    JOperatorFloatExpression();
     float getValue(JExpressionMemory* zMemory) override;
+
+    void setOperator(
+        Framework::Text op, std::function<float(float a, float b)> accumulator);
+    Framework::Text getOperator();
+    void addValue(JFloatExpression* value);
+    const Framework::RCArray<JFloatExpression>& getValues() const;
+};
+
+class JOperatorFloatExpressionFactory
+    : public SubTypeFactory<JFloatExpression, JOperatorFloatExpression>
+{
+public:
+    JOperatorFloatExpressionFactory();
+    JOperatorFloatExpression* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(JOperatorFloatExpression* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(JOperatorFloatExpression* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
+    Framework::Text getTypeToken() const override;
 };
 
 class JBoolOperatorBoolExpression : public JBoolExpression
 {
 private:
+    Framework::Text op;
     std::function<bool(bool a, bool b)> accumulator;
-    Framework::RCArray<JBoolExpression>* values;
+    Framework::RCArray<JBoolExpression> values;
 
 public:
-    JBoolOperatorBoolExpression(std::function<bool(bool a, bool b)> accumulator,
-        Framework::RCArray<JBoolExpression>* values);
-    ~JBoolOperatorBoolExpression();
+    JBoolOperatorBoolExpression();
     bool getValue(JExpressionMemory* zMemory) override;
+
+    void setOperator(
+        Framework::Text op, std::function<float(float a, float b)> accumulator);
+    Framework::Text getOperator();
+    void addValue(JBoolExpression* value);
+    const Framework::RCArray<JBoolExpression>& getValues() const;
+};
+
+class JBoolOperatorBoolExpressionFactory
+    : public SubTypeFactory<JBoolExpression, JBoolOperatorBoolExpression>
+{
+public:
+    JBoolOperatorBoolExpressionFactory();
+    JBoolOperatorBoolExpression* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(JBoolOperatorBoolExpression* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(JBoolOperatorBoolExpression* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
+    Framework::Text getTypeToken() const override;
 };
 
 class JFloatOperatorBoolExpression : public JBoolExpression
 {
 private:
+    Framework::Text op;
     std::function<bool(float a, float b)> accumulator;
-    Framework::RCArray<JFloatExpression>* values;
+    Framework::RCArray<JFloatExpression> values;
 
 public:
-    JFloatOperatorBoolExpression(
-        std::function<bool(float a, float b)> accumulator,
-        Framework::RCArray<JFloatExpression>* values);
-    ~JFloatOperatorBoolExpression();
+    JFloatOperatorBoolExpression();
     bool getValue(JExpressionMemory* zMemory) override;
+
+    void setOperator(
+        Framework::Text op, std::function<bool(float a, float b)> accumulator);
+    Framework::Text getOperator();
+    void addValue(JFloatExpression* value);
+    const Framework::RCArray<JFloatExpression>& getValues() const;
+};
+
+class JFloatOperatorBoolExpressionFactory
+    : public SubTypeFactory<JBoolExpression, JFloatOperatorBoolExpression>
+{
+public:
+    JFloatOperatorBoolExpressionFactory();
+    JFloatOperatorBoolExpression* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(JFloatOperatorBoolExpression* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(JFloatOperatorBoolExpression* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
+    Framework::Text getTypeToken() const override;
 };
 
 class JBlockTypeBoolExpression : public JBoolExpression
@@ -164,19 +325,32 @@ private:
     JFloatExpression* z;
 
 public:
-    JBlockTypeBoolExpression(int typeId,
-        JFloatExpression* x,
-        JFloatExpression* y,
-        JFloatExpression* z);
+    JBlockTypeBoolExpression();
     ~JBlockTypeBoolExpression();
     bool getValue(JExpressionMemory* zMemory) override;
+
+    void setTypeId(int typeId);
+    int getTypeId() const;
+    void setX(JFloatExpression* x);
+    JFloatExpression* zX() const;
+    void setY(JFloatExpression* y);
+    JFloatExpression* zY() const;
+    void setZ(JFloatExpression* z);
+    JFloatExpression* zZ() const;
 };
 
-namespace JExpressionParser
+class JBlockTypeBoolExpressionFactory
+    : public SubTypeFactory<JBoolExpression, JBlockTypeBoolExpression>
 {
-    JFloatExpression* parseFloatExpression(Framework::JSON::JSONValue* zValue);
-    Framework::JSON::Validator::JSONValidator* getFloatValidator();
-
-    JBoolExpression* parseBoolExpression(Framework::JSON::JSONValue* zValue);
-    Framework::JSON::Validator::JSONValidator* getBoolValidator();
-}; // namespace JExpressionParser
+public:
+    JBlockTypeBoolExpressionFactory();
+    JBlockTypeBoolExpression* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(JBlockTypeBoolExpression* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(JBlockTypeBoolExpression* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
+    Framework::Text getTypeToken() const override;
+};

+ 100 - 81
FactoryCraft/LightSources.cpp

@@ -79,20 +79,14 @@ bool BasicLightSource::onTick(TickQueue* zQueue, int numTicks, bool& blocked)
 
 void BasicLightSource::onPostTick() {}
 
-BasicLightSourceBlockType::BasicLightSourceBlockType(
-    Framework::Text itemTypeName,
-    ModelInfo* model,
-    Framework::Text name,
-    float hardness,
-    int mapColor,
-    int lightColor,
-    Framework::RCArray<Framework::Text> groupNames)
-    : BlockType(0, model, 1, 1, 1, name, false, mapColor, groupNames, hardness),
-      itemTypeName(itemTypeName),
+BasicLightSourceBlockType::BasicLightSourceBlockType()
+    : BlockType(),
+      itemTypeName(),
+      itemTypeId(0),
       transparent(1),
       passable(1),
       interactable(1),
-      lightColor(lightColor)
+      lightColor(0XFFFFFFFF)
 {}
 
 void BasicLightSourceBlockType::createSuperBlock(
@@ -161,16 +155,6 @@ Item* BasicLightSourceBlockType::createItem() const
     return Game::INSTANCE->zItemType(itemTypeId)->createItem();
 }
 
-int BasicLightSourceBlockType::getLightColor() const
-{
-    return lightColor;
-}
-
-Framework::Text BasicLightSourceBlockType::getItemTypeName() const
-{
-    return itemTypeName;
-}
-
 ItemType* BasicLightSourceBlockType::createItemType() const
 {
     return (new LightSourceItemType(getItemTypeName(),
@@ -184,79 +168,114 @@ ItemType* BasicLightSourceBlockType::createItemType() const
         ->setColor(0x00F69A54);
 }
 
+void BasicLightSourceBlockType::setItemTypeName(Framework::Text itemTypeName)
+{
+    this->itemTypeName = itemTypeName;
+}
+
+Framework::Text BasicLightSourceBlockType::getItemTypeName() const
+{
+    return itemTypeName;
+}
+
+void BasicLightSourceBlockType::setTransparent(bool transparent)
+{
+    this->transparent = transparent;
+}
+
+bool BasicLightSourceBlockType::isTransparent() const
+{
+    return transparent;
+}
+
+void BasicLightSourceBlockType::setPassable(bool passable)
+{
+    this->passable = passable;
+}
+
+bool BasicLightSourceBlockType::isPassable() const
+{
+    return passable;
+}
+
+void BasicLightSourceBlockType::setInteractable(bool interactable)
+{
+    this->interactable = interactable;
+}
+
+bool BasicLightSourceBlockType::isInteractable() const
+{
+    return interactable;
+}
+
+void BasicLightSourceBlockType::setLightColor(int lightColor)
+{
+    this->lightColor = lightColor;
+}
+
+int BasicLightSourceBlockType::getLightColor() const
+{
+    return lightColor;
+}
+
 BasicLightSourceBlockTypeFactory::BasicLightSourceBlockTypeFactory()
-    : SubTypeFactory()
+    : BlockTypeFactoryBase()
 {}
 
-BasicLightSourceBlockType* BasicLightSourceBlockTypeFactory::fromJson(
+BasicLightSourceBlockType* BasicLightSourceBlockTypeFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
-    Framework::RCArray<Framework::Text> groupNames;
-    for (Framework::JSON::JSONValue* value :
-        *zJson->zValue("groupNames")->asArray())
-    {
-        groupNames.add(new Framework::Text(value->asString()->getString()));
-    }
-    return new BasicLightSourceBlockType(
-        zJson->zValue("itemType")->asString()->getString(),
-        Game::INSTANCE->zTypeRegistry()->fromJson<ModelInfo>(
-            zJson->zValue("model")),
-        zJson->zValue("name")->asString()->getString(),
-        (float)zJson->zValue("hardness")->asNumber()->getNumber(),
-        (int)zJson->zValue("mapColor")->asString()->getString(),
-        (int)zJson->zValue("lightColor")->asString()->getString(),
-        groupNames);
+    return new BasicLightSourceBlockType();
 }
 
-Framework::JSON::JSONObject* BasicLightSourceBlockTypeFactory::toJson(
-    BasicLightSourceBlockType* zObject) const
+void BasicLightSourceBlockTypeFactory::fromJson(
+    BasicLightSourceBlockType* zResult,
+    Framework::JSON::JSONObject* zJson) const
+{
+    zResult->setItemTypeName(zJson->zValue("itemType")->asString()->getString());
+    zResult->setTransparent(zJson->zValue("transparent")->asBool()->getBool());
+    zResult->setPassable(zJson->zValue("passable")->asBool()->getBool());
+    zResult->setInteractable(
+        zJson->zValue("interactable")->asBool()->getBool());
+    zResult->setLightColor(
+        (int)zJson->zValue("lightColor")->asString()->getString());
+    BlockTypeFactoryBase::fromJson(zResult, zJson);
+}
+
+void BasicLightSourceBlockTypeFactory::toJson(
+    BasicLightSourceBlockType* zObject,
+    Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue("itemType",
+    zResult->addValue("itemType",
         new Framework::JSON::JSONString(zObject->getItemTypeName()));
-    result->addValue(
-        "model", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zModel()));
-    result->addValue(
-        "name", new Framework::JSON::JSONString(zObject->getName()));
-    result->addValue(
-        "hardness", new Framework::JSON::JSONNumber(zObject->getHardness()));
-    result->addValue(
-        "mapColor", new Framework::JSON::JSONString(zObject->getMapColor()));
-    result->addValue("lightColor",
+    zResult->addValue(
+        "transparent", new Framework::JSON::JSONBool(zObject->isTransparent()));
+    zResult->addValue(
+        "passable", new Framework::JSON::JSONBool(zObject->isPassable()));
+    zResult->addValue("interactable",
+        new Framework::JSON::JSONBool(zObject->isInteractable()));
+    zResult->addValue("lightColor",
         new Framework::JSON::JSONString(zObject->getLightColor()));
-    Framework::JSON::JSONArray* groupNames = new Framework::JSON::JSONArray();
-    for (Framework::Text* groupName : zObject->getGroupNames())
-    {
-        groupNames->addValue(new Framework::JSON::JSONString(*groupName));
-    }
-    result->addValue("groupNames", groupNames);
-    return result;
+    BlockTypeFactoryBase::toJson(zObject, zResult);
 }
 
-Framework::JSON::Validator::JSONValidator*
-BasicLightSourceBlockTypeFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
+JSONObjectValidationBuilder* BasicLightSourceBlockTypeFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
-    return builder->withRequiredString("itemType")
-        ->finishString()
-        ->withRequiredAttribute(
-            "model", Game::INSTANCE->zTypeRegistry()->getValidator<ModelInfo>())
-        ->withRequiredString("name")
-        ->finishString()
-        ->withRequiredNumber("hardness")
-        ->withDefault(1.0)
-        ->finishNumber()
-        ->withRequiredString("mapColor")
-        ->finishString()
-        ->withRequiredString("lightColor")
-        ->finishString()
-        ->withRequiredArray("groupNames")
-        ->withDefault(new Framework::JSON::JSONArray())
-        ->addAcceptedStringInArray()
-        ->finishString()
-        ->finishArray()
-        ->finishObject();
+    return BlockTypeFactoryBase::addToValidator(
+        builder->withRequiredString("itemType")
+            ->finishString()
+            ->withRequiredBool("transparent")
+            ->withDefault(true)
+            ->finishBool()
+            ->withRequiredBool("passable")
+            ->withDefault(true)
+            ->finishBool()
+            ->withRequiredBool("interactable")
+            ->withDefault(true)
+            ->finishBool()
+            ->withRequiredString("lightColor")
+            ->finishString());
 }
 
 Framework::Text BasicLightSourceBlockTypeFactory::getTypeToken() const

+ 20 - 16
FactoryCraft/LightSources.h

@@ -70,13 +70,7 @@ private:
     int lightColor;
 
 public:
-    BasicLightSourceBlockType(Framework::Text itemTypeName,
-        ModelInfo* model,
-        Framework::Text name,
-        float hardness,
-        int mapColor,
-        int lightColor,
-        Framework::RCArray<Framework::Text> groupNames);
+    BasicLightSourceBlockType();
 
 protected:
     virtual void createSuperBlock(Block* zBlock, Item* zItem) const override;
@@ -92,22 +86,32 @@ public:
         Framework::Vec3<int> position, int dimensionId) const override;
     virtual Item* createItem() const override;
 
-    int getLightColor() const;
-    Framework::Text getItemTypeName() const;
     virtual ItemType* createItemType() const override;
+
+    void setItemTypeName(Framework::Text itemTypeName);
+    Framework::Text getItemTypeName() const;
+    void setTransparent(bool transparent);
+    bool isTransparent() const;
+    void setPassable(bool passable);
+    bool isPassable() const;
+    void setInteractable(bool interactable);
+    bool isInteractable() const;
+    void setLightColor(int lightColor);
+    int getLightColor() const;
 };
 
 class BasicLightSourceBlockTypeFactory
-    : public SubTypeFactory<BlockType, BasicLightSourceBlockType>
+    : public BlockTypeFactoryBase<BasicLightSourceBlockType>
 {
 public:
     BasicLightSourceBlockTypeFactory();
-    BasicLightSourceBlockType* fromJson(
+    BasicLightSourceBlockType* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(BasicLightSourceBlockType* zResult,
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(
-        BasicLightSourceBlockType* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    void toJson(BasicLightSourceBlockType* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };

+ 64 - 28
FactoryCraft/ModelInfo.cpp

@@ -2,16 +2,29 @@
 
 using namespace Framework;
 
-ModelInfo::ModelInfo(const char* modelPath,
-    Framework::RCArray<Framework::Text> texturePaths,
-    bool transparent, float size)
+ModelInfo::ModelInfo()
     : ReferenceCounter(),
-      modelPath(modelPath),
-      texturePaths(texturePaths),
-      transparent(transparent),
-      size(size)
+      modelPath(),
+      texturePaths(),
+      transparent(false),
+      size(1.0f)
 {}
 
+ModelInfo::ModelInfo(const char* modelPath,
+    Framework::RCArray<Framework::Text> texturePaths,
+    bool transparent,
+    float size)
+    : ReferenceCounter()
+{
+    setModelPath(modelPath);
+    for (Framework::Text* t : texturePaths)
+    {
+        addTexturePath(*t);
+    }
+    setTransparent(transparent);
+    setSize(size);
+}
+
 void ModelInfo::writeTo(Framework::StreamWriter* zWriter) const
 {
     char len = (char)modelPath.getLength();
@@ -29,6 +42,26 @@ void ModelInfo::writeTo(Framework::StreamWriter* zWriter) const
     zWriter->schreibe((char*)&size, 4);
 }
 
+void ModelInfo::setModelPath(Framework::Text path)
+{
+    modelPath = path;
+}
+
+void ModelInfo::addTexturePath(Framework::Text path)
+{
+    texturePaths.add(new Framework::Text(path));
+}
+
+void ModelInfo::setTransparent(bool transparent)
+{
+    this->transparent = transparent;
+}
+
+void ModelInfo::setSize(float size)
+{
+    this->size = size;
+}
+
 Framework::Text ModelInfo::getModelPath() const
 {
     return modelPath;
@@ -53,44 +86,48 @@ ModelInfoFactory::ModelInfoFactory()
     : TypeFactory()
 {}
 
-ModelInfo* ModelInfoFactory::fromJson(Framework::JSON::JSONValue* zJson) const
+ModelInfo* ModelInfoFactory::createValue(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new ModelInfo();
+}
+
+void ModelInfoFactory::fromJson(
+    ModelInfo* zResult, Framework::JSON::JSONObject* zJson) const
 {
-    Framework::RCArray<Framework::Text> texturePaths;
+    zResult->setModelPath(
+        zJson->asObject()->zValue("modelPath")->asString()->getString());
     for (Framework::JSON::JSONValue* v :
         *zJson->asObject()->zValue("texturePaths")->asArray())
     {
-        texturePaths.add(new Framework::Text(v->asString()->getString()));
+        zResult->addTexturePath(v->asString()->getString());
     }
-    return new ModelInfo(
-        zJson->asObject()->zValue("modelPath")->asString()->getString(),
-        texturePaths,
-        zJson->asObject()->zValue("transparent")->asBool()->getBool(),
+    zResult->setTransparent(
+        zJson->asObject()->zValue("transparent")->asBool()->getBool());
+    zResult->setSize(
         (float)zJson->asObject()->zValue("size")->asNumber()->getNumber());
 }
 
-Framework::JSON::JSONValue* ModelInfoFactory::toJson(ModelInfo* zObject) const
+void ModelInfoFactory::toJson(
+    ModelInfo* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* obj = new Framework::JSON::JSONObject();
     Framework::JSON::JSONArray* arr = new Framework::JSON::JSONArray();
     for (Framework::Text* t : zObject->texturePaths)
     {
         arr->addValue(new Framework::JSON::JSONString(t->getText()));
     }
-    obj->addValue("texturePaths", arr);
-    obj->addValue(
+    zResult->addValue("texturePaths", arr);
+    zResult->addValue(
         "modelPath", new Framework::JSON::JSONString(zObject->modelPath));
-    obj->addValue(
+    zResult->addValue(
         "transparent", new Framework::JSON::JSONBool(zObject->transparent));
-    obj->addValue(
-        "size", new Framework::JSON::JSONNumber(zObject->size));
-    return obj;
+    zResult->addValue("size", new Framework::JSON::JSONNumber(zObject->size));
 }
 
-Framework::JSON::Validator::JSONValidator*
-ModelInfoFactory::getValidator() const
+JSONObjectValidationBuilder* ModelInfoFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
-    return Framework::JSON::Validator::JSONValidator::buildForObject()
-        ->withRequiredArray("texturePaths")
+    return builder->withRequiredArray("texturePaths")
         ->addAcceptedStringInArray()
         ->finishString()
         ->finishArray()
@@ -102,6 +139,5 @@ ModelInfoFactory::getValidator() const
         ->withRequiredNumber("size")
         ->whichIsGreaterThen(0)
         ->withDefault(1.0)
-        ->finishNumber()
-        ->finishObject();
+        ->finishNumber();
 }

+ 13 - 4
FactoryCraft/ModelInfo.h

@@ -3,6 +3,7 @@
 #include <Array.h>
 #include <Text.h>
 #include <Writer.h>
+
 #include "TypeRegistry.h"
 
 class ModelInfoFactory;
@@ -16,18 +17,22 @@ private:
     float size;
 
 public:
+    ModelInfo();
     ModelInfo(const char* modelPath,
         Framework::RCArray<Framework::Text> texturePaths,
         bool transparent,
         float size);
     void writeTo(Framework::StreamWriter* zWriter) const;
+    void setModelPath(Framework::Text path);
+    void addTexturePath(Framework::Text path);
+    void setTransparent(bool transparent);
+    void setSize(float size);
 
     Framework::Text getModelPath() const;
     Framework::RCArray<Framework::Text> getTexturePaths() const;
     bool isTransparent() const;
     float getSize() const;
 
-
     friend ModelInfoFactory;
 };
 
@@ -35,7 +40,11 @@ class ModelInfoFactory : public TypeFactory<ModelInfo>
 {
 public:
     ModelInfoFactory();
-    ModelInfo* fromJson(Framework::JSON::JSONValue* zJson) const override;
-    Framework::JSON::JSONValue* toJson(ModelInfo* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator() const override;
+    ModelInfo* createValue(Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(
+        ModelInfo* zResult, Framework::JSON::JSONObject* zJson) const override;
+    void toJson(ModelInfo* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
 };

+ 1 - 0
FactoryCraft/MultiblockStructure.cpp

@@ -1,5 +1,6 @@
 #include "MultiblockStructure.h"
 
+#include "Block.h"
 #include "Game.h"
 
 using namespace Framework;

+ 12 - 7
FactoryCraft/NetworkMessage.cpp

@@ -1,9 +1,12 @@
 #include "NetworkMessage.h"
 
+#include "ChatMessage.h"
+#include "ChatObserver.h"
 #include "Chunk.h"
+#include "ChunkMap.h"
+#include "Dimension.h"
 #include "Entity.h"
 #include "Game.h"
-#include "ChunkMap.h"
 
 NetworkMessage::NetworkMessage()
     : Framework::ReferenceCounter(),
@@ -54,7 +57,7 @@ void NetworkMessage::addressEntity(const Entity* zEntity)
     *(int*)(address + 6) = zEntity->getId();
 }
 
-void NetworkMessage::addressDimension(const Dimension *zDim)
+void NetworkMessage::addressDimension(const Dimension* zDim)
 {
     delete[] address;
     addressLength = 5;
@@ -77,7 +80,8 @@ void NetworkMessage::addressBlock(const Block* zBlock)
     *(int*)(address + 14) = pos.z;
 }
 
-void NetworkMessage::openDialog(Framework::Text dialogName, Framework::Text uiml)
+void NetworkMessage::openDialog(
+    Framework::Text dialogName, Framework::Text uiml)
 {
     delete[] address;
     addressLength = (char)(4 + dialogName.getLength());
@@ -134,7 +138,7 @@ void NetworkMessage::sendChatMessage(ChatMessage* zMsg)
     addressLength = 1;
     address = new char[1];
     address[0] = 4; // chat message
-    InMemoryBuffer buffer;
+    Framework::InMemoryBuffer buffer;
     zMsg->writeTo(&buffer);
     char* msg = new char[buffer.getSize()];
     buffer.lese(msg, (int)buffer.getSize());
@@ -147,7 +151,7 @@ void NetworkMessage::sendChatOptions(ChatObserver* zOptions)
     addressLength = 1;
     address = new char[1];
     address[0] = 5; // chat options
-    InMemoryBuffer buffer;
+    Framework::InMemoryBuffer buffer;
     zOptions->writeTo(&buffer);
     char* msg = new char[buffer.getSize()];
     buffer.lese(msg, (int)buffer.getSize());
@@ -160,14 +164,15 @@ void NetworkMessage::sendMap(ChunkMap* zMap)
     addressLength = 1;
     address = new char[1];
     address[0] = 6; // map data
-    InMemoryBuffer buffer;
+    Framework::InMemoryBuffer buffer;
     zMap->writeTo(&buffer);
     char* msg = new char[buffer.getSize()];
     buffer.lese(msg, (int)buffer.getSize());
     setMessage(msg, (int)buffer.getSize());
 }
 
-void NetworkMessage::sendPlayerPositions(char* msg, int length) {
+void NetworkMessage::sendPlayerPositions(char* msg, int length)
+{
     delete[] address;
     addressLength = 1;
     address = new char[1];

+ 11 - 10
FactoryCraft/NoBlock.cpp

@@ -1,17 +1,18 @@
 #include "NoBlock.h"
 
 NoBlockBlockType::NoBlockBlockType(const Block* defaultB, Framework::Text name)
-    : BlockType(0,
-        new ModelInfo("", Framework::RCArray<Framework::Text>(), 0, 1.f),
-        0,
-        1,
-        0,
-        name,
-        false,
-        0,
-        Framework::RCArray<Framework::Text>(), 0),
+    : BlockType(),
       defaultB(defaultB)
-{}
+{
+    setModel(new ModelInfo("", Framework::RCArray<Framework::Text>(), 0, 1.f));
+    setNeedModelSubscription(false);
+    setInitialMaxHP(1);
+    setLightSource(false);
+    setName(name);
+    setNeedModelSubscription(false);
+    setMapColor(0);
+    setHardness(0.f);
+}
 
 ItemType* NoBlockBlockType::createItemType() const
 {

+ 0 - 11
FactoryCraft/OverworldDimension.cpp

@@ -1,11 +0,0 @@
-#include "OverworldDimension.h"
-
-OverworldDimensionFactory::OverworldDimensionFactory()
-    : DimensionFactory(DimensionEnum::OVERWORLD)
-{}
-
-Dimension* OverworldDimensionFactory::createDimension() {
-    Dimension* d = new Dimension(DimensionEnum::OVERWORLD);
-    d->configureDayNightCyncle(300, 30, 600);
-    return d;
-}

+ 0 - 11
FactoryCraft/OverworldDimension.h

@@ -1,11 +0,0 @@
-#pragma once
-
-#include "Dimension.h"
-
-class OverworldDimensionFactory : public DimensionFactory
-{
-public:
-    OverworldDimensionFactory();
-
-    Dimension* createDimension() override;
-};

+ 0 - 479
FactoryCraft/OverworldDimensionGenerator.cpp

@@ -1,479 +0,0 @@
-#include "OverworldDimensionGenerator.h"
-
-#include "FastNoiseWrapper.h"
-#include "RandNoise.h"
-#include "WormCaveGenerator.h"
-#include "Dimension.h"
-
-OverworldDimensionGeneratorFactory::OverworldDimensionGeneratorFactory()
-    : DimensionGeneratorFactory("Overworld", DimensionEnum::OVERWORLD)
-{}
-
-DimensionGenerator* OverworldDimensionGeneratorFactory::createDimensionGenerator(
-    int worldSeed, Framework::JSON::JSONValue* config)
-{
-    return new BiomedCavedDimensionGenerator(config, worldSeed, getDimensionId());
-}
-
-Framework::JSON::Validator::JSONValidator*
-OverworldDimensionGeneratorFactory::getConfigValidator()
-{
-    auto validator = Framework::JSON::Validator::JSONValidator::buildForObject()
-                         ->withRequiredString("dimension")
-                         ->withExactMatch("Overworld")
-                         ->finishString();
-    return BiomedCavedDimensionGenerator::addConfigAttributes(validator)
-        ->finishObject();
-}
-
-Framework::JSON::JSONValue* OverworldDimensionGeneratorFactory::getDefaultConfig()
-{
-    return Framework::JSON::Parser::getValue(
-        "{"
-        "    \"bioms\": ["
-        "        {"
-        "            \"blocks\": ["
-        "                {"
-        "                    \"blockType\": \"Grass\","
-        "                    \"condition\": {"
-        "                        \"operator\": \"&&\","
-        "                        \"type\": \"operator\","
-        "                        \"values\": ["
-        "                            {"
-        "                                \"operator\": \"==\","
-        "                                \"type\": \"operator\","
-        "                                \"values\": ["
-        "                                    {"
-        "                                        \"name\": \"z\","
-        "                                        \"type\": \"variable\""
-        "                                    },"
-        "                                    {"
-        "                                        \"name\": \"h\","
-        "                                        \"type\": \"variable\""
-        "                                    }"
-        "                                ]"
-        "                            },"
-        "                            {"
-        "                                \"blockType\": \"Dirt\","
-        "                                \"type\": \"blockType\","
-        "                                \"x\": {"
-        "                                    \"name\": \"x\","
-        "                                    \"type\": \"variable\""
-        "                                },"
-        "                                \"y\": {"
-        "                                    \"name\": \"y\","
-        "                                    \"type\": \"variable\""
-        "                                },"
-        "                                \"z\": {"
-        "                                    \"operator\": \"-\","
-        "                                    \"type\": \"operator\","
-        "                                    \"values\": ["
-        "                                        {"
-        "                                            \"name\": \"z\","
-        "                                            \"type\": \"variable\""
-        "                                        },"
-        "                                        {"
-        "                                            \"type\": \"constant\","
-        "                                            \"value\": 1"
-        "                                        }"
-        "                                    ]"
-        "                                }"
-        "                            }"
-        "                        ]"
-        "                    },"
-        "                    \"noise\": {"
-        "                        \"seed\": {"
-        "                            \"operator\": \"+\","
-        "                            \"type\": \"operator\","
-        "                            \"values\": ["
-        "                                {"
-        "                                    \"name\": \"dimensionSeed\","
-        "                                    \"type\": \"variable\""
-        "                                },"
-        "                                {"
-        "                                    \"type\": \"constant\","
-        "                                    \"value\": 3"
-        "                                }"
-        "                            ]"
-        "                        },"
-        "                        \"type\": \"random\""
-        "                    },"
-        "                    \"threshold\": 0.25,"
-        "                    \"type\": \"blockType\""
-        "                },"
-        "                {"
-        "                    \"blockType\": \"Gravel\","
-        "                    \"condition\": {"
-        "                        \"operator\": \"<\","
-        "                        \"type\": \"operator\","
-        "                        \"values\": ["
-        "                            {"
-        "                                \"name\": \"z\","
-        "                                \"type\": \"variable\""
-        "                            },"
-        "                            {"
-        "                                \"name\": \"h\","
-        "                                \"type\": \"variable\""
-        "                            }"
-        "                        ]"
-        "                    },"
-        "                    \"noise\": {"
-        "                        \"frequency\": 0.1,"
-        "                        \"seed\": {"
-        "                            \"operator\": \"+\","
-        "                            \"type\": \"operator\","
-        "                            \"values\": ["
-        "                                {"
-        "                                    \"name\": \"dimensionSeed\","
-        "                                    \"type\": \"variable\""
-        "                                },"
-        "                                {"
-        "                                    \"type\": \"constant\","
-        "                                    \"value\": 2"
-        "                                }"
-        "                            ]"
-        "                        },"
-        "                        \"type\": \"ValueCubic\""
-        "                    },"
-        "                    \"threshold\": 0.35,"
-        "                    \"type\": \"blockType\""
-        "                },"
-        "                {"
-        "                    \"blockType\": \"Dirt\","
-        "                    \"condition\": {"
-        "                        \"operator\": \"<\","
-        "                        \"type\": \"operator\","
-        "                        \"values\": ["
-        "                            {"
-        "                                \"name\": \"z\","
-        "                                \"type\": \"variable\""
-        "                            },"
-        "                            {"
-        "                                \"name\": \"h\","
-        "                                \"type\": \"variable\""
-        "                            }"
-        "                        ]"
-        "                    },"
-        "                    \"noise\": {"
-        "                        \"frequency\": 0.125,"
-        "                        \"seed\": {"
-        "                            \"operator\": \"+\","
-        "                            \"type\": \"operator\","
-        "                            \"values\": ["
-        "                                {"
-        "                                    \"name\": \"dimensionSeed\","
-        "                                    \"type\": \"variable\""
-        "                                },"
-        "                                {"
-        "                                    \"type\": \"constant\","
-        "                                    \"value\": 1"
-        "                                }"
-        "                            ]"
-        "                        },"
-        "                        \"type\": \"ValueCubic\""
-        "                    },"
-        "                    \"threshold\": 0.35,"
-        "                    \"type\": \"blockType\""
-        "                },"
-        "                {"
-        "                    \"blockType\": \"Sand\","
-        "                    \"condition\": {"
-        "                        \"operator\": \"&&\","
-        "                        \"type\": \"operator\","
-        "                        \"values\": ["
-        "                            {"
-        "                                \"operator\": \"<\","
-        "                                \"type\": \"operator\","
-        "                                \"values\": ["
-        "                                    {"
-        "                                        \"name\": \"z\","
-        "                                        \"type\": \"variable\""
-        "                                    },"
-        "                                    {"
-        "                                        \"name\": \"h\","
-        "                                        \"type\": \"variable\""
-        "                                    }"
-        "                                ]"
-        "                            },"
-        "                            {"
-        "                                \"operator\": \">\","
-        "                                \"type\": \"operator\","
-        "                                \"values\": ["
-        "                                    {"
-        "                                        \"name\": \"z\","
-        "                                        \"type\": \"variable\""
-        "                                    },"
-        "                                    {"
-        "                                        \"name\": \"underground1\","
-        "                                        \"type\": \"variable\""
-        "                                    }"
-        "                                ]"
-        "                            }"
-        "                        ]"
-        "                    },"
-        "                    \"noise\": {"
-        "                        \"frequency\": 0.125,"
-        "                        \"seed\": {"
-        "                            \"operator\": \"+\","
-        "                            \"type\": \"operator\","
-        "                            \"values\": ["
-        "                                {"
-        "                                    \"name\": \"dimensionSeed\","
-        "                                    \"type\": \"variable\""
-        "                                },"
-        "                                {"
-        "                                    \"type\": \"constant\","
-        "                                    \"value\": 2"
-        "                                }"
-        "                            ]"
-        "                        },"
-        "                        \"type\": \"ValueCubic\""
-        "                    },"
-        "                    \"threshold\": 0.35,"
-        "                    \"type\": \"blockType\""
-        "                },"
-        "                {"
-        "                    \"blockType\": \"Dirt\","
-        "                    \"condition\": {"
-        "                        \"operator\": \"&&\","
-        "                        \"type\": \"operator\","
-        "                        \"values\": ["
-        "                            {"
-        "                                \"operator\": \"<\","
-        "                                \"type\": \"operator\","
-        "                                \"values\": ["
-        "                                    {"
-        "                                        \"name\": \"z\","
-        "                                        \"type\": \"variable\""
-        "                                    },"
-        "                                    {"
-        "                                        \"name\": \"h\","
-        "                                        \"type\": \"variable\""
-        "                                    }"
-        "                                ]"
-        "                            },"
-        "                            {"
-        "                                \"operator\": \">\","
-        "                                \"type\": \"operator\","
-        "                                \"values\": ["
-        "                                    {"
-        "                                        \"name\": \"z\","
-        "                                        \"type\": \"variable\""
-        "                                    },"
-        "                                    {"
-        "                                        \"name\": \"underground1\","
-        "                                        \"type\": \"variable\""
-        "                                    }"
-        "                                ]"
-        "                            }"
-        "                        ]"
-        "                    },"
-        "                    \"type\": \"blockType\""
-        "                },"
-        "                {"
-        "                    \"blockType\": \"Stone\","
-        "                    \"condition\": {"
-        "                        \"operator\": \"<\","
-        "                        \"type\": \"operator\","
-        "                        \"values\": ["
-        "                            {"
-        "                                \"name\": \"z\","
-        "                                \"type\": \"variable\""
-        "                            },"
-        "                            {"
-        "                                \"name\": \"underground1\","
-        "                                \"type\": \"variable\""
-        "                            }"
-        "                        ]"
-        "                    },"
-        "                    \"type\": \"blockType\""
-        "                }"
-        "            ],"
-        "            \"layerModifier\": ["
-        "                {"
-        "                    \"multiplier\": 0.2,"
-        "                    \"name\": \"h\""
-        "                }"
-        "            ],"
-        "            \"name\": \"Grassland\","
-        "            \"structurCollections\": ["
-        "                {"
-        "                    \"noise\": {"
-        "                        \"seed\": {"
-        "                            \"name\": \"dimensionSeed\","
-        "                            \"type\": \"variable\""
-        "                        },"
-        "                        \"type\": \"random\""
-        "                    },"
-        "                    \"structures\": ["
-        "                        {"
-        "                            \"leaves\": \"Birch Wood Leaves\","
-        "                            \"maxSize\": 15,"
-        "                            \"minSize\": 8,"
-        "                            \"propability\": 0.5,"
-        "                            \"type\": \"Tree\","
-        "                            \"wood\": \"Birch Wood\""
-        "                        },"
-        "                        {"
-        "                            \"leaves\": \"Beech Wood Leaves\","
-        "                            \"maxSize\": 13,"
-        "                            \"minSize\": 8,"
-        "                            \"propability\": 0.25,"
-        "                            \"type\": \"Tree\","
-        "                            \"wood\": \"Beech Wood\""
-        "                        },"
-        "                        {"
-        "                            \"leaves\": \"Oak Wood Leaves\","
-        "                            \"maxSize\": 15,"
-        "                            \"minSize\": 10,"
-        "                            \"propability\": 0.125,"
-        "                            \"type\": \"Tree\","
-        "                            \"wood\": \"Oak Wood\""
-        "                        },"
-        "                        {"
-        "                            \"leaves\": \"Pine Wood Leaves\","
-        "                            \"maxSize\": 24,"
-        "                            \"minSize\": 15,"
-        "                            \"propability\": 0.075,"
-        "                            \"type\": \"Tree\","
-        "                            \"wood\": \"Pine Wood\""
-        "                        }"
-        "                    ],"
-        "                    \"threshold\": 0.001"
-        "                }"
-        "            ]"
-        "        }"
-        "    ],"
-        "    \"dimension\": \"Overworld\","
-        "    \"dimensionSeed\": {"
-        "        \"operator\": \"+\","
-        "        \"type\": \"operator\","
-        "        \"values\": ["
-        "            {"
-        "                \"name\": \"worldSeed\","
-        "                \"type\": \"variable\""
-        "            },"
-        "            {"
-        "                \"name\": \"dimensionId\","
-        "                \"type\": \"variable\""
-        "            }"
-        "        ]"
-        "    },"
-        "    \"heightLayers\": ["
-        "        {"
-        "            \"name\": \"h\","
-        "            \"noise\": {"
-        "                \"seed\": {"
-        "                    \"name\": \"dimensionSeed\","
-        "                    \"type\": \"variable\""
-        "                },"
-        "                \"type\": \"ValueCubic\""
-        "            },"
-        "            \"value\": {"
-        "                \"operator\": \"+\","
-        "                \"type\": \"operator\","
-        "                \"values\": ["
-        "                    {"
-        "                        \"type\": \"constant\","
-        "                        \"value\": 50"
-        "                    },"
-        "                    {"
-        "                        \"operator\": \"*\","
-        "                        \"type\": \"operator\","
-        "                        \"values\": ["
-        "                            {"
-        "                                \"type\": \"noise\","
-        "                                \"x\": {"
-        "                                    \"name\": \"x\","
-        "                                    \"type\": \"variable\""
-        "                                },"
-        "                                \"y\": {"
-        "                                    \"name\": \"y\","
-        "                                    \"type\": \"variable\""
-        "                                },"
-        "                                \"z\": {"
-        "                                    \"type\": \"constant\","
-        "                                    \"value\": 0"
-        "                                }"
-        "                            },"
-        "                            {"
-        "                                \"type\": \"constant\","
-        "                                \"value\": 400"
-        "                            }"
-        "                        ]"
-        "                    }"
-        "                ]"
-        "            }"
-        "        },"
-        "        {"
-        "            \"name\": \"underground1\","
-        "            \"noise\": {"
-        "                \"seed\": {"
-        "                    \"name\": \"dimensionSeed\","
-        "                    \"type\": \"variable\""
-        "                },"
-        "                \"type\": \"ValueCubic\""
-        "            },"
-        "            \"value\": {"
-        "                \"operator\": \"-\","
-        "                \"type\": \"operator\","
-        "                \"values\": ["
-        "                    {"
-        "                        \"name\": \"h\","
-        "                        \"type\": \"variable\""
-        "                    },"
-        "                    {"
-        "                        \"type\": \"constant\","
-        "                        \"value\": 5"
-        "                    },"
-        "                    {"
-        "                        \"operator\": \"*\","
-        "                        \"type\": \"operator\","
-        "                        \"values\": ["
-        "                            {"
-        "                                \"type\": \"noise\","
-        "                                \"x\": {"
-        "                                    \"name\": \"x\","
-        "                                    \"type\": \"variable\""
-        "                                },"
-        "                                \"y\": {"
-        "                                    \"name\": \"y\","
-        "                                    \"type\": \"variable\""
-        "                                },"
-        "                                \"z\": {"
-        "                                    \"type\": \"constant\","
-        "                                    \"value\": 0"
-        "                                }"
-        "                            },"
-        "                            {"
-        "                                \"type\": \"constant\","
-        "                                \"value\": 45"
-        "                            }"
-        "                        ]"
-        "                    }"
-        "                ]"
-        "            }"
-        "        }"
-        "    ],"
-        "    \"noiseMaps\": ["
-        "        {"
-        "            \"name\": \"biomNoise\","
-        "            \"noise\": {"
-        "                \"cellularDistanceFunction\": \"Hybrid\","
-        "                \"cellularJitter\": 1,"
-        "                \"cellularReturnType\": \"CellValue\","
-        "                \"domainWarpAmp\": 30,"
-        "                \"domainWarpType\": \"OpenSimplex2Reduced\","
-        "                \"fractalType\": \"None\","
-        "                \"frequency\": 0.015,"
-        "                \"rotationType3D\": \"None\","
-        "                \"seed\": {"
-        "                    \"name\": \"dimensionSeed\","
-        "                    \"type\": \"variable\""
-        "                },"
-        "                \"type\": \"Cellular\""
-        "            }"
-        "        }"
-        "    ]"
-        "}");
-}

+ 0 - 14
FactoryCraft/OverworldDimensionGenerator.h

@@ -1,14 +0,0 @@
-#pragma once
-
-#include "DimensionGenerator.h"
-#include "Noise.h"
-
-class OverworldDimensionGeneratorFactory : public DimensionGeneratorFactory
-{
-public:
-    OverworldDimensionGeneratorFactory();
-    DimensionGenerator* createDimensionGenerator(
-        int worldSeed, Framework::JSON::JSONValue* config) override;
-    Framework::JSON::Validator::JSONValidator* getConfigValidator() override;
-    Framework::JSON::JSONValue* getDefaultConfig() override;
-};

+ 101 - 74
FactoryCraft/PlaceableProof.cpp

@@ -1,13 +1,14 @@
 #include "PlaceableProof.h"
 
 #include "BlockFilter.h"
+#include "Dimension.h"
 #include "Game.h"
 
 PlaceableProof::PlaceableProof()
     : ReferenceCounter()
 {}
 
-PlaceableProofAnd::PlaceableProofAnd(Framework::RCArray<PlaceableProof> proofs)
+PlaceableProofAnd::PlaceableProofAnd()
     : proofs(proofs)
 {}
 
@@ -24,6 +25,11 @@ bool PlaceableProofAnd::isPlacable(
     return true;
 }
 
+void PlaceableProofAnd::addProof(PlaceableProof* proof)
+{
+    proofs.add(proof);
+}
+
 const Framework::RCArray<PlaceableProof>& PlaceableProofAnd::getProofs() const
 {
     return proofs;
@@ -33,42 +39,41 @@ PlaceableProofAndFactory::PlaceableProofAndFactory()
     : SubTypeFactory()
 {}
 
-PlaceableProofAnd* PlaceableProofAndFactory::fromJson(
+PlaceableProofAnd* PlaceableProofAndFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
-    Framework::RCArray<PlaceableProof> proofs;
+    return new PlaceableProofAnd();
+}
+
+void PlaceableProofAndFactory::fromJson(
+    PlaceableProofAnd* zResult, Framework::JSON::JSONObject* zJson) const
+{
     for (Framework::JSON::JSONValue* zProof :
         *zJson->zValue("proofs")->asArray())
     {
-        proofs.add(
+        zResult->addProof(
             Game::INSTANCE->zTypeRegistry()->fromJson<PlaceableProof>(zProof));
     }
-    return new PlaceableProofAnd(proofs);
 }
 
-Framework::JSON::JSONObject* PlaceableProofAndFactory::toJson(
-    PlaceableProofAnd* zObject) const
+void PlaceableProofAndFactory::toJson(
+    PlaceableProofAnd* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
     Framework::JSON::JSONArray* proofs = new Framework::JSON::JSONArray();
     for (PlaceableProof* proof : zObject->getProofs())
     {
         proofs->addValue(Game::INSTANCE->zTypeRegistry()->toJson(proof));
     }
-    result->addValue("proofs", proofs);
-    return result;
+    zResult->addValue("proofs", proofs);
 }
 
-Framework::JSON::Validator::JSONValidator*
-PlaceableProofAndFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
+JSONObjectValidationBuilder* PlaceableProofAndFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
     return builder->withRequiredArray("proofs")
         ->addAcceptedTypeInArray(
             Game::INSTANCE->zTypeRegistry()->getValidator<PlaceableProof>())
-        ->finishArray()
-        ->finishObject();
+        ->finishArray();
 }
 
 Framework::Text PlaceableProofAndFactory::getTypeToken() const
@@ -76,7 +81,7 @@ Framework::Text PlaceableProofAndFactory::getTypeToken() const
     return "and";
 }
 
-PlaceableProofOr::PlaceableProofOr(Framework::RCArray<PlaceableProof> proofs)
+PlaceableProofOr::PlaceableProofOr()
     : proofs(proofs)
 {}
 
@@ -93,6 +98,11 @@ bool PlaceableProofOr::isPlacable(
     return false;
 }
 
+void PlaceableProofOr::addProof(PlaceableProof* proof)
+{
+    proofs.add(proof);
+}
+
 const Framework::RCArray<PlaceableProof>& PlaceableProofOr::getProofs() const
 {
     return proofs;
@@ -102,42 +112,41 @@ PlaceableProofOrFactory::PlaceableProofOrFactory()
     : SubTypeFactory()
 {}
 
-PlaceableProofOr* PlaceableProofOrFactory::fromJson(
+PlaceableProofOr* PlaceableProofOrFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
-    Framework::RCArray<PlaceableProof> proofs;
+    return new PlaceableProofOr();
+}
+
+void PlaceableProofOrFactory::fromJson(
+    PlaceableProofOr* zResult, Framework::JSON::JSONObject* zJson) const
+{
     for (Framework::JSON::JSONValue* zProof :
         *zJson->zValue("proofs")->asArray())
     {
-        proofs.add(
+        zResult->addProof(
             Game::INSTANCE->zTypeRegistry()->fromJson<PlaceableProof>(zProof));
     }
-    return new PlaceableProofOr(proofs);
 }
 
-Framework::JSON::JSONObject* PlaceableProofOrFactory::toJson(
-    PlaceableProofOr* zObject) const
+void PlaceableProofOrFactory::toJson(
+    PlaceableProofOr* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
     Framework::JSON::JSONArray* proofs = new Framework::JSON::JSONArray();
     for (PlaceableProof* proof : zObject->getProofs())
     {
         proofs->addValue(Game::INSTANCE->zTypeRegistry()->toJson(proof));
     }
-    result->addValue("proofs", proofs);
-    return result;
+    zResult->addValue("proofs", proofs);
 }
 
-Framework::JSON::Validator::JSONValidator*
-PlaceableProofOrFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
+JSONObjectValidationBuilder* PlaceableProofOrFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
     return builder->withRequiredArray("proofs")
         ->addAcceptedTypeInArray(
             Game::INSTANCE->zTypeRegistry()->getValidator<PlaceableProof>())
-        ->finishArray()
-        ->finishObject();
+        ->finishArray();
 }
 
 Framework::Text PlaceableProofOrFactory::getTypeToken() const
@@ -145,8 +154,9 @@ Framework::Text PlaceableProofOrFactory::getTypeToken() const
     return "or";
 }
 
-PlaceableProofNot::PlaceableProofNot(PlaceableProof* proof)
-    : PlaceableProof()
+PlaceableProofNot::PlaceableProofNot()
+    : PlaceableProof(),
+      proof(proof)
 {}
 
 PlaceableProofNot::~PlaceableProofNot()
@@ -160,6 +170,8 @@ bool PlaceableProofNot::isPlacable(
     return !proof->isPlacable(item, pos, dimensionId);
 }
 
+void PlaceableProofNot::setProof(PlaceableProof* proof) {}
+
 PlaceableProof* PlaceableProofNot::zProof() const
 {
     return proof;
@@ -169,32 +181,31 @@ PlaceableProofNotFactory::PlaceableProofNotFactory()
     : SubTypeFactory()
 {}
 
-PlaceableProofNot* PlaceableProofNotFactory::fromJson(
+PlaceableProofNot* PlaceableProofNotFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
-    return new PlaceableProofNot(
-        Game::INSTANCE->zTypeRegistry()->fromJson<PlaceableProof>(
-            zJson->zValue("proof")));
+    return new PlaceableProofNot();
 }
 
-Framework::JSON::JSONObject* PlaceableProofNotFactory::toJson(
-    PlaceableProofNot* zObject) const
+void PlaceableProofNotFactory::fromJson(
+    PlaceableProofNot* zResult, Framework::JSON::JSONObject* zJson) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue(
+    zResult->setProof(Game::INSTANCE->zTypeRegistry()->fromJson<PlaceableProof>(
+        zJson->zValue("proof")));
+}
+
+void PlaceableProofNotFactory::toJson(
+    PlaceableProofNot* zObject, Framework::JSON::JSONObject* zResult) const
+{
+    zResult->addValue(
         "proof", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zProof()));
-    return result;
 }
 
-Framework::JSON::Validator::JSONValidator*
-PlaceableProofNotFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
+JSONObjectValidationBuilder* PlaceableProofNotFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
-    return builder
-        ->withRequiredAttribute("proof",
-            Game::INSTANCE->zTypeRegistry()->getValidator<PlaceableProof>())
-        ->finishObject();
+    return builder->withRequiredAttribute("proof",
+        Game::INSTANCE->zTypeRegistry()->getValidator<PlaceableProof>());
 }
 
 Framework::Text PlaceableProofNotFactory::getTypeToken() const
@@ -202,12 +213,11 @@ Framework::Text PlaceableProofNotFactory::getTypeToken() const
     return "not";
 }
 
-PlaceableProofBlockFilter::PlaceableProofBlockFilter(
-    Direction direction, int distance, BlockFilter* filter)
+PlaceableProofBlockFilter::PlaceableProofBlockFilter()
     : PlaceableProof(),
-      direction(direction),
-      distance(distance),
-      filter(filter)
+      direction(NO_DIRECTION),
+      distance(1),
+      filter(0)
 {}
 
 PlaceableProofBlockFilter::~PlaceableProofBlockFilter()
@@ -224,16 +234,31 @@ bool PlaceableProofBlockFilter::isPlacable(
         && filter->test(dim->zBlockOrDefault(pos));
 }
 
+void PlaceableProofBlockFilter::setDirection(Direction direction)
+{
+    this->direction = direction;
+}
+
 Direction PlaceableProofBlockFilter::getDirection() const
 {
     return direction;
 }
 
+void PlaceableProofBlockFilter::setDistance(int distance)
+{
+    this->distance = distance;
+}
+
 int PlaceableProofBlockFilter::getDistance() const
 {
     return distance;
 }
 
+void PlaceableProofBlockFilter::setFilter(BlockFilter* filter)
+{
+    this->filter = filter;
+}
+
 BlockFilter* PlaceableProofBlockFilter::zFilter() const
 {
     return filter;
@@ -243,7 +268,14 @@ PlaceableProofBlockFilterFactory::PlaceableProofBlockFilterFactory()
     : SubTypeFactory()
 {}
 
-PlaceableProofBlockFilter* PlaceableProofBlockFilterFactory::fromJson(
+PlaceableProofBlockFilter* PlaceableProofBlockFilterFactory::createValue(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new PlaceableProofBlockFilter();
+}
+
+void PlaceableProofBlockFilterFactory::fromJson(
+    PlaceableProofBlockFilter* zResult,
     Framework::JSON::JSONObject* zJson) const
 {
     Direction dir = NO_DIRECTION;
@@ -286,14 +318,14 @@ PlaceableProofBlockFilter* PlaceableProofBlockFilterFactory::fromJson(
     {
         dir = WEST;
     }
-    return new PlaceableProofBlockFilter(dir,
-        (int)zJson->zValue("distance")->asNumber()->getNumber(),
-        Game::INSTANCE->zTypeRegistry()->fromJson<BlockFilter>(
-            zJson->zValue("filter")));
+    zResult->setDirection(dir);
+    zResult->setFilter(Game::INSTANCE->zTypeRegistry()->fromJson<BlockFilter>(
+        zJson->zValue("filter")));
 }
 
-Framework::JSON::JSONObject* PlaceableProofBlockFilterFactory::toJson(
-    PlaceableProofBlockFilter* zObject) const
+void PlaceableProofBlockFilterFactory::toJson(
+    PlaceableProofBlockFilter* zObject,
+    Framework::JSON::JSONObject* zResult) const
 {
     Framework::Text dir = "";
     if (zObject->getDirection() == NORTH)
@@ -320,19 +352,15 @@ Framework::JSON::JSONObject* PlaceableProofBlockFilterFactory::toJson(
     {
         dir = "bottom";
     }
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue("direction", new Framework::JSON::JSONString(dir));
-    result->addValue(
+    zResult->addValue("direction", new Framework::JSON::JSONString(dir));
+    zResult->addValue(
         "distance", new Framework::JSON::JSONNumber(zObject->getDistance()));
-    result->addValue(
+    zResult->addValue(
         "filter", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zFilter()));
-    return result;
 }
 
-Framework::JSON::Validator::JSONValidator*
-PlaceableProofBlockFilterFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
+JSONObjectValidationBuilder* PlaceableProofBlockFilterFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
     return builder->withRequiredString("direction")
         ->whichIsOneOf({"top", "bottom", "north", "east", "south", "west"})
@@ -342,8 +370,7 @@ PlaceableProofBlockFilterFactory::getValidator(
         ->withDefault(1.0)
         ->finishNumber()
         ->withRequiredAttribute("filter",
-            Game::INSTANCE->zTypeRegistry()->getValidator<BlockFilter>())
-        ->finishObject();
+            Game::INSTANCE->zTypeRegistry()->getValidator<BlockFilter>());
 }
 
 Framework::Text PlaceableProofBlockFilterFactory::getTypeToken() const

+ 38 - 29
FactoryCraft/PlaceableProof.h

@@ -24,9 +24,10 @@ private:
     Framework::RCArray<PlaceableProof> proofs;
 
 public:
-    PlaceableProofAnd(Framework::RCArray<PlaceableProof> proofs);
+    PlaceableProofAnd();
     bool isPlacable(
         const Item* item, Framework::Vec3<float> pos, int dimensionId) override;
+    void addProof(PlaceableProof* proof);
     const Framework::RCArray<PlaceableProof>& getProofs() const;
 };
 
@@ -35,13 +36,14 @@ class PlaceableProofAndFactory
 {
 public:
     PlaceableProofAndFactory();
-    PlaceableProofAnd* fromJson(
+    PlaceableProofAnd* createValue(
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(
-        PlaceableProofAnd* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    void fromJson(PlaceableProofAnd* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(PlaceableProofAnd* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };
 
@@ -51,9 +53,10 @@ private:
     Framework::RCArray<PlaceableProof> proofs;
 
 public:
-    PlaceableProofOr(Framework::RCArray<PlaceableProof> proofs);
+    PlaceableProofOr();
     bool isPlacable(
         const Item* item, Framework::Vec3<float> pos, int dimensionId) override;
+    void addProof(PlaceableProof* proof);
     const Framework::RCArray<PlaceableProof>& getProofs() const;
 };
 
@@ -62,13 +65,14 @@ class PlaceableProofOrFactory
 {
 public:
     PlaceableProofOrFactory();
-    PlaceableProofOr* fromJson(
+    PlaceableProofOr* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(PlaceableProofOr* zResult,
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(
-        PlaceableProofOr* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    void toJson(PlaceableProofOr* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };
 
@@ -78,10 +82,11 @@ private:
     PlaceableProof* proof;
 
 public:
-    PlaceableProofNot(PlaceableProof* proof);
+    PlaceableProofNot();
     ~PlaceableProofNot();
     bool isPlacable(
         const Item* item, Framework::Vec3<float> pos, int dimensionId) override;
+    void setProof(PlaceableProof* proof);
     PlaceableProof* zProof() const;
 };
 
@@ -90,13 +95,14 @@ class PlaceableProofNotFactory
 {
 public:
     PlaceableProofNotFactory();
-    PlaceableProofNot* fromJson(
+    PlaceableProofNot* createValue(
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(
-        PlaceableProofNot* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    void fromJson(PlaceableProofNot* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(PlaceableProofNot* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };
 
@@ -108,13 +114,15 @@ private:
     BlockFilter* filter;
 
 public:
-    PlaceableProofBlockFilter(
-        Direction direction, int distance, BlockFilter* filter);
+    PlaceableProofBlockFilter();
     ~PlaceableProofBlockFilter();
     bool isPlacable(
         const Item* item, Framework::Vec3<float> pos, int dimensionId) override;
+    void setDirection(Direction direction);
     Direction getDirection() const;
+    void setDistance(int distance);
     int getDistance() const;
+    void setFilter(BlockFilter* filter);
     BlockFilter* zFilter() const;
 };
 
@@ -123,13 +131,14 @@ class PlaceableProofBlockFilterFactory
 {
 public:
     PlaceableProofBlockFilterFactory();
-    PlaceableProofBlockFilter* fromJson(
+    PlaceableProofBlockFilter* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(PlaceableProofBlockFilter* zResult,
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(
-        PlaceableProofBlockFilter* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    void toJson(PlaceableProofBlockFilter* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };
 

+ 10 - 7
FactoryCraft/Player.cpp

@@ -1,10 +1,13 @@
 #include "Player.h"
 
 #include "ArrayUtils.h"
+#include "Block.h"
 #include "Game.h"
 #include "ItemFilter.h"
+#include "ItemStack.h"
 #include "PlayerHand.h"
 #include "QuestDialog.h"
+#include "UIController.h"
 
 Player::Player(Framework::Vec3<float> location, int dimensionId, int entityId)
     : Entity(EntityTypeEnum::PLAYER, location, dimensionId, entityId),
@@ -123,14 +126,15 @@ void Player::useItemSlot(ItemSlot* zSlot, bool left)
             {
                 ItemStack* stack = zSlot->takeItemsOut(
                     zSlot->getNumberOfItems(), NO_DIRECTION);
-                Array<ItemSlot*> fromSlots;
+                Framework::Array<ItemSlot*> fromSlots;
                 for (ItemSlot* slot : *this)
                 {
                     if (slot != zSlot) fromSlots.add(slot);
                 }
-                Array<ItemSlot*> targetSlots;
+                Framework::Array<ItemSlot*> targetSlots;
                 targetSlots.add(zSlot);
-                TypeItemFilter filter(stack->zItem()->zItemType());
+                TypeItemFilter filter;
+                filter.setType(stack->zItem()->zItemType());
                 localTransaction(&fromSlots,
                     &targetSlots,
                     &filter,
@@ -240,7 +244,7 @@ void Player::playerApi(
     case 5:
         {
             // request gui
-            Text uiml = getPlayerGUI();
+            Framework::Text uiml = getPlayerGUI();
             int msgSize = 6 + uiml.getLength();
             char* msg = new char[msgSize];
             msg[0] = 2; // gui message
@@ -405,8 +409,7 @@ void Player::onFall(float collisionSpeed)
 }
 
 PlayerEntityType::PlayerEntityType()
-    : EntityType(
-        "Player",
+    : EntityType("Player",
         new ModelInfo("player", toArray("player.ltdb/player.png", 6), 0, 1.f))
 {}
 
@@ -436,7 +439,7 @@ void PlayerEntityType::saveSuperEntity(
         throw "PlayerEntityType::saveSuperEntity was called with an entity "
               "witch is not an instance of Player";
     zWriter->schreibe((char*)&zPlayer->leftHandPosition, 4);
-    char len = (char)textLength(zPlayer->getName());
+    char len = (char)Framework::textLength(zPlayer->getName());
     zWriter->schreibe(&len, 1);
     zWriter->schreibe(zPlayer->getName(), (int)len);
     EntityType::saveSuperEntity(zEntity, zWriter);

+ 11 - 4
FactoryCraft/PlayerHand.cpp

@@ -4,8 +4,11 @@
 #include "Entity.h"
 
 PlayerHandItemType::PlayerHandItemType()
-    : ItemType("PlayerHand", 0, 0, Framework::RCArray<Framework::Text>())
-{}
+    : ItemType()
+{
+    setName("PlayerHand");
+    setMaxStackSize(0);
+}
 
 Item* PlayerHandItemType::createItem() const
 {
@@ -20,8 +23,12 @@ ItemSkill* PlayerHandItemType::createDefaultItemSkill() const
 void PlayerHandItemType::levelUpItemSkill(ItemSkill* zSkill) const {}
 
 PlayerHandSkill::PlayerHandSkill()
-    : ItemSkill(0.f, 1.f, 1.f)
-{}
+    : ItemSkill()
+{
+    setXp(0.f);
+    setMaxXp(1.f);
+    setLevel(1.f);
+}
 
 bool PlayerHandSkill::use(Entity* zActor, Item* zUsedItem, Block* zTarget)
 {

+ 140 - 113
FactoryCraft/Quest.cpp

@@ -1,13 +1,13 @@
 #include "Quest.h"
 
+#include <Datei.h>
 #include <Fenster.h>
 #include <TextFeld.h>
 
 #include "Game.h"
 
-QuestRequirementStorage::QuestRequirementStorage(Framework::Text requirementId)
+QuestRequirementStorage::QuestRequirementStorage()
     : ReferenceCounter(),
-      requirementId(requirementId),
       fulfilled(0)
 {}
 
@@ -21,6 +21,11 @@ bool QuestRequirementStorage::isFullfilled() const
     return fulfilled;
 }
 
+void QuestRequirementStorage::setRequirementId(Framework::Text requirementId)
+{
+    this->requirementId = requirementId;
+}
+
 const Framework::Text& QuestRequirementStorage::getRequirementId() const
 {
     return requirementId;
@@ -30,42 +35,42 @@ QuestRequirementStorageType::QuestRequirementStorageType()
     : TypeFactory<QuestRequirementStorage>()
 {}
 
-QuestRequirementStorage* QuestRequirementStorageType::fromJson(
-    Framework::JSON::JSONValue* zJson) const
+QuestRequirementStorage* QuestRequirementStorageType::createValue(
+    Framework::JSON::JSONObject* zJson) const
 {
-    QuestRequirementStorage* result = new QuestRequirementStorage(
+    return new QuestRequirementStorage();
+}
+
+void QuestRequirementStorageType::fromJson(
+    QuestRequirementStorage* zResult, Framework::JSON::JSONObject* zJson) const
+{
+    zResult->setRequirementId(
         zJson->asObject()->zValue("requirementId")->asString()->getString());
-    result->setFullfilled(
+    zResult->setFullfilled(
         zJson->asObject()->zValue("fulfilled")->asBool()->getBool());
-    return result;
 }
 
-Framework::JSON::JSONValue* QuestRequirementStorageType::toJson(
-    QuestRequirementStorage* zObject) const
+void QuestRequirementStorageType::toJson(QuestRequirementStorage* zObject,
+    Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue("requirementId",
+    zResult->addValue("requirementId",
         new Framework::JSON::JSONString(zObject->getRequirementId()));
-    result->addValue(
+    zResult->addValue(
         "fulfilled", new Framework::JSON::JSONBool(zObject->isFullfilled()));
-    return result;
 }
 
-Framework::JSON::Validator::JSONValidator*
-QuestRequirementStorageType::getValidator() const
+JSONObjectValidationBuilder* QuestRequirementStorageType::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
-    return Framework::JSON::Validator::JSONValidator::buildForObject()
-        ->withRequiredString("requirementId")
+    return builder->withRequiredString("requirementId")
         ->finishString()
         ->withRequiredBool("fulfilled")
         ->withDefault(false)
-        ->finishBool()
-        ->finishObject();
+        ->finishBool();
 }
 
-QuestStorage::QuestStorage(Framework::Text questId)
-    : questId(questId),
-      finished(0),
+QuestStorage::QuestStorage()
+    : finished(0),
       rewarded(0),
       data(new Framework::JSON::JSONObject())
 {}
@@ -104,12 +109,17 @@ QuestRequirementStorage* QuestStorage::zStorage(Framework::Text requirementId)
             return storage;
         }
     }
-    QuestRequirementStorage* result
-        = new QuestRequirementStorage(requirementId);
+    QuestRequirementStorage* result = new QuestRequirementStorage();
+    result->setRequirementId(requirementId);
     requirements.add(result);
     return result;
 }
 
+void QuestStorage::setQuestId(Framework::Text questId)
+{
+    this->questId = questId;
+}
+
 const Framework::Text& QuestStorage::getQuestId() const
 {
     return questId;
@@ -151,37 +161,41 @@ QuestStorageType::QuestStorageType()
     : TypeFactory<QuestStorage>()
 {}
 
-QuestStorage* QuestStorageType::fromJson(
-    Framework::JSON::JSONValue* zJson) const
+QuestStorage* QuestStorageType::createValue(
+    Framework::JSON::JSONObject* zJson) const
 {
-    QuestStorage* result = new QuestStorage(
+    return new QuestStorage();
+}
+
+void QuestStorageType::fromJson(
+    QuestStorage* zResult, Framework::JSON::JSONObject* zJson) const
+{
+    zResult->setQuestId(
         zJson->asObject()->zValue("questId")->asString()->getString());
-    result->finished
-        = zJson->asObject()->zValue("finished")->asBool()->getBool();
-    result->rewarded
-        = zJson->asObject()->zValue("rewarded")->asBool()->getBool();
+    zResult->setQuestFinished(
+        zJson->asObject()->zValue("finished")->asBool()->getBool());
+    zResult->setQuestRewarded(
+        zJson->asObject()->zValue("rewarded")->asBool()->getBool());
     Framework::JSON::JSONArray* rewardsArray
         = zJson->asObject()->zValue("requirements")->asArray();
     for (int i = 0; i < rewardsArray->getLength(); i++)
     {
-        result->requirements.add(
+        zResult->requirements.add(
             Game::INSTANCE->zTypeRegistry()->fromJson<QuestRequirementStorage>(
                 rewardsArray->zValue(i)->asObject()));
     }
-    result->data->release();
-    result->data = zJson->asObject()->getValue("data")->asObject();
-    return result;
+    zResult->data->release();
+    zResult->data = zJson->asObject()->getValue("data")->asObject();
 }
 
-Framework::JSON::JSONValue* QuestStorageType::toJson(
-    QuestStorage* zObject) const
+void QuestStorageType::toJson(
+    QuestStorage* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue(
+    zResult->addValue(
         "questId", new Framework::JSON::JSONString(zObject->questId));
-    result->addValue(
+    zResult->addValue(
         "finished", new Framework::JSON::JSONBool(zObject->finished));
-    result->addValue(
+    zResult->addValue(
         "rewarded", new Framework::JSON::JSONBool(zObject->rewarded));
     Framework::JSON::JSONArray* rewardsArray = new Framework::JSON::JSONArray();
     for (QuestRequirementStorage* storage : zObject->requirements)
@@ -189,17 +203,15 @@ Framework::JSON::JSONValue* QuestStorageType::toJson(
         rewardsArray->addValue(
             Game::INSTANCE->zTypeRegistry()->toJson(storage));
     }
-    result->addValue("requirements", rewardsArray);
+    zResult->addValue("requirements", rewardsArray);
     Framework::Text dataString = zObject->data->toString();
-    result->addValue("data", Framework::JSON::Parser::getValue(dataString));
-    return result;
+    zResult->addValue("data", Framework::JSON::Parser::getValue(dataString));
 }
 
-Framework::JSON::Validator::JSONValidator*
-QuestStorageType::getValidator() const
+JSONObjectValidationBuilder* QuestStorageType::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
-    return Framework::JSON::Validator::JSONValidator::buildForObject()
-        ->withRequiredString("questId")
+    return builder->withRequiredString("questId")
         ->finishString()
         ->withRequiredBool("finished")
         ->withDefault(false)
@@ -213,7 +225,6 @@ QuestStorageType::getValidator() const
         ->finishArray()
         ->withRequiredObject("data")
         ->allowAdditionalAttriutes()
-        ->finishObject()
         ->finishObject();
 }
 
@@ -250,7 +261,8 @@ QuestStorage* QuestParty::zQuestStorage(Framework::Text questId)
             return storage;
         }
     }
-    QuestStorage* result = new QuestStorage(questId);
+    QuestStorage* result = new QuestStorage();
+    result->setQuestId(questId);
     questStorage.add(result);
     return result;
 }
@@ -273,36 +285,41 @@ QuestPartyType::QuestPartyType()
     : TypeFactory<QuestParty>()
 {}
 
-QuestParty* QuestPartyType::fromJson(Framework::JSON::JSONValue* zJson) const
+QuestParty* QuestPartyType::createValue(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new QuestParty();
+}
+
+void QuestPartyType::fromJson(
+    QuestParty* zResult, Framework::JSON::JSONObject* zJson) const
 {
-    QuestParty* result = new QuestParty();
     Framework::JSON::JSONArray* membersArray
         = zJson->asObject()->zValue("members")->asArray();
     for (int i = 0; i < membersArray->getLength(); i++)
     {
-        result->memberEntityIds.add(
+        zResult->memberEntityIds.add(
             (int)membersArray->zValue(i)->asNumber()->getNumber());
     }
     Framework::JSON::JSONArray* storagesArray
         = zJson->asObject()->zValue("quests")->asArray();
     for (int i = 0; i < storagesArray->getLength(); i++)
     {
-        result->questStorage.add(
+        zResult->questStorage.add(
             Game::INSTANCE->zTypeRegistry()->fromJson<QuestStorage>(
                 storagesArray->zValue(i)->asObject()));
     }
-    return result;
 }
 
-Framework::JSON::JSONValue* QuestPartyType::toJson(QuestParty* zObject) const
+void QuestPartyType::toJson(
+    QuestParty* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
     Framework::JSON::JSONArray* membersArray = new Framework::JSON::JSONArray();
     for (int memberEntityId : zObject->memberEntityIds)
     {
         membersArray->addValue(new Framework::JSON::JSONNumber(memberEntityId));
     }
-    result->addValue("members", membersArray);
+    zResult->addValue("members", membersArray);
     Framework::JSON::JSONArray* storagesArray
         = new Framework::JSON::JSONArray();
     for (QuestStorage* storage : zObject->questStorage)
@@ -310,14 +327,13 @@ Framework::JSON::JSONValue* QuestPartyType::toJson(QuestParty* zObject) const
         storagesArray->addValue(
             Game::INSTANCE->zTypeRegistry()->toJson(storage));
     }
-    result->addValue("quests", storagesArray);
-    return result;
+    zResult->addValue("quests", storagesArray);
 }
 
-Framework::JSON::Validator::JSONValidator* QuestPartyType::getValidator() const
+JSONObjectValidationBuilder* QuestPartyType::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
-    return Framework::JSON::Validator::JSONValidator::buildForObject()
-        ->withRequiredArray("members")
+    return builder->withRequiredArray("members")
         ->addAcceptedNumberInArray()
         ->finishNumber()
         ->removeInvalidEntries()
@@ -326,13 +342,11 @@ Framework::JSON::Validator::JSONValidator* QuestPartyType::getValidator() const
         ->addAcceptedTypeInArray(
             Game::INSTANCE->zTypeRegistry()->getValidator<QuestStorage>())
         ->removeInvalidEntries()
-        ->finishArray()
-        ->finishObject();
+        ->finishArray();
 }
 
-Quest::Quest(Framework::Text questId)
+Quest::Quest()
     : ReferenceCounter(),
-      questId(questId),
       mainQuest(0)
 {}
 
@@ -387,6 +401,11 @@ bool Quest::isActive(QuestParty* zParty)
     return active;
 }
 
+void Quest::setQuestId(Framework::Text questId)
+{
+    this->questId = questId;
+}
+
 const Framework::Text& Quest::getQuestId() const
 {
     return questId;
@@ -412,13 +431,19 @@ QuestType::QuestType()
     : TypeFactory<Quest>()
 {}
 
-Quest* QuestType::fromJson(Framework::JSON::JSONValue* zJson) const
+Quest* QuestType::createValue(Framework::JSON::JSONObject* zJson) const
+{
+    return new Quest();
+}
+
+void QuestType::fromJson(
+    Quest* zResult, Framework::JSON::JSONObject* zJson) const
 {
-    Quest* result = new Quest(
+    zResult->setQuestId(
         zJson->asObject()->zValue("questId")->asString()->getString());
-    result->questName
+    zResult->questName
         = zJson->asObject()->zValue("questName")->asString()->getString();
-    result->description
+    zResult->description
         = zJson->asObject()->zValue("description")->asString()->getString();
     Framework::JSON::JSONArray* requiredQuestGroups
         = zJson->asObject()->zValue("requiredQuestIds")->asArray();
@@ -428,16 +453,16 @@ Quest* QuestType::fromJson(Framework::JSON::JSONValue* zJson) const
             = requiredQuestGroups->zValue(i)->asArray();
         for (int j = 0; j < requiredQuestIdsArray->getLength(); j++)
         {
-            result->requiredQuestsIds.add(new Framework::Text(
+            zResult->requiredQuestsIds.add(new Framework::Text(
                 requiredQuestIdsArray->zValue(j)->asString()->getString()));
-            result->requiredQuestsGroups.add(i);
+            zResult->requiredQuestsGroups.add(i);
         }
     }
     Framework::JSON::JSONArray* requirementsArray
         = zJson->asObject()->zValue("requirements")->asArray();
     for (int i = 0; i < requirementsArray->getLength(); i++)
     {
-        result->requirements.add(
+        zResult->requirements.add(
             Game::INSTANCE->zTypeRegistry()->fromJson<QuestRequirement>(
                 requirementsArray->zValue(i)));
     }
@@ -445,23 +470,22 @@ Quest* QuestType::fromJson(Framework::JSON::JSONValue* zJson) const
         = zJson->asObject()->zValue("rewards")->asArray();
     for (int i = 0; i < rewardsArray->getLength(); i++)
     {
-        result->rewards.add(
+        zResult->rewards.add(
             Game::INSTANCE->zTypeRegistry()->fromJson<QuestReward>(
                 rewardsArray->zValue(i)));
     }
-    result->imagePath
+    zResult->imagePath
         = zJson->asObject()->zValue("imagePath")->asString()->getString();
-    return result;
 }
 
-Framework::JSON::JSONValue* QuestType::toJson(Quest* zObject) const
+void QuestType::toJson(
+    Quest* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue(
+    zResult->addValue(
         "questId", new Framework::JSON::JSONString(zObject->questId));
-    result->addValue(
+    zResult->addValue(
         "questName", new Framework::JSON::JSONString(zObject->questName));
-    result->addValue(
+    zResult->addValue(
         "description", new Framework::JSON::JSONString(zObject->description));
     Framework::JSON::JSONArray* requiredQuestGroupArray
         = new Framework::JSON::JSONArray();
@@ -490,7 +514,7 @@ Framework::JSON::JSONValue* QuestType::toJson(Quest* zObject) const
         requiredQuestGroupArray->addValue(requiredQuestIdsArray);
         requiredQuestIdsArray = new Framework::JSON::JSONArray();
     }
-    result->addValue("requiredQuestIds", requiredQuestGroupArray);
+    zResult->addValue("requiredQuestIds", requiredQuestGroupArray);
     Framework::JSON::JSONArray* requirementsArray
         = new Framework::JSON::JSONArray();
     for (QuestRequirement* requirement : zObject->requirements)
@@ -498,22 +522,21 @@ Framework::JSON::JSONValue* QuestType::toJson(Quest* zObject) const
         requirementsArray->addValue(
             Game::INSTANCE->zTypeRegistry()->toJson(requirement));
     }
-    result->addValue("requirements", requirementsArray);
+    zResult->addValue("requirements", requirementsArray);
     Framework::JSON::JSONArray* rewardsArray = new Framework::JSON::JSONArray();
     for (QuestReward* reward : zObject->rewards)
     {
         rewardsArray->addValue(Game::INSTANCE->zTypeRegistry()->toJson(reward));
     }
-    result->addValue("rewards", rewardsArray);
-    result->addValue(
+    zResult->addValue("rewards", rewardsArray);
+    zResult->addValue(
         "imagePath", new Framework::JSON::JSONString(zObject->imagePath));
-    return result;
 }
 
-Framework::JSON::Validator::JSONValidator* QuestType::getValidator() const
+JSONObjectValidationBuilder* QuestType::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
-    return Framework::JSON::Validator::JSONValidator::buildForObject()
-        ->withRequiredString("questId")
+    return builder->withRequiredString("questId")
         ->finishString()
         ->withRequiredString("questName")
         ->finishString()
@@ -535,13 +558,11 @@ Framework::JSON::Validator::JSONValidator* QuestType::getValidator() const
             Game::INSTANCE->zTypeRegistry()->getValidator<QuestReward>())
         ->finishArray()
         ->withRequiredString("imagePath")
-        ->finishString()
-        ->finishObject();
+        ->finishString();
 }
 
-QuestCollection::QuestCollection(Framework::Text name)
-    : ReferenceCounter(),
-      name(name)
+QuestCollection::QuestCollection()
+    : ReferenceCounter()
 {}
 
 void QuestCollection::processEvent(QuestEvent* zEvent, QuestParty* zParty)
@@ -571,6 +592,11 @@ void QuestCollection::addQuest(Quest* zQuest)
     quests.add(zQuest);
 }
 
+void QuestCollection::setName(Framework::Text name)
+{
+    this->name = name;
+}
+
 const Framework::Text& QuestCollection::getName() const
 {
     return name;
@@ -594,47 +620,48 @@ QuestCollectionType::QuestCollectionType()
     : TypeFactory<QuestCollection>()
 {}
 
-QuestCollection* QuestCollectionType::fromJson(
-    Framework::JSON::JSONValue* zJson) const
+QuestCollection* QuestCollectionType::createValue(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new QuestCollection();
+}
+
+void QuestCollectionType::fromJson(
+    QuestCollection* zResult, Framework::JSON::JSONObject* zJson) const
 {
-    QuestCollection* result = new QuestCollection(
+    zResult->setName(
         zJson->asObject()->zValue("name")->asString()->getString());
     Framework::JSON::JSONArray* questsArray
         = zJson->asObject()->zValue("quests")->asArray();
     for (int i = 0; i < questsArray->getLength(); i++)
     {
-        result->quests.add(Game::INSTANCE->zTypeRegistry()->fromJson<Quest>(
+        zResult->quests.add(Game::INSTANCE->zTypeRegistry()->fromJson<Quest>(
             questsArray->zValue(i)->asObject()));
     }
-    return result;
 }
 
-Framework::JSON::JSONValue* QuestCollectionType::toJson(
-    QuestCollection* zObject) const
+void QuestCollectionType::toJson(
+    QuestCollection* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue("name", new Framework::JSON::JSONString(zObject->name));
+    zResult->addValue("name", new Framework::JSON::JSONString(zObject->name));
     Framework::JSON::JSONArray* questsArray = new Framework::JSON::JSONArray();
     for (Quest* quest : zObject->quests)
     {
         questsArray->addValue(Game::INSTANCE->zTypeRegistry()->toJson(quest));
     }
-    result->addValue("quests", questsArray);
-    return result;
+    zResult->addValue("quests", questsArray);
 }
 
-Framework::JSON::Validator::JSONValidator*
-QuestCollectionType::getValidator() const
+JSONObjectValidationBuilder* QuestCollectionType::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
-    return Framework::JSON::Validator::JSONValidator::buildForObject()
-        ->withRequiredString("name")
+    return builder->withRequiredString("name")
         ->finishString()
         ->withRequiredArray("quests")
         ->addAcceptedTypeInArray(
             Game::INSTANCE->zTypeRegistry()->getValidator<Quest>())
         ->removeInvalidEntries()
-        ->finishArray()
-        ->finishObject();
+        ->finishArray();
 }
 
 QuestManager::QuestManager()
@@ -771,7 +798,7 @@ void QuestManager::saveQuests()
         questCollectionsArray->addValue(
             Game::INSTANCE->zTypeRegistry()->toJson(questCollection));
     }
-    Datei datei(questDir + "/quests.json");
+    Framework::Datei datei(questDir + "/quests.json");
     if (!datei.existiert()) datei.erstellen();
     datei.open(Framework::Datei::Style::schreiben);
     Framework::Text jsonStr = questCollectionsArray->toString();

+ 47 - 21
FactoryCraft/Quest.h

@@ -16,10 +16,11 @@ private:
     bool fulfilled;
 
 public:
-    QuestRequirementStorage(Framework::Text requirementId);
+    QuestRequirementStorage();
 
     void setFullfilled(bool fullfilled);
     bool isFullfilled() const;
+    void setRequirementId(Framework::Text requirementId);
     const Framework::Text& getRequirementId() const;
 
     friend QuestRequirementStorageType;
@@ -29,11 +30,14 @@ class QuestRequirementStorageType : public TypeFactory<QuestRequirementStorage>
 {
 public:
     QuestRequirementStorageType();
-    QuestRequirementStorage* fromJson(
-        Framework::JSON::JSONValue* zJson) const override;
-    Framework::JSON::JSONValue* toJson(
-        QuestRequirementStorage* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator() const override;
+    QuestRequirementStorage* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(QuestRequirementStorage* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(QuestRequirementStorage* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
 };
 
 class QuestStorageType;
@@ -49,7 +53,7 @@ private:
     Framework::JSON::JSONObject* data;
 
 public:
-    QuestStorage(Framework::Text questId);
+    QuestStorage();
     ~QuestStorage();
 
     void setQuestFinished(bool finished);
@@ -57,6 +61,7 @@ public:
     bool isQuestFinished() const;
     bool isQuestRewarded() const;
     QuestRequirementStorage* zStorage(Framework::Text requirementId);
+    void setQuestId(Framework::Text questId);
     const Framework::Text& getQuestId() const;
     bool isVisible() const;
     void setVisible(bool visible);
@@ -72,9 +77,14 @@ class QuestStorageType : public TypeFactory<QuestStorage>
 {
 public:
     QuestStorageType();
-    QuestStorage* fromJson(Framework::JSON::JSONValue* zJson) const override;
-    Framework::JSON::JSONValue* toJson(QuestStorage* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator() const override;
+    QuestStorage* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(QuestStorage* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(QuestStorage* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
 };
 
 class QuestPartyType;
@@ -102,9 +112,14 @@ class QuestPartyType : public TypeFactory<QuestParty>
 {
 public:
     QuestPartyType();
-    QuestParty* fromJson(Framework::JSON::JSONValue* zJson) const override;
-    Framework::JSON::JSONValue* toJson(QuestParty* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator() const override;
+    QuestParty* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(
+        QuestParty* zResult, Framework::JSON::JSONObject* zJson) const override;
+    void toJson(QuestParty* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
 };
 
 class QuestType;
@@ -125,11 +140,12 @@ private:
     Framework::RCArray<QuestReward> rewards;
 
 public:
-    Quest(Framework::Text questId);
+    Quest();
 
     void processEvent(QuestEvent* zEvent, QuestStorage* zStorage);
     bool isVisible(QuestParty* zParty, QuestManager* zManager);
     bool isActive(QuestParty* zParty);
+    void setQuestId(Framework::Text questId);
     const Framework::Text& getQuestId() const;
     void setVisible(bool visible, QuestParty* zParty, QuestManager* zManager);
 
@@ -141,9 +157,13 @@ class QuestType : public TypeFactory<Quest>
 {
 public:
     QuestType();
-    Quest* fromJson(Framework::JSON::JSONValue* zJson) const override;
-    Framework::JSON::JSONValue* toJson(Quest* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator() const override;
+    Quest* createValue(Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(
+        Quest* zResult, Framework::JSON::JSONObject* zJson) const override;
+    void toJson(
+        Quest* zObject, Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
 };
 
 class QuestCollectionType;
@@ -155,12 +175,13 @@ private:
     Framework::RCArray<Quest> quests;
 
 public:
-    QuestCollection(Framework::Text name);
+    QuestCollection();
 
     void processEvent(QuestEvent* zEvent, QuestParty* zParty);
     bool isVisible(QuestParty* zParty, QuestManager* zManager);
     void addQuest(Quest* zQuest);
 
+    void setName(Framework::Text name);
     const Framework::Text& getName() const;
     void setQuestVisible(bool visible,
         Framework::Text questId,
@@ -175,9 +196,14 @@ class QuestCollectionType : public TypeFactory<QuestCollection>
 {
 public:
     QuestCollectionType();
-    QuestCollection* fromJson(Framework::JSON::JSONValue* zJson) const override;
-    Framework::JSON::JSONValue* toJson(QuestCollection* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator() const override;
+    QuestCollection* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(QuestCollection* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(QuestCollection* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
 };
 
 class QuestManager : public virtual Framework::ReferenceCounter

+ 7 - 4
FactoryCraft/QuestDialog.cpp

@@ -4,6 +4,7 @@
 #include <TextFeld.h>
 
 #include "Game.h"
+#include "Quest.h"
 
 QuestDialog::QuestDialog(int playerId)
     : UIDialog("quests", playerId, 0)
@@ -243,7 +244,8 @@ void QuestDialog::api(
                                     requirementId))
                             {
                                 requirement->api(zRequest,
-                                    (RCPointer<Framework::XML::Element>)
+                                    (Framework::RCPointer<
+                                        Framework::XML::Element>)
                                         requirementsContainer.getFirstElement(),
                                     zParty->zQuestStorage(questId));
                             }
@@ -290,7 +292,8 @@ void QuestDialog::api(
                             if (reward->getRewardId().istGleich(reqardId))
                             {
                                 reward->api(zRequest,
-                                    (RCPointer<Framework::XML::Element>)
+                                    (Framework::RCPointer<
+                                        Framework::XML::Element>)
                                         requirementsContainer.getFirstElement(),
                                     zParty->zQuestStorage(questId));
                             }
@@ -429,14 +432,14 @@ void QuestDialog::showQuestDetails(
             Framework::Text("quests;(char)5;") += reward->getRewardId());
     }
     zParent->addChild(rewardsContainer);
-    zParent->addChild(new XML::Element(
+    zParent->addChild(new Framework::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(
+        zParent->addChild(new Framework::XML::Element(
             "<button id=\"give_rewards\" width=\"100\" height=\"20\" "
             "align-left=\"quest_rewards\" align-top=\"quest_requirements\" "
             "margin-left=\"10\" margin-top=\"10\" "

+ 48 - 35
FactoryCraft/QuestRequirement.cpp

@@ -4,11 +4,8 @@
 
 #include "Quest.h"
 
-QuestRequirement::QuestRequirement(
-    Framework::Text id, Framework::Text description)
-    : ReferenceCounter(),
-      id(id),
-      description(description)
+QuestRequirement::QuestRequirement()
+    : ReferenceCounter()
 {}
 
 void QuestRequirement::api(Framework::StreamReader* message,
@@ -16,20 +13,28 @@ void QuestRequirement::api(Framework::StreamReader* message,
     QuestStorage* zStorage)
 {}
 
+void QuestRequirement::setRequirementId(Framework::Text id)
+{
+    this->id = id;
+}
+
 const Framework::Text& QuestRequirement::getRequirementId() const
 {
     return id;
 }
 
+void QuestRequirement::setDescription(Framework::Text description)
+{
+    this->description = description;
+}
+
 const Framework::Text& QuestRequirement::getDescription() const
 {
     return description;
 }
 
-QuestRequirementOpenDialog::QuestRequirementOpenDialog(
-    Framework::Text id, Framework::Text description, Framework::Text dialogId)
-    : QuestRequirement(id, description),
-      dialogId(dialogId)
+QuestRequirementOpenDialog::QuestRequirementOpenDialog()
+    : QuestRequirement()
 {}
 
 void QuestRequirementOpenDialog::processEvent(
@@ -83,44 +88,52 @@ void QuestRequirementOpenDialog::addRequirementUIML(QuestStorage* zStorage,
     zParent->addChild(container);
 }
 
+void QuestRequirementOpenDialog::setDialogId(Framework::Text dialogId)
+{
+    this->dialogId = dialogId;
+}
+
+const Framework::Text& QuestRequirementOpenDialog::getDialogId() const
+{
+    return dialogId;
+}
+
 QuestRequirementOpenDialogType::QuestRequirementOpenDialogType()
-    : SubTypeFactory()
+    : QuestRequirementFactoryBase()
 {}
 
-QuestRequirementOpenDialog* QuestRequirementOpenDialogType::fromJson(
+QuestRequirementOpenDialog* QuestRequirementOpenDialogType::createValue(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new QuestRequirementOpenDialog();
+}
+
+void QuestRequirementOpenDialogType::fromJson(
+    QuestRequirementOpenDialog* zResult,
     Framework::JSON::JSONObject* zJson) const
 {
-    return new QuestRequirementOpenDialog(
-        zJson->zValue("id")->asString()->getString(),
-        zJson->zValue("description")->asString()->getString(),
-        zJson->zValue("dialogId")->asString()->getString());
+    zResult->setDialogId(zJson->zValue("dialogId")->asString()->getString());
+    QuestRequirementFactoryBase::fromJson(zResult, zJson);
 }
 
-Framework::JSON::JSONObject* QuestRequirementOpenDialogType::toJson(
-    QuestRequirementOpenDialog* zObject) const
+void QuestRequirementOpenDialogType::toJson(QuestRequirementOpenDialog* zObject,
+    Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* json = new Framework::JSON::JSONObject();
-    json->addValue(
-        "id", new Framework::JSON::JSONString(zObject->getRequirementId()));
-    json->addValue("description",
-        new Framework::JSON::JSONString(zObject->getDescription()));
-    json->addValue(
+    zResult->addValue(
         "dialogId", new Framework::JSON::JSONString(zObject->dialogId));
-    return json;
+    QuestRequirementFactoryBase::toJson(zObject, zResult);
 }
 
-Framework::JSON::Validator::JSONValidator*
-QuestRequirementOpenDialogType::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
+JSONObjectValidationBuilder* QuestRequirementOpenDialogType::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
-    return builder->withRequiredString("id")
-        ->finishString()
-        ->withRequiredString("description")
-        ->finishString()
-        ->withRequiredString("dialogId")
-        ->finishString()
-        ->finishObject();
+    return QuestRequirementFactoryBase::addToValidator(
+        builder->withRequiredString("id")
+            ->finishString()
+            ->withRequiredString("description")
+            ->finishString()
+            ->withRequiredString("dialogId")
+            ->finishString());
 }
 
 Framework::Text QuestRequirementOpenDialogType::getTypeToken() const

+ 52 - 11
FactoryCraft/QuestRequirement.h

@@ -12,7 +12,7 @@ protected:
     Framework::Text description;
 
 public:
-    QuestRequirement(Framework::Text id, Framework::Text description);
+    QuestRequirement();
     virtual void processEvent(QuestEvent* zEvent, QuestStorage* zStorage) = 0;
     virtual void addRequirementUIML(QuestStorage* zStorage,
         Framework::XML::Element* zParent,
@@ -21,10 +21,50 @@ public:
     virtual void api(Framework::StreamReader* message,
         Framework::XML::Element* zParent,
         QuestStorage* zStorage);
+    void setRequirementId(Framework::Text id);
     const Framework::Text& getRequirementId() const;
+    void setDescription(Framework::Text description);
     const Framework::Text& getDescription() const;
 };
 
+template<typename S> class QuestRequirementFactoryBase
+    : public SubTypeFactory<QuestRequirement, S>
+{
+public:
+    QuestRequirementFactoryBase()
+        : SubTypeFactory<QuestRequirement, S>()
+    {}
+
+    void fromJson(S* zResult, Framework::JSON::JSONObject* zJson) const override
+    {
+        QuestRequirement* zRequirement
+            = dynamic_cast<QuestRequirement*>(zResult);
+        zRequirement->setRequirementId(
+            zJson->zValue("id")->asString()->getString());
+        zRequirement->setDescription(
+            zJson->zValue("description")->asString()->getString());
+    }
+
+    void toJson(S* zObject, Framework::JSON::JSONObject* zResult) const override
+    {
+        QuestRequirement* zRequirement
+            = dynamic_cast<QuestRequirement*>(zObject);
+        zResult->addValue("id",
+            new Framework::JSON::JSONString(zRequirement->getRequirementId()));
+        zResult->addValue("description",
+            new Framework::JSON::JSONString(zRequirement->getDescription()));
+    }
+
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override
+    {
+        return builder->withRequiredString("id")
+            ->finishString()
+            ->withRequiredString("description")
+            ->finishString();
+    }
+};
+
 class QuestRequirementOpenDialogType;
 
 class QuestRequirementOpenDialog : public QuestRequirement
@@ -33,29 +73,30 @@ private:
     Framework::Text dialogId;
 
 public:
-    QuestRequirementOpenDialog(Framework::Text id,
-        Framework::Text description,
-        Framework::Text dialogId);
+    QuestRequirementOpenDialog();
     void processEvent(QuestEvent* zEvent, QuestStorage* zStorage) override;
     void addRequirementUIML(QuestStorage* zStorage,
         Framework::XML::Element* zParent,
         Framework::Text onClickPrefix) override;
+    void setDialogId(Framework::Text dialogId);
+    const Framework::Text& getDialogId() const;
 
     friend QuestRequirementOpenDialogType;
 };
 
 class QuestRequirementOpenDialogType
-    : public SubTypeFactory<QuestRequirement, QuestRequirementOpenDialog>
+    : public QuestRequirementFactoryBase<QuestRequirementOpenDialog>
 {
 public:
     QuestRequirementOpenDialogType();
-    QuestRequirementOpenDialog* fromJson(
+    QuestRequirementOpenDialog* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(QuestRequirementOpenDialog* zResult,
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(
-        QuestRequirementOpenDialog* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    void toJson(QuestRequirementOpenDialog* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };
 

+ 84 - 59
FactoryCraft/QuestReward.cpp

@@ -5,8 +5,9 @@
 #include "Entity.h"
 #include "Game.h"
 #include "Player.h"
+#include "Quest.h"
 
-QuestReward::QuestReward(Framework::Text rewardId)
+QuestReward::QuestReward()
     : ReferenceCounter(),
       rewardId(rewardId)
 {}
@@ -22,20 +23,31 @@ void QuestReward::api(Framework::StreamReader* message,
     QuestStorage* zStorage)
 {}
 
+void QuestReward::setRewardId(Framework::Text rewardId)
+{
+    this->rewardId = rewardId;
+}
+
 const Framework::Text& QuestReward::getRewardId() const
 {
     return rewardId;
 }
 
-ItemStackInfo::ItemStackInfo(Item* item, int count)
+ItemStackInfo::ItemStackInfo()
     : ReferenceCounter(),
-      item(item),
-      count(count)
+      item(0),
+      count(0)
 {}
 
 ItemStackInfo::~ItemStackInfo()
 {
-    item->release();
+    if (item) item->release();
+}
+
+void ItemStackInfo::setItem(Item* item)
+{
+    if (this->item) this->item->release();
+    this->item = item;
 }
 
 Item* ItemStackInfo::zItem() const
@@ -43,6 +55,11 @@ Item* ItemStackInfo::zItem() const
     return item;
 }
 
+void ItemStackInfo::setCount(int count)
+{
+    this->count = count;
+}
+
 int ItemStackInfo::getCount() const
 {
     return count;
@@ -52,47 +69,51 @@ ItemStackInfoType::ItemStackInfoType()
     : TypeFactory<ItemStackInfo>()
 {}
 
-ItemStackInfo* ItemStackInfoType::fromJson(
-    Framework::JSON::JSONValue* zJson) const
+ItemStackInfo* ItemStackInfoType::createValue(
+    Framework::JSON::JSONObject* zJson) const
 {
-    return new ItemStackInfo(Game::INSTANCE->zTypeRegistry()->fromJson<Item>(
-                                 zJson->asObject()->zValue("item")),
+    return new ItemStackInfo();
+}
+
+void ItemStackInfoType::fromJson(
+    ItemStackInfo* zObject, Framework::JSON::JSONObject* zJson) const
+{
+    zObject->setItem(Game::INSTANCE->zTypeRegistry()->fromJson<Item>(
+        zJson->asObject()->zValue("item")));
+    zObject->setCount(
         (int)zJson->asObject()->zValue("count")->asNumber()->getNumber());
 }
 
-Framework::JSON::JSONValue* ItemStackInfoType::toJson(
-    ItemStackInfo* zObject) const
+void ItemStackInfoType::toJson(
+    ItemStackInfo* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue(
+    zResult->addValue(
         "item", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zItem()));
-    result->addValue(
+    zResult->addValue(
         "count", new Framework::JSON::JSONNumber((double)zObject->getCount()));
-    return result;
 }
 
-Framework::JSON::Validator::JSONValidator*
-ItemStackInfoType::getValidator() const
+JSONObjectValidationBuilder* ItemStackInfoType::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
-    return Framework::JSON::Validator::JSONValidator::buildForObject()
+    return builder
         ->withRequiredAttribute(
             "item", Game::INSTANCE->zTypeRegistry()->getValidator<Item>())
         ->withRequiredNumber("count")
         ->withDefault(1.0)
         ->whichIsGreaterOrEqual(1.0)
-        ->finishNumber()
-        ->finishObject();
+        ->finishNumber();
 }
 
-QuestRewardGiveItems::QuestRewardGiveItems(Framework::Text rewardId)
-    : QuestReward(rewardId)
+QuestRewardGiveItems::QuestRewardGiveItems()
+    : QuestReward()
 {}
 
 void QuestRewardGiveItems::giveReward(Framework::XML::Element* zParent,
     QuestStorage* zStorage,
     Entity* zTargetEntity)
 {
-    Player *p = dynamic_cast<Player*>(zTargetEntity);
+    Player* p = dynamic_cast<Player*>(zTargetEntity);
     if (p)
     {
         zStorage->putValue(
@@ -142,74 +163,78 @@ void QuestRewardGiveItems::addRewardUIML(Framework::XML::Element* zParent,
             new Framework::XML::Element(info->zItem()->getTooltipUIML()));
         auto text = new Framework::XML::Element(
             "<text margin-left=\"10\" width=\"auto\" height=\"auto\"/>");
-        text->setAttribute(
-            "id", (Framework::Text("reward_") += rewardId) += "_item_description");
+        text->setAttribute("id",
+            (Framework::Text("reward_") += rewardId) += "_item_description");
         text->setText((Framework::Text(info->getCount()) += " ")
                       += info->zItem()->getName());
         text->setAttribute("align-left", stack->getAttributeValue("id"));
         text->setAttribute("align-y", stack->getAttributeValue("id"));
         container->addChild(stack);
         container->addChild(text);
-        if (zStorage->containsKey( (Framework::Text("reward_") += rewardId) += "_given_to"))
-		{
-			auto givenTo = new Framework::XML::Element(
-				"<text width=\"auto\" height=\"auto\" margin-top=\"10\" text-color=\"0xFF00FF00\"/>");
-            auto name = zStorage->zValue(
-				(Framework::Text("reward_") += rewardId) += "_given_to")->asString();
-            givenTo->setText((Framework::Text("Given to: ") += name->getString()));
+        if (zStorage->containsKey(
+                (Framework::Text("reward_") += rewardId) += "_given_to"))
+        {
+            auto givenTo = new Framework::XML::Element(
+                "<text width=\"auto\" height=\"auto\" margin-top=\"10\" "
+                "text-color=\"0xFF00FF00\"/>");
+            auto name = zStorage
+                            ->zValue((Framework::Text("reward_") += rewardId)
+                                     += "_given_to")
+                            ->asString();
+            givenTo->setText(
+                (Framework::Text("Given to: ") += name->getString()));
             givenTo->setAttribute("align-top", text->getAttributeValue("id"));
             givenTo->setAttribute("align-x", text->getAttributeValue("id"));
             container->addChild(givenTo);
-		}
+        }
     }
     zParent->addChild(container);
 }
 
 QuestRewardGiveItemsType::QuestRewardGiveItemsType()
-    : SubTypeFactory()
+    : QuestRewardFactoryBase()
 {}
 
-QuestRewardGiveItems* QuestRewardGiveItemsType::fromJson(
+QuestRewardGiveItems* QuestRewardGiveItemsType::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
-    QuestRewardGiveItems* result = new QuestRewardGiveItems(
-        zJson->zValue("rewardId")->asString()->getString());
+    return new QuestRewardGiveItems();
+}
+
+void QuestRewardGiveItemsType::fromJson(
+    QuestRewardGiveItems* zResult, Framework::JSON::JSONObject* zJson) const
+{
     Framework::JSON::JSONArray* itemsJson = zJson->zValue("items")->asArray();
     for (Framework::JSON::JSONValue* itemJson : *itemsJson)
     {
-        result->items.add(
+        zResult->items.add(
             Game::INSTANCE->zTypeRegistry()->fromJson<ItemStackInfo>(itemJson));
     }
-    return result;
+    QuestRewardFactoryBase::fromJson(zResult, zJson);
 }
 
-Framework::JSON::JSONObject* QuestRewardGiveItemsType::toJson(
-    QuestRewardGiveItems* zObject) const
+void QuestRewardGiveItemsType::toJson(
+    QuestRewardGiveItems* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue(
+    zResult->addValue(
         "rewardId", new Framework::JSON::JSONString(zObject->getRewardId()));
     Framework::JSON::JSONArray* itemsJson = new Framework::JSON::JSONArray();
     for (ItemStackInfo* item : zObject->items)
     {
         itemsJson->addValue(Game::INSTANCE->zTypeRegistry()->toJson(item));
     }
-    result->addValue("items", itemsJson);
-    return result;
-}
-
-Framework::JSON::Validator::JSONValidator*
-QuestRewardGiveItemsType::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
-{
-    return builder->withRequiredString("rewardId")
-        ->finishString()
-        ->withRequiredArray("items")
-        ->addAcceptedTypeInArray(
-            Game::INSTANCE->zTypeRegistry()->getValidator<ItemStackInfo>())
-        ->finishArray()
-        ->finishObject();
+    zResult->addValue("items", itemsJson);
+    QuestRewardFactoryBase::toJson(zObject, zResult);
+}
+
+JSONObjectValidationBuilder* QuestRewardGiveItemsType::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return QuestRewardFactoryBase::addToValidator(
+        builder->withRequiredArray("items")
+            ->addAcceptedTypeInArray(
+                Game::INSTANCE->zTypeRegistry()->getValidator<ItemStackInfo>())
+            ->finishArray());
 }
 
 Framework::Text QuestRewardGiveItemsType::getTypeToken() const

+ 56 - 18
FactoryCraft/QuestReward.h

@@ -12,23 +12,53 @@ protected:
     Framework::Text rewardId;
 
 public:
-    QuestReward(Framework::Text rewardId);
+    QuestReward();
 
     virtual void giveReward(Framework::XML::Element* zParent,
         QuestStorage* zStorage,
         Entity* zTargetEntity)
         = 0;
-    virtual void addRewardUIML(
-        Framework::XML::Element* zParent, QuestStorage* zStorage, Framework::Text onClickPrefix)
+    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);
-
+    virtual void api(Framework::StreamReader* message,
+        Framework::XML::Element* zParent,
+        QuestStorage* zStorage);
+    void setRewardId(Framework::Text rewardId);
     const Framework::Text& getRewardId() const;
 };
 
+template<typename S> class QuestRewardFactoryBase
+    : public SubTypeFactory<QuestReward, S>
+{
+public:
+    QuestRewardFactoryBase()
+        : SubTypeFactory<QuestReward, S>()
+    {}
+
+    void fromJson(S* zResult, Framework::JSON::JSONObject* zJson) const override
+    {
+        QuestReward* zRequirement = dynamic_cast<QuestReward*>(zResult);
+        zRequirement->setRewardId(zJson->zValue("rewardId")->asString()->getString());
+    }
+
+    void toJson(S* zObject, Framework::JSON::JSONObject* zResult) const override
+    {
+        QuestReward* zRequirement = dynamic_cast<QuestReward*>(zObject);
+        zResult->addValue(
+            "rewardId", new Framework::JSON::JSONString(zRequirement->getRewardId()));
+    }
+
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override
+    {
+        return builder->withRequiredString("rewardId")->finishString();
+    }
+};
+
 class ItemStackInfo : public virtual Framework::ReferenceCounter
 {
 private:
@@ -36,9 +66,11 @@ private:
     int count;
 
 public:
-    ItemStackInfo(Item* item, int count);
+    ItemStackInfo();
     ~ItemStackInfo();
+    void setItem(Item* item);
     Item* zItem() const;
+    void setCount(int count);
     int getCount() const;
 };
 
@@ -46,9 +78,14 @@ class ItemStackInfoType : public TypeFactory<ItemStackInfo>
 {
 public:
     ItemStackInfoType();
-    ItemStackInfo* fromJson(Framework::JSON::JSONValue* zJson) const override;
-    Framework::JSON::JSONValue* toJson(ItemStackInfo* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator() const override;
+    ItemStackInfo* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(ItemStackInfo* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(ItemStackInfo* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
 };
 
 class QuestRewardGiveItemsType;
@@ -59,7 +96,7 @@ private:
     Framework::RCArray<ItemStackInfo> items;
 
 public:
-    QuestRewardGiveItems(Framework::Text rewardId);
+    QuestRewardGiveItems();
 
     void giveReward(Framework::XML::Element* zParent,
         QuestStorage* zStorage,
@@ -72,16 +109,17 @@ public:
 };
 
 class QuestRewardGiveItemsType
-    : public SubTypeFactory<QuestReward, QuestRewardGiveItems>
+    : public QuestRewardFactoryBase<QuestRewardGiveItems>
 {
 public:
     QuestRewardGiveItemsType();
-    QuestRewardGiveItems* fromJson(
+    QuestRewardGiveItems* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(QuestRewardGiveItems* zResult,
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(
-        QuestRewardGiveItems* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    void toJson(QuestRewardGiveItems* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };

+ 198 - 178
FactoryCraft/Recipie.cpp

@@ -4,12 +4,11 @@
 #include "Game.h"
 #include "Item.h"
 
-RecipieInput::RecipieInput(
-    ItemFilter* filter, ItemModifier* modifier, int amount)
+RecipieInput::RecipieInput()
     : ReferenceCounter(),
-      filter(filter),
-      modifier(modifier),
-      amount(amount)
+      filter(0),
+      modifier(0),
+      amount(0)
 {}
 
 RecipieInput::~RecipieInput()
@@ -18,16 +17,33 @@ RecipieInput::~RecipieInput()
     if (modifier) modifier->release();
 }
 
+void RecipieInput::setFilter(ItemFilter* filter)
+{
+    if (filter) filter->release();
+    filter = filter;
+}
+
 ItemFilter* RecipieInput::zFilter() const
 {
     return filter;
 }
 
+void RecipieInput::setModifier(ItemModifier* modifier)
+{
+    if (modifier) modifier->release();
+    modifier = modifier;
+}
+
 ItemModifier* RecipieInput::zModifier() const
 {
     return modifier;
 }
 
+void RecipieInput::setAmount(int amount)
+{
+    this->amount = amount;
+}
+
 int RecipieInput::getAmount() const
 {
     return amount;
@@ -37,38 +53,43 @@ RecipieInputFactory::RecipieInputFactory()
     : TypeFactory()
 {}
 
-RecipieInput* RecipieInputFactory::fromJson(
-    Framework::JSON::JSONValue* zJson) const
+RecipieInput* RecipieInputFactory::createValue(
+    Framework::JSON::JSONObject* zJson) const
 {
-    return new RecipieInput(
-        Game::INSTANCE->zTypeRegistry()->fromJson<ItemFilter>(
-            zJson->asObject()->zValue("filter")),
+    return new RecipieInput();
+}
+
+void RecipieInputFactory::fromJson(
+    RecipieInput* zResult, Framework::JSON::JSONObject* zJson) const
+{
+    zResult->setFilter(Game::INSTANCE->zTypeRegistry()->fromJson<ItemFilter>(
+        zJson->asObject()->zValue("filter")));
+    zResult->setModifier(
         Game::INSTANCE->zTypeRegistry()->fromJson<ItemModifier>(
-            zJson->asObject()->zValue("modifier")),
+            zJson->asObject()->zValue("modifier")));
+    zResult->setAmount(
         (int)zJson->asObject()->zValue("amount")->asNumber()->getNumber());
 }
 
-Framework::JSON::JSONValue* RecipieInputFactory::toJson(
-    RecipieInput* zObject) const
+void RecipieInputFactory::toJson(
+    RecipieInput* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue(
+    zResult->addValue(
         "filter", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zFilter()));
-    result->addValue("modifier",
+    zResult->addValue("modifier",
         Game::INSTANCE->zTypeRegistry()->toJson(zObject->zModifier()));
-    result->addValue("amount",
+    zResult->addValue("amount",
         new Framework::JSON::JSONNumber((double)zObject->getAmount()));
-    return result;
 }
 
-Framework::JSON::Validator::JSONValidator*
-RecipieInputFactory::getValidator() const
+JSONObjectValidationBuilder* RecipieInputFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
     Framework::JSON::JSONObject* defaultModifier
         = new Framework::JSON::JSONObject();
     defaultModifier->addValue(
         "type", new Framework::JSON::JSONString("consume"));
-    return Framework::JSON::Validator::JSONValidator::buildForObject()
+    return builder
         ->withRequiredAttribute("filter",
             Game::INSTANCE->zTypeRegistry()->getValidator<ItemFilter>())
         ->withRequiredAttribute("modifier",
@@ -82,15 +103,14 @@ RecipieInputFactory::getValidator() const
         ->withRequiredNumber("amount")
         ->whichIsGreaterOrEqual(1.0)
         ->withDefault(1.0)
-        ->finishNumber()
-        ->finishObject();
+        ->finishNumber();
 }
 
-RecipieOutput::RecipieOutput(int itemTypeId, int amount, ItemModifier* modifier)
+RecipieOutput::RecipieOutput()
     : ReferenceCounter(),
-      itemTypeId(itemTypeId),
-      amount(amount),
-      modifier(modifier)
+      itemTypeId(0),
+      amount(0),
+      modifier(0)
 {}
 
 RecipieOutput::~RecipieOutput()
@@ -98,16 +118,32 @@ RecipieOutput::~RecipieOutput()
     modifier->release();
 }
 
+void RecipieOutput::setItemTypeId(int itemTypeId)
+{
+    this->itemTypeId = itemTypeId;
+}
+
 int RecipieOutput::getItemTypeId() const
 {
     return itemTypeId;
 }
 
+void RecipieOutput::setAmount(int amount)
+{
+    this->amount = amount;
+}
+
 int RecipieOutput::getAmount() const
 {
     return amount;
 }
 
+void RecipieOutput::setModifier(ItemModifier* modifier)
+{
+    if (this->modifier) this->modifier->release();
+    this->modifier = modifier;
+}
+
 ItemModifier* RecipieOutput::zModifier() const
 {
     return modifier;
@@ -127,33 +163,38 @@ RecipieOutputFactory::RecipieOutputFactory()
     : TypeFactory()
 {}
 
-RecipieOutput* RecipieOutputFactory::fromJson(
-    Framework::JSON::JSONValue* zJson) const
+RecipieOutput* RecipieOutputFactory::createValue(
+    Framework::JSON::JSONObject* zJson) const
 {
-    return new RecipieOutput(
-        Game::INSTANCE->getItemTypeId(
-            zJson->asObject()->zValue("itemType")->asString()->getString()),
-        (int)zJson->asObject()->zValue("amount")->asNumber()->getNumber(),
+    return new RecipieOutput();
+}
+
+void RecipieOutputFactory::fromJson(
+    RecipieOutput* zResult, Framework::JSON::JSONObject* zJson) const
+{
+    zResult->setItemTypeId(Game::INSTANCE->getItemTypeId(
+        zJson->asObject()->zValue("itemType")->asString()->getString()));
+    zResult->setAmount(
+        (int)zJson->asObject()->zValue("amount")->asNumber()->getNumber());
+    zResult->setModifier(
         Game::INSTANCE->zTypeRegistry()->fromJson<ItemModifier>(
             zJson->asObject()->zValue("modifier")));
 }
 
-Framework::JSON::JSONValue* RecipieOutputFactory::toJson(
-    RecipieOutput* zObject) const
+void RecipieOutputFactory::toJson(
+    RecipieOutput* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue("itemType",
+    zResult->addValue("itemType",
         new Framework::JSON::JSONString(
             Game::INSTANCE->zItemType(zObject->getItemTypeId())->getName()));
-    result->addValue("amount",
+    zResult->addValue("amount",
         new Framework::JSON::JSONNumber((double)zObject->getAmount()));
-    result->addValue("modifier",
+    zResult->addValue("modifier",
         Game::INSTANCE->zTypeRegistry()->toJson(zObject->zModifier()));
-    return result;
 }
 
-Framework::JSON::Validator::JSONValidator*
-RecipieOutputFactory::getValidator() const
+JSONObjectValidationBuilder* RecipieOutputFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
     Framework::JSON::JSONObject* defaultModifier
         = new Framework::JSON::JSONObject();
@@ -168,8 +209,7 @@ RecipieOutputFactory::getValidator() const
                 new Framework::Text(Game::INSTANCE->zItemType(i)->getName()));
         }
     }
-    return Framework::JSON::Validator::JSONValidator::buildForObject()
-        ->withRequiredString("itemType")
+    return builder->withRequiredString("itemType")
         ->whichIsOneOf(itemTypes)
         ->finishString()
         ->withRequiredAttribute("modifier",
@@ -183,17 +223,20 @@ RecipieOutputFactory::getValidator() const
         ->withRequiredNumber("amount")
         ->whichIsGreaterOrEqual(1.0)
         ->withDefault(1.0)
-        ->finishNumber()
-        ->finishObject();
+        ->finishNumber();
 }
 
-Recipie::Recipie(
-    Framework::RCArray<RecipieOutput> outputs, Framework::Text groupName)
+Recipie::Recipie()
     : ReferenceCounter(),
       groupName(groupName),
       outputs(outputs)
 {}
 
+void Recipie::addOutput(RecipieOutput* outputs)
+{
+    this->outputs.add(outputs);
+}
+
 Framework::Array<ItemInfo> Recipie::getOutput() const
 {
     Framework::Array<ItemInfo> result;
@@ -226,6 +269,11 @@ bool Recipie::createsOutput(int itemTypeId)
     return 0;
 }
 
+void Recipie::setGroupName(Framework::Text groupName)
+{
+    this->groupName = groupName;
+}
+
 const Framework::RCArray<RecipieOutput>& Recipie::getOutputs() const
 {
     return outputs;
@@ -236,11 +284,8 @@ Framework::Text Recipie::getGroupName() const
     return groupName;
 }
 
-UnshapedRecipie::UnshapedRecipie(Framework::RCArray<RecipieInput> inputs,
-    Framework::RCArray<RecipieOutput> outputs,
-    Framework::Text groupName)
-    : Recipie(outputs, groupName),
-      inputs(inputs)
+UnshapedRecipie::UnshapedRecipie()
+    : Recipie()
 {}
 
 bool UnshapedRecipie::testApplicability(CraftingStorage* zStorage)
@@ -311,95 +356,71 @@ Framework::Text UnshapedRecipie::getRecipieUIML()
     return result;
 }
 
+void UnshapedRecipie::addInput(RecipieInput* input)
+{
+    inputs.add(input);
+}
+
 const Framework::RCArray<RecipieInput>& UnshapedRecipie::getInputs() const
 {
     return inputs;
 }
 
 UnshapedRecipieFactory::UnshapedRecipieFactory()
-    : SubTypeFactory()
+    : RecipieFactory()
 {}
 
-UnshapedRecipie* UnshapedRecipieFactory::fromJson(
+UnshapedRecipie* UnshapedRecipieFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
-    Framework::RCArray<RecipieInput> inputs;
-    Framework::RCArray<RecipieOutput> outputs;
+    return new UnshapedRecipie();
+}
+
+void UnshapedRecipieFactory::fromJson(
+    UnshapedRecipie* zResult, Framework::JSON::JSONObject* zJson) const
+{
     for (Framework::JSON::JSONValue* input :
         *zJson->zValue("inputs")->asArray())
     {
-        inputs.add(
+        zResult->addInput(
             Game::INSTANCE->zTypeRegistry()->fromJson<RecipieInput>(input));
     }
-    for (Framework::JSON::JSONValue* output :
-        *zJson->zValue("outputs")->asArray())
-    {
-        outputs.add(
-            Game::INSTANCE->zTypeRegistry()->fromJson<RecipieOutput>(output));
-    }
-    return new UnshapedRecipie(
-        inputs, outputs, zJson->zValue("group")->asString()->getString());
+    RecipieFactory::fromJson(zResult, zJson);
 }
 
-Framework::JSON::JSONObject* UnshapedRecipieFactory::toJson(
-    UnshapedRecipie* zObject) const
+void UnshapedRecipieFactory::toJson(
+    UnshapedRecipie* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
     Framework::JSON::JSONArray* inputs = new Framework::JSON::JSONArray();
     for (RecipieInput* input : zObject->getInputs())
     {
         inputs->addValue(Game::INSTANCE->zTypeRegistry()->toJson(input));
     }
-    result->addValue("inputs", inputs);
-    Framework::JSON::JSONArray* outputs = new Framework::JSON::JSONArray();
-    for (RecipieOutput* output : zObject->getOutputs())
-    {
-        inputs->addValue(Game::INSTANCE->zTypeRegistry()->toJson(output));
-    }
-    result->addValue("outputs", outputs);
-    result->addValue(
-        "group", new Framework::JSON::JSONString(zObject->getGroupName()));
-    return nullptr;
-}
-
-Framework::JSON::Validator::JSONValidator* UnshapedRecipieFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
-{
-    return builder->withRequiredArray("inputs")
-        ->addAcceptedTypeInArray(
-            Game::INSTANCE->zTypeRegistry()->getValidator<RecipieInput>())
-        ->finishArray()
-        ->withRequiredArray("outputs")
-        ->addAcceptedTypeInArray(
-            Game::INSTANCE->zTypeRegistry()->getValidator<RecipieOutput>())
-        ->finishArray()
-        ->withRequiredString("group")
-        ->finishString()
-        ->finishObject();
+    zResult->addValue("inputs", inputs);
+    RecipieFactory::toJson(zObject, zResult);
 }
 
-Framework::Text UnshapedRecipieFactory::getTypeToken() const
+JSONObjectValidationBuilder* UnshapedRecipieFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
-    return "unshaped";
+    return RecipieFactory::addToValidator(
+        builder->withRequiredArray("inputs")
+            ->addAcceptedTypeInArray(
+                Game::INSTANCE->zTypeRegistry()->getValidator<RecipieInput>())
+            ->finishArray());
 }
 
-ShapedRecipie::ShapedRecipie(int width,
-    int height,
-    Framework::RCArray<RecipieInput> inputs,
-    Framework::RCArray<RecipieOutput> outputs,
-    Framework::Text groupName)
-    : Recipie(outputs, groupName),
-      inputs(inputs),
-      width(width),
-      height(height)
+Framework::Text UnshapedRecipieFactory::getTypeToken() const
 {
-    while (this->inputs.getEintragAnzahl() < width * height)
-    {
-        this->inputs.add(new RecipieInput(0, 0, 0));
-    }
+    return "unshaped";
 }
 
+ShapedRecipie::ShapedRecipie()
+    : Recipie(),
+      width(0),
+      height(0)
+{}
+
 bool ShapedRecipie::testApplicability(CraftingStorage* zStorage)
 {
     ShapedCraftingStorage* zShapedStorage
@@ -474,34 +495,59 @@ Framework::Text ShapedRecipie::getRecipieUIML()
     return result;
 }
 
+void ShapedRecipie::setWidth(int width)
+{
+    this->width = width;
+}
+
 int ShapedRecipie::getWidth() const
 {
     return width;
 }
 
+void ShapedRecipie::setHeight(int height)
+{
+    this->height = height;
+}
+
 int ShapedRecipie::getHeight() const
 {
     return height;
 }
 
+void ShapedRecipie::addInput(RecipieInput* input)
+{
+    inputs.add(input);
+}
+
+void ShapedRecipie::setInput(int index, RecipieInput* input)
+{
+    inputs.set(input, index);
+}
+
 const Framework::RCArray<RecipieInput>& ShapedRecipie::getInputs() const
 {
     return inputs;
 }
 
 ShapedRecipieFactory::ShapedRecipieFactory()
-    : SubTypeFactory()
+    : RecipieFactory()
 {}
 
-ShapedRecipie* ShapedRecipieFactory::fromJson(
+ShapedRecipie* ShapedRecipieFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
+{
+    return new ShapedRecipie();
+}
+
+void ShapedRecipieFactory::fromJson(
+    ShapedRecipie* zResult, Framework::JSON::JSONObject* zJson) const
 {
     int width = (int)zJson->zValue("width")->asNumber()->getNumber();
     int height = (int)zJson->zValue("height")->asNumber()->getNumber();
-    Framework::RCArray<RecipieInput> inputs;
     for (int i = 0; i < width * height; i++)
     {
-        inputs.add(new RecipieInput(0, 0, 0));
+        zResult->addInput(new RecipieInput());
     }
     for (Framework::JSON::JSONValue* input :
         *zJson->zValue("inputs")->asArray())
@@ -513,34 +559,23 @@ ShapedRecipie* ShapedRecipieFactory::fromJson(
             std::cout << "Invalid input position in shaped recipie with width="
                       << width << ", height=" << height << "\n"
                       << (x >= width ? x : y) << "\n";
-            return 0;
+            return;
         }
-        inputs.set(Game::INSTANCE->zTypeRegistry()->fromJson<RecipieInput>(
-                       input->asObject()->zValue("input")),
-            y * width + x);
-    }
-    Framework::RCArray<RecipieOutput> outputs;
-    for (Framework::JSON::JSONValue* output :
-        *zJson->zValue("outputs")->asArray())
-    {
-        outputs.add(
-            Game::INSTANCE->zTypeRegistry()->fromJson<RecipieOutput>(output));
+        zResult->setInput(y * width + x,
+            Game::INSTANCE->zTypeRegistry()->fromJson<RecipieInput>(
+                input->asObject()->zValue("input")));
     }
-    return new ShapedRecipie(
-        (int)zJson->zValue("width")->asNumber()->getNumber(),
-        (int)zJson->zValue("height")->asNumber()->getNumber(),
-        inputs,
-        outputs,
-        zJson->zValue("group")->asString()->getString());
+    zResult->setWidth((int)zJson->zValue("width")->asNumber()->getNumber());
+    zResult->setHeight((int)zJson->zValue("height")->asNumber()->getNumber());
+    RecipieFactory::fromJson(zResult, zJson);
 }
 
-Framework::JSON::JSONObject* ShapedRecipieFactory::toJson(
-    ShapedRecipie* zObject) const
+void ShapedRecipieFactory::toJson(
+    ShapedRecipie* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue(
+    zResult->addValue(
         "width", new Framework::JSON::JSONNumber(zObject->getWidth()));
-    result->addValue(
+    zResult->addValue(
         "height", new Framework::JSON::JSONNumber(zObject->getHeight()));
     Framework::JSON::JSONArray* inputs = new Framework::JSON::JSONArray();
     for (int i = 0; i < zObject->getWidth() * zObject->getHeight(); i++)
@@ -554,47 +589,32 @@ Framework::JSON::JSONObject* ShapedRecipieFactory::toJson(
             Game::INSTANCE->zTypeRegistry()->toJson(zObject->getInputs().z(i)));
         inputs->addValue(input);
     }
-    result->addValue("inputs", inputs);
-    Framework::JSON::JSONArray* outputs = new Framework::JSON::JSONArray();
-    for (RecipieOutput* output : zObject->getOutputs())
-    {
-        outputs->addValue(Game::INSTANCE->zTypeRegistry()->toJson(output));
-    }
-    result->addValue("outputs", outputs);
-    result->addValue(
-        "group", new Framework::JSON::JSONString(zObject->getGroupName()));
-    return result;
-}
-
-Framework::JSON::Validator::JSONValidator* ShapedRecipieFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
-{
-    return builder->withRequiredArray("inputs")
-        ->addAcceptedObjectInArray()
-        ->withRequiredNumber("x")
-        ->whichIsGreaterOrEqual(0.0)
-        ->finishNumber()
-        ->withRequiredNumber("y")
-        ->whichIsGreaterOrEqual(0.0)
-        ->finishNumber()
-        ->withRequiredAttribute("input",
-            Game::INSTANCE->zTypeRegistry()->getValidator<RecipieInput>())
-        ->finishObject()
-        ->finishArray()
-        ->withRequiredArray("outputs")
-        ->addAcceptedTypeInArray(
-            Game::INSTANCE->zTypeRegistry()->getValidator<RecipieOutput>())
-        ->finishArray()
-        ->withRequiredNumber("width")
-        ->whichIsGreaterOrEqual(1.0)
-        ->finishNumber()
-        ->withRequiredNumber("height")
-        ->whichIsGreaterOrEqual(1.0)
-        ->finishNumber()
-        ->withRequiredString("group")
-        ->finishString()
-        ->finishObject();
+    zResult->addValue("inputs", inputs);
+    RecipieFactory::toJson(zObject, zResult);
+}
+
+JSONObjectValidationBuilder* ShapedRecipieFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return RecipieFactory::addToValidator(
+        builder->withRequiredArray("inputs")
+            ->addAcceptedObjectInArray()
+            ->withRequiredNumber("x")
+            ->whichIsGreaterOrEqual(0.0)
+            ->finishNumber()
+            ->withRequiredNumber("y")
+            ->whichIsGreaterOrEqual(0.0)
+            ->finishNumber()
+            ->withRequiredAttribute("input",
+                Game::INSTANCE->zTypeRegistry()->getValidator<RecipieInput>())
+            ->finishObject()
+            ->finishArray()
+            ->withRequiredNumber("width")
+            ->whichIsGreaterOrEqual(1.0)
+            ->finishNumber()
+            ->withRequiredNumber("height")
+            ->whichIsGreaterOrEqual(1.0)
+            ->finishNumber());
 }
 
 Framework::Text ShapedRecipieFactory::getTypeToken() const

+ 95 - 31
FactoryCraft/Recipie.h

@@ -27,10 +27,13 @@ private:
     int amount;
 
 public:
-    RecipieInput(ItemFilter* filter, ItemModifier* modifier, int amount);
+    RecipieInput();
     ~RecipieInput();
+    void setFilter(ItemFilter* filter);
     ItemFilter* zFilter() const;
+    void setModifier(ItemModifier* modifier);
     ItemModifier* zModifier() const;
+    void setAmount(int amount);
     int getAmount() const;
 };
 
@@ -38,9 +41,14 @@ class RecipieInputFactory : public TypeFactory<RecipieInput>
 {
 public:
     RecipieInputFactory();
-    RecipieInput* fromJson(Framework::JSON::JSONValue* zJson) const override;
-    Framework::JSON::JSONValue* toJson(RecipieInput* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator() const override;
+    RecipieInput* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(RecipieInput* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(RecipieInput* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
 };
 
 class RecipieOutput : public Framework::ReferenceCounter
@@ -51,10 +59,13 @@ private:
     ItemModifier* modifier;
 
 public:
-    RecipieOutput(int itemTypeId, int amount, ItemModifier* modifier);
+    RecipieOutput();
     ~RecipieOutput();
+    void setItemTypeId(int itemTypeId);
     int getItemTypeId() const;
+    void setAmount(int amount);
     int getAmount() const;
+    void setModifier(ItemModifier* modifier);
     ItemModifier* zModifier() const;
     Item* createItem() const;
 };
@@ -63,9 +74,14 @@ class RecipieOutputFactory : public TypeFactory<RecipieOutput>
 {
 public:
     RecipieOutputFactory();
-    RecipieOutput* fromJson(Framework::JSON::JSONValue* zJson) const override;
-    Framework::JSON::JSONValue* toJson(RecipieOutput* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator() const override;
+    RecipieOutput* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(RecipieOutput* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(RecipieOutput* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
 };
 
 class Recipie : public virtual Framework::ReferenceCounter
@@ -75,43 +91,89 @@ protected:
     Framework::RCArray<RecipieOutput> outputs;
 
 public:
-    Recipie(
-        Framework::RCArray<RecipieOutput> outputs, Framework::Text groupName);
+    Recipie();
     virtual bool testApplicability(CraftingStorage* zStorage) = 0;
     virtual void apply(CraftingStorage* zStorage) = 0;
     virtual Framework::Text getRecipieUIML() = 0;
+    void addOutput(RecipieOutput* outputs);
     virtual Framework::Array<ItemInfo> getOutput() const;
     bool createsOutput(int itemTypeId);
+    void setGroupName(Framework::Text groupName);
     const Framework::RCArray<RecipieOutput>& getOutputs() const;
     Framework::Text getGroupName() const;
 };
 
+template<typename S> class RecipieFactory : public SubTypeFactory<Recipie, S>
+{
+public:
+    RecipieFactory()
+        : SubTypeFactory<Recipie, S>()
+    {}
+
+    void fromJson(S* zResult, Framework::JSON::JSONObject* zJson) const override
+    {
+        Recipie* zRecipie = dynamic_cast<Recipie*>(zResult);
+        for (Framework::JSON::JSONValue* output :
+            *zJson->zValue("outputs")->asArray())
+        {
+            zRecipie->addOutput(
+                Game::INSTANCE->zTypeRegistry()->fromJson<RecipieOutput>(
+                    output));
+        }
+        zRecipie->setGroupName(zJson->zValue("group")->asString()->getString());
+    }
+
+    void toJson(S* zObject, Framework::JSON::JSONObject* zResult) const override
+    {
+        Recipie* zRecipie = dynamic_cast<Recipie*>(zResult);
+        Framework::JSON::JSONArray* outputs = new Framework::JSON::JSONArray();
+        for (RecipieOutput* output : zRecipie->getOutputs())
+        {
+            outputs->addValue(Game::INSTANCE->zTypeRegistry()->toJson(output));
+        }
+        zResult->addValue("outputs", outputs);
+        zResult->addValue(
+            "group", new Framework::JSON::JSONString(zRecipie->getGroupName()));
+    };
+
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override
+    {
+        return builder->withRequiredArray("outputs")
+            ->addAcceptedTypeInArray(
+                Game::INSTANCE->zTypeRegistry()->getValidator<RecipieOutput>())
+            ->finishArray()
+            ->withRequiredString("group")
+            ->finishString();
+    }
+};
+
 class UnshapedRecipie : public Recipie
 {
 private:
     Framework::RCArray<RecipieInput> inputs;
 
 public:
-    UnshapedRecipie(Framework::RCArray<RecipieInput> inputs,
-        Framework::RCArray<RecipieOutput> outputs,
-        Framework::Text groupName);
+    UnshapedRecipie();
     bool testApplicability(CraftingStorage* zStorage) override;
     void apply(CraftingStorage* zStorage) override;
     Framework::Text getRecipieUIML() override;
+    void addInput(RecipieInput* input);
     const Framework::RCArray<RecipieInput>& getInputs() const;
 };
 
-class UnshapedRecipieFactory : public SubTypeFactory<Recipie, UnshapedRecipie>
+class UnshapedRecipieFactory : public RecipieFactory<UnshapedRecipie>
 {
 public:
     UnshapedRecipieFactory();
-    UnshapedRecipie* fromJson(
+    UnshapedRecipie* createValue(
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(
-        UnshapedRecipie* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    void fromJson(UnshapedRecipie* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(UnshapedRecipie* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };
 
@@ -123,28 +185,30 @@ private:
     int height;
 
 public:
-    ShapedRecipie(int width,
-        int height,
-        Framework::RCArray<RecipieInput> inputs,
-        Framework::RCArray<RecipieOutput> outputs,
-        Framework::Text groupName);
+    ShapedRecipie();
     bool testApplicability(CraftingStorage* zStorage) override;
     void apply(CraftingStorage* zStorage) override;
     Framework::Text getRecipieUIML() override;
+    void setWidth(int width);
     int getWidth() const;
+    void setHeight(int height);
     int getHeight() const;
+    void addInput(RecipieInput* input);
+    void setInput(int index, RecipieInput* input);
     const Framework::RCArray<RecipieInput>& getInputs() const;
 };
 
-class ShapedRecipieFactory : public SubTypeFactory<Recipie, ShapedRecipie>
+class ShapedRecipieFactory : public RecipieFactory<ShapedRecipie>
 {
 public:
     ShapedRecipieFactory();
-    ShapedRecipie* fromJson(
+    ShapedRecipie* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(ShapedRecipie* zResult,
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(ShapedRecipie* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    void toJson(ShapedRecipie* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };

+ 1 - 0
FactoryCraft/SaveCommand.cpp

@@ -1,5 +1,6 @@
 #include "SaveCommand.h"
 
+#include "Chat.h"
 #include "Game.h"
 
 SaveCommand::SaveCommand()

+ 6 - 5
FactoryCraft/Server.cpp

@@ -7,6 +7,8 @@
 #include <JSON.h>
 #include <Klient.h>
 
+#include "PlayerRegister.h"
+
 // Inhalt der LoginServer Klasse aus LoginServer.h
 // Konstruktor
 FactoryCraftServer::FactoryCraftServer(InitDatei* zIni)
@@ -207,8 +209,8 @@ void FCKlient::setForegroundClient(SKlient* foreground)
     foregroundReader = new NetworkReader(foreground);
     foregroundWriter = new NetworkWriter(foreground);
     if (foreground && background)
-        zGameClient
-            = Game::INSTANCE->addPlayer(dynamic_cast<FCKlient*>(getThis()), name);
+        zGameClient = Game::INSTANCE->addPlayer(
+            dynamic_cast<FCKlient*>(getThis()), name);
     foregroundRunning = 1;
     new AsynchronCall([this]() {
         while (this->foreground->waitForNextMessage())
@@ -242,9 +244,8 @@ void FCKlient::setBackgroundClient(SKlient* background)
     backgroundReader = new NetworkReader(background);
     backgroundWriter = new NetworkWriter(background);
     if (foreground && background)
-        zGameClient
-            = Game::INSTANCE->addPlayer(dynamic_cast<FCKlient*>(getThis()),
-                name);
+        zGameClient = Game::INSTANCE->addPlayer(
+            dynamic_cast<FCKlient*>(getThis()), name);
     backgroundRunning = 1;
     new AsynchronCall([this]() {
         while (this->background->waitForNextMessage())

+ 1 - 0
FactoryCraft/Start.cpp

@@ -12,6 +12,7 @@
 #include <Text.h>
 #include <Zeit.h>
 
+#include "Chat.h"
 #include "ChunkMap.h"
 #include "Server.h"
 

+ 147 - 49
FactoryCraft/StructureCollection.cpp

@@ -1,52 +1,33 @@
 #include "StructureCollection.h"
 
+#include "Constants.h"
 #include "Game.h"
 #include "JNoise.h"
 
-StructureTemplateCollection::StructureTemplateCollection(
-    Framework::JSON::JSONValue* zConfig, JExpressionMemory* zMemory)
-    : ReferenceCounter()
-{
-    activeNoise = JNoise::parseNoise(
-        zConfig->asObject()->zValue("activeNoise"), zMemory);
-    structureNoise = JNoise::parseNoise(
-        zConfig->asObject()->zValue("structureNoise"), zMemory);
-    threshold
-        = zConfig->asObject()->zValue("threshold")->asNumber()->getNumber();
-    condition = JExpressionParser::parseBoolExpression(
-        zConfig->asObject()->zValue("condition"));
-    bool first = 1;
-    for (Framework::JSON::JSONValue* value :
-        *zConfig->asObject()->zValue("structures")->asArray())
-    {
-        GeneratorTemplate* templ
-            = Game::INSTANCE->zTypeRegistry()->fromJson<GeneratorTemplate>(value);
-        if (first)
-        {
-            minAffected = templ->getMinAffectedOffset();
-            maxAffected = templ->getMaxAffectedOffset();
-            first = 0;
-        }
-        else
-        {
-            Framework::Vec3<int> min = templ->getMinAffectedOffset();
-            Framework::Vec3<int> max = templ->getMaxAffectedOffset();
-            if (minAffected.x > min.x) minAffected.x = min.x;
-            if (minAffected.y > min.y) minAffected.y = min.y;
-            if (minAffected.z > min.z) minAffected.z = min.z;
-            if (maxAffected.x < max.x) maxAffected.x = max.x;
-            if (maxAffected.y < max.y) maxAffected.y = max.y;
-            if (maxAffected.z < max.z) maxAffected.z = max.z;
-        }
-        structures.add(templ);
-    }
-}
+StructureTemplateCollection::StructureTemplateCollection()
+    : ReferenceCounter(),
+      activeNoise(0),
+      activeNoiseConfig(0),
+      structureNoise(0),
+      structureNoiseConfig(0),
+      condition(0)
+{}
 
 StructureTemplateCollection::~StructureTemplateCollection()
 {
-    activeNoise->release();
-    structureNoise->release();
-    condition->release();
+    if (activeNoise) activeNoise->release();
+    if (activeNoiseConfig) activeNoiseConfig->release();
+    if (structureNoise) structureNoise->release();
+    if (structureNoiseConfig) structureNoiseConfig->release();
+    if (condition) condition->release();
+}
+
+void StructureTemplateCollection::initialize(JExpressionMemory* zMemory)
+{
+    if (activeNoise) activeNoise->release();
+    if (structureNoise) structureNoise->release();
+    activeNoise = JNoise::parseNoise(activeNoiseConfig, zMemory);
+    structureNoise = JNoise::parseNoise(structureNoiseConfig, zMemory);
 }
 
 void StructureTemplateCollection::generateStructures(int x,
@@ -91,6 +72,72 @@ void StructureTemplateCollection::generateStructures(int x,
     }
 }
 
+void StructureTemplateCollection::setThreshold(double threshold) {
+    this->threshold = threshold;
+}
+
+double StructureTemplateCollection::getThreshold() const
+{
+    return threshold;
+}
+
+void StructureTemplateCollection::setCondition(JBoolExpression* condition) {
+	if (this->condition) this->condition->release();
+	this->condition = condition;
+}
+
+JBoolExpression* StructureTemplateCollection::zCondition() const
+{
+    return condition;
+}
+
+void StructureTemplateCollection::setActiveNoiseConfig(
+    Framework::JSON::JSONObject* activeNoiseConfig)
+{
+    if (this->activeNoiseConfig) this->activeNoiseConfig->release();
+    this->activeNoiseConfig = activeNoiseConfig;
+}
+
+Framework::JSON::JSONObject*
+StructureTemplateCollection::zActiveNoiseConfig() const
+{
+    return activeNoiseConfig;
+}
+
+void StructureTemplateCollection::setStructureNoiseConfig(
+    Framework::JSON::JSONObject* structureNoiseConfig)
+{
+    if (this->structureNoiseConfig) this->structureNoiseConfig->release();
+    this->structureNoiseConfig = structureNoiseConfig;
+}
+
+Framework::JSON::JSONObject*
+StructureTemplateCollection::zStructureNoiseConfig() const
+{
+    return structureNoiseConfig;
+}
+
+void StructureTemplateCollection::addStructure(GeneratorTemplate* structure)
+{
+    structures.add(structure);
+    if (structures.getEintragAnzahl() == 1)
+    {
+        minAffected = structure->getMinAffectedOffset();
+        maxAffected = structure->getMaxAffectedOffset();
+    }
+    else
+    {
+        Framework::Vec3<int> min = structure->getMinAffectedOffset();
+        Framework::Vec3<int> max = structure->getMaxAffectedOffset();
+        if (minAffected.x > min.x) minAffected.x = min.x;
+        if (minAffected.y > min.y) minAffected.y = min.y;
+        if (minAffected.z > min.z) minAffected.z = min.z;
+        if (maxAffected.x < max.x) maxAffected.x = max.x;
+        if (maxAffected.y < max.y) maxAffected.y = max.y;
+        if (maxAffected.z < max.z) maxAffected.z = max.z;
+    }
+}
+
 const Framework::RCArray<GeneratorTemplate>&
 StructureTemplateCollection::getStructures() const
 {
@@ -107,20 +154,71 @@ Framework::Vec3<int> StructureTemplateCollection::getMaxAffected() const
     return maxAffected;
 }
 
-Framework::JSON::Validator::JSONValidator*
-StructureTemplateCollection::getConfigValidator()
+StructureTemplateCollectionFactory::StructureTemplateCollectionFactory()
+    : TypeFactory<StructureTemplateCollection>()
+{}
+
+StructureTemplateCollection* StructureTemplateCollectionFactory::createValue(
+    Framework::JSON::JSONObject* zJson) const
 {
-    return Framework::JSON::Validator::JSONValidator::buildForObject()
+    return new StructureTemplateCollection();
+}
+
+void StructureTemplateCollectionFactory::fromJson(
+    StructureTemplateCollection* zResult,
+    Framework::JSON::JSONObject* zJson) const
+{
+    zResult->setActiveNoiseConfig(zJson->getValue("activeNoise")->asObject());
+    zResult->setStructureNoiseConfig(
+        zJson->getValue("structureNoise")->asObject());
+    zResult->setThreshold(zJson->zValue("threshold")->asNumber()->getNumber());
+    zResult->setCondition(
+        Game::INSTANCE->zTypeRegistry()->fromJson<JBoolExpression>(
+            zJson->zValue("condition")));
+    for (Framework::JSON::JSONValue* structure :
+        *zJson->zValue("structures")->asArray())
+    {
+        zResult->addStructure(
+            Game::INSTANCE->zTypeRegistry()->fromJson<GeneratorTemplate>(
+                structure->asObject()));
+    }
+}
+
+void StructureTemplateCollectionFactory::toJson(
+    StructureTemplateCollection* zObject,
+    Framework::JSON::JSONObject* zResult) const
+{
+    zResult->addValue("activeNoise",
+        dynamic_cast<Framework::JSON::JSONValue*>(
+            zObject->zActiveNoiseConfig()->getThis()));
+    zResult->addValue("structureNoise",
+        dynamic_cast<Framework::JSON::JSONValue*>(
+            zObject->zStructureNoiseConfig()->getThis()));
+    zResult->addValue(
+        "threshold", new Framework::JSON::JSONNumber(zObject->getThreshold()));
+    zResult->addValue("condition",
+        Game::INSTANCE->zTypeRegistry()->toJson(zObject->zCondition()));
+    Framework::JSON::JSONArray* structures = new Framework::JSON::JSONArray();
+    for (GeneratorTemplate* t : zObject->getStructures())
+    {
+        structures->addValue(Game::INSTANCE->zTypeRegistry()->toJson(t));
+    }
+    zResult->addValue("structures", structures);
+}
+
+JSONObjectValidationBuilder* StructureTemplateCollectionFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return builder
         ->withRequiredAttribute("activeNoise", JNoise::getValidator(false))
         ->withRequiredAttribute("structureNoise", JNoise::getValidator(false))
         ->withRequiredNumber("threshold")
         ->whichIsGreaterThen(0)
         ->finishNumber()
-        ->withRequiredAttribute(
-            "condition", JExpressionParser::getBoolValidator())
+        ->withRequiredAttribute("condition",
+            Game::INSTANCE->zTypeRegistry()->getValidator<JBoolExpression>())
         ->withRequiredArray("structures")
         ->addAcceptedTypeInArray(
             Game::INSTANCE->zTypeRegistry()->getValidator<GeneratorTemplate>())
-        ->finishArray()
-        ->finishObject();
-}
+        ->finishArray();
+}

+ 28 - 3
FactoryCraft/StructureCollection.h

@@ -10,7 +10,9 @@ class StructureTemplateCollection : public virtual Framework::ReferenceCounter
 {
 private:
     Noise* activeNoise;
+    Framework::JSON::JSONObject* activeNoiseConfig;
     Noise* structureNoise;
+    Framework::JSON::JSONObject* structureNoiseConfig;
     double threshold;
     Framework::RCArray<GeneratorTemplate> structures;
     Framework::Vec3<int> minAffected;
@@ -18,9 +20,9 @@ private:
     JBoolExpression* condition;
 
 public:
-    StructureTemplateCollection(
-        Framework::JSON::JSONValue* zConfig, JExpressionMemory* zMemory);
+    StructureTemplateCollection();
     ~StructureTemplateCollection();
+    void initialize(JExpressionMemory* zMemory);
     void generateStructures(int x,
         int y,
         int z,
@@ -30,9 +32,32 @@ public:
         Framework::Vec3<int> maxPos,
         Framework::RCArray<GeneratedStructure>* zResult);
 
+    void setThreshold(double threshold);
+    double getThreshold() const;
+    void setCondition(JBoolExpression* condition);
+    JBoolExpression* zCondition() const;
+    void setActiveNoiseConfig(Framework::JSON::JSONObject* activeNoiseConfig);
+    Framework::JSON::JSONObject* zActiveNoiseConfig() const;
+    void setStructureNoiseConfig(
+        Framework::JSON::JSONObject* structureNoiseConfig);
+    Framework::JSON::JSONObject* zStructureNoiseConfig() const;
+    void addStructure(GeneratorTemplate* structure);
     const Framework::RCArray<GeneratorTemplate>& getStructures() const;
     Framework::Vec3<int> getMinAffected() const;
     Framework::Vec3<int> getMaxAffected() const;
+};
 
-    static Framework::JSON::Validator::JSONValidator* getConfigValidator();
+class StructureTemplateCollectionFactory
+    : public TypeFactory<StructureTemplateCollection>
+{
+public:
+    StructureTemplateCollectionFactory();
+    StructureTemplateCollection* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(StructureTemplateCollection* zResult,
+        Framework::JSON::JSONObject* zJson) const override;
+    void toJson(StructureTemplateCollection* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
 };

+ 123 - 83
FactoryCraft/TreeSeblingBlock.cpp

@@ -1,10 +1,12 @@
 #include "TreeSeblingBlock.h"
 
 #include "BasicBlocks.h"
+#include "Dimension.h"
 #include "Game.h"
 #include "NoBlock.h"
 #include "RandNoise.h"
 #include "TreeTemplate.h"
+#include "WorldGenerator.h"
 
 TreeSeblingBlock::TreeSeblingBlock(int typeId,
     Framework::Vec3<int> pos,
@@ -45,8 +47,8 @@ void TreeSeblingBlock::onPostTick()
                     dim,
                     [wood = wood, leaves = leaves](GeneratorTemplate* tmpl) {
                         TreeTemplate* tree = dynamic_cast<TreeTemplate*>(tmpl);
-                        return tree && tree->getWoodType() == wood
-                            && tree->getLeavesType() == leaves;
+                        return tree && tree->zWoodType() == wood
+                            && tree->zLeavesType() == leaves;
                     }))
             {
                 Game::INSTANCE->zDimension(dim)->placeBlock(
@@ -58,29 +60,18 @@ void TreeSeblingBlock::onPostTick()
 
 Framework::Text TreeSeblingBlock::getTargetUIML()
 {
-    return Text("<targetInfo><text width=\"auto\" height=\"auto\">")
+    return Framework::Text("<targetInfo><text width=\"auto\" height=\"auto\">")
          + Game::INSTANCE->zBlockType(typeId)->getName() + "\n" + "Growth: "
-         + Text((int)(seblingTicks / (float)seblingTicksMax * 100.f))
+         + Framework::Text((int)(seblingTicks / (float)seblingTicksMax * 100.f))
          + "%</text></targetInfo>";
 }
 
-TreeSeblingBlockType::TreeSeblingBlockType(Framework::Text itemTypeName,
-    ModelInfo* model,
-    Framework::Text woodTypeName,
-    Framework::Text leavesTypeName,
-    Framework::Text name,
-    int mapColor,
-    float hardness,
-    Framework::RCArray<Framework::Text> groupNames)
-    : BlockType(
-        0, model, true, 10, false, name, false, mapColor, groupNames, hardness),
-      itemTypeName(itemTypeName),
+TreeSeblingBlockType::TreeSeblingBlockType()
+    : BlockType(),
       transparent(true),
       passable(true),
       speedModifier(0.5f),
-      interactable(1),
-      woodTypeName(woodTypeName),
-      leavesTypeName(leavesTypeName)
+      interactable(1)
 {}
 
 bool TreeSeblingBlockType::initialize(Game* zGame)
@@ -98,21 +89,76 @@ bool TreeSeblingBlockType::initialize(Game* zGame)
     return itemTypeId >= 0 && BlockType::initialize(zGame);
 }
 
+void TreeSeblingBlockType::setItemTypeName(Framework::Text itemTypeName)
+{
+    this->itemTypeName = itemTypeName;
+}
+
 Framework::Text TreeSeblingBlockType::getItemTypeName() const
 {
     return itemTypeName;
 }
 
+void TreeSeblingBlockType::setWoodTypeName(Framework::Text woodTypeName)
+{
+    this->woodTypeName = woodTypeName;
+}
+
 Framework::Text TreeSeblingBlockType::getWoodTypeName() const
 {
     return woodTypeName;
 }
 
+void TreeSeblingBlockType::setLeavesTypeName(Framework::Text leavesTypeName)
+{
+    this->leavesTypeName = leavesTypeName;
+}
+
 Framework::Text TreeSeblingBlockType::getLeavesTypeName() const
 {
     return leavesTypeName;
 }
 
+void TreeSeblingBlockType::setTransparent(bool transparent)
+{
+    this->transparent = transparent;
+}
+
+bool TreeSeblingBlockType::isTransparent() const
+{
+    return transparent;
+}
+
+void TreeSeblingBlockType::setPassable(bool passable)
+{
+    this->passable = passable;
+}
+
+bool TreeSeblingBlockType::isPassable() const
+{
+    return passable;
+}
+
+void TreeSeblingBlockType::setSpeedModifier(float speedModifier)
+{
+    this->speedModifier = speedModifier;
+}
+
+float TreeSeblingBlockType::getSpeedModifier() const
+{
+    return speedModifier;
+}
+
+void TreeSeblingBlockType::setInteractable(bool interactable)
+{
+    this->interactable = interactable;
+}
+
+bool TreeSeblingBlockType::isInteractable() const
+{
+    return interactable;
+}
+
 ItemType* TreeSeblingBlockType::createItemType() const
 {
     return new BasicBlockItemType(getItemTypeName(),
@@ -125,7 +171,9 @@ ItemType* TreeSeblingBlockType::createItemType() const
         getHardness(),
         speedModifier,
         getName(),
-        0, 50, getGroupNames());
+        0,
+        50,
+        getGroupNames());
 }
 
 void TreeSeblingBlockType::createSuperBlock(Block* zBlock, Item* zItem) const
@@ -184,83 +232,75 @@ Block* TreeSeblingBlockType::createBlock(
 }
 
 TreeSeblingBlockTypeFactory::TreeSeblingBlockTypeFactory()
-    : SubTypeFactory()
+    : BlockTypeFactoryBase()
 {}
 
-TreeSeblingBlockType* TreeSeblingBlockTypeFactory::fromJson(
+TreeSeblingBlockType* TreeSeblingBlockTypeFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
 {
-    Framework::RCArray<Framework::Text> groupNames;
-    for (Framework::JSON::JSONValue* value :
-        *zJson->zValue("groupNames")->asArray())
-    {
-        groupNames.add(new Framework::Text(value->asString()->getString()));
-    }
-    return new TreeSeblingBlockType(
-        zJson->zValue("itemType")->asString()->getString(),
-        Game::INSTANCE->zTypeRegistry()->fromJson<ModelInfo>(
-            zJson->zValue("model")),
-        zJson->zValue("woodType")->asString()->getString(),
-        zJson->zValue("leavesType")->asString()->getString(),
-        zJson->zValue("name")->asString()->getString(),
-        (int)zJson->zValue("mapColor")->asString()->getString(),
-        (float)zJson->zValue("hardness")->asNumber()->getNumber(),
-        groupNames);
+    return new TreeSeblingBlockType();
 }
 
-Framework::JSON::JSONObject* TreeSeblingBlockTypeFactory::toJson(
-    TreeSeblingBlockType* zObject) const
+void TreeSeblingBlockTypeFactory::fromJson(
+    TreeSeblingBlockType* zResult, Framework::JSON::JSONObject* zJson) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue("itemType",
+    zResult->setItemTypeName(
+        zJson->zValue("itemType")->asString()->getString());
+    zResult->setWoodTypeName(
+        zJson->zValue("woodType")->asString()->getString());
+    zResult->setLeavesTypeName(
+        zJson->zValue("leavesType")->asString()->getString());
+    zResult->setTransparent(zJson->zValue("transparent")->asBool()->getBool());
+    zResult->setPassable(zJson->zValue("passable")->asBool()->getBool());
+    zResult->setSpeedModifier(
+        (float)zJson->zValue("speedModifier")->asNumber()->getNumber());
+    zResult->setInteractable(
+        zJson->zValue("interactable")->asBool()->getBool());
+    BlockTypeFactoryBase::fromJson(zResult, zJson);
+}
+
+void TreeSeblingBlockTypeFactory::toJson(
+    TreeSeblingBlockType* zObject, Framework::JSON::JSONObject* zResult) const
+{
+    zResult->addValue("itemType",
         new Framework::JSON::JSONString(zObject->getItemTypeName()));
-    result->addValue(
-        "model", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zModel()));
-    result->addValue(
-        "name", new Framework::JSON::JSONString(zObject->getName()));
-    result->addValue(
-        "hardness", new Framework::JSON::JSONNumber(zObject->getHardness()));
-    result->addValue(
-        "mapColor", new Framework::JSON::JSONString(zObject->getMapColor()));
-    result->addValue("woodType",
+    zResult->addValue("woodType",
         new Framework::JSON::JSONString(zObject->getWoodTypeName()));
-    result->addValue("leavesType",
+    zResult->addValue("leavesType",
         new Framework::JSON::JSONString(zObject->getLeavesTypeName()));
-    Framework::JSON::JSONArray* groupNames = new Framework::JSON::JSONArray();
-    for (Framework::Text* groupName : zObject->getGroupNames())
-    {
-        groupNames->addValue(new Framework::JSON::JSONString(*groupName));
-    }
-    result->addValue("groupNames", groupNames);
-    return result;
+    zResult->addValue("transparent",
+        new Framework::JSON::JSONNumber(zObject->isTransparent()));
+    zResult->addValue(
+        "passable", new Framework::JSON::JSONNumber(zObject->isPassable()));
+    zResult->addValue("speedModifier",
+        new Framework::JSON::JSONNumber(zObject->getSpeedModifier()));
+    zResult->addValue("interactable",
+        new Framework::JSON::JSONNumber(zObject->isInteractable()));
+    BlockTypeFactoryBase::toJson(zObject, zResult);
 }
 
-Framework::JSON::Validator::JSONValidator*
-TreeSeblingBlockTypeFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
+JSONObjectValidationBuilder* TreeSeblingBlockTypeFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
-    return builder->withRequiredString("itemType")
-        ->finishString()
-        ->withRequiredAttribute(
-            "model", Game::INSTANCE->zTypeRegistry()->getValidator<ModelInfo>())
-        ->withRequiredString("name")
-        ->finishString()
-        ->withRequiredNumber("hardness")
-        ->withDefault(1.0)
-        ->finishNumber()
-        ->withRequiredString("mapColor")
-        ->finishString()
-        ->withRequiredString("woodType")
-        ->finishString()
-        ->withRequiredString("leavesType")
-        ->finishString()
-        ->withRequiredArray("groupNames")
-        ->withDefault(new Framework::JSON::JSONArray())
-        ->addAcceptedStringInArray()
-        ->finishString()
-        ->finishArray()
-        ->finishObject();
+    return BlockTypeFactoryBase::addToValidator(
+        builder->withRequiredString("itemType")
+            ->finishString()
+            ->withRequiredString("woodType")
+            ->finishString()
+            ->withRequiredString("leavesType")
+            ->finishString()
+            ->withRequiredBool("transparent")
+            ->withDefault(true)
+            ->finishBool()
+            ->withRequiredBool("passable")
+            ->withDefault(true)
+            ->finishBool()
+            ->withRequiredNumber("speedModifier")
+            ->withDefault(0.5)
+            ->finishNumber()
+            ->withRequiredBool("interactable")
+            ->withDefault(true)
+            ->finishBool());
 }
 
 Framework::Text TreeSeblingBlockTypeFactory::getTypeToken() const

+ 22 - 16
FactoryCraft/TreeSeblingBlock.h

@@ -41,14 +41,7 @@ private:
     int leavesTypeId;
 
 public:
-    TreeSeblingBlockType(Framework::Text itemTypeName,
-        ModelInfo* model,
-        Framework::Text woodTypeName,
-        Framework::Text leavesTypeName,
-        Framework::Text name,
-        int mapColor,
-        float hardness,
-        Framework::RCArray<Framework::Text> groupNames);
+    TreeSeblingBlockType();
 
 protected:
     virtual void createSuperBlock(Block* zBlock, Item* zItem) const override;
@@ -63,23 +56,36 @@ protected:
 
 public:
     virtual bool initialize(Game* zGame) override;
+    virtual ItemType* createItemType() const override;
+
+    void setItemTypeName(Framework::Text itemTypeName);
     Framework::Text getItemTypeName() const;
+    void setWoodTypeName(Framework::Text woodTypeName);
     Framework::Text getWoodTypeName() const;
+    void setLeavesTypeName(Framework::Text leavesTypeName);
     Framework::Text getLeavesTypeName() const;
-    virtual ItemType* createItemType() const override;
+    void setTransparent(bool transparent);
+    bool isTransparent() const;
+    void setPassable(bool passable);
+    bool isPassable() const;
+    void setSpeedModifier(float speedModifier);
+    float getSpeedModifier() const;
+    void setInteractable(bool interactable);
+    bool isInteractable() const;
 };
 
 class TreeSeblingBlockTypeFactory
-    : public SubTypeFactory<BlockType, TreeSeblingBlockType>
+    : public BlockTypeFactoryBase<TreeSeblingBlockType>
 {
 public:
     TreeSeblingBlockTypeFactory();
-    TreeSeblingBlockType* fromJson(
+    TreeSeblingBlockType* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(TreeSeblingBlockType* zResult,
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJson(
-        TreeSeblingBlockType* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    void toJson(TreeSeblingBlockType* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     Framework::Text getTypeToken() const override;
 };

+ 90 - 67
FactoryCraft/TreeTemplate.cpp

@@ -1,21 +1,18 @@
 #include "TreeTemplate.h"
 
+#include "Dimension.h"
 #include "Game.h"
 #include "MultiblockTree.h"
 
-TreeTemplate::TreeTemplate(float propability,
-    int woodBlockTypeId,
-    int leaveBlockType,
-    int minHeight,
-    int maxHeight)
-    : GeneratorTemplate(propability,
-        Framework::Vec3<int>(-2, -2, 0),
-        Framework::Vec3<int>(5, 5, maxHeight)),
-      woodBlockTypeId(woodBlockTypeId),
-      leaveBlockType(leaveBlockType),
-      minHeight(minHeight),
-      maxHeight(maxHeight)
-{}
+TreeTemplate::TreeTemplate()
+    : GeneratorTemplate(),
+      woodBlockTypeId(0),
+      leaveBlockType(0),
+      minHeight(0),
+      maxHeight(0)
+{
+    setMinPosOffset(Framework::Vec3<int>(-2, -2, 0));
+}
 
 GeneratedStructure* TreeTemplate::generateAt(
     Framework::Vec3<int> location, Noise* zNoise, int dimensionId)
@@ -73,59 +70,88 @@ GeneratedStructure* TreeTemplate::generateAt(
     return generated;
 }
 
-const BlockType* TreeTemplate::getWoodType() const
+void TreeTemplate::setWoodTypeId(int id)
+{
+    woodBlockTypeId = id;
+}
+
+void TreeTemplate::setLeavesTypeId(int id)
+{
+    leaveBlockType = id;
+}
+
+const BlockType* TreeTemplate::zWoodType() const
 {
     return Game::INSTANCE->zBlockType(woodBlockTypeId);
 }
 
-const BlockType* TreeTemplate::getLeavesType() const
+const BlockType* TreeTemplate::zLeavesType() const
 {
     return Game::INSTANCE->zBlockType(leaveBlockType);
 }
 
+void TreeTemplate::setMinHeight(int height)
+{
+    minHeight = height;
+}
+
+void TreeTemplate::setMaxHeight(int height)
+{
+    maxHeight = height;
+    Framework::Vec3<int>(5, 5, maxHeight);
+}
+
+int TreeTemplate::getMinHeight() const
+{
+    return minHeight;
+}
+
+int TreeTemplate::getMaxHeight() const
+{
+    return maxHeight;
+}
+
 TreeTemplateFactory::TreeTemplateFactory()
-    : SubTypeFactory()
+    : GeneratorTemplateFactory()
 {}
 
-TreeTemplate* TreeTemplateFactory::fromJson(
-    Framework::JSON::JSONObject* zConfig) const
+TreeTemplate* TreeTemplateFactory::createValue(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new TreeTemplate();
+}
+
+void TreeTemplateFactory::fromJson(
+    TreeTemplate* zResult, Framework::JSON::JSONObject* zConfig) const
 {
-    return new TreeTemplate((float)zConfig->asObject()
-                                ->zValue("propability")
-                                ->asNumber()
-                                ->getNumber(),
-        BlockType::getTypeId(
-            zConfig->asObject()->zValue("wood")->asString()->getString()),
-        BlockType::getTypeId(
-            zConfig->asObject()->zValue("leaves")->asString()->getString()),
-        (int)(round(
-            zConfig->asObject()->zValue("minSize")->asNumber()->getNumber())),
-        (int)(round(
-            zConfig->asObject()->zValue("maxSize")->asNumber()->getNumber())));
+    zResult->setWoodTypeId(BlockType::getTypeId(
+        zConfig->asObject()->zValue("wood")->asString()->getString()));
+    zResult->setLeavesTypeId(BlockType::getTypeId(
+        zConfig->asObject()->zValue("leaves")->asString()->getString()));
+    zResult->setMinHeight(
+        (int)(zConfig->asObject()->zValue("minSize")->asNumber()->getNumber()));
+    zResult->setMinHeight(
+        (int)(zConfig->asObject()->zValue("maxSize")->asNumber()->getNumber()));
+    GeneratorTemplateFactory::fromJson(zResult, zConfig);
 }
 
-Framework::JSON::JSONObject* TreeTemplateFactory::toJson(
-    TreeTemplate* zObject) const
+void TreeTemplateFactory::toJson(
+    TreeTemplate* zObject, Framework::JSON::JSONObject* zResult) const
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    result->addValue("propability",
+    zResult->addValue("propability",
         new Framework::JSON::JSONNumber((double)zObject->getPropability()));
-    result->addValue("wood",
-        new Framework::JSON::JSONString(
-            BlockType::getTypeName(zObject->woodBlockTypeId)));
-    result->addValue("leaves",
-        new Framework::JSON::JSONString(
-            BlockType::getTypeName(zObject->leaveBlockType)));
-    result->addValue(
-        "minSize", new Framework::JSON::JSONNumber((double)zObject->minHeight));
-    result->addValue(
-        "maxSize", new Framework::JSON::JSONNumber((double)zObject->maxHeight));
-    return result;
+    zResult->addValue("wood",
+        new Framework::JSON::JSONString(zObject->zWoodType()->getName()));
+    zResult->addValue("leaves",
+        new Framework::JSON::JSONString(zObject->zLeavesType()->getName()));
+    zResult->addValue("minSize",
+        new Framework::JSON::JSONNumber((double)zObject->getMinHeight()));
+    zResult->addValue("maxSize",
+        new Framework::JSON::JSONNumber((double)zObject->getMaxHeight()));
 }
 
-Framework::JSON::Validator::JSONValidator* TreeTemplateFactory::getValidator(
-    Framework::JSON::Validator::ObjectValidationBuilder<
-        Framework::JSON::Validator::JSONValidator>* builder) const
+JSONObjectValidationBuilder* TreeTemplateFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
 {
     Framework::RCArray<Framework::Text> blockTypeNames;
     for (int i = 0; i < Game::INSTANCE->getBlockTypeCount(); i++)
@@ -136,25 +162,22 @@ Framework::JSON::Validator::JSONValidator* TreeTemplateFactory::getValidator(
                 new Framework::Text(Game::INSTANCE->zBlockType(i)->getName()));
         }
     }
-    return builder->withRequiredString("type")
-        ->withExactMatch("Tree")
-        ->finishString()
-        ->withRequiredString("wood")
-        ->whichIsOneOf(blockTypeNames)
-        ->finishString()
-        ->withRequiredString("leaves")
-        ->whichIsOneOf(blockTypeNames)
-        ->finishString()
-        ->withRequiredNumber("minSize")
-        ->whichIsGreaterThen(0)
-        ->finishNumber()
-        ->withRequiredNumber("maxSize")
-        ->whichIsGreaterThen(0)
-        ->finishNumber()
-        ->withRequiredNumber("propability")
-        ->whichIsGreaterThen(0)
-        ->finishNumber()
-        ->finishObject();
+    return GeneratorTemplateFactory::addToValidator(
+        builder->withRequiredString("wood")
+            ->whichIsOneOf(blockTypeNames)
+            ->finishString()
+            ->withRequiredString("leaves")
+            ->whichIsOneOf(blockTypeNames)
+            ->finishString()
+            ->withRequiredNumber("minSize")
+            ->whichIsGreaterThen(0)
+            ->finishNumber()
+            ->withRequiredNumber("maxSize")
+            ->whichIsGreaterThen(0)
+            ->finishNumber()
+            ->withRequiredNumber("propability")
+            ->whichIsGreaterThen(0)
+            ->finishNumber());
 }
 
 Framework::Text TreeTemplateFactory::getTypeToken() const

+ 18 - 16
FactoryCraft/TreeTemplate.h

@@ -12,28 +12,30 @@ private:
     int maxHeight;
 
 public:
-    TreeTemplate(float propability,
-        int woodBlockTypeId,
-        int leaveBlockType,
-        int minHeight,
-        int maxHeight);
+    TreeTemplate();
     virtual GeneratedStructure* generateAt(
         Framework::Vec3<int> location, Noise* zNoise, int dimensionId) override;
-    const BlockType* getWoodType() const;
-    const BlockType* getLeavesType() const;
-
-    friend class TreeTemplateFactory;
+    void setWoodTypeId(int id);
+    void setLeavesTypeId(int id);
+    const BlockType* zWoodType() const;
+    const BlockType* zLeavesType() const;
+    void setMinHeight(int height);
+    void setMaxHeight(int height);
+    int getMinHeight() const;
+    int getMaxHeight() const;
 };
 
-class TreeTemplateFactory
-    : public SubTypeFactory<GeneratorTemplate, TreeTemplate>
+class TreeTemplateFactory : public GeneratorTemplateFactory<TreeTemplate>
 {
 public:
     TreeTemplateFactory();
-    TreeTemplate* fromJson(Framework::JSON::JSONObject* zConfig) const override;
-    Framework::JSON::JSONObject* toJson(TreeTemplate* zObject) const override;
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const override;
+    TreeTemplate* createValue(
+        Framework::JSON::JSONObject* zJson) const override;
+    void fromJson(TreeTemplate* zResult,
+        Framework::JSON::JSONObject* zConfig) const override;
+    void toJson(TreeTemplate* zObject,
+        Framework::JSON::JSONObject* zResult) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
     virtual Framework::Text getTypeToken() const override;
 };

+ 20 - 102
FactoryCraft/TypeRegistry.cpp

@@ -16,10 +16,9 @@
 #include "GeneratorRule.h"
 #include "Grass.h"
 #include "GrowingPlant.h"
+#include "JsonExpression.h"
 #include "LightSources.h"
 #include "ModelInfo.h"
-#include "OverworldDimension.h"
-#include "OverworldDimensionGenerator.h"
 #include "PlaceableProof.h"
 #include "Quest.h"
 #include "Recipie.h"
@@ -29,13 +28,6 @@
 TypeRegistry::TypeRegistry()
     : ReferenceCounter()
 {
-    // register dimension generators
-    registerDimensionGeneratorFactory(new OverworldDimensionGeneratorFactory());
-    // register dimensions
-    registerDimension(new OverworldDimensionFactory());
-    // register rules
-    registerGeneratorRuleFactory(new BlockTypeGeneratorRuleFactory());
-    registerGeneratorRuleFactory(new BlockInstanceGeneratorRuleFactory());
     // register templates
     registerSubType(new TreeTemplateFactory());
 
@@ -109,100 +101,26 @@ TypeRegistry::TypeRegistry()
     registerSubType(new AnyItemFilterFactory());
     registerSubType(new TypeItemFilterFactory());
     registerSubType(new GroupItemFilterFactory());
-}
-
-void TypeRegistry::registerGeneratorRuleFactory(GeneratorRuleFactory* factory)
-{
-    generatorRules.add(factory);
-}
-
-GeneratorRule* TypeRegistry::createGeneratorRule(
-    Framework::JSON::JSONValue* zConfig, JExpressionMemory* zMemory)
-{
-    for (GeneratorRuleFactory* f : generatorRules)
-    {
-        Framework::JSON::Validator::JSONValidator* validator
-            = f->getValidator();
-        if (validator->isValid(zConfig))
-        {
-            validator->release();
-            return f->createRule(zConfig, zMemory);
-        }
-        validator->release();
-    }
-    return 0;
-}
 
-Framework::JSON::Validator::JSONValidator*
-TypeRegistry::getGeneratorRuleValidator()
-{
-    auto validator = Framework::JSON::Validator::JSONValidator::buildForOneOf()
-                         ->typeSpecifiedByAttribute("type");
-    for (GeneratorRuleFactory* f : generatorRules)
-    {
-        validator->addAcceptedType(f->getValidator());
-    }
-    return validator->finishOneOf();
-}
-
-void TypeRegistry::registerDimensionGeneratorFactory(
-    DimensionGeneratorFactory* factory)
-{
-    dimensionGenerators.add(factory);
-}
-
-DimensionGenerator* TypeRegistry::createDimensionGenerator(
-    Framework::JSON::JSONValue* zConfig, int worldSeed)
-{
-    for (DimensionGeneratorFactory* f : dimensionGenerators)
-    {
-        Framework::JSON::Validator::JSONValidator* validator
-            = f->getConfigValidator();
-        if (validator->isValid(zConfig))
-        {
-            validator->release();
-            std::cout << "Loaded Config for dimension '" << f->getName()
-                      << "' with id " << f->getDimensionId() << "\n";
-            return f->createDimensionGenerator(worldSeed, zConfig);
-        }
-        validator->release();
-    }
-    return 0;
-}
-
-Framework::JSON::Validator::JSONValidator*
-TypeRegistry::getDimensionGeneratorValidator()
-{
-    auto validator = Framework::JSON::Validator::JSONValidator::buildForOneOf()
-                         ->typeSpecifiedByAttribute("dimension");
-    for (DimensionGeneratorFactory* f : dimensionGenerators)
-    {
-        validator->addAcceptedType(f->getConfigValidator());
-    }
-    return validator->finishOneOf();
-}
-
-const Framework::RCArray<DimensionGeneratorFactory>&
-TypeRegistry::getDimensionGeneratorFactories() const
-{
-    return dimensionGenerators;
-}
-
-void TypeRegistry::registerDimension(DimensionFactory* factory)
-{
-    dimensionFactories.add(factory);
-}
-
-Dimension* TypeRegistry::createDimension(int id)
-{
-    for (DimensionFactory* factory : dimensionFactories)
-    {
-        if (factory->getDimensionId() == id)
-        {
-            return factory->createDimension();
-        }
-    }
-    return 0;
+    // json Expressions
+    registerSubType(new JVariableFloatExpressionFactory());
+    registerSubType(new JVariableBoolExpressionFactory());
+    registerSubType(new JConstantFloatExpressionFactory());
+    registerSubType(new JConstantBoolExpressionFactory());
+    registerSubType(new JNoiseFloatExpressionFactory());
+    registerSubType(new JOperatorFloatExpressionFactory());
+    registerSubType(new JBoolOperatorBoolExpressionFactory());
+    registerSubType(new JFloatOperatorBoolExpressionFactory());
+    registerSubType(new JBlockTypeBoolExpressionFactory());
+
+    // world generator
+    registerType(new WorldHeightLayerFactory());
+    registerSubType(new BlockTypeGeneratorRuleFactory());
+    registerSubType(new BlockInstanceGeneratorRuleFactory());
+    registerSubType(new BiomedCavedDimensionGeneratorFactory());
+    registerType(new BiomGeneratorFactory());
+    registerType(new StructureTemplateCollectionFactory());
+    registerSubType(new TreeTemplateFactory());
 }
 
 void TypeRegistry::writeSyntaxInfo(Framework::Text folderPath) const

+ 168 - 141
FactoryCraft/TypeRegistry.h

@@ -7,12 +7,10 @@
 #include <typeinfo>
 
 class TypeRegistry;
-class GeneratorRuleFactory;
-class GeneratorRule;
-class DimensionGenerator;
-class JExpressionMemory;
-class DimensionFactory;
-class Dimension;
+
+#define JSONObjectValidationBuilder                      \
+    Framework::JSON::Validator::ObjectValidationBuilder< \
+        Framework::JSON::Validator::JSONValidator>
 
 /*
  * Used to convert an object of type T to a JSONValue and vice versa.
@@ -23,14 +21,27 @@ template<typename T> class TypeFactory : public Framework::ReferenceCounter
 public:
     TypeFactory()
         : ReferenceCounter(){};
-    virtual T* fromJson(Framework::JSON::JSONValue* zJson) const = 0;
-    virtual Framework::JSON::JSONValue* toJson(T* zObject) const = 0;
-    virtual Framework::JSON::Validator::JSONValidator* getValidator() const = 0;
+    virtual T* createValue(Framework::JSON::JSONObject* zJson) const = 0;
+    virtual void fromJson(T* zResult, Framework::JSON::JSONObject* zJson) const
+        = 0;
+    virtual void toJson(T* zObject, Framework::JSON::JSONObject* zResult) const
+        = 0;
+    virtual JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const
+        = 0;
+
+    virtual Framework::JSON::Validator::JSONValidator* getValidator() const
+    {
+        return addToValidator(
+            Framework::JSON::Validator::JSONValidator::buildForObject())
+            ->finishObject();
+    };
 };
 
 /*
- * Used to convert an object of type S witch inherits from type T to a JSONValue
- * and vice versa. Can be registered at the TypeRegistry to be used by the JSON
+ * Used to convert an object of type S witch inherits from type T to a
+ * JSONValue and vice versa. Can be registered at the TypeRegistry to be
+ * used by the JSON
  */
 template<typename T,
     typename S,
@@ -40,13 +51,22 @@ class SubTypeFactory : public Framework::ReferenceCounter
 public:
     SubTypeFactory()
         : ReferenceCounter(){};
-
-    virtual S* fromJson(Framework::JSON::JSONObject* zJson) const = 0;
-    virtual Framework::JSON::JSONObject* toJson(S* zObject) const = 0;
-    virtual Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const
+    virtual S* createValue(Framework::JSON::JSONObject* zJson) const = 0;
+    virtual void fromJson(S* zResult, Framework::JSON::JSONObject* zJson) const
+        = 0;
+    virtual void toJson(S* zObject, Framework::JSON::JSONObject* zResult) const
+        = 0;
+    virtual JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const
         = 0;
+
+    virtual Framework::JSON::Validator::JSONValidator* getValidator() const
+    {
+        return addToValidator(
+            Framework::JSON::Validator::JSONValidator::buildForObject())
+            ->finishObject();
+    };
+
     virtual Framework::Text getTypeToken() const = 0;
 };
 
@@ -55,23 +75,23 @@ template<typename T> class SubTypeFactoryRef
 {
 private:
     Framework::Text typetoken;
-    std::function<T*(Framework::JSON::JSONObject*)> fromJsonFunc;
-    std::function<Framework::JSON::JSONObject*(T*)> toJsonFunc;
-    std::function<Framework::JSON::Validator::JSONValidator*(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>*)>
+    std::function<T*(Framework::JSON::JSONObject*)> createJValueFunc;
+    std::function<void(T*, Framework::JSON::JSONObject*)> fromJsonFunc;
+    std::function<void(T*, Framework::JSON::JSONObject*)> toJsonFunc;
+    std::function<JSONObjectValidationBuilder*(JSONObjectValidationBuilder*)>
         getValidatorFunc;
     Framework::ReferenceCounter* factory;
 
 public:
     SubTypeFactoryRef(Framework::Text typetoken,
-        std::function<T*(Framework::JSON::JSONObject*)> fromJsonFunc,
-        std::function<Framework::JSON::JSONObject*(T*)> toJsonFunc,
-        std::function<Framework::JSON::Validator::JSONValidator*(
-            Framework::JSON::Validator::ObjectValidationBuilder<
-                Framework::JSON::Validator::JSONValidator>*)> getValidatorFunc,
+        std::function<T*(Framework::JSON::JSONObject*)> createJValueFunc,
+        std::function<void(T*, Framework::JSON::JSONObject*)> fromJsonFunc,
+        std::function<void(T*, Framework::JSON::JSONObject*)> toJsonFunc,
+        std::function<JSONObjectValidationBuilder*(
+            JSONObjectValidationBuilder*)> getValidatorFunc,
         Framework::ReferenceCounter* factory)
         : ReferenceCounter(),
+          createJValueFunc(createJValueFunc),
           typetoken(typetoken),
           fromJsonFunc(fromJsonFunc),
           toJsonFunc(toJsonFunc),
@@ -84,19 +104,23 @@ public:
         factory->release();
     }
 
-    T* fromJson(Framework::JSON::JSONObject* zJson) const
+    T* createValue(Framework::JSON::JSONObject* zJson) const
+    {
+        return createJValueFunc(zJson);
+    }
+
+    void fromJson(T* zResult, Framework::JSON::JSONObject* zJson) const
     {
-        return fromJsonFunc(zJson);
+        fromJsonFunc(zResult, zJson);
     }
 
-    Framework::JSON::JSONObject* toJSON(T* zObject) const
+    void toJSON(T* zObject, Framework::JSON::JSONObject* zResult) const
     {
-        return toJsonFunc(zObject);
+        toJsonFunc(zObject, zResult);
     }
 
-    Framework::JSON::Validator::JSONValidator* getValidator(
-        Framework::JSON::Validator::ObjectValidationBuilder<
-            Framework::JSON::Validator::JSONValidator>* builder) const
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const
     {
         return getValidatorFunc(builder);
     }
@@ -119,7 +143,7 @@ public:
         : TypeFactory<T>()
     {}
 
-    T* fromJson(Framework::JSON::JSONValue* zJson) const override
+    T* createValue(Framework::JSON::JSONObject* zJson) const override
     {
         for (SubTypeFactoryRef<T>* factory : factories)
         {
@@ -129,36 +153,53 @@ public:
                     ->getString()
                     .istGleich(factory->getTypetoken()))
             {
-                return factory->fromJson(zJson->asObject());
+                return factory->createValue(zJson->asObject());
             }
         }
         return 0;
     }
 
-    Framework::JSON::JSONValue* toJson(T* zObject) const override
+    void fromJson(T* zResult, Framework::JSON::JSONObject* zJson) const override
+    {
+        for (SubTypeFactoryRef<T>* factory : factories)
+        {
+            if (zJson->asObject()
+                    ->zValue("type")
+                    ->asString()
+                    ->getString()
+                    .istGleich(factory->getTypetoken()))
+            {
+                factory->fromJson(zResult, zJson->asObject());
+            }
+        }
+    }
+
+    void toJson(T* zObject, Framework::JSON::JSONObject* zResult) const override
     {
         auto name = typeNames.begin();
         for (SubTypeFactoryRef<T>* factory : factories)
         {
             if (name->istGleich(typeid(*zObject).name()))
             {
-                Framework::JSON::JSONObject* result = factory->toJSON(zObject);
-                if (result)
-                {
-                    result->addValue("type",
-                        new Framework::JSON::JSONString(
-                            factory->getTypetoken()));
-                    return result;
-                }
+                factory->toJSON(zObject, zResult);
+                zResult->addValue("type",
+                    new Framework::JSON::JSONString(factory->getTypetoken()));
+                return;
             }
             name++;
         }
-        return 0;
+    }
+
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override
+    {
+        throw "Can not add polymorph json validator to an object "
+              "validation builder";
     }
 
     Framework::JSON::Validator::JSONValidator* getValidator() const override
     {
-        Framework::JSON::Validator::JSONValidator* result = 0;
+        Framework::JSON::Validator::JSONValidator* result;
         if (!insideGetValidator)
         {
             insideGetValidator = true;
@@ -167,15 +208,20 @@ public:
                       ->typeSpecifiedByAttribute("type");
             for (SubTypeFactoryRef<T>* factory : factories)
             {
-                validator = validator->addAcceptedType(factory->getValidator(
-                    Framework::JSON::Validator::JSONValidator::buildForObject()
-                        ->withRequiredString("type")
-                        ->withExactMatch(factory->getTypetoken())
-                        ->finishString()
-                        ->setObjectReferenceId(
-                            ((Framework::Text("_type_") += typeid(T).name())
-                                += "_")
-                            += factory->getTypetoken())));
+                validator = validator->addAcceptedType(
+                    factory
+                        ->addToValidator(
+                            Framework::JSON::Validator::JSONValidator::
+                                buildForObject()
+                                    ->withRequiredString("type")
+                                    ->withExactMatch(factory->getTypetoken())
+                                    ->finishString()
+                                    ->setObjectReferenceId(
+                                        ((Framework::Text("_type_")
+                                             += typeid(T).name())
+                                            += "_")
+                                        += factory->getTypetoken()))
+                        ->finishObject());
             }
             result = validator->finishOneOf();
             insideGetValidator = false;
@@ -205,24 +251,21 @@ public:
         factories.add(new SubTypeFactoryRef<T>(
             factory->getTypeToken(),
             [factory](Framework::JSON::JSONObject* zJson) {
-                S* value = factory->fromJson(zJson);
+                S* value = factory->createValue(zJson);
                 if (value)
                 {
-                    return dynamic_cast<T*>(factory->fromJson(zJson));
+                    return dynamic_cast<T*>(value);
                 }
                 return (T*)0;
             },
-            [factory](T* zObject) {
-                S* value = dynamic_cast<S*>(zObject);
-                if (value)
-                {
-                    return factory->toJson(value);
-                }
-                return (Framework::JSON::JSONObject*)0;
+            [factory](T* zResult, Framework::JSON::JSONObject* zJson) {
+                factory->fromJson(dynamic_cast<S*>(zResult), zJson);
+            },
+            [factory](T* zObject, Framework::JSON::JSONObject* zResult) {
+                factory->toJson(dynamic_cast<S*>(zObject), zResult);
             },
-            [factory](Framework::JSON::Validator::ObjectValidationBuilder<
-                Framework::JSON::Validator::JSONValidator>* builder) {
-                return factory->getValidator(builder);
+            [factory](JSONObjectValidationBuilder* builder) {
+                return factory->addToValidator(builder);
             },
             dynamic_cast<Framework::ReferenceCounter*>(factory)));
         typeNames.add(new Framework::Text(typeid(S).name()));
@@ -235,23 +278,31 @@ thread_local bool PolymorphTypeFactory<T>::insideGetValidator = false;
 class TypeFatoryRef : public Framework::ReferenceCounter
 {
 private:
-    std::function<void*(Framework::JSON::JSONValue*)> fromJsonFunc;
-    std::function<Framework::JSON::JSONValue*(void*)> toJsonFunc;
+    std::function<void*(Framework::JSON::JSONObject*)> createValueFunc;
+    std::function<void(void*, Framework::JSON::JSONObject*)> fromJsonFunc;
+    std::function<void(void*, Framework::JSON::JSONObject*)> toJsonFunc;
     std::function<Framework::JSON::Validator::JSONValidator*()>
         getValidatorFunc;
+    std::function<JSONObjectValidationBuilder*(JSONObjectValidationBuilder*)>
+        addToValidatorFunc;
     Framework::ReferenceCounter* factory;
 
 public:
     TypeFatoryRef(
-        std::function<void*(Framework::JSON::JSONValue*)> fromJsonFunc,
-        std::function<Framework::JSON::JSONValue*(void*)> toJsonFunc,
+        std::function<void*(Framework::JSON::JSONObject*)> createValueFunc,
+        std::function<void(void*, Framework::JSON::JSONObject*)> fromJsonFunc,
+        std::function<void(void*, Framework::JSON::JSONObject*)> toJsonFunc,
         std::function<Framework::JSON::Validator::JSONValidator*()>
             getValidatorFunc,
+        std::function<JSONObjectValidationBuilder*(
+            JSONObjectValidationBuilder*)> addToValidatorFunc,
         Framework::ReferenceCounter* factory)
         : ReferenceCounter(),
+          createValueFunc(createValueFunc),
           fromJsonFunc(fromJsonFunc),
           toJsonFunc(toJsonFunc),
           getValidatorFunc(getValidatorFunc),
+          addToValidatorFunc(addToValidatorFunc),
           factory(factory)
     {}
 
@@ -260,14 +311,19 @@ public:
         factory->release();
     }
 
-    void* fromJson(Framework::JSON::JSONValue* zJson) const
+    void* createValue(Framework::JSON::JSONObject* zJson) const
+    {
+        return createValueFunc(zJson);
+    }
+
+    void fromJson(void* zResult, Framework::JSON::JSONObject* zJson) const
     {
-        return fromJsonFunc(zJson);
+        return fromJsonFunc(zResult, zJson);
     }
 
-    Framework::JSON::JSONValue* toJSON(void* zObject) const
+    void toJSON(void* zObject, Framework::JSON::JSONObject* zResult) const
     {
-        return toJsonFunc(zObject);
+        return toJsonFunc(zObject, zResult);
     }
 
     Framework::JSON::Validator::JSONValidator* getValidator() const
@@ -275,81 +331,27 @@ public:
         return getValidatorFunc();
     }
 
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const
+    {
+        return addToValidatorFunc(builder);
+    }
+
     template<typename T> TypeFactory<T>* zFactory() const
     {
         return (TypeFactory<T>*)(factory);
     }
 };
 
-class GeneratorRuleFactory : public virtual Framework::ReferenceCounter
-{
-public:
-    GeneratorRuleFactory();
-    virtual GeneratorRule* createRule(
-        Framework::JSON::JSONValue* zConfig, JExpressionMemory* zMemory)
-        = 0;
-    virtual Framework::JSON::Validator::JSONValidator* getValidator() = 0;
-};
-
-class DimensionFactory : public virtual Framework::ReferenceCounter
-{
-private:
-    int dimensionId;
-
-public:
-    DimensionFactory(int dimensionId);
-    virtual ~DimensionFactory() = default;
-
-    virtual Dimension* createDimension() = 0;
-    int getDimensionId() const;
-};
-
-class DimensionGeneratorFactory : public virtual Framework::ReferenceCounter
-{
-private:
-    Framework::Text name;
-    int dimensionId;
-
-public:
-    DimensionGeneratorFactory(Framework::Text name, int dimensionId);
-
-    virtual DimensionGenerator* createDimensionGenerator(
-        int worldSeed, Framework::JSON::JSONValue* config)
-        = 0;
-    virtual Framework::JSON::Validator::JSONValidator* getConfigValidator() = 0;
-    virtual Framework::JSON::JSONValue* getDefaultConfig() = 0;
-
-    Framework::Text getName() const;
-    int getDimensionId() const;
-};
-
 class TypeRegistry : public Framework::ReferenceCounter
 {
 private:
-    Framework::RCArray<GeneratorRuleFactory> generatorRules;
-    Framework::RCArray<DimensionGeneratorFactory> dimensionGenerators;
-    Framework::RCArray<DimensionFactory> dimensionFactories;
     Framework::RCTrie<TypeFatoryRef> parsableTypes;
     Framework::RCArray<Framework::Text> parsableTypeNames;
 
 public:
     TypeRegistry();
 
-    void registerGeneratorRuleFactory(GeneratorRuleFactory* factory);
-    GeneratorRule* createGeneratorRule(
-        Framework::JSON::JSONValue* zConfig, JExpressionMemory* zMemory);
-    Framework::JSON::Validator::JSONValidator* getGeneratorRuleValidator();
-
-    void registerDimensionGeneratorFactory(DimensionGeneratorFactory* factory);
-    DimensionGenerator* createDimensionGenerator(
-        Framework::JSON::JSONValue* zConfig, int worldSeed);
-    Framework::JSON::Validator::JSONValidator* getDimensionGeneratorValidator();
-    const Framework::RCArray<DimensionGeneratorFactory>&
-    getDimensionGeneratorFactories() const;
-
-    void registerDimension(DimensionFactory* factory);
-    Dimension* createDimension(int id);
-
     template<typename T,
         typename S,
         typename = std::enable_if<std::is_base_of<T, S>::value>>
@@ -387,11 +389,19 @@ public:
             throw Framework::Text("Type already registered: ") + typeId;
         }
         typeFactoryRef = new TypeFatoryRef(
-            [factory](Framework::JSON::JSONValue* zJson) {
-                return factory->fromJson(zJson);
+            [factory](Framework::JSON::JSONObject* zJson) {
+                return (void*)factory->createValue(zJson);
+            },
+            [factory](void* zResult, Framework::JSON::JSONObject* zJson) {
+                factory->fromJson((T*)zResult, zJson);
+            },
+            [factory](void* zObject, Framework::JSON::JSONObject* zResult) {
+                factory->toJson((T*)zObject, zResult);
             },
-            [factory](void* zObject) { return factory->toJson((T*)zObject); },
             [factory]() { return factory->getValidator(); },
+            [factory](JSONObjectValidationBuilder* builder) {
+                return factory->addToValidator(builder);
+            },
             factory);
         parsableTypes.set(typeId, typeId.getLength(), typeFactoryRef);
         parsableTypeNames.add(new Framework::Text(typeId));
@@ -406,7 +416,9 @@ public:
         {
             throw Framework::Text("Type not registered: ") + typeId;
         }
-        return (T*)(typeFactoryRef->fromJson(zJson));
+        T* result = (T*)(typeFactoryRef->createValue(zJson->asObject()));
+        (typeFactoryRef->fromJson(result, zJson->asObject()));
+        return result;
     }
 
     template<typename T> Framework::JSON::JSONValue* toJson(T* zObject) const
@@ -418,7 +430,9 @@ public:
         {
             throw Framework::Text("Type not registered: ") + typeId;
         }
-        return typeFactoryRef->toJSON(zObject);
+        Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
+        typeFactoryRef->toJSON(zObject, result);
+        return result;
     }
 
     template<typename T>
@@ -434,6 +448,19 @@ public:
         return typeFactoryRef->getValidator();
     }
 
+    template<typename T> JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const
+    {
+        Framework::Text typeId = typeid(T).name();
+        TypeFatoryRef* typeFactoryRef
+            = parsableTypes.z(typeId, typeId.getLength());
+        if (!typeFactoryRef)
+        {
+            throw Framework::Text("Type not registered: ") + typeId;
+        }
+        return typeFactoryRef->addToValidator(builder);
+    }
+
     template<typename T> Framework::JSON::JSONValue* getValidParts(
         Framework::JSON::JSONValue* zJson) const
     {

+ 1 - 0
FactoryCraft/UIDialog.cpp

@@ -2,6 +2,7 @@
 
 #include "Game.h"
 #include "NetworkMessage.h"
+#include "Quest.h"
 
 UIDialog::UIDialog(
     Framework::Text id, int playerId, Framework::XML::Element* uiml)

+ 29 - 104
FactoryCraft/WorldGenerator.cpp

@@ -3,9 +3,10 @@
 #include <Betriebssystem.h>
 #include <functional>
 
+#include "Dimension.h"
 #include "Game.h"
+#include "JsonUtils.h"
 #include "NoiseInterpolator.h"
-#include "OverworldDimension.h"
 
 using namespace Framework;
 using namespace Framework::JSON;
@@ -19,130 +20,54 @@ WorldGenerator::WorldGenerator(int seed)
     setName("World Generator");
     std::cout << "loading world generator configs. Changes at the config files "
                  "may lead to a sudden change in landscape.\n";
-    JSONValidator* validator = buildConfigValidator();
-    loadConfig("data/generator", validator);
-    validator->release();
-    addMissingDimensions();
-
-    start();
-}
-
-WorldGenerator::~WorldGenerator() {}
-
-Framework::JSON::Validator::JSONValidator*
-WorldGenerator::buildConfigValidator()
-{
     JSONValidator* configValidator
         = JSONValidator::buildForArray()
               ->removeInvalidEntries()
               ->addAcceptedTypeInArray(Game::INSTANCE->zTypeRegistry()
-                                           ->getDimensionGeneratorValidator())
+                                           ->getValidator<DimensionGenerator>())
               ->finishArray();
-    Datei syntaxFile(new Text("data/syntax/generatorValidation.xml"));
-    syntaxFile.erstellen();
-    Text syntaxContent = configValidator->zConstraints()->toString();
-    syntaxFile.open(Datei::Style::schreiben);
-    syntaxFile.schreibe(syntaxContent, syntaxContent.getLength());
-    syntaxFile.close();
-    return configValidator;
-}
-
-void WorldGenerator::loadConfig(
-    const char* path, Framework::JSON::Validator::JSONValidator* zValidator)
-{
-    std::cout << "loading dimension configs from '" << path << "'" << std::endl;
-    Datei file(new Text(path));
-    if (file.istOrdner())
-    {
-        RCArray<Text>* fileNames = file.getDateiListe();
-        if (fileNames)
-        {
-            for (Text* name : *fileNames)
-            {
-                loadConfig(Text(path) + "/" + *name, zValidator);
-            }
-            fileNames->release();
-        }
-    }
-    else
-    {
-        JSONValue* json = loadJSONFromFile(path);
-        if (!json)
-        {
-            std::cout << "ERROR: the file does not contain valid json\n";
-        }
-        else
-        {
+    loadAllJsonsFromDirectory("data/generator",
+        [this, configValidator, seed](
+            Framework::JSON::JSONValue* zValue, Framework::Text path) {
+            std::cout << "loading dimension configs from '" << path << "'"
+                      << std::endl;
             Framework::RCArray<JSONValidationResult> invalidParts;
-            JSONValue* valid = zValidator->getValidParts(json, &invalidParts);
+            JSONValue* valid
+                = configValidator->getValidParts(zValue, &invalidParts);
             for (JSONValidationResult* invalidPart : invalidParts)
             {
                 invalidPart->printInvalidInfo();
             }
-            json->release();
             if (valid)
             {
                 for (JSONValue* config : *valid->asArray())
-                    loadDimensionConfig(config);
+                {
+                    DimensionGenerator* generator
+                        = Game::INSTANCE->zTypeRegistry()
+                              ->fromJson<DimensionGenerator>(config);
+                    generator->initialize(seed);
+                    dimensionGenerators.add(generator);
+                }
                 valid->release();
             }
-        }
-    }
-}
+        });
+    configValidator->release();
 
-void WorldGenerator::loadDimensionConfig(Framework::JSON::JSONValue* zConfig)
-{
-    DimensionGenerator* generator
-        = Game::INSTANCE->zTypeRegistry()->createDimensionGenerator(
-            zConfig, seed);
-    if (generator)
-    {
-        dimensionGenerators.add(generator);
-    }
-    else
-    {
-        std::cout << "ERROR: could not find dimension factory for config \n"
-                  << zConfig->toString() << "\n";
-    }
+    start();
 }
 
-void WorldGenerator::addMissingDimensions()
+WorldGenerator::~WorldGenerator() {}
+
+Dimension* WorldGenerator::createDimension(int dimensionId)
 {
-    for (DimensionGeneratorFactory* factory : Game::INSTANCE->zTypeRegistry()->getDimensionGeneratorFactories())
+    for (DimensionGenerator* generator : dimensionGenerators)
     {
-        bool found = 0;
-        for (DimensionGenerator* generator : dimensionGenerators)
-        {
-            if (generator->getDimensionId() == factory->getDimensionId())
-            {
-                found = 1;
-                break;
-            }
-        }
-        if (!found)
-        {
-            std::cout << "WARNING: missing config for dimension '"
-                      << factory->getName() << "' with id "
-                      << factory->getDimensionId()
-                      << ". Default config will be used.";
-            JSONValue* defaultConfig = factory->getDefaultConfig();
-            Datei file(new Text(
-                Text("data/generator/") + factory->getName() + ".json"));
-            if (!file.existiert())
-            {
-                file.erstellen();
-                file.open(Datei::Style::schreiben);
-                Text conficContent
-                    = Text("[") + defaultConfig->toString() + "]";
-                file.schreibe(conficContent, conficContent.getLength());
-                file.close();
-                std::cout << "Default config was written to '" << *file.zPfad()
-                          << "'\n";
-            }
-            loadDimensionConfig(defaultConfig);
-            defaultConfig->release();
-        }
+        if (generator->getDimensionId() == dimensionId)
+            return generator->createDimension();
     }
+    std::cout << "ERROR: no dimension generator found for dimension "
+              << dimensionId << "\n";
+    return 0;
 }
 
 DimensionGenerator* WorldGenerator::zGenerator(int dimensionId)

+ 1 - 5
FactoryCraft/WorldGenerator.h

@@ -15,16 +15,12 @@ private:
     bool exit;
     int seed;
 
-    Framework::JSON::Validator::JSONValidator *buildConfigValidator();
-    void loadConfig(
-        const char* path, Framework::JSON::Validator::JSONValidator *zValidator);
-    void loadDimensionConfig(Framework::JSON::JSONValue* zConfig);
-    void addMissingDimensions();
     DimensionGenerator* zGenerator(int dimensionId);
 
 public:
     WorldGenerator(int seed);
     ~WorldGenerator();
+    Dimension *createDimension(int dimensionId);
     void thread() override;
     void requestGeneration(Area request);
     void exitAndWait();

+ 9 - 4
FactoryCraft/WorldLoader.cpp

@@ -1,9 +1,14 @@
 #include "WorldLoader.h"
 
+#include <Datei.h>
 #include <Punkt.h>
 #include <Text.h>
 
+#include "Dimension.h"
+#include "Entity.h"
+#include "EntityType.h"
 #include "Game.h"
+#include "WorldGenerator.h"
 
 using namespace Framework;
 
@@ -12,20 +17,20 @@ WorldLoader::WorldLoader()
       exit(0)
 {
     setName("World Loader");
-    Datei d;
+    Framework::Datei d;
     d.setDatei(Game::INSTANCE->getWorldDirectory() + "/dim");
     RCArray<Text>* names = d.getDateiListe();
     if (names)
     {
         for (Text* name : *names)
         {
-            Datei entities;
+            Framework::Datei entities;
             entities.setDatei(Game::INSTANCE->getWorldDirectory() + "/dim/"
                               + Text(name->getText()) + "/entities");
-            if (entities.open(Datei::Style::lesen))
+            if (entities.open(Framework::Datei::Style::lesen))
             {
                 Dimension* dim
-                    = Game::INSTANCE->zTypeRegistry()->createDimension(
+                    = Game::INSTANCE->zGenerator()->createDimension(
                         (int)*name);
                 if (dim)
                 {

+ 15 - 13
FactoryCraft/WormCaveGenerator.cpp

@@ -1,5 +1,6 @@
 #include "WormCaveGenerator.h"
 
+#include "Constants.h"
 #include "FastNoiseWrapper.h"
 #include "Game.h"
 #include "RandNoise.h"
@@ -18,7 +19,7 @@ NoiseWorm3D::NoiseWorm3D(Noise* pitch,
     : ReferenceCounter(),
       startChunk(Game::INSTANCE->getChunkCenter(startPos.x, startPos.y))
 {
-    Vec3<float> lastPos = (Vec3<float>)startPos;
+    Framework::Vec3<float> lastPos = (Framework::Vec3<float>)startPos;
     keyPoints.add(lastPos);
     this->size.add((float)minRad);
     minAffected.x = (int)lastPos.x - minRad;
@@ -29,7 +30,7 @@ NoiseWorm3D::NoiseWorm3D(Noise* pitch,
     maxAffected.z = (int)lastPos.z + minRad;
     while (keyPoints.getEintragAnzahl() < distant * 20)
     {
-        Vec3<float> defaultDir(1.f, 0.f, 0.f);
+        Framework::Vec3<float> defaultDir(1.f, 0.f, 0.f);
         if (keyPoints.getEintragAnzahl() > 1)
         {
             defaultDir = keyPoints.get(keyPoints.getEintragAnzahl() - 1)
@@ -41,8 +42,9 @@ NoiseWorm3D::NoiseWorm3D(Noise* pitch,
         n = (float)pitch->getNoise(lastPos.x, lastPos.y, lastPos.z);
         defaultDir.z = ((float)n - 0.3f) * 2.f;
         lastPos = lastPos + defaultDir;
-        if ((Vec2<float>(lastPos.x, lastPos.y)
-                - (Vec2<float>((float)startPos.x, (float)startPos.y)))
+        if ((Framework::Vec2<float>(lastPos.x, lastPos.y)
+                - (Framework::Vec2<float>(
+                    (float)startPos.x, (float)startPos.y)))
                 .getLengthSq()
             >= (float)(distant * distant))
             break;
@@ -80,8 +82,8 @@ void NoiseWorm3D::getPartAffectedByChunk(
         int outsideCounter = 0;
         while (pi && si)
         {
-            if ((Vec2<float>((float)x, (float)y)
-                    - Vec2<float>(pi.val().x, pi.val().y))
+            if ((Framework::Vec2<float>((float)x, (float)y)
+                    - Framework::Vec2<float>(pi.val().x, pi.val().y))
                     .getLengthSq()
                 < (si.val() + CHUNK_SIZE / 2) * (si.val() + CHUNK_SIZE / 2))
             {
@@ -146,7 +148,8 @@ bool NoiseWorm3D::isInside(int x, int y, int z)
         auto si = size.begin();
         while (pi && si)
         {
-            if (Vec3<float>((float)x, (float)y, (float)z).abstandSq(pi.val())
+            if (Framework::Vec3<float>((float)x, (float)y, (float)z)
+                    .abstandSq(pi.val())
                 < si.val() * si.val())
                 return 1;
             ++pi;
@@ -201,7 +204,7 @@ NoiseWorm3D* WormCaveGenerator::zWormOfChunk(int x, int y)
             return worm;
         }
     }
-    for (Punkt p : noWormChunks)
+    for (Framework::Punkt p : noWormChunks)
     {
         if (p.x == x && p.y == y) return 0;
     }
@@ -218,7 +221,7 @@ NoiseWorm3D* WormCaveGenerator::zWormOfChunk(int x, int y)
         noise->SetFrequency(0.005f);
         FastNoiseWrapper* yaw
             = new FastNoiseWrapper(noise, seed - x * y - y - x);
-        Vec3<int> start(
+        Framework::Vec3<int> start(
             (int)(cNoise / cavePosibillity * CHUNK_SIZE) + x - CHUNK_SIZE / 2,
             (int)(cNoise / cavePosibillity * CHUNK_SIZE) + y - CHUNK_SIZE / 2,
             (int)(cNoise / cavePosibillity * 200));
@@ -248,7 +251,7 @@ NoiseWorm3D* WormCaveGenerator::zWormOfChunk(int x, int y)
         if (noWormChunks.getEintragAnzahl()
             > (maxDistant * 2) / CHUNK_SIZE * (maxDistant * 2) / CHUNK_SIZE * 3)
             noWormChunks.remove(0);
-        noWormChunks.add(Punkt(x, y));
+        noWormChunks.add(Framework::Punkt(x, y));
     }
     return 0;
 }
@@ -256,7 +259,7 @@ NoiseWorm3D* WormCaveGenerator::zWormOfChunk(int x, int y)
 CaveChunkGenerator* WormCaveGenerator::getGeneratorForChunk(int x, int y)
 {
     Framework::RCArray<NoiseWorm3D> affected;
-    Punkt center = Game::getChunkCenter(x, y);
+    Framework::Punkt center = Game::getChunkCenter(x, y);
     int offset = (int)ceil((float)maxDistant / CHUNK_SIZE);
     for (int cx = -offset; cx <= offset; cx++)
     {
@@ -264,8 +267,7 @@ CaveChunkGenerator* WormCaveGenerator::getGeneratorForChunk(int x, int y)
         {
             NoiseWorm3D* worm = zWormOfChunk(
                 center.x + cx * CHUNK_SIZE, center.y + cy * CHUNK_SIZE);
-            if (worm)
-                worm->getPartAffectedByChunk(x, y, &affected);
+            if (worm) worm->getPartAffectedByChunk(x, y, &affected);
         }
     }
     return new WormCaveChunkGenerator(affected);

+ 0 - 4
Windows Version/Windows Version.vcxproj

@@ -220,8 +220,6 @@ copy ..\..\..\..\..\Allgemein\Framework\x64\release\Framework.dll Framework.dll<
     <ClCompile Include="..\FactoryCraft\NetworkMessage.cpp" />
     <ClCompile Include="..\FactoryCraft\NoBlock.cpp" />
     <ClCompile Include="..\FactoryCraft\Noise.cpp" />
-    <ClCompile Include="..\FactoryCraft\OverworldDimension.cpp" />
-    <ClCompile Include="..\FactoryCraft\OverworldDimensionGenerator.cpp" />
     <ClCompile Include="..\FactoryCraft\NoiseInterpolator.cpp" />
     <ClCompile Include="..\FactoryCraft\PlaceableProof.cpp" />
     <ClCompile Include="..\FactoryCraft\Player.cpp" />
@@ -323,8 +321,6 @@ copy ..\..\..\..\..\Allgemein\Framework\x64\release\Framework.dll Framework.dll<
     <ClInclude Include="..\FactoryCraft\NetworkMessage.h" />
     <ClInclude Include="..\FactoryCraft\Noise.h" />
     <ClInclude Include="..\FactoryCraft\NoBlock.h" />
-    <ClInclude Include="..\FactoryCraft\OverworldDimension.h" />
-    <ClInclude Include="..\FactoryCraft\OverworldDimensionGenerator.h" />
     <ClInclude Include="..\FactoryCraft\NoiseInterpolator.h" />
     <ClInclude Include="..\FactoryCraft\PlaceableProof.h" />
     <ClInclude Include="..\FactoryCraft\Player.h" />

+ 0 - 18
Windows Version/Windows Version.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>
@@ -94,9 +91,6 @@
     <Filter Include="world\generator\biom\rules">
       <UniqueIdentifier>{3a03ed08-0a9d-4887-a1f0-d2a84028c425}</UniqueIdentifier>
     </Filter>
-    <Filter Include="world\dimensions">
-      <UniqueIdentifier>{2ad688cd-aafc-4b2b-8163-964d1e87d087}</UniqueIdentifier>
-    </Filter>
     <Filter Include="quests">
       <UniqueIdentifier>{58a901d6-aa56-4225-b9cd-9b12552701cc}</UniqueIdentifier>
     </Filter>
@@ -135,9 +129,6 @@
     <ClCompile Include="..\FactoryCraft\WorldGenerator.cpp">
       <Filter>world\generator</Filter>
     </ClCompile>
-    <ClCompile Include="..\FactoryCraft\OverworldDimensionGenerator.cpp">
-      <Filter>world\generator\dimensions</Filter>
-    </ClCompile>
     <ClCompile Include="..\FactoryCraft\TickWorker.cpp">
       <Filter>world\ticking</Filter>
     </ClCompile>
@@ -363,9 +354,6 @@
     <ClCompile Include="..\FactoryCraft\BlockInfoCommand.cpp">
       <Filter>chat\commands</Filter>
     </ClCompile>
-    <ClCompile Include="..\FactoryCraft\OverworldDimension.cpp">
-      <Filter>world\dimensions</Filter>
-    </ClCompile>
     <ClCompile Include="..\FactoryCraft\BlockInstanceGeneratorRule.cpp">
       <Filter>world\generator\biom\rules</Filter>
     </ClCompile>
@@ -461,9 +449,6 @@
     <ClInclude Include="..\FactoryCraft\DimensionGenerator.h">
       <Filter>world\generator</Filter>
     </ClInclude>
-    <ClInclude Include="..\FactoryCraft\OverworldDimensionGenerator.h">
-      <Filter>world\generator\dimensions</Filter>
-    </ClInclude>
     <ClInclude Include="..\FactoryCraft\TickWorker.h">
       <Filter>world\ticking</Filter>
     </ClInclude>
@@ -668,9 +653,6 @@
     <ClInclude Include="..\FactoryCraft\BlockInfoCommand.h">
       <Filter>chat\commands</Filter>
     </ClInclude>
-    <ClInclude Include="..\FactoryCraft\OverworldDimension.h">
-      <Filter>world\dimensions</Filter>
-    </ClInclude>
     <ClInclude Include="..\FactoryCraft\Constants.h">
       <Filter>static</Filter>
     </ClInclude>

+ 17 - 15
Windows Version/data/generator/overworld.json

@@ -1,6 +1,8 @@
 [
   {
-    "dimension": "Overworld",
+    "type": "cavedBioms",
+    "name": "Overworld",
+    "id": 0,
     "dimensionSeed": {
       "type": "operator",
       "operator": "+",
@@ -305,7 +307,7 @@
               "operator": "&&",
               "values": [
                 {
-                  "type": "operator",
+                  "type": "comparsion",
                   "operator": "==i",
                   "values": [
                     {
@@ -329,7 +331,7 @@
                   ]
                 },
                 {
-                  "type": "operator",
+                  "type": "comparsion",
                   "operator": ">=i",
                   "values": [
                     {
@@ -343,7 +345,7 @@
                   ]
                 },
                 {
-                  "type": "operator",
+                  "type": "comparsion",
                   "operator": "<i",
                   "values": [
                     {
@@ -369,7 +371,7 @@
               "operator": "&&",
               "values": [
                 {
-                  "type": "operator",
+                  "type": "comparsion",
                   "operator": ">=i",
                   "values": [
                     {
@@ -383,7 +385,7 @@
                   ]
                 },
                 {
-                  "type": "operator",
+                  "type": "comparsion",
                   "operator": "<i",
                   "values": [
                     {
@@ -403,7 +405,7 @@
             "type": "blockType",
             "blockType": "Air",
             "condition": {
-              "type": "operator",
+              "type": "comparsion",
               "operator": ">i",
               "values": [
                 {
@@ -443,7 +445,7 @@
               "operator": "&&",
               "values": [
                 {
-                  "type": "operator",
+                  "type": "comparsion",
                   "operator": "==i",
                   "values": [
                     {
@@ -508,7 +510,7 @@
             },
             "threshold": 0.35,
             "condition": {
-              "type": "operator",
+              "type": "comparsion",
               "operator": "<i",
               "values": [
                 {
@@ -545,7 +547,7 @@
             },
             "threshold": 0.35,
             "condition": {
-              "type": "operator",
+              "type": "comparsion",
               "operator": "<i",
               "values": [
                 {
@@ -586,7 +588,7 @@
               "operator": "&&",
               "values": [
                 {
-                  "type": "operator",
+                  "type": "comparsion",
                   "operator": "<i",
                   "values": [
                     {
@@ -600,7 +602,7 @@
                   ]
                 },
                 {
-                  "type": "operator",
+                  "type": "comparsion",
                   "operator": ">i",
                   "values": [
                     {
@@ -624,7 +626,7 @@
               "operator": "&&",
               "values": [
                 {
-                  "type": "operator",
+                  "type": "comparsion",
                   "operator": "<i",
                   "values": [
                     {
@@ -638,7 +640,7 @@
                   ]
                 },
                 {
-                  "type": "operator",
+                  "type": "comparsion",
                   "operator": ">i",
                   "values": [
                     {
@@ -658,7 +660,7 @@
             "type": "blockType",
             "blockType": "Stone",
             "condition": {
-              "type": "operator",
+              "type": "comparsion",
               "operator": "<=i",
               "values": [
                 {