diff options
Diffstat (limited to 'source/Chunk.cpp')
-rw-r--r-- | source/Chunk.cpp | 166 |
1 files changed, 103 insertions, 63 deletions
diff --git a/source/Chunk.cpp b/source/Chunk.cpp index 41cc0e7f6..3616f6b8e 100644 --- a/source/Chunk.cpp +++ b/source/Chunk.cpp @@ -492,15 +492,10 @@ void cChunk::BroadcastPendingBlockChanges(void) void cChunk::CheckBlocks(void) { cCSLock Lock2(m_CSBlockLists); - unsigned int NumTickBlocks = m_ToTickBlocks.size(); - Lock2.Unlock(); - - if (NumTickBlocks == 0) + if (m_ToTickBlocks.size() == 0) { return; } - - Lock2.Lock(); std::deque< unsigned int > ToTickBlocks = m_ToTickBlocks; m_ToTickBlocks.clear(); Lock2.Unlock(); @@ -1131,17 +1126,18 @@ void cChunk::SetBlock( int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType } m_ToTickBlocks.push_back(index); - CheckNeighbors(a_RelX, a_RelY, a_RelZ); + QueueTickBlockNeighbors(a_RelX, a_RelY, a_RelZ); - Vector3i WorldPos = PositionToWorldPosition( a_RelX, a_RelY, a_RelZ ); - cBlockEntity* BlockEntity = GetBlockEntity( WorldPos ); - if( BlockEntity ) + Vector3i WorldPos = PositionToWorldPosition(a_RelX, a_RelY, a_RelZ); + cBlockEntity * BlockEntity = GetBlockEntity(WorldPos); + if (BlockEntity != NULL) { BlockEntity->Destroy(); - RemoveBlockEntity( BlockEntity ); + RemoveBlockEntity(BlockEntity); delete BlockEntity; } - switch( a_BlockType ) + + switch (a_BlockType) { case E_BLOCK_CHEST: { @@ -1181,76 +1177,52 @@ void cChunk::SetBlock( int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType -void cChunk::CheckNeighbors(int a_RelX, int a_RelY, int a_RelZ) +void cChunk::QueueTickBlock(int a_RelX, int a_RelY, int a_RelZ) { - int BlockX = m_PosX * cChunkDef::Width + a_RelX; - int BlockZ = m_PosZ * cChunkDef::Width + a_RelZ; - if (a_RelX < cChunkDef::Width - 1) - { - m_ToTickBlocks.push_back(MakeIndexNoCheck(a_RelX + 1, a_RelY, a_RelZ)); - } - else - { - m_ChunkMap->CheckBlock(BlockX + 1, a_RelY, BlockZ); - } - - if (a_RelX > 0) - { - m_ToTickBlocks.push_back( MakeIndexNoCheck(a_RelX - 1, a_RelY, a_RelZ)); - } - else - { - m_ChunkMap->CheckBlock(BlockX - 1, a_RelY, BlockZ); - } - - if (a_RelY < cChunkDef::Height - 1) - { - m_ToTickBlocks.push_back(MakeIndexNoCheck(a_RelX, a_RelY + 1, a_RelZ)); - } - - if (a_RelY > 0) - { - m_ToTickBlocks.push_back(MakeIndexNoCheck(a_RelX, a_RelY - 1, a_RelZ)); - } - - if (a_RelZ < cChunkDef::Width - 1) - { - m_ToTickBlocks.push_back(MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ + 1)); - } - else + if (!IsValid()) { - m_ChunkMap->CheckBlock(BlockX, a_RelY, BlockZ + 1); + return; } - if (a_RelZ > 0) - { - m_ToTickBlocks.push_back(MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ - 1)); - } - else - { - m_ChunkMap->CheckBlock(BlockX, a_RelY, BlockZ - 1); - } + m_ToTickBlocks.push_back(MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ)); } -void cChunk::CheckBlock(int a_RelX, int a_RelY, int a_RelZ) +void cChunk::QueueTickBlockNeighbors(int a_RelX, int a_RelY, int a_RelZ) { - if (!IsValid()) + int BlockX = m_PosX * cChunkDef::Width + a_RelX; + int BlockZ = m_PosZ * cChunkDef::Width + a_RelZ; + struct { - return; + int x, y, z; } - - m_ToTickBlocks.push_back(MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ)); + Coords[] = + { + { 1, 0, 0}, + {-1, 0, 0}, + { 0, 1, 0}, + { 0, -1, 0}, + { 0, 0, 1}, + { 0, 0, -1}, + } ; + for (int i = 0; i < ARRAYCOUNT(Coords); i++) + { + cChunk * ch = GetNeighborChunk(BlockX + Coords[i].x, a_RelY, BlockZ + Coords[i].z); + if (ch != NULL) + { + ch->QueueTickBlock(a_RelX + Coords[i].x, a_RelY + Coords[i].y, a_RelZ + Coords[i].z); + } + } // for i - Coords[] } -void cChunk::FastSetBlock( int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta) +void cChunk::FastSetBlock(int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta) { ASSERT(!((a_X < 0 || a_X >= Width || a_Y < 0 || a_Y >= Height || a_Z < 0 || a_Z >= Width))); @@ -1833,6 +1805,74 @@ void cChunk::GetBlockInfo(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_Bloc +cChunk * cChunk::GetNeighborChunk(int a_BlockX, int a_BlockY, int a_BlockZ) +{ + // Convert coords to relative, then call the relative version: + a_BlockX -= m_PosX * cChunkDef::Width; + a_BlockZ -= m_PosZ * cChunkDef::Width; + return GetRelNeighborChunk(a_BlockX, a_BlockY, a_BlockZ); +} + + + + + +cChunk * cChunk::GetRelNeighborChunk(int a_RelX, int a_RelY, int a_RelZ) +{ + bool ReturnThis = true; + if (a_RelX < 0) + { + if (m_NeighborXM != NULL) + { + cChunk * Candidate = m_NeighborXM->GetRelNeighborChunk(a_RelX + cChunkDef::Width, a_RelY, a_RelZ); + if (Candidate != NULL) + { + return Candidate; + } + } + // Going X first failed, but if the request is crossing Z as well, let's try the Z first later on. + ReturnThis = false; + } + else if (a_RelX >= cChunkDef::Width) + { + if (m_NeighborXP != NULL) + { + cChunk * Candidate = m_NeighborXP->GetRelNeighborChunk(a_RelX - cChunkDef::Width, a_RelY, a_RelZ); + if (Candidate != NULL) + { + return Candidate; + } + } + // Going X first failed, but if the request is crossing Z as well, let's try the Z first later on. + ReturnThis = false; + } + + if (a_RelZ < 0) + { + if (m_NeighborZM != NULL) + { + return m_NeighborZM->GetRelNeighborChunk(a_RelX, a_RelY, a_RelZ + cChunkDef::Width); + // For requests crossing both X and Z, the X-first way has been already tried + } + return NULL; + } + else if (a_RelZ >= cChunkDef::Width) + { + if (m_NeighborZP != NULL) + { + return m_NeighborZP->GetRelNeighborChunk(a_RelX, a_RelY, a_RelZ - cChunkDef::Width); + // For requests crossing both X and Z, the X-first way has been already tried + } + return NULL; + } + + return (ReturnThis ? this : NULL); +} + + + + + void cChunk::BroadcastPlayerAnimation(const cPlayer & a_Player, char a_Animation, const cClientHandle * a_Exclude) { for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr ) |