2012-06-14 09:06:06 -04:00
// BioGen.cpp
// Implements the various biome generators
# include "Globals.h"
# include "BioGen.h"
2014-11-03 04:36:12 -05:00
# include <iostream>
2014-10-26 14:58:16 -04:00
# include "IntGen.h"
2014-10-30 11:24:35 -04:00
# include "ProtIntGen.h"
2014-10-23 09:15:10 -04:00
# include "../IniFile.h"
2013-05-12 13:55:49 -04:00
# include "../LinearUpscale.h"
2012-06-14 09:06:06 -04:00
2014-07-17 16:15:34 -04:00
////////////////////////////////////////////////////////////////////////////////
2012-06-14 09:06:06 -04:00
// cBioGenConstant:
2019-09-07 17:02:05 -04:00
void cBioGenConstant : : GenBiomes ( cChunkCoords a_ChunkCoords , cChunkDef : : BiomeMap & a_BiomeMap )
2012-06-14 09:06:06 -04:00
{
2019-09-07 17:02:05 -04:00
UNUSED ( a_ChunkCoords ) ;
2013-12-20 10:01:34 -05:00
for ( size_t i = 0 ; i < ARRAYCOUNT ( a_BiomeMap ) ; i + + )
2012-06-14 09:06:06 -04:00
{
a_BiomeMap [ i ] = m_Biome ;
}
}
2013-10-10 09:49:24 -04:00
void cBioGenConstant : : InitializeBiomeGen ( cIniFile & a_IniFile )
2013-02-02 13:17:46 -05:00
{
2019-09-01 15:47:03 -04:00
AString defaultBiome ;
switch ( StringToDimension ( a_IniFile . GetValue ( " General " , " Dimension " , " Overworld " ) ) )
{
case dimOverworld : defaultBiome = " Plains " ; break ;
case dimNether : defaultBiome = " Nether " ; break ;
case dimEnd : defaultBiome = " End " ; break ;
case dimNotSet : defaultBiome = " Swampland " ; break ;
}
AString Biome = a_IniFile . GetValueSet ( " Generator " , " ConstantBiome " , defaultBiome ) ;
2013-02-02 13:17:46 -05:00
m_Biome = StringToBiome ( Biome ) ;
2014-02-03 16:01:12 -05:00
if ( m_Biome = = biInvalidBiome )
2013-02-02 13:17:46 -05:00
{
LOGWARN ( " [Generator]::ConstantBiome value \" %s \" not recognized, using \" Plains \" . " , Biome . c_str ( ) ) ;
m_Biome = biPlains ;
}
}
2014-07-17 16:15:34 -04:00
////////////////////////////////////////////////////////////////////////////////
2012-06-14 09:06:06 -04:00
// cBioGenCache:
2015-05-19 06:50:59 -04:00
cBioGenCache : : cBioGenCache ( cBiomeGenPtr a_BioGenToCache , size_t a_CacheSize ) :
2012-06-14 09:06:06 -04:00
m_BioGenToCache ( a_BioGenToCache ) ,
m_CacheSize ( a_CacheSize ) ,
m_NumHits ( 0 ) ,
m_NumMisses ( 0 ) ,
m_TotalChain ( 0 )
{
2019-09-07 17:02:05 -04:00
m_CacheData . resize ( m_CacheSize ) ;
m_CacheOrder . resize ( m_CacheSize ) ;
2015-05-19 06:50:59 -04:00
for ( size_t i = 0 ; i < m_CacheSize ; i + + )
2012-06-14 09:06:06 -04:00
{
2015-05-24 09:58:24 -04:00
m_CacheOrder [ i ] = i ;
2012-06-14 09:06:06 -04:00
}
}
2019-09-07 17:02:05 -04:00
void cBioGenCache : : GenBiomes ( cChunkCoords a_ChunkCoords , cChunkDef : : BiomeMap & a_BiomeMap )
2012-06-14 09:06:06 -04:00
{
if ( ( ( m_NumHits + m_NumMisses ) % 1024 ) = = 10 )
{
2016-04-18 06:30:23 -04:00
// LOGD("BioGenCache: %u hits, %u misses, saved %.2f %%", static_cast<unsigned>(m_NumHits), static_cast<unsigned>(m_NumMisses), 100.0 * m_NumHits / (m_NumHits + m_NumMisses));
// LOGD("BioGenCache: Avg cache chain length: %.2f", static_cast<double>(m_TotalChain) / m_NumHits);
2012-06-14 09:06:06 -04:00
}
2014-09-03 12:48:47 -04:00
2015-05-19 06:50:59 -04:00
for ( size_t i = 0 ; i < m_CacheSize ; i + + )
2012-06-14 09:06:06 -04:00
{
2019-09-07 17:02:05 -04:00
if ( m_CacheData [ m_CacheOrder [ i ] ] . m_Coords ! = a_ChunkCoords )
2012-06-14 09:06:06 -04:00
{
continue ;
}
// Found it in the cache
2015-05-19 06:50:59 -04:00
size_t Idx = m_CacheOrder [ i ] ;
2016-02-05 16:45:45 -05:00
2012-06-14 09:06:06 -04:00
// Move to front:
2015-05-19 06:50:59 -04:00
for ( size_t j = i ; j > 0 ; j - - )
2012-06-14 09:06:06 -04:00
{
m_CacheOrder [ j ] = m_CacheOrder [ j - 1 ] ;
}
m_CacheOrder [ 0 ] = Idx ;
2016-02-05 16:45:45 -05:00
2012-06-14 09:06:06 -04:00
// Use the cached data:
memcpy ( a_BiomeMap , m_CacheData [ Idx ] . m_BiomeMap , sizeof ( a_BiomeMap ) ) ;
2016-02-05 16:45:45 -05:00
2012-06-14 09:06:06 -04:00
m_NumHits + + ;
m_TotalChain + = i ;
return ;
} // for i - cache
2016-02-05 16:45:45 -05:00
2012-06-14 09:06:06 -04:00
// Not in the cache:
m_NumMisses + + ;
2019-09-07 17:02:05 -04:00
m_BioGenToCache - > GenBiomes ( a_ChunkCoords , a_BiomeMap ) ;
2016-02-05 16:45:45 -05:00
2012-06-14 09:06:06 -04:00
// Insert it as the first item in the MRU order:
2015-05-19 06:50:59 -04:00
size_t Idx = m_CacheOrder [ m_CacheSize - 1 ] ;
for ( size_t i = m_CacheSize - 1 ; i > 0 ; i - - )
2012-06-14 09:06:06 -04:00
{
m_CacheOrder [ i ] = m_CacheOrder [ i - 1 ] ;
} // for i - m_CacheOrder[]
m_CacheOrder [ 0 ] = Idx ;
memcpy ( m_CacheData [ Idx ] . m_BiomeMap , a_BiomeMap , sizeof ( a_BiomeMap ) ) ;
2019-09-07 17:02:05 -04:00
m_CacheData [ Idx ] . m_Coords = a_ChunkCoords ;
2012-06-14 09:06:06 -04:00
}
2013-10-10 09:49:24 -04:00
void cBioGenCache : : InitializeBiomeGen ( cIniFile & a_IniFile )
2013-02-02 13:17:46 -05:00
{
2013-10-10 09:49:24 -04:00
super : : InitializeBiomeGen ( a_IniFile ) ;
m_BioGenToCache - > InitializeBiomeGen ( a_IniFile ) ;
2013-02-02 13:17:46 -05:00
}
2014-09-01 16:33:58 -04:00
////////////////////////////////////////////////////////////////////////////////
// cBioGenMulticache:
2014-10-19 08:01:59 -04:00
cBioGenMulticache : : cBioGenMulticache ( cBiomeGenPtr a_BioGenToCache , size_t a_SubCacheSize , size_t a_NumSubCaches ) :
m_NumSubCaches ( a_NumSubCaches )
2014-09-01 16:33:58 -04:00
{
2014-10-19 08:01:59 -04:00
m_Caches . reserve ( a_NumSubCaches ) ;
for ( size_t i = 0 ; i < a_NumSubCaches ; i + + )
2014-09-02 20:53:21 -04:00
{
2014-10-19 08:01:59 -04:00
m_Caches . push_back ( cBiomeGenPtr ( new cBioGenCache ( a_BioGenToCache , a_SubCacheSize ) ) ) ;
2014-09-02 12:05:53 -04:00
}
2014-09-01 16:33:58 -04:00
}
2019-09-07 17:02:05 -04:00
void cBioGenMulticache : : GenBiomes ( cChunkCoords a_ChunkCoords , cChunkDef : : BiomeMap & a_BiomeMap )
2014-09-01 16:33:58 -04:00
{
2014-09-03 12:48:47 -04:00
const size_t coefficient = 3 ;
2019-09-07 17:02:05 -04:00
const size_t cacheIdx = ( static_cast < size_t > ( a_ChunkCoords . m_ChunkX ) + coefficient * static_cast < size_t > ( a_ChunkCoords . m_ChunkZ ) ) % m_NumSubCaches ;
2014-09-01 16:33:58 -04:00
2019-09-07 17:02:05 -04:00
m_Caches [ cacheIdx ] - > GenBiomes ( a_ChunkCoords , a_BiomeMap ) ;
2014-09-01 16:33:58 -04:00
}
void cBioGenMulticache : : InitializeBiomeGen ( cIniFile & a_IniFile )
{
2014-10-19 08:01:59 -04:00
for ( auto itr : m_Caches )
2014-09-02 04:49:46 -04:00
{
2014-10-19 08:01:59 -04:00
itr - > InitializeBiomeGen ( a_IniFile ) ;
2014-09-02 04:49:46 -04:00
}
2014-09-01 16:33:58 -04:00
}
2013-02-02 13:17:46 -05:00
2014-07-17 16:15:34 -04:00
////////////////////////////////////////////////////////////////////////////////
2012-06-14 09:06:06 -04:00
// cBiomeGenList:
void cBiomeGenList : : InitializeBiomes ( const AString & a_Biomes )
{
2014-05-27 15:18:15 -04:00
AStringVector Split = StringSplitAndTrim ( a_Biomes , " , " ) ;
2012-06-14 09:06:06 -04:00
// Convert each string in the list into biome:
for ( AStringVector : : const_iterator itr = Split . begin ( ) ; itr ! = Split . end ( ) ; + + itr )
{
2012-11-20 14:45:28 -05:00
AStringVector Split2 = StringSplit ( * itr , " : " ) ;
if ( Split2 . size ( ) < 1 )
{
continue ;
}
int Count = 1 ;
if ( Split2 . size ( ) > = 2 )
{
2015-01-25 10:25:15 -05:00
if ( ! StringToInteger ( Split2 [ 1 ] , Count ) )
2012-11-20 14:45:28 -05:00
{
LOGWARNING ( " Cannot decode biome count: \" %s \" ; using 1. " , Split2 [ 1 ] . c_str ( ) ) ;
Count = 1 ;
}
}
EMCSBiome Biome = StringToBiome ( Split2 [ 0 ] ) ;
2014-02-03 16:07:38 -05:00
if ( Biome ! = biInvalidBiome )
2012-06-14 09:06:06 -04:00
{
2012-11-20 14:45:28 -05:00
for ( int i = 0 ; i < Count ; i + + )
{
m_Biomes . push_back ( Biome ) ;
}
}
else
{
LOGWARNING ( " Cannot decode biome name: \" %s \" ; skipping " , Split2 [ 0 ] . c_str ( ) ) ;
2012-06-14 09:06:06 -04:00
}
} // for itr - Split[]
if ( ! m_Biomes . empty ( ) )
{
2015-07-09 13:15:37 -04:00
m_BiomesCount = static_cast < int > ( m_Biomes . size ( ) ) ;
2012-06-14 09:06:06 -04:00
return ;
}
// There were no biomes, add default biomes:
static EMCSBiome Biomes [ ] =
{
biOcean ,
biPlains ,
biDesert ,
biExtremeHills ,
biForest ,
biTaiga ,
biSwampland ,
biRiver ,
biFrozenOcean ,
biFrozenRiver ,
biIcePlains ,
biIceMountains ,
biMushroomIsland ,
biMushroomShore ,
biBeach ,
biDesertHills ,
biForestHills ,
biTaigaHills ,
biExtremeHillsEdge ,
biJungle ,
biJungleHills ,
} ;
m_Biomes . reserve ( ARRAYCOUNT ( Biomes ) ) ;
2013-12-20 10:01:34 -05:00
for ( size_t i = 0 ; i < ARRAYCOUNT ( Biomes ) ; i + + )
2012-06-14 09:06:06 -04:00
{
m_Biomes . push_back ( Biomes [ i ] ) ;
}
2015-07-09 13:15:37 -04:00
m_BiomesCount = static_cast < int > ( m_Biomes . size ( ) ) ;
2012-06-14 09:06:06 -04:00
}
2014-07-17 16:15:34 -04:00
////////////////////////////////////////////////////////////////////////////////
2012-06-14 09:06:06 -04:00
// cBioGenCheckerboard:
2019-09-07 17:02:05 -04:00
void cBioGenCheckerboard : : GenBiomes ( cChunkCoords a_ChunkCoords , cChunkDef : : BiomeMap & a_BiomeMap )
2012-06-14 09:06:06 -04:00
{
for ( int z = 0 ; z < cChunkDef : : Width ; z + + )
{
2019-09-07 17:02:05 -04:00
int Base = ( cChunkDef : : Width * a_ChunkCoords . m_ChunkZ + z ) / m_BiomeSize ;
2012-06-14 09:06:06 -04:00
for ( int x = 0 ; x < cChunkDef : : Width ; x + + )
{
2019-09-07 17:02:05 -04:00
int Add = cChunkDef : : Width * a_ChunkCoords . m_ChunkX + x ;
2015-05-19 06:50:59 -04:00
size_t BiomeIdx = static_cast < size_t > ( ( ( ( Base + Add / m_BiomeSize ) % m_BiomesCount ) + m_BiomesCount ) % m_BiomesCount ) ; // Need to add and modulo twice because of negative numbers
2013-11-29 15:45:20 -05:00
a_BiomeMap [ x + cChunkDef : : Width * z ] = m_Biomes [ BiomeIdx ] ;
2012-06-14 09:06:06 -04:00
}
}
}
2013-10-10 09:49:24 -04:00
void cBioGenCheckerboard : : InitializeBiomeGen ( cIniFile & a_IniFile )
2013-02-02 13:17:46 -05:00
{
2013-10-10 09:49:24 -04:00
super : : InitializeBiomeGen ( a_IniFile ) ;
2013-02-02 13:17:46 -05:00
AString Biomes = a_IniFile . GetValueSet ( " Generator " , " CheckerBoardBiomes " , " " ) ;
m_BiomeSize = a_IniFile . GetValueSetI ( " Generator " , " CheckerboardBiomeSize " , 64 ) ;
m_BiomeSize = ( m_BiomeSize < 8 ) ? 8 : m_BiomeSize ;
InitializeBiomes ( Biomes ) ;
}
2014-07-17 16:15:34 -04:00
////////////////////////////////////////////////////////////////////////////////
2012-06-14 09:06:06 -04:00
// cBioGenVoronoi :
2019-09-07 17:02:05 -04:00
void cBioGenVoronoi : : GenBiomes ( cChunkCoords a_ChunkCoords , cChunkDef : : BiomeMap & a_BiomeMap )
2012-06-14 09:06:06 -04:00
{
2019-09-07 17:02:05 -04:00
int BaseZ = cChunkDef : : Width * a_ChunkCoords . m_ChunkZ ;
int BaseX = cChunkDef : : Width * a_ChunkCoords . m_ChunkX ;
2012-06-14 09:06:06 -04:00
for ( int z = 0 ; z < cChunkDef : : Width ; z + + )
{
int AbsoluteZ = BaseZ + z ;
for ( int x = 0 ; x < cChunkDef : : Width ; x + + )
{
2013-11-27 15:42:13 -05:00
int VoronoiCellValue = m_Voronoi . GetValueAt ( BaseX + x , AbsoluteZ ) / 8 ;
2015-05-19 06:50:59 -04:00
cChunkDef : : SetBiome ( a_BiomeMap , x , z , m_Biomes [ static_cast < size_t > ( VoronoiCellValue % m_BiomesCount ) ] ) ;
2012-06-14 09:06:06 -04:00
} // for x
} // for z
}
2013-10-10 09:49:24 -04:00
void cBioGenVoronoi : : InitializeBiomeGen ( cIniFile & a_IniFile )
2013-02-02 13:17:46 -05:00
{
2013-10-10 09:49:24 -04:00
super : : InitializeBiomeGen ( a_IniFile ) ;
2014-09-17 17:24:22 -04:00
int CellSize = a_IniFile . GetValueSetI ( " Generator " , " VoronoiCellSize " , 128 ) ;
int JitterSize = a_IniFile . GetValueSetI ( " Generator " , " VoronoiJitterSize " , CellSize ) ;
int OddRowOffset = a_IniFile . GetValueSetI ( " Generator " , " VoronoiOddRowOffset " , 0 ) ;
m_Voronoi . SetCellSize ( CellSize ) ;
m_Voronoi . SetJitterSize ( JitterSize ) ;
m_Voronoi . SetOddRowOffset ( OddRowOffset ) ;
InitializeBiomes ( a_IniFile . GetValueSet ( " Generator " , " VoronoiBiomes " , " " ) ) ;
2012-06-14 09:06:06 -04:00
}
2014-07-17 16:15:34 -04:00
////////////////////////////////////////////////////////////////////////////////
2012-06-14 09:06:06 -04:00
// cBioGenDistortedVoronoi:
2019-09-07 17:02:05 -04:00
void cBioGenDistortedVoronoi : : GenBiomes ( cChunkCoords a_ChunkCoords , cChunkDef : : BiomeMap & a_BiomeMap )
2012-06-14 09:06:06 -04:00
{
2019-09-07 17:02:05 -04:00
int BaseZ = cChunkDef : : Width * a_ChunkCoords . m_ChunkZ ;
int BaseX = cChunkDef : : Width * a_ChunkCoords . m_ChunkX ;
2016-02-05 16:45:45 -05:00
2012-07-29 16:15:03 -04:00
// Distortions for linear interpolation:
int DistortX [ cChunkDef : : Width + 1 ] [ cChunkDef : : Width + 1 ] ;
int DistortZ [ cChunkDef : : Width + 1 ] [ cChunkDef : : Width + 1 ] ;
for ( int x = 0 ; x < = 4 ; x + + ) for ( int z = 0 ; z < = 4 ; z + + )
{
Distort ( BaseX + x * 4 , BaseZ + z * 4 , DistortX [ 4 * x ] [ 4 * z ] , DistortZ [ 4 * x ] [ 4 * z ] ) ;
}
2016-02-05 16:45:45 -05:00
2014-03-21 17:53:46 -04:00
LinearUpscale2DArrayInPlace < cChunkDef : : Width + 1 , cChunkDef : : Width + 1 , 4 , 4 > ( & DistortX [ 0 ] [ 0 ] ) ;
LinearUpscale2DArrayInPlace < cChunkDef : : Width + 1 , cChunkDef : : Width + 1 , 4 , 4 > ( & DistortZ [ 0 ] [ 0 ] ) ;
2016-02-05 16:45:45 -05:00
2012-06-14 09:06:06 -04:00
for ( int z = 0 ; z < cChunkDef : : Width ; z + + )
{
for ( int x = 0 ; x < cChunkDef : : Width ; x + + )
{
2013-11-27 15:42:13 -05:00
int VoronoiCellValue = m_Voronoi . GetValueAt ( DistortX [ x ] [ z ] , DistortZ [ x ] [ z ] ) / 8 ;
2015-05-19 06:50:59 -04:00
cChunkDef : : SetBiome ( a_BiomeMap , x , z , m_Biomes [ static_cast < size_t > ( VoronoiCellValue % m_BiomesCount ) ] ) ;
2012-06-14 09:06:06 -04:00
} // for x
} // for z
}
2013-10-10 09:49:24 -04:00
void cBioGenDistortedVoronoi : : InitializeBiomeGen ( cIniFile & a_IniFile )
2013-02-02 13:17:46 -05:00
{
2013-11-27 15:42:13 -05:00
super : : InitializeBiomeGen ( a_IniFile ) ;
m_CellSize = a_IniFile . GetValueSetI ( " Generator " , " DistortedVoronoiCellSize " , 96 ) ;
m_Voronoi . SetCellSize ( m_CellSize ) ;
InitializeBiomes ( a_IniFile . GetValueSet ( " Generator " , " DistortedVoronoiBiomes " , " " ) ) ;
2013-02-02 13:17:46 -05:00
}
2018-07-26 17:24:36 -04:00
2012-06-14 09:06:06 -04:00
void cBioGenDistortedVoronoi : : Distort ( int a_BlockX , int a_BlockZ , int & a_DistortedX , int & a_DistortedZ )
{
2015-07-09 13:15:37 -04:00
double NoiseX = m_Noise . CubicNoise3D ( static_cast < float > ( a_BlockX / m_CellSize ) , static_cast < float > ( a_BlockZ / m_CellSize ) , 1000 ) ;
NoiseX + = 0.5 * m_Noise . CubicNoise3D ( 2 * static_cast < float > ( a_BlockX / m_CellSize ) , 2 * static_cast < float > ( a_BlockZ / m_CellSize ) , 2000 ) ;
NoiseX + = 0.08 * m_Noise . CubicNoise3D ( 16 * static_cast < float > ( a_BlockX / m_CellSize ) , 16 * static_cast < float > ( a_BlockZ / m_CellSize ) , 3000 ) ;
double NoiseZ = m_Noise . CubicNoise3D ( static_cast < float > ( a_BlockX / m_CellSize ) , static_cast < float > ( a_BlockZ / m_CellSize ) , 4000 ) ;
NoiseZ + = 0.5 * m_Noise . CubicNoise3D ( 2 * static_cast < float > ( a_BlockX / m_CellSize ) , 2 * static_cast < float > ( a_BlockZ / m_CellSize ) , 5000 ) ;
NoiseZ + = 0.08 * m_Noise . CubicNoise3D ( 16 * static_cast < float > ( a_BlockX / m_CellSize ) , 16 * static_cast < float > ( a_BlockZ / m_CellSize ) , 6000 ) ;
2016-02-05 16:45:45 -05:00
2015-07-09 13:15:37 -04:00
a_DistortedX = a_BlockX + static_cast < int > ( m_CellSize * 0.5 * NoiseX ) ;
a_DistortedZ = a_BlockZ + static_cast < int > ( m_CellSize * 0.5 * NoiseZ ) ;
2012-06-14 09:06:06 -04:00
}
2014-07-17 16:15:34 -04:00
////////////////////////////////////////////////////////////////////////////////
2013-01-24 07:15:36 -05:00
// cBioGenMultiStepMap :
cBioGenMultiStepMap : : cBioGenMultiStepMap ( int a_Seed ) :
2013-04-24 10:35:13 -04:00
m_Noise1 ( a_Seed + 1000 ) ,
m_Noise2 ( a_Seed + 2000 ) ,
m_Noise3 ( a_Seed + 3000 ) ,
m_Noise4 ( a_Seed + 4000 ) ,
m_Noise5 ( a_Seed + 5000 ) ,
m_Noise6 ( a_Seed + 6000 ) ,
2013-01-24 07:15:36 -05:00
m_Seed ( a_Seed ) ,
m_OceanCellSize ( 384 ) ,
2013-03-24 12:07:51 -04:00
m_MushroomIslandSize ( 64 ) ,
m_RiverCellSize ( 384 ) ,
m_RiverWidthThreshold ( 0.125 ) ,
m_LandBiomesSize ( 1024 )
2013-01-24 07:15:36 -05:00
{
}
2013-10-10 09:49:24 -04:00
void cBioGenMultiStepMap : : InitializeBiomeGen ( cIniFile & a_IniFile )
2013-01-24 07:15:36 -05:00
{
m_OceanCellSize = a_IniFile . GetValueSetI ( " Generator " , " MultiStepMapOceanCellSize " , m_OceanCellSize ) ;
m_MushroomIslandSize = a_IniFile . GetValueSetI ( " Generator " , " MultiStepMapMushroomIslandSize " , m_MushroomIslandSize ) ;
m_RiverCellSize = a_IniFile . GetValueSetI ( " Generator " , " MultiStepMapRiverCellSize " , m_RiverCellSize ) ;
2013-03-24 12:07:51 -04:00
m_RiverWidthThreshold = a_IniFile . GetValueSetF ( " Generator " , " MultiStepMapRiverWidth " , m_RiverWidthThreshold ) ;
2015-07-09 13:15:37 -04:00
m_LandBiomesSize = static_cast < float > ( a_IniFile . GetValueSetI ( " Generator " , " MultiStepMapLandBiomeSize " , static_cast < int > ( m_LandBiomesSize ) ) ) ;
2013-01-24 07:15:36 -05:00
}
2019-09-07 17:02:05 -04:00
void cBioGenMultiStepMap : : GenBiomes ( cChunkCoords a_ChunkCoords , cChunkDef : : BiomeMap & a_BiomeMap )
2013-01-24 07:15:36 -05:00
{
2019-09-07 17:02:05 -04:00
DecideOceanLandMushroom ( a_ChunkCoords , a_BiomeMap ) ;
AddRivers ( a_ChunkCoords , a_BiomeMap ) ;
ApplyTemperatureHumidity ( a_ChunkCoords , a_BiomeMap ) ;
2013-01-24 07:15:36 -05:00
}
2019-09-07 17:02:05 -04:00
void cBioGenMultiStepMap : : DecideOceanLandMushroom ( cChunkCoords a_ChunkCoords , cChunkDef : : BiomeMap & a_BiomeMap )
2013-01-24 07:15:36 -05:00
{
// Distorted Voronoi over 3 biomes, with mushroom having only a special occurence.
2016-02-05 16:45:45 -05:00
2013-01-24 07:15:36 -05:00
// Prepare a distortion lookup table, by distorting a 5x5 area and using that as 1:4 zoom (linear interpolate):
2019-09-07 17:02:05 -04:00
int BaseZ = cChunkDef : : Width * a_ChunkCoords . m_ChunkZ ;
int BaseX = cChunkDef : : Width * a_ChunkCoords . m_ChunkX ;
2013-01-24 07:15:36 -05:00
int DistortX [ cChunkDef : : Width + 1 ] [ cChunkDef : : Width + 1 ] ;
int DistortZ [ cChunkDef : : Width + 1 ] [ cChunkDef : : Width + 1 ] ;
int DistortSize = m_OceanCellSize / 2 ;
for ( int x = 0 ; x < = 4 ; x + + ) for ( int z = 0 ; z < = 4 ; z + + )
{
Distort ( BaseX + x * 4 , BaseZ + z * 4 , DistortX [ 4 * x ] [ 4 * z ] , DistortZ [ 4 * x ] [ 4 * z ] , DistortSize ) ;
}
2014-03-21 17:53:46 -04:00
LinearUpscale2DArrayInPlace < cChunkDef : : Width + 1 , cChunkDef : : Width + 1 , 4 , 4 > ( & DistortX [ 0 ] [ 0 ] ) ;
LinearUpscale2DArrayInPlace < cChunkDef : : Width + 1 , cChunkDef : : Width + 1 , 4 , 4 > ( & DistortZ [ 0 ] [ 0 ] ) ;
2016-02-05 16:45:45 -05:00
2013-01-24 07:15:36 -05:00
// Prepare a 9x9 area of neighboring cell seeds
// (assuming that 7x7 cell area is larger than a chunk being generated)
const int NEIGHBORHOOD_SIZE = 4 ; // How many seeds in each direction to check
int CellX = BaseX / m_OceanCellSize ;
int CellZ = BaseZ / m_OceanCellSize ;
int SeedX [ 2 * NEIGHBORHOOD_SIZE + 1 ] [ 2 * NEIGHBORHOOD_SIZE + 1 ] ;
int SeedZ [ 2 * NEIGHBORHOOD_SIZE + 1 ] [ 2 * NEIGHBORHOOD_SIZE + 1 ] ;
EMCSBiome SeedV [ 2 * NEIGHBORHOOD_SIZE + 1 ] [ 2 * NEIGHBORHOOD_SIZE + 1 ] ;
for ( int xc = 0 ; xc < 2 * NEIGHBORHOOD_SIZE + 1 ; xc + + )
{
int RealCellX = xc + CellX - NEIGHBORHOOD_SIZE ;
int CellBlockX = RealCellX * m_OceanCellSize ;
for ( int zc = 0 ; zc < 2 * NEIGHBORHOOD_SIZE + 1 ; zc + + )
{
int RealCellZ = zc + CellZ - NEIGHBORHOOD_SIZE ;
int CellBlockZ = RealCellZ * m_OceanCellSize ;
2013-04-24 10:35:13 -04:00
int OffsetX = ( m_Noise2 . IntNoise3DInt ( RealCellX , 16 * RealCellX + 32 * RealCellZ , RealCellZ ) / 8 ) % m_OceanCellSize ;
int OffsetZ = ( m_Noise4 . IntNoise3DInt ( RealCellX , 32 * RealCellX - 16 * RealCellZ , RealCellZ ) / 8 ) % m_OceanCellSize ;
2013-01-24 07:15:36 -05:00
SeedX [ xc ] [ zc ] = CellBlockX + OffsetX ;
SeedZ [ xc ] [ zc ] = CellBlockZ + OffsetZ ;
2014-02-03 16:07:38 -05:00
SeedV [ xc ] [ zc ] = ( ( ( m_Noise6 . IntNoise3DInt ( RealCellX , RealCellX - RealCellZ + 1000 , RealCellZ ) / 11 ) % 256 ) > 90 ) ? biOcean : ( biInvalidBiome ) ;
2013-01-24 07:15:36 -05:00
} // for z
} // for x
2016-02-05 16:45:45 -05:00
2013-01-24 07:15:36 -05:00
for ( int xc = 1 ; xc < 2 * NEIGHBORHOOD_SIZE ; xc + + ) for ( int zc = 1 ; zc < 2 * NEIGHBORHOOD_SIZE ; zc + + )
{
if (
( SeedV [ xc ] [ zc ] = = biOcean ) & &
( SeedV [ xc - 1 ] [ zc ] = = biOcean ) & &
( SeedV [ xc + 1 ] [ zc ] = = biOcean ) & &
( SeedV [ xc ] [ zc - 1 ] = = biOcean ) & &
( SeedV [ xc ] [ zc + 1 ] = = biOcean ) & &
( SeedV [ xc - 1 ] [ zc - 1 ] = = biOcean ) & &
( SeedV [ xc + 1 ] [ zc - 1 ] = = biOcean ) & &
( SeedV [ xc - 1 ] [ zc + 1 ] = = biOcean ) & &
( SeedV [ xc + 1 ] [ zc + 1 ] = = biOcean )
)
{
SeedV [ xc ] [ zc ] = biMushroomIsland ;
}
}
2016-02-05 16:45:45 -05:00
2013-01-24 07:15:36 -05:00
// For each column find the nearest distorted cell and use its value as the biome:
int MushroomOceanThreshold = m_OceanCellSize * m_OceanCellSize * m_MushroomIslandSize / 1024 ;
int MushroomShoreThreshold = m_OceanCellSize * m_OceanCellSize * m_MushroomIslandSize / 2048 ;
for ( int z = 0 ; z < cChunkDef : : Width ; z + + )
{
for ( int x = 0 ; x < cChunkDef : : Width ; x + + )
{
int AbsoluteZ = DistortZ [ x ] [ z ] ;
int AbsoluteX = DistortX [ x ] [ z ] ;
int MinDist = m_OceanCellSize * m_OceanCellSize * 16 ; // There has to be a cell closer than this
EMCSBiome Biome = biPlains ;
// Find the nearest cell seed:
for ( int xs = 1 ; xs < 2 * NEIGHBORHOOD_SIZE ; xs + + ) for ( int zs = 1 ; zs < 2 * NEIGHBORHOOD_SIZE ; zs + + )
{
int Dist = ( SeedX [ xs ] [ zs ] - AbsoluteX ) * ( SeedX [ xs ] [ zs ] - AbsoluteX ) + ( SeedZ [ xs ] [ zs ] - AbsoluteZ ) * ( SeedZ [ xs ] [ zs ] - AbsoluteZ ) ;
if ( Dist > = MinDist )
{
continue ;
}
MinDist = Dist ;
Biome = SeedV [ xs ] [ zs ] ;
// Shrink mushroom biome and add a shore:
if ( Biome = = biMushroomIsland )
{
if ( Dist > MushroomOceanThreshold )
{
Biome = biOcean ;
}
else if ( Dist > MushroomShoreThreshold )
{
Biome = biMushroomShore ;
}
}
} // for zs, xs
cChunkDef : : SetBiome ( a_BiomeMap , x , z , Biome ) ;
} // for x
} // for z
}
2019-09-07 17:02:05 -04:00
void cBioGenMultiStepMap : : AddRivers ( cChunkCoords a_ChunkCoords , cChunkDef : : BiomeMap & a_BiomeMap )
2013-01-24 07:15:36 -05:00
{
for ( int z = 0 ; z < cChunkDef : : Width ; z + + )
{
2019-09-07 17:02:05 -04:00
float NoiseCoordZ = static_cast < float > ( a_ChunkCoords . m_ChunkZ * cChunkDef : : Width + z ) / m_RiverCellSize ;
2013-01-24 07:15:36 -05:00
for ( int x = 0 ; x < cChunkDef : : Width ; x + + )
{
2014-02-03 16:07:38 -05:00
if ( cChunkDef : : GetBiome ( a_BiomeMap , x , z ) ! = biInvalidBiome )
2013-01-24 07:15:36 -05:00
{
// Biome already set, skip this column
continue ;
}
2016-02-05 16:45:45 -05:00
2019-09-07 17:02:05 -04:00
float NoiseCoordX = static_cast < float > ( a_ChunkCoords . m_ChunkX * cChunkDef : : Width + x ) / m_RiverCellSize ;
2016-02-05 16:45:45 -05:00
2013-04-24 10:35:13 -04:00
double Noise = m_Noise1 . CubicNoise2D ( NoiseCoordX , NoiseCoordZ ) ;
Noise + = 0.5 * m_Noise3 . CubicNoise2D ( 2 * NoiseCoordX , 2 * NoiseCoordZ ) ;
Noise + = 0.1 * m_Noise5 . CubicNoise2D ( 8 * NoiseCoordX , 8 * NoiseCoordZ ) ;
2016-02-05 16:45:45 -05:00
2013-01-24 07:15:36 -05:00
if ( ( Noise > 0 ) & & ( Noise < m_RiverWidthThreshold ) )
{
cChunkDef : : SetBiome ( a_BiomeMap , x , z , biRiver ) ;
}
} // for x
} // for z
}
2019-09-07 17:02:05 -04:00
void cBioGenMultiStepMap : : ApplyTemperatureHumidity ( cChunkCoords a_ChunkCoords , cChunkDef : : BiomeMap & a_BiomeMap )
2013-01-24 07:15:36 -05:00
{
IntMap TemperatureMap ;
IntMap HumidityMap ;
2019-09-07 17:02:05 -04:00
BuildTemperatureHumidityMaps ( a_ChunkCoords , TemperatureMap , HumidityMap ) ;
2016-02-05 16:45:45 -05:00
2013-01-24 07:15:36 -05:00
FreezeWaterBiomes ( a_BiomeMap , TemperatureMap ) ;
DecideLandBiomes ( a_BiomeMap , TemperatureMap , HumidityMap ) ;
}
void cBioGenMultiStepMap : : Distort ( int a_BlockX , int a_BlockZ , int & a_DistortedX , int & a_DistortedZ , int a_CellSize )
{
2015-07-09 13:15:37 -04:00
double NoiseX = m_Noise3 . CubicNoise2D ( static_cast < float > ( a_BlockX / a_CellSize ) , static_cast < float > ( a_BlockZ / a_CellSize ) ) ;
NoiseX + = 0.5 * m_Noise2 . CubicNoise2D ( 2 * static_cast < float > ( a_BlockX / a_CellSize ) , 2 * static_cast < float > ( a_BlockZ / a_CellSize ) ) ;
NoiseX + = 0.1 * m_Noise1 . CubicNoise2D ( 16 * static_cast < float > ( a_BlockX / a_CellSize ) , 16 * static_cast < float > ( a_BlockZ / a_CellSize ) ) ;
double NoiseZ = m_Noise6 . CubicNoise2D ( static_cast < float > ( a_BlockX / a_CellSize ) , static_cast < float > ( a_BlockZ / a_CellSize ) ) ;
NoiseZ + = 0.5 * m_Noise5 . CubicNoise2D ( 2 * static_cast < float > ( a_BlockX / a_CellSize ) , 2 * static_cast < float > ( a_BlockZ / a_CellSize ) ) ;
NoiseZ + = 0.1 * m_Noise4 . CubicNoise2D ( 16 * static_cast < float > ( a_BlockX / a_CellSize ) , 16 * static_cast < float > ( a_BlockZ / a_CellSize ) ) ;
2016-02-05 16:45:45 -05:00
2015-07-09 13:15:37 -04:00
a_DistortedX = a_BlockX + static_cast < int > ( a_CellSize * 0.5 * NoiseX ) ;
a_DistortedZ = a_BlockZ + static_cast < int > ( a_CellSize * 0.5 * NoiseZ ) ;
2013-01-24 07:15:36 -05:00
}
2019-09-07 17:02:05 -04:00
void cBioGenMultiStepMap : : BuildTemperatureHumidityMaps ( cChunkCoords a_ChunkCoords , IntMap & a_TemperatureMap , IntMap & a_HumidityMap )
2013-01-24 07:15:36 -05:00
{
2013-03-24 12:07:51 -04:00
// Linear interpolation over 8x8 blocks; use double for better precision:
DblMap TemperatureMap ;
DblMap HumidityMap ;
2013-03-19 11:10:00 -04:00
for ( int z = 0 ; z < 17 ; z + = 8 )
2013-01-24 07:15:36 -05:00
{
2019-09-07 17:02:05 -04:00
float NoiseCoordZ = static_cast < float > ( a_ChunkCoords . m_ChunkZ * cChunkDef : : Width + z ) / m_LandBiomesSize ;
2013-03-19 11:10:00 -04:00
for ( int x = 0 ; x < 17 ; x + = 8 )
2013-01-24 07:15:36 -05:00
{
2019-09-07 17:02:05 -04:00
float NoiseCoordX = static_cast < float > ( a_ChunkCoords . m_ChunkX * cChunkDef : : Width + x ) / m_LandBiomesSize ;
2016-02-05 16:45:45 -05:00
2013-04-24 10:35:13 -04:00
double NoiseT = m_Noise1 . CubicNoise2D ( NoiseCoordX , NoiseCoordZ ) ;
NoiseT + = 0.5 * m_Noise2 . CubicNoise2D ( 2 * NoiseCoordX , 2 * NoiseCoordZ ) ;
NoiseT + = 0.1 * m_Noise3 . CubicNoise2D ( 8 * NoiseCoordX , 8 * NoiseCoordZ ) ;
2013-03-24 12:07:51 -04:00
TemperatureMap [ x + 17 * z ] = NoiseT ;
2013-01-24 07:15:36 -05:00
2013-04-24 10:35:13 -04:00
double NoiseH = m_Noise4 . CubicNoise2D ( NoiseCoordX , NoiseCoordZ ) ;
NoiseH + = 0.5 * m_Noise5 . CubicNoise2D ( 2 * NoiseCoordX , 2 * NoiseCoordZ ) ;
NoiseH + = 0.1 * m_Noise6 . CubicNoise2D ( 8 * NoiseCoordX , 8 * NoiseCoordZ ) ;
2013-03-24 12:07:51 -04:00
HumidityMap [ x + 17 * z ] = NoiseH ;
2013-01-24 07:15:36 -05:00
} // for x
} // for z
2014-03-21 17:53:46 -04:00
LinearUpscale2DArrayInPlace < 17 , 17 , 8 , 8 > ( TemperatureMap ) ;
LinearUpscale2DArrayInPlace < 17 , 17 , 8 , 8 > ( HumidityMap ) ;
2016-02-05 16:45:45 -05:00
2013-03-24 12:07:51 -04:00
// Re-map into integral values in [0 .. 255] range:
2013-12-20 10:01:34 -05:00
for ( size_t idx = 0 ; idx < ARRAYCOUNT ( a_TemperatureMap ) ; idx + + )
2013-03-24 12:07:51 -04:00
{
2015-07-13 16:17:43 -04:00
a_TemperatureMap [ idx ] = Clamp ( static_cast < int > ( 128 + TemperatureMap [ idx ] * 128 ) , 0 , 255 ) ;
a_HumidityMap [ idx ] = Clamp ( static_cast < int > ( 128 + HumidityMap [ idx ] * 128 ) , 0 , 255 ) ;
2013-03-24 12:07:51 -04:00
}
2013-01-24 07:15:36 -05:00
}
void cBioGenMultiStepMap : : DecideLandBiomes ( cChunkDef : : BiomeMap & a_BiomeMap , const IntMap & a_TemperatureMap , const IntMap & a_HumidityMap )
{
static const EMCSBiome BiomeMap [ ] =
{
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/* 0 */ biTundra , biTundra , biTundra , biTundra , biPlains , biPlains , biPlains , biPlains , biPlains , biPlains , biDesert , biDesert , biDesert , biDesert , biDesert , biDesert ,
/* 1 */ biTundra , biTundra , biTundra , biTundra , biPlains , biPlains , biPlains , biPlains , biPlains , biPlains , biDesert , biDesert , biDesert , biDesert , biDesert , biDesert ,
/* 2 */ biTundra , biTundra , biTundra , biTundra , biPlains , biExtremeHills , biPlains , biPlains , biPlains , biPlains , biDesert , biDesert , biDesertHills , biDesertHills , biDesert , biDesert ,
/* 3 */ biTundra , biTundra , biTundra , biTundra , biExtremeHills , biExtremeHills , biPlains , biPlains , biPlains , biPlains , biDesert , biDesert , biDesertHills , biDesertHills , biDesert , biDesert ,
/* 4 */ biTundra , biTundra , biIceMountains , biIceMountains , biExtremeHills , biExtremeHills , biPlains , biPlains , biPlains , biPlains , biForestHills , biForestHills , biExtremeHills , biExtremeHills , biDesertHills , biDesert ,
/* 5 */ biTundra , biTundra , biIceMountains , biIceMountains , biExtremeHills , biExtremeHills , biPlains , biPlains , biPlains , biPlains , biForestHills , biForestHills , biExtremeHills , biExtremeHills , biDesertHills , biDesert ,
/* 6 */ biTundra , biTundra , biIceMountains , biIceMountains , biForestHills , biForestHills , biForest , biForest , biForest , biForest , biForest , biForestHills , biExtremeHills , biExtremeHills , biPlains , biPlains ,
/* 7 */ biTundra , biTundra , biIceMountains , biIceMountains , biForestHills , biForestHills , biForest , biForest , biForest , biForest , biForest , biForestHills , biExtremeHills , biExtremeHills , biPlains , biPlains ,
/* 8 */ biTundra , biTundra , biTaiga , biTaiga , biForest , biForest , biForest , biForest , biForest , biForest , biForest , biForestHills , biExtremeHills , biExtremeHills , biPlains , biPlains ,
/* 9 */ biTundra , biTundra , biTaiga , biTaiga , biForest , biForest , biForest , biForest , biForest , biForest , biForest , biForestHills , biExtremeHills , biExtremeHills , biPlains , biPlains ,
/* 10 */ biTaiga , biTaiga , biTaiga , biIceMountains , biForestHills , biForestHills , biForest , biForest , biForest , biForest , biJungle , biJungle , biSwampland , biSwampland , biSwampland , biSwampland ,
/* 11 */ biTaiga , biTaiga , biIceMountains , biIceMountains , biExtremeHills , biForestHills , biForest , biForest , biForest , biForest , biJungle , biJungle , biSwampland , biSwampland , biSwampland , biSwampland ,
/* 12 */ biTaiga , biTaiga , biIceMountains , biIceMountains , biExtremeHills , biJungleHills , biJungle , biJungle , biJungle , biJungle , biJungle , biJungle , biSwampland , biSwampland , biSwampland , biSwampland ,
/* 13 */ biTaiga , biTaiga , biTaiga , biIceMountains , biJungleHills , biJungleHills , biJungle , biJungle , biJungle , biJungle , biJungle , biJungle , biSwampland , biSwampland , biSwampland , biSwampland ,
/* 14 */ biTaiga , biTaiga , biTaiga , biTaiga , biJungle , biJungle , biJungle , biJungle , biJungle , biJungle , biJungle , biJungle , biSwampland , biSwampland , biSwampland , biSwampland ,
/* 15 */ biTaiga , biTaiga , biTaiga , biTaiga , biJungle , biJungle , biJungle , biJungle , biJungle , biJungle , biJungle , biJungle , biSwampland , biSwampland , biSwampland , biSwampland ,
} ;
for ( int z = 0 ; z < cChunkDef : : Width ; z + + )
{
2013-03-19 11:10:00 -04:00
int idxZ = 17 * z ;
2013-01-24 07:15:36 -05:00
for ( int x = 0 ; x < cChunkDef : : Width ; x + + )
{
2014-02-03 16:07:38 -05:00
if ( cChunkDef : : GetBiome ( a_BiomeMap , x , z ) ! = biInvalidBiome )
2013-01-24 07:15:36 -05:00
{
// Already set before
continue ;
}
2013-03-19 11:10:00 -04:00
int idx = idxZ + x ;
2013-01-24 07:15:36 -05:00
int Temperature = a_TemperatureMap [ idx ] / 16 ; // -> [0..15] range
int Humidity = a_HumidityMap [ idx ] / 16 ; // -> [0..15] range
cChunkDef : : SetBiome ( a_BiomeMap , x , z , BiomeMap [ Temperature + 16 * Humidity ] ) ;
} // for x
} // for z
}
void cBioGenMultiStepMap : : FreezeWaterBiomes ( cChunkDef : : BiomeMap & a_BiomeMap , const IntMap & a_TemperatureMap )
{
int idx = 0 ;
for ( int z = 0 ; z < cChunkDef : : Width ; z + + )
{
for ( int x = 0 ; x < cChunkDef : : Width ; x + + , idx + + )
{
if ( a_TemperatureMap [ idx ] > 4 * 16 )
{
// Not frozen
continue ;
}
switch ( cChunkDef : : GetBiome ( a_BiomeMap , x , z ) )
{
case biRiver : cChunkDef : : SetBiome ( a_BiomeMap , x , z , biFrozenRiver ) ; break ;
case biOcean : cChunkDef : : SetBiome ( a_BiomeMap , x , z , biFrozenOcean ) ; break ;
2013-12-07 18:45:32 -05:00
default : break ;
2013-01-24 07:15:36 -05:00
}
} // for x
2013-03-19 11:10:00 -04:00
idx + = 1 ;
2013-01-24 07:15:36 -05:00
} // for z
}
2013-11-28 13:58:20 -05:00
2014-07-17 16:15:34 -04:00
////////////////////////////////////////////////////////////////////////////////
2013-11-28 13:58:20 -05:00
// cBioGenTwoLevel:
cBioGenTwoLevel : : cBioGenTwoLevel ( int a_Seed ) :
m_VoronoiLarge ( a_Seed + 1000 ) ,
m_VoronoiSmall ( a_Seed + 2000 ) ,
2014-06-20 11:10:18 -04:00
m_Noise1 ( a_Seed + 5001 ) ,
m_Noise2 ( a_Seed + 5002 ) ,
m_Noise3 ( a_Seed + 5003 ) ,
m_Noise4 ( a_Seed + 5004 ) ,
m_Noise5 ( a_Seed + 5005 ) ,
2015-01-23 10:42:54 -05:00
m_Noise6 ( a_Seed + 5006 ) ,
m_FreqX1 ( 0.0 ) ,
m_AmpX1 ( 0.0 ) ,
m_FreqX2 ( 0.0 ) ,
m_AmpX2 ( 0.0 ) ,
m_FreqX3 ( 0.0 ) ,
m_AmpX3 ( 0.0 ) ,
m_FreqZ1 ( 0.0 ) ,
m_AmpZ1 ( 0.0 ) ,
m_FreqZ2 ( 0.0 ) ,
m_AmpZ2 ( 0.0 ) ,
m_FreqZ3 ( 0.0 ) ,
m_AmpZ3 ( 0.0 )
2013-11-28 13:58:20 -05:00
{
}
2019-09-07 17:02:05 -04:00
void cBioGenTwoLevel : : GenBiomes ( cChunkCoords a_ChunkCoords , cChunkDef : : BiomeMap & a_BiomeMap )
2013-11-28 13:58:20 -05:00
{
2019-09-07 17:02:05 -04:00
int BaseZ = cChunkDef : : Width * a_ChunkCoords . m_ChunkZ ;
int BaseX = cChunkDef : : Width * a_ChunkCoords . m_ChunkX ;
2016-02-05 16:45:45 -05:00
2013-11-28 13:58:20 -05:00
// Distortions for linear interpolation:
int DistortX [ cChunkDef : : Width + 1 ] [ cChunkDef : : Width + 1 ] ;
int DistortZ [ cChunkDef : : Width + 1 ] [ cChunkDef : : Width + 1 ] ;
for ( int x = 0 ; x < = 4 ; x + + ) for ( int z = 0 ; z < = 4 ; z + + )
{
2014-10-16 05:00:15 -04:00
float BlockX = static_cast < float > ( BaseX + x * 4 ) ;
float BlockZ = static_cast < float > ( BaseZ + z * 4 ) ;
2014-09-27 16:01:47 -04:00
double NoiseX = m_AmpX1 * m_Noise1 . CubicNoise2D ( BlockX * m_FreqX1 , BlockZ * m_FreqX1 ) ;
NoiseX + = m_AmpX2 * m_Noise2 . CubicNoise2D ( BlockX * m_FreqX2 , BlockZ * m_FreqX2 ) ;
NoiseX + = m_AmpX3 * m_Noise3 . CubicNoise2D ( BlockX * m_FreqX3 , BlockZ * m_FreqX3 ) ;
double NoiseZ = m_AmpZ1 * m_Noise4 . CubicNoise2D ( BlockX * m_FreqZ1 , BlockZ * m_FreqZ1 ) ;
NoiseZ + = m_AmpZ2 * m_Noise5 . CubicNoise2D ( BlockX * m_FreqZ2 , BlockZ * m_FreqZ2 ) ;
NoiseZ + = m_AmpZ3 * m_Noise6 . CubicNoise2D ( BlockX * m_FreqZ3 , BlockZ * m_FreqZ3 ) ;
2016-02-05 16:45:45 -05:00
2015-07-09 13:15:37 -04:00
DistortX [ 4 * x ] [ 4 * z ] = static_cast < int > ( BlockX + NoiseX ) ;
DistortZ [ 4 * x ] [ 4 * z ] = static_cast < int > ( BlockZ + NoiseZ ) ;
2013-11-28 13:58:20 -05:00
}
2016-02-05 16:45:45 -05:00
2014-03-21 17:53:46 -04:00
LinearUpscale2DArrayInPlace < cChunkDef : : Width + 1 , cChunkDef : : Width + 1 , 4 , 4 > ( & DistortX [ 0 ] [ 0 ] ) ;
LinearUpscale2DArrayInPlace < cChunkDef : : Width + 1 , cChunkDef : : Width + 1 , 4 , 4 > ( & DistortZ [ 0 ] [ 0 ] ) ;
2016-02-05 16:45:45 -05:00
2013-11-28 13:58:20 -05:00
// Apply distortion to each block coord, then query the voronoi maps for biome group and biome index and choose biome based on that:
for ( int z = 0 ; z < cChunkDef : : Width ; z + + )
{
for ( int x = 0 ; x < cChunkDef : : Width ; x + + )
{
2014-09-17 17:24:22 -04:00
int SeedX , SeedZ , MinDist2 ;
int BiomeGroup = m_VoronoiLarge . GetValueAt ( DistortX [ x ] [ z ] , DistortZ [ x ] [ z ] , SeedX , SeedZ , MinDist2 ) / 7 ;
2015-05-19 06:50:59 -04:00
size_t BiomeIdx = static_cast < size_t > ( m_VoronoiSmall . GetValueAt ( DistortX [ x ] [ z ] , DistortZ [ x ] [ z ] , SeedX , SeedZ , MinDist2 ) / 11 ) ;
2014-09-17 17:24:22 -04:00
int MinDist1 = ( DistortX [ x ] [ z ] - SeedX ) * ( DistortX [ x ] [ z ] - SeedX ) + ( DistortZ [ x ] [ z ] - SeedZ ) * ( DistortZ [ x ] [ z ] - SeedZ ) ;
2014-10-19 10:07:29 -04:00
cChunkDef : : SetBiome ( a_BiomeMap , x , z , SelectBiome ( BiomeGroup , BiomeIdx , ( MinDist1 < MinDist2 / 4 ) ? 1 : 0 ) ) ;
2013-11-28 13:58:20 -05:00
}
}
}
2015-05-19 06:50:59 -04:00
EMCSBiome cBioGenTwoLevel : : SelectBiome ( int a_BiomeGroup , size_t a_BiomeIdx , int a_DistLevel )
2013-11-28 13:58:20 -05:00
{
// TODO: Move this into settings
struct BiomeLevels
{
EMCSBiome InnerBiome ;
EMCSBiome OuterBiome ;
} ;
2016-02-05 16:45:45 -05:00
2013-11-28 13:58:20 -05:00
static BiomeLevels bgOcean [ ] =
{
{ biOcean , biOcean , } ,
{ biOcean , biOcean , } ,
{ biOcean , biOcean , } ,
{ biOcean , biOcean , } ,
{ biOcean , biDeepOcean , } ,
{ biOcean , biDeepOcean , } ,
{ biDeepOcean , biDeepOcean , } ,
{ biDeepOcean , biDeepOcean , } ,
{ biDeepOcean , biDeepOcean , } ,
{ biDeepOcean , biDeepOcean , } ,
{ biMushroomIsland , biMushroomShore , }
} ;
static BiomeLevels bgFrozen [ ] =
{
{ biIcePlains , biIcePlains , } ,
{ biIceMountains , biIceMountains , } ,
{ biFrozenOcean , biFrozenRiver , } ,
{ biColdTaiga , biColdTaiga , } ,
{ biColdTaigaHills , biColdTaigaHills , } ,
{ biColdTaigaM , biColdTaigaM , } ,
{ biIcePlainsSpikes , biIcePlainsSpikes , } ,
{ biExtremeHills , biExtremeHillsEdge , } ,
{ biExtremeHillsPlus , biExtremeHillsEdge , } ,
{ biExtremeHillsPlusM , biExtremeHillsPlusM , } ,
} ;
static BiomeLevels bgTemperate [ ] =
{
{ biBirchForestHills , biBirchForest , } ,
{ biBirchForest , biBirchForest , } ,
{ biBirchForestHillsM , biBirchForestM , } ,
{ biBirchForestM , biBirchForestM , } ,
{ biForest , biForestHills , } ,
{ biFlowerForest , biFlowerForest , } ,
{ biRoofedForest , biForest , } ,
{ biRoofedForest , biRoofedForest , } ,
{ biRoofedForestM , biForest , } ,
{ biPlains , biPlains , } ,
{ biSunflowerPlains , biSunflowerPlains , } ,
{ biSwampland , biSwampland , } ,
{ biSwamplandM , biSwamplandM , } ,
} ;
static BiomeLevels bgWarm [ ] =
{
{ biDesertHills , biDesert , } ,
{ biDesert , biDesert , } ,
{ biDesertM , biDesertM , } ,
{ biSavannaPlateau , biSavanna , } ,
{ biSavanna , biSavanna , } ,
{ biSavannaM , biSavannaM , } ,
} ;
static BiomeLevels bgMesa [ ] =
{
{ biMesaPlateau , biMesa , } ,
{ biMesaPlateauF , biMesa , } ,
{ biMesaPlateauFM , biMesa , } ,
{ biMesaPlateauM , biMesa , } ,
{ biMesaBryce , biMesaBryce , } ,
{ biSavanna , biSavanna , } ,
{ biSavannaPlateau , biSavanna , } ,
} ;
static BiomeLevels bgConifers [ ] =
{
{ biTaiga , biTaiga , } ,
{ biTaigaM , biTaigaM , } ,
{ biMegaTaiga , biMegaTaiga , } ,
{ biMegaSpruceTaiga , biMegaSpruceTaiga , } ,
{ biMegaSpruceTaigaHills , biMegaSpruceTaiga , }
} ;
static BiomeLevels bgDenseTrees [ ] =
{
{ biJungleHills , biJungle , } ,
{ biJungle , biJungleEdge , } ,
{ biJungleM , biJungleEdgeM , } ,
} ;
static struct
{
BiomeLevels * Biomes ;
size_t Count ;
} BiomeGroups [ ] =
{
{ bgOcean , ARRAYCOUNT ( bgOcean ) , } ,
{ bgOcean , ARRAYCOUNT ( bgOcean ) , } ,
{ bgFrozen , ARRAYCOUNT ( bgFrozen ) , } ,
{ bgFrozen , ARRAYCOUNT ( bgFrozen ) , } ,
{ bgTemperate , ARRAYCOUNT ( bgTemperate ) , } ,
{ bgTemperate , ARRAYCOUNT ( bgTemperate ) , } ,
{ bgConifers , ARRAYCOUNT ( bgConifers ) , } ,
{ bgConifers , ARRAYCOUNT ( bgConifers ) , } ,
{ bgWarm , ARRAYCOUNT ( bgWarm ) , } ,
{ bgWarm , ARRAYCOUNT ( bgWarm ) , } ,
{ bgMesa , ARRAYCOUNT ( bgMesa ) , } ,
{ bgDenseTrees , ARRAYCOUNT ( bgDenseTrees ) , } ,
} ;
2015-05-19 06:50:59 -04:00
size_t Group = static_cast < size_t > ( a_BiomeGroup ) % ARRAYCOUNT ( BiomeGroups ) ;
2013-11-28 13:58:20 -05:00
size_t Index = a_BiomeIdx % BiomeGroups [ Group ] . Count ;
return ( a_DistLevel > 0 ) ? BiomeGroups [ Group ] . Biomes [ Index ] . InnerBiome : BiomeGroups [ Group ] . Biomes [ Index ] . OuterBiome ;
}
void cBioGenTwoLevel : : InitializeBiomeGen ( cIniFile & a_IniFile )
{
2014-09-25 14:47:16 -04:00
m_VoronoiLarge . SetCellSize ( a_IniFile . GetValueSetI ( " Generator " , " TwoLevelLargeCellSize " , 1024 ) ) ;
m_VoronoiSmall . SetCellSize ( a_IniFile . GetValueSetI ( " Generator " , " TwoLevelSmallCellSize " , 128 ) ) ;
2015-07-09 13:15:37 -04:00
m_FreqX1 = static_cast < float > ( a_IniFile . GetValueSetF ( " Generator " , " TwoLevelDistortXOctave1Freq " , 0.01 ) ) ;
m_AmpX1 = static_cast < float > ( a_IniFile . GetValueSetF ( " Generator " , " TwoLevelDistortXOctave1Amp " , 80 ) ) ;
m_FreqX2 = static_cast < float > ( a_IniFile . GetValueSetF ( " Generator " , " TwoLevelDistortXOctave2Freq " , 0.05 ) ) ;
m_AmpX2 = static_cast < float > ( a_IniFile . GetValueSetF ( " Generator " , " TwoLevelDistortXOctave2Amp " , 20 ) ) ;
2016-03-18 13:53:17 -04:00
m_FreqX3 = static_cast < float > ( a_IniFile . GetValueSetF ( " Generator " , " TwoLevelDistortXOctave3Freq " , 0.1 ) ) ;
2015-07-09 13:15:37 -04:00
m_AmpX3 = static_cast < float > ( a_IniFile . GetValueSetF ( " Generator " , " TwoLevelDistortXOctave3Amp " , 8 ) ) ;
m_FreqZ1 = static_cast < float > ( a_IniFile . GetValueSetF ( " Generator " , " TwoLevelDistortZOctave1Freq " , 0.01 ) ) ;
m_AmpZ1 = static_cast < float > ( a_IniFile . GetValueSetF ( " Generator " , " TwoLevelDistortZOctave1Amp " , 80 ) ) ;
m_FreqZ2 = static_cast < float > ( a_IniFile . GetValueSetF ( " Generator " , " TwoLevelDistortZOctave2Freq " , 0.05 ) ) ;
m_AmpZ2 = static_cast < float > ( a_IniFile . GetValueSetF ( " Generator " , " TwoLevelDistortZOctave2Amp " , 20 ) ) ;
m_FreqZ3 = static_cast < float > ( a_IniFile . GetValueSetF ( " Generator " , " TwoLevelDistortZOctave3Freq " , 0.1 ) ) ;
m_AmpZ3 = static_cast < float > ( a_IniFile . GetValueSetF ( " Generator " , " TwoLevelDistortZOctave3Amp " , 8 ) ) ;
2013-11-28 13:58:20 -05:00
}
2014-09-17 17:24:22 -04:00
2014-10-26 14:58:16 -04:00
////////////////////////////////////////////////////////////////////////////////
// cBioGenGrown:
class cBioGenGrown :
public cBiomeGen
{
public :
cBioGenGrown ( int a_Seed )
{
auto FinalRivers =
2016-02-05 16:45:45 -05:00
2015-03-01 09:51:07 -05:00
std : : make_shared < cIntGenChoice < 2 , 7 > > ( a_Seed + 12 )
2015-03-11 06:42:45 -04:00
| MakeIntGen < cIntGenZoom < 10 > > ( a_Seed + 11 )
| MakeIntGen < cIntGenSmooth < 8 > > ( a_Seed + 6 )
| MakeIntGen < cIntGenSmooth < 6 > > ( a_Seed + 5 )
| MakeIntGen < cIntGenZoom < 8 > > ( a_Seed + 10 )
| MakeIntGen < cIntGenSmooth < 6 > > ( a_Seed + 5 )
| MakeIntGen < cIntGenZoom < 8 > > ( a_Seed + 9 )
| MakeIntGen < cIntGenSmooth < 6 > > ( a_Seed + 5 )
| MakeIntGen < cIntGenZoom < 8 > > ( a_Seed + 8 )
| MakeIntGen < cIntGenSmooth < 6 > > ( a_Seed + 5 )
| MakeIntGen < cIntGenZoom < 9 > > ( a_Seed + 4 )
| MakeIntGen < cIntGenRiver < 7 > > ( a_Seed + 3 )
| MakeIntGen < cIntGenZoom < 10 > > ( a_Seed + 2 )
| MakeIntGen < cIntGenSmooth < 8 > > ( a_Seed + 1 ) ;
2014-11-02 10:36:59 -05:00
auto alteration =
std : : make_shared < cIntGenZoom < 8 > > ( a_Seed ,
std : : make_shared < cIntGenLandOcean < 6 > > ( a_Seed , 20
) ) ;
auto alteration2 =
std : : make_shared < cIntGenZoom < 8 > > ( a_Seed + 1 ,
std : : make_shared < cIntGenZoom < 6 > > ( a_Seed + 2 ,
std : : make_shared < cIntGenZoom < 5 > > ( a_Seed + 1 ,
std : : make_shared < cIntGenZoom < 4 > > ( a_Seed + 2 ,
std : : make_shared < cIntGenLandOcean < 4 > > ( a_Seed + 1 , 10
) ) ) ) ) ;
2014-10-26 14:58:16 -04:00
auto FinalBiomes =
2014-11-02 10:36:59 -05:00
std : : make_shared < cIntGenSmooth < 8 > > ( a_Seed + 1 ,
std : : make_shared < cIntGenZoom < 10 > > ( a_Seed + 15 ,
std : : make_shared < cIntGenSmooth < 7 > > ( a_Seed + 1 ,
std : : make_shared < cIntGenZoom < 9 > > ( a_Seed + 16 ,
2014-10-26 14:58:16 -04:00
std : : make_shared < cIntGenBeaches < 6 > > (
2014-11-02 10:36:59 -05:00
std : : make_shared < cIntGenZoom < 8 > > ( a_Seed + 1 ,
2014-10-29 10:28:27 -04:00
std : : make_shared < cIntGenAddIslands < 6 > > ( a_Seed + 2004 , 10 ,
2014-11-02 10:36:59 -05:00
std : : make_shared < cIntGenAddToOcean < 6 > > ( a_Seed + 10 , 500 , biDeepOcean ,
std : : make_shared < cIntGenReplaceRandomly < 8 > > ( a_Seed + 1 , biPlains , biSunflowerPlains , 20 ,
std : : make_shared < cIntGenMBiomes < 8 > > ( a_Seed + 5 , alteration2 ,
std : : make_shared < cIntGenAlternateBiomes < 8 > > ( a_Seed + 1 , alteration ,
std : : make_shared < cIntGenBiomeEdges < 8 > > ( a_Seed + 3 ,
std : : make_shared < cIntGenZoom < 10 > > ( a_Seed + 2 ,
std : : make_shared < cIntGenZoom < 7 > > ( a_Seed + 4 ,
std : : make_shared < cIntGenReplaceRandomly < 5 > > ( a_Seed + 99 , biIcePlains , biIcePlainsSpikes , 50 ,
std : : make_shared < cIntGenZoom < 5 > > ( a_Seed + 8 ,
std : : make_shared < cIntGenAddToOcean < 4 > > ( a_Seed + 10 , 300 , biDeepOcean ,
std : : make_shared < cIntGenAddToOcean < 6 > > ( a_Seed + 9 , 8 , biMushroomIsland ,
std : : make_shared < cIntGenBiomes < 8 > > ( a_Seed + 3000 ,
std : : make_shared < cIntGenAddIslands < 8 > > ( a_Seed + 2000 , 200 ,
std : : make_shared < cIntGenZoom < 8 > > ( a_Seed + 5 ,
std : : make_shared < cIntGenRareBiomeGroups < 6 > > ( a_Seed + 5 , 50 ,
std : : make_shared < cIntGenBiomeGroupEdges < 6 > > (
std : : make_shared < cIntGenAddIslands < 8 > > ( a_Seed + 2000 , 200 ,
std : : make_shared < cIntGenZoom < 8 > > ( a_Seed + 7 ,
2014-10-30 11:24:35 -04:00
std : : make_shared < cIntGenSetRandomly < 6 > > ( a_Seed + 8 , 50 , bgOcean ,
2014-11-02 10:36:59 -05:00
std : : make_shared < cIntGenReplaceRandomly < 6 > > ( a_Seed + 101 , bgIce , bgTemperate , 150 ,
std : : make_shared < cIntGenAddIslands < 6 > > ( a_Seed + 2000 , 200 ,
2014-10-30 11:24:35 -04:00
std : : make_shared < cIntGenSetRandomly < 6 > > ( a_Seed + 9 , 50 , bgOcean ,
2015-03-10 18:19:03 -04:00
std : : make_shared < cIntGenLandOcean < 5 > > ( a_Seed + 100 , 30 )
2015-03-11 06:42:45 -04:00
| MakeIntGen < cIntGenZoom < 6 > > ( a_Seed + 10 )
2015-03-10 18:19:03 -04:00
) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ;
2014-10-26 14:58:16 -04:00
m_Gen =
std : : make_shared < cIntGenSmooth < 16 > > ( a_Seed ,
std : : make_shared < cIntGenZoom < 18 > > ( a_Seed ,
2014-11-02 10:36:59 -05:00
std : : make_shared < cIntGenSmooth < 11 > > ( a_Seed ,
std : : make_shared < cIntGenZoom < 13 > > ( a_Seed ,
std : : make_shared < cIntGenMixRivers < 8 > > (
2014-10-26 14:58:16 -04:00
FinalBiomes , FinalRivers
2014-11-02 10:36:59 -05:00
) ) ) ) ) ;
2014-10-26 14:58:16 -04:00
}
2019-09-07 17:02:05 -04:00
virtual void GenBiomes ( cChunkCoords a_ChunkCoords , cChunkDef : : BiomeMap & a_Biomes ) override
2014-10-26 14:58:16 -04:00
{
cIntGen < 16 , 16 > : : Values vals ;
2019-09-07 17:02:05 -04:00
m_Gen - > GetInts ( a_ChunkCoords . m_ChunkX * cChunkDef : : Width , a_ChunkCoords . m_ChunkZ * cChunkDef : : Width , vals ) ;
2014-10-26 14:58:16 -04:00
for ( int z = 0 ; z < cChunkDef : : Width ; z + + )
{
for ( int x = 0 ; x < cChunkDef : : Width ; x + + )
{
2015-07-09 13:15:37 -04:00
cChunkDef : : SetBiome ( a_Biomes , x , z , static_cast < EMCSBiome > ( vals [ x + cChunkDef : : Width * z ] ) ) ;
2014-10-26 14:58:16 -04:00
}
}
}
protected :
2014-10-27 04:35:21 -04:00
std : : shared_ptr < cIntGen < 16 , 16 > > m_Gen ;
2014-10-26 14:58:16 -04:00
} ;
2014-10-30 11:24:35 -04:00
////////////////////////////////////////////////////////////////////////////////
2015-03-01 06:13:39 -05:00
// cBioGenProtGrown:
2014-10-30 11:24:35 -04:00
class cBioGenProtGrown :
public cBiomeGen
{
public :
cBioGenProtGrown ( int a_Seed )
{
auto FinalRivers =
std : : make_shared < cProtIntGenSmooth > ( a_Seed + 1 ,
2014-10-31 07:52:07 -04:00
std : : make_shared < cProtIntGenZoom > ( a_Seed + 2 ,
std : : make_shared < cProtIntGenRiver > ( a_Seed + 3 ,
std : : make_shared < cProtIntGenZoom > ( a_Seed + 4 ,
std : : make_shared < cProtIntGenSmooth > ( a_Seed + 5 ,
2014-10-30 11:24:35 -04:00
std : : make_shared < cProtIntGenZoom > ( a_Seed + 8 ,
2014-10-31 07:52:07 -04:00
std : : make_shared < cProtIntGenSmooth > ( a_Seed + 5 ,
2014-10-30 11:24:35 -04:00
std : : make_shared < cProtIntGenZoom > ( a_Seed + 9 ,
2014-10-31 07:52:07 -04:00
std : : make_shared < cProtIntGenSmooth > ( a_Seed + 5 ,
2014-10-30 11:24:35 -04:00
std : : make_shared < cProtIntGenZoom > ( a_Seed + 10 ,
2014-10-31 07:52:07 -04:00
std : : make_shared < cProtIntGenSmooth > ( a_Seed + 5 ,
2014-11-02 10:36:59 -05:00
std : : make_shared < cProtIntGenSmooth > ( a_Seed + 6 ,
2014-10-30 11:24:35 -04:00
std : : make_shared < cProtIntGenZoom > ( a_Seed + 11 ,
std : : make_shared < cProtIntGenChoice > ( a_Seed + 12 , 2
2014-10-31 07:52:07 -04:00
) ) ) ) ) ) ) ) ) ) ) ) ) ) ;
auto alteration =
std : : make_shared < cProtIntGenZoom > ( a_Seed ,
std : : make_shared < cProtIntGenLandOcean > ( a_Seed , 20
) ) ;
2014-10-30 11:24:35 -04:00
2014-11-01 16:01:33 -04:00
auto alteration2 =
std : : make_shared < cProtIntGenZoom > ( a_Seed + 1 ,
std : : make_shared < cProtIntGenZoom > ( a_Seed + 2 ,
std : : make_shared < cProtIntGenZoom > ( a_Seed + 1 ,
std : : make_shared < cProtIntGenZoom > ( a_Seed + 2 ,
std : : make_shared < cProtIntGenLandOcean > ( a_Seed + 1 , 10
) ) ) ) ) ;
2014-10-30 11:24:35 -04:00
auto FinalBiomes =
2014-10-31 07:52:07 -04:00
std : : make_shared < cProtIntGenSmooth > ( a_Seed + 1 ,
2014-10-30 11:24:35 -04:00
std : : make_shared < cProtIntGenZoom > ( a_Seed + 15 ,
2014-10-31 07:52:07 -04:00
std : : make_shared < cProtIntGenSmooth > ( a_Seed + 1 ,
2014-10-30 11:24:35 -04:00
std : : make_shared < cProtIntGenZoom > ( a_Seed + 16 ,
std : : make_shared < cProtIntGenBeaches > (
std : : make_shared < cProtIntGenZoom > ( a_Seed + 1 ,
std : : make_shared < cProtIntGenAddIslands > ( a_Seed + 2004 , 10 ,
2014-10-31 07:52:07 -04:00
std : : make_shared < cProtIntGenAddToOcean > ( a_Seed + 10 , 500 , biDeepOcean ,
std : : make_shared < cProtIntGenReplaceRandomly > ( a_Seed + 1 , biPlains , biSunflowerPlains , 20 ,
2014-11-01 16:01:33 -04:00
std : : make_shared < cProtIntGenMBiomes > ( a_Seed + 5 , alteration2 ,
2014-10-31 07:52:07 -04:00
std : : make_shared < cProtIntGenAlternateBiomes > ( a_Seed + 1 , alteration ,
2014-11-01 11:37:56 -04:00
std : : make_shared < cProtIntGenBiomeEdges > ( a_Seed + 3 ,
std : : make_shared < cProtIntGenZoom > ( a_Seed + 2 ,
2014-10-30 11:24:35 -04:00
std : : make_shared < cProtIntGenZoom > ( a_Seed + 4 ,
2014-10-31 07:52:07 -04:00
std : : make_shared < cProtIntGenReplaceRandomly > ( a_Seed + 99 , biIcePlains , biIcePlainsSpikes , 50 ,
2014-10-30 11:24:35 -04:00
std : : make_shared < cProtIntGenZoom > ( a_Seed + 8 ,
2014-10-31 07:52:07 -04:00
std : : make_shared < cProtIntGenAddToOcean > ( a_Seed + 10 , 300 , biDeepOcean ,
std : : make_shared < cProtIntGenAddToOcean > ( a_Seed + 9 , 8 , biMushroomIsland ,
2014-10-30 11:24:35 -04:00
std : : make_shared < cProtIntGenBiomes > ( a_Seed + 3000 ,
2014-10-31 07:52:07 -04:00
std : : make_shared < cProtIntGenAddIslands > ( a_Seed + 2000 , 200 ,
2014-10-30 11:24:35 -04:00
std : : make_shared < cProtIntGenZoom > ( a_Seed + 5 ,
2014-10-31 07:52:07 -04:00
std : : make_shared < cProtIntGenRareBiomeGroups > ( a_Seed + 5 , 50 ,
2014-10-30 11:24:35 -04:00
std : : make_shared < cProtIntGenBiomeGroupEdges > (
2014-10-31 07:52:07 -04:00
std : : make_shared < cProtIntGenAddIslands > ( a_Seed + 2000 , 200 ,
2014-10-30 11:24:35 -04:00
std : : make_shared < cProtIntGenZoom > ( a_Seed + 7 ,
std : : make_shared < cProtIntGenSetRandomly > ( a_Seed + 8 , 50 , bgOcean ,
2014-10-31 07:52:07 -04:00
std : : make_shared < cProtIntGenReplaceRandomly > ( a_Seed + 101 , bgIce , bgTemperate , 150 ,
std : : make_shared < cProtIntGenAddIslands > ( a_Seed + 2000 , 200 ,
2014-10-30 11:24:35 -04:00
std : : make_shared < cProtIntGenSetRandomly > ( a_Seed + 9 , 50 , bgOcean ,
std : : make_shared < cProtIntGenZoom > ( a_Seed + 10 ,
2014-10-31 07:52:07 -04:00
std : : make_shared < cProtIntGenLandOcean > ( a_Seed + 100 , 30
2014-11-01 16:01:33 -04:00
) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ;
2014-10-30 11:24:35 -04:00
m_Gen =
std : : make_shared < cProtIntGenSmooth > ( a_Seed ,
std : : make_shared < cProtIntGenZoom > ( a_Seed ,
std : : make_shared < cProtIntGenSmooth > ( a_Seed ,
std : : make_shared < cProtIntGenZoom > ( a_Seed ,
std : : make_shared < cProtIntGenMixRivers > (
FinalBiomes , FinalRivers
2014-10-31 07:52:07 -04:00
) ) ) ) ) ;
2014-10-30 11:24:35 -04:00
}
2019-09-07 17:02:05 -04:00
virtual void GenBiomes ( cChunkCoords a_ChunkCoords , cChunkDef : : BiomeMap & a_Biomes ) override
2014-10-30 11:24:35 -04:00
{
int vals [ 16 * 16 ] ;
2019-09-07 17:02:05 -04:00
m_Gen - > GetInts ( a_ChunkCoords . m_ChunkX * cChunkDef : : Width , a_ChunkCoords . m_ChunkZ * cChunkDef : : Width , 16 , 16 , vals ) ;
2014-10-30 11:24:35 -04:00
for ( int z = 0 ; z < cChunkDef : : Width ; z + + )
{
for ( int x = 0 ; x < cChunkDef : : Width ; x + + )
{
2015-07-09 13:15:37 -04:00
cChunkDef : : SetBiome ( a_Biomes , x , z , static_cast < EMCSBiome > ( vals [ x + cChunkDef : : Width * z ] ) ) ;
2014-10-30 11:24:35 -04:00
}
}
}
protected :
std : : shared_ptr < cProtIntGen > m_Gen ;
} ;
2014-09-17 17:24:22 -04:00
////////////////////////////////////////////////////////////////////////////////
// cBiomeGen:
2014-10-19 08:01:59 -04:00
cBiomeGenPtr cBiomeGen : : CreateBiomeGen ( cIniFile & a_IniFile , int a_Seed , bool & a_CacheOffByDefault )
2014-09-17 17:24:22 -04:00
{
2019-09-01 15:47:03 -04:00
AString BiomeGenName = a_IniFile . GetValue ( " Generator " , " BiomeGen " ) ;
2014-09-17 17:24:22 -04:00
if ( BiomeGenName . empty ( ) )
{
2019-09-01 15:47:03 -04:00
LOGWARN ( " [Generator] BiomeGen value not set in world.ini, using \" Grown \" . " ) ;
BiomeGenName = " Grown " ;
2014-09-17 17:24:22 -04:00
}
2014-10-20 16:55:07 -04:00
cBiomeGen * res = nullptr ;
2014-09-17 17:24:22 -04:00
a_CacheOffByDefault = false ;
if ( NoCaseCompare ( BiomeGenName , " constant " ) = = 0 )
{
res = new cBioGenConstant ;
a_CacheOffByDefault = true ; // we're generating faster than a cache would retrieve data :)
}
else if ( NoCaseCompare ( BiomeGenName , " checkerboard " ) = = 0 )
{
res = new cBioGenCheckerboard ;
a_CacheOffByDefault = true ; // we're (probably) generating faster than a cache would retrieve data
}
else if ( NoCaseCompare ( BiomeGenName , " voronoi " ) = = 0 )
{
res = new cBioGenVoronoi ( a_Seed ) ;
}
else if ( NoCaseCompare ( BiomeGenName , " distortedvoronoi " ) = = 0 )
{
res = new cBioGenDistortedVoronoi ( a_Seed ) ;
}
else if ( NoCaseCompare ( BiomeGenName , " twolevel " ) = = 0 )
{
res = new cBioGenTwoLevel ( a_Seed ) ;
}
2019-09-01 15:47:03 -04:00
else if ( NoCaseCompare ( BiomeGenName , " multistepmap " ) = = 0 )
2014-10-26 14:58:16 -04:00
{
2019-09-01 15:47:03 -04:00
res = new cBioGenMultiStepMap ( a_Seed ) ;
2014-10-26 14:58:16 -04:00
}
2014-10-30 11:24:35 -04:00
else if ( NoCaseCompare ( BiomeGenName , " grownprot " ) = = 0 )
{
res = new cBioGenProtGrown ( a_Seed ) ;
}
2014-09-17 17:24:22 -04:00
else
{
2019-09-01 15:47:03 -04:00
if ( NoCaseCompare ( BiomeGenName , " grown " ) ! = 0 )
2014-09-17 17:24:22 -04:00
{
2019-09-01 15:47:03 -04:00
LOGWARNING ( " Unknown BiomeGen \" %s \" , using \" Grown \" instead. " , BiomeGenName . c_str ( ) ) ;
2014-09-17 17:24:22 -04:00
}
2019-09-01 15:47:03 -04:00
res = new cBioGenGrown ( a_Seed ) ;
2014-09-17 17:24:22 -04:00
}
res - > InitializeBiomeGen ( a_IniFile ) ;
2014-10-19 08:01:59 -04:00
return cBiomeGenPtr ( res ) ;
2014-09-17 17:24:22 -04:00
}
2014-11-03 04:36:12 -05:00
////////////////////////////////////////////////////////////////////////////////
// Performance tests:
// Change to 1 to enable the perf test:
#if 0
class cBioGenPerfTest
{
public :
cBioGenPerfTest ( )
{
std : : cout < < " BioGen performance tests commencing, please wait... " < < std : : endl ;
TestGen ( " MultiStepMap " , std : : make_unique < cBioGenMultiStepMap > ( 1 ) . get ( ) ) ;
TestGen ( " Grown " , std : : make_unique < cBioGenGrown > ( 1 ) . get ( ) ) ;
TestGen ( " GrownProt " , std : : make_unique < cBioGenProtGrown > ( 1 ) . get ( ) ) ;
std : : cout < < " BioGen performance tests complete. " < < std : : endl ;
}
protected :
void TestGen ( const AString & & a_GenName , cBiomeGen * a_BioGen )
{
// Initialize the default settings for the generator:
cIniFile iniFile ;
a_BioGen - > InitializeBiomeGen ( iniFile ) ;
// Generate the biomes:
auto start = std : : chrono : : system_clock : : now ( ) ;
for ( int z = 0 ; z < 100 ; z + + )
{
for ( int x = 0 ; x < 100 ; x + + )
{
cChunkDef : : BiomeMap biomes ;
a_BioGen - > GenBiomes ( x , z , biomes ) ;
} // for x
} // for z
auto dur = std : : chrono : : system_clock : : now ( ) - start ;
double milliseconds = static_cast < double > ( ( std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( dur ) ) . count ( ) ) ;
std : : cout < < a_GenName < < " : " < < 1000.0 * 100.0 * 100.0 / milliseconds < < " chunks per second " < < std : : endl ;
}
} g_BioGenPerfTest ;
2014-11-03 05:48:03 -05:00
# endif