From 5f4df3e87dc43bb9cbf19ea1e15d73ee0b5d1755 Mon Sep 17 00:00:00 2001
From: Mattes D <github@xoft.cz>
Date: Sun, 8 Sep 2019 15:40:12 +0200
Subject: ShapeGen, HeiGen: Changed to use cChunkCoords.

---
 src/Generating/ComposableGenerator.cpp  |   2 +-
 src/Generating/ComposableGenerator.h    |  11 ++--
 src/Generating/CompositedHeiGen.h       |   8 +--
 src/Generating/DistortedHeightmap.cpp   |  36 +++++------
 src/Generating/DistortedHeightmap.h     |   7 +--
 src/Generating/DungeonRoomsFinisher.cpp |   2 +-
 src/Generating/EndGen.cpp               |  36 +++++------
 src/Generating/EndGen.h                 |   9 ++-
 src/Generating/HeiGen.cpp               | 107 +++++++++++---------------------
 src/Generating/HeiGen.h                 |  28 +++++----
 src/Generating/Noise3DGenerator.cpp     |  42 ++++++-------
 src/Generating/Noise3DGenerator.h       |  16 +++--
 src/Generating/PrefabStructure.cpp      |   2 +-
 src/Generating/ShapeGen.cpp             |   4 +-
 src/Generating/StructGen.cpp            |   2 +-
 src/Generating/TwoHeights.cpp           |  14 ++---
 src/Generating/VerticalStrategy.cpp     |   4 +-
 src/Generating/VillageGen.cpp           |   4 +-
 18 files changed, 146 insertions(+), 188 deletions(-)

(limited to 'src/Generating')

diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp
index 65278051a..f28de931b 100644
--- a/src/Generating/ComposableGenerator.cpp
+++ b/src/Generating/ComposableGenerator.cpp
@@ -163,7 +163,7 @@ void cComposableGenerator::Generate(int a_ChunkX, int a_ChunkZ, cChunkDesc & a_C
 	cChunkDesc::Shape shape;
 	if (a_ChunkDesc.IsUsingDefaultHeight())
 	{
-		m_ShapeGen->GenShape(a_ChunkX, a_ChunkZ, shape);
+		m_ShapeGen->GenShape(a_ChunkDesc.GetChunkCoords(), shape);
 		a_ChunkDesc.SetHeightFromShape(shape);
 	}
 	else
diff --git a/src/Generating/ComposableGenerator.h b/src/Generating/ComposableGenerator.h
index 3007d9824..59ce25352 100644
--- a/src/Generating/ComposableGenerator.h
+++ b/src/Generating/ComposableGenerator.h
@@ -86,7 +86,7 @@ public:
 	virtual ~cTerrainShapeGen() {}  // Force a virtual destructor in descendants
 
 	/** Generates the shape for the given chunk */
-	virtual void GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) = 0;
+	virtual void GenShape(cChunkCoords a_ChunkCoords, cChunkDesc::Shape & a_Shape) = 0;
 
 	/** Reads parameters from the ini file, prepares generator for use. */
 	virtual void InitializeShapeGen(cIniFile & a_IniFile) {}
@@ -118,7 +118,7 @@ public:
 	virtual ~cTerrainHeightGen() {}  // Force a virtual destructor in descendants
 
 	/** Retrieves the heightmap for the specified chunk. */
-	virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) = 0;
+	virtual void GenHeightMap(cChunkCoords a_ChunkCoords, cChunkDef::HeightMap & a_HeightMap) = 0;
 
 	/** Initializes the generator, reading its parameters from the INI file. */
 	virtual void InitializeHeightGen(cIniFile & a_IniFile) {}
@@ -128,11 +128,10 @@ public:
 	Descendants may provide a better-performing method. */
 	virtual HEIGHTTYPE GetHeightAt(int a_BlockX, int a_BlockZ)
 	{
-		int chunkX, chunkZ;
-		cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, chunkX, chunkZ);
+		auto chunkCoords = cChunkDef::BlockToChunk({a_BlockX, 0, a_BlockZ});
 		cChunkDef::HeightMap heightMap;
-		GenHeightMap(chunkX, chunkZ, heightMap);
-		return cChunkDef::GetHeight(heightMap, a_BlockX - chunkX * cChunkDef::Width, a_BlockZ - chunkZ * cChunkDef::Width);
+		GenHeightMap(chunkCoords, heightMap);
+		return cChunkDef::GetHeight(heightMap, a_BlockX - chunkCoords.m_ChunkX * cChunkDef::Width, a_BlockZ - chunkCoords.m_ChunkZ * cChunkDef::Width);
 	}
 
 	/** Creates a cTerrainHeightGen descendant based on the INI file settings. */
diff --git a/src/Generating/CompositedHeiGen.h b/src/Generating/CompositedHeiGen.h
index d7be3c8ac..4c1d4b783 100644
--- a/src/Generating/CompositedHeiGen.h
+++ b/src/Generating/CompositedHeiGen.h
@@ -30,12 +30,12 @@ public:
 
 
 	// cTerrainHeightGen overrides:
