summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ClientHandle.cpp1
-rw-r--r--src/ClientHandle.h3
-rw-r--r--src/Entities/Player.cpp79
3 files changed, 45 insertions, 38 deletions
diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp
index 6febbfc3a..303583769 100644
--- a/src/ClientHandle.cpp
+++ b/src/ClientHandle.cpp
@@ -603,7 +603,6 @@ void cClientHandle::StreamChunk(int a_ChunkX, int a_ChunkZ, cChunkSender::eChunk
-// Removes the client from all chunks. Used when switching worlds or destroying the player
void cClientHandle::RemoveFromAllChunks()
{
cWorld * World = m_Player->GetWorld();
diff --git a/src/ClientHandle.h b/src/ClientHandle.h
index da59bdea8..7d829653b 100644
--- a/src/ClientHandle.h
+++ b/src/ClientHandle.h
@@ -125,7 +125,8 @@ public: // tolua_export
/** Remove all loaded chunks that are no longer in range */
void UnloadOutOfRangeChunks(void);
- // Removes the client from all chunks. Used when switching worlds or destroying the player
+ /** Removes the client from all chunks. Used when destroying the player.
+ When switching worlds, RemoveFromWorld does this function's job so it isn't called. */
void RemoveFromAllChunks(void);
inline bool IsLoggedIn(void) const { return (m_State >= csAuthenticating); }
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index f28258969..889aef778 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -1780,64 +1780,71 @@ bool cPlayer::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn, Vector3d
return false;
}
- // Ask the plugins if the player is allowed to changing the world
+ // Ask the plugins if the player is allowed to change the world
if (cRoot::Get()->GetPluginManager()->CallHookEntityChangingWorld(*this, *a_World))
{
- // A Plugin doesn't allow the player to changing the world
+ // A Plugin doesn't allow the player to change the world
return false;
}
- // The clienthandle caches the coords of the chunk we're standing at. Invalidate this.
- GetClientHandle()->InvalidateCachedSentChunk();
+ GetWorld()->QueueTask([this, a_World, a_ShouldSendRespawn, a_NewPosition](cWorld & a_OldWorld)
+ {
+ // The clienthandle caches the coords of the chunk we're standing at. Invalidate this.
+ GetClientHandle()->InvalidateCachedSentChunk();
- // Prevent further ticking in this world
- SetIsTicking(false);
+ // Prevent further ticking in this world
+ SetIsTicking(false);
- // Tell others we are gone
- GetWorld()->BroadcastDestroyEntity(*this);
+ // Tell others we are gone
+ GetWorld()->BroadcastDestroyEntity(*this);
- // Remove player from world
- GetWorld()->RemovePlayer(this, false);
+ // Remove player from world
+ GetWorld()->RemovePlayer(this, false);
- // Set position to the new position
- SetPosition(a_NewPosition);
- FreezeInternal(a_NewPosition, false);
+ // Set position to the new position
+ SetPosition(a_NewPosition);
+ FreezeInternal(a_NewPosition, false);
- // Stop all mobs from targeting this player
- StopEveryoneFromTargetingMe();
+ // Stop all mobs from targeting this player
+ StopEveryoneFromTargetingMe();
- // Send the respawn packet:
- if (a_ShouldSendRespawn && (m_ClientHandle != nullptr))
- {
- m_ClientHandle->SendRespawn(a_World->GetDimension());
- }
+ cClientHandle * ch = this->GetClientHandle();
+ if (ch != nullptr)
+ {
+ // Send the respawn packet:
+ if (a_ShouldSendRespawn)
+ {
+ m_ClientHandle->SendRespawn(a_World->GetDimension());
+ }
- // Update the view distance.
- m_ClientHandle->SetViewDistance(m_ClientHandle->GetRequestedViewDistance());
- // Send current weather of target world to player
- if (a_World->GetDimension() == dimOverworld)
- {
- m_ClientHandle->SendWeather(a_World->GetWeather());
- }
+ // Update the view distance.
+ ch->SetViewDistance(m_ClientHandle->GetRequestedViewDistance());
- // Broadcast the player into the new world.
- a_World->BroadcastSpawnEntity(*this);
+ // Send current weather of target world to player
+ if (a_World->GetDimension() == dimOverworld)
+ {
+ ch->SendWeather(a_World->GetWeather());
+ }
+ }
+
+ // Broadcast the player into the new world.
+ a_World->BroadcastSpawnEntity(*this);
+
+ // Queue add to new world and removal from the old one
+
+ SetWorld(a_World); // Chunks may be streamed before cWorld::AddPlayer() sets the world to the new value
+ cChunk * ParentChunk = this->GetParentChunk();
- // Queue add to new world and removal from the old one
- cChunk * ParentChunk = GetParentChunk();
- cWorld * OldWorld = GetWorld();
- SetWorld(a_World); // Chunks may be streamed before cWorld::AddPlayer() sets the world to the new value
- OldWorld->QueueTask([this, ParentChunk, a_World](cWorld & a_OldWorld)
- {
LOGD("Warping player \"%s\" from world \"%s\" to \"%s\". Source chunk: (%d, %d) ",
this->GetName().c_str(),
a_OldWorld.GetName().c_str(), a_World->GetName().c_str(),
ParentChunk->GetPosX(), ParentChunk->GetPosZ()
);
ParentChunk->RemoveEntity(this);
- a_World->AddPlayer(this, &a_OldWorld); // New world will appropriate and announce client at his next tick
+ a_World->AddPlayer(this, &a_OldWorld); // New world will take over and announce client at its next tick
});
+
return true;
}