summaryrefslogtreecommitdiffstats
path: root/src/Generating
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/Generating/CMakeLists.txt2
-rw-r--r--src/Generating/Caves.cpp3
-rw-r--r--src/Generating/ChunkGenerator.cpp1
-rw-r--r--src/Generating/ComposableGenerator.cpp98
-rw-r--r--src/Generating/DungeonRoomsFinisher.cpp279
-rw-r--r--src/Generating/DungeonRoomsFinisher.h52
-rw-r--r--src/Generating/FinishGen.cpp2
-rw-r--r--src/Generating/HeiGen.cpp10
-rw-r--r--src/Generating/StructGen.cpp58
-rw-r--r--src/Generating/StructGen.h26
10 files changed, 474 insertions, 57 deletions
diff --git a/src/Generating/CMakeLists.txt b/src/Generating/CMakeLists.txt
index 58df9d421..33d622b42 100644
--- a/src/Generating/CMakeLists.txt
+++ b/src/Generating/CMakeLists.txt
@@ -12,6 +12,7 @@ SET (SRCS
CompoGen.cpp
ComposableGenerator.cpp
DistortedHeightmap.cpp
+ DungeonRoomsFinisher.cpp
EndGen.cpp
FinishGen.cpp
GridStructGen.cpp
@@ -40,6 +41,7 @@ SET (HDRS
CompoGen.h
ComposableGenerator.h
DistortedHeightmap.h
+ DungeonRoomsFinisher.h
EndGen.h
FinishGen.h
GridStructGen.h
diff --git a/src/Generating/Caves.cpp b/src/Generating/Caves.cpp
index 6fc371958..71154dff9 100644
--- a/src/Generating/Caves.cpp
+++ b/src/Generating/Caves.cpp
@@ -166,6 +166,9 @@ cCaveTunnel::cCaveTunnel(
if ((a_BlockStartY <= 0) && (a_BlockEndY <= 0))
{
// Don't bother detailing this cave, it's under the world anyway
+ m_MinBlockX = m_MaxBlockX = 0;
+ m_MinBlockY = m_MaxBlockY = -1;
+ m_MinBlockZ = m_MaxBlockZ = 0;
return;
}
diff --git a/src/Generating/ChunkGenerator.cpp b/src/Generating/ChunkGenerator.cpp
index 3d5af152c..a1188f984 100644
--- a/src/Generating/ChunkGenerator.cpp
+++ b/src/Generating/ChunkGenerator.cpp
@@ -27,6 +27,7 @@ const unsigned int QUEUE_SKIP_LIMIT = 500;
cChunkGenerator::cChunkGenerator(void) :
super("cChunkGenerator"),
+ m_Seed(0), // Will be overwritten by the actual generator
m_Generator(NULL),
m_PluginInterface(NULL),
m_ChunkSink(NULL)
diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp
index cedb9aeb7..6f4007d24 100644
--- a/src/Generating/ComposableGenerator.cpp
+++ b/src/Generating/ComposableGenerator.cpp
@@ -19,6 +19,7 @@
#include "Caves.h"
#include "DistortedHeightmap.h"
+#include "DungeonRoomsFinisher.h"
#include "EndGen.h"
#include "MineShafts.h"
#include "NetherFortGen.h"
@@ -343,6 +344,14 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
float Threshold = (float)a_IniFile.GetValueSetF("Generator", "DualRidgeCavesThreshold", 0.3);
m_FinishGens.push_back(new cStructGenDualRidgeCaves(Seed, Threshold));
}
+ else if (NoCaseCompare(*itr, "DungeonRooms") == 0)
+ {
+ int GridSize = a_IniFile.GetValueSetI("Generator", "DungeonRoomsGridSize", 48);
+ int MaxSize = a_IniFile.GetValueSetI("Generator", "DungeonRoomsMaxSize", 7);
+ int MinSize = a_IniFile.GetValueSetI("Generator", "DungeonRoomsMinSize", 5);
+ AString HeightDistrib = a_IniFile.GetValueSet ("Generator", "DungeonRoomsHeightDistrib", "0, 0; 10, 10; 11, 500; 40, 500; 60, 40; 90, 1");
+ m_FinishGens.push_back(new cDungeonRoomsFinisher(*m_HeightGen, Seed, GridSize, MaxSize, MinSize, HeightDistrib));
+ }
else if (NoCaseCompare(*itr, "Ice") == 0)
{
m_FinishGens.push_back(new cFinishGenIce);
@@ -387,6 +396,28 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
m_FinishGens.push_back(new cFinishGenSingleTopBlock(Seed, E_BLOCK_LILY_PAD, AllowedBiomes, 4, AllowedBlocks));
}
+ else if (NoCaseCompare(*itr, "NaturalPatches") == 0)
+ {
+ cStructGenOreNests::OreList Ores;
+
+ // Dirt vein
+ cStructGenOreNests::OreInfo DirtVein;
+ DirtVein.BlockType = E_BLOCK_DIRT;
+ DirtVein.MaxHeight = 127;
+ DirtVein.NumNests = 20;
+ DirtVein.NestSize = 32;
+ Ores.push_back(DirtVein);
+
+ // Gravel vein
+ cStructGenOreNests::OreInfo GravelVein;
+ GravelVein.BlockType = E_BLOCK_DIRT;
+ GravelVein.MaxHeight = 127;
+ GravelVein.NumNests = 20;
+ GravelVein.NestSize = 32;
+ Ores.push_back(GravelVein);
+
+ m_FinishGens.push_back(new cStructGenOreNests(Seed, Ores, E_BLOCK_STONE));
+ }
else if (NoCaseCompare(*itr, "NetherClumpFoliage") == 0)
{
m_FinishGens.push_back(new cFinishGenNetherClumpFoliage(Seed));
@@ -398,9 +429,74 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
int MaxDepth = a_IniFile.GetValueSetI("Generator", "NetherFortsMaxDepth", 12);
m_FinishGens.push_back(new cNetherFortGen(Seed, GridSize, MaxOffset, MaxDepth));
}
+ else if (NoCaseCompare(*itr, "NetherOreNests") == 0)
+ {
+ cStructGenOreNests::OreList Ores;
+
+ // Quartz vein
+ cStructGenOreNests::OreInfo QuartzVein;
+ QuartzVein.BlockType = E_BLOCK_NETHER_QUARTZ_ORE;
+ QuartzVein.MaxHeight = 255;
+ QuartzVein.NumNests = 80;
+ QuartzVein.NestSize = 8;
+ Ores.push_back(QuartzVein);
+
+ m_FinishGens.push_back(new cStructGenOreNests(Seed, Ores, E_BLOCK_NETHERRACK));
+
+ }
else if (NoCaseCompare(*itr, "OreNests") == 0)
{
- m_FinishGens.push_back(new cStructGenOreNests(Seed));
+ cStructGenOreNests::OreList Ores;
+
+ // Coal vein
+ cStructGenOreNests::OreInfo CoalVein;
+ CoalVein.BlockType = E_BLOCK_COAL_ORE;
+ CoalVein.MaxHeight = 127;
+ CoalVein.NumNests = 50;
+ CoalVein.NestSize = 10;
+ Ores.push_back(CoalVein);
+
+ // Iron vein
+ cStructGenOreNests::OreInfo IronVein;
+ IronVein.BlockType = E_BLOCK_IRON_ORE;
+ IronVein.MaxHeight = 64;
+ IronVein.NumNests = 14;
+ IronVein.NestSize = 6;
+ Ores.push_back(IronVein);
+
+ // Gold vein
+ cStructGenOreNests::OreInfo GoldVein;
+ GoldVein.BlockType = E_BLOCK_GOLD_ORE;
+ GoldVein.MaxHeight = 32;
+ GoldVein.NumNests = 2;
+ GoldVein.NestSize = 6;
+ Ores.push_back(GoldVein);
+
+ // Redstone vein
+ cStructGenOreNests::OreInfo RedstoneVein;
+ RedstoneVein.BlockType = E_BLOCK_REDSTONE_ORE;
+ RedstoneVein.MaxHeight = 16;
+ RedstoneVein.NumNests = 4;
+ RedstoneVein.NestSize = 6;
+ Ores.push_back(RedstoneVein);
+
+ // Lapis vein
+ cStructGenOreNests::OreInfo LapisVein;
+ LapisVein.BlockType = E_BLOCK_LAPIS_ORE;
+ LapisVein.MaxHeight = 30;
+ LapisVein.NumNests = 2;
+ LapisVein.NestSize = 5;
+ Ores.push_back(LapisVein);
+
+ // Diamond vein
+ cStructGenOreNests::OreInfo DiamondVein;
+ DiamondVein.BlockType = E_BLOCK_DIAMOND_ORE;
+ DiamondVein.MaxHeight = 15;
+ DiamondVein.NumNests = 1;
+ DiamondVein.NestSize = 4;
+ Ores.push_back(DiamondVein);
+
+ m_FinishGens.push_back(new cStructGenOreNests(Seed, Ores, E_BLOCK_STONE));
}
else if (NoCaseCompare(*itr, "POCPieces") == 0)
{
diff --git a/src/Generating/DungeonRoomsFinisher.cpp b/src/Generating/DungeonRoomsFinisher.cpp
new file mode 100644
index 000000000..f213455d6
--- /dev/null
+++ b/src/Generating/DungeonRoomsFinisher.cpp
@@ -0,0 +1,279 @@
+
+// DungeonRoomsFinisher.cpp
+
+// Declares the cDungeonRoomsFinisher class representing the finisher that generates dungeon rooms
+
+#include "Globals.h"
+#include "DungeonRoomsFinisher.h"
+#include "../FastRandom.h"
+
+
+
+
+
+/** Height, in blocks, of the internal dungeon room open space. This many air blocks Y-wise. */
+static const int ROOM_HEIGHT = 4;
+
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+// cDungeonRoom:
+
+class cDungeonRoom :
+ public cGridStructGen::cStructure
+{
+ typedef cGridStructGen::cStructure super;
+
+public:
+
+ cDungeonRoom(
+ int a_GridX, int a_GridZ,
+ int a_OriginX, int a_OriginZ,
+ int a_HalfSizeX, int a_HalfSizeZ,
+ int a_FloorHeight,
+ cNoise & a_Noise
+ ) :
+ super(a_GridX, a_GridZ, a_OriginX, a_OriginZ),
+ m_StartX(a_OriginX - a_HalfSizeX),
+ m_EndX(a_OriginX + a_HalfSizeX),
+ m_StartZ(a_OriginZ - a_HalfSizeZ),
+ m_EndZ(a_OriginZ + a_HalfSizeZ),
+ m_FloorHeight(a_FloorHeight)
+ {
+ /*
+ Pick coords next to the wall for the chests.
+ This is done by indexing the possible coords, picking any one for the first chest
+ and then picking another position for the second chest that is not adjacent to the first pos
+ */
+ int rnd = a_Noise.IntNoise2DInt(a_OriginX, a_OriginZ) / 7;
+ int SizeX = m_EndX - m_StartX - 1;
+ int SizeZ = m_EndZ - m_StartZ - 1;
+ int NumPositions = 2 * SizeX + 2 * SizeZ;
+ int FirstChestPos = rnd % NumPositions; // The corner positions are a bit more likely, but we don't mind
+ rnd = rnd / 512;
+ int SecondChestPos = (FirstChestPos + 2 + (rnd % (NumPositions - 3))) % NumPositions;
+ m_Chest1 = DecodeChestCoords(FirstChestPos, SizeX, SizeZ);
+ m_Chest2 = DecodeChestCoords(SecondChestPos, SizeX, SizeZ);
+ }
+
+protected:
+
+ // The X range of the room, start inclusive, end exclusive:
+ int m_StartX, m_EndX;
+
+ // The Z range of the room, start inclusive, end exclusive:
+ int m_StartZ, m_EndZ;
+
+ /** The Y coord of the floor of the room */
+ int m_FloorHeight;
+
+ /** The (absolute) coords of the first chest. The Y coord represents the chest's Meta value (facing). */
+ Vector3i m_Chest1;
+
+ /** The (absolute) coords of the second chest. The Y coord represents the chest's Meta value (facing). */
+ Vector3i m_Chest2;
+
+
+
+ /** Decodes the position index along the room walls into a proper 2D position for a chest. */
+ Vector3i DecodeChestCoords(int a_PosIdx, int a_SizeX, int a_SizeZ)
+ {
+ if (a_PosIdx < a_SizeX)
+ {
+ // Return a coord on the ZM side of the room:
+ return Vector3i(m_StartX + a_PosIdx + 1, E_META_CHEST_FACING_ZP, m_StartZ + 1);
+ }
+ a_PosIdx -= a_SizeX;
+ if (a_PosIdx < a_SizeZ)
+ {
+ // Return a coord on the XP side of the room:
+ return Vector3i(m_EndX - 1, E_META_CHEST_FACING_XM, m_StartZ + a_PosIdx + 1);
+ }
+ a_PosIdx -= a_SizeZ;
+ if (a_PosIdx < a_SizeX)
+ {
+ // Return a coord on the ZP side of the room:
+ return Vector3i(m_StartX + a_PosIdx + 1, E_META_CHEST_FACING_ZM, m_StartZ + 1);
+ }
+ a_PosIdx -= a_SizeX;
+ // Return a coord on the XM side of the room:
+ return Vector3i(m_StartX + 1, E_META_CHEST_FACING_XP, m_StartZ + a_PosIdx + 1);
+ }
+
+
+
+ /** Fills the specified area of blocks in the chunk with the specified blocktype if they are one of the overwritten block types.
+ The coords are absolute, start coords are inclusive, end coords are exclusive. */
+ void ReplaceCuboid(cChunkDesc & a_ChunkDesc, int a_StartX, int a_StartY, int a_StartZ, int a_EndX, int a_EndY, int a_EndZ, BLOCKTYPE a_DstBlockType)
+ {
+ int BlockX = a_ChunkDesc.GetChunkX() * cChunkDef::Width;
+ int BlockZ = a_ChunkDesc.GetChunkZ() * cChunkDef::Width;
+ int RelStartX = Clamp(a_StartX - BlockX, 0, cChunkDef::Width - 1);
+ int RelStartZ = Clamp(a_StartZ - BlockZ, 0, cChunkDef::Width - 1);
+ int RelEndX = Clamp(a_EndX - BlockX, 0, cChunkDef::Width);
+ int RelEndZ = Clamp(a_EndZ - BlockZ, 0, cChunkDef::Width);
+ for (int y = a_StartY; y < a_EndY; y++)
+ {
+ for (int z = RelStartZ; z < RelEndZ; z++)
+ {
+ for (int x = RelStartX; x < RelEndX; x++)
+ {
+ if (cBlockInfo::CanBeTerraformed(a_ChunkDesc.GetBlockType(x, y, z)))
+ {
+ a_ChunkDesc.SetBlockType(x, y, z, a_DstBlockType);
+ }
+ } // for x
+ } // for z
+ } // for z
+ }
+
+
+
+ /** Fills the specified area of blocks in the chunk with a random pattern of the specified blocktypes, if they are one of the overwritten block types.
+ The coords are absolute, start coords are inclusive, end coords are exclusive. The first blocktype uses 75% chance, the second 25% chance. */
+ void ReplaceCuboidRandom(cChunkDesc & a_ChunkDesc, int a_StartX, int a_StartY, int a_StartZ, int a_EndX, int a_EndY, int a_EndZ, BLOCKTYPE a_DstBlockType1, BLOCKTYPE a_DstBlockType2)
+ {
+ int BlockX = a_ChunkDesc.GetChunkX() * cChunkDef::Width;
+ int BlockZ = a_ChunkDesc.GetChunkZ() * cChunkDef::Width;
+ int RelStartX = Clamp(a_StartX - BlockX, 0, cChunkDef::Width - 1);
+ int RelStartZ = Clamp(a_StartZ - BlockZ, 0, cChunkDef::Width - 1);
+ int RelEndX = Clamp(a_EndX - BlockX, 0, cChunkDef::Width);
+ int RelEndZ = Clamp(a_EndZ - BlockZ, 0, cChunkDef::Width);
+ cFastRandom rnd;
+ for (int y = a_StartY; y < a_EndY; y++)
+ {
+ for (int z = RelStartZ; z < RelEndZ; z++)
+ {
+ for (int x = RelStartX; x < RelEndX; x++)
+ {
+ if (cBlockInfo::CanBeTerraformed(a_ChunkDesc.GetBlockType(x, y, z)))
+ {
+ BLOCKTYPE BlockType = (rnd.NextInt(101) < 75) ? a_DstBlockType1 : a_DstBlockType2;
+ a_ChunkDesc.SetBlockType(x, y, z, BlockType);
+ }
+ } // for x
+ } // for z
+ } // for z
+ }
+
+
+
+ /** Tries to place a chest at the specified (absolute) coords.
+ Does nothing if the coords are outside the chunk. */
+ void TryPlaceChest(cChunkDesc & a_ChunkDesc, const Vector3i & a_Chest)
+ {
+ int RelX = a_Chest.x - a_ChunkDesc.GetChunkX() * cChunkDef::Width;
+ int RelZ = a_Chest.z - a_ChunkDesc.GetChunkZ() * cChunkDef::Width;
+ if (
+ (RelX < 0) || (RelX >= cChunkDef::Width) || // The X coord is not in this chunk
+ (RelZ < 0) || (RelZ >= cChunkDef::Width) // The Z coord is not in this chunk
+ )
+ {
+ return;
+ }
+ a_ChunkDesc.SetBlockTypeMeta(RelX, m_FloorHeight + 1, RelZ, E_BLOCK_CHEST, (NIBBLETYPE)a_Chest.y);
+
+ // TODO: Fill the chest with random loot
+ }
+
+
+
+ // cGridStructGen::cStructure override:
+ virtual void DrawIntoChunk(cChunkDesc & a_ChunkDesc) override
+ {
+ if (
+ (m_EndX < a_ChunkDesc.GetChunkX() * cChunkDef::Width) ||
+ (m_StartX >= a_ChunkDesc.GetChunkX() * cChunkDef::Width + cChunkDef::Width) ||
+ (m_EndZ < a_ChunkDesc.GetChunkZ() * cChunkDef::Width) ||
+ (m_StartZ >= a_ChunkDesc.GetChunkZ() * cChunkDef::Width + cChunkDef::Width)
+ )
+ {
+ // The chunk is not intersecting the room at all, bail out
+ return;
+ }
+ int b = m_FloorHeight + 1; // Bottom
+ int t = m_FloorHeight + 1 + ROOM_HEIGHT; // Top
+ ReplaceCuboidRandom(a_ChunkDesc, m_StartX, m_FloorHeight, m_StartZ, m_EndX + 1, b, m_EndZ + 1, E_BLOCK_MOSSY_COBBLESTONE, E_BLOCK_COBBLESTONE); // Floor
+ ReplaceCuboid(a_ChunkDesc, m_StartX + 1, b, m_StartZ + 1, m_EndX, t, m_EndZ, E_BLOCK_AIR); // Insides
+
+ // Walls:
+ ReplaceCuboid(a_ChunkDesc, m_StartX, b, m_StartZ, m_StartX + 1, t, m_EndZ, E_BLOCK_COBBLESTONE); // XM wall
+ ReplaceCuboid(a_ChunkDesc, m_EndX, b, m_StartZ, m_EndX + 1, t, m_EndZ, E_BLOCK_COBBLESTONE); // XP wall
+ ReplaceCuboid(a_ChunkDesc, m_StartX, b, m_StartZ, m_EndX + 1, t, m_StartZ + 1, E_BLOCK_COBBLESTONE); // ZM wall
+ ReplaceCuboid(a_ChunkDesc, m_StartX, b, m_EndZ, m_EndX + 1, t, m_EndZ + 1, E_BLOCK_COBBLESTONE); // ZP wall
+
+ // Place chests:
+ TryPlaceChest(a_ChunkDesc, m_Chest1);
+ TryPlaceChest(a_ChunkDesc, m_Chest2);
+
+ // Place the spawner:
+ int CenterX = (m_StartX + m_EndX) / 2 - a_ChunkDesc.GetChunkX() * cChunkDef::Width;
+ int CenterZ = (m_StartZ + m_EndZ) / 2 - a_ChunkDesc.GetChunkZ() * cChunkDef::Width;
+ if (
+ (CenterX >= 0) && (CenterX < cChunkDef::Width) &&
+ (CenterZ >= 0) && (CenterZ < cChunkDef::Width)
+ )
+ {
+ a_ChunkDesc.SetBlockTypeMeta(CenterX, b, CenterZ, E_BLOCK_MOB_SPAWNER, 0);
+ // TODO: Set the spawned mob
+ }
+ }
+} ;
+
+
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+// cDungeonRoomsFinisher:
+
+cDungeonRoomsFinisher::cDungeonRoomsFinisher(cTerrainHeightGen & a_HeightGen, int a_Seed, int a_GridSize, int a_MaxSize, int a_MinSize, const AString & a_HeightDistrib) :
+ super(a_Seed + 100, a_GridSize, a_GridSize, a_GridSize, a_GridSize, a_MaxSize, a_MaxSize, 1024),
+ m_HeightGen(a_HeightGen),
+ m_MaxHalfSize((a_MaxSize + 1) / 2),
+ m_MinHalfSize((a_MinSize + 1) / 2),
+ m_HeightProbability(cChunkDef::Height)
+{
+ // Initialize the height probability distribution:
+ m_HeightProbability.SetDefString(a_HeightDistrib);
+
+ // Normalize the min and max size:
+ if (m_MinHalfSize > m_MaxHalfSize)
+ {
+ std::swap(m_MinHalfSize, m_MaxHalfSize);
+ }
+}
+
+
+
+
+
+
+cDungeonRoomsFinisher::cStructurePtr cDungeonRoomsFinisher::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ)
+{
+ // Select a random room size in each direction:
+ int rnd = m_Noise.IntNoise2DInt(a_OriginX, a_OriginZ) / 7;
+ int HalfSizeX = m_MinHalfSize + (rnd % (m_MaxHalfSize - m_MinHalfSize + 1));
+ rnd = rnd / 32;
+ int HalfSizeZ = m_MinHalfSize + (rnd % (m_MaxHalfSize - m_MinHalfSize + 1));
+ rnd = rnd / 32;
+
+ // Select a random floor height for the room, based on the height generator:
+ int ChunkX, ChunkZ;
+ int RelX = a_OriginX, RelY = 0, RelZ = a_OriginZ;
+ cChunkDef::AbsoluteToRelative(RelX, RelY, RelZ, ChunkX, ChunkZ);
+ cChunkDef::HeightMap HeightMap;
+ m_HeightGen.GenHeightMap(ChunkX, ChunkZ, HeightMap);
+ int Height = cChunkDef::GetHeight(HeightMap, RelX, RelZ); // Max room height at {a_OriginX, a_OriginZ}
+ Height = Clamp(m_HeightProbability.MapValue(rnd % m_HeightProbability.GetSum()), 10, Height - 5);
+
+ // Create the dungeon room descriptor:
+ return cStructurePtr(new cDungeonRoom(a_GridX, a_GridZ, a_OriginX, a_OriginZ, HalfSizeX, HalfSizeZ, Height, m_Noise));
+}
+
+
+
+
diff --git a/src/Generating/DungeonRoomsFinisher.h b/src/Generating/DungeonRoomsFinisher.h
new file mode 100644
index 000000000..2b52c9de6
--- /dev/null
+++ b/src/Generating/DungeonRoomsFinisher.h
@@ -0,0 +1,52 @@
+
+// DungeonRoomsFinisher.h
+
+// Declares the cDungeonRoomsFinisher class representing the finisher that generates dungeon rooms
+
+
+
+
+
+#pragma once
+
+#include "GridStructGen.h"
+#include "../ProbabDistrib.h"
+
+
+
+
+
+class cDungeonRoomsFinisher :
+ public cGridStructGen
+{
+ typedef cGridStructGen super;
+
+public:
+ /** Creates a new dungeon room finisher.
+ a_HeightGen is the underlying height generator, so that the rooms can always be placed under the terrain.
+ a_MaxSize and a_MinSize are the maximum and minimum sizes of the room's internal (air) area, in blocks across.
+ a_HeightDistrib is the string defining the height distribution for the rooms (cProbabDistrib format). */
+ cDungeonRoomsFinisher(cTerrainHeightGen & a_HeightGen, int a_Seed, int a_GridSize, int a_MaxSize, int a_MinSize, const AString & a_HeightDistrib);
+
+protected:
+
+ /** The height gen that is used for limiting the rooms' Y coords */
+ cTerrainHeightGen & m_HeightGen;
+
+ /** Maximum half-size (from center to wall) of the dungeon room's inner (air) area. Default is 3 (vanilla). */
+ int m_MaxHalfSize;
+
+ /** Minimum half-size (from center to wall) of the dungeon room's inner (air) area. Default is 2 (vanilla). */
+ int m_MinHalfSize;
+
+ /** The height probability distribution to make the spawners more common in layers 10 - 40, less common outside this range. */
+ cProbabDistrib m_HeightProbability;
+
+
+ // cGridStructGen overrides:
+ virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override;
+} ;
+
+
+
+
diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp
index e8324095e..eb57a5faa 100644
--- a/src/Generating/FinishGen.cpp
+++ b/src/Generating/FinishGen.cpp
@@ -484,8 +484,6 @@ int cFinishGenSingleTopBlock::GetNumToGen(const cChunkDef::BiomeMap & a_BiomeMap
void cFinishGenSingleTopBlock::GenFinish(cChunkDesc & a_ChunkDesc)
{
- // Add Lilypads on top of water surface in Swampland
-
int NumToGen = GetNumToGen(a_ChunkDesc.GetBiomeMap());
int ChunkX = a_ChunkDesc.GetChunkX();
int ChunkZ = a_ChunkDesc.GetChunkZ();
diff --git a/src/Generating/HeiGen.cpp b/src/Generating/HeiGen.cpp
index ba11b31b4..79d529a6a 100644
--- a/src/Generating/HeiGen.cpp
+++ b/src/Generating/HeiGen.cpp
@@ -239,7 +239,13 @@ bool cHeiGenCache::GetHeightAt(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_Rel
cHeiGenClassic::cHeiGenClassic(int a_Seed) :
m_Seed(a_Seed),
- m_Noise(a_Seed)
+ m_Noise(a_Seed),
+ m_HeightFreq1(1.0f),
+ m_HeightAmp1(1.0f),
+ m_HeightFreq2(0.5f),
+ m_HeightAmp2(0.5f),
+ m_HeightFreq3(0.1f),
+ m_HeightAmp3(0.1f)
{
}
@@ -432,7 +438,7 @@ const cHeiGenBiomal::sGenParam cHeiGenBiomal::m_GenParam[256] =
/* biExtremeHillsM */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 131
/* biFlowerForest */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 132
/* biTaigaM */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 133
- /* biSwamplandM */ { 1.0f, 2.0f, 1.10f, 5.0f, 0.01f, 8.0f, 60}, // 134
+ /* biSwamplandM */ { 1.0f, 3.0f, 1.10f, 7.0f, 0.01f, 0.01f, 60}, // 134
// Biomes 135 .. 139 unused, 5 empty placeholders here:
{}, {}, {}, {}, {}, // 135 .. 139
diff --git a/src/Generating/StructGen.cpp b/src/Generating/StructGen.cpp
index f7e609353..731324b0d 100644
--- a/src/Generating/StructGen.cpp
+++ b/src/Generating/StructGen.cpp
@@ -13,45 +13,6 @@
////////////////////////////////////////////////////////////////////////////////
-// cStructGenOreNests configuration:
-
-const int MAX_HEIGHT_COAL = 127;
-const int NUM_NESTS_COAL = 50;
-const int NEST_SIZE_COAL = 10;
-
-const int MAX_HEIGHT_IRON = 64;
-const int NUM_NESTS_IRON = 14;
-const int NEST_SIZE_IRON = 6;
-
-const int MAX_HEIGHT_REDSTONE = 16;
-const int NUM_NESTS_REDSTONE = 4;
-const int NEST_SIZE_REDSTONE = 6;
-
-const int MAX_HEIGHT_GOLD = 32;
-const int NUM_NESTS_GOLD = 2;
-const int NEST_SIZE_GOLD = 6;
-
-const int MAX_HEIGHT_DIAMOND = 15;
-const int NUM_NESTS_DIAMOND = 1;
-const int NEST_SIZE_DIAMOND = 4;
-
-const int MAX_HEIGHT_LAPIS = 30;
-const int NUM_NESTS_LAPIS = 2;
-const int NEST_SIZE_LAPIS = 5;
-
-const int MAX_HEIGHT_DIRT = 127;
-const int NUM_NESTS_DIRT = 20;
-const int NEST_SIZE_DIRT = 32;
-
-const int MAX_HEIGHT_GRAVEL = 70;
-const int NUM_NESTS_GRAVEL = 15;
-const int NEST_SIZE_GRAVEL = 32;
-
-
-
-
-
-////////////////////////////////////////////////////////////////////////////////
// cStructGenTrees:
void cStructGenTrees::GenFinish(cChunkDesc & a_ChunkDesc)
@@ -311,14 +272,15 @@ void cStructGenOreNests::GenFinish(cChunkDesc & a_ChunkDesc)
int ChunkX = a_ChunkDesc.GetChunkX();
int ChunkZ = a_ChunkDesc.GetChunkZ();
cChunkDef::BlockTypes & BlockTypes = a_ChunkDesc.GetBlockTypes();
- GenerateOre(ChunkX, ChunkZ, E_BLOCK_COAL_ORE, MAX_HEIGHT_COAL, NUM_NESTS_COAL, NEST_SIZE_COAL, BlockTypes, 1);
- GenerateOre(ChunkX, ChunkZ, E_BLOCK_IRON_ORE, MAX_HEIGHT_IRON, NUM_NESTS_IRON, NEST_SIZE_IRON, BlockTypes, 2);
- GenerateOre(ChunkX, ChunkZ, E_BLOCK_REDSTONE_ORE, MAX_HEIGHT_REDSTONE, NUM_NESTS_REDSTONE, NEST_SIZE_REDSTONE, BlockTypes, 3);
- GenerateOre(ChunkX, ChunkZ, E_BLOCK_GOLD_ORE, MAX_HEIGHT_GOLD, NUM_NESTS_GOLD, NEST_SIZE_GOLD, BlockTypes, 4);
- GenerateOre(ChunkX, ChunkZ, E_BLOCK_DIAMOND_ORE, MAX_HEIGHT_DIAMOND, NUM_NESTS_DIAMOND, NEST_SIZE_DIAMOND, BlockTypes, 5);
- GenerateOre(ChunkX, ChunkZ, E_BLOCK_LAPIS_ORE, MAX_HEIGHT_LAPIS, NUM_NESTS_LAPIS, NEST_SIZE_LAPIS, BlockTypes, 6);
- GenerateOre(ChunkX, ChunkZ, E_BLOCK_DIRT, MAX_HEIGHT_DIRT, NUM_NESTS_DIRT, NEST_SIZE_DIRT, BlockTypes, 10);
- GenerateOre(ChunkX, ChunkZ, E_BLOCK_GRAVEL, MAX_HEIGHT_GRAVEL, NUM_NESTS_GRAVEL, NEST_SIZE_GRAVEL, BlockTypes, 11);
+
+ int seq = 1;
+
+ // Generate the ores from the ore list.
+ for (OreList::const_iterator itr = m_OreList.begin(); itr != m_OreList.end(); ++itr)
+ {
+ GenerateOre(ChunkX, ChunkZ, itr->BlockType, itr->MaxHeight, itr->NumNests, itr->NestSize, BlockTypes, seq);
+ seq++;
+ }
}
@@ -376,7 +338,7 @@ void cStructGenOreNests::GenerateOre(int a_ChunkX, int a_ChunkZ, BLOCKTYPE a_Ore
}
int Index = cChunkDef::MakeIndexNoCheck(BlockX, BlockY, BlockZ);
- if (a_BlockTypes[Index] == E_BLOCK_STONE)
+ if (a_BlockTypes[Index] == m_ToReplace)
{
a_BlockTypes[Index] = a_OreType;
}
diff --git a/src/Generating/StructGen.h b/src/Generating/StructGen.h
index 9176bc192..55d5bc1c7 100644
--- a/src/Generating/StructGen.h
+++ b/src/Generating/StructGen.h
@@ -76,11 +76,29 @@ class cStructGenOreNests :
public cFinishGen
{
public:
- cStructGenOreNests(int a_Seed) : m_Noise(a_Seed), m_Seed(a_Seed) {}
-
+ struct OreInfo
+ {
+ BLOCKTYPE BlockType; // The type of the nest.
+ int MaxHeight; // The highest possible a nest can occur
+ int NumNests; // How many nests per chunk
+ int NestSize; // The amount of blocks a nest can have.
+ };
+
+ typedef std::vector<OreInfo> OreList;
+
+ cStructGenOreNests(int a_Seed, OreList a_OreList, BLOCKTYPE a_ToReplace) :
+ m_Noise(a_Seed),
+ m_Seed(a_Seed),
+ m_OreList(a_OreList),
+ m_ToReplace(a_ToReplace)
+ {}
+
protected:
- cNoise m_Noise;
- int m_Seed;
+ cNoise m_Noise;
+ int m_Seed;
+
+ OreList m_OreList; // A list of possible ores.
+ BLOCKTYPE m_ToReplace;
// cFinishGen override:
virtual void GenFinish(cChunkDesc & a_ChunkDesc) override;