summaryrefslogtreecommitdiffstats
path: root/source/Generating
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--source/Generating/ComposableGenerator.cpp13
-rw-r--r--source/Generating/EndGen.cpp217
-rw-r--r--source/Generating/EndGen.h69
-rw-r--r--source/Generating/FinishGen.cpp6
4 files changed, 301 insertions, 4 deletions
diff --git a/source/Generating/ComposableGenerator.cpp b/source/Generating/ComposableGenerator.cpp
index 7cf099c1f..c038712aa 100644
--- a/source/Generating/ComposableGenerator.cpp
+++ b/source/Generating/ComposableGenerator.cpp
@@ -19,6 +19,7 @@
#include "Caves.h"
#include "DistortedHeightmap.h"
+#include "EndGen.h"
#include "MineShafts.h"
#include "Noise3DGenerator.h"
#include "Ravines.h"
@@ -250,6 +251,11 @@ void cComposableGenerator::InitHeightGen(cIniFile & a_IniFile)
m_HeightGen = new cDistortedHeightmap(Seed, *m_BiomeGen);
((cDistortedHeightmap *)m_HeightGen)->Initialize(a_IniFile);
}
+ else if (NoCaseCompare(HeightGenName, "End") == 0)
+ {
+ m_HeightGen = new cEndGen(Seed);
+ ((cEndGen *)m_HeightGen)->Initialize(a_IniFile);
+ }
else if (NoCaseCompare(HeightGenName, "Noise3D") == 0)
{
m_HeightGen = new cNoise3DComposable(Seed);
@@ -337,6 +343,11 @@ void cComposableGenerator::InitCompositionGen(cIniFile & a_IniFile)
m_CompositionGen = new cDistortedHeightmap(m_ChunkGenerator.GetSeed(), *m_BiomeGen);
((cDistortedHeightmap *)m_CompositionGen)->Initialize(a_IniFile);
}
+ else if (NoCaseCompare(CompoGenName, "end") == 0)
+ {
+ m_CompositionGen = new cEndGen(m_ChunkGenerator.GetSeed());
+ ((cEndGen *)m_CompositionGen)->Initialize(a_IniFile);
+ }
else if (NoCaseCompare(CompoGenName, "nether") == 0)
{
m_CompositionGen = new cCompoGenNether(m_ChunkGenerator.GetSeed());
@@ -469,7 +480,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
// Finishers, alpha-sorted:
if (NoCaseCompare(*itr, "BottomLava") == 0)
{
- int DefaultBottomLavaLevel = (m_World->GetDimension() == cWorld::dimNether) ? 30 : 10;
+ int DefaultBottomLavaLevel = (m_World->GetDimension() == dimNether) ? 30 : 10;
int BottomLavaLevel = a_IniFile.GetValueSetI("Generator", "BottomLavaLevel", DefaultBottomLavaLevel);
m_FinishGens.push_back(new cFinishGenBottomLava(BottomLavaLevel));
}
diff --git a/source/Generating/EndGen.cpp b/source/Generating/EndGen.cpp
new file mode 100644
index 000000000..30fa457db
--- /dev/null
+++ b/source/Generating/EndGen.cpp
@@ -0,0 +1,217 @@
+
+// EndGen.cpp
+
+// Implements the cEndGen class representing the generator for the End, both as a HeightGen and CompositionGen
+
+#include "Globals.h"
+#include "EndGen.h"
+#include "../../iniFile/iniFile.h"
+#include "../LinearUpscale.h"
+
+
+
+
+
+enum
+{
+ // Interpolation cell size:
+ INTERPOL_X = 4,
+ INTERPOL_Y = 4,
+ INTERPOL_Z = 4,
+
+ // Size of chunk data, downscaled before interpolation:
+ DIM_X = 16 / INTERPOL_X + 1,
+ DIM_Y = 256 / INTERPOL_Y + 1,
+ DIM_Z = 16 / INTERPOL_Z + 1,
+} ;
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cEndGen:
+
+cEndGen::cEndGen(int a_Seed) :
+ m_Seed(a_Seed),
+ m_IslandSizeX(256),
+ m_IslandSizeY(96),
+ m_IslandSizeZ(256),
+ m_FrequencyX(80),
+ m_FrequencyY(80),
+ m_FrequencyZ(80)
+{
+ m_Perlin.AddOctave(1, 1);
+ m_Perlin.AddOctave(2, 0.5);
+ m_Perlin.AddOctave(4, 0.25);
+}
+
+
+
+
+
+void cEndGen::Initialize(cIniFile & a_IniFile)
+{
+ m_IslandSizeX = a_IniFile.GetValueSetI("Generator", "EndGenIslandSizeX", m_IslandSizeX);
+ m_IslandSizeY = a_IniFile.GetValueSetI("Generator", "EndGenIslandSizeY", m_IslandSizeY);
+ m_IslandSizeZ = a_IniFile.GetValueSetI("Generator", "EndGenIslandSizeZ", m_IslandSizeZ);
+
+ m_FrequencyX = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "EndGenFrequencyX", m_FrequencyX);
+ m_FrequencyY = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "EndGenFrequencyY", m_FrequencyY);
+ m_FrequencyZ = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "EndGenFrequencyZ", m_FrequencyZ);
+
+ // Recalculate the min and max chunk coords of the island
+ m_MaxChunkX = (m_IslandSizeX + cChunkDef::Width - 1) / cChunkDef::Width;
+ m_MinChunkX = -m_MaxChunkX;
+ m_MaxChunkZ = (m_IslandSizeZ + cChunkDef::Width - 1) / cChunkDef::Width;
+ m_MinChunkZ = -m_MaxChunkZ;
+}
+
+
+
+
+
+/// Unless the LastChunk coords are equal to coords given, prepares the internal state (noise array)
+void cEndGen::PrepareState(int a_ChunkX, int a_ChunkZ)
+{
+ ASSERT(!IsChunkOutsideRange(a_ChunkX, a_ChunkZ)); // Should be filtered before calling this function
+
+ if ((m_LastChunkX == a_ChunkX) && (m_LastChunkZ == a_ChunkZ))
+ {
+ return;
+ }
+
+ m_LastChunkX = a_ChunkX;
+ m_LastChunkZ = a_ChunkZ;
+
+ GenerateNoiseArray();
+}
+
+
+
+
+
+/// Generates the m_NoiseArray array for the current chunk
+void cEndGen::GenerateNoiseArray(void)
+{
+ NOISE_DATATYPE NoiseData[DIM_X * DIM_Y * DIM_Z]; // [x + DIM_X * z + DIM_X * DIM_Z * y]
+ NOISE_DATATYPE Workspace[DIM_X * DIM_Y * DIM_Z]; // [x + DIM_X * z + DIM_X * DIM_Z * y]
+
+ // Generate the downscaled noise:
+ NOISE_DATATYPE StartX = ((NOISE_DATATYPE)(m_LastChunkX * cChunkDef::Width)) / m_FrequencyX;
+ NOISE_DATATYPE EndX = ((NOISE_DATATYPE)((m_LastChunkX + 1) * cChunkDef::Width)) / m_FrequencyX;
+ NOISE_DATATYPE StartZ = ((NOISE_DATATYPE)(m_LastChunkZ * cChunkDef::Width)) / m_FrequencyZ;
+ NOISE_DATATYPE EndZ = ((NOISE_DATATYPE)((m_LastChunkZ + 1) * cChunkDef::Width)) / m_FrequencyZ;
+ NOISE_DATATYPE StartY = 0;
+ NOISE_DATATYPE EndY = ((NOISE_DATATYPE)257) / m_FrequencyY;
+ m_Perlin.Generate3D(NoiseData, DIM_X, DIM_Z, DIM_Y, StartX, EndX, StartZ, EndZ, StartY, EndY, Workspace);
+
+ // Add distance:
+ int idx = 0;
+ for (int y = 0; y < DIM_Y; y++)
+ {
+ NOISE_DATATYPE ValY = (NOISE_DATATYPE)(2 * INTERPOL_Y * y - m_IslandSizeY) / m_IslandSizeY;
+ ValY = ValY * ValY;
+ for (int z = 0; z < DIM_Z; z++)
+ {
+ NOISE_DATATYPE ValZ = (NOISE_DATATYPE)(m_LastChunkZ * cChunkDef::Width + (z * cChunkDef::Width / (DIM_Z - 1))) / m_IslandSizeZ;
+ ValZ = ValZ * ValZ;
+ for (int x = 0; x < DIM_X; x++)
+ {
+ // NOISE_DATATYPE ValX = StartX + (EndX - StartX) * x / (DIM_X - 1);
+ NOISE_DATATYPE ValX = (NOISE_DATATYPE)(m_LastChunkX * cChunkDef::Width + (x * cChunkDef::Width / (DIM_X - 1))) / m_IslandSizeX;
+ ValX = ValX * ValX;
+ NoiseData[idx++] += ValX + ValZ + ValY;
+ } // for x
+ } // for z
+ } // for y
+
+ // Upscale into real chunk size:
+ LinearUpscale3DArray(NoiseData, DIM_X, DIM_Z, DIM_Y, m_NoiseArray, INTERPOL_X, INTERPOL_Z, INTERPOL_Y);
+}
+
+
+
+
+
+/// Returns true if the chunk is outside of the island's dimensions
+bool cEndGen::IsChunkOutsideRange(int a_ChunkX, int a_ChunkZ)
+{
+ return (
+ (a_ChunkX < m_MinChunkX) || (a_ChunkX > m_MaxChunkX) ||
+ (a_ChunkZ < m_MinChunkZ) || (a_ChunkZ > m_MaxChunkZ)
+ );
+}
+
+
+
+
+
+void cEndGen::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap)
+{
+ if (IsChunkOutsideRange(a_ChunkX, a_ChunkZ))
+ {
+ for (int i = 0; i < ARRAYCOUNT(a_HeightMap); i++)
+ {
+ a_HeightMap[i] = 0;
+ }
+ return;
+ }
+
+ PrepareState(a_ChunkX, a_ChunkZ);
+
+ 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++)
+ {
+ cChunkDef::SetHeight(a_HeightMap, x, z, MaxY);
+ for (int y = MaxY; y > 0; y--)
+ {
+ if (m_NoiseArray[y * 17 * 17 + z * 17 + x] <= 0)
+ {
+ cChunkDef::SetHeight(a_HeightMap, x, z, y);
+ break;
+ }
+ } // for y
+ } // for x
+ } // for z
+}
+
+
+
+
+
+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
+}
+
+
+
+
diff --git a/source/Generating/EndGen.h b/source/Generating/EndGen.h
new file mode 100644
index 000000000..cd316ed67
--- /dev/null
+++ b/source/Generating/EndGen.h
@@ -0,0 +1,69 @@
+
+// EndGen.h
+
+// Declares the cEndGen class representing the generator for the End, both as a HeightGen and CompositionGen
+
+
+
+
+
+#pragma once
+
+#include "ComposableGenerator.h"
+#include "../Noise.h"
+
+
+
+
+
+class cEndGen :
+ public cTerrainHeightGen,
+ public cTerrainCompositionGen
+{
+public:
+ cEndGen(int a_Seed);
+
+ void Initialize(cIniFile & a_IniFile);
+
+protected:
+
+ /// Seed for the noise
+ int m_Seed;
+
+ /// The Perlin noise used for generating
+ cPerlinNoise m_Perlin;
+
+ // XYZ size of the "island", in blocks:
+ int m_IslandSizeX;
+ int m_IslandSizeY;
+ int m_IslandSizeZ;
+
+ // XYZ Frequencies of the noise functions:
+ NOISE_DATATYPE m_FrequencyX;
+ NOISE_DATATYPE m_FrequencyY;
+ NOISE_DATATYPE m_FrequencyZ;
+
+ // Minimum and maximum chunk coords for chunks inside the island area. Chunks outside won't get calculated at all
+ int m_MinChunkX, m_MaxChunkX;
+ int m_MinChunkZ, m_MaxChunkZ;
+
+ // Noise array for the last chunk (in the noise range)
+ int m_LastChunkX;
+ int m_LastChunkZ;
+ NOISE_DATATYPE m_NoiseArray[17 * 17 * 257]; // x + 17 * z + 17 * 17 * y
+
+ /// Unless the LastChunk coords are equal to coords given, prepares the internal state (noise array)
+ void PrepareState(int a_ChunkX, int a_ChunkZ);
+
+ /// Generates the m_NoiseArray array for the current chunk
+ void GenerateNoiseArray(void);
+
+ /// Returns true if the chunk is outside of the island's dimensions
+ bool IsChunkOutsideRange(int a_ChunkX, int a_ChunkZ);
+
+ // cTerrainHeightGen overrides:
+ virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override;
+
+ // cTerrainCompositionGen overrides:
+ virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) override;
+} ;
diff --git a/source/Generating/FinishGen.cpp b/source/Generating/FinishGen.cpp
index df9b2f265..8899e4bd0 100644
--- a/source/Generating/FinishGen.cpp
+++ b/source/Generating/FinishGen.cpp
@@ -531,19 +531,19 @@ cFinishGenFluidSprings::cFinishGenFluidSprings(int a_Seed, BLOCKTYPE a_Fluid, cI
int DefaultChance;
switch (a_World.GetDimension())
{
- case cWorld::dimNether:
+ case dimNether:
{
DefaultHeightDistribution = IsWater ? DEF_NETHER_WATER_SPRINGS : DEF_NETHER_LAVA_SPRINGS;
DefaultChance = IsWater ? 0 : 15;
break;
}
- case cWorld::dimOverworld:
+ case dimOverworld:
{
DefaultHeightDistribution = IsWater ? DEF_OVERWORLD_WATER_SPRINGS : DEF_OVERWORLD_LAVA_SPRINGS;
DefaultChance = IsWater ? 24 : 9;
break;
}
- case cWorld::dimEnd:
+ case dimEnd:
{
DefaultHeightDistribution = IsWater ? DEF_END_WATER_SPRINGS : DEF_END_LAVA_SPRINGS;
DefaultChance = 0;