瀏覽代碼

add plants to world generator

Kolja Strohm 17 小時之前
父節點
當前提交
2a275394de

+ 64 - 0
FactoryCraft/BiomGenerator.cpp

@@ -30,6 +30,10 @@ void BiomGenerator::initialize(JExpressionMemory* zMemory)
     {
         collection->initialize(zMemory);
     }
+    for (PlantConfig* plantConfig : plantConfigs)
+    {
+        plantConfig->initialize(zMemory);
+    }
     if (condition)
     {
         condition->compile(zMemory);
@@ -74,6 +78,39 @@ void BiomGenerator::generateStructures(int x,
     }
 }
 
+void BiomGenerator::generatePlants(int x,
+    int y,
+    int z,
+    int dimensionId,
+    Chunk* zChunk,
+    bool underground,
+    bool underwater,
+    int seaFluidBlockTypeId)
+{
+    PlantConfig* chosenConfig = 0;
+    double maxValue = 0.0;
+    for (PlantConfig* plantConfig : plantConfigs)
+    {
+        double value = plantConfig->doesGeneratePlant(x,
+            y,
+            z,
+            dimensionId,
+            zChunk,
+            underground,
+            underwater,
+            seaFluidBlockTypeId);
+        if (value > maxValue)
+        {
+            maxValue = value;
+            chosenConfig = plantConfig;
+        }
+    }
+    if (chosenConfig)
+    {
+        chosenConfig->generatePlantAt(x, y, z, dimensionId, zChunk);
+    }
+}
+
 void BiomGenerator::generateEntities(int x, int y, int z, int dimensionId)
 {
     for (EntityGenerator* entityGen : entityGenerators)
@@ -182,6 +219,16 @@ BiomGenerator::getEntityGenerators() const
     return entityGenerators;
 }
 
+void BiomGenerator::addPlantConfig(PlantConfig* config)
+{
+    plantConfigs.add(config);
+}
+
+const Framework::RCArray<PlantConfig>& BiomGenerator::getPlantConfigs() const
+{
+    return plantConfigs;
+}
+
 BiomGeneratorFactory::BiomGeneratorFactory()
     : ObjectTypeFactory()
 {}
@@ -218,6 +265,12 @@ BiomGenerator* BiomGeneratorFactory::fromJson(
         result->addEntityGenerator(
             Game::INSTANCE->zTypeRegistry()->fromJson<EntityGenerator>(value));
     }
+    for (Framework::JSON::JSONValue* value :
+        *zJson->asObject()->zValue("plants")->asArray())
+    {
+        result->addPlantConfig(
+            Game::INSTANCE->zTypeRegistry()->fromJson<PlantConfig>(value));
+    }
     return result;
 }
 
@@ -254,6 +307,13 @@ Framework::JSON::JSONObject* BiomGeneratorFactory::toJsonObject(
             Game::INSTANCE->zTypeRegistry()->toJson<EntityGenerator>(entity));
     }
     result->addValue("entities", entities);
+    Framework::JSON::JSONArray* plants = new Framework::JSON::JSONArray();
+    for (PlantConfig* plant : zObject->getPlantConfigs())
+    {
+        plants->addValue(
+            Game::INSTANCE->zTypeRegistry()->toJson<PlantConfig>(plant));
+    }
+    result->addValue("plants", plants);
     return result;
 }
 
@@ -277,5 +337,9 @@ JSONObjectValidationBuilder* BiomGeneratorFactory::addToValidator(
         ->withRequiredArray("entities")
         ->addAcceptedTypeInArray(
             Game::INSTANCE->zTypeRegistry()->getValidator<EntityGenerator>())
+        ->finishArray()
+        ->withRequiredArray("plants")
+        ->addAcceptedTypeInArray(
+            Game::INSTANCE->zTypeRegistry()->getValidator<PlantConfig>())
         ->finishArray();
 }

+ 12 - 3
FactoryCraft/BiomGenerator.h

@@ -8,6 +8,7 @@
 #include "GeneratorRule.h"
 #include "JNoise.h"
 #include "JsonExpression.h"
