Merge pull request #3100 from LogicParrot/mobTick2
Move mob tick code to cChunk
This commit is contained in:
commit
dc15d274b5
@ -40,6 +40,7 @@
|
|||||||
#include "SetChunkData.h"
|
#include "SetChunkData.h"
|
||||||
#include "BoundingBox.h"
|
#include "BoundingBox.h"
|
||||||
#include "Blocks/ChunkInterface.h"
|
#include "Blocks/ChunkInterface.h"
|
||||||
|
#include "Mobs/Wolf.h"
|
||||||
|
|
||||||
#include "json/json.h"
|
#include "json/json.h"
|
||||||
|
|
||||||
@ -641,13 +642,11 @@ void cChunk::Tick(std::chrono::milliseconds a_Dt)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!((*itr)->IsMob())) // Mobs are ticked inside cWorld::TickMobs() (as we don't have to tick them if they are far away from players)
|
// Tick all entities in this chunk - including mobs.
|
||||||
{
|
// In the past Cuberite ticked mobs in cWorld. This is no longer the case.
|
||||||
// Tick all entities in this chunk (except mobs):
|
ASSERT((*itr)->GetParentChunk() == this);
|
||||||
ASSERT((*itr)->GetParentChunk() == this);
|
(*itr)->Tick(a_Dt, *this);
|
||||||
(*itr)->Tick(a_Dt, *this);
|
ASSERT((*itr)->GetParentChunk() == this);
|
||||||
ASSERT((*itr)->GetParentChunk() == this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do not move mobs that are detached from the world to neighbors. They're either scheduled for teleportation or for removal.
|
// Do not move mobs that are detached from the world to neighbors. They're either scheduled for teleportation or for removal.
|
||||||
// Because the schedulded destruction is going to look for them in this chunk. See cEntity::destroy.
|
// Because the schedulded destruction is going to look for them in this chunk. See cEntity::destroy.
|
||||||
@ -1853,11 +1852,11 @@ bool cChunk::AddClient(cClientHandle * a_Client)
|
|||||||
|
|
||||||
void cChunk::RemoveClient(cClientHandle * a_Client)
|
void cChunk::RemoveClient(cClientHandle * a_Client)
|
||||||
{
|
{
|
||||||
auto itr = std::remove(m_LoadedByClient.begin(), m_LoadedByClient.end(), a_Client);
|
auto ClientItr = std::remove(m_LoadedByClient.begin(), m_LoadedByClient.end(), a_Client);
|
||||||
// We should always remove at most one client.
|
// We should always remove at most one client.
|
||||||
ASSERT(std::distance(itr, m_LoadedByClient.end()) <= 1);
|
ASSERT(std::distance(ClientItr, m_LoadedByClient.end()) <= 1);
|
||||||
// Note: itr can equal m_LoadedByClient.end()
|
// Note: itr can equal m_LoadedByClient.end()
|
||||||
m_LoadedByClient.erase(itr, m_LoadedByClient.end());
|
m_LoadedByClient.erase(ClientItr, m_LoadedByClient.end());
|
||||||
|
|
||||||
if (!a_Client->IsDestroyed())
|
if (!a_Client->IsDestroyed())
|
||||||
{
|
{
|
||||||
@ -1874,6 +1873,37 @@ void cChunk::RemoveClient(cClientHandle * a_Client)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// All clients were removed. No one sees this chunk any more.
|
||||||
|
// Delete all hostiles inside it.
|
||||||
|
if (!HasAnyClients())
|
||||||
|
{
|
||||||
|
for (auto Entity : m_Entities)
|
||||||
|
{
|
||||||
|
if (Entity->IsTicking() && Entity->IsMob())
|
||||||
|
{
|
||||||
|
auto Monster = static_cast<cMonster *>(Entity);
|
||||||
|
if (
|
||||||
|
(Monster->GetMobFamily() == cMonster::eFamily::mfHostile) &&
|
||||||
|
(Monster->GetCustomName().empty()) // Monsters that have name tags are never removed
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Non-hostile wolves should not be removed when player is too far
|
||||||
|
if (Monster->GetMobType() != eMonsterType::mtWolf)
|
||||||
|
{
|
||||||
|
Monster->Destroy(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto Wolf = static_cast<cWolf *>(Monster);
|
||||||
|
if (Wolf->IsAngry())
|
||||||
|
{
|
||||||
|
Monster->Destroy(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1131,52 +1131,6 @@ void cWorld::TickMobs(std::chrono::milliseconds a_Dt)
|
|||||||
}
|
}
|
||||||
} // for i - AllFamilies[]
|
} // for i - AllFamilies[]
|
||||||
} // if (Spawning enabled)
|
} // if (Spawning enabled)
|
||||||
|
|
||||||
class cCallback : public cEntityCallback
|
|
||||||
{
|
|
||||||
virtual bool Item(cEntity * a_Entity) override
|
|
||||||
{
|
|
||||||
if (!a_Entity->IsMob())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!a_Entity->IsTicking())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto Monster = static_cast<cMonster *>(a_Entity);
|
|
||||||
ASSERT(Monster->GetParentChunk() != nullptr); // A ticking entity must have a valid parent chunk
|
|
||||||
|
|
||||||
// Tick close mobs
|
|
||||||
if (Monster->GetParentChunk()->HasAnyClients())
|
|
||||||
{
|
|
||||||
Monster->Tick(m_Dt, *(a_Entity->GetParentChunk()));
|
|
||||||
}
|
|
||||||
// Destroy far hostile mobs
|
|
||||||
else if ((Monster->GetMobFamily() == cMonster::eFamily::mfHostile))
|
|
||||||
{
|
|
||||||
if (Monster->GetMobType() != eMonsterType::mtWolf)
|
|
||||||
{
|
|
||||||
Monster->Destroy(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto Wolf = static_cast<cWolf *>(Monster);
|
|
||||||
if (Wolf->IsAngry())
|
|
||||||
{
|
|
||||||
Monster->Destroy(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
std::chrono::milliseconds m_Dt;
|
|
||||||
} Callback;
|
|
||||||
|
|
||||||
Callback.m_Dt = a_Dt;
|
|
||||||
ForEachEntity(Callback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user