summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/Generating/GridStructGen.cpp13
-rw-r--r--src/Generating/PieceGenerator.cpp287
-rw-r--r--src/Generating/PieceGenerator.h52
-rw-r--r--src/Generating/Prefab.cpp14
-rw-r--r--src/Generating/Prefab.h2
-rw-r--r--src/Generating/PrefabPiecePool.cpp12
-rw-r--r--src/Generating/VillageGen.cpp12
-rw-r--r--src/StringUtils.h6
8 files changed, 351 insertions, 47 deletions
diff --git a/src/Generating/GridStructGen.cpp b/src/Generating/GridStructGen.cpp
index 0068783eb..83a98706f 100644
--- a/src/Generating/GridStructGen.cpp
+++ b/src/Generating/GridStructGen.cpp
@@ -101,12 +101,13 @@ cGridStructGen::cGridStructGen(int a_Seed):
void cGridStructGen::SetGeneratorParams(const AStringMap & a_GeneratorParams)
{
ASSERT(m_Cache.empty()); // No changing the params after chunks are generated
- m_GridSizeX = GetStringMapInteger<int>(a_GeneratorParams, "GridSizeX", m_GridSizeX);
- m_GridSizeZ = GetStringMapInteger<int>(a_GeneratorParams, "GridSizeZ", m_GridSizeZ);
- m_MaxOffsetX = GetStringMapInteger<int>(a_GeneratorParams, "MaxOffsetX", m_MaxOffsetX);
- m_MaxOffsetZ = GetStringMapInteger<int>(a_GeneratorParams, "MaxOffsetZ", m_MaxOffsetZ);
- m_MaxStructureSizeX = GetStringMapInteger<int>(a_GeneratorParams, "MaxStructureSizeX", m_MaxStructureSizeX);
- m_MaxStructureSizeZ = GetStringMapInteger<int>(a_GeneratorParams, "MaxStructureSizeZ", m_MaxStructureSizeZ);
+ m_GridSizeX = GetStringMapInteger<int> (a_GeneratorParams, "GridSizeX", m_GridSizeX);
+ m_GridSizeZ = GetStringMapInteger<int> (a_GeneratorParams, "GridSizeZ", m_GridSizeZ);
+ m_MaxOffsetX = GetStringMapInteger<int> (a_GeneratorParams, "MaxOffsetX", m_MaxOffsetX);
+ m_MaxOffsetZ = GetStringMapInteger<int> (a_GeneratorParams, "MaxOffsetZ", m_MaxOffsetZ);
+ m_MaxStructureSizeX = GetStringMapInteger<int> (a_GeneratorParams, "MaxStructureSizeX", m_MaxStructureSizeX);
+ m_MaxStructureSizeZ = GetStringMapInteger<int> (a_GeneratorParams, "MaxStructureSizeZ", m_MaxStructureSizeZ);
+ m_MaxCacheSize = GetStringMapInteger<size_t>(a_GeneratorParams, "MaxCacheSize", m_MaxCacheSize);
// Silently fix out-of-range parameters:
if (m_MaxOffsetX < 1)
diff --git a/src/Generating/PieceGenerator.cpp b/src/Generating/PieceGenerator.cpp
index 842ac349b..f8ae1d961 100644
--- a/src/Generating/PieceGenerator.cpp
+++ b/src/Generating/PieceGenerator.cpp
@@ -95,19 +95,19 @@ cPiece::cConnector cPiece::RotateMoveConnector(const cConnector & a_Connector, i
case 1:
{
// 1 CCW rotation:
- res.m_Direction = RotateBlockFaceCCW(res.m_Direction);
+ res.m_Direction = cConnector::RotateDirectionCCW(res.m_Direction);
break;
}
case 2:
{
// 2 rotations ( = axis flip):
- res.m_Direction = MirrorBlockFaceY(res.m_Direction);
+ res.m_Direction = cConnector::RotateDirection(res.m_Direction);
break;
}
case 3:
{
// 1 CW rotation:
- res.m_Direction = RotateBlockFaceCW(res.m_Direction);
+ res.m_Direction = cConnector::RotateDirectionCW(res.m_Direction);
break;
}
}
@@ -159,7 +159,7 @@ cCuboid cPiece::RotateMoveHitBox(int a_NumCCWRotations, int a_MoveX, int a_MoveY
////////////////////////////////////////////////////////////////////////////////
// cPiece::cConnector:
-cPiece::cConnector::cConnector(int a_X, int a_Y, int a_Z, int a_Type, eBlockFace a_Direction) :
+cPiece::cConnector::cConnector(int a_X, int a_Y, int a_Z, int a_Type, eDirection a_Direction) :
m_Pos(a_X, a_Y, a_Z),
m_Type(a_Type),
m_Direction(a_Direction)
@@ -170,7 +170,7 @@ cPiece::cConnector::cConnector(int a_X, int a_Y, int a_Z, int a_Type, eBlockFace
-cPiece::cConnector::cConnector(const Vector3i & a_Pos, int a_Type, eBlockFace a_Direction) :
+cPiece::cConnector::cConnector(const Vector3i & a_Pos, int a_Type, eDirection a_Direction) :
m_Pos(a_Pos),
m_Type(a_Type),
m_Direction(a_Direction)
@@ -181,6 +181,247 @@ cPiece::cConnector::cConnector(const Vector3i & a_Pos, int a_Type, eBlockFace a_
+Vector3i cPiece::cConnector::AddDirection(const Vector3i & a_Pos, eDirection a_Direction)
+{
+ switch (a_Direction)
+ {
+ case dirXM: return Vector3i(a_Pos.x - 1, a_Pos.y, a_Pos.z);
+ case dirXP: return Vector3i(a_Pos.x + 1, a_Pos.y, a_Pos.z);
+ case dirYM: return Vector3i(a_Pos.x, a_Pos.y - 1, a_Pos.z);
+ case dirYP: return Vector3i(a_Pos.x, a_Pos.y + 1, a_Pos.z);
+ case dirZM: return Vector3i(a_Pos.x, a_Pos.y, a_Pos.z - 1);
+ case dirZP: return Vector3i(a_Pos.x, a_Pos.y, a_Pos.z + 1);
+ case dirYM_XM_ZM: return Vector3i(a_Pos.x, a_Pos.y - 1, a_Pos.z);
+ case dirYM_XM_ZP: return Vector3i(a_Pos.x, a_Pos.y - 1, a_Pos.z);
+ case dirYM_XP_ZM: return Vector3i(a_Pos.x, a_Pos.y - 1, a_Pos.z);
+ case dirYM_XP_ZP: return Vector3i(a_Pos.x, a_Pos.y - 1, a_Pos.z);
+ case dirYP_XM_ZM: return Vector3i(a_Pos.x, a_Pos.y + 1, a_Pos.z);
+ case dirYP_XM_ZP: return Vector3i(a_Pos.x, a_Pos.y + 1, a_Pos.z);
+ case dirYP_XP_ZM: return Vector3i(a_Pos.x, a_Pos.y + 1, a_Pos.z);
+ case dirYP_XP_ZP: return Vector3i(a_Pos.x, a_Pos.y + 1, a_Pos.z);
+ }
+ #if !defined(__clang__)
+ ASSERT(!"Unknown connector direction");
+ return a_Pos;
+ #endif
+}
+
+
+
+
+
+const char * cPiece::cConnector::DirectionToString(eDirection a_Direction)
+{
+ switch (a_Direction)
+ {
+ case dirXM: return "x-";
+ case dirXP: return "x+";
+ case dirYM: return "y-";
+ case dirYP: return "y+";
+ case dirZM: return "z-";
+ case dirZP: return "z+";
+ case dirYM_XM_ZM: return "y-x-z-";
+ case dirYM_XM_ZP: return "y-x-z+";
+ case dirYM_XP_ZM: return "y-x+z-";
+ case dirYM_XP_ZP: return "y-x+z+";
+ case dirYP_XM_ZM: return "y+x-z-";
+ case dirYP_XM_ZP: return "y+x-z+";
+ case dirYP_XP_ZM: return "y+x+z-";
+ case dirYP_XP_ZP: return "y+x+z+";
+ }
+ #if !defined(__clang__)
+ ASSERT(!"Unknown connector direction");
+ return "<unknown>";
+ #endif
+}
+
+
+
+
+
+bool cPiece::cConnector::IsValidDirection(int a_Direction)
+{
+ switch (a_Direction)
+ {
+ case dirXM:
+ case dirXP:
+ case dirYM:
+ case dirYP:
+ case dirZM:
+ case dirZP:
+ case dirYM_XM_ZM:
+ case dirYM_XM_ZP:
+ case dirYM_XP_ZM:
+ case dirYM_XP_ZP:
+ case dirYP_XM_ZM:
+ case dirYP_XM_ZP:
+ case dirYP_XP_ZM:
+ case dirYP_XP_ZP:
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+
+
+
+cPiece::cConnector::eDirection cPiece::cConnector::RotateDirection(eDirection a_Direction)
+{
+ // 180-degree rotation:
+ switch (a_Direction)
+ {
+ case dirXM: return dirXP;
+ case dirXP: return dirXM;
+ case dirYM: return dirYM;
+ case dirYP: return dirYP;
+ case dirZM: return dirZM;
+ case dirZP: return dirZP;
+ case dirYM_XM_ZM: return dirYM_XP_ZP;
+ case dirYM_XM_ZP: return dirYM_XP_ZM;
+ case dirYM_XP_ZM: return dirYM_XM_ZP;
+ case dirYM_XP_ZP: return dirYM_XM_ZM;
+ case dirYP_XM_ZM: return dirYP_XP_ZP;
+ case dirYP_XM_ZP: return dirYP_XP_ZM;
+ case dirYP_XP_ZM: return dirYP_XM_ZP;
+ case dirYP_XP_ZP: return dirYP_XM_ZM;
+ }
+ #if !defined(__clang__)
+ ASSERT(!"Unknown connector direction");
+ return a_Direction;
+ #endif
+}
+
+
+
+
+
+cPiece::cConnector::eDirection cPiece::cConnector::RotateDirectionCCW(eDirection a_Direction)
+{
+ // 90 degrees CCW rotation:
+ switch (a_Direction)
+ {
+ case dirXM: return dirZP;
+ case dirXP: return dirZM;
+ case dirYM: return dirYM;
+ case dirYP: return dirYP;
+ case dirZM: return dirXM;
+ case dirZP: return dirXP;
+ case dirYM_XM_ZM: return dirYM_XM_ZP;
+ case dirYM_XM_ZP: return dirYM_XP_ZP;
+ case dirYM_XP_ZM: return dirYM_XM_ZM;
+ case dirYM_XP_ZP: return dirYM_XP_ZM;
+ case dirYP_XM_ZM: return dirYP_XM_ZP;
+ case dirYP_XM_ZP: return dirYP_XP_ZP;
+ case dirYP_XP_ZM: return dirYP_XM_ZM;
+ case dirYP_XP_ZP: return dirYP_XP_ZM;
+ }
+ #if !defined(__clang__)
+ ASSERT(!"Unknown connector direction");
+ return a_Direction;
+ #endif
+}
+
+
+
+
+
+cPiece::cConnector::eDirection cPiece::cConnector::RotateDirectionCW(eDirection a_Direction)
+{
+ // 90 degrees CW rotation:
+ switch (a_Direction)
+ {
+ case dirXM: return dirZM;
+ case dirXP: return dirZP;
+ case dirYM: return dirYM;
+ case dirYP: return dirYP;
+ case dirZM: return dirXP;
+ case dirZP: return dirXM;
+ case dirYM_XM_ZM: return dirYM_XP_ZM;
+ case dirYM_XM_ZP: return dirYM_XM_ZM;
+ case dirYM_XP_ZM: return dirYM_XP_ZP;
+ case dirYM_XP_ZP: return dirYM_XM_ZP;
+ case dirYP_XM_ZM: return dirYP_XP_ZM;
+ case dirYP_XM_ZP: return dirYP_XM_ZM;
+ case dirYP_XP_ZM: return dirYP_XP_ZP;
+ case dirYP_XP_ZP: return dirYP_XM_ZP;
+ }
+ #if !defined(__clang__)
+ ASSERT(!"Unknown connector direction");
+ return a_Direction;
+ #endif
+}
+
+
+
+
+
+bool cPiece::cConnector::StringToDirection(const AString & a_Value, eDirection & a_Out)
+{
+ // First try converting as a number:
+ int dirInt;
+ if (StringToInteger(a_Value, dirInt))
+ {
+ if (!IsValidDirection(dirInt))
+ {
+ return false;
+ }
+ a_Out = static_cast<eDirection>(dirInt);
+ return true;
+ }
+
+ // Compare to string representation:
+ static const struct
+ {
+ const char * m_String;
+ eDirection m_Value;
+ } StringDirections[] =
+ {
+ {"x-", dirXM},
+ {"x+", dirXP},
+ {"y-", dirYM},
+ {"y+", dirYP},
+ {"z-", dirZM},
+ {"z+", dirZP},
+ {"y-x-z-", dirYM_XM_ZM},
+ {"y-x-z+", dirYM_XM_ZP},
+ {"y-x+z-", dirYM_XP_ZM},
+ {"y-x+z+", dirYM_XP_ZP},
+ {"y+x-z-", dirYP_XM_ZM},
+ {"y+x-z+", dirYP_XM_ZP},
+ {"y+x+z-", dirYP_XP_ZM},
+ {"y+x+z+", dirYP_XP_ZP},
+
+ // Alternate names, with slashes:
+ {"y-/x-/z-", dirYM_XM_ZM},
+ {"y-/x-/z+", dirYM_XM_ZP},
+ {"y-/x+/z-", dirYM_XP_ZM},
+ {"y-/x+/z+", dirYM_XP_ZP},
+ {"y+/x-/z-", dirYP_XM_ZM},
+ {"y+/x-/z+", dirYP_XM_ZP},
+ {"y+/x+/z-", dirYP_XP_ZM},
+ {"y+/x+/z+", dirYP_XP_ZP},
+ };
+ auto lcValue = StrToLower(a_Value);
+ for (size_t i = 0; i < ARRAYCOUNT(StringDirections); i++)
+ {
+ if (strcmp(lcValue.c_str(), StringDirections[i].m_String) == 0)
+ {
+ a_Out = StringDirections[i].m_Value;
+ return true;
+ }
+ }
+
+ // Not understood, failure:
+ return false;
+}
+
+
+
+
+
////////////////////////////////////////////////////////////////////////////////
// cPlacedPiece:
@@ -332,26 +573,35 @@ bool cPieceGenerator::TryPlacePieceAtConnector(
)
{
// Translation of direction - direction -> number of CCW rotations needed:
- // You need DirectionRotationTable[rot1][rot2] CCW turns to connect rot1 to rot2 (they are opposite)
- static const int DirectionRotationTable[6][6] =
+ // You need DirectionRotationTable[rot2][rot1] CCW turns to connect rot1 to rot2 (they are opposite)
+ // -1 if not possible
+ static const int DirectionRotationTable[14][14] =
{
- /* YM, YP, ZM, ZP, XM, XP */
- /* YM */ { 0, 0, 0, 0, 0, 0},
- /* YP */ { 0, 0, 0, 0, 0, 0},
- /* ZM */ { 0, 0, 2, 0, 1, 3},
- /* ZP */ { 0, 0, 0, 2, 3, 1},
- /* XM */ { 0, 0, 3, 1, 2, 0},
- /* XP */ { 0, 0, 1, 3, 0, 2},
+ /* YM, YP, ZM, ZP, XM, XP, YM-XM-ZM, YM-XM-ZP, YM-XP-ZM, YM-XP-ZP, YP-XM-ZM, YP-XM-ZP, YP-XP-ZM, YP-XP-ZP */
+ /* YM */ { 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ /* YP */ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ /* ZM */ {-1, -1, 2, 0, 1, 3, -1, -1, -1, -1, -1, -1, -1, -1},
+ /* ZP */ {-1, -1, 0, 2, 3, 1, -1, -1, -1, -1, -1, -1, -1, -1},
+ /* XM */ {-1, -1, 3, 1, 2, 0, -1, -1, -1, -1, -1, -1, -1, -1},
+ /* XP */ {-1, -1, 1, 3, 0, 2, -1, -1, -1, -1, -1, -1, -1, -1},
+ /* YM-XM-ZM */ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 3, 1, 2},
+ /* YM-XM-ZP */ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 0, 2, 3},
+ /* YM-XP-ZM */ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 2, 0, 1},
+ /* YM-XP-ZP */ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 1, 3, 0},
+ /* YP-XM-ZM */ {-1, -1, -1, -1, -1, -1, 0, 3, 1, 2, -1, -1, -1, -1},
+ /* YP-XM-ZP */ {-1, -1, -1, -1, -1, -1, 1, 0, 2, 3, -1, -1, -1, -1},
+ /* YP-XP-ZM */ {-1, -1, -1, -1, -1, -1, 3, 2, 0, 1, -1, -1, -1, -1},
+ /* YP-XP-ZP */ {-1, -1, -1, -1, -1, -1, 2, 1, 3, 0, -1, -1, -1, -1},
};
// Get a list of available connections:
+ ASSERT(a_Connector.m_Direction < ARRAYCOUNT(DirectionRotationTable));
const int * RotTable = DirectionRotationTable[a_Connector.m_Direction];
cConnections Connections;
int WantedConnectorType = -a_Connector.m_Type;
cPieces AvailablePieces = m_PiecePool.GetPiecesWithConnector(WantedConnectorType);
Connections.reserve(AvailablePieces.size());
- Vector3i ConnPos = a_Connector.m_Pos; // The position at which the new connector should be placed - 1 block away from the connector
- AddFaceDirection(ConnPos.x, ConnPos.y, ConnPos.z, a_Connector.m_Direction);
+ Vector3i ConnPos = cPiece::cConnector::AddDirection(a_Connector.m_Pos, a_Connector.m_Direction); // The position at which the new connector should be placed - 1 block away from the current connector
int WeightTotal = 0;
for (cPieces::iterator itrP = AvailablePieces.begin(), endP = AvailablePieces.end(); itrP != endP; ++itrP)
{
@@ -372,8 +622,9 @@ bool cPieceGenerator::TryPlacePieceAtConnector(
continue;
}
// This is a same-type connector, find out how to rotate to it:
+ ASSERT(itrC->m_Direction < ARRAYCOUNT(DirectionRotationTable[0]));
int NumCCWRotations = RotTable[itrC->m_Direction];
- if (!(*itrP)->CanRotateCCW(NumCCWRotations))
+ if ((NumCCWRotations < 0) || !(*itrP)->CanRotateCCW(NumCCWRotations))
{
// Doesn't support this rotation
continue;
@@ -482,7 +733,7 @@ void cPieceGenerator::DebugConnectorPool(const cPieceGenerator::cFreeConnectors
idx,
itr->m_Connector.m_Pos.x, itr->m_Connector.m_Pos.y, itr->m_Connector.m_Pos.z,
itr->m_Connector.m_Type,
- BlockFaceToString(itr->m_Connector.m_Direction).c_str(),
+ cPiece::cConnector::DirectionToString(itr->m_Connector.m_Direction),
itr->m_Piece->GetDepth()
);
} // for itr - a_ConnectorPool[]
diff --git a/src/Generating/PieceGenerator.h b/src/Generating/PieceGenerator.h
index 1d0e9deda..1900d9d02 100644
--- a/src/Generating/PieceGenerator.h
+++ b/src/Generating/PieceGenerator.h
@@ -36,6 +36,27 @@ public:
struct cConnector
{
+ enum eDirection
+ {
+ // The following values correspond to equivalent eBlockFace values:
+ dirXM = BLOCK_FACE_XM, // Pointing towards the X- side of the prefab
+ dirXP = BLOCK_FACE_XP, // Pointing towards the X+ side of the prefab
+ dirYM = BLOCK_FACE_YM, // Pointing towards the Y- side of the prefab, doesn't change with rotation around the Y axis
+ dirYP = BLOCK_FACE_YP, // Pointing towards the Y+ side of the prefab, doesn't change with rotation around the Y axis
+ dirZM = BLOCK_FACE_ZM, // Pointing towards the Z- side of the prefab
+ dirZP = BLOCK_FACE_ZP, // Pointing towards the Z+ side of the prefab
+
+ // Special kind of the vertical connectors (changes with rotation around the Y axis)
+ dirYM_XM_ZM = BLOCK_FACE_MAX + 1, // Pointing towards the Y- side of the prefab, conceptually at the X- Z- corner of the block
+ dirYM_XM_ZP, // Pointing towards the Y- side of the prefab, conceptually at the X- Z+ corner of the block
+ dirYM_XP_ZM, // Pointing towards the Y- side of the prefab, conceptually at the X+ Z- corner of the block
+ dirYM_XP_ZP, // Pointing towards the Y- side of the prefab, conceptually at the X+ Z+ corner of the block
+ dirYP_XM_ZM, // Pointing towards the Y+ side of the prefab, conceptually at the X- Z- corner of the block
+ dirYP_XM_ZP, // Pointing towards the Y+ side of the prefab, conceptually at the X- Z+ corner of the block
+ dirYP_XP_ZM, // Pointing towards the Y+ side of the prefab, conceptually at the X+ Z- corner of the block
+ dirYP_XP_ZP, // Pointing towards the Y+ side of the prefab, conceptually at the X+ Z+ corner of the block
+ };
+
/** Position relative to the piece */
Vector3i m_Pos;
@@ -45,10 +66,35 @@ public:
/** Direction in which the connector is facing.
Will be matched by the opposite direction for the connecting connector. */
- eBlockFace m_Direction;
+ eDirection m_Direction;
+
+ cConnector(int a_X, int a_Y, int a_Z, int a_Type, eDirection a_Direction);
+ cConnector(const Vector3i & a_Pos, int a_Type, eDirection a_Direction);
+
+ /** Returns the position of the block that has the specified direction from the specified position.
+ Similar to ::AddFaceDirection() */
+ static Vector3i AddDirection(const Vector3i & a_Pos, eDirection a_Direction);
+
+ /** Returns the string representation of the direction.
+ For debugging purposes. */
+ static const char * DirectionToString(eDirection a_Direction);
+
+ /** Returns true if the specified number corresponds to a valid eDirection. */
+ static bool IsValidDirection(int a_Direction);
+
+ /** Returns the direction corresponding to the given direction rotated 180 degrees around the Y axis. */
+ static eDirection RotateDirection(eDirection a_Direction);
+
+ /** Returns the direction corresponding to the given direction rotated 90 degrees CCW around the Y axis. */
+ static eDirection RotateDirectionCCW(eDirection a_Direction);
+
+ /** Returns the direction corresponding to the given direction rotated 90 degrees CW around the Y axis. */
+ static eDirection RotateDirectionCW(eDirection a_Direction);
- cConnector(int a_X, int a_Y, int a_Z, int a_Type, eBlockFace a_Direction);
- cConnector(const Vector3i & a_Pos, int a_Type, eBlockFace a_Direction);
+ /** Converts the string representation of a direction into the eDirection enum value.
+ Returns true if successful, false on failure.
+ Accepts both numbers and string representations such as "x+" or "Y+X-Z+". */
+ static bool StringToDirection(const AString & a_Value, eDirection & a_Out);
};
typedef std::vector<cConnector> cConnectors;
diff --git a/src/Generating/Prefab.cpp b/src/Generating/Prefab.cpp
index e7d9ba711..de2f5f95d 100644
--- a/src/Generating/Prefab.cpp
+++ b/src/Generating/Prefab.cpp
@@ -299,7 +299,7 @@ void cPrefab::SetDefaultWeight(int a_DefaultWeight)
-void cPrefab::AddConnector(int a_RelX, int a_RelY, int a_RelZ, eBlockFace a_Direction, int a_Type)
+void cPrefab::AddConnector(int a_RelX, int a_RelY, int a_RelZ, cPiece::cConnector::eDirection a_Direction, int a_Type)
{
m_Connectors.push_back(cConnector(a_RelX, a_RelY, a_RelZ, a_Type, a_Direction));
}
@@ -390,7 +390,7 @@ void cPrefab::ParseConnectors(const char * a_ConnectorsDef)
{
continue;
}
- // Split into components: "Type: X, Y, Z: Face":
+ // Split into components: "Type: X, Y, Z: Direction":
AStringVector Defs = StringSplitAndTrim(*itr, ":");
if (Defs.size() != 3)
{
@@ -404,11 +404,11 @@ void cPrefab::ParseConnectors(const char * a_ConnectorsDef)
continue;
}
- // Check that the BlockFace is within range:
- int BlockFace = atoi(Defs[2].c_str());
- if ((BlockFace < 0) || (BlockFace >= 6))
+ // Check that the Direction is valid:
+ cPiece::cConnector::eDirection Direction;
+ if (!cPiece::cConnector::StringToDirection(Defs[2], Direction))
{
- LOGWARNING("Bad prefab Connector Blockface: \"%s\", skipping.", Defs[2].c_str());
+ LOGWARNING("Bad prefab Connector direction: \"%s\", skipping.", Defs[2].c_str());
continue;
}
@@ -416,7 +416,7 @@ void cPrefab::ParseConnectors(const char * a_ConnectorsDef)
m_Connectors.push_back(cPiece::cConnector(
atoi(Coords[0].c_str()), atoi(Coords[1].c_str()), atoi(Coords[2].c_str()), // Connector pos
atoi(Defs[0].c_str()), // Connector type
- static_cast<eBlockFace>(BlockFace)
+ Direction
));
} // for itr - Lines[]
}
diff --git a/src/Generating/Prefab.h b/src/Generating/Prefab.h
index bb961f2b3..59b80a8a8 100644
--- a/src/Generating/Prefab.h
+++ b/src/Generating/Prefab.h
@@ -132,7 +132,7 @@ public:
void SetAddWeightIfSame(int a_AddWeightIfSame) { m_AddWeightIfSame = a_AddWeightIfSame; }
/** Adds the specified connector to the list of connectors this piece supports. */
- void AddConnector(int a_RelX, int a_RelY, int a_RelZ, eBlockFace a_Direction, int a_Type);
+ void AddConnector(int a_RelX, int a_RelY, int a_RelZ, cPiece::cConnector::eDirection a_Direction, int a_Type);
/** Returns whether the prefab should be moved Y-wise to ground before drawing, rather than staying
at the coords governed by the connectors. */
diff --git a/src/Generating/PrefabPiecePool.cpp b/src/Generating/PrefabPiecePool.cpp
index 407915e56..9c4e24e92 100644
--- a/src/Generating/PrefabPiecePool.cpp
+++ b/src/Generating/PrefabPiecePool.cpp
@@ -487,17 +487,23 @@ bool cPrefabPiecePool::ReadConnectorsCubesetVer1(
break;
}
int Type = 0, RelX = 0, RelY = 0, RelZ = 0;
- eBlockFace Direction = BLOCK_FACE_NONE;
+ AString DirectionStr;
+ cPiece::cConnector::eDirection Direction = cPiece::cConnector::dirYM;
if (
!a_LuaState.GetNamedValue("Type", Type) ||
!a_LuaState.GetNamedValue("RelX", RelX) ||
!a_LuaState.GetNamedValue("RelY", RelY) ||
!a_LuaState.GetNamedValue("RelZ", RelZ) ||
- !a_LuaState.GetNamedValue("Direction", Direction)
+ !a_LuaState.GetNamedValue("Direction", DirectionStr) ||
+ !cPiece::cConnector::StringToDirection(DirectionStr, Direction)
)
{
- CONDWARNING(a_LogWarnings, "Piece %s in file %s has a malformed Connector at index %d. Skipping the connector.", a_PieceName.c_str(), a_FileName.c_str(), idx);
+ CONDWARNING(a_LogWarnings, "Piece %s in file %s has a malformed Connector at index %d ({%d, %d, %d}, type %d, direction %s). Skipping the connector.",
+ a_PieceName.c_str(), a_FileName.c_str(), idx, RelX, RelY, RelZ, Type, DirectionStr.c_str()
+ );
res = false;
+ lua_pop(a_LuaState, 1); // stk: [Connectors]
+ idx += 1;
continue;
}
a_Prefab->AddConnector(RelX, RelY, RelZ, Direction, Type);
diff --git a/src/Generating/VillageGen.cpp b/src/Generating/VillageGen.cpp
index ccea3338d..6d5216a16 100644
--- a/src/Generating/VillageGen.cpp
+++ b/src/Generating/VillageGen.cpp
@@ -64,22 +64,22 @@ public:
BA.Create(len, 1, 3, cBlockArea::baTypes | cBlockArea::baMetas);
BA.Fill(cBlockArea::baTypes | cBlockArea::baMetas, E_BLOCK_GRAVEL, 0);
cPrefab * RoadPiece = new cPrefab(BA, 1);
- RoadPiece->AddConnector(0, 0, 1, BLOCK_FACE_XM, -2);
- RoadPiece->AddConnector(len - 1, 0, 1, BLOCK_FACE_XP, -2);
+ RoadPiece->AddConnector(0, 0, 1, cPiece::cConnector::dirXM, -2);
+ RoadPiece->AddConnector(len - 1, 0, 1, cPiece::cConnector::dirXP, -2);
RoadPiece->SetDefaultWeight(100);
// Add the road connectors:
for (int x = 1; x < len; x += 12)
{
- RoadPiece->AddConnector(x, 0, 0, BLOCK_FACE_ZM, 2);
- RoadPiece->AddConnector(x, 0, 2, BLOCK_FACE_ZP, 2);
+ RoadPiece->AddConnector(x, 0, 0, cPiece::cConnector::dirZM, 2);
+ RoadPiece->AddConnector(x, 0, 2, cPiece::cConnector::dirZP, 2);
}
// Add the buildings connectors:
for (int x = 7; x < len; x += 12)
{
- RoadPiece->AddConnector(x, 0, 0, BLOCK_FACE_ZM, 1);
- RoadPiece->AddConnector(x, 0, 2, BLOCK_FACE_ZP, 1);
+ RoadPiece->AddConnector(x, 0, 0, cPiece::cConnector::dirZM, 1);
+ RoadPiece->AddConnector(x, 0, 2, cPiece::cConnector::dirZP, 1);
}
m_AllPieces.push_back(RoadPiece);
m_PiecesByConnector[-2].push_back(RoadPiece);
diff --git a/src/StringUtils.h b/src/StringUtils.h
index e2be2b9c0..620323e70 100644
--- a/src/StringUtils.h
+++ b/src/StringUtils.h
@@ -220,10 +220,10 @@ bool StringToInteger(const AString & a_str, T & a_Num)
-/** Returns an integer from a key-value string map.
-Returns a_Default if the key is not present or the value is not an int. */
+/** Returns a number (of any integer type T) from a key-value string map.
+Returns a_Default if the key is not present or the value is not a number representable in type T. */
template <typename T>
-int GetStringMapInteger(const AStringMap & a_Map, const AString & a_Key, T a_Default)
+T GetStringMapInteger(const AStringMap & a_Map, const AString & a_Key, T a_Default)
{
// Try to locate the key:
auto itr = a_Map.find(a_Key);