ソースを参照

Improve Drop configuration for blocks and entities

Kolja Strohm 2 日 前
コミット
129e007172
57 ファイル変更2430 行追加1433 行削除
  1. 10 101
      FactoryCraft/Animal.cpp
  2. 4 11
      FactoryCraft/Animal.h
  3. 2 185
      FactoryCraft/BasicBlocks.cpp
  4. 0 55
      FactoryCraft/BasicBlocks.h
  5. 76 87
      FactoryCraft/BasicTool.cpp
  6. 10 10
      FactoryCraft/Block.cpp
  7. 4 2
      FactoryCraft/Block.h
  8. 15 1
      FactoryCraft/BlockType.cpp
  9. 39 1
      FactoryCraft/BlockType.h
  10. 0 15
      FactoryCraft/Chest.cpp
  11. 0 1
      FactoryCraft/Chest.h
  12. 53 0
      FactoryCraft/DefaultBlockItemDrop.cpp
  13. 27 0
      FactoryCraft/DefaultBlockItemDrop.h
  14. 67 0
      FactoryCraft/DefaultInventoryDrop.cpp
  15. 27 0
      FactoryCraft/DefaultInventoryDrop.h
  16. 53 0
      FactoryCraft/DropChanceCondition.cpp
  17. 34 0
      FactoryCraft/DropChanceCondition.h
  18. 18 0
      FactoryCraft/DropCondition.h
  19. 218 0
      FactoryCraft/DropConditionOperator.cpp
  20. 103 0
      FactoryCraft/DropConditionOperator.h
  21. 38 0
      FactoryCraft/DropConfig.cpp
  22. 71 0
      FactoryCraft/DropConfig.h
  23. 94 0
      FactoryCraft/DropUsedItemCondition.cpp
  24. 60 0
      FactoryCraft/DropUsedItemCondition.h
  25. 10 4
      FactoryCraft/Entity.cpp
  26. 4 2
      FactoryCraft/Entity.h
  27. 28 3
      FactoryCraft/EntityType.cpp
  28. 79 7
      FactoryCraft/EntityType.h
  29. 15 0
      FactoryCraft/FactoryCraft.vcxproj
  30. 54 0
      FactoryCraft/FactoryCraft.vcxproj.filters
  31. 1 1
      FactoryCraft/FluidBlock.cpp
  32. 15 18
      FactoryCraft/FluidContainer.cpp
  33. 2 1
      FactoryCraft/GeneratorRule.h
  34. 3 1
      FactoryCraft/GeneratorTemplate.h
  35. 9 10
      FactoryCraft/Grass.cpp
  36. 3 3
      FactoryCraft/Grass.h
  37. 7 5
      FactoryCraft/ItemEntity.cpp
  38. 2 1
      FactoryCraft/MultiblockStructure.cpp
  39. 5 1
      FactoryCraft/MultiblockStructure.h
  40. 9 5
      FactoryCraft/MultiblockTree.cpp
  41. 4 1
      FactoryCraft/MultiblockTree.h
  42. 9 9
      FactoryCraft/Player.cpp
  43. 2 1
      FactoryCraft/Player.h
  44. 6 2
      FactoryCraft/PlayerHand.cpp
  45. 1 6
      FactoryCraft/QuestRequirement.cpp
  46. 132 0
      FactoryCraft/SpecificItemDrop.cpp
  47. 40 0
      FactoryCraft/SpecificItemDrop.h
  48. 1 5
      FactoryCraft/TreeTemplate.cpp
  49. 18 1
      FactoryCraft/TypeRegistry.cpp
  50. 3 3
      FactoryCraft/TypeRegistry.h
  51. 15 0
      Windows Version/Windows Version.vcxproj
  52. 54 0
      Windows Version/Windows Version.vcxproj.filters
  53. 645 645
      Windows Version/data/generator/overworld.json
  54. 14 12
      Windows Version/data/items/itemTypes.json
  55. 61 61
      Windows Version/data/quests/quests.json
  56. 103 103
      Windows Version/data/recipies/blocks.json
  57. 53 53
      Windows Version/data/recipies/tools.json

+ 10 - 101
FactoryCraft/Animal.cpp

@@ -19,41 +19,6 @@ Animal::~Animal()
     }
     }
 }
 }
 
 
-void Animal::onDeath()
-{
-    if (!removed)
-    {
-        for (const SpawnConfig& config : spawns)
-        {
-            if ((double)rand() / RAND_MAX < config.chance)
-            {
-                int amount = config.min
-                           + (int)((config.max - config.min)
-                                   * ((double)rand() / RAND_MAX));
-                if (amount > 0)
-                {
-                    ItemStack* spawnedItems
-                        = Game::INSTANCE->zItemType(config.typeId)
-                              ->createItemStack(amount);
-                    if (spawnedItems)
-                    {
-                        Game::INSTANCE->spawnItem(
-                            location + Framework::Vec3<float>(0.5f, 0.5f, 0.5f),
-                            getDimensionId(),
-                            spawnedItems);
-                    }
-                }
-            }
-        }
-    }
-    Entity::onDeath();
-}
-
-void Animal::setSpawns(const Framework::Array<SpawnConfig>& spawnConfig)
-{
-    spawns = spawnConfig;
-}
-
 void Animal::setAI(AnimalAI* ai)
 void Animal::setAI(AnimalAI* ai)
 {
 {
     if (this->ai)
     if (this->ai)
@@ -82,8 +47,8 @@ void Animal::tick(const Dimension* zDimension)
     Entity::tick(zDimension);
     Entity::tick(zDimension);
 }
 }
 
 
-AnimalEntityType::AnimalEntityType(Framework::Text name, ModelInfo* model)
-    : EntityType(name, model)
+AnimalEntityType::AnimalEntityType()
+    : EntityType()
 {}
 {}
 
 
 AnimalEntityType::~AnimalEntityType()
 AnimalEntityType::~AnimalEntityType()
@@ -111,63 +76,25 @@ Entity* AnimalEntityType::createEntity(
 {
 {
     Animal* result = new Animal(getId(), position, dimensionId, entityId);
     Animal* result = new Animal(getId(), position, dimensionId, entityId);
     result->setAI(Game::INSTANCE->zTypeRegistry()->fromJson<AnimalAI>(ai));
     result->setAI(Game::INSTANCE->zTypeRegistry()->fromJson<AnimalAI>(ai));
-    result->setSpawns(spawns);
     return result;
     return result;
 }
 }
 
 
 AnimalEntityTypeFactory::AnimalEntityTypeFactory()
 AnimalEntityTypeFactory::AnimalEntityTypeFactory()
-    : SubTypeFactory()
+    : EntityTypeFactoryBase()
 {}
 {}
 
 
-AnimalEntityType* AnimalEntityTypeFactory::fromJson(
+AnimalEntityType* AnimalEntityTypeFactory::createValue(
     Framework::JSON::JSONObject* zJson) const
     Framework::JSON::JSONObject* zJson) const
 {
 {
-    Framework::Text name = zJson->zValue("typeName")->asString()->getString();
-    AnimalEntityType* result = new AnimalEntityType(name,
-        Game::INSTANCE->zTypeRegistry()->fromJson<ModelInfo>(
-            zJson->zValue("model")));
-    Framework::JSON::JSONArray* spawnsJson = zJson->zValue("spawns")->asArray();
-    for (int i = 0; i < spawnsJson->getLength(); i++)
-    {
-        Framework::JSON::JSONObject* spawnJson
-            = spawnsJson->zValue(i)->asObject();
-        result->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,
-        });
-    }
+    AnimalEntityType* result = new AnimalEntityType();
     result->ai = zJson->getValue("ai")->asObject();
     result->ai = zJson->getValue("ai")->asObject();
     return result;
     return result;
 }
 }
 
 
-Framework::JSON::JSONObject* AnimalEntityTypeFactory::toJsonObject(
-    AnimalEntityType* zObject) const
+void AnimalEntityTypeFactory::addToJson(
+    Framework::JSON::JSONObject* zJson, AnimalEntityType* zObject) const
 {
 {
-    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
-    Framework::JSON::JSONArray* spawnsJson = new Framework::JSON::JSONArray();
-    for (int i = 0; i < zObject->spawns.getEintragAnzahl(); i++)
-    {
-        SpawnConfig spawn = zObject->spawns.get(i);
-        Framework::JSON::JSONObject* spawnJson
-            = new Framework::JSON::JSONObject();
-        spawnJson->addValue("min", new Framework::JSON::JSONNumber(spawn.min));
-        spawnJson->addValue("max", new Framework::JSON::JSONNumber(spawn.max));
-        spawnJson->addValue(
-            "chance", new Framework::JSON::JSONNumber(spawn.chance));
-        spawnJson->addValue(
-            "itemType", new Framework::JSON::JSONString(spawn.itemTypeName));
-        spawnsJson->addValue(spawnJson);
-    }
-    result->addValue("spawns", spawnsJson);
-    result->addValue(
-        "typeName", new Framework::JSON::JSONString(zObject->getName()));
-    result->addValue(
-        "model", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zModel()));
-    result->addValue("ai", zObject->ai->clone());
-    return result;
+    zJson->addValue("ai", zObject->ai->clone());
 }
 }
 
 
 const char* AnimalEntityTypeFactory::getTypeToken() const
 const char* AnimalEntityTypeFactory::getTypeToken() const
@@ -178,24 +105,6 @@ const char* AnimalEntityTypeFactory::getTypeToken() const
 JSONObjectValidationBuilder* AnimalEntityTypeFactory::addToValidator(
 JSONObjectValidationBuilder* AnimalEntityTypeFactory::addToValidator(
     JSONObjectValidationBuilder* builder) const
     JSONObjectValidationBuilder* builder) const
 {
 {
-    return builder
-        ->withRequiredAttribute("spawns",
-            Framework::Validator::DataValidator::buildForArray()
-                ->addAcceptedObjectInArray()
-                ->withRequiredAttribute("itemType",
-                    Game::INSTANCE->zTypeRegistry()
-                        ->getValidator<Framework::Text>(
-                            ItemTypeNameFactory::TYPE_ID))
-                ->withRequiredNumber("chance")
-                ->finishNumber()
-                ->withRequiredNumber("min")
-                ->finishNumber()
-                ->withRequiredNumber("max")
-                ->finishNumber()
-                ->finishObject()
-                ->finishArray())
-        ->withRequiredString("typeName")
-        ->finishString()
-        ->withRequiredAttribute("model",
-            Game::INSTANCE->zTypeRegistry()->getValidator<ModelInfo>());
+    return builder->withRequiredAttribute(
+        "ai", Game::INSTANCE->zTypeRegistry()->getValidator<AnimalAI>());
 }
 }

+ 4 - 11
FactoryCraft/Animal.h

