cWorldGenerator speedup - doesn't call GetChunk() anymore, not queueing the chunk it's generating to be loaded recursively.
cChunk fix - setting a block to the same value doesn't mark chunk dirty (resulted in un-unloadable chunks) git-svn-id: http://mc-server.googlecode.com/svn/trunk@279 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
parent
008addf5d7
commit
2928cb6853
@ -805,8 +805,6 @@ void cChunk::SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_Block
|
||||
|
||||
assert(IsValid()); // Is this chunk loaded / generated?
|
||||
|
||||
MarkDirty();
|
||||
|
||||
int index = a_Y + (a_Z * 128) + (a_X * 128 * 16);
|
||||
char OldBlockMeta = GetLight( m_BlockMeta, index );
|
||||
char OldBlockType = m_BlockType[index];
|
||||
@ -819,6 +817,8 @@ void cChunk::SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_Block
|
||||
return;
|
||||
}
|
||||
|
||||
MarkDirty();
|
||||
|
||||
cCSLock Lock(m_CSBlockLists);
|
||||
m_PendingSendBlocks.push_back( index );
|
||||
|
||||
@ -871,14 +871,15 @@ void cChunk::FastSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_B
|
||||
|
||||
assert(IsValid());
|
||||
|
||||
MarkDirty();
|
||||
|
||||
const int index = a_Y + (a_Z * 128) + (a_X * 128 * 16);
|
||||
const char OldBlock = m_BlockType[index];
|
||||
if (OldBlock == a_BlockType)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MarkDirty();
|
||||
|
||||
m_BlockType[index] = a_BlockType;
|
||||
|
||||
{
|
||||
@ -1107,7 +1108,7 @@ bool cChunk::HasClient( cClientHandle* a_Client )
|
||||
|
||||
|
||||
|
||||
bool cChunk::HasAnyClient(void)
|
||||
bool cChunk::HasAnyClients(void)
|
||||
{
|
||||
cCSLock Lock(m_CSClients);
|
||||
return !m_LoadedByClient.empty();
|
||||
|
@ -114,10 +114,10 @@ public:
|
||||
|
||||
void SendBlockTo( int a_X, int a_Y, int a_Z, cClientHandle* a_Client );
|
||||
|
||||
void AddClient ( cClientHandle* a_Client );
|
||||
void RemoveClient( cClientHandle* a_Client );
|
||||
bool HasClient ( cClientHandle* a_Client );
|
||||
bool HasAnyClient(void); // Returns true if theres any client in the chunk; false otherwise
|
||||
void AddClient (cClientHandle* a_Client );
|
||||
void RemoveClient (cClientHandle* a_Client );
|
||||
bool HasClient (cClientHandle* a_Client );
|
||||
bool HasAnyClients(void); // Returns true if theres any client in the chunk; false otherwise
|
||||
|
||||
void AddEntity( cEntity * a_Entity );
|
||||
void RemoveEntity( cEntity * a_Entity);
|
||||
|
@ -53,11 +53,11 @@ bool cChunkGenerator::Start(cWorld * a_World, const AString & a_WorldGeneratorNa
|
||||
|
||||
if (a_WorldGeneratorName.compare("Test") == 0 )
|
||||
{
|
||||
m_pWorldGenerator = new cWorldGenerator_Test();
|
||||
m_pWorldGenerator = new cWorldGenerator_Test(a_World);
|
||||
}
|
||||
else // Default
|
||||
{
|
||||
m_pWorldGenerator = new cWorldGenerator();
|
||||
m_pWorldGenerator = new cWorldGenerator(a_World);
|
||||
}
|
||||
|
||||
return super::Start();
|
||||
@ -129,17 +129,22 @@ void cChunkGenerator::Execute(void)
|
||||
bool SkipEnabled = (m_Queue.size() > QUEUE_SKIP_LIMIT);
|
||||
Lock.Unlock(); // Unlock ASAP
|
||||
|
||||
cChunkPtr Chunk = m_World->GetChunk(coords.m_ChunkX, 0, coords.m_ChunkZ);
|
||||
if ((Chunk != NULL) && (Chunk->IsValid() || (SkipEnabled && !Chunk->HasAnyClient())))
|
||||
if (
|
||||
m_World->IsChunkValid(coords.m_ChunkX, 0, coords.m_ChunkZ) ||
|
||||
(SkipEnabled && m_World->HasChunkAnyClients(coords.m_ChunkX, 0, coords.m_ChunkZ))
|
||||
)
|
||||
{
|
||||
// Already generated / overload-skip, ignore request
|
||||
continue;
|
||||
}
|
||||
|
||||
LOG("Generating chunk [%d, %d]", coords.m_ChunkX, coords.m_ChunkZ);
|
||||
m_pWorldGenerator->GenerateChunk(Chunk);
|
||||
|
||||
Chunk->SetValid();
|
||||
LOG("Generating chunk [%d, %d]", coords.m_ChunkX, coords.m_ChunkZ);
|
||||
m_pWorldGenerator->GenerateChunk(coords.m_ChunkX, 0, coords.m_ChunkZ);
|
||||
|
||||
// Chunk->SetValid();
|
||||
|
||||
// Save the chunk right after generating, so that we don't have to generate it again on next run
|
||||
m_World->GetStorage().QueueSaveChunk(coords.m_ChunkX, coords.m_ChunkZ);
|
||||
} // while (!bStop)
|
||||
}
|
||||
|
||||
|
@ -276,6 +276,17 @@ bool cChunkMap::IsChunkValid(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
||||
|
||||
|
||||
|
||||
bool cChunkMap::HasChunkAnyClients(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
||||
{
|
||||
cCSLock Lock(m_CSLayers);
|
||||
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
|
||||
return (Chunk != NULL) && Chunk->HasAnyClients();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkMap::Tick( float a_Dt, MTRand & a_TickRandom )
|
||||
{
|
||||
cCSLock Lock(m_CSLayers);
|
||||
@ -389,7 +400,6 @@ void cChunkMap::cChunkLayer::Save(void)
|
||||
|
||||
void cChunkMap::cChunkLayer::UnloadUnusedChunks(void)
|
||||
{
|
||||
cWorld * World = m_Parent->GetWorld();
|
||||
for (int i = 0; i < ARRAYCOUNT(m_Chunks); i++)
|
||||
{
|
||||
if ((m_Chunks[i] != NULL) && (m_Chunks[i]->CanUnload()))
|
||||
|
@ -36,13 +36,14 @@ public:
|
||||
void BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, cPacket * a_Packet, cClientHandle * a_Exclude = NULL);
|
||||
void UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z); // a_Player rclked block entity at the coords specified, handle it
|
||||
|
||||
void MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
||||
void MarkChunkSaving(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
||||
void MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
||||
void ChunkDataLoaded(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities);
|
||||
void SetChunkData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities);
|
||||
void GetChunkData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback * a_Callback);
|
||||
bool IsChunkValid (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
||||
void MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
||||
void MarkChunkSaving (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
||||
void MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
||||
void ChunkDataLoaded (int a_ChunkX, int a_ChunkY, int a_ChunkZ, const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities);
|
||||
void SetChunkData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities);
|
||||
void GetChunkData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback * a_Callback);
|
||||
bool IsChunkValid (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
||||
bool HasChunkAnyClients(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
||||
|
||||
void Tick( float a_Dt, MTRand & a_TickRand );
|
||||
|
||||
|
@ -105,7 +105,7 @@ void cMonsterConfig::AssignAttributes(cMonster *m, const char* n)
|
||||
m->SetAttackRange (itr->m_AttackRange);
|
||||
m->SetSightDistance(itr->m_SightDistance);
|
||||
m->SetAttackRate ((int)itr->m_AttackRate);
|
||||
m->SetMaxHealth ((int)itr->m_MaxHealth);
|
||||
m->SetMaxHealth ((short)itr->m_MaxHealth);
|
||||
}
|
||||
} // for itr - m_pState->AttributesList[]
|
||||
}
|
||||
|
@ -1009,6 +1009,15 @@ bool cWorld::IsChunkValid(int a_ChunkX, int a_ChunkY, int a_ChunkZ) const
|
||||
|
||||
|
||||
|
||||
bool cWorld::HasChunkAnyClients(int a_ChunkX, int a_ChunkY, int a_ChunkZ) const
|
||||
{
|
||||
return m_ChunkMap->HasChunkAnyClients(a_ChunkX, a_ChunkY, a_ChunkZ);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::SetMaxPlayers(int iMax)
|
||||
{
|
||||
m_MaxPlayers = MAX_PLAYERS;
|
||||
|
@ -70,13 +70,14 @@ public:
|
||||
|
||||
void BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, cPacket * a_Packet, cClientHandle * a_Exclude = NULL);
|
||||
|
||||
void MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
||||
void MarkChunkSaving(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
||||
void MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
||||
void ChunkDataLoaded(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities);
|
||||
void SetChunkData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities);
|
||||
void GetChunkData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback * a_Callback);
|
||||
bool IsChunkValid (int a_ChunkX, int a_ChunkY, int a_ChunkZ) const;
|
||||
void MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
||||
void MarkChunkSaving (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
||||
void MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
||||
void ChunkDataLoaded (int a_ChunkX, int a_ChunkY, int a_ChunkZ, const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities);
|
||||
void SetChunkData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities);
|
||||
void GetChunkData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback * a_Callback);
|
||||
bool IsChunkValid (int a_ChunkX, int a_ChunkY, int a_ChunkZ) const;
|
||||
bool HasChunkAnyClients(int a_ChunkX, int a_ChunkY, int a_ChunkZ) const;
|
||||
|
||||
// MOTD
|
||||
const AString & GetDescription(void) const {return m_Description; }
|
||||
|
@ -14,7 +14,8 @@
|
||||
|
||||
|
||||
|
||||
cWorldGenerator::cWorldGenerator()
|
||||
cWorldGenerator::cWorldGenerator(cWorld * a_World) :
|
||||
m_World(a_World)
|
||||
{
|
||||
}
|
||||
|
||||
@ -30,15 +31,19 @@ cWorldGenerator::~cWorldGenerator()
|
||||
|
||||
|
||||
|
||||
void cWorldGenerator::GenerateChunk( cChunkPtr a_Chunk )
|
||||
void cWorldGenerator::GenerateChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
||||
{
|
||||
assert(!a_Chunk->IsValid());
|
||||
// TODO: use a raw char array instead of the entire chunk, then set it as chunk's blockdata
|
||||
|
||||
memset(a_Chunk->pGetBlockData(), 0, cChunk::c_BlockDataSize);
|
||||
GenerateTerrain( a_Chunk );
|
||||
GenerateFoliage( a_Chunk );
|
||||
a_Chunk->CalculateHeightmap();
|
||||
a_Chunk->CalculateLighting();
|
||||
cChunkPtr Chunk = m_World->GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
|
||||
assert(!Chunk->IsValid());
|
||||
|
||||
memset(Chunk->pGetBlockData(), 0, cChunk::c_BlockDataSize);
|
||||
GenerateTerrain(Chunk);
|
||||
GenerateFoliage(Chunk);
|
||||
Chunk->CalculateHeightmap();
|
||||
Chunk->CalculateLighting();
|
||||
Chunk->SetValid();
|
||||
}
|
||||
|
||||
|
||||
|
@ -15,13 +15,16 @@
|
||||
class cWorldGenerator
|
||||
{
|
||||
public:
|
||||
cWorldGenerator();
|
||||
cWorldGenerator(cWorld * a_World);
|
||||
~cWorldGenerator();
|
||||
|
||||
virtual void GenerateChunk( cChunkPtr a_Chunk );
|
||||
virtual void GenerateChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
||||
|
||||
protected:
|
||||
|
||||
cWorld * m_World;
|
||||
|
||||
// Thread-unsafe:
|
||||
MTRand r1;
|
||||
|
||||
virtual void GenerateTerrain( cChunkPtr a_Chunk );
|
||||
|
@ -10,6 +10,10 @@
|
||||
class cWorldGenerator_Test :
|
||||
public cWorldGenerator
|
||||
{
|
||||
public:
|
||||
|
||||
cWorldGenerator_Test(cWorld * a_World) : cWorldGenerator(a_World) {}
|
||||
|
||||
protected:
|
||||
virtual void GenerateTerrain( cChunkPtr a_Chunk ) override;
|
||||
virtual void GenerateFoliage( cChunkPtr a_Chunk ) override;
|
||||
|
Loading…
Reference in New Issue
Block a user