diff options
Diffstat (limited to 'src/Generating/PieceGenerator.h')
-rw-r--r-- | src/Generating/PieceGenerator.h | 138 |
1 files changed, 120 insertions, 18 deletions
diff --git a/src/Generating/PieceGenerator.h b/src/Generating/PieceGenerator.h index 43ffed7a2..13ef05e42 100644 --- a/src/Generating/PieceGenerator.h +++ b/src/Generating/PieceGenerator.h @@ -18,6 +18,7 @@ Each uses a slightly different approach to generating: #pragma once +#include "ComposableGenerator.h" #include "../Defines.h" #include "../Cuboid.h" #include "../Noise/Noise.h" @@ -49,9 +50,70 @@ public: 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); }; - + typedef std::vector<cConnector> cConnectors; - + + + /** Base class (interface) for strategies for placing the starting pieces vertically. + Descendants can override the GetVerticalPlacement() method to provide custom placement decisions. */ + class cVerticalStrategy + { + public: + // Force a virtual destructor in descendants + virtual ~cVerticalStrategy() {} + + /** Returns the Y coord of the piece */ + virtual int GetVerticalPlacement(int a_BlockX, int a_BlockZ) = 0; + + /** Initializes the strategy's parameters from the string representation. + a_Params is the string containing only the parameters (substring after the first pipe character in the strategy description string). + If a_LogWarnings is true, logs any problems to the console. + Returns true if successful, false if the string parsing failed. + Used when loading the strategy from a file. */ + virtual bool InitializeFromString(const AString & a_Params, bool a_LogWarnings) = 0; + + /** Called when the piece pool is assigned to a generator, + so that the strategies may bind to the underlying subgenerators. */ + virtual void AssignGens(int a_Seed, cBiomeGenPtr & a_BiomeGen, cTerrainHeightGenPtr & a_TerrainHeightGen, int a_SeaLevel) {} + }; + + typedef SharedPtr<cVerticalStrategy> cVerticalStrategyPtr; + + + /** Base class (interface) for the vertical limit of piece placement. + Each placed piece can have a limit, represented by this class, that gets queried for validity of the placement. */ + class cVerticalLimit + { + public: + virtual ~cVerticalLimit() {} + + /** Called to inquire whether the specified piece can be placed at the specified height. + a_BlockX, a_BlockZ is the column of the connector that is being queried. + a_Height is the requested height of the piece's lowest block. */ + virtual bool CanBeAtHeight(int a_BlockX, int a_BlockZ, int a_Height) = 0; + + /** Initializes the limit's parameters from the string representation. + a_Params is the string containing only the parameters (substring after the first pipe character in the limit description string). + Returns true if successful, false if the string parsing failed. + If a_LogWarnings is true, any error while parsing the string is output to the server console. + Used when loading the limit from a file. */ + virtual bool InitializeFromString(const AString & a_Params, bool a_LogWarnings) = 0; + + /** Called when the piece pool is assigned to a generator, + so that the limits may bind to the underlying subgenerators. */ + virtual void AssignGens(int a_Seed, cBiomeGenPtr & a_BiomeGen, cTerrainHeightGenPtr & a_TerrainHeightGen, int a_SeaLevel) {} + }; + + typedef SharedPtr<cVerticalLimit> cVerticalLimitPtr; + + + /** The strategy used for vertical placement of this piece when it is used as a starting piece. */ + cVerticalStrategyPtr m_VerticalStrategy; + + /** The checker that verifies each placement's vertical position. */ + cVerticalLimitPtr m_VerticalLimit; + + /** Returns all of the available connectors that the piece has. Each connector has a (relative) position in the piece, and a type associated with it. */ virtual cConnectors GetConnectors(void) const = 0; @@ -66,7 +128,43 @@ public: /** Returns true if the piece can be rotated CCW the specific number of 90-degree turns. */ virtual bool CanRotateCCW(int a_NumRotations) const = 0; + + /** Returns the height, based on m_VerticalStrategy, for this piece when used as the starting piece. + If there's no strategy assigned to this piece, returns -1. */ + int GetStartingPieceHeight(int a_BlockX, int a_BlockZ) + { + if (m_VerticalStrategy != nullptr) + { + return m_VerticalStrategy->GetVerticalPlacement(a_BlockX, a_BlockZ); + } + return -1; + } + void SetVerticalStrategy(cVerticalStrategyPtr a_VerticalStrategy) + { + m_VerticalStrategy = a_VerticalStrategy; + } + + cVerticalStrategyPtr GetVerticalStrategy(void) const + { + return m_VerticalStrategy; + } + + cVerticalLimitPtr GetVerticalLimit(void) const + { + return m_VerticalLimit; + } + + /** Sets the vertical strategy based on the description in the string. + If a_LogWarnings is true, logs the parsing problems into the server console. + Returns true if successful, false if strategy parsing failed (no strategy assigned). */ + bool SetVerticalStrategyFromString(const AString & a_StrategyDesc, bool a_LogWarnings); + + /** Sets the vertical limit based on the description string. + Returns true if successful, false if limit parsing failed (no limit assigned). + If a_LogWarnings is true, any problem is reported into the server console. */ + bool SetVerticalLimitFromString(const AString & a_LimitDesc, bool a_LogWarnings); + /** Returns a copy of the a_Pos after rotating the piece the specified number of CCW rotations. */ Vector3i RotatePos(const Vector3i & a_Pos, int a_NumCCWRotations) const; @@ -112,22 +210,24 @@ public: /** Returns the relative weight with which the a_NewPiece is to be selected for placing under a_PlacedPiece through a_ExistingConnector. a_ExistingConnector is the original connector, before any movement or rotation is applied to it. This allows the pool to tweak the piece's chances, based on the previous pieces in the tree and the connector used. - The higher the number returned, the higher the chance the piece will be chosen. 0 means the piece will never be chosen. - */ + The higher the number returned, the higher the chance the piece will be chosen. 0 means the piece will never be chosen. */ virtual int GetPieceWeight( const cPlacedPiece & a_PlacedPiece, const cPiece::cConnector & a_ExistingConnector, const cPiece & a_NewPiece - ) { return 1; } + ) + { + return 1; + } /** Returns the relative weight with which the a_NewPiece is to be selected for placing as the first piece. This allows the pool to tweak the piece's chances. The higher the number returned, the higher the chance the piece will be chosen. 0 means the piece will not be chosen. - If all pieces return 0, a random piece is chosen, with all equal chances. - */ - virtual int GetStartingPieceWeight( - const cPiece & a_NewPiece - ) { return 1; } + If all pieces return 0, a random piece is chosen, with all equal chances. */ + virtual int GetStartingPieceWeight(const cPiece & a_NewPiece) + { + return 1; + } /** Called after a piece is placed, to notify the pool that it has been used. The pool may adjust the pieces it will return the next time. */ @@ -229,9 +329,9 @@ protected: int m_Seed; - /** Selects a starting piece and places it, including the rotations. + /** Selects a starting piece and places it, including its height and rotation. Also puts the piece's connectors in a_OutConnectors. */ - cPlacedPiece * PlaceStartingPiece(int a_BlockX, int a_BlockY, int a_BlockZ, cFreeConnectors & a_OutConnectors); + cPlacedPiece * PlaceStartingPiece(int a_BlockX, int a_BlockZ, cFreeConnectors & a_OutConnectors); /** Tries to place a new piece at the specified (placed) connector. Returns true if successful. */ bool TryPlacePieceAtConnector( @@ -269,13 +369,14 @@ class cBFSPieceGenerator : public cPieceGenerator { typedef cPieceGenerator super; - + public: cBFSPieceGenerator(cPiecePool & a_PiecePool, int a_Seed); - + /** Generates a placement for pieces at the specified coords. - Caller must free each individual cPlacedPiece in a_OutPieces. */ - void PlacePieces(int a_BlockX, int a_BlockY, int a_BlockZ, int a_MaxDepth, cPlacedPieces & a_OutPieces); + The Y coord is generated automatically based on the starting piece that is chosen. + Caller must free each individual cPlacedPiece in a_OutPieces using cPieceGenerator::FreePieces(). */ + void PlacePieces(int a_BlockX, int a_BlockZ, int a_MaxDepth, cPlacedPieces & a_OutPieces); }; @@ -289,8 +390,9 @@ public: cDFSPieceGenerator(cPiecePool & a_PiecePool, int a_Seed); /** Generates a placement for pieces at the specified coords. - Caller must free each individual cPlacedPiece in a_OutPieces. */ - void PlacePieces(int a_BlockX, int a_BlockY, int a_BlockZ, cPlacedPieces & a_OutPieces); + The Y coord is generated automatically based on the starting piece that is chosen. + Caller must free each individual cPlacedPiece in a_OutPieces using cPieceGenerator::FreePieces(). */ + void PlacePieces(int a_BlockX, int a_BlockZ, cPlacedPieces & a_OutPieces); }; |