+#include "PlantConfig.h"
 #include "StructureCollection.h"
 
 class Block;
@@ -23,9 +24,7 @@ private:
     Framework::Vec3<int> minStructureOffset;
     Framework::Vec3<int> maxStructureOffset;
     Framework::RCArray<EntityGenerator> entityGenerators;
-
-protected:
-    int seed;
+    Framework::RCArray<PlantConfig> plantConfigs;
 
 public:
     BiomGenerator();
@@ -42,6 +41,14 @@ public:
         Framework::Vec3<int>& minPos,
         Framework::Vec3<int>& maxPos,
         Framework::RCArray<GeneratedStructure>* zResult);
+    void generatePlants(int x,
+        int y,
+        int z,
+        int dimensionId,
+        Chunk* zChunk,
+        bool underground,
+        bool underwater,
+        int seaFluidBlockTypeId);
     void generateEntities(int x, int y, int z, int dimensionId);
 
     const Framework::RCArray<StructureTemplateCollection>& getTemplates() const;
@@ -58,6 +65,8 @@ public:
     const Framework::RCArray<GeneratorRule>& getGeneratorRules() const;
     void addEntityGenerator(EntityGenerator* generator);
     const Framework::RCArray<EntityGenerator>& getEntityGenerators() const;
+    void addPlantConfig(PlantConfig* config);
+    const Framework::RCArray<PlantConfig>& getPlantConfigs() const;
 };
 
 class BiomGeneratorFactory : public ObjectTypeFactory<BiomGenerator>

+ 1 - 1
FactoryCraft/Block.h

@@ -15,7 +15,7 @@
 
 #define CONST_BLOCK(maybeBlock, type) \
     ((maybeBlock) ? (maybeBlock)      \
-                  : Game::INSTANCE->zBlockType((int)type)->zDefault())
+                  : Game::INSTANCE->zBlockType((int)(type))->zDefault())
 
 class ItemType;
 class Chunk;

+ 39 - 0
FactoryCraft/DimensionGenerator.cpp

@@ -380,6 +380,7 @@ Chunk* BiomedCavedDimensionGenerator::generateChunk(int centerX, int centerY)
             }
         }
     }
+    // generate cave borders
     bool generatedMore = true;
     while (generatedMore)
     {
@@ -457,6 +458,44 @@ Chunk* BiomedCavedDimensionGenerator::generateChunk(int centerX, int centerY)
             }
         }
     }
+    // generate plants
+    for (int x = -CHUNK_SIZE / 2; x < CHUNK_SIZE / 2; x++)
+    {
+        for (int y = -CHUNK_SIZE / 2; y < CHUNK_SIZE / 2; y++)
+        {
+            *xPos = (float)x + (float)centerX;
+            *yPos = (float)y + (float)centerY;
+            // calculate height layers
+            calculateHeightLayers();
+            // calculate biom
+            BiomGenerator* biom = zBiomGenerator();
+            // generate blocks
+            for (int z = (int)round(*terrainHeightP) + 1; z > 0; z--)
+            {
+                auto current = chunk->getBlockTypeAt(Framework::Vec3<int>(
+                    x + CHUNK_SIZE / 2, y + CHUNK_SIZE / 2, z));
+                auto below = chunk->getBlockTypeAt(Framework::Vec3<int>(
+                    x + CHUNK_SIZE / 2, y + CHUNK_SIZE / 2, z - 1));
+                if ((current == BlockTypeEnum::AIR
+                        || current == seaFluidBlockTypeId)
+                    && below != BlockTypeEnum::AIR
+                    && below != seaFluidBlockTypeId)
+                {
+                    *zPos = (float)z;
+                    bool underwater = current == seaFluidBlockTypeId;
+                    bool underground = z < *terrainHeightP;
+                    biom->generatePlants(x + centerX,
+                        y + centerY,
+                        z,
+                        getDimensionId(),
+                        chunk,
+                        underground,
+                        underwater,
+                        seaFluidBlockTypeId);
+                }
+            }
+        }
+    }
     caveGen->release();
     structures->release();
 #ifdef CHUNK_GENERATION_DEBUG_LOG

