From 564261cfd9e385dfe6331c0585cae3b46989dd17 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 7 May 2014 22:34:06 +0200 Subject: cNetherFortGen uses cGridStructGen. WIP, this doesn't work properly yet. --- src/Generating/Caves.h | 2 +- src/Generating/GridStructGen.cpp | 12 +-- src/Generating/NetherFortGen.cpp | 223 ++++----------------------------------- src/Generating/NetherFortGen.h | 61 ++--------- src/Generating/PrefabPiecePool.h | 8 +- 5 files changed, 42 insertions(+), 264 deletions(-) (limited to 'src/Generating') diff --git a/src/Generating/Caves.h b/src/Generating/Caves.h index 7c45c056b..2a9fa01b8 100644 --- a/src/Generating/Caves.h +++ b/src/Generating/Caves.h @@ -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. void GetCavesForChunk(int a_ChunkX, int a_ChunkZ, cCaveSystems & a_Caves); - // cStructGen override: + // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; } ; diff --git a/src/Generating/GridStructGen.cpp b/src/Generating/GridStructGen.cpp index 975fd3fdc..2f064d3a0 100644 --- a/src/Generating/GridStructGen.cpp +++ b/src/Generating/GridStructGen.cpp @@ -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 MinGridX = MinBlockX / m_GridSizeX; int MinGridZ = MinBlockZ / m_GridSizeZ; - int MaxGridX = MaxBlockX / m_GridSizeX; - int MaxGridZ = MaxBlockX / m_GridSizeZ; - if (MinGridX < 0) + int MaxGridX = (MaxBlockX + m_GridSizeX - 1) / m_GridSizeX; + int MaxGridZ = (MaxBlockZ + m_GridSizeZ - 1) / m_GridSizeZ; + if (MinBlockX < 0) { --MinGridX; } - if (MinGridZ < 0) + if (MinBlockZ < 0) { --MinGridZ; } - if (MaxGridX < 0) + if (MaxBlockX < 0) { --MaxGridX; } - if (MaxGridZ < 0) + if (MaxBlockZ < 0) { --MaxGridZ; } diff --git a/src/Generating/NetherFortGen.cpp b/src/Generating/NetherFortGen.cpp index d90fdeb0a..ac7fd0b7b 100644 --- a/src/Generating/NetherFortGen.cpp +++ b/src/Generating/NetherFortGen.cpp @@ -20,20 +20,21 @@ static const int NEIGHBORHOOD_SIZE = 3; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cNetherFortGen::cNetherFort: -class cNetherFortGen::cNetherFort +class cNetherFortGen::cNetherFort : + public cGridStructGen::cStructure { + typedef cGridStructGen::cStructure super; + public: cNetherFortGen & m_ParentGen; - int m_BlockX, m_BlockZ; int m_GridSize; int m_Seed; 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_BlockX(a_BlockX), - m_BlockZ(a_BlockZ), m_GridSize(a_GridSize), m_Seed(a_Seed) { @@ -43,8 +44,8 @@ public: // Generate pieces: for (int i = 0; m_Pieces.size() < (size_t)(a_MaxDepth * a_MaxDepth / 8 + a_MaxDepth); i++) { - cBFSPieceGenerator pg(m_ParentGen, a_Seed + i); - pg.PlacePieces(a_BlockX, BlockY, a_BlockZ, a_MaxDepth, m_Pieces); + cBFSPieceGenerator pg(cNetherFortGen::m_PiecePool, a_Seed + i); + pg.PlacePieces(a_OriginX, BlockY, a_OriginZ, a_MaxDepth, m_Pieces); } } @@ -56,7 +57,7 @@ public: /** 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) { @@ -107,214 +108,30 @@ public: /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cNetherFortGen: +cPrefabPiecePool cNetherFortGen::m_PiecePool(g_NetherFortPrefabs, g_NetherFortPrefabsCount, g_NetherFortStartingPrefabs, g_NetherFortStartingPrefabsCount); + + + + + cNetherFortGen::cNetherFortGen(int a_Seed, int a_GridSize, int a_MaxDepth) : - m_Seed(a_Seed), - m_Noise(a_Seed), - m_GridSize(a_GridSize), + super(a_Seed, a_GridSize, a_GridSize, a_MaxDepth * 10, a_MaxDepth * 10, 200), 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: cPlacedPieces Pieces; - cBFSPieceGenerator pg(*this, a_Seed); + cBFSPieceGenerator pg(m_PiecePool, a_Seed); pg.PlacePieces(0, 64, 0, a_MaxDepth, Pieces); - */ -} - - - - - -cNetherFortGen::~cNetherFortGen() -{ - ClearCache(); - 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) +cGridStructGen::cStructurePtr cNetherFortGen::CreateStructure(int a_OriginX, int a_OriginZ) { - // TODO + return cStructurePtr(new cNetherFort(*this, a_OriginX, a_OriginZ, m_GridSizeX, m_MaxDepth, m_Seed)); } - - - - -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 -} - - - - diff --git a/src/Generating/NetherFortGen.h b/src/Generating/NetherFortGen.h index d51596b9e..f35801a3c 100644 --- a/src/Generating/NetherFortGen.h +++ b/src/Generating/NetherFortGen.h @@ -10,77 +10,34 @@ #pragma once #include "ComposableGenerator.h" -#include "PieceGenerator.h" +#include "PrefabPiecePool.h" +#include "GridStructGen.h" class cNetherFortGen : - public cFinishGen, - public cPiecePool + public cGridStructGen { + typedef cGridStructGen super; + public: cNetherFortGen(int a_Seed, int a_GridSize, int a_MaxDepth); - virtual ~cNetherFortGen(); - protected: friend class cNetherFortPerfTest; // fwd: NetherFortGen.cpp class cNetherFort; // fwd: NetherFortGen.cpp - typedef std::list 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 */ int m_MaxDepth; - - /** Cache of the most recently used systems. MoveToFront used. */ - cNetherForts m_Cache; - /** All the pieces that are allowed for building. - This is the list that's used for memory allocation and deallocation for the pieces. */ - cPieces m_AllPieces; + /** The pool of pieces to use for generating. Static, so that it's shared by multiple generators. */ + static cPrefabPiecePool m_PiecePool; - /** 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. - The pieces are copies out of m_AllPieces and shouldn't be ever delete-d. */ - 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; + // cGridStructGen overrides: + virtual cStructurePtr CreateStructure(int a_OriginX, int a_OriginZ) override; } ; diff --git a/src/Generating/PrefabPiecePool.h b/src/Generating/PrefabPiecePool.h index 2a7993063..c6a5ad360 100644 --- a/src/Generating/PrefabPiecePool.h +++ b/src/Generating/PrefabPiecePool.h @@ -20,11 +20,15 @@ class cPrefabPiecePool : public cPiecePool { 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. 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. 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( const cPrefab::sDef * a_PieceDefs, size_t a_NumPieceDefs, 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. */ 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. May be called multiple times with different PieceDefs, will add all such pieces. */ void AddStartingPieceDefs(const cPrefab::sDef * a_StartingPieceDefs, size_t a_NumStartingPieceDefs); -- cgit v1.2.3