Esempio n. 1
0
	/** Fills the specified column with the specified pattern; restarts the pattern when air is reached,
	switches to ocean floor pattern if ocean is reached. Always adds bedrock at the very bottom. */
	void FillColumnPattern(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ, const cPattern::BlockInfo * a_Pattern, const Byte * a_ShapeColumn)
	{
		bool HasHadWater = false;
		int PatternIdx = 0;
		HEIGHTTYPE top = std::max(m_SeaLevel, a_ChunkDesc.GetHeight(a_RelX, a_RelZ));
		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, a_Pattern[PatternIdx].m_BlockType, a_Pattern[PatternIdx].m_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:
			if (a_ChunkDesc.GetBiome(a_RelX, a_RelZ) == biDeepOcean)
			{
				a_Pattern = patGravel.Get();
			}
			else
			{
				a_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);
	}
Esempio n. 2
0
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 = ChooseOceanFloorPattern(a_RelX, a_RelZ);
		HasHadWater = true;
	}  // for y
	a_ChunkDesc.SetBlockType(a_RelX, 0, a_RelZ, E_BLOCK_BEDROCK);
}
Esempio n. 3
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);
}
Esempio n. 4
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);
		}
	}