Cuberite
A lightweight, fast and extensible game server for Minecraft
CompoGenBiomal.cpp
Go to the documentation of this file.
1 
2 // CompoGenBiomal.cpp
3 
4 // Implements the cCompoGenBiomal class representing the biome-aware composition generator
5 
6 #include "Globals.h"
7 
8 #include "CompoGenBiomal.h"
9 
10 #include "../IniFile.h"
11 #include "../Noise/Noise.h"
12 #include "../LinearUpscale.h"
13 
14 
15 
16 
17 
19 // cPattern:
20 
25 class cPattern
26 {
27 public:
28  struct BlockInfo
29  {
32  };
33 
34  constexpr cPattern(std::initializer_list<BlockInfo> a_TopBlocks)
35  {
36  ASSERT(a_TopBlocks.size() <= cChunkDef::Height);
37  // Copy the pattern into the top:
38  size_t i = 0;
39  for (const auto & Block : a_TopBlocks)
40  {
41  m_Pattern[i] = Block;
42  ++i;
43  }
44 
45  // The remaining blocks default to stone
46  }
47 
48  const BlockInfo * Get(void) const { return m_Pattern; }
49 
50 protected:
52 } ;
53 
54 
55 
56 
57 
59 // Land top block patterns:
60 
61 static constexpr cPattern patGrass =
62 {
63  {E_BLOCK_GRASS, 0},
67 } ;
68 
69 static constexpr cPattern patSand =
70 {
71  { E_BLOCK_SAND, 0},
72  { E_BLOCK_SAND, 0},
73  { E_BLOCK_SAND, 0},
74  { E_BLOCK_SANDSTONE, 0},
75 } ;
76 
77 static constexpr cPattern patDirt =
78 {
83 } ;
84 
85 static constexpr cPattern patPodzol =
86 {
91 } ;
92 
93 static constexpr cPattern patGrassLess =
94 {
99 } ;
100 
101 static constexpr cPattern patMycelium =
102 {
103  {E_BLOCK_MYCELIUM, 0},
104  {E_BLOCK_DIRT, 0},
105  {E_BLOCK_DIRT, 0},
106  {E_BLOCK_DIRT, 0},
107 } ;
108 
109 static constexpr cPattern patGravel =
110 {
111  {E_BLOCK_GRAVEL, 0},
112  {E_BLOCK_GRAVEL, 0},
113  {E_BLOCK_GRAVEL, 0},
114  {E_BLOCK_STONE, 0},
115 } ;
116 
117 static constexpr cPattern patStone =
118 {
119  {E_BLOCK_STONE, 0},
120  {E_BLOCK_STONE, 0},
121  {E_BLOCK_STONE, 0},
122  {E_BLOCK_STONE, 0},
123 } ;
124 
125 
126 
128 // Ocean floor patterns:
129 
130 static constexpr cPattern patOFSand =
131 {
132  {E_BLOCK_SAND, 0},
133  {E_BLOCK_SAND, 0},
134  {E_BLOCK_SAND, 0},
135  {E_BLOCK_SANDSTONE, 0}
136 } ;
137 
138 static constexpr cPattern patOFClay =
139 {
140  { E_BLOCK_CLAY, 0},
141  { E_BLOCK_CLAY, 0},
142  { E_BLOCK_SAND, 0},
143  { E_BLOCK_SAND, 0},
144 } ;
145 
146 static constexpr cPattern patOFOrangeClay =
147 {
151 } ;
152 
153 
154 
155 
156 
158 // cCompoGenBiomal:
159 
162 {
163 public:
164  cCompoGenBiomal(int a_Seed) :
165  m_SeaLevel(62),
166  m_OceanFloorSelect(a_Seed + 1),
167  m_MesaFloor(a_Seed + 2)
168  {
169  initMesaPattern(a_Seed);
170  }
171 
172 protected:
175 
178 
181 
184 
185 
186  // cTerrainCompositionGen overrides:
187  virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) override
188  {
189  a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0);
190  for (int z = 0; z < cChunkDef::Width; z++)
191  {
192  for (int x = 0; x < cChunkDef::Width; x++)
193  {
194  ComposeColumn(a_ChunkDesc, x, z, &(a_Shape[x * 256 + z * 16 * 256]));
195  } // for x
196  } // for z
197  }
198 
199 
200 
201  virtual void InitializeCompoGen(cIniFile & a_IniFile) override
202  {
203  m_SeaLevel = static_cast<HEIGHTTYPE>(a_IniFile.GetValueSetI("Generator", "SeaLevel", m_SeaLevel));
204  }
205 
206 
207 
209  void initMesaPattern(int a_Seed)
210  {
211  // In a loop, choose whether to use one, two or three layers of stained clay, then choose a color and width for each layer
212  // Separate each group with another layer of hardened clay
213  cNoise patternNoise(a_Seed);
214  static NIBBLETYPE allowedColors[] =
215  {
231  } ;
232  static int layerSizes[] = // Adjust the chance so that thinner layers occur more commonly
233  {
234  1, 1, 1, 1, 1, 1,
235  2, 2, 2, 2,
236  3, 3,
237  } ;
238  int idx = ARRAYCOUNT(m_MesaPattern) - 1;
239  while (idx >= 0)
240  {
241  // A layer group of 1 - 2 color stained clay:
242  int rnd = patternNoise.IntNoise1DInt(idx) / 7;
243  int numLayers = (rnd % 2) + 1;
244  rnd /= 2;
245  for (int lay = 0; lay < numLayers; lay++)
246  {
247  int numBlocks = layerSizes[(static_cast<size_t>(rnd) % ARRAYCOUNT(layerSizes))];
248  NIBBLETYPE Color = allowedColors[static_cast<size_t>(rnd / 4) % ARRAYCOUNT(allowedColors)];
249  if (
250  ((numBlocks == 3) && (numLayers == 2)) || // In two-layer mode disallow the 3-high layers:
251  (Color == E_META_STAINED_CLAY_WHITE)) // White stained clay can ever be only 1 block high
252  {
253  numBlocks = 1;
254  }
255  numBlocks = std::min(idx + 1, numBlocks); // Limit by idx so that we don't have to check inside the loop
256  rnd /= 32;
257  for (int block = 0; block < numBlocks; block++, idx--)
258  {
259  m_MesaPattern[idx].m_BlockMeta = Color;
261  } // for block
262  } // for lay
263 
264  // A layer of hardened clay in between the layer group:
265  int numBlocks = (rnd % 4) + 1; // All heights the same probability
266  if ((numLayers == 2) && (numBlocks < 4))
267  {
268  // For two layers of stained clay, add an extra block of hardened clay:
269  numBlocks++;
270  }
271  numBlocks = std::min(idx + 1, numBlocks); // Limit by idx so that we don't have to check inside the loop
272  for (int block = 0; block < numBlocks; block++, idx--)
273  {
274  m_MesaPattern[idx].m_BlockMeta = 0;
276  } // for block
277  } // while (idx >= 0)
278  }
279 
280 
281 
283  void ComposeColumn(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ, const Byte * a_ShapeColumn)
284  {
285  // Frequencies for the podzol floor selecting noise:
286  const NOISE_DATATYPE FrequencyX = 8;
287  const NOISE_DATATYPE FrequencyZ = 8;
288 
289  EMCSBiome Biome = a_ChunkDesc.GetBiome(a_RelX, a_RelZ);
290  switch (Biome)
291  {
292  case biOcean:
293  case biPlains:
294  case biForest:
295  case biTaiga:
296  case biSwampland:
297  case biRiver:
298  case biFrozenOcean:
299  case biFrozenRiver:
300  case biIcePlains:
301  case biIceMountains:
302  case biForestHills:
303  case biTaigaHills:
304  case biExtremeHillsEdge:
305  case biExtremeHillsPlus:
306  case biExtremeHills:
307  case biJungle:
308  case biJungleHills:
309  case biJungleEdge:
310  case biDeepOcean:
311  case biStoneBeach:
312  case biColdBeach:
313  case biBirchForest:
314  case biBirchForestHills:
315  case biRoofedForest:
316  case biColdTaiga:
317  case biColdTaigaHills:
318  case biSavanna:
319  case biSavannaPlateau:
320  case biSunflowerPlains:
321  case biFlowerForest:
322  case biTaigaM:
323  case biSwamplandM:
324  case biIcePlainsSpikes:
325  case biJungleM:
326  case biJungleEdgeM:
327  case biBirchForestM:
328  case biBirchForestHillsM:
329  case biRoofedForestM:
330  case biColdTaigaM:
331  case biSavannaM:
332  case biSavannaPlateauM:
333  {
334  FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patGrass.Get(), a_ShapeColumn);
335  return;
336  }
337 
338  case biMegaTaiga:
339  case biMegaTaigaHills:
340  case biMegaSpruceTaiga:
342  {
343  // Select the pattern to use - podzol, grass or grassless dirt:
344  NOISE_DATATYPE NoiseX = (static_cast<NOISE_DATATYPE>(a_ChunkDesc.GetChunkX() * cChunkDef::Width + a_RelX)) / FrequencyX;
345  NOISE_DATATYPE NoiseY = (static_cast<NOISE_DATATYPE>(a_ChunkDesc.GetChunkZ() * cChunkDef::Width + a_RelZ)) / FrequencyZ;
346  NOISE_DATATYPE Val = m_OceanFloorSelect.CubicNoise2D(NoiseX, NoiseY);
347  const cPattern::BlockInfo * Pattern = (Val < -0.9) ? patGrassLess.Get() : ((Val > 0) ? patPodzol.Get() : patGrass.Get());
348  FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, Pattern, a_ShapeColumn);
349  return;
350  }
351 
352  case biDesertHills:
353  case biDesert:
354  case biDesertM:
355  case biBeach:
356  {
357  FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patSand.Get(), a_ShapeColumn);
358  return;
359  }
360 
361  case biMushroomIsland:
362  case biMushroomShore:
363  {
364  FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patMycelium.Get(), a_ShapeColumn);
365  return;
366  }
367 
368  case biMesa:
369  case biMesaPlateauF:
370  case biMesaPlateau:
371  case biMesaBryce:
372  case biMesaPlateauFM:
373  case biMesaPlateauM:
374  {
375  // Mesa biomes need special handling, because they don't follow the usual "4 blocks from top pattern",
376  // instead, they provide a "from bottom" pattern with varying base height,
377  // usually 4 blocks below the ocean level
378  FillColumnMesa(a_ChunkDesc, a_RelX, a_RelZ, a_ShapeColumn);
379  return;
380  }
381 
382  case biExtremeHillsPlusM:
383  case biExtremeHillsM:
384  {
385  // Select the pattern to use - gravel, stone or grass:
386  NOISE_DATATYPE NoiseX = (static_cast<NOISE_DATATYPE>(a_ChunkDesc.GetChunkX() * cChunkDef::Width + a_RelX)) / FrequencyX;
387  NOISE_DATATYPE NoiseY = (static_cast<NOISE_DATATYPE>(a_ChunkDesc.GetChunkZ() * cChunkDef::Width + a_RelZ)) / FrequencyZ;
388  NOISE_DATATYPE Val = m_OceanFloorSelect.CubicNoise2D(NoiseX, NoiseY);
389  const cPattern::BlockInfo * Pattern = (Val < 0.0) ? patStone.Get() : patGrass.Get();
390  FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, Pattern, a_ShapeColumn);
391  return;
392  }
393  case biInvalidBiome:
394  case biNether:
395  case biEnd:
396  case biNumBiomes:
397  case biVariant:
398  case biNumVariantBiomes:
399  {
400  // This generator is not supposed to be used for these biomes, but it has to produce *something*
401  // so let's produce stone:
402  FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patStone.Get(), a_ShapeColumn);
403  return;
404  }
405  } // switch (Biome)
406  }
407 
408 
409 
412  void FillColumnPattern(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ, const cPattern::BlockInfo * a_Pattern, const Byte * a_ShapeColumn)
413  {
414  bool HasHadWater = false;
415  int PatternIdx = 0;
416  HEIGHTTYPE top = a_ChunkDesc.GetHeight(a_RelX, a_RelZ);
417  if (top < m_SeaLevel)
418  {
419  top = m_SeaLevel;
420  a_ChunkDesc.SetHeight(a_RelX, a_RelZ, top - 1);
421  }
422  for (int y = top; y > 0; y--)
423  {
424  if (a_ShapeColumn[y] > 0)
425  {
426  // "ground" part, use the pattern:
427  a_ChunkDesc.SetBlockTypeMeta(a_RelX, y, a_RelZ, a_Pattern[PatternIdx].m_BlockType, a_Pattern[PatternIdx].m_BlockMeta);
428  PatternIdx++;
429  continue;
430  }
431 
432  // "air" or "water" part:
433  // Reset the pattern index to zero, so that the pattern is repeated from the top again:
434  PatternIdx = 0;
435 
436  if (y >= m_SeaLevel)
437  {
438  // "air" part, do nothing
439  continue;
440  }
441 
442  a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STATIONARY_WATER);
443  if (HasHadWater)
444  {
445  continue;
446  }
447 
448  // Select the ocean-floor pattern to use:
449  if (a_ChunkDesc.GetBiome(a_RelX, a_RelZ) == biDeepOcean)
450  {
451  a_Pattern = patGravel.Get();
452  }
453  else
454  {
455  a_Pattern = ChooseOceanFloorPattern(a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ(), a_RelX, a_RelZ);
456  }
457  HasHadWater = true;
458  } // for y
459  a_ChunkDesc.SetBlockType(a_RelX, 0, a_RelZ, E_BLOCK_BEDROCK);
460  }
461 
462 
463 
465  void FillColumnMesa(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ, const Byte * a_ShapeColumn)
466  {
467  // Frequencies for the clay floor noise:
468  const NOISE_DATATYPE FrequencyX = 50;
469  const NOISE_DATATYPE FrequencyZ = 50;
470 
471  int Top = a_ChunkDesc.GetHeight(a_RelX, a_RelZ);
472  if (Top < m_SeaLevel)
473  {
474  // The terrain is below sealevel, handle as regular ocean with red sand floor:
475  FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patOFOrangeClay.Get(), a_ShapeColumn);
476  return;
477  }
478 
479  NOISE_DATATYPE NoiseX = (static_cast<NOISE_DATATYPE>(a_ChunkDesc.GetChunkX() * cChunkDef::Width + a_RelX)) / FrequencyX;
480  NOISE_DATATYPE NoiseY = (static_cast<NOISE_DATATYPE>(a_ChunkDesc.GetChunkZ() * cChunkDef::Width + a_RelZ)) / FrequencyZ;
481  int ClayFloor = m_SeaLevel - 6 + static_cast<int>(4.f * m_MesaFloor.CubicNoise2D(NoiseX, NoiseY));
482  if (ClayFloor >= Top)
483  {
484  ClayFloor = Top - 1;
485  }
486 
487  if (Top - m_SeaLevel < 5)
488  {
489  // Simple case: top is red sand, then hardened clay down to ClayFloor, then stone:
490  a_ChunkDesc.SetBlockTypeMeta(a_RelX, Top, a_RelZ, E_BLOCK_SAND, E_META_SAND_RED);
491  for (int y = Top - 1; y >= ClayFloor; y--)
492  {
493  a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_HARDENED_CLAY);
494  }
495  for (int y = ClayFloor - 1; y > 0; y--)
496  {
497  a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STONE);
498  }
499  a_ChunkDesc.SetBlockType(a_RelX, 0, a_RelZ, E_BLOCK_BEDROCK);
500  return;
501  }
502 
503  // Difficult case: use the mesa pattern and watch for overhangs:
504  int PatternIdx = cChunkDef::Height - (Top - ClayFloor); // We want the block at index ClayFloor to be pattern's 256th block (first stone)
505  const cPattern::BlockInfo * Pattern = m_MesaPattern;
506  bool HasHadWater = false;
507  for (int y = Top; y > 0; y--)
508  {
509  if (a_ShapeColumn[y] > 0)
510  {
511  // "ground" part, use the pattern:
512  a_ChunkDesc.SetBlockTypeMeta(a_RelX, y, a_RelZ, Pattern[PatternIdx].m_BlockType, Pattern[PatternIdx].m_BlockMeta);
513  PatternIdx++;
514  continue;
515  }
516 
517  if (y >= m_SeaLevel)
518  {
519  // "air" part, do nothing
520  continue;
521  }
522 
523  // "water" part, fill with water and choose new pattern for ocean floor, if not chosen already:
524  PatternIdx = 0;
525  a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STATIONARY_WATER);
526  if (HasHadWater)
527  {
528  continue;
529  }
530 
531  // Select the ocean-floor pattern to use:
532  Pattern = ChooseOceanFloorPattern(a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ(), a_RelX, a_RelZ);
533  HasHadWater = true;
534  } // for y
535  a_ChunkDesc.SetBlockType(a_RelX, 0, a_RelZ, E_BLOCK_BEDROCK);
536 
537  EMCSBiome MesaVersion = a_ChunkDesc.GetBiome(a_RelX, a_RelZ);
538  if ((MesaVersion == biMesaPlateauF) || (MesaVersion == biMesaPlateauFM))
539  {
540  if (Top < 95 + static_cast<int>(m_MesaFloor.CubicNoise2D(NoiseY * 2, NoiseX * 2) * 6))
541  {
542  return;
543  }
544 
545  BLOCKTYPE Block = (m_MesaFloor.CubicNoise2D(NoiseX * 4, NoiseY * 4) < 0) ? E_BLOCK_DIRT : E_BLOCK_GRASS;
546  NIBBLETYPE Meta = (Block == E_BLOCK_GRASS) ? 0 : 1;
547 
548  a_ChunkDesc.SetBlockTypeMeta(a_RelX, Top, a_RelZ, Block, Meta);
549  }
550  }
551 
552 
553 
556  const cPattern::BlockInfo * ChooseOceanFloorPattern(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelZ)
557  {
558  // Frequencies for the ocean floor selecting noise:
559  const NOISE_DATATYPE FrequencyX = 3;
560  const NOISE_DATATYPE FrequencyZ = 3;
561 
562  // Select the ocean-floor pattern to use:
563  NOISE_DATATYPE NoiseX = (static_cast<NOISE_DATATYPE>(a_ChunkX * cChunkDef::Width + a_RelX)) / FrequencyX;
564  NOISE_DATATYPE NoiseY = (static_cast<NOISE_DATATYPE>(a_ChunkZ * cChunkDef::Width + a_RelZ)) / FrequencyZ;
565  NOISE_DATATYPE Val = m_OceanFloorSelect.CubicNoise2D(NoiseX, NoiseY);
566  if (Val < -0.95)
567  {
568  return patOFClay.Get();
569  }
570  else if (Val < 0)
571  {
572  return patOFSand.Get();
573  }
574  else
575  {
576  return patDirt.Get();
577  }
578  }
579 } ;
580 
581 
582 
583 
584 
585 std::unique_ptr<cTerrainCompositionGen> CreateCompoGenBiomal(int a_Seed)
586 {
587  return std::make_unique<cCompoGenBiomal>(a_Seed);
588 }
EMCSBiome
Biome IDs The first batch corresponds to the clientside biomes, used by MineCraft.
Definition: BiomeDef.h:18
@ biJungleEdge
Definition: BiomeDef.h:50
@ biIceMountains
Definition: BiomeDef.h:38
@ biMesa
Definition: BiomeDef.h:64
@ biMesaPlateau
Definition: BiomeDef.h:66
@ biExtremeHillsM
Definition: BiomeDef.h:79
@ biForestHills
Definition: BiomeDef.h:43
@ biNether
Definition: BiomeDef.h:31
@ biBirchForest
Definition: BiomeDef.h:54
@ biBirchForestM
Definition: BiomeDef.h:86
@ biDesert
Definition: BiomeDef.h:24
@ biMesaPlateauF
Definition: BiomeDef.h:65
@ biSunflowerPlains
Definition: BiomeDef.h:77
@ biExtremeHillsPlusM
Definition: BiomeDef.h:92
@ biColdTaigaHills
Definition: BiomeDef.h:58
@ biFlowerForest
Definition: BiomeDef.h:80
@ biInvalidBiome
Definition: BiomeDef.h:19
@ biMegaSpruceTaiga
Definition: BiomeDef.h:90
@ biStoneBeach
Definition: BiomeDef.h:52
@ biMushroomShore
Definition: BiomeDef.h:40
@ biSavanna
Definition: BiomeDef.h:62
@ biTaigaHills
Definition: BiomeDef.h:44
@ biExtremeHillsPlus
Definition: BiomeDef.h:61
@ biJungle
Definition: BiomeDef.h:46
@ biMegaTaiga
Definition: BiomeDef.h:59
@ biJungleHills
Definition: BiomeDef.h:47
@ biOcean
Definition: BiomeDef.h:22
@ biDesertHills
Definition: BiomeDef.h:42
@ biBeach
Definition: BiomeDef.h:41
@ biForest
Definition: BiomeDef.h:26
@ biJungleEdgeM
Definition: BiomeDef.h:85
@ biTaigaM
Definition: BiomeDef.h:81
@ biBirchForestHillsM
Definition: BiomeDef.h:87
@ biJungleM
Definition: BiomeDef.h:84
@ biExtremeHillsEdge
Definition: BiomeDef.h:45
@ biNumVariantBiomes
Definition: BiomeDef.h:99
@ biFrozenRiver
Definition: BiomeDef.h:35
@ biRiver
Definition: BiomeDef.h:29
@ biMesaPlateauFM
Definition: BiomeDef.h:96
@ biMushroomIsland
Definition: BiomeDef.h:39
@ biDeepOcean
Definition: BiomeDef.h:51
@ biSavannaPlateauM
Definition: BiomeDef.h:94
@ biMesaBryce
Definition: BiomeDef.h:95
@ biPlains
Definition: BiomeDef.h:23
@ biRoofedForestM
Definition: BiomeDef.h:88
@ biBirchForestHills
Definition: BiomeDef.h:55
@ biColdBeach
Definition: BiomeDef.h:53
@ biMegaSpruceTaigaHills
Definition: BiomeDef.h:91
@ biSavannaM
Definition: BiomeDef.h:93
@ biSwamplandM
Definition: BiomeDef.h:82
@ biVariant
Definition: BiomeDef.h:73
@ biEnd
Definition: BiomeDef.h:33
@ biIcePlainsSpikes
Definition: BiomeDef.h:83
@ biFrozenOcean
Definition: BiomeDef.h:34
@ biExtremeHills
Definition: BiomeDef.h:25
@ biColdTaiga
Definition: BiomeDef.h:57
@ biMegaTaigaHills
Definition: BiomeDef.h:60
@ biNumBiomes
Definition: BiomeDef.h:69
@ biRoofedForest
Definition: BiomeDef.h:56
@ biIcePlains
Definition: BiomeDef.h:36
@ biTaiga
Definition: BiomeDef.h:27
@ biDesertM
Definition: BiomeDef.h:78
@ biSavannaPlateau
Definition: BiomeDef.h:63
@ biMesaPlateauM
Definition: BiomeDef.h:97
@ biColdTaigaM
Definition: BiomeDef.h:89
@ biSwampland
Definition: BiomeDef.h:28
@ E_META_STAINED_CLAY_RED
Definition: BlockType.h:858
@ E_META_DIRT_NORMAL
Definition: BlockType.h:639
@ E_META_DIRT_PODZOL
Definition: BlockType.h:642
@ E_META_STAINED_CLAY_WHITE
Definition: BlockType.h:844
@ E_META_STAINED_CLAY_BROWN
Definition: BlockType.h:856
@ E_META_STAINED_CLAY_LIGHTGRAY
Definition: BlockType.h:852
@ E_META_DIRT_GRASSLESS
Definition: BlockType.h:640
@ E_META_SAND_RED
Definition: BlockType.h:806
@ E_META_STAINED_CLAY_YELLOW
Definition: BlockType.h:848
@ E_META_STAINED_GLASS_ORANGE
Definition: BlockType.h:863
@ E_META_STAINED_CLAY_ORANGE
Definition: BlockType.h:845
@ E_BLOCK_CLAY
Definition: BlockType.h:96
@ E_BLOCK_AIR
Definition: BlockType.h:10
@ E_BLOCK_GRASS
Definition: BlockType.h:12
@ E_BLOCK_BEDROCK
Definition: BlockType.h:17
@ E_BLOCK_MYCELIUM
Definition: BlockType.h:125
@ E_BLOCK_GRAVEL
Definition: BlockType.h:23
@ E_BLOCK_STAINED_CLAY
Definition: BlockType.h:177
@ E_BLOCK_HARDENED_CLAY
Definition: BlockType.h:191
@ E_BLOCK_SANDSTONE
Definition: BlockType.h:34
@ E_BLOCK_STONE
Definition: BlockType.h:11
@ E_BLOCK_DIRT
Definition: BlockType.h:13
@ E_BLOCK_SAND
Definition: BlockType.h:22
@ E_BLOCK_STATIONARY_WATER
Definition: BlockType.h:19
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
Definition: ChunkDef.h:44
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
std::unique_ptr< cTerrainCompositionGen > CreateCompoGenBiomal(int a_Seed)
Returns a new instance of the Biomal composition generator.
static constexpr cPattern patSand
static constexpr cPattern patGrass
static constexpr cPattern patGrassLess
static constexpr cPattern patOFOrangeClay
static constexpr cPattern patStone
static constexpr cPattern patPodzol
static constexpr cPattern patOFClay
static constexpr cPattern patDirt
static constexpr cPattern patOFSand
static constexpr cPattern patGravel
static constexpr cPattern patMycelium
#define ARRAYCOUNT(X)
Evaluates to the number of elements in an array (compile-time!)
Definition: Globals.h:231
#define ASSERT(x)
Definition: Globals.h:276
unsigned char Byte
Definition: Globals.h:161
float NOISE_DATATYPE
The datatype used by all the noise generators.
Definition: Noise.h:9
static const int Width
Definition: ChunkDef.h:124
static const int Height
Definition: ChunkDef.h:125
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
void SetHeight(int a_RelX, int a_RelZ, HEIGHTTYPE a_Height)
Definition: ChunkDesc.cpp:135
void SetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
Definition: ChunkDesc.cpp:63
void FillBlocks(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
Definition: ChunkDesc.cpp:54
int GetChunkZ() const
Definition: ChunkDesc.h:50
This class is used to store a column pattern initialized at runtime, so that the program doesn't need...
constexpr cPattern(std::initializer_list< BlockInfo > a_TopBlocks)
BlockInfo m_Pattern[cChunkDef::Height]
const BlockInfo * Get(void) const
cPattern::BlockInfo m_MesaPattern[2 *cChunkDef::Height]
The pattern used for mesa biomes.
const cPattern::BlockInfo * ChooseOceanFloorPattern(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelZ)
Returns the pattern to use for an ocean floor in the specified column.
cNoise m_OceanFloorSelect
Noise used for selecting between dirt and sand on the ocean floor.
void FillColumnPattern(cChunkDesc &a_ChunkDesc, int a_RelX, int a_RelZ, const cPattern::BlockInfo *a_Pattern, const Byte *a_ShapeColumn)
Fills the specified column with the specified pattern; restarts the pattern when air is reached,...
HEIGHTTYPE m_SeaLevel
The block height at which water is generated instead of air.
cCompoGenBiomal(int a_Seed)
void initMesaPattern(int a_Seed)
Initializes the m_MesaPattern with a pattern based on the generator's seed.
virtual void InitializeCompoGen(cIniFile &a_IniFile) override
Reads parameters from the ini file, prepares generator for use.
void FillColumnMesa(cChunkDesc &a_ChunkDesc, int a_RelX, int a_RelZ, const Byte *a_ShapeColumn)
Fills the specified column with mesa pattern, based on the column height.
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.
cNoise m_MesaFloor
Noise used for the floor of the clay blocks in mesa biomes.
void ComposeColumn(cChunkDesc &a_ChunkDesc, int a_RelX, int a_RelZ, const Byte *a_ShapeColumn)
Composes a single column in a_ChunkDesc.
The interface that a terrain composition generator must implement Terrain composition takes chunk coo...
int GetValueSetI(const AString &keyname, const AString &valuename, const int defValue=0) override
Definition: IniFile.cpp:559
Definition: Noise.h:20
int IntNoise1DInt(int a_X) const
Definition: Noise.h:233
NOISE_DATATYPE CubicNoise2D(NOISE_DATATYPE a_X, NOISE_DATATYPE a_Y) const
Definition: Noise.cpp:593