From d7669c6709d3c8818bcffd30f65a9b77eeaed81c Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Sun, 17 Jun 2012 05:34:37 +0000 Subject: Fixed leaves blockticking - must touch neighboring chunks, too, instead of self at wrong places. git-svn-id: http://mc-server.googlecode.com/svn/trunk@626 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/cChunk.cpp | 77 ++++++++++++++++++++++++++++++++++++++----------------- source/cChunk.h | 1 + 2 files changed, 55 insertions(+), 23 deletions(-) (limited to 'source') diff --git a/source/cChunk.cpp b/source/cChunk.cpp index 70ece5893..647478339 100644 --- a/source/cChunk.cpp +++ b/source/cChunk.cpp @@ -591,29 +591,7 @@ void cChunk::TickBlocks(MTRand & a_TickRandom) break; } - case E_BLOCK_LEAVES: - { - NIBBLETYPE Meta = GetMeta(m_BlockTickX, m_BlockTickY, m_BlockTickZ); - if (((Meta & 0x04) == 0) && ((Meta & 0x08) == 1)){ - int x,y,z,f = 0; - for( y = 4; y > - 5; y-- ) { - for( x = - 4; x < 5; x++ ){ - for( z = - 4; z < 5; z++ ){ - if((x<0 ? -x : x) + (y<0 ? -y : y) + (z<0 ? -z : z) > 4) continue; - if(GetBlock(m_BlockTickX + x, m_BlockTickY + y, m_BlockTickZ + z) == E_BLOCK_LOG){ - f = 1; - } - } - } - } - if(f==0){ - SetBlock(m_BlockTickX, m_BlockTickY, m_BlockTickZ, 0, 0); - }else{ - SetMeta(m_BlockTickX, m_BlockTickY, m_BlockTickZ, Meta -= 8); - } - } - break; - } + case E_BLOCK_LEAVES: TickLeaves(m_BlockTickX, m_BlockTickY, m_BlockTickZ); break; default: { @@ -759,6 +737,59 @@ void cChunk::TickFarmland(int a_RelX, int a_RelY, int a_RelZ) +void cChunk::TickLeaves(int a_RelX, int a_RelY, int a_RelZ) +{ + // Since leaves-checking is a costly operation, it is done only if leaves are marked for checking (Meta has its 0x08 bit cleared) + // TODO: The meta is cleared (check flag set) each time a block next to the leaves changes + + NIBBLETYPE Meta = GetMeta(m_BlockTickX, m_BlockTickY, m_BlockTickZ); + if ((Meta & 0x04) != 0) + { + // Player-placed leaves, don't decay + return; + } + if ((Meta & 0x08) == 0) + { + // These leaves have been checked for decay lately and nothing around them changed + return; + } + + // TODO: We need a proper BFS check - is the leaves block connected to a log via other leaves blocks? + for (int y = 4; y > - 5; y--) + { + for (int z = - 4; z < 5; z++ ) + { + for (int x = - 4; x < 5; x++ ) + { + if (abs(x) + abs(y) + abs(z) > 4) + { + // Too far away + continue; + } + BLOCKTYPE BlockType; + NIBBLETYPE BlockMeta; + if (!UnboundedRelGetBlock(a_RelX + x, a_RelY + y, a_RelZ + z, BlockType, BlockMeta)) + { + // Too close to unloaded chunks, don't check at all + return; + } + if (BlockType == E_BLOCK_LOG) + { + // Wood found, the leaves stay; mark them as checked: + SetNibble(m_BlockMeta, a_RelX, a_RelY, a_RelZ, Meta & 0x07); + return; + } + } + } + } + // Decay the leaves. Let them drop something if the random is right + m_World->DigBlock(m_PosX * cChunkDef::Width + a_RelX, a_RelY, m_PosZ * cChunkDef::Width + a_RelZ); +} + + + + + 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 diff --git a/source/cChunk.h b/source/cChunk.h index 7ebb37e43..9ecbe89b8 100644 --- a/source/cChunk.h +++ b/source/cChunk.h @@ -237,6 +237,7 @@ private: void TickGrass (int a_RelX, int a_RelY, int a_RelZ, MTRand & a_TickRandom); 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); + void TickLeaves (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); -- cgit v1.2.3