-	virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override
+	virtual void GenHeightMap(cChunkCoords a_ChunkCoords, cChunkDef::HeightMap & a_HeightMap) override
 	{
 		cChunkDesc::Shape shape;
-		m_ShapeGen->GenShape(a_ChunkX, a_ChunkZ, shape);
-		cChunkDesc desc({a_ChunkX, a_ChunkZ});
-		m_BiomeGen->GenBiomes({a_ChunkX, a_ChunkZ}, desc.GetBiomeMap());  // Need to initialize biomes for the composition gen
+		m_ShapeGen->GenShape(a_ChunkCoords, shape);
+		cChunkDesc desc(a_ChunkCoords);
+		m_BiomeGen->GenBiomes(a_ChunkCoords, desc.GetBiomeMap());  // Need to initialize biomes for the composition gen
 		desc.SetHeightFromShape(shape);
 		m_CompositionGen->ComposeTerrain(desc, shape);
 		memcpy(a_HeightMap, desc.GetHeightMap(), sizeof(a_HeightMap));
diff --git a/src/Generating/DistortedHeightmap.cpp b/src/Generating/DistortedHeightmap.cpp
index 713a63145..1b1737e8c 100644
--- a/src/Generating/DistortedHeightmap.cpp
+++ b/src/Generating/DistortedHeightmap.cpp
@@ -121,8 +121,7 @@ const cDistortedHeightmap::sGenParam cDistortedHeightmap::m_GenParam[256] =
 cDistortedHeightmap::cDistortedHeightmap(int a_Seed, cBiomeGenPtr a_BiomeGen) :
 	m_NoiseDistortX(a_Seed + 1000),
 	m_NoiseDistortZ(a_Seed + 2000),
-	m_CurChunkX(0x7fffffff),  // Set impossible coords for the chunk so that it's always considered stale
-	m_CurChunkZ(0x7fffffff),
+	m_CurChunkCoords(0x7fffffff, 0x7fffffff),  // Set impossible coords for the chunk so that it's always considered stale
 	m_BiomeGen(a_BiomeGen),
 	m_UnderlyingHeiGen(new cHeiGenBiomal(a_Seed, a_BiomeGen)),
 	m_HeightGen(m_UnderlyingHeiGen, 64),
@@ -161,17 +160,16 @@ void cDistortedHeightmap::Initialize(cIniFile & a_IniFile)
 
 
 
-void cDistortedHeightmap::PrepareState(int a_ChunkX, int a_ChunkZ)
+void cDistortedHeightmap::PrepareState(cChunkCoords a_ChunkCoords)
 {
-	if ((m_CurChunkX == a_ChunkX) && (m_CurChunkZ == a_ChunkZ))
+	if (m_CurChunkCoords == a_ChunkCoords)
 	{
 		return;
 	}
-	m_CurChunkX = a_ChunkX;
-	m_CurChunkZ = a_ChunkZ;
+	m_CurChunkCoords = a_ChunkCoords;
 
 
-	m_HeightGen.GenHeightMap(a_ChunkX, a_ChunkZ, m_CurChunkHeights);
+	m_HeightGen.GenHeightMap(a_ChunkCoords, m_CurChunkHeights);
 	UpdateDistortAmps();
 	GenerateHeightArray();
 }
@@ -186,12 +184,12 @@ void cDistortedHeightmap::GenerateHeightArray(void)
 	NOISE_DATATYPE DistortNoiseX[DIM_X * DIM_Y * DIM_Z];
 	NOISE_DATATYPE DistortNoiseZ[DIM_X * DIM_Y * DIM_Z];
 	NOISE_DATATYPE Workspace[DIM_X * DIM_Y * DIM_Z];
-	NOISE_DATATYPE StartX = static_cast<NOISE_DATATYPE>(m_CurChunkX * cChunkDef::Width) / m_FrequencyX;
-	NOISE_DATATYPE EndX   = static_cast<NOISE_DATATYPE>((m_CurChunkX + 1) * cChunkDef::Width - 1) / m_FrequencyX;
+	NOISE_DATATYPE StartX = static_cast<NOISE_DATATYPE>(m_CurChunkCoords.m_ChunkX * cChunkDef::Width) / m_FrequencyX;
+	NOISE_DATATYPE EndX   = static_cast<NOISE_DATATYPE>((m_CurChunkCoords.m_ChunkX + 1) * cChunkDef::Width - 1) / m_FrequencyX;
 	NOISE_DATATYPE StartY = 0;
 	NOISE_DATATYPE EndY   = static_cast<NOISE_DATATYPE>(257) / m_FrequencyY;
-	NOISE_DATATYPE StartZ = static_cast<NOISE_DATATYPE>(m_CurChunkZ * cChunkDef::Width) / m_FrequencyZ;
-	NOISE_DATATYPE EndZ   = static_cast<NOISE_DATATYPE>((m_CurChunkZ + 1) * cChunkDef::Width - 1) / m_FrequencyZ;
+	NOISE_DATATYPE StartZ = static_cast<NOISE_DATATYPE>(m_CurChunkCoords.m_ChunkZ * cChunkDef::Width) / m_FrequencyZ;
+	NOISE_DATATYPE EndZ   = static_cast<NOISE_DATATYPE>((m_CurChunkCoords.m_ChunkZ + 1) * cChunkDef::Width - 1) / m_FrequencyZ;
 
 	m_NoiseDistortX.Generate3D(DistortNoiseX, DIM_X, DIM_Y, DIM_Z, StartX, EndX, StartY, EndY, StartZ, EndZ, Workspace);
 	m_NoiseDistortZ.Generate3D(DistortNoiseZ, DIM_X, DIM_Y, DIM_Z, StartX, EndX, StartY, EndY, StartZ, EndZ, Workspace);
@@ -210,8 +208,8 @@ void cDistortedHeightmap::GenerateHeightArray(void)
 			{
 				NOISE_DATATYPE DistX = DistortNoiseX[NoiseArrayIdx + x] * m_DistortAmpX[AmpIdx + x];
 				NOISE_DATATYPE DistZ = DistortNoiseZ[NoiseArrayIdx + x] * m_DistortAmpZ[AmpIdx + x];
-				DistX += static_cast<NOISE_DATATYPE>(m_CurChunkX * cChunkDef::Width + x * INTERPOL_X);
-				DistZ += static_cast<NOISE_DATATYPE>(m_CurChunkZ * cChunkDef::Width + z * INTERPOL_Z);
+				DistX += static_cast<NOISE_DATATYPE>(m_CurChunkCoords.m_ChunkX * cChunkDef::Width + x * INTERPOL_X);
+				DistZ += static_cast<NOISE_DATATYPE>(m_CurChunkCoords.m_ChunkZ * cChunkDef::Width + z * INTERPOL_Z);
 				// Adding 0.5 helps alleviate the interpolation artifacts
 				DistHei[NoiseArrayIdx + x] = static_cast<NOISE_DATATYPE>(GetHeightmapAt(DistX, DistZ)) + static_cast<NOISE_DATATYPE>(0.5);
 			}
@@ -231,9 +229,9 @@ void cDistortedHeightmap::GenerateHeightArray(void)
 
 
 
-void cDistortedHeightmap::GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape)
+void cDistortedHeightmap::GenShape(cChunkCoords a_ChunkCoords, cChunkDesc::Shape & a_Shape)
 {
-	PrepareState(a_ChunkX, a_ChunkZ);
+	PrepareState(a_ChunkCoords);
 	for (int z = 0; z < cChunkDef::Width; z++)
 	{
 		for (int x = 0; x < cChunkDef::Width; x++)
@@ -268,8 +266,8 @@ int cDistortedHeightmap::GetHeightmapAt(NOISE_DATATYPE a_X, NOISE_DATATYPE a_Z)
 	int ChunkX, ChunkZ;
 	cChunkDef::AbsoluteToRelative(RelX, RelY, RelZ, ChunkX, ChunkZ);
 
-	// If we're withing the same chunk, return the pre-cached heightmap:
-	if ((ChunkX == m_CurChunkX) && (ChunkZ == m_CurChunkZ))
+	// If we're within the same chunk, return the pre-cached heightmap:
+	if ((ChunkX == m_CurChunkCoords.m_ChunkX) && (ChunkZ == m_CurChunkCoords.m_ChunkZ))
 	{
 		return cChunkDef::GetHeight(m_CurChunkHeights, RelX, RelZ);
 	}
@@ -284,7 +282,7 @@ int cDistortedHeightmap::GetHeightmapAt(NOISE_DATATYPE a_X, NOISE_DATATYPE a_Z)
 
 	// The height is not in the cache, generate full heightmap and get it there:
 	cChunkDef::HeightMap Heightmap;
-	m_HeightGen.GenHeightMap(ChunkX, ChunkZ, Heightmap);
+	m_HeightGen.GenHeightMap({ChunkX, ChunkZ}, Heightmap);
 	return cChunkDef::GetHeight(Heightmap, RelX, RelZ);
 }
 
@@ -299,7 +297,7 @@ void cDistortedHeightmap::UpdateDistortAmps(void)
 	{
 		for (int x = -1; x <= 1; x++)
 		{
-			m_BiomeGen->GenBiomes({m_CurChunkX + x, m_CurChunkZ + z}, Biomes[x + 1][z + 1]);
+			m_BiomeGen->GenBiomes({m_CurChunkCoords.m_ChunkX + x, m_CurChunkCoords.m_ChunkZ + z}, Biomes[x + 1][z + 1]);
 		}  // for x
 	}  // for z
 
diff --git a/src/Generating/DistortedHeightmap.h b/src/Generating/DistortedHeightmap.h
index eaa6aa8d9..d27ad098b 100644
--- a/src/Generating/DistortedHeightmap.h
+++ b/src/Generating/DistortedHeightmap.h
@@ -49,8 +49,7 @@ protected:
 	NOISE_DATATYPE m_FrequencyY;
 	NOISE_DATATYPE m_FrequencyZ;
 
-	int m_CurChunkX;
-	int m_CurChunkZ;
+	cChunkCoords m_CurChunkCoords;
 	NOISE_DATATYPE m_DistortedHeightmap[17 * 257 * 17];
 
 	/** The bime generator to query for biomes. */
@@ -82,7 +81,7 @@ protected:
 
 
 	/** Unless the LastChunk coords are equal to coords given, prepares the internal state (noise arrays, heightmap). */
-	void PrepareState(int a_ChunkX, int a_ChunkZ);
+	void PrepareState(cChunkCoords a_ChunkCoords);
 
 	/** Generates the m_DistortedHeightmap array for the current chunk. */
 	void GenerateHeightArray(void);
@@ -101,6 +100,6 @@ protected:
 
 
 	// cTerrainShapeGen overrides:
-	virtual void GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) override;
+	virtual void GenShape(cChunkCoords a_ChunkCoords, cChunkDesc::Shape & a_Shape) override;
 	virtual void InitializeShapeGen(cIniFile & a_IniFile) override;
 } ;
