9 #include "../IniFile.h"
49 AString CompoGenName = a_IniFile.
GetValue(
"Generator",
"CompositionGen");
50 if (CompoGenName.empty())
52 LOGWARN(
"[Generator] CompositionGen value not set in world.ini, using \"Biomal\".");
53 CompoGenName =
"Biomal";
57 std::unique_ptr<cTerrainCompositionGen> res;
69 res = std::make_unique<cCompoGenClassic>();
73 res = std::make_unique<cCompoGenDebugBiomes>();
75 else if (
NoCaseCompare(CompoGenName,
"DistortedHeightmap") == 0)
82 res = std::make_unique<cEndGen>(a_Seed);
86 res = std::make_unique<cCompoGenNether>(a_Seed);
95 res = std::make_unique<cCompoGenSameBlock>();
99 LOGWARN(
"Unknown CompositionGen \"%s\", using \"Biomal\" instead.", CompoGenName.c_str());
100 a_IniFile.
SetValue(
"Generator",
"CompositionGen",
"Biomal");
106 res->InitializeCompoGen(a_IniFile);
150 m_BiomeGen->GenBiomes(a_ChunkCoords, a_BiomeMap);
177 bool ShouldUpdateHeightmap =
false;
187 Finisher->GenFinish(a_ChunkDesc);
189 ShouldUpdateHeightmap =
true;
192 if (ShouldUpdateHeightmap)
208 a_IniFile.
GetValueSet(
"Generator",
"BiomeGen",
"Grown");
209 a_IniFile.
GetValueSet(
"Generator",
"ShapeGen",
"BiomalNoise3D");
210 a_IniFile.
GetValueSet(
"Generator",
"CompositionGen",
"Biomal");
222 "SinglePieceStructures: JungleTemple|WitchHut|DesertPyramid|DesertWell, "
233 "OverworldClumpFlowers, "
241 a_IniFile.
GetValueSet(
"Generator",
"Generator",
"Composable");
242 a_IniFile.
GetValueSet(
"Generator",
"BiomeGen",
"Constant");
243 a_IniFile.
GetValueSet(
"Generator",
"ConstantBiome",
"Nether");
244 a_IniFile.
GetValueSet(
"Generator",
"ShapeGen",
"HeightMap");
245 a_IniFile.
GetValueSet(
"Generator",
"HeightGen",
"Flat");
246 a_IniFile.
GetValueSet(
"Generator",
"FlatHeight",
"128");
247 a_IniFile.
GetValueSet(
"Generator",
"CompositionGen",
"Nether");
253 "NetherClumpFoliage, "
255 "PieceStructures: NetherFort, "
263 a_IniFile.
GetValueSet(
"Generator",
"BiomeGen",
"Constant");
264 a_IniFile.
GetValueSet(
"Generator",
"ConstantBiome",
"End");
265 a_IniFile.
GetValueSet(
"Generator",
"ShapeGen",
"End");
266 a_IniFile.
GetValueSet(
"Generator",
"CompositionGen",
"End");
267 a_IniFile.
GetValueSet(
"Generator",
"Finishers",
"EnderDragonFightStructures");
273 ASSERT(!
"Unhandled dimension");
285 bool CacheOffByDefault =
false;
290 int CacheSize = a_IniFile.
GetValueSetI(
"Generator",
"BiomeGenCacheSize", CacheOffByDefault ? 0 : 16);
295 int MultiCacheLength = a_IniFile.
GetValueSetI(
"Generator",
"BiomeGenMultiCacheLength", 128);
298 LOGWARNING(
"Biomegen cache size set too low, would hurt performance instead of helping. Increasing from %d to %d",
303 LOGD(
"Using a cache for biomegen of size %d.", CacheSize);
304 if (MultiCacheLength > 0)
306 LOGD(
"Enabling multicache for biomegen of length %d.", MultiCacheLength);
307 m_BiomeGen = std::make_unique<cBioGenMulticache>(std::move(
m_BiomeGen),
static_cast<size_t>(CacheSize),
static_cast<size_t>(MultiCacheLength));
311 m_BiomeGen = std::make_unique<cBioGenMulticache>(std::move(
m_BiomeGen),
static_cast<size_t>(CacheSize), 1);
321 bool CacheOffByDefault =
false;
363 int CompoGenCacheSize = a_IniFile.
GetValueSetI(
"Generator",
"CompositionGenCacheSize", 64);
364 if (CompoGenCacheSize > 0)
380 auto seaLevel = a_IniFile.
GetValueI(
"Generator",
"SeaLevel");
386 for (AStringVector::const_iterator itr = Str.begin(); itr != Str.end(); ++itr)
393 const auto & finisher = split[0];
402 int BottomLavaLevel = a_IniFile.
GetValueSetI(
"Generator",
"BottomLavaLevel", DefaultBottomLavaLevel);
403 m_FinishGens.push_back(std::make_unique<cFinishGenBottomLava>(BottomLavaLevel));
412 AllowedBiomes.push_back(
biMesa);
435 Gen->Initialize(a_IniFile,
"DirtPockets");
438 else if (
NoCaseCompare(finisher,
"DistortedMembraneOverhangs") == 0)
440 m_FinishGens.push_back(std::make_unique<cStructGenDistortedMembraneOverhangs>(
m_Seed));
444 float Threshold =
static_cast<float>(a_IniFile.
GetValueSetF(
"Generator",
"DualRidgeCavesThreshold", 0.3));
445 m_FinishGens.push_back(std::make_unique<cStructGenDualRidgeCaves>(
m_Seed, Threshold));
449 int GridSize = a_IniFile.
GetValueSetI(
"Generator",
"DungeonRoomsGridSize", 48);
450 int MaxSize = a_IniFile.
GetValueSetI(
"Generator",
"DungeonRoomsMaxSize", 7);
451 int MinSize = a_IniFile.
GetValueSetI(
"Generator",
"DungeonRoomsMinSize", 5);
452 AString HeightDistrib = a_IniFile.
GetValueSet (
"Generator",
"DungeonRoomsHeightDistrib",
"0, 0; 10, 10; 11, 500; 40, 500; 60, 40; 90, 1");
455 else if (
NoCaseCompare(finisher,
"EnderDragonFightStructures") == 0)
458 "76|3|false; 79|3|true; 82|3|true; "
459 "85|4|false; 88|4|false; 91|4|false; "
460 "94|5|false; 97|5|false; 100|5|false; "
462 int Radius = a_IniFile.
GetValueSetI(
"Generator",
"ObsidianPillarsRadius", 43);
463 auto Gen = std::make_unique<cEnderDragonFightStructuresGen>(
m_Seed);
464 Gen->Init(Pillars, Radius);
477 m_FinishGens.push_back(std::make_unique<cFinishGenIce>());
481 int Probability = a_IniFile.
GetValueSetI(
"Generator",
"LavaLakesProbability", 10);
508 int GridSize = a_IniFile.
GetValueSetI(
"Generator",
"MineShaftsGridSize", 512);
509 int MaxOffset = a_IniFile.
GetValueSetI(
"Generator",
"MineShaftsMaxOffset", 256);
510 int MaxSystemSize = a_IniFile.
GetValueSetI(
"Generator",
"MineShaftsMaxSystemSize", 160);
511 int ChanceCorridor = a_IniFile.
GetValueSetI(
"Generator",
"MineShaftsChanceCorridor", 600);
512 int ChanceCrossing = a_IniFile.
GetValueSetI(
"Generator",
"MineShaftsChanceCrossing", 200);
513 int ChanceStaircase = a_IniFile.
GetValueSetI(
"Generator",
"MineShaftsChanceStaircase", 200);
514 m_FinishGens.push_back(std::make_unique<cStructGenMineShafts>(
515 m_Seed, GridSize, MaxOffset, MaxSystemSize,
516 ChanceCorridor, ChanceCrossing, ChanceStaircase
538 Gen->Initialize(a_IniFile,
"OrePockets");
541 else if (
NoCaseCompare(finisher,
"OverworldClumpFlowers") == 0)
548 if (split.size() < 2)
550 LOGWARNING(
"The PieceStructures generator needs the structures to use. Example: \"PieceStructures: NetherFort\".");
554 auto Gen = std::make_unique<cPieceStructuresGen>(
m_Seed);
563 bool PreSimulateFallingBlocks = a_IniFile.
GetValueSetB(
"Generator",
"PreSimulatorFallingBlocks",
true);
564 bool PreSimulateWater = a_IniFile.
GetValueSetB(
"Generator",
"PreSimulatorWater",
true);
565 bool PreSimulateLava = a_IniFile.
GetValueSetB(
"Generator",
"PreSimulatorLava",
true);
567 m_FinishGens.push_back(std::make_unique<cFinishGenPreSimulator>(PreSimulateFallingBlocks, PreSimulateWater, PreSimulateLava));
575 int GridSize = a_IniFile.
GetValueSetI(
"Generator",
"RoughRavinesGridSize", 256);
576 int MaxOffset = a_IniFile.
GetValueSetI(
"Generator",
"RoughRavinesMaxOffset", 128);
577 int MaxSize = a_IniFile.
GetValueSetI(
"Generator",
"RoughRavinesMaxSize", 128);
578 int MinSize = a_IniFile.
GetValueSetI(
"Generator",
"RoughRavinesMinSize", 64);
579 double MaxCenterWidth = a_IniFile.
GetValueSetF(
"Generator",
"RoughRavinesMaxCenterWidth", 8);
580 double MinCenterWidth = a_IniFile.
GetValueSetF(
"Generator",
"RoughRavinesMinCenterWidth", 2);
581 double MaxRoughness = a_IniFile.
GetValueSetF(
"Generator",
"RoughRavinesMaxRoughness", 0.2);
582 double MinRoughness = a_IniFile.
GetValueSetF(
"Generator",
"RoughRavinesMinRoughness", 0.05);
583 double MaxFloorHeightEdge = a_IniFile.
GetValueSetF(
"Generator",
"RoughRavinesMaxFloorHeightEdge", 8);
584 double MinFloorHeightEdge = a_IniFile.
GetValueSetF(
"Generator",
"RoughRavinesMinFloorHeightEdge", 30);
585 double MaxFloorHeightCenter = a_IniFile.
GetValueSetF(
"Generator",
"RoughRavinesMaxFloorHeightCenter", 20);
586 double MinFloorHeightCenter = a_IniFile.
GetValueSetF(
"Generator",
"RoughRavinesMinFloorHeightCenter", 6);
587 double MaxCeilingHeightEdge = a_IniFile.
GetValueSetF(
"Generator",
"RoughRavinesMaxCeilingHeightEdge", 56);
588 double MinCeilingHeightEdge = a_IniFile.
GetValueSetF(
"Generator",
"RoughRavinesMinCeilingHeightEdge", 38);
589 double MaxCeilingHeightCenter = a_IniFile.
GetValueSetF(
"Generator",
"RoughRavinesMaxCeilingHeightCenter", 58);
590 double MinCeilingHeightCenter = a_IniFile.
GetValueSetF(
"Generator",
"RoughRavinesMinCeilingHeightCenter", 36);
593 static_cast<float>(MaxCenterWidth),
594 static_cast<float>(MinCenterWidth),
595 static_cast<float>(MaxRoughness),
596 static_cast<float>(MinRoughness),
597 static_cast<float>(MaxFloorHeightEdge),
598 static_cast<float>(MinFloorHeightEdge),
599 static_cast<float>(MaxFloorHeightCenter),
600 static_cast<float>(MinFloorHeightCenter),
601 static_cast<float>(MaxCeilingHeightEdge),
602 static_cast<float>(MinCeilingHeightEdge),
603 static_cast<float>(MaxCeilingHeightCenter),
604 static_cast<float>(MinCeilingHeightCenter),
608 else if (
NoCaseCompare(finisher,
"SinglePieceStructures") == 0)
610 if (split.size() < 2)
612 LOGWARNING(
"The SinglePieceStructures generator needs the structures to use. Example: \"SinglePieceStructures: DesertPyramid\".");
616 auto Gen = std::make_unique<cSinglePieceStructuresGen>(
m_Seed);
628 m_FinishGens.push_back(std::make_unique<cFinishGenSnow>());
632 int MaxCactusHeight = a_IniFile.
GetValueI(
"Plants",
"MaxCactusHeight", 3);
633 int MaxSugarcaneHeight = a_IniFile.
GetValueI(
"Plants",
"MaxSugarcaneHeight", 3);
634 m_FinishGens.push_back(std::make_unique<cFinishGenSprinkleFoliage>(
m_Seed, MaxCactusHeight, MaxSugarcaneHeight));
646 int GridSize = a_IniFile.
GetValueSetI(
"Generator",
"VillageGridSize", 384);
647 int MaxOffset = a_IniFile.
GetValueSetI(
"Generator",
"VillageMaxOffset", 128);
648 int MaxDepth = a_IniFile.
GetValueSetI(
"Generator",
"VillageMaxDepth", 2);
649 int MaxSize = a_IniFile.
GetValueSetI(
"Generator",
"VillageMaxSize", 128);
650 int MinDensity = a_IniFile.
GetValueSetI(
"Generator",
"VillageMinDensity", 50);
651 int MaxDensity = a_IniFile.
GetValueSetI(
"Generator",
"VillageMaxDensity", 80);
652 AString PrefabList = a_IniFile.
GetValueSet(
"Generator",
"VillagePrefabs",
"PlainsVillage, SandVillage");
654 m_FinishGens.push_back(std::make_unique<cVillageGen>(
m_Seed, GridSize, MaxOffset, MaxDepth, MaxSize, MinDensity, MaxDensity, *
m_BiomeGen, *
m_CompositedHeightCache, seaLevel, Prefabs));
663 int Probability = a_IniFile.
GetValueSetI(
"Generator",
"WaterLakesProbability", 25);
672 int Size = a_IniFile.
GetValueSetI(
"Generator",
"WormNestCavesSize", 64);
673 int Grid = a_IniFile.
GetValueSetI(
"Generator",
"WormNestCavesGrid", 96);
674 int MaxOffset = a_IniFile.
GetValueSetI(
"Generator",
"WormNestMaxOffset", 32);
675 m_FinishGens.push_back(std::make_unique<cStructGenWormNestCaves>(
m_Seed, Size, Grid, MaxOffset));
679 LOGWARNING(
"Unknown Finisher in the [Generator] section: \"%s\". Ignoring.", finisher.c_str());
@ E_BLOCK_STATIONARY_LAVA
@ E_BLOCK_STATIONARY_WATER
eDimension
Dimension of a world.
std::unique_ptr< cTerrainCompositionGen > CreateCompoGenBiomal(int a_Seed)
Returns a new instance of the Biomal composition generator.
void LOGWARNING(std::string_view a_Format, const Args &... args)
AStringVector StringSplitAndTrim(const AString &str, const AString &delim)
Split the string at any of the listed delimiters and trim each value.
int NoCaseCompare(const AString &s1, const AString &s2)
Case-insensitive string comparison.
std::vector< AString > AStringVector
unsigned char Level(const BlockState Block)
Wraps the chunk coords into a single structure.
EMCSBiome BiomeMap[Width *Width]
The type used for any biomemap operations and storage inside Cuberite, using Cuberite biomes (need no...
bool IsUsingDefaultHeight(void) const
bool IsUsingDefaultBiomes(void) const
Byte Shape[256 *16 *16]
The datatype used to represent the entire chunk worth of shape.
bool IsUsingDefaultFinish(void) const
void GetShapeFromHeight(Shape &a_Shape) const
Sets the shape in a_Shape to match the heightmap stored currently in m_HeightMap.
bool IsUsingDefaultComposition(void) const
cChunkCoords GetChunkCoords() const
cChunkDef::BiomeMap & GetBiomeMap(void)
void UpdateHeightmap(void)
Updates the heightmap to match the current contents.
void SetHeightFromShape(const Shape &a_Shape)
Sets the heightmap to match the given shape data.
virtual void Initialize(cIniFile &a_IniFile)
Called to initialize the generator on server startup.
eDimension m_Dimension
The dimension, read from the INI file.
int m_Seed
The main seed, read from the INI file, used for the entire generator.
The interface that a biome generator must implement A biome generator takes chunk coords on input and...
static std::unique_ptr< cBiomeGen > CreateBiomeGen(cIniFile &a_IniFile, int a_Seed, bool &a_CacheOffByDefault)
Creates the correct BiomeGen descendant based on the ini file settings.
The interface that a terrain shape generator must implement A terrain shape generator takes chunk coo...
static std::unique_ptr< cTerrainShapeGen > CreateShapeGen(cIniFile &a_IniFile, cBiomeGen &a_BiomeGen, int a_Seed, bool &a_CacheOffByDefault)
Creates the correct TerrainShapeGen descendant based on the ini file settings and the seed provided.
static std::unique_ptr< cTerrainCompositionGen > CreateCompositionGen(cIniFile &a_IniFile, cBiomeGen &a_BiomeGen, cTerrainShapeGen &a_ShapeGen, int a_Seed)
Creates the correct TerrainCompositionGen descendant based on the ini file settings and the seed prov...
virtual void GenerateBiomes(cChunkCoords a_ChunkCoords, cChunkDef::BiomeMap &a_BiomeMap) override
Generates the biomes for the specified chunk.
virtual void Initialize(cIniFile &a_IniFile) override
Called to initialize the generator on server startup.
void InitFinishGens(cIniFile &a_IniFile)
Reads the finishers from the ini and initializes m_FinishGens accordingly.
static void InitializeGeneratorDefaults(cIniFile &a_IniFile, eDimension a_Dimension)
If there's no particular sub-generator set in the INI file, adds the default one, based on the dimens...
std::unique_ptr< cBiomeGen > m_BiomeGen
The biome generator.
std::vector< std::unique_ptr< cFinishGen > > m_FinishGens
The finisher generators, in the order in which they are applied.
std::unique_ptr< cTerrainShapeGen > m_ShapeGen
The terrain shape generator.
std::unique_ptr< cTerrainHeightGen > m_CompositedHeightCache
The cache for the heights of the composited terrain.
void InitShapeGen(cIniFile &a_IniFile)
Reads the ShapeGen settings from the ini and initializes m_ShapeGen accordingly.
void InitBiomeGen(cIniFile &a_IniFile)
Reads the BiomeGen settings from the ini and initializes m_BiomeGen accordingly.
std::unique_ptr< cTerrainCompositionGen > m_CompositionGen
The terrain composition generator.
virtual void Generate(cChunkDesc &a_ChunkDesc) override
Does the actual chunk generation.
void InitCompositionGen(cIniFile &a_IniFile)
Reads the CompositionGen settings from the ini and initializes m_CompositionGen accordingly.
static std::vector< BiomeInfo > ParseIniFile(cIniFile &a_IniFile, const AString &a_ClumpPrefix)
Parses an inifile in search for all clumps.
std::vector< EMCSBiome > BiomeList
std::vector< BLOCKTYPE > BlockList
static const OreInfos & DefaultOverworldOres(void)
Returns a vector of OreInfo structures describing the default Overworld ores, usable in the construct...
static const OreInfos & DefaultNetherOres(void)
Returns a vector of OreInfo structures describing the default Nether ores, usable in the constructor.
static const OreInfos & DefaultNaturalPatches(void)
Returns a vector of OreInfo structures describing the default Overworld non-ore pockets (dirt,...
AString GetValue(const AString &keyname, const AString &valuename, const AString &defValue="") const override
Get the value at the specified key and value, returns defValue on failure.
int GetValueI(const AString &keyname, const AString &valuename, const int defValue=0) const
int GetValueSetI(const AString &keyname, const AString &valuename, const int defValue=0) override
bool SetValue(const int keyID, const int valueID, const AString &value)
AString GetValueSet(const AString &keyname, const AString &valuename, const AString &defValue="") override
Gets the value; if not found, write the default to the repository.
bool GetValueSetB(const AString &keyname, const AString &valuename, const bool defValue=false) override
double GetValueSetF(const AString &keyname, const AString &valuename, const double defValue=0.0)