+ 2 - 0
FactoryCraft/FactoryCraft.vcxproj

@@ -182,6 +182,7 @@
     <ClInclude Include="NoiseInterpolator.h" />
     <ClInclude Include="OpenDialogInteractionConfig.h" />
     <ClInclude Include="PlaceableProof.h" />
+    <ClInclude Include="PlantConfig.h" />
     <ClInclude Include="Player.h" />
     <ClInclude Include="PlayerHand.h" />
     <ClInclude Include="PlayerRegister.h" />
@@ -308,6 +309,7 @@
     <ClCompile Include="NoiseInterpolator.cpp" />
     <ClCompile Include="OpenDialogInteractionConfig.cpp" />
     <ClCompile Include="PlaceableProof.cpp" />
+    <ClCompile Include="PlantConfig.cpp" />
     <ClCompile Include="Player.cpp" />
     <ClCompile Include="PlayerHand.cpp" />
     <ClCompile Include="PlayerRegister.cpp" />

+ 9 - 0
FactoryCraft/FactoryCraft.vcxproj.filters

@@ -127,6 +127,9 @@
     <Filter Include="UI\Observable">
       <UniqueIdentifier>{545fce4e-6aa4-4b61-8e95-ece0430bb029}</UniqueIdentifier>
     </Filter>
+    <Filter Include="world\generator\biom\plants">
+      <UniqueIdentifier>{5e366c8e-008c-4c5b-935e-ea58adcdc94c}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="Chunk.h">
@@ -513,6 +516,9 @@
     <ClInclude Include="RecipieGroupConfig.h">
       <Filter>inventory\recipies</Filter>
     </ClInclude>
+    <ClInclude Include="PlantConfig.h">
+      <Filter>world\generator\biom\plants</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Server.cpp">
@@ -887,5 +893,8 @@
     <ClCompile Include="RecipieGroupConfig.cpp">
       <Filter>inventory\recipies</Filter>
     </ClCompile>
+    <ClCompile Include="PlantConfig.cpp">
+      <Filter>world\generator\biom\plants</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 1 - 0
FactoryCraft/JsonExpression.cpp

@@ -1123,6 +1123,7 @@ Framework::Assembly::AssemblyBlock& JBlockTypeBoolExpression::buildAssembly(
             Framework::Assembly::R8,
             Framework::Assembly::R9},
         {});
+    codeBlock.addLoadValue(&typeId, Framework::Assembly::RCX);
     codeBlock.addCompare(Framework::Assembly::RAX,
         Framework::Assembly::RCX,
         Framework::Assembly::LOWER32);

+ 269 - 0
FactoryCraft/PlantConfig.cpp