diff --git a/src/Generating/DungeonRoomsFinisher.cpp b/src/Generating/DungeonRoomsFinisher.cpp
index 06d45ce8c..768dd27cf 100644
--- a/src/Generating/DungeonRoomsFinisher.cpp
+++ b/src/Generating/DungeonRoomsFinisher.cpp
@@ -321,7 +321,7 @@ cDungeonRoomsFinisher::cStructurePtr cDungeonRoomsFinisher::CreateStructure(int
 	int RelX = a_OriginX, RelY = 0, RelZ = a_OriginZ;
 	cChunkDef::AbsoluteToRelative(RelX, RelY, RelZ, ChunkX, ChunkZ);
 	cChunkDesc::Shape shape;
-	m_ShapeGen->GenShape(ChunkX, ChunkZ, shape);
+	m_ShapeGen->GenShape({ChunkX, ChunkZ}, shape);
 	int height = 0;
 	int idx = RelX * 256 + RelZ * 16 * 256;
 	for (int y = 6; y < cChunkDef::Height; y++)
diff --git a/src/Generating/EndGen.cpp b/src/Generating/EndGen.cpp
index 69760e8b3..82dc5c414 100644
--- a/src/Generating/EndGen.cpp
+++ b/src/Generating/EndGen.cpp
@@ -44,8 +44,7 @@ cEndGen::cEndGen(int a_Seed) :
 	m_MaxChunkX(0),
 	m_MinChunkZ(0),
 	m_MaxChunkZ(0),
-	m_LastChunkX(0x7fffffff),  // Use dummy coords that won't ever be used by real chunks
-	m_LastChunkZ(0x7fffffff)
+	m_LastChunkCoords(0x7fffffff, 0x7fffffff)  // Use dummy coords that won't ever be used by real chunks
 {
 	m_Perlin.AddOctave(1, 1);
 	m_Perlin.AddOctave(2, 0.5);
@@ -77,17 +76,16 @@ void cEndGen::InitializeCompoGen(cIniFile & a_IniFile)
 
 
 
-void cEndGen::PrepareState(int a_ChunkX, int a_ChunkZ)
+void cEndGen::PrepareState(cChunkCoords a_ChunkCoords)
 {
-	ASSERT(!IsChunkOutsideRange(a_ChunkX, a_ChunkZ));  // Should be filtered before calling this function
+	ASSERT(!IsChunkOutsideRange(a_ChunkCoords));  // Should be filtered before calling this function
 
-	if ((m_LastChunkX == a_ChunkX) && (m_LastChunkZ == a_ChunkZ))
+	if (m_LastChunkCoords == a_ChunkCoords)
 	{
 		return;
 	}
 
-	m_LastChunkX = a_ChunkX;
-	m_LastChunkZ = a_ChunkZ;
+	m_LastChunkCoords = a_ChunkCoords;
 
 	GenerateNoiseArray();
 }
@@ -102,10 +100,10 @@ void cEndGen::GenerateNoiseArray(void)
 	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 = static_cast<NOISE_DATATYPE>(m_LastChunkX       * cChunkDef::Width) / m_FrequencyX;
-	NOISE_DATATYPE EndX   = static_cast<NOISE_DATATYPE>((m_LastChunkX + 1) * cChunkDef::Width) / m_FrequencyX;
-	NOISE_DATATYPE StartZ = static_cast<NOISE_DATATYPE>(m_LastChunkZ       * cChunkDef::Width) / m_FrequencyZ;
-	NOISE_DATATYPE EndZ   = static_cast<NOISE_DATATYPE>((m_LastChunkZ + 1) * cChunkDef::Width) / m_FrequencyZ;
+	NOISE_DATATYPE StartX = static_cast<NOISE_DATATYPE>(m_LastChunkCoords.m_ChunkX       * cChunkDef::Width) / m_FrequencyX;
+	NOISE_DATATYPE EndX   = static_cast<NOISE_DATATYPE>((m_LastChunkCoords.m_ChunkX + 1) * cChunkDef::Width) / m_FrequencyX;
+	NOISE_DATATYPE StartZ = static_cast<NOISE_DATATYPE>(m_LastChunkCoords.m_ChunkZ       * cChunkDef::Width) / m_FrequencyZ;
+	NOISE_DATATYPE EndZ   = static_cast<NOISE_DATATYPE>((m_LastChunkCoords.m_ChunkZ + 1) * cChunkDef::Width) / m_FrequencyZ;
 	NOISE_DATATYPE StartY = 0;
 	NOISE_DATATYPE EndY   = static_cast<NOISE_DATATYPE>(257) / m_FrequencyY;
 	m_Perlin.Generate3D(NoiseData, DIM_X, DIM_Z, DIM_Y, StartX, EndX, StartZ, EndZ, StartY, EndY, Workspace);
@@ -118,12 +116,12 @@ void cEndGen::GenerateNoiseArray(void)
 		ValY = ValY * ValY;
 		for (int z = 0; z < DIM_Z; z++)
 		{
-			NOISE_DATATYPE ValZ = static_cast<NOISE_DATATYPE>(m_LastChunkZ * cChunkDef::Width + (z * cChunkDef::Width / (DIM_Z - 1))) / m_IslandSizeZ;
+			NOISE_DATATYPE ValZ = static_cast<NOISE_DATATYPE>(m_LastChunkCoords.m_ChunkZ * 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 = static_cast<NOISE_DATATYPE>(m_LastChunkX * cChunkDef::Width + (x * cChunkDef::Width / (DIM_X - 1))) / m_IslandSizeX;
+				NOISE_DATATYPE ValX = static_cast<NOISE_DATATYPE>(m_LastChunkCoords.m_ChunkX * cChunkDef::Width + (x * cChunkDef::Width / (DIM_X - 1))) / m_IslandSizeX;
 				ValX = ValX * ValX;
 				NoiseData[idx++] += ValX + ValZ + ValY;
 			}  // for x
@@ -138,11 +136,11 @@ void cEndGen::GenerateNoiseArray(void)
 
 
 
-bool cEndGen::IsChunkOutsideRange(int a_ChunkX, int a_ChunkZ)
+bool cEndGen::IsChunkOutsideRange(cChunkCoords a_ChunkCoords)
 {
 	return (
-		(a_ChunkX < m_MinChunkX) || (a_ChunkX > m_MaxChunkX) ||
-		(a_ChunkZ < m_MinChunkZ) || (a_ChunkZ > m_MaxChunkZ)
+		(a_ChunkCoords.m_ChunkX < m_MinChunkX) || (a_ChunkCoords.m_ChunkX > m_MaxChunkX) ||
+		(a_ChunkCoords.m_ChunkZ < m_MinChunkZ) || (a_ChunkCoords.m_ChunkZ > m_MaxChunkZ)
 	);
 }
 
@@ -150,10 +148,10 @@ bool cEndGen::IsChunkOutsideRange(int a_ChunkX, int a_ChunkZ)
 
 
 
-void cEndGen::GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape)
+void cEndGen::GenShape(cChunkCoords a_ChunkCoords, cChunkDesc::Shape & a_Shape)
 {
 	// If the chunk is outside out range, fill the shape with zeroes:
-	if (IsChunkOutsideRange(a_ChunkX, a_ChunkZ))
+	if (IsChunkOutsideRange(a_ChunkCoords))
 	{
 		for (size_t i = 0; i < ARRAYCOUNT(a_Shape); i++)
 		{
@@ -162,7 +160,7 @@ void cEndGen::GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape)
 		return;
 	}
 
-	PrepareState(a_ChunkX, a_ChunkZ);
+	PrepareState(a_ChunkCoords);
 
 	int MaxY = std::min(static_cast<int>(1.75 * m_IslandSizeY + 1), cChunkDef::Height - 1);
 	for (int z = 0; z < cChunkDef::Width; z++)
diff --git a/src/Generating/EndGen.h b/src/Generating/EndGen.h
index 5008c2670..f3d9fde7b 100644
--- a/src/Generating/EndGen.h
+++ b/src/Generating/EndGen.h
@@ -46,23 +46,22 @@ protected:
 	int m_MinChunkZ, m_MaxChunkZ;
 
 	// Noise array for the last chunk (in the noise range)
-	int m_LastChunkX;
-	int m_LastChunkZ;
+	cChunkCoords m_LastChunkCoords;
 	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);
+	void PrepareState(cChunkCoords a_ChunkCoords);
 
 	/** 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);
+	bool IsChunkOutsideRange(cChunkCoords a_ChunkCoords);
 
 
 	// cTerrainShapeGen overrides:
-	virtual void GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) override;
+	virtual void GenShape(cChunkCoords a_ChunkCoords, cChunkDesc::Shape & a_Shape) override;
 
 
 	// cTerrainCompositionGen overrides:
diff --git a/src/Generating/HeiGen.cpp b/src/Generating/HeiGen.cpp
index 2f7af0a36..16b7c826b 100644
--- a/src/Generating/HeiGen.cpp
+++ b/src/Generating/HeiGen.cpp
@@ -55,10 +55,13 @@ public:
 	}
 
 	// cTerrainHeightGen overrides:
-	virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override
+	virtual void GenHeightMap(cChunkCoords a_ChunkCoords, cChunkDef::HeightMap & a_HeightMap) override
 	{
 		int heights[cChunkDef::Width * cChunkDef::Width];
-		m_Gen->GetInts(a_ChunkX * cChunkDef::Width, a_ChunkZ * cChunkDef::Width, static_cast<size_t>(cChunkDef::Width), static_cast<size_t>(cChunkDef::Width), heights);
+		m_Gen->GetInts(
+			a_ChunkCoords.m_ChunkX * cChunkDef::Width, a_ChunkCoords.m_ChunkZ * cChunkDef::Width,
+			static_cast<size_t>(cChunkDef::Width), static_cast<size_t>(cChunkDef::Width), heights
+		);
 		for (size_t i = 0; i < ARRAYCOUNT(heights); i++)
 		{
 			a_HeightMap[i] = static_cast<HEIGHTTYPE>(std::max(std::min(60 + heights[i], cChunkDef::Height - 60), 40));
@@ -78,8 +81,9 @@ protected:
 ////////////////////////////////////////////////////////////////////////////////
 // cHeiGenFlat:
 
-void cHeiGenFlat::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap)
+void cHeiGenFlat::GenHeightMap(cChunkCoords a_ChunkCoords, cChunkDef::HeightMap & a_HeightMap)
 {
+	UNUSED(a_ChunkCoords);
 	for (size_t i = 0; i < ARRAYCOUNT(a_HeightMap); i++)
 	{
 		a_HeightMap[i] = m_Height;
@@ -105,17 +109,15 @@ void cHeiGenFlat::InitializeHeightGen(cIniFile & a_IniFile)
 cHeiGenCache::cHeiGenCache(cTerrainHeightGenPtr a_HeiGenToCache, size_t a_CacheSize) :
 	m_HeiGenToCache(a_HeiGenToCache),
 	m_CacheSize(a_CacheSize),
-	m_CacheOrder(new size_t[a_CacheSize]),
-	m_CacheData(new sCacheData[a_CacheSize]),
 	m_NumHits(0),
 	m_NumMisses(0),
 	m_TotalChain(0)
 {
+	m_CacheOrder.resize(a_CacheSize);
+	m_CacheData.resize(a_CacheSize);
 	for (size_t i = 0; i < m_CacheSize; i++)
 	{
 		m_CacheOrder[i] = i;
-		m_CacheData[i].m_ChunkX = 0x7fffffff;
-		m_CacheData[i].m_ChunkZ = 0x7fffffff;
 	}
 }
 
@@ -123,19 +125,7 @@ cHeiGenCache::cHeiGenCache(cTerrainHeightGenPtr a_HeiGenToCache, size_t a_CacheS
 
 
 
-cHeiGenCache::~cHeiGenCache()
-{
-	delete[] m_CacheData;
-	m_CacheData = nullptr;
-	delete[] m_CacheOrder;
-	m_CacheOrder = nullptr;
-}
-
-
-
-
-
-void cHeiGenCache::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap)
+void cHeiGenCache::GenHeightMap(cChunkCoords a_ChunkCoords, cChunkDef::HeightMap & a_HeightMap)
 {
 	/*
 	if (((m_NumHits + m_NumMisses) % 1024) == 10)
@@ -147,10 +137,7 @@ void cHeiGenCache::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap
 
 	for (size_t i = 0; i < m_CacheSize; i++)
 	{
-		if (
-			(m_CacheData[m_CacheOrder[i]].m_ChunkX != a_ChunkX) ||
-			(m_CacheData[m_CacheOrder[i]].m_ChunkZ != a_ChunkZ)
-		)
+		if (m_CacheData[m_CacheOrder[i]].m_Coords != a_ChunkCoords)
 		{
 			continue;
 		}
@@ -174,7 +161,7 @@ void cHeiGenCache::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap
 
 	// Not in the cache:
 	m_NumMisses++;
-	m_HeiGenToCache->GenHeightMap(a_ChunkX, a_ChunkZ, a_HeightMap);
+	m_HeiGenToCache->GenHeightMap(a_ChunkCoords, a_HeightMap);
 
 	// Insert it as the first item in the MRU order:
 	auto Idx = m_CacheOrder[m_CacheSize - 1];
@@ -184,8 +171,7 @@ void cHeiGenCache::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap
 	}  // for i - m_CacheOrder[]
 	m_CacheOrder[0] = Idx;
 	memcpy(m_CacheData[Idx].m_HeightMap, a_HeightMap, sizeof(a_HeightMap));
-	m_CacheData[Idx].m_ChunkX = a_ChunkX;
-	m_CacheData[Idx].m_ChunkZ = a_ChunkZ;
+	m_CacheData[Idx].m_Coords = a_ChunkCoords;
 }
 
 
@@ -205,7 +191,7 @@ HEIGHTTYPE cHeiGenCache::GetHeightAt(int a_BlockX, int a_BlockZ)
 
 	// Chunk not in cache, generate the chunk and ask again:
 	cChunkDef::HeightMap heightMap;
-	GenHeightMap(chunkX, chunkZ, heightMap);
+	GenHeightMap({chunkX, chunkZ}, heightMap);
 	return cChunkDef::GetHeight(heightMap, a_BlockX - chunkX * cChunkDef::Width, a_BlockZ - chunkZ * cChunkDef::Width);
 }
 
@@ -217,7 +203,7 @@ bool cHeiGenCache::GetHeightAt(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_Rel
 {
 	for (size_t i = 0; i < m_CacheSize; i++)
 	{
-		if ((m_CacheData[i].m_ChunkX == a_ChunkX) && (m_CacheData[i].m_ChunkZ == a_ChunkZ))
+		if ((m_CacheData[i].m_Coords.m_ChunkX == a_ChunkX) && (m_CacheData[i].m_Coords.m_ChunkZ == a_ChunkZ))
 		{
 			a_Height = cChunkDef::GetHeight(m_CacheData[i].m_HeightMap, a_RelX, a_RelZ);
 			return true;
@@ -248,13 +234,13 @@ cHeiGenMultiCache::cHeiGenMultiCache(cTerrainHeightGenPtr a_HeiGenToCache, size_
 
 
 
-void cHeiGenMultiCache::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap)
+void cHeiGenMultiCache::GenHeightMap(cChunkCoords a_ChunkCoords, cChunkDef::HeightMap & a_HeightMap)
 {
 	// Get the subcache responsible for this chunk:
-	const size_t cacheIdx = (static_cast<size_t>(a_ChunkX) + m_CoeffZ * static_cast<size_t>(a_ChunkZ)) % m_NumSubCaches;
+	const size_t cacheIdx = (static_cast<size_t>(a_ChunkCoords.m_ChunkX) + m_CoeffZ * static_cast<size_t>(a_ChunkCoords.m_ChunkZ)) % m_NumSubCaches;
 
 	// Ask the subcache:
-	m_SubCaches[cacheIdx]->GenHeightMap(a_ChunkX, a_ChunkZ, a_HeightMap);
+	m_SubCaches[cacheIdx]->GenHeightMap(a_ChunkCoords, a_HeightMap);
 }
 
 
@@ -274,7 +260,7 @@ HEIGHTTYPE cHeiGenMultiCache::GetHeightAt(int a_BlockX, int a_BlockZ)
 
 	// Chunk not in cache, generate the chunk and ask again:
 	cChunkDef::HeightMap heightMap;
-	GenHeightMap(chunkX, chunkZ, heightMap);
+	GenHeightMap({chunkX, chunkZ}, heightMap);
 	return cChunkDef::GetHeight(heightMap, a_BlockX - chunkX * cChunkDef::Width, a_BlockZ - chunkZ * cChunkDef::Width);
 }
 
@@ -332,14 +318,14 @@ float cHeiGenClassic::GetNoise(float x, float y)
 
 
 
-void cHeiGenClassic::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap)
+void cHeiGenClassic::GenHeightMap(cChunkCoords a_ChunkCoords, cChunkDef::HeightMap & a_HeightMap)
 {
 	for (int z = 0; z < cChunkDef::Width; z++)
 	{
-		const float zz = static_cast<float>(a_ChunkZ * cChunkDef::Width + z);
+		const float zz = static_cast<float>(a_ChunkCoords.m_ChunkZ * cChunkDef::Width + z);
 		for (int x = 0; x < cChunkDef::Width; x++)
 		{
-			const float xx = static_cast<float>(a_ChunkX * cChunkDef::Width + x);
+			const float xx = static_cast<float>(a_ChunkCoords.m_ChunkX * cChunkDef::Width + x);
 
 			HEIGHTTYPE hei = static_cast<HEIGHTTYPE>(Clamp(static_cast<int>(64 + (GetNoise(xx * 0.05f, zz * 0.05f) * 16)), 10, 250));
 			cChunkDef::SetHeight(a_HeightMap, x, z, hei);
@@ -380,12 +366,12 @@ cHeiGenMountains::cHeiGenMountains(int a_Seed) :
 
 
 
-void cHeiGenMountains::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap)
+void cHeiGenMountains::GenHeightMap(cChunkCoords a_ChunkCoords, cChunkDef::HeightMap & a_HeightMap)
 {
-	NOISE_DATATYPE StartX = static_cast<NOISE_DATATYPE>(a_ChunkX * cChunkDef::Width);
-	NOISE_DATATYPE EndX   = static_cast<NOISE_DATATYPE>(a_ChunkX * cChunkDef::Width + cChunkDef::Width - 1);
-	NOISE_DATATYPE StartZ = static_cast<NOISE_DATATYPE>(a_ChunkZ * cChunkDef::Width);
-	NOISE_DATATYPE EndZ   = static_cast<NOISE_DATATYPE>(a_ChunkZ * cChunkDef::Width + cChunkDef::Width - 1);
+	NOISE_DATATYPE StartX = static_cast<NOISE_DATATYPE>(a_ChunkCoords.m_ChunkX * cChunkDef::Width);
+	NOISE_DATATYPE EndX   = static_cast<NOISE_DATATYPE>(a_ChunkCoords.m_ChunkX * cChunkDef::Width + cChunkDef::Width - 1);
+	NOISE_DATATYPE StartZ = static_cast<NOISE_DATATYPE>(a_ChunkCoords.m_ChunkZ * cChunkDef::Width);
+	NOISE_DATATYPE EndZ   = static_cast<NOISE_DATATYPE>(a_ChunkCoords.m_ChunkZ * cChunkDef::Width + cChunkDef::Width - 1);
 	NOISE_DATATYPE Workspace[16 * 16];
 	NOISE_DATATYPE MountainNoise[16 * 16];
 	NOISE_DATATYPE DitchNoise[16 * 16];
@@ -523,7 +509,7 @@ const cHeiGenBiomal::sGenParam cHeiGenBiomal::m_GenParam[256] =
 
 
 
-void cHeiGenBiomal::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap)
+void cHeiGenBiomal::GenHeightMap(cChunkCoords a_ChunkCoords, cChunkDef::HeightMap & a_HeightMap)
 {
 	// Generate a 3x3 chunk area of biomes around this chunk:
 	BiomeNeighbors Biomes;
@@ -531,19 +517,12 @@ void cHeiGenBiomal::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMa
 	{
 		for (int x = -1; x <= 1; x++)
 		{
-			m_BiomeGen->GenBiomes({a_ChunkX + x, a_ChunkZ + z}, Biomes[x + 1][z + 1]);
+			m_BiomeGen->GenBiomes({a_ChunkCoords.m_ChunkX + x, a_ChunkCoords.m_ChunkZ + z}, Biomes[x + 1][z + 1]);
 		}  // for x
 	}  // for z
 
-	/*
-	_X 2013_04_22:
-	There's no point in precalculating the entire perlin noise arrays, too many values are calculated uselessly,
-	resulting in speed DEcrease.
-	*/
-
-	//*
 	// Linearly interpolate 4x4 blocks of heightmap:
-	// Must be done on a floating point datatype, else the results are ugly!
+	// Must be done on a floating point datatype, otherwise the results are ugly!
 	const int STEPZ = 4;  // Must be a divisor of 16
 	const int STEPX = 4;  // Must be a divisor of 16
 	NOISE_DATATYPE Height[17 * 17];
@@ -551,7 +530,7 @@ void cHeiGenBiomal::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMa
 	{
 		for (int x = 0; x < 17; x += STEPX)
 		{
-			Height[x + 17 * z] = GetHeightAt(x, z, a_ChunkX, a_ChunkZ, Biomes);
+			Height[x + 17 * z] = GetHeightAt(x, z, a_ChunkCoords.m_ChunkX, a_ChunkCoords.m_ChunkZ, Biomes);
 		}
 	}
 	LinearUpscale2DArrayInPlace<17, 17, STEPX, STEPZ>(Height);
@@ -564,18 +543,6 @@ void cHeiGenBiomal::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMa
 			cChunkDef::SetHeight(a_HeightMap, x, z, static_cast<HEIGHTTYPE>(Height[x + 17 * z]));
 		}
 	}
