Explorar el Código

Improve Drop configuration for blocks and entities

Kolja Strohm hace 2 días
padre
commit
129e007172
Se han modificado 57 ficheros con 2430 adiciones y 1433 borrados
  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)
 {
     if (this->ai)
@@ -82,8 +47,8 @@ void Animal::tick(const Dimension* zDimension)
     Entity::tick(zDimension);
 }
 
-AnimalEntityType::AnimalEntityType(Framework::Text name, ModelInfo* model)
-    : EntityType(name, model)
+AnimalEntityType::AnimalEntityType()
+    : EntityType()
 {}
 
 AnimalEntityType::~AnimalEntityType()
@@ -111,63 +76,25 @@ Entity* AnimalEntityType::createEntity(
 {
     Animal* result = new Animal(getId(), position, dimensionId, entityId);
     result->setAI(Game::INSTANCE->zTypeRegistry()->fromJson<AnimalAI>(ai));
-    result->setSpawns(spawns);
     return result;
 }
 
 AnimalEntityTypeFactory::AnimalEntityTypeFactory()
-    : SubTypeFactory()
+    : EntityTypeFactoryBase()
 {}
 
-AnimalEntityType* AnimalEntityTypeFactory::fromJson(
+AnimalEntityType* AnimalEntityTypeFactory::createValue(
     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();
     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
@@ -178,24 +105,6 @@ const char* AnimalEntityTypeFactory::getTypeToken() const
 JSONObjectValidationBuilder* AnimalEntityTypeFactory::addToValidator(
     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
 {
 private:
-    Framework::Array<SpawnConfig> spawns;
     AnimalAI* ai;
 
-protected:
-    void onDeath() override;
-
 public:
     Animal(int typeId,
         Framework::Vec3<float> location,
         int dimensionId,
         int entityId);
     ~Animal();
-    void setSpawns(const Framework::Array<SpawnConfig>& spawnConfig);
     void setAI(AnimalAI* ai);
     bool interact(Item* zItem, Entity* zActor) override;
     void takeDamage(Entity* zSource, float damage) override;
@@ -33,7 +28,6 @@ class AnimalEntityType : public EntityType
 {
 private:
     Framework::JSON::JSONObject* ai;
-    Framework::Array<SpawnConfig> spawns;
 
 protected:
     virtual void loadSuperEntity(
@@ -42,7 +36,7 @@ protected:
         Entity* zEntity, Framework::StreamWriter* zWriter) const;
 
 public:
-    AnimalEntityType(Framework::Text name, ModelInfo* model);
+    AnimalEntityType();
     ~AnimalEntityType();
 
     Entity* createEntity(Framework::Vec3<float> position,
@@ -52,14 +46,13 @@ public:
     friend AnimalEntityTypeFactory;
 };
 
-class AnimalEntityTypeFactory
-    : public SubTypeFactory<EntityType, AnimalEntityType>
+class AnimalEntityTypeFactory : public EntityTypeFactoryBase<AnimalEntityType>
 {
 public:
     AnimalEntityTypeFactory();
-    AnimalEntityType* fromJson(
+    virtual AnimalEntityType* createValue(
         Framework::JSON::JSONObject* zJson) const override;
-    Framework::JSON::JSONObject* toJsonObject(
+    virtual void addToJson(Framework::JSON::JSONObject* zJson,
         AnimalEntityType* zObject) const override;
     JSONObjectValidationBuilder* addToValidator(
         JSONObjectValidationBuilder* builder) const override;

+ 2 - 185
FactoryCraft/BasicBlocks.cpp

@@ -208,8 +208,7 @@ Framework::JSON::JSONObject* BasicBlockTypeFactory::toJsonObject(
 JSONObjectValidationBuilder* BasicBlockTypeFactory::addToValidator(
     JSONObjectValidationBuilder* builder) const
 {
-    return BlockTypeFactoryBase::addToValidator(
-        builder
+    return BlockTypeFactoryBase::addToValidator(builder
             ->withRequiredAttribute("itemType",
                 Game::INSTANCE->zTypeRegistry()->getValidator<Framework::Text>(
                     ItemTypeNameFactory::TYPE_ID),
@@ -232,186 +231,4 @@ JSONObjectValidationBuilder* BasicBlockTypeFactory::addToValidator(
 const char* BasicBlockTypeFactory::getTypeToken() const
 {
     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;
 };
 
-struct SpawnConfig
-{
-    int min;
-    int max;
-    double chance;
-    Framework::Text itemTypeName;
-    int typeId;
-};
-
 class BasicBlockType : public BlockType
 {
 private:
@@ -79,50 +70,4 @@ public:
     virtual JSONObjectValidationBuilder* addToValidator(
         JSONObjectValidationBuilder* builder) 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>(
             zJson->asObject()->zValue("targetFilter")));
     result->setCooldownTicks((int)zJson->asObject()
-                                 ->zValue("cooldownTicks")
-                                 ->asNumber()
-                                 ->getNumber());
+            ->zValue("cooldownTicks")
+            ->asNumber()
+            ->getNumber());
     result->setReplacementBlockTypeId(
         Game::INSTANCE->getBlockTypeId(zJson->asObject()
-                                           ->zValue("replacementBlockType")
-                                           ->asString()
-                                           ->getString()));
+                ->zValue("replacementBlockType")
+                ->asString()
+                ->getString()));
     result->setCooldownTicks((int)zJson->asObject()
-                                 ->zValue("cooldownTicks")
-                                 ->asNumber()
-                                 ->getNumber());
+            ->zValue("cooldownTicks")
+            ->asNumber()
+            ->getNumber());
     result->setStaminaCost((float)zJson->asObject()
-                               ->zValue("staminaCost")
-                               ->asNumber()
-                               ->getNumber());
+            ->zValue("staminaCost")
+            ->asNumber()
+            ->getNumber());
     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")
             ->asNumber()
             ->getNumber());
     result->setDurabilityCost((float)zJson->asObject()
-                                  ->zValue("durabilityCost")
-                                  ->asNumber()
-                                  ->getNumber());
+            ->zValue("durabilityCost")
+            ->asNumber()
+            ->getNumber());
     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")
             ->asNumber()
             ->getNumber());
@@ -1068,7 +1066,7 @@ BlockReplaceItemSkill* BlockReplaceItemSkillFactory::fromJson(
         *zJson->zValue("configs")->asArray())
     {
         result->addConfig(Game::INSTANCE->zTypeRegistry()
-                              ->fromJson<BlockReplaceItemSkillConfig>(value));
+                ->fromJson<BlockReplaceItemSkillConfig>(value));
     }
     return result;
 }
@@ -1085,8 +1083,7 @@ Framework::JSON::JSONObject* BlockReplaceItemSkillFactory::toJsonObject(
         new Framework::JSON::JSONNumber(
             zObject->zInvalidUseConfig()->getStaminaCostDevider()));
     result->addValue("invalidAdditionalStaminaCostDeviderPerLevel",
-        new Framework::JSON::JSONNumber(
-            zObject->zInvalidUseConfig()
+        new Framework::JSON::JSONNumber(zObject->zInvalidUseConfig()
                 ->getAdditionalStaminaCostDeviderPerLevel()));
     result->addValue("invalidDurabilityCost",
         new Framework::JSON::JSONNumber(
@@ -1095,8 +1092,7 @@ Framework::JSON::JSONObject* BlockReplaceItemSkillFactory::toJsonObject(
         new Framework::JSON::JSONNumber(
             zObject->zInvalidUseConfig()->getDurabilityCostDevider()));
     result->addValue("invalidAdditionalDurabilityCostDeviderPerLevel",
-        new Framework::JSON::JSONNumber(
-            zObject->zInvalidUseConfig()
+        new Framework::JSON::JSONNumber(zObject->zInvalidUseConfig()
                 ->getAdditionalDurabilityCostDeviderPerLevel()));
     result->addValue("invalidCooldownTicks",
         new Framework::JSON::JSONNumber(
@@ -1143,8 +1139,7 @@ JSONObjectValidationBuilder* BlockReplaceItemSkillFactory::addToValidator(
             ->withDefault(20)
             ->finishNumber()
             ->withRequiredArray("configs")
-            ->addAcceptedTypeInArray(
-                Game::INSTANCE->zTypeRegistry()
+            ->addAcceptedTypeInArray(Game::INSTANCE->zTypeRegistry()
                     ->getValidator<BlockReplaceItemSkillConfig>())
             ->finishArray());
 }
@@ -1413,81 +1408,77 @@ DamagingItemSkillConfig* DamagingItemSkillConfigFactory::fromJson(
     result->setDamage(
         (float)zJson->asObject()->zValue("damage")->asNumber()->getNumber());
     result->setDamagePerHeadHardness((float)zJson->asObject()
-                                         ->zValue("damagePerHeadHardness")
-                                         ->asNumber()
-                                         ->getNumber());
+            ->zValue("damagePerHeadHardness")
+            ->asNumber()
+            ->getNumber());
     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")
             ->asNumber()
             ->getNumber());
     result->setDamagePerLevel((float)zJson->asObject()
-                                  ->zValue("damagePerLevel")
-                                  ->asNumber()
-                                  ->getNumber());
+            ->zValue("damagePerLevel")
+            ->asNumber()
+            ->getNumber());
     result->setDamageMultiplierPerLevel((float)zJson->asObject()
-                                            ->zValue("damageMultiplierPerLevel")
-                                            ->asNumber()
-                                            ->getNumber());
+            ->zValue("damageMultiplierPerLevel")
+            ->asNumber()
+            ->getNumber());
     result->setDamageDevider((float)zJson->asObject()
-                                 ->zValue("damageDevider")
-                                 ->asNumber()
-                                 ->getNumber());
+            ->zValue("damageDevider")
+            ->asNumber()
+            ->getNumber());
     result->setDamageDeviderPerHardness((float)zJson->asObject()
-                                            ->zValue("damageDeviderPerHardness")
-                                            ->asNumber()
-                                            ->getNumber());
+            ->zValue("damageDeviderPerHardness")
+            ->asNumber()
+            ->getNumber());
     result->setStaminaCost((float)zJson->asObject()
-                               ->zValue("staminaCost")
-                               ->asNumber()
-                               ->getNumber());
+            ->zValue("staminaCost")
+            ->asNumber()
+            ->getNumber());
     result->setStaminaCostPerDamage((float)zJson->asObject()
-                                        ->zValue("staminaCostPerDamage")
-                                        ->asNumber()
-                                        ->getNumber());
+            ->zValue("staminaCostPerDamage")
+            ->asNumber()
+            ->getNumber());
     result->setStaminaCostPerHardness((float)zJson->asObject()
-                                          ->zValue("staminaCostPerHardness")
-                                          ->asNumber()
-                                          ->getNumber());
+            ->zValue("staminaCostPerHardness")
+            ->asNumber()
+            ->getNumber());
     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")
             ->asNumber()
             ->getNumber());
     result->setDurabilityCost((float)zJson->asObject()
-                                  ->zValue("durabilityCost")
-                                  ->asNumber()
-                                  ->getNumber());
+            ->zValue("durabilityCost")
+            ->asNumber()
+            ->getNumber());
     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")
             ->asNumber()
             ->getNumber());
     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")
             ->asNumber()
             ->getNumber());
     result->setXpGainPerDamage((float)zJson->asObject()
-                                   ->zValue("xpGainPerDamage")
-                                   ->asNumber()
-                                   ->getNumber());
+            ->zValue("xpGainPerDamage")
+            ->asNumber()
+            ->getNumber());
     return result;
 }
 
