void cEndGen::ComposeTerrain(cChunkDesc & a_ChunkDesc) { if (IsChunkOutsideRange(a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ())) { a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0); return; } PrepareState(a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ()); int MaxY = std::min((int)(1.75 * m_IslandSizeY + 1), cChunkDef::Height - 1); for (int z = 0; z < cChunkDef::Width; z++) { for (int x = 0; x < cChunkDef::Width; x++) { for (int y = MaxY; y > 0; y--) { if (m_NoiseArray[y * 17 * 17 + z * 17 + x] <= 0) { a_ChunkDesc.SetBlockTypeMeta(x, y, z, E_BLOCK_END_STONE, 0); } else { a_ChunkDesc.SetBlockTypeMeta(x, y, z, E_BLOCK_AIR, 0); } } // for y } // for x } // for z }
void cCompoGenSameBlock::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) { a_ChunkDesc.SetHeightFromShape(a_Shape); a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0); for (int z = 0; z < cChunkDef::Width; z++) { for (int x = 0; x < cChunkDef::Width; x++) { int Start; if (m_IsBedrocked) { a_ChunkDesc.SetBlockType(x, 0, z, E_BLOCK_BEDROCK); Start = 1; } else { Start = 0; } for (int y = a_ChunkDesc.GetHeight(x, z); y >= Start; y--) { a_ChunkDesc.SetBlockType(x, y, z, m_BlockType); } // for y } // for z } // for x }
void cCompoGenClassic::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) { /* 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 */ a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0); a_ChunkDesc.SetHeightFromShape(a_Shape); // The patterns to use for different situations, must be same length! const BLOCKTYPE PatternGround[] = {m_BlockTop, m_BlockMiddle, m_BlockMiddle, m_BlockMiddle} ; const BLOCKTYPE PatternBeach[] = {m_BlockBeach, m_BlockBeach, m_BlockBeach, m_BlockBeachBottom} ; const BLOCKTYPE PatternOcean[] = {m_BlockMiddle, m_BlockMiddle, m_BlockMiddle, m_BlockBottom} ; 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_ChunkDesc.GetHeight(x, 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) { a_ChunkDesc.SetBlockType(x, y, z, m_BlockSea); } // Fill from height till the bottom: for (int y = Height; y >= 1; y--) { a_ChunkDesc.SetBlockType(x, y, z, (Height - y < PatternLength) ? Pattern[Height - y] : m_BlockBottom); } // The last layer is always bedrock: a_ChunkDesc.SetBlockType(x, 0, z, E_BLOCK_BEDROCK); } // for x } // for z }
// cTerrainCompositionGen overrides: virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) override { 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, &(a_Shape[x * 256 + z * 16 * 256])); } // for x } // for z }
void cNoise3DComposable::ComposeTerrain(cChunkDesc & a_ChunkDesc) { GenerateNoiseArrayIfNeeded(a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ()); a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0); // Make basic terrain composition: for (int z = 0; z < cChunkDef::Width; z++) { for (int x = 0; x < cChunkDef::Width; x++) { int LastAir = a_ChunkDesc.GetHeight(x, z) + 1; bool HasHadWater = false; for (int y = LastAir; y < m_SeaLevel; y++) { a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_STATIONARY_WATER); } for (int y = LastAir - 1; y > 0; y--) { if (m_NoiseArray[x + 17 * z + 17 * 17 * y] > m_AirThreshold) { // "air" part LastAir = y; if (y < m_SeaLevel) { a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_STATIONARY_WATER); HasHadWater = true; } continue; } // "ground" part: if (LastAir - y > 4) { a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_STONE); continue; } if (HasHadWater) { a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_SAND); } else { a_ChunkDesc.SetBlockType(x, y, z, (LastAir == y + 1) ? E_BLOCK_GRASS : E_BLOCK_DIRT); } } // for y a_ChunkDesc.SetBlockType(x, 0, z, E_BLOCK_BEDROCK); } // for x } // for z }
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 cCompoGenDebugBiomes::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) { static BLOCKTYPE Blocks[] = { E_BLOCK_STONE, E_BLOCK_COBBLESTONE, E_BLOCK_LOG, E_BLOCK_PLANKS, E_BLOCK_SANDSTONE, E_BLOCK_WOOL, 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, } ; a_ChunkDesc.SetHeightFromShape(a_Shape); a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0); for (int z = 0; z < cChunkDef::Width; z++) { for (int x = 0; x < cChunkDef::Width; x++) { BLOCKTYPE BlockType = Blocks[a_ChunkDesc.GetBiome(x, z)]; for (int y = a_ChunkDesc.GetHeight(x, z); y >= 0; y--) { a_ChunkDesc.SetBlockType(x, y, z, BlockType); } // for y } // for z } // for x }
void cDistortedHeightmap::ComposeTerrain(cChunkDesc & a_ChunkDesc) { // Frequencies for the ocean floor selecting noise: NOISE_DATATYPE FrequencyX = 3; NOISE_DATATYPE FrequencyZ = 3; // 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++) { int NoiseArrayIdx = x + 17 * 257 * z; int LastAir = a_ChunkDesc.GetHeight(x, z) + 1; bool HasHadWater = false; for (int y = LastAir - 1; y > 0; y--) { int HeightMapHeight = (int)m_DistortedHeightmap[NoiseArrayIdx + 17 * y]; if (y >= HeightMapHeight) { // "air" part LastAir = y; if (y < m_SeaLevel) { a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_STATIONARY_WATER); HasHadWater = true; } continue; } // "ground" part: if (y < LastAir - 4) { a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_STONE); continue; } if (HasHadWater) { // Decide between clay, sand and dirt NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(m_CurChunkX * cChunkDef::Width + x)) / FrequencyX; NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(m_CurChunkZ * cChunkDef::Width + z)) / FrequencyZ; NOISE_DATATYPE Val = m_OceanFloorSelect.CubicNoise2D(NoiseX, NoiseY); if (Val < -0.95) { // Clay: switch (LastAir - y) { case 0: case 1: { a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_CLAY); break; } case 2: case 3: { a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_SAND); break; } case 4: { a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_SANDSTONE); break; } } // switch (floor depth) } else if (Val < 0) { a_ChunkDesc.SetBlockType(x, y, z, (y < LastAir - 3) ? E_BLOCK_SANDSTONE : E_BLOCK_SAND); } else { a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_DIRT); } } else { switch (a_ChunkDesc.GetBiome(x, z)) { case biOcean: case biPlains: case biExtremeHills: 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: { a_ChunkDesc.SetBlockType(x, y, z, (y == LastAir - 1) ? E_BLOCK_GRASS : E_BLOCK_DIRT); break; } case biDesertHills: case biDesert: case biBeach: { a_ChunkDesc.SetBlockType(x, y, z, (y < LastAir - 3) ? E_BLOCK_SANDSTONE : E_BLOCK_SAND); break; } case biMushroomIsland: case biMushroomShore: { a_ChunkDesc.SetBlockType(x, y, z, (y == LastAir - 1) ? E_BLOCK_MYCELIUM : E_BLOCK_DIRT); break; } } } } // for y a_ChunkDesc.SetBlockType(x, 0, z, E_BLOCK_BEDROCK); } // for x } // for z }
void cCompoGenBiomal::ComposeTerrain(cChunkDesc & a_ChunkDesc) { a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0); int ChunkX = a_ChunkDesc.GetChunkX(); int ChunkZ = a_ChunkDesc.GetChunkZ(); /* _X 2013_04_22: There's no point in generating the whole cubic noise at once, because the noise values are used in only about 20 % of the cases, so the speed gained by precalculating is lost by precalculating too much data */ for (int z = 0; z < cChunkDef::Width; z++) { for (int x = 0; x < cChunkDef::Width; x++) { int Height = a_ChunkDesc.GetHeight(x, z); if (Height > m_SeaLevel) { switch (a_ChunkDesc.GetBiome(x, z)) { case biOcean: case biPlains: case biExtremeHills: 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 biExtremeHillsPlus: case biSavanna: case biSavannaPlateau: case biSunflowerPlains: case biExtremeHillsM: case biFlowerForest: case biTaigaM: case biSwamplandM: case biIcePlainsSpikes: case biJungleM: case biJungleEdgeM: case biBirchForestM: case biBirchForestHillsM: case biRoofedForestM: case biColdTaigaM: case biExtremeHillsPlusM: case biSavannaM: case biSavannaPlateauM: { FillColumnGrass(x, z, Height, a_ChunkDesc.GetBlockTypes()); break; } case biMesa: case biMesaPlateauF: case biMesaPlateau: case biMesaBryce: case biMesaPlateauFM: case biMesaPlateauM: { FillColumnClay(x, z, Height, a_ChunkDesc.GetBlockTypes()); break; } case biMegaTaiga: case biMegaTaigaHills: case biMegaSpruceTaiga: case biMegaSpruceTaigaHills: { FillColumnDirt(x, z, Height, a_ChunkDesc.GetBlockTypes()); break; } case biDesertHills: case biDesert: case biDesertM: case biBeach: { FillColumnSand(x, z, Height, a_ChunkDesc.GetBlockTypes()); break; } case biMushroomIsland: case biMushroomShore: { FillColumnMycelium(x, z, Height, a_ChunkDesc.GetBlockTypes()); break; } default: { // TODO ASSERT(!"CompoGenBiomal: Biome not implemented yet!"); break; } } } else { switch (a_ChunkDesc.GetBiome(x, z)) { case biDesert: case biBeach: { // Fill with water, sand, sandstone and stone FillColumnWaterSand(x, z, Height, a_ChunkDesc.GetBlockTypes()); break; } default: { // Fill with water, sand/dirt/clay mix and stone if (m_Noise.CubicNoise2D(0.3f * (cChunkDef::Width * ChunkX + x), 0.3f * (cChunkDef::Width * ChunkZ + z)) < 0) { FillColumnWaterSand(x, z, Height, a_ChunkDesc.GetBlockTypes()); } else { FillColumnWaterDirt(x, z, Height, a_ChunkDesc.GetBlockTypes()); } break; } } // switch (biome) a_ChunkDesc.SetHeight(x, z, m_SeaLevel + 1); } // else (under water) a_ChunkDesc.SetBlockType(x, 0, z, E_BLOCK_BEDROCK); } // for x } // for z }