Merge pull request #3569 from cuberite/AddVerticalConn
PieceGenerator: Added rotation-aware vertical connectors.
This commit is contained in:
commit
7b8380c6df
@ -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)
|
||||
|
@ -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[]
|
||||
|
@ -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, eBlockFace a_Direction);
|
||||
cConnector(const Vector3i & a_Pos, int a_Type, eBlockFace a_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);
|
||||
|
||||
/** 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;
|
||||
|
@ -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[]
|
||||
}
|
||||
|
@ -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. */
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -4,8 +4,6 @@ if (CMAKE_BUILD_TYPE STREQUAL "COVERAGE")
|
||||
setup_target_for_coverage("${PROJECT_NAME}_coverage" "ctest" coverage)
|
||||
endif()
|
||||
|
||||
# include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
add_subdirectory(BoundingBox)
|
||||
add_subdirectory(ByteBuffer)
|
||||
add_subdirectory(ChunkData)
|
||||
@ -16,4 +14,5 @@ add_subdirectory(LoadablePieces)
|
||||
add_subdirectory(LuaThreadStress)
|
||||
add_subdirectory(Network)
|
||||
add_subdirectory(OSSupport)
|
||||
add_subdirectory(PieceRotation)
|
||||
add_subdirectory(SchematicFileSerializer)
|
||||
|
15
tests/PieceRotation/Bindings.h
Normal file
15
tests/PieceRotation/Bindings.h
Normal file
@ -0,0 +1,15 @@
|
||||
|
||||
// Bindings.h
|
||||
|
||||
// Dummy include file needed for LuaState to compile successfully
|
||||
|
||||
|
||||
|
||||
|
||||
struct lua_State;
|
||||
|
||||
int tolua_AllToLua_open(lua_State * a_LuaState);
|
||||
|
||||
|
||||
|
||||
|
102
tests/PieceRotation/CMakeLists.txt
Normal file
102
tests/PieceRotation/CMakeLists.txt
Normal file
@ -0,0 +1,102 @@
|
||||
enable_testing()
|
||||
|
||||
include_directories(${CMAKE_SOURCE_DIR}/src/)
|
||||
include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/lib/)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
add_definitions(-DTEST_GLOBALS=1)
|
||||
|
||||
set (SHARED_SRCS
|
||||
${CMAKE_SOURCE_DIR}/src/BiomeDef.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/BlockArea.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/Cuboid.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/ChunkData.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/StringCompression.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/StringUtils.cpp
|
||||
|
||||
${CMAKE_SOURCE_DIR}/src/Bindings/LuaState.cpp
|
||||
|
||||
${CMAKE_SOURCE_DIR}/src/Generating/ChunkDesc.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/Generating/PieceGenerator.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/Generating/Prefab.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/Generating/PrefabPiecePool.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/Generating/VerticalLimit.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/Generating/VerticalStrategy.cpp
|
||||
|
||||
${CMAKE_SOURCE_DIR}/src/Noise/Noise.cpp
|
||||
|
||||
${CMAKE_SOURCE_DIR}/src/OSSupport/CriticalSection.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/OSSupport/Event.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/OSSupport/File.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/OSSupport/GZipFile.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/OSSupport/StackTrace.cpp
|
||||
|
||||
${CMAKE_SOURCE_DIR}/src/WorldStorage/FastNBT.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/WorldStorage/SchematicFileSerializer.cpp
|
||||
)
|
||||
|
||||
set (SHARED_HDRS
|
||||
${CMAKE_SOURCE_DIR}/src/BiomeDef.h
|
||||
${CMAKE_SOURCE_DIR}/src/BlockArea.h
|
||||
${CMAKE_SOURCE_DIR}/src/Cuboid.h
|
||||
${CMAKE_SOURCE_DIR}/src/ChunkData.h
|
||||
${CMAKE_SOURCE_DIR}/src/Globals.h
|
||||
${CMAKE_SOURCE_DIR}/src/StringCompression.h
|
||||
${CMAKE_SOURCE_DIR}/src/StringUtils.h
|
||||
|
||||
${CMAKE_SOURCE_DIR}/src/Bindings/LuaState.h
|
||||
|
||||
${CMAKE_SOURCE_DIR}/src/Generating/ChunkDesc.h
|
||||
${CMAKE_SOURCE_DIR}/src/Generating/PieceGenerator.h
|
||||
${CMAKE_SOURCE_DIR}/src/Generating/Prefab.h
|
||||
${CMAKE_SOURCE_DIR}/src/Generating/PrefabPiecePool.h
|
||||
${CMAKE_SOURCE_DIR}/src/Generating/VerticalLimit.h
|
||||
${CMAKE_SOURCE_DIR}/src/Generating/VerticalStrategy.h
|
||||
|
||||
${CMAKE_SOURCE_DIR}/src/Noise/Noise.h
|
||||
|
||||
${CMAKE_SOURCE_DIR}/src/OSSupport/CriticalSection.h
|
||||
${CMAKE_SOURCE_DIR}/src/OSSupport/Event.h
|
||||
${CMAKE_SOURCE_DIR}/src/OSSupport/File.h
|
||||
${CMAKE_SOURCE_DIR}/src/OSSupport/GZipFile.h
|
||||
${CMAKE_SOURCE_DIR}/src/OSSupport/StackTrace.h
|
||||
|
||||
${CMAKE_SOURCE_DIR}/src/WorldStorage/FastNBT.h
|
||||
${CMAKE_SOURCE_DIR}/src/WorldStorage/SchematicFileSerializer.h
|
||||
)
|
||||
|
||||
set (SRCS
|
||||
PieceRotationTest.cpp
|
||||
Stubs.cpp
|
||||
LuaState_Typedefs.inc
|
||||
LuaState_Declaration.inc
|
||||
Bindings.h
|
||||
)
|
||||
|
||||
|
||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
add_flags_cxx("-Wno-error=global-constructors")
|
||||
add_flags_cxx("-Wno-error=switch-enum")
|
||||
endif()
|
||||
|
||||
|
||||
if (MSVC)
|
||||
# Add the MSVC-specific LeakFinder sources:
|
||||
list (APPEND SHARED_SRCS ${CMAKE_SOURCE_DIR}/src/LeakFinder.cpp ${CMAKE_SOURCE_DIR}/src/StackWalker.cpp)
|
||||
list (APPEND SHARED_HDRS ${CMAKE_SOURCE_DIR}/src/LeakFinder.h ${CMAKE_SOURCE_DIR}/src/StackWalker.h)
|
||||
endif()
|
||||
|
||||
source_group("Shared" FILES ${SHARED_SRCS} ${SHARED_HDRS})
|
||||
source_group("Sources" FILES ${SRCS})
|
||||
add_executable(PieceRotation ${SRCS} ${SHARED_SRCS} ${SHARED_HDRS})
|
||||
target_link_libraries(PieceRotation tolualib zlib)
|
||||
add_test(NAME PieceRotation-test WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMAND PieceRotation)
|
||||
|
||||
|
||||
|
||||
|
||||
# Put the projects into solution folders (MSVC):
|
||||
set_target_properties(
|
||||
PieceRotation
|
||||
PROPERTIES FOLDER Tests
|
||||
)
|
4
tests/PieceRotation/LuaState_Declaration.inc
Normal file
4
tests/PieceRotation/LuaState_Declaration.inc
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
// LuaState_Declaration.inc
|
||||
|
||||
// Dummy include file needed for LuaState to compile successfully
|
19
tests/PieceRotation/LuaState_Typedefs.inc
Normal file
19
tests/PieceRotation/LuaState_Typedefs.inc
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
// LuaState_Typedefs.inc
|
||||
|
||||
// Dummy include file needed for LuaState to compile successfully
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Forward-declare classes that are used in the API but never called:
|
||||
struct HTTPRequest;
|
||||
struct HTTPTemplateRequest;
|
||||
class cPluginLua;
|
||||
class cBoundingBox;
|
||||
template <typename T> class cItemCallback;
|
||||
class cEntity;
|
||||
|
||||
|
||||
|
170
tests/PieceRotation/PieceRotationTest.cpp
Normal file
170
tests/PieceRotation/PieceRotationTest.cpp
Normal file
@ -0,0 +1,170 @@
|
||||
// PieceRotation.cpp
|
||||
|
||||
// Implements the tests for cPiece::cConnector::eDirection rotations
|
||||
|
||||
#include "Globals.h"
|
||||
#include <exception>
|
||||
#include <map>
|
||||
#include "Generating/PieceGenerator.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static cPiece::cConnector::eDirection g_AllDirections[] =
|
||||
{
|
||||
cPiece::cConnector::dirXM,
|
||||
cPiece::cConnector::dirXP,
|
||||
cPiece::cConnector::dirYM,
|
||||
cPiece::cConnector::dirYP,
|
||||
cPiece::cConnector::dirZM,
|
||||
cPiece::cConnector::dirZP,
|
||||
cPiece::cConnector::dirYM_XM_ZM,
|
||||
cPiece::cConnector::dirYM_XM_ZP,
|
||||
cPiece::cConnector::dirYM_XP_ZM,
|
||||
cPiece::cConnector::dirYM_XP_ZP,
|
||||
cPiece::cConnector::dirYP_XM_ZM,
|
||||
cPiece::cConnector::dirYP_XM_ZP,
|
||||
cPiece::cConnector::dirYP_XP_ZM,
|
||||
cPiece::cConnector::dirYP_XP_ZP,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cTestFailure: public std::exception
|
||||
{
|
||||
public:
|
||||
cTestFailure(const char * a_Expression, const char * a_FileName, const int a_Line):
|
||||
std::exception(),
|
||||
m_Expression(a_Expression),
|
||||
m_FileName(a_FileName),
|
||||
m_Line(a_Line)
|
||||
{
|
||||
}
|
||||
|
||||
const std::string m_Expression;
|
||||
const std::string m_FileName;
|
||||
const int m_Line;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define EXPECT(X) if (!(X)) \
|
||||
{ \
|
||||
ASSERT(X); \
|
||||
throw cTestFailure(#X, __FILE__, __LINE__); \
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Tests that rotating a direction in one way and then the opposite way produces the original direction. */
|
||||
static void testBackAndForth()
|
||||
{
|
||||
for (size_t i = 0; i < ARRAYCOUNT(g_AllDirections); ++i)
|
||||
{
|
||||
auto rotated = cPiece::cConnector::RotateDirectionCW(g_AllDirections[i]);
|
||||
auto back = cPiece::cConnector::RotateDirectionCCW(rotated);
|
||||
EXPECT(back == g_AllDirections[i]);
|
||||
}
|
||||
for (size_t i = 0; i < ARRAYCOUNT(g_AllDirections); ++i)
|
||||
{
|
||||
auto rotated = cPiece::cConnector::RotateDirectionCCW(g_AllDirections[i]);
|
||||
auto back = cPiece::cConnector::RotateDirectionCW(rotated);
|
||||
EXPECT(back == g_AllDirections[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Tests rotating the direction 360 degrees. */
|
||||
static void testFullRotation()
|
||||
{
|
||||
// Rotate 90 degrees CCW four times:
|
||||
for (size_t i = 0; i < ARRAYCOUNT(g_AllDirections); ++i)
|
||||
{
|
||||
auto d = g_AllDirections[i];
|
||||
for (int j = 0; j < 4; ++j)
|
||||
{
|
||||
d = cPiece::cConnector::RotateDirectionCCW(d);
|
||||
}
|
||||
EXPECT(d == g_AllDirections[i]);
|
||||
}
|
||||
|
||||
// Rotate 90 degrees CW four times:
|
||||
for (size_t i = 0; i < ARRAYCOUNT(g_AllDirections); ++i)
|
||||
{
|
||||
auto d = g_AllDirections[i];
|
||||
for (int j = 0; j < 4; ++j)
|
||||
{
|
||||
d = cPiece::cConnector::RotateDirectionCW(d);
|
||||
}
|
||||
EXPECT(d == g_AllDirections[i]);
|
||||
}
|
||||
|
||||
// Rotate 180 degrees twice:
|
||||
for (size_t i = 0; i < ARRAYCOUNT(g_AllDirections); ++i)
|
||||
{
|
||||
auto d = g_AllDirections[i];
|
||||
d = cPiece::cConnector::RotateDirection(d);
|
||||
d = cPiece::cConnector::RotateDirection(d);
|
||||
EXPECT(d == g_AllDirections[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Tests that no two values are rotated onto the same destination value. */
|
||||
template <class Fn>
|
||||
static void testPermutation(Fn & a_Fn)
|
||||
{
|
||||
std::map<cPiece::cConnector::eDirection, int> numDest;
|
||||
for (size_t i = 0; i < ARRAYCOUNT(g_AllDirections); ++i)
|
||||
{
|
||||
auto d = a_Fn(g_AllDirections[i]);
|
||||
EXPECT(numDest[d] == 0);
|
||||
numDest[d] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
LOG("PieceRotation test starting.");
|
||||
try
|
||||
{
|
||||
testBackAndForth();
|
||||
testFullRotation();
|
||||
testPermutation(cPiece::cConnector::RotateDirection);
|
||||
testPermutation(cPiece::cConnector::RotateDirectionCW);
|
||||
testPermutation(cPiece::cConnector::RotateDirectionCCW);
|
||||
}
|
||||
catch (const cTestFailure & f)
|
||||
{
|
||||
LOGERROR("Test failed:\tExpression: %s\n\tFile: %s (%d)", f.m_Expression.c_str(), f.m_FileName.c_str(), f.m_Line);
|
||||
return 1;
|
||||
}
|
||||
catch (const std::exception & exc)
|
||||
{
|
||||
LOGERROR("Exception caught: %s", exc.what());
|
||||
return 2;
|
||||
}
|
||||
LOG("PieceRotation test succeeded.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
290
tests/PieceRotation/Stubs.cpp
Normal file
290
tests/PieceRotation/Stubs.cpp
Normal file
@ -0,0 +1,290 @@
|
||||
|
||||
// Stubs.cpp
|
||||
|
||||
// Implements stubs of various Cuberite methods that are needed for linking but not for runtime
|
||||
// This is required so that we don't bring in the entire Cuberite via dependencies
|
||||
|
||||
#include "Globals.h"
|
||||
#include "BlockInfo.h"
|
||||
#include "Bindings.h"
|
||||
#include "Bindings/DeprecatedBindings.h"
|
||||
#include "Bindings/LuaJson.h"
|
||||
#include "Bindings/ManualBindings.h"
|
||||
#include "BlockEntities/BlockEntity.h"
|
||||
#include "Blocks/BlockHandler.h"
|
||||
#include "Generating/ChunkDesc.h"
|
||||
#include "DeadlockDetect.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// fwd:
|
||||
struct lua_State;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Prototypes, needed by clang:
|
||||
extern "C" int luaopen_lsqlite3(lua_State * a_LuaState);
|
||||
extern "C" int luaopen_lxp(lua_State * a_LuaState);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cManualBindings::Bind(lua_State * a_LuaState)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void DeprecatedBindings::Bind(lua_State * a_LuaState)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cLuaJson::Bind(cLuaState & a_LuaState)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int tolua_AllToLua_open(lua_State * a_LuaState)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
extern "C" int luaopen_lsqlite3(lua_State * a_LuaState)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
extern "C" int luaopen_lxp(lua_State * a_LuaState)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBlockInfo::~cBlockInfo()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBlockInfo::Initialize(cBlockInfo::cBlockInfoArray & a_BlockInfos)
|
||||
{
|
||||
// The piece-loading code uses the handlers for rotations, so we need valid handlers
|
||||
// Insert dummy handlers:
|
||||
for (size_t i = 0; i < ARRAYCOUNT(a_BlockInfos); i++)
|
||||
{
|
||||
a_BlockInfos[i].m_Handler = new cBlockHandler(static_cast<BLOCKTYPE>(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBlockHandler::cBlockHandler(BLOCKTYPE a_BlockType)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cBlockHandler::GetPlacementBlockTypeMeta(
|
||||
cChunkInterface & a_ChunkInterface, cPlayer * a_Player,
|
||||
int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
|
||||
int a_CursorX, int a_CursorY, int a_CursorZ,
|
||||
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
|
||||
)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBlockHandler::OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBlockHandler::OnPlacedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, const sSetBlock & a_BlockChange)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBlockHandler::OnDestroyedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBlockHandler::OnPlaced(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBlockHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBlockHandler::NeighborChanged(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_WhichNeighbor)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBlockHandler::ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBlockHandler::DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_BlockPluginInterface, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, bool a_CanDrop)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cBlockHandler::CanBeAt(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ, const cChunk & a_Chunk)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cBlockHandler::IsUseable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cBlockHandler::IsClickedThrough(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cBlockHandler::DoesIgnoreBuildCollision(void)
|
||||
{
|
||||
return (m_BlockType == E_BLOCK_AIR);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cBlockHandler::DoesDropOnUnsuitable(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBlockHandler::Check(cChunkInterface & a_ChunkInterface, cBlockPluginInterface & a_PluginInterface, int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ColourID cBlockHandler::GetMapBaseColourID(NIBBLETYPE a_Meta)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cBlockHandler::IsInsideBlock(const Vector3d & a_Position, const BLOCKTYPE a_BlockType, const NIBBLETYPE a_BlockMeta)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBlockEntity * cBlockEntity::CreateByBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cDeadlockDetect::TrackCriticalSection(cCriticalSection & a_CS, const AString & a_Name)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cDeadlockDetect::UntrackCriticalSection(cCriticalSection & a_CS)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user