2012-05-25 03:18:52 -04:00
|
|
|
|
|
|
|
// CompoGen.cpp
|
|
|
|
|
|
|
|
/* Implements the various terrain composition generators:
|
|
|
|
- cCompoGenSameBlock
|
|
|
|
- cCompoGenDebugBiomes
|
|
|
|
- cCompoGenClassic
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "Globals.h"
|
|
|
|
#include "CompoGen.h"
|
|
|
|
#include "BlockID.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// cCompoGenSameBlock:
|
|
|
|
|
|
|
|
void cCompoGenSameBlock::ComposeTerrain(
|
|
|
|
int a_ChunkX, int a_ChunkZ,
|
|
|
|
cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated
|
|
|
|
cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated
|
|
|
|
const cChunkDef::HeightMap & a_HeightMap, // The height map to fit
|
|
|
|
cEntityList & a_Entities, // Entitites may be generated along with the terrain
|
|
|
|
cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...)
|
|
|
|
)
|
|
|
|
{
|
|
|
|
memset(a_BlockTypes, E_BLOCK_AIR, sizeof(a_BlockTypes));
|
|
|
|
memset(a_BlockMeta, 0, sizeof(a_BlockMeta));
|
|
|
|
for (int z = 0; z < cChunkDef::Width; z++)
|
|
|
|
{
|
|
|
|
for (int x = 0; x < cChunkDef::Width; x++)
|
|
|
|
{
|
|
|
|
int Start;
|
|
|
|
if (m_IsBedrocked)
|
|
|
|
{
|
|
|
|
a_BlockTypes[cChunkDef::MakeIndex(x, 0, z)] = E_BLOCK_BEDROCK;
|
|
|
|
Start = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Start = 0;
|
|
|
|
}
|
|
|
|
for (int y = a_HeightMap[x + cChunkDef::Width * z]; y >= Start; y--)
|
|
|
|
{
|
|
|
|
a_BlockTypes[cChunkDef::MakeIndex(x, y, z)] = m_BlockType;
|
|
|
|
} // for y
|
|
|
|
} // for z
|
|
|
|
} // for x
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// cCompoGenDebugBiomes:
|
|
|
|
|
|
|
|
void cCompoGenDebugBiomes::ComposeTerrain(
|
|
|
|
int a_ChunkX, int a_ChunkZ,
|
|
|
|
cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated
|
|
|
|
cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated
|
|
|
|
const cChunkDef::HeightMap & a_HeightMap, // The height map to fit
|
|
|
|
cEntityList & a_Entities, // Entitites may be generated along with the terrain
|
|
|
|
cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...)
|
|
|
|
)
|
|
|
|
{
|
2012-05-27 10:05:36 -04:00
|
|
|
static BLOCKTYPE Blocks[] =
|
|
|
|
{
|
|
|
|
E_BLOCK_STONE,
|
|
|
|
E_BLOCK_COBBLESTONE,
|
|
|
|
E_BLOCK_LOG,
|
|
|
|
E_BLOCK_PLANKS,
|
|
|
|
E_BLOCK_SANDSTONE,
|
|
|
|
E_BLOCK_WHITE_CLOTH,
|
|
|
|
E_BLOCK_COAL_ORE,
|
|
|
|
E_BLOCK_IRON_ORE,
|
|
|
|
E_BLOCK_GOLD_ORE,
|
|
|
|
E_BLOCK_DIAMOND_ORE,
|
|
|
|
E_BLOCK_LAPIS_ORE,
|
|
|
|
E_BLOCK_REDSTONE_ORE,
|
|
|
|
E_BLOCK_IRON_BLOCK,
|
|
|
|
E_BLOCK_GOLD_BLOCK,
|
|
|
|
E_BLOCK_DIAMOND_BLOCK,
|
|
|
|
E_BLOCK_LAPIS_BLOCK,
|
|
|
|
E_BLOCK_BRICK,
|
|
|
|
E_BLOCK_MOSSY_COBBLESTONE,
|
|
|
|
E_BLOCK_OBSIDIAN,
|
|
|
|
E_BLOCK_NETHERRACK,
|
|
|
|
E_BLOCK_SOULSAND,
|
|
|
|
E_BLOCK_NETHER_BRICK,
|
|
|
|
E_BLOCK_BEDROCK,
|
|
|
|
} ;
|
|
|
|
|
2012-05-25 03:18:52 -04:00
|
|
|
memset(a_BlockTypes, E_BLOCK_AIR, sizeof(a_BlockTypes));
|
|
|
|
memset(a_BlockMeta, 0, sizeof(a_BlockMeta));
|
|
|
|
|
|
|
|
cChunkDef::BiomeMap BiomeMap;
|
|
|
|
m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, BiomeMap);
|
|
|
|
|
|
|
|
for (int z = 0; z < cChunkDef::Width; z++)
|
|
|
|
{
|
|
|
|
for (int x = 0; x < cChunkDef::Width; x++)
|
|
|
|
{
|
2012-05-27 10:05:36 -04:00
|
|
|
BLOCKTYPE BlockType = Blocks[cChunkDef::GetBiome(BiomeMap, x, z) % ARRAYCOUNT(Blocks)];
|
2012-05-25 03:18:52 -04:00
|
|
|
for (int y = a_HeightMap[x + cChunkDef::Width * z]; y >= 0; y--)
|
|
|
|
{
|
|
|
|
cChunkDef::SetBlock(a_BlockTypes, x, y, z, BlockType);
|
|
|
|
} // for y
|
|
|
|
} // for z
|
|
|
|
} // for x
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// cCompoGenClassic:
|
|
|
|
|
|
|
|
cCompoGenClassic::cCompoGenClassic(int a_SeaLevel, int a_BeachHeight, int a_BeachDepth) :
|
|
|
|
m_SeaLevel(a_SeaLevel),
|
|
|
|
m_BeachHeight(a_BeachHeight),
|
|
|
|
m_BeachDepth(a_BeachDepth)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cCompoGenClassic::ComposeTerrain(
|
|
|
|
int a_ChunkX, int a_ChunkZ,
|
|
|
|
cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated
|
|
|
|
cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated
|
|
|
|
const cChunkDef::HeightMap & a_HeightMap, // The height map to fit
|
|
|
|
cEntityList & a_Entities, // Entitites may be generated along with the terrain
|
|
|
|
cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...)
|
|
|
|
)
|
|
|
|
{
|
|
|
|
/* The classic composition means:
|
|
|
|
- 1 layer of grass, 3 of dirt and the rest stone, if the height > sealevel + beachheight
|
|
|
|
- 3 sand and a 1 sandstone, rest stone if between sealevel and sealevel + beachheight
|
|
|
|
- water from waterlevel to height, then 3 sand, 1 sandstone, the rest stone, if water depth < beachdepth
|
|
|
|
- water from waterlevel, then 3 dirt, the rest stone otherwise
|
|
|
|
- bedrock at the bottom
|
|
|
|
*/
|
|
|
|
|
|
|
|
memset(a_BlockTypes, E_BLOCK_AIR, sizeof(a_BlockTypes));
|
|
|
|
memset(a_BlockMeta, 0, sizeof(a_BlockMeta));
|
|
|
|
|
|
|
|
// The patterns to use for different situations, must be same length!
|
|
|
|
static const BLOCKTYPE PatternGround[] = {E_BLOCK_GRASS, E_BLOCK_DIRT, E_BLOCK_DIRT, E_BLOCK_DIRT} ;
|
|
|
|
static const BLOCKTYPE PatternBeach[] = {E_BLOCK_SAND, E_BLOCK_SAND, E_BLOCK_SAND, E_BLOCK_SANDSTONE} ;
|
|
|
|
static const BLOCKTYPE PatternOcean[] = {E_BLOCK_DIRT, E_BLOCK_DIRT, E_BLOCK_DIRT, E_BLOCK_STONE} ;
|
|
|
|
static int PatternLength = ARRAYCOUNT(PatternGround);
|
|
|
|
ASSERT(ARRAYCOUNT(PatternGround) == ARRAYCOUNT(PatternBeach));
|
|
|
|
ASSERT(ARRAYCOUNT(PatternGround) == ARRAYCOUNT(PatternOcean));
|
|
|
|
|
|
|
|
for (int z = 0; z < cChunkDef::Width; z++)
|
|
|
|
{
|
|
|
|
for (int x = 0; x < cChunkDef::Width; x++)
|
|
|
|
{
|
|
|
|
int Height = a_HeightMap[x + cChunkDef::Width * z];
|
|
|
|
const BLOCKTYPE * Pattern;
|
|
|
|
if (Height > m_SeaLevel + m_BeachHeight)
|
|
|
|
{
|
|
|
|
Pattern = PatternGround;
|
|
|
|
}
|
|
|
|
else if (Height > m_SeaLevel - m_BeachDepth)
|
|
|
|
{
|
|
|
|
Pattern = PatternBeach;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Pattern = PatternOcean;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fill water from sealevel down to height (if any):
|
|
|
|
for (int y = m_SeaLevel; y >= Height; --y)
|
|
|
|
{
|
|
|
|
cChunkDef::SetBlock(a_BlockTypes, x, y, z, E_BLOCK_STATIONARY_WATER);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fill from height till the bottom:
|
|
|
|
for (int y = Height; y >= 1; y--)
|
|
|
|
{
|
|
|
|
cChunkDef::SetBlock(a_BlockTypes, x, y, z, (Height - y < PatternLength) ? Pattern[Height - y] : E_BLOCK_STONE);
|
|
|
|
}
|
|
|
|
|
|
|
|
// The last layer is always bedrock:
|
|
|
|
cChunkDef::SetBlock(a_BlockTypes, x, 0, z, E_BLOCK_BEDROCK);
|
|
|
|
} // for x
|
|
|
|
} // for z
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|