Browse Source

add grass on the surface

Kolja Strohm 2 years ago
parent
commit
ec29d595c1

+ 2 - 0
FactoryCraft/BiomGenerator.h

@@ -19,6 +19,8 @@ protected:
 
 public:
     BiomGenerator();
+    virtual Framework::Either<Block*, int> generateAboveSurfaceBlock(
+        int x, int y, int z, int surfaceHeight) = 0;
     virtual Framework::Either<Block*, int> generateSurfaceBlock(
         int x, int y, int z)
         = 0;

+ 2 - 1
FactoryCraft/BlockType.h

@@ -36,8 +36,9 @@ public:
     static const int SEBLING_WOOD_BEECH = 19;
     static const int SEBLING_WOOD_PINE = 20;
     static const int TORCH = 21;
+    static const int GRASS = 22;
 
-    static const int MAX_VALUE = 21;
+    static const int MAX_VALUE = 22;
 };
 
 class BlockType : public virtual Framework::ReferenceCounter

+ 10 - 0
FactoryCraft/DimensionGenerator.cpp

@@ -219,6 +219,11 @@ Chunk* DimensionGenerator::generateChunk(int centerX, int centerY)
                     else if (z < height)
                         generated = biom->generateBelowSurfaceBlock(
                             x + centerX, y + centerY, z);
+                    else if (z >= height)
+                    {
+                        generated = biom->generateAboveSurfaceBlock(
+                            x + centerX, y + centerY, z, height);
+                    }
                     zm.messungEnde();
                     blockGenTime += zm.getSekunden();
                 }
@@ -283,6 +288,11 @@ Framework::Either<Block*, int> DimensionGenerator::generateBlock(
     else if (location.z < height)
         return biom->generateBelowSurfaceBlock(
             location.x, location.y, location.z);
+    if (location.z >= height)
+    {
+        return biom->generateAboveSurfaceBlock(
+            location.x, location.x, location.z, height);
+    }
     return BlockTypeEnum::AIR;
 }
 

+ 2 - 0
FactoryCraft/FactoryCraft.vcxproj

@@ -120,6 +120,7 @@
     <ClInclude Include="GeneratedStructure.h" />
     <ClInclude Include="GenerationTemplate.h" />
     <ClInclude Include="GrasslandBiom.h" />
+    <ClInclude Include="Grass.h" />
     <ClInclude Include="Inventory.h" />
     <ClInclude Include="Item.h" />
     <ClInclude Include="ItemEntity.h" />
@@ -182,6 +183,7 @@
     <ClCompile Include="GeneratedStructure.cpp" />
     <ClCompile Include="GenerationTemplate.cpp" />
     <ClCompile Include="GrasslandBiom.cpp" />
+    <ClCompile Include="Grass.cpp" />
     <ClCompile Include="Inventory.cpp" />
     <ClCompile Include="Item.cpp" />
     <ClCompile Include="ItemEntity.cpp" />

+ 6 - 0
FactoryCraft/FactoryCraft.vcxproj.filters

@@ -258,6 +258,9 @@
     <ClInclude Include="Tickable.h">
       <Filter>world\ticking</Filter>
     </ClInclude>
+    <ClInclude Include="Grass.h">
+      <Filter>world\blocks</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Server.cpp">
@@ -434,5 +437,8 @@
     <ClCompile Include="ShapedNoise.cpp">
       <Filter>world\generator\noise</Filter>
     </ClCompile>
+    <ClCompile Include="Grass.cpp">
+      <Filter>world\blocks</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 94 - 0
FactoryCraft/Grass.cpp