@@ -8,19 +8,14 @@
 class Animal : public Entity
 class Animal : public Entity
 {
 {
 private:
 private:
-    Framework::Array<SpawnConfig> spawns;
     AnimalAI* ai;
     AnimalAI* ai;
 
 
-protected:
-    void onDeath() override;
-
 public:
 public:
     Animal(int typeId,
     Animal(int typeId,
         Framework::Vec3<float> location,
         Framework::Vec3<float> location,
         int dimensionId,
         int dimensionId,
         int entityId);
         int entityId);
     ~Animal();
     ~Animal();
-    void setSpawns(const Framework::Array<SpawnConfig>& spawnConfig);
     void setAI(AnimalAI* ai);
     void setAI(AnimalAI* ai);
     bool interact(Item* zItem, Entity* zActor) override;
     bool interact(Item* zItem, Entity* zActor) override;
     void takeDamage(Entity* zSource, float damage) override;
     void takeDamage(Entity* zSource, float damage) override;
@@ -33,7 +28,6 @@ class AnimalEntityType : public EntityType
 {
 {
 private:
 private:
     Framework::JSON::JSONObject* ai;
     Framework::JSON::JSONObject* ai;
-    Framework::Array<SpawnConfig> spawns;
 
 
 protected:
 protected:
     virtual void loadSuperEntity(
     virtual void loadSuperEntity(
@@ -42,7 +36,7 @@ protected:
         Entity* zEntity, Framework::StreamWriter* zWriter) const;
         Entity* zEntity, Framework::StreamWriter* zWriter) const;
 
 
 public:
 public:
-    AnimalEntityType(Framework::Text name, ModelInfo* model);
+    AnimalEntityType();
     ~AnimalEntityType();
     ~AnimalEntityType();
 
 
     Entity* createEntity(Framework::Vec3<float> position,
     Entity* createEntity(Framework::Vec3<float> position,
@@ -52,14 +46,13 @@ public:
     friend AnimalEntityTypeFactory;
     friend AnimalEntityTypeFactory;
 };
 };
 
 
-class AnimalEntityTypeFactory
-    : public SubTypeFactory<EntityType, AnimalEntityType>
+class AnimalEntityTypeFactory : public EntityTypeFactoryBase<AnimalEntityType>
 {
 {
 public:
 public:
     AnimalEntityTypeFactory();
     AnimalEntityTypeFactory();
-    AnimalEntityType* fromJson(
+    virtual AnimalEntityType* createValue(
         Framework::JSON::JSONObject* zJson) const override;
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJsonObject(
+    virtual void addToJson(Framework::JSON::JSONObject* zJson,
         AnimalEntityType* zObject) const override;
         AnimalEntityType* zObject) const override;
     JSONObjectValidationBuilder* addToValidator(
     JSONObjectValidationBuilder* addToValidator(
         JSONObjectValidationBuilder* builder) const override;
         JSONObjectValidationBuilder* builder) const override;

+ 2 - 185
FactoryCraft/BasicBlocks.cpp

@@ -208,8 +208,7 @@ Framework::JSON::JSONObject* BasicBlockTypeFactory::toJsonObject(
 JSONObjectValidationBuilder* BasicBlockTypeFactory::addToValidator(
 JSONObjectValidationBuilder* BasicBlockTypeFactory::addToValidator(
     JSONObjectValidationBuilder* builder) const
     JSONObjectValidationBuilder* builder) const
 {
 {
-    return BlockTypeFactoryBase::addToValidator(
-        builder
+    return BlockTypeFactoryBase::addToValidator(builder
             ->withRequiredAttribute("itemType",
             ->withRequiredAttribute("itemType",
                 Game::INSTANCE->zTypeRegistry()->getValidator<Framework::Text>(
                 Game::INSTANCE->zTypeRegistry()->getValidator<Framework::Text>(
                     ItemTypeNameFactory::TYPE_ID),
                     ItemTypeNameFactory::TYPE_ID),
@@ -232,186 +231,4 @@ JSONObjectValidationBuilder* BasicBlockTypeFactory::addToValidator(
 const char* BasicBlockTypeFactory::getTypeToken() const
 const char* BasicBlockTypeFactory::getTypeToken() const
 {
 {
     return "basicBlock";
     return "basicBlock";
-}
-
-AdditionalItemSpawningBlock::AdditionalItemSpawningBlock(
-    int typeId, Framework::Vec3<int> pos, int dimensionId)
-    : BasicBlock(typeId, pos, dimensionId)
-{}
-
-void AdditionalItemSpawningBlock::addSpawn(SpawnConfig config)
-{
-    spawns.add(config);
-}
-
-void AdditionalItemSpawningBlock::onDestroy()
-{
-    for (const SpawnConfig& config : spawns)
-    {
-        if ((double)rand() / RAND_MAX < config.chance)
-        {
-            int amount = config.min
-                       + (int)((config.max - config.min)
-                               * ((double)rand() / RAND_MAX));
-            if (amount > 0)
-            {
-                ItemStack* spawnedItems
-                    = Game::INSTANCE->zItemType(config.typeId)
-                          ->createItemStack(amount);
-                if (spawnedItems)
-                {
-                    Game::INSTANCE->spawnItem(
-                        location + Framework::Vec3<float>(0.5f, 0.5f, 0.5f),
-                        getDimensionId(),
-                        spawnedItems);
-                }
-            }
-        }
-    }
-    BasicBlock::onDestroy();
-}
-
-AdditionalItemSpawningBlockType::AdditionalItemSpawningBlockType()
-    : BasicBlockType(),
-      spawns()
-{}
-
-void AdditionalItemSpawningBlockType::createSuperBlock(
-    Block* zBlock, Item* zItem) const
-{
-    AdditionalItemSpawningBlock* block
-        = dynamic_cast<AdditionalItemSpawningBlock*>(zBlock);
-    if (block)
-    {
-        for (const SpawnConfig& config : spawns)
-        {
-            block->addSpawn(config);
-        }
-    }
-    BasicBlockType::createSuperBlock(zBlock, zItem);
-}
-
-bool AdditionalItemSpawningBlockType::initialize(Game* zGame)
-{
-    for (auto iterator = spawns.begin(); iterator; iterator++)
-    {
-        int itemTypeId
-            = Game::INSTANCE->getItemTypeId(iterator.val().itemTypeName);
-        if (itemTypeId < 0)
-        {
-            return false;
-        }
-        iterator.set({iterator.val().min,
-            iterator.val().max,
-            iterator.val().chance,
-            iterator.val().itemTypeName,
-            itemTypeId});
-    }
-    return BasicBlockType::initialize(zGame);
-}
-
-Block* AdditionalItemSpawningBlockType::createBlock(
-    Framework::Vec3<int> position, int dimensionId) const
-{
-    AdditionalItemSpawningBlock* block
-        = new AdditionalItemSpawningBlock(getId(), position, dimensionId);
-    return block;
-}
-
-void AdditionalItemSpawningBlockType::addSpawn(SpawnConfig config)
-{
-    spawns.add(config);
-}
-
-const Framework::Array<SpawnConfig>&
-AdditionalItemSpawningBlockType::getSpawns() const
-{
-    return spawns;
-}
-
-AdditionalItemSpawningBlockTypeFactory::AdditionalItemSpawningBlockTypeFactory()
-    : BasicBlockTypeFactory()
-{}
-
-BasicBlockType* AdditionalItemSpawningBlockTypeFactory::createValue(
-    Framework::JSON::JSONObject* zJson) const
-{
-    return new AdditionalItemSpawningBlockType();
-}
-
-BasicBlockType* AdditionalItemSpawningBlockTypeFactory::fromJson(
-    Framework::JSON::JSONObject* zJson) const
-{
-    AdditionalItemSpawningBlockType* result
-        = dynamic_cast<AdditionalItemSpawningBlockType*>(
-            BasicBlockTypeFactory::fromJson(zJson));
-    Framework::JSON::JSONArray* spawnsJson = zJson->zValue("spawns")->asArray();
-    for (int i = 0; i < spawnsJson->getLength(); i++)
-    {
-        Framework::JSON::JSONObject* spawnJson
-            = spawnsJson->zValue(i)->asObject();
-        result->addSpawn(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 result;
-}
-
-Framework::JSON::JSONObject*
-AdditionalItemSpawningBlockTypeFactory::toJsonObject(
-    BasicBlockType* zObject) const
-{
-    AdditionalItemSpawningBlockType* zType
-        = dynamic_cast<AdditionalItemSpawningBlockType*>(zObject);
-    Framework::JSON::JSONObject* result
-        = BasicBlockTypeFactory::toJsonObject(zObject);
-    Framework::JSON::JSONArray* spawns = new Framework::JSON::JSONArray();
-    for (const SpawnConfig& config : zType->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;
-}
-
-JSONObjectValidationBuilder*
-AdditionalItemSpawningBlockTypeFactory::addToValidator(
-    JSONObjectValidationBuilder* builder) const
-{
-    return BasicBlockTypeFactory::addToValidator(builder->withRequiredAttribute(
-        "spawns",
-        Framework::Validator::DataValidator::buildForArray()
-            ->addAcceptedObjectInArray()
-            ->withRequiredAttribute("itemType",
-                Game::INSTANCE->zTypeRegistry()->getValidator<Framework::Text>(
-                    ItemTypeNameFactory::TYPE_ID))
-            ->withRequiredNumber("chance")
-            ->finishNumber()
-            ->withRequiredNumber("min")
-            ->finishNumber()
-            ->withRequiredNumber("max")
-            ->finishNumber()
-            ->finishObject()
-            ->finishArray()));
-}
-
-const char* AdditionalItemSpawningBlockTypeFactory::getTypeToken() const
-{
-    return "additionalItemsBlockType";
-}
-
-const char* AdditionalItemSpawningBlockTypeFactory::getTypeName() const
-{
-    return typeid(AdditionalItemSpawningBlockType).name();
-}
+}

+ 0 - 55
FactoryCraft/BasicBlocks.h

@@ -24,15 +24,6 @@ public:
     friend BasicBlockType;
     friend BasicBlockType;
 };
 };
 
 
-struct SpawnConfig
-{
-    int min;
-    int max;
-    double chance;
-    Framework::Text itemTypeName;
-    int typeId;
-};
-
 class BasicBlockType : public BlockType
 class BasicBlockType : public BlockType
 {
 {
 private:
 private:
@@ -79,50 +70,4 @@ public:
     virtual JSONObjectValidationBuilder* addToValidator(
     virtual JSONObjectValidationBuilder* addToValidator(
         JSONObjectValidationBuilder* builder) const override;
         JSONObjectValidationBuilder* builder) const override;
     virtual const char* getTypeToken() const override;
     virtual const char* getTypeToken() const override;
-};
-
-class AdditionalItemSpawningBlock : public BasicBlock
-{
-private:
-    Framework::Array<SpawnConfig> spawns;
-
-public:
-    AdditionalItemSpawningBlock(
-        int typeId, Framework::Vec3<int> pos, int dimensionId);
-    void addSpawn(SpawnConfig config);
-    virtual void onDestroy() override;
-};
-
-class AdditionalItemSpawningBlockType : public BasicBlockType
-{
-private:
-    Framework::Array<SpawnConfig> spawns;
-
-public:
-    AdditionalItemSpawningBlockType();
-
-protected:
-    virtual void createSuperBlock(Block* zBlock, Item* zItem) const override;
-
-public:
-    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 BasicBlockTypeFactory
-{
-public:
-    AdditionalItemSpawningBlockTypeFactory();
-    BasicBlockType* createValue(
-        Framework::JSON::JSONObject* zJson) const override;
-    BasicBlockType* fromJson(Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJsonObject(
-        BasicBlockType* zObject) const override;
-    JSONObjectValidationBuilder* addToValidator(
-        JSONObjectValidationBuilder* builder) const override;
-    const char* getTypeToken() const override;
-    const char* getTypeName() const override;
 };
 };

+ 76 - 87
FactoryCraft/BasicTool.cpp

@@ -785,41 +785,39 @@ BlockReplaceItemSkillConfig* BlockReplaceItemSkillConfigFactory::fromJson(
         Game::INSTANCE->zTypeRegistry()->fromJson<BlockFilter>(
         Game::INSTANCE->zTypeRegistry()->fromJson<BlockFilter>(
             zJson->asObject()->zValue("targetFilter")));
             zJson->asObject()->zValue("targetFilter")));
     result->setCooldownTicks((int)zJson->asObject()
     result->setCooldownTicks((int)zJson->asObject()
-                                 ->zValue("cooldownTicks")
-                                 ->asNumber()
-                                 ->getNumber());
+            ->zValue("cooldownTicks")
+            ->asNumber()
+            ->getNumber());
     result->setReplacementBlockTypeId(
     result->setReplacementBlockTypeId(
         Game::INSTANCE->getBlockTypeId(zJson->asObject()
         Game::INSTANCE->getBlockTypeId(zJson->asObject()
-                                           ->zValue("replacementBlockType")
-                                           ->asString()
-                                           ->getString()));
+                ->zValue("replacementBlockType")
+                ->asString()
+                ->getString()));
     result->setCooldownTicks((int)zJson->asObject()
     result->setCooldownTicks((int)zJson->asObject()
-                                 ->zValue("cooldownTicks")
-                                 ->asNumber()
-                                 ->getNumber());
+            ->zValue("cooldownTicks")
+            ->asNumber()
+            ->getNumber());
     result->setStaminaCost((float)zJson->asObject()
     result->setStaminaCost((float)zJson->asObject()
-                               ->zValue("staminaCost")
-                               ->asNumber()
-                               ->getNumber());
+            ->zValue("staminaCost")
+            ->asNumber()
+            ->getNumber());
     result->setStaminaCostDevider((float)zJson->asObject()
     result->setStaminaCostDevider((float)zJson->asObject()
-                                      ->zValue("staminaCostDevider")
-                                      ->asNumber()
-                                      ->getNumber());
-    result->setAdditionalStaminaCostDeviderPerLevel(
-        (float)zJson->asObject()
+            ->zValue("staminaCostDevider")
+            ->asNumber()
+            ->getNumber());
+    result->setAdditionalStaminaCostDeviderPerLevel((float)zJson->asObject()
             ->zValue("additionalStaminaCostDeviderPerLevel")
             ->zValue("additionalStaminaCostDeviderPerLevel")
             ->asNumber()
             ->asNumber()
             ->getNumber());
             ->getNumber());
     result->setDurabilityCost((float)zJson->asObject()
     result->setDurabilityCost((float)zJson->asObject()
-                                  ->zValue("durabilityCost")
-                                  ->asNumber()
-                                  ->getNumber());
+            ->zValue("durabilityCost")
+            ->asNumber()
+            ->getNumber());
     result->setDurabilityCostDevider((float)zJson->asObject()
     result->setDurabilityCostDevider((float)zJson->asObject()
-                                         ->zValue("durabilityCostDevider")
-                                         ->asNumber()
-                                         ->getNumber());
-    result->setAdditionalDurabilityCostDeviderPerLevel(
-        (float)zJson->asObject()
+            ->zValue("durabilityCostDevider")
+            ->asNumber()
+            ->getNumber());
+    result->setAdditionalDurabilityCostDeviderPerLevel((float)zJson->asObject()
             ->zValue("additionalDurabilityCostDeviderPerLevel")
             ->zValue("additionalDurabilityCostDeviderPerLevel")
             ->asNumber()
             ->asNumber()
             ->getNumber());
             ->getNumber());
@@ -1068,7 +1066,7 @@ BlockReplaceItemSkill* BlockReplaceItemSkillFactory::fromJson(
         *zJson->zValue("configs")->asArray())
         *zJson->zValue("configs")->asArray())
     {
     {
         result->addConfig(Game::INSTANCE->zTypeRegistry()
         result->addConfig(Game::INSTANCE->zTypeRegistry()
-                              ->fromJson<BlockReplaceItemSkillConfig>(value));
+                ->fromJson<BlockReplaceItemSkillConfig>(value));
     }
     }
     return result;
     return result;
 }
 }
@@ -1085,8 +1083,7 @@ Framework::JSON::JSONObject* BlockReplaceItemSkillFactory::toJsonObject(
         new Framework::JSON::JSONNumber(
         new Framework::JSON::JSONNumber(
             zObject->zInvalidUseConfig()->getStaminaCostDevider()));
             zObject->zInvalidUseConfig()->getStaminaCostDevider()));
     result->addValue("invalidAdditionalStaminaCostDeviderPerLevel",
     result->addValue("invalidAdditionalStaminaCostDeviderPerLevel",
-        new Framework::JSON::JSONNumber(
-            zObject->zInvalidUseConfig()
+        new Framework::JSON::JSONNumber(zObject->zInvalidUseConfig()
                 ->getAdditionalStaminaCostDeviderPerLevel()));
                 ->getAdditionalStaminaCostDeviderPerLevel()));
     result->addValue("invalidDurabilityCost",
     result->addValue("invalidDurabilityCost",
         new Framework::JSON::JSONNumber(
         new Framework::JSON::JSONNumber(
@@ -1095,8 +1092,7 @@ Framework::JSON::JSONObject* BlockReplaceItemSkillFactory::toJsonObject(
         new Framework::JSON::JSONNumber(
         new Framework::JSON::JSONNumber(
             zObject->zInvalidUseConfig()->getDurabilityCostDevider()));
             zObject->zInvalidUseConfig()->getDurabilityCostDevider()));
     result->addValue("invalidAdditionalDurabilityCostDeviderPerLevel",
     result->addValue("invalidAdditionalDurabilityCostDeviderPerLevel",
-        new Framework::JSON::JSONNumber(
-            zObject->zInvalidUseConfig()
+        new Framework::JSON::JSONNumber(zObject->zInvalidUseConfig()
                 ->getAdditionalDurabilityCostDeviderPerLevel()));
                 ->getAdditionalDurabilityCostDeviderPerLevel()));
     result->addValue("invalidCooldownTicks",
     result->addValue("invalidCooldownTicks",
         new Framework::JSON::JSONNumber(
         new Framework::JSON::JSONNumber(
@@ -1143,8 +1139,7 @@ JSONObjectValidationBuilder* BlockReplaceItemSkillFactory::addToValidator(
             ->withDefault(20)
             ->withDefault(20)
             ->finishNumber()
             ->finishNumber()
             ->withRequiredArray("configs")
             ->withRequiredArray("configs")
-            ->addAcceptedTypeInArray(
-                Game::INSTANCE->zTypeRegistry()
+            ->addAcceptedTypeInArray(Game::INSTANCE->zTypeRegistry()
                     ->getValidator<BlockReplaceItemSkillConfig>())
                     ->getValidator<BlockReplaceItemSkillConfig>())
             ->finishArray());
             ->finishArray());
 }
 }
@@ -1413,81 +1408,77 @@ DamagingItemSkillConfig* DamagingItemSkillConfigFactory::fromJson(
     result->setDamage(
     result->setDamage(
         (float)zJson->asObject()->zValue("damage")->asNumber()->getNumber());
         (float)zJson->asObject()->zValue("damage")->asNumber()->getNumber());
     result->setDamagePerHeadHardness((float)zJson->asObject()
     result->setDamagePerHeadHardness((float)zJson->asObject()
-                                         ->zValue("damagePerHeadHardness")
-                                         ->asNumber()
-                                         ->getNumber());
+            ->zValue("damagePerHeadHardness")
+            ->asNumber()
+            ->getNumber());
     result->setBaseDamageMultiplier((float)zJson->asObject()
     result->setBaseDamageMultiplier((float)zJson->asObject()
-                                        ->zValue("baseDamageMultiplier")
-                                        ->asNumber()
-                                        ->getNumber());
-    result->setDamageMultiplierPerHeadHardness(
-        (float)zJson->asObject()
+            ->zValue("baseDamageMultiplier")
+            ->asNumber()
+            ->getNumber());
+    result->setDamageMultiplierPerHeadHardness((float)zJson->asObject()
             ->zValue("damageMultiplierPerHeadHardness")
             ->zValue("damageMultiplierPerHeadHardness")
             ->asNumber()
             ->asNumber()
             ->getNumber());
             ->getNumber());
     result->setDamagePerLevel((float)zJson->asObject()
     result->setDamagePerLevel((float)zJson->asObject()
-                                  ->zValue("damagePerLevel")
-                                  ->asNumber()
-                                  ->getNumber());
+            ->zValue("damagePerLevel")
+            ->asNumber()
+            ->getNumber());
     result->setDamageMultiplierPerLevel((float)zJson->asObject()
     result->setDamageMultiplierPerLevel((float)zJson->asObject()
-                                            ->zValue("damageMultiplierPerLevel")
-                                            ->asNumber()
-                                            ->getNumber());
+            ->zValue("damageMultiplierPerLevel")
+            ->asNumber()
+            ->getNumber());
     result->setDamageDevider((float)zJson->asObject()
     result->setDamageDevider((float)zJson->asObject()
-                                 ->zValue("damageDevider")
-                                 ->asNumber()
-                                 ->getNumber());
+            ->zValue("damageDevider")
+            ->asNumber()
+            ->getNumber());
     result->setDamageDeviderPerHardness((float)zJson->asObject()
     result->setDamageDeviderPerHardness((float)zJson->asObject()
-                                            ->zValue("damageDeviderPerHardness")
-                                            ->asNumber()
-                                            ->getNumber());
+            ->zValue("damageDeviderPerHardness")
+            ->asNumber()
+            ->getNumber());
     result->setStaminaCost((float)zJson->asObject()
     result->setStaminaCost((float)zJson->asObject()
-                               ->zValue("staminaCost")
-                               ->asNumber()
-                               ->getNumber());
+            ->zValue("staminaCost")
+            ->asNumber()
+            ->getNumber());
     result->setStaminaCostPerDamage((float)zJson->asObject()
     result->setStaminaCostPerDamage((float)zJson->asObject()
-                                        ->zValue("staminaCostPerDamage")
-                                        ->asNumber()
-                                        ->getNumber());
+            ->zValue("staminaCostPerDamage")
+            ->asNumber()
+            ->getNumber());
     result->setStaminaCostPerHardness((float)zJson->asObject()
     result->setStaminaCostPerHardness((float)zJson->asObject()
-                                          ->zValue("staminaCostPerHardness")
-                                          ->asNumber()
-                                          ->getNumber());
+            ->zValue("staminaCostPerHardness")
+            ->asNumber()
+            ->getNumber());
     result->setStaminaCostDevider((float)zJson->asObject()
     result->setStaminaCostDevider((float)zJson->asObject()
-                                      ->zValue("staminaCostDevider")
-                                      ->asNumber()
-                                      ->getNumber());
-    result->setStaminaCostDeviderPerLevel(
-        (float)zJson->asObject()
+            ->zValue("staminaCostDevider")
+            ->asNumber()
+            ->getNumber());
+    result->setStaminaCostDeviderPerLevel((float)zJson->asObject()
             ->zValue("staminaCostDeviderPerLevel")
             ->zValue("staminaCostDeviderPerLevel")
             ->asNumber()
             ->asNumber()
             ->getNumber());
             ->getNumber());
     result->setDurabilityCost((float)zJson->asObject()
     result->setDurabilityCost((float)zJson->asObject()
-                                  ->zValue("durabilityCost")
-                                  ->asNumber()
-                                  ->getNumber());
+            ->zValue("durabilityCost")
+            ->asNumber()
+            ->getNumber());
     result->setDurabilityCostPerDamage((float)zJson->asObject()
     result->setDurabilityCostPerDamage((float)zJson->asObject()
-                                           ->zValue("durabilityCostPerDamage")
-                                           ->asNumber()
-                                           ->getNumber());
-    result->setDurabilityCostPerHardness(
-        (float)zJson->asObject()
+            ->zValue("durabilityCostPerDamage")
+            ->asNumber()
+            ->getNumber());
+    result->setDurabilityCostPerHardness((float)zJson->asObject()
             ->zValue("durabilityCostPerHardness")
             ->zValue("durabilityCostPerHardness")
             ->asNumber()
             ->asNumber()
             ->getNumber());
             ->getNumber());
     result->setDurabilityCostDevider((float)zJson->asObject()
     result->setDurabilityCostDevider((float)zJson->asObject()
-                                         ->zValue("durabilityCostDevider")
-                                         ->asNumber()
-                                         ->getNumber());
-    result->setAdditionalDurabilityCostDeviderPerLevel(
-        (float)zJson->asObject()
+            ->zValue("durabilityCostDevider")
+            ->asNumber()
+            ->getNumber());
+    result->setAdditionalDurabilityCostDeviderPerLevel((float)zJson->asObject()
             ->zValue("additionalDurabilityCostDeviderPerLevel")
             ->zValue("additionalDurabilityCostDeviderPerLevel")
             ->asNumber()
             ->asNumber()
             ->getNumber());
             ->getNumber());
     result->setXpGainPerDamage((float)zJson->asObject()
     result->setXpGainPerDamage((float)zJson->asObject()
-                                   ->zValue("xpGainPerDamage")
-                                   ->asNumber()
-                                   ->getNumber());
+            ->zValue("xpGainPerDamage")
+            ->asNumber()
+            ->getNumber());
     return result;
     return result;
 }
 }
 
 
@@ -1708,7 +1699,7 @@ bool DamagingItemSkill::use(Entity* zActor, Item* zUsedItem, Block* zTarget)
     }
     }
     zActor->setStamina(zActor->getStamina() - staminaCost);
     zActor->setStamina(zActor->getStamina() - staminaCost);
     setXp(getXp() + usedConfig->getXpGainPerDamage() * damage);
     setXp(getXp() + usedConfig->getXpGainPerDamage() * damage);
-    zTarget->setHP(zTarget->getHP() - damage);
+    zTarget->setHP(zActor, zUsedItem, this, zTarget->getHP() - damage);
     return true;
     return true;
 }
 }
 
 
@@ -1831,8 +1822,7 @@ Framework::JSON::JSONObject* DamagingItemSkillFactory::toJsonObject(
         new Framework::JSON::JSONNumber(
         new Framework::JSON::JSONNumber(
             zObject->zInvalidUseConfig()->getDurabilityCostDevider()));
             zObject->zInvalidUseConfig()->getDurabilityCostDevider()));
     result->addValue("invalidDurabilityCostDeviderPerLevel",
     result->addValue("invalidDurabilityCostDeviderPerLevel",
-        new Framework::JSON::JSONNumber(
-            zObject->zInvalidUseConfig()
+        new Framework::JSON::JSONNumber(zObject->zInvalidUseConfig()
                 ->getAdditionalDurabilityCostDeviderPerLevel()));
                 ->getAdditionalDurabilityCostDeviderPerLevel()));
     Framework::JSON::JSONArray* configs = new Framework::JSON::JSONArray();
     Framework::JSON::JSONArray* configs = new Framework::JSON::JSONArray();
     for (DamagingItemSkillConfig* config : zObject->getConfigs())
     for (DamagingItemSkillConfig* config : zObject->getConfigs())
@@ -1881,8 +1871,7 @@ JSONObjectValidationBuilder* DamagingItemSkillFactory::addToValidator(
             ->withDefault(0.02)
             ->withDefault(0.02)
             ->finishNumber()
             ->finishNumber()
             ->withRequiredArray("configs")
             ->withRequiredArray("configs")
-            ->addAcceptedTypeInArray(
-                Game::INSTANCE->zTypeRegistry()
+            ->addAcceptedTypeInArray(Game::INSTANCE->zTypeRegistry()
                     ->getValidator<DamagingItemSkillConfig>())
                     ->getValidator<DamagingItemSkillConfig>())
             ->finishArray());
             ->finishArray());
 }
 }

+ 10 - 10
FactoryCraft/Block.cpp

@@ -36,7 +36,7 @@ Block::Block(
 
 
 Block::~Block() {}
 Block::~Block() {}
 
 
-void Block::onDestroy()
+void Block::onDestroy(Entity* zActor, Item* zUsedItem, ItemSkill* zUsedSkill)
 {
 {
     if (!deadAndRemoved)
     if (!deadAndRemoved)
     {
     {
@@ -56,17 +56,16 @@ void Block::onDestroy()
                 Game::INSTANCE->zDimension(dimensionId)->sendBlockInfo(pos);
                 Game::INSTANCE->zDimension(dimensionId)->sendBlockInfo(pos);
             }
             }
         }
         }
-        Item* blockItem = zBlockType()->getItemFromBlock(this);
-        if (blockItem)
+        if (zActor)
         {
         {
-            Game::INSTANCE->spawnItem(
-                location + Framework::Vec3<float>(0.5f, 0.5f, 0.5f),
-                dimensionId,
-                blockItem);
+            for (const DropConfig* config : zBlockType()->getDropConfigs())
+            {
+                config->onObjectDestroyed(zActor, zUsedItem, zUsedSkill, this);
+            }
         }
         }
         deadAndRemoved = 1;
         deadAndRemoved = 1;
         for (MultiblockStructure* structure : structures)
         for (MultiblockStructure* structure : structures)
-            structure->onBlockRemoved(this);
+            structure->onBlockRemoved(zActor, zUsedItem, zUsedSkill, this);
         Game::INSTANCE->zDimension(dimensionId)
         Game::INSTANCE->zDimension(dimensionId)
             ->placeBlock(
             ->placeBlock(
                 getPos(), BlockTypeEnum::AIR); // this will be deleted here
                 getPos(), BlockTypeEnum::AIR); // this will be deleted here
@@ -325,13 +324,14 @@ bool Block::isVisible() const
     return 0;
     return 0;
 }
 }
 
 
-void Block::setHP(float hp)
+void Block::setHP(
+    Entity* zActor, Item* zUsedItem, ItemSkill* zUsedSkill, float hp)
 {
 {
     bool isDead = this->hp == 0.f;
     bool isDead = this->hp == 0.f;
     this->hp = MAX(0.f, hp);
     this->hp = MAX(0.f, hp);
     if (!isDead && this->hp == 0.f)
     if (!isDead && this->hp == 0.f)
     {
     {
-        onDestroy(); // this will be deleted
+        onDestroy(zActor, zUsedItem, zUsedSkill); // this will be deleted
     }
     }
     else
     else
     {
     {

+ 4 - 2
FactoryCraft/Block.h

@@ -69,7 +69,8 @@ protected:
     /// the order of blocks called will be exactly the same as onTick
     /// the order of blocks called will be exactly the same as onTick
     /// </summary>
     /// </summary>
     virtual void onPostTick() = 0;
     virtual void onPostTick() = 0;
-    virtual void onDestroy();
+    virtual void onDestroy(
+        Entity* zActor, Item* zUsedItem, ItemSkill* zUsedSkill);
 
 
     virtual void onDialogClosed(Framework::Text dialogId);
     virtual void onDialogClosed(Framework::Text dialogId);
     void broadcastModelInfoChange();
     void broadcastModelInfoChange();
@@ -108,7 +109,8 @@ public:
     float getSpeedModifier() const;
     float getSpeedModifier() const;
     const Framework::Vec3<int> getPos() const;
     const Framework::Vec3<int> getPos() const;
     bool isVisible() const;
     bool isVisible() const;
-    void setHP(float hp);
+    void setHP(
+        Entity* zActor, Item* zUsedItem, ItemSkill* zUsedSkill, float hp);
     bool isDeadAndRemoved() const;
     bool isDeadAndRemoved() const;
     const unsigned char* getLightEmisionColor() const;
     const unsigned char* getLightEmisionColor() const;
     virtual void filterPassingLight(unsigned char rgb[3]) const;
     virtual void filterPassingLight(unsigned char rgb[3]) const;

+ 15 - 1
FactoryCraft/BlockType.cpp

@@ -2,10 +2,10 @@
 
 
 #include "BasicBlocks.h"
 #include "BasicBlocks.h"
 #include "Block.h"
 #include "Block.h"
+#include "Dimension.h"
 #include "Game.h"
 #include "Game.h"
 #include "ItemType.h"
 #include "ItemType.h"
 #include "MultiblockStructure.h"
 #include "MultiblockStructure.h"
-#include "Dimension.h"
 
 
 using namespace Framework;
 using namespace Framework;
 
 
@@ -111,6 +111,10 @@ void BlockType::createSuperItem(Block* zBlock, Item* zItem) const
 
 
 bool BlockType::initialize(Game* zGame)
 bool BlockType::initialize(Game* zGame)
 {
 {
+    for (DropConfig* config : dropConfigs)
+    {
+        config->initialize();
+    }
     return true;
     return true;
 }
 }
 
 
@@ -123,6 +127,16 @@ BlockType* BlockType::initializeDefault()
     return this;
     return this;
 }
 }
 
 
+void BlockType::addDropConfig(DropConfig* config)
+{
+    dropConfigs.add(config);
+}
+
+const Framework::RCArray<DropConfig>& BlockType::getDropConfigs() const
+{
+    return dropConfigs;
+}
+
 const Block* BlockType::zDefault() const
 const Block* BlockType::zDefault() const
 {
 {
     return defaultBlock;
     return defaultBlock;

+ 39 - 1
FactoryCraft/BlockType.h

@@ -5,6 +5,7 @@
 #include <Vec3.h>
 #include <Vec3.h>
 #include <Writer.h>
 #include <Writer.h>
 
 
+#include "DropConfig.h"
 #include "ModelInfo.h"
 #include "ModelInfo.h"
 
 
 class Item;
 class Item;
@@ -33,6 +34,7 @@ private:
     Block* defaultBlock;
     Block* defaultBlock;
     Framework::RCArray<Framework::Text> groupNames;
     Framework::RCArray<Framework::Text> groupNames;
     float hardness;
     float hardness;
+    Framework::RCArray<DropConfig> dropConfigs;
 
 
 protected:
 protected:
     BlockType();
     BlockType();
@@ -52,6 +54,8 @@ protected:
 public:
 public:
     virtual bool initialize(Game* zGame);
     virtual bool initialize(Game* zGame);
     BlockType* initializeDefault();
     BlockType* initializeDefault();
+    void addDropConfig(DropConfig* config);
+    const Framework::RCArray<DropConfig>& getDropConfigs() const;
     virtual const Block* zDefault() const;
     virtual const Block* zDefault() const;
 
 
     virtual ItemType* createItemType() const = 0;
     virtual ItemType* createItemType() const = 0;
@@ -130,6 +134,13 @@ public:
         zType->setGroupNames(groupNames);
         zType->setGroupNames(groupNames);
         zType->setHardness(
         zType->setHardness(
             (float)zJson->zValue("hardness")->asNumber()->getNumber());
             (float)zJson->zValue("hardness")->asNumber()->getNumber());
+        for (Framework::JSON::JSONValue* value :
+            *zJson->zValue("drops")->asArray())
+        {
+            zType->addDropConfig(
+                Game::INSTANCE->zTypeRegistry()->fromJson<DropConfig>(
+                    value->asObject()));
+        }
         return result;
         return result;
     }
     }
 
 
@@ -160,6 +171,13 @@ public:
             groupNames->addValue(new Framework::JSON::JSONString(*groupName));
             groupNames->addValue(new Framework::JSON::JSONString(*groupName));
         }
         }
         result->addValue("groupNames", groupNames);
         result->addValue("groupNames", groupNames);
+        Framework::JSON::JSONArray* drops = new Framework::JSON::JSONArray();
+        for (DropConfig* drop : zType->getDropConfigs())
+        {
+            drops->addValue(
+                Game::INSTANCE->zTypeRegistry()->toJson<DropConfig>(drop));
+        }
+        result->addValue("drops", drops);
         result->addValue(
         result->addValue(
             "hardness", new Framework::JSON::JSONNumber(zType->getHardness()));
             "hardness", new Framework::JSON::JSONNumber(zType->getHardness()));
         return result;
         return result;
@@ -168,6 +186,18 @@ public:
     virtual JSONObjectValidationBuilder* addToValidator(
     virtual JSONObjectValidationBuilder* addToValidator(
         JSONObjectValidationBuilder* builder) const override
         JSONObjectValidationBuilder* builder) const override
     {
     {
+        Framework::JSON::JSONArray* defaultDrops
+            = new Framework::JSON::JSONArray();
+        Framework::JSON::JSONObject* defaultBlockItemDrop
+            = new Framework::JSON::JSONObject();
+        defaultBlockItemDrop->addValue(
+            "type", new Framework::JSON::JSONString("blockItem"));
+        Framework::JSON::JSONObject* defaultDropCondition
+            = new Framework::JSON::JSONObject();
+        defaultDropCondition->addValue(
+            "type", new Framework::JSON::JSONString("allways"));
+        defaultBlockItemDrop->addValue("condition", defaultDropCondition);
+        defaultDrops->addValue(defaultBlockItemDrop);
         return builder
         return builder
             ->withRequiredAttribute("model",
             ->withRequiredAttribute("model",
                 Game::INSTANCE->zTypeRegistry()->getValidator<ModelInfo>())
                 Game::INSTANCE->zTypeRegistry()->getValidator<ModelInfo>())
@@ -194,7 +224,15 @@ public:
             ->finishArray()
             ->finishArray()
             ->withRequiredNumber("hardness")
             ->withRequiredNumber("hardness")
             ->withDefault(1.0)
             ->withDefault(1.0)
-            ->finishNumber();
+            ->finishNumber()
+            ->withRequiredAttribute("drops",
+                Framework::Validator::DataValidator::buildForArray()
+                    ->addAcceptedTypeInArray(Game::INSTANCE->zTypeRegistry()
+                            ->getValidator<DropConfig>())
+                    ->withDefault(defaultDrops)
+                    ->finishArray(),
+                false,
+                true);
     }
     }
 
 
 protected:
 protected:

+ 0 - 15
FactoryCraft/Chest.cpp

@@ -23,21 +23,6 @@ Chest::Chest(int typeId, Framework::Vec3<int> pos, int dimensionId)
     }
     }
 }
 }
 
 
-void Chest::onDestroy()
-{
-    for (ItemSlot* slot : *this)
-    {
-        if (!slot->isEmpty())
-        {
-            Game::INSTANCE->spawnItem(
-                location + Framework::Vec3<float>(0.5f, 0.5f, 0.5f),
-                getDimensionId(),
-                slot->takeItemsOut(slot->getNumberOfItems(), NO_DIRECTION));
-        }
-    }
-    BasicBlock::onDestroy();
-}
-
 void Chest::onDialogClosed(Framework::Text dialogId)
 void Chest::onDialogClosed(Framework::Text dialogId)
 {
 {
     if (dialogId.istGleich(getDialogId()))
     if (dialogId.istGleich(getDialogId()))

+ 0 - 1
FactoryCraft/Chest.h

@@ -8,7 +8,6 @@ private:
     bool open;
     bool open;
     int userEntityId;
     int userEntityId;
 
 
-    virtual void onDestroy() override;
     virtual void onDialogClosed(Framework::Text dialogId) override;
     virtual void onDialogClosed(Framework::Text dialogId) override;
     Framework::Text getDialogId() const;
     Framework::Text getDialogId() const;
 
 

+ 53 - 0
FactoryCraft/DefaultBlockItemDrop.cpp

@@ -0,0 +1,53 @@
+#include "DefaultBlockItemDrop.h"
+
+#include "Block.h"
+
+DefaultBlockItemDrop::DefaultBlockItemDrop()
+    : DropConfig()
+{}
+
+void DefaultBlockItemDrop::doDrop(Entity* zActor,
+    Item* zItem,
+    ItemSkill* zUsedSkill,
+    Framework::Either<Block*, Entity*> zDestroyedObject) const
+{
+    if (zDestroyedObject.isA())
+    {
+        Item* blockItem
+            = zDestroyedObject.getA()->zBlockType()->getItemFromBlock(
+                zDestroyedObject.getA());
+        if (blockItem)
+        {
+            Game::INSTANCE->spawnItem(
+                zDestroyedObject.getA()->getLocation()
+                    + Framework::Vec3<float>(0.5f, 0.5f, 0.5f),
+                zDestroyedObject.getA()->getDimensionId(),
+                blockItem);
+        }
+    }
+}
+
+DefaultBlockItemDropFactory::DefaultBlockItemDropFactory()
+    : DropConfigFactory()
+{}
+
+JSONObjectValidationBuilder* DefaultBlockItemDropFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return DropConfigFactory::addToValidator(builder);
+}
+
+const char* DefaultBlockItemDropFactory::getTypeToken() const
+{
+    return "blockItem";
+}
+
+DefaultBlockItemDrop* DefaultBlockItemDropFactory::createInstance(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new DefaultBlockItemDrop();
+}
+
+void DefaultBlockItemDropFactory::addToJson(
+    Framework::JSON::JSONObject* zJson, DefaultBlockItemDrop* zObject) const
+{}

+ 27 - 0
FactoryCraft/DefaultBlockItemDrop.h

@@ -0,0 +1,27 @@
+#pragma once
+
+#include "DropConfig.h"
+
+class DefaultBlockItemDrop : public DropConfig
+{
+public:
+    DefaultBlockItemDrop();
+    void doDrop(Entity* zActor,
+        Item* zItem,
+        ItemSkill* zUsedSkill,
+        Framework::Either<Block*, Entity*> zDestroyedObject) const override;
+};
+
+class DefaultBlockItemDropFactory
+    : public DropConfigFactory<DefaultBlockItemDrop>
+{
+public:
+    DefaultBlockItemDropFactory();
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
+    const char* getTypeToken() const override;
+    DefaultBlockItemDrop* createInstance(
+        Framework::JSON::JSONObject* zJson) const override;
+    void addToJson(Framework::JSON::JSONObject* zJson,
+        DefaultBlockItemDrop* zObject) const override;
+};

+ 67 - 0
FactoryCraft/DefaultInventoryDrop.cpp

@@ -0,0 +1,67 @@
+#include "DefaultInventoryDrop.h"
+
+#include <Block.h>
+#include <Entity.h>
+#include <Inventory.h>
+#include <ItemSlot.h>
+
+DefaultInventoryItemDrop::DefaultInventoryItemDrop()
+    : DropConfig()
+{}
+
+void DefaultInventoryItemDrop::doDrop(Entity* zActor,
+    Item* zItem,
+    ItemSkill* zUsedSkill,
+    Framework::Either<Block*, Entity*> zDestroyedObject) const
+{
+    Inventory* inventory;
+    if (zDestroyedObject.isA())
+    {
+        inventory = dynamic_cast<Inventory*>(zDestroyedObject.getA());
+    }
+    else
+    {
+        inventory = dynamic_cast<Inventory*>(zDestroyedObject.getB());
+    }
+    for (ItemSlot* slot : *inventory)
+    {
+        if (!slot->isEmpty())
+        {
+            ItemStack* stack
+                = slot->takeItemsOut(slot->getNumberOfItems(), NO_DIRECTION);
+            if (stack)
+            {
+                Game::INSTANCE->spawnItem(
+                    inventory->getLocation()
+                        + Framework::Vec3<float>(0.5f, 0.5f, 0.5f),
+                    inventory->getDimensionId(),
+                    stack);
+            }
+        }
+    }
+}
+
+DefaultInventoryItemDropFactory::DefaultInventoryItemDropFactory()
+    : DropConfigFactory()
+{}
+
+JSONObjectValidationBuilder* DefaultInventoryItemDropFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return DropConfigFactory::addToValidator(builder);
+}
+
+const char* DefaultInventoryItemDropFactory::getTypeToken() const
+{
+    return "inventoryContent";
+}
+
+DefaultInventoryItemDrop* DefaultInventoryItemDropFactory::createInstance(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new DefaultInventoryItemDrop();
+}
+
+void DefaultInventoryItemDropFactory::addToJson(
+    Framework::JSON::JSONObject* zJson, DefaultInventoryItemDrop* zObject) const
+{}

+ 27 - 0
FactoryCraft/DefaultInventoryDrop.h

@@ -0,0 +1,27 @@
+#pragma once
+
+#include "DropConfig.h"
+
+class DefaultInventoryItemDrop : public DropConfig
+{
+public:
+    DefaultInventoryItemDrop();
+    void doDrop(Entity* zActor,
+        Item* zItem,
+        ItemSkill* zUsedSkill,
+        Framework::Either<Block*, Entity*> zDestroyedObject) const override;
+};
+
+class DefaultInventoryItemDropFactory
+    : public DropConfigFactory<DefaultInventoryItemDrop>
+{
+public:
+    DefaultInventoryItemDropFactory();
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
+    const char* getTypeToken() const override;
+    DefaultInventoryItemDrop* createInstance(
+        Framework::JSON::JSONObject* zJson) const override;
+    void addToJson(Framework::JSON::JSONObject* zJson,
+        DefaultInventoryItemDrop* zObject) const override;
+};

+ 53 - 0
FactoryCraft/DropChanceCondition.cpp

@@ -0,0 +1,53 @@
+#include "DropChanceCondition.h"
+
+DropChanceCondition::DropChanceCondition(double chance)
+    : DropCondition(),
+      chance(chance)
+{}
+
+double DropChanceCondition::getChance() const
+{
+    return chance;
+}
+
+bool DropChanceCondition::evaluate(Entity* zActor,
+    Item* zItem,
+    ItemSkill* zUsedSkill,
+    Framework::Either<Block*, Entity*> zDestroyedObject)
+{
+    return (double)std::rand() / RAND_MAX > chance;
+}
+
+DropChanceConditionFactory::DropChanceConditionFactory()
+    : SubTypeFactory()
+{}
+
+JSONObjectValidationBuilder* DropChanceConditionFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return builder->withRequiredNumber("chance")
+        ->whichIsGreaterThen(0.0)
+        ->whichIsLessOrEqual(1.0)
+        ->finishNumber();
+}
+
+const char* DropChanceConditionFactory::getTypeToken() const
+{
+    return "chance";
+}
+
+DropChanceCondition* DropChanceConditionFactory::fromJson(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new DropChanceCondition(
+        zJson->zValue("chance")->asNumber()->getNumber());
+}
+
+Framework::JSON::JSONObject* DropChanceConditionFactory::toJsonObject(
+    DropChanceCondition* zObject) const
+{
+    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
+    result->addValue(
+        "chance", new Framework::JSON::JSONNumber(zObject->getChance()));
+    return result;
+}

+ 34 - 0
FactoryCraft/DropChanceCondition.h

@@ -0,0 +1,34 @@
+#pragma once
+
+#include "DropCondition.h"
+#include "TypeRegistry.h"
+
+class DropChanceCondition : public DropCondition
+{
+private:
+    double chance;
+
+public:
+    DropChanceCondition(double chance);
+    double getChance() const;
+    bool evaluate(Entity* zActor,
+        Item* zItem,
+        ItemSkill* zUsedSkill,
+        Framework::Either<Block*, Entity*> zDestroyedObject) override;
+};
+
+class DropChanceConditionFactory
+    : public SubTypeFactory<DropCondition, DropChanceCondition>
+{
+public:
+    DropChanceConditionFactory();
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
+    const char* getTypeToken() const override;
+
+protected:
+    DropChanceCondition* fromJson(
+        Framework::JSON::JSONObject* zJson) const override;
+    Framework::JSON::JSONObject* toJsonObject(
+        DropChanceCondition* zObject) const override;
+};

+ 18 - 0
FactoryCraft/DropCondition.h

@@ -0,0 +1,18 @@
+#pragma once
+
+#include <Either.h>
+
+class Entity;
+class Item;
+class ItemSkill;
+class Block;
+
+class DropCondition
+{
+public:
+    virtual bool evaluate(Entity* zActor,
+        Item* zItem,
+        ItemSkill* zUsedSkill,
+        Framework::Either<Block*, Entity*> zDestroyedObject)
+        = 0;
+};

+ 218 - 0
FactoryCraft/DropConditionOperator.cpp

@@ -0,0 +1,218 @@
+#include "DropConditionOperator.h"
+
+#include "Game.h"
+
+DropConditionOperator::DropConditionOperator(ConditionalOperator op)
+    : DropCondition(),
+      op(op)
+{}
+
+DropConditionOperator::~DropConditionOperator()
+{
+    for (DropCondition* condition : conditions)
+    {
+        delete condition;
+    }
+}
+
+ConditionalOperator DropConditionOperator::getOperator() const
+{
+    return op;
+}
+
+const Framework::Array<DropCondition*>&
+DropConditionOperator::getConditions() const
+{
+    return conditions;
+}
+
+void DropConditionOperator::addCondition(DropCondition* condition)
+{
+    conditions.add(condition);
+}
+
+bool DropConditionOperator::evaluate(Entity* zActor,
+    Item* zItem,
+    ItemSkill* zUsedSkill,
+    Framework::Either<Block*, Entity*> zDestroyedObject)
+{
+    switch (op)
+    {
+    case AND:
+        {
+            bool result = true;
+            for (DropCondition* condition : conditions)
+            {
+                result &= condition->evaluate(
+                    zActor, zItem, zUsedSkill, zDestroyedObject);
+            }
+            return result;
+        }
+    case OR:
+        {
+            bool result = false;
+            for (DropCondition* condition : conditions)
+            {
+                result |= condition->evaluate(
+                    zActor, zItem, zUsedSkill, zDestroyedObject);
+            }
+            return result;
+        }
+    }
+    return false;
+}
+
+DropConditionNegation::DropConditionNegation(DropCondition* condition)
+    : DropCondition(),
+      condition(condition)
+{}
+
+DropConditionNegation::~DropConditionNegation()
+{
+    delete condition;
+}
+
+const DropCondition* DropConditionNegation::zCondition() const
+{
+    return condition;
+}
+
+bool DropConditionNegation::evaluate(Entity* zActor,
+    Item* zItem,
+    ItemSkill* zUsedSkill,
+    Framework::Either<Block*, Entity*> zDestroyedObject)
+{
+    return !condition->evaluate(zActor, zItem, zUsedSkill, zDestroyedObject);
+}
+
+DropAllwaysCondition::DropAllwaysCondition()
+    : DropCondition()
+{}
+
+bool DropAllwaysCondition::evaluate(Entity* zActor,
+    Item* zItem,
+    ItemSkill* zUsedSkill,
+    Framework::Either<Block*, Entity*> zDestroyedObject)
+{
+    return true;
+}
+
+DropConditionOperatorFactory::DropConditionOperatorFactory()
+    : SubTypeFactory()
+{}
+
+JSONObjectValidationBuilder* DropConditionOperatorFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return builder->withRequiredString("operator")
+        ->whichIsOneOf({"AND", "OR"})
+        ->finishString()
+        ->withRequiredAttribute("conditions",
+            Framework::Validator::DataValidator::buildForArray()
+                ->addAcceptedTypeInArray(Game::INSTANCE->zTypeRegistry()
+                        ->getValidator<DropCondition>())
+                ->finishArray());
+}
+
+const char* DropConditionOperatorFactory::getTypeToken() const
+{
+    return "operator";
+}
+
+DropConditionOperator* DropConditionOperatorFactory::fromJson(
+    Framework::JSON::JSONObject* zJson) const
+{
+    DropConditionOperator* result = new DropConditionOperator(
+        zJson->zValue("operator")->asString()->getString().istGleich("AND")
+            ? AND
+            : OR);
+    for (Framework::JSON::JSONValue* value :
+        *zJson->zValue("conditions")->asArray())
+    {
+        result->addCondition(
+            Game::INSTANCE->zTypeRegistry()->fromJson<DropCondition>(value));
+    }
+    return result;
+}
+
+Framework::JSON::JSONObject* DropConditionOperatorFactory::toJsonObject(
+    DropConditionOperator* zObject) const
+{
+    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
+    switch (zObject->getOperator())
+    {
+    case AND:
+        result->addValue("operator", new Framework::JSON::JSONString("AND"));
+        break;
+    case OR:
+        result->addValue("operator", new Framework::JSON::JSONString("OR"));
+        break;
+    }
+    Framework::JSON::JSONArray* array = new Framework::JSON::JSONArray();
+    for (DropCondition* condition : zObject->getConditions())
+    {
+        array->addValue(Game::INSTANCE->zTypeRegistry()->toJson(condition));
+    }
+    result->addValue("conditions", array);
+    return nullptr;
+}
+
+DropConditionNegationFactory::DropConditionNegationFactory()
+    : SubTypeFactory()
+{}
+
+JSONObjectValidationBuilder* DropConditionNegationFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return builder->withRequiredAttribute("condition",
+        Game::INSTANCE->zTypeRegistry()->getValidator<DropCondition>());
+}
+
+const char* DropConditionNegationFactory::getTypeToken() const
+{
+    return "not";
+}
+
+DropConditionNegation* DropConditionNegationFactory::fromJson(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new DropConditionNegation(
+        Game::INSTANCE->zTypeRegistry()->fromJson<DropCondition>(
+            zJson->zValue("condition")));
+}
+
+Framework::JSON::JSONObject* DropConditionNegationFactory::toJsonObject(
+    DropConditionNegation* zObject) const
+{
+    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
+    result->addValue("condition",
+        Game::INSTANCE->zTypeRegistry()->toJson(zObject->zCondition()));
+    return result;
+}
+
+DropAllwaysConditionFactory::DropAllwaysConditionFactory()
+    : SubTypeFactory()
+{}
+
+JSONObjectValidationBuilder* DropAllwaysConditionFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return builder;
+}
+
+const char* DropAllwaysConditionFactory::getTypeToken() const
+{
+    return "allways";
+}
+
+DropAllwaysCondition* DropAllwaysConditionFactory::fromJson(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new DropAllwaysCondition();
+}
+
+Framework::JSON::JSONObject* DropAllwaysConditionFactory::toJsonObject(
+    DropAllwaysCondition* zObject) const
+{
+    return new Framework::JSON::JSONObject();
+}

