summaryrefslogtreecommitdiffstats
path: root/src/Entities/Player.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Entities/Player.cpp')
-rw-r--r--src/Entities/Player.cpp120
1 files changed, 49 insertions, 71 deletions
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index e7b6ade15..421eddbd5 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -193,9 +193,6 @@ bool cPlayer::Initialize(OwnedEntity a_Self, cWorld & a_World)
cPluginManager::Get()->CallHookSpawnedEntity(*GetWorld(), *this);
- // Spawn the entity on the clients:
- GetWorld()->BroadcastSpawnEntity(*this);
-
return true;
}
@@ -243,6 +240,9 @@ void cPlayer::SpawnOn(cClientHandle & a_Client)
{
return;
}
+
+ LOGD("Spawing %s on %s", GetName().c_str(), a_Client.GetUsername().c_str());
+
a_Client.SendPlayerSpawn(*this);
a_Client.SendEntityHeadLook(*this);
a_Client.SendEntityEquipment(*this, 0, m_Inventory.GetEquippedItem());
@@ -1225,7 +1225,7 @@ void cPlayer::Respawn(void)
if (GetWorld() != m_SpawnWorld)
{
- ScheduleMoveToWorld(m_SpawnWorld, GetLastBedPos(), false);
+ MoveToWorld(m_SpawnWorld, GetLastBedPos(), false);
}
else
{
@@ -2003,92 +2003,70 @@ void cPlayer::TossItems(const cItems & a_Items)
-bool cPlayer::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn, Vector3d a_NewPosition)
+void cPlayer::DoMoveToWorld(const cEntity::sWorldChangeInfo & a_WorldChangeInfo)
{
- ASSERT(a_World != nullptr);
- ASSERT(IsTicking());
+ ASSERT(a_WorldChangeInfo.m_NewWorld != nullptr);
- if (GetWorld() == a_World)
+ // Reset portal cooldown
+ if (a_WorldChangeInfo.m_SetPortalCooldown)
{
- // Don't move to same world
- return false;
+ m_PortalCooldownData.m_TicksDelayed = 0;
+ m_PortalCooldownData.m_ShouldPreventTeleportation = true;
}
- // Ask the plugins if the player is allowed to change the world
- if (cRoot::Get()->GetPluginManager()->CallHookEntityChangingWorld(*this, *a_World))
+ if (m_World == a_WorldChangeInfo.m_NewWorld)
{
- // A Plugin doesn't allow the player to change the world
- return false;
+ // Moving to same world, don't need to remove from world
+ SetPosition(a_WorldChangeInfo.m_NewPosition);
+ return;
}
- 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);
+ LOGD("Warping player \"%s\" from world \"%s\" to \"%s\". Source chunk: (%d, %d) ",
+ GetName(), GetWorld()->GetName(), a_WorldChangeInfo.m_NewWorld->GetName(),
+ GetChunkX(), GetChunkZ()
+ );
- // Tell others we are gone
- GetWorld()->BroadcastDestroyEntity(*this);
+ // Stop all mobs from targeting this player
+ StopEveryoneFromTargetingMe();
- // Remove player from world
- // Make sure that RemovePlayer didn't return a valid smart pointer, due to the second parameter being false
- // We remain valid and not destructed after this call
- VERIFY(!GetWorld()->RemovePlayer(*this, false));
+ // Prevent further ticking in this world
+ SetIsTicking(false);
- // Set position to the new position
- ResetPosition(a_NewPosition);
- FreezeInternal(a_NewPosition, false);
+ // Remove from the old world
+ auto & OldWorld = *GetWorld();
+ auto Self = OldWorld.RemovePlayer(*this);
- // Stop all mobs from targeting this player
- StopEveryoneFromTargetingMe();
+ ResetPosition(a_WorldChangeInfo.m_NewPosition);
+ FreezeInternal(a_WorldChangeInfo.m_NewPosition, false);
+ SetWorld(a_WorldChangeInfo.m_NewWorld); // Chunks may be streamed before cWorld::AddPlayer() sets the world to the new value
- // Deal with new world
- SetWorld(a_World);
+ // Set capabilities based on new world
+ SetCapabilities();
- // Set capabilities based on new world
- SetCapabilities();
+ cClientHandle * ch = GetClientHandle();
+ if (ch != nullptr)
+ {
+ // The clienthandle caches the coords of the chunk we're standing at. Invalidate this.
+ ch->InvalidateCachedSentChunk();
- cClientHandle * ch = this->GetClientHandle();
- if (ch != nullptr)
+ // Send the respawn packet:
+ if (a_WorldChangeInfo.m_SendRespawn)
{
- // 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());
- }
+ ch->SendRespawn(a_WorldChangeInfo.m_NewWorld->GetDimension());
}
- // Broadcast the player into the new world.
- a_World->BroadcastSpawnEntity(*this);
-
- // Queue add to new world and removal from the old one
+ // Update the view distance.
+ ch->SetViewDistance(ch->GetRequestedViewDistance());
- // Chunks may be streamed before cWorld::AddPlayer() sets the world to the new value
- cChunk * ParentChunk = this->GetParentChunk();
-
- 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()
- );
-
- // New world will take over and announce client at its next tick
- auto PlayerPtr = static_cast<cPlayer *>(ParentChunk->RemoveEntity(*this).release());
- a_World->AddPlayer(std::unique_ptr<cPlayer>(PlayerPtr), &a_OldWorld);
- });
+ // Send current weather of target world to player
+ if (a_WorldChangeInfo.m_NewWorld->GetDimension() == dimOverworld)
+ {
+ ch->SendWeather(a_WorldChangeInfo.m_NewWorld->GetWeather());
+ }
+ }
- return true;
+ // New world will take over and announce client at its next tick
+ a_WorldChangeInfo.m_NewWorld->AddPlayer(std::move(Self), &OldWorld);
}
@@ -2515,7 +2493,7 @@ void cPlayer::HandleFloater()
}
m_World->DoWithEntityByID(m_FloaterID, [](cEntity & a_Entity)
{
- a_Entity.Destroy(true);
+ a_Entity.Destroy();
return true;
}
);