2012-06-14 09:06:06 -04:00
|
|
|
|
|
|
|
// BioGen.cpp
|
|
|
|
|
|
|
|
// Implements the various biome generators
|
|
|
|
|
|
|
|
#include "Globals.h"
|
|
|
|
#include "BioGen.h"
|
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:
|
|
|
|
|
|
|
|
void cBioGenConstant::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap)
|
|
|
|
{
|
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
|
|
|
{
|
2014-05-31 17:28:51 -04:00
|
|
|
AString Biome = a_IniFile.GetValueSet("Generator", "ConstantBiome", "");
|
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:
|
|
|
|
|
2014-10-19 08:01:59 -04:00
|
|
|
cBioGenCache::cBioGenCache(cBiomeGenPtr a_BioGenToCache, int a_CacheSize) :
|
2012-06-14 09:06:06 -04:00
|
|
|
m_BioGenToCache(a_BioGenToCache),
|
|
|
|
m_CacheSize(a_CacheSize),
|
|
|
|
m_CacheOrder(new int[a_CacheSize]),
|
|
|
|
m_CacheData(new sCacheData[a_CacheSize]),
|
|
|
|
m_NumHits(0),
|
|
|
|
m_NumMisses(0),
|
|
|
|
m_TotalChain(0)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < m_CacheSize; i++)
|
|
|
|
{
|
|
|
|
m_CacheOrder[i] = i;
|
|
|
|
m_CacheData[i].m_ChunkX = 0x7fffffff;
|
|
|
|
m_CacheData[i].m_ChunkZ = 0x7fffffff;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cBioGenCache::~cBioGenCache()
|
|
|
|
{
|
2012-11-15 09:02:17 -05:00
|
|
|
delete[] m_CacheData;
|
2014-10-20 16:55:07 -04:00
|
|
|
m_CacheData = nullptr;
|
2012-11-15 09:02:17 -05:00
|
|
|
delete[] m_CacheOrder;
|
2014-10-20 16:55:07 -04:00
|
|
|
m_CacheOrder = nullptr;
|
2012-06-14 09:06:06 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cBioGenCache::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap)
|
|
|
|
{
|
|
|
|
if (((m_NumHits + m_NumMisses) % 1024) == 10)
|
|
|
|
{
|
|
|
|
LOGD("BioGenCache: %d hits, %d misses, saved %.2f %%", m_NumHits, m_NumMisses, 100.0 * m_NumHits / (m_NumHits + m_NumMisses));
|
|
|
|
LOGD("BioGenCache: Avg cache chain length: %.2f", (float)m_TotalChain / m_NumHits);
|
|
|
|
}
|
2014-09-03 12:48:47 -04:00
|
|
|
|
2012-06-14 09:06:06 -04:00
|
|
|
for (int i = 0; i < m_CacheSize; i++)
|
|
|
|
{
|
|
|
|
if (
|
|
|
|
(m_CacheData[m_CacheOrder[i]].m_ChunkX != a_ChunkX) ||
|
|
|
|
(m_CacheData[m_CacheOrder[i]].m_ChunkZ != a_ChunkZ)
|
|
|
|
)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// Found it in the cache
|
|
|
|
int Idx = m_CacheOrder[i];
|
|
|
|
|
|
|
|
// Move to front:
|
|
|
|
for (int j = i; j > 0; j--)
|
|
|
|
{
|
|
|
|
m_CacheOrder[j] = m_CacheOrder[j - 1];
|
|
|
|
}
|
|
|
|
m_CacheOrder[0] = Idx;
|
|
|
|
|
|
|
|
// Use the cached data:
|
|
|
|
memcpy(a_BiomeMap, m_CacheData[Idx].m_BiomeMap, sizeof(a_BiomeMap));
|
|
|
|
|
|
|
|
m_NumHits++;
|
|
|
|
m_TotalChain += i;
|
|
|
|
return;
|
|
|
|
} // for i - cache
|
|
|
|
|
|
|
|
// Not in the cache:
|
|
|
|
m_NumMisses++;
|
|
|
|
m_BioGenToCache->GenBiomes(a_ChunkX, a_ChunkZ, a_BiomeMap);
|
|
|
|
|
|
|
|
// Insert it as the first item in the MRU order:
|
|
|
|
int Idx = m_CacheOrder[m_CacheSize - 1];
|
|
|
|
for (int i = m_CacheSize - 1; i > 0; i--)
|
|
|
|
{
|
|
|
|
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));
|
|
|
|
m_CacheData[Idx].m_ChunkX = a_ChunkX;
|
|
|
|
m_CacheData[Idx].m_ChunkZ = a_ChunkZ;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cBioGenMulticache::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap)
|
|
|
|
{
|
2014-09-03 12:48:47 -04:00
|
|
|
const size_t coefficient = 3;
|
2014-10-19 08:01:59 -04:00
|
|
|
const size_t cacheIdx = ((size_t)a_ChunkX + coefficient * (size_t)a_ChunkZ) % m_NumSubCaches;
|
2014-09-01 16:33:58 -04:00
|
|
|
|
2014-09-02 04:49:46 -04:00
|
|
|
m_Caches[cacheIdx]->GenBiomes(a_ChunkX, a_ChunkZ, 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)
|
|
|
|
{
|
|
|
|
Count = atol(Split2[1].c_str());
|
|
|
|
if (Count <= 0)
|
|
|
|
{
|
|
|
|
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())
|
|
|
|
{
|
|
|
|
m_BiomesCount = (int)m_Biomes.size();
|
|
|
|
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]);
|
|
|
|
}
|
|
|
|
m_BiomesCount = (int)m_Biomes.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-07-17 16:15:34 -04:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2012-06-14 09:06:06 -04:00
|
|
|
// cBioGenCheckerboard:
|
|
|
|
|
|
|
|
void cBioGenCheckerboard::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap)
|
|
|
|
{
|
|
|
|
for (int z = 0; z < cChunkDef::Width; z++)
|
|
|
|
{
|
2013-11-29 15:45:20 -05:00
|
|
|
int Base = (cChunkDef::Width * a_ChunkZ + z) / m_BiomeSize;
|
2012-06-14 09:06:06 -04:00
|
|
|
for (int x = 0; x < cChunkDef::Width; x++)
|
|
|
|
{
|
|
|
|
int Add = cChunkDef::Width * a_ChunkX + x;
|
2013-11-29 15:45:20 -05:00
|
|
|
int BiomeIdx = (((Base + Add / m_BiomeSize) % m_BiomesCount) + m_BiomesCount) % m_BiomesCount; // Need to add and modulo twice because of negative numbers
|
|
|
|
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 :
|
|
|
|
|
|
|
|
void cBioGenVoronoi::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap)
|
|
|
|
{
|
|
|
|
int BaseZ = cChunkDef::Width * a_ChunkZ;
|
|
|
|
int BaseX = cChunkDef::Width * a_ChunkX;
|
|
|
|
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;
|
|
|
|
cChunkDef::SetBiome(a_BiomeMap, x, z, m_Biomes[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:
|
|
|
|
|
|
|
|
void cBioGenDistortedVoronoi::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap)
|
|
|
|
{
|
|
|
|
int BaseZ = cChunkDef::Width * a_ChunkZ;
|
|
|
|
int BaseX = cChunkDef::Width * a_ChunkX;
|
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]);
|
|
|
|
}
|
|
|
|
|
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]);
|
2012-07-29 16:15:03 -04: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;
|
|
|
|
cChunkDef::SetBiome(a_BiomeMap, x, z, m_Biomes[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
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2012-06-14 09:06:06 -04:00
|
|
|
void cBioGenDistortedVoronoi::Distort(int a_BlockX, int a_BlockZ, int & a_DistortedX, int & a_DistortedZ)
|
|
|
|
{
|
|
|
|
double NoiseX = m_Noise.CubicNoise3D((float)a_BlockX / m_CellSize, (float)a_BlockZ / m_CellSize, 1000);
|
|
|
|
NoiseX += 0.5 * m_Noise.CubicNoise3D(2 * (float)a_BlockX / m_CellSize, 2 * (float)a_BlockZ / m_CellSize, 2000);
|
|
|
|
NoiseX += 0.08 * m_Noise.CubicNoise3D(16 * (float)a_BlockX / m_CellSize, 16 * (float)a_BlockZ / m_CellSize, 3000);
|
|
|
|
double NoiseZ = m_Noise.CubicNoise3D((float)a_BlockX / m_CellSize, (float)a_BlockZ / m_CellSize, 4000);
|
|
|
|
NoiseZ += 0.5 * m_Noise.CubicNoise3D(2 * (float)a_BlockX / m_CellSize, 2 * (float)a_BlockZ / m_CellSize, 5000);
|
|
|
|
NoiseZ += 0.08 * m_Noise.CubicNoise3D(16 * (float)a_BlockX / m_CellSize, 16 * (float)a_BlockZ / m_CellSize, 6000);
|
|
|
|
|
|
|
|
a_DistortedX = a_BlockX + (int)(m_CellSize * 0.5 * NoiseX);
|
|
|
|
a_DistortedZ = a_BlockZ + (int)(m_CellSize * 0.5 * NoiseZ);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
2013-01-24 07:15:36 -05:00
|
|
|
m_LandBiomesSize = (float)a_IniFile.GetValueSetI("Generator", "MultiStepMapLandBiomeSize", (int)m_LandBiomesSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cBioGenMultiStepMap::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap)
|
|
|
|
{
|
|
|
|
DecideOceanLandMushroom(a_ChunkX, a_ChunkZ, a_BiomeMap);
|
|
|
|
AddRivers(a_ChunkX, a_ChunkZ, a_BiomeMap);
|
|
|
|
ApplyTemperatureHumidity(a_ChunkX, a_ChunkZ, a_BiomeMap);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cBioGenMultiStepMap::DecideOceanLandMushroom(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap)
|
|
|
|
{
|
|
|
|
// Distorted Voronoi over 3 biomes, with mushroom having only a special occurence.
|
|
|
|
|
|
|
|
// Prepare a distortion lookup table, by distorting a 5x5 area and using that as 1:4 zoom (linear interpolate):
|
|
|
|
int BaseZ = cChunkDef::Width * a_ChunkZ;
|
|
|
|
int BaseX = cChunkDef::Width * a_ChunkX;
|
|
|
|
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]);
|
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
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cBioGenMultiStepMap::AddRivers(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap)
|
|
|
|
{
|
|
|
|
for (int z = 0; z < cChunkDef::Width; z++)
|
|
|
|
{
|
|
|
|
float NoiseCoordZ = (float)(a_ChunkZ * cChunkDef::Width + z) / m_RiverCellSize;
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
float NoiseCoordX = (float)(a_ChunkX * cChunkDef::Width + x) / m_RiverCellSize;
|
|
|
|
|
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);
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cBioGenMultiStepMap::ApplyTemperatureHumidity(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap)
|
|
|
|
{
|
|
|
|
IntMap TemperatureMap;
|
|
|
|
IntMap HumidityMap;
|
|
|
|
BuildTemperatureHumidityMaps(a_ChunkX, a_ChunkZ, TemperatureMap, HumidityMap);
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2013-04-24 10:35:13 -04:00
|
|
|
double NoiseX = m_Noise3.CubicNoise2D( (float)a_BlockX / a_CellSize, (float)a_BlockZ / a_CellSize);
|
|
|
|
NoiseX += 0.5 * m_Noise2.CubicNoise2D(2 * (float)a_BlockX / a_CellSize, 2 * (float)a_BlockZ / a_CellSize);
|
|
|
|
NoiseX += 0.1 * m_Noise1.CubicNoise2D(16 * (float)a_BlockX / a_CellSize, 16 * (float)a_BlockZ / a_CellSize);
|
|
|
|
double NoiseZ = m_Noise6.CubicNoise2D( (float)a_BlockX / a_CellSize, (float)a_BlockZ / a_CellSize);
|
|
|
|
NoiseZ += 0.5 * m_Noise5.CubicNoise2D(2 * (float)a_BlockX / a_CellSize, 2 * (float)a_BlockZ / a_CellSize);
|
|
|
|
NoiseZ += 0.1 * m_Noise4.CubicNoise2D(16 * (float)a_BlockX / a_CellSize, 16 * (float)a_BlockZ / a_CellSize);
|
2013-01-24 07:15:36 -05:00
|
|
|
|
|
|
|
a_DistortedX = a_BlockX + (int)(a_CellSize * 0.5 * NoiseX);
|
|
|
|
a_DistortedZ = a_BlockZ + (int)(a_CellSize * 0.5 * NoiseZ);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cBioGenMultiStepMap::BuildTemperatureHumidityMaps(int a_ChunkX, int a_ChunkZ, IntMap & a_TemperatureMap, IntMap & a_HumidityMap)
|
|
|
|
{
|
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
|
|
|
{
|
|
|
|
float NoiseCoordZ = (float)(a_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
|
|
|
{
|
|
|
|
float NoiseCoordX = (float)(a_ChunkX * cChunkDef::Width + x) / m_LandBiomesSize;
|
|
|
|
|
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);
|
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
|
|
|
{
|
|
|
|
a_TemperatureMap[idx] = std::max(0, std::min(255, (int)(128 + TemperatureMap[idx] * 128)));
|
|
|
|
a_HumidityMap[idx] = std::max(0, std::min(255, (int)(128 + HumidityMap[idx] * 128)));
|
|
|
|
}
|
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),
|
|
|
|
m_Noise6(a_Seed + 5006)
|
2013-11-28 13:58:20 -05:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cBioGenTwoLevel::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap)
|
|
|
|
{
|
|
|
|
int BaseZ = cChunkDef::Width * a_ChunkZ;
|
|
|
|
int BaseX = cChunkDef::Width * a_ChunkX;
|
|
|
|
|
|
|
|
// 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);
|
2013-11-28 13:58:20 -05:00
|
|
|
|
2014-09-27 16:01:47 -04:00
|
|
|
DistortX[4 * x][4 * z] = (int)(BlockX + NoiseX);
|
|
|
|
DistortZ[4 * x][4 * z] = (int)(BlockZ + NoiseZ);
|
2013-11-28 13:58:20 -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]);
|
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;
|
|
|
|
int BiomeIdx = m_VoronoiSmall.GetValueAt(DistortX[x][z], DistortZ[x][z], SeedX, SeedZ, MinDist2) / 11;
|
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
EMCSBiome cBioGenTwoLevel::SelectBiome(int a_BiomeGroup, int a_BiomeIdx, int a_DistLevel)
|
|
|
|
{
|
|
|
|
// TODO: Move this into settings
|
|
|
|
struct BiomeLevels
|
|
|
|
{
|
|
|
|
EMCSBiome InnerBiome;
|
|
|
|
EMCSBiome OuterBiome;
|
|
|
|
} ;
|
|
|
|
|
|
|
|
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), },
|
|
|
|
} ;
|
|
|
|
size_t Group = a_BiomeGroup % ARRAYCOUNT(BiomeGroups);
|
|
|
|
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));
|
2014-09-27 16:01:47 -04:00
|
|
|
m_FreqX1 = (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortXOctave1Freq", 0.01);
|
|
|
|
m_AmpX1 = (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortXOctave1Amp", 80);
|
|
|
|
m_FreqX2 = (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortXOctave2Freq", 0.05);
|
|
|
|
m_AmpX2 = (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortXOctave2Amp", 20);
|
|
|
|
m_FreqX3 = (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortXOctave3Freq", 0.1),
|
|
|
|
m_AmpX3 = (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortXOctave3Amp", 8);
|
|
|
|
m_FreqZ1 = (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortZOctave1Freq", 0.01);
|
|
|
|
m_AmpZ1 = (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortZOctave1Amp", 80);
|
|
|
|
m_FreqZ2 = (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortZOctave2Freq", 0.05);
|
|
|
|
m_AmpZ2 = (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortZOctave2Amp", 20);
|
|
|
|
m_FreqZ3 = (float)a_IniFile.GetValueSetF("Generator", "TwoLevelDistortZOctave3Freq", 0.1);
|
|
|
|
m_AmpZ3 = (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 =
|
2014-10-30 11:24:35 -04:00
|
|
|
std::make_shared<cIntGenSmooth<6>> (a_Seed + 1,
|
|
|
|
std::make_shared<cIntGenZoom <8>> (a_Seed + 3,
|
|
|
|
std::make_shared<cIntGenRiver <6>> (a_Seed + 2,
|
2014-10-26 14:58:16 -04:00
|
|
|
std::make_shared<cIntGenSmooth<8>> (a_Seed + 4,
|
|
|
|
std::make_shared<cIntGenZoom <10>> (a_Seed + 5,
|
|
|
|
std::make_shared<cIntGenZoom <7>> (a_Seed + 6,
|
|
|
|
std::make_shared<cIntGenZoom <5>> (a_Seed + 7,
|
|
|
|
std::make_shared<cIntGenZoom <4>> (a_Seed + 8,
|
|
|
|
std::make_shared<cIntGenZoom <4>> (a_Seed + 9,
|
|
|
|
std::make_shared<cIntGenZoom <4>> (a_Seed + 10,
|
|
|
|
std::make_shared<cIntGenZoom <4>> (a_Seed + 11,
|
|
|
|
std::make_shared<cIntGenChoice<2, 4>>(a_Seed + 12
|
|
|
|
))))))))))));
|
|
|
|
|
|
|
|
auto FinalBiomes =
|
2014-10-30 11:24:35 -04:00
|
|
|
std::make_shared<cIntGenSmooth <6>> (a_Seed + 1008,
|
|
|
|
std::make_shared<cIntGenZoom <8>>(a_Seed + 15,
|
|
|
|
std::make_shared<cIntGenSmooth <6>> (a_Seed + 1000,
|
|
|
|
std::make_shared<cIntGenZoom <8>> (a_Seed + 16,
|
2014-10-26 14:58:16 -04:00
|
|
|
std::make_shared<cIntGenBeaches <6>> (
|
|
|
|
std::make_shared<cIntGenSmooth <8>> (a_Seed + 1002,
|
2014-10-29 10:28:27 -04:00
|
|
|
std::make_shared<cIntGenZoom <10>>(a_Seed + 1,
|
|
|
|
std::make_shared<cIntGenSmooth <7>> (a_Seed + 1002,
|
|
|
|
std::make_shared<cIntGenZoom <9>> (a_Seed + 2,
|
|
|
|
std::make_shared<cIntGenAddIslands <6>> (a_Seed + 2004, 10,
|
|
|
|
std::make_shared<cIntGenZoom <6>> (a_Seed + 4,
|
2014-10-30 11:24:35 -04:00
|
|
|
std::make_shared<cIntGenAddToOcean <5>> (a_Seed + 9, 10, biMushroomIsland,
|
|
|
|
std::make_shared<cIntGenReplaceRandomly<7>> (biIcePlains, biIcePlainsSpikes, 5, a_Seed + 99,
|
2014-10-29 10:28:27 -04:00
|
|
|
std::make_shared<cIntGenZoom <7>> (a_Seed + 8,
|
2014-10-26 14:58:16 -04:00
|
|
|
std::make_shared<cIntGenAddToOcean <5>> (a_Seed + 10, 500, biDeepOcean,
|
|
|
|
std::make_shared<cIntGenBiomes <7>> (a_Seed + 3000,
|
|
|
|
std::make_shared<cIntGenZoom <7>> (a_Seed + 5,
|
|
|
|
std::make_shared<cIntGenBiomeGroupEdges<5>> (
|
|
|
|
std::make_shared<cIntGenSmooth <7>> (a_Seed + 1003,
|
|
|
|
std::make_shared<cIntGenZoom <9>> (a_Seed + 7,
|
2014-10-30 11:24:35 -04:00
|
|
|
std::make_shared<cIntGenSetRandomly <6>> (a_Seed + 8, 50, bgOcean,
|
2014-10-26 14:58:16 -04:00
|
|
|
std::make_shared<cIntGenReplaceRandomly<6>> (bgIce, bgTemperate, 50, a_Seed + 101,
|
|
|
|
std::make_shared<cIntGenAddIslands <6>> (a_Seed + 2000, 70,
|
2014-10-30 11:24:35 -04:00
|
|
|
std::make_shared<cIntGenSetRandomly <6>> (a_Seed + 9, 50, bgOcean,
|
2014-10-26 14:58:16 -04:00
|
|
|
std::make_shared<cIntGenSmooth <6>> (a_Seed + 1004,
|
|
|
|
std::make_shared<cIntGenZoom <8>> (a_Seed + 10,
|
2014-10-26 17:56:02 -04:00
|
|
|
std::make_shared<cIntGenLandOcean <6>> (a_Seed + 100, 65
|
2014-10-31 07:52:07 -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-10-30 11:24:35 -04:00
|
|
|
std::make_shared<cIntGenZoom <11>>(a_Seed,
|
|
|
|
std::make_shared<cIntGenSmooth <7>>(a_Seed,
|
|
|
|
std::make_shared<cIntGenZoom <9>>(a_Seed,
|
|
|
|
std::make_shared<cIntGenMixRivers<6>> (
|
2014-10-26 14:58:16 -04:00
|
|
|
FinalBiomes, FinalRivers
|
2014-10-30 11:24:35 -04:00
|
|
|
))))));
|
2014-10-26 14:58:16 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_Biomes) override
|
|
|
|
{
|
|
|
|
cIntGen<16, 16>::Values vals;
|
|
|
|
m_Gen->GetInts(a_ChunkX * cChunkDef::Width, a_ChunkZ * cChunkDef::Width, vals);
|
|
|
|
for (int z = 0; z < cChunkDef::Width; z++)
|
|
|
|
{
|
|
|
|
for (int x = 0; x < cChunkDef::Width; x++)
|
|
|
|
{
|
|
|
|
cChunkDef::SetBiome(a_Biomes, x, z, (EMCSBiome)vals[x + cChunkDef::Width * z]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// cBioGenGrown:
|
|
|
|
|
|
|
|
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,
|
|
|
|
std::make_shared<cProtIntGenSmooth>(a_Seed + 5,
|
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
|
|
|
|
|
|
|
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,
|
|
|
|
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 11:37:56 -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
|
|
|
}
|
|
|
|
|
|
|
|
virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_Biomes) override
|
|
|
|
{
|
|
|
|
int vals[16 * 16];
|
|
|
|
m_Gen->GetInts(a_ChunkX * cChunkDef::Width, a_ChunkZ * cChunkDef::Width, 16, 16, vals);
|
|
|
|
for (int z = 0; z < cChunkDef::Width; z++)
|
|
|
|
{
|
|
|
|
for (int x = 0; x < cChunkDef::Width; x++)
|
|
|
|
{
|
|
|
|
cChunkDef::SetBiome(a_Biomes, x, z, (EMCSBiome)vals[x + cChunkDef::Width * z]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
{
|
|
|
|
AString BiomeGenName = a_IniFile.GetValueSet("Generator", "BiomeGen", "");
|
|
|
|
if (BiomeGenName.empty())
|
|
|
|
{
|
|
|
|
LOGWARN("[Generator] BiomeGen value not set in world.ini, using \"MultiStepMap\".");
|
|
|
|
BiomeGenName = "MultiStepMap";
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
}
|
2014-10-26 14:58:16 -04:00
|
|
|
else if (NoCaseCompare(BiomeGenName, "grown") == 0)
|
|
|
|
{
|
|
|
|
res = new cBioGenGrown(a_Seed);
|
|
|
|
}
|
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
|
|
|
|
{
|
|
|
|
if (NoCaseCompare(BiomeGenName, "multistepmap") != 0)
|
|
|
|
{
|
|
|
|
LOGWARNING("Unknown BiomeGen \"%s\", using \"MultiStepMap\" instead.", BiomeGenName.c_str());
|
|
|
|
}
|
|
|
|
res = new cBioGenMultiStepMap(a_Seed);
|
|
|
|
|
|
|
|
/*
|
|
|
|
// Performance-testing:
|
|
|
|
LOGINFO("Measuring performance of cBioGenMultiStepMap...");
|
|
|
|
clock_t BeginTick = clock();
|
|
|
|
for (int x = 0; x < 5000; x++)
|
|
|
|
{
|
|
|
|
cChunkDef::BiomeMap Biomes;
|
|
|
|
res->GenBiomes(x * 5, x * 5, Biomes);
|
|
|
|
}
|
|
|
|
clock_t Duration = clock() - BeginTick;
|
|
|
|
LOGINFO("cBioGenMultiStepMap for 5000 chunks took %d ticks (%.02f sec)", Duration, (double)Duration / CLOCKS_PER_SEC);
|
|
|
|
//*/
|
|
|
|
}
|
|
|
|
res->InitializeBiomeGen(a_IniFile);
|
|
|
|
|
2014-10-19 08:01:59 -04:00
|
|
|
return cBiomeGenPtr(res);
|
2014-09-17 17:24:22 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|