@@ -0,0 +1,94 @@
+#include "Grass.h"
+
+#include "Game.h"
+
+GrassBlock::GrassBlock(
+    int typeId, const ItemType* zTool, Framework::Vec3<int> pos)
+    : Block(typeId, zTool, pos, 0)
+{
+    tickSource = 1;
+}
+
+bool GrassBlock::onTick(TickQueue* zQueue, int numTicks, bool& blocked)
+{
+    // TODO: spread to neighbor blocks if light level is hight enought
+    return 0;
+}
+
+void GrassBlock::onPostTick() {}
+
+void GrassBlock::onDestroy()
+{
+    if (!deadAndRemoved)
+    {
+        for (int i = 0; i < 6; i++)
+        {
+            if (neighbourTypes[i] == BlockTypeEnum::NO_BLOCK)
+            {
+                Framework::Vec3<int> pos
+                    = getPos() + getDirection(getDirectionFromIndex(i));
+                Game::INSTANCE->zDimension(getDimensionId())
+                    ->placeBlock(pos,
+                        Game::INSTANCE->zGenerator()->generateSingleBlock(
+                            pos, getDimensionId()));
+            }
+        }
+        // TODO: calculate chance for dropping wheat seeds
+        for (MultiblockStructure* structure : structures)
+            structure->onBlockRemoved(this);
+        Game::INSTANCE->zDimension(getDimensionId())
+            ->placeBlock(
+                getPos(), BlockTypeEnum::AIR); // this will be deleted here
+    }
+}
+
+GrassBlockType::GrassBlockType(
+    int typeId, int itemTypeId, ModelInfo model, const char* name)
+    : BlockType(typeId, 0, model, 1, 10, 0, name),
+      itemType(itemTypeId),
+      transparent(true),
+      passable(true),
+      hardness(0.1f),
+      zTool(0),
+      speedModifier(0.5f),
+      interactable(1)
+{}
+
+void GrassBlockType::createSuperBlock(Block* zBlock, Item* zItem) const
+{
+    GrassBlock* block = dynamic_cast<GrassBlock*>(zBlock);
+    if (!block)
+        throw "GrassBlockType::createSuperBlock was called with a block "
+              "witch is not an instance of GrassBlock";
+    block->transparent = transparent;
+    block->passable = passable;
+    block->hp = (float)getInitialMaxHP();
+    block->maxHP = (float)getInitialMaxHP();
+    block->hardness = hardness;
+    block->zTool = zTool;
+    block->speedModifier = speedModifier;
+    block->interactable = interactable;
+    BlockType::createSuperBlock(zBlock, zItem);
+}
+
+void GrassBlockType::loadSuperBlock(
+    Block* zBlock, Framework::StreamReader* zReader, int dimensionId) const
+{
+    BlockType::loadSuperBlock(zBlock, zReader, dimensionId);
+}
+
+void GrassBlockType::saveSuperBlock(
+    Block* zBlock, Framework::StreamWriter* zWriter) const
+{
+    BlockType::saveSuperBlock(zBlock, zWriter);
+}
+
+Item* GrassBlockType::createItem() const
+{
+    return 0;
+}
+
+Block* GrassBlockType::createBlock(Framework::Vec3<int> position) const
+{
+    return new GrassBlock(getId(), zTool, position);
+}

+ 47 - 0
FactoryCraft/Grass.h

@@ -0,0 +1,47 @@
+#pragma once
+
+#include "Block.h"
+
+class GrassBlockType;
+
+class GrassBlock : public Block
+{
+public:
+    GrassBlock(int typeId,
+        const ItemType* zTool,
+        Framework::Vec3<int> pos);
+    virtual bool onTick(
+        TickQueue* zQueue, int numTicks, bool& blocked) override;
+    virtual void onPostTick() override;
+    virtual void onDestroy() override;
+
+    friend GrassBlockType;
+};
+
+class GrassBlockType : public BlockType
+{
+private:
+    int itemType;
+    bool transparent;
+    bool passable;
+    float hardness;
+    const ItemType* zTool;
+    float speedModifier;
+    bool interactable;
+
+protected:
+    virtual void createSuperBlock(Block* zBlock, Item* zItem) const override;
+    virtual void loadSuperBlock(Block* zBlock,
+        Framework::StreamReader* zReader,
+        int dimensionId) const override;
+    virtual void saveSuperBlock(
+        Block* zBlock, Framework::StreamWriter* zWriter) const override;
+    virtual Item* createItem() const override;
+    virtual Block* createBlock(Framework::Vec3<int> position) const override;
+
+public:
+    GrassBlockType(int typeId,
+        int itemTypeId,
+        ModelInfo model,
+        const char* name);
+};

