// GridStructGen.cpp
// Implements the cGridStructGen class representing a common base class for structure generators that place structures in a semi-random grid
#include "Globals.h"
#include "GridStructGen.h"
cGridStructGen::cGridStructGen(
int a_Seed,
int a_GridSizeX, int a_GridSizeZ,
int a_MaxStructureSizeX, int a_MaxStructureSizeZ,
size_t a_MaxCacheSize
) :
m_Seed(a_Seed),
m_GridSizeX(a_GridSizeX),
m_GridSizeZ(a_GridSizeZ),
m_MaxStructureSizeX(a_MaxStructureSizeX),
m_MaxStructureSizeZ(a_MaxStructureSizeZ),
m_MaxCacheSize(a_MaxCacheSize)
{
}
void cGridStructGen::GetStructuresForChunk(int a_ChunkX, int a_ChunkZ, cStructurePtrs & a_Structures)
{
// Calculate the min and max grid coords of the structures to be returned:
int MinBlockX = a_ChunkX * cChunkDef::Width - m_MaxStructureSizeX;
int MinBlockZ = a_ChunkZ * cChunkDef::Width - m_MaxStructureSizeZ;
int MaxBlockX = a_ChunkX * cChunkDef::Width + m_MaxStructureSizeX + cChunkDef::Width - 1;
int MaxBlockZ = a_ChunkZ * cChunkDef::Width + m_MaxStructureSizeZ + cChunkDef::Width - 1;
int MinGridX = MinBlockX / m_GridSizeX;
int MinGridZ = MinBlockZ / m_GridSizeZ;
int MaxGridX = (MaxBlockX + m_GridSizeX - 1) / m_GridSizeX;
int MaxGridZ = (MaxBlockZ + m_GridSizeZ - 1) / m_GridSizeZ;
if (MinBlockX < 0)
{
--MinGridX;
}
if (MinBlockZ < 0)
{
--MinGridZ;
}
if (MaxBlockX < 0)
{
--MaxGridX;
}
if (MaxBlockZ < 0)
{
--MaxGridZ;
}
// Walk the cache, move each structure that we want into a_Structures:
for (cStructurePtrs::iterator itr = m_Cache.begin(), end = m_Cache.end(); itr != end;)
{
if (
((*itr)->m_OriginX >= MinBlockX) && ((*itr)->m_OriginX < MaxBlockX) &&
((*itr)->m_OriginZ >= MinBlockZ) && ((*itr)->m_OriginZ < MaxBlockZ)
)
{
// want
a_Structures.push_back(*itr);
itr = m_Cache.erase(itr);
}
else
{
// don't want
++itr;
}
} // for itr - m_Cache[]
// Create those structures that haven't been in the cache:
for (int x = MinGridX; x < MaxGridX; x++)
{
int OriginX = x * m_GridSizeX;
for (int z = MinGridZ; z < MaxGridZ; z++)
{
int OriginZ = z * m_GridSizeZ;
bool Found = false;
for (cStructurePtrs::const_iterator itr = a_Structures.begin(), end = a_Structures.end(); itr != end; ++itr)
{
if (((*itr)->m_OriginX == OriginX) && ((*itr)->m_OriginZ == OriginZ))
{
Found = true;
break;
}
} // for itr - a_Structures[]
if (!Found)
{
a_Structures.push_back(CreateStructure(OriginX, OriginZ));
}
} // for z
} // for x
// Copy a_Forts into m_Cache to the beginning:
cStructurePtrs StructuresCopy (a_Structures);
m_Cache.splice(m_Cache.begin(), StructuresCopy, StructuresCopy.begin(), StructuresCopy.end());
// Trim the cache if it's too long:
size_t CacheSize = 0;
for (cStructurePtrs::iterator itr = m_Cache.begin(), end = m_Cache.end(); itr != end; ++itr)
{
CacheSize += (*itr)->GetCacheCost();
if (CacheSize > m_MaxCacheSize)
{
// Erase all items from this one till the cache end
m_Cache.erase(itr, m_Cache.end());
break;
}
}
}
void cGridStructGen::GenFinish(cChunkDesc & a_ChunkDesc)
{
int ChunkX = a_ChunkDesc.GetChunkX();
int ChunkZ = a_ChunkDesc.GetChunkZ();
cStructurePtrs Structures;
GetStructuresForChunk(ChunkX, ChunkZ, Structures);
for (cStructurePtrs::const_iterator itr = Structures.begin(); itr != Structures.end(); ++itr)
{
(*itr)->DrawIntoChunk(a_ChunkDesc);
} // for itr - Structures[]
}