From fbabf9ee8c7f0940e6f7d01e0362849bf4f6396b Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Fri, 8 Jun 2012 12:16:39 +0000 Subject: [PATCH] Sugarcane and Pumpkins get placed (quite rarely) in the SprinkleSmallFoliage FinishGen git-svn-id: http://mc-server.googlecode.com/svn/trunk@576 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/CompoGen.cpp | 20 +++++---- source/CompoGen.h | 20 +++++---- source/FinishGen.cpp | 89 +++++++++++++++++++++++++++++++++++--- source/FinishGen.h | 10 ++++- source/cChunkGenerator.cpp | 36 ++++++++------- 5 files changed, 136 insertions(+), 39 deletions(-) diff --git a/source/CompoGen.cpp b/source/CompoGen.cpp index 44bfa3ad5..6cdf8f05e 100644 --- a/source/CompoGen.cpp +++ b/source/CompoGen.cpp @@ -119,18 +119,20 @@ void cCompoGenDebugBiomes::ComposeTerrain( /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cCompoGenClassic: -cCompoGenClassic::cCompoGenClassic(int a_SeaLevel, int a_BeachHeight, int a_BeachDepth, - BLOCKTYPE a_BlockTop, BLOCKTYPE a_BlockMiddle, BLOCKTYPE a_BlockBottom, - BLOCKTYPE a_BlockBeach, BLOCKTYPE a_BlockBeachBottom, BLOCKTYPE a_BlockSea) : +cCompoGenClassic::cCompoGenClassic( + int a_SeaLevel, int a_BeachHeight, int a_BeachDepth, + BLOCKTYPE a_BlockTop, BLOCKTYPE a_BlockMiddle, BLOCKTYPE a_BlockBottom, + BLOCKTYPE a_BlockBeach, BLOCKTYPE a_BlockBeachBottom, BLOCKTYPE a_BlockSea +) : m_SeaLevel(a_SeaLevel), m_BeachHeight(a_BeachHeight), m_BeachDepth(a_BeachDepth), - m_BlockTop(a_BlockTop), - m_BlockMiddle(a_BlockMiddle), - m_BlockBottom(a_BlockBottom), - m_BlockBeach(a_BlockBeach), - m_BlockBeachBottom(a_BlockBeachBottom), - m_BlockSea(a_BlockSea) + m_BlockTop(a_BlockTop), + m_BlockMiddle(a_BlockMiddle), + m_BlockBottom(a_BlockBottom), + m_BlockBeach(a_BlockBeach), + m_BlockBeachBottom(a_BlockBeachBottom), + m_BlockSea(a_BlockSea) { } diff --git a/source/CompoGen.h b/source/CompoGen.h index 2a669f43b..e04494fd8 100644 --- a/source/CompoGen.h +++ b/source/CompoGen.h @@ -79,21 +79,23 @@ class cCompoGenClassic : public cTerrainCompositionGen { public: - cCompoGenClassic(int a_SeaLevel, int a_BeachHeight, int a_BeachDepth, - BLOCKTYPE a_BlockTop, BLOCKTYPE a_BlockMiddle, BLOCKTYPE a_BlockBottom, - BLOCKTYPE a_BlockBeach, BLOCKTYPE a_BlockBeachBottom, BLOCKTYPE a_BlockSea); + cCompoGenClassic( + int a_SeaLevel, int a_BeachHeight, int a_BeachDepth, + BLOCKTYPE a_BlockTop, BLOCKTYPE a_BlockMiddle, BLOCKTYPE a_BlockBottom, + BLOCKTYPE a_BlockBeach, BLOCKTYPE a_BlockBeachBottom, BLOCKTYPE a_BlockSea + ); protected: int m_SeaLevel; int m_BeachHeight; int m_BeachDepth; - BLOCKTYPE m_BlockTop; - BLOCKTYPE m_BlockMiddle; - BLOCKTYPE m_BlockBottom; - BLOCKTYPE m_BlockBeach; - BLOCKTYPE m_BlockBeachBottom; - BLOCKTYPE m_BlockSea; + BLOCKTYPE m_BlockTop; + BLOCKTYPE m_BlockMiddle; + BLOCKTYPE m_BlockBottom; + BLOCKTYPE m_BlockBeach; + BLOCKTYPE m_BlockBeachBottom; + BLOCKTYPE m_BlockSea; // cTerrainCompositionGen overrides: virtual void ComposeTerrain( diff --git a/source/FinishGen.cpp b/source/FinishGen.cpp index f4eb5ab10..9761d4373 100644 --- a/source/FinishGen.cpp +++ b/source/FinishGen.cpp @@ -17,9 +17,70 @@ +static inline bool IsWater(BLOCKTYPE a_BlockType) +{ + return (a_BlockType == E_BLOCK_STATIONARY_WATER) || (a_BlockType == E_BLOCK_WATER); +} + + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cFinishGenSprinkleFoliage: +bool cFinishGenSprinkleFoliage::TryAddSugarcane( + int a_ChunkX, int a_ChunkZ, + int a_RelX, int a_RelY, int a_RelZ, + cChunkDef::BlockTypes & a_BlockTypes, + cChunkDef::BlockNibbles & a_BlockMeta +) +{ + // We'll be doing comparison to neighbors, so require the coords to be 1 block away from the chunk edges: + if ( + (a_RelX < 1) || (a_RelX >= cChunkDef::Width - 1) || + (a_RelY < 1) || (a_RelY >= cChunkDef::Height - 2) || + (a_RelZ < 1) || (a_RelZ >= cChunkDef::Width - 1) + ) + { + return false; + } + + // Only allow dirt, grass or sand below sugarcane: + switch (cChunkDef::GetBlock(a_BlockTypes, a_RelX, a_RelY, a_RelZ)) + { + case E_BLOCK_DIRT: + case E_BLOCK_GRASS: + case E_BLOCK_SAND: + { + break; + } + default: + { + return false; + } + } + + // Water is required next to the block below the sugarcane: + if ( + !IsWater(cChunkDef::GetBlock(a_BlockTypes, a_RelX - 1, a_RelY, a_RelZ)) && + !IsWater(cChunkDef::GetBlock(a_BlockTypes, a_RelX + 1, a_RelY, a_RelZ)) && + !IsWater(cChunkDef::GetBlock(a_BlockTypes, a_RelX , a_RelY, a_RelZ - 1)) && + !IsWater(cChunkDef::GetBlock(a_BlockTypes, a_RelX , a_RelY, a_RelZ + 1)) + ) + { + return false; + } + + // All conditions met, place a sugarcane here: + cChunkDef::SetBlock(a_BlockTypes, a_RelX, a_RelY + 1, a_RelZ, E_BLOCK_SUGARCANE); + return true; +} + + + + + void cFinishGenSprinkleFoliage::GenFinish( int a_ChunkX, int a_ChunkZ, cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change @@ -88,18 +149,36 @@ void cFinishGenSprinkleFoliage::GenFinish( cChunkDef::SetBlock (a_BlockTypes, x, ++Top, z, E_BLOCK_TALL_GRASS); cChunkDef::SetNibble(a_BlockMeta, x, Top, z, E_META_TALL_GRASS_GRASS); } + else if (TryAddSugarcane(a_ChunkX, a_ChunkZ, x, Top, z, a_BlockTypes, a_BlockMeta)) + { + ++Top; + } + else if ((val1 > 0.5) && (val2 < -0.5)) + { + cChunkDef::SetBlock (a_BlockTypes, x, ++Top, z, E_BLOCK_PUMPKIN); + cChunkDef::SetNibble(a_BlockMeta, x, Top, z, (int)(val3 * 8) % 4); + } break; } // case E_BLOCK_GRASS case E_BLOCK_SAND: { - if (val1 + val2 > 0.f) + int y = Top + 1; + if ( + (x > 0) && (x < cChunkDef::Width - 1) && + (z > 0) && (z < cChunkDef::Width - 1) && + (val1 + val2 > 0.5f) && + (cChunkDef::GetBlock(a_BlockTypes, x + 1, y, z) == E_BLOCK_AIR) && + (cChunkDef::GetBlock(a_BlockTypes, x - 1, y, z) == E_BLOCK_AIR) && + (cChunkDef::GetBlock(a_BlockTypes, x, y, z + 1) == E_BLOCK_AIR) && + (cChunkDef::GetBlock(a_BlockTypes, x, y, z - 1) == E_BLOCK_AIR) + ) { cChunkDef::SetBlock(a_BlockTypes, x, ++Top, z, E_BLOCK_CACTUS); - if (val1 > val2) - { - cChunkDef::SetBlock(a_BlockTypes, x, ++Top, z, E_BLOCK_CACTUS); - } + } + else if (TryAddSugarcane(a_ChunkX, a_ChunkZ, x, Top, z, a_BlockTypes, a_BlockMeta)) + { + ++Top; } break; } diff --git a/source/FinishGen.h b/source/FinishGen.h index 2391d1638..816e2ca7c 100644 --- a/source/FinishGen.h +++ b/source/FinishGen.h @@ -64,7 +64,15 @@ public: protected: int m_Seed; - + + /// Tries to place sugarcane at the coords specified, returns true if successful + bool TryAddSugarcane( + int a_ChunkX, int a_ChunkZ, + int a_RelX, int a_RelY, int a_RelZ, // relative block coords of the sugarcane's base + cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change + cChunkDef::BlockNibbles & a_BlockMeta // Block meta to read and change + ); + // cFinishGen override: virtual void GenFinish( int a_ChunkX, int a_ChunkZ, diff --git a/source/cChunkGenerator.cpp b/source/cChunkGenerator.cpp index d595f333f..7a1e4ad14 100644 --- a/source/cChunkGenerator.cpp +++ b/source/cChunkGenerator.cpp @@ -224,19 +224,23 @@ void cChunkGenerator::InitHeightGen(cIniFile & a_IniFile) + + BLOCKTYPE ResolveBlock(AString BlockType, BLOCKTYPE DefaultBlock) { - int Block = BlockStringToType(BlockType); - if(Block < 0) - { - LOGWARN("[Generator] Could not parse block value \"%s\". Using default.", BlockType.c_str()); - return DefaultBlock; - } - return (BLOCKTYPE) Block; + int Block = BlockStringToType(BlockType); + if(Block < 0) + { + LOGWARN("[Generator] Could not parse block value \"%s\". Using default.", BlockType.c_str()); + return DefaultBlock; + } + return (BLOCKTYPE) Block; } + + void cChunkGenerator::InitCompositionGen(cIniFile & a_IniFile) { AString CompoGenName = a_IniFile.GetValue("Generator", "CompositionGen", ""); @@ -271,14 +275,16 @@ void cChunkGenerator::InitCompositionGen(cIniFile & a_IniFile) int SeaLevel = a_IniFile.GetValueI("Generator", "ClassicSeaLevel", 60); int BeachHeight = a_IniFile.GetValueI("Generator", "ClassicBeachHeight", 2); int BeachDepth = a_IniFile.GetValueI("Generator", "ClassicBeachDepth", 4); - BLOCKTYPE BlockTop = ResolveBlock(a_IniFile.GetValue("Generator", "ClassicBlockTop", "grass"), E_BLOCK_GRASS); - BLOCKTYPE BlockMiddle = ResolveBlock(a_IniFile.GetValue("Generator", "ClassicBlockMiddle", "dirt"), E_BLOCK_DIRT); - BLOCKTYPE BlockBottom = ResolveBlock(a_IniFile.GetValue("Generator", "ClassicBlockBottom", "stone"), E_BLOCK_STONE); - BLOCKTYPE BlockBeach = ResolveBlock(a_IniFile.GetValue("Generator", "ClassicBlockBeach", "sand"), E_BLOCK_SAND); - BLOCKTYPE BlockBeachBottom = ResolveBlock(a_IniFile.GetValue("Generator", "ClassicBlockBeachBottom", "sandstone"), E_BLOCK_SANDSTONE); - BLOCKTYPE BlockSea = ResolveBlock(a_IniFile.GetValue("Generator", "ClassicBlockSea", "9"), E_BLOCK_STATIONARY_WATER); - m_CompositionGen = new cCompoGenClassic(SeaLevel, BeachHeight, BeachDepth, BlockTop, BlockMiddle, BlockBottom, BlockBeach, - BlockBeachBottom, BlockSea); + BLOCKTYPE BlockTop = ResolveBlock(a_IniFile.GetValue("Generator", "ClassicBlockTop", "grass"), E_BLOCK_GRASS); + BLOCKTYPE BlockMiddle = ResolveBlock(a_IniFile.GetValue("Generator", "ClassicBlockMiddle", "dirt"), E_BLOCK_DIRT); + BLOCKTYPE BlockBottom = ResolveBlock(a_IniFile.GetValue("Generator", "ClassicBlockBottom", "stone"), E_BLOCK_STONE); + BLOCKTYPE BlockBeach = ResolveBlock(a_IniFile.GetValue("Generator", "ClassicBlockBeach", "sand"), E_BLOCK_SAND); + BLOCKTYPE BlockBeachBottom = ResolveBlock(a_IniFile.GetValue("Generator", "ClassicBlockBeachBottom", "sandstone"), E_BLOCK_SANDSTONE); + BLOCKTYPE BlockSea = ResolveBlock(a_IniFile.GetValue("Generator", "ClassicBlockSea", "9"), E_BLOCK_STATIONARY_WATER); + m_CompositionGen = new cCompoGenClassic( + SeaLevel, BeachHeight, BeachDepth, BlockTop, BlockMiddle, BlockBottom, BlockBeach, + BlockBeachBottom, BlockSea + ); } else {