23 m_PiecePool(a_PiecePool),
41 for (cPieces::const_iterator itr = StartingPieces.begin(), end = StartingPieces.end(); itr != end; ++itr)
48 int Chosen = rnd % Total;
49 StartingPiece = StartingPieces.front();
50 for (cPieces::const_iterator itr = StartingPieces.begin(), end = StartingPieces.end(); itr != end; ++itr)
63 StartingPiece = StartingPieces[
static_cast<size_t>(rnd) % StartingPieces.size()];
68 int Rotations[4] = {0};
70 for (
size_t i = 1; i <
ARRAYCOUNT(Rotations); i++)
74 Rotations[NumRotations] =
static_cast<int>(i);
78 int Rotation = Rotations[rnd % NumRotations];
86 for (cPiece::cConnectors::const_iterator itr = Conn.begin(), end = Conn.end(); itr != end; ++itr)
88 a_OutConnectors.push_back(
109 int WantedConnectorType = -a_Connector.
m_Type;
111 Connections.reserve(AvailablePieces.size());
114 for (cPieces::iterator itrP = AvailablePieces.begin(), endP = AvailablePieces.end(); itrP != endP; ++itrP)
125 auto verticalLimit = (*itrP)->GetVerticalLimit();
126 for (cPiece::cConnectors::iterator itrC = Connectors.begin(), endC = Connectors.end(); itrC != endC; ++itrC)
128 if (itrC->m_Type != WantedConnectorType)
134 if ((NumCCWRotations < 0) || !(*itrP)->CanRotateCCW(NumCCWRotations))
141 if ((verticalLimit !=
nullptr) && (!verticalLimit->CanBeAtHeight(ConnPos.
x, ConnPos.
z, ConnPos.
y - itrC->m_Pos.y)))
146 if (!
CheckConnection(a_Connector, ConnPos, **itrP, *itrC, NumCCWRotations, a_OutPieces))
152 Connections.emplace_back(**itrP, *itrC, NumCCWRotations, Weight);
153 WeightTotal += Weight;
156 if (Connections.empty())
165 size_t ChosenIndex = 0;
166 for (cConnections::const_iterator itr = Connections.begin(), end = Connections.end(); itr != end; ++itr, ++ChosenIndex)
168 rnd -= itr->m_Weight;
180 auto PlacedPiece = std::make_unique<cPlacedPiece>(&a_ParentPiece, *(Conn.
m_Piece), ConnPos, Conn.
m_NumCCWRotations);
184 for (cPiece::cConnectors::const_iterator itr = Connectors.begin(), end = Connectors.end(); itr != end; ++itr)
193 a_OutPieces.push_back(std::move(PlacedPiece));
207 int a_NumCCWRotations,
213 RotatedHitBox.
Sort();
214 for (cPlacedPieces::const_iterator itr = a_OutPieces.begin(), end = a_OutPieces.end(); itr != end; ++itr)
216 if ((*itr)->GetHitBox().DoesIntersect(RotatedHitBox))
254 size_t NumProcessed = 0;
255 while (ConnectorPool.size() > NumProcessed)
278 if (NumProcessed > 1000)
280 typedef cPieceGeneratorBFSTree::cFreeConnectors::difference_type difType;
281 ConnectorPool.erase(ConnectorPool.begin(), ConnectorPool.begin() +
static_cast<difType
>(NumProcessed));
295 fmt::print(
" Connector pool: {0} items\n", a_ConnectorPool.size() - a_NumProcessed);
298 typedef cPieceGeneratorBFSTree::cFreeConnectors::difference_type difType;
300 for (
auto itr = a_ConnectorPool.cbegin() +
static_cast<difType
>(a_NumProcessed), end = a_ConnectorPool.cend(); itr != end; ++itr, ++idx)
302 fmt::print(
" {0}: {{{1}, {2}, {3}}}, type {4}, direction {5}, depth {6}\n",
304 itr->m_Connector.m_Pos.x, itr->m_Connector.m_Pos.y, itr->m_Connector.m_Pos.z,
305 itr->m_Connector.m_Type,
307 itr->m_Piece->GetDepth()
322 m_Connector(a_Connector),
323 m_NumCCWRotations(a_NumCCWRotations),
337 m_Connector(a_Connector)
std::vector< cPiece * > cPieces
std::unique_ptr< cPlacedPiece > cPlacedPiecePtr
std::vector< cPlacedPiecePtr > cPlacedPieces
#define ARRAYCOUNT(X)
Evaluates to the number of elements in an array (compile-time!)
unsigned char Rotation(const BlockState Block)
bool CheckConnection(const cPiece::cConnector &a_ExistingConnector, const Vector3i &a_ToPos, const cPiece &a_Piece, const cPiece::cConnector &a_NewConnector, int a_NumCCWRotations, const cPlacedPieces &a_OutPieces)
Checks if the specified piece would fit with the already-placed pieces, using the specified connector...
bool TryPlacePieceAtConnector(const cPlacedPiece &a_ParentPiece, const cPiece::cConnector &a_Connector, cPlacedPieces &a_OutPieces, cFreeConnectors &a_OutConnectors)
Tries to place a new piece at the specified (placed) connector.
cPlacedPiecePtr PlaceStartingPiece(int a_BlockX, int a_BlockZ, cFreeConnectors &a_OutConnectors)
Selects a starting piece and places it, including its height and rotation.
void DebugConnectorPool(const cFreeConnectors &a_ConnectorPool, size_t a_NumProcessed)
DEBUG: Outputs all the connectors in the pool into stdout.
std::vector< cConnection > cConnections
cPieceGeneratorBFSTree(cPiecePool &a_PiecePool, int a_Seed)
Creates a new object tied to the specified PiecePool, using the specified seed.
cPiecePool & m_PiecePool
The pool from which pieces are taken.
void PlacePieces(int a_BlockX, int a_BlockZ, int a_MaxDepth, cPlacedPieces &a_OutPieces)
Generates a placement for pieces at the specified coords.
std::vector< cFreeConnector > cFreeConnectors
cNoise m_Noise
The noise used for random number generation.
The type used for storing a connection from one piece to another, while building the piece tree.
cPiece::cConnector m_Connector
cConnection(cPiece &a_Piece, cPiece::cConnector &a_Connector, int a_NumCCWRotations, int a_Weight)
The type used for storing a pool of connectors that will be attempted to expand by another piece.
cPiece::cConnector m_Connector
cFreeConnector(cPlacedPiece *a_Piece, const cPiece::cConnector &a_Connector)
Represents a single piece.
virtual cConnectors GetConnectors(void) const =0
Returns all of the available connectors that the piece has.
cCuboid RotateHitBoxToConnector(const cConnector &a_MyConnector, const Vector3i &a_ToConnectorPos, int a_NumCCWRotations) const
Returns the hitbox after the specified number of rotations and moved so that a_MyConnector is placed ...
virtual bool CanRotateCCW(int a_NumRotations) const =0
Returns true if the piece can be rotated CCW the specific number of 90-degree turns.
int GetStartingPieceHeight(int a_BlockX, int a_BlockZ)
Returns the height, based on m_VerticalStrategy, for this piece when used as the starting piece.
Vector3i RotatePos(const Vector3i &a_Pos, int a_NumCCWRotations) const
Returns a copy of the a_Pos after rotating the piece the specified number of CCW rotations.
cConnector RotateMoveConnector(const cConnector &a_Connector, int a_NumCCWRotations, int a_MoveX, int a_MoveY, int a_MoveZ) const
Returns a copy of the connector that is rotated and then moved by the specified amounts.
std::vector< cConnector > cConnectors
static int GetNumCCWRotationsToFit(eDirection a_FixedDir, eDirection a_RotatingDir)
Returns the number of CCW rotations that a_RotatingDir requires in order to be the counter-direction ...
int m_Type
Type of the connector.
Vector3i m_Pos
Position relative to the piece.
eDirection m_Direction
Direction in which the connector is facing.
static const char * DirectionToString(eDirection a_Direction)
Returns the string representation of the direction.
static Vector3i AddDirection(const Vector3i &a_Pos, eDirection a_Direction)
Returns the position of the block that has the specified direction from the specified position.
This class is an interface that stores pieces for a generator.
virtual int GetStartingPieceWeight(const cPiece &a_NewPiece)
Returns the relative weight with which the a_NewPiece is to be selected for placing as the first piec...
virtual int GetPieceWeight(const cPlacedPiece &a_PlacedPiece, const cPiece::cConnector &a_ExistingConnector, const cPiece &a_NewPiece)
Returns the relative weight with which the a_NewPiece is to be selected for placing under a_PlacedPie...
virtual cPieces GetStartingPieces(void)=0
Returns the pieces that should be used as the starting point.
virtual cPieces GetPiecesWithConnector(int a_ConnectorType)=0
Returns a list of pieces that contain the specified connector type.
virtual void Reset(void)=0
Called when the pool has finished the current structure and should reset any piece-counters it has fo...
Represents a single piece that has been placed to specific coords in the world.
int IntNoise3DInt(int a_X, int a_Y, int a_Z) const
int IntNoise2DInt(int a_X, int a_Y) const