@@ -1708,7 +1699,7 @@ bool DamagingItemSkill::use(Entity* zActor, Item* zUsedItem, Block* zTarget)
     }
     zActor->setStamina(zActor->getStamina() - staminaCost);
     setXp(getXp() + usedConfig->getXpGainPerDamage() * damage);
-    zTarget->setHP(zTarget->getHP() - damage);
+    zTarget->setHP(zActor, zUsedItem, this, zTarget->getHP() - damage);
     return true;
 }
 
@@ -1831,8 +1822,7 @@ Framework::JSON::JSONObject* DamagingItemSkillFactory::toJsonObject(
         new Framework::JSON::JSONNumber(
             zObject->zInvalidUseConfig()->getDurabilityCostDevider()));
     result->addValue("invalidDurabilityCostDeviderPerLevel",
-        new Framework::JSON::JSONNumber(
-            zObject->zInvalidUseConfig()
+        new Framework::JSON::JSONNumber(zObject->zInvalidUseConfig()
                 ->getAdditionalDurabilityCostDeviderPerLevel()));
     Framework::JSON::JSONArray* configs = new Framework::JSON::JSONArray();
     for (DamagingItemSkillConfig* config : zObject->getConfigs())
@@ -1881,8 +1871,7 @@ JSONObjectValidationBuilder* DamagingItemSkillFactory::addToValidator(
             ->withDefault(0.02)
             ->finishNumber()
             ->withRequiredArray("configs")
-            ->addAcceptedTypeInArray(
-                Game::INSTANCE->zTypeRegistry()
+            ->addAcceptedTypeInArray(Game::INSTANCE->zTypeRegistry()
                     ->getValidator<DamagingItemSkillConfig>())
             ->finishArray());
 }

+ 10 - 10
FactoryCraft/Block.cpp

@@ -36,7 +36,7 @@ Block::Block(
 
 Block::~Block() {}
 
-void Block::onDestroy()
+void Block::onDestroy(Entity* zActor, Item* zUsedItem, ItemSkill* zUsedSkill)
 {
     if (!deadAndRemoved)
     {
@@ -56,17 +56,16 @@ void Block::onDestroy()
                 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;
         for (MultiblockStructure* structure : structures)
-            structure->onBlockRemoved(this);
+            structure->onBlockRemoved(zActor, zUsedItem, zUsedSkill, this);
         Game::INSTANCE->zDimension(dimensionId)
             ->placeBlock(
                 getPos(), BlockTypeEnum::AIR); // this will be deleted here
@@ -325,13 +324,14 @@ bool Block::isVisible() const
     return 0;
 }
 
-void Block::setHP(float hp)
+void Block::setHP(
+    Entity* zActor, Item* zUsedItem, ItemSkill* zUsedSkill, float hp)
 {
     bool isDead = this->hp == 0.f;
     this->hp = MAX(0.f, hp);
     if (!isDead && this->hp == 0.f)
     {
-        onDestroy(); // this will be deleted
+        onDestroy(zActor, zUsedItem, zUsedSkill); // this will be deleted
     }
     else
     {

+ 4 - 2
FactoryCraft/Block.h

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

+ 15 - 1
FactoryCraft/BlockType.cpp

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

+ 39 - 1
FactoryCraft/BlockType.h

@@ -5,6 +5,7 @@
 #include <Vec3.h>
 #include <Writer.h>
 
+#include "DropConfig.h"
 #include "ModelInfo.h"
 
 class Item;
@@ -33,6 +34,7 @@ private:
     Block* defaultBlock;
     Framework::RCArray<Framework::Text> groupNames;
     float hardness;
+    Framework::RCArray<DropConfig> dropConfigs;
 
 protected:
     BlockType();
@@ -52,6 +54,8 @@ protected:
 public:
     virtual bool initialize(Game* zGame);
     BlockType* initializeDefault();
+    void addDropConfig(DropConfig* config);
+    const Framework::RCArray<DropConfig>& getDropConfigs() const;
     virtual const Block* zDefault() const;
 
     virtual ItemType* createItemType() const = 0;
@@ -130,6 +134,13 @@ public:
         zType->setGroupNames(groupNames);
         zType->setHardness(
             (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;
     }
 
@@ -160,6 +171,13 @@ public:
             groupNames->addValue(new Framework::JSON::JSONString(*groupName));
         }
         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(
             "hardness", new Framework::JSON::JSONNumber(zType->getHardness()));
         return result;
@@ -168,6 +186,18 @@ public:
     virtual JSONObjectValidationBuilder* addToValidator(
         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
             ->withRequiredAttribute("model",
                 Game::INSTANCE->zTypeRegistry()->getValidator<ModelInfo>())
@@ -194,7 +224,15 @@ public:
             ->finishArray()
             ->withRequiredNumber("hardness")
             ->withDefault(1.0)
-            ->finishNumber();
+            ->finishNumber()
+            ->withRequiredAttribute("drops",
+                Framework::Validator::DataValidator::buildForArray()
+                    ->addAcceptedTypeInArray(Game::INSTANCE->zTypeRegistry()
+                            ->getValidator<DropConfig>())
+                    ->withDefault(defaultDrops)
+                    ->finishArray(),
+                false,
+                true);
     }
 
 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)
 {
     if (dialogId.istGleich(getDialogId()))

+ 0 - 1
FactoryCraft/Chest.h

@@ -8,7 +8,6 @@ private:
     bool open;
     int userEntityId;
 
-    virtual void onDestroy() override;
     virtual void onDialogClosed(Framework::Text dialogId) override;
     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 "Dimension.h"
+#include "EntityType.h"
 #include "Game.h"
 #include "ItemSkill.h"
 #include "ItemStack.h"
@@ -230,10 +231,14 @@ Entity::Entity(
       placeBlockCooldown(0)
 {}
 
-void Entity::onDeath()
+void Entity::onDeath(Entity* zActor, Item* zUsedItem, ItemSkill* zUsedSkill)
 {
     if (!removed)
     {
+        for (DropConfig* config : zType()->getDropConfigs())
+        {
+            config->onObjectDestroyed(zActor, zUsedItem, zUsedSkill, this);
+        }
         Dimension* dim = Game::INSTANCE->zDimension(dimensionId);
         if (dim)
         {
@@ -751,7 +756,7 @@ void Entity::onFall(float collisionSpeed)
 {
     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
 }
 
-void Entity::setHP(float hp)
+void Entity::setHP(
+    Entity* zActor, Item* zUsedItem, ItemSkill* zUsedSkill, float hp)
 {
     currentHP = MIN(MAX(hp, 0), maxHP);
     NetworkMessage* msg = new NetworkMessage();
@@ -782,7 +788,7 @@ void Entity::setHP(float hp)
     notifyStatusBarObservers(msg);
     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>>
         statusBarObservers;
 
-    virtual void onDeath();
+    virtual void onDeath(
+        Entity* zActor, Item* zUsedItem, ItemSkill* zUsedSkill);
     virtual bool useItem(int typeId, ItemStack* zStack, bool left);
     Entity(int typeId,
         Framework::Vec3<float> location,
@@ -113,7 +114,8 @@ public:
     void setChatSecurityLevel(int level);
     void setPosition(Framework::Vec3<float> pos);
     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 setHunger(float hunger);
     void setThirst(float thirst);

+ 28 - 3
FactoryCraft/EntityType.cpp

@@ -4,10 +4,10 @@
 #include "Game.h"
 #include "ItemType.h"
 
-EntityType::EntityType(Framework::Text name, ModelInfo* model)
+EntityType::EntityType()
     : ReferenceCounter(),
-      name(name),
-      model(model),
+      name(""),
+      model(0),
       id(-1)
 {}
 
@@ -99,9 +99,34 @@ void EntityType::createSuperEntity(Entity* zEntity) const {}
 
 bool EntityType::initialize(Game* zGame)
 {
+    for (DropConfig* config : dropConfigs)
+    {
+        config->initialize();
+    }
     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* entity = createEntity(Framework::Vec3<float>(0, 0, 0), 0, 0);

+ 79 - 7
FactoryCraft/EntityType.h

@@ -5,6 +5,7 @@
 #include <Vec3.h>
 #include <Writer.h>
 
+#include "DropConfig.h"
 #include "ModelInfo.h"
 
 class Entity;
@@ -22,10 +23,11 @@ class EntityType : public virtual Framework::ReferenceCounter
 private:
     Framework::Text name;
     int id;
-    ModelInfo *model;
+    ModelInfo* model;
+    Framework::RCArray<DropConfig> dropConfigs;
 
 protected:
-    EntityType(Framework::Text name, ModelInfo* model);
+    EntityType();
     ~EntityType();
 
     virtual void loadSuperEntity(
@@ -35,18 +37,88 @@ protected:
     virtual void createSuperEntity(Entity* zEntity) const;
 
 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 void saveEntity(
         Entity* zEntity, Framework::StreamWriter* zWriter) const;
     virtual Entity* createEntityAt(
         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;
     ModelInfo* zModel() const;
     void setTypeId(int id);
     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="BlockInstanceGeneratorRule.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="FactorizeNoise.h" />
     <ClInclude Include="FlattenNoise.h" />
@@ -228,10 +235,16 @@
     <ClCompile Include="Chunk.cpp" />
     <ClCompile Include="ChunkMap.cpp" />
     <ClCompile Include="CraftingStorage.cpp" />
+    <ClCompile Include="DefaultBlockItemDrop.cpp" />
+    <ClCompile Include="DefaultInventoryDrop.cpp" />
     <ClCompile Include="Dimension.cpp" />
     <ClCompile Include="DimensionGenerator.cpp" />
     <ClCompile Include="DimensionMap.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="EntityGenerator.cpp" />
     <ClCompile Include="EntityType.cpp" />
@@ -289,6 +302,8 @@
     <ClCompile Include="ScaleNoise.cpp" />
     <ClCompile Include="Server.cpp" />
     <ClCompile Include="ShapedNoise.cpp" />
+    <ClCompile Include="SpecificItemDrop.cpp" />
+    <ClCompile Include="SpecificItemDrop.h" />
     <ClCompile Include="Start.cpp" />
     <ClCompile Include="StructureCollection.cpp" />
     <ClCompile Include="TickOrganizer.cpp" />

+ 54 - 0
FactoryCraft/FactoryCraft.vcxproj.filters

@@ -106,6 +106,15 @@
     <Filter Include="world\generator\biom\entityGenerator">
       <UniqueIdentifier>{1c0b5b43-9fe2-496d-bcfc-b51005126d2a}</UniqueIdentifier>
     </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>
     <ClInclude Include="Chunk.h">
@@ -423,6 +432,27 @@
     <ClInclude Include="ItemTypeNameFactory.h">
       <Filter>server\config</Filter>
     </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>
     <ClCompile Include="Server.cpp">
@@ -725,5 +755,29 @@
     <ClCompile Include="ItemTypeNameFactory.cpp">
       <Filter>server\config</Filter>
     </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>
 </Project>

+ 1 - 1
FactoryCraft/FluidBlock.cpp

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

+ 15 - 18
FactoryCraft/FluidContainer.cpp

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

+ 2 - 1
FactoryCraft/GeneratorRule.h

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

+ 3 - 1
FactoryCraft/GeneratorTemplate.h

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

+ 9 - 10
FactoryCraft/Grass.cpp

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

+ 3 - 3
FactoryCraft/Grass.h

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

+ 7 - 5
FactoryCraft/ItemEntity.cpp

@@ -19,7 +19,7 @@ ItemEntity::ItemEntity(
     maxStamina = 10;
     maxHunger = 10;
     maxThirst = 10;
-    setHP(10);
+    setHP(0, 0, 0, 10.f);
     setStamina(10);
     setHunger(10);
     setThirst(10);
@@ -71,7 +71,7 @@ void ItemEntity::tick(const Dimension* zDimension)
             // add items of this entity to the other entity
             zOther->interactWith(this, NO_DIRECTION)
                 .pullItems(slot->getNumberOfItems(), 0);
-            if (slot->getNumberOfItems() == 0) onDeath();
+            if (slot->getNumberOfItems() == 0) onDeath(0, 0, 0);
         }
     }
     Entity::tick(zDimension);
@@ -79,7 +79,7 @@ void ItemEntity::tick(const Dimension* zDimension)
 
 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
@@ -95,8 +95,10 @@ ModelInfo* ItemEntity::zSpecialModel() const
 }
 
 ItemEntityType::ItemEntityType()
-    : EntityType("Item", 0)
-{}
+    : EntityType()
+{
+    setName("Item");
+}
 
 Entity* ItemEntityType::createEntity(
     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);
 }
 
-void MultiblockStructure::onBlockRemoved(Block* zBlock)
+void MultiblockStructure::onBlockRemoved(
+    Entity* zActor, Item* zUsedItem, ItemSkill* zUsedSkill, Block* zBlock)
 {
     for (auto i = memberBlockPositions.begin(); i; ++i)
     {

+ 5 - 1
FactoryCraft/MultiblockStructure.h

@@ -8,6 +8,9 @@
 
 class MultiblockStructureType;
 class Block;
+class Entity;
+class Item;
+class ItemSkill;
 
 class MultiblockStructureEnum
 {
@@ -38,7 +41,8 @@ public:
     void onBlockLoaded(Block* block);
     void onBlockUnloaded(Block* zBlock);
     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 isFullyLoaded() const;

+ 9 - 5
FactoryCraft/MultiblockTree.cpp

@@ -6,15 +6,19 @@ using namespace Framework;
 
 MultiblockTree::MultiblockTree(
     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))
     {
-        MultiblockStructure::onBlockRemoved(zBlock);
+        MultiblockStructure::onBlockRemoved(
+            zActor, zUsedItem, zUsedSkill, zBlock);
         for (int d = 4; d >= 0; d--)
         {
             bool foundStablizer = 0;
@@ -66,7 +70,7 @@ void MultiblockTree::onBlockRemoved(Block* zBlock)
             if (!foundStablizer)
             {
                 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,
         __int64 structureId,
         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

+ 9 - 9
FactoryCraft/Player.cpp

@@ -31,7 +31,7 @@ Player::Player(Framework::Vec3<float> location, int dimensionId, int entityId)
     maxStamina = 10;
     maxHunger = 10;
     maxThirst = 10;
-    setHP(10);
+    setHP(0, 0, 0, 10.f);
     setStamina(10);
     setHunger(10);
     setThirst(10);
@@ -367,21 +367,21 @@ void Player::onFall(float collisionSpeed)
     // 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(
         name + " died!", Chat::CHANNEL_INFO);
     // TODO: respown
 }
 
 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(
     Entity* zEntity, Framework::StreamReader* zReader) const

+ 2 - 1
FactoryCraft/Player.h

@@ -42,7 +42,8 @@ public:
     void playerApi(
         Framework::StreamReader* zRequest, NetworkMessage* zResponse);
     void onFall(float collisionSpeed) override;
-    void onDeath() override;
+    void onDeath(
+        Entity* zActor, Item* zUsedItem, ItemSkill* zUsedSkill) override;
 
     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)
         {
             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
         {
             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

+ 1 - 6
FactoryCraft/QuestRequirement.cpp

@@ -131,12 +131,7 @@ JSONObjectValidationBuilder* QuestRequirementOpenDialogType::addToValidator(
     JSONObjectValidationBuilder* builder) const
 {
     return QuestRequirementFactoryBase::addToValidator(
-        builder->withRequiredString("id")
-            ->finishString()
-            ->withRequiredString("description")
-            ->finishString()
-            ->withRequiredString("dialogId")
-            ->finishString());
+        builder->withRequiredString("dialogId")->finishString());
 }
 
 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* builder) const
 {
-    return GeneratorTemplateFactory::addToValidator(
-        builder
+    return GeneratorTemplateFactory::addToValidator(builder
             ->withRequiredAttribute("wood",
                 Game::INSTANCE->zTypeRegistry()->getValidator<Framework::Text>(
                     BlockTypeNameFactory::TYPE_ID))
@@ -170,9 +169,6 @@ JSONObjectValidationBuilder* TreeTemplateFactory::addToValidator(
             ->finishNumber()
             ->withRequiredNumber("maxSize")
             ->whichIsGreaterThen(0)
-            ->finishNumber()
-            ->withRequiredNumber("propability")
-            ->whichIsGreaterThen(0)
             ->finishNumber());
 }
 

+ 18 - 1
FactoryCraft/TypeRegistry.cpp

@@ -10,8 +10,13 @@
 #include "BlockInstanceGeneratorRule.h"
 #include "BlockTypeGeneratorRule.h"
 #include "Chest.h"
+#include "DefaultBlockItemDrop.h"
+#include "DefaultInventoryDrop.h"
 #include "Dimension.h"
 #include "DimensionGenerator.h"
+#include "DropChanceCondition.h"
+#include "DropConditionOperator.h"
+#include "DropUsedItemCondition.h"
 #include "FluidBlock.h"
 #include "FluidContainer.h"
 #include "GeneratorRule.h"
@@ -23,6 +28,7 @@
 #include "PlaceableProof.h"
 #include "Quest.h"
 #include "Recipie.h"
+#include "SpecificItemDrop.h"
 #include "TreeSeblingBlock.h"
 #include "TreeTemplate.h"
 
@@ -43,7 +49,6 @@ TypeRegistry::TypeRegistry()
     // block types
     registerType(new ModelInfoFactory());
     registerSubType(new BasicBlockTypeFactory());
-    registerSubType(new AdditionalItemSpawningBlockTypeFactory());
     registerSubType(new BasicLightSourceBlockTypeFactory());
     registerSubType(new ChestBlockTypeFactory());
     registerSubType(new FluidBlockTypeFactory());
@@ -123,6 +128,18 @@ TypeRegistry::TypeRegistry()
 
     // entities
     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

+ 3 - 3
FactoryCraft/TypeRegistry.h

@@ -405,8 +405,8 @@ public:
         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
             = parsableTypes.z(typeId, typeId.getLength());
@@ -416,7 +416,7 @@ public:
                 << 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>

+ 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\ChunkMap.cpp" />
     <ClCompile Include="..\FactoryCraft\CraftingStorage.cpp" />
+    <ClCompile Include="..\FactoryCraft\DefaultBlockItemDrop.cpp" />
+    <ClCompile Include="..\FactoryCraft\DefaultInventoryDrop.cpp" />
     <ClCompile Include="..\FactoryCraft\Dimension.cpp" />
     <ClCompile Include="..\FactoryCraft\DimensionGenerator.cpp" />
     <ClCompile Include="..\FactoryCraft\DimensionMap.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\EntityGenerator.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\Server.cpp" />
     <ClCompile Include="..\FactoryCraft\ShapedNoise.cpp" />
+    <ClCompile Include="..\FactoryCraft\SpecificItemDrop.cpp" />
     <ClCompile Include="..\FactoryCraft\Start.cpp" />
     <ClCompile Include="..\FactoryCraft\StructureCollection.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\BlockInstanceGeneratorRule.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\FactorizeNoise.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\Dimension.h" />
     <ClInclude Include="..\FactoryCraft\ShapedNoise.h" />
+    <ClInclude Include="..\FactoryCraft\SpecificItemDrop.h" />
     <ClInclude Include="..\FactoryCraft\StructureCollection.h" />
     <ClInclude Include="..\FactoryCraft\Tickable.h" />
     <ClInclude Include="..\FactoryCraft\TickOrganizer.h" />

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

@@ -106,6 +106,15 @@
     <Filter Include="world\generator\biom\entityGenerator">
       <UniqueIdentifier>{87911234-37d0-41ac-975c-329d2963ca52}</UniqueIdentifier>
     </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>
     <ClCompile Include="..\FactoryCraft\Server.cpp">
@@ -408,6 +417,27 @@
     <ClCompile Include="..\FactoryCraft\ItemTypeNameFactory.cpp">
       <Filter>server\config</Filter>
     </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>
     <ClInclude Include="..\FactoryCraft\Chunk.h">
@@ -725,5 +755,29 @@
     <ClInclude Include="..\FactoryCraft\ItemTypeNameFactory.h">
       <Filter>server\config</Filter>
     </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>
 </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",
-                    "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",
-                    "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",
                 "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",
                     "operator": "-",
                     "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",
     "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",
     "group": "inventory",