summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/CMakeLists.txt27
-rw-r--r--src/Generating/ComposableGenerator.cpp17
-rw-r--r--src/Generating/MineShafts.cpp2
-rw-r--r--src/Generating/NetherFortGen.cpp265
-rw-r--r--src/Generating/NetherFortGen.h86
-rw-r--r--src/Generating/Prefabs/CMakeLists.txt13
-rw-r--r--src/Generating/Prefabs/NetherFortPrefabs.cpp303
-rw-r--r--src/Generating/Prefabs/NetherFortPrefabs.h15
8 files changed, 713 insertions, 15 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 448dc4b70..ca874517e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -6,14 +6,14 @@ include_directories (SYSTEM "${PROJECT_SOURCE_DIR}/../lib/jsoncpp/include")
include_directories (SYSTEM "${PROJECT_SOURCE_DIR}/../lib/polarssl/include")
set(FOLDERS OSSupport HTTPServer Items Blocks Protocol Generating)
-set(FOLDERS ${FOLDERS} WorldStorage Mobs Entities Simulator UI BlockEntities)
+set(FOLDERS ${FOLDERS} WorldStorage Mobs Entities Simulator UI BlockEntities Generating/Prefabs)
if (NOT MSVC)
- #Bindings needs to reference other folders so are done here
+ # Bindings need to reference other folders, so they are done here instead
- #lib dependecies are not included
+ # lib dependencies are not included
set(BINDING_DEPENDECIES
tolua
@@ -104,7 +104,6 @@ if (NOT MSVC)
Bindings/PluginLua
Bindings/PluginManager
Bindings/WebPlugin
- Bindings/WebPlugin
)
target_link_libraries(Bindings lua sqlite tolualib)
@@ -138,6 +137,7 @@ if (NOT MSVC)
else ()
+ # MSVC-specific handling: Put all files into one project, separate by the folders:
# Generate the Bindings if they don't exist:
if (NOT EXISTS "${PROJECT_SOURCE_DIR}/Bindings/Bindings.cpp")
@@ -149,6 +149,14 @@ else ()
)
endif()
+ # Get all files in this folder:
+ file(GLOB_RECURSE SOURCE
+ "*.cpp"
+ "*.h"
+ "*.pkg"
+ )
+ source_group("" FILES ${SOURCE})
+
# Add all subfolders as solution-folders:
list(APPEND FOLDERS "Resources")
list(APPEND FOLDERS "Bindings")
@@ -159,23 +167,16 @@ else ()
"${PATH}/*.rc"
"${PATH}/*.pkg"
)
- source_group("${PATH}" FILES ${FOLDER_FILES})
+ string(REPLACE "/" "\\" PROJECT_PATH ${PATH})
+ source_group("${PROJECT_PATH}" FILES ${FOLDER_FILES})
endfunction(includefolder)
foreach(folder ${FOLDERS})
includefolder(${folder})
endforeach(folder)
- file(GLOB_RECURSE SOURCE
- "*.cpp"
- "*.h"
- "*.pkg"
- )
-
include_directories("${PROJECT_SOURCE_DIR}")
- source_group("" FILES ${SOURCE})
-
# Precompiled headers (1st part)
SET_SOURCE_FILES_PROPERTIES(
Globals.cpp PROPERTIES COMPILE_FLAGS "/Yc\"Globals.h\""
diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp
index 6c00b5905..339f5709a 100644
--- a/src/Generating/ComposableGenerator.cpp
+++ b/src/Generating/ComposableGenerator.cpp
@@ -21,6 +21,7 @@
#include "DistortedHeightmap.h"
#include "EndGen.h"
#include "MineShafts.h"
+#include "NetherFortGen.h"
#include "Noise3DGenerator.h"
#include "POCPieceGenerator.h"
#include "Ravines.h"
@@ -191,9 +192,11 @@ void cComposableGenerator::DoGenerate(int a_ChunkX, int a_ChunkZ, cChunkDesc & a
m_HeightGen->GenHeightMap(a_ChunkX, a_ChunkZ, a_ChunkDesc.GetHeightMap());
}
+ bool ShouldUpdateHeightmap = false;
if (a_ChunkDesc.IsUsingDefaultComposition())
{
m_CompositionGen->ComposeTerrain(a_ChunkDesc);
+ ShouldUpdateHeightmap = true;
}
if (a_ChunkDesc.IsUsingDefaultFinish())
@@ -202,6 +205,12 @@ void cComposableGenerator::DoGenerate(int a_ChunkX, int a_ChunkZ, cChunkDesc & a
{
(*itr)->GenFinish(a_ChunkDesc);
} // for itr - m_FinishGens[]
+ ShouldUpdateHeightmap = true;
+ }
+
+ if (ShouldUpdateHeightmap)
+ {
+ a_ChunkDesc.UpdateHeightmap();
}
}
@@ -349,7 +358,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
int ChanceCrossing = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCrossing", 200);
int ChanceStaircase = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceStaircase", 200);
m_FinishGens.push_back(new cStructGenMineShafts(
- Seed, GridSize, MaxSystemSize,
+ Seed, GridSize, MaxSystemSize,
ChanceCorridor, ChanceCrossing, ChanceStaircase
));
}
@@ -361,6 +370,12 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
{
m_FinishGens.push_back(new cFinishGenNetherClumpFoliage(Seed));
}
+ else if (NoCaseCompare(*itr, "NetherForts") == 0)
+ {
+ int GridSize = a_IniFile.GetValueSetI("Generator", "NetherFortsGridSize", 512);
+ int MaxDepth = a_IniFile.GetValueSetI("Generator", "NetherFortsMaxDepth", 6);
+ m_FinishGens.push_back(new cNetherFortGen(Seed, GridSize, MaxDepth));
+ }
else if (NoCaseCompare(*itr, "OreNests") == 0)
{
m_FinishGens.push_back(new cStructGenOreNests(Seed));
diff --git a/src/Generating/MineShafts.cpp b/src/Generating/MineShafts.cpp
index 28dc37567..231295c3f 100644
--- a/src/Generating/MineShafts.cpp
+++ b/src/Generating/MineShafts.cpp
@@ -1340,7 +1340,7 @@ void cStructGenMineShafts::GetMineShaftSystemsForChunk(
BaseX -= NEIGHBORHOOD_SIZE / 2;
BaseZ -= NEIGHBORHOOD_SIZE / 2;
- // Walk the cache, move each cave system that we want into a_Caves:
+ // Walk the cache, move each cave system that we want into a_Mineshafts:
int StartX = BaseX * m_GridSize;
int EndX = (BaseX + NEIGHBORHOOD_SIZE + 1) * m_GridSize;
int StartZ = BaseZ * m_GridSize;
diff --git a/src/Generating/NetherFortGen.cpp b/src/Generating/NetherFortGen.cpp
new file mode 100644
index 000000000..25658da46
--- /dev/null
+++ b/src/Generating/NetherFortGen.cpp
@@ -0,0 +1,265 @@
+
+// NetherFortGen.cpp
+
+// Implements the cNetherFortGen class representing the nether fortress generator
+
+#include "Globals.h"
+#include "NetherFortGen.h"
+#include "Prefabs/NetherFortPrefabs.h"
+
+
+
+
+
+static const int NEIGHBORHOOD_SIZE = 3;
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cNetherFortGen::cNetherFort:
+
+class cNetherFortGen::cNetherFort
+{
+public:
+ cNetherFortGen & m_ParentGen;
+ int m_BlockX, m_BlockZ;
+ int m_GridSize;
+ int m_Seed;
+ cPlacedPieces m_Pieces;
+
+ cNetherFort(cNetherFortGen & a_ParentGen, int a_BlockX, int a_BlockZ, int a_GridSize, int a_MaxDepth, int a_Seed) :
+ m_ParentGen(a_ParentGen),
+ m_BlockX(a_BlockX),
+ m_BlockZ(a_BlockZ),
+ m_GridSize(a_GridSize),
+ m_Seed(a_Seed)
+ {
+ // TODO: Proper Y-coord placement
+ int BlockY = 64;
+
+ // Generate pieces:
+ cBFSPieceGenerator pg(m_ParentGen, a_Seed);
+ pg.PlacePieces(a_BlockX, BlockY, a_BlockZ, a_MaxDepth, m_Pieces);
+ }
+
+
+ /** Carves the system into the chunk data */
+ void ProcessChunk(cChunkDesc & a_Chunk)
+ {
+ for (cPlacedPieces::const_iterator itr = m_Pieces.begin(), end = m_Pieces.end(); itr != end; ++itr)
+ {
+ const cPrefab & Prefab = (const cPrefab &)((*itr)->GetPiece());
+ Prefab.Draw(a_Chunk, *itr);
+ } // for itr - m_PlacedPieces[]
+ }
+};
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cNetherFortGen:
+
+cNetherFortGen::cNetherFortGen(int a_Seed, int a_GridSize, int a_MaxDepth) :
+ m_Seed(a_Seed),
+ m_Noise(a_Seed),
+ m_GridSize(a_GridSize),
+ m_MaxDepth(a_MaxDepth)
+{
+ // Initialize the prefabs:
+ for (size_t i = 0; i < g_NetherFortPrefabs1Count; i++)
+ {
+ cPrefab * Prefab = new cPrefab(g_NetherFortPrefabs1[i]);
+ m_AllPieces.push_back(Prefab);
+ if (Prefab->HasConnectorType(0))
+ {
+ m_OuterPieces.push_back(Prefab);
+ }
+ if (Prefab->HasConnectorType(1))
+ {
+ m_InnerPieces.push_back(Prefab);
+ }
+ }
+
+ // Initialize the starting piece prefabs:
+ for (size_t i = 0; i < g_NetherFortStartingPrefabs1Count; i++)
+ {
+ m_StartingPieces.push_back(new cPrefab(g_NetherFortStartingPrefabs1[i]));
+ }
+
+ // DEBUG: Try one round of placement:
+ cPlacedPieces Pieces;
+ cBFSPieceGenerator pg(*this, a_Seed);
+ pg.PlacePieces(0, 64, 0, a_MaxDepth, Pieces);
+}
+
+
+
+
+
+cNetherFortGen::~cNetherFortGen()
+{
+ ClearCache();
+ for (cPieces::iterator itr = m_AllPieces.begin(), end = m_AllPieces.end(); itr != end; ++itr)
+ {
+ delete *itr;
+ } // for itr - m_AllPieces[]
+ m_AllPieces.clear();
+}
+
+
+
+
+
+void cNetherFortGen::ClearCache(void)
+{
+ // TODO
+}
+
+
+
+
+
+void cNetherFortGen::GetFortsForChunk(int a_ChunkX, int a_ChunkZ, cNetherForts & a_Forts)
+{
+ int BaseX = a_ChunkX * cChunkDef::Width / m_GridSize;
+ int BaseZ = a_ChunkZ * cChunkDef::Width / m_GridSize;
+ if (BaseX < 0)
+ {
+ --BaseX;
+ }
+ if (BaseZ < 0)
+ {
+ --BaseZ;
+ }
+ BaseX -= NEIGHBORHOOD_SIZE / 2;
+ BaseZ -= NEIGHBORHOOD_SIZE / 2;
+
+ // Walk the cache, move each cave system that we want into a_Forts:
+ int StartX = BaseX * m_GridSize;
+ int EndX = (BaseX + NEIGHBORHOOD_SIZE + 1) * m_GridSize;
+ int StartZ = BaseZ * m_GridSize;
+ int EndZ = (BaseZ + NEIGHBORHOOD_SIZE + 1) * m_GridSize;
+ for (cNetherForts::iterator itr = m_Cache.begin(), end = m_Cache.end(); itr != end;)
+ {
+ if (
+ ((*itr)->m_BlockX >= StartX) && ((*itr)->m_BlockX < EndX) &&
+ ((*itr)->m_BlockZ >= StartZ) && ((*itr)->m_BlockZ < EndZ)
+ )
+ {
+ // want
+ a_Forts.push_back(*itr);
+ itr = m_Cache.erase(itr);
+ }
+ else
+ {
+ // don't want
+ ++itr;
+ }
+ } // for itr - m_Cache[]
+
+ // Create those forts that haven't been in the cache:
+ for (int x = 0; x < NEIGHBORHOOD_SIZE; x++)
+ {
+ int RealX = (BaseX + x) * m_GridSize;
+ for (int z = 0; z < NEIGHBORHOOD_SIZE; z++)
+ {
+ int RealZ = (BaseZ + z) * m_GridSize;
+ bool Found = false;
+ for (cNetherForts::const_iterator itr = a_Forts.begin(), end = a_Forts.end(); itr != end; ++itr)
+ {
+ if (((*itr)->m_BlockX == RealX) && ((*itr)->m_BlockZ == RealZ))
+ {
+ Found = true;
+ break;
+ }
+ } // for itr - a_Mineshafts
+ if (!Found)
+ {
+ a_Forts.push_back(new cNetherFort(*this, RealX, RealZ, m_GridSize, m_MaxDepth, m_Seed));
+ }
+ } // for z
+ } // for x
+
+ // Copy a_Forts into m_Cache to the beginning:
+ cNetherForts FortsCopy (a_Forts);
+ m_Cache.splice(m_Cache.begin(), FortsCopy, FortsCopy.begin(), FortsCopy.end());
+
+ // Trim the cache if it's too long:
+ if (m_Cache.size() > 100)
+ {
+ cNetherForts::iterator itr = m_Cache.begin();
+ std::advance(itr, 100);
+ for (cNetherForts::iterator end = m_Cache.end(); itr != end; ++itr)
+ {
+ delete *itr;
+ }
+ itr = m_Cache.begin();
+ std::advance(itr, 100);
+ m_Cache.erase(itr, m_Cache.end());
+ }
+}
+
+
+
+
+
+void cNetherFortGen::GenFinish(cChunkDesc & a_ChunkDesc)
+{
+ int ChunkX = a_ChunkDesc.GetChunkX();
+ int ChunkZ = a_ChunkDesc.GetChunkZ();
+ cNetherForts Forts;
+ GetFortsForChunk(ChunkX, ChunkZ, Forts);
+ for (cNetherForts::const_iterator itr = Forts.begin(); itr != Forts.end(); ++itr)
+ {
+ (*itr)->ProcessChunk(a_ChunkDesc);
+ } // for itr - Forts[]
+}
+
+
+
+
+
+cPieces cNetherFortGen::GetPiecesWithConnector(int a_ConnectorType)
+{
+ switch (a_ConnectorType)
+ {
+ case 0: return m_OuterPieces;
+ case 1: return m_InnerPieces;
+ default: return cPieces();
+ }
+}
+
+
+
+
+
+cPieces cNetherFortGen::GetStartingPieces(void)
+{
+ return m_StartingPieces;
+}
+
+
+
+
+
+void cNetherFortGen::PiecePlaced(const cPiece & a_Piece)
+{
+ UNUSED(a_Piece);
+}
+
+
+
+
+
+void cNetherFortGen::Reset(void)
+{
+ // Nothing needed
+}
+
+
+
+
diff --git a/src/Generating/NetherFortGen.h b/src/Generating/NetherFortGen.h
new file mode 100644
index 000000000..10ba01396
--- /dev/null
+++ b/src/Generating/NetherFortGen.h
@@ -0,0 +1,86 @@
+
+// NetherFortGen.h
+
+// Declares the cNetherFortGen class representing the nether fortress generator
+
+
+
+
+
+#pragma once
+
+#include "ComposableGenerator.h"
+#include "PieceGenerator.h"
+
+
+
+
+
+class cNetherFortGen :
+ public cFinishGen,
+ public cPiecePool
+{
+public:
+ cNetherFortGen(int a_Seed, int a_GridSize, int a_MaxDepth);
+
+ virtual ~cNetherFortGen();
+
+protected:
+ class cNetherFort; // fwd: NetherFortGen.cpp
+ typedef std::list<cNetherFort *> cNetherForts;
+
+
+ /** The seed used for generating*/
+ int m_Seed;
+
+ /** The noise used for generating */
+ cNoise m_Noise;
+
+ /** Average spacing between the fortresses*/
+ int m_GridSize;
+
+ /** Maximum depth of the piece-generator tree */
+ int m_MaxDepth;
+
+ /** Cache of the most recently used systems. MoveToFront used. */
+ cNetherForts m_Cache;
+
+ /** All the pieces that are allowed for building.
+ This is the list that's used for memory allocation and deallocation for the pieces. */
+ cPieces m_AllPieces;
+
+ /** The pieces that are used as starting pieces.
+ This list is not shared and the pieces need deallocation. */
+ cPieces m_StartingPieces;
+
+ /** The pieces that have an "outer" connector.
+ The pieces are copies out of m_AllPieces and shouldn't be ever delete-d. */
+ cPieces m_OuterPieces;
+
+ /** The pieces that have an "inner" connector.
+ The pieces are copies out of m_AllPieces and shouldn't be ever delete-d. */
+ cPieces m_InnerPieces;
+
+
+ /** Clears everything from the cache.
+ Also invalidates the forst returned by GetFortsForChunk(). */
+ void ClearCache(void);
+
+ /** Returns all forts that *may* intersect the given chunk.
+ The returned forts live within m_Cache.They are valid until the next call
+ to this function (which may delete some of the pointers). */
+ void GetFortsForChunk(int a_ChunkX, int a_ChunkZ, cNetherForts & a_Forts);
+
+ // cFinishGen overrides:
+ virtual void GenFinish(cChunkDesc & a_ChunkDesc) override;
+
+ // cPiecePool overrides:
+ virtual cPieces GetPiecesWithConnector(int a_ConnectorType) override;
+ virtual cPieces GetStartingPieces(void) override;
+ virtual void PiecePlaced(const cPiece & a_Piece) override;
+ virtual void Reset(void) override;
+} ;
+
+
+
+
diff --git a/src/Generating/Prefabs/CMakeLists.txt b/src/Generating/Prefabs/CMakeLists.txt
new file mode 100644
index 000000000..1e60447e7
--- /dev/null
+++ b/src/Generating/Prefabs/CMakeLists.txt
@@ -0,0 +1,13 @@
+
+cmake_minimum_required (VERSION 2.6)
+project (MCServer)
+
+include_directories ("${PROJECT_SOURCE_DIR}/../../")
+
+file(GLOB SOURCE
+ "*.cpp"
+)
+
+add_library(Generating_Prefabs ${SOURCE})
+
+target_link_libraries(Generating_Prefabs OSSupport iniFile Blocks)
diff --git a/src/Generating/Prefabs/NetherFortPrefabs.cpp b/src/Generating/Prefabs/NetherFortPrefabs.cpp
new file mode 100644
index 000000000..ea3a298c0
--- /dev/null
+++ b/src/Generating/Prefabs/NetherFortPrefabs.cpp
@@ -0,0 +1,303 @@
+
+// NetherFortPrefabs.cpp
+
+// Defines all the prefabs for nether forts
+
+#include "Globals.h"
+#include "NetherFortPrefabs.h"
+
+
+
+
+
+/*
+The nether fortress has two types of connectors, Outer and Inner. Outer is Type 0, Inner is Type 1.
+*/
+
+
+
+
+
+const cPrefab::sDef g_NetherFortPrefabs1[] =
+{
+ // BalconyCorridor:
+ // The data has been exported from gallery Nether, area index 37, ID 288
+ {
+ // Size:
+ 13, 7, 9, // SizeX = 13, SizeY = 7, SizeZ = 9
+
+ // Block definitions:
+ "a:112: 0\n" /* netherbrick */
+ "b: 0: 0\n" /* air */
+ "c:114: 4\n" /* netherbrickstairs */
+ "d:114: 7\n" /* netherbrickstairs */
+ "e:114: 5\n" /* netherbrickstairs */
+ "f: 44: 6\n" /* step */
+ "g:113: 0\n" /* netherbrickfence */
+ "h:114: 2\n" /* netherbrickstairs */
+ "i:114: 3\n" /* netherbrickstairs */
+ "j:114: 0\n" /* netherbrickstairs */
+ "k:114: 1\n" /* netherbrickstairs */,
+
+ // Block data:
+ // Level 1
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "bbbbaaaaabbbb"
+ "bbbbbbbbbbbbb"
+ "bbbbbbbbbbbbb"
+ "bbbbbbbbbbbbb"
+
+ // Level 2
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaabaaabaaaa"
+ "bbcdaaaaadebb"
+ "bbbcdddddebbb"
+ "bbbbbbbbbbbbb"
+ "bbbbbbbbbbbbb"
+
+ // Level 3
+ "aaaaaaaaaaaaa"
+ "bbbbbbbbbbbbb"
+ "bbbbbbbbbbbbb"
+ "bbbbbbbbbbbbb"
+ "aaaabfffbaaaa"
+ "bbaaaaaaaaabb"
+ "bbaaaaaaaaabb"
+ "bbaaaaaaaaabb"
+ "bbaaaaaaaaabb"
+
+ // Level 4
+ "agagagagagaga"
+ "bbbbbbbbbbbbb"
+ "bbbbbbbbbbbbb"
+ "bbbbbbbbbbbbb"
+ "agaabbbbbaaga"
+ "bbaaabbbaaabb"
+ "bbgbbbbbbbgbb"
+ "bbgbbbbbbbgbb"
+ "bbgggggggggbb"
+
+ // Level 5
+ "agagagagagaga"
+ "bbbbbbbbbbbbb"
+ "bbbbbbbbbbbbb"
+ "bbbbbbbbbbbbb"
+ "agaabbbbbaaga"
+ "bbaaabbbaaabb"
+ "bbbbbbbbbbbbb"
+ "bbbbbbbbbbbbb"
+ "bbbbbbbbbbbbb"
+
+ // Level 6
+ "agagagagagaga"
+ "bbbbbbbbbbbbb"
+ "bbbbbbbbbbbbb"
+ "bbbbbbbbbbbbb"
+ "agaabbbbbaaga"
+ "bbaaabbbaaabb"
+ "bbbbbbbbbbbbb"
+ "bbbbbbbbbbbbb"
+ "bbbbbbbbbbbbb"
+
+ // Level 7
+ "hhhhhhhhhhhhh"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "iijaaaaaaaiii"
+ "bbjiiiiiiikbb"
+ "bbbbbbbbbbbbb"
+ "bbbbbbbbbbbbb"
+ "bbbbbbbbbbbbb",
+
+ // Connections:
+ "1: 0, 2, 2: 4\n" /* Type 1, BLOCK_FACE_XM */
+ "1: 12, 2, 2: 5\n" /* Type 1, BLOCK_FACE_XP */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotations */
+
+ // Merge strategy:
+ cBlockArea::msImprint,
+ },
+} ; // g_NetherFortPrefabs1
+
+
+
+
+
+const cPrefab::sDef g_NetherFortStartingPrefabs1[] =
+{
+ // CentralRoom:
+ // The data has been exported from gallery Nether, area index 22, ID 164
+ {
+ // Size:
+ 13, 9, 13, // SizeX = 13, SizeY = 9, SizeZ = 13
+
+ // Block definitions:
+ "a:112: 0\n" /* netherbrick */
+ "b: 0: 0\n" /* air */
+ "c: 10: 0\n" /* lava */
+ "d:113: 0\n" /* netherbrickfence */,
+
+ // Block data:
+ // Level 1
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+
+ // Level 2
+ "aaaaabbbaaaaa"
+ "aaaaabbbaaaaa"
+ "aabbbbbbbbbaa"
+ "aabbbbbbbbbaa"
+ "aabbbbbbbbbaa"
+ "aabbbaaabbbaa"
+ "aabbbacabbbaa"
+ "aabbbaaabbbaa"
+ "aabbbbbbbbbaa"
+ "aabbbbbbbbbaa"
+ "aabbbbbbbbbaa"
+ "aaaaabbbaaaaa"
+ "aaaaabbbaaaaa"
+
+ // Level 3
+ "aaaaabbbaaaaa"
+ "aaadabbbadaaa"
+ "aabbbbbbbbbaa"
+ "adbbbbbbbbbda"
+ "aabbbbbbbbbaa"
+ "adbbbbbbbbbda"
+ "aabbbbbbbbbaa"
+ "adbbbbbbbbbda"
+ "aabbbbbbbbbaa"
+ "adbbbbbbbbbda"
+ "aabbbbbbbbbaa"
+ "aaadabbbadaaa"
+ "aaaaabbbaaaaa"
+
+ // Level 4
+ "aaaaabbbaaaaa"
+ "aaadabbbadaaa"
+ "aabbbbbbbbbaa"
+ "adbbbbbbbbbda"
+ "aabbbbbbbbbaa"
+ "adbbbbbbbbbda"
+ "aabbbbbbbbbaa"
+ "adbbbbbbbbbda"
+ "aabbbbbbbbbaa"
+ "adbbbbbbbbbda"
+ "aabbbbbbbbbaa"
+ "aaadabbbadaaa"
+ "aaaaabbbaaaaa"
+
+ // Level 5
+ "adadabbbadada"
+ "daaaabbbaaaad"
+ "aabbbbbbbbbaa"
+ "dabbbbbbbbbad"
+ "aabbbbbbbbbaa"
+ "dabbbbbbbbbad"
+ "aabbbbbbbbbaa"
+ "dabbbbbbbbbad"
+ "aabbbbbbbbbaa"
+ "dabbbbbbbbbad"
+ "aabbbbbbbbbaa"
+ "daaaabbbaaaad"
+ "adadabbbadada"
+
+ // Level 6
+ "adadaaaaadada"
+ "daaaaaaaaaaad"
+ "aabbbbbbbbbaa"
+ "dabbbbbbbbbad"
+ "aabbbbbbbbbaa"
+ "dabbbbbbbbbad"
+ "aabbbbbbbbbaa"
+ "dabbbbbbbbbad"
+ "aabbbbbbbbbaa"
+ "dabbbbbbbbbad"
+ "aabbbbbbbbbaa"
+ "daaaaaaaaaaad"
+ "adadaaaaadada"
+
+ // Level 7
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+
+ // Level 8
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+ "aaaaaaaaaaaaa"
+
+ // Level 9
+ "dadadadadadad"
+ "abbbbbbbbbbba"
+ "dbbbbbbbbbbbd"
+ "abbbbbbbbbbba"
+ "dbbbbbbbbbbbd"
+ "abbbbbbbbbbba"
+ "dbbbbbbbbbbbd"
+ "abbbbbbbbbbba"
+ "dbbbbbbbbbbbd"
+ "abbbbbbbbbbba"
+ "dbbbbbbbbbbbd"
+ "abbbbbbbbbbba"
+ "dadadadadadad",
+
+ // Connections:
+ "0: 6, 1, 0: 2\n" /* Type 0, BLOCK_FACE_ZM */
+ "1: 6, 1, 12: 3\n" /* Type 1, BLOCK_FACE_ZP */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotations */
+
+ // Merge strategy:
+ cBlockArea::msImprint,
+ },
+} ; // g_NetherFortStartingPrefabs1
+
+const size_t g_NetherFortPrefabs1Count = ARRAYCOUNT(g_NetherFortPrefabs1);
+const size_t g_NetherFortStartingPrefabs1Count = ARRAYCOUNT(g_NetherFortStartingPrefabs1);
+
+
+
+
diff --git a/src/Generating/Prefabs/NetherFortPrefabs.h b/src/Generating/Prefabs/NetherFortPrefabs.h
new file mode 100644
index 000000000..37a91689d
--- /dev/null
+++ b/src/Generating/Prefabs/NetherFortPrefabs.h
@@ -0,0 +1,15 @@
+
+// NetherFortPrefabs.h
+
+// Declares the data used for nether fortress prefabs
+
+#include "../Prefab.h"
+
+
+
+
+
+extern const cPrefab::sDef g_NetherFortPrefabs1[];
+extern const cPrefab::sDef g_NetherFortStartingPrefabs1[];
+extern const size_t g_NetherFortPrefabs1Count;
+extern const size_t g_NetherFortStartingPrefabs1Count;