Added new biomegen: Grown
This commit is contained in:
parent
ec8c050666
commit
7e1d603080
@ -14,6 +14,7 @@ static const QString s_GeneratorNames[] =
|
||||
QString("Checkerboard"),
|
||||
QString("Constant"),
|
||||
QString("DistortedVoronoi"),
|
||||
QString("Grown"),
|
||||
QString("MultiStepMap"),
|
||||
QString("TwoLevel"),
|
||||
QString("Voronoi"),
|
||||
|
@ -13,75 +13,76 @@ TEMPLATE = app
|
||||
|
||||
|
||||
SOURCES +=\
|
||||
MainWindow.cpp \
|
||||
BiomeView.cpp \
|
||||
../../src/Generating/BioGen.cpp \
|
||||
../../src/VoronoiMap.cpp \
|
||||
../../src/Noise.cpp \
|
||||
../../src/StringUtils.cpp \
|
||||
../../src/LoggerListeners.cpp \
|
||||
../../src/Logger.cpp \
|
||||
../../src/IniFile.cpp \
|
||||
../../src/OSSupport/File.cpp \
|
||||
../../src/OSSupport/CriticalSection.cpp \
|
||||
../../src/OSSupport/IsThread.cpp \
|
||||
../../src/BiomeDef.cpp \
|
||||
ChunkCache.cpp \
|
||||
ChunkSource.cpp \
|
||||
ChunkLoader.cpp \
|
||||
../../src/StringCompression.cpp \
|
||||
../../src/WorldStorage/FastNBT.cpp \
|
||||
../../lib/zlib/adler32.c \
|
||||
../../lib/zlib/compress.c \
|
||||
../../lib/zlib/crc32.c \
|
||||
../../lib/zlib/deflate.c \
|
||||
../../lib/zlib/gzclose.c \
|
||||
../../lib/zlib/gzlib.c \
|
||||
../../lib/zlib/gzread.c \
|
||||
../../lib/zlib/gzwrite.c \
|
||||
../../lib/zlib/infback.c \
|
||||
../../lib/zlib/inffast.c \
|
||||
../../lib/zlib/inflate.c \
|
||||
../../lib/zlib/inftrees.c \
|
||||
../../lib/zlib/trees.c \
|
||||
../../lib/zlib/uncompr.c \
|
||||
../../lib/zlib/zutil.c \
|
||||
GeneratorSetup.cpp \
|
||||
QtBiomeVisualiser.cpp \
|
||||
QtChunk.cpp
|
||||
MainWindow.cpp \
|
||||
BiomeView.cpp \
|
||||
../../src/Generating/BioGen.cpp \
|
||||
../../src/VoronoiMap.cpp \
|
||||
../../src/Noise.cpp \
|
||||
../../src/StringUtils.cpp \
|
||||
../../src/LoggerListeners.cpp \
|
||||
../../src/Logger.cpp \
|
||||
../../src/IniFile.cpp \
|
||||
../../src/OSSupport/File.cpp \
|
||||
../../src/OSSupport/CriticalSection.cpp \
|
||||
../../src/OSSupport/IsThread.cpp \
|
||||
../../src/BiomeDef.cpp \
|
||||
ChunkCache.cpp \
|
||||
ChunkSource.cpp \
|
||||
ChunkLoader.cpp \
|
||||
../../src/StringCompression.cpp \
|
||||
../../src/WorldStorage/FastNBT.cpp \
|
||||
../../lib/zlib/adler32.c \
|
||||
../../lib/zlib/compress.c \
|
||||
../../lib/zlib/crc32.c \
|
||||
../../lib/zlib/deflate.c \
|
||||
../../lib/zlib/gzclose.c \
|
||||
../../lib/zlib/gzlib.c \
|
||||
../../lib/zlib/gzread.c \
|
||||
../../lib/zlib/gzwrite.c \
|
||||
../../lib/zlib/infback.c \
|
||||
../../lib/zlib/inffast.c \
|
||||
../../lib/zlib/inflate.c \
|
||||
../../lib/zlib/inftrees.c \
|
||||
../../lib/zlib/trees.c \
|
||||
../../lib/zlib/uncompr.c \
|
||||
../../lib/zlib/zutil.c \
|
||||
GeneratorSetup.cpp \
|
||||
QtBiomeVisualiser.cpp \
|
||||
QtChunk.cpp
|
||||
|
||||
HEADERS += MainWindow.h \
|
||||
Globals.h \
|
||||
BiomeView.h \
|
||||
../../src/Generating/BioGen.h \
|
||||
../../src/VoronoiMap.h \
|
||||
../../src/Noise.h \
|
||||
../../src/StringUtils.h \
|
||||
../../src/LoggerListeners.h \
|
||||
../../src/Logger.h \
|
||||
../../src/IniFile.h \
|
||||
../../src/OSSupport/File.h \
|
||||
../../src/OSSupport/CriticalSection.h \
|
||||
../../src/OSSupport/IsThread.h \
|
||||
../../src/BiomeDef.h \
|
||||
ChunkCache.h \
|
||||
ChunkSource.h \
|
||||
ChunkLoader.h \
|
||||
../../src/StringCompression.h \
|
||||
../../src/WorldStorage/FastNBT.h \
|
||||
../../lib/zlib/crc32.h \
|
||||
../../lib/zlib/deflate.h \
|
||||
../../lib/zlib/gzguts.h \
|
||||
../../lib/zlib/inffast.h \
|
||||
../../lib/zlib/inffixed.h \
|
||||
../../lib/zlib/inflate.h \
|
||||
../../lib/zlib/inftrees.h \
|
||||
../../lib/zlib/trees.h \
|
||||
../../lib/zlib/zconf.h \
|
||||
../../lib/zlib/zlib.h \
|
||||
../../lib/zlib/zutil.h \
|
||||
GeneratorSetup.h \
|
||||
QtChunk.h
|
||||
Globals.h \
|
||||
BiomeView.h \
|
||||
../../src/Generating/BioGen.h \
|
||||
../../src/Generating/IntGen.h \
|
||||
../../src/VoronoiMap.h \
|
||||
../../src/Noise.h \
|
||||
../../src/StringUtils.h \
|
||||
../../src/LoggerListeners.h \
|
||||
../../src/Logger.h \
|
||||
../../src/IniFile.h \
|
||||
../../src/OSSupport/File.h \
|
||||
../../src/OSSupport/CriticalSection.h \
|
||||
../../src/OSSupport/IsThread.h \
|
||||
../../src/BiomeDef.h \
|
||||
ChunkCache.h \
|
||||
ChunkSource.h \
|
||||
ChunkLoader.h \
|
||||
../../src/StringCompression.h \
|
||||
../../src/WorldStorage/FastNBT.h \
|
||||
../../lib/zlib/crc32.h \
|
||||
../../lib/zlib/deflate.h \
|
||||
../../lib/zlib/gzguts.h \
|
||||
../../lib/zlib/inffast.h \
|
||||
../../lib/zlib/inffixed.h \
|
||||
../../lib/zlib/inflate.h \
|
||||
../../lib/zlib/inftrees.h \
|
||||
../../lib/zlib/trees.h \
|
||||
../../lib/zlib/zconf.h \
|
||||
../../lib/zlib/zlib.h \
|
||||
../../lib/zlib/zutil.h \
|
||||
GeneratorSetup.h \
|
||||
QtChunk.h
|
||||
|
||||
INCLUDEPATH += $$_PRO_FILE_PWD_ \
|
||||
$$_PRO_FILE_PWD_/../../lib \
|
||||
|
@ -113,6 +113,12 @@ extern AString BiomeToString(int a_Biome);
|
||||
/** Returns true if the biome has no downfall - deserts and savannas */
|
||||
extern bool IsBiomeNoDownfall(EMCSBiome a_Biome);
|
||||
|
||||
/** Returns true if the biome is an ocean biome. */
|
||||
inline bool IsBiomeOcean(int a_Biome)
|
||||
{
|
||||
return ((a_Biome == biOcean) || (a_Biome == biDeepOcean));
|
||||
}
|
||||
|
||||
/** Returns true if the biome is very cold
|
||||
(has snow on ground everywhere, turns top water to ice, has snowfall instead of rain everywhere).
|
||||
Doesn't report mildly cold biomes (where it snows above certain elevation), use IsBiomeCold() for those. */
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "Globals.h"
|
||||
#include "BioGen.h"
|
||||
#include "IntGen.h"
|
||||
#include "../IniFile.h"
|
||||
#include "../LinearUpscale.h"
|
||||
|
||||
@ -916,6 +917,94 @@ void cBioGenTwoLevel::InitializeBiomeGen(cIniFile & a_IniFile)
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cBioGenGrown:
|
||||
|
||||
class cBioGenGrown:
|
||||
public cBiomeGen
|
||||
{
|
||||
public:
|
||||
cBioGenGrown(int a_Seed)
|
||||
{
|
||||
auto FinalRivers =
|
||||
std::make_shared<cIntGenSmooth<8>> (a_Seed + 1,
|
||||
std::make_shared<cIntGenRiver <10>> (a_Seed + 2,
|
||||
std::make_shared<cIntGenZoom <12>> (a_Seed + 3,
|
||||
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 =
|
||||
std::make_shared<cIntGenSmooth <8>> (a_Seed + 1008,
|
||||
std::make_shared<cIntGenZoom <10>>(a_Seed + 15,
|
||||
std::make_shared<cIntGenSmooth <7>> (a_Seed + 1000,
|
||||
std::make_shared<cIntGenZoom <9>> (a_Seed + 16,
|
||||
std::make_shared<cIntGenSmooth <6>> (a_Seed + 1001,
|
||||
std::make_shared<cIntGenZoom <8>> (a_Seed,
|
||||
std::make_shared<cIntGenSmooth <6>> (a_Seed + 1002,
|
||||
std::make_shared<cIntGenZoom <8>> (a_Seed + 1,
|
||||
std::make_shared<cIntGenBeaches <6>> (
|
||||
std::make_shared<cIntGenSmooth <8>> (a_Seed + 1002,
|
||||
std::make_shared<cIntGenZoom <10>>(a_Seed + 2,
|
||||
std::make_shared<cIntGenZoom <7>> (a_Seed + 3,
|
||||
std::make_shared<cIntGenAddIslands <5>> (a_Seed + 2004, 10,
|
||||
std::make_shared<cIntGenZoom <5>> (a_Seed + 4,
|
||||
std::make_shared<cIntGenAddToOcean <4>> (a_Seed + 9, 50, biMushroomIsland,
|
||||
std::make_shared<cIntGenZoom <6>> (a_Seed + 8,
|
||||
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,
|
||||
std::make_shared<cIntGenReplaceRandomly<6>> (bgJungle, bgTemperate, 50, a_Seed + 100,
|
||||
std::make_shared<cIntGenReplaceRandomly<6>> (bgIce, bgTemperate, 50, a_Seed + 101,
|
||||
std::make_shared<cIntGenAddIslands <6>> (a_Seed + 2000, 70,
|
||||
std::make_shared<cIntGenSmooth <6>> (a_Seed + 1004,
|
||||
std::make_shared<cIntGenZoom <8>> (a_Seed + 10,
|
||||
std::make_shared<cIntGenAddIslands <6>> (a_Seed + 2003, 50,
|
||||
std::make_shared<cIntGenZoom <6>> (a_Seed + 11,
|
||||
std::make_shared<cIntLandOcean <5>> (a_Seed + 100, 65
|
||||
))))))))))))))))))))))))))))));
|
||||
|
||||
m_Gen =
|
||||
std::make_shared<cIntGenSmooth <16>>(a_Seed,
|
||||
std::make_shared<cIntGenZoom <18>>(a_Seed,
|
||||
std::make_shared<cIntGenSmooth <11>>(a_Seed,
|
||||
std::make_shared<cIntGenZoom <13>>(a_Seed,
|
||||
std::make_shared<cIntGenMixRivers<8>> (
|
||||
FinalBiomes, FinalRivers
|
||||
)))));
|
||||
}
|
||||
|
||||
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:
|
||||
cIntGenPtr<16, 16> m_Gen;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cBiomeGen:
|
||||
|
||||
@ -952,6 +1041,10 @@ cBiomeGenPtr cBiomeGen::CreateBiomeGen(cIniFile & a_IniFile, int a_Seed, bool &
|
||||
{
|
||||
res = new cBioGenTwoLevel(a_Seed);
|
||||
}
|
||||
else if (NoCaseCompare(BiomeGenName, "grown") == 0)
|
||||
{
|
||||
res = new cBioGenGrown(a_Seed);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NoCaseCompare(BiomeGenName, "multistepmap") != 0)
|
||||
|
954
src/Generating/IntGen.h
Normal file
954
src/Generating/IntGen.h
Normal file
@ -0,0 +1,954 @@
|
||||
|
||||
// IntGen.h
|
||||
|
||||
// Declares the cIntGen class and descendants for generating and filtering various 2D arrays of ints
|
||||
|
||||
/*
|
||||
The integers generated may be interpreted in several ways:
|
||||
- land/see designators
|
||||
- 0 = ocean
|
||||
- >0 = land
|
||||
- biome group designators
|
||||
- 0 = ocean
|
||||
- 1 = desert biomes
|
||||
- 2 = temperate biomes
|
||||
- 3 = mountains (hills and forests)
|
||||
- 4 = jungle
|
||||
- 5 = ice biomes
|
||||
- biome IDs
|
||||
The interpretation depends on the generator used and on the position in the chain.
|
||||
|
||||
The generators can be chained together - one produces data that another one consumes.
|
||||
Some of such chain connections require changing the data dimensions between the two, which is handled automatically
|
||||
by using templates.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../BiomeDef.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Constants representing the biome group designators. */
|
||||
const int bgOcean = 0;
|
||||
const int bgDesert = 1;
|
||||
const int bgTemperate = 2;
|
||||
const int bgMountains = 3;
|
||||
const int bgJungle = 4;
|
||||
const int bgIce = 5;
|
||||
const int bgMax = 5; // Maximum biome group value
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Interface that all the generator classes provide. */
|
||||
template <int SizeX, int SizeZ = SizeX>
|
||||
class cIntGen
|
||||
{
|
||||
public:
|
||||
/** Holds the array of values generated by this class (descendant). */
|
||||
typedef int Values[SizeX * SizeZ];
|
||||
|
||||
/** Generates the array of templated size into a_Values, based on given min coords. */
|
||||
virtual void GetInts(int a_MinX, int a_MinZ, Values & a_Values) = 0;
|
||||
};
|
||||
|
||||
template <int SizeX, int SizeZ = SizeX>
|
||||
using cIntGenPtr = std::shared_ptr<cIntGen<SizeX, SizeZ>>;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Provides additional cNoise member and its helper functions. */
|
||||
template <int SizeX, int SizeZ = SizeX>
|
||||
class cIntGenWithNoise :
|
||||
public cIntGen<SizeX, SizeZ>
|
||||
{
|
||||
typedef cIntGen<SizeX, SizeZ> super;
|
||||
|
||||
public:
|
||||
cIntGenWithNoise(int a_Seed) :
|
||||
m_Noise(a_Seed)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
cNoise m_Noise;
|
||||
|
||||
/** Chooses one of a_Val1 or a_Val2, based on m_Noise and the coordinates for querying the noise. */
|
||||
int ChooseRandomOne(int a_RndX, int a_RndZ, int a_Val1, int a_Val2)
|
||||
{
|
||||
int rnd = m_Noise.IntNoise2DInt(a_RndX, a_RndZ) / 7;
|
||||
return ((rnd & 1) == 0) ? a_Val1 : a_Val2;
|
||||
}
|
||||
|
||||
/** Chooses one of a_ValN, based on m_Noise and the coordinates for querying the noise. */
|
||||
int ChooseRandomOne(int a_RndX, int a_RndZ, int a_Val1, int a_Val2, int a_Val3, int a_Val4)
|
||||
{
|
||||
int rnd = m_Noise.IntNoise2DInt(a_RndX, a_RndZ) / 7;
|
||||
switch (rnd % 4)
|
||||
{
|
||||
case 0: return a_Val1;
|
||||
case 1: return a_Val2;
|
||||
case 2: return a_Val3;
|
||||
default: return a_Val4;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Generates a 2D array of random integers in the specified range [0 .. Range). */
|
||||
template <int Range, int SizeX, int SizeZ = SizeX>
|
||||
class cIntGenChoice :
|
||||
public cIntGenWithNoise<SizeX, SizeZ>
|
||||
{
|
||||
typedef cIntGenWithNoise<SizeX, SizeZ> super;
|
||||
|
||||
public:
|
||||
cIntGenChoice(int a_Seed) :
|
||||
super(a_Seed)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
virtual void GetInts(int a_MinX, int a_MinZ, Values & a_Values) override
|
||||
{
|
||||
for (int z = 0; z < SizeZ; z++)
|
||||
{
|
||||
int BaseZ = a_MinZ + z;
|
||||
for (int x = 0; x < SizeX; x++)
|
||||
{
|
||||
a_Values[x + SizeX * z] = (m_Noise.IntNoise2DInt(a_MinX + x, BaseZ) / 7) % Range;
|
||||
}
|
||||
} // for z
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Decides between the ocean and landmass biomes.
|
||||
Has a threshold (in percent) of how much land, the larger the threshold, the more land.
|
||||
Generates 0 for ocean, biome group ID for landmass. */
|
||||
template <int SizeX, int SizeZ = SizeX>
|
||||
class cIntLandOcean :
|
||||
public cIntGenWithNoise<SizeX, SizeZ>
|
||||
{
|
||||
typedef cIntGenWithNoise<SizeX, SizeZ> super;
|
||||
|
||||
public:
|
||||
cIntLandOcean(int a_Seed, int a_Threshold) :
|
||||
super(a_Seed),
|
||||
m_Threshold(a_Threshold)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
virtual void GetInts(int a_MinX, int a_MinZ, Values & a_Values) override
|
||||
{
|
||||
for (int z = 0; z < SizeZ; z++)
|
||||
{
|
||||
int BaseZ = a_MinZ + z;
|
||||
for (int x = 0; x < SizeX; x++)
|
||||
{
|
||||
int rnd = (m_Noise.IntNoise2DInt(a_MinX + x, BaseZ) / 7);
|
||||
a_Values[x + SizeX * z] = ((rnd % 100) < m_Threshold) ? ((rnd / 128) % bgMax + 1) : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
int m_Threshold;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template <int SizeX, int SizeZ = SizeX>
|
||||
class cIntGenZoom :
|
||||
public cIntGenWithNoise<SizeX, SizeZ>
|
||||
{
|
||||
typedef cIntGenWithNoise<SizeX, SizeZ> super;
|
||||
|
||||
protected:
|
||||
static const int m_LowerSizeX = (SizeX / 2) + 2;
|
||||
static const int m_LowerSizeZ = (SizeZ / 2) + 2;
|
||||
|
||||
public:
|
||||
typedef cIntGenPtr<m_LowerSizeX, m_LowerSizeZ> Underlying;
|
||||
|
||||
|
||||
cIntGenZoom(int a_Seed, Underlying a_UnderlyingGen) :
|
||||
super(a_Seed),
|
||||
m_UnderlyingGen(a_UnderlyingGen)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
virtual void GetInts(int a_MinX, int a_MinZ, Values & a_Values) override
|
||||
{
|
||||
// Generate the underlying data with half the resolution:
|
||||
int lowerMinX = a_MinX >> 1;
|
||||
int lowerMinZ = a_MinZ >> 1;
|
||||
int Underlying[m_LowerSizeX * m_LowerSizeZ];
|
||||
m_UnderlyingGen->GetInts(lowerMinX, lowerMinZ, Underlying);
|
||||
const int lowStepX = (m_LowerSizeX - 1) * 2;
|
||||
const int lowStepZ = (m_LowerSizeZ - 1) * 2;
|
||||
int Cache[lowStepX * lowStepZ];
|
||||
|
||||
// Discreet-interpolate the values into twice the size:
|
||||
for (int z = 0; z < m_LowerSizeZ - 1; ++z)
|
||||
{
|
||||
int idx = (z * 2) * lowStepX;
|
||||
int PrevZ0 = Underlying[z * m_LowerSizeX];
|
||||
int PrevZ1 = Underlying[(z + 1) * m_LowerSizeX];
|
||||
|
||||
for (int x = 0; x < m_LowerSizeX - 1; ++x)
|
||||
{
|
||||
int ValX1Z0 = Underlying[x + 1 + z * m_LowerSizeX];
|
||||
int ValX1Z1 = Underlying[x + 1 + (z + 1) * m_LowerSizeX];
|
||||
int RndX = (x + lowerMinX) * 2;
|
||||
int RndZ = (z + lowerMinZ) * 2;
|
||||
Cache[idx] = PrevZ0;
|
||||
Cache[idx + lowStepX] = ChooseRandomOne(RndX, RndZ, PrevZ0, PrevZ1);
|
||||
idx++;
|
||||
Cache[idx] = ChooseRandomOne(RndX, RndZ, PrevZ0, ValX1Z0);
|
||||
Cache[idx + lowStepX] = ChooseRandomOne(RndX, RndZ, PrevZ0, ValX1Z0, PrevZ1, ValX1Z1);
|
||||
idx++;
|
||||
PrevZ0 = ValX1Z0;
|
||||
PrevZ1 = ValX1Z1;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy from Cache into a_Values; take into account the even/odd offsets in a_Min:
|
||||
for (int z = 0; z < SizeZ; ++z)
|
||||
{
|
||||
memcpy(a_Values + z * SizeX, Cache + (z + (a_MinZ & 1)) * lowStepX + (a_MinX & 1), SizeX * sizeof(int));
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
Underlying m_UnderlyingGen;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template <int SizeX, int SizeZ = SizeX>
|
||||
class cIntGenSmooth :
|
||||
public cIntGenWithNoise<SizeX, SizeZ>
|
||||
{
|
||||
typedef cIntGenWithNoise<SizeX, SizeZ> super;
|
||||
static const int m_UnderlyingSizeX = SizeX + 2;
|
||||
static const int m_UnderlyingSizeZ = SizeZ + 2;
|
||||
|
||||
public:
|
||||
typedef cIntGenPtr<m_UnderlyingSizeX, m_UnderlyingSizeZ> Underlying;
|
||||
|
||||
|
||||
cIntGenSmooth(int a_Seed, Underlying a_Underlying) :
|
||||
super(a_Seed),
|
||||
m_Underlying(a_Underlying)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
virtual void GetInts(int a_MinX, int a_MinZ, Values & a_Values) override
|
||||
{
|
||||
// Generate the underlying values:
|
||||
int Cache[(SizeX + 2) * (SizeZ + 2)];
|
||||
m_Underlying->GetInts(a_MinX - 1, a_MinZ - 1, Cache);
|
||||
|
||||
// Smooth - for each square check if the surroundings are the same, if so, expand them diagonally.
|
||||
// Also get rid of single-pixel irregularities (A-B-A):
|
||||
for (int z = 0; z < SizeZ; z++)
|
||||
{
|
||||
int NoiseZ = a_MinZ + z;
|
||||
for (int x = 0; x < SizeX; x++)
|
||||
{
|
||||
int val = Cache[x + 1 + (z + 1) * m_UnderlyingSizeX];
|
||||
int Above = Cache[x + 1 + z * m_UnderlyingSizeX];
|
||||
int Below = Cache[x + 1 + (z + 2) * m_UnderlyingSizeX];
|
||||
int Left = Cache[x + (z + 1) * m_UnderlyingSizeX];
|
||||
int Right = Cache[x + 2 + (z + 1) * m_UnderlyingSizeX];
|
||||
|
||||
if ((Left == Right) && (Above == Below))
|
||||
{
|
||||
if (((m_Noise.IntNoise2DInt(a_MinX + x, NoiseZ) / 7) % 2) == 0)
|
||||
{
|
||||
val = Left;
|
||||
}
|
||||
else
|
||||
{
|
||||
val = Above;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Left == Right)
|
||||
{
|
||||
val = Left;
|
||||
}
|
||||
|
||||
if (Above == Below)
|
||||
{
|
||||
val = Above;
|
||||
}
|
||||
}
|
||||
|
||||
a_Values[x + z * SizeX] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
Underlying m_Underlying;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template<int SizeX, int SizeZ = SizeX>
|
||||
class cIntGenBeaches :
|
||||
public cIntGen<SizeX, SizeZ>
|
||||
{
|
||||
typedef cIntGen<SizeX, SizeZ> super;
|
||||
static const int m_UnderlyingSizeX = SizeX + 2;
|
||||
static const int m_UnderlyingSizeZ = SizeZ + 2;
|
||||
|
||||
public:
|
||||
typedef cIntGenPtr<m_UnderlyingSizeX, m_UnderlyingSizeZ> Underlying;
|
||||
|
||||
|
||||
cIntGenBeaches(Underlying a_Underlying) :
|
||||
m_Underlying(a_Underlying)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
virtual void GetInts(int a_MinX, int a_MinZ, Values & a_Values) override
|
||||
{
|
||||
// Map for biome -> its beach:
|
||||
static const int ToBeach[] =
|
||||
{
|
||||
/* biOcean */ biOcean,
|
||||
/* biPlains */ biBeach,
|
||||
/* biDesert */ biBeach,
|
||||
/* biExtremeHills */ biStoneBeach,
|
||||
/* biForest */ biBeach,
|
||||
/* biTaiga */ biColdBeach,
|
||||
/* biSwampland */ biSwampland,
|
||||
/* biRiver */ biRiver,
|
||||
/* biNether */ biNether,
|
||||
/* biEnd */ biEnd,
|
||||
/* biFrozenOcean */ biColdBeach,
|
||||
/* biFrozenRiver */ biColdBeach,
|
||||
/* biIcePlains */ biColdBeach,
|
||||
/* biIceMountains */ biColdBeach,
|
||||
/* biMushroomIsland */ biMushroomShore,
|
||||
/* biMushroomShore */ biMushroomShore,
|
||||
/* biBeach */ biBeach,
|
||||
/* biDesertHills */ biBeach,
|
||||
/* biForestHills */ biBeach,
|
||||
/* biTaigaHills */ biColdBeach,
|
||||
/* biExtremeHillsEdge */ biStoneBeach,
|
||||
/* biJungle */ biBeach,
|
||||
/* biJungleHills */ biBeach,
|
||||
/* biJungleEdge */ biBeach,
|
||||
/* biDeepOcean */ biOcean,
|
||||
/* biStoneBeach */ biStoneBeach,
|
||||
/* biColdBeach */ biColdBeach,
|
||||
/* biBirchForest */ biBeach,
|
||||
/* biBirchForestHills */ biBeach,
|
||||
/* biRoofedForest */ biBeach,
|
||||
/* biColdTaiga */ biColdBeach,
|
||||
/* biColdTaigaHills */ biColdBeach,
|
||||
/* biMegaTaiga */ biStoneBeach,
|
||||
/* biMegaTaigaHills */ biStoneBeach,
|
||||
/* biExtremeHillsPlus */ biStoneBeach,
|
||||
/* biSavanna */ biBeach,
|
||||
/* biSavannaPlateau */ biBeach,
|
||||
/* biMesa */ biMesa,
|
||||
/* biMesaPlateauF */ biMesa,
|
||||
/* biMesaPlateau */ biMesa,
|
||||
};
|
||||
|
||||
// Generate the underlying values:
|
||||
int Cache[m_UnderlyingSizeX * m_UnderlyingSizeZ];
|
||||
m_Underlying->GetInts(a_MinX - 1, a_MinZ - 1, Cache);
|
||||
|
||||
// Add beaches between ocean and biomes:
|
||||
for (int z = 0; z < SizeZ; z++)
|
||||
{
|
||||
for (int x = 0; x < SizeX; x++)
|
||||
{
|
||||
int val = Cache[x + 1 + (z + 1) * m_UnderlyingSizeX];
|
||||
int Above = Cache[x + 1 + z * m_UnderlyingSizeX];
|
||||
int Below = Cache[x + 1 + (z + 2) * m_UnderlyingSizeX];
|
||||
int Left = Cache[x + (z + 1) * m_UnderlyingSizeX];
|
||||
int Right = Cache[x + 2 + (z + 1) * m_UnderlyingSizeX];
|
||||
if (!IsBiomeOcean(val))
|
||||
{
|
||||
if (IsBiomeOcean(Above) || IsBiomeOcean(Below) || IsBiomeOcean(Left) || IsBiomeOcean(Right))
|
||||
{
|
||||
val = ToBeach[(val % 128) % ARRAYCOUNT(ToBeach)];
|
||||
}
|
||||
}
|
||||
a_Values[x + z * SizeX] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
Underlying m_Underlying;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Generates the underlying numbers and then randomly changes some zeroes into nonzeroes. */
|
||||
template <int SizeX, int SizeZ = SizeX>
|
||||
class cIntGenAddIslands :
|
||||
public cIntGenWithNoise<SizeX, SizeZ>
|
||||
{
|
||||
typedef cIntGenWithNoise<SizeX, SizeZ> super;
|
||||
|
||||
public:
|
||||
typedef cIntGenPtr<SizeX, SizeZ> Underlying;
|
||||
|
||||
|
||||
cIntGenAddIslands(int a_Seed, int a_Threshold, Underlying a_Underlying) :
|
||||
super(a_Seed),
|
||||
m_Threshold(a_Threshold),
|
||||
m_Underlying(a_Underlying)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
virtual void GetInts(int a_MinX, int a_MinZ, Values & a_Values) override
|
||||
{
|
||||
m_Underlying->GetInts(a_MinX, a_MinZ, a_Values);
|
||||
for (int z = 0; z < SizeZ; z++)
|
||||
{
|
||||
for (int x = 0; x < SizeX; x++)
|
||||
{
|
||||
if (a_Values[x + z * SizeX] == 0)
|
||||
{
|
||||
int rnd = m_Noise.IntNoise2DInt(a_MinX + x, a_MinZ + z) / 7;
|
||||
if (rnd % 100 < m_Threshold)
|
||||
{
|
||||
a_Values[x + z * SizeX] = (rnd / 100) % 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
int m_Threshold;
|
||||
|
||||
Underlying m_Underlying;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** A filter that adds an edge biome group between two biome groups that need an edge between them. */
|
||||
template <int SizeX, int SizeZ = SizeX>
|
||||
class cIntGenBiomeGroupEdges :
|
||||
public cIntGen<SizeX, SizeZ>
|
||||
{
|
||||
typedef cIntGen<SizeX, SizeZ> super;
|
||||
|
||||
static const int m_UnderlyingSizeX = SizeX + 2;
|
||||
static const int m_UnderlyingSizeZ = SizeZ + 2;
|
||||
|
||||
public:
|
||||
|
||||
typedef cIntGenPtr<m_UnderlyingSizeX, m_UnderlyingSizeZ> Underlying;
|
||||
|
||||
cIntGenBiomeGroupEdges(Underlying a_Underlying) :
|
||||
m_Underlying(a_Underlying)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
virtual void GetInts(int a_MinX, int a_MinZ, Values & a_Values)
|
||||
{
|
||||
// Generate the underlying biome groups:
|
||||
int Cache[m_UnderlyingSizeX * m_UnderlyingSizeZ];
|
||||
m_Underlying->GetInts(a_MinX, a_MinZ, Cache);
|
||||
|
||||
// Change the biomes on incompatible edges into an edge biome:
|
||||
for (int z = 0; z < SizeZ; z++)
|
||||
{
|
||||
for (int x = 0; x < SizeX; x++)
|
||||
{
|
||||
int v = Cache[x + 1 + (z + 1) * m_UnderlyingSizeX];
|
||||
int Above = Cache[x + 1 + z * m_UnderlyingSizeX];
|
||||
int Below = Cache[x + 1 + (z + 2) * m_UnderlyingSizeX];
|
||||
int Left = Cache[x + (z + 1) * m_UnderlyingSizeX];
|
||||
int Right = Cache[x + 2 + (z + 1) * m_UnderlyingSizeX];
|
||||
switch (v)
|
||||
{
|
||||
// Oceans don't need any edges:
|
||||
case bgOcean:
|
||||
{
|
||||
v = bgOcean;
|
||||
break;
|
||||
}
|
||||
|
||||
// Desert should neighbor only oceans, desert and temperates; change to temperate when another:
|
||||
case bgDesert:
|
||||
{
|
||||
if (
|
||||
!IsDesertCompatible(Above) ||
|
||||
!IsDesertCompatible(Below) ||
|
||||
!IsDesertCompatible(Left) ||
|
||||
!IsDesertCompatible(Right)
|
||||
)
|
||||
{
|
||||
v = bgTemperate;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Ice should not neighbor deserts; change to temperate:
|
||||
case bgIce:
|
||||
{
|
||||
if (
|
||||
(Above == bgDesert) ||
|
||||
(Below == bgDesert) ||
|
||||
(Left == bgDesert) ||
|
||||
(Right == bgDesert)
|
||||
)
|
||||
{
|
||||
v = bgTemperate;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Jungle should not neighbor Desert or Ice; change to temperate:
|
||||
case bgJungle:
|
||||
{
|
||||
if (
|
||||
!IsJungleCompatible(Above) ||
|
||||
!IsJungleCompatible(Below) ||
|
||||
!IsJungleCompatible(Left) ||
|
||||
!IsJungleCompatible(Right)
|
||||
)
|
||||
{
|
||||
v = bgTemperate;
|
||||
}
|
||||
}
|
||||
}
|
||||
a_Values[x + z * SizeX] = v;
|
||||
} // for x
|
||||
} // for z
|
||||
}
|
||||
|
||||
protected:
|
||||
Underlying m_Underlying;
|
||||
|
||||
|
||||
inline bool IsDesertCompatible(int a_BiomeGroup)
|
||||
{
|
||||
return ((a_BiomeGroup == bgOcean) || (a_BiomeGroup == bgDesert) || (a_BiomeGroup == bgTemperate));
|
||||
}
|
||||
|
||||
inline bool IsJungleCompatible(int a_BiomeGroup)
|
||||
{
|
||||
return ((a_BiomeGroup != bgDesert) && (a_BiomeGroup != bgIce));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template <int SizeX, int SizeZ = SizeX>
|
||||
class cIntGenBiomes :
|
||||
public cIntGenWithNoise<SizeX, SizeZ>
|
||||
{
|
||||
typedef cIntGenWithNoise<SizeX, SizeZ> super;
|
||||
|
||||
public:
|
||||
typedef cIntGenPtr<SizeX, SizeZ> Underlying;
|
||||
|
||||
|
||||
cIntGenBiomes(int a_Seed, Underlying a_Underlying) :
|
||||
super(a_Seed),
|
||||
m_Underlying(a_Underlying)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
virtual void GetInts(int a_MinX, int a_MinZ, Values & a_Values) override
|
||||
{
|
||||
// Define the per-biome-group biomes:
|
||||
static const int OceanBiomes[] =
|
||||
{
|
||||
biOcean, // biDeepOcean,
|
||||
};
|
||||
|
||||
static const int DesertBiomes[] =
|
||||
{
|
||||
biDesert, biDesert, biSavanna, biPlains,
|
||||
};
|
||||
|
||||
static const int TemperateBiomes[] =
|
||||
{
|
||||
biForest, biRoofedForest, biExtremeHills, biPlains, biBirchForest, biSwampland,
|
||||
};
|
||||
|
||||
static const int MountainBiomes[] =
|
||||
{
|
||||
biExtremeHills, biForest, biTaiga, biPlains,
|
||||
};
|
||||
|
||||
static const int JungleBiomes[] =
|
||||
{
|
||||
biJungle, biJungle, biForest,
|
||||
};
|
||||
|
||||
static const int IceBiomes[] =
|
||||
{
|
||||
biIcePlains, biIcePlains, biColdTaiga,
|
||||
};
|
||||
|
||||
static const cBiomesInGroups BiomesInGroups[] =
|
||||
{
|
||||
{ static_cast<int>(ARRAYCOUNT(OceanBiomes)), OceanBiomes},
|
||||
{ static_cast<int>(ARRAYCOUNT(DesertBiomes)), DesertBiomes},
|
||||
{ static_cast<int>(ARRAYCOUNT(TemperateBiomes)), TemperateBiomes},
|
||||
{ static_cast<int>(ARRAYCOUNT(MountainBiomes)), MountainBiomes},
|
||||
{ static_cast<int>(ARRAYCOUNT(JungleBiomes)), JungleBiomes},
|
||||
{ static_cast<int>(ARRAYCOUNT(IceBiomes)), IceBiomes},
|
||||
};
|
||||
|
||||
// Generate the underlying values, representing biome groups:
|
||||
m_Underlying->GetInts(a_MinX, a_MinZ, a_Values);
|
||||
|
||||
// Overwrite each biome group with a random biome from that group:
|
||||
for (int z = 0; z < SizeZ; z++)
|
||||
{
|
||||
int IdxZ = z * SizeX;
|
||||
for (int x = 0; x < SizeX; x++)
|
||||
{
|
||||
int val = a_Values[x + IdxZ];
|
||||
const cBiomesInGroups & Biomes = BiomesInGroups[val % ARRAYCOUNT(BiomesInGroups)];
|
||||
int rnd = (m_Noise.IntNoise2DInt(x + a_MinX, z + a_MinZ) / 7);
|
||||
a_Values[x + IdxZ] = Biomes.Biomes[rnd % Biomes.Count];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
struct cBiomesInGroups
|
||||
{
|
||||
const int Count;
|
||||
const int * Biomes;
|
||||
};
|
||||
|
||||
|
||||
/** The underlying int generator */
|
||||
Underlying m_Underlying;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template <int SizeX, int SizeZ = SizeX>
|
||||
class cIntGenReplaceRandomly :
|
||||
public cIntGenWithNoise<SizeX, SizeZ>
|
||||
{
|
||||
typedef cIntGenWithNoise<SizeX, SizeZ> super;
|
||||
|
||||
public:
|
||||
typedef cIntGenPtr<SizeX, SizeZ> Underlying;
|
||||
|
||||
|
||||
cIntGenReplaceRandomly(int a_From, int a_To, int a_Chance, int a_Seed, Underlying a_Underlying) :
|
||||
super(a_Seed),
|
||||
m_From(a_From),
|
||||
m_To(a_To),
|
||||
m_Chance(a_Chance),
|
||||
m_Underlying(a_Underlying)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
virtual void GetInts(int a_MinX, int a_MinZ, Values & a_Values) override
|
||||
{
|
||||
// Generate the underlying values:
|
||||
m_Underlying->GetInts(a_MinX, a_MinZ, a_Values);
|
||||
|
||||
// Replace some of the values:
|
||||
for (int z = 0; z < SizeZ; z++)
|
||||
{
|
||||
int idxZ = z * SizeX;
|
||||
for (int x = 0; x < SizeX; x++)
|
||||
{
|
||||
int idx = x + idxZ;
|
||||
if (a_Values[idx] == m_From)
|
||||
{
|
||||
int rnd = m_Noise.IntNoise2DInt(x + a_MinX, z + a_MinZ) / 7;
|
||||
if (rnd % 100 < m_Chance)
|
||||
{
|
||||
a_Values[idx] = m_To;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // for z
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
int m_From;
|
||||
int m_To;
|
||||
int m_Chance;
|
||||
Underlying m_Underlying;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Mixer that joins together finalized biomes and rivers.
|
||||
It first checks for oceans; if there's no ocean, it checks for a river. */
|
||||
template <int SizeX, int SizeZ = SizeX>
|
||||
class cIntGenMixRivers:
|
||||
public cIntGen<SizeX, SizeZ>
|
||||
{
|
||||
typedef cIntGen<SizeX, SizeZ> super;
|
||||
|
||||
public:
|
||||
typedef cIntGenPtr<SizeX, SizeZ> Underlying;
|
||||
|
||||
|
||||
cIntGenMixRivers(Underlying a_Biomes, Underlying a_Rivers):
|
||||
m_Biomes(a_Biomes),
|
||||
m_Rivers(a_Rivers)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
virtual void GetInts(int a_MinX, int a_MinZ, Values & a_Values) override
|
||||
{
|
||||
// Generate the underlying data:
|
||||
m_Biomes->GetInts(a_MinX, a_MinZ, a_Values);
|
||||
Values Rivers;
|
||||
m_Rivers->GetInts(a_MinX, a_MinZ, Rivers);
|
||||
|
||||
// Mix the values:
|
||||
for (int z = 0; z < SizeZ; z++)
|
||||
{
|
||||
int idxZ = z * SizeX;
|
||||
for (int x = 0; x < SizeX; x++)
|
||||
{
|
||||
int idx = x + idxZ;
|
||||
if (IsBiomeOcean(a_Values[idx]))
|
||||
{
|
||||
// Oceans are kept without any changes
|
||||
continue;
|
||||
}
|
||||
if (Rivers[idx] != biRiver)
|
||||
{
|
||||
// There's no river, keep the current value
|
||||
continue;
|
||||
}
|
||||
|
||||
// There's a river, change the output to a river or a frozen river, based on the original biome:
|
||||
if (IsBiomeVeryCold((EMCSBiome)a_Values[idx]))
|
||||
{
|
||||
a_Values[idx] = biFrozenRiver;
|
||||
}
|
||||
else
|
||||
{
|
||||
a_Values[idx] = biRiver;
|
||||
}
|
||||
} // for x
|
||||
} // for z
|
||||
}
|
||||
|
||||
protected:
|
||||
Underlying m_Biomes;
|
||||
Underlying m_Rivers;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Generates a river based on the underlying data.
|
||||
This is basically an edge detector over the underlying data. The rivers are the edges where the underlying data
|
||||
changes from one pixel to its neighbor. */
|
||||
template <int SizeX, int SizeZ = SizeX>
|
||||
class cIntGenRiver:
|
||||
public cIntGenWithNoise<SizeX, SizeZ>
|
||||
{
|
||||
typedef cIntGenWithNoise<SizeX, SizeZ> super;
|
||||
static const int UnderlyingSizeX = SizeX + 2;
|
||||
static const int UnderlyingSizeZ = SizeZ + 2;
|
||||
|
||||
public:
|
||||
typedef cIntGenPtr<UnderlyingSizeX, UnderlyingSizeZ> Underlying;
|
||||
|
||||
|
||||
cIntGenRiver(int a_Seed, Underlying a_Underlying):
|
||||
super(a_Seed),
|
||||
m_Underlying(a_Underlying)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
virtual void GetInts(int a_MinX, int a_MinZ, Values & a_Values) override
|
||||
{
|
||||
// Generate the underlying data:
|
||||
int Cache[UnderlyingSizeX * UnderlyingSizeZ];
|
||||
m_Underlying->GetInts(a_MinX - 1, a_MinZ - 1, Cache);
|
||||
|
||||
// Detect the edges:
|
||||
for (int z = 0; z < SizeZ; z++)
|
||||
{
|
||||
for (int x = 0; x < SizeX; x++)
|
||||
{
|
||||
int Above = Cache[x + 1 + z * UnderlyingSizeX];
|
||||
int Below = Cache[x + 1 + (z + 2) * UnderlyingSizeX];
|
||||
int Left = Cache[x + (z + 1) * UnderlyingSizeX];
|
||||
int Right = Cache[x + 2 + (z + 1) * UnderlyingSizeX];
|
||||
int val = Cache[x + 1 + (z + 1) * UnderlyingSizeX];
|
||||
|
||||
if ((val == Above) && (val == Below) && (val == Left) && (val == Right))
|
||||
{
|
||||
val = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
val = biRiver;
|
||||
}
|
||||
a_Values[x + z * SizeX] = val;
|
||||
} // for x
|
||||
} // for z
|
||||
}
|
||||
|
||||
protected:
|
||||
Underlying m_Underlying;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Turns some of the oceans into the specified biome. Used for mushroom and deep ocean.
|
||||
The biome is only placed if at least 3 of its neighbors are ocean and only with the specified chance. */
|
||||
template <int SizeX, int SizeZ = SizeX>
|
||||
class cIntGenAddToOcean:
|
||||
public cIntGenWithNoise<SizeX, SizeZ>
|
||||
{
|
||||
typedef cIntGenWithNoise<SizeX, SizeZ> super;
|
||||
static const int UnderlyingSizeX = SizeX + 2;
|
||||
static const int UnderlyingSizeZ = SizeZ + 2;
|
||||
|
||||
public:
|
||||
typedef cIntGenPtr<UnderlyingSizeX, UnderlyingSizeZ> Underlying;
|
||||
|
||||
|
||||
cIntGenAddToOcean(int a_Seed, int a_Chance, int a_ToValue, Underlying a_Underlying):
|
||||
super(a_Seed),
|
||||
m_Chance(a_Chance),
|
||||
m_ToValue(a_ToValue),
|
||||
m_Underlying(a_Underlying)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
virtual void GetInts(int a_MinX, int a_MinZ, Values & a_Values) override
|
||||
{
|
||||
// Generate the underlying data:
|
||||
int Cache[UnderlyingSizeX * UnderlyingSizeZ];
|
||||
m_Underlying->GetInts(a_MinX - 1, a_MinZ - 1, Cache);
|
||||
|
||||
// Add the mushroom islands:
|
||||
for (int z = 0; z < SizeZ; z++)
|
||||
{
|
||||
for (int x = 0; x < SizeX; x++)
|
||||
{
|
||||
int val = Cache[x + 1 + (z + 1) * UnderlyingSizeX];
|
||||
if (!IsBiomeOcean(val))
|
||||
{
|
||||
a_Values[x + z * SizeX] = val;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Count the ocean neighbors:
|
||||
int Above = Cache[x + 1 + z * UnderlyingSizeX];
|
||||
int Below = Cache[x + 1 + (z + 2) * UnderlyingSizeX];
|
||||
int Left = Cache[x + (z + 1) * UnderlyingSizeX];
|
||||
int Right = Cache[x + 2 + (z + 1) * UnderlyingSizeX];
|
||||
int NumOceanNeighbors = 0;
|
||||
if (IsBiomeOcean(Above))
|
||||
{
|
||||
NumOceanNeighbors += 1;
|
||||
}
|
||||
if (IsBiomeOcean(Above))
|
||||
{
|
||||
NumOceanNeighbors += 1;
|
||||
}
|
||||
if (IsBiomeOcean(Above))
|
||||
{
|
||||
NumOceanNeighbors += 1;
|
||||
}
|
||||
if (IsBiomeOcean(Above))
|
||||
{
|
||||
NumOceanNeighbors += 1;
|
||||
}
|
||||
|
||||
// If at least 3 ocean neighbors and the chance is right, change:
|
||||
if ((NumOceanNeighbors >= 3) && ((m_Noise.IntNoise2DInt(x + a_MinX, z + a_MinZ) / 7) % 1000 < m_Chance))
|
||||
{
|
||||
a_Values[x + z * SizeX] = m_ToValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
a_Values[x + z * SizeX] = val;
|
||||
}
|
||||
} // for x
|
||||
} // for z
|
||||
}
|
||||
|
||||
protected:
|
||||
/** Chance, in permille, of changing the biome. */
|
||||
int m_Chance;
|
||||
|
||||
/** The value to change the ocean into. */
|
||||
int m_ToValue;
|
||||
|
||||
Underlying m_Underlying;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user