From a7c87e92ce35092f3abd1ea59ba15ea7cb369343 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Sat, 2 Jun 2012 20:44:15 +0000 Subject: Added the Biomal composition generator. git-svn-id: http://mc-server.googlecode.com/svn/trunk@541 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/CompoGen.cpp | 225 ++++++++++++++++++++++++++++++++++++++++++++- source/CompoGen.h | 49 +++++++++- source/StructGen.cpp | 7 +- source/cChunkGenerator.cpp | 19 ++-- source/cChunkGenerator.h | 1 + 5 files changed, 283 insertions(+), 18 deletions(-) (limited to 'source') diff --git a/source/CompoGen.cpp b/source/CompoGen.cpp index f340e0ad4..7487d223b 100644 --- a/source/CompoGen.cpp +++ b/source/CompoGen.cpp @@ -23,6 +23,7 @@ void cCompoGenSameBlock::ComposeTerrain( 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 + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to cEntityList & a_Entities, // Entitites may be generated along with the terrain cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) ) @@ -63,6 +64,7 @@ void cCompoGenDebugBiomes::ComposeTerrain( 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 + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to cEntityList & a_Entities, // Entitites may be generated along with the terrain cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) ) @@ -97,14 +99,11 @@ void cCompoGenDebugBiomes::ComposeTerrain( 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++) { - BLOCKTYPE BlockType = Blocks[cChunkDef::GetBiome(BiomeMap, x, z) % ARRAYCOUNT(Blocks)]; + BLOCKTYPE BlockType = Blocks[cChunkDef::GetBiome(a_BiomeMap, x, z) % ARRAYCOUNT(Blocks)]; for (int y = a_HeightMap[x + cChunkDef::Width * z]; y >= 0; y--) { cChunkDef::SetBlock(a_BlockTypes, x, y, z, BlockType); @@ -136,6 +135,7 @@ void cCompoGenClassic::ComposeTerrain( 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 + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to cEntityList & a_Entities, // Entitites may be generated along with the terrain cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) ) @@ -163,7 +163,7 @@ void cCompoGenClassic::ComposeTerrain( { for (int x = 0; x < cChunkDef::Width; x++) { - int Height = a_HeightMap[x + cChunkDef::Width * z]; + int Height = cChunkDef::GetHeight(a_HeightMap, x, z); const BLOCKTYPE * Pattern; if (Height > m_SeaLevel + m_BeachHeight) { @@ -199,3 +199,218 @@ void cCompoGenClassic::ComposeTerrain( + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cCompoGenBiomal: + +void cCompoGenBiomal::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 + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entitites may be generated along with the terrain + cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) +) +{ + memset(a_BlockTypes, 0, 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 Height = cChunkDef::GetHeight(a_HeightMap, x, z); + if (Height > m_SeaLevel) + { + switch (cChunkDef::GetBiome(a_BiomeMap, 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 biDesertHills: + case biForestHills: + case biTaigaHills: + case biExtremeHillsEdge: + case biJungle: + case biJungleHills: + { + FillColumnGrass(x, z, Height, a_BlockTypes); + break; + } + case biDesert: + case biBeach: + { + FillColumnSand(x, z, Height, a_BlockTypes); + break; + } + case biMushroomIsland: + case biMushroomShore: + { + FillColumnMycelium(x, z, Height, a_BlockTypes); + break; + } + default: + { + // TODO + ASSERT(!"CompoGenBiomal: Biome not implemented yet!"); + break; + } + } + } + else + { + switch (cChunkDef::GetBiome(a_BiomeMap, x, z)) + { + case biDesert: + case biBeach: + { + // Fill with water, sand, sandstone and stone + FillColumnWaterSand(x, z, Height, a_BlockTypes); + break; + } + default: + { + // Fill with water, sand/dirt/clay mix and stone + FillColumnWaterMix(a_ChunkX, a_ChunkZ, x, z, Height, a_BlockTypes); + break; + } + } + } + } + } +} + + + + + +void cCompoGenBiomal::FillColumnGrass(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) +{ + BLOCKTYPE Pattern[] = + { + E_BLOCK_GRASS, + 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); + } +} + + + + + +void cCompoGenBiomal::FillColumnSand(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) +{ + BLOCKTYPE Pattern[] = + { + E_BLOCK_SAND, + E_BLOCK_SAND, + E_BLOCK_SAND, + E_BLOCK_SANDSTONE, + } ; + 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); + } +} + + + + + + +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); + } +} + + + + + +void cCompoGenBiomal::FillColumnWaterSand(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) +{ + FillColumnSand(a_RelX, a_RelZ, a_Height, a_BlockTypes); + for (int y = a_Height + 1; y <= m_SeaLevel + 1; y++) + { + cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_WATER); + } +} + + + + + +void cCompoGenBiomal::FillColumnWaterMix(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes) +{ + if (m_Noise.CubicNoise2D(0.5f * (cChunkDef::Width * a_ChunkX + a_RelX), 0.5f * (cChunkDef::Width * a_ChunkZ + a_RelZ)) < 0) + { + FillColumnWaterSand(a_RelX, a_RelZ, a_Height, a_BlockTypes); + } + else + { + // 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_WATER); + } + } +} + + + + + + +void cCompoGenBiomal::FillColumnPattern(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes, const BLOCKTYPE * a_Pattern, int a_PatternSize) +{ + for (int y = a_Height, idx = 0; (y >= 0) && (idx < a_PatternSize); y--, idx++) + { + cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, a_Pattern[idx]); + } +} + + + + diff --git a/source/CompoGen.h b/source/CompoGen.h index a3a524533..74e38757b 100644 --- a/source/CompoGen.h +++ b/source/CompoGen.h @@ -5,6 +5,7 @@ - cCompoGenSameBlock - cCompoGenDebugBiomes - cCompoGenClassic + - cCompoGenBiomal */ @@ -14,6 +15,7 @@ #pragma once #include "cChunkGenerator.h" +#include "cNoise.h" @@ -39,6 +41,7 @@ protected: 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 + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to cEntityList & a_Entities, // Entitites may be generated along with the terrain cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) ) override; @@ -52,11 +55,9 @@ class cCompoGenDebugBiomes : public cTerrainCompositionGen { public: - cCompoGenDebugBiomes(cBiomeGen * a_BiomeGen) : m_BiomeGen(a_BiomeGen) {} + cCompoGenDebugBiomes(void) {} protected: - - cBiomeGen * m_BiomeGen; // cTerrainCompositionGen overrides: virtual void ComposeTerrain( @@ -64,6 +65,7 @@ protected: 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 + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to cEntityList & a_Entities, // Entitites may be generated along with the terrain cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) ) override; @@ -91,9 +93,50 @@ protected: 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 + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to + cEntityList & a_Entities, // Entitites may be generated along with the terrain + cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) + ) override; +} ; + + + + + +class cCompoGenBiomal : + public cTerrainCompositionGen +{ +public: + cCompoGenBiomal(int a_Seed, int a_SeaLevel) : + m_Noise(a_Seed + 1000), + m_SeaLevel(a_SeaLevel - 1) // we do an adjustment later in filling the terrain with water + { + } + +protected: + + cNoise m_Noise; + int m_SeaLevel; + + // cTerrainCompositionGen overrides: + virtual void 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 + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to cEntityList & a_Entities, // Entitites may be generated along with the terrain cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) ) override; + + void FillColumnGrass (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); + void FillColumnSand (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); + void FillColumnMycelium (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); + void FillColumnWaterSand(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); + + void FillColumnWaterMix (int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes); + + void FillColumnPattern (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes, const BLOCKTYPE * a_Pattern, int a_PatternSize); } ; diff --git a/source/StructGen.cpp b/source/StructGen.cpp index a15b0bcb9..5f1d9da74 100644 --- a/source/StructGen.cpp +++ b/source/StructGen.cpp @@ -82,6 +82,9 @@ void cStructGenTrees::GenStructures( cChunkDef::BlockNibbles * BlM; cChunkDef::HeightMap * Hei; + cChunkDef::BiomeMap Biomes; + m_BiomeGen->GenBiomes(BaseX, BaseZ, Biomes); + if ((x != 1) || (z != 1)) { BlT = &WorkerBlockTypes; @@ -89,7 +92,7 @@ void cStructGenTrees::GenStructures( Hei = &WorkerHeight; m_HeightGen->GenHeightMap (BaseX, BaseZ, *Hei); - m_CompositionGen->ComposeTerrain(BaseX, BaseZ, *BlT, *BlM, *Hei, Entities, BlockEntities); + m_CompositionGen->ComposeTerrain(BaseX, BaseZ, *BlT, *BlM, *Hei, Biomes, Entities, BlockEntities); // TODO: Free the entity lists } else @@ -99,8 +102,6 @@ void cStructGenTrees::GenStructures( Hei = &a_HeightMap; } - cChunkDef::BiomeMap Biomes; - m_BiomeGen->GenBiomes(BaseX, BaseZ, Biomes); int NumTrees = GetNumTrees(BaseX, BaseZ, Biomes); for (int i = 0; i < NumTrees; i++) diff --git a/source/cChunkGenerator.cpp b/source/cChunkGenerator.cpp index 23d6b8422..31df6ba5d 100644 --- a/source/cChunkGenerator.cpp +++ b/source/cChunkGenerator.cpp @@ -251,19 +251,24 @@ void cChunkGenerator::InitCompositionGen(cIniFile & a_IniFile) } else if (NoCaseCompare(CompoGenName, "debugbiomes") == 0) { - m_CompositionGen = new cCompoGenDebugBiomes(m_BiomeGen); + m_CompositionGen = new cCompoGenDebugBiomes; } - else + else if (NoCaseCompare(CompoGenName, "classic") == 0) { - if (NoCaseCompare(CompoGenName, "classic") != 0) - { - LOGWARN("Unknown CompositionGen \"%s\", using \"classic\" instead.", CompoGenName.c_str()); - } int SeaLevel = a_IniFile.GetValueI("Generator", "ClassicSeaLevel", 60); int BeachHeight = a_IniFile.GetValueI("Generator", "ClassicBeachHeight", 2); int BeachDepth = a_IniFile.GetValueI("Generator", "ClassicBeachDepth", 4); m_CompositionGen = new cCompoGenClassic(SeaLevel, BeachHeight, BeachDepth); } + else + { + if (NoCaseCompare(CompoGenName, "biomal") != 0) + { + LOGWARN("Unknown CompositionGen \"%s\", using \"biomal\" instead.", CompoGenName.c_str()); + } + int SeaLevel = a_IniFile.GetValueI("Generator", "BiomalSeaLevel", 62); + m_CompositionGen = new cCompoGenBiomal(m_Seed, SeaLevel); + } } @@ -461,7 +466,7 @@ void cChunkGenerator::DoGenerate(int a_ChunkX, int a_ChunkY, int a_ChunkZ) // Use the composed generator: m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, BiomeMap); m_HeightGen->GenHeightMap(a_ChunkX, a_ChunkZ, HeightMap); - m_CompositionGen->ComposeTerrain(a_ChunkX, a_ChunkZ, BlockTypes, BlockMeta, HeightMap, Entities, BlockEntities); + m_CompositionGen->ComposeTerrain(a_ChunkX, a_ChunkZ, BlockTypes, BlockMeta, HeightMap, BiomeMap, Entities, BlockEntities); for (cStructureGenList::iterator itr = m_StructureGens.begin(); itr != m_StructureGens.end(); ++itr) { (*itr)->GenStructures(a_ChunkX, a_ChunkZ, BlockTypes, BlockMeta, HeightMap, Entities, BlockEntities); diff --git a/source/cChunkGenerator.h b/source/cChunkGenerator.h index 0cf11b74c..126d94fb8 100644 --- a/source/cChunkGenerator.h +++ b/source/cChunkGenerator.h @@ -93,6 +93,7 @@ public: cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated (the whole array gets initialized, even air) cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated (the whole array gets initialized) const cChunkDef::HeightMap & a_HeightMap, // The height map to fit + const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to cEntityList & a_Entities, // Entitites may be generated along with the terrain cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...) ) = 0; -- cgit v1.2.3