-	//*/
-
-	/*
-	// For each height, go through neighboring biomes and add up their idea of height:
-	for (int z = 0; z < cChunkDef::Width; z++)
-	{
-		for (int x = 0; x < cChunkDef::Width; x++)
-		{
-			cChunkDef::SetHeight(a_HeightMap, x, z, GetHeightAt(x, z, a_ChunkX, a_ChunkZ, Biomes));
-		}  // for x
-	}
-	//*/
 }
 
 
@@ -662,7 +629,7 @@ NOISE_DATATYPE cHeiGenBiomal::GetHeightAt(int a_RelX, int a_RelZ, int a_ChunkX,
 class cHeiGenMinMax:
 	public cTerrainHeightGen
 {
-	typedef cTerrainHeightGen super;
+	typedef cTerrainHeightGen Super;
 
 	/** Size of the averaging process, in columns (for each direction). Must be less than 16. */
 	static const int AVERAGING_SIZE = 4;
@@ -690,13 +657,13 @@ public:
 	}
 
 
-	virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap)
+	virtual void GenHeightMap(cChunkCoords a_ChunkCoords, cChunkDef::HeightMap & a_HeightMap) override
 	{
 		// Generate the biomes for the 3 * 3 neighbors:
 		cChunkDef::BiomeMap neighborBiomes[3][3];
 		for (int z = 0; z < 3; z++) for (int x = 0; x < 3; x++)
 		{
-			m_BiomeGen->GenBiomes({a_ChunkX + x - 1, a_ChunkZ + z - 1}, neighborBiomes[z][x]);
+			m_BiomeGen->GenBiomes({a_ChunkCoords.m_ChunkX + x - 1, a_ChunkCoords.m_ChunkZ + z - 1}, neighborBiomes[z][x]);
 		}
 
 		// Get the min and max heights based on the biomes:
@@ -736,9 +703,9 @@ public:
 		// Generate the base noise:
 		NOISE_DATATYPE noise[cChunkDef::Width * cChunkDef::Width];
 		NOISE_DATATYPE workspace[cChunkDef::Width * cChunkDef::Width];
-		NOISE_DATATYPE startX = static_cast<float>(a_ChunkX * cChunkDef::Width);
+		NOISE_DATATYPE startX = static_cast<float>(a_ChunkCoords.m_ChunkX * cChunkDef::Width);
 		NOISE_DATATYPE endX = startX + cChunkDef::Width - 1;
-		NOISE_DATATYPE startZ = static_cast<float>(a_ChunkZ * cChunkDef::Width);
+		NOISE_DATATYPE startZ = static_cast<float>(a_ChunkCoords.m_ChunkZ * cChunkDef::Width);
 		NOISE_DATATYPE endZ = startZ + cChunkDef::Width - 1;
 		m_Perlin.Generate2D(noise, 16, 16, startX, endX, startZ, endZ, workspace);
 
@@ -756,7 +723,7 @@ public:
 	}
 
 
