diff options
Diffstat (limited to 'src/Chunk.cpp')
-rw-r--r-- | src/Chunk.cpp | 83 |
1 files changed, 46 insertions, 37 deletions
diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 44fcefbe1..8255fdcaf 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -71,6 +71,7 @@ cChunk::cChunk( m_IsDirty(false), m_IsSaving(false), m_HasLoadFailed(false), + m_EntityTickIteratorData(std::make_pair(false, m_Entities.end())), m_StayCount(0), m_PosX(a_ChunkX), m_PosY(a_ChunkY), @@ -576,33 +577,40 @@ void cChunk::Tick(float a_Dt) } // Tick all entities in this chunk (except mobs): - for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr) + m_EntityTickIteratorData.first = true; + for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end();) { - // Mobs are tickes inside MobTick (as we don't have to tick them if they are far away from players) + // Mobs are ticked inside cWorld::TickMobs() (as we don't have to tick them if they are far away from players) + // Don't tick things queued to be removed if (!((*itr)->IsMob())) { + m_EntityTickIteratorData.second = itr; (*itr)->Tick(a_Dt, *this); - } - } // for itr - m_Entitites[] - - // Remove all entities that were scheduled for removal: - for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end();) - { - if ((*itr)->IsDestroyed()) + + if (itr != m_EntityTickIteratorData.second) { - LOGD("Destroying entity #%i (%s)", (*itr)->GetUniqueID(), (*itr)->GetClass()); - cEntity * ToDelete = *itr; - itr = m_Entities.erase(itr); - delete ToDelete; - continue; + itr = m_EntityTickIteratorData.second; } - ++itr; + else + { + ++itr; + } + continue; + } + ++itr; } // for itr - m_Entitites[] + m_EntityTickIteratorData.first = false; - // If any entity moved out of the chunk, move it to the neighbor: for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end();) { - if ( + if ((*itr)->IsDestroyed()) // Remove all entities that were scheduled for removal: + { + LOGD("Destroying entity #%i (%s)", (*itr)->GetUniqueID(), (*itr)->GetClass()); + cEntity * ToDelete = *itr; + itr = m_Entities.erase(itr); + delete ToDelete; + } + else if ( // If any entity moved out of the chunk, move it to the neighbor: ((*itr)->GetChunkX() != m_PosX) || ((*itr)->GetChunkZ() != m_PosZ) ) @@ -614,7 +622,7 @@ void cChunk::Tick(float a_Dt) { ++itr; } - } + } // for itr - m_Entitites[] ApplyWeatherToTop(); } @@ -899,7 +907,6 @@ void cChunk::ApplyWeatherToTop() } break; } // case (snowy biomes) - // TODO: Rainy biomes should check for farmland and cauldrons default: { break; @@ -1760,7 +1767,7 @@ void cChunk::RemoveBlockEntity( cBlockEntity* a_BlockEntity ) -bool cChunk::AddClient(cClientHandle* a_Client) +bool cChunk::AddClient(cClientHandle * a_Client) { for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) { @@ -1791,7 +1798,7 @@ bool cChunk::AddClient(cClientHandle* a_Client) -void cChunk::RemoveClient( cClientHandle* a_Client ) +void cChunk::RemoveClient(cClientHandle * a_Client) { for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) { @@ -1799,12 +1806,12 @@ void cChunk::RemoveClient( cClientHandle* a_Client ) { continue; } - + m_LoadedByClient.erase(itr); if (!a_Client->IsDestroyed()) { - for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr ) + for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr) { /* // DEBUG: @@ -1824,7 +1831,7 @@ void cChunk::RemoveClient( cClientHandle* a_Client ) -bool cChunk::HasClient( cClientHandle* a_Client ) +bool cChunk::HasClient(cClientHandle* a_Client) { for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) { @@ -1855,9 +1862,9 @@ void cChunk::AddEntity(cEntity * a_Entity) { MarkDirty(); } - - ASSERT(std::find(m_Entities.begin(), m_Entities.end(), a_Entity) == m_Entities.end()); // Not there already - + + ASSERT(std::find(m_Entities.begin(), m_Entities.end(), a_Entity) == m_Entities.end()); + m_Entities.push_back(a_Entity); } @@ -1867,17 +1874,19 @@ void cChunk::AddEntity(cEntity * a_Entity) void cChunk::RemoveEntity(cEntity * a_Entity) { - size_t SizeBefore = m_Entities.size(); - m_Entities.remove(a_Entity); - size_t SizeAfter = m_Entities.size(); - - if (SizeBefore != SizeAfter) + if (m_EntityTickIteratorData.first) { - // Mark as dirty if it was a server-generated entity: - if (!a_Entity->IsPlayer()) - { - MarkDirty(); - } + m_EntityTickIteratorData.second = m_Entities.erase(m_EntityTickIteratorData.second); + } + else + { + m_Entities.remove(a_Entity); + } + + // Mark as dirty if it was a server-generated entity: + if (!a_Entity->IsPlayer()) + { + MarkDirty(); } } |