Add cWorld::RemoveEntity and use in cEntity (#4003)
* Add cWorld::RemoveEntity and use in cEntity * cEntity: Remove uneeded asserts from Destroy and DoMoveToWorld
This commit is contained in:
parent
028a35ef0d
commit
ef1f371dab
@ -223,8 +223,6 @@ cChunk * cEntity::GetParentChunk()
|
|||||||
|
|
||||||
void cEntity::Destroy(bool a_ShouldBroadcast)
|
void cEntity::Destroy(bool a_ShouldBroadcast)
|
||||||
{
|
{
|
||||||
ASSERT(IsTicking());
|
|
||||||
ASSERT(GetParentChunk() != nullptr);
|
|
||||||
SetIsTicking(false);
|
SetIsTicking(false);
|
||||||
|
|
||||||
// Unleash leashed mobs
|
// Unleash leashed mobs
|
||||||
@ -238,17 +236,17 @@ void cEntity::Destroy(bool a_ShouldBroadcast)
|
|||||||
m_World->BroadcastDestroyEntity(*this);
|
m_World->BroadcastDestroyEntity(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
cChunk * ParentChunk = GetParentChunk();
|
auto ParentChunkCoords = cChunkDef::BlockToChunk(GetPosition());
|
||||||
m_World->QueueTask([this, ParentChunk](cWorld & a_World)
|
m_World->QueueTask([this, ParentChunkCoords](cWorld & a_World)
|
||||||
{
|
{
|
||||||
LOGD("Destroying entity #%i (%s) from chunk (%d, %d)",
|
LOGD("Destroying entity #%i (%s) from chunk (%d, %d)",
|
||||||
this->GetUniqueID(), this->GetClass(),
|
this->GetUniqueID(), this->GetClass(),
|
||||||
ParentChunk->GetPosX(), ParentChunk->GetPosZ()
|
ParentChunkCoords.m_ChunkX, ParentChunkCoords.m_ChunkZ
|
||||||
);
|
);
|
||||||
|
|
||||||
// Make sure that RemoveEntity returned a valid smart pointer
|
// Make sure that RemoveEntity returned a valid smart pointer
|
||||||
// Also, not storing the returned pointer means automatic destruction
|
// Also, not storing the returned pointer means automatic destruction
|
||||||
VERIFY(ParentChunk->RemoveEntity(*this));
|
VERIFY(a_World.RemoveEntity(*this));
|
||||||
});
|
});
|
||||||
Destroyed();
|
Destroyed();
|
||||||
}
|
}
|
||||||
@ -1565,7 +1563,6 @@ bool cEntity::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn, Vector3d
|
|||||||
{
|
{
|
||||||
UNUSED(a_ShouldSendRespawn);
|
UNUSED(a_ShouldSendRespawn);
|
||||||
ASSERT(a_World != nullptr);
|
ASSERT(a_World != nullptr);
|
||||||
ASSERT(IsTicking());
|
|
||||||
|
|
||||||
if (GetWorld() == a_World)
|
if (GetWorld() == a_World)
|
||||||
{
|
{
|
||||||
@ -1586,6 +1583,9 @@ bool cEntity::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn, Vector3d
|
|||||||
// Tell others we are gone
|
// Tell others we are gone
|
||||||
GetWorld()->BroadcastDestroyEntity(*this);
|
GetWorld()->BroadcastDestroyEntity(*this);
|
||||||
|
|
||||||
|
// Take note of old chunk coords
|
||||||
|
auto OldChunkCoords = cChunkDef::BlockToChunk(GetPosition());
|
||||||
|
|
||||||
// Set position to the new position
|
// Set position to the new position
|
||||||
SetPosition(a_NewPosition);
|
SetPosition(a_NewPosition);
|
||||||
|
|
||||||
@ -1600,16 +1600,15 @@ bool cEntity::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn, Vector3d
|
|||||||
|
|
||||||
// Queue add to new world and removal from the old one
|
// Queue add to new world and removal from the old one
|
||||||
cWorld * OldWorld = GetWorld();
|
cWorld * OldWorld = GetWorld();
|
||||||
cChunk * ParentChunk = GetParentChunk();
|
|
||||||
SetWorld(a_World); // Chunks may be streamed before cWorld::AddPlayer() sets the world to the new value
|
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)
|
OldWorld->QueueTask([this, OldChunkCoords, a_World](cWorld & a_OldWorld)
|
||||||
{
|
{
|
||||||
LOGD("Warping entity #%i (%s) from world \"%s\" to \"%s\". Source chunk: (%d, %d) ",
|
LOGD("Warping entity #%i (%s) from world \"%s\" to \"%s\". Source chunk: (%d, %d) ",
|
||||||
this->GetUniqueID(), this->GetClass(),
|
this->GetUniqueID(), this->GetClass(),
|
||||||
a_OldWorld.GetName().c_str(), a_World->GetName().c_str(),
|
a_OldWorld.GetName().c_str(), a_World->GetName().c_str(),
|
||||||
ParentChunk->GetPosX(), ParentChunk->GetPosZ()
|
OldChunkCoords.m_ChunkX, OldChunkCoords.m_ChunkZ
|
||||||
);
|
);
|
||||||
a_World->AddEntity(ParentChunk->RemoveEntity(*this));
|
a_World->AddEntity(a_OldWorld.RemoveEntity(*this));
|
||||||
cRoot::Get()->GetPluginManager()->CallHookEntityChangedWorld(*this, a_OldWorld);
|
cRoot::Get()->GetPluginManager()->CallHookEntityChangedWorld(*this, a_OldWorld);
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
|
@ -3709,6 +3709,36 @@ bool cWorld::HasEntity(UInt32 a_UniqueID)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
OwnedEntity cWorld::RemoveEntity(cEntity & a_Entity)
|
||||||
|
{
|
||||||
|
// Check if the entity is in the chunkmap:
|
||||||
|
auto Entity = m_ChunkMap->RemoveEntity(a_Entity);
|
||||||
|
if (Entity != nullptr)
|
||||||
|
{
|
||||||
|
return Entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the entity is in the queue to be added to the world:
|
||||||
|
cCSLock Lock(m_CSEntitiesToAdd);
|
||||||
|
auto itr = std::find_if(m_EntitiesToAdd.begin(), m_EntitiesToAdd.end(),
|
||||||
|
[&a_Entity](const OwnedEntity & a_OwnedEntity)
|
||||||
|
{
|
||||||
|
return (a_OwnedEntity.get() == &a_Entity);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (itr != m_EntitiesToAdd.end())
|
||||||
|
{
|
||||||
|
Entity = std::move(*itr);
|
||||||
|
m_EntitiesToAdd.erase(itr);
|
||||||
|
}
|
||||||
|
return Entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
unsigned int cWorld::GetNumPlayers(void)
|
unsigned int cWorld::GetNumPlayers(void)
|
||||||
{
|
{
|
||||||
|
@ -301,6 +301,10 @@ public:
|
|||||||
Note: Only loaded chunks are considered. */
|
Note: Only loaded chunks are considered. */
|
||||||
bool HasEntity(UInt32 a_UniqueID);
|
bool HasEntity(UInt32 a_UniqueID);
|
||||||
|
|
||||||
|
/** Removes the entity from the world.
|
||||||
|
Returns an owning reference to the found entity. */
|
||||||
|
OwnedEntity RemoveEntity(cEntity & a_Entity);
|
||||||
|
|
||||||
/** Calls the callback for each entity in the entire world; returns true if all entities processed, false if the callback aborted by returning true */
|
/** Calls the callback for each entity in the entire world; returns true if all entities processed, false if the callback aborted by returning true */
|
||||||
bool ForEachEntity(cEntityCallback & a_Callback); // Exported in ManualBindings.cpp
|
bool ForEachEntity(cEntityCallback & a_Callback); // Exported in ManualBindings.cpp
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user