+ 103 - 0
FactoryCraft/DropConditionOperator.h

@@ -0,0 +1,103 @@
+#pragma once
+
+#include <Array.h>
+
+#include "DropCondition.h"
+#include "TypeRegistry.h"
+
+enum ConditionalOperator
+{
+    AND,
+    OR
+};
+
+class DropConditionOperator : public DropCondition
+{
+private:
+    Framework::Array<DropCondition*> conditions;
+    ConditionalOperator op;
+
+public:
+    DropConditionOperator(ConditionalOperator op);
+    ~DropConditionOperator();
+    void addCondition(DropCondition* condition);
+    ConditionalOperator getOperator() const;
+    const Framework::Array<DropCondition*>& getConditions() const;
+    bool evaluate(Entity* zActor,
+        Item* zItem,
+        ItemSkill* zUsedSkill,
+        Framework::Either<Block*, Entity*> zDestroyedObject) override;
+};
+
+class DropConditionNegation : public DropCondition
+{
+private:
+    DropCondition* condition;
+
+public:
+    DropConditionNegation(DropCondition* condition);
+    ~DropConditionNegation();
+    const DropCondition* zCondition() const;
+    bool evaluate(Entity* zActor,
+        Item* zItem,
+        ItemSkill* zUsedSkill,
+        Framework::Either<Block*, Entity*> zDestroyedObject) override;
+};
+
+class DropAllwaysCondition : public DropCondition
+{
+public:
+    DropAllwaysCondition();
+    bool evaluate(Entity* zActor,
+        Item* zItem,
+        ItemSkill* zUsedSkill,
+        Framework::Either<Block*, Entity*> zDestroyedObject) override;
+};
+
+class DropConditionOperatorFactory
+    : public SubTypeFactory<DropCondition, DropConditionOperator>
+{
+public:
+    DropConditionOperatorFactory();
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
+    const char* getTypeToken() const override;
+
+protected:
+    DropConditionOperator* fromJson(
+        Framework::JSON::JSONObject* zJson) const override;
+    Framework::JSON::JSONObject* toJsonObject(
+        DropConditionOperator* zObject) const override;
+};
+
+class DropConditionNegationFactory
+    : public SubTypeFactory<DropCondition, DropConditionNegation>
+{
+public:
+    DropConditionNegationFactory();
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
+    const char* getTypeToken() const override;
+
+protected:
+    DropConditionNegation* fromJson(
+        Framework::JSON::JSONObject* zJson) const override;
+    Framework::JSON::JSONObject* toJsonObject(
+        DropConditionNegation* zObject) const override;
+};
+
+class DropAllwaysConditionFactory
+    : public SubTypeFactory<DropCondition, DropAllwaysCondition>
+{
+public:
+    DropAllwaysConditionFactory();
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
+    const char* getTypeToken() const override;
+
+protected:
+    DropAllwaysCondition* fromJson(
+        Framework::JSON::JSONObject* zJson) const override;
+    Framework::JSON::JSONObject* toJsonObject(
+        DropAllwaysCondition* zObject) const override;
+};

