Added the Biomal height generator, made it the default height generator.
git-svn-id: http://mc-server.googlecode.com/svn/trunk@536 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
parent
4ea767f39b
commit
7abaede245
@ -85,6 +85,10 @@ enum EMCSBiome
|
|||||||
biExtremeHillsEdge = 20,
|
biExtremeHillsEdge = 20,
|
||||||
biJungle = 21,
|
biJungle = 21,
|
||||||
biJungleHills = 22,
|
biJungleHills = 22,
|
||||||
|
|
||||||
|
// Automatically capture the maximum biome value into biMaxBiome:
|
||||||
|
biNumBiomes, // True number of biomes, since they are zero-based
|
||||||
|
biMaxBiome = biNumBiomes - 1, // The maximum biome value
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
@ -89,3 +89,124 @@ void cHeiGenClassic::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightM
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// cHeiGenBiomal:
|
||||||
|
|
||||||
|
const cHeiGenBiomal::sGenParam cHeiGenBiomal::m_GenParam[biNumBiomes] =
|
||||||
|
{
|
||||||
|
/* Fast-changing | Middle-changing | Slow-changing |*/
|
||||||
|
/* Biome | Freq1 | Amp1 | Freq2 | Amp2 | Freq3 | Amp3 | BaseHeight */
|
||||||
|
/* biOcean */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // done
|
||||||
|
/* biPlains */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 68}, // done
|
||||||
|
/* biDesert */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 68}, // done
|
||||||
|
/* biExtremeHills */ { 0.2f, 4.0f, 0.05f, 20.0f, 0.01f, 16.0f, 100}, // done
|
||||||
|
/* biForest */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 70}, // done
|
||||||
|
/* biTaiga */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 70}, // done
|
||||||
|
/* biSwampland */ { 0.1f, 1.1f, 0.05f, 1.5f, 0.02f, 2.5f, 61.5}, // done
|
||||||
|
/* biRiver */ { 0.2f, 3.0f, 0.05f, 1.0f, 0.01f, 1.0f, 56}, // done
|
||||||
|
/* biNether */ { 0.1f, 0.0f, 0.01f, 0.0f, 0.01f, 0.0f, 0}, // Unused, but must be here due to indexing
|
||||||
|
/* biSky */ { 0.1f, 0.0f, 0.01f, 0.0f, 0.01f, 0.0f, 0}, // Unused, but must be here due to indexing
|
||||||
|
/* biFrozenOcean */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // done
|
||||||
|
/* biFrozenRiver */ { 0.2f, 3.0f, 0.05f, 1.0f, 0.01f, 1.0f, 56}, // done
|
||||||
|
/* biIcePlains */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 68}, // done
|
||||||
|
/* biIceMountains */ { 0.2f, 2.0f, 0.05f, 10.0f, 0.01f, 8.0f, 80}, // done
|
||||||
|
/* biMushroomIsland */ { 0.1f, 2.0f, 0.05f, 8.0f, 0.01f, 6.0f, 80}, // done
|
||||||
|
/* biMushroomShore */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 64}, // done
|
||||||
|
/* biBeach */ { 0.1f, 0.5f, 0.05f, 1.0f, 0.01f, 1.0f, 64}, // done
|
||||||
|
/* biDesertHills */ { 0.2f, 2.0f, 0.05f, 5.0f, 0.01f, 4.0f, 75}, // done
|
||||||
|
/* biForestHills */ { 0.2f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 80}, // done
|
||||||
|
/* biTaigaHills */ { 0.2f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 80}, // done
|
||||||
|
/* biExtremeHillsEdge */ { 0.2f, 3.0f, 0.05f, 16.0f, 0.01f, 12.0f, 80}, // done
|
||||||
|
/* biJungle */ { 0.1f, 3.0f, 0.05f, 6.0f, 0.01f, 6.0f, 70}, // done
|
||||||
|
/* biJungleHills */ { 0.2f, 3.0f, 0.05f, 12.0f, 0.01f, 10.0f, 80}, // done
|
||||||
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cHeiGenBiomal::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap)
|
||||||
|
{
|
||||||
|
// Generate a 3x3 chunk area of biomes around this chunk:
|
||||||
|
BiomeNeighbors Biomes;
|
||||||
|
for (int z = -1; z <= 1; z++)
|
||||||
|
{
|
||||||
|
for (int x = -1; x <= 1; x++)
|
||||||
|
{
|
||||||
|
m_BiomeGen.GenBiomes(a_ChunkX + x, a_ChunkZ + z, Biomes[x + 1][z + 1]);
|
||||||
|
} // for x
|
||||||
|
} // for z
|
||||||
|
|
||||||
|
// For each height, go through neighboring biomes and add up their idea of height:
|
||||||
|
for (int z = 0; z < cChunkDef::Width; z++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < cChunkDef::Width; x++)
|
||||||
|
{
|
||||||
|
cChunkDef::SetHeight(a_HeightMap, x, z, GetHeightAt(x, z, a_ChunkX, a_ChunkZ, Biomes));
|
||||||
|
} // for x
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
HEIGHTTYPE cHeiGenBiomal::GetHeightAt(int a_RelX, int a_RelZ, int a_ChunkX, int a_ChunkZ, const cHeiGenBiomal::BiomeNeighbors & a_BiomeNeighbors)
|
||||||
|
{
|
||||||
|
// Sum up how many biomes of each type there are in the neighborhood:
|
||||||
|
int BiomeCounts[biNumBiomes];
|
||||||
|
memset(BiomeCounts, 0, sizeof(BiomeCounts));
|
||||||
|
int Sum = 0;
|
||||||
|
for (int z = -8; z <= 8; z++)
|
||||||
|
{
|
||||||
|
int FinalZ = a_RelZ + z + cChunkDef::Width;
|
||||||
|
int IdxZ = FinalZ / cChunkDef::Width;
|
||||||
|
int ModZ = FinalZ % cChunkDef::Width;
|
||||||
|
int WeightZ = 9 - abs(z);
|
||||||
|
for (int x = -8; x <= 8; x++)
|
||||||
|
{
|
||||||
|
int FinalX = a_RelX + x + cChunkDef::Width;
|
||||||
|
int IdxX = FinalX / cChunkDef::Width;
|
||||||
|
int ModX = FinalX % cChunkDef::Width;
|
||||||
|
EMCSBiome Biome = cChunkDef::GetBiome(a_BiomeNeighbors[IdxX][IdxZ], ModX, ModZ);
|
||||||
|
if ((Biome < 0) || (Biome >= ARRAYCOUNT(BiomeCounts)))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int WeightX = 9 - abs(x);
|
||||||
|
BiomeCounts[Biome] += WeightX + WeightZ;
|
||||||
|
Sum += WeightX + WeightZ;
|
||||||
|
} // for x
|
||||||
|
} // for z
|
||||||
|
|
||||||
|
// For each biome type that has a nonzero count, calc its height and add it:
|
||||||
|
if (Sum > 0)
|
||||||
|
{
|
||||||
|
int Height = 0;
|
||||||
|
int BlockX = a_ChunkX * cChunkDef::Width + a_RelX;
|
||||||
|
int BlockZ = a_ChunkZ * cChunkDef::Width + a_RelZ;
|
||||||
|
for (int i = 0; i < ARRAYCOUNT(BiomeCounts); i++)
|
||||||
|
{
|
||||||
|
if (BiomeCounts[i] == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
float oct1 = m_Noise.CubicNoise2D(BlockX * m_GenParam[i].m_HeightFreq1, BlockZ * m_GenParam[i].m_HeightFreq1) * m_GenParam[i].m_HeightAmp1;
|
||||||
|
float oct2 = m_Noise.CubicNoise2D(BlockX * m_GenParam[i].m_HeightFreq2, BlockZ * m_GenParam[i].m_HeightFreq2) * m_GenParam[i].m_HeightAmp2;
|
||||||
|
float oct3 = m_Noise.CubicNoise2D(BlockX * m_GenParam[i].m_HeightFreq3, BlockZ * m_GenParam[i].m_HeightFreq3) * m_GenParam[i].m_HeightAmp3;
|
||||||
|
Height += BiomeCounts[i] * (int)(m_GenParam[i].m_BaseHeight + oct1 + oct2 + oct3);
|
||||||
|
}
|
||||||
|
int res = (HEIGHTTYPE)(Height / Sum);
|
||||||
|
return min(250, max(res, 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
// No known biome around? Weird. Return a bogus value:
|
||||||
|
ASSERT(!"cHeiGenBiomal: Biome sum failed, no known biome around");
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,3 +62,40 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class cHeiGenBiomal :
|
||||||
|
public cTerrainHeightGen
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
cHeiGenBiomal(int a_Seed, cBiomeGen & a_BiomeGen) :
|
||||||
|
m_Noise(a_Seed),
|
||||||
|
m_BiomeGen(a_BiomeGen)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
typedef cChunkDef::BiomeMap BiomeNeighbors[3][3];
|
||||||
|
|
||||||
|
cNoise m_Noise;
|
||||||
|
cBiomeGen & m_BiomeGen;
|
||||||
|
|
||||||
|
// Per-biome terrain generator parameters:
|
||||||
|
struct sGenParam
|
||||||
|
{
|
||||||
|
float m_HeightFreq1, m_HeightAmp1;
|
||||||
|
float m_HeightFreq2, m_HeightAmp2;
|
||||||
|
float m_HeightFreq3, m_HeightAmp3;
|
||||||
|
float m_BaseHeight;
|
||||||
|
} ;
|
||||||
|
static const sGenParam m_GenParam[biNumBiomes];
|
||||||
|
|
||||||
|
// cTerrainHeightGen override:
|
||||||
|
virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override;
|
||||||
|
|
||||||
|
HEIGHTTYPE GetHeightAt(int a_RelX, int a_RelZ, int a_ChunkX, int a_ChunkZ, const BiomeNeighbors & a_BiomeNeighbors);
|
||||||
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -117,6 +117,7 @@ void cChunkGenerator::InitBiomeGen(cIniFile & a_IniFile)
|
|||||||
EMCSBiome b = StringToBiome(Biome);
|
EMCSBiome b = StringToBiome(Biome);
|
||||||
if (b == -1)
|
if (b == -1)
|
||||||
{
|
{
|
||||||
|
LOGWARN("[Generator]::ConstantBiome value \"%s\" not recognized, using \"Plains\".", Biome.c_str());
|
||||||
b = biPlains;
|
b = biPlains;
|
||||||
}
|
}
|
||||||
m_BiomeGen = new cBioGenConstant(b);
|
m_BiomeGen = new cBioGenConstant(b);
|
||||||
@ -163,12 +164,8 @@ void cChunkGenerator::InitHeightGen(cIniFile & a_IniFile)
|
|||||||
int Height = a_IniFile.GetValueI("Generator", "FlatHeight", 5);
|
int Height = a_IniFile.GetValueI("Generator", "FlatHeight", 5);
|
||||||
m_HeightGen = new cHeiGenFlat(Height);
|
m_HeightGen = new cHeiGenFlat(Height);
|
||||||
}
|
}
|
||||||
else // "classic" or <not found>
|
else if (NoCaseCompare(HeightGenName, "classic") == 0)
|
||||||
{
|
{
|
||||||
if (NoCaseCompare(HeightGenName, "classic") != 0)
|
|
||||||
{
|
|
||||||
LOGWARN("Unknown HeightGen \"%s\", using \"classic\" instead.", HeightGenName.c_str());
|
|
||||||
}
|
|
||||||
// These used to be in terrain.ini, but now they are in world.ini (so that multiple worlds can have different values):
|
// These used to be in terrain.ini, but now they are in world.ini (so that multiple worlds can have different values):
|
||||||
float HeightFreq1 = (float)a_IniFile.GetValueF("Generator", "ClassicHeightFreq1", 0.1);
|
float HeightFreq1 = (float)a_IniFile.GetValueF("Generator", "ClassicHeightFreq1", 0.1);
|
||||||
float HeightFreq2 = (float)a_IniFile.GetValueF("Generator", "ClassicHeightFreq2", 1.0);
|
float HeightFreq2 = (float)a_IniFile.GetValueF("Generator", "ClassicHeightFreq2", 1.0);
|
||||||
@ -178,6 +175,14 @@ void cChunkGenerator::InitHeightGen(cIniFile & a_IniFile)
|
|||||||
float HeightAmp3 = (float)a_IniFile.GetValueF("Generator", "ClassicHeightAmp3", 0.5);
|
float HeightAmp3 = (float)a_IniFile.GetValueF("Generator", "ClassicHeightAmp3", 0.5);
|
||||||
m_HeightGen = new cHeiGenClassic(m_Seed, HeightFreq1, HeightAmp1, HeightFreq2, HeightAmp2, HeightFreq3, HeightAmp3);
|
m_HeightGen = new cHeiGenClassic(m_Seed, HeightFreq1, HeightAmp1, HeightFreq2, HeightAmp2, HeightFreq3, HeightAmp3);
|
||||||
}
|
}
|
||||||
|
else // "biomal" or <not found>
|
||||||
|
{
|
||||||
|
if (NoCaseCompare(HeightGenName, "biomal") != 0)
|
||||||
|
{
|
||||||
|
LOGWARN("Unknown HeightGen \"%s\", using \"Biomal\" instead.", HeightGenName.c_str());
|
||||||
|
}
|
||||||
|
m_HeightGen = new cHeiGenBiomal(m_Seed, *m_BiomeGen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ float cNoise::IntNoise( int a_X ) const
|
|||||||
{
|
{
|
||||||
int x = ((a_X*m_Seed)<<13) ^ a_X;
|
int x = ((a_X*m_Seed)<<13) ^ a_X;
|
||||||
return ( 1.0f - ( (x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0f);
|
return ( 1.0f - ( (x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0f);
|
||||||
|
// returns a float number in the range of [-1, 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -27,6 +28,7 @@ float cNoise::IntNoise2D( int a_X, int a_Y ) const
|
|||||||
int n = a_X + a_Y * 57 + m_Seed*57*57;
|
int n = a_X + a_Y * 57 + m_Seed*57*57;
|
||||||
n = (n<<13) ^ n;
|
n = (n<<13) ^ n;
|
||||||
return ( 1.0f - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0f);
|
return ( 1.0f - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0f);
|
||||||
|
// returns a float number in the range of [-1, 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -38,6 +40,7 @@ float cNoise::IntNoise3D( int a_X, int a_Y, int a_Z ) const
|
|||||||
int n = a_X + a_Y * 57 + a_Z * 57*57 + m_Seed*57*57*57;
|
int n = a_X + a_Y * 57 + a_Z * 57*57 + m_Seed*57*57*57;
|
||||||
n = (n<<13) ^ n;
|
n = (n<<13) ^ n;
|
||||||
return ( 1.0f - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0f);
|
return ( 1.0f - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0f);
|
||||||
|
// returns a float number in the range of [-1, 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user