1
0

Chunk coords mostly "upgraded" to include the Y coord for future compatibility

git-svn-id: http://mc-server.googlecode.com/svn/trunk@285 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
madmaxoft@gmail.com 2012-02-17 17:56:25 +00:00
parent a97774624a
commit 510133bd35
11 changed files with 101 additions and 67 deletions

View File

@ -313,7 +313,7 @@ bool cWSSCompact::cPAKFile::LoadChunk(const cChunkCoords & a_Chunk, int a_Offset
}
}
a_World->ChunkDataLoaded(a_Chunk.m_ChunkX, 0, a_Chunk.m_ChunkZ, UncompressedData.data(), Entities, BlockEntities);
a_World->ChunkDataLoaded(a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ, UncompressedData.data(), Entities, BlockEntities);
return true;
}
@ -348,11 +348,11 @@ bool cWSSCompact::cPAKFile::SaveChunkToData(const cChunkCoords & a_Chunk, cWorld
{
// Serialize the chunk:
cJsonChunkSerializer Serializer;
a_World->GetChunkData(a_Chunk.m_ChunkX, 0, a_Chunk.m_ChunkZ, &Serializer);
a_World->GetChunkData(a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ, &Serializer);
if (Serializer.GetBlockData().empty())
{
// Chunk not valid
LOG("cWSSCompact: Trying to save chunk [%d, %d] that has no data, ignoring request.", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ);
LOG("cWSSCompact: Trying to save chunk [%d, %d, %d] that has no data, ignoring request.", a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ);
return false;
}
@ -371,7 +371,7 @@ bool cWSSCompact::cPAKFile::SaveChunkToData(const cChunkCoords & a_Chunk, cWorld
int errorcode = CompressString(Data.data(), Data.size(), CompressedData);
if ( errorcode != Z_OK )
{
LOGERROR("Error %i compressing data for chunk [%d, %d]", errorcode, a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ);
LOGERROR("Error %i compressing data for chunk [%d, %d, %d]", errorcode, a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ);
return false;
}
@ -382,7 +382,7 @@ bool cWSSCompact::cPAKFile::SaveChunkToData(const cChunkCoords & a_Chunk, cWorld
sChunkHeader * Header = new sChunkHeader;
if (Header == NULL)
{
LOGWARNING("Cannot create a new chunk header to save chunk [%d, %d]", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ);
LOGWARNING("Cannot create a new chunk header to save chunk [%d, %d, %d]", a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ);
return false;
}
Header->m_CompressedSize = (int)CompressedData.size();

View File

@ -161,12 +161,12 @@ void cWorldStorage::WaitForFinish(void)
void cWorldStorage::QueueLoadChunk(int a_ChunkX, int a_ChunkZ)
void cWorldStorage::QueueLoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
{
// Queues the chunk for loading; if not loaded, the chunk will be generated
cCSLock Lock(m_CSLoadQueue);
m_LoadQueue.remove (cChunkCoords(a_ChunkX, a_ChunkZ)); // Don't add twice
m_LoadQueue.push_back(cChunkCoords(a_ChunkX, a_ChunkZ));
m_LoadQueue.remove (cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); // Don't add twice
m_LoadQueue.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ));
m_Event.Set();
}
@ -174,11 +174,11 @@ void cWorldStorage::QueueLoadChunk(int a_ChunkX, int a_ChunkZ)
void cWorldStorage::QueueSaveChunk(int a_ChunkX, int a_ChunkZ)
void cWorldStorage::QueueSaveChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
{
cCSLock Lock(m_CSSaveQueue);
m_SaveQueue.remove (cChunkCoords(a_ChunkX, a_ChunkZ)); // Don't add twice
m_SaveQueue.push_back(cChunkCoords(a_ChunkX, a_ChunkZ));
m_SaveQueue.remove (cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); // Don't add twice
m_SaveQueue.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ));
m_Event.Set();
}
@ -268,7 +268,7 @@ void cWorldStorage::Execute(void)
bool cWorldStorage::LoadOneChunk(void)
{
cChunkCoords ToLoad(0, 0);
cChunkCoords ToLoad(0, 0, 0);
bool HasMore;
bool ShouldLoad = false;
{
@ -284,7 +284,7 @@ bool cWorldStorage::LoadOneChunk(void)
if (ShouldLoad && !LoadChunk(ToLoad))
{
// The chunk couldn't be loaded, generate it:
m_World->GetGenerator().GenerateChunk(ToLoad.m_ChunkX, ToLoad.m_ChunkZ);
m_World->GetGenerator().GenerateChunk(ToLoad.m_ChunkX, ToLoad.m_ChunkY, ToLoad.m_ChunkZ);
}
return HasMore;
}
@ -295,7 +295,7 @@ bool cWorldStorage::LoadOneChunk(void)
bool cWorldStorage::SaveOneChunk(void)
{
cChunkCoords Save(0, 0);
cChunkCoords Save(0, 0, 0);
bool HasMore;
bool ShouldSave = false;
{
@ -308,16 +308,16 @@ bool cWorldStorage::SaveOneChunk(void)
}
HasMore = (m_SaveQueue.size() > 0);
}
if (ShouldSave)
if (ShouldSave && m_World->IsChunkValid(Save.m_ChunkX, Save.m_ChunkY, Save.m_ChunkZ))
{
m_World->MarkChunkSaving(Save.m_ChunkX, 0, Save.m_ChunkZ);
m_World->MarkChunkSaving(Save.m_ChunkX, Save.m_ChunkY, Save.m_ChunkZ);
if (m_SaveSchema->SaveChunk(Save))
{
m_World->MarkChunkSaved(Save.m_ChunkX, 0, Save.m_ChunkZ);
m_World->MarkChunkSaved(Save.m_ChunkX, Save.m_ChunkY, Save.m_ChunkZ);
}
else
{
LOGWARNING("Cannot save chunk [%d, %d]", Save.m_ChunkX, Save.m_ChunkZ);
LOGWARNING("Cannot save chunk [%d, %d, %d]", Save.m_ChunkX, Save.m_ChunkY, Save.m_ChunkZ);
}
}
return HasMore;
@ -329,7 +329,7 @@ bool cWorldStorage::SaveOneChunk(void)
bool cWorldStorage::LoadChunk(const cChunkCoords & a_Chunk)
{
if (m_World->IsChunkValid(a_Chunk.m_ChunkX, 0, a_Chunk.m_ChunkZ))
if (m_World->IsChunkValid(a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ))
{
// Already loaded (can happen, since the queue is async)
return true;

View File

@ -97,8 +97,8 @@ public:
cWorldStorage(void);
~cWorldStorage();
void QueueLoadChunk(int a_ChunkX, int a_ChunkZ); // Queues the chunk for loading; if not loaded, the chunk will be generated
void QueueSaveChunk(int a_ChunkX, int a_ChunkZ);
void QueueLoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Queues the chunk for loading; if not loaded, the chunk will be generated
void QueueSaveChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
void UnqueueLoad(const cChunkCoords & a_Chunk);
void UnqueueSave(const cChunkCoords & a_Chunk);

View File

@ -20,6 +20,15 @@
/** This is really only a placeholder to be used in places where we need to "make up" a chunk's Y coord.
It will help us when the new chunk format comes out and we need to patch everything up for compatibility.
*/
#define ZERO_CHUNK_Y 0
namespace Json
{
class Value;
@ -238,13 +247,14 @@ class cChunkCoords
{
public:
int m_ChunkX;
int m_ChunkY;
int m_ChunkZ;
cChunkCoords(int a_ChunkX, int a_ChunkZ) : m_ChunkX(a_ChunkX), m_ChunkZ(a_ChunkZ) {}
cChunkCoords(int a_ChunkX, int a_ChunkY, int a_ChunkZ) : m_ChunkX(a_ChunkX), m_ChunkY(a_ChunkY), m_ChunkZ(a_ChunkZ) {}
bool operator == (const cChunkCoords & a_Other)
{
return ((m_ChunkX == a_Other.m_ChunkX) && (m_ChunkZ == a_Other.m_ChunkZ));
return ((m_ChunkX == a_Other.m_ChunkX) && (m_ChunkY == a_Other.m_ChunkY) && (m_ChunkZ == a_Other.m_ChunkZ));
}
} ;

View File

@ -81,14 +81,14 @@ void cChunkGenerator::Stop(void)
void cChunkGenerator::GenerateChunk(int a_ChunkX, int a_ChunkZ)
void cChunkGenerator::GenerateChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
{
cCSLock Lock(m_CS);
// Check if it is already in the queue:
for (cChunkCoordsList::iterator itr = m_Queue.begin(); itr != m_Queue.end(); ++itr)
{
if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkZ == a_ChunkZ))
if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkY == a_ChunkY) && (itr->m_ChunkZ == a_ChunkZ))
{
// Already in the queue, bail out
return;
@ -100,7 +100,7 @@ void cChunkGenerator::GenerateChunk(int a_ChunkX, int a_ChunkZ)
{
LOGWARN("WARNING: Adding chunk [%i, %i] to generation queue; Queue is too big! (%i)", a_ChunkX, a_ChunkZ, m_Queue.size());
}
m_Queue.push_back(cChunkCoords(a_ChunkX, a_ChunkZ));
m_Queue.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ));
m_Event.Set();
}
@ -130,24 +130,32 @@ void cChunkGenerator::Execute(void)
Lock.Unlock(); // Unlock ASAP
if (
m_World->IsChunkValid(coords.m_ChunkX, 0, coords.m_ChunkZ) ||
(SkipEnabled && m_World->HasChunkAnyClients(coords.m_ChunkX, 0, coords.m_ChunkZ))
m_World->IsChunkValid(coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ) ||
(SkipEnabled && m_World->HasChunkAnyClients(coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ))
)
{
// Already generated / overload-skip, ignore request
continue;
}
LOG("Generating chunk [%d, %d]", coords.m_ChunkX, coords.m_ChunkZ);
m_pWorldGenerator->GenerateChunk(coords.m_ChunkX, 0, coords.m_ChunkZ);
LOG("Generating chunk [%d, %d, %d]", coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ);
DoGenerate(coords.m_ChunkX, coords.m_ChunkY, 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);
m_World->GetStorage().QueueSaveChunk(coords.m_ChunkX, coords.m_ChunkY, coords.m_ChunkZ);
} // while (!bStop)
}
void cChunkGenerator::DoGenerate(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
{
// TODO: Convert this not to require the actual cChunkPtr (generate into raw char array)
// char BlockData[cChunk::c_BlockDataSize];
m_pWorldGenerator->GenerateChunk(a_ChunkX, a_ChunkY, a_ChunkZ);
}

View File

@ -42,19 +42,21 @@ public:
bool Start(cWorld * a_World, const AString & a_WorldGeneratorName);
void Stop(void);
void GenerateChunk(int a_ChunkX, int a_ChunkZ); // Queues the chunk for generation; removes duplicate requests
void GenerateChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Queues the chunk for generation; removes duplicate requests
private:
// cIsThread override:
virtual void Execute(void) override;
cWorld * m_World;
cWorldGenerator * m_pWorldGenerator;
cCriticalSection m_CS;
cChunkCoordsList m_Queue;
cEvent m_Event; // Set when an item is added to the queue or the thread should terminate
// cIsThread override:
virtual void Execute(void) override;
void DoGenerate(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
};

View File

@ -103,10 +103,10 @@ cChunkPtr cChunkMap::GetChunk( int a_ChunkX, int a_ChunkY, int a_ChunkZ )
return cChunkPtr();
}
cChunkPtr Chunk = Layer->GetChunk(a_ChunkX, a_ChunkZ);
cChunkPtr Chunk = Layer->GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ);
if (!(Chunk->IsValid()))
{
m_World->GetStorage().QueueLoadChunk(a_ChunkX, a_ChunkZ);
m_World->GetStorage().QueueLoadChunk(a_ChunkX, a_ChunkY, a_ChunkZ);
}
return Chunk;
}
@ -125,7 +125,7 @@ cChunkPtr cChunkMap::GetChunkNoGen( int a_ChunkX, int a_ChunkY, int a_ChunkZ )
return cChunkPtr();
}
cChunkPtr Chunk = Layer->GetChunk(a_ChunkX, a_ChunkZ);
cChunkPtr Chunk = Layer->GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ);
// TODO: Load, but do not generate, if not valid
@ -341,7 +341,7 @@ cChunkMap::cChunkLayer::cChunkLayer(int a_LayerX, int a_LayerZ, cChunkMap * a_Pa
cChunkPtr cChunkMap::cChunkLayer::GetChunk( int a_ChunkX, int a_ChunkZ )
cChunkPtr cChunkMap::cChunkLayer::GetChunk( int a_ChunkX, int a_ChunkY, int a_ChunkZ )
{
// Always returns an assigned chunkptr, but the chunk needn't be valid (loaded / generated) - callers must check
@ -371,7 +371,8 @@ void cChunkMap::cChunkLayer::Tick(float a_Dt, MTRand & a_TickRand)
{
for (int i = 0; i < ARRAYCOUNT(m_Chunks); i++)
{
if ((m_Chunks[i] != NULL) && (m_Chunks[i]->IsValid()))
// Only tick chunks that are valid and have clients:
if ((m_Chunks[i] != NULL) && m_Chunks[i]->IsValid() && m_Chunks[i]->HasAnyClients())
{
m_Chunks[i]->Tick(a_Dt, a_TickRand);
}
@ -382,6 +383,23 @@ void cChunkMap::cChunkLayer::Tick(float a_Dt, MTRand & a_TickRand)
int cChunkMap::cChunkLayer::GetNumChunksLoaded(void) const
{
int NumChunks = 0;
for ( int i = 0; i < ARRAYCOUNT(m_Chunks); ++i )
{
if (m_Chunks[i] != NULL)
{
NumChunks++;
}
} // for i - m_Chunks[]
return NumChunks;
}
void cChunkMap::cChunkLayer::Save(void)
{
cWorld * World = m_Parent->GetWorld();
@ -389,7 +407,7 @@ void cChunkMap::cChunkLayer::Save(void)
{
if ((m_Chunks[i] != NULL) && m_Chunks[i]->IsValid() && m_Chunks[i]->IsDirty())
{
World->GetStorage().QueueSaveChunk(m_Chunks[i]->GetPosX(), m_Chunks[i]->GetPosZ());
World->GetStorage().QueueSaveChunk(m_Chunks[i]->GetPosX(), m_Chunks[i]->GetPosY(), m_Chunks[i]->GetPosZ());
}
} // for i - m_Chunks[]
}

View File

@ -89,18 +89,12 @@ private:
cChunkLayer(int a_LayerX, int a_LayerZ, cChunkMap * a_Parent);
/// Always returns an assigned chunkptr, but the chunk needn't be valid (loaded / generated) - callers must check
cChunkPtr GetChunk( int a_ChunkX, int a_ChunkZ );
cChunkPtr GetChunk( int a_ChunkX, int a_ChunkY, int a_ChunkZ );
int GetX(void) const {return m_LayerX; }
int GetZ(void) const {return m_LayerZ; }
int GetNumChunksLoaded(void) const
{
int NumChunks = 0;
for( int i = 0; i < LAYER_SIZE*LAYER_SIZE; ++i )
if( m_Chunks[i].get() )
NumChunks++;
return NumChunks;
}
int GetNumChunksLoaded(void) const ;
void Save(void);
void UnloadUnusedChunks(void);

View File

@ -342,7 +342,7 @@ void cClientHandle::StreamChunks(void)
int RelZ = (*itr).m_ChunkZ - ChunkPosZ;
if ((RelX > VIEWDISTANCE) || (RelX < -VIEWDISTANCE) || (RelZ > VIEWDISTANCE) || (RelZ < -VIEWDISTANCE))
{
World->GetChunk((*itr).m_ChunkX, 0, (*itr).m_ChunkZ)->RemoveClient(this);
World->GetChunk(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ)->RemoveClient(this);
itr = m_LoadedChunks.erase(itr);
}
else
@ -372,13 +372,13 @@ void cClientHandle::StreamChunks(void)
// For each distance add chunks in a hollow square centered around current position:
for (int i = -d; i <= d; ++i)
{
StreamChunk(ChunkPosX + d, ChunkPosZ + i);
StreamChunk(ChunkPosX - d, ChunkPosZ + i);
StreamChunk(ChunkPosX + d, ZERO_CHUNK_Y, ChunkPosZ + i);
StreamChunk(ChunkPosX - d, ZERO_CHUNK_Y, ChunkPosZ + i);
} // for i
for (int i = -d + 1; i < d; ++i)
{
StreamChunk(ChunkPosX + i, ChunkPosZ + d);
StreamChunk(ChunkPosX + i, ChunkPosZ - d);
StreamChunk(ChunkPosX + i, ZERO_CHUNK_Y, ChunkPosZ + d);
StreamChunk(ChunkPosX + i, ZERO_CHUNK_Y, ChunkPosZ - d);
} // for i
} // for d
@ -388,13 +388,13 @@ void cClientHandle::StreamChunks(void)
// For each distance touch chunks in a hollow square centered around current position:
for (int i = -d; i <= d; ++i)
{
World->GetChunk(ChunkPosX + d, 0, ChunkPosZ + i);
World->GetChunk(ChunkPosX - d, 0, ChunkPosZ + i);
World->GetChunk(ChunkPosX + d, ZERO_CHUNK_Y, ChunkPosZ + i);
World->GetChunk(ChunkPosX - d, ZERO_CHUNK_Y, ChunkPosZ + i);
} // for i
for (int i = -d + 1; i < d; ++i)
{
World->GetChunk(ChunkPosX + i, 0, ChunkPosZ + d);
World->GetChunk(ChunkPosX + i, 0, ChunkPosZ - d);
World->GetChunk(ChunkPosX + i, ZERO_CHUNK_Y, ChunkPosZ + d);
World->GetChunk(ChunkPosX + i, ZERO_CHUNK_Y, ChunkPosZ - d);
} // for i
} // for d
}
@ -402,7 +402,7 @@ void cClientHandle::StreamChunks(void)
void cClientHandle::StreamChunk(int a_ChunkX, int a_ChunkZ)
void cClientHandle::StreamChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
{
cWorld * World = m_Player->GetWorld();
assert(World != NULL);
@ -412,8 +412,8 @@ void cClientHandle::StreamChunk(int a_ChunkX, int a_ChunkZ)
{
Chunk->AddClient(this);
cCSLock Lock(m_CSChunkLists);
m_LoadedChunks.push_back(cChunkCoords(a_ChunkX, a_ChunkZ));
m_ChunksToSend.push_back(cChunkCoords(a_ChunkX, a_ChunkZ));
m_LoadedChunks.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ));
m_ChunksToSend.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ));
}
}
@ -430,7 +430,7 @@ void cClientHandle::RemoveFromAllChunks()
{
for (cChunkCoordsList::iterator itr = m_LoadedChunks.begin(); itr != m_LoadedChunks.end(); ++itr)
{
World->GetChunk(itr->m_ChunkX, 0, itr->m_ChunkZ)->RemoveClient(this);
World->GetChunk(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ)->RemoveClient(this);
}
}
m_LoadedChunks.clear();
@ -1656,7 +1656,7 @@ void cClientHandle::Tick(float a_Dt)
int NumSent = 0;
for (cChunkCoordsList::iterator itr = m_ChunksToSend.begin(); itr != m_ChunksToSend.end();)
{
cChunkPtr Chunk = World->GetChunk(itr->m_ChunkX, 0, itr->m_ChunkZ);
cChunkPtr Chunk = World->GetChunk(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ);
if (!Chunk->IsValid())
{
++itr;

View File

@ -201,7 +201,7 @@ private:
void SendConfirmPosition(void);
/// Adds a single chunk to be streamed to the client; used by StreamChunks()
void StreamChunk(int a_ChunkX, int a_ChunkZ);
void StreamChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
// cSocketThreads::cCallback overrides:
virtual void DataReceived (const char * a_Data, int a_Size) override; // Data is received from the client

View File

@ -273,6 +273,8 @@ cWorld::cWorld( const AString & a_WorldName )
g_BlockTransparent[ E_BLOCK_TORCH ] = true;
g_BlockTransparent[ E_BLOCK_SIGN_POST ] = true;
g_BlockTransparent[ E_BLOCK_WALLSIGN ] = true;
// TODO: Also set flowers, mushrooms etc as transparent
// One hit break blocks
g_BlockOneHitDig[ E_BLOCK_SAPLING ] = true;