@@ -0,0 +1,269 @@
+#include "PlantConfig.h"
+
+#include "Chunk.h"
+#include "Dimension.h"
+#include "Game.h"
+#include "JNoise.h"
+
+PlantConfig::PlantConfig()
+    : Framework::ReferenceCounter(),
+      condition(0),
+      noise(0),
+      noiseConfig(0),
+      threshold(0.0),
+      locations(0),
+      plantBlockTypeName(""),
+      plantblockTypeId(0),
+      plantHeight(0)
+{}
+
+PlantConfig::~PlantConfig()
+{
+    if (condition)
+    {
+        condition->release();
+    }
+    if (noise)
+    {
+        noise->release();
+    }
+    if (noiseConfig)
+    {
+        noiseConfig->release();
+    }
+}
+
+void PlantConfig::initialize(JExpressionMemory* zMemory)
+{
+    condition->compile(zMemory);
+    if (noise)
+    {
+        noise->release();
+    }
+    noise = JNoise::parseNoise(noiseConfig, zMemory);
+    plantblockTypeId = Game::INSTANCE->getBlockTypeId(plantBlockTypeName);
+}
+
+double PlantConfig::doesGeneratePlant(int x,
+    int y,
+    int z,
+    int dimensionId,
+    Chunk* zChunk,
+    bool underground,
+    bool underwater,
+    int seaFluidBlockTypeId)
+{
+    if (underwater && !(locations & PlantLocation::UNDERWATER))
+    {
+        return 0.0;
+    }
+    if (!underwater && underground && !(locations & PlantLocation::CAVE))
+    {
+        return 0.0;
+    }
+    if (!underwater && !underground && !(locations & PlantLocation::SURFACE))
+    {
+        return 0.0;
+    }
+    if (z + plantHeight > WORLD_HEIGHT)
+    {
+        return 0.0;
+    }
+    for (int i = 0; i < plantHeight; i++)
+    {
+        int result = zChunk->getBlockTypeAt(
+            Dimension::chunkCoordinates({x, y, z + i}));
+        if (result != BlockTypeEnum::AIR && result != seaFluidBlockTypeId)
+        {
+            return 0.0;
+        }
+    }
+    if (!condition->getValue())
+    {
+        return 0.0;
+    }
+    if (!noise)
+    {
+        return 0.0;
+    }
+    return noise->getNoise((double)x, (double)y, (double)z) - threshold;
+}
+
+void PlantConfig::generatePlantAt(
+    int x, int y, int z, int dimensionId, Chunk* zChunk)
+{
+    for (int i = 0; i < plantHeight; i++)
+    {
+        zChunk->putBlockTypeAt(
+            Dimension::chunkCoordinates({x, y, z + i}), plantblockTypeId);
+    }
+}
+
+void PlantConfig::setCondition(JBoolExpression* condition)
+{
+    if (this->condition)
+    {
+        this->condition->release();
+    }
+    this->condition = condition;
+}
+
+JBoolExpression* PlantConfig::zCondition() const
+{
+    return condition;
+}
+
+void PlantConfig::setNoiseConfig(Framework::JSON::JSONObject* noiseConfig)
+{
+    if (this->noiseConfig)
+    {
+        this->noiseConfig->release();
+    }
+    this->noiseConfig = noiseConfig;
+}
+
+Framework::JSON::JSONObject* PlantConfig::zNoiseConfig() const
+{
+    return noiseConfig;
+}
+
+void PlantConfig::setThreshold(double threshold)
+{
+    this->threshold = threshold;
+}
+
+double PlantConfig::getThreshold() const
+{
+    return threshold;
+}
+
+void PlantConfig::setLocations(int locations)
+{
+    this->locations = locations;
+}
+
+int PlantConfig::getLocations() const
+{
+    return locations;
+}
+
+void PlantConfig::setPlantBlockTypeName(Framework::Text name)
+{
+    this->plantBlockTypeName = name;
+}
+
+Framework::Text PlantConfig::getPlantBlockTypeName() const
+{
+    return plantBlockTypeName;
+}
+
+void PlantConfig::setPlantHeight(int height)
+{
+    this->plantHeight = height;
+}
+
+int PlantConfig::getPlantHeight() const
+{
+    return plantHeight;
+}
+
+PlantConfigFactory::PlantConfigFactory()
+    : ObjectTypeFactory<PlantConfig>()
+{}
+
+PlantConfig* PlantConfigFactory::fromJson(
+    Framework::JSON::JSONObject* zJson) const
+{
+    PlantConfig* config = new PlantConfig();
+    config->setCondition(
+        Game::INSTANCE->zTypeRegistry()->fromJson<JBoolExpression>(
+            zJson->zValue("condition")));
+    config->setNoiseConfig(zJson->getValue("noise")->asObject());
+    config->setThreshold(zJson->zValue("threshold")->asNumber()->getNumber());
+    config->setLocations(0);
+    Framework::JSON::JSONArray* zLocationsArray
+        = zJson->zValue("locations")->asArray();
+    for (int i = 0; i < zLocationsArray->getLength(); i++)
+    {
+        Framework::Text locationStr
+            = zLocationsArray->zValue(i)->asString()->getString();
+        if (locationStr.istGleich("CAVE"))
+        {
+            config->setLocations(config->getLocations() | PlantLocation::CAVE);
+        }
+        else if (locationStr.istGleich("UNDERWATER"))
+        {
+            config->setLocations(
+                config->getLocations() | PlantLocation::UNDERWATER);
+        }
+        else if (locationStr.istGleich("SURFACE"))
+        {
+            config->setLocations(
+                config->getLocations() | PlantLocation::SURFACE);
+        }
+    }
+    config->setPlantBlockTypeName(
+        zJson->zValue("plantBlock")->asString()->getString());
+    config->setPlantHeight(
+        (int)zJson->zValue("plantHeight")->asNumber()->getNumber());
+    return config;
+}
+
+Framework::JSON::JSONObject* PlantConfigFactory::toJsonObject(
+    PlantConfig* zObject) const
+{
+    Framework::JSON::JSONObject* zJson = new Framework::JSON::JSONObject();
+    zJson->addValue("condition",
+        Game::INSTANCE->zTypeRegistry()->toJson<JBoolExpression>(
+            zObject->zCondition()));
+    zJson->addValue("noise",
+        dynamic_cast<Framework::JSON::JSONObject*>(
+            zObject->zNoiseConfig()->getThis()));
+    zJson->addValue(
+        "threshold", new Framework::JSON::JSONNumber(zObject->getThreshold()));
+    Framework::JSON::JSONArray* zLocationsArray
+        = new Framework::JSON::JSONArray();
+    int locations = zObject->getLocations();
+    if (locations & PlantLocation::CAVE)
+    {
+        zLocationsArray->addValue(new Framework::JSON::JSONString("CAVE"));
+    }
+    if (locations & PlantLocation::UNDERWATER)
+    {
+        zLocationsArray->addValue(
+            new Framework::JSON::JSONString("UNDERWATER"));
+    }
+    if (locations & PlantLocation::SURFACE)
+    {
+        zLocationsArray->addValue(new Framework::JSON::JSONString("SURFACE"));
+    }
+    zJson->addValue("locations", zLocationsArray);
+    zJson->addValue("plantBlock",
+        new Framework::JSON::JSONString(zObject->getPlantBlockTypeName()));
+    zJson->addValue("plantHeight",
+        new Framework::JSON::JSONNumber(zObject->getPlantHeight()));
+    return zJson;
+}
+
+JSONObjectValidationBuilder* PlantConfigFactory::addToValidator(
+    JSONObjectValidationBuilder* builder) const
+{
+    return builder
+        ->withRequiredAttribute("condition",
+            Game::INSTANCE->zTypeRegistry()->getValidator<JBoolExpression>())
+        ->withRequiredAttribute("noise", JNoise::getValidator(false))
+        ->withRequiredNumber("threshold")
+        ->withDefault(0.5)
+        ->finishNumber()
+        ->withRequiredArray("locations")
+        ->addAcceptedStringInArray()
+        ->whichIsOneOf({"CAVE", "UNDERWATER", "SURFACE"})
+        ->finishString()
+        ->finishArray()
+        ->withRequiredAttribute("plantBlock",
+            Game::INSTANCE->zTypeRegistry()->getValidator<Framework::Text>(
+                BlockTypeNameFactory::TYPE_ID))
+        ->withRequiredNumber("plantHeight")
+        ->whichIsGreaterOrEqual(1)
+        ->finishNumber();
+}

