1
0

Generator: Shape initial refactoring.

The code compiles, but several structure generators are broken, crash on start.
This commit is contained in:
Mattes D
2014-11-12 21:24:26 +01:00
parent b525eee8e0
commit 5fb2526e07
23 changed files with 1383 additions and 1373 deletions

View File

@@ -14,163 +14,6 @@
////////////////////////////////////////////////////////////////////////////////
// cPattern:
/// This class is used to store a column pattern initialized at runtime,
/// so that the program doesn't need to explicitly set 256 values for each pattern
/// Each pattern has 256 blocks so that there's no need to check pattern bounds when assigning the
/// pattern - there will always be enough pattern left, even for the whole chunk height
class cPattern
{
public:
cPattern(cDistortedHeightmap::sBlockInfo * a_TopBlocks, size_t a_Count)
{
// Copy the pattern into the top:
for (size_t i = 0; i < a_Count; i++)
{
m_Pattern[i] = a_TopBlocks[i];
}
// Fill the rest with stone:
static cDistortedHeightmap::sBlockInfo Stone = {E_BLOCK_STONE, 0};
for (size_t i = a_Count; i < cChunkDef::Height; i++)
{
m_Pattern[i] = Stone;
}
}
const cDistortedHeightmap::sBlockInfo * Get(void) const { return m_Pattern; }
protected:
cDistortedHeightmap::sBlockInfo m_Pattern[cChunkDef::Height];
} ;
////////////////////////////////////////////////////////////////////////////////
// The arrays to use for the top block pattern definitions:
static cDistortedHeightmap::sBlockInfo tbGrass[] =
{
{E_BLOCK_GRASS, 0},
{E_BLOCK_DIRT, E_META_DIRT_NORMAL},
{E_BLOCK_DIRT, E_META_DIRT_NORMAL},
{E_BLOCK_DIRT, E_META_DIRT_NORMAL},
} ;
static cDistortedHeightmap::sBlockInfo tbSand[] =
{
{ E_BLOCK_SAND, 0},
{ E_BLOCK_SAND, 0},
{ E_BLOCK_SAND, 0},
{ E_BLOCK_SANDSTONE, 0},
} ;
static cDistortedHeightmap::sBlockInfo tbDirt[] =
{
{E_BLOCK_DIRT, E_META_DIRT_NORMAL},
{E_BLOCK_DIRT, E_META_DIRT_NORMAL},
{E_BLOCK_DIRT, E_META_DIRT_NORMAL},
{E_BLOCK_DIRT, E_META_DIRT_NORMAL},
} ;
static cDistortedHeightmap::sBlockInfo tbPodzol[] =
{
{E_BLOCK_DIRT, E_META_DIRT_PODZOL},
{E_BLOCK_DIRT, E_META_DIRT_NORMAL},
{E_BLOCK_DIRT, E_META_DIRT_NORMAL},
{E_BLOCK_DIRT, E_META_DIRT_NORMAL},
} ;
static cDistortedHeightmap::sBlockInfo tbGrassLess[] =
{
{E_BLOCK_DIRT, E_META_DIRT_GRASSLESS},
{E_BLOCK_DIRT, E_META_DIRT_NORMAL},
{E_BLOCK_DIRT, E_META_DIRT_NORMAL},
{E_BLOCK_DIRT, E_META_DIRT_NORMAL},
} ;
static cDistortedHeightmap::sBlockInfo tbMycelium[] =
{
{E_BLOCK_MYCELIUM, 0},
{E_BLOCK_DIRT, 0},
{E_BLOCK_DIRT, 0},
{E_BLOCK_DIRT, 0},
} ;
static cDistortedHeightmap::sBlockInfo tbGravel[] =
{
{E_BLOCK_GRAVEL, 0},
{E_BLOCK_GRAVEL, 0},
{E_BLOCK_GRAVEL, 0},
{E_BLOCK_STONE, 0},
} ;
static cDistortedHeightmap::sBlockInfo tbStone[] =
{
{E_BLOCK_STONE, 0},
{E_BLOCK_STONE, 0},
{E_BLOCK_STONE, 0},
{E_BLOCK_STONE, 0},
} ;
////////////////////////////////////////////////////////////////////////////////
// Ocean floor pattern top-block definitions:
static cDistortedHeightmap::sBlockInfo tbOFSand[] =
{
{E_BLOCK_SAND, 0},
{E_BLOCK_SAND, 0},
{E_BLOCK_SAND, 0},
{E_BLOCK_SANDSTONE, 0}
} ;
static cDistortedHeightmap::sBlockInfo tbOFClay[] =
{
{ E_BLOCK_CLAY, 0},
{ E_BLOCK_CLAY, 0},
{ E_BLOCK_SAND, 0},
{ E_BLOCK_SAND, 0},
} ;
static cDistortedHeightmap::sBlockInfo tbOFRedSand[] =
{
{ E_BLOCK_SAND, E_META_SAND_RED},
{ E_BLOCK_SAND, E_META_SAND_RED},
{ E_BLOCK_SAND, E_META_SAND_RED},
{ E_BLOCK_SANDSTONE, 0},
} ;
////////////////////////////////////////////////////////////////////////////////
// Individual patterns to use:
static cPattern patGrass (tbGrass, ARRAYCOUNT(tbGrass));
static cPattern patSand (tbSand, ARRAYCOUNT(tbSand));
static cPattern patDirt (tbDirt, ARRAYCOUNT(tbDirt));
static cPattern patPodzol (tbPodzol, ARRAYCOUNT(tbPodzol));
static cPattern patGrassLess(tbGrassLess, ARRAYCOUNT(tbGrassLess));
static cPattern patMycelium (tbMycelium, ARRAYCOUNT(tbMycelium));
static cPattern patGravel (tbGravel, ARRAYCOUNT(tbGravel));
static cPattern patStone (tbStone, ARRAYCOUNT(tbStone));
static cPattern patOFSand (tbOFSand, ARRAYCOUNT(tbOFSand));
static cPattern patOFClay (tbOFClay, ARRAYCOUNT(tbOFClay));
static cPattern patOFRedSand(tbOFRedSand, ARRAYCOUNT(tbOFRedSand));
////////////////////////////////////////////////////////////////////////////////
// cDistortedHeightmap:
@@ -237,7 +80,7 @@ const cDistortedHeightmap::sGenParam cDistortedHeightmap::m_GenParam[256] =
{0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 110 .. 119
{0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 120 .. 128
// Release 1.7 /* biome variants:
// Release 1.7 biome variants:
/* biSunflowerPlains */ { 1.0f, 1.0f}, // 129
/* biDesertM */ { 1.0f, 1.0f}, // 130
/* biExtremeHillsM */ {16.0f, 16.0f}, // 131
@@ -279,8 +122,6 @@ const cDistortedHeightmap::sGenParam cDistortedHeightmap::m_GenParam[256] =
cDistortedHeightmap::cDistortedHeightmap(int a_Seed, cBiomeGenPtr a_BiomeGen) :
m_NoiseDistortX(a_Seed + 1000),
m_NoiseDistortZ(a_Seed + 2000),
m_OceanFloorSelect(a_Seed + 3000),
m_MesaFloor(a_Seed + 4000),
m_BiomeGen(a_BiomeGen),
m_UnderlyingHeiGen(new cHeiGenBiomal(a_Seed, a_BiomeGen)),
m_HeightGen(m_UnderlyingHeiGen, 64),
@@ -293,8 +134,6 @@ cDistortedHeightmap::cDistortedHeightmap(int a_Seed, cBiomeGenPtr a_BiomeGen) :
m_NoiseDistortZ.AddOctave((NOISE_DATATYPE)1, (NOISE_DATATYPE)0.5);
m_NoiseDistortZ.AddOctave((NOISE_DATATYPE)0.5, (NOISE_DATATYPE)1);
m_NoiseDistortZ.AddOctave((NOISE_DATATYPE)0.25, (NOISE_DATATYPE)2);
InitMesaPattern(a_Seed);
}
@@ -309,7 +148,7 @@ void cDistortedHeightmap::Initialize(cIniFile & a_IniFile)
}
// Read the params from the INI file:
m_SeaLevel = a_IniFile.GetValueSetI("Generator", "DistortedHeightmapSeaLevel", 62);
m_SeaLevel = a_IniFile.GetValueSetI("Generator", "SeaLevel", 62);
m_FrequencyX = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "DistortedHeightmapFrequencyX", 10);
m_FrequencyY = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "DistortedHeightmapFrequencyY", 10);
m_FrequencyZ = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "DistortedHeightmapFrequencyZ", 10);
@@ -321,89 +160,6 @@ void cDistortedHeightmap::Initialize(cIniFile & a_IniFile)
void cDistortedHeightmap::InitMesaPattern(int a_Seed)
{
// Stone in the bottom half of the pattern:
for (int i = cChunkDef::Height; i < 2 * cChunkDef::Height; i++)
{
m_MesaPattern[i].BlockMeta = 0;
m_MesaPattern[i].BlockType = E_BLOCK_STONE;
}
// Stained and hardened clay in the top half of the pattern
// In a loop, choose whether to use one or two layers of stained clay, then choose a color and width for each layer
// Separate each group with another layer of hardened clay
cNoise PatternNoise((unsigned)a_Seed);
static NIBBLETYPE AllowedColors[] =
{
E_META_STAINED_CLAY_YELLOW,
E_META_STAINED_CLAY_YELLOW,
E_META_STAINED_CLAY_RED,
E_META_STAINED_CLAY_RED,
E_META_STAINED_CLAY_WHITE,
E_META_STAINED_CLAY_BROWN,
E_META_STAINED_CLAY_BROWN,
E_META_STAINED_CLAY_BROWN,
E_META_STAINED_CLAY_ORANGE,
E_META_STAINED_CLAY_ORANGE,
E_META_STAINED_CLAY_ORANGE,
E_META_STAINED_CLAY_ORANGE,
E_META_STAINED_CLAY_ORANGE,
E_META_STAINED_CLAY_ORANGE,
E_META_STAINED_CLAY_LIGHTGRAY,
} ;
static int LayerSizes[] = // Adjust the chance so that thinner layers occur more commonly
{
1, 1, 1, 1, 1, 1,
2, 2, 2, 2,
3, 3,
} ;
int Idx = cChunkDef::Height - 1;
while (Idx >= 0)
{
// A layer group of 1 - 2 color stained clay:
int Random = PatternNoise.IntNoise1DInt(Idx) / 7;
int NumLayers = (Random % 2) + 1;
Random /= 2;
for (int Lay = 0; Lay < NumLayers; Lay++)
{
int NumBlocks = LayerSizes[(Random % ARRAYCOUNT(LayerSizes))];
NIBBLETYPE Color = AllowedColors[(Random / 4) % ARRAYCOUNT(AllowedColors)];
if (
((NumBlocks == 3) && (NumLayers == 2)) || // In two-layer mode disallow the 3-high layers:
(Color == E_META_STAINED_CLAY_WHITE)) // White stained clay can ever be only 1 block high
{
NumBlocks = 1;
}
NumBlocks = std::min(Idx + 1, NumBlocks); // Limit by Idx so that we don't have to check inside the loop
Random /= 32;
for (int Block = 0; Block < NumBlocks; Block++, Idx--)
{
m_MesaPattern[Idx].BlockMeta = Color;
m_MesaPattern[Idx].BlockType = E_BLOCK_STAINED_CLAY;
} // for Block
} // for Lay
// A layer of hardened clay in between the layer group:
int NumBlocks = (Random % 4) + 1; // All heights the same probability
if ((NumLayers == 2) && (NumBlocks < 4))
{
// For two layers of stained clay, add an extra block of hardened clay:
NumBlocks++;
}
NumBlocks = std::min(Idx + 1, NumBlocks); // Limit by Idx so that we don't have to check inside the loop
for (int Block = 0; Block < NumBlocks; Block++, Idx--)
{
m_MesaPattern[Idx].BlockMeta = 0;
m_MesaPattern[Idx].BlockType = E_BLOCK_HARDENED_CLAY;
} // for Block
} // while (Idx >= 0)
}
void cDistortedHeightmap::PrepareState(int a_ChunkX, int a_ChunkZ)
{
if ((m_CurChunkX == a_ChunkX) && (m_CurChunkZ == a_ChunkZ))
@@ -474,23 +230,17 @@ void cDistortedHeightmap::GenerateHeightArray(void)
void cDistortedHeightmap::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap)
void cDistortedHeightmap::GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape)
{
PrepareState(a_ChunkX, a_ChunkZ);
for (int z = 0; z < cChunkDef::Width; z++)
{
for (int x = 0; x < cChunkDef::Width; x++)
{
int NoiseArrayIdx = x + 17 * 257 * z;
cChunkDef::SetHeight(a_HeightMap, x, z, m_SeaLevel - 1);
for (int y = cChunkDef::Height - 1; y > m_SeaLevel - 1; y--)
int idx = x + 17 * 257 * z;
for (int y = 0; y < cChunkDef::Height; y++)
{
int HeightMapHeight = (int)m_DistortedHeightmap[NoiseArrayIdx + 17 * y];
if (y < HeightMapHeight)
{
cChunkDef::SetHeight(a_HeightMap, x, z, y);
break;
}
a_Shape[y + x * 256 + z * 16 * 256] = (y < m_DistortedHeightmap[idx + y * 17]) ? 1 : 0;
} // for y
} // for x
} // for z
@@ -500,36 +250,7 @@ void cDistortedHeightmap::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::He
void cDistortedHeightmap::InitializeHeightGen(cIniFile & a_IniFile)
{
Initialize(a_IniFile);
}
void cDistortedHeightmap::ComposeTerrain(cChunkDesc & a_ChunkDesc)
{
// Prepare the internal state for generating this chunk:
PrepareState(a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ());
// Compose:
a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0);
for (int z = 0; z < cChunkDef::Width; z++)
{
for (int x = 0; x < cChunkDef::Width; x++)
{
ComposeColumn(a_ChunkDesc, x, z);
} // for x
} // for z
}
void cDistortedHeightmap::InitializeCompoGen(cIniFile & a_IniFile)
void cDistortedHeightmap::InitializeShapeGen(cIniFile & a_IniFile)
{
Initialize(a_IniFile);
}
@@ -654,275 +375,3 @@ void cDistortedHeightmap::GetDistortAmpsAt(BiomeNeighbors & a_Neighbors, int a_R
void cDistortedHeightmap::ComposeColumn(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ)
{
// Frequencies for the podzol floor selecting noise:
const NOISE_DATATYPE FrequencyX = 8;
const NOISE_DATATYPE FrequencyZ = 8;
EMCSBiome Biome = a_ChunkDesc.GetBiome(a_RelX, a_RelZ);
switch (Biome)
{
case biOcean:
case biPlains:
case biForest:
case biTaiga:
case biSwampland:
case biRiver:
case biFrozenOcean:
case biFrozenRiver:
case biIcePlains:
case biIceMountains:
case biForestHills:
case biTaigaHills:
case biExtremeHillsEdge:
case biExtremeHillsPlus:
case biExtremeHills:
case biJungle:
case biJungleHills:
case biJungleEdge:
case biDeepOcean:
case biStoneBeach:
case biColdBeach:
case biBirchForest:
case biBirchForestHills:
case biRoofedForest:
case biColdTaiga:
case biColdTaigaHills:
case biSavanna:
case biSavannaPlateau:
case biSunflowerPlains:
case biFlowerForest:
case biTaigaM:
case biSwamplandM:
case biIcePlainsSpikes:
case biJungleM:
case biJungleEdgeM:
case biBirchForestM:
case biBirchForestHillsM:
case biRoofedForestM:
case biColdTaigaM:
case biSavannaM:
case biSavannaPlateauM:
{
FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patGrass.Get());
return;
}
case biMegaTaiga:
case biMegaTaigaHills:
case biMegaSpruceTaiga:
case biMegaSpruceTaigaHills:
{
// Select the pattern to use - podzol, grass or grassless dirt:
NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(m_CurChunkX * cChunkDef::Width + a_RelX)) / FrequencyX;
NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(m_CurChunkZ * cChunkDef::Width + a_RelZ)) / FrequencyZ;
NOISE_DATATYPE Val = m_OceanFloorSelect.CubicNoise2D(NoiseX, NoiseY);
const sBlockInfo * Pattern = (Val < -0.9) ? patGrassLess.Get() : ((Val > 0) ? patPodzol.Get() : patGrass.Get());
FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, Pattern);
return;
}
case biDesertHills:
case biDesert:
case biDesertM:
case biBeach:
{
FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patSand.Get());
return;
}
case biMushroomIsland:
case biMushroomShore:
{
FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patMycelium.Get());
return;
}
case biMesa:
case biMesaPlateauF:
case biMesaPlateau:
case biMesaBryce:
case biMesaPlateauFM:
case biMesaPlateauM:
{
// Mesa biomes need special handling, because they don't follow the usual "4 blocks from top pattern",
// instead, they provide a "from bottom" pattern with varying base height,
// usually 4 blocks below the ocean level
FillColumnMesa(a_ChunkDesc, a_RelX, a_RelZ);
return;
}
case biExtremeHillsPlusM:
case biExtremeHillsM:
{
// Select the pattern to use - gravel, stone or grass:
NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(m_CurChunkX * cChunkDef::Width + a_RelX)) / FrequencyX;
NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(m_CurChunkZ * cChunkDef::Width + a_RelZ)) / FrequencyZ;
NOISE_DATATYPE Val = m_OceanFloorSelect.CubicNoise2D(NoiseX, NoiseY);
const sBlockInfo * Pattern = (Val < 0.0) ? patStone.Get() : patGrass.Get();
FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, Pattern);
return;
}
default:
{
ASSERT(!"Unhandled biome");
return;
}
} // switch (Biome)
}
void cDistortedHeightmap::FillColumnPattern(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ, const sBlockInfo * a_Pattern)
{
int NoiseArrayIdx = a_RelX + 17 * 257 * a_RelZ;
bool HasHadWater = false;
int PatternIdx = 0;
for (int y = a_ChunkDesc.GetHeight(a_RelX, a_RelZ); y > 0; y--)
{
int HeightMapHeight = (int)m_DistortedHeightmap[NoiseArrayIdx + 17 * y];
if (y < HeightMapHeight)
{
// "ground" part, use the pattern:
a_ChunkDesc.SetBlockTypeMeta(a_RelX, y, a_RelZ, a_Pattern[PatternIdx].BlockType, a_Pattern[PatternIdx].BlockMeta);
PatternIdx++;
continue;
}
// "air" or "water" part:
// Reset the pattern index to zero, so that the pattern is repeated from the top again:
PatternIdx = 0;
if (y >= m_SeaLevel)
{
// "air" part, do nothing
continue;
}
a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STATIONARY_WATER);
if (HasHadWater)
{
continue;
}
// Select the ocean-floor pattern to use:
a_Pattern = a_ChunkDesc.GetBiome(a_RelX, a_RelZ) == biDeepOcean ? patGravel.Get() : ChooseOceanFloorPattern(a_RelX, a_RelZ);
HasHadWater = true;
} // for y
a_ChunkDesc.SetBlockType(a_RelX, 0, a_RelZ, E_BLOCK_BEDROCK);
}
void cDistortedHeightmap::FillColumnMesa(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ)
{
// Frequencies for the clay floor noise:
const NOISE_DATATYPE FrequencyX = 50;
const NOISE_DATATYPE FrequencyZ = 50;
int Top = a_ChunkDesc.GetHeight(a_RelX, a_RelZ);
if (Top < m_SeaLevel)
{
// The terrain is below sealevel, handle as regular ocean:
FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patOFRedSand.Get());
return;
}
NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(m_CurChunkX * cChunkDef::Width + a_RelX)) / FrequencyX;
NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(m_CurChunkZ * cChunkDef::Width + a_RelZ)) / FrequencyZ;
int ClayFloor = m_SeaLevel - 6 + (int)(4.f * m_MesaFloor.CubicNoise2D(NoiseX, NoiseY));
if (ClayFloor >= Top)
{
ClayFloor = Top - 1;
}
if (Top - m_SeaLevel < 5)
{
// Simple case: top is red sand, then hardened clay down to ClayFloor, then stone:
a_ChunkDesc.SetBlockTypeMeta(a_RelX, Top, a_RelZ, E_BLOCK_SAND, E_META_SAND_RED);
for (int y = Top - 1; y >= ClayFloor; y--)
{
a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_HARDENED_CLAY);
}
for (int y = ClayFloor - 1; y > 0; y--)
{
a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STONE);
}
a_ChunkDesc.SetBlockType(a_RelX, 0, a_RelZ, E_BLOCK_BEDROCK);
return;
}
// Difficult case: use the mesa pattern and watch for overhangs:
int NoiseArrayIdx = a_RelX + 17 * 257 * a_RelZ;
int PatternIdx = cChunkDef::Height - (Top - ClayFloor); // We want the block at index ClayFloor to be pattern's 256th block (first stone)
const sBlockInfo * Pattern = m_MesaPattern;
bool HasHadWater = false;
for (int y = Top; y > 0; y--)
{
int HeightMapHeight = (int)m_DistortedHeightmap[NoiseArrayIdx + 17 * y];
if (y < HeightMapHeight)
{
// "ground" part, use the pattern:
a_ChunkDesc.SetBlockTypeMeta(a_RelX, y, a_RelZ, Pattern[PatternIdx].BlockType, Pattern[PatternIdx].BlockMeta);
PatternIdx++;
continue;
}
if (y >= m_SeaLevel)
{
// "air" part, do nothing
continue;
}
// "water" part, fill with water and choose new pattern for ocean floor, if not chosen already:
PatternIdx = 0;
a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STATIONARY_WATER);
if (HasHadWater)
{
continue;
}
// Select the ocean-floor pattern to use:
Pattern = ChooseOceanFloorPattern(a_RelX, a_RelZ);
HasHadWater = true;
} // for y
a_ChunkDesc.SetBlockType(a_RelX, 0, a_RelZ, E_BLOCK_BEDROCK);
}
const cDistortedHeightmap::sBlockInfo * cDistortedHeightmap::ChooseOceanFloorPattern(int a_RelX, int a_RelZ)
{
// Frequencies for the ocean floor selecting noise:
const NOISE_DATATYPE FrequencyX = 3;
const NOISE_DATATYPE FrequencyZ = 3;
// Select the ocean-floor pattern to use:
NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(m_CurChunkX * cChunkDef::Width + a_RelX)) / FrequencyX;
NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(m_CurChunkZ * cChunkDef::Width + a_RelZ)) / FrequencyZ;
NOISE_DATATYPE Val = m_OceanFloorSelect.CubicNoise2D(NoiseX, NoiseY);
if (Val < -0.95)
{
return patOFClay.Get();
}
else if (Val < 0)
{
return patOFSand.Get();
}
else
{
return patDirt.Get();
}
}