summaryrefslogtreecommitdiffstats
path: root/src/Chunk.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Chunk.cpp')
-rw-r--r--src/Chunk.cpp93
1 files changed, 55 insertions, 38 deletions
diff --git a/src/Chunk.cpp b/src/Chunk.cpp
index 44fcefbe1..399c8b9c7 100644
--- a/src/Chunk.cpp
+++ b/src/Chunk.cpp
@@ -579,30 +579,25 @@ void cChunk::Tick(float a_Dt)
for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr)
{
// Mobs are tickes inside MobTick (as we don't have to tick them if they are far away from players)
- if (!((*itr)->IsMob()))
+ // Don't tick things queued to be removed
+ if (
+ !((*itr)->IsMob()) &&
+ (std::find(m_EntitiesToRemove.begin(), m_EntitiesToRemove.end(), (*itr)->GetUniqueID()) == m_EntitiesToRemove.end())
+ )
{
(*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())
- {
- LOGD("Destroying entity #%i (%s)", (*itr)->GetUniqueID(), (*itr)->GetClass());
- cEntity * ToDelete = *itr;
- itr = m_Entities.erase(itr);
- delete ToDelete;
- continue;
- }
- ++itr;
- } // for itr - m_Entitites[]
-
- // 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 (
+ std::vector<int>::iterator itr2 = std::find(m_EntitiesToRemove.begin(), m_EntitiesToRemove.end(), (*itr)->GetUniqueID());
+ if (itr2 != m_EntitiesToRemove.end())
+ {
+ itr = m_Entities.erase(itr);
+ m_EntitiesToRemove.erase(itr2);
+ }
+ else if ( // If any entity moved out of the chunk, move it to the neighbor:
((*itr)->GetChunkX() != m_PosX) ||
((*itr)->GetChunkZ() != m_PosZ)
)
@@ -612,9 +607,19 @@ void cChunk::Tick(float a_Dt)
}
else
{
- ++itr;
+ 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
+ {
+ ++itr;
+ }
}
- }
+ } // for itr - m_Entitites[]
ApplyWeatherToTop();
}
@@ -899,7 +904,6 @@ void cChunk::ApplyWeatherToTop()
}
break;
} // case (snowy biomes)
- // TODO: Rainy biomes should check for farmland and cauldrons
default:
{
break;
@@ -1760,7 +1764,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 +1795,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 +1803,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 +1828,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 +1859,22 @@ void cChunk::AddEntity(cEntity * a_Entity)
{
MarkDirty();
}
-
- ASSERT(std::find(m_Entities.begin(), m_Entities.end(), a_Entity) == m_Entities.end()); // Not there already
-
+
+ if (std::find(m_Entities.begin(), m_Entities.end(), a_Entity) != m_Entities.end())
+ {
+ // Not there already
+ std::vector<int>::iterator itr = std::find(m_EntitiesToRemove.begin(), m_EntitiesToRemove.end(), a_Entity->GetUniqueID());
+ if (itr != m_EntitiesToRemove.end())
+ {
+ m_EntitiesToRemove.erase(itr);
+ return;
+ }
+ else
+ {
+ ASSERT(!"Entity already present when AddEntity was called!");
+ }
+ }
+
m_Entities.push_back(a_Entity);
}
@@ -1867,17 +1884,12 @@ 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)
+ m_EntitiesToRemove.push_back(a_Entity->GetUniqueID());
+
+ // Mark as dirty if it was a server-generated entity:
+ if (!a_Entity->IsPlayer())
{
- // Mark as dirty if it was a server-generated entity:
- if (!a_Entity->IsPlayer())
- {
- MarkDirty();
- }
+ MarkDirty();
}
}
@@ -1887,6 +1899,11 @@ void cChunk::RemoveEntity(cEntity * a_Entity)
bool cChunk::HasEntity(int a_EntityID)
{
+ if (std::find(m_EntitiesToRemove.begin(), m_EntitiesToRemove.end(), a_EntityID) != m_EntitiesToRemove.end())
+ {
+ return false; // If EntitiesToRemove contains our ID, this chunk doesn't have it, as it should be removed soon
+ }
+
for (cEntityList::const_iterator itr = m_Entities.begin(), end = m_Entities.end(); itr != end; ++itr)
{
if ((*itr)->GetUniqueID() == a_EntityID)