+ 63 - 0
FactoryCraft/PlantConfig.h

@@ -0,0 +1,63 @@
+#pragma once
+
+#include "JsonExpression.h"
+#include "TypeRegistry.h"
+
+class PlantLocation
+{
+public:
+    static const int CAVE = 1;
+    static const int UNDERWATER = 2;
+    static const int SURFACE = 4;
+};
+
+class PlantConfig : public virtual Framework::ReferenceCounter
+{
+private:
+    JBoolExpression* condition;
+    Noise* noise;
+    Framework::JSON::JSONObject* noiseConfig;
+    double threshold;
+    int locations;
+    Framework::Text plantBlockTypeName;
+    int plantblockTypeId;
+    int plantHeight;
+
+public:
+    PlantConfig();
+    ~PlantConfig();
+    void initialize(JExpressionMemory* zMemory);
+    double doesGeneratePlant(int x,
+        int y,
+        int z,
+        int dimensionId,
+        Chunk* zChunk,
+        bool underground,
+        bool underwater,
+        int seaFluidBlockTypeId);
+    void generatePlantAt(int x, int y, int z, int dimensionId, Chunk* zChunk);
+
+    void setCondition(JBoolExpression* condition);
+    JBoolExpression* zCondition() const;
+    void setNoiseConfig(Framework::JSON::JSONObject* noiseConfig);
+    Framework::JSON::JSONObject* zNoiseConfig() const;
+    void setThreshold(double threshold);
+    double getThreshold() const;
+    void setLocations(int locations);
+    int getLocations() const;
+    void setPlantBlockTypeName(Framework::Text name);
+    Framework::Text getPlantBlockTypeName() const;
+    void setPlantHeight(int height);
+    int getPlantHeight() const;
+};
+
+class PlantConfigFactory : public ObjectTypeFactory<PlantConfig>
+{
+public:
+    PlantConfigFactory();
+    PlantConfig* fromJson(Framework::JSON::JSONObject* zJson) const override;
+    Framework::JSON::JSONObject* toJsonObject(
+        PlantConfig* zObject) const override;
+    JSONObjectValidationBuilder* addToValidator(
+        JSONObjectValidationBuilder* builder) const override;
+};

