Cuberite
A lightweight, fast and extensible game server for Minecraft
CompoGen.cpp
Go to the documentation of this file.
1 
2 // CompoGen.cpp
3 
4 /* Implements the various terrain composition generators:
5  - cCompoGenSameBlock
6  - cCompoGenDebugBiomes
7  - cCompoGenClassic
8 */
9 
10 #include "Globals.h"
11 #include "CompoGen.h"
12 #include "../Item.h"
13 #include "../LinearUpscale.h"
14 #include "../IniFile.h"
15 
16 
17 
18 
19 
21 // cCompoGenSameBlock:
22 
24 {
25  a_ChunkDesc.SetHeightFromShape(a_Shape);
26  a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0);
27  for (int z = 0; z < cChunkDef::Width; z++)
28  {
29  for (int x = 0; x < cChunkDef::Width; x++)
30  {
31  int Start;
32  if (m_IsBedrocked)
33  {
34  a_ChunkDesc.SetBlockType(x, 0, z, E_BLOCK_BEDROCK);
35  Start = 1;
36  }
37  else
38  {
39  Start = 0;
40  }
41  for (int y = a_ChunkDesc.GetHeight(x, z); y >= Start; y--)
42  {
43  a_ChunkDesc.SetBlockType(x, y, z, m_BlockType);
44  } // for y
45  } // for z
46  } // for x
47 }
48 
49 
50 
51 
52 
54 {
55  m_BlockType = static_cast<BLOCKTYPE>(GetIniItemSet(a_IniFile, "Generator", "SameBlockType", "stone").m_ItemType);
56  m_IsBedrocked = (a_IniFile.GetValueSetI("Generator", "SameBlockBedrocked", 1) != 0);
57 }
58 
59 
60 
61 
62 
64 // cCompoGenDebugBiomes:
65 
67 {
68  static BLOCKTYPE Blocks[] =
69  {
93  } ;
94 
95  a_ChunkDesc.SetHeightFromShape(a_Shape);
96  a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0);
97 
98  for (int z = 0; z < cChunkDef::Width; z++)
99  {
100  for (int x = 0; x < cChunkDef::Width; x++)
101  {
102  BLOCKTYPE BlockType = Blocks[a_ChunkDesc.GetBiome(x, z)];
103  for (int y = a_ChunkDesc.GetHeight(x, z); y >= 0; y--)
104  {
105  a_ChunkDesc.SetBlockType(x, y, z, BlockType);
106  } // for y
107  } // for z
108  } // for x
109 }
110 
111 
112 
113 
114 
116 // cCompoGenClassic:
117 
119  m_SeaLevel(60),
120  m_BeachHeight(2),
121  m_BeachDepth(4),
122  m_BlockTop(E_BLOCK_GRASS),
123  m_BlockMiddle(E_BLOCK_DIRT),
124  m_BlockBottom(E_BLOCK_STONE),
125  m_BlockBeach(E_BLOCK_SAND),
126  m_BlockBeachBottom(E_BLOCK_SANDSTONE),
127  m_BlockSea(E_BLOCK_STATIONARY_WATER)
128 {
129 }
130 
131 
132 
133 
134 
136 {
137  /* The classic composition means:
138  - 1 layer of grass, 3 of dirt and the rest stone, if the height > sealevel + beachheight
139  - 3 sand and a 1 sandstone, rest stone if between sealevel and sealevel + beachheight
140  - water from waterlevel to height, then 3 sand, 1 sandstone, the rest stone, if water depth < beachdepth
141  - water from waterlevel, then 3 dirt, the rest stone otherwise
142  - bedrock at the bottom
143  */
144 
145  a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0);
146  a_ChunkDesc.SetHeightFromShape(a_Shape);
147 
148  // The patterns to use for different situations, must be same length!
149  const BLOCKTYPE PatternGround[] = {m_BlockTop, m_BlockMiddle, m_BlockMiddle, m_BlockMiddle} ;
151  const BLOCKTYPE PatternOcean[] = {m_BlockMiddle, m_BlockMiddle, m_BlockMiddle, m_BlockBottom} ;
152  static int PatternLength = ARRAYCOUNT(PatternGround);
153  ASSERT(ARRAYCOUNT(PatternGround) == ARRAYCOUNT(PatternBeach));
154  ASSERT(ARRAYCOUNT(PatternGround) == ARRAYCOUNT(PatternOcean));
155 
156  for (int z = 0; z < cChunkDef::Width; z++)
157  {
158  for (int x = 0; x < cChunkDef::Width; x++)
159  {
160  int Height = a_ChunkDesc.GetHeight(x, z);
161  const BLOCKTYPE * Pattern;
162  if (Height > m_SeaLevel + m_BeachHeight)
163  {
164  Pattern = PatternGround;
165  }
166  else if (Height > m_SeaLevel - m_BeachDepth)
167  {
168  Pattern = PatternBeach;
169  }
170  else
171  {
172  Pattern = PatternOcean;
173  }
174 
175  // Fill water from sealevel down to height (if any):
176  for (int y = m_SeaLevel; y >= Height; --y)
177  {
178  a_ChunkDesc.SetBlockType(x, y, z, m_BlockSea);
179  }
180 
181  // Fill from height till the bottom:
182  for (int y = Height; y >= 1; y--)
183  {
184  a_ChunkDesc.SetBlockType(x, y, z, (Height - y < PatternLength) ? Pattern[Height - y] : m_BlockBottom);
185  }
186 
187  // The last layer is always bedrock:
188  a_ChunkDesc.SetBlockType(x, 0, z, E_BLOCK_BEDROCK);
189  } // for x
190  } // for z
191 }
192 
193 
194 
195 
196 
198 {
199  m_SeaLevel = a_IniFile.GetValueSetI("Generator", "SeaLevel", m_SeaLevel);
200  m_BeachHeight = a_IniFile.GetValueSetI("Generator", "ClassicBeachHeight", m_BeachHeight);
201  m_BeachDepth = a_IniFile.GetValueSetI("Generator", "ClassicBeachDepth", m_BeachDepth);
202  m_BlockTop = static_cast<BLOCKTYPE>(GetIniItemSet(a_IniFile, "Generator", "ClassicBlockTop", "grass").m_ItemType);
203  m_BlockMiddle = static_cast<BLOCKTYPE>(GetIniItemSet(a_IniFile, "Generator", "ClassicBlockMiddle", "dirt").m_ItemType);
204  m_BlockBottom = static_cast<BLOCKTYPE>(GetIniItemSet(a_IniFile, "Generator", "ClassicBlockBottom", "stone").m_ItemType);
205  m_BlockBeach = static_cast<BLOCKTYPE>(GetIniItemSet(a_IniFile, "Generator", "ClassicBlockBeach", "sand").m_ItemType);
206  m_BlockBeachBottom = static_cast<BLOCKTYPE>(GetIniItemSet(a_IniFile, "Generator", "ClassicBlockBeachBottom", "sandstone").m_ItemType);
207  m_BlockSea = static_cast<BLOCKTYPE>(GetIniItemSet(a_IniFile, "Generator", "ClassicBlockSea", "stationarywater").m_ItemType);
208 }
209 
210 
211 
212 
213 
215 // cCompoGenNether:
216 
218  m_Noise1(a_Seed + 10),
219  m_Noise2(a_Seed * a_Seed * 10 + a_Seed * 1000 + 6000),
220  m_MaxThreshold(25000)
221 {
222 }
223 
224 
225 
226 
227 
229 {
230  HEIGHTTYPE MaxHeight = a_ChunkDesc.GetMaxHeight();
231 
232  const int SEGMENT_HEIGHT = 8;
233  const int INTERPOL_X = 16; // Must be a divisor of 16
234  const int INTERPOL_Z = 16; // Must be a divisor of 16
235  // Interpolate the chunk in 16 * SEGMENT_HEIGHT * 16 "segments", each SEGMENT_HEIGHT blocks high and each linearly interpolated separately.
236  // Have two buffers, one for the lowest floor and one for the highest floor, so that Y-interpolation can be done between them
237  // Then swap the buffers and use the previously-top one as the current-bottom, without recalculating it.
238 
239  int FloorBuf1[17 * 17];
240  int FloorBuf2[17 * 17];
241  int * FloorHi = FloorBuf1;
242  int * FloorLo = FloorBuf2;
243  int BaseX = a_ChunkDesc.GetChunkX() * cChunkDef::Width;
244  int BaseZ = a_ChunkDesc.GetChunkZ() * cChunkDef::Width;
245 
246  // Interpolate the lowest floor:
247  for (int z = 0; z <= 16 / INTERPOL_Z; z++) for (int x = 0; x <= 16 / INTERPOL_X; x++)
248  {
249  // We need to store the intermediate result in a volatile variable, otherwise gcc -O2 optimizes
250  // through the undefined behavior in cNoise and produces different data than the other platforms / build types (#4384)
251  volatile int intermediate =
252  m_Noise1.IntNoise3DInt(BaseX + INTERPOL_X * x, 0, BaseZ + INTERPOL_Z * z) *
253  m_Noise2.IntNoise3DInt(BaseX + INTERPOL_X * x, 0, BaseZ + INTERPOL_Z * z);
254  FloorLo[INTERPOL_X * x + 17 * INTERPOL_Z * z] = intermediate / 256;
255  } // for x, z - FloorLo[]
256  LinearUpscale2DArrayInPlace<17, 17, INTERPOL_X, INTERPOL_Z>(FloorLo);
257 
258  // Interpolate segments:
259  for (int Segment = 0; Segment < MaxHeight; Segment += SEGMENT_HEIGHT)
260  {
261  // First update the high floor:
262  for (int z = 0; z <= 16 / INTERPOL_Z; z++) for (int x = 0; x <= 16 / INTERPOL_X; x++)
263  {
264  // We need to store the intermediate result in a volatile variable, otherwise gcc -O2 optimizes
265  // through the undefined behavior in cNoise and produces different data than the other platforms / build types (#4384)
266  volatile int intermediate =
267  m_Noise1.IntNoise3DInt(BaseX + INTERPOL_X * x, Segment + SEGMENT_HEIGHT, BaseZ + INTERPOL_Z * z) *
268  m_Noise2.IntNoise3DInt(BaseX + INTERPOL_Z * x, Segment + SEGMENT_HEIGHT, BaseZ + INTERPOL_Z * z);
269  FloorHi[INTERPOL_X * x + 17 * INTERPOL_Z * z] = intermediate / 256;
270  } // for x, z - FloorLo[]
271  LinearUpscale2DArrayInPlace<17, 17, INTERPOL_X, INTERPOL_Z>(FloorHi);
272 
273  // Interpolate between FloorLo and FloorHi:
274  for (int z = 0; z < 16; z++) for (int x = 0; x < 16; x++)
275  {
276  int Threshold = static_cast<int>(m_Noise1.CubicNoise2D(static_cast<float>(BaseX + x) / 75, static_cast<float>(BaseZ + z) / 75) * m_MaxThreshold);
277  int Lo = FloorLo[x + 17 * z] / 256;
278  int Hi = FloorHi[x + 17 * z] / 256;
279  for (int y = 0; y < SEGMENT_HEIGHT; y++)
280  {
281  int Val = Lo + (Hi - Lo) * y / SEGMENT_HEIGHT;
282  if (Val < Threshold)
283  {
284  a_ChunkDesc.SetBlockType(x, y + Segment, z, E_BLOCK_NETHERRACK);
285  }
286  }
287  }
288 
289  // Swap the floors:
290  std::swap(FloorLo, FloorHi);
291  }
292 
293  // Bedrock at the bottom and at the top, cover ceiling with netherrack:
294  for (int z = 0; z < 16; z++) for (int x = 0; x < 16; x++)
295  {
296  a_ChunkDesc.SetBlockType(x, 0, z, E_BLOCK_BEDROCK);
297 
298  int Height = a_ChunkDesc.GetHeight(x, z);
299  a_ChunkDesc.SetBlockType(x, Height, z, E_BLOCK_BEDROCK);
300 
301  NOISE_DATATYPE CeilingDisguise = (m_Noise1.CubicNoise2D(static_cast<float>(a_ChunkDesc.GetChunkX() * cChunkDef::Width + x) / 10, static_cast<float>(a_ChunkDesc.GetChunkZ() * cChunkDef::Width + z) / 10));
302  if (CeilingDisguise < 0)
303  {
304  CeilingDisguise = -CeilingDisguise;
305  }
306 
307  int CeilingDisguiseHeight = Height - 2 - FloorC(CeilingDisguise * 3);
308 
309  for (int y = Height - 1; y > CeilingDisguiseHeight; y--)
310  {
311  a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_NETHERRACK);
312  }
313  }
314 }
315 
316 
317 
318 
319 
321 {
322  m_MaxThreshold = a_IniFile.GetValueSetF("Generator", "NetherMaxThreshold", m_MaxThreshold);
323 }
324 
325 
326 
327 
328 
330 // cCompoGenCache:
331 
332 cCompoGenCache::cCompoGenCache(std::unique_ptr<cTerrainCompositionGen> a_Underlying, int a_CacheSize) :
333  m_Underlying(std::move(a_Underlying)),
334  m_CacheSize(a_CacheSize),
335  m_CacheOrder(new int[ToUnsigned(a_CacheSize)]),
336  m_CacheData(new sCacheData[ToUnsigned(a_CacheSize)]),
337  m_NumHits(0),
338  m_NumMisses(0),
339  m_TotalChain(0)
340 {
341  for (int i = 0; i < m_CacheSize; i++)
342  {
343  m_CacheOrder[i] = i;
344  m_CacheData[i].m_ChunkX = 0x7fffffff;
345  m_CacheData[i].m_ChunkZ = 0x7fffffff;
346  }
347 }
348 
349 
350 
351 
352 
354 {
355  delete[] m_CacheData;
356  m_CacheData = nullptr;
357  delete[] m_CacheOrder;
358  m_CacheOrder = nullptr;
359 }
360 
361 
362 
363 
364 
365 void cCompoGenCache::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape)
366 {
367  #ifndef NDEBUG
368  if (((m_NumHits + m_NumMisses) % 1024) == 10)
369  {
370  // LOGD("CompoGenCache: %d hits, %d misses, saved %.2f %%", m_NumHits, m_NumMisses, 100.0 * m_NumHits / (m_NumHits + m_NumMisses));
371  // LOGD("CompoGenCache: Avg cache chain length: %.2f", static_cast<float>(m_TotalChain) / m_NumHits);
372  }
373  #endif // !NDEBUG
374 
375  int ChunkX = a_ChunkDesc.GetChunkX();
376  int ChunkZ = a_ChunkDesc.GetChunkZ();
377 
378  for (int i = 0; i < m_CacheSize; i++)
379  {
380  if (
381  (m_CacheData[m_CacheOrder[i]].m_ChunkX != ChunkX) ||
382  (m_CacheData[m_CacheOrder[i]].m_ChunkZ != ChunkZ)
383  )
384  {
385  continue;
386  }
387  // Found it in the cache
388  int Idx = m_CacheOrder[i];
389 
390  // Move to front:
391  for (int j = i; j > 0; j--)
392  {
393  m_CacheOrder[j] = m_CacheOrder[j - 1];
394  }
395  m_CacheOrder[0] = Idx;
396 
397  // Use the cached data:
398  memcpy(a_ChunkDesc.GetBlockTypes(), m_CacheData[Idx].m_BlockTypes, sizeof(a_ChunkDesc.GetBlockTypes()));
399  memcpy(a_ChunkDesc.GetBlockMetasUncompressed(), m_CacheData[Idx].m_BlockMetas, sizeof(a_ChunkDesc.GetBlockMetasUncompressed()));
400  memcpy(a_ChunkDesc.GetHeightMap(), m_CacheData[Idx].m_HeightMap, sizeof(a_ChunkDesc.GetHeightMap()));
401 
402  m_NumHits++;
403  m_TotalChain += i;
404  return;
405  } // for i - cache
406 
407  // Not in the cache:
408  m_NumMisses++;
409  m_Underlying->ComposeTerrain(a_ChunkDesc, a_Shape);
410 
411  // Insert it as the first item in the MRU order:
412  int Idx = m_CacheOrder[m_CacheSize - 1];
413  for (int i = m_CacheSize - 1; i > 0; i--)
414  {
415  m_CacheOrder[i] = m_CacheOrder[i - 1];
416  } // for i - m_CacheOrder[]
417  m_CacheOrder[0] = Idx;
418  memcpy(m_CacheData[Idx].m_BlockTypes, a_ChunkDesc.GetBlockTypes(), sizeof(a_ChunkDesc.GetBlockTypes()));
419  memcpy(m_CacheData[Idx].m_BlockMetas, a_ChunkDesc.GetBlockMetasUncompressed(), sizeof(a_ChunkDesc.GetBlockMetasUncompressed()));
420  memcpy(m_CacheData[Idx].m_HeightMap, a_ChunkDesc.GetHeightMap(), sizeof(a_ChunkDesc.GetHeightMap()));
421  m_CacheData[Idx].m_ChunkX = ChunkX;
422  m_CacheData[Idx].m_ChunkZ = ChunkZ;
423 }
424 
425 
426 
427 
428 
430 {
431  m_Underlying->InitializeCompoGen(a_IniFile);
432 }
cItem GetIniItemSet(cIniFile &a_IniFile, const char *a_Section, const char *a_Key, const char *a_Default)
Returns a cItem representing the item described in an IniFile's value; if the value doesn't exist,...
Definition: BlockType.cpp:270
@ E_BLOCK_DIAMOND_BLOCK
Definition: BlockType.h:67
@ E_BLOCK_REDSTONE_ORE
Definition: BlockType.h:87
@ E_BLOCK_COAL_ORE
Definition: BlockType.h:26
@ E_BLOCK_DIAMOND_ORE
Definition: BlockType.h:66
@ E_BLOCK_BRICK
Definition: BlockType.h:55
@ E_BLOCK_AIR
Definition: BlockType.h:10
@ E_BLOCK_WOOL
Definition: BlockType.h:45
@ E_BLOCK_GOLD_BLOCK
Definition: BlockType.h:51
@ E_BLOCK_MOSSY_COBBLESTONE
Definition: BlockType.h:58
@ E_BLOCK_LAPIS_ORE
Definition: BlockType.h:31
@ E_BLOCK_IRON_BLOCK
Definition: BlockType.h:52
@ E_BLOCK_LAPIS_BLOCK
Definition: BlockType.h:32
@ E_BLOCK_GRASS
Definition: BlockType.h:12
@ E_BLOCK_BEDROCK
Definition: BlockType.h:17
@ E_BLOCK_OBSIDIAN
Definition: BlockType.h:59
@ E_BLOCK_SOULSAND
Definition: BlockType.h:103
@ E_BLOCK_IRON_ORE
Definition: BlockType.h:25
@ E_BLOCK_PLANKS
Definition: BlockType.h:15
@ E_BLOCK_SANDSTONE
Definition: BlockType.h:34
@ E_BLOCK_GOLD_ORE
Definition: BlockType.h:24
@ E_BLOCK_STONE
Definition: BlockType.h:11
@ E_BLOCK_DIRT
Definition: BlockType.h:13
@ E_BLOCK_NETHERRACK
Definition: BlockType.h:102
@ E_BLOCK_LOG
Definition: BlockType.h:27
@ E_BLOCK_SAND
Definition: BlockType.h:22
@ E_BLOCK_STATIONARY_WATER
Definition: BlockType.h:19
@ E_BLOCK_NETHER_BRICK
Definition: BlockType.h:127
@ E_BLOCK_COBBLESTONE
Definition: BlockType.h:14
unsigned char HEIGHTTYPE
The type used by the heightmap.
Definition: ChunkDef.h:47
unsigned char BLOCKTYPE
The datatype used by blockdata.
Definition: ChunkDef.h:41
@ INTERPOL_Z
Definition: EndGen.cpp:20
@ INTERPOL_X
Definition: EndGen.cpp:18
#define ARRAYCOUNT(X)
Evaluates to the number of elements in an array (compile-time!)
Definition: Globals.h:231
auto ToUnsigned(T a_Val)
Definition: Globals.h:387
#define ASSERT(x)
Definition: Globals.h:276
std::enable_if< std::is_arithmetic< T >::value, C >::type FloorC(T a_Value)
Floors a value, then casts it to C (an int by default).
Definition: Globals.h:347
float NOISE_DATATYPE
The datatype used by all the noise generators.
Definition: Noise.h:9
BlockType
Definition: BlockTypes.h:4
Definition: FastNBT.h:132
static const int Width
Definition: ChunkDef.h:124
HEIGHTTYPE GetHeight(int a_RelX, int a_RelZ) const
Definition: ChunkDesc.cpp:144
EMCSBiome GetBiome(int a_RelX, int a_RelZ) const
Definition: ChunkDesc.cpp:126
void SetBlockType(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType)
Definition: ChunkDesc.cpp:81
Byte Shape[256 *16 *16]
The datatype used to represent the entire chunk worth of shape.
Definition: ChunkDesc.h:36
int GetChunkX() const
Definition: ChunkDesc.h:49
cChunkDef::BlockTypes & GetBlockTypes(void)
Definition: ChunkDesc.h:235
cChunkDef::HeightMap & GetHeightMap(void)
Definition: ChunkDesc.h:239
BlockNibbleBytes & GetBlockMetasUncompressed(void)
Definition: ChunkDesc.h:238
void FillBlocks(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
Definition: ChunkDesc.cpp:54
int GetChunkZ() const
Definition: ChunkDesc.h:50
void SetHeightFromShape(const Shape &a_Shape)
Sets the heightmap to match the given shape data.
Definition: ChunkDesc.cpp:153
HEIGHTTYPE GetMaxHeight(void) const
Returns the maximum height value in the heightmap.
Definition: ChunkDesc.cpp:397
virtual void ComposeTerrain(cChunkDesc &a_ChunkDesc, const cChunkDesc::Shape &a_Shape) override
Generates the chunk's composition into a_ChunkDesc, using the terrain shape provided in a_Shape.
Definition: CompoGen.cpp:23
BLOCKTYPE m_BlockType
Definition: CompoGen.h:37
virtual void InitializeCompoGen(cIniFile &a_IniFile) override
Reads parameters from the ini file, prepares generator for use.
Definition: CompoGen.cpp:53
virtual void ComposeTerrain(cChunkDesc &a_ChunkDesc, const cChunkDesc::Shape &a_Shape) override
Generates the chunk's composition into a_ChunkDesc, using the terrain shape provided in a_Shape.
Definition: CompoGen.cpp:66
BLOCKTYPE m_BlockBeach
Definition: CompoGen.h:79
virtual void ComposeTerrain(cChunkDesc &a_ChunkDesc, const cChunkDesc::Shape &a_Shape) override
Generates the chunk's composition into a_ChunkDesc, using the terrain shape provided in a_Shape.
Definition: CompoGen.cpp:135
BLOCKTYPE m_BlockTop
Definition: CompoGen.h:76
BLOCKTYPE m_BlockBeachBottom
Definition: CompoGen.h:80
BLOCKTYPE m_BlockMiddle
Definition: CompoGen.h:77
BLOCKTYPE m_BlockSea
Definition: CompoGen.h:81
BLOCKTYPE m_BlockBottom
Definition: CompoGen.h:78
virtual void InitializeCompoGen(cIniFile &a_IniFile) override
Reads parameters from the ini file, prepares generator for use.
Definition: CompoGen.cpp:197
cCompoGenClassic(void)
Definition: CompoGen.cpp:118
cCompoGenNether(int a_Seed)
Definition: CompoGen.cpp:217
virtual void ComposeTerrain(cChunkDesc &a_ChunkDesc, const cChunkDesc::Shape &a_Shape) override
Generates the chunk's composition into a_ChunkDesc, using the terrain shape provided in a_Shape.
Definition: CompoGen.cpp:228
cNoise m_Noise2
Definition: CompoGen.h:100
cNoise m_Noise1
Definition: CompoGen.h:99
virtual void InitializeCompoGen(cIniFile &a_IniFile) override
Reads parameters from the ini file, prepares generator for use.
Definition: CompoGen.cpp:320
double m_MaxThreshold
Definition: CompoGen.h:102
sCacheData * m_CacheData
Definition: CompoGen.h:141
virtual ~cCompoGenCache() override
Definition: CompoGen.cpp:353
virtual void InitializeCompoGen(cIniFile &a_IniFile) override
Reads parameters from the ini file, prepares generator for use.
Definition: CompoGen.cpp:429
int * m_CacheOrder
Definition: CompoGen.h:140
virtual void ComposeTerrain(cChunkDesc &a_ChunkDesc, const cChunkDesc::Shape &a_Shape) override
Generates the chunk's composition into a_ChunkDesc, using the terrain shape provided in a_Shape.
Definition: CompoGen.cpp:365
cCompoGenCache(std::unique_ptr< cTerrainCompositionGen > a_Underlying, int a_CacheSize)
Definition: CompoGen.cpp:332
int m_TotalChain
Definition: CompoGen.h:146
std::unique_ptr< cTerrainCompositionGen > m_Underlying
Definition: CompoGen.h:127
cChunkDef::BlockTypes m_BlockTypes
Definition: CompoGen.h:133
cChunkDesc::BlockNibbleBytes m_BlockMetas
Definition: CompoGen.h:134
cChunkDef::HeightMap m_HeightMap
Definition: CompoGen.h:135
int GetValueSetI(const AString &keyname, const AString &valuename, const int defValue=0) override
Definition: IniFile.cpp:559
double GetValueSetF(const AString &keyname, const AString &valuename, const double defValue=0.0)
Definition: IniFile.cpp:549
short m_ItemType
Definition: Item.h:163
NOISE_DATATYPE CubicNoise2D(NOISE_DATATYPE a_X, NOISE_DATATYPE a_Y) const
Definition: Noise.cpp:593
int IntNoise3DInt(int a_X, int a_Y, int a_Z) const
Definition: Noise.h:254