-	virtual void InitializeHeightGen(cIniFile & a_IniFile)
+	virtual void InitializeHeightGen(cIniFile & a_IniFile) override
 	{
 		// No settings available
 	}
diff --git a/src/Generating/HeiGen.h b/src/Generating/HeiGen.h
index 24fe7e82e..e4fa12fb3 100644
--- a/src/Generating/HeiGen.h
+++ b/src/Generating/HeiGen.h
@@ -29,10 +29,10 @@ class cHeiGenCache :
 {
 public:
 	cHeiGenCache(cTerrainHeightGenPtr a_HeiGenToCache, size_t a_CacheSize);
-	virtual ~cHeiGenCache() override;
+	virtual ~cHeiGenCache() override = default;
 
 	// cTerrainHeightGen overrides:
-	virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override;
+	virtual void GenHeightMap(cChunkCoords a_ChunkCoords, cChunkDef::HeightMap & a_HeightMap) override;
 	virtual HEIGHTTYPE GetHeightAt(int a_BlockX, int a_BlockZ) override;
 
 	/** Retrieves height at the specified point in the cache, returns true if found, false if not found */
@@ -41,18 +41,22 @@ public:
 protected:
 	struct sCacheData
 	{
-		int m_ChunkX;
-		int m_ChunkZ;
+		cChunkCoords m_Coords;
 		cChunkDef::HeightMap m_HeightMap;
+
+		/** Default constructor: Fill in bogus coords, so that the item is not used until properly calculated. */
+		sCacheData():
+			m_Coords(0x7fffffff, 0x7fffffff)
+		{}
 	} ;
 
 	/** The terrain height generator that is being cached. */
 	cTerrainHeightGenPtr m_HeiGenToCache;
 
 	// To avoid moving large amounts of data for the MRU behavior, we MRU-ize indices to an array of the actual data
-	size_t       m_CacheSize;
-	size_t *     m_CacheOrder;  // MRU-ized order, indices into m_CacheData array
-	sCacheData * m_CacheData;   // m_CacheData[m_CacheOrder[0]] is the most recently used
+	size_t                  m_CacheSize;
+	std::vector<size_t>     m_CacheOrder;  // MRU-ized order, indices into m_CacheData array
+	std::vector<sCacheData> m_CacheData;   // m_CacheData[m_CacheOrder[0]] is the most recently used
 
 	// Cache statistics
 	size_t m_NumHits;
@@ -72,7 +76,7 @@ public:
 	cHeiGenMultiCache(cTerrainHeightGenPtr a_HeightGenToCache, size_t a_SubCacheSize, size_t a_NumSubCaches);
 
 	// cTerrainHeightGen overrides:
-	virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override;
+	virtual void GenHeightMap(cChunkCoords a_ChunkCoords, cChunkDef::HeightMap & a_HeightMap) override;
 	virtual HEIGHTTYPE GetHeightAt(int a_BlockX, int a_BlockZ) override;
 
 	/** Retrieves height at the specified point in the cache, returns true if found, false if not found */
@@ -108,7 +112,7 @@ protected:
 	HEIGHTTYPE m_Height;
 
 	// cTerrainHeightGen overrides:
-	virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override;
+	virtual void GenHeightMap(cChunkCoords a_ChunkCoords, cChunkDef::HeightMap & a_HeightMap) override;
 	virtual void InitializeHeightGen(cIniFile & a_IniFile) override;
 } ;
 
