Cuberite
A lightweight, fast and extensible game server for Minecraft
VerticalStrategy.cpp
Go to the documentation of this file.
1 
2 // VerticalStrategy.cpp
3 
4 // Implements the various classes descending from cPiece::cVerticalStrategy
5 
6 #include "Globals.h"
7 #include "VerticalStrategy.h"
8 #include "../Noise/Noise.h"
9 
10 
11 
12 
13 
14 // Constant that is added to random seed
15 static const int SEED_OFFSET = 135;
16 
17 
18 
20 // Globals:
21 
27 {
28  static bool ParseRange(const AString & a_Params, int & a_Min, int & a_Range, bool a_LogWarnings)
29  {
30  auto params = StringSplitAndTrim(a_Params, "|");
31  if (params.size() == 0)
32  {
33  // No params, generate directly on top:
34  return true;
35  }
36  if (!StringToInteger(params[0], a_Min))
37  {
38  // Failed to parse the min rel height:
39  CONDWARNING(a_LogWarnings, "Cannot parse minimum height from string \"%s\"!", params[0].c_str());
40  return false;
41  }
42  if (params.size() == 1)
43  {
44  // Only one param was given, there's no range
45  return true;
46  }
47  int maxHeight = a_Min;
48  if (!StringToInteger(params[1], maxHeight))
49  {
50  CONDWARNING(a_LogWarnings, "Cannot parse maximum height from string \"%s\"!", params[1].c_str());
51  return false;
52  }
53  if (maxHeight < a_Min)
54  {
55  std::swap(maxHeight, a_Min);
56  }
57  a_Range = maxHeight - a_Min + 1;
58  return true;
59  }
60 }
61 
62 
63 
64 
65 
67 
70 {
71 public:
73  m_Height(-1000) // Default to "unassigned" height
74  {
75  }
76 
77 
78  virtual int GetVerticalPlacement(int a_BlockX, int a_BlockZ) override
79  {
80  return m_Height;
81  }
82 
83 
84  virtual bool InitializeFromString(const AString & a_Params, bool a_LogWarnings) override
85  {
86  // Params: "<Height>", compulsory
87  if (!StringToInteger(a_Params, m_Height))
88  {
89  CONDWARNING(a_LogWarnings, "Cannot parse the fixed height from string \"%s\"!", a_Params.c_str());
90  return false;
91  }
92  return true;
93  }
94 
95 protected:
98  int m_Height;
99 };
100 
101 
102 
103 
104 
106 
109 {
110 public:
112  m_Seed(0),
113  m_Min(-1), // Default to "unassigned" height
114  m_Range(1)
115  {
116  }
117 
118 
119  virtual int GetVerticalPlacement(int a_BlockX, int a_BlockZ) override
120  {
121  cNoise Noise(m_Seed);
122  return m_Min + (Noise.IntNoise2DInt(a_BlockX, a_BlockZ) / 7) % m_Range;
123  }
124 
125 
126  virtual bool InitializeFromString(const AString & a_Params, bool a_LogWarnings) override
127  {
128  // Params: "<MinHeight>|<MaxHeight>", all compulsory
129  auto params = StringSplitAndTrim(a_Params, "|");
130  if (params.size() != 2)
131  {
132  CONDWARNING(a_LogWarnings, "Cannot parse the range parameters from string \"%s\"!", a_Params.c_str());
133  return false;
134  }
135  int Max = 0;
136  if (!StringToInteger(params[0], m_Min) || !StringToInteger(params[1], Max))
137  {
138  CONDWARNING(a_LogWarnings, "Cannot parse the minimum or maximum height from string \"%s\"!", a_Params.c_str());
139  return false;
140  }
141  if (m_Min > Max)
142  {
143  std::swap(m_Min, Max);
144  }
145  m_Range = Max - m_Min + 1;
146  return true;
147  }
148 
149 
150  virtual void AssignGens(int a_Seed, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_TerrainHeightGen, int a_SeaLevel) override
151  {
152  m_Seed = a_Seed + SEED_OFFSET;
153  }
154 
155 protected:
157  int m_Seed;
158 
161 };
162 
163 
164 
165 
166 
168 
171 {
172 public:
173 
174  virtual int GetVerticalPlacement(int a_BlockX, int a_BlockZ) override
175  {
176  ASSERT(m_HeightGen != nullptr);
177 
178  int ChunkX, ChunkZ;
179  cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ);
180  cChunkDef::HeightMap HeightMap;
181  m_HeightGen->GenHeightMap({ChunkX, ChunkZ}, HeightMap);
182  cNoise noise(m_Seed);
183  int rel = m_MinRelHeight + (noise.IntNoise2DInt(a_BlockX, a_BlockZ) / 7) % m_RelHeightRange + 1;
184  return cChunkDef::GetHeight(HeightMap, a_BlockX - ChunkX * cChunkDef::Width, a_BlockZ - ChunkZ * cChunkDef::Width) + rel;
185  }
186 
187 
188  virtual bool InitializeFromString(const AString & a_Params, bool a_LogWarnings) override
189  {
190  // Params: "<MinRelativeHeight>|<MaxRelativeHeight>", all optional
191  m_MinRelHeight = 0;
192  m_RelHeightRange = 1;
193  return VerticalStrategy::ParseRange(a_Params, m_MinRelHeight, m_RelHeightRange, a_LogWarnings);
194  }
195 
196 
197  virtual void AssignGens(int a_Seed, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen, int a_SeaLevel) override
198  {
199  m_Seed = a_Seed + SEED_OFFSET;
200  m_HeightGen = &a_HeightGen;
201  }
202 
203 protected:
205  int m_Seed;
206 
209 
212 
215 };
216 
217 
218 
219 
220 
222 
225 {
226 public:
227 
228  virtual int GetVerticalPlacement(int a_BlockX, int a_BlockZ) override
229  {
230  ASSERT(m_HeightGen != nullptr);
231 
232  int ChunkX, ChunkZ;
233  cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ);
234  cChunkDef::HeightMap HeightMap;
235  m_HeightGen->GenHeightMap({ChunkX, ChunkZ}, HeightMap);
236  int terrainHeight = static_cast<int>(cChunkDef::GetHeight(HeightMap, a_BlockX - ChunkX * cChunkDef::Width, a_BlockZ - ChunkZ * cChunkDef::Width));
237  terrainHeight = std::max(1 + terrainHeight, m_SeaLevel);
238  cNoise noise(m_Seed);
239  int rel = m_MinRelHeight + (noise.IntNoise2DInt(a_BlockX, a_BlockZ) / 7) % m_RelHeightRange + 1;
240  return terrainHeight + rel;
241  }
242 
243 
244  virtual bool InitializeFromString(const AString & a_Params, bool a_LogWarnings) override
245  {
246  // Params: "<MinRelativeHeight>|<MaxRelativeHeight>", all optional
247  m_MinRelHeight = 0;
248  m_RelHeightRange = 1;
249  return VerticalStrategy::ParseRange(a_Params, m_MinRelHeight, m_RelHeightRange, a_LogWarnings);
250  }
251 
252 
253  virtual void AssignGens(int a_Seed, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen, int a_SeaLevel) override
254  {
255  m_Seed = a_Seed + SEED_OFFSET;
256  m_HeightGen = &a_HeightGen;
257  m_SeaLevel = a_SeaLevel;
258  }
259 
260 protected:
262  int m_Seed;
263 
266 
269 
272 
275 };
276 
277 
278 
279 
280 
282 // CreateVerticalStrategyFromString:
283 
284 cPiece::cVerticalStrategyPtr CreateVerticalStrategyFromString(const AString & a_StrategyDesc, bool a_LogWarnings)
285 {
286  // Break apart the strategy class, the first parameter before the first pipe char:
287  auto idxPipe = a_StrategyDesc.find('|');
288  if (idxPipe == AString::npos)
289  {
290  idxPipe = a_StrategyDesc.length();
291  }
292  AString StrategyClass = a_StrategyDesc.substr(0, idxPipe);
293 
294  // Create a strategy class based on the class string:
296  if (NoCaseCompare(StrategyClass, "Fixed") == 0)
297  {
298  Strategy = std::make_shared<cVerticalStrategyFixed>();
299  }
300  else if (NoCaseCompare(StrategyClass, "Range") == 0)
301  {
302  Strategy = std::make_shared<cVerticalStrategyRange>();
303  }
304  else if (NoCaseCompare(StrategyClass, "TerrainTop") == 0)
305  {
306  Strategy = std::make_shared<cVerticalStrategyTerrainTop>();
307  }
308  else if (NoCaseCompare(StrategyClass, "TerrainOrOceanTop") == 0)
309  {
310  Strategy = std::make_shared<cVerticalStrategyTerrainOrOceanTop>();
311  }
312  else
313  {
314  return nullptr;
315  }
316 
317  // Initialize the strategy's parameters:
318  AString Params;
319  if (idxPipe < a_StrategyDesc.length())
320  {
321  Params = a_StrategyDesc.substr(idxPipe + 1);
322  }
323  if (!Strategy->InitializeFromString(Params, a_LogWarnings))
324  {
325  return nullptr;
326  }
327 
328  return Strategy;
329 }
cPiece::cVerticalStrategyPtr CreateVerticalStrategyFromString(const AString &a_StrategyDesc, bool a_LogWarnings)
Returns a new cPiece::cVerticalStrategy descendant based on the specified description.
static const int SEED_OFFSET
#define ASSERT(x)
Definition: Globals.h:276
#define CONDWARNING(ShouldLog,...)
Definition: LoggerSimple.h:99
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::string AString
Definition: StringUtils.h:11
bool StringToInteger(const AString &a_str, T &a_Num)
Parses any integer type.
Definition: StringUtils.h:143
Parses a string containing a range in which both values are optional ("<MinHeight>|<MaxHeight>") into...
static bool ParseRange(const AString &a_Params, int &a_Min, int &a_Range, bool a_LogWarnings)
static void BlockToChunk(int a_X, int a_Z, int &a_ChunkX, int &a_ChunkZ)
Converts absolute block coords to chunk coords:
Definition: ChunkDef.h:210
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 HEIGHTTYPE GetHeight(const HeightMap &a_HeightMap, int a_X, int a_Z)
Definition: ChunkDef.h:303
The interface that a biome generator must implement A biome generator takes chunk coords on input and...
The interface that is used to query terrain height from the shape generator.
virtual void GenHeightMap(cChunkCoords a_ChunkCoords, cChunkDef::HeightMap &a_HeightMap)=0
Retrieves the heightmap for the specified chunk.
std::shared_ptr< cVerticalStrategy > cVerticalStrategyPtr
Definition: PiecePool.h:121
Base class (interface) for strategies for placing the starting pieces vertically.
Definition: PiecePool.h:101
A vertical strategy that places the piece at a predefined height.
virtual int GetVerticalPlacement(int a_BlockX, int a_BlockZ) override
Returns the Y coord of the piece.
int m_Height
Height at which the pieces are placed.
virtual bool InitializeFromString(const AString &a_Params, bool a_LogWarnings) override
Initializes the strategy's parameters from the string representation.
A vertical strategy that places the piece in a random height between two heights.
virtual bool InitializeFromString(const AString &a_Params, bool a_LogWarnings) override
Initializes the strategy's parameters from the string representation.
virtual int GetVerticalPlacement(int a_BlockX, int a_BlockZ) override
Returns the Y coord of the piece.
virtual void AssignGens(int a_Seed, cBiomeGen &a_BiomeGen, cTerrainHeightGen &a_TerrainHeightGen, int a_SeaLevel) override
Called when the piece pool is assigned to a generator, so that the strategies may bind to the underly...
int m_Min
Range for the random generator.
int m_Seed
Seed for the random generator.
A vertical strategy that places the piece in a specified range relative to the top of the terrain.
virtual bool InitializeFromString(const AString &a_Params, bool a_LogWarnings) override
Initializes the strategy's parameters from the string representation.
int m_Seed
Seed for the random generator.
cTerrainHeightGen * m_HeightGen
Height generator from which the top of the terrain is read.
virtual void AssignGens(int a_Seed, cBiomeGen &a_BiomeGen, cTerrainHeightGen &a_HeightGen, int a_SeaLevel) override
Called when the piece pool is assigned to a generator, so that the strategies may bind to the underly...
int m_MinRelHeight
Minimum relative height at which the prefab is placed.
virtual int GetVerticalPlacement(int a_BlockX, int a_BlockZ) override
Returns the Y coord of the piece.
int m_RelHeightRange
Range of the relative heights at which the prefab can be placed above the minimum.
A vertical strategy that places the piece within a range on top of the terrain or ocean,...
int m_RelHeightRange
Range of the relative heights at which the prefab can be placed above the minimum.
cTerrainHeightGen * m_HeightGen
Height generator from which the top of the terrain is read.
virtual void AssignGens(int a_Seed, cBiomeGen &a_BiomeGen, cTerrainHeightGen &a_HeightGen, int a_SeaLevel) override
Called when the piece pool is assigned to a generator, so that the strategies may bind to the underly...
int m_SeaLevel
The sea level used by the world.
int m_Seed
Seed for the random generator.
virtual bool InitializeFromString(const AString &a_Params, bool a_LogWarnings) override
Initializes the strategy's parameters from the string representation.
int m_MinRelHeight
Minimum relative height at which the prefab is placed.
virtual int GetVerticalPlacement(int a_BlockX, int a_BlockZ) override
Returns the Y coord of the piece.
Definition: Noise.h:20
int IntNoise2DInt(int a_X, int a_Y) const
Definition: Noise.h:243