2014-05-11 16:35:41 -04:00
// VillageGen.cpp
// Implements the cVillageGen class representing the village generator
# include "Globals.h"
# include "VillageGen.h"
2014-05-14 18:14:06 -04:00
# include "PieceGenerator.h"
2014-05-11 16:35:41 -04:00
2014-05-12 16:43:59 -04:00
/*
How village generating works :
2014-11-12 15:24:26 -05:00
By descending from a cGridStructGen , a semi - random ( jitter ) grid is generated . A village may be generated for each
2015-11-11 04:32:42 -05:00
of the grid ' s cells . Each cell checks the biomes in an entire chunk around its center , only generating a village if
all biomes are village - friendly . If yes , the entire village structure is built for that cell . If not , the cell
2014-05-12 16:43:59 -04:00
is left village - less .
2014-05-14 18:14:06 -04:00
A village is generated using the regular BFS piece generator . The well piece is used as the starting piece ,
the roads and houses are then used as the following pieces . Only the houses are read from the prefabs ,
though , the roads are generated by code and their content is ignored . A special subclass of the cPiecePool
class is used , so that the roads connect to each other and to the well only in predefined manners .
2014-05-12 16:43:59 -04:00
2014-05-21 17:16:43 -04:00
The well has connectors of type " 2 " . The houses have connectors of type " -1 " . The roads have connectors of
2014-05-22 15:47:56 -04:00
both types ' opposites , type " -2 " at the far ends and type " 1 " on the long edges . Additionally , there are
type " 2 " connectors along the long edges of the roads as well , so that the roads create T junctions .
2014-05-14 18:14:06 -04:00
When the village is about to be drawn into a chunk , it queries the heights for each piece intersecting the
2015-11-11 04:32:42 -05:00
chunk . The pieces are shifted so that their first connector lies on the surface , and the roads are drawn
2014-05-12 16:43:59 -04:00
directly by turning the surface blocks into gravel / sandstone .
2014-05-22 15:47:56 -04:00
The village prefabs are stored in global piecepools ( one pool per village type ) . In order to support
per - village density setting , the cVillage class itself implements the cPiecePool interface , relaying the
calls to the underlying cVillagePiecePool , after processing the density check .
2014-05-12 16:43:59 -04:00
*/
2014-05-14 18:14:06 -04:00
class cVillagePiecePool :
public cPrefabPiecePool
{
typedef cPrefabPiecePool super ;
public :
cVillagePiecePool (
const cPrefab : : sDef * a_PieceDefs , size_t a_NumPieceDefs ,
const cPrefab : : sDef * a_StartingPieceDefs , size_t a_NumStartingPieceDefs
) :
super ( a_PieceDefs , a_NumPieceDefs , a_StartingPieceDefs , a_NumStartingPieceDefs )
2015-06-20 09:37:41 -04:00
{
AddRoadPieces ( ) ;
}
cVillagePiecePool ( void )
{
AddRoadPieces ( ) ;
}
void AddRoadPieces ( void )
2014-05-14 18:14:06 -04:00
{
2014-05-15 04:43:54 -04:00
// Add the road pieces:
2014-05-22 15:47:56 -04:00
for ( int len = 27 ; len < 60 ; len + = 12 )
2014-05-15 04:43:54 -04:00
{
cBlockArea BA ;
BA . Create ( len , 1 , 3 , cBlockArea : : baTypes | cBlockArea : : baMetas ) ;
BA . Fill ( cBlockArea : : baTypes | cBlockArea : : baMetas , E_BLOCK_GRAVEL , 0 ) ;
cPrefab * RoadPiece = new cPrefab ( BA , 1 ) ;
RoadPiece - > AddConnector ( 0 , 0 , 1 , BLOCK_FACE_XM , - 2 ) ;
RoadPiece - > AddConnector ( len - 1 , 0 , 1 , BLOCK_FACE_XP , - 2 ) ;
2014-05-24 09:03:39 -04:00
RoadPiece - > SetDefaultWeight ( 100 ) ;
2016-02-05 16:45:45 -05:00
2014-05-15 04:43:54 -04:00
// Add the road connectors:
2014-05-22 15:47:56 -04:00
for ( int x = 1 ; x < len ; x + = 12 )
2014-05-15 04:43:54 -04:00
{
RoadPiece - > AddConnector ( x , 0 , 0 , BLOCK_FACE_ZM , 2 ) ;
RoadPiece - > AddConnector ( x , 0 , 2 , BLOCK_FACE_ZP , 2 ) ;
}
2016-02-05 16:45:45 -05:00
2014-05-15 04:43:54 -04:00
// Add the buildings connectors:
2014-05-22 15:47:56 -04:00
for ( int x = 7 ; x < len ; x + = 12 )
2014-05-15 04:43:54 -04:00
{
RoadPiece - > AddConnector ( x , 0 , 0 , BLOCK_FACE_ZM , 1 ) ;
RoadPiece - > AddConnector ( x , 0 , 2 , BLOCK_FACE_ZP , 1 ) ;
}
m_AllPieces . push_back ( RoadPiece ) ;
m_PiecesByConnector [ - 2 ] . push_back ( RoadPiece ) ;
m_PiecesByConnector [ 1 ] . push_back ( RoadPiece ) ;
m_PiecesByConnector [ 2 ] . push_back ( RoadPiece ) ;
} // for len - roads of varying length
2014-05-14 18:14:06 -04:00
}
2016-02-05 16:45:45 -05:00
2014-05-14 18:14:06 -04:00
// cPrefabPiecePool overrides:
virtual int GetPieceWeight ( const cPlacedPiece & a_PlacedPiece , const cPiece : : cConnector & a_ExistingConnector , const cPiece & a_NewPiece ) override
{
2014-05-24 09:03:39 -04:00
// Roads cannot branch T-wise (appending -2 connector to a +2 connector on a 1-high piece):
if ( ( a_ExistingConnector . m_Type = = 2 ) & & ( a_PlacedPiece . GetDepth ( ) > 0 ) & & ( a_PlacedPiece . GetPiece ( ) . GetSize ( ) . y = = 1 ) )
2014-05-14 18:14:06 -04:00
{
return 0 ;
}
2016-02-05 16:45:45 -05:00
2015-05-24 07:56:56 -04:00
return static_cast < const cPrefab & > ( a_NewPiece ) . GetPieceWeight ( a_PlacedPiece , a_ExistingConnector ) ;
2014-05-14 18:14:06 -04:00
}
2014-07-17 17:15:53 -04:00
} ;
2014-05-14 18:14:06 -04:00
2014-05-11 16:35:41 -04:00
class cVillageGen : : cVillage :
2014-05-22 15:47:56 -04:00
public cGridStructGen : : cStructure ,
protected cPiecePool
2014-05-11 16:35:41 -04:00
{
typedef cGridStructGen : : cStructure super ;
2016-02-05 16:45:45 -05:00
2014-05-11 16:35:41 -04:00
public :
2014-05-12 16:43:59 -04:00
cVillage (
int a_Seed ,
2014-06-16 10:12:50 -04:00
int a_GridX , int a_GridZ ,
2014-05-12 16:43:59 -04:00
int a_OriginX , int a_OriginZ ,
int a_MaxRoadDepth ,
int a_MaxSize ,
2014-05-22 15:47:56 -04:00
int a_Density ,
2015-06-20 09:37:41 -04:00
cVillagePiecePool & a_Prefabs ,
cTerrainHeightGenPtr a_HeightGen
2014-05-12 16:43:59 -04:00
) :
2014-06-16 10:12:50 -04:00
super ( a_GridX , a_GridZ , a_OriginX , a_OriginZ ) ,
2014-05-11 16:35:41 -04:00
m_Seed ( a_Seed ) ,
2014-05-12 16:43:59 -04:00
m_Noise ( a_Seed ) ,
m_MaxSize ( a_MaxSize ) ,
2014-05-22 15:47:56 -04:00
m_Density ( a_Density ) ,
2014-11-12 15:24:26 -05:00
m_Borders ( a_OriginX - a_MaxSize , 0 , a_OriginZ - a_MaxSize , a_OriginX + a_MaxSize , cChunkDef : : Height - 1 , a_OriginZ + a_MaxSize ) ,
2014-05-12 16:43:59 -04:00
m_Prefabs ( a_Prefabs ) ,
2015-06-20 09:37:41 -04:00
m_HeightGen ( a_HeightGen )
2014-05-11 16:35:41 -04:00
{
2014-05-25 17:50:16 -04:00
// Generate the pieces for this village; don't care about the Y coord:
2014-05-22 15:47:56 -04:00
cBFSPieceGenerator pg ( * this , a_Seed ) ;
2015-11-11 04:32:42 -05:00
pg . PlacePieces ( a_OriginX , a_OriginZ , a_MaxRoadDepth + 1 , m_Pieces ) ;
2014-05-25 17:50:16 -04:00
if ( m_Pieces . empty ( ) )
{
return ;
}
2014-05-11 16:35:41 -04:00
}
2016-02-05 16:45:45 -05:00
2014-05-31 04:33:12 -04:00
~ cVillage ( )
{
cPieceGenerator : : FreePieces ( m_Pieces ) ;
}
2016-02-05 16:45:45 -05:00
2014-05-11 16:35:41 -04:00
protected :
/** Seed for the random functions */
int m_Seed ;
2016-02-05 16:45:45 -05:00
2014-05-12 16:43:59 -04:00
/** The noise used as a pseudo-random generator */
cNoise m_Noise ;
2016-02-05 16:45:45 -05:00
2015-05-09 03:25:09 -04:00
/** Maximum size, in X / Z blocks, of the village (radius from the origin) */
2014-05-12 16:43:59 -04:00
int m_MaxSize ;
2016-02-05 16:45:45 -05:00
2014-05-22 15:47:56 -04:00
/** The density for this village. Used to refrain from populating all house connectors. Range [0, 100] */
int m_Density ;
2016-02-05 16:45:45 -05:00
2014-08-03 09:31:59 -04:00
/** Borders of the village - no item may reach out of this cuboid. */
2014-05-12 16:43:59 -04:00
cCuboid m_Borders ;
2016-02-05 16:45:45 -05:00
2014-05-11 16:35:41 -04:00
/** Prefabs to use for buildings */
2015-06-20 09:37:41 -04:00
cVillagePiecePool & m_Prefabs ;
2016-02-05 16:45:45 -05:00
2014-05-12 16:43:59 -04:00
/** The underlying height generator, used for placing the structures on top of the terrain. */
2014-10-19 08:01:59 -04:00
cTerrainHeightGenPtr m_HeightGen ;
2016-02-05 16:45:45 -05:00
2014-05-14 18:14:06 -04:00
/** The village pieces, placed by the generator. */
cPlacedPieces m_Pieces ;
2016-02-05 16:45:45 -05:00
2014-05-22 15:47:56 -04:00
// cGridStructGen::cStructure overrides:
2014-05-11 16:35:41 -04:00
virtual void DrawIntoChunk ( cChunkDesc & a_Chunk ) override
{
2014-05-12 16:43:59 -04:00
// Iterate over all items
2014-05-17 15:54:04 -04:00
// Each intersecting prefab is placed on ground, then drawn
2014-05-12 16:43:59 -04:00
// Each intersecting road is drawn by replacing top soil blocks with gravel / sandstone blocks
2014-05-17 15:54:04 -04:00
cChunkDef : : HeightMap HeightMap ; // Heightmap for this chunk, used by roads
2014-10-19 08:01:59 -04:00
m_HeightGen - > GenHeightMap ( a_Chunk . GetChunkX ( ) , a_Chunk . GetChunkZ ( ) , HeightMap ) ;
2014-05-17 15:54:04 -04:00
for ( cPlacedPieces : : iterator itr = m_Pieces . begin ( ) , end = m_Pieces . end ( ) ; itr ! = end ; + + itr )
2014-05-14 18:14:06 -04:00
{
2015-05-24 07:56:56 -04:00
const cPrefab & Prefab = static_cast < const cPrefab & > ( ( * itr ) - > GetPiece ( ) ) ;
2014-05-17 15:54:04 -04:00
if ( ( * itr ) - > GetPiece ( ) . GetSize ( ) . y = = 1 )
{
2014-05-17 16:26:09 -04:00
// It's a road, special handling (change top terrain blocks to m_RoadBlock)
DrawRoad ( a_Chunk , * * itr , HeightMap ) ;
2014-05-17 15:54:04 -04:00
continue ;
}
2014-05-25 17:50:16 -04:00
if ( Prefab . ShouldMoveToGround ( ) & & ! ( * itr ) - > HasBeenMovedToGround ( ) )
2014-05-17 15:54:04 -04:00
{
PlacePieceOnGround ( * * itr ) ;
}
2014-05-14 18:14:06 -04:00
Prefab . Draw ( a_Chunk , * itr ) ;
} // for itr - m_PlacedPieces[]
2014-05-11 16:35:41 -04:00
}
2015-11-11 04:32:42 -05:00
2014-05-17 15:54:04 -04:00
/** Adjusts the Y coord of the given piece so that the piece is on the ground.
Ground level is assumed to be represented by the first connector in the piece . */
void PlacePieceOnGround ( cPlacedPiece & a_Piece )
{
cPiece : : cConnector FirstConnector = a_Piece . GetRotatedConnector ( 0 ) ;
int ChunkX , ChunkZ ;
int BlockX = FirstConnector . m_Pos . x ;
int BlockZ = FirstConnector . m_Pos . z ;
int BlockY ;
cChunkDef : : AbsoluteToRelative ( BlockX , BlockY , BlockZ , ChunkX , ChunkZ ) ;
cChunkDef : : HeightMap HeightMap ;
2014-10-19 08:01:59 -04:00
m_HeightGen - > GenHeightMap ( ChunkX , ChunkZ , HeightMap ) ;
2014-05-17 15:54:04 -04:00
int TerrainHeight = cChunkDef : : GetHeight ( HeightMap , BlockX , BlockZ ) ;
2014-05-25 17:50:16 -04:00
a_Piece . MoveToGroundBy ( TerrainHeight - FirstConnector . m_Pos . y + 1 ) ;
2014-05-17 15:54:04 -04:00
}
2016-02-05 16:45:45 -05:00
2014-05-17 16:26:09 -04:00
/** Draws the road into the chunk.
The heightmap is not queried from the heightgen , but is given via parameter , so that it may be queried just
once for all roads in a chunk . */
void DrawRoad ( cChunkDesc & a_Chunk , cPlacedPiece & a_Road , cChunkDef : : HeightMap & a_HeightMap )
{
cCuboid RoadCoords = a_Road . GetHitBox ( ) ;
RoadCoords . Sort ( ) ;
int MinX = std : : max ( RoadCoords . p1 . x - a_Chunk . GetChunkX ( ) * cChunkDef : : Width , 0 ) ;
int MaxX = std : : min ( RoadCoords . p2 . x - a_Chunk . GetChunkX ( ) * cChunkDef : : Width , cChunkDef : : Width - 1 ) ;
int MinZ = std : : max ( RoadCoords . p1 . z - a_Chunk . GetChunkZ ( ) * cChunkDef : : Width , 0 ) ;
int MaxZ = std : : min ( RoadCoords . p2 . z - a_Chunk . GetChunkZ ( ) * cChunkDef : : Width , cChunkDef : : Width - 1 ) ;
2015-06-20 09:37:41 -04:00
auto WaterRoadBlockType = m_Prefabs . GetVillageWaterRoadBlockType ( ) ;
auto WaterRoadBlockMeta = m_Prefabs . GetVillageWaterRoadBlockMeta ( ) ;
auto RoadBlockType = m_Prefabs . GetVillageRoadBlockType ( ) ;
auto RoadBlockMeta = m_Prefabs . GetVillageRoadBlockMeta ( ) ;
2014-05-17 16:26:09 -04:00
for ( int z = MinZ ; z < = MaxZ ; z + + )
{
for ( int x = MinX ; x < = MaxX ; x + + )
{
2014-06-11 13:12:29 -04:00
if ( IsBlockWater ( a_Chunk . GetBlockType ( x , cChunkDef : : GetHeight ( a_HeightMap , x , z ) , z ) ) )
{
2015-06-20 09:37:41 -04:00
a_Chunk . SetBlockTypeMeta ( x , cChunkDef : : GetHeight ( a_HeightMap , x , z ) , z , WaterRoadBlockType , WaterRoadBlockMeta ) ;
2014-06-11 13:12:29 -04:00
}
else
{
2015-06-20 09:37:41 -04:00
a_Chunk . SetBlockTypeMeta ( x , cChunkDef : : GetHeight ( a_HeightMap , x , z ) , z , RoadBlockType , RoadBlockMeta ) ;
2014-06-11 13:12:29 -04:00
}
2014-05-17 16:26:09 -04:00
}
}
}
2016-02-05 16:45:45 -05:00
2014-05-22 15:47:56 -04:00
// cPiecePool overrides:
2015-05-23 07:56:08 -04:00
virtual cPieces GetPiecesWithConnector ( int a_ConnectorType ) override
2014-05-22 15:47:56 -04:00
{
return m_Prefabs . GetPiecesWithConnector ( a_ConnectorType ) ;
}
2016-02-05 16:45:45 -05:00
2015-05-23 07:56:08 -04:00
virtual cPieces GetStartingPieces ( void ) override
2014-05-22 15:47:56 -04:00
{
return m_Prefabs . GetStartingPieces ( ) ;
}
2016-02-05 16:45:45 -05:00
2014-05-22 15:47:56 -04:00
virtual int GetPieceWeight (
const cPlacedPiece & a_PlacedPiece ,
const cPiece : : cConnector & a_ExistingConnector ,
const cPiece & a_NewPiece
) override
{
// Check against the density:
if ( a_ExistingConnector . m_Type = = 1 )
{
const Vector3i & Coords = a_PlacedPiece . GetRotatedConnector ( a_ExistingConnector ) . m_Pos ;
int rnd = ( m_Noise . IntNoise3DInt ( Coords . x , Coords . y , Coords . z ) / 7 ) % 100 ;
if ( rnd > m_Density )
{
return 0 ;
}
}
2016-02-05 16:45:45 -05:00
2014-05-22 15:47:56 -04:00
// Density check passed, relay to m_Prefabs:
return m_Prefabs . GetPieceWeight ( a_PlacedPiece , a_ExistingConnector , a_NewPiece ) ;
}
2016-02-05 16:45:45 -05:00
2014-05-27 16:08:20 -04:00
virtual int GetStartingPieceWeight ( const cPiece & a_NewPiece ) override
{
return m_Prefabs . GetStartingPieceWeight ( a_NewPiece ) ;
}
2016-02-05 16:45:45 -05:00
2014-05-22 15:47:56 -04:00
virtual void PiecePlaced ( const cPiece & a_Piece ) override
{
m_Prefabs . PiecePlaced ( a_Piece ) ;
}
2016-02-05 16:45:45 -05:00
2014-05-22 15:47:56 -04:00
virtual void Reset ( void ) override
{
m_Prefabs . Reset ( ) ;
}
2016-02-05 16:45:45 -05:00
2014-05-25 17:50:16 -04:00
void MoveAllDescendants ( cPlacedPieces & a_PlacedPieces , size_t a_Pivot , int a_HeightDifference )
{
size_t num = a_PlacedPieces . size ( ) ;
cPlacedPiece * Pivot = a_PlacedPieces [ a_Pivot ] ;
for ( size_t i = a_Pivot + 1 ; i < num ; i + + )
{
if (
( a_PlacedPieces [ i ] - > GetParent ( ) = = Pivot ) & & // It is a direct dependant of the pivot
2015-05-24 07:56:56 -04:00
! ( static_cast < const cPrefab & > ( a_PlacedPieces [ i ] - > GetPiece ( ) ) ) . ShouldMoveToGround ( ) // It attaches strictly by connectors
2014-05-25 17:50:16 -04:00
)
{
a_PlacedPieces [ i ] - > MoveToGroundBy ( a_HeightDifference ) ;
MoveAllDescendants ( a_PlacedPieces , i , a_HeightDifference ) ;
}
} // for i - a_PlacedPieces[]
}
2014-05-11 16:35:41 -04:00
} ;
2014-07-17 16:15:34 -04:00
////////////////////////////////////////////////////////////////////////////////
2014-05-11 16:35:41 -04:00
// cVillageGen:
2015-06-20 09:37:41 -04:00
cVillageGen : : cVillageGen (
int a_Seed ,
int a_GridSize ,
int a_MaxOffset ,
int a_MaxDepth ,
int a_MaxSize ,
int a_MinDensity ,
int a_MaxDensity ,
cBiomeGenPtr a_BiomeGen ,
cTerrainHeightGenPtr a_HeightGen ,
2015-11-11 04:32:42 -05:00
int a_SeaLevel ,
2015-06-20 09:37:41 -04:00
const AStringVector & a_PrefabsToLoad
) :
2014-06-16 10:12:50 -04:00
super ( a_Seed , a_GridSize , a_GridSize , a_MaxOffset , a_MaxOffset , a_MaxSize , a_MaxSize , 100 ) ,
2014-05-22 15:47:56 -04:00
m_Noise ( a_Seed + 1000 ) ,
2014-05-14 18:14:06 -04:00
m_MaxDepth ( a_MaxDepth ) ,
m_MaxSize ( a_MaxSize ) ,
2014-05-22 15:47:56 -04:00
m_MinDensity ( a_MinDensity ) ,
m_MaxDensity ( a_MaxDensity ) ,
2014-05-11 16:35:41 -04:00
m_BiomeGen ( a_BiomeGen ) ,
m_HeightGen ( a_HeightGen )
{
2015-06-20 09:37:41 -04:00
for ( const auto & toLoad : a_PrefabsToLoad )
{
auto prefabs = std : : make_shared < cVillagePiecePool > ( ) ;
auto fileName = Printf ( " Prefabs%sVillages%s%s.cubeset " , cFile : : GetPathSeparator ( ) . c_str ( ) , cFile : : GetPathSeparator ( ) . c_str ( ) , toLoad . c_str ( ) ) ;
if ( prefabs - > LoadFromFile ( fileName , true ) )
{
if ( NoCaseCompare ( prefabs - > GetIntendedUse ( ) , " village " ) ! = 0 )
{
LOGWARNING ( " Village generator: File %s is intended for use in \" %s \" , rather than villages. Loading the file, but the generator may behave unexpectedly. " ,
fileName . c_str ( ) , prefabs - > GetIntendedUse ( ) . c_str ( )
) ;
}
2015-11-11 04:32:42 -05:00
prefabs - > AssignGens ( a_Seed , m_BiomeGen , m_HeightGen , a_SeaLevel ) ;
2015-06-20 09:37:41 -04:00
m_Pools . push_back ( std : : move ( prefabs ) ) ;
}
}
2014-05-11 16:35:41 -04:00
}
2014-06-16 10:12:50 -04:00
cGridStructGen : : cStructurePtr cVillageGen : : CreateStructure ( int a_GridX , int a_GridZ , int a_OriginX , int a_OriginZ )
2014-05-11 16:35:41 -04:00
{
// Generate the biomes for the chunk surrounding the origin:
int ChunkX , ChunkZ ;
cChunkDef : : BlockToChunk ( a_OriginX , a_OriginZ , ChunkX , ChunkZ ) ;
cChunkDef : : BiomeMap Biomes ;
2014-10-19 08:01:59 -04:00
m_BiomeGen - > GenBiomes ( ChunkX , ChunkZ , Biomes ) ;
2014-05-11 16:35:41 -04:00
2015-06-20 09:37:41 -04:00
// Get a list of pools that support each biome within the chunk:
// If just one column's biome is not allowed, the pool is not used because it's likely that an unfriendly biome is too close
auto availablePools = m_Pools ;
2014-05-11 16:35:41 -04:00
for ( size_t i = 0 ; i < ARRAYCOUNT ( Biomes ) ; i + + )
{
2015-06-20 09:37:41 -04:00
auto biome = Biomes [ i ] ;
availablePools . erase ( std : : remove_if ( availablePools . begin ( ) , availablePools . end ( ) ,
[ biome ] ( SharedPtr < cPrefabPiecePool > a_Pool )
2014-05-11 16:35:41 -04:00
{
2015-06-20 09:37:41 -04:00
return ! a_Pool - > IsBiomeAllowed ( biome ) ;
} ) ,
availablePools . end ( )
) ;
// Bail out if no compatible pools left:
if ( availablePools . empty ( ) )
{
return cStructurePtr ( ) ;
}
}
// Pick one pool from the available pools:
if ( availablePools . empty ( ) )
{
return cStructurePtr ( ) ;
}
auto rnd = m_Noise . IntNoise2DInt ( a_OriginX , a_OriginZ ) / 11 ;
auto pool = availablePools [ static_cast < size_t > ( rnd ) % availablePools . size ( ) ] ;
rnd / = 137 ;
2014-05-11 16:35:41 -04:00
2014-05-22 15:47:56 -04:00
// Choose density for the village, random between m_MinDensity and m_MaxDensity:
int Density ;
2015-06-20 09:37:41 -04:00
if ( pool - > GetMaxDensity ( ) > pool - > GetMinDensity ( ) )
2014-05-22 15:47:56 -04:00
{
2015-06-20 09:37:41 -04:00
Density = pool - > GetMinDensity ( ) + rnd % ( pool - > GetMaxDensity ( ) - pool - > GetMinDensity ( ) ) ;
2014-05-22 15:47:56 -04:00
}
else
{
2015-06-20 09:37:41 -04:00
Density = pool - > GetMinDensity ( ) ;
2014-05-22 15:47:56 -04:00
}
2016-02-05 16:45:45 -05:00
2014-05-11 16:35:41 -04:00
// Create a village based on the chosen prefabs:
2015-06-20 09:37:41 -04:00
return cStructurePtr ( new cVillage ( m_Seed , a_GridX , a_GridZ , a_OriginX , a_OriginZ , m_MaxDepth , m_MaxSize , Density , * pool . get ( ) , m_HeightGen ) ) ;
2014-05-11 16:35:41 -04:00
}