+ 38 - 0
FactoryCraft/DropConfig.cpp

@@ -0,0 +1,38 @@
+#include "DropConfig.h"
+
+DropConfig::DropConfig()
+    : ReferenceCounter(),
+      condition(0)
+{}
+
+DropConfig::~DropConfig()
+{
+    delete condition;
+}
+
+void DropConfig::setCondition(DropCondition* condition)
+{
+    if (this->condition)
+    {
+        delete this->condition;
+    }
+    this->condition = condition;
+}
+
+void DropConfig::initialize() {}
+
+const DropCondition* DropConfig::zCondition() const
+{
+    return condition;
+}
+
+void DropConfig::onObjectDestroyed(Entity* zActor,
+    Item* zItem,
+    ItemSkill* zUsedSkill,
+    Framework::Either<Block*, Entity*> zDestroyedObject) const
+{
+    if (condition->evaluate(zActor, zItem, zUsedSkill, zDestroyedObject))
+    {
+        doDrop(zActor, zItem, zUsedSkill, zDestroyedObject);
+    }
+}

+ 71 - 0
FactoryCraft/DropConfig.h

@@ -0,0 +1,71 @@
+#pragma once
+
+#include <ReferenceCounter.h>
+
+#include "DropCondition.h"
+#include "Game.h"
+#include "TypeRegistry.h"
+
+class DropConfig : public virtual Framework::ReferenceCounter
+{
+private:
+    DropCondition* condition;
+
+public:
+    DropConfig();
+    virtual ~DropConfig();
+    void setCondition(DropCondition* condition);
+    virtual void initialize();
+    const DropCondition* zCondition() const;
+    void onObjectDestroyed(Entity* zActor,
+        Item* zItem,
+        ItemSkill* zUsedSkill,
+        Framework::Either<Block*, Entity*> zDestroyedObject) const;
+
+protected:
+    virtual void doDrop(Entity* zActor,
+        Item* zItem,
+        ItemSkill* zUsedSkill,
+        Framework::Either<Block*, Entity*> zDestroyedObject) const
+        = 0;
+};
+
+template<typename T> class DropConfigFactory
+    : public SubTypeFactory<DropConfig, T>
+{
+public:
+    DropConfigFactory()
+        : SubTypeFactory<DropConfig, T>()
+    {}
+
+    virtual JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override
+    {
+        return builder->withRequiredAttribute("condition",
+            Game::INSTANCE->zTypeRegistry()->getValidator<DropCondition>());
+    }
+
+    T* fromJson(Framework::JSON::JSONObject* zJson) const
+    {
+        T* result = createInstance(zJson);
+        DropCondition* condition
+            = Game::INSTANCE->zTypeRegistry()->fromJson<DropCondition>(
+                zJson->zValue("condition"));
+        result->setCondition(condition);
+        return result;
+    }
+
+    Framework::JSON::JSONObject* toJsonObject(T* zObject) const override
+    {
+        Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
+        result->addValue("condition",
+            Game::INSTANCE->zTypeRegistry()->toJson(zObject->zCondition()));
+        addToJson(result, zObject);
+        return result;
+    }
+
+protected:
+    virtual T* createInstance(Framework::JSON::JSONObject* zObject) const = 0;
+    virtual void addToJson(Framework::JSON::JSONObject* zJson, T* zObject) const
+        = 0;
+};

+ 94 - 0
FactoryCraft/DropUsedItemCondition.cpp

@@ -0,0 +1,94 @@
+#include "DropUsedItemCondition.h"
+
+#include "Game.h"
+
+DropUsedItemCondition::DropUsedItemCondition(ItemFilter* filter)
+    : DropCondition(),
+      filter(filter)
+{}
+
+DropUsedItemCondition::~DropUsedItemCondition()
+{
+    filter->release();
+}
+
+const ItemFilter* DropUsedItemCondition::zFilter() const
+{
+    return filter;
+}
+
+bool DropUsedItemCondition::evaluate(Entity* zActor,
+    Item* zItem,
+    ItemSkill* zUsedSkill,
+    Framework::Either<Block*, Entity*> zDestroyedObject)
+{
+    return zItem && filter->matchItem(zItem);
+}
+
+bool DropNoUsedItemCondition::evaluate(Entity* zActor,
+    Item* zItem,
+    ItemSkill* zUsedSkill,
+    Framework::Either<Block*, Entity*> zDestroyedObject)
+{
+    return !zItem;
+}
+
+DropUsedItemConditionFactory::DropUsedItemConditionFactory()
+    : SubTypeFactory()
+{}
+
+JSONObjectValidationBuilder* DropUsedItemConditionFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return builder->withRequiredAttribute(
+        "filter", Game::INSTANCE->zTypeRegistry()->getValidator<ItemFilter>());
+}
+
+const char* DropUsedItemConditionFactory::getTypeToken() const
+{
+    return "itemFilter";
+}
+
+DropUsedItemCondition* DropUsedItemConditionFactory::fromJson(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new DropUsedItemCondition(
+        Game::INSTANCE->zTypeRegistry()->fromJson<ItemFilter>(
+            zJson->zValue("filter")));
+}
+
+Framework::JSON::JSONObject* DropUsedItemConditionFactory::toJsonObject(
+    DropUsedItemCondition* zObject) const
+{
+    Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
+    result->addValue(
+        "filter", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zFilter()));
+    return result;
+}
+
+DropNoUsedItemConditionFactory::DropNoUsedItemConditionFactory()
+    : SubTypeFactory()
+{}
+
+JSONObjectValidationBuilder* DropNoUsedItemConditionFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return builder;
+}
+
+const char* DropNoUsedItemConditionFactory::getTypeToken() const
+{
+    return "noItem";
+}
+
+DropNoUsedItemCondition* DropNoUsedItemConditionFactory::fromJson(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new DropNoUsedItemCondition();
+}
+
+Framework::JSON::JSONObject* DropNoUsedItemConditionFactory::toJsonObject(
+    DropNoUsedItemCondition* zObject) const
+{
+    return new Framework::JSON::JSONObject();
+}

+ 60 - 0
FactoryCraft/DropUsedItemCondition.h

@@ -0,0 +1,60 @@
+#pragma once
+
+#include "DropCondition.h"
+#include "ItemFilter.h"
+
+class DropUsedItemCondition : public DropCondition
+{
+private:
+    ItemFilter* filter;
+
+public:
+    DropUsedItemCondition(ItemFilter* filter);
+    ~DropUsedItemCondition();
+    const ItemFilter* zFilter() const;
+    virtual bool evaluate(Entity* zActor,
+        Item* zItem,
+        ItemSkill* zUsedSkill,
+        Framework::Either<Block*, Entity*> zDestroyedObject) override;
+};
+
+class DropNoUsedItemCondition : public DropCondition
+{
+public:
+    virtual bool evaluate(Entity* zActor,
+        Item* zItem,
+        ItemSkill* zUsedSkill,
+        Framework::Either<Block*, Entity*> zDestroyedObject) override;
+};
+
+class DropUsedItemConditionFactory
+    : public SubTypeFactory<DropCondition, DropUsedItemCondition>
+{
+public:
+    DropUsedItemConditionFactory();
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
+    const char* getTypeToken() const override;
+
+protected:
+    DropUsedItemCondition* fromJson(
+        Framework::JSON::JSONObject* zJson) const override;
+    Framework::JSON::JSONObject* toJsonObject(
+        DropUsedItemCondition* zObject) const override;
+};
+
+class DropNoUsedItemConditionFactory
+    : public SubTypeFactory<DropCondition, DropNoUsedItemCondition>
+{
+public:
+    DropNoUsedItemConditionFactory();
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
+    const char* getTypeToken() const override;
+
+protected:
+    DropNoUsedItemCondition* fromJson(
+        Framework::JSON::JSONObject* zJson) const override;
+    Framework::JSON::JSONObject* toJsonObject(
+        DropNoUsedItemCondition* zObject) const override;
+};

+ 10 - 4
FactoryCraft/Entity.cpp

@@ -4,6 +4,7 @@
 
 
 #include "BlockType.h"
 #include "BlockType.h"
 #include "Dimension.h"
 #include "Dimension.h"
+#include "EntityType.h"
 #include "Game.h"
 #include "Game.h"
 #include "ItemSkill.h"
 #include "ItemSkill.h"
 #include "ItemStack.h"
 #include "ItemStack.h"
