1
0

cNetherFortGen uses cGridStructGen.

WIP, this doesn't work properly yet.
This commit is contained in:
madmaxoft 2014-05-07 22:34:06 +02:00
parent da5db2ddf9
commit 564261cfd9
5 changed files with 42 additions and 264 deletions

View File

@ -93,7 +93,7 @@ protected:
/// Returns all caves that *may* intersect the given chunk. All the caves are valid until the next call to this function. /// Returns all caves that *may* intersect the given chunk. All the caves are valid until the next call to this function.
void GetCavesForChunk(int a_ChunkX, int a_ChunkZ, cCaveSystems & a_Caves); void GetCavesForChunk(int a_ChunkX, int a_ChunkZ, cCaveSystems & a_Caves);
// cStructGen override: // cFinishGen override:
virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; virtual void GenFinish(cChunkDesc & a_ChunkDesc) override;
} ; } ;

View File

@ -37,21 +37,21 @@ void cGridStructGen::GetStructuresForChunk(int a_ChunkX, int a_ChunkZ, cStructur
int MaxBlockZ = a_ChunkZ * cChunkDef::Width + m_MaxStructureSizeZ + cChunkDef::Width - 1; int MaxBlockZ = a_ChunkZ * cChunkDef::Width + m_MaxStructureSizeZ + cChunkDef::Width - 1;
int MinGridX = MinBlockX / m_GridSizeX; int MinGridX = MinBlockX / m_GridSizeX;
int MinGridZ = MinBlockZ / m_GridSizeZ; int MinGridZ = MinBlockZ / m_GridSizeZ;
int MaxGridX = MaxBlockX / m_GridSizeX; int MaxGridX = (MaxBlockX + m_GridSizeX - 1) / m_GridSizeX;
int MaxGridZ = MaxBlockX / m_GridSizeZ; int MaxGridZ = (MaxBlockZ + m_GridSizeZ - 1) / m_GridSizeZ;
if (MinGridX < 0) if (MinBlockX < 0)
{ {
--MinGridX; --MinGridX;
} }
if (MinGridZ < 0) if (MinBlockZ < 0)
{ {
--MinGridZ; --MinGridZ;
} }
if (MaxGridX < 0) if (MaxBlockX < 0)
{ {
--MaxGridX; --MaxGridX;
} }
if (MaxGridZ < 0) if (MaxBlockZ < 0)
{ {
--MaxGridZ; --MaxGridZ;
} }

View File

@ -20,20 +20,21 @@ static const int NEIGHBORHOOD_SIZE = 3;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cNetherFortGen::cNetherFort: // cNetherFortGen::cNetherFort:
class cNetherFortGen::cNetherFort class cNetherFortGen::cNetherFort :
public cGridStructGen::cStructure
{ {
typedef cGridStructGen::cStructure super;
public: public:
cNetherFortGen & m_ParentGen; cNetherFortGen & m_ParentGen;
int m_BlockX, m_BlockZ;
int m_GridSize; int m_GridSize;
int m_Seed; int m_Seed;
cPlacedPieces m_Pieces; cPlacedPieces m_Pieces;
cNetherFort(cNetherFortGen & a_ParentGen, int a_BlockX, int a_BlockZ, int a_GridSize, int a_MaxDepth, int a_Seed) : cNetherFort(cNetherFortGen & a_ParentGen, int a_OriginX, int a_OriginZ, int a_GridSize, int a_MaxDepth, int a_Seed) :
super(a_OriginX, a_OriginZ),
m_ParentGen(a_ParentGen), m_ParentGen(a_ParentGen),
m_BlockX(a_BlockX),
m_BlockZ(a_BlockZ),
m_GridSize(a_GridSize), m_GridSize(a_GridSize),
m_Seed(a_Seed) m_Seed(a_Seed)
{ {
@ -43,8 +44,8 @@ public:
// Generate pieces: // Generate pieces:
for (int i = 0; m_Pieces.size() < (size_t)(a_MaxDepth * a_MaxDepth / 8 + a_MaxDepth); i++) for (int i = 0; m_Pieces.size() < (size_t)(a_MaxDepth * a_MaxDepth / 8 + a_MaxDepth); i++)
{ {
cBFSPieceGenerator pg(m_ParentGen, a_Seed + i); cBFSPieceGenerator pg(cNetherFortGen::m_PiecePool, a_Seed + i);
pg.PlacePieces(a_BlockX, BlockY, a_BlockZ, a_MaxDepth, m_Pieces); pg.PlacePieces(a_OriginX, BlockY, a_OriginZ, a_MaxDepth, m_Pieces);
} }
} }
@ -56,7 +57,7 @@ public:
/** Carves the system into the chunk data */ /** Carves the system into the chunk data */
void ProcessChunk(cChunkDesc & a_Chunk) virtual void DrawIntoChunk(cChunkDesc & a_Chunk)
{ {
for (cPlacedPieces::const_iterator itr = m_Pieces.begin(), end = m_Pieces.end(); itr != end; ++itr) for (cPlacedPieces::const_iterator itr = m_Pieces.begin(), end = m_Pieces.end(); itr != end; ++itr)
{ {
@ -107,214 +108,30 @@ public:
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cNetherFortGen: // cNetherFortGen:
cPrefabPiecePool cNetherFortGen::m_PiecePool(g_NetherFortPrefabs, g_NetherFortPrefabsCount, g_NetherFortStartingPrefabs, g_NetherFortStartingPrefabsCount);
cNetherFortGen::cNetherFortGen(int a_Seed, int a_GridSize, int a_MaxDepth) : cNetherFortGen::cNetherFortGen(int a_Seed, int a_GridSize, int a_MaxDepth) :
m_Seed(a_Seed), super(a_Seed, a_GridSize, a_GridSize, a_MaxDepth * 10, a_MaxDepth * 10, 200),
m_Noise(a_Seed),
m_GridSize(a_GridSize),
m_MaxDepth(a_MaxDepth) m_MaxDepth(a_MaxDepth)
{ {
// Initialize the prefabs:
for (size_t i = 0; i < g_NetherFortPrefabsCount; i++)
{
cPrefab * Prefab = new cPrefab(g_NetherFortPrefabs[i]);
m_AllPieces.push_back(Prefab);
if (Prefab->HasConnectorType(0))
{
m_OuterPieces.push_back(Prefab);
}
if (Prefab->HasConnectorType(1))
{
m_InnerPieces.push_back(Prefab);
}
}
// Initialize the starting piece prefabs:
for (size_t i = 0; i < g_NetherFortStartingPrefabsCount; i++)
{
m_StartingPieces.push_back(new cPrefab(g_NetherFortStartingPrefabs[i]));
}
/* /*
// DEBUG: Try one round of placement: // DEBUG: Try one round of placement:
cPlacedPieces Pieces; cPlacedPieces Pieces;
cBFSPieceGenerator pg(*this, a_Seed); cBFSPieceGenerator pg(m_PiecePool, a_Seed);
pg.PlacePieces(0, 64, 0, a_MaxDepth, Pieces); pg.PlacePieces(0, 64, 0, a_MaxDepth, Pieces);
*/ //*/
} }
cNetherFortGen::~cNetherFortGen() cGridStructGen::cStructurePtr cNetherFortGen::CreateStructure(int a_OriginX, int a_OriginZ)
{ {
ClearCache(); return cStructurePtr(new cNetherFort(*this, a_OriginX, a_OriginZ, m_GridSizeX, m_MaxDepth, m_Seed));
for (cPieces::iterator itr = m_AllPieces.begin(), end = m_AllPieces.end(); itr != end; ++itr)
{
delete *itr;
} // for itr - m_AllPieces[]
m_AllPieces.clear();
} }
void cNetherFortGen::ClearCache(void)
{
// TODO
}
void cNetherFortGen::GetFortsForChunk(int a_ChunkX, int a_ChunkZ, cNetherForts & a_Forts)
{
int BaseX = a_ChunkX * cChunkDef::Width / m_GridSize;
int BaseZ = a_ChunkZ * cChunkDef::Width / m_GridSize;
if (BaseX < 0)
{
--BaseX;
}
if (BaseZ < 0)
{
--BaseZ;
}
BaseX -= NEIGHBORHOOD_SIZE / 2;
BaseZ -= NEIGHBORHOOD_SIZE / 2;
// Walk the cache, move each cave system that we want into a_Forts:
int StartX = BaseX * m_GridSize;
int EndX = (BaseX + NEIGHBORHOOD_SIZE + 1) * m_GridSize;
int StartZ = BaseZ * m_GridSize;
int EndZ = (BaseZ + NEIGHBORHOOD_SIZE + 1) * m_GridSize;
for (cNetherForts::iterator itr = m_Cache.begin(), end = m_Cache.end(); itr != end;)
{
if (
((*itr)->m_BlockX >= StartX) && ((*itr)->m_BlockX < EndX) &&
((*itr)->m_BlockZ >= StartZ) && ((*itr)->m_BlockZ < EndZ)
)
{
// want
a_Forts.push_back(*itr);
itr = m_Cache.erase(itr);
}
else
{
// don't want
++itr;
}
} // for itr - m_Cache[]
// Create those forts that haven't been in the cache:
for (int x = 0; x < NEIGHBORHOOD_SIZE; x++)
{
int RealX = (BaseX + x) * m_GridSize;
for (int z = 0; z < NEIGHBORHOOD_SIZE; z++)
{
int RealZ = (BaseZ + z) * m_GridSize;
bool Found = false;
for (cNetherForts::const_iterator itr = a_Forts.begin(), end = a_Forts.end(); itr != end; ++itr)
{
if (((*itr)->m_BlockX == RealX) && ((*itr)->m_BlockZ == RealZ))
{
Found = true;
break;
}
} // for itr - a_Mineshafts
if (!Found)
{
a_Forts.push_back(new cNetherFort(*this, RealX, RealZ, m_GridSize, m_MaxDepth, m_Seed));
}
} // for z
} // for x
// Copy a_Forts into m_Cache to the beginning:
cNetherForts FortsCopy (a_Forts);
m_Cache.splice(m_Cache.begin(), FortsCopy, FortsCopy.begin(), FortsCopy.end());
// Trim the cache if it's too long:
if (m_Cache.size() > 100)
{
cNetherForts::iterator itr = m_Cache.begin();
std::advance(itr, 100);
for (cNetherForts::iterator end = m_Cache.end(); itr != end; ++itr)
{
delete *itr;
}
itr = m_Cache.begin();
std::advance(itr, 100);
m_Cache.erase(itr, m_Cache.end());
}
}
void cNetherFortGen::GenFinish(cChunkDesc & a_ChunkDesc)
{
int ChunkX = a_ChunkDesc.GetChunkX();
int ChunkZ = a_ChunkDesc.GetChunkZ();
cNetherForts Forts;
GetFortsForChunk(ChunkX, ChunkZ, Forts);
for (cNetherForts::const_iterator itr = Forts.begin(); itr != Forts.end(); ++itr)
{
(*itr)->ProcessChunk(a_ChunkDesc);
} // for itr - Forts[]
}
cPieces cNetherFortGen::GetPiecesWithConnector(int a_ConnectorType)
{
switch (a_ConnectorType)
{
case 0: return m_OuterPieces;
case 1: return m_InnerPieces;
default: return cPieces();
}
}
cPieces cNetherFortGen::GetStartingPieces(void)
{
return m_StartingPieces;
}
int cNetherFortGen::GetPieceWeight(const cPlacedPiece & a_PlacedPiece, const cPiece::cConnector & a_ExistingConnector, const cPiece & a_NewPiece)
{
return ((const cPrefab &)a_NewPiece).GetPieceWeight(a_PlacedPiece, a_ExistingConnector);
}
void cNetherFortGen::PiecePlaced(const cPiece & a_Piece)
{
UNUSED(a_Piece);
}
void cNetherFortGen::Reset(void)
{
// Nothing needed
}

View File

@ -10,77 +10,34 @@
#pragma once #pragma once
#include "ComposableGenerator.h" #include "ComposableGenerator.h"
#include "PieceGenerator.h" #include "PrefabPiecePool.h"
#include "GridStructGen.h"
class cNetherFortGen : class cNetherFortGen :
public cFinishGen, public cGridStructGen
public cPiecePool
{ {
typedef cGridStructGen super;
public: public:
cNetherFortGen(int a_Seed, int a_GridSize, int a_MaxDepth); cNetherFortGen(int a_Seed, int a_GridSize, int a_MaxDepth);
virtual ~cNetherFortGen();
protected: protected:
friend class cNetherFortPerfTest; // fwd: NetherFortGen.cpp friend class cNetherFortPerfTest; // fwd: NetherFortGen.cpp
class cNetherFort; // fwd: NetherFortGen.cpp class cNetherFort; // fwd: NetherFortGen.cpp
typedef std::list<cNetherFort *> cNetherForts;
/** The seed used for generating*/
int m_Seed;
/** The noise used for generating */
cNoise m_Noise;
/** Average spacing between the fortresses*/
int m_GridSize;
/** Maximum depth of the piece-generator tree */ /** Maximum depth of the piece-generator tree */
int m_MaxDepth; int m_MaxDepth;
/** Cache of the most recently used systems. MoveToFront used. */
cNetherForts m_Cache;
/** All the pieces that are allowed for building. /** The pool of pieces to use for generating. Static, so that it's shared by multiple generators. */
This is the list that's used for memory allocation and deallocation for the pieces. */ static cPrefabPiecePool m_PiecePool;
cPieces m_AllPieces;
/** The pieces that are used as starting pieces.
This list is not shared and the pieces need deallocation. */
cPieces m_StartingPieces;
/** The pieces that have an "outer" connector.
The pieces are copies out of m_AllPieces and shouldn't be ever delete-d. */
cPieces m_OuterPieces;
/** The pieces that have an "inner" connector. // cGridStructGen overrides:
The pieces are copies out of m_AllPieces and shouldn't be ever delete-d. */ virtual cStructurePtr CreateStructure(int a_OriginX, int a_OriginZ) override;
cPieces m_InnerPieces;
/** Clears everything from the cache.
Also invalidates the forst returned by GetFortsForChunk(). */
void ClearCache(void);
/** Returns all forts that *may* intersect the given chunk.
The returned forts live within m_Cache.They are valid until the next call
to this function (which may delete some of the pointers). */
void GetFortsForChunk(int a_ChunkX, int a_ChunkZ, cNetherForts & a_Forts);
// cFinishGen overrides:
virtual void GenFinish(cChunkDesc & a_ChunkDesc) override;
// cPiecePool overrides:
virtual cPieces GetPiecesWithConnector(int a_ConnectorType) override;
virtual cPieces GetStartingPieces(void) override;
virtual int GetPieceWeight(const cPlacedPiece & a_PlacedPiece, const cPiece::cConnector & a_ExistingConnector, const cPiece & a_NewPiece) override;
virtual void PiecePlaced(const cPiece & a_Piece) override;
virtual void Reset(void) override;
} ; } ;

View File

@ -20,11 +20,15 @@ class cPrefabPiecePool :
public cPiecePool public cPiecePool
{ {
public: public:
/** Creates an empty instance. Prefabs can be added by calling AddPieceDefs() and AddStartingPieceDefs(). */
cPrefabPiecePool(void);
/** Creates a piece pool with prefabs from the specified definitions. /** Creates a piece pool with prefabs from the specified definitions.
If both a_PieceDefs and a_StartingPieceDefs are given, only the a_StartingPieceDefs are used as starting If both a_PieceDefs and a_StartingPieceDefs are given, only the a_StartingPieceDefs are used as starting
pieces for the pool, and they do not participate in the generation any further. pieces for the pool, and they do not participate in the generation any further.
If only a_PieceDefs is given, any such piece can be chosen as a starting piece, and all the pieces are used If only a_PieceDefs is given, any such piece can be chosen as a starting piece, and all the pieces are used
for generating. */ for generating.
More pieces can be added to the instance afterwards by calling AddPieceDefs() and AddStartingPieceDefs(). */
cPrefabPiecePool( cPrefabPiecePool(
const cPrefab::sDef * a_PieceDefs, size_t a_NumPieceDefs, const cPrefab::sDef * a_PieceDefs, size_t a_NumPieceDefs,
const cPrefab::sDef * a_StartingPieceDefs, size_t a_NumStartingPieceDefs const cPrefab::sDef * a_StartingPieceDefs, size_t a_NumStartingPieceDefs
@ -35,7 +39,7 @@ public:
May be called multiple times with different PieceDefs, will add all such pieces. */ May be called multiple times with different PieceDefs, will add all such pieces. */
void AddPieceDefs(const cPrefab::sDef * a_PieceDefs, size_t a_NumPieceDefs); void AddPieceDefs(const cPrefab::sDef * a_PieceDefs, size_t a_NumPieceDefs);
/** Adds pieces from the specified definitions into m_StartingPieces. Doesn't add to /** Adds pieces from the specified definitions into m_StartingPieces. Doesn't add them to
the m_PiecesByConnector map. the m_PiecesByConnector map.
May be called multiple times with different PieceDefs, will add all such pieces. */ May be called multiple times with different PieceDefs, will add all such pieces. */
void AddStartingPieceDefs(const cPrefab::sDef * a_StartingPieceDefs, size_t a_NumStartingPieceDefs); void AddStartingPieceDefs(const cPrefab::sDef * a_StartingPieceDefs, size_t a_NumStartingPieceDefs);