summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/ClientHandle.h3
-rw-r--r--src/Entities/Entity.h5
-rw-r--r--src/Entities/Player.cpp2
-rw-r--r--src/Entities/Player.h2
-rw-r--r--src/World.cpp28
-rw-r--r--src/World.h9
6 files changed, 42 insertions, 7 deletions
diff --git a/src/ClientHandle.h b/src/ClientHandle.h
index 659c67658..3f1cdf55a 100644
--- a/src/ClientHandle.h
+++ b/src/ClientHandle.h
@@ -250,7 +250,8 @@ public:
void SendData(const char * a_Data, size_t a_Size);
- /** Called when the player moves into a different world; queues sreaming the new chunks */
+ /** Called when the player moves into a different world.
+ Locks the current world, doesn't lock the new world. */
void MoveToWorld(cWorld & a_World, bool a_SendRespawnPacket);
/** Called when the player will enchant a Item */
diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h
index 0c393c0f5..9fe771120 100644
--- a/src/Entities/Entity.h
+++ b/src/Entities/Entity.h
@@ -421,6 +421,9 @@ public:
UNUSED(a_Killer);
}
+ /** Sets the internal world pointer to a new cWorld, doesn't update anything else. */
+ void SetWorld(cWorld * a_World) { m_World = a_World; }
+
protected:
static cCriticalSection m_CSCount;
static int m_EntityCount;
@@ -485,8 +488,6 @@ protected:
virtual void Destroyed(void) {} // Called after the entity has been destroyed
- void SetWorld(cWorld * a_World) { m_World = a_World; }
-
/** Called in each tick to handle air-related processing i.e. drowning */
virtual void HandleAir();
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index 3a9324d09..b83419903 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -1595,8 +1595,6 @@ bool cPlayer::MoveToWorld(const char * a_WorldName)
m_ClientHandle->MoveToWorld(*World, (OldDimension != World->GetDimension()));
// Add player to all the necessary parts of the new world
- SetWorld(World);
- m_ClientHandle->StreamChunks();
World->AddEntity(this);
World->AddPlayer(this);
diff --git a/src/Entities/Player.h b/src/Entities/Player.h
index b7cb27d6c..83b9ad593 100644
--- a/src/Entities/Player.h
+++ b/src/Entities/Player.h
@@ -328,6 +328,8 @@ public:
void SetVisible( bool a_bVisible ); // tolua_export
bool IsVisible(void) const { return m_bVisible; } // tolua_export
+ /** Moves the player to the specified world.
+ Returns true if successful, false on failure (world not found). */
bool MoveToWorld(const char * a_WorldName); // tolua_export
bool SaveToDisk(void);
diff --git a/src/World.cpp b/src/World.cpp
index 88e9c32e6..ccd47d3b0 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -743,6 +743,17 @@ void cWorld::Tick(float a_Dt, int a_LastTickDurationMSec)
m_LastTimeUpdate = m_WorldAge;
}
+ // Add entities waiting in the queue to be added:
+ {
+ cCSLock Lock(m_CSEntitiesToAdd);
+ for (cEntityList::iterator itr = m_EntitiesToAdd.begin(), end = m_EntitiesToAdd.end(); itr != end; ++itr)
+ {
+ (*itr)->SetWorld(this);
+ m_ChunkMap->AddEntity(*itr);
+ }
+ m_EntitiesToAdd.clear();
+ }
+
m_ChunkMap->Tick(a_Dt);
TickClients(a_Dt);
@@ -2808,9 +2819,11 @@ void cWorld::ScheduleTask(int a_DelayTicks, cTask * a_Task)
+
void cWorld::AddEntity(cEntity * a_Entity)
{
- m_ChunkMap->AddEntity(a_Entity);
+ cCSLock Lock(m_CSEntitiesToAdd);
+ m_EntitiesToAdd.push_back(a_Entity);
}
@@ -2819,6 +2832,19 @@ void cWorld::AddEntity(cEntity * a_Entity)
bool cWorld::HasEntity(int a_UniqueID)
{
+ // Check if the entity is in the queue to be added to the world:
+ {
+ cCSLock Lock(m_CSEntitiesToAdd);
+ for (cEntityList::const_iterator itr = m_EntitiesToAdd.begin(), end = m_EntitiesToAdd.end(); itr != end; ++itr)
+ {
+ if ((*itr)->GetUniqueID() == a_UniqueID)
+ {
+ return true;
+ }
+ } // for itr - m_EntitiesToAdd[]
+ }
+
+ // Check if the entity is in the chunkmap:
return m_ChunkMap->HasEntity(a_UniqueID);
}
diff --git a/src/World.h b/src/World.h
index 98b241a2b..4c014a976 100644
--- a/src/World.h
+++ b/src/World.h
@@ -301,7 +301,8 @@ public:
void SendPlayerList(cPlayer * a_DestPlayer); // Sends playerlist to the player
- /** Adds the entity into its appropriate chunk; takes ownership of the entity ptr */
+ /** Adds the entity into its appropriate chunk; takes ownership of the entity ptr.
+ The entity is added lazily - this function only puts it in a queue that is then processed by the Tick thread. */
void AddEntity(cEntity * a_Entity);
bool HasEntity(int a_UniqueID);
@@ -926,6 +927,12 @@ private:
/** Clients that are scheduled for adding, waiting for TickClients to add them */
cClientHandleList m_ClientsToAdd;
+ /** Guards m_EntitiesToAdd */
+ cCriticalSection m_CSEntitiesToAdd;
+
+ /** List of entities that are scheduled for adding, waiting for the Tick thread to add them. */
+ cEntityList m_EntitiesToAdd;
+
cWorld(const AString & a_WorldName);
virtual ~cWorld();