@@ -133,7 +137,7 @@ protected:
 	float GetNoise(float x, float y);
 
 	// cTerrainHeightGen overrides:
-	virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override;
+	virtual void GenHeightMap(cChunkCoords a_ChunkCoords, cChunkDef::HeightMap & a_HeightMap) override;
 	virtual void InitializeHeightGen(cIniFile & a_IniFile) override;
 } ;
 
@@ -155,7 +159,7 @@ protected:
 	cPerlinNoise m_Perlin;
 
 	// cTerrainHeightGen overrides:
-	virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override;
+	virtual void GenHeightMap(cChunkCoords a_ChunkCoords, cChunkDef::HeightMap & a_HeightMap) override;
 	virtual void InitializeHeightGen(cIniFile & a_IniFile) override;
 } ;
 
@@ -176,7 +180,7 @@ public:
 	}
 
 	// cTerrainHeightGen overrides:
-	virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override;
+	virtual void GenHeightMap(cChunkCoords a_ChunkCoords, cChunkDef::HeightMap & a_HeightMap) override;
 	virtual HEIGHTTYPE GetHeightAt(int a_BlockX, int a_BlockZ) override  // Need to provide this override due to clang's overzealous detection of overloaded virtuals
 	{
 		return Super::GetHeightAt(a_BlockX, a_BlockZ);
diff --git a/src/Generating/Noise3DGenerator.cpp b/src/Generating/Noise3DGenerator.cpp
index edef4001e..68e3f5377 100644
--- a/src/Generating/Noise3DGenerator.cpp
+++ b/src/Generating/Noise3DGenerator.cpp
@@ -368,8 +368,7 @@ cNoise3DComposable::cNoise3DComposable(int a_Seed) :
 	m_ChoiceFrequencyY(0.0),
 	m_ChoiceFrequencyZ(0.0),
 	m_AirThreshold(0.0),
-	m_LastChunkX(0x7fffffff),  // Use dummy coords that won't ever be used by real chunks
-	m_LastChunkZ(0x7fffffff)
+	m_LastChunkCoords(0x7fffffff, 0x7fffffff)  // Use dummy coords that won't ever be used by real chunks
 {
 }
 
@@ -430,15 +429,14 @@ void cNoise3DComposable::Initialize(cIniFile & a_IniFile)
 
 
 
-void cNoise3DComposable::GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ)
+void cNoise3DComposable::GenerateNoiseArrayIfNeeded(cChunkCoords a_ChunkCoords)
 {
-	if ((a_ChunkX == m_LastChunkX) && (a_ChunkZ == m_LastChunkZ))
+	if (a_ChunkCoords == m_LastChunkCoords)
 	{
 		// The noise for this chunk is already generated in m_NoiseArray
 		return;
 	}
-	m_LastChunkX = a_ChunkX;
-	m_LastChunkZ = a_ChunkZ;
+	m_LastChunkCoords = a_ChunkCoords;
 
 	// Generate all the noises:
 	NOISE_DATATYPE ChoiceNoise[5 * 5 * 33];
@@ -446,8 +444,8 @@ void cNoise3DComposable::GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ)
 	NOISE_DATATYPE DensityNoiseA[5 * 5 * 33];
 	NOISE_DATATYPE DensityNoiseB[5 * 5 * 33];
 	NOISE_DATATYPE BaseNoise[5 * 5];
-	NOISE_DATATYPE BlockX = static_cast<NOISE_DATATYPE>(a_ChunkX * cChunkDef::Width);
-	NOISE_DATATYPE BlockZ = static_cast<NOISE_DATATYPE>(a_ChunkZ * cChunkDef::Width);
+	NOISE_DATATYPE BlockX = static_cast<NOISE_DATATYPE>(a_ChunkCoords.m_ChunkX * cChunkDef::Width);
+	NOISE_DATATYPE BlockZ = static_cast<NOISE_DATATYPE>(a_ChunkCoords.m_ChunkZ * cChunkDef::Width);
 	// Note that we have to swap the X and Y coords, because noise generator uses [x + SizeX * y + SizeX * SizeY * z] ordering and we want "BlockY" to be "x":
 	m_ChoiceNoise.Generate3D  (ChoiceNoise,   33, 5, 5, 0, 257 / m_ChoiceFrequencyY, BlockX / m_ChoiceFrequencyX, (BlockX + 17) / m_ChoiceFrequencyX, BlockZ / m_ChoiceFrequencyZ, (BlockZ + 17) / m_ChoiceFrequencyZ, Workspace);
 	m_DensityNoiseA.Generate3D(DensityNoiseA, 33, 5, 5, 0, 257 / m_FrequencyY,       BlockX / m_FrequencyX,       (BlockX + 17) / m_FrequencyX,       BlockZ / m_FrequencyZ,       (BlockZ + 17) / m_FrequencyZ,       Workspace);
@@ -489,9 +487,9 @@ void cNoise3DComposable::GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ)
 
 
 
