summaryrefslogtreecommitdiffstats
path: root/source/Generating
diff options
context:
space:
mode:
authormadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2013-03-14 10:52:57 +0100
committermadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2013-03-14 10:52:57 +0100
commitff403fdbf0b4c372057fc8369797ddf652cfd727 (patch)
tree0f9f22c6a8ea41e879cbd49011ccd2c9f25d2604 /source/Generating
parentChanged DelayedFluidSimulatorData to be a vector rather than a list, performance doubled :) (diff)
downloadcuberite-ff403fdbf0b4c372057fc8369797ddf652cfd727.tar
cuberite-ff403fdbf0b4c372057fc8369797ddf652cfd727.tar.gz
cuberite-ff403fdbf0b4c372057fc8369797ddf652cfd727.tar.bz2
cuberite-ff403fdbf0b4c372057fc8369797ddf652cfd727.tar.lz
cuberite-ff403fdbf0b4c372057fc8369797ddf652cfd727.tar.xz
cuberite-ff403fdbf0b4c372057fc8369797ddf652cfd727.tar.zst
cuberite-ff403fdbf0b4c372057fc8369797ddf652cfd727.zip
Diffstat (limited to 'source/Generating')
-rw-r--r--source/Generating/ComposableGenerator.cpp20
-rw-r--r--source/Generating/FinishGen.cpp175
-rw-r--r--source/Generating/FinishGen.h37
3 files changed, 229 insertions, 3 deletions
diff --git a/source/Generating/ComposableGenerator.cpp b/source/Generating/ComposableGenerator.cpp
index 0cd6bfb4f..e9196757b 100644
--- a/source/Generating/ComposableGenerator.cpp
+++ b/source/Generating/ComposableGenerator.cpp
@@ -24,6 +24,11 @@
+
+
+
+
+
cComposableGenerator::cComposableGenerator(cChunkGenerator & a_ChunkGenerator) :
super(a_ChunkGenerator),
m_BiomeGen(NULL),
@@ -308,7 +313,7 @@ void cComposableGenerator::InitStructureGens(cIniFile & a_IniFile)
AString Structures = a_IniFile.GetValueSet("Generator", "Structures", "Ravines,WormNestCaves,OreNests,Trees");
int Seed = m_ChunkGenerator.GetSeed();
- AStringVector Str = StringSplit(Structures, ",");
+ AStringVector Str = StringSplitAndTrim(Structures, ",");
for (AStringVector::const_iterator itr = Str.begin(); itr != Str.end(); ++itr)
{
if (NoCaseCompare(*itr, "trees") == 0)
@@ -355,13 +360,14 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
int Seed = m_ChunkGenerator.GetSeed();
AString Structures = a_IniFile.GetValueSet("Generator", "Finishers", "SprinkleFoliage,Ice,Snow,Lilypads,BottomLava,DeadBushes,PreSimulator");
- AStringVector Str = StringSplit(Structures, ",");
+ AStringVector Str = StringSplitAndTrim(Structures, ",");
for (AStringVector::const_iterator itr = Str.begin(); itr != Str.end(); ++itr)
{
// Finishers, alpha-sorted:
if (NoCaseCompare(*itr, "BottomLava") == 0)
{
- int BottomLavaLevel = a_IniFile.GetValueSetI("Generator", "BottomLavaLevel", 10);
+ int DefaultBottomLavaLevel = (m_World->GetDimension() == cWorld::dimNether) ? 30 : 10;
+ int BottomLavaLevel = a_IniFile.GetValueSetI("Generator", "BottomLavaLevel", DefaultBottomLavaLevel);
m_FinishGens.push_back(new cFinishGenBottomLava(BottomLavaLevel));
}
else if (NoCaseCompare(*itr, "DeadBushes") == 0)
@@ -372,6 +378,10 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
{
m_FinishGens.push_back(new cFinishGenIce);
}
+ else if (NoCaseCompare(*itr, "LavaSprings") == 0)
+ {
+ m_FinishGens.push_back(new cFinishGenFluidSprings(Seed, E_BLOCK_LAVA, a_IniFile, *m_World));
+ }
else if (NoCaseCompare(*itr, "Lilypads") == 0)
{
m_FinishGens.push_back(new cFinishGenLilypads(Seed));
@@ -388,6 +398,10 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
{
m_FinishGens.push_back(new cFinishGenSprinkleFoliage(Seed));
}
+ else if (NoCaseCompare(*itr, "WaterSprings") == 0)
+ {
+ m_FinishGens.push_back(new cFinishGenFluidSprings(Seed, E_BLOCK_WATER, a_IniFile, *m_World));
+ }
} // for itr - Str[]
}
diff --git a/source/Generating/FinishGen.cpp b/source/Generating/FinishGen.cpp
index 83788fcab..8c13b6158 100644
--- a/source/Generating/FinishGen.cpp
+++ b/source/Generating/FinishGen.cpp
@@ -13,6 +13,18 @@
#include "../Noise.h"
#include "../BlockID.h"
#include "../Simulator/FluidSimulator.h" // for cFluidSimulator::CanWashAway()
+#include "../World.h"
+
+
+
+
+
+#define DEF_NETHER_WATER_SPRINGS "0, 0; 255, 0"
+#define DEF_NETHER_LAVA_SPRINGS "0, 0; 30, 0; 31, 50; 120, 50; 127, 0"
+#define DEF_OVERWORLD_WATER_SPRINGS "0, 0; 10, 10; 11, 75; 16, 83; 20, 83; 24, 78; 32, 62; 40, 40; 44, 15; 48, 7; 56, 2; 64, 1; 255, 0"
+#define DEF_OVERWORLD_LAVA_SPRINGS "0, 0; 10, 5; 11, 45; 48, 2; 64, 1; 255, 0"
+#define DEF_END_WATER_SPRINGS "0, 0; 255, 0"
+#define DEF_END_LAVA_SPRINGS "0, 0; 255, 0"
@@ -629,3 +641,166 @@ void cFinishGenDeadBushes::GenFinish(
} // for i
}
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cFinishGenFluidSprings:
+
+cFinishGenFluidSprings::cFinishGenFluidSprings(int a_Seed, BLOCKTYPE a_Fluid, cIniFile & a_IniFile, const cWorld & a_World) :
+ m_Noise(a_Seed + a_Fluid * 100), // Need to take fluid into account, otherwise water and lava springs generate next to each other
+ m_HeightDistribution(255),
+ m_Fluid(a_Fluid)
+{
+ bool IsWater = (a_Fluid == E_BLOCK_WATER);
+ AString SectionName = IsWater ? "WaterSprings" : "LavaSprings";
+ AString DefaultHeightDistribution;
+ int DefaultChance;
+ switch (a_World.GetDimension())
+ {
+ case cWorld::dimNether:
+ {
+ DefaultHeightDistribution = IsWater ? DEF_NETHER_WATER_SPRINGS : DEF_NETHER_LAVA_SPRINGS;
+ DefaultChance = IsWater ? 0 : 15;
+ break;
+ }
+ case cWorld::dimOverworld:
+ {
+ DefaultHeightDistribution = IsWater ? DEF_OVERWORLD_WATER_SPRINGS : DEF_OVERWORLD_LAVA_SPRINGS;
+ DefaultChance = IsWater ? 24 : 9;
+ break;
+ }
+ case cWorld::dimEnd:
+ {
+ DefaultHeightDistribution = IsWater ? DEF_END_WATER_SPRINGS : DEF_END_LAVA_SPRINGS;
+ DefaultChance = 0;
+ break;
+ }
+ default:
+ {
+ ASSERT(!"Unhandled world dimension");
+ break;
+ }
+ } // switch (dimension)
+ AString HeightDistribution = a_IniFile.GetValueSet(SectionName, "HeightDistribution", DefaultHeightDistribution);
+ m_HeightDistribution.SetDefString(HeightDistribution);
+ m_Chance = a_IniFile.GetValueSetI(SectionName, "Chance", DefaultChance);
+}
+
+
+
+
+
+void cFinishGenFluidSprings::GenFinish(
+ int a_ChunkX, int a_ChunkZ,
+ cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change
+ cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change
+ cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data
+ const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to
+ cEntityList & a_Entities, // Entities may be added or deleted
+ cBlockEntityList & a_BlockEntities // Block entities may be added or deleted
+)
+{
+ int ChanceRnd = (m_Noise.IntNoise3DInt(128 * a_ChunkX, 512, 256 * a_ChunkZ) / 13) % 100;
+ if (ChanceRnd > m_Chance)
+ {
+ // Not in this chunk
+ return;
+ }
+
+ // Get the height at which to try:
+ int Height = m_Noise.IntNoise3DInt(128 * a_ChunkX, 512, 256 * a_ChunkZ) / 11;
+ Height %= m_HeightDistribution.GetSum();
+ Height = m_HeightDistribution.MapValue(Height);
+
+ // Try adding the spring at the height, if unsuccessful, move lower:
+ for (int y = Height; y > 1; y--)
+ {
+ // TODO: randomize the order in which the coords are being checked
+ for (int z = 1; z < cChunkDef::Width - 1; z++)
+ {
+ for (int x = 1; x < cChunkDef::Width - 1; x++)
+ {
+ switch (cChunkDef::GetBlock(a_BlockTypes, x, y, z))
+ {
+ case E_BLOCK_NETHERRACK:
+ {
+ if (m_Fluid != E_BLOCK_LAVA)
+ {
+ // Only lava springs in the netherrack
+ continue;
+ }
+ // fallthrough:
+ }
+ case E_BLOCK_STONE:
+ {
+ if (TryPlaceSpring(a_BlockTypes, a_BlockMeta, x, y, z))
+ {
+ // Succeeded, bail out
+ return;
+ }
+ }
+ } // switch (BlockType)
+ } // for x
+ } // for y
+ } // for y
+}
+
+
+
+
+
+bool cFinishGenFluidSprings::TryPlaceSpring(
+ cChunkDef::BlockTypes & a_BlockTypes,
+ cChunkDef::BlockNibbles & a_BlockMetas,
+ int x, int y, int z
+)
+{
+ // In order to place a spring, it needs exactly one of the XZ neighbors or a below neighbor to be air
+ // Also, its neighbor on top of it must be non-air
+ if (cChunkDef::GetBlock(a_BlockTypes, x, y + 1, z) == E_BLOCK_AIR)
+ {
+ return false;
+ }
+
+ static const struct
+ {
+ int x, y, z;
+ } Coords[] =
+ {
+ {-1, 0, 0},
+ { 1, 0, 0},
+ { 0, -1, 0},
+ { 0, 0, -1},
+ { 0, 0, 1},
+ } ;
+ int NumAirNeighbors = 0;
+ for (int i = 0; i < ARRAYCOUNT(Coords); i++)
+ {
+ switch (cChunkDef::GetBlock(a_BlockTypes, x + Coords[i].x, y + Coords[i].y, z + Coords[i].z))
+ {
+ case E_BLOCK_AIR:
+ {
+ NumAirNeighbors += 1;
+ if (NumAirNeighbors > 1)
+ {
+ return false;
+ }
+ }
+ }
+ }
+ if (NumAirNeighbors == 0)
+ {
+ return false;
+ }
+
+ // Has exactly one air neighbor, place a spring:
+ cChunkDef::SetBlock(a_BlockTypes, x, y, z, m_Fluid);
+ cChunkDef::SetNibble(a_BlockMetas, x, y, z, 0);
+ return true;
+}
+
+
+
+
diff --git a/source/Generating/FinishGen.h b/source/Generating/FinishGen.h
index 573060843..dde073f67 100644
--- a/source/Generating/FinishGen.h
+++ b/source/Generating/FinishGen.h
@@ -17,6 +17,7 @@
#include "ComposableGenerator.h"
#include "../Noise.h"
+#include "../ProbabDistrib.h"
@@ -223,3 +224,39 @@ protected:
+
+class cFinishGenFluidSprings :
+ public cFinishGen
+{
+public:
+ cFinishGenFluidSprings(int a_Seed, BLOCKTYPE a_Fluid, cIniFile & a_IniFile, const cWorld & a_World);
+
+protected:
+
+ cNoise m_Noise;
+ cProbabDistrib m_HeightDistribution;
+ BLOCKTYPE m_Fluid;
+ int m_Chance; ///< Chance, [0..100], that a spring will be generated in a chunk
+
+ // cFinishGen override:
+ virtual void GenFinish(
+ int a_ChunkX, int a_ChunkZ,
+ cChunkDef::BlockTypes & a_BlockTypes, // Block types to read and change
+ cChunkDef::BlockNibbles & a_BlockMeta, // Block meta to read and change
+ cChunkDef::HeightMap & a_HeightMap, // Height map to read and change by the current data
+ const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to
+ cEntityList & a_Entities, // Entities may be added or deleted
+ cBlockEntityList & a_BlockEntities // Block entities may be added or deleted
+ ) override;
+
+ /// Tries to place a spring at the specified coords, checks neighbors. Returns true if successful
+ bool TryPlaceSpring(
+ cChunkDef::BlockTypes & a_BlockTypes,
+ cChunkDef::BlockNibbles & a_BlockMetas,
+ int x, int y, int z
+ );
+} ;
+
+
+
+