From 6d36a82e190525f895bc93588d2e81f220ab5f5b Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Fri, 8 Jun 2012 14:17:33 +0000 Subject: Sugarcane grows and can be grown using bonemeal. git-svn-id: http://mc-server.googlecode.com/svn/trunk@578 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/cChunk.cpp | 158 +++++++++++++++++++++++++++++------------------ source/cChunk.h | 3 + source/cChunkMap.cpp | 17 +++++ source/cChunkMap.h | 3 + source/cClientHandle.cpp | 5 ++ source/cWorld.cpp | 6 ++ 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) } -- cgit v1.2.3