summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/Entities/Player.cpp3
-rw-r--r--src/World.cpp35
-rw-r--r--src/World.h8
3 files changed, 31 insertions, 15 deletions
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index e4c0fdaa5..50bec3608 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -1827,8 +1827,7 @@ bool cPlayer::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn, Vector3d
ParentChunk->GetPosX(), ParentChunk->GetPosZ()
);
ParentChunk->RemoveEntity(this);
- a_World->AddPlayer(this);
- cRoot::Get()->GetPluginManager()->CallHookEntityChangedWorld(*this, a_OldWorld);
+ a_World->AddPlayer(this, &a_OldWorld); // New world will appropriate and announce client at his next tick
});
return true;
}
diff --git a/src/World.cpp b/src/World.cpp
index c687e9549..c10cb52e9 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -2990,10 +2990,10 @@ void cWorld::CollectPickupsByPlayer(cPlayer & a_Player)
-void cWorld::AddPlayer(cPlayer * a_Player)
+void cWorld::AddPlayer(cPlayer * a_Player, cWorld * a_OldWorld)
{
cCSLock Lock(m_CSPlayersToAdd);
- m_PlayersToAdd.push_back(a_Player);
+ m_PlayersToAdd.emplace_back(a_Player, a_OldWorld);
}
@@ -3010,7 +3010,10 @@ void cWorld::RemovePlayer(cPlayer * a_Player, bool a_RemoveFromChunk)
}
{
cCSLock Lock(m_CSPlayersToAdd);
- m_PlayersToAdd.remove(a_Player);
+ m_PlayersToAdd.remove_if([&](const std::pair< cPlayer *, cWorld * > & value) -> bool
+ {
+ return (value.first == a_Player);
+ });
}
{
cCSLock Lock(m_CSPlayers);
@@ -3895,7 +3898,7 @@ void cWorld::AddQueuedPlayers(void)
ASSERT(m_TickThread.IsCurrentThread());
// Grab the list of players to add, it has to be locked to access it:
- cPlayerList PlayersToAdd;
+ cAwaitingPlayerList PlayersToAdd;
{
cCSLock Lock(m_CSPlayersToAdd);
std::swap(PlayersToAdd, m_PlayersToAdd);
@@ -3904,8 +3907,9 @@ void cWorld::AddQueuedPlayers(void)
// Add all the players in the grabbed list:
{
cCSLock Lock(m_CSPlayers);
- for (auto Player : PlayersToAdd)
+ for (auto & AwaitingPlayer : PlayersToAdd)
{
+ auto & Player = AwaitingPlayer.first;
ASSERT(std::find(m_Players.begin(), m_Players.end(), Player) == m_Players.end()); // Is it already in the list? HOW?
LOGD("Adding player %s to world \"%s\".", Player->GetName().c_str(), m_WorldName.c_str());
@@ -3922,9 +3926,10 @@ void cWorld::AddQueuedPlayers(void)
// Add all the players' clienthandles:
{
cCSLock Lock(m_CSClients);
- for (cPlayerList::iterator itr = PlayersToAdd.begin(), end = PlayersToAdd.end(); itr != end; ++itr)
+ for (auto & AwaitingPlayer : PlayersToAdd)
{
- cClientHandlePtr Client = (*itr)->GetClientHandlePtr();
+ auto & Player = AwaitingPlayer.first;
+ cClientHandlePtr Client = Player->GetClientHandlePtr();
if (Client != nullptr)
{
m_Clients.push_back(Client);
@@ -3933,16 +3938,26 @@ void cWorld::AddQueuedPlayers(void)
} // Lock(m_CSClients)
// Stream chunks to all eligible clients:
- for (cPlayerList::iterator itr = PlayersToAdd.begin(), end = PlayersToAdd.end(); itr != end; ++itr)
+ for (auto & AwaitingPlayer : PlayersToAdd)
{
- cClientHandle * Client = (*itr)->GetClientHandle();
+ auto & Player = AwaitingPlayer.first;
+ cClientHandle * Client = Player->GetClientHandle();
if (Client != nullptr)
{
Client->SendPlayerMoveLook();
Client->SendHealth();
- Client->SendWholeInventory(*(*itr)->GetWindow());
+ Client->SendWholeInventory(*Player->GetWindow());
}
} // for itr - PlayersToAdd[]
+
+ // Call EntityChangedWorld callback on all eligible clients
+ for (auto & AwaitingPlayer : PlayersToAdd)
+ {
+ if (AwaitingPlayer.second != nullptr)
+ {
+ cRoot::Get()->GetPluginManager()->CallHookEntityChangedWorld(*(static_cast <cEntity *>(AwaitingPlayer.first)), *AwaitingPlayer.second);
+ }
+ }
}
diff --git a/src/World.h b/src/World.h
index c1794b159..a00e181b6 100644
--- a/src/World.h
+++ b/src/World.h
@@ -61,6 +61,7 @@ class cBroadcaster;
typedef std::list< cPlayer * > cPlayerList;
+typedef std::list< std::pair< cPlayer *, cWorld * > > cAwaitingPlayerList;
typedef SharedPtr<cSetChunkData> cSetChunkDataPtr; // TODO: Change to unique_ptr once we go C++11
typedef std::vector<cSetChunkDataPtr> cSetChunkDataPtrs;
@@ -262,8 +263,9 @@ public:
/** Adds the player to the world.
Uses a queue to store the player object until the Tick thread processes the addition event.
- Also adds the player as an entity in the chunkmap, and the player's ClientHandle, if any, for ticking. */
- void AddPlayer(cPlayer * a_Player);
+ Also adds the player as an entity in the chunkmap, and the player's ClientHandle, if any, for ticking.
+ If a_OldWorld is provided, a corresponding ENTITY_CHANGED_WORLD event is triggerred after the addition. */
+ void AddPlayer(cPlayer * a_Player, cWorld * a_OldWorld = nullptr);
/** Removes the player from the world.
Removes the player from the addition queue, too, if appropriate.
@@ -1006,7 +1008,7 @@ private:
cCriticalSection m_CSPlayersToAdd;
/** List of players that are scheduled for adding, waiting for the Tick thread to add them. */
- cPlayerList m_PlayersToAdd;
+ cAwaitingPlayerList m_PlayersToAdd;
/** CS protecting m_SetChunkDataQueue. */
cCriticalSection m_CSSetChunkDataQueue;