+ 8 - 0
FactoryCraft/GrasslandBiom.cpp

@@ -41,6 +41,14 @@ GrasslandBiom::~GrasslandBiom()
     if (heightNoise) heightNoise->release();
 }
 
+Framework::Either<Block*, int> GrasslandBiom::generateAboveSurfaceBlock(
+    int x, int y, int z, int surfaceHeight)
+{
+    if (z > surfaceHeight)
+        return BlockTypeEnum::AIR;
+    return BlockTypeEnum::GRASS;
+}
+
 Framework::Either<Block*, int> GrasslandBiom::generateSurfaceBlock(
     int x, int y, int z)
 {

+ 2 - 0
FactoryCraft/GrasslandBiom.h

@@ -15,6 +15,8 @@ class GrasslandBiom : public BiomGenerator
 public:
     GrasslandBiom();
     ~GrasslandBiom();
+    Framework::Either<Block*, int> generateAboveSurfaceBlock(
+        int x, int y, int z, int surfaceHeight) override;
     Framework::Either<Block*, int> generateSurfaceBlock(
         int x, int y, int z) override;
     Framework::Either<Block*, int> generateBelowSurfaceBlock(

+ 9 - 1
FactoryCraft/ModelInfo.cpp

@@ -4,7 +4,8 @@ using namespace Framework;
 
 ModelInfo::ModelInfo(
     const char* modelPath, const char* texturPath, int textureCount)
-    : modelPath(modelPath)
+    : modelPath(modelPath),
+      transparent(1)
 {
     for (int i = 0; i < textureCount; i++)
         texturePaths.add(new Text(texturPath));
@@ -31,4 +32,11 @@ void ModelInfo::writeTo(Framework::StreamWriter* zWriter) const
         zWriter->schreibe(&len, 1);
         zWriter->schreibe(t->getText(), (int)len);
     }
+    zWriter->schreibe((char*)&transparent, 1);
+}
+
+ModelInfo& ModelInfo::setTransparent()
+{
+    transparent = 1;
+    return *this;
 }

+ 2 - 0
FactoryCraft/ModelInfo.h

@@ -9,10 +9,12 @@ class ModelInfo
 private:
     const Framework::Text modelPath;
     Framework::RCArray<Framework::Text> texturePaths;
+    bool transparent;
 
 public:
     ModelInfo(const char* modelPath, const char* texturPath, int textureCount);
     ModelInfo(
         const char* modelPath, std::initializer_list<const char*> texturePaths);
     void writeTo(Framework::StreamWriter* zWriter) const;
+    ModelInfo& setTransparent();
 };

+ 6 - 0
FactoryCraft/StaticInitializerOrder.cpp

@@ -5,6 +5,7 @@
 #include "BasicBlocks.h"
 #include "NoBlock.h"
 #include "TreeSeblingBlock.h"
+#include "Grass.h"
 // dimensions
 #include "OverworldDimension.h"
 // entities
@@ -194,6 +195,11 @@ void initializeBlockTypes()
          BlockTypeEnum::LEAVES_WOOD_PINE, "Pine Wood Sebling"))
         ->setHardness(0.1f)
         ->initializeDefault();
+    (new GrassBlockType(BlockTypeEnum::GRASS,
+         ItemTypeEnum::GRASS,
+         ModelInfo("grass", "blocks.ltdb/grass.png", 16).setTransparent(),
+         "Grass"))
+        ->initializeDefault();
 }
 
 void initializeItemTypes()