summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--source/cChunk.cpp158
-rw-r--r--source/cChunk.h3
-rw-r--r--source/cChunkMap.cpp17
-rw-r--r--source/cChunkMap.h3
-rw-r--r--source/cClientHandle.cpp5
-rw-r--r--source/cWorld.cpp6
6 files changed, 132 insertions, 60 deletions
diff --git a/source/cChunk.cpp b/source/cChunk.cpp
index aaef14cf3..1b70e84d1 100644
--- a/source/cChunk.cpp
+++ b/source/cChunk.cpp
@@ -567,10 +567,11 @@ void cChunk::TickBlocks(MTRand & a_TickRandom)
break;
}
- case E_BLOCK_GRASS: TickGrass(m_BlockTickX, m_BlockTickY, m_BlockTickZ, a_TickRandom); break;
+ case E_BLOCK_GRASS: TickGrass (m_BlockTickX, m_BlockTickY, m_BlockTickZ, a_TickRandom); break;
case E_BLOCK_PUMPKIN_STEM:
case E_BLOCK_MELON_STEM: TickMelonPumpkin(m_BlockTickX, m_BlockTickY, m_BlockTickZ, Index, ID, a_TickRandom); break;
- case E_BLOCK_FARMLAND: TickFarmland(m_BlockTickX, m_BlockTickY, m_BlockTickZ); break;
+ case E_BLOCK_FARMLAND: TickFarmland (m_BlockTickX, m_BlockTickY, m_BlockTickZ); break;
+ case E_BLOCK_SUGARCANE: GrowSugarcane (m_BlockTickX, m_BlockTickY, m_BlockTickZ, 1); break;
case E_BLOCK_SAPLING:
{
@@ -666,6 +667,76 @@ void cChunk::TickMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, int a_BlockIdx
+void cChunk::TickFarmland(int a_RelX, int a_RelY, int a_RelZ)
+{
+ // TODO: Rain hydrates blocks, too. Check world weather, don't search for water if raining.
+
+ // Search for water in a close proximity:
+ // Ref.: http://www.minecraftwiki.net/wiki/Farmland#Hydrated_Farmland_Tiles
+ bool Found = false;
+ for (int y = a_RelY; y <= a_RelY + 1; y++)
+ {
+ for (int z = a_RelZ - 4; z <= a_RelZ + 4; z++)
+ {
+ for (int x = a_RelX - 4; x <= a_RelX + 4; x++)
+ {
+ BLOCKTYPE BlockType;
+ NIBBLETYPE Meta; // unused
+
+ if (!UnboundedRelGetBlock(x, y, z, BlockType, Meta))
+ {
+ // Too close to an unloaded chunk, we might miss a water block there, so don't tick at all
+ return;
+ }
+ if (
+ (BlockType == E_BLOCK_WATER) ||
+ (BlockType == E_BLOCK_STATIONARY_WATER)
+ )
+ {
+ Found = true;
+ break;
+ }
+ } // for x
+ if (Found)
+ {
+ break;
+ }
+ } // for z
+ if (Found)
+ {
+ break;
+ }
+ } // for y
+
+ NIBBLETYPE BlockMeta = GetMeta(a_RelX, a_RelY, a_RelZ);
+
+ if (Found)
+ {
+ // Water was found, hydrate the block until hydration reaches 7:
+ if (BlockMeta < 7)
+ {
+ FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_FARMLAND, ++BlockMeta);
+ }
+ return;
+ }
+
+ // Water wasn't found, de-hydrate block:
+ if (BlockMeta > 0)
+ {
+ FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_FARMLAND, --BlockMeta);
+ return;
+ }
+
+ // Farmland too dry. Turn back to dirt:
+ FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_DIRT, 0);
+
+ // TODO: Uproot whatever was growing on top:
+}
+
+
+
+
+
void cChunk::GrowMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, MTRand & a_TickRandom)
{
// Convert the stem BlockType into produce BlockType
@@ -745,70 +816,37 @@ void cChunk::GrowMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_Bl
-void cChunk::TickFarmland(int a_RelX, int a_RelY, int a_RelZ)
+void cChunk::GrowSugarcane(int a_RelX, int a_RelY, int a_RelZ, int a_NumBlocks)
{
- // TODO: Rain hydrates blocks, too. Check world weather, don't search for water if raining.
-
- // Search for water in a close proximity:
- // Ref.: http://www.minecraftwiki.net/wiki/Farmland#Hydrated_Farmland_Tiles
- bool Found = false;
- for (int y = a_RelY; y <= a_RelY + 1; y++)
- {
- for (int z = a_RelZ - 4; z <= a_RelZ + 4; z++)
- {
- for (int x = a_RelX - 4; x <= a_RelX + 4; x++)
- {
- BLOCKTYPE BlockType;
- NIBBLETYPE Meta; // unused
-
- if (!UnboundedRelGetBlock(x, y, z, BlockType, Meta))
- {
- // Too close to an unloaded chunk, we might miss a water block there, so don't tick at all
- return;
- }
- if (
- (BlockType == E_BLOCK_WATER) ||
- (BlockType == E_BLOCK_STATIONARY_WATER)
- )
- {
- Found = true;
- break;
- }
- } // for x
- if (Found)
- {
- break;
- }
- } // for z
- if (Found)
- {
- break;
- }
- } // for y
-
- NIBBLETYPE BlockMeta = GetMeta(a_RelX, a_RelY, a_RelZ);
-
- if (Found)
+ // Check the total height of the sugarcane blocks here:
+ int Top = a_RelY + 1;
+ while (
+ (Top < cChunkDef::Height) &&
+ (GetBlock(a_RelX, Top, a_RelZ) == E_BLOCK_SUGARCANE)
+ )
{
- // Water was found, hydrate the block until hydration reaches 7:
- if (BlockMeta < 7)
- {
- FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_FARMLAND, ++BlockMeta);
- }
- return;
+ ++Top;
}
-
- // Water wasn't found, de-hydrate block:
- if (BlockMeta > 0)
+ int Bottom = a_RelY - 1;
+ while (
+ (Bottom > 0) &&
+ (GetBlock(a_RelX, Bottom, a_RelZ) == E_BLOCK_SUGARCANE)
+ )
{
- FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_FARMLAND, --BlockMeta);
- return;
+ --Bottom;
}
- // Farmland too dry. Turn back to dirt:
- FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_DIRT, 0);
-
- // TODO: Uproot whatever was growing on top:
+ // Grow by at most a_NumBlocks, but no more than height 3:
+ int ToGrow = std::min(a_NumBlocks, 4 - (Top - Bottom));
+ for (int i = 0; i < ToGrow; i++)
+ {
+ BLOCKTYPE BlockType;
+ NIBBLETYPE BlockMeta;
+ if (UnboundedRelGetBlock(a_RelX, Top + i, a_RelZ, BlockType, BlockMeta) && (BlockType == E_BLOCK_AIR))
+ {
+ UnboundedRelFastSetBlock(a_RelX, Top + i, a_RelZ, E_BLOCK_SUGARCANE, 0);
+ }
+ } // for i
}
diff --git a/source/cChunk.h b/source/cChunk.h
index 3c01b08e5..d5bc5675e 100644
--- a/source/cChunk.h
+++ b/source/cChunk.h
@@ -235,6 +235,9 @@ private:
void TickMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, int a_BlockIdx, BLOCKTYPE a_BlockType, MTRand & a_TickRandom);
void TickFarmland (int a_RelX, int a_RelY, int a_RelZ);
+ /// Grows sugarcane by the specified number of blocks, but no more than 3 blocks high (used by both bonemeal and ticking)
+ void GrowSugarcane (int a_RelX, int a_RelY, int a_RelZ, int a_NumBlocks);
+
/// Grows a melon or a pumpkin next to the block specified (assumed to be the stem)
void GrowMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, MTRand & a_Random);
diff --git a/source/cChunkMap.cpp b/source/cChunkMap.cpp
index 1638e2b06..6938c1cb7 100644
--- a/source/cChunkMap.cpp
+++ b/source/cChunkMap.cpp
@@ -1101,6 +1101,23 @@ void cChunkMap::GrowMelonPumpkin(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCK
+void cChunkMap::GrowSugarcane(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBlocksToGrow)
+{
+ int ChunkX, ChunkZ;
+ cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ);
+
+ cCSLock Lock(m_CSLayers);
+ cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ);
+ if (Chunk != NULL)
+ {
+ Chunk->GrowSugarcane(a_BlockX, a_BlockY, a_BlockZ, a_NumBlocksToGrow);
+ }
+}
+
+
+
+
+
void cChunkMap::SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ)
{
int ChunkX, ChunkZ;
diff --git a/source/cChunkMap.h b/source/cChunkMap.h
index da5a5066f..69f0f3830 100644
--- a/source/cChunkMap.h
+++ b/source/cChunkMap.h
@@ -154,6 +154,9 @@ public:
/// Grows a melon or a pumpkin next to the block specified (assumed to be the stem)
void GrowMelonPumpkin(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, MTRand & a_Rand);
+ /// Grows a sugarcane present at the block specified by the amount of blocks specified, up to the max height of 3
+ void GrowSugarcane(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBlocksToGrow);
+
/// Sets the blockticking to start at the specified block. Only one blocktick per chunk may be set, second call overwrites the first call
void SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ);
diff --git a/source/cClientHandle.cpp b/source/cClientHandle.cpp
index 4c4461201..11a534442 100644
--- a/source/cClientHandle.cpp
+++ b/source/cClientHandle.cpp
@@ -1271,6 +1271,11 @@ void cClientHandle::HandleBlockPlace(cPacket_BlockPlace * a_Packet)
}
break;
}
+ case E_ITEM_SUGARCANE:
+ {
+ a_Packet->m_ItemType = E_BLOCK_SUGARCANE;
+ break;
+ }
default:
{
break;
diff --git a/source/cWorld.cpp b/source/cWorld.cpp
index fb2517a80..048dc1e30 100644
--- a/source/cWorld.cpp
+++ b/source/cWorld.cpp
@@ -915,6 +915,12 @@ void cWorld::GrowPlant(int a_BlockX, int a_BlockY, int a_BlockZ)
} // for i - 50 times
break;
}
+
+ case E_BLOCK_SUGARCANE:
+ {
+ m_ChunkMap->GrowSugarcane(a_BlockX, a_BlockY, a_BlockZ, 3);
+ break;
+ }
} // switch (BlockType)
}