+ 2 - 0
FactoryCraft/TypeRegistry.cpp

@@ -30,6 +30,7 @@
 #include "ModelInfo.h"
 #include "OpenDialogInteractionConfig.h"
 #include "PlaceableProof.h"
+#include "PlantConfig.h"
 #include "Quest.h"
 #include "Recipie.h"
 #include "RecipieGroupConfig.h"
@@ -139,6 +140,7 @@ TypeRegistry::TypeRegistry()
     registerType(new StructureTemplateCollectionFactory());
     registerSubType(new TreeTemplateFactory());
     registerType(new EntityGeneratorFactory());
+    registerType(new PlantConfigFactory());
 
     // entities
     registerSubType(new AnimalEntityTypeFactory());

+ 4 - 4
NoiseTest/NoiseTest.vcxproj

@@ -29,26 +29,26 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v143</PlatformToolset>
+    <PlatformToolset>v145</PlatformToolset>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v143</PlatformToolset>
+    <PlatformToolset>v145</PlatformToolset>
     <WholeProgramOptimization>true</WholeProgramOptimization>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v143</PlatformToolset>
+    <PlatformToolset>v145</PlatformToolset>
     <CharacterSet>MultiByte</CharacterSet>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v143</PlatformToolset>
+    <PlatformToolset>v145</PlatformToolset>
     <WholeProgramOptimization>true</WholeProgramOptimization>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>

+ 6 - 4
Windows Version/Windows Version.vcxproj

@@ -29,26 +29,26 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v143</PlatformToolset>
+    <PlatformToolset>v145</PlatformToolset>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v143</PlatformToolset>
+    <PlatformToolset>v145</PlatformToolset>
     <WholeProgramOptimization>true</WholeProgramOptimization>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v143</PlatformToolset>
+    <PlatformToolset>v145</PlatformToolset>
     <CharacterSet>MultiByte</CharacterSet>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v143</PlatformToolset>
+    <PlatformToolset>v145</PlatformToolset>
     <WholeProgramOptimization>true</WholeProgramOptimization>
     <CharacterSet>MultiByte</CharacterSet>
   </PropertyGroup>
@@ -241,6 +241,7 @@ copy ..\..\..\..\..\Allgemein\Framework\x64\release\Framework.dll Framework.dll<
     <ClCompile Include="..\FactoryCraft\NoiseInterpolator.cpp" />
     <ClCompile Include="..\FactoryCraft\OpenDialogInteractionConfig.cpp" />
     <ClCompile Include="..\FactoryCraft\PlaceableProof.cpp" />
