Improve cPlayer::DoMoveToWorld (#3113)
This commit is contained in:
parent
61078e8402
commit
5625598afa
|
@ -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()
|
void cClientHandle::RemoveFromAllChunks()
|
||||||
{
|
{
|
||||||
cWorld * World = m_Player->GetWorld();
|
cWorld * World = m_Player->GetWorld();
|
||||||
|
|
|
@ -125,7 +125,8 @@ public: // tolua_export
|
||||||
/** Remove all loaded chunks that are no longer in range */
|
/** Remove all loaded chunks that are no longer in range */
|
||||||
void UnloadOutOfRangeChunks(void);
|
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);
|
void RemoveFromAllChunks(void);
|
||||||
|
|
||||||
inline bool IsLoggedIn(void) const { return (m_State >= csAuthenticating); }
|
inline bool IsLoggedIn(void) const { return (m_State >= csAuthenticating); }
|
||||||
|
|
|
@ -1780,64 +1780,71 @@ bool cPlayer::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn, Vector3d
|
||||||
return false;
|
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))
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The clienthandle caches the coords of the chunk we're standing at. Invalidate this.
|
GetWorld()->QueueTask([this, a_World, a_ShouldSendRespawn, a_NewPosition](cWorld & a_OldWorld)
|
||||||
GetClientHandle()->InvalidateCachedSentChunk();
|
|
||||||
|
|
||||||
// Prevent further ticking in this world
|
|
||||||
SetIsTicking(false);
|
|
||||||
|
|
||||||
// Tell others we are gone
|
|
||||||
GetWorld()->BroadcastDestroyEntity(*this);
|
|
||||||
|
|
||||||
// Remove player from world
|
|
||||||
GetWorld()->RemovePlayer(this, false);
|
|
||||||
|
|
||||||
// Set position to the new position
|
|
||||||
SetPosition(a_NewPosition);
|
|
||||||
FreezeInternal(a_NewPosition, false);
|
|
||||||
|
|
||||||
// Stop all mobs from targeting this player
|
|
||||||
StopEveryoneFromTargetingMe();
|
|
||||||
|
|
||||||
// Send the respawn packet:
|
|
||||||
if (a_ShouldSendRespawn && (m_ClientHandle != nullptr))
|
|
||||||
{
|
{
|
||||||
m_ClientHandle->SendRespawn(a_World->GetDimension());
|
// The clienthandle caches the coords of the chunk we're standing at. Invalidate this.
|
||||||
}
|
GetClientHandle()->InvalidateCachedSentChunk();
|
||||||
|
|
||||||
// Update the view distance.
|
// Prevent further ticking in this world
|
||||||
m_ClientHandle->SetViewDistance(m_ClientHandle->GetRequestedViewDistance());
|
SetIsTicking(false);
|
||||||
|
|
||||||
// Send current weather of target world to player
|
// Tell others we are gone
|
||||||
if (a_World->GetDimension() == dimOverworld)
|
GetWorld()->BroadcastDestroyEntity(*this);
|
||||||
{
|
|
||||||
m_ClientHandle->SendWeather(a_World->GetWeather());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Broadcast the player into the new world.
|
// Remove player from world
|
||||||
a_World->BroadcastSpawnEntity(*this);
|
GetWorld()->RemovePlayer(this, false);
|
||||||
|
|
||||||
|
// Set position to the new position
|
||||||
|
SetPosition(a_NewPosition);
|
||||||
|
FreezeInternal(a_NewPosition, false);
|
||||||
|
|
||||||
|
// Stop all mobs from targeting this player
|
||||||
|
StopEveryoneFromTargetingMe();
|
||||||
|
|
||||||
|
cClientHandle * ch = this->GetClientHandle();
|
||||||
|
if (ch != nullptr)
|
||||||
|
{
|
||||||
|
// Send the respawn packet:
|
||||||
|
if (a_ShouldSendRespawn)
|
||||||
|
{
|
||||||
|
m_ClientHandle->SendRespawn(a_World->GetDimension());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Update the view distance.
|
||||||
|
ch->SetViewDistance(m_ClientHandle->GetRequestedViewDistance());
|
||||||
|
|
||||||
|
// 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) ",
|
LOGD("Warping player \"%s\" from world \"%s\" to \"%s\". Source chunk: (%d, %d) ",
|
||||||
this->GetName().c_str(),
|
this->GetName().c_str(),
|
||||||
a_OldWorld.GetName().c_str(), a_World->GetName().c_str(),
|
a_OldWorld.GetName().c_str(), a_World->GetName().c_str(),
|
||||||
ParentChunk->GetPosX(), ParentChunk->GetPosZ()
|
ParentChunk->GetPosX(), ParentChunk->GetPosZ()
|
||||||
);
|
);
|
||||||
ParentChunk->RemoveEntity(this);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user