@@ -230,10 +231,14 @@ Entity::Entity(
       placeBlockCooldown(0)
       placeBlockCooldown(0)
 {}
 {}
 
 
-void Entity::onDeath()
+void Entity::onDeath(Entity* zActor, Item* zUsedItem, ItemSkill* zUsedSkill)
 {
 {
     if (!removed)
     if (!removed)
     {
     {
+        for (DropConfig* config : zType()->getDropConfigs())
+        {
+            config->onObjectDestroyed(zActor, zUsedItem, zUsedSkill, this);
+        }
         Dimension* dim = Game::INSTANCE->zDimension(dimensionId);
         Dimension* dim = Game::INSTANCE->zDimension(dimensionId);
         if (dim)
         if (dim)
         {
         {
@@ -751,7 +756,7 @@ void Entity::onFall(float collisionSpeed)
 {
 {
     if (collisionSpeed > 10)
     if (collisionSpeed > 10)
     {
     {
-        setHP(getCurrentHP() - (collisionSpeed - 10.f) / 2.5f);
+        setHP(this, 0, 0, getCurrentHP() - (collisionSpeed - 10.f) / 2.5f);
     }
     }
 }
 }
 
 
@@ -770,7 +775,8 @@ void Entity::takeDamage(Entity* zSource, float damage)
     // TODO: implement this
     // TODO: implement this
 }
 }
 
 
-void Entity::setHP(float hp)
+void Entity::setHP(
+    Entity* zActor, Item* zUsedItem, ItemSkill* zUsedSkill, float hp)
 {
 {
     currentHP = MIN(MAX(hp, 0), maxHP);
     currentHP = MIN(MAX(hp, 0), maxHP);
     NetworkMessage* msg = new NetworkMessage();
     NetworkMessage* msg = new NetworkMessage();
@@ -782,7 +788,7 @@ void Entity::setHP(float hp)
     notifyStatusBarObservers(msg);
     notifyStatusBarObservers(msg);
     if (currentHP == 0)
     if (currentHP == 0)
     {
     {
-        onDeath();
+        onDeath(zActor, zUsedItem, zUsedSkill);
     }
     }
 }
 }
 
 

+ 4 - 2
FactoryCraft/Entity.h

@@ -84,7 +84,8 @@ protected:
     Framework::Array<Framework::ImmutablePair<int, Framework::Text>>
     Framework::Array<Framework::ImmutablePair<int, Framework::Text>>
         statusBarObservers;
         statusBarObservers;
 
 
-    virtual void onDeath();
+    virtual void onDeath(
+        Entity* zActor, Item* zUsedItem, ItemSkill* zUsedSkill);
     virtual bool useItem(int typeId, ItemStack* zStack, bool left);
     virtual bool useItem(int typeId, ItemStack* zStack, bool left);
     Entity(int typeId,
     Entity(int typeId,
         Framework::Vec3<float> location,
         Framework::Vec3<float> location,
@@ -113,7 +114,8 @@ public:
     void setChatSecurityLevel(int level);
     void setChatSecurityLevel(int level);
     void setPosition(Framework::Vec3<float> pos);
     void setPosition(Framework::Vec3<float> pos);
     virtual void takeDamage(Entity* zSource, float damage);
     virtual void takeDamage(Entity* zSource, float damage);
-    void setHP(float hp);
+    void setHP(
+        Entity* zActor, Item* zUsedItem, ItemSkill* zUsedSkill, float hp);
     void setStamina(float stamina);
     void setStamina(float stamina);
     void setHunger(float hunger);
     void setHunger(float hunger);
     void setThirst(float thirst);
     void setThirst(float thirst);

+ 28 - 3
FactoryCraft/EntityType.cpp

@@ -4,10 +4,10 @@
 #include "Game.h"
 #include "Game.h"
 #include "ItemType.h"
 #include "ItemType.h"
 
 
-EntityType::EntityType(Framework::Text name, ModelInfo* model)
+EntityType::EntityType()
     : ReferenceCounter(),
     : ReferenceCounter(),
-      name(name),
-      model(model),
+      name(""),
+      model(0),
       id(-1)
       id(-1)
 {}
 {}
 
 
@@ -99,9 +99,34 @@ void EntityType::createSuperEntity(Entity* zEntity) const {}
 
 
 bool EntityType::initialize(Game* zGame)
 bool EntityType::initialize(Game* zGame)
 {
 {
+    for (DropConfig* config : dropConfigs)
+    {
+        config->initialize();
+    }
     return true;
     return true;
 }
 }
 
 
+void EntityType::addDropConfig(DropConfig* config)
+{
+    dropConfigs.add(config);
+}
+
+void EntityType::setName(Framework::Text name)
+{
+    this->name = name;
+}
+
+void EntityType::setModel(ModelInfo* model)
+{
+    if (this->model) this->model->release();
+    this->model = model;
+}
+
+const Framework::RCArray<DropConfig>& EntityType::getDropConfigs() const
+{
+    return dropConfigs;
+}
+
 Entity* EntityType::loadEntity(Framework::StreamReader* zReader) const
 Entity* EntityType::loadEntity(Framework::StreamReader* zReader) const
 {
 {
     Entity* entity = createEntity(Framework::Vec3<float>(0, 0, 0), 0, 0);
     Entity* entity = createEntity(Framework::Vec3<float>(0, 0, 0), 0, 0);

+ 79 - 7
FactoryCraft/EntityType.h

@@ -5,6 +5,7 @@
 #include <Vec3.h>
 #include <Vec3.h>
 #include <Writer.h>
 #include <Writer.h>
 
 
+#include "DropConfig.h"
 #include "ModelInfo.h"
 #include "ModelInfo.h"
 
 
 class Entity;
 class Entity;
@@ -22,10 +23,11 @@ class EntityType : public virtual Framework::ReferenceCounter
 private:
 private:
     Framework::Text name;
     Framework::Text name;
     int id;
     int id;
-    ModelInfo *model;
+    ModelInfo* model;
+    Framework::RCArray<DropConfig> dropConfigs;
 
 
 protected:
 protected:
-    EntityType(Framework::Text name, ModelInfo* model);
+    EntityType();
     ~EntityType();
     ~EntityType();
 
 
     virtual void loadSuperEntity(
     virtual void loadSuperEntity(
@@ -35,18 +37,88 @@ protected:
     virtual void createSuperEntity(Entity* zEntity) const;
     virtual void createSuperEntity(Entity* zEntity) const;
 
 
 public:
 public:
-    virtual bool initialize(Game *zGame);
+    virtual bool initialize(Game* zGame);
+    void addDropConfig(DropConfig* config);
+    void setName(Framework::Text name);
+    void setModel(ModelInfo* model);
+    const Framework::RCArray<DropConfig>& getDropConfigs() const;
     virtual Entity* loadEntity(Framework::StreamReader* zReader) const;
     virtual Entity* loadEntity(Framework::StreamReader* zReader) const;
     virtual void saveEntity(
     virtual void saveEntity(
         Entity* zEntity, Framework::StreamWriter* zWriter) const;
         Entity* zEntity, Framework::StreamWriter* zWriter) const;
     virtual Entity* createEntityAt(
     virtual Entity* createEntityAt(
         Framework::Vec3<float> position, int dimensionId) const;
         Framework::Vec3<float> position, int dimensionId) const;
-    virtual Entity* createEntity(Framework::Vec3<float> position,
-        int dimensionId,
-        int entityId) const = 0;
+    virtual Entity* createEntity(
+        Framework::Vec3<float> position, int dimensionId, int entityId) const
+        = 0;
 
 
     int getId() const;
     int getId() const;
     ModelInfo* zModel() const;
     ModelInfo* zModel() const;
     void setTypeId(int id);
     void setTypeId(int id);
     Framework::Text getName() const;
     Framework::Text getName() const;
-};
+};
+
+template<typename S> class EntityTypeFactoryBase
+    : public SubTypeFactory<EntityType, S>
+{
+public:
+    EntityTypeFactoryBase()
+        : SubTypeFactory<EntityType, S>()
+    {}
+
+    virtual S* fromJson(Framework::JSON::JSONObject* zJson) const override
+    {
+        S* result = createValue(zJson);
+        EntityType* zType = dynamic_cast<EntityType*>(result);
+        zType->setModel(Game::INSTANCE->zTypeRegistry()->fromJson<ModelInfo>(
+            zJson->zValue("model")->asObject()));
+        zType->setName(zJson->zValue("typeName")->asString()->getString());
+        for (Framework::JSON::JSONValue* value :
+            *zJson->zValue("drops")->asArray())
+        {
+            zType->addDropConfig(
+                Game::INSTANCE->zTypeRegistry()->fromJson<DropConfig>(
+                    value->asObject()));
+        }
+        return result;
+    }
+
+    virtual Framework::JSON::JSONObject* toJsonObject(S* zObject) const override
+    {
+        Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
+        EntityType* zType = dynamic_cast<EntityType*>(zObject);
+        result->addValue("model",
+            Game::INSTANCE->zTypeRegistry()->toJson<ModelInfo>(
+                zType->zModel()));
+        result->addValue(
+            "typeName", new Framework::JSON::JSONString(zType->getName()));
+        Framework::JSON::JSONArray* drops = new Framework::JSON::JSONArray();
+        for (DropConfig* drop : zType->getDropConfigs())
+        {
+            drops->addValue(
+                Game::INSTANCE->zTypeRegistry()->toJson<DropConfig>(drop));
+        }
+        result->addValue("drops", drops);
+        addToJson(result, zObject);
+        return result;
+    }
+
+    virtual JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override
+    {
+        return builder
+            ->withRequiredAttribute("model",
+                Game::INSTANCE->zTypeRegistry()->getValidator<ModelInfo>())
+            ->withRequiredString("typeName")
+            ->finishString()
+            ->withRequiredAttribute("drops",
+                Framework::Validator::DataValidator::buildForArray()
+                    ->addAcceptedTypeInArray(Game::INSTANCE->zTypeRegistry()
+                            ->getValidator<DropConfig>())
+                    ->finishArray());
+    }
+
+protected:
+    virtual S* createValue(Framework::JSON::JSONObject* zJson) const = 0;
+    virtual void addToJson(Framework::JSON::JSONObject* zJson, S* zObject) const
+        = 0;
+};

+ 15 - 0
FactoryCraft/FactoryCraft.vcxproj

@@ -103,6 +103,13 @@
     <ClInclude Include="BlockInfoCommand.h" />
     <ClInclude Include="BlockInfoCommand.h" />
     <ClInclude Include="BlockInstanceGeneratorRule.h" />
     <ClInclude Include="BlockInstanceGeneratorRule.h" />
     <ClInclude Include="BlockTypeNameFactory.h" />
     <ClInclude Include="BlockTypeNameFactory.h" />
+    <ClInclude Include="DefaultBlockItemDrop.h" />
+    <ClInclude Include="DefaultInventoryDrop.h" />
+    <ClInclude Include="DropChanceCondition.h" />
+    <ClInclude Include="DropCondition.h" />
+    <ClInclude Include="DropConditionOperator.h" />
+    <ClInclude Include="DropConfig.h" />
+    <ClInclude Include="DropUsedItemCondition.h" />
     <ClInclude Include="EntityGenerator.h" />
     <ClInclude Include="EntityGenerator.h" />
     <ClInclude Include="FactorizeNoise.h" />
     <ClInclude Include="FactorizeNoise.h" />
     <ClInclude Include="FlattenNoise.h" />
     <ClInclude Include="FlattenNoise.h" />
@@ -228,10 +235,16 @@
     <ClCompile Include="Chunk.cpp" />
     <ClCompile Include="Chunk.cpp" />
     <ClCompile Include="ChunkMap.cpp" />
     <ClCompile Include="ChunkMap.cpp" />
     <ClCompile Include="CraftingStorage.cpp" />
     <ClCompile Include="CraftingStorage.cpp" />
+    <ClCompile Include="DefaultBlockItemDrop.cpp" />
+    <ClCompile Include="DefaultInventoryDrop.cpp" />
     <ClCompile Include="Dimension.cpp" />
     <ClCompile Include="Dimension.cpp" />
     <ClCompile Include="DimensionGenerator.cpp" />
     <ClCompile Include="DimensionGenerator.cpp" />
     <ClCompile Include="DimensionMap.cpp" />
     <ClCompile Include="DimensionMap.cpp" />
     <ClCompile Include="DoLaterHandler.cpp" />
     <ClCompile Include="DoLaterHandler.cpp" />
+    <ClCompile Include="DropChanceCondition.cpp" />
+    <ClCompile Include="DropConditionOperator.cpp" />
+    <ClCompile Include="DropConfig.cpp" />
+    <ClCompile Include="DropUsedItemCondition.cpp" />
     <ClCompile Include="Entity.cpp" />
     <ClCompile Include="Entity.cpp" />
     <ClCompile Include="EntityGenerator.cpp" />
     <ClCompile Include="EntityGenerator.cpp" />
     <ClCompile Include="EntityType.cpp" />
     <ClCompile Include="EntityType.cpp" />
@@ -289,6 +302,8 @@
     <ClCompile Include="ScaleNoise.cpp" />
     <ClCompile Include="ScaleNoise.cpp" />
     <ClCompile Include="Server.cpp" />
     <ClCompile Include="Server.cpp" />
     <ClCompile Include="ShapedNoise.cpp" />
     <ClCompile Include="ShapedNoise.cpp" />
+    <ClCompile Include="SpecificItemDrop.cpp" />
+    <ClCompile Include="SpecificItemDrop.h" />
     <ClCompile Include="Start.cpp" />
     <ClCompile Include="Start.cpp" />
     <ClCompile Include="StructureCollection.cpp" />
     <ClCompile Include="StructureCollection.cpp" />
     <ClCompile Include="TickOrganizer.cpp" />
     <ClCompile Include="TickOrganizer.cpp" />

+ 54 - 0
FactoryCraft/FactoryCraft.vcxproj.filters

@@ -106,6 +106,15 @@
     <Filter Include="world\generator\biom\entityGenerator">
     <Filter Include="world\generator\biom\entityGenerator">
       <UniqueIdentifier>{1c0b5b43-9fe2-496d-bcfc-b51005126d2a}</UniqueIdentifier>
       <UniqueIdentifier>{1c0b5b43-9fe2-496d-bcfc-b51005126d2a}</UniqueIdentifier>
     </Filter>
     </Filter>
+    <Filter Include="drops">
+      <UniqueIdentifier>{d5d3529a-6b9a-46b4-bb24-beb9ce304151}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="drops\conditions">
+      <UniqueIdentifier>{c8428697-9bc8-457c-8420-5bbb89f629f4}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="drops\implementations">
+      <UniqueIdentifier>{591cb52f-39d0-4c28-a756-069e7b868f1c}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClInclude Include="Chunk.h">
     <ClInclude Include="Chunk.h">
@@ -423,6 +432,27 @@
     <ClInclude Include="ItemTypeNameFactory.h">
     <ClInclude Include="ItemTypeNameFactory.h">
       <Filter>server\config</Filter>
       <Filter>server\config</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="DropCondition.h">
+      <Filter>drops</Filter>
+    </ClInclude>
+    <ClInclude Include="DropConfig.h">
+      <Filter>drops</Filter>
+    </ClInclude>
+    <ClInclude Include="DropUsedItemCondition.h">
+      <Filter>drops\conditions</Filter>
+    </ClInclude>
+    <ClInclude Include="DefaultBlockItemDrop.h">
+      <Filter>drops\implementations</Filter>
+    </ClInclude>
+    <ClInclude Include="DefaultInventoryDrop.h">
+      <Filter>drops\implementations</Filter>
+    </ClInclude>
+    <ClInclude Include="DropChanceCondition.h">
+      <Filter>drops\conditions</Filter>
+    </ClInclude>
+    <ClInclude Include="DropConditionOperator.h">
+      <Filter>drops\conditions</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="Server.cpp">
     <ClCompile Include="Server.cpp">
@@ -725,5 +755,29 @@
     <ClCompile Include="ItemTypeNameFactory.cpp">
     <ClCompile Include="ItemTypeNameFactory.cpp">
       <Filter>server\config</Filter>
       <Filter>server\config</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="SpecificItemDrop.h">
+      <Filter>drops\implementations</Filter>
+    </ClCompile>
+    <ClCompile Include="DropChanceCondition.cpp">
+      <Filter>drops\conditions</Filter>
+    </ClCompile>
+    <ClCompile Include="DropConditionOperator.cpp">
+      <Filter>drops\conditions</Filter>
+    </ClCompile>
+    <ClCompile Include="DropUsedItemCondition.cpp">
+      <Filter>drops\conditions</Filter>
+    </ClCompile>
+    <ClCompile Include="DropConfig.cpp">
+      <Filter>drops</Filter>
+    </ClCompile>
+    <ClCompile Include="DefaultBlockItemDrop.cpp">
+      <Filter>drops\implementations</Filter>
+    </ClCompile>
+    <ClCompile Include="DefaultInventoryDrop.cpp">
+      <Filter>drops\implementations</Filter>
+    </ClCompile>
+    <ClCompile Include="SpecificItemDrop.cpp">
+      <Filter>drops\implementations</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
 </Project>
 </Project>

+ 1 - 1
FactoryCraft/FluidBlock.cpp

@@ -166,7 +166,7 @@ void FluidBlock::doFlow()
     if (distanceToSource > maxFlowDistance)
     if (distanceToSource > maxFlowDistance)
     {
     {
         distanceToSource = maxFlowDistance;
         distanceToSource = maxFlowDistance;
-        Game::INSTANCE->doLater([this]() { setHP(0.f); });
+        Game::INSTANCE->doLater([this]() { setHP(0, 0, 0, 0.f); });
     }
     }
     if (changed)
     if (changed)
     {
     {

+ 15 - 18
FactoryCraft/FluidContainer.cpp

@@ -243,22 +243,21 @@ FluidContainerItemSkillConfig* FluidContainerItemSkillConfigFactory::fromJson(
         Game::INSTANCE->zTypeRegistry()->fromJson<BlockFilter>(
         Game::INSTANCE->zTypeRegistry()->fromJson<BlockFilter>(
             zJson->asObject()->zValue("targetFilter")));
             zJson->asObject()->zValue("targetFilter")));
     result->setStaminaCost((float)zJson->asObject()
     result->setStaminaCost((float)zJson->asObject()
-                               ->zValue("staminaCost")
-                               ->asNumber()
-                               ->getNumber());
+            ->zValue("staminaCost")
+            ->asNumber()
+            ->getNumber());
     result->setStaminaCostDevider((float)zJson->asObject()
     result->setStaminaCostDevider((float)zJson->asObject()
-                                      ->zValue("staminaCostDevider")
-                                      ->asNumber()
-                                      ->getNumber());
-    result->setStaminaCostDeviderPerLevel(
-        (float)zJson->asObject()
+            ->zValue("staminaCostDevider")
+            ->asNumber()
+            ->getNumber());
+    result->setStaminaCostDeviderPerLevel((float)zJson->asObject()
             ->zValue("staminaCostDeviderPerLevel")
             ->zValue("staminaCostDeviderPerLevel")
             ->asNumber()
             ->asNumber()
             ->getNumber());
             ->getNumber());
     result->setCooldownTicks((int)zJson->asObject()
     result->setCooldownTicks((int)zJson->asObject()
-                                 ->zValue("cooldownTicks")
-                                 ->asNumber()
-                                 ->getNumber());
+            ->zValue("cooldownTicks")
+            ->asNumber()
+            ->getNumber());
     result->setXpGain(
     result->setXpGain(
         (float)zJson->asObject()->zValue("xpGain")->asNumber()->getNumber());
         (float)zJson->asObject()->zValue("xpGain")->asNumber()->getNumber());
     return result;
     return result;
@@ -403,7 +402,7 @@ bool FluidContainerItemSkill::use(
     {
     {
         usedItem->setFluidTypeId(fluidBlock->zBlockType()->getId());
         usedItem->setFluidTypeId(fluidBlock->zBlockType()->getId());
         usedItem->setAmount(usedItem->getAmount() + 1000);
         usedItem->setAmount(usedItem->getAmount() + 1000);
-        zTarget->setHP(0);
+        zTarget->setHP(zActor, zUsedItem, this, 0);
     }
     }
     this->cooldownTicks = usedConfig->getCooldownTicks();
     this->cooldownTicks = usedConfig->getCooldownTicks();
     setXp(getXp() + usedConfig->getXpGain());
     setXp(getXp() + usedConfig->getXpGain());
@@ -459,8 +458,8 @@ FluidContainerItemSkill* FluidContainerItemSkillFactory::fromJson(
         *zJson->zValue("configs")->asArray())
         *zJson->zValue("configs")->asArray())
     {
     {
         result->addConfig(Game::INSTANCE->zTypeRegistry()
         result->addConfig(Game::INSTANCE->zTypeRegistry()
-                              ->fromJson<FluidContainerItemSkillConfig>(
-                                  configValue->asObject()));
+                ->fromJson<FluidContainerItemSkillConfig>(
+                    configValue->asObject()));
     }
     }
     FluidContainerItemSkillConfig* invalidConfig
     FluidContainerItemSkillConfig* invalidConfig
         = new FluidContainerItemSkillConfig();
         = new FluidContainerItemSkillConfig();
@@ -527,8 +526,7 @@ JSONObjectValidationBuilder* FluidContainerItemSkillFactory::addToValidator(
         ->withDefault(10)
         ->withDefault(10)
         ->finishNumber()
         ->finishNumber()
         ->withRequiredArray("configs")
         ->withRequiredArray("configs")
-        ->addAcceptedTypeInArray(
-            Game::INSTANCE->zTypeRegistry()
+        ->addAcceptedTypeInArray(Game::INSTANCE->zTypeRegistry()
                 ->getValidator<FluidContainerItemSkillConfig>())
                 ->getValidator<FluidContainerItemSkillConfig>())
         ->finishArray();
         ->finishArray();
 }
 }
@@ -752,8 +750,7 @@ Framework::JSON::JSONObject* FluidContainerItemTypeFactory::toJsonObject(
 JSONObjectValidationBuilder* FluidContainerItemTypeFactory::addToValidator(
 JSONObjectValidationBuilder* FluidContainerItemTypeFactory::addToValidator(
     JSONObjectValidationBuilder* builder) const
     JSONObjectValidationBuilder* builder) const
 {
 {
-    return ItemTypeFactoryBase::addToValidator(
-        builder
+    return ItemTypeFactoryBase::addToValidator(builder
             ->withRequiredAttribute("levelUpRule",
             ->withRequiredAttribute("levelUpRule",
                 Game::INSTANCE->zTypeRegistry()
                 Game::INSTANCE->zTypeRegistry()
                     ->getValidator<ItemSkillLevelUpRule>())
                     ->getValidator<ItemSkillLevelUpRule>())

+ 2 - 1
FactoryCraft/GeneratorRule.h

@@ -89,7 +89,8 @@ public:
         JSONObjectValidationBuilder* builder) const override
         JSONObjectValidationBuilder* builder) const override
     {
     {
         return builder
         return builder
-            ->withRequiredAttribute("noise", JNoise::getValidator(true))
+            ->withRequiredAttribute(
+                "noise", JNoise::getValidator(true), false, true)
             ->withRequiredAttribute("condition",
             ->withRequiredAttribute("condition",
                 Game::INSTANCE->zTypeRegistry()
                 Game::INSTANCE->zTypeRegistry()
                     ->getValidator<JBoolExpression>())
                     ->getValidator<JBoolExpression>())

+ 3 - 1
FactoryCraft/GeneratorTemplate.h

@@ -62,7 +62,9 @@ public:
     JSONObjectValidationBuilder* addToValidator(
     JSONObjectValidationBuilder* addToValidator(
         JSONObjectValidationBuilder* builder) const override
         JSONObjectValidationBuilder* builder) const override
     {
     {
-        return builder->withRequiredNumber("propability")->finishNumber();
+        return builder->withRequiredNumber("propability")
+            ->whichIsGreaterThen(0)
+            ->finishNumber();
     }
     }
 
 
 protected:
 protected:

+ 9 - 10
FactoryCraft/Grass.cpp

@@ -4,7 +4,7 @@
 #include "ItemEntity.h"
 #include "ItemEntity.h"
 
 
 GrassBlock::GrassBlock(int typeId, Framework::Vec3<int> pos, int dimensionId)
 GrassBlock::GrassBlock(int typeId, Framework::Vec3<int> pos, int dimensionId)
-    : AdditionalItemSpawningBlock(typeId, pos, dimensionId)
+    : BasicBlock(typeId, pos, dimensionId)
 {
 {
     transparent = 1;
     transparent = 1;
 }
 }
@@ -30,7 +30,7 @@ TickSourceType GrassBlock::isTickSource() const
 }
 }
 
 
 GrassBlockType::GrassBlockType()
 GrassBlockType::GrassBlockType()
-    : AdditionalItemSpawningBlockType()
+    : BasicBlockType()
 {}
 {}
 
 
 ItemType* GrassBlockType::createItemType() const
 ItemType* GrassBlockType::createItemType() const
@@ -40,20 +40,19 @@ ItemType* GrassBlockType::createItemType() const
 
 
 void GrassBlockType::createSuperBlock(Block* zBlock, Item* zItem) const
 void GrassBlockType::createSuperBlock(Block* zBlock, Item* zItem) const
 {
 {
-    AdditionalItemSpawningBlockType::createSuperBlock(zBlock, zItem);
+    BasicBlockType::createSuperBlock(zBlock, zItem);
 }
 }
 
 
 void GrassBlockType::loadSuperBlock(
 void GrassBlockType::loadSuperBlock(
     Block* zBlock, Framework::StreamReader* zReader, int dimensionId) const
     Block* zBlock, Framework::StreamReader* zReader, int dimensionId) const
 {
 {
-    AdditionalItemSpawningBlockType::loadSuperBlock(
-        zBlock, zReader, dimensionId);
+    BasicBlockType::loadSuperBlock(zBlock, zReader, dimensionId);
 }
 }
 
 
 void GrassBlockType::saveSuperBlock(
 void GrassBlockType::saveSuperBlock(
     Block* zBlock, Framework::StreamWriter* zWriter) const
     Block* zBlock, Framework::StreamWriter* zWriter) const
 {
 {
-    AdditionalItemSpawningBlockType::saveSuperBlock(zBlock, zWriter);
+    BasicBlockType::saveSuperBlock(zBlock, zWriter);
 }
 }
 
 
 Item* GrassBlockType::createItem() const
 Item* GrassBlockType::createItem() const
@@ -68,7 +67,7 @@ Block* GrassBlockType::createBlock(
 }
 }
 
 
 GrassBlockTypeFactory::GrassBlockTypeFactory()
 GrassBlockTypeFactory::GrassBlockTypeFactory()
-    : AdditionalItemSpawningBlockTypeFactory()
+    : BasicBlockTypeFactory()
 {}
 {}
 
 
 BasicBlockType* GrassBlockTypeFactory::createValue(
 BasicBlockType* GrassBlockTypeFactory::createValue(
@@ -80,19 +79,19 @@ BasicBlockType* GrassBlockTypeFactory::createValue(
 BasicBlockType* GrassBlockTypeFactory::fromJson(
 BasicBlockType* GrassBlockTypeFactory::fromJson(
     Framework::JSON::JSONObject* zJson) const
     Framework::JSON::JSONObject* zJson) const
 {
 {
-    return AdditionalItemSpawningBlockTypeFactory::fromJson(zJson);
+    return BasicBlockTypeFactory::fromJson(zJson);
 }
 }
 
 
 Framework::JSON::JSONObject* GrassBlockTypeFactory::toJsonObject(
 Framework::JSON::JSONObject* GrassBlockTypeFactory::toJsonObject(
     BasicBlockType* zObject) const
     BasicBlockType* zObject) const
 {
 {
-    return AdditionalItemSpawningBlockTypeFactory::toJsonObject(zObject);
+    return BasicBlockTypeFactory::toJsonObject(zObject);
 }
 }
 
 
 JSONObjectValidationBuilder* GrassBlockTypeFactory::addToValidator(
 JSONObjectValidationBuilder* GrassBlockTypeFactory::addToValidator(
     JSONObjectValidationBuilder* builder) const
     JSONObjectValidationBuilder* builder) const
 {
 {
-    return AdditionalItemSpawningBlockTypeFactory::addToValidator(builder);
+    return BasicBlockTypeFactory::addToValidator(builder);
 }
 }
 
 
 const char* GrassBlockTypeFactory::getTypeToken() const
 const char* GrassBlockTypeFactory::getTypeToken() const

+ 3 - 3
FactoryCraft/Grass.h

@@ -5,7 +5,7 @@
 
 
 class GrassBlockType;
 class GrassBlockType;
 
 
-class GrassBlock : public AdditionalItemSpawningBlock
+class GrassBlock : public BasicBlock
 {
 {
 public:
 public:
     GrassBlock(int typeId, Framework::Vec3<int> pos, int dimensionId);
     GrassBlock(int typeId, Framework::Vec3<int> pos, int dimensionId);
@@ -18,7 +18,7 @@ public:
     friend GrassBlockType;
     friend GrassBlockType;
 };
 };
 
 
-class GrassBlockType : public AdditionalItemSpawningBlockType
+class GrassBlockType : public BasicBlockType
 {
 {
 public:
 public:
     GrassBlockType();
     GrassBlockType();
@@ -38,7 +38,7 @@ public:
     virtual ItemType* createItemType() const override;
     virtual ItemType* createItemType() const override;
 };
 };
 
 
-class GrassBlockTypeFactory : public AdditionalItemSpawningBlockTypeFactory
+class GrassBlockTypeFactory : public BasicBlockTypeFactory
 {
 {
 public:
 public:
     GrassBlockTypeFactory();
     GrassBlockTypeFactory();

+ 7 - 5
FactoryCraft/ItemEntity.cpp

@@ -19,7 +19,7 @@ ItemEntity::ItemEntity(
     maxStamina = 10;
     maxStamina = 10;
     maxHunger = 10;
     maxHunger = 10;
     maxThirst = 10;
     maxThirst = 10;
-    setHP(10);
+    setHP(0, 0, 0, 10.f);
     setStamina(10);
     setStamina(10);
     setHunger(10);
     setHunger(10);
     setThirst(10);
     setThirst(10);
@@ -71,7 +71,7 @@ void ItemEntity::tick(const Dimension* zDimension)
             // add items of this entity to the other entity
             // add items of this entity to the other entity
             zOther->interactWith(this, NO_DIRECTION)
             zOther->interactWith(this, NO_DIRECTION)
                 .pullItems(slot->getNumberOfItems(), 0);
                 .pullItems(slot->getNumberOfItems(), 0);
-            if (slot->getNumberOfItems() == 0) onDeath();
+            if (slot->getNumberOfItems() == 0) onDeath(0, 0, 0);
         }
         }
     }
     }
     Entity::tick(zDimension);
     Entity::tick(zDimension);
@@ -79,7 +79,7 @@ void ItemEntity::tick(const Dimension* zDimension)
 
 
 void ItemEntity::onFall(float collisionSpeed)
 void ItemEntity::onFall(float collisionSpeed)
 {
 {
-    if (collisionSpeed >= 50.f) this->setHP(0);
+    if (collisionSpeed >= 50.f) this->setHP(0, 0, 0, 0.f);
 }
 }
 
 
 bool ItemEntity::hasDefaultModel() const
 bool ItemEntity::hasDefaultModel() const
@@ -95,8 +95,10 @@ ModelInfo* ItemEntity::zSpecialModel() const
 }
 }
 
 
 ItemEntityType::ItemEntityType()
 ItemEntityType::ItemEntityType()
-    : EntityType("Item", 0)
-{}
+    : EntityType()
+{
+    setName("Item");
+}
 
 
 Entity* ItemEntityType::createEntity(
 Entity* ItemEntityType::createEntity(
     Framework::Vec3<float> position, int dimensionId, int entityId) const
     Framework::Vec3<float> position, int dimensionId, int entityId) const

+ 2 - 1
FactoryCraft/MultiblockStructure.cpp

@@ -53,7 +53,8 @@ void MultiblockStructure::addMemberPosition(Framework::Vec3<int> blockPos)
     affectedChunks.add(center);
     affectedChunks.add(center);
 }
 }
 
 
-void MultiblockStructure::onBlockRemoved(Block* zBlock)
+void MultiblockStructure::onBlockRemoved(
+    Entity* zActor, Item* zUsedItem, ItemSkill* zUsedSkill, Block* zBlock)
 {
 {
     for (auto i = memberBlockPositions.begin(); i; ++i)
     for (auto i = memberBlockPositions.begin(); i; ++i)
     {
     {

+ 5 - 1
FactoryCraft/MultiblockStructure.h

@@ -8,6 +8,9 @@
 
 
 class MultiblockStructureType;
 class MultiblockStructureType;
 class Block;
 class Block;
+class Entity;
+class Item;
+class ItemSkill;
 
 
 class MultiblockStructureEnum
 class MultiblockStructureEnum
 {
 {
@@ -38,7 +41,8 @@ public:
     void onBlockLoaded(Block* block);
     void onBlockLoaded(Block* block);
     void onBlockUnloaded(Block* zBlock);
     void onBlockUnloaded(Block* zBlock);
     void addMemberPosition(Framework::Vec3<int> blockPos);
     void addMemberPosition(Framework::Vec3<int> blockPos);
-    virtual void onBlockRemoved(Block* zBlock);
+    virtual void onBlockRemoved(
+        Entity* zActor, Item* zUsedItem, ItemSkill* zUsedSkill, Block* zBlock);
 
 
     bool isEmpty() const;
     bool isEmpty() const;
     bool isFullyLoaded() const;
     bool isFullyLoaded() const;

+ 9 - 5
FactoryCraft/MultiblockTree.cpp

@@ -6,15 +6,19 @@ using namespace Framework;
 
 
 MultiblockTree::MultiblockTree(
 MultiblockTree::MultiblockTree(
     int dimensionId, __int64 structureId, Framework::Vec3<int> uniquePosition)
     int dimensionId, __int64 structureId, Framework::Vec3<int> uniquePosition)
-    : MultiblockStructure(
-        dimensionId, structureId, uniquePosition, MultiblockStructureEnum::TREE)
+    : MultiblockStructure(dimensionId,
+          structureId,
+          uniquePosition,
+          MultiblockStructureEnum::TREE)
 {}
 {}
 
 
-void MultiblockTree::onBlockRemoved(Block* zBlock)
+void MultiblockTree::onBlockRemoved(
+    Entity* zActor, Item* zUsedItem, ItemSkill* zUsedSkill, Block* zBlock)
 {
 {
     if (isBlockMember(zBlock))
     if (isBlockMember(zBlock))
     {
     {
-        MultiblockStructure::onBlockRemoved(zBlock);
+        MultiblockStructure::onBlockRemoved(
+            zActor, zUsedItem, zUsedSkill, zBlock);
         for (int d = 4; d >= 0; d--)
         for (int d = 4; d >= 0; d--)
         {
         {
             bool foundStablizer = 0;
             bool foundStablizer = 0;
@@ -66,7 +70,7 @@ void MultiblockTree::onBlockRemoved(Block* zBlock)
             if (!foundStablizer)
             if (!foundStablizer)
             {
             {
                 for (Block* b : checked)
                 for (Block* b : checked)
-                    b->setHP(0);
+                    b->setHP(zActor, zUsedItem, zUsedSkill, 0);
             }
             }
         }
         }
     }
     }

+ 4 - 1
FactoryCraft/MultiblockTree.h

@@ -8,7 +8,10 @@ public:
     MultiblockTree(int dimensionId,
     MultiblockTree(int dimensionId,
         __int64 structureId,
         __int64 structureId,
         Framework::Vec3<int> uniquePosition);
         Framework::Vec3<int> uniquePosition);
-    virtual void onBlockRemoved(Block* zBlock) override;
+    virtual void onBlockRemoved(Entity* zActor,
+        Item* zUsedItem,
+        ItemSkill* zUsedSkill,
+        Block* zBlock) override;
 };
 };
 
 
 class MultiblockTreeStructureType : public MultiblockStructureType
 class MultiblockTreeStructureType : public MultiblockStructureType

+ 9 - 9
FactoryCraft/Player.cpp

@@ -31,7 +31,7 @@ Player::Player(Framework::Vec3<float> location, int dimensionId, int entityId)
     maxStamina = 10;
     maxStamina = 10;
     maxHunger = 10;
     maxHunger = 10;
     maxThirst = 10;
     maxThirst = 10;
-    setHP(10);
+    setHP(0, 0, 0, 10.f);
     setStamina(10);
     setStamina(10);
     setHunger(10);
     setHunger(10);
     setThirst(10);
     setThirst(10);
@@ -367,21 +367,21 @@ void Player::onFall(float collisionSpeed)
     // TODO: check validity
     // TODO: check validity
 }
 }
 
 
-void Player::onDeath()
+void Player::onDeath(Entity* zActor, Item* zUsedItem, ItemSkill* zUsedSkill)
 {
 {
-    this->setHP(this->getMaxHP());
+    this->setHP(zActor, zUsedItem, zUsedSkill, this->getMaxHP());
     Game::INSTANCE->zChat()->broadcastMessage(
     Game::INSTANCE->zChat()->broadcastMessage(
         name + " died!", Chat::CHANNEL_INFO);
         name + " died!", Chat::CHANNEL_INFO);
     // TODO: respown
     // TODO: respown
 }
 }
 
 
 PlayerEntityType::PlayerEntityType()
 PlayerEntityType::PlayerEntityType()
-    : EntityType("Player",
-        new ModelInfo("entities.m3/player",
-            toArray("entities.ltdb/player.png", 6),
-            0,
-            1.f))
-{}
+    : EntityType()
+{
+    setName("Player");
+    setModel(new ModelInfo(
+        "entities.m3/player", toArray("entities.ltdb/player.png", 6), 0, 1.f));
+}
 
 
 void PlayerEntityType::loadSuperEntity(
 void PlayerEntityType::loadSuperEntity(
     Entity* zEntity, Framework::StreamReader* zReader) const
     Entity* zEntity, Framework::StreamReader* zReader) const

+ 2 - 1
FactoryCraft/Player.h

@@ -42,7 +42,8 @@ public:
     void playerApi(
     void playerApi(
         Framework::StreamReader* zRequest, NetworkMessage* zResponse);
         Framework::StreamReader* zRequest, NetworkMessage* zResponse);
     void onFall(float collisionSpeed) override;
     void onFall(float collisionSpeed) override;
-    void onDeath() override;
+    void onDeath(
+        Entity* zActor, Item* zUsedItem, ItemSkill* zUsedSkill) override;
 
 
     friend PlayerEntityType;
     friend PlayerEntityType;
 };
 };

+ 6 - 2
FactoryCraft/PlayerHand.cpp

@@ -37,12 +37,16 @@ bool PlayerHandSkill::use(Entity* zActor, Item* zUsedItem, Block* zTarget)
         if (zTarget && zTarget->getHardness() <= 1)
         if (zTarget && zTarget->getHardness() <= 1)
         {
         {
             zActor->setStamina(zActor->getStamina() - 0.001f);
             zActor->setStamina(zActor->getStamina() - 0.001f);
-            zTarget->setHP(zTarget->getHP() - 1 / (zTarget->getHardness() + 1));
+            zTarget->setHP(zActor,
+                zUsedItem,
+                this,
+                zTarget->getHP() - 1 / (zTarget->getHardness() + 1));
         }
         }
         else
         else
         {
         {
             zActor->setStamina(zActor->getStamina() - 0.001f);
             zActor->setStamina(zActor->getStamina() - 0.001f);
-            zActor->setHP(zActor->getCurrentHP() - 0.01f);
+            zActor->setHP(
+                zActor, zUsedItem, this, zActor->getCurrentHP() - 0.01f);
         }
         }
     }
     }
     return false; // item was not changed
     return false; // item was not changed

+ 1 - 6
FactoryCraft/QuestRequirement.cpp

@@ -131,12 +131,7 @@ JSONObjectValidationBuilder* QuestRequirementOpenDialogType::addToValidator(
     JSONObjectValidationBuilder* builder) const
     JSONObjectValidationBuilder* builder) const
 {
 {
     return QuestRequirementFactoryBase::addToValidator(
     return QuestRequirementFactoryBase::addToValidator(
-        builder->withRequiredString("id")
-            ->finishString()
-            ->withRequiredString("description")
-            ->finishString()
-            ->withRequiredString("dialogId")
-            ->finishString());
+        builder->withRequiredString("dialogId")->finishString());
 }
 }
 
 
 const char* QuestRequirementOpenDialogType::getTypeToken() const
 const char* QuestRequirementOpenDialogType::getTypeToken() const

+ 132 - 0
FactoryCraft/SpecificItemDrop.cpp

@@ -0,0 +1,132 @@
+#include "SpecificItemDrop.h"
+
+#include "Block.h"
+#include "Entity.h"
+#include "Inventory.h"
+#include "ItemStack.h"
+
+SpecificItemDrop::SpecificItemDrop(
+    Framework::Text itemTypeName, ItemModifier* modifier, int amount)
+    : DropConfig(),
+      itemTypeName(itemTypeName),
+      zType(0),
+      modifier(modifier),
+      amount(amount)
+{}
+
+SpecificItemDrop::~SpecificItemDrop()
+{
+    if (modifier) modifier->release();
+}
+
+void SpecificItemDrop::initialize()
+{
+    if (!zType)
+    {
+        int id = Game::INSTANCE->getItemTypeId(itemTypeName);
+        if (id >= 0)
+        {
+            zType = Game::INSTANCE->zItemType(id);
+        }
+    }
+}
+
+Framework::Text SpecificItemDrop::getItemTypeName() const
+{
+    return itemTypeName;
+}
+
+const ItemModifier* SpecificItemDrop::zModifier() const
+{
+    return modifier;
+}
+
+int SpecificItemDrop::getAmount() const
+{
+    return amount;
+}
+
+void SpecificItemDrop::doDrop(Entity* zActor,
+    Item* zItem,
+    ItemSkill* zUsedSkill,
+    Framework::Either<Block*, Entity*> zDestroyedObject) const
+{
+    if (zType)
+    {
+        Item* item = zType->createItem();
+        if (item)
+        {
+            if (modifier)
+            {
+                modifier->applyOn(item);
+            }
+            ItemStack* stack = new ItemStack(item, amount);
+            Inventory* inventory;
+            if (zDestroyedObject.isA())
+            {
+                inventory = dynamic_cast<Inventory*>(zDestroyedObject.getA());
+            }
+            else
+            {
+                inventory = dynamic_cast<Inventory*>(zDestroyedObject.getB());
+            }
+            Game::INSTANCE->spawnItem(
+                inventory->getLocation()
+                    + Framework::Vec3<float>(0.5f, 0.5f, 0.5f),
+                inventory->getDimensionId(),
+                stack);
+        }
+    }
+}
+
+SpecificItemDropFactory::SpecificItemDropFactory()
+    : DropConfigFactory()
+{}
+
+JSONObjectValidationBuilder* SpecificItemDropFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return DropConfigFactory::addToValidator(builder)
+        ->withRequiredAttribute("itemType",
+            Game::INSTANCE->zTypeRegistry()->getValidator<Framework::Text>(
+                ItemTypeNameFactory::TYPE_ID))
+        ->withRequiredAttribute("modifier",
+            Game::INSTANCE->zTypeRegistry()->getValidator<ItemModifier>(),
+            false,
+            true)
+        ->withRequiredNumber("amount")
+        ->whichIsGreaterThen(0.0)
+        ->withDefault(1.0)
+        ->finishNumber();
+}
+
+const char* SpecificItemDropFactory::getTypeToken() const
+{
+    return "specificItem";
+}
+
+SpecificItemDrop* SpecificItemDropFactory::createInstance(
+    Framework::JSON::JSONObject* zJson) const
+{
+    return new SpecificItemDrop(
+        zJson->zValue("itemType")->asString()->getString(),
+        zJson->hasValue("modifier")
+            ? Game::INSTANCE->zTypeRegistry()->fromJson<ItemModifier>(
+                  zJson->zValue("modifier"))
+            : 0,
+        (int)zJson->zValue("amount")->asNumber()->getNumber());
+}
+
+void SpecificItemDropFactory::addToJson(
+    Framework::JSON::JSONObject* zJson, SpecificItemDrop* zObject) const
+{
+    zJson->addValue("itemType",
+        new Framework::JSON::JSONString(zObject->getItemTypeName()));
+    if (zObject->zModifier())
+    {
+        zJson->addValue("modifier",
+            Game::INSTANCE->zTypeRegistry()->toJson(zObject->zModifier()));
+    }
+    zJson->addValue(
+        "amount", new Framework::JSON::JSONNumber(zObject->getAmount()));
+}

+ 40 - 0
FactoryCraft/SpecificItemDrop.h

@@ -0,0 +1,40 @@
+#pragma once
+
+#include "DropConfig.h"
+#include "ItemModifier.h"
+#include "ItemType.h"
+
+class SpecificItemDrop : public DropConfig
+{
+private:
+    Framework::Text itemTypeName;
+    const ItemType* zType;
+    ItemModifier* modifier;
+    int amount;
+
+public:
+    SpecificItemDrop(
+        Framework::Text itemTypeName, ItemModifier* modifier, int amount);
+    ~SpecificItemDrop();
+    void initialize() override;
+    Framework::Text getItemTypeName() const;
+    const ItemModifier* zModifier() const;
+    int getAmount() const;
+    void doDrop(Entity* zActor,
+        Item* zItem,
+        ItemSkill* zUsedSkill,
+        Framework::Either<Block*, Entity*> zDestroyedObject) const override;
+};
+
+class SpecificItemDropFactory : public DropConfigFactory<SpecificItemDrop>
+{
+public:
+    SpecificItemDropFactory();
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
+    const char* getTypeToken() const override;
+    SpecificItemDrop* createInstance(
+        Framework::JSON::JSONObject* zJson) const override;
+    void addToJson(Framework::JSON::JSONObject* zJson,
+        SpecificItemDrop* zObject) const override;
+};

+ 1 - 5
FactoryCraft/TreeTemplate.cpp

@@ -157,8 +157,7 @@ Framework::JSON::JSONObject* TreeTemplateFactory::toJsonObject(
 JSONObjectValidationBuilder* TreeTemplateFactory::addToValidator(
 JSONObjectValidationBuilder* TreeTemplateFactory::addToValidator(
     JSONObjectValidationBuilder* builder) const
     JSONObjectValidationBuilder* builder) const
 {
 {
-    return GeneratorTemplateFactory::addToValidator(
-        builder
+    return GeneratorTemplateFactory::addToValidator(builder
             ->withRequiredAttribute("wood",
             ->withRequiredAttribute("wood",
                 Game::INSTANCE->zTypeRegistry()->getValidator<Framework::Text>(
                 Game::INSTANCE->zTypeRegistry()->getValidator<Framework::Text>(
                     BlockTypeNameFactory::TYPE_ID))
                     BlockTypeNameFactory::TYPE_ID))
@@ -170,9 +169,6 @@ JSONObjectValidationBuilder* TreeTemplateFactory::addToValidator(
             ->finishNumber()
             ->finishNumber()
             ->withRequiredNumber("maxSize")
             ->withRequiredNumber("maxSize")
             ->whichIsGreaterThen(0)
             ->whichIsGreaterThen(0)
-            ->finishNumber()
-            ->withRequiredNumber("propability")
-            ->whichIsGreaterThen(0)
             ->finishNumber());
             ->finishNumber());
 }
 }
 
 

+ 18 - 1
FactoryCraft/TypeRegistry.cpp

@@ -10,8 +10,13 @@
 #include "BlockInstanceGeneratorRule.h"
 #include "BlockInstanceGeneratorRule.h"
 #include "BlockTypeGeneratorRule.h"
 #include "BlockTypeGeneratorRule.h"
 #include "Chest.h"
 #include "Chest.h"
+#include "DefaultBlockItemDrop.h"
+#include "DefaultInventoryDrop.h"
 #include "Dimension.h"
 #include "Dimension.h"
 #include "DimensionGenerator.h"
 #include "DimensionGenerator.h"
+#include "DropChanceCondition.h"
+#include "DropConditionOperator.h"
+#include "DropUsedItemCondition.h"
 #include "FluidBlock.h"
 #include "FluidBlock.h"
 #include "FluidContainer.h"
 #include "FluidContainer.h"
 #include "GeneratorRule.h"
 #include "GeneratorRule.h"
@@ -23,6 +28,7 @@
 #include "PlaceableProof.h"
 #include "PlaceableProof.h"
 #include "Quest.h"
 #include "Quest.h"
 #include "Recipie.h"
 #include "Recipie.h"
+#include "SpecificItemDrop.h"
 #include "TreeSeblingBlock.h"
 #include "TreeSeblingBlock.h"
 #include "TreeTemplate.h"
 #include "TreeTemplate.h"
 
 
@@ -43,7 +49,6 @@ TypeRegistry::TypeRegistry()
     // block types
     // block types
     registerType(new ModelInfoFactory());
     registerType(new ModelInfoFactory());
     registerSubType(new BasicBlockTypeFactory());
     registerSubType(new BasicBlockTypeFactory());
-    registerSubType(new AdditionalItemSpawningBlockTypeFactory());
     registerSubType(new BasicLightSourceBlockTypeFactory());
     registerSubType(new BasicLightSourceBlockTypeFactory());
     registerSubType(new ChestBlockTypeFactory());
     registerSubType(new ChestBlockTypeFactory());
     registerSubType(new FluidBlockTypeFactory());
     registerSubType(new FluidBlockTypeFactory());
@@ -123,6 +128,18 @@ TypeRegistry::TypeRegistry()
 
 
     // entities
     // entities
     registerSubType(new AnimalEntityTypeFactory());
     registerSubType(new AnimalEntityTypeFactory());
+
+    // drop conditions
+    registerSubType(new DropChanceConditionFactory());
+    registerSubType(new DropConditionOperatorFactory());
+    registerSubType(new DropConditionNegationFactory());
+    registerSubType(new DropUsedItemConditionFactory());
+    registerSubType(new DropNoUsedItemConditionFactory());
+
+    // drop configs
+    registerSubType(new DefaultBlockItemDropFactory());
+    registerSubType(new DefaultInventoryItemDropFactory());
+    registerSubType(new SpecificItemDropFactory());
 }
 }
 
 
 void TypeRegistry::writeSyntaxInfo(Framework::Text folderPath) const
 void TypeRegistry::writeSyntaxInfo(Framework::Text folderPath) const

+ 3 - 3
FactoryCraft/TypeRegistry.h

@@ -405,8 +405,8 @@ public:
         return toJson<T*>(typeid(T).name(), zObject);
         return toJson<T*>(typeid(T).name(), zObject);
     }
     }
 
 
-    template<typename T>
-    Framework::JSON::JSONValue* toJson(Framework::Text typeId, T zObject) const
+    template<typename T> Framework::JSON::JSONValue* toJson(
+        Framework::Text typeId, const T zObject) const
     {
     {
         TypeFatoryRef* typeFactoryRef
         TypeFatoryRef* typeFactoryRef
             = parsableTypes.z(typeId, typeId.getLength());
             = parsableTypes.z(typeId, typeId.getLength());
@@ -416,7 +416,7 @@ public:
                 << Framework::Text("Type not registered: ") + typeId;
                 << Framework::Text("Type not registered: ") + typeId;
             throw Framework::Text("Type not registered: ") + typeId;
             throw Framework::Text("Type not registered: ") + typeId;
         }
         }
-        return typeFactoryRef->toJson(zObject);
+        return typeFactoryRef->toJson((void*)zObject);
     }
     }
 
 
     template<typename T>
     template<typename T>

+ 15 - 0
Windows Version/Windows Version.vcxproj

@@ -183,10 +183,16 @@ copy ..\..\..\..\..\Allgemein\Framework\x64\release\Framework.dll Framework.dll<
     <ClCompile Include="..\FactoryCraft\Chunk.cpp" />
     <ClCompile Include="..\FactoryCraft\Chunk.cpp" />
     <ClCompile Include="..\FactoryCraft\ChunkMap.cpp" />
     <ClCompile Include="..\FactoryCraft\ChunkMap.cpp" />
     <ClCompile Include="..\FactoryCraft\CraftingStorage.cpp" />
     <ClCompile Include="..\FactoryCraft\CraftingStorage.cpp" />
+    <ClCompile Include="..\FactoryCraft\DefaultBlockItemDrop.cpp" />
+    <ClCompile Include="..\FactoryCraft\DefaultInventoryDrop.cpp" />
     <ClCompile Include="..\FactoryCraft\Dimension.cpp" />
     <ClCompile Include="..\FactoryCraft\Dimension.cpp" />
     <ClCompile Include="..\FactoryCraft\DimensionGenerator.cpp" />
     <ClCompile Include="..\FactoryCraft\DimensionGenerator.cpp" />
     <ClCompile Include="..\FactoryCraft\DimensionMap.cpp" />
     <ClCompile Include="..\FactoryCraft\DimensionMap.cpp" />
     <ClCompile Include="..\FactoryCraft\DoLaterHandler.cpp" />
     <ClCompile Include="..\FactoryCraft\DoLaterHandler.cpp" />
+    <ClCompile Include="..\FactoryCraft\DropChanceCondition.cpp" />
+    <ClCompile Include="..\FactoryCraft\DropConditionOperator.cpp" />
+    <ClCompile Include="..\FactoryCraft\DropConfig.cpp" />
+    <ClCompile Include="..\FactoryCraft\DropUsedItemCondition.cpp" />
     <ClCompile Include="..\FactoryCraft\Entity.cpp" />
     <ClCompile Include="..\FactoryCraft\Entity.cpp" />
     <ClCompile Include="..\FactoryCraft\EntityGenerator.cpp" />
     <ClCompile Include="..\FactoryCraft\EntityGenerator.cpp" />
     <ClCompile Include="..\FactoryCraft\EntityType.cpp" />
     <ClCompile Include="..\FactoryCraft\EntityType.cpp" />
@@ -244,6 +250,7 @@ copy ..\..\..\..\..\Allgemein\Framework\x64\release\Framework.dll Framework.dll<
     <ClCompile Include="..\FactoryCraft\ScaleNoise.cpp" />
     <ClCompile Include="..\FactoryCraft\ScaleNoise.cpp" />
     <ClCompile Include="..\FactoryCraft\Server.cpp" />
     <ClCompile Include="..\FactoryCraft\Server.cpp" />
     <ClCompile Include="..\FactoryCraft\ShapedNoise.cpp" />
     <ClCompile Include="..\FactoryCraft\ShapedNoise.cpp" />
+    <ClCompile Include="..\FactoryCraft\SpecificItemDrop.cpp" />
     <ClCompile Include="..\FactoryCraft\Start.cpp" />
     <ClCompile Include="..\FactoryCraft\Start.cpp" />
     <ClCompile Include="..\FactoryCraft\StructureCollection.cpp" />
     <ClCompile Include="..\FactoryCraft\StructureCollection.cpp" />
     <ClCompile Include="..\FactoryCraft\TickOrganizer.cpp" />
     <ClCompile Include="..\FactoryCraft\TickOrganizer.cpp" />
@@ -267,6 +274,13 @@ copy ..\..\..\..\..\Allgemein\Framework\x64\release\Framework.dll Framework.dll<
     <ClInclude Include="..\FactoryCraft\BlockInfoCommand.h" />
     <ClInclude Include="..\FactoryCraft\BlockInfoCommand.h" />
     <ClInclude Include="..\FactoryCraft\BlockInstanceGeneratorRule.h" />
     <ClInclude Include="..\FactoryCraft\BlockInstanceGeneratorRule.h" />
     <ClInclude Include="..\FactoryCraft\BlockTypeNameFactory.h" />
     <ClInclude Include="..\FactoryCraft\BlockTypeNameFactory.h" />
+    <ClInclude Include="..\FactoryCraft\DefaultBlockItemDrop.h" />
+    <ClInclude Include="..\FactoryCraft\DefaultInventoryDrop.h" />
+    <ClInclude Include="..\FactoryCraft\DropChanceCondition.h" />
+    <ClInclude Include="..\FactoryCraft\DropCondition.h" />
+    <ClInclude Include="..\FactoryCraft\DropConditionOperator.h" />
+    <ClInclude Include="..\FactoryCraft\DropConfig.h" />
+    <ClInclude Include="..\FactoryCraft\DropUsedItemCondition.h" />
     <ClInclude Include="..\FactoryCraft\EntityGenerator.h" />
     <ClInclude Include="..\FactoryCraft\EntityGenerator.h" />
     <ClInclude Include="..\FactoryCraft\FactorizeNoise.h" />
     <ClInclude Include="..\FactoryCraft\FactorizeNoise.h" />
     <ClInclude Include="..\FactoryCraft\FlattenNoise.h" />
     <ClInclude Include="..\FactoryCraft\FlattenNoise.h" />
@@ -350,6 +364,7 @@ copy ..\..\..\..\..\Allgemein\Framework\x64\release\Framework.dll Framework.dll<
     <ClInclude Include="..\FactoryCraft\Server.h" />
     <ClInclude Include="..\FactoryCraft\Server.h" />
     <ClInclude Include="..\FactoryCraft\Dimension.h" />
     <ClInclude Include="..\FactoryCraft\Dimension.h" />
     <ClInclude Include="..\FactoryCraft\ShapedNoise.h" />
     <ClInclude Include="..\FactoryCraft\ShapedNoise.h" />
+    <ClInclude Include="..\FactoryCraft\SpecificItemDrop.h" />
     <ClInclude Include="..\FactoryCraft\StructureCollection.h" />
     <ClInclude Include="..\FactoryCraft\StructureCollection.h" />
     <ClInclude Include="..\FactoryCraft\Tickable.h" />
     <ClInclude Include="..\FactoryCraft\Tickable.h" />
     <ClInclude Include="..\FactoryCraft\TickOrganizer.h" />
     <ClInclude Include="..\FactoryCraft\TickOrganizer.h" />

+ 54 - 0
Windows Version/Windows Version.vcxproj.filters

@@ -106,6 +106,15 @@
     <Filter Include="world\generator\biom\entityGenerator">
     <Filter Include="world\generator\biom\entityGenerator">
       <UniqueIdentifier>{87911234-37d0-41ac-975c-329d2963ca52}</UniqueIdentifier>
       <UniqueIdentifier>{87911234-37d0-41ac-975c-329d2963ca52}</UniqueIdentifier>
     </Filter>
     </Filter>
+    <Filter Include="drops">
+      <UniqueIdentifier>{79a25f96-c848-40a9-ad5f-f26d89fcd0ad}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="drops\conditions">
+      <UniqueIdentifier>{df6eb2a2-0491-4687-92ce-dd34edaaee45}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="drops\implementations">
+      <UniqueIdentifier>{d4e7dadf-eb55-4257-ad1b-90d18018a9fe}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\FactoryCraft\Server.cpp">
     <ClCompile Include="..\FactoryCraft\Server.cpp">
@@ -408,6 +417,27 @@
     <ClCompile Include="..\FactoryCraft\ItemTypeNameFactory.cpp">
     <ClCompile Include="..\FactoryCraft\ItemTypeNameFactory.cpp">
       <Filter>server\config</Filter>
       <Filter>server\config</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="..\FactoryCraft\DropChanceCondition.cpp">
+      <Filter>drops\conditions</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FactoryCraft\DropConditionOperator.cpp">
+      <Filter>drops\conditions</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FactoryCraft\DropUsedItemCondition.cpp">
+      <Filter>drops\conditions</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FactoryCraft\DefaultBlockItemDrop.cpp">
+      <Filter>drops\implementations</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FactoryCraft\DefaultInventoryDrop.cpp">
+      <Filter>drops\implementations</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FactoryCraft\SpecificItemDrop.cpp">
+      <Filter>drops\implementations</Filter>
+    </ClCompile>
+    <ClCompile Include="..\FactoryCraft\DropConfig.cpp">
+      <Filter>drops</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\FactoryCraft\Chunk.h">
     <ClInclude Include="..\FactoryCraft\Chunk.h">
@@ -725,5 +755,29 @@
     <ClInclude Include="..\FactoryCraft\ItemTypeNameFactory.h">
     <ClInclude Include="..\FactoryCraft\ItemTypeNameFactory.h">
       <Filter>server\config</Filter>
       <Filter>server\config</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="..\FactoryCraft\DropCondition.h">
+      <Filter>drops</Filter>
+    </ClInclude>
+    <ClInclude Include="..\FactoryCraft\DropConfig.h">
+      <Filter>drops</Filter>
+    </ClInclude>
+    <ClInclude Include="..\FactoryCraft\DropChanceCondition.h">
+      <Filter>drops\conditions</Filter>
+    </ClInclude>
+    <ClInclude Include="..\FactoryCraft\DropConditionOperator.h">
+      <Filter>drops\conditions</Filter>
+    </ClInclude>
+    <ClInclude Include="..\FactoryCraft\DropUsedItemCondition.h">
+      <Filter>drops\conditions</Filter>
+    </ClInclude>
+    <ClInclude Include="..\FactoryCraft\DefaultBlockItemDrop.h">
+      <Filter>drops\implementations</Filter>
+    </ClInclude>
+    <ClInclude Include="..\FactoryCraft\DefaultInventoryDrop.h">
+      <Filter>drops\implementations</Filter>
+    </ClInclude>
+    <ClInclude Include="..\FactoryCraft\SpecificItemDrop.h">
+      <Filter>drops\implementations</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
 </Project>
 </Project>

+ 645 - 645
Windows Version/data/generator/overworld.json

@@ -1,686 +1,686 @@
 [
 [
-  {
-    "type": "cavedBioms",
-    "name": "Overworld",
-    "id": 0,
-    "dimensionSeed": {
-      "type": "operator",
-      "operator": "+",
-      "values": [
-        {
-          "type": "variable",
-          "name": "worldSeed"
-        },
-        {
-          "type": "variable",
-          "name": "dimensionId"
-        }
-      ]
-    },
-    "biomNoise": {
-        "type": "Cellular",
-      "seed": {
-        "type": "variable",
-        "name": "dimensionSeed"
-      },
-      "rotationType3D": "None",
-      "frequency": 0.015,
-      "fractalType": "None",
-      "cellularDistanceFunction": "Hybrid",
-      "cellularReturnType": "CellValue",
-      "cellularJitter": 1,
-      "domainWarpType": "OpenSimplex2Reduced",
-      "domainWarpAmp": 30
-    },
-    "heightLayers": [
-      {
-        "name": "h",
-        "noise": {
-          "type": "factorize",
-          "noiseA": {
-            "type": "flatten",
-            "noise": {
-              "type": "Perlin",
-              "multiplier": 0.05,
-              "seed": {
-                "type": "operator",
-                "operator": "+",
-                "values": [
-                  {
-                    "type": "variable",
-                    "name": "dimensionSeed"
-                  },
-                  {
-                    "type": "constant",
-                    "value": 23
-                  }
-                ]
-              }
-            },
-            "factor": 0.5,
-            "addition": 0.25
-          },
-          "noiseB": {
-            "type": "multiply",
-            "base": {
-              "type": "factorize",
-              "noiseA": {
-                "type": "Perlin",
-                "frequency": 0.02,
-                "seed": {
-                  "type": "operator",
-                  "operator": "+",
-                  "values": [
-                    {
-                      "type": "variable",
-                      "name": "dimensionSeed"
-                    },
-                    {
-                      "type": "constant",
-                      "value": 22
-                    }
-                  ]
-                }
-              },
-              "noiseB": {
-                "type": "Perlin",
-                "frequency": 0.25,
-                "seed": {
-                  "type": "operator",
-                  "operator": "+",
-                  "values": [
-                    {
-                      "type": "variable",
-                      "name": "dimensionSeed"
-                    },
-                    {
-                      "type": "constant",
-                      "value": 21
-                    }
-                  ]
-                }
-              },
-              "factorA": 0.9
-            },
-            "multiplier": {
-              "type": "flatten",
-              "noise": {
-                "type": "scale",
-                "noise": {
-                  "type": "negate",
-                  "noise": {
-                    "type": "scale",
-                    "noise": {
-                      "type": "Cellular",
-                      "multiplier": 0.4,
-                      "frequency": 0.005,
-                      "rotationType3D": "None",
-                      "fractalType": "DomainWarpIndependent",
-                      "cellularDistanceFunction": "Euclidean",
-                      "cellularReturnType": "Distance",
-                      "cellularJitter": 1.5,
-                      "domainWarpType": "OpenSimplex2Reduced",
-                      "domainWarpAmp": 100,
-                      "fractalOctaves": 3,
-                      "fractalLacunarity": 2,
-                      "fractalGain": 0.5,
-                      "seed": {
-                        "type": "operator",
-                        "operator": "+",
-                        "values": [
-                          {
-                            "type": "variable",
-                            "name": "dimensionSeed"
-                          },
-                          {
-                            "type": "constant",
-                            "value": 20
-                          }
-                        ]
-                      }
-                    },
-                    "factor": 3.5
-                  }
-                },
-                "factor": 1.5
-              },
-              "factor": 0.95,
-              "addition": 0.05
-            }
-          },
-          "factorA": 0.5
-        },
-        "value": {
-          "type": "operator",
-          "operator": "+",
-          "values": [
-            {
-              "type": "constant",
-              "value": 50
-            },
-            {
-              "type": "operator",
-              "operator": "*",
-              "values": [
+    {
+        "type": "cavedBioms",
+        "name": "Overworld",
+        "id": 0,
+        "dimensionSeed": {
+            "type": "operator",
+            "operator": "+",
+            "values": [
                 {
                 {
-                  "type": "noise",
-                  "name": "h",
-                  "x": {
                     "type": "variable",
                     "type": "variable",
-                    "name": "x"
-                  },
-                  "y": {
-                    "type": "variable",
-                    "name": "y"
-                  },
-                  "z": {
-                    "type": "constant",
-                    "value": 0
-                  }
+                    "name": "worldSeed"
                 },
                 },
                 {
                 {
-                  "type": "constant",
-                  "value": 400
-                }
-              ]
-            }
-          ]
-        }
-      },
-      {
-        "name": "u",
-        "noise": {
-          "type": "ValueCubic",
-          "seed": {
-            "type": "variable",
-            "name": "dimensionSeed"
-          }
-        },
-        "value": {
-          "type": "operator",
-          "operator": "-",
-          "values": [
-            {
-              "type": "variable",
-              "name": "h"
-            },
-            {
-              "type": "constant",
-              "value": 5
-            },
-            {
-              "type": "operator",
-              "operator": "*",
-              "values": [
-                {
-                  "type": "noise",
-                  "name": "u",
-                  "x": {
                     "type": "variable",
                     "type": "variable",
-                    "name": "x"
-                  },
-                  "y": {
-                    "type": "variable",
-                    "name": "y"
-                  },
-                  "z": {
-                    "type": "constant",
-                    "value": 0
-                  }
-                },
-                {
-                  "type": "constant",
-                  "value": 45
+                    "name": "dimensionId"
                 }
                 }
-              ]
-            }
-          ]
-        }
-      }
-    ],
-    "bioms": [
-      {
-        "name": "Grassland",
-        "entities": [],
-        "structurCollections": [
-          {
-            "activeNoise": {
-              "type": "random",
-              "seed": {
+            ]
+        },
+        "biomNoise": {
+            "type": "Cellular",
+            "seed": {
                 "type": "variable",
                 "type": "variable",
                 "name": "dimensionSeed"
                 "name": "dimensionSeed"
-              }
             },
             },
-            "structureNoise": {
-              "type": "random",
-              "seed": {
-                "type": "operator",
-                "operator": "+",
-                "values": [
-                  {
-                    "type": "variable",
-                    "name": "dimensionSeed"
-                  },
-                  {
-                    "type": "constant",
-                    "value": 10
-                  }
-                ]
-              }
-            },
-            "threshold": 0.0025,
-            "structures": [
-              {
-                "type": "Tree",
-                "wood": "Birch Wood",
-                "leaves": "Birch Wood Leaves",
-                "minSize": 8,
-                "maxSize": 15,
-                "propability": 0.5
-              },
-              {
-                "type": "Tree",
-                "wood": "Beech Wood",
-                "leaves": "Beech Wood Leaves",
-                "minSize": 8,
-                "maxSize": 13,
-                "propability": 0.25
-              },
-              {
-                "type": "Tree",
-                "wood": "Oak Wood",
-                "leaves": "Oak Wood Leaves",
-                "minSize": 10,
-                "maxSize": 15,
-                "propability": 0.125
-              },
-              {
-                "type": "Tree",
-                "wood": "Pine Wood",
-                "leaves": "Pine Wood Leaves",
-                "minSize": 15,
-                "maxSize": 24,
-                "propability": 0.075
-              }
-            ],
-            "condition": {
-              "type": "operator",
-              "operator": "&&",
-              "values": [
-                {
-                  "type": "comparsion",
-                  "operator": "==i",
-                  "values": [
-                    {
-                      "type": "variable",
-                      "name": "z"
+            "rotationType3D": "None",
+            "frequency": 0.015,
+            "fractalType": "None",
+            "cellularDistanceFunction": "Hybrid",
+            "cellularReturnType": "CellValue",
+            "cellularJitter": 1,
+            "domainWarpType": "OpenSimplex2Reduced",
+            "domainWarpAmp": 30
+        },
+        "heightLayers": [
+            {
+                "name": "h",
+                "noise": {
+                    "type": "factorize",
+                    "noiseA": {
+                        "type": "flatten",
+                        "noise": {
+                            "type": "Perlin",
+                            "multiplier": 0.05,
+                            "seed": {
+                                "type": "operator",
+                                "operator": "+",
+                                "values": [
+                                    {
+                                        "type": "variable",
+                                        "name": "dimensionSeed"
+                                    },
+                                    {
+                                        "type": "constant",
+                                        "value": 23
+                                    }
+                                ]
+                            }
+                        },
+                        "factor": 0.5,
+                        "addition": 0.25
                     },
                     },
-                    {
-                      "type": "operator",
-                      "operator": "-",
-                      "values": [
-                        {
-                          "type": "variable",
-                          "name": "h"
+                    "noiseB": {
+                        "type": "multiply",
+                        "base": {
+                            "type": "factorize",
+                            "noiseA": {
+                                "type": "Perlin",
+                                "frequency": 0.02,
+                                "seed": {
+                                    "type": "operator",
+                                    "operator": "+",
+                                    "values": [
+                                        {
+                                            "type": "variable",
+                                            "name": "dimensionSeed"
+                                        },
+                                        {
+                                            "type": "constant",
+                                            "value": 22
+                                        }
+                                    ]
+                                }
+                            },
+                            "noiseB": {
+                                "type": "Perlin",
+                                "frequency": 0.25,
+                                "seed": {
+                                    "type": "operator",
+                                    "operator": "+",
+                                    "values": [
+                                        {
+                                            "type": "variable",
+                                            "name": "dimensionSeed"
+                                        },
+                                        {
+                                            "type": "constant",
+                                            "value": 21
+                                        }
+                                    ]
+                                }
+                            },
+                            "factorA": 0.9
                         },
                         },
-                        {
-                          "type": "constant",
-                          "value": 1
+                        "multiplier": {
+                            "type": "flatten",
+                            "noise": {
+                                "type": "scale",
+                                "noise": {
+                                    "type": "negate",
+                                    "noise": {
+                                        "type": "scale",
+                                        "noise": {
+                                            "type": "Cellular",
+                                            "multiplier": 0.4,
+                                            "frequency": 0.005,
+                                            "rotationType3D": "None",
+                                            "fractalType": "DomainWarpIndependent",
+                                            "cellularDistanceFunction": "Euclidean",
+                                            "cellularReturnType": "Distance",
+                                            "cellularJitter": 1.5,
+                                            "domainWarpType": "OpenSimplex2Reduced",
+                                            "domainWarpAmp": 100,
+                                            "fractalOctaves": 3,
+                                            "fractalLacunarity": 2,
+                                            "fractalGain": 0.5,
+                                            "seed": {
+                                                "type": "operator",
+                                                "operator": "+",
+                                                "values": [
+                                                    {
+                                                        "type": "variable",
+                                                        "name": "dimensionSeed"
+                                                    },
+                                                    {
+                                                        "type": "constant",
+                                                        "value": 20
+                                                    }
+                                                ]
+                                            }
+                                        },
+                                        "factor": 3.5
+                                    }
+                                },
+                                "factor": 1.5
+                            },
+                            "factor": 0.95,
+                            "addition": 0.05
                         }
                         }
-                      ]
-                    }
-                  ]
-                },
-                {
-                  "type": "comparsion",
-                  "operator": ">=i",
-                  "values": [
-                    {
-                      "type": "variable",
-                      "name": "h"
                     },
                     },
-                    {
-                      "type": "constant",
-                      "value": 200
-                    }
-                  ]
+                    "factorA": 0.5
                 },
                 },
-                {
-                  "type": "comparsion",
-                  "operator": "<i",
-                  "values": [
-                    {
-                      "type": "variable",
-                      "name": "h"
-                    },
-                    {
-                      "type": "constant",
-                      "value": 300
-                    }
-                  ]
-                }
-              ]
-            }
-          }
-        ],
-        "blocks": [
-          {
-            "type": "blockInstance",
-            "blockType": "Water",
-            "condition": {
-              "type": "operator",
-              "operator": "&&",
-              "values": [
-                {
-                  "type": "comparsion",
-                  "operator": ">=i",
-                  "values": [
-                    {
-                      "type": "variable",
-                      "name": "z"
-                    },
-                    {
-                      "type": "variable",
-                      "name": "h"
-                    }
-                  ]
-                },
-                {
-                  "type": "comparsion",
-                  "operator": "<i",
-                  "values": [
-                    {
-                      "type": "variable",
-                      "name": "z"
-                    },
-                    {
-                      "type": "constant",
-                      "value": 200
-                    }
-                  ]
-                }
-              ]
-            }
-          },
-          {
-            "type": "blockType",
-            "blockType": "Air",
-            "condition": {
-              "type": "comparsion",
-              "operator": ">i",
-              "values": [
-                {
-                  "type": "variable",
-                  "name": "z"
-                },
-                {
-                  "type": "variable",
-                  "name": "h"
+                "value": {
+                    "type": "operator",
+                    "operator": "+",
+                    "values": [
+                        {
+                            "type": "constant",
+                            "value": 50
+                        },
+                        {
+                            "type": "operator",
+                            "operator": "*",
+                            "values": [
+                                {
+                                    "type": "noise",
+                                    "name": "h",
+                                    "x": {
+                                        "type": "variable",
+                                        "name": "x"
+                                    },
+                                    "y": {
+                                        "type": "variable",
+                                        "name": "y"
+                                    },
+                                    "z": {
+                                        "type": "constant",
+                                        "value": 0
+                                    }
+                                },
+                                {
+                                    "type": "constant",
+                                    "value": 400
+                                }
+                            ]
+                        }
+                    ]
                 }
                 }
-              ]
-            }
-          },
-          {
-            "type": "blockType",
-            "blockType": "Grass",
-            "noise": {
-              "type": "random",
-              "seed": {
-                "type": "operator",
-                "operator": "+",
-                "values": [
-                  {
-                    "type": "variable",
-                    "name": "dimensionSeed"
-                  },
-                  {
-                    "type": "constant",
-                    "value": 3
-                  }
-                ]
-              }
             },
             },
-            "threshold": 0.25,
-            "condition": {
-              "type": "operator",
-              "operator": "&&",
-              "values": [
-                {
-                  "type": "comparsion",
-                  "operator": "==i",
-                  "values": [
-                    {
-                      "type": "variable",
-                      "name": "z"
-                    },
-                    {
-                      "type": "variable",
-                      "name": "h"
+            {
+                "name": "u",
+                "noise": {
+                    "type": "ValueCubic",
+                    "seed": {
+                        "type": "variable",
+                        "name": "dimensionSeed"
                     }
                     }
-                  ]
                 },
                 },
-                {
-                  "type": "blockType",
-                  "x": {
-                    "type": "variable",
-                    "name": "x"
-                  },
-                  "y": {
-                    "type": "variable",
-                    "name": "y"
-                  },
-                  "z": {
+                "value": {
                     "type": "operator",
                     "type": "operator",
                     "operator": "-",
                     "operator": "-",
                     "values": [
                     "values": [
-                      {
-                        "type": "variable",
-                        "name": "z"
-                      },
-                      {
-                        "type": "constant",
-                        "value": 1
-                      }
+                        {
+                            "type": "variable",
+                            "name": "h"
+                        },
+                        {
+                            "type": "constant",
+                            "value": 5
+                        },
+                        {
+                            "type": "operator",
+                            "operator": "*",
+                            "values": [
+                                {
+                                    "type": "noise",
+                                    "name": "u",
+                                    "x": {
+                                        "type": "variable",
+                                        "name": "x"
+                                    },
+                                    "y": {
+                                        "type": "variable",
+                                        "name": "y"
+                                    },
+                                    "z": {
+                                        "type": "constant",
+                                        "value": 0
+                                    }
+                                },
+                                {
+                                    "type": "constant",
+                                    "value": 45
+                                }
+                            ]
+                        }
                     ]
                     ]
-                  },
-                  "blockType": "Dirt"
-                }
-              ]
-            }
-          },
-          {
-            "type": "blockType",
-            "blockType": "Gravel",
-            "noise": {
-              "type": "ValueCubic",
-              "frequency": 0.1,
-              "seed": {
-                "type": "operator",
-                "operator": "+",
-                "values": [
-                  {
-                    "type": "variable",
-                    "name": "dimensionSeed"
-                  },
-                  {
-                    "type": "constant",
-                    "value": 2
-                  }
-                ]
-              }
-            },
-            "threshold": 0.35,
-            "condition": {
-              "type": "comparsion",
-              "operator": "<i",
-              "values": [
-                {
-                  "type": "variable",
-                  "name": "z"
-                },
-                {
-                  "type": "variable",
-                  "name": "h"
-                }
-              ]
-            }
-          },
-          {
-            "type": "blockType",
-            "blockType": "Dirt",
-            "noise": {
-              "type": "ValueCubic",
-              "frequency": 0.125,
-              "seed": {
-                "type": "operator",
-                "operator": "+",
-                "values": [
-                  {
-                    "type": "variable",
-                    "name": "dimensionSeed"
-                  },
-                  {
-                    "type": "constant",
-                    "value": 1
-                  }
-                ]
-              }
-            },
-            "threshold": 0.35,
-            "condition": {
-              "type": "comparsion",
-              "operator": "<i",
-              "values": [
-                {
-                  "type": "variable",
-                  "name": "z"
-                },
-                {
-                  "type": "variable",
-                  "name": "h"
                 }
                 }
-              ]
             }
             }
-          },
-          {
-            "type": "blockType",
-            "blockType": "Sand",
-            "noise": {
-              "type": "ValueCubic",
-              "frequency": 0.125,
-              "seed": {
-                "type": "operator",
-                "operator": "+",
-                "values": [
-                  {
-                    "type": "variable",
-                    "name": "dimensionSeed"
-                  },
-                  {
-                    "type": "constant",
-                    "value": 2
-                  }
-                ]
-              }
-            },
-            "threshold": 0.35,
-            "condition": {
-              "type": "operator",
-              "operator": "&&",
-              "values": [
-                {
-                  "type": "comparsion",
-                  "operator": "<i",
-                  "values": [
+        ],
+        "bioms": [
+            {
+                "name": "Grassland",
+                "entities": [],
+                "structurCollections": [
+                    {
+                        "activeNoise": {
+                            "type": "random",
+                            "seed": {
+                                "type": "variable",
+                                "name": "dimensionSeed"
+                            }
+                        },
+                        "structureNoise": {
+                            "type": "random",
+                            "seed": {
+                                "type": "operator",
+                                "operator": "+",
+                                "values": [
+                                    {
+                                        "type": "variable",
+                                        "name": "dimensionSeed"
+                                    },
+                                    {
+                                        "type": "constant",
+                                        "value": 10
+                                    }
+                                ]
+                            }
+                        },
+                        "threshold": 0.0025,
+                        "structures": [
+                            {
+                                "type": "Tree",
+                                "wood": "Birch Wood",
+                                "leaves": "Birch Wood Leaves",
+                                "minSize": 8,
+                                "maxSize": 15,
+                                "propability": 0.5
+                            },
+                            {
+                                "type": "Tree",
+                                "wood": "Beech Wood",
+                                "leaves": "Beech Wood Leaves",
+                                "minSize": 8,
+                                "maxSize": 13,
+                                "propability": 0.25
+                            },
+                            {
+                                "type": "Tree",
+                                "wood": "Oak Wood",
+                                "leaves": "Oak Wood Leaves",
+                                "minSize": 10,
+                                "maxSize": 15,
+                                "propability": 0.125
+                            },
+                            {
+                                "type": "Tree",
+                                "wood": "Pine Wood",
+                                "leaves": "Pine Wood Leaves",
+                                "minSize": 15,
+                                "maxSize": 24,
+                                "propability": 0.075
+                            }
+                        ],
+                        "condition": {
+                            "type": "operator",
+                            "operator": "&&",
+                            "values": [
+                                {
+                                    "type": "comparsion",
+                                    "operator": "==i",
+                                    "values": [
+                                        {
+                                            "type": "variable",
+                                            "name": "z"
+                                        },
+                                        {
+                                            "type": "operator",
+                                            "operator": "-",
+                                            "values": [
+                                                {
+                                                    "type": "variable",
+                                                    "name": "h"
+                                                },
+                                                {
+                                                    "type": "constant",
+                                                    "value": 1
+                                                }
+                                            ]
+                                        }
+                                    ]
+                                },
+                                {
+                                    "type": "comparsion",
+                                    "operator": ">=i",
+                                    "values": [
+                                        {
+                                            "type": "variable",
+                                            "name": "h"
+                                        },
+                                        {
+                                            "type": "constant",
+                                            "value": 200
+                                        }
+                                    ]
+                                },
+                                {
+                                    "type": "comparsion",
+                                    "operator": "<i",
+                                    "values": [
+                                        {
+                                            "type": "variable",
+                                            "name": "h"
+                                        },
+                                        {
+                                            "type": "constant",
+                                            "value": 300
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    }
+                ],
+                "blocks": [
                     {
                     {
-                      "type": "variable",
-                      "name": "z"
+                        "type": "blockInstance",
+                        "blockType": "Water",
+                        "condition": {
+                            "type": "operator",
+                            "operator": "&&",
+                            "values": [
+                                {
+                                    "type": "comparsion",
+                                    "operator": ">=i",
+                                    "values": [
+                                        {
+                                            "type": "variable",
+                                            "name": "z"
+                                        },
+                                        {
+                                            "type": "variable",
+                                            "name": "h"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "type": "comparsion",
+                                    "operator": "<i",
+                                    "values": [
+                                        {
+                                            "type": "variable",
+                                            "name": "z"
+                                        },
+                                        {
+                                            "type": "constant",
+                                            "value": 200
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
                     },
                     },
                     {
                     {
-                      "type": "variable",
-                      "name": "h"
-                    }
-                  ]
-                },
-                {
-                  "type": "comparsion",
-                  "operator": ">i",
-                  "values": [
+                        "type": "blockType",
+                        "blockType": "Air",
+                        "condition": {
+                            "type": "comparsion",
+                            "operator": ">i",
+                            "values": [
+                                {
+                                    "type": "variable",
+                                    "name": "z"
+                                },
+                                {
+                                    "type": "variable",
+                                    "name": "h"
+                                }
+                            ]
+                        }
+                    },
                     {
                     {
-                      "type": "variable",
-                      "name": "z"
+                        "type": "blockType",
+                        "blockType": "Grass",
+                        "noise": {
+                            "type": "random",
+                            "seed": {
+                                "type": "operator",
+                                "operator": "+",
+                                "values": [
+                                    {
+                                        "type": "variable",
+                                        "name": "dimensionSeed"
+                                    },
+                                    {
+                                        "type": "constant",
+                                        "value": 3
+                                    }
+                                ]
+                            }
+                        },
+                        "threshold": 0.25,
+                        "condition": {
+                            "type": "operator",
+                            "operator": "&&",
+                            "values": [
+                                {
+                                    "type": "comparsion",
+                                    "operator": "==i",
+                                    "values": [
+                                        {
+                                            "type": "variable",
+                                            "name": "z"
+                                        },
+                                        {
+                                            "type": "variable",
+                                            "name": "h"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "type": "blockType",
+                                    "x": {
+                                        "type": "variable",
+                                        "name": "x"
+                                    },
+                                    "y": {
+                                        "type": "variable",
+                                        "name": "y"
+                                    },
+                                    "z": {
+                                        "type": "operator",
+                                        "operator": "-",
+                                        "values": [
+                                            {
+                                                "type": "variable",
+                                                "name": "z"
+                                            },
+                                            {
+                                                "type": "constant",
+                                                "value": 1
+                                            }
+                                        ]
+                                    },
+                                    "blockType": "Dirt"
+                                }
+                            ]
+                        }
                     },
                     },
                     {
                     {
-                      "type": "variable",
-                      "name": "u"
-                    }
-                  ]
-                }
-              ]
-            }
-          },
-          {
-            "type": "blockType",
-            "blockType": "Dirt",
-            "condition": {
-              "type": "operator",
-              "operator": "&&",
-              "values": [
-                {
-                  "type": "comparsion",
-                  "operator": "<i",
-                  "values": [
+                        "type": "blockType",
+                        "blockType": "Gravel",
+                        "noise": {
+                            "type": "ValueCubic",
+                            "frequency": 0.1,
+                            "seed": {
+                                "type": "operator",
+                                "operator": "+",
+                                "values": [
+                                    {
+                                        "type": "variable",
+                                        "name": "dimensionSeed"
+                                    },
+                                    {
+                                        "type": "constant",
+                                        "value": 2
+                                    }
+                                ]
+                            }
+                        },
+                        "threshold": 0.35,
+                        "condition": {
+                            "type": "comparsion",
+                            "operator": "<i",
+                            "values": [
+                                {
+                                    "type": "variable",
+                                    "name": "z"
+                                },
+                                {
+                                    "type": "variable",
+                                    "name": "h"
+                                }
+                            ]
+                        }
+                    },
                     {
                     {
-                      "type": "variable",
-                      "name": "z"
+                        "type": "blockType",
+                        "blockType": "Dirt",
+                        "noise": {
+                            "type": "ValueCubic",
+                            "frequency": 0.125,
+                            "seed": {
+                                "type": "operator",
+                                "operator": "+",
+                                "values": [
+                                    {
+                                        "type": "variable",
+                                        "name": "dimensionSeed"
+                                    },
+                                    {
+                                        "type": "constant",
+                                        "value": 1
+                                    }
+                                ]
+                            }
+                        },
+                        "threshold": 0.35,
+                        "condition": {
+                            "type": "comparsion",
+                            "operator": "<i",
+                            "values": [
+                                {
+                                    "type": "variable",
+                                    "name": "z"
+                                },
+                                {
+                                    "type": "variable",
+                                    "name": "h"
+                                }
+                            ]
+                        }
                     },
                     },
                     {
                     {
-                      "type": "variable",
-                      "name": "h"
-                    }
-                  ]
-                },
-                {
-                  "type": "comparsion",
-                  "operator": ">i",
-                  "values": [
+                        "type": "blockType",
+                        "blockType": "Sand",
+                        "noise": {
+                            "type": "ValueCubic",
+                            "frequency": 0.125,
+                            "seed": {
+                                "type": "operator",
+                                "operator": "+",
+                                "values": [
+                                    {
+                                        "type": "variable",
+                                        "name": "dimensionSeed"
+                                    },
+                                    {
+                                        "type": "constant",
+                                        "value": 2
+                                    }
+                                ]
+                            }
+                        },
+                        "threshold": 0.35,
+                        "condition": {
+                            "type": "operator",
+                            "operator": "&&",
+                            "values": [
+                                {
+                                    "type": "comparsion",
+                                    "operator": "<i",
+                                    "values": [
+                                        {
+                                            "type": "variable",
+                                            "name": "z"
+                                        },
+                                        {
+                                            "type": "variable",
+                                            "name": "h"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "type": "comparsion",
+                                    "operator": ">i",
+                                    "values": [
+                                        {
+                                            "type": "variable",
+                                            "name": "z"
+                                        },
+                                        {
+                                            "type": "variable",
+                                            "name": "u"
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    },
                     {
                     {
-                      "type": "variable",
-                      "name": "z"
+                        "type": "blockType",
+                        "blockType": "Dirt",
+                        "condition": {
+                            "type": "operator",
+                            "operator": "&&",
+                            "values": [
+                                {
+                                    "type": "comparsion",
+                                    "operator": "<i",
+                                    "values": [
+                                        {
+                                            "type": "variable",
+                                            "name": "z"
+                                        },
+                                        {
+                                            "type": "variable",
+                                            "name": "h"
+                                        }
+                                    ]
+                                },
+                                {
+                                    "type": "comparsion",
+                                    "operator": ">i",
+                                    "values": [
+                                        {
+                                            "type": "variable",
+                                            "name": "z"
+                                        },
+                                        {
+                                            "type": "variable",
+                                            "name": "u"
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
                     },
                     },
                     {
                     {
-                      "type": "variable",
-                      "name": "u"
+                        "type": "blockType",
+                        "blockType": "Stone",
+                        "condition": {
+                            "type": "comparsion",
+                            "operator": "<=i",
+                            "values": [
+                                {
+                                    "type": "variable",
+                                    "name": "z"
+                                },
+                                {
+                                    "type": "variable",
+                                    "name": "u"
+                                }
+                            ]
+                        }
                     }
                     }
-                  ]
-                }
-              ]
-            }
-          },
-          {
-            "type": "blockType",
-            "blockType": "Stone",
-            "condition": {
-              "type": "comparsion",
-              "operator": "<=i",
-              "values": [
-                {
-                  "type": "variable",
-                  "name": "z"
-                },
-                {
-                  "type": "variable",
-                  "name": "u"
+                ],
+                "condition": {
+                    "type": "constant",
+                    "value": true
                 }
                 }
-              ]
             }
             }
-          }
-        ],
-        "condition": {
-          "type": "constant",
-          "value": true
-        }
-      }
-    ]
-  }
+        ]
+    }
 ]
 ]

+ 14 - 12
Windows Version/data/items/itemTypes.json

@@ -1,17 +1,19 @@
 [
 [
-  {
-    "type": "basic",
-    "name": "Wooden Stick",
-    "model": {
-      "modelPath": "items.m3/stick",
-      "texturePaths": [
-        "items.ltdb/stick.png"
-      ]
+    {
+
+        "type": "basic",
+        
+        "name": "Wooden Stick",
+        "model": {
+            "modelPath": "items.m3/stick",
+            "texturePaths": [
+                "items.ltdb/stick.png"
+            ]
+        },
+        "itemName": "Wooden Stick",
+        "hp": 1,
+        "durability": 10
     },
     },
-    "itemName": "Wooden Stick",
-    "hp": 1,
-    "durability": 10
-  },
   {
   {
     "type": "basic",
     "type": "basic",
     "name": "Resin",
     "name": "Resin",

+ 61 - 61
Windows Version/data/quests/quests.json

@@ -1,64 +1,64 @@
 [
 [
-  {
-    "name": "Tutorial",
-    "quests": [
-      {
-        "questId": "tutorial_1",
-        "questName": "Quest Dialog",
-        "description": "Welcome to Factory Craft!\nThis is a tutorial quest to get you started.\nYou have already completed it by opening the quest dialog.\nHere you can see all current open or completed quests.\nCompleting a quest can make other quests visible.\nYou can view all current quests by clicking on a quest category on the left.",
-        "imagePath": "data/images/gui_icons.ltdb/questdialog.png",
-        "requirements": [
-          {
-            "id": "1",
-            "description": "Open the quest dialog",
-            "type": "open_dialog",
-            "dialogId": "quests"
-          }
-        ],
-        "rewards": [
-          {
-            "rewardId": "1",
-            "type": "give_items",
-            "items": [
-              {
-                "item": {
-                  "type": "Flint"
-                },
-                "count": 10
-              }
-            ]
-          }
+    {
+        "name": "Tutorial",
+        "quests": [
+            {
+                "questId": "tutorial_1",
+                "questName": "Quest Dialog",
+                "description": "Welcome to Factory Craft!\nThis is a tutorial quest to get you started.\nYou have already completed it by opening the quest dialog.\nHere you can see all current open or completed quests.\nCompleting a quest can make other quests visible.\nYou can view all current quests by clicking on a quest category on the left.",
+                "imagePath": "data/images/gui_icons.ltdb/questdialog.png",
+                "requirements": [
+                    {
+                        "id": "1",
+                        "description": "Open the quest dialog",
+                        "type": "open_dialog",
+                        "dialogId": "quests"
+                    }
+                ],
+                "rewards": [
+                    {
+                        "rewardId": "1",
+                        "type": "give_items",
+                        "items": [
+                            {
+                                "item": {
+                                    "type": "Flint"
+                                },
+                                "count": 10
+                            }
+                        ]
+                    }
+                ]
+            },
+            {
+                "questId": "tutorial_2",
+                "questName": "Inventory",
+                "description": "Your inventory shows you all the items you currently have.\nYou can open it by pressing the tab key on your keyboard.\nIn your inventory you can also combine items to to create new once.\n",
+                "imagePath": "data/images/gui_icons.ltdb/questdialog.png",
+                "requiredQuestIds": [ [ "tutorial_1" ] ],
+                "requirements": [
+                    {
+                        "id": "1",
+                        "description": "Open your inventory",
+                        "type": "open_dialog",
+                        "dialogId": "player_inventory"
+                    }
+                ],
+                "rewards": [
+                    {
+                        "rewardId": "1",
+                        "type": "give_items",
+                        "items": [
+                            {
+                                "item": {
+                                    "type": "Wooden Stick"
+                                },
+                                "count": 10
+                            }
+                        ]
+                    }
+                ]
+            }
         ]
         ]
-      },
-      {
-        "questId": "tutorial_2",
-        "questName": "Inventory",
-        "description": "Your inventory shows you all the items you currently have.\nYou can open it by pressing the tab key on your keyboard.\nIn your inventory you can also combine items to to create new once.\n",
-        "imagePath": "data/images/gui_icons.ltdb/questdialog.png",
-        "requiredQuestIds": [ [ "tutorial_1" ] ],
-        "requirements": [
-          {
-            "id": "1",
-            "description": "Open your inventory",
-            "type": "open_dialog",
-            "dialogId": "player_inventory"
-          }
-        ],
-        "rewards": [
-          {
-            "rewardId": "1",
-            "type": "give_items",
-            "items": [
-              {
-                "item": {
-                  "type": "Wooden Stick"
-                },
-                "count": 10
-              }
-            ]
-          }
-        ]
-      }
-    ]
-  }
+    }
 ]
 ]

+ 103 - 103
Windows Version/data/recipies/blocks.json

@@ -1,105 +1,105 @@
 [
 [
-  {
-    "type": "shaped",
-    "group": "inventory",
-    "width": 3,
-    "height": 3,
-    "inputs": [
-      {
-        "x": 1,
-        "y": 1,
-        "input": {
-          "filter": {
-            "type": "type",
-            "itemType": "Flint"
-          }
-        }
-      },
-      {
-        "x": 0,
-        "y": 0,
-        "input": {
-          "filter": {
-            "type": "type",
-            "itemType": "Wooden Stick"
-          }
-        }
-      },
-      {
-        "x": 0,
-        "y": 1,
-        "input": {
-          "filter": {
-            "type": "type",
-            "itemType": "Wooden Stick"
-          }
-        }
-      },
-      {
-        "x": 0,
-        "y": 2,
-        "input": {
-          "filter": {
-            "type": "type",
-            "itemType": "Wooden Stick"
-          }
-        }
-      },
-      {
-        "x": 1,
-        "y": 0,
-        "input": {
-          "filter": {
-            "type": "type",
-            "itemType": "Wooden Stick"
-          }
-        }
-      },
-      {
-        "x": 1,
-        "y": 2,
-        "input": {
-          "filter": {
-            "type": "type",
-            "itemType": "Wooden Stick"
-          }
-        }
-      },
-      {
-        "x": 2,
-        "y": 0,
-        "input": {
-          "filter": {
-            "type": "type",
-            "itemType": "Wooden Stick"
-          }
-        }
-      },
-      {
-        "x": 2,
-        "y": 1,
-        "input": {
-          "filter": {
-            "type": "type",
-            "itemType": "Wooden Stick"
-          }
-        }
-      },
-      {
-        "x": 2,
-        "y": 2,
-        "input": {
-          "filter": {
-            "type": "type",
-            "itemType": "Wooden Stick"
-          }
-        }
-      }
-    ],
-    "outputs": [
-      {
-        "itemType": "Wooden Chest"
-      }
-    ]
-  }
+    {
+        "type":"shaped",
+        "group": "inventory",
+        "width": 3,
+        "height": 3,
+        "inputs": [
+            {
+                "x": 1,
+                "y": 1,
+                "input": {
+                    "filter": {
+                        "type": "type",
+                        "itemType": "Flint"
+                    }
+                }
+            },
+            {
+                "x": 0,
+                "y": 0,
+                "input": {
+                    "filter": {
+                        "type": "type",
+                        "itemType": "Wooden Stick"
+                    }
+                }
+            },
+            {
+                "x": 0,
+                "y": 1,
+                "input": {
+                    "filter": {
+                        "type": "type",
+                        "itemType": "Wooden Stick"
+                    }
+                }
+            },
+            {
+                "x": 0,
+                "y": 2,
+                "input": {
+                    "filter": {
+                        "type": "type",
+                        "itemType": "Wooden Stick"
+                    }
+                }
+            },
+            {
+                "x": 1,
+                "y": 0,
+                "input": {
+                    "filter": {
+                        "type": "type",
+                        "itemType": "Wooden Stick"
+                    }
+                }
+            },
+            {
+                "x": 1,
+                "y": 2,
+                "input": {
+                    "filter": {
+                        "type": "type",
+                        "itemType": "Wooden Stick"
+                    }
+                }
+            },
+            {
+                "x": 2,
+                "y": 0,
+                "input": {
+                    "filter": {
+                        "type": "type",
+                        "itemType": "Wooden Stick"
+                    }
+                }
+            },
+            {
+                "x": 2,
+                "y": 1,
+                "input": {
+                    "filter": {
+                        "type": "type",
+                        "itemType": "Wooden Stick"
+                    }
+                }
+            },
+            {
+                "x": 2,
+                "y": 2,
+                "input": {
+                    "filter": {
+                        "type": "type",
+                        "itemType": "Wooden Stick"
+                    }
+                }
+            }
+        ],
+        "outputs": [
+            {
+                "itemType": "Wooden Chest"
+            }
+        ]
+    }
 ]
 ]

+ 53 - 53
Windows Version/data/recipies/tools.json

@@ -1,57 +1,57 @@
 [
 [
-  {
-    "type": "shaped",
-    "group": "inventory",
-    "width": 2,
-    "height": 3,
-    "inputs": [
-      {
-        "x": 0,
-        "y": 0,
-        "input": {
-          "filter": {
-            "type": "type",
-            "itemType": "Flint"
-          }
-        }
-      },
-      {
-        "x": 1,
-        "y": 0,
-        "input": {
-          "filter": {
-            "type": "type",
-            "itemType": "Flint"
-          }
-        }
-      },
-      {
-        "x": 1,
-        "y": 1,
-        "input": {
-          "filter": {
-            "type": "type",
-            "itemType": "Wooden Stick"
-          }
-        }
-      },
-      {
-        "x": 1,
-        "y": 2,
-        "input": {
-          "filter": {
-            "type": "type",
-            "itemType": "Wooden Stick"
-          }
-        }
-      }
-    ],
-    "outputs": [
-      {
-        "itemType": "Hoe"
-      }
-    ]
-  },
+    {
+        "type": "shaped",
+        "group": "inventory",
+        "width": 2,
+        "height": 3,
+        "inputs": [
+            {
+                "x": 0,
+                "y": 0,
+                "input": {
+                    "filter": {
+                        "type": "type",
+                        "itemType": "Flint"
+                    }
+                }
+            },
+            {
+                "x": 1,
+                "y": 0,
+                "input": {
+                    "filter": {
+                        "type": "type",
+                        "itemType": "Flint"
+                    }
+                }
+            },
+            {
+                "x": 1,
+                "y": 1,
+                "input": {
+                    "filter": {
+                        "type": "type",
+                        "itemType": "Wooden Stick"
+                    }
+                }
+            },
+            {
+                "x": 1,
+                "y": 2,
+                "input": {
+                    "filter": {
+                        "type": "type",
+                        "itemType": "Wooden Stick"
+                    }
+                }
+            }
+        ],
+        "outputs": [
+            {
+                "itemType": "Hoe"
+            }
+        ]
+    },
   {
   {
     "type": "shaped",
     "type": "shaped",
     "group": "inventory",
     "group": "inventory",