+    <ClCompile Include="..\FactoryCraft\PlantConfig.cpp" />
     <ClCompile Include="..\FactoryCraft\Player.cpp" />
     <ClCompile Include="..\FactoryCraft\PlayerHand.cpp" />
     <ClCompile Include="..\FactoryCraft\PlayerRegister.cpp" />
@@ -372,6 +373,7 @@ copy ..\..\..\..\..\Allgemein\Framework\x64\release\Framework.dll Framework.dll<
     <ClInclude Include="..\FactoryCraft\NoiseInterpolator.h" />
     <ClInclude Include="..\FactoryCraft\OpenDialogInteractionConfig.h" />
     <ClInclude Include="..\FactoryCraft\PlaceableProof.h" />
+    <ClInclude Include="..\FactoryCraft\PlantConfig.h" />
     <ClInclude Include="..\FactoryCraft\Player.h" />
     <ClInclude Include="..\FactoryCraft\PlayerHand.h" />
     <ClInclude Include="..\FactoryCraft\PlayerRegister.h" />

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

@@ -127,6 +127,9 @@
     <Filter Include="UI\Observable">
       <UniqueIdentifier>{0959e746-5b3e-4592-b633-8899ba10be59}</UniqueIdentifier>
     </Filter>
+    <Filter Include="world\generator\biom\plants">
+      <UniqueIdentifier>{a0c4e992-95df-42f1-8e50-bc332ce9f179}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\FactoryCraft\Server.cpp">
@@ -498,6 +501,9 @@
     <ClCompile Include="..\FactoryCraft\RecipieGroupConfig.cpp">
       <Filter>inventory\recipies</Filter>
     </ClCompile>
+    <ClCompile Include="..\FactoryCraft\PlantConfig.cpp">
+      <Filter>world\generator\biom\plants</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\FactoryCraft\Chunk.h">
@@ -887,5 +893,8 @@
     <ClInclude Include="..\FactoryCraft\RecipieGroupConfig.h">
       <Filter>inventory\recipies</Filter>
     </ClInclude>
+    <ClInclude Include="..\FactoryCraft\PlantConfig.h">
+      <Filter>world\generator\biom\plants</Filter>
+    </ClInclude>
   </ItemGroup>
 </Project>

+ 1 - 0
Windows Version/data/blocks/blockTypes.json

@@ -884,6 +884,7 @@
       ],
       "transparent": true
     },
+    "damagableByHand": true,
     "transparent": true,
     "passable": true,
     "speedModifier": 0.5,

+ 53 - 0
Windows Version/data/generator/overworld.json

@@ -451,6 +451,59 @@
                         "blockType": "Stone",
                         "topLayer": "u"
                     }
+                ],
+                "plants": [
+                    {
+                        "plantBlock": "Grass",
+                        "condition": {
+                            "blockType": "Dirt",
+                            "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
+                                    }
+                                ]
+                            }
+                        },
+                        "locations": [
+                            "SURFACE"
+                        ],
+                        "plantHeight": 1,
+                        "threshold": 0.7,
+                        "noise": {
+                            "type": "random",
+                            "seed": {
+                                "type": "operator",
+                                "operator": "+",
+                                "values": [
+                                    {
+                                        "type": "variable",
+                                        "name": "dimensionSeed"
+                                    },
+                                    {
+                                        "type": "constant",
+                                        "value": 55
+                                    }
+                                ]
+                            }
+                        }
+                    }
                 ]
             }
         ]

+ 4 - 4
assembly/assembly.vcxproj

@@ -29,26 +29,26 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v143</PlatformToolset>
+    <PlatformToolset>v145</PlatformToolset>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v143</PlatformToolset>
+    <PlatformToolset>v145</PlatformToolset>
     <WholeProgramOptimization>true</WholeProgramOptimization>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v143</PlatformToolset>
+    <PlatformToolset>v145</PlatformToolset>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v143</PlatformToolset>
+    <PlatformToolset>v145</PlatformToolset>
     <WholeProgramOptimization>true</WholeProgramOptimization>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>