summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Chunk.cpp33
-rw-r--r--src/Chunk.h1
-rw-r--r--src/Entities/Entity.cpp3
-rw-r--r--src/Entities/Entity.h10
-rw-r--r--src/Entities/Player.cpp1
-rw-r--r--src/World.cpp14
-rw-r--r--src/World.h3
7 files changed, 26 insertions, 39 deletions
diff --git a/src/Chunk.cpp b/src/Chunk.cpp
index 8255fdcaf..727eb451d 100644
--- a/src/Chunk.cpp
+++ b/src/Chunk.cpp
@@ -71,7 +71,6 @@ 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),
@@ -577,44 +576,39 @@ void cChunk::Tick(float a_Dt)
}
// Tick all entities in this chunk (except mobs):
- m_EntityTickIteratorData.first = true;
- for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end();)
+ for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr)
{
// 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);
-
- if (itr != m_EntityTickIteratorData.second)
- {
- itr = m_EntityTickIteratorData.second;
- }
- else
- {
- ++itr;
- }
continue;
}
- ++itr;
} // for itr - m_Entitites[]
- m_EntityTickIteratorData.first = false;
for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end();)
{
if ((*itr)->IsDestroyed()) // Remove all entities that were scheduled for removal:
{
LOGD("Destroying entity #%i (%s)", (*itr)->GetUniqueID(), (*itr)->GetClass());
+ MarkDirty();
cEntity * ToDelete = *itr;
itr = m_Entities.erase(itr);
delete ToDelete;
}
+ else if ((*itr)->IsTravellingThroughPortal())
+ {
+ MarkDirty();
+ (*itr)->SetIsTravellingThroughPortal(false);
+ itr = m_Entities.erase(itr);
+ }
else if ( // If any entity moved out of the chunk, move it to the neighbor:
((*itr)->GetChunkX() != m_PosX) ||
((*itr)->GetChunkZ() != m_PosZ)
)
{
+ MarkDirty();
MoveEntityToNewChunk(*itr);
itr = m_Entities.erase(itr);
}
@@ -1874,14 +1868,7 @@ void cChunk::AddEntity(cEntity * a_Entity)
void cChunk::RemoveEntity(cEntity * a_Entity)
{
- if (m_EntityTickIteratorData.first)
- {
- m_EntityTickIteratorData.second = m_Entities.erase(m_EntityTickIteratorData.second);
- }
- else
- {
- m_Entities.remove(a_Entity);
- }
+ m_Entities.remove(a_Entity);
// Mark as dirty if it was a server-generated entity:
if (!a_Entity->IsPlayer())
diff --git a/src/Chunk.h b/src/Chunk.h
index 1619df333..dfdabea04 100644
--- a/src/Chunk.h
+++ b/src/Chunk.h
@@ -425,7 +425,6 @@ private:
// A critical section is not needed, because all chunk access is protected by its parent ChunkMap's csLayers
cClientHandleList m_LoadedByClient;
cEntityList m_Entities;
- std::pair<bool, cEntityList::iterator> m_EntityTickIteratorData;
cBlockEntityList m_BlockEntities;
/** Number of times the chunk has been requested to stay (by various cChunkStay objects); if zero, the chunk can be unloaded */
diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp
index 9110cd83b..9a8c6586d 100644
--- a/src/Entities/Entity.cpp
+++ b/src/Entities/Entity.cpp
@@ -57,6 +57,7 @@ cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, d
, m_Width(a_Width)
, m_Height(a_Height)
, m_InvulnerableTicks(0)
+ , m_IsTravellingThroughPortal(false)
{
cCSLock Lock(m_CSCount);
m_EntityCount++;
@@ -1183,7 +1184,7 @@ bool cEntity::MoveToWorld(const AString & a_WorldName, cWorld * a_World, bool a_
}
// Remove all links to the old world
- GetWorld()->RemoveEntity(this);
+ SetIsTravellingThroughPortal(true); // cChunk handles entity removal
GetWorld()->BroadcastDestroyEntity(*this);
// Queue add to new world
diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h
index 8975803a2..0293968ab 100644
--- a/src/Entities/Entity.h
+++ b/src/Entities/Entity.h
@@ -374,6 +374,12 @@ public:
virtual bool MoveToWorld(const AString & a_WorldName, cWorld * a_World = NULL, bool a_ShouldSendRespawn = true);
// tolua_end
+
+ /** Returns if the entity is travelling through a portal. Set to true by MoveToWorld and to false when the entity is removed by the old chunk */
+ bool IsTravellingThroughPortal(void) const { return m_IsTravellingThroughPortal; }
+
+ /** Sets if the entity has begun travelling through a portal or not */
+ void SetIsTravellingThroughPortal(bool a_Flag) { m_IsTravellingThroughPortal = a_Flag; }
/// Updates clients of changes in the entity.
virtual void BroadcastMovementUpdate(const cClientHandle * a_Exclude = NULL);
@@ -470,6 +476,9 @@ protected:
/** True when entity is initialised (Initialize()) and false when destroyed pending deletion (Destroy()) */
bool m_IsInitialized;
+ /** True when entity is being moved across worlds, false anytime else */
+ bool m_IsTravellingThroughPortal;
+
eEntityType m_EntityType;
cWorld * m_World;
@@ -492,7 +501,6 @@ protected:
/// Time, in ticks, since the last damage dealt by the void. Reset to zero when moving out of the void.
int m_TicksSinceLastVoidDamage;
-
virtual void Destroyed(void) {} // Called after the entity has been destroyed
/** Called in each tick to handle air-related processing i.e. drowning */
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index e975abdf5..b72f14f57 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -1600,6 +1600,7 @@ bool cPlayer::MoveToWorld(const AString & a_WorldName, cWorld * a_World, bool a_
}
// Remove player from the old world
+ SetIsTravellingThroughPortal(true); // cChunk handles entity removal
m_World->RemovePlayer(this);
// Queue adding player to the new world, including all the necessary adjustments to the object
diff --git a/src/World.cpp b/src/World.cpp
index 3ed2f5f13..c9199b6ba 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -2417,7 +2417,10 @@ void cWorld::AddPlayer(cPlayer * a_Player)
void cWorld::RemovePlayer(cPlayer * a_Player)
{
- m_ChunkMap->RemoveEntity(a_Player);
+ if (!a_Player->IsTravellingThroughPortal())
+ {
+ m_ChunkMap->RemoveEntity(a_Player);
+ }
{
cCSLock Lock(m_CSPlayersToAdd);
m_PlayersToAdd.remove(a_Player);
@@ -2919,15 +2922,6 @@ bool cWorld::HasEntity(int a_UniqueID)
-void cWorld::RemoveEntity(cEntity * a_Entity)
-{
- m_ChunkMap->RemoveEntity(a_Entity);
-}
-
-
-
-
-
/*
unsigned int cWorld::GetNumPlayers(void)
{
diff --git a/src/World.h b/src/World.h
index 0592c78fc..1d9026a5d 100644
--- a/src/World.h
+++ b/src/World.h
@@ -313,9 +313,6 @@ public:
bool HasEntity(int a_UniqueID);
- /** Removes the entity, the entity ptr ownership is assumed taken by the caller */
- void RemoveEntity(cEntity * a_Entity);
-
/** Calls the callback for each entity in the entire world; returns true if all entities processed, false if the callback aborted by returning true */
bool ForEachEntity(cEntityCallback & a_Callback); // Exported in ManualBindings.cpp