summaryrefslogtreecommitdiffstats
path: root/src/Generating/PieceGenerator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Generating/PieceGenerator.cpp')
-rw-r--r--src/Generating/PieceGenerator.cpp124
1 files changed, 91 insertions, 33 deletions
diff --git a/src/Generating/PieceGenerator.cpp b/src/Generating/PieceGenerator.cpp
index 8999a5ff7..5de231f75 100644
--- a/src/Generating/PieceGenerator.cpp
+++ b/src/Generating/PieceGenerator.cpp
@@ -286,7 +286,8 @@ cPlacedPiece::cPlacedPiece(const cPlacedPiece * a_Parent, const cPiece & a_Piece
m_Parent(a_Parent),
m_Piece(&a_Piece),
m_Coords(a_Coords),
- m_NumCCWRotations(a_NumCCWRotations)
+ m_NumCCWRotations(a_NumCCWRotations),
+ m_HasBeenMovedToGround(false)
{
m_Depth = (m_Parent == NULL) ? 0 : (m_Parent->GetDepth() + 1);
m_HitBox = a_Piece.RotateMoveHitBox(a_NumCCWRotations, a_Coords.x, a_Coords.y, a_Coords.z);
@@ -297,6 +298,36 @@ cPlacedPiece::cPlacedPiece(const cPlacedPiece * a_Parent, const cPiece & a_Piece
+cPiece::cConnector cPlacedPiece::GetRotatedConnector(size_t a_Index) const
+{
+ cPiece::cConnectors Connectors = m_Piece->GetConnectors();
+ ASSERT(Connectors.size() >= a_Index);
+ return m_Piece->RotateMoveConnector(Connectors[a_Index], m_NumCCWRotations, m_Coords.x, m_Coords.y, m_Coords.z);
+}
+
+
+
+
+
+cPiece::cConnector cPlacedPiece::GetRotatedConnector(const cPiece::cConnector & a_Connector) const
+{
+ return m_Piece->RotateMoveConnector(a_Connector, m_NumCCWRotations, m_Coords.x, m_Coords.y, m_Coords.z);
+}
+
+
+
+
+
+void cPlacedPiece::MoveToGroundBy(int a_OffsetY)
+{
+ m_Coords.y += a_OffsetY;
+ m_HasBeenMovedToGround = true;
+}
+
+
+
+
+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cPieceGenerator:
@@ -331,7 +362,31 @@ cPlacedPiece * cPieceGenerator::PlaceStartingPiece(int a_BlockX, int a_BlockY, i
// Choose a random one of the starting pieces:
cPieces StartingPieces = m_PiecePool.GetStartingPieces();
- cPiece * StartingPiece = StartingPieces[rnd % StartingPieces.size()];
+ int Total = 0;
+ for (cPieces::const_iterator itr = StartingPieces.begin(), end = StartingPieces.end(); itr != end; ++itr)
+ {
+ Total += m_PiecePool.GetStartingPieceWeight(**itr);
+ }
+ cPiece * StartingPiece;
+ if (Total > 0)
+ {
+ int Chosen = rnd % Total;
+ StartingPiece = StartingPieces.front();
+ for (cPieces::const_iterator itr = StartingPieces.begin(), end = StartingPieces.end(); itr != end; ++itr)
+ {
+ Chosen -= m_PiecePool.GetStartingPieceWeight(**itr);
+ if (Chosen <= 0)
+ {
+ StartingPiece = *itr;
+ break;
+ }
+ }
+ }
+ else
+ {
+ // All pieces returned zero weight, but we need one to start. Choose with equal chance:
+ StartingPiece = StartingPieces[rnd % StartingPieces.size()];
+ }
rnd = rnd >> 16;
// Choose a random supported rotation:
@@ -339,9 +394,9 @@ cPlacedPiece * cPieceGenerator::PlaceStartingPiece(int a_BlockX, int a_BlockY, i
int NumRotations = 1;
for (size_t i = 1; i < ARRAYCOUNT(Rotations); i++)
{
- if (StartingPiece->CanRotateCCW(i))
+ if (StartingPiece->CanRotateCCW((int)i))
{
- Rotations[NumRotations] = i;
+ Rotations[NumRotations] = (int)i;
NumRotations += 1;
}
}
@@ -388,22 +443,26 @@ bool cPieceGenerator::TryPlacePieceAtConnector(
// Get a list of available connections:
const int * RotTable = DirectionRotationTable[a_Connector.m_Direction];
cConnections Connections;
- cPieces AvailablePieces = m_PiecePool.GetPiecesWithConnector(a_Connector.m_Type);
+ 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);
-
- /*
- // DEBUG:
- printf("Placing piece at connector pos {%d, %d, %d}, direction %s\n", ConnPos.x, ConnPos.y, ConnPos.z, BlockFaceToString(a_Connector.m_Direction).c_str());
- //*/
-
+ int WeightTotal = 0;
for (cPieces::iterator itrP = AvailablePieces.begin(), endP = AvailablePieces.end(); itrP != endP; ++itrP)
{
+ // Get the relative chance of this piece being generated in this path:
+ int Weight = m_PiecePool.GetPieceWeight(a_ParentPiece, a_Connector, **itrP);
+ if (Weight <= 0)
+ {
+ continue;
+ }
+
+ // Try fitting each of the piece's connector:
cPiece::cConnectors Connectors = (*itrP)->GetConnectors();
for (cPiece::cConnectors::iterator itrC = Connectors.begin(), endC = Connectors.end(); itrC != endC; ++itrC)
{
- if (itrC->m_Type != a_Connector.m_Type)
+ if (itrC->m_Type != WantedConnectorType)
{
continue;
}
@@ -419,7 +478,9 @@ bool cPieceGenerator::TryPlacePieceAtConnector(
// Doesn't fit in this rotation
continue;
}
- Connections.push_back(cConnection(**itrP, *itrC, NumCCWRotations));
+ // Fits, add it to list of possibile connections:
+ Connections.push_back(cConnection(**itrP, *itrC, NumCCWRotations, Weight));
+ WeightTotal += Weight;
} // for itrC - Connectors[]
} // for itrP - AvailablePieces[]
if (Connections.empty())
@@ -427,21 +488,23 @@ bool cPieceGenerator::TryPlacePieceAtConnector(
// No available connections, bail out
return false;
}
+ ASSERT(WeightTotal > 0);
- // Choose a random connection from the list:
- int rnd = m_Noise.IntNoise3DInt(a_Connector.m_Pos.x, a_Connector.m_Pos.y, a_Connector.m_Pos.z) / 7;
- cConnection & Conn = Connections[rnd % Connections.size()];
+ // Choose a random connection from the list, based on the weights:
+ int rnd = (m_Noise.IntNoise3DInt(a_Connector.m_Pos.x, a_Connector.m_Pos.y, a_Connector.m_Pos.z) / 7) % WeightTotal;
+ size_t ChosenIndex = 0;
+ for (cConnections::const_iterator itr = Connections.begin(), end = Connections.end(); itr != end; ++itr, ++ChosenIndex)
+ {
+ rnd -= itr->m_Weight;
+ if (rnd <= 0)
+ {
+ // This is the piece to choose
+ break;
+ }
+ }
+ cConnection & Conn = Connections[ChosenIndex];
// Place the piece:
- /*
- // DEBUG
- printf("Chosen connector at {%d, %d, %d}, direction %s, needs %d rotations\n",
- Conn.m_Connector.m_Pos.x, Conn.m_Connector.m_Pos.y, Conn.m_Connector.m_Pos.z,
- BlockFaceToString(Conn.m_Connector.m_Direction).c_str(),
- Conn.m_NumCCWRotations
- );
- //*/
-
Vector3i NewPos = Conn.m_Piece->RotatePos(Conn.m_Connector.m_Pos, Conn.m_NumCCWRotations);
ConnPos -= NewPos;
cPlacedPiece * PlacedPiece = new cPlacedPiece(&a_ParentPiece, *(Conn.m_Piece), ConnPos, Conn.m_NumCCWRotations);
@@ -449,12 +512,6 @@ bool cPieceGenerator::TryPlacePieceAtConnector(
// Add the new piece's connectors to the list of free connectors:
cPiece::cConnectors Connectors = Conn.m_Piece->GetConnectors();
-
- /*
- // DEBUG:
- printf("Adding %u connectors to the pool\n", Connectors.size() - 1);
- //*/
-
for (cPiece::cConnectors::const_iterator itr = Connectors.begin(), end = Connectors.end(); itr != end; ++itr)
{
if (itr->m_Pos.Equals(Conn.m_Connector.m_Pos))
@@ -524,10 +581,11 @@ void cPieceGenerator::DebugConnectorPool(const cPieceGenerator::cFreeConnectors
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cPieceGenerator::cConnection:
-cPieceGenerator::cConnection::cConnection(cPiece & a_Piece, cPiece::cConnector & a_Connector, int a_NumCCWRotations) :
+cPieceGenerator::cConnection::cConnection(cPiece & a_Piece, cPiece::cConnector & a_Connector, int a_NumCCWRotations, int a_Weight) :
m_Piece(&a_Piece),
m_Connector(a_Connector),
- m_NumCCWRotations(a_NumCCWRotations)
+ m_NumCCWRotations(a_NumCCWRotations),
+ m_Weight(a_Weight)
{
}