-void cNoise3DComposable::GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape)
+void cNoise3DComposable::GenShape(cChunkCoords a_ChunkCoords, cChunkDesc::Shape & a_Shape)
 {
-	GenerateNoiseArrayIfNeeded(a_ChunkX, a_ChunkZ);
+	GenerateNoiseArrayIfNeeded(a_ChunkCoords);
 
 	// Translate the noise array into Shape:
 	for (int z = 0; z < cChunkDef::Width; z++)
@@ -519,8 +517,7 @@ cBiomalNoise3DComposable::cBiomalNoise3DComposable(int a_Seed, cBiomeGenPtr a_Bi
 	m_DensityNoiseB(a_Seed + 2),
 	m_BaseNoise(a_Seed + 3),
 	m_BiomeGen(a_BiomeGen),
-	m_LastChunkX(0x7fffffff),  // Set impossible coords for the chunk so that it's always considered stale
-	m_LastChunkZ(0x7fffffff)
+	m_LastChunkCoords(0x7fffffff, 0x7fffffff)  // Set impossible coords for the chunk so that it's always considered stale
 {
 	// Generate the weight distribution for summing up neighboring biomes:
 	m_WeightSum = 0;
@@ -590,20 +587,19 @@ void cBiomalNoise3DComposable::Initialize(cIniFile & a_IniFile)
 
 
 
-void cBiomalNoise3DComposable::GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ)
+void cBiomalNoise3DComposable::GenerateNoiseArrayIfNeeded(cChunkCoords a_ChunkCoords)
 {
-	if ((a_ChunkX == m_LastChunkX) && (a_ChunkZ == m_LastChunkZ))
+	if (a_ChunkCoords == m_LastChunkCoords)
 	{
 		// The noise for this chunk is already generated in m_NoiseArray
 		return;
 	}
-	m_LastChunkX = a_ChunkX;
-	m_LastChunkZ = a_ChunkZ;
+	m_LastChunkCoords = a_ChunkCoords;
 
 	// Calculate the parameters for the biomes:
 	ChunkParam MidPoint;
 	ChunkParam HeightAmp;
-	CalcBiomeParamArrays(a_ChunkX, a_ChunkZ, HeightAmp, MidPoint);
+	CalcBiomeParamArrays(a_ChunkCoords, HeightAmp, MidPoint);
 
 	// Generate all the noises:
 	NOISE_DATATYPE ChoiceNoise[5 * 5 * 33];
@@ -611,8 +607,8 @@ void cBiomalNoise3DComposable::GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_Ch
 	NOISE_DATATYPE DensityNoiseA[5 * 5 * 33];
 	NOISE_DATATYPE DensityNoiseB[5 * 5 * 33];
 	NOISE_DATATYPE BaseNoise[5 * 5];
-	NOISE_DATATYPE BlockX = static_cast<NOISE_DATATYPE>(a_ChunkX * cChunkDef::Width);
-	NOISE_DATATYPE BlockZ = static_cast<NOISE_DATATYPE>(a_ChunkZ * cChunkDef::Width);
+	NOISE_DATATYPE BlockX = static_cast<NOISE_DATATYPE>(a_ChunkCoords.m_ChunkX * cChunkDef::Width);
+	NOISE_DATATYPE BlockZ = static_cast<NOISE_DATATYPE>(a_ChunkCoords.m_ChunkZ * cChunkDef::Width);
 	// Note that we have to swap the X and Y coords, because noise generator uses [x + SizeX * y + SizeX * SizeY * z] ordering and we want "BlockY" to be "x":
 	m_ChoiceNoise.Generate3D  (ChoiceNoise,   33, 5, 5, 0, 257 / m_ChoiceFrequencyY, BlockX / m_ChoiceFrequencyX, (BlockX + 17) / m_ChoiceFrequencyX, BlockZ / m_ChoiceFrequencyZ, (BlockZ + 17) / m_ChoiceFrequencyZ, Workspace);
 	m_DensityNoiseA.Generate3D(DensityNoiseA, 33, 5, 5, 0, 257 / m_FrequencyY,       BlockX / m_FrequencyX,       (BlockX + 17) / m_FrequencyX,       BlockZ / m_FrequencyZ,       (BlockZ + 17) / m_FrequencyZ,       Workspace);
@@ -655,7 +651,7 @@ void cBiomalNoise3DComposable::GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_Ch
 
 
 
-void cBiomalNoise3DComposable::CalcBiomeParamArrays(int a_ChunkX, int a_ChunkZ, ChunkParam & a_HeightAmp, ChunkParam & a_MidPoint)
+void cBiomalNoise3DComposable::CalcBiomeParamArrays(cChunkCoords a_ChunkCoords, ChunkParam & a_HeightAmp, ChunkParam & a_MidPoint)
 {
 	// Generate the 3 * 3 chunks of biomes around this chunk:
 	cChunkDef::BiomeMap neighborBiomes[3 * 3];
@@ -663,7 +659,7 @@ void cBiomalNoise3DComposable::CalcBiomeParamArrays(int a_ChunkX, int a_ChunkZ,
 	{
 		for (int x = 0; x < 3; x++)
 		{
-			m_BiomeGen->GenBiomes({a_ChunkX + x - 1, a_ChunkZ + z - 1}, neighborBiomes[x + 3 * z]);
+			m_BiomeGen->GenBiomes({a_ChunkCoords.m_ChunkX + x - 1, a_ChunkCoords.m_ChunkZ + z - 1}, neighborBiomes[x + 3 * z]);
 		}
 	}
 
@@ -784,9 +780,9 @@ void cBiomalNoise3DComposable::GetBiomeParams(EMCSBiome a_Biome, NOISE_DATATYPE
 
 
 
-void cBiomalNoise3DComposable::GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape)
+void cBiomalNoise3DComposable::GenShape(cChunkCoords a_ChunkCoords, cChunkDesc::Shape & a_Shape)
 {
-	GenerateNoiseArrayIfNeeded(a_ChunkX, a_ChunkZ);
+	GenerateNoiseArrayIfNeeded(a_ChunkCoords);
 
 	// Translate the noise array into Shape:
 	for (int z = 0; z < cChunkDef::Width; z++)
diff --git a/src/Generating/Noise3DGenerator.h b/src/Generating/Noise3DGenerator.h
index fa760f5f3..1f7123588 100644
--- a/src/Generating/Noise3DGenerator.h
+++ b/src/Generating/Noise3DGenerator.h
@@ -115,16 +115,15 @@ protected:
 	NOISE_DATATYPE m_AirThreshold;
 
 	// Cache for the last calculated chunk (reused between heightmap and composition queries):
-	int m_LastChunkX;
-	int m_LastChunkZ;
+	cChunkCoords m_LastChunkCoords;
 	NOISE_DATATYPE m_NoiseArray[17 * 17 * 257];  // x + 17 * z + 17 * 17 * y
 
 
 	/** Generates the 3D noise array used for terrain generation (m_NoiseArray), unless the LastChunk coords are equal to coords given */
-	void GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ);
+	void GenerateNoiseArrayIfNeeded(cChunkCoords a_ChunkCoords);
 
 	// cTerrainHeightGen overrides:
-	virtual void GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) override;
+	virtual void GenShape(cChunkCoords a_ChunkCoords, cChunkDesc::Shape & a_Shape) override;
 	virtual void InitializeShapeGen(cIniFile & a_IniFile) override { Initialize(a_IniFile); }
 } ;
 
@@ -184,8 +183,7 @@ protected:
 	NOISE_DATATYPE m_AirThreshold;
 
 	// Cache for the last calculated chunk (reused between heightmap and composition queries):
-	int m_LastChunkX;
-	int m_LastChunkZ;
+	cChunkCoords m_LastChunkCoords;
 	NOISE_DATATYPE m_NoiseArray[17 * 17 * 257];  // 257 * x + y + 257 * 17 * z
 
 	/** Weights for summing up neighboring biomes. */
@@ -196,16 +194,16 @@ protected:
 
 
 	/** Generates the 3D noise array used for terrain generation (m_NoiseArray), unless the LastChunk coords are equal to coords given */
-	void GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ);
+	void GenerateNoiseArrayIfNeeded(cChunkCoords a_ChunkCoords);
 
 	/** Calculates the biome-related parameters for the chunk. */
-	void CalcBiomeParamArrays(int a_ChunkX, int a_ChunkZ, ChunkParam & a_HeightAmp, ChunkParam & a_MidPoint);
+	void CalcBiomeParamArrays(cChunkCoords a_ChunkCoords, ChunkParam & a_HeightAmp, ChunkParam & a_MidPoint);
 
 	/** Returns the parameters for the specified biome. */
 	void GetBiomeParams(EMCSBiome a_Biome, NOISE_DATATYPE & a_HeightAmp, NOISE_DATATYPE & a_MidPoint);
 
 	// cTerrainShapeGen overrides:
-	virtual void GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) override;
+	virtual void GenShape(cChunkCoords a_ChunkCoords, cChunkDesc::Shape & a_Shape) override;
 	virtual void InitializeShapeGen(cIniFile & a_IniFile) override { Initialize(a_IniFile); }
 } ;
 
diff --git a/src/Generating/PrefabStructure.cpp b/src/Generating/PrefabStructure.cpp
index c37398be9..0474a3962 100644
--- a/src/Generating/PrefabStructure.cpp
+++ b/src/Generating/PrefabStructure.cpp
@@ -55,7 +55,7 @@ void cPrefabStructure::PlacePieceOnGround(cPlacedPiece & a_Piece)
 	int BlockY;
 	cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ);
 	cChunkDef::HeightMap HeightMap;
