diff options
Diffstat (limited to 'src/ChunkMap.cpp')
-rw-r--r-- | src/ChunkMap.cpp | 64 |
1 files changed, 48 insertions, 16 deletions
diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index d7164a6a5..d2ccca94e 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -34,8 +34,15 @@ // cChunkMap: cChunkMap::cChunkMap(cWorld * a_World ) - : m_World( a_World ) + : m_World( a_World ), + m_Pool( + new cListAllocationPool<cChunkData::sChunkSection, 1600>( + std::auto_ptr<cAllocationPool<cChunkData::sChunkSection>::cStarvationCallbacks>( + new cStarvationCallbacks()) + ) + ) { + } @@ -78,7 +85,7 @@ cChunkMap::cChunkLayer * cChunkMap::GetLayer(int a_LayerX, int a_LayerZ) } // Not found, create new: - cChunkLayer * Layer = new cChunkLayer(a_LayerX, a_LayerZ, this); + cChunkLayer * Layer = new cChunkLayer(a_LayerX, a_LayerZ, this, *m_Pool); if (Layer == NULL) { LOGERROR("cChunkMap: Cannot create new layer, server out of memory?"); @@ -219,9 +226,8 @@ bool cChunkMap::LockedGetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTY return false; } - int Index = cChunkDef::MakeIndexNoCheck(a_BlockX, a_BlockY, a_BlockZ); - a_BlockType = Chunk->GetBlock(Index); - a_BlockMeta = Chunk->GetMeta(Index); + a_BlockType = Chunk->GetBlock(a_BlockX, a_BlockY, a_BlockZ); + a_BlockMeta = Chunk->GetMeta(a_BlockX, a_BlockY, a_BlockZ); return true; } @@ -242,8 +248,7 @@ bool cChunkMap::LockedGetBlockType(int a_BlockX, int a_BlockY, int a_BlockZ, BLO return false; } - int Index = cChunkDef::MakeIndexNoCheck(a_BlockX, a_BlockY, a_BlockZ); - a_BlockType = Chunk->GetBlock(Index); + a_BlockType = Chunk->GetBlock(a_BlockX, a_BlockY, a_BlockZ); return true; } @@ -264,8 +269,7 @@ bool cChunkMap::LockedGetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIB return false; } - int Index = cChunkDef::MakeIndexNoCheck(a_BlockX, a_BlockY, a_BlockZ); - a_BlockMeta = Chunk->GetMeta(Index); + a_BlockMeta = Chunk->GetMeta(a_BlockX, a_BlockY, a_BlockZ); return true; } @@ -1255,7 +1259,7 @@ void cChunkMap::SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYP -void cChunkMap::SetBlock(cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta) +void cChunkMap::SetBlock(cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta, bool a_SendToClients) { cChunkInterface ChunkInterface(this); if (a_BlockType == E_BLOCK_AIR) @@ -1270,7 +1274,7 @@ void cChunkMap::SetBlock(cWorldInterface & a_WorldInterface, int a_BlockX, int a cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ ); if ((Chunk != NULL) && Chunk->IsValid()) { - Chunk->SetBlock(X, Y, Z, a_BlockType, a_BlockMeta ); + Chunk->SetBlock(X, Y, Z, a_BlockType, a_BlockMeta, a_SendToClients); m_World->GetSimulatorManager()->WakeUp(a_BlockX, a_BlockY, a_BlockZ, Chunk); } BlockHandler(a_BlockType)->OnPlaced(ChunkInterface, a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); @@ -1484,9 +1488,8 @@ bool cChunkMap::GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure) res = false; continue; } - int idx = cChunkDef::MakeIndexNoCheck(itr->x, itr->y, itr->z); - itr->BlockType = Chunk->GetBlock(idx); - itr->BlockMeta = Chunk->GetMeta(idx); + itr->BlockType = Chunk->GetBlock(itr->x, itr->y, itr->z); + itr->BlockMeta = Chunk->GetMeta(itr->x, itr->y, itr->z); } return res; } @@ -1669,6 +1672,30 @@ void cChunkMap::AddEntity(cEntity * a_Entity) +void cChunkMap::AddEntityIfNotPresent(cEntity * a_Entity) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(a_Entity->GetChunkX(), ZERO_CHUNK_Y, a_Entity->GetChunkZ()); + if ( + (Chunk == NULL) || // Chunk not present at all + (!Chunk->IsValid() && !a_Entity->IsPlayer()) // Chunk present, but no valid data; players need to spawn in such chunks (#953) + ) + { + LOGWARNING("Entity at %p (%s, ID %d) spawning in a non-existent chunk, the entity is lost.", + a_Entity, a_Entity->GetClass(), a_Entity->GetUniqueID() + ); + return; + } + if (!Chunk->HasEntity(a_Entity->GetUniqueID())) + { + Chunk->AddEntity(a_Entity); + } +} + + + + + bool cChunkMap::HasEntity(int a_UniqueID) { cCSLock Lock(m_CSLayers); @@ -2650,11 +2677,16 @@ void cChunkMap::QueueTickBlock(int a_BlockX, int a_BlockY, int a_BlockZ) //////////////////////////////////////////////////////////////////////////////// // cChunkMap::cChunkLayer: -cChunkMap::cChunkLayer::cChunkLayer(int a_LayerX, int a_LayerZ, cChunkMap * a_Parent) +cChunkMap::cChunkLayer::cChunkLayer( + int a_LayerX, int a_LayerZ, + cChunkMap * a_Parent, + cAllocationPool<cChunkData::sChunkSection> & a_Pool +) : m_LayerX( a_LayerX ) , m_LayerZ( a_LayerZ ) , m_Parent( a_Parent ) , m_NumChunksLoaded( 0 ) + , m_Pool(a_Pool) { memset(m_Chunks, 0, sizeof(m_Chunks)); } @@ -2696,7 +2728,7 @@ cChunkPtr cChunkMap::cChunkLayer::GetChunk( int a_ChunkX, int a_ChunkY, int a_Ch cChunk * neixp = (LocalX < LAYER_SIZE - 1) ? m_Chunks[Index + 1] : m_Parent->FindChunk(a_ChunkX + 1, a_ChunkZ); cChunk * neizm = (LocalZ > 0) ? m_Chunks[Index - LAYER_SIZE] : m_Parent->FindChunk(a_ChunkX , a_ChunkZ - 1); cChunk * neizp = (LocalZ < LAYER_SIZE - 1) ? m_Chunks[Index + LAYER_SIZE] : m_Parent->FindChunk(a_ChunkX , a_ChunkZ + 1); - m_Chunks[Index] = new cChunk(a_ChunkX, 0, a_ChunkZ, m_Parent, m_Parent->GetWorld(), neixm, neixp, neizm, neizp); + m_Chunks[Index] = new cChunk(a_ChunkX, 0, a_ChunkZ, m_Parent, m_Parent->GetWorld(), neixm, neixp, neizm, neizp, m_Pool); } return m_Chunks[Index]; } |