Cuberite
A lightweight, fast and extensible game server for Minecraft
StructGen.cpp
Go to the documentation of this file.
1 
2 // StructGen.h
3 
4 #include "Globals.h"
5 #include "StructGen.h"
6 #include "Trees.h"
7 #include "../BlockArea.h"
8 #include "../LinearUpscale.h"
9 #include "../BlockInfo.h"
10 
11 
12 
13 
14 
16 // cStructGenTrees:
17 
19 {
20  int ChunkX = a_ChunkDesc.GetChunkX();
21  int ChunkZ = a_ChunkDesc.GetChunkZ();
22 
23  cChunkDesc WorkerDesc({ChunkX, ChunkZ});
24 
25  // Generate trees:
26  for (int x = 0; x <= 2; x++)
27  {
28  int BaseX = ChunkX + x - 1;
29  for (int z = 0; z <= 2; z++)
30  {
31  int BaseZ = ChunkZ + z - 1;
32 
33  cChunkDesc * Dest;
34 
35  if ((x != 1) || (z != 1))
36  {
37  Dest = &WorkerDesc;
38  WorkerDesc.SetChunkCoords({BaseX, BaseZ});
39 
40  // TODO: This may cause a lot of wasted calculations, instead of pulling data out of a single (cChunkDesc) cache
41 
42  cChunkDesc::Shape workerShape;
43  m_BiomeGen.GenBiomes ({BaseX, BaseZ}, WorkerDesc.GetBiomeMap());
44  m_ShapeGen.GenShape ({BaseX, BaseZ}, workerShape);
45  WorkerDesc.SetHeightFromShape (workerShape);
46  m_CompositionGen.ComposeTerrain(WorkerDesc, workerShape);
47  }
48  else
49  {
50  Dest = &a_ChunkDesc;
51  }
52 
53  double NumTrees = GetNumTrees(BaseX, BaseZ, Dest->GetBiomeMap());
54 
55  sSetBlockVector OutsideLogs, OutsideOther;
56  if (NumTrees < 1)
57  {
58  Vector3i Pos;
59  Pos.x = (m_Noise.IntNoise3DInt(BaseX + BaseZ, BaseZ, 0) / 19) % cChunkDef::Width;
60  Pos.z = (m_Noise.IntNoise3DInt(BaseX - BaseZ, 0, BaseZ) / 19) % cChunkDef::Width;
61  Pos.y = Dest->GetHeight(Pos.x, Pos.z);
62 
63  if (std::abs(m_Noise.IntNoise3D(BaseX * cChunkDef::Width + Pos.x, Pos.y, BaseZ * cChunkDef::Width + Pos.z)) <= NumTrees)
64  {
65  GenerateSingleTree(BaseX, BaseZ, 0, Pos, *Dest, OutsideLogs, OutsideOther);
66  }
67  }
68  else
69  {
70  for (int i = 0; i < NumTrees; i++)
71  {
72  Vector3i Pos;
73  Pos.x = (m_Noise.IntNoise3DInt(BaseX + BaseZ, BaseZ, i) / 19) % cChunkDef::Width;
74  Pos.z = (m_Noise.IntNoise3DInt(BaseX - BaseZ, i, BaseZ) / 19) % cChunkDef::Width;
75  Pos.y = Dest->GetHeight(Pos.x, Pos.z);
76 
77  GenerateSingleTree(BaseX, BaseZ, i, Pos, *Dest, OutsideLogs, OutsideOther);
78  }
79  }
80  sSetBlockVector IgnoredOverflow;
81  IgnoredOverflow.reserve(OutsideOther.size());
82  ApplyTreeImage(ChunkX, ChunkZ, a_ChunkDesc, OutsideOther, IgnoredOverflow);
83  IgnoredOverflow.clear();
84  IgnoredOverflow.reserve(OutsideLogs.size());
85  ApplyTreeImage(ChunkX, ChunkZ, a_ChunkDesc, OutsideLogs, IgnoredOverflow);
86  } // for z
87  } // for x
88 
89  a_ChunkDesc.UpdateHeightmap();
90 }
91 
92 
93 
94 
95 
97  int a_ChunkX, int a_ChunkZ, int a_Seq,
98  Vector3i a_Pos,
99  cChunkDesc & a_ChunkDesc,
100  sSetBlockVector & a_OutsideLogs,
101  sSetBlockVector & a_OutsideOther
102 )
103 {
104  if ((a_Pos.y <= 0) || (a_Pos.y >= 230))
105  {
106  return;
107  }
108 
109  // Check the block underneath the tree:
110  BLOCKTYPE TopBlock = a_ChunkDesc.GetBlockType(a_Pos.x, a_Pos.y, a_Pos.z);
111  if ((TopBlock != E_BLOCK_DIRT) && (TopBlock != E_BLOCK_GRASS) && (TopBlock != E_BLOCK_FARMLAND) && (TopBlock != E_BLOCK_MYCELIUM))
112  {
113  return;
114  }
115 
116  sSetBlockVector TreeLogs, TreeOther;
118  { a_ChunkX * cChunkDef::Width + a_Pos.x, a_Pos.y + 1, a_ChunkZ * cChunkDef::Width + a_Pos.z },
119  m_Noise, a_Seq,
120  a_ChunkDesc.GetBiome(a_Pos.x, a_Pos.z),
121  TreeLogs, TreeOther
122  );
123 
124  // Check if the generated image fits the terrain. Only the logs are checked:
125  for (sSetBlockVector::const_iterator itr = TreeLogs.begin(); itr != TreeLogs.end(); ++itr)
126  {
127  if ((itr->m_ChunkX != a_ChunkX) || (itr->m_ChunkZ != a_ChunkZ))
128  {
129  // Outside the chunk
130  continue;
131  }
132  if (itr->m_RelY >= cChunkDef::Height)
133  {
134  // Above the chunk, cut off (this shouldn't happen too often, we're limiting trees to y < 230)
135  continue;
136  }
137 
138  BLOCKTYPE Block = a_ChunkDesc.GetBlockType(itr->m_RelX, itr->m_RelY, itr->m_RelZ);
139  switch (Block)
140  {
142  {
143  break;
144  }
145  default:
146  {
147  // There's something in the way, abort this tree altogether
148  return;
149  }
150  }
151  }
152 
153  ApplyTreeImage(a_ChunkX, a_ChunkZ, a_ChunkDesc, TreeOther, a_OutsideOther);
154  ApplyTreeImage(a_ChunkX, a_ChunkZ, a_ChunkDesc, TreeLogs, a_OutsideLogs);
155 }
156 
157 
158 
159 
160 
162  int a_ChunkX, int a_ChunkZ,
163  cChunkDesc & a_ChunkDesc,
164  const sSetBlockVector & a_Image,
165  sSetBlockVector & a_Overflow
166 )
167 {
168  // Put the generated image into a_BlockTypes, push things outside this chunk into a_Blocks
169  for (sSetBlockVector::const_iterator itr = a_Image.begin(), end = a_Image.end(); itr != end; ++itr)
170  {
171  if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkZ == a_ChunkZ) && (itr->m_RelY < cChunkDef::Height))
172  {
173  // Inside this chunk, integrate into a_ChunkDesc:
174  switch (a_ChunkDesc.GetBlockType(itr->m_RelX, itr->m_RelY, itr->m_RelZ))
175  {
176  case E_BLOCK_NEW_LEAVES:
177  case E_BLOCK_LEAVES:
180  {
181  if ((itr->m_BlockType != E_BLOCK_LOG) && (itr->m_BlockType != E_BLOCK_NEW_LOG))
182  {
183  break;
184  }
185  // fallthrough:
186  }
188  {
189  a_ChunkDesc.SetBlockTypeMeta(itr->m_RelX, itr->m_RelY, itr->m_RelZ, itr->m_BlockType, itr->m_BlockMeta);
190  // If grass is below our tree, turn it to dirt
191  if (
192  (cBlockInfo::IsSolid(itr->m_BlockType)) &&
193  (a_ChunkDesc.GetBlockType(itr->m_RelX, itr->m_RelY - 1, itr->m_RelZ) == E_BLOCK_GRASS)
194  )
195  {
196  a_ChunkDesc.SetBlockType(itr->m_RelX, itr->m_RelY - 1, itr->m_RelZ, E_BLOCK_DIRT);
197  }
198  break;
199  }
200 
201  } // switch (GetBlock())
202  continue;
203  }
204 
205  // Outside the chunk, push into a_Overflow.
206  // Don't check if already present there, by separating logs and others we don't need the checks anymore:
207  a_Overflow.push_back(*itr);
208  }
209 }
210 
211 
212 
213 
214 
216  int a_ChunkX, int a_ChunkZ,
217  const cChunkDef::BiomeMap & a_Biomes
218 )
219 {
220  auto BiomeTrees = [](EMCSBiome a_Biome)
221  {
222  switch (a_Biome)
223  {
224  case biOcean: return 2.0;
225  case biPlains: return 0.03125;
226  case biDesert: return 0.0;
227  case biExtremeHills: return 3.0;
228  case biForest: return 30.0;
229  case biTaiga: return 30.0;
230  case biSwampland: return 8.0;
231  case biRiver: return 0.0;
232  case biNether: return 0.0;
233  case biEnd: return 0.0;
234  case biFrozenOcean: return 0.0;
235  case biFrozenRiver: return 0.0;
236  case biIcePlains: return 0.03125;
237  case biIceMountains: return 0.125;
238  case biMushroomIsland: return 3.0;
239  case biMushroomShore: return 3.0;
240  case biBeach: return 0.0;
241  case biDesertHills: return 0.0;
242  case biForestHills: return 20.0;
243  case biTaigaHills: return 20.0;
244  case biExtremeHillsEdge: return 5.0;
245  case biJungle: return 120.0;
246  case biJungleHills: return 90.0;
247  case biJungleEdge: return 90.0;
248  case biDeepOcean: return 0.0;
249  case biStoneBeach: return 0.0;
250  case biColdBeach: return 0.0;
251  case biBirchForest: return 30.0;
252  case biBirchForestHills: return 20.0;
253  case biRoofedForest: return 50.0;
254  case biColdTaiga: return 20.0;
255  case biColdTaigaHills: return 15.0;
256  case biMegaTaiga: return 15.0;
257  case biMegaTaigaHills: return 15.0;
258  case biExtremeHillsPlus: return 3.0;
259  case biSavanna: return 8.0;
260  case biSavannaPlateau: return 12.0;
261  case biMesa: return 2.0;
262  case biMesaPlateauF: return 8.0;
263  case biMesaPlateau: return 8.0;
264  // Biome variants
265  case biSunflowerPlains: return 0.03125;
266  case biDesertM: return 0.0;
267  case biExtremeHillsM: return 4.0;
268  case biFlowerForest: return 2.0;
269  case biTaigaM: return 30.0;
270  case biSwamplandM: return 8.0;
271  case biIcePlainsSpikes: return 0.0078125;
272  case biJungleM: return 120.0;
273  case biJungleEdgeM: return 90.0;
274  case biBirchForestM: return 30.0;
275  case biBirchForestHillsM: return 20.0;
276  case biRoofedForestM: return 40.0;
277  case biColdTaigaM: return 30.0;
278  case biMegaSpruceTaiga: return 15.0;
279  case biMegaSpruceTaigaHills: return 15.0;
280  case biExtremeHillsPlusM: return 4.0;
281  case biSavannaM: return 8.0;
282  case biSavannaPlateauM: return 12.0;
283  case biMesaBryce: return 4.0;
284  case biMesaPlateauFM: return 12.0;
285  case biMesaPlateauM: return 12.0;
286  // Non-biomes
287  case biInvalidBiome:
288  case biNumBiomes:
289  case biVariant:
290  case biNumVariantBiomes:
291  {
292  break;
293  }
294  }
295  UNREACHABLE("Unsupported biome");
296  };
297 
298  double NumTrees = 0.0;
299  for (auto Biome : a_Biomes)
300  {
301  NumTrees += BiomeTrees(Biome);
302  }
303 
304  return NumTrees / (cChunkDef::Width * cChunkDef::Width * 4);
305 }
306 
307 
308 
309 
310 
312 // cStructGenLakes:
313 
315 {
316  int ChunkX = a_ChunkDesc.GetChunkX();
317  int ChunkZ = a_ChunkDesc.GetChunkZ();
318 
319  for (int z = -1; z < 2; z++) for (int x = -1; x < 2; x++)
320  {
321  if (((m_Noise.IntNoise2DInt(ChunkX + x, ChunkZ + z) / 17) % 100) > m_Probability)
322  {
323  continue;
324  }
325 
326  cBlockArea Lake;
327  CreateLakeImage(ChunkX + x, ChunkZ + z, a_ChunkDesc.GetMinHeight(), Lake);
328 
329  int OfsX = Lake.GetOriginX() + x * cChunkDef::Width;
330  int OfsZ = Lake.GetOriginZ() + z * cChunkDef::Width;
331 
332  // Merge the lake into the current data
333  a_ChunkDesc.WriteBlockArea(Lake, OfsX, Lake.GetOriginY(), OfsZ, cBlockArea::msLake);
334  } // for x, z - neighbor chunks
335 }
336 
337 
338 
339 
340 
341 void cStructGenLakes::CreateLakeImage(int a_ChunkX, int a_ChunkZ, int a_MaxLakeHeight, cBlockArea & a_Lake)
342 {
343  a_Lake.Create(16, 8, 16);
344  a_Lake.Fill(cBlockArea::baTypes, E_BLOCK_SPONGE); // Sponge is the NOP blocktype for lake merging strategy
345 
346  // Make a random position in the chunk by using a random 16 block XZ offset and random height up to chunk's max height minus 6
347  int MinHeight = std::max(a_MaxLakeHeight - 6, 2);
348  int Rnd = m_Noise.IntNoise3DInt(a_ChunkX, 128, a_ChunkZ) / 11;
349  // Random offset [-8 .. 8], with higher probability around 0; add up four three-bit-wide randoms [0 .. 28], divide and subtract to get range
350  int OffsetX = 4 * ((Rnd & 0x07) + ((Rnd & 0x38) >> 3) + ((Rnd & 0x1c0) >> 6) + ((Rnd & 0xe00) >> 9)) / 7 - 8;
351  Rnd >>= 12;
352  // Random offset [-8 .. 8], with higher probability around 0; add up four three-bit-wide randoms [0 .. 28], divide and subtract to get range
353  int OffsetZ = 4 * ((Rnd & 0x07) + ((Rnd & 0x38) >> 3) + ((Rnd & 0x1c0) >> 6) + ((Rnd & 0xe00) >> 9)) / 7 - 8;
354  Rnd = m_Noise.IntNoise3DInt(a_ChunkX, 512, a_ChunkZ) / 13;
355  // Random height [1 .. MinHeight] with preference to center heights
356  int HeightY = 1 + (((Rnd & 0x1ff) % MinHeight) + (((Rnd >> 9) & 0x1ff) % MinHeight)) / 2;
357 
358  a_Lake.SetOrigin(OffsetX, HeightY, OffsetZ);
359 
360  // Hollow out a few bubbles inside the blockarea:
361  int NumBubbles = 4 + ((Rnd >> 18) & 0x03); // 4 .. 7 bubbles
362  BLOCKTYPE * BlockTypes = a_Lake.GetBlockTypes();
363  for (int i = 0; i < NumBubbles; i++)
364  {
365  int BubbleRnd = m_Noise.IntNoise3DInt(a_ChunkX, i, a_ChunkZ) / 13;
366  const int BubbleR = 2 + (BubbleRnd & 0x03); // 2 .. 5
367  const int Range = 16 - 2 * BubbleR;
368  const int BubbleX = BubbleR + (BubbleRnd % Range);
369  BubbleRnd >>= 4;
370  const int BubbleY = 4 + (BubbleRnd & 0x01); // 4 .. 5
371  BubbleRnd >>= 1;
372  const int BubbleZ = BubbleR + (BubbleRnd % Range);
373  const int HalfR = BubbleR / 2; // 1 .. 2
374  const int RSquared = BubbleR * BubbleR;
375  for (int y = -HalfR; y <= HalfR; y++)
376  {
377  // BubbleY + y is in the [0, 7] bounds
378  int DistY = 4 * y * y / 3;
379  int IdxY = (BubbleY + y) * 16 * 16;
380  for (int z = -BubbleR; z <= BubbleR; z++)
381  {
382  int DistYZ = DistY + z * z;
383  if (DistYZ >= RSquared)
384  {
385  continue;
386  }
387  int IdxYZ = BubbleX + IdxY + (BubbleZ + z) * 16;
388  for (int x = -BubbleR; x <= BubbleR; x++)
389  {
390  if (x * x + DistYZ < RSquared)
391  {
392  BlockTypes[x + IdxYZ] = E_BLOCK_AIR;
393  }
394  } // for x
395  } // for z
396  } // for y
397  } // for i - bubbles
398 
399  // Turn air in the bottom half into liquid:
400  for (int y = 0; y < 4; y++)
401  {
402  for (int z = 0; z < 16; z++) for (int x = 0; x < 16; x++)
403  {
404  if (BlockTypes[x + z * 16 + y * 16 * 16] == E_BLOCK_AIR)
405  {
406  BlockTypes[x + z * 16 + y * 16 * 16] = m_Fluid;
407  }
408  } // for z, x
409  } // for y
410 
411  // TODO: Turn sponge next to lava into stone
412 
413  // a_Lake.SaveToSchematicFile(fmt::format(FMT_STRING("Lake_{}_{}.schematic"), a_ChunkX, a_ChunkZ));
414 }
415 
416 
417 
418 
419 
421 // cStructGenDirectOverhangs:
422 
424  m_Noise1(a_Seed),
425  m_Noise2(a_Seed + 1000)
426 {
427 }
428 
429 
430 
431 
432 
434 {
435  // If there is no column of the wanted biome, bail out:
436  if (!HasWantedBiome(a_ChunkDesc))
437  {
438  return;
439  }
440 
441  HEIGHTTYPE MaxHeight = a_ChunkDesc.GetMaxHeight();
442 
443  const int SEGMENT_HEIGHT = 8;
444  const int INTERPOL_X = 16; // Must be a divisor of 16
445  const int INTERPOL_Z = 16; // Must be a divisor of 16
446  // Interpolate the chunk in 16 * SEGMENT_HEIGHT * 16 "segments", each SEGMENT_HEIGHT blocks high and each linearly interpolated separately.
447  // Have two buffers, one for the lowest floor and one for the highest floor, so that Y-interpolation can be done between them
448  // Then swap the buffers and use the previously-top one as the current-bottom, without recalculating it.
449 
450  int FloorBuf1[17 * 17];
451  int FloorBuf2[17 * 17];
452  int * FloorHi = FloorBuf1;
453  int * FloorLo = FloorBuf2;
454  int BaseX = a_ChunkDesc.GetChunkX() * cChunkDef::Width;
455  int BaseZ = a_ChunkDesc.GetChunkZ() * cChunkDef::Width;
456  int BaseY = 63;
457 
458  // Interpolate the lowest floor:
459  for (int z = 0; z <= 16 / INTERPOL_Z; z++) for (int x = 0; x <= 16 / INTERPOL_X; x++)
460  {
461  FloorLo[INTERPOL_X * x + 17 * INTERPOL_Z * z] =
462  m_Noise1.IntNoise3DInt(BaseX + INTERPOL_X * x, BaseY, BaseZ + INTERPOL_Z * z) *
463  m_Noise2.IntNoise3DInt(BaseX + INTERPOL_X * x, BaseY, BaseZ + INTERPOL_Z * z) /
464  256;
465  } // for x, z - FloorLo[]
466  LinearUpscale2DArrayInPlace<17, 17, INTERPOL_X, INTERPOL_Z>(FloorLo);
467 
468  // Interpolate segments:
469  for (int Segment = BaseY; Segment < MaxHeight; Segment += SEGMENT_HEIGHT)
470  {
471  // First update the high floor:
472  for (int z = 0; z <= 16 / INTERPOL_Z; z++) for (int x = 0; x <= 16 / INTERPOL_X; x++)
473  {
474  FloorHi[INTERPOL_X * x + 17 * INTERPOL_Z * z] = (
475  m_Noise1.IntNoise3DInt(BaseX + INTERPOL_X * x, Segment + SEGMENT_HEIGHT, BaseZ + INTERPOL_Z * z) *
476  m_Noise2.IntNoise3DInt(BaseX + INTERPOL_Z * x, Segment + SEGMENT_HEIGHT, BaseZ + INTERPOL_Z * z) / 256
477  );
478  } // for x, z - FloorLo[]
479  LinearUpscale2DArrayInPlace<17, 17, INTERPOL_X, INTERPOL_Z>(FloorHi);
480 
481  // Interpolate between FloorLo and FloorHi:
482  for (int z = 0; z < 16; z++) for (int x = 0; x < 16; x++)
483  {
484  EMCSBiome biome = a_ChunkDesc.GetBiome(x, z);
485 
486  if ((biome == biExtremeHills) || (biome == biExtremeHillsEdge))
487  {
488  int Lo = FloorLo[x + 17 * z] / 256;
489  int Hi = FloorHi[x + 17 * z] / 256;
490  for (int y = 0; y < SEGMENT_HEIGHT; y++)
491  {
492  int Val = Lo + (Hi - Lo) * y / SEGMENT_HEIGHT;
493  if (Val < 0)
494  {
495  a_ChunkDesc.SetBlockType(x, y + Segment, z, E_BLOCK_AIR);
496  }
497  } // for y
498  break;
499  } // if (biome)
500  } // for z, x
501 
502  // Swap the floors:
503  std::swap(FloorLo, FloorHi);
504  }
505 }
506 
507 
508 
509 
510 
512 {
513  cChunkDef::BiomeMap & Biomes = a_ChunkDesc.GetBiomeMap();
514  for (size_t i = 0; i < ARRAYCOUNT(Biomes); i++)
515  {
516  switch (Biomes[i])
517  {
518  case biExtremeHills:
519  case biExtremeHillsEdge:
520  {
521  return true;
522  }
523  default:
524  {
525  break;
526  }
527  }
528  } // for i
529  return false;
530 }
531 
532 
533 
534 
535 
537 // cStructGenDistortedMembraneOverhangs:
538 
540  m_NoiseX(a_Seed + 1000),
541  m_NoiseY(a_Seed + 2000),
542  m_NoiseZ(a_Seed + 3000),
543  m_NoiseH(a_Seed + 4000)
544 {
545 }
546 
547 
548 
549 
550 
552 {
553  const NOISE_DATATYPE Frequency = static_cast<NOISE_DATATYPE>(16);
554  const NOISE_DATATYPE Amount = static_cast<NOISE_DATATYPE>(1);
555  for (int y = 50; y < 128; y++)
556  {
557  NOISE_DATATYPE NoiseY = static_cast<NOISE_DATATYPE>(y) / 32;
558  // TODO: proper water level - where to get?
559  BLOCKTYPE ReplacementBlock = (y > 62) ? E_BLOCK_AIR : E_BLOCK_STATIONARY_WATER;
560  for (int z = 0; z < cChunkDef::Width; z++)
561  {
562  NOISE_DATATYPE NoiseZ = static_cast<NOISE_DATATYPE>(a_ChunkDesc.GetChunkZ() * cChunkDef::Width + z) / Frequency;
563  for (int x = 0; x < cChunkDef::Width; x++)
564  {
565  NOISE_DATATYPE NoiseX = static_cast<NOISE_DATATYPE>(a_ChunkDesc.GetChunkX() * cChunkDef::Width + x) / Frequency;
566  NOISE_DATATYPE DistortX = m_NoiseX.CubicNoise3D(NoiseX, NoiseY, NoiseZ) * Amount;
567  NOISE_DATATYPE DistortY = m_NoiseY.CubicNoise3D(NoiseX, NoiseY, NoiseZ) * Amount;
568  NOISE_DATATYPE DistortZ = m_NoiseZ.CubicNoise3D(NoiseX, NoiseY, NoiseZ) * Amount;
569  int MembraneHeight = 96 - static_cast<int>((DistortY + m_NoiseH.CubicNoise2D(NoiseX + DistortX, NoiseZ + DistortZ)) * 30);
570  if (MembraneHeight < y)
571  {
572  a_ChunkDesc.SetBlockType(x, y, z, ReplacementBlock);
573  }
574  } // for y
575  } // for x
576  } // for z
577 }
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_BLOCK_NEW_LEAVES
Definition: BlockType.h:180
@ E_BLOCK_SPONGE
Definition: BlockType.h:29
@ E_BLOCK_FARMLAND
Definition: BlockType.h:72
@ E_BLOCK_AIR
Definition: BlockType.h:10
@ E_BLOCK_LEAVES
Definition: BlockType.h:28
@ E_BLOCK_GRASS
Definition: BlockType.h:12
@ E_BLOCK_NEW_LOG
Definition: BlockType.h:181
@ E_BLOCK_MYCELIUM
Definition: BlockType.h:125
@ E_BLOCK_HUGE_BROWN_MUSHROOM
Definition: BlockType.h:114
@ E_BLOCK_HUGE_RED_MUSHROOM
Definition: BlockType.h:115
@ E_BLOCK_DIRT
Definition: BlockType.h:13
@ E_BLOCK_LOG
Definition: BlockType.h:27
@ E_BLOCK_STATIONARY_WATER
Definition: BlockType.h:19
std::vector< sSetBlock > sSetBlockVector
Definition: ChunkDef.h:441
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
void GetTreeImageByBiome(Vector3i a_BlockPos, cNoise &a_Noise, int a_Seq, EMCSBiome a_Biome, sSetBlockVector &a_LogBlocks, sSetBlockVector &a_OtherBlocks)
Fills a_LogBlocks and a_OtherBlocks (dirt & leaves) with the blocks required to form a tree at the sp...
Definition: Trees.cpp:310
#define CASE_TREE_OVERWRITTEN_BLOCKS
Definition: Trees.h:38
#define CASE_TREE_ALLOWED_BLOCKS
Definition: Trees.h:27
#define UNREACHABLE(x)
Definition: Globals.h:288
#define ARRAYCOUNT(X)
Evaluates to the number of elements in an array (compile-time!)
Definition: Globals.h:231
float NOISE_DATATYPE
The datatype used by all the noise generators.
Definition: Noise.h:9
void Create(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes=baTypes|baMetas|baBlockEntities)
Creates a new area of the specified size and contents.
Definition: BlockArea.cpp:338
void SetOrigin(int a_OriginX, int a_OriginY, int a_OriginZ)
Resets the origin.
Definition: BlockArea.cpp:387
int GetOriginZ(void) const
Definition: BlockArea.h:356
int GetOriginY(void) const
Definition: BlockArea.h:355
BLOCKTYPE * GetBlockTypes(void) const
Returns the internal pointer to the block types.
Definition: BlockArea.h:389
void Fill(int a_DataTypes, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta=0, NIBBLETYPE a_BlockLight=0, NIBBLETYPE a_BlockSkyLight=0x0f)
Fills the entire block area with the specified data.
Definition: BlockArea.cpp:773
int GetOriginX(void) const
Definition: BlockArea.h:354
static bool IsSolid(BLOCKTYPE Block)
Is this block solid (player cannot walk through)?
Definition: BlockInfo.cpp:892
static const int Width
Definition: ChunkDef.h:124
static const int Height
Definition: ChunkDef.h:125
EMCSBiome BiomeMap[Width *Width]
The type used for any biomemap operations and storage inside Cuberite, using Cuberite biomes (need no...
Definition: ChunkDef.h:137
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 SetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
Definition: ChunkDesc.cpp:63
void SetChunkCoords(cChunkCoords a_Coords)
Definition: ChunkDesc.cpp:45
HEIGHTTYPE GetMinHeight(void) const
Returns the minimum height value in the heightmap.
Definition: ChunkDesc.cpp:414
BLOCKTYPE GetBlockType(int a_RelX, int a_RelY, int a_RelZ) const
Definition: ChunkDesc.cpp:90
void WriteBlockArea(const cBlockArea &a_BlockArea, int a_RelX, int a_RelY, int a_RelZ, cBlockArea::eMergeStrategy a_MergeStrategy=cBlockArea::msOverwrite)
Writes the block area into the chunk, with its origin set at the specified relative coords.
Definition: ChunkDesc.cpp:271
cChunkDef::BiomeMap & GetBiomeMap(void)
Definition: ChunkDesc.h:234
int GetChunkZ() const
Definition: ChunkDesc.h:50
void UpdateHeightmap(void)
Updates the heightmap to match the current contents.
Definition: ChunkDesc.cpp:612
HEIGHTTYPE GetMaxHeight(void) const
Returns the maximum height value in the heightmap.
Definition: ChunkDesc.cpp:397
virtual void GenBiomes(cChunkCoords a_ChunkCoords, cChunkDef::BiomeMap &a_BiomeMap)=0
Generates biomes for the given chunk.
virtual void GenShape(cChunkCoords a_ChunkCoords, cChunkDesc::Shape &a_Shape)=0
Generates the shape for the given chunk.
virtual void ComposeTerrain(cChunkDesc &a_ChunkDesc, const cChunkDesc::Shape &a_Shape)=0
Generates the chunk's composition into a_ChunkDesc, using the terrain shape provided in a_Shape.
double GetNumTrees(int a_ChunkX, int a_ChunkZ, const cChunkDef::BiomeMap &a_Biomes)
Get the the number of trees to generate in a_Chunk If the value is between 0 and 1,...
Definition: StructGen.cpp:215
virtual void GenFinish(cChunkDesc &a_ChunkDesc) override
Definition: StructGen.cpp:18
void ApplyTreeImage(int a_ChunkX, int a_ChunkZ, cChunkDesc &a_ChunkDesc, const sSetBlockVector &a_Image, sSetBlockVector &a_Overflow)
Applies an image into chunk blockdata; all blocks outside the chunk will be appended to a_Overflow.
Definition: StructGen.cpp:161
cTerrainCompositionGen & m_CompositionGen
Definition: StructGen.h:39
cTerrainShapeGen & m_ShapeGen
Definition: StructGen.h:38
cBiomeGen & m_BiomeGen
Definition: StructGen.h:37
void GenerateSingleTree(int a_ChunkX, int a_ChunkZ, int a_Seq, Vector3i a_Pos, cChunkDesc &a_ChunkDesc, sSetBlockVector &a_OutsideLogs, sSetBlockVector &a_OutsideOther)
Generates and applies an image of a single tree.
Definition: StructGen.cpp:96
cNoise m_Noise
Definition: StructGen.h:36
int m_Probability
Chance, [0 .
Definition: StructGen.h:97
cNoise m_Noise
Definition: StructGen.h:91
void CreateLakeImage(int a_ChunkX, int a_ChunkZ, int a_MaxLakeHeight, cBlockArea &a_Lake)
Creates a lake image for the specified chunk into a_Lake.
Definition: StructGen.cpp:341
virtual void GenFinish(cChunkDesc &a_ChunkDesc) override
Definition: StructGen.cpp:314
BLOCKTYPE m_Fluid
Definition: StructGen.h:93
bool HasWantedBiome(cChunkDesc &a_ChunkDesc) const
Definition: StructGen.cpp:511
virtual void GenFinish(cChunkDesc &a_ChunkDesc) override
Definition: StructGen.cpp:433
cStructGenDirectOverhangs(int a_Seed)
Definition: StructGen.cpp:423
virtual void GenFinish(cChunkDesc &a_ChunkDesc) override
Definition: StructGen.cpp:551
NOISE_DATATYPE CubicNoise2D(NOISE_DATATYPE a_X, NOISE_DATATYPE a_Y) const
Definition: Noise.cpp:593
NOISE_DATATYPE CubicNoise3D(NOISE_DATATYPE a_X, NOISE_DATATYPE a_Y, NOISE_DATATYPE a_Z) const
Definition: Noise.cpp:621
int IntNoise3DInt(int a_X, int a_Y, int a_Z) const
Definition: Noise.h:254
int IntNoise2DInt(int a_X, int a_Y) const
Definition: Noise.h:243
NOISE_DATATYPE IntNoise3D(int a_X, int a_Y, int a_Z) const
Definition: Noise.h:210
T x
Definition: Vector3.h:17
T y
Definition: Vector3.h:17
T z
Definition: Vector3.h:17