Cuberite
A lightweight, fast and extensible game server for Minecraft
ShapeGen.cpp
Go to the documentation of this file.
1 
2 // ShapeGen.cpp
3 
4 // Implements the function to create a cTerrainShapeGen descendant based on INI file settings
5 
6 #include "Globals.h"
7 #include "HeiGen.h"
8 #include "../IniFile.h"
9 #include "DistortedHeightmap.h"
10 #include "EndGen.h"
11 #include "Noise3DGenerator.h"
12 #include "TwoHeights.h"
13 
14 
15 
16 
17 
19 // cTerrainHeightToShapeGen:
20 
23  public cTerrainShapeGen
24 {
25 public:
26  cTerrainHeightToShapeGen(std::unique_ptr<cTerrainHeightGen> a_HeightGen):
27  m_HeightGen(std::move(a_HeightGen))
28  {
29  }
30 
31 
32  // cTerrainShapeGen overrides:
33  virtual void GenShape(cChunkCoords a_ChunkCoords, cChunkDesc::Shape & a_Shape) override
34  {
35  // Generate the heightmap:
36  cChunkDef::HeightMap heightMap;
37  m_HeightGen->GenHeightMap(a_ChunkCoords, heightMap);
38 
39  // Convert from heightmap to shape:
40  for (int z = 0; z < cChunkDef::Width; z++)
41  {
42  for (int x = 0; x < cChunkDef::Width; x++)
43  {
44  int height = cChunkDef::GetHeight(heightMap, x, z) + 1;
45  Byte * shapeColumn = &(a_Shape[(x + 16 * z) * 256]);
46  for (int y = 0; y < height; y++)
47  {
48  shapeColumn[y] = 1;
49  }
50  for (int y = height; y < cChunkDef::Height; y++)
51  {
52  shapeColumn[y] = 0;
53  }
54  } // for x
55  } // for z
56  }
57 
58 
59  virtual void InitializeShapeGen(cIniFile & a_IniFile) override
60  {
61  m_HeightGen->InitializeHeightGen(a_IniFile);
62  }
63 
64 protected:
66  std::unique_ptr<cTerrainHeightGen> m_HeightGen;
67 };
68 
69 typedef std::shared_ptr<cTerrainHeightToShapeGen> cTerrainHeightToShapeGenPtr;
70 
71 
72 
73 
74 
76 // cTerrainShapeGen:
77 
78 std::unique_ptr<cTerrainShapeGen> cTerrainShapeGen::CreateShapeGen(
79  cIniFile & a_IniFile,
80  cBiomeGen & a_BiomeGen,
81  int a_Seed,
82  bool & a_CacheOffByDefault
83 )
84 {
85  AString shapeGenName = a_IniFile.GetValue("Generator", "ShapeGen");
86  if (shapeGenName.empty())
87  {
88  LOGWARN("[Generator] ShapeGen value not set in world.ini, using \"BiomalNoise3D\".");
89  shapeGenName = "BiomalNoise3D";
90  }
91 
92  // If the shapegen is HeightMap, redirect to older HeightMap-based generators:
93  if (NoCaseCompare(shapeGenName, "HeightMap") == 0)
94  {
95  auto heightGen = cTerrainHeightGen::CreateHeightGen(a_IniFile, a_BiomeGen, a_Seed, a_CacheOffByDefault);
96  if (heightGen != nullptr)
97  {
98  return std::make_unique<cTerrainHeightToShapeGen>(std::move(heightGen));
99  }
100 
101  // The height gen was not recognized; several heightgens were promoted to shape gens, so let's try them instead:
102  shapeGenName = a_IniFile.GetValue("Generator", "HeightGen", "");
103  if (shapeGenName.empty())
104  {
105  LOGWARNING("[Generator] ShapeGen set to HeightMap, but HeightGen not set. Reverting to \"BiomalNoise3D\".");
106  shapeGenName = "BiomalNoise3D";
107  a_IniFile.SetValue("Generator", "ShapeGen", shapeGenName);
108  }
109  }
110 
111  // Choose the shape generator based on the name:
112  a_CacheOffByDefault = false;
113  std::unique_ptr<cTerrainShapeGen> res;
114  if (NoCaseCompare(shapeGenName, "DistortedHeightmap") == 0)
115  {
116  res = std::make_unique<cDistortedHeightmap>(a_Seed, a_BiomeGen);
117  }
118  else if (NoCaseCompare(shapeGenName, "End") == 0)
119  {
120  res = std::make_unique<cEndGen>(a_Seed);
121  }
122  else if (NoCaseCompare(shapeGenName, "BiomalNoise3D") == 0)
123  {
124  res = std::make_unique<cBiomalNoise3DComposable>(a_Seed, a_BiomeGen);
125  }
126  else if (NoCaseCompare(shapeGenName, "Noise3D") == 0)
127  {
128  res = std::make_unique<cNoise3DComposable>(a_Seed);
129  }
130  else if (NoCaseCompare(shapeGenName, "TwoHeights") == 0)
131  {
132  res = CreateShapeGenTwoHeights(a_Seed, a_BiomeGen);
133  }
134  else
135  {
136  // No match found, force-set the default and retry
137  LOGWARN("Unknown ShapeGen \"%s\", using \"BiomalNoise3D\" instead.", shapeGenName.c_str());
138  a_IniFile.SetValue("Generator", "ShapeGen", "BiomalNoise3D");
139  return CreateShapeGen(a_IniFile, a_BiomeGen, a_Seed, a_CacheOffByDefault);
140  }
141 
142  // Read the settings:
143  res->InitializeShapeGen(a_IniFile);
144 
145  return res;
146 }
std::shared_ptr< cTerrainHeightToShapeGen > cTerrainHeightToShapeGenPtr
Definition: ShapeGen.cpp:69
std::unique_ptr< cTerrainShapeGen > CreateShapeGenTwoHeights(int a_Seed, cBiomeGen &a_BiomeGen)
Creates and returns a new instance of the cTwoHeights terrain shape generator.
Definition: TwoHeights.cpp:116
unsigned char Byte
Definition: Globals.h:161
void LOGWARNING(std::string_view a_Format, const Args &... args)
Definition: LoggerSimple.h:67
#define LOGWARN
Definition: LoggerSimple.h:88
int NoCaseCompare(const AString &s1, const AString &s2)
Case-insensitive string comparison.
std::string AString
Definition: StringUtils.h:11
Definition: FastNBT.h:132
Wraps the chunk coords into a single structure.
Definition: ChunkDef.h:57
HEIGHTTYPE HeightMap[Width *Width]
The type used for any heightmap operations and storage; idx = x + Width * z; Height points to the hig...
Definition: ChunkDef.h:132
static const int Width
Definition: ChunkDef.h:124
static const int Height
Definition: ChunkDef.h:125
static HEIGHTTYPE GetHeight(const HeightMap &a_HeightMap, int a_X, int a_Z)
Definition: ChunkDef.h:303
Byte Shape[256 *16 *16]
The datatype used to represent the entire chunk worth of shape.
Definition: ChunkDesc.h:36
The interface that a biome generator must implement A biome generator takes chunk coords on input and...
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.
Definition: ShapeGen.cpp:78
static std::unique_ptr< cTerrainHeightGen > CreateHeightGen(cIniFile &a_IniFile, cBiomeGen &a_BiomeGen, int a_Seed, bool &a_CacheOffByDefault)
Creates a cTerrainHeightGen descendant based on the INI file settings.
Definition: HeiGen.cpp:835
Converts old-style height-generators into new-style shape-generators.
Definition: ShapeGen.cpp:24
cTerrainHeightToShapeGen(std::unique_ptr< cTerrainHeightGen > a_HeightGen)
Definition: ShapeGen.cpp:26
virtual void GenShape(cChunkCoords a_ChunkCoords, cChunkDesc::Shape &a_Shape) override
Generates the shape for the given chunk.
Definition: ShapeGen.cpp:33
virtual void InitializeShapeGen(cIniFile &a_IniFile) override
Reads parameters from the ini file, prepares generator for use.
Definition: ShapeGen.cpp:59
std::unique_ptr< cTerrainHeightGen > m_HeightGen
The height generator being converted.
Definition: ShapeGen.cpp:66
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.
Definition: IniFile.cpp:485
bool SetValue(const int keyID, const int valueID, const AString &value)
Definition: IniFile.cpp:397