Пример #1
0
void cCompoGenBiomal::FillColumnMycelium (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes)
{
	BLOCKTYPE Pattern[] =
	{
		E_BLOCK_MYCELIUM,
		E_BLOCK_DIRT,
		E_BLOCK_DIRT,
		E_BLOCK_DIRT,
	} ;
	FillColumnPattern(a_RelX, a_RelZ, a_Height, a_BlockTypes, Pattern, ARRAYCOUNT(Pattern));
	
	for (int y = a_Height - ARRAYCOUNT(Pattern); y > 0; y--)
	{
		cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE);
	}
}
Пример #2
0
void cCompoGenBiomal::FillColumnClay(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes)
{
	BLOCKTYPE Pattern[] =
	{
		E_BLOCK_HARDENED_CLAY,
		E_BLOCK_HARDENED_CLAY,
		E_BLOCK_HARDENED_CLAY,
		E_BLOCK_HARDENED_CLAY,
	} ;
	FillColumnPattern(a_RelX, a_RelZ, a_Height, a_BlockTypes, Pattern, ARRAYCOUNT(Pattern));
	
	for (int y = a_Height - ARRAYCOUNT(Pattern); y > 0; y--)
	{
		cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE);
	}
}
Пример #3
0
void cCompoGenBiomal::FillColumnWaterDirt(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes)
{
	// Dirt
	BLOCKTYPE Pattern[] =
	{
		E_BLOCK_DIRT,
		E_BLOCK_DIRT,
		E_BLOCK_DIRT,
		E_BLOCK_DIRT,
	} ;
	FillColumnPattern(a_RelX, a_RelZ, a_Height, a_BlockTypes, Pattern, ARRAYCOUNT(Pattern));

	for (int y = a_Height - ARRAYCOUNT(Pattern); y > 0; y--)
	{
		cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE);
	}
	for (int y = a_Height + 1; y <= m_SeaLevel + 1; y++)
	{
		cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STATIONARY_WATER);
	}
}
Пример #4
0
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);
}
Пример #5
0
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 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 biExtremeHillsPlus:
		case biExtremeHills:
		{
			// Select the pattern to use - 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.1) ? patStone.Get() : patGrass.Get();
			FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, Pattern);
			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.9) ? patStone.Get() : ((Val > 0) ? patGravel.Get() : patGrass.Get());
			FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, Pattern);
			return;
		}
		default:
		{
			ASSERT(!"Unhandled biome");
			return;
		}
	}  // switch (Biome)
}
Пример #6
0
	/** Fills the specified column with mesa pattern, based on the column height */
	void FillColumnMesa(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ, const Byte * a_ShapeColumn)
	{
		// 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 with red sand floor:
			FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patOFOrangeClay.Get(), a_ShapeColumn);
			return;
		}

		NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(a_ChunkDesc.GetChunkX() * cChunkDef::Width + a_RelX)) / FrequencyX;
		NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(a_ChunkDesc.GetChunkZ() * 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 PatternIdx = cChunkDef::Height - (Top - ClayFloor);  // We want the block at index ClayFloor to be pattern's 256th block (first stone)
		const cPattern::BlockInfo * Pattern = m_MesaPattern;
		bool HasHadWater = false;
		for (int y = Top; y > 0; y--)
		{
			if (a_ShapeColumn[y] > 0)
			{
				// "ground" part, use the pattern:
				a_ChunkDesc.SetBlockTypeMeta(a_RelX, y, a_RelZ, Pattern[PatternIdx].m_BlockType, Pattern[PatternIdx].m_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_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ(), a_RelX, a_RelZ);
			HasHadWater = true;
		}  // for y
		a_ChunkDesc.SetBlockType(a_RelX, 0, a_RelZ, E_BLOCK_BEDROCK);

		EMCSBiome MesaVersion = a_ChunkDesc.GetBiome(a_RelX, a_RelZ);
		if ((MesaVersion == biMesaPlateauF) || (MesaVersion == biMesaPlateauFM))
		{
			if (Top < 95 + static_cast<int>(m_MesaFloor.CubicNoise2D(NoiseY * 2, NoiseX * 2) * 6))
			{
				return;
			}

			BLOCKTYPE Block = (m_MesaFloor.CubicNoise2D(NoiseX * 4, NoiseY * 4) < 0) ? E_BLOCK_DIRT : E_BLOCK_GRASS;
			NIBBLETYPE Meta = (Block == E_BLOCK_GRASS) ? 0 : 1;

			a_ChunkDesc.SetBlockTypeMeta(a_RelX, Top, a_RelZ, Block, Meta);
		}
	}