summaryrefslogtreecommitdiffstats
path: root/src/Blocks/BlockSugarCane.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/Blocks/BlockSugarCane.h')
-rw-r--r--src/Blocks/BlockSugarCane.h140
1 files changed, 140 insertions, 0 deletions
diff --git a/src/Blocks/BlockSugarCane.h b/src/Blocks/BlockSugarCane.h
new file mode 100644
index 000000000..cffe667e5
--- /dev/null
+++ b/src/Blocks/BlockSugarCane.h
@@ -0,0 +1,140 @@
+
+#pragma once
+
+#include "BlockPlant.h"
+
+
+
+
+
+class cBlockSugarCaneHandler final :
+ public cBlockPlant<false>
+{
+ using Super = cBlockPlant<false>;
+
+public:
+
+ using Super::Super;
+
+private:
+
+ virtual cItems ConvertToPickups(const NIBBLETYPE a_BlockMeta, const cItem * const a_Tool) const override
+ {
+ return cItem(E_ITEM_SUGARCANE, 1, 0);
+ }
+
+
+
+
+
+ virtual bool CanBeAt(const cChunk & a_Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta) const override
+ {
+ if (a_Position.y <= 0)
+ {
+ return false;
+ }
+
+ switch (a_Chunk.GetBlock(a_Position.addedY(-1)))
+ {
+ case E_BLOCK_DIRT:
+ case E_BLOCK_GRASS:
+ case E_BLOCK_FARMLAND:
+ case E_BLOCK_SAND:
+ {
+ static const Vector3i Coords[] =
+ {
+ {-1, -1, 0},
+ { 1, -1, 0},
+ { 0, -1, -1},
+ { 0, -1, 1},
+ } ;
+ for (size_t i = 0; i < ARRAYCOUNT(Coords); i++)
+ {
+ BLOCKTYPE BlockType;
+ NIBBLETYPE BlockMeta;
+ if (!a_Chunk.UnboundedRelGetBlock(a_Position + Coords[i], BlockType, BlockMeta))
+ {
+ // Too close to the edge, cannot simulate
+ return true;
+ }
+ if (IsBlockWater(BlockType) || (BlockType == E_BLOCK_FROSTED_ICE))
+ {
+ return true;
+ }
+ } // for i - Coords[]
+ // Not directly neighboring a water block
+ return false;
+ }
+ case E_BLOCK_SUGARCANE:
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+
+
+
+ virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
+ {
+ UNUSED(a_Meta);
+ return 7;
+ }
+
+
+
+
+
+ virtual int Grow(cChunk & a_Chunk, Vector3i a_RelPos, int a_NumStages = 1) const override
+ {
+ // Check the total height of the sugarcane blocks here:
+ int top = a_RelPos.y + 1;
+ while (
+ (top < cChunkDef::Height) &&
+ (a_Chunk.GetBlock({a_RelPos.x, top, a_RelPos.z}) == E_BLOCK_SUGARCANE)
+ )
+ {
+ ++top;
+ }
+ int bottom = a_RelPos.y - 1;
+ while (
+ (bottom > 0) &&
+ (a_Chunk.GetBlock({a_RelPos.x, bottom, a_RelPos.z}) == E_BLOCK_SUGARCANE)
+ )
+ {
+ --bottom;
+ }
+
+ // Grow by at most a_NumStages, but no more than max height:
+ auto toGrow = std::min(a_NumStages, a_Chunk.GetWorld()->GetMaxSugarcaneHeight() + 1 - (top - bottom));
+ Vector3i topPos(a_RelPos.x, top, a_RelPos.z);
+ for (int i = 0; i < toGrow; i++)
+ {
+ if (a_Chunk.GetBlock(topPos.addedY(i)) == E_BLOCK_AIR)
+ {
+ a_Chunk.SetBlock(topPos.addedY(i), E_BLOCK_SUGARCANE, 0);
+ }
+ else
+ {
+ return i;
+ }
+ } // for i
+ return toGrow;
+ }
+
+ virtual PlantAction CanGrow(cChunk & a_Chunk, Vector3i a_RelPos) const override
+ {
+ // Only allow growing if there's an air block above:
+ if (((a_RelPos.y + 1) < cChunkDef::Height) && (a_Chunk.GetBlock(a_RelPos.addedY(1)) == E_BLOCK_AIR))
+ {
+ return Super::CanGrow(a_Chunk, a_RelPos);
+ }
+ return paStay;
+ }
+} ;
+
+
+
+