8 #include "../Noise/Noise.h"
37 auto idxPipe = Params.find(
'|');
38 if (idxPipe != AString::npos)
40 AString blocksToReplaceStr = Params.substr(0, idxPipe);
42 for (
size_t i = 0; i < blocksToReplace.size(); i++)
47 CONDWARNING(a_LogWarnings,
"Cannot parse block type from string \"%s\"!", blocksToReplace[i].c_str());
53 Params = Params.substr(idxPipe + 1, Params.length() - 1);
57 CONDWARNING(a_LogWarnings,
"You must specify at least one block to replace%s!",
"");
63 auto idxSqBracketStart = Params.find(
'[');
64 auto idxSqBracketStartLast = Params.find_last_of(
'[');
66 bool isMultiMeta =
false;
67 if ((idxSqBracketStart != idxSqBracketStartLast) && (idxSqBracketStartLast != Params.length() - 1))
74 auto idxSqBracketEnd = Params.find(
']');
75 if ((idxSqBracketEnd == Params.length() - 1) && (idxSqBracketStart != AString::npos))
77 AString metaParamsStr = Params.substr(idxSqBracketStart + 1, Params.length() - idxSqBracketStart - 2);
78 std::array<int, 4> metaParamsInt;
79 if (!
ParseMeta(metaParamsStr, metaParamsInt, a_LogWarnings))
89 Params = Params.substr(0, idxSqBracketStart);
96 for (
size_t i = 0; i < BlocksToRandomize.size(); i++)
98 AString block = BlocksToRandomize[i];
104 auto sqBrStart = block.find(
'[');
105 if (sqBrStart != AString::npos)
107 auto sqBrEnd = block.find(
']');
108 if (sqBrEnd != block.size() - 1)
110 CONDWARNING(a_LogWarnings,
"If present, block meta params must be at the end of block to randomize definition \"%s\"!", block.c_str());
114 AString metaParamsStr = block.substr(sqBrStart + 1, block.size() - sqBrStart - 2);
116 std::array<int, 4> metaParamsInt;
117 if (!
ParseMeta(metaParamsStr, metaParamsInt, a_LogWarnings))
122 Block.m_MinMeta = metaParamsInt[0];
123 Block.m_MaxMeta = metaParamsInt[1];
124 Block.m_MinNoiseMeta = metaParamsInt[2];
125 Block.m_MaxNoiseMeta = metaParamsInt[3];
127 block = block.substr(0, sqBrStart);
134 if (BlockParams.size() < 2)
136 CONDWARNING(a_LogWarnings,
"Block weight is required param \"%s\"!", BlockParams[0].c_str());
146 a_LogWarnings,
"Cannot parse block type from string \"%s\"!",
147 BlockParams[0].c_str());
156 "Cannot parse block weight from string \"%s\"!",
157 BlockParams[1].c_str());
163 Block.m_Weight = BlockWeight;
170 CONDWARNING(a_LogWarnings,
"You must specify at least one block to randomize%s!",
"");
181 bool ParseMeta(
const AString & a_Meta, std::array<int, 4> & a_ParsedMeta,
bool a_LogWarnings)
185 for (
size_t i = 0; i < MetaParams.size(); i++)
191 CONDWARNING(a_LogWarnings,
"Cannot parse meta param from string \"%s\", meta: %s!", MetaParams[i].c_str(), a_Meta.c_str());
197 CONDWARNING(a_LogWarnings,
"Unsupported meta param \"%d\"!", Value);
201 a_ParsedMeta[i] = Value;
204 if (MetaParams.size() == 1)
207 a_ParsedMeta[1] = a_ParsedMeta[0];
209 else if (MetaParams.size() == 2)
212 a_ParsedMeta[2] = a_ParsedMeta[0];
213 a_ParsedMeta[3] = a_ParsedMeta[1];
215 else if (MetaParams.size() == 3)
217 a_ParsedMeta[3] = a_ParsedMeta[1];
236 for (
size_t i = 0; i < NumBlocks; i++)
245 weightDelta += blockToRnd.m_Weight;
246 if (BlockRnd <= weightDelta)
248 BlockTypes[i] = blockToRnd.m_Type;
251 if (blockToRnd.m_MinMeta < blockToRnd.m_MaxMeta)
253 int BlockMetaRnd = std::clamp(
static_cast<int>(PieceNoise.
IntNoise2DInRange(a_PieceRot*2,
static_cast<int>(i),
static_cast<float>(blockToRnd.m_MinNoiseMeta),
static_cast<float>(blockToRnd.m_MaxNoiseMeta))), blockToRnd.m_MinMeta, blockToRnd.m_MaxMeta);
254 BlockMetas[i] =
static_cast<NIBBLETYPE>(BlockMetaRnd);
256 else if ((blockToRnd.m_MaxMeta > -1) && (blockToRnd.m_MaxMeta == blockToRnd.m_MinMeta))
259 BlockMetas[i] =
static_cast<NIBBLETYPE>(blockToRnd.m_MaxMeta);
269 BlockMetas[i] =
static_cast<NIBBLETYPE>(BlockMetaRnd);
318 auto idxCurlyStart = a_Definition.find(
'{');
319 auto idxCurlyFirstEnd = a_Definition.find(
'}');
320 if ((idxCurlyStart == AString::npos) && (idxCurlyFirstEnd == AString::npos))
322 CONDWARNING(a_LogWarnings,
"Piece metadata \"Modifiers\" needs at least one valid modifier definition \"%s\"!", a_Definition.c_str());
328 for (
size_t i = 0; i < modifiersStr.size(); i++)
332 if (modifierStr.size() == 0)
336 auto idxCurlyEnd = modifierStr.find(
'}');
337 if (idxCurlyEnd == AString::npos)
339 CONDWARNING(a_LogWarnings,
"Modifier definition must end with curly bracket \"%s\"!!", modifierStr.c_str());
343 modifierStr = modifierStr.substr(0, idxCurlyEnd);
346 auto idxPipe = modifierStr.find(
'|');
347 if (idxPipe == AString::npos)
349 idxPipe = modifierStr.length();
351 AString ModifierClass = modifierStr.substr(0, idxPipe);
357 Modifier = std::make_shared<cPieceModifierRandomizeBlocks>();
360 if (Modifier ==
nullptr)
362 CONDWARNING(a_LogWarnings,
"Unknown modifier class \"%s\" %s!", ModifierClass.c_str(), modifierStr.c_str());
368 if (idxPipe < modifierStr.length())
370 Params = modifierStr.substr(idxPipe + 1);
373 if (!Modifier->InitializeFromString(Params, a_LogWarnings))
375 CONDWARNING(a_LogWarnings,
"InitializeFromString error \"%s\" -- %!", Params.c_str(), modifierStr.c_str());
379 a_Modifiers->push_back(Modifier);
int BlockStringToType(const AString &a_BlockTypeString)
Translates a blocktype string into blocktype.
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
unsigned char BLOCKTYPE
The datatype used by blockdata.
bool CreatePieceModifierFromString(const AString &a_Definition, std::shared_ptr< cPiece::cPieceModifiers > &a_Modifiers, bool a_LogWarnings)
static const int SEED_OFFSET
std::vector< cRandomizedBlock > cRandomizedBlocks
#define CONDWARNING(ShouldLog,...)
AStringVector StringSplitAndTrim(const AString &str, const AString &delim)
Split the string at any of the listed delimiters and trim each value.
AString TrimString(const AString &str)
Trims whitespace at both ends of the string.
int NoCaseCompare(const AString &s1, const AString &s2)
Case-insensitive string comparison.
bool StringToInteger(const AString &a_str, T &a_Num)
Parses any integer type.
NIBBLETYPE * GetBlockMetas(void) const
size_t GetBlockCount(void) const
BLOCKTYPE * GetBlockTypes(void) const
Returns the internal pointer to the block types.
A modifier which is pseudo-randomly replacing blocks to other types and metas.
int m_MaxMeta
Maximum meta to randomize.
int m_MinMeta
Minimum meta to randomize.
int m_MaxNoiseMeta
Maximum meta in noise range.
cPieceModifierRandomizeBlocks(void)
virtual bool InitializeFromString(const AString &a_Params, bool a_LogWarnings) override
Initializes the modifier's parameters from the string representation.
bool ParseMeta(const AString &a_Meta, std::array< int, 4 > &a_ParsedMeta, bool a_LogWarnings)
int m_MinNoiseMeta
Minimum meta in noise range.
virtual void AssignSeed(int a_Seed) override
Called when the piece pool is assigned to a generator, so that the modifiers can access world seed.
std::map< BLOCKTYPE, int > m_BlocksToReplace
Block types of a blocks which are being replaced by this strategy.
virtual void Modify(cBlockArea &a_Image, const Vector3i a_PiecePos, const int a_PieceRot) override
Called prior to writing piece to a chunk, so that modifiers can modify blocks in the blockarea.
cRandomizedBlocks m_BlocksToRandomize
Randomized blocks with their weights and meta params.
Used to store block type, meta, weight and some more params.
std::shared_ptr< cPieceModifier > cPieceModifierPtr
Base class (interface) for piece modifiers.
int IntNoise3DInt(int a_X, int a_Y, int a_Z) const
NOISE_DATATYPE IntNoise2DInRange(int a_X, int a_Y, float a_Min, float a_Max) const