-	m_HeightGen->GenHeightMap(ChunkX, ChunkZ, HeightMap);
+	m_HeightGen->GenHeightMap({ChunkX, ChunkZ}, HeightMap);
 	int TerrainHeight = cChunkDef::GetHeight(HeightMap, BlockX, BlockZ);
 	a_Piece.MoveToGroundBy(TerrainHeight - FirstConnector.m_Pos.y + 1);
 }
diff --git a/src/Generating/ShapeGen.cpp b/src/Generating/ShapeGen.cpp
index 20c89e33e..28f3478ba 100644
--- a/src/Generating/ShapeGen.cpp
+++ b/src/Generating/ShapeGen.cpp
@@ -30,11 +30,11 @@ public:
 
 
 	// cTerrainShapeGen overrides:
-	virtual void GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) override
+	virtual void GenShape(cChunkCoords a_ChunkCoords, cChunkDesc::Shape & a_Shape) override
 	{
 		// Generate the heightmap:
 		cChunkDef::HeightMap heightMap;
-		m_HeightGen->GenHeightMap(a_ChunkX, a_ChunkZ, heightMap);
+		m_HeightGen->GenHeightMap(a_ChunkCoords, heightMap);
 
 		// Convert from heightmap to shape:
 		for (int z = 0; z < cChunkDef::Width; z++)
diff --git a/src/Generating/StructGen.cpp b/src/Generating/StructGen.cpp
index 35e9b8991..d3351c5c5 100644
--- a/src/Generating/StructGen.cpp
+++ b/src/Generating/StructGen.cpp
@@ -40,7 +40,7 @@ void cStructGenTrees::GenFinish(cChunkDesc & a_ChunkDesc)
 
 				cChunkDesc::Shape workerShape;
 				m_BiomeGen->GenBiomes           ({BaseX, BaseZ}, WorkerDesc.GetBiomeMap());
-				m_ShapeGen->GenShape            (BaseX, BaseZ, workerShape);
+				m_ShapeGen->GenShape            ({BaseX, BaseZ}, workerShape);
 				WorkerDesc.SetHeightFromShape   (workerShape);
 				m_CompositionGen->ComposeTerrain(WorkerDesc, workerShape);
 			}
diff --git a/src/Generating/TwoHeights.cpp b/src/Generating/TwoHeights.cpp
index 06c474458..dd05fe835 100644
--- a/src/Generating/TwoHeights.cpp
+++ b/src/Generating/TwoHeights.cpp
@@ -29,23 +29,23 @@ public:
 
 
 	// cTerrainShapeGen override:
-	virtual void GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) override
+	virtual void GenShape(cChunkCoords a_ChunkCoords, cChunkDesc::Shape & a_Shape) override
 	{
 		// Generate the two heightmaps:
 		cChunkDef::HeightMap heightsA;
 		cChunkDef::HeightMap heightsB;
-		m_HeightA.GenHeightMap(a_ChunkX, a_ChunkZ, heightsA);
-		m_HeightB.GenHeightMap(a_ChunkX, a_ChunkZ, heightsB);
+		m_HeightA.GenHeightMap(a_ChunkCoords, heightsA);
+		m_HeightB.GenHeightMap(a_ChunkCoords, heightsB);
 
 		// Generate the choice noise:
 		NOISE_DATATYPE smallChoice[33 * 5 * 5];
 		NOISE_DATATYPE workspace[33 * 5 * 5];
 		NOISE_DATATYPE startX = 0;
 		NOISE_DATATYPE endX = 256 * m_FrequencyY;
-		NOISE_DATATYPE startY =  a_ChunkX * cChunkDef::Width * m_FrequencyX;
-		NOISE_DATATYPE endY   = (a_ChunkX * cChunkDef::Width + cChunkDef::Width + 1) * m_FrequencyX;
-		NOISE_DATATYPE startZ =  a_ChunkZ * cChunkDef::Width * m_FrequencyZ;
-		NOISE_DATATYPE endZ   = (a_ChunkZ * cChunkDef::Width + cChunkDef::Width + 1) * m_FrequencyZ;
+		NOISE_DATATYPE startY =  a_ChunkCoords.m_ChunkX * cChunkDef::Width * m_FrequencyX;
+		NOISE_DATATYPE endY   = (a_ChunkCoords.m_ChunkX * cChunkDef::Width + cChunkDef::Width + 1) * m_FrequencyX;
+		NOISE_DATATYPE startZ =  a_ChunkCoords.m_ChunkZ * cChunkDef::Width * m_FrequencyZ;
+		NOISE_DATATYPE endZ   = (a_ChunkCoords.m_ChunkZ * cChunkDef::Width + cChunkDef::Width + 1) * m_FrequencyZ;
 		m_Choice.Generate3D(smallChoice, 33, 5, 5, startX, endX, startY, endY, startZ, endZ, workspace);
 		NOISE_DATATYPE choice[257 * 17 * 17];
 		LinearUpscale3DArray(smallChoice, 33, 5, 5, choice, 8, 4, 4);
diff --git a/src/Generating/VerticalStrategy.cpp b/src/Generating/VerticalStrategy.cpp
index fa85a05d7..6ca7cec9d 100644
--- a/src/Generating/VerticalStrategy.cpp
+++ b/src/Generating/VerticalStrategy.cpp
@@ -190,7 +190,7 @@ public:
 		int ChunkX, ChunkZ;
 		cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ);
 		cChunkDef::HeightMap HeightMap;
-		m_HeightGen->GenHeightMap(ChunkX, ChunkZ, HeightMap);
+		m_HeightGen->GenHeightMap({ChunkX, ChunkZ}, HeightMap);
 		cNoise noise(m_Seed);
 		int rel = m_MinRelHeight + (noise.IntNoise2DInt(a_BlockX, a_BlockZ) / 7) % m_RelHeightRange + 1;
 		return cChunkDef::GetHeight(HeightMap, a_BlockX - ChunkX * cChunkDef::Width, a_BlockZ - ChunkZ * cChunkDef::Width) + rel;
@@ -244,7 +244,7 @@ public:
 		int ChunkX, ChunkZ;
 		cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ);
 		cChunkDef::HeightMap HeightMap;
-		m_HeightGen->GenHeightMap(ChunkX, ChunkZ, HeightMap);
+		m_HeightGen->GenHeightMap({ChunkX, ChunkZ}, HeightMap);
 		int terrainHeight = static_cast<int>(cChunkDef::GetHeight(HeightMap, a_BlockX - ChunkX * cChunkDef::Width, a_BlockZ - ChunkZ * cChunkDef::Width));
 		terrainHeight = std::max(1 + terrainHeight, m_SeaLevel);
 		cNoise noise(m_Seed);
diff --git a/src/Generating/VillageGen.cpp b/src/Generating/VillageGen.cpp
index 48bf9e467..c2693608d 100644
--- a/src/Generating/VillageGen.cpp
+++ b/src/Generating/VillageGen.cpp
@@ -178,7 +178,7 @@ protected:
 		// Each intersecting prefab is placed on ground, then drawn
 		// Each intersecting road is drawn by replacing top soil blocks with gravel / sandstone blocks
 		cChunkDef::HeightMap HeightMap;  // Heightmap for this chunk, used by roads
-		m_HeightGen->GenHeightMap(a_Chunk.GetChunkX(), a_Chunk.GetChunkZ(), HeightMap);
+		m_HeightGen->GenHeightMap(a_Chunk.GetChunkCoords(), HeightMap);
 		for (cPlacedPieces::iterator itr = m_Pieces.begin(), end = m_Pieces.end(); itr != end; ++itr)
 		{
 			const cPrefab & Prefab = static_cast<const cPrefab &>((*itr)->GetPiece());
@@ -208,7 +208,7 @@ protected:
 		int BlockY;
 		cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ);
 		cChunkDef::HeightMap HeightMap;
-		m_HeightGen->GenHeightMap(ChunkX, ChunkZ, HeightMap);
+		m_HeightGen->GenHeightMap({ChunkX, ChunkZ}, HeightMap);
 		int TerrainHeight = cChunkDef::GetHeight(HeightMap, BlockX, BlockZ);
 		a_Piece.MoveToGroundBy(TerrainHeight - FirstConnector.m_Pos.y + 1);
 	}
-- 
cgit v1.2.3