Cuberite
A lightweight, fast and extensible game server for Minecraft
Trees.cpp
Go to the documentation of this file.
1 
2 // Trees.cpp
3 
4 // Implements helper functions used for generating trees
5 
6 #include "Globals.h"
7 #include "Trees.h"
8 #include "../BlockType.h"
9 #include "../World.h"
10 
11 
12 
13 
14 
15 typedef struct
16 {
17  int x, z;
18 } sCoords;
19 
20 typedef struct
21 {
22  int x, z;
24 } sMetaCoords;
25 
26 static const sCoords Corners[] =
27 {
28  {-1, -1},
29  {-1, 1},
30  {1, -1},
31  {1, 1},
32 } ;
33 
35 static const Vector3d & pickBranchDirection(const cNoise a_Noise, Vector3i a_BlockPos, int a_Seq)
36 {
37  static const std::array<Vector3d, 32> directions =
38  {
39  {
40  { -1, 0, 0 }, { 0, 0, -1 },
41  { -1, 0, 1 }, { -1, 0, -1 },
42  { 1, 0, 1 }, { 1, 0, -1 },
43  { 1, 0, 0 }, { 0, 0, 1 },
44 
45  { -0.5, 0, 0 }, { 0, 0, -0.5 },
46  { -0.5, 0, 0.5 }, { -0.5, 0, -0.5 },
47  { 0.5, 0, 0.5 }, { 0.5, 0, -0.5 },
48  { 0.5, 0, 0 }, { 0, 0, 0.5 },
49 
50  { -1, 0.5, 0 }, { 0, 0.5, -1 },
51  { -1, 0.5, 1 }, { -1, 0.5, -1 },
52  { 1, 0.5, 1 }, { 1, 0.5, -1 },
53  { 1, 0.5, 0 }, { 0, 0.5, 1 },
54 
55  { -0.5, 0.5, 0 }, { 0, 0.5, -0.5 },
56  { -0.5, 0.5, 0.5 }, { -0.5, 0.5, -0.5 },
57  { 0.5, 0.5, 0.5 }, { 0.5, 0.5, -0.5 },
58  { 0.5, 0.5, 0 }, { 0, 0.5, 0.5 },
59  }
60  };
61 
62  size_t index = static_cast<size_t>(a_Noise.IntNoise3DInt(a_BlockPos * a_Seq)) % directions.size();
63  return directions[index];
64 }
65 
66 // BigO = a big ring of blocks, used for generating horz slices of treetops, the number indicates the radius
67 
68 static const sCoords BigO1[] =
69 {
70  /* -1 */ {0, -1},
71  /* 0 */ {-1, 0}, {1, 0},
72  /* 1 */ {0, 1},
73 } ;
74 
75 static const sCoords BigO2[] =
76 {
77  /* -2 */ {-1, -2}, {0, -2}, {1, -2},
78  /* -1 */ {-2, -1}, {-1, -1}, {0, -1}, {1, -1}, {2, -1},
79  /* 0 */ {-2, 0}, {-1, 0}, {1, 0}, {2, 0},
80  /* 1 */ {-2, 1}, {-1, 1}, {0, 1}, {1, 1}, {2, 1},
81  /* 2 */ {-1, 2}, {0, 2}, {1, 2},
82 } ;
83 
84 static const sCoords BigO3[] =
85 {
86  /* -3 */ {-2, -3}, {-1, -3}, {0, -3}, {1, -3}, {2, -3},
87  /* -2 */ {-3, -2}, {-2, -2}, {-1, -2}, {0, -2}, {1, -2}, {2, -2}, {3, -2},
88  /* -1 */ {-3, -1}, {-2, -1}, {-1, -1}, {0, -1}, {1, -1}, {2, -1}, {3, -1},
89  /* 0 */ {-3, 0}, {-2, 0}, {-1, 0}, {1, 0}, {2, 0}, {3, 0},
90  /* 1 */ {-3, 1}, {-2, 1}, {-1, 1}, {0, 1}, {1, 1}, {2, 1}, {3, 1},
91  /* 2 */ {-3, 2}, {-2, 2}, {-1, 2}, {0, 2}, {1, 2}, {2, 2}, {3, 2},
92  /* 3 */ {-2, 3}, {-1, 3}, {0, 3}, {1, 3}, {2, 3},
93 } ;
94 
95 
96 static const sCoords BigO4[] = // Part of dark oak tree
97 {
98  /* -4 */ {-2, -4}, {-1, -4}, {0, -4}, {1, -4}, {2, -4},
99  /* -3 */ {-3, -3}, {-2, -3}, {-1, -3}, {0, -3}, {1, -3}, {2, -3}, {3, -3},
100  /* -2 */ {-4, -2}, {-3, -2}, {-2, -2}, {-1, -2}, {0, -2}, {1, -2}, {2, -2}, {3, -2}, {4, -2},
101  /* -1 */ {-4, -1}, {-3, -1}, {-2, -1}, {-1, -1}, {0, -1}, {1, -1}, {2, -1}, {3, -1}, {4, -1},
102  /* 0 */ {-4, 0}, {-3, 0}, {-2, 0}, {-1, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0},
103  /* 1 */ {-4, 1}, {-3, 1}, {-2, 1}, {-1, 1}, {0, 1}, {1, 1}, {2, 1}, {3, 1}, {4, 1},
104  /* 2 */ {-4, 2}, {-3, 2}, {-2, 2}, {-1, 2}, {0, 2}, {1, 2}, {2, 2}, {3, 2}, {4, 2},
105  /* 3 */ {-3, 3}, {-2, 3}, {-1, 3}, {0, 3}, {1, 3}, {2, 3}, {3, 3},
106  /* 4 */ {-2, 4}, {-1, 4}, {0, 4}, {1, 4}, {2, 4},
107 };
108 
109 static const sCoords BigO3Jungle[] =
110 {
111  /* -3 */ {0, -3}, {1, -3},
112  /* -2 */ {-1, -2}, {0, -2}, {1, -2}, {2, -2},
113  /* -1 */ {-2, -1}, {-1, -1}, {0, -1}, {1, -1}, {2, -1}, {3, -1},
114  /* 0 */ {-3, 0}, {-2, 0}, {-1, 0}, {0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0},
115  /* 1 */ {-3, 1}, {-2, 1}, {-1, 1}, {0, 1}, {1, 1}, {2, 1}, {3, 1}, {4, 1},
116  /* 2 */ {-2, 2}, {-1, 2}, {0, 2}, {1, 2}, {2, 2}, {3, 2},
117  /* 3 */ {-1, 3}, {0, 3}, {1, 3}, {2, 3},
118  /* 4 */ {0, 4}, {1, 4},
119 };
120 
121 static const sCoords BigO4Jungle[] =
122 {
123  /* -4 */ {0, -4}, {1, -4},
124  /* -3 */ {-2, -3}, {-1, -3}, {0, -3}, {1, -3}, {2, -3}, {3, -3},
125  /* -2 */ {-3, -2}, {-2, -2}, {-1, -2}, {0, -2}, {1, -2}, {2, -2}, {3, -2}, {4, -2},
126  /* -1 */ {-3, -1}, {-2, -1}, {-1, -1}, {0, -1}, {1, -1}, {2, -1}, {3, -1}, {4, -1},
127  /* 0 */ {-4, 0}, {-3, 0}, {-2, 0}, {-1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0},
128  /* 1 */ {-4, 1}, {-3, 1}, {-2, 1}, {-1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1},
129  /* 2 */ {-3, 2}, {-2, 2}, {-1, 2}, {0, 2}, {1, 2}, {2, 2}, {3, 2}, {4, 2},
130  /* 3 */ {-3, 3}, {-2, 3}, {-1, 3}, {0, 3}, {1, 3}, {2, 3}, {3, 3}, {4, 3},
131  /* 4 */ {-2, 4}, {-1, 4}, {0, 4}, {1, 4}, {2, 4}, {3, 4},
132  /* 5 */ {0, 5}, {1, 5},
133 };
134 
135 static const sCoords BigO5Jungle[] =
136 {
137  /* -5 */ {0, -5}, {1, -5},
138  /* -4 */ {-2, -4}, {-1, -4}, {0, -4}, {1, -4}, {2, -4}, {3, -4},
139  /* -3 */ {-3, -3}, {-2, -3}, {-1, -3}, {0, -3}, {1, -3}, {2, -3}, {3, -3}, {4, -3},
140  /* -2 */ {-4, -2}, {-3, -2}, {-2, -2}, {-1, -2}, {0, -2}, {1, -2}, {2, -2}, {3, -2}, {4, -2}, {5, -2},
141  /* -1 */ {-4, -1}, {-3, -1}, {-2, -1}, {-1, -1}, {0, -1}, {1, -1}, {2, -1}, {3, -1}, {4, -1}, {5, -1},
142  /* 0 */ {-5, 0}, {-4, 0}, {-3, 0}, {-2, 0}, {-1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0},
143  /* 1 */ {-5, 1}, {-4, 1}, {-3, 1}, {-2, 1}, {-1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1}, {6, 1},
144  /* 2 */ {-4, 2}, {-3, 2}, {-2, 2}, {-1, 2}, {0, 2}, {1, 2}, {2, 2}, {3, 2}, {4, 2}, {5, 2},
145  /* 3 */ {-4, 3}, {-3, 3}, {-2, 3}, {-1, 3}, {0, 3}, {1, 3}, {2, 3}, {3, 3}, {4, 3}, {5, 3},
146  /* 4 */ {-3, 4}, {-2, 4}, {-1, 4}, {0, 4}, {1, 4}, {2, 4}, {3, 4}, {4, 4},
147  /* 5 */ {-2, 5}, {-1, 5}, {0, 5}, {1, 5}, {2, 5}, {3, 5},
148  /* 6 */ {0, 6}, {1, 6},
149 } ;
150 
151 static const sCoords TopLargePine[] =
152 {
153  /* 0 */ {0, 0}, {1, 0},
154  /* 1 */ {0, 1}, {1, 1},
155 } ;
156 
157 static const sCoords BigOF2Pine[] =
158 {
159  /* -1 */ {0, -1}, {1, -1},
160  /* 0 */ {-1, 0}, {0, 0}, {1, 0}, {2, 0},
161  /* 1 */ {-1, 1}, {0, 1}, {1, 1}, {2, 1},
162  /* 2 */ {0, 2}, {1, 2},
163 } ;
164 
165 static const sCoords BigO2Pine[] =
166 {
167  /* -2 */ {0, -2}, {1, -2},
168  /* -1 */ {-1, -1}, {0, -1}, {1, -1}, {2, -1},
169  /* 0 */ {-2, 0}, {-1, 0}, {2, 0}, {3, 0},
170  /* 1 */ {-2, 1}, {-1, 1}, {2, 1}, {3, 1},
171  /* 2 */ {-1, 2}, {0, 2}, {1, 2}, {2, 2},
172  /* 3 */ {0, 3}, {1, 3},
173 } ;
174 
175 static const sCoords BigO3Pine[] =
176 {
177  /* -3 */ {0, -3}, {1, -3},
178  /* -2 */ {-1, -2}, {0, -2}, {1, -2}, {2, -2},
179  /* -1 */ {-2, -1}, {-1, -1}, {0, -1}, {1, -1}, {2, -1}, {3, -1},
180  /* 0 */ {-3, 0}, {-2, 0}, {-1, 0}, {2, 0}, {3, 0}, {4, 0},
181  /* 1 */ {-3, 1}, {-2, 1}, {-1, 1}, {2, 1}, {3, 1}, {4, 1},
182  /* 2 */ {-2, 2}, {-1, 2}, {0, 2}, {1, 2}, {2, 2}, {3, 2},
183  /* 3 */ {-1, 3}, {0, 3}, {1, 3}, {2, 3},
184  /* 4 */ {0, 4}, {1, 4},
185 };
186 
187 static const sCoords BigO1Spruce[] =
188 {
189  /* -1 */ {0, -1}, {1, -1},
190  /* 0 */ {-1, 0}, {2, 0},
191  /* 1 */ {-1, 1}, {2, 1},
192  /* 2 */ {0, 2}, {1, 2},
193 } ;
194 
195 
196 
197 typedef struct
198 {
199  const sCoords * Coords;
200  size_t Count;
201 } sCoordsArr;
202 
203 static const sCoordsArr BigOLayers[] =
204 {
205  {BigO1, ARRAYCOUNT(BigO1)},
206  {BigO2, ARRAYCOUNT(BigO2)},
207  {BigO3, ARRAYCOUNT(BigO3)},
208  {BigO4, ARRAYCOUNT(BigO4)},
209 } ;
210 
211 static const sCoordsArr BigOJungleLayers[] =
212 {
216 };
217 
218 static const sCoordsArr BigOPineLayers[] =
219 {
224 };
225 
227 {
229  {nullptr, 0},
230 };
231 
233 {
236 };
237 
239 {
242 };
243 
245 {
248 };
249 
250 static const sCoordsArr BigOSpruceTop[] =
251 {
254 };
255 
256 
257 
258 
259 
261 inline void PushCoordBlocks(int a_BlockX, int a_Height, int a_BlockZ, sSetBlockVector & a_Blocks, const sCoords * a_Coords, size_t a_NumCoords, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta)
262 {
263  for (size_t i = 0; i < a_NumCoords; i++)
264  {
265  a_Blocks.emplace_back(a_BlockX + a_Coords[i].x, a_Height, a_BlockZ + a_Coords[i].z, a_BlockType, a_Meta);
266  }
267 }
268 
269 
270 
271 
272 
273 inline void PushCornerBlocks(int a_BlockX, int a_Height, int a_BlockZ, int a_Seq, cNoise & a_Noise, int a_Chance, sSetBlockVector & a_Blocks, int a_CornersDist, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta)
274 {
275  for (size_t i = 0; i < ARRAYCOUNT(Corners); i++)
276  {
277  int x = a_BlockX + Corners[i].x;
278  int z = a_BlockZ + Corners[i].z;
279  if (a_Noise.IntNoise3DInt(x + 64 * a_Seq, a_Height, z + 64 * a_Seq) <= a_Chance)
280  {
281  a_Blocks.emplace_back(x, a_Height, z, a_BlockType, a_Meta);
282  }
283  } // for i - Corners[]
284 }
285 
286 
287 
288 
289 
290 inline void PushSomeColumns(int a_BlockX, int a_Height, int a_BlockZ, int a_ColumnHeight, int a_Seq, cNoise & a_Noise, int a_Chance, sSetBlockVector & a_Blocks, const sMetaCoords * a_Coords, size_t a_NumCoords, BLOCKTYPE a_BlockType)
291 {
292  for (size_t i = 0; i < a_NumCoords; i++)
293  {
294  int x = a_BlockX + a_Coords[i].x;
295  int z = a_BlockZ + a_Coords[i].z;
296  if (a_Noise.IntNoise3DInt(x + 64 * a_Seq, a_Height + static_cast<int>(i), z + 64 * a_Seq) <= a_Chance)
297  {
298  for (int j = 0; j < a_ColumnHeight; j++)
299  {
300  a_Blocks.emplace_back(x, a_Height - j, z, a_BlockType, a_Coords[i].Meta);
301  }
302  }
303  } // for i - a_Coords[]
304 }
305 
306 
307 
308 
309 
310 void GetTreeImageByBiome(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, EMCSBiome a_Biome, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
311 {
312  switch (a_Biome)
313  {
314  case biPlains:
315  case biForest:
316  case biForestHills:
317  case biSunflowerPlains:
318  case biFlowerForest:
319  case biDeepOcean:
320  case biStoneBeach:
321  case biColdBeach:
322  {
323  // Apple or birch trees:
324  if (a_Noise.IntNoise3DInt(a_BlockPos.addedY(16 * a_Seq).addedZ(16 * a_Seq)) < 0x5fffffff)
325  {
326  GetAppleTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
327  }
328  else
329  {
330  GetBirchTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
331  }
332  return;
333  }
334 
335  case biColdTaiga:
336  case biColdTaigaM:
337  case biColdTaigaHills:
338  case biIcePlains:
339  case biIceMountains:
340  case biTaiga:
341  case biTaigaHills:
342  case biTaigaM:
343  {
344  // Conifers
345  GetConiferTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks, false);
346  return;
347  }
348 
349  case biSwamplandM:
350  case biSwampland:
351  {
352  // Swamp trees:
353  GetSwampTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
354  return;
355  }
356 
357  case biJungle:
358  case biJungleHills:
359  case biJungleEdge:
360  case biJungleM:
361  case biJungleEdgeM:
362  {
363  // Apple bushes, large jungle trees, small jungle trees
364  if (a_Noise.IntNoise3DInt(a_BlockPos.addedY(16 * a_Seq).addedZ(16 * a_Seq)) < 0x6fffffff)
365  {
366  GetAppleBushImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
367  }
368  else
369  {
370  bool IsLarge = a_Noise.IntNoise3DInt(a_BlockPos.addedX(32 * a_Seq).addedY(32 * a_Seq)) < 0x60000000;
371  GetJungleTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks, IsLarge);
372  }
373  return;
374  }
375 
376  case biBirchForest:
377  case biBirchForestHills:
378  {
379  GetBirchTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
380  return;
381  }
382 
383  case biBirchForestM:
384  case biBirchForestHillsM:
385  {
386  GetTallBirchTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
387  return;
388  }
389 
390  case biMegaTaiga:
391  case biMegaTaigaHills:
392  {
393  bool IsLarge = a_Noise.IntNoise3DInt(a_BlockPos.addedX(32 * a_Seq).addedY(32 * a_Seq)) < 0x30000000;
394  GetConiferTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks, IsLarge);
395  return;
396  }
397 
398  case biMegaSpruceTaiga:
400  {
401  bool IsLarge = a_Noise.IntNoise3DInt(a_BlockPos.addedX(32 * a_Seq).addedY(32 * a_Seq)) < 0x30000000;
402  GetSpruceTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks, IsLarge);
403  return;
404  }
405 
406  case biExtremeHills:
407  case biExtremeHillsM:
408  case biExtremeHillsEdge:
409  case biExtremeHillsPlus:
410  case biExtremeHillsPlusM:
411  {
412  if (a_Noise.IntNoise3DInt(a_BlockPos.addedY(16 * a_Seq).addedZ(16 * a_Seq)) < 0x6fffffff)
413  {
414  GetConiferTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
415  }
416  else
417  {
418  GetAppleTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
419  }
420  return;
421  }
422 
423  case biSavanna:
424  case biSavannaPlateau:
425  case biSavannaM:
426  case biSavannaPlateauM:
427  {
428  GetAcaciaTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
429  return;
430  }
431 
432  case biRoofedForest:
433  case biRoofedForestM:
434  {
435  // 53 % DarkOak
436  // 23 % SmallAppleTree
437  // 16 % RedMushroom
438  // 4 % BrownMushroom
439  // 4 % Birch
440  const int DarkOakProb = 53;
441  const int SmallAppleTreeProb = DarkOakProb + 23;
442  const int RedMushroomProb = SmallAppleTreeProb + 16;
443  const int BrownMushroomProb = RedMushroomProb + 4;
444 
445  static_assert(BrownMushroomProb + 4 == 100);
446 
447  auto RandomValue = a_Noise.IntNoise3DInt(a_BlockPos.addedY(16 * a_Seq).addedZ(16 * a_Seq)) % 100;
448  if (RandomValue < DarkOakProb)
449  {
450  GetDarkoakTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
451  }
452  else if ((RandomValue >= DarkOakProb) && (RandomValue < SmallAppleTreeProb))
453  {
454  GetSmallAppleTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
455  }
456  else if ((RandomValue >= SmallAppleTreeProb) && (RandomValue < RedMushroomProb))
457  {
458  GetRedMushroomTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
459  }
460  else if ((RandomValue >= RedMushroomProb) && (RandomValue < BrownMushroomProb))
461  {
462  GetBrownMushroomTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
463  }
464  else
465  {
466  GetBirchTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
467  }
468  return;
469  }
470 
471  case biMesa:
472  case biMesaPlateauF:
473  case biMesaPlateau:
474  case biMesaBryce:
475  case biMesaPlateauFM:
476  case biMesaPlateauM:
477  {
478  GetSmallAppleTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
479  return;
480  }
481  case biMushroomIsland:
482  case biMushroomShore:
483  {
484  if (a_Noise.IntNoise3DInt(a_BlockPos.addedY(16 * a_Seq).addedZ(16 * a_Seq)) < 0x6fffffff)
485  {
486  GetBrownMushroomTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
487  }
488  else
489  {
490  GetRedMushroomTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
491  }
492  return;
493  }
494  case biDesert:
495  case biDesertHills:
496  case biDesertM:
497  case biRiver:
498  case biBeach:
499  case biHell:
500  case biSky:
501  case biOcean:
502  case biFrozenOcean:
503  case biFrozenRiver:
504  case biIcePlainsSpikes:
505  case biVariant:
506  case biNumBiomes:
507  case biNumVariantBiomes:
508  case biInvalidBiome:
509  {
510  // These biomes have no trees, or are non-biome members of the enum.
511  return;
512  }
513  }
514 
515  ASSERT(!"Invalid biome type!");
516 }
517 
518 
519 
520 
521 
522 void GetAppleTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
523 {
524  if (a_Noise.IntNoise3DInt(a_BlockPos.addedX(32 * a_Seq).addedY(32 * a_Seq)) < 0x73333333)
525  {
526  GetSmallAppleTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
527  }
528  else
529  {
530  GetLargeAppleTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
531  }
532 }
533 
534 
535 
536 
537 
538 void GetSmallAppleTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
539 {
540  /* Small apple tree has:
541  - a top plus (no log)
542  - optional BigO1 + random corners (log)
543  - 2 layers of BigO2 + random corners (log)
544  - 1 to 3 blocks of trunk
545  */
546 
547  int Random = a_Noise.IntNoise3DInt(a_BlockPos.addedX(64 * a_Seq)) >> 3;
548  HEIGHTTYPE Heights[] = {1, 2, 2, 3} ;
549  HEIGHTTYPE Height = 1 + Heights[Random & 3];
550  Random >>= 2;
551 
552  // Pre-alloc so that we don't realloc too often later:
553  a_LogBlocks.reserve(static_cast<size_t>(Height + 5));
554  a_OtherBlocks.reserve(ARRAYCOUNT(BigO2) * 2 + ARRAYCOUNT(BigO1) + ARRAYCOUNT(Corners) * 3 + 3 + 5);
555 
556  // Trunk:
557  for (int i = 0; i < Height; i++)
558  {
559  a_LogBlocks.emplace_back(a_BlockPos.addedY(i), E_BLOCK_LOG, E_META_LOG_APPLE);
560  }
561  int Hei = a_BlockPos.y + Height;
562 
563  // 2 BigO2 + corners layers:
564  for (int i = 0; i < 2; i++)
565  {
566  PushCoordBlocks (a_BlockPos.x, Hei, a_BlockPos.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
567  PushCornerBlocks(a_BlockPos.x, Hei, a_BlockPos.z, a_Seq, a_Noise, 0x5000000 - i * 0x10000000, a_OtherBlocks, 2, E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
568  a_LogBlocks.emplace_back(a_BlockPos.x, Hei, a_BlockPos.z, E_BLOCK_LOG, E_META_LOG_APPLE);
569  Hei++;
570  } // for i - 2*
571 
572  // Optional BigO1 + corners layer:
573  if ((Random & 1) == 0)
574  {
575  PushCoordBlocks (a_BlockPos.x, Hei, a_BlockPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
576  PushCornerBlocks(a_BlockPos.x, Hei, a_BlockPos.z, a_Seq, a_Noise, 0x6000000, a_OtherBlocks, 1, E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
577  a_LogBlocks.emplace_back(a_BlockPos.x, Hei, a_BlockPos.z, E_BLOCK_LOG, E_META_LOG_APPLE);
578  Hei++;
579  }
580 
581  // Top plus:
582  PushCoordBlocks(a_BlockPos.x, Hei, a_BlockPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
583  a_OtherBlocks.emplace_back(a_BlockPos.x, Hei, a_BlockPos.z, E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
584 }
585 
586 
587 
588 
589 
590 void GetLargeAppleTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
591 {
592  int Height = 7 + a_Noise.IntNoise3DInt(a_BlockPos) % 4;
593 
594  // Create branches
595  for (int i = 4; i < Height; i++)
596  {
597  // Get a direction for the trunk to go to.
598  Vector3d BranchStartDirection = pickBranchDirection(a_Noise, a_BlockPos.addedY(i), a_Seq);
599  Vector3d BranchDirection = pickBranchDirection(a_Noise, a_BlockPos.addedY(i * a_Seq), a_Seq) / 3;
600 
601  int BranchLength = 2 + a_Noise.IntNoise3DInt(a_BlockPos * a_Seq) % 3;
602  GetTreeBranch(E_BLOCK_LOG, E_META_LOG_APPLE, a_BlockPos.addedY(i), BranchLength, BranchStartDirection, BranchDirection, a_LogBlocks);
603  }
604 
605  // Place leaves around each log block
606  for (auto itr : a_LogBlocks)
607  {
608  // Get the log's X and Z coordinates
609  int X = itr.GetX();
610  int Z = itr.GetZ();
611 
612  a_OtherBlocks.emplace_back(X, itr.m_RelY - 2, Z, E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
613  PushCoordBlocks(X, itr.m_RelY - 2, Z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
614  for (int y = -1; y <= 1; y++)
615  {
616  PushCoordBlocks (X, itr.m_RelY + y, Z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
617  }
618  PushCoordBlocks(X, itr.m_RelY + 2, Z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
619  a_OtherBlocks.emplace_back(X, itr.m_RelY + 2, Z, E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
620  }
621 
622  // Trunk:
623  for (int i = 0; i < Height; i++)
624  {
625  a_LogBlocks.emplace_back(a_BlockPos.addedY(i), E_BLOCK_LOG, E_META_LOG_APPLE);
626  }
627 }
628 
629 
630 
631 
632 
633 Vector3d GetTreeBranch(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_BlockPos, int a_BranchLength, Vector3d a_StartDirection, Vector3d a_Direction, sSetBlockVector & a_LogBlocks)
634 {
635  Vector3d CurrentPos = Vector3d(a_BlockPos);
636  Vector3d Direction = a_StartDirection;
637  for (int i = 0; i < a_BranchLength; i++)
638  {
639  CurrentPos += Direction;
640  Direction += a_Direction;
641  Direction.Clamp(-1.0, 1.0);
642  a_LogBlocks.emplace_back(CurrentPos.Floor(), a_BlockType, GetLogMetaFromDirection(a_BlockMeta, Direction));
643  }
644  return CurrentPos;
645 }
646 
647 
648 
649 
650 
652 {
653  a_Direction.Abs();
654 
655  if ((a_Direction.y > a_Direction.x) && (a_Direction.y > a_Direction.z))
656  {
657  return a_BlockMeta;
658  }
659  else if (a_Direction.x > a_Direction.z)
660  {
661  return a_BlockMeta + 4;
662  }
663  else
664  {
665  return a_BlockMeta + 8;
666  }
667 }
668 
669 
670 
671 
672 
673 void GetBirchTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
674 {
675  HEIGHTTYPE Height = 5 + static_cast<HEIGHTTYPE>(a_Noise.IntNoise3DInt(a_BlockPos.addedX(64 * a_Seq)) % 3);
676 
677  // Prealloc, so that we don't realloc too often later:
678  a_LogBlocks.reserve(static_cast<size_t>(Height));
679  a_OtherBlocks.reserve(80);
680 
681  // The entire trunk, out of logs:
682  for (int i = Height - 1; i >= 0; --i)
683  {
684  a_LogBlocks.emplace_back(a_BlockPos.addedY(i), E_BLOCK_LOG, E_META_LOG_BIRCH);
685  }
686  int h = a_BlockPos.y + Height;
687 
688  // Top layer - just the Plus:
689  PushCoordBlocks(a_BlockPos.x, h, a_BlockPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH);
690  a_OtherBlocks.emplace_back(a_BlockPos.x, h, a_BlockPos.z, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); // There's no log at this layer
691  h--;
692 
693  // Second layer - log, Plus and maybe Corners:
694  PushCoordBlocks (a_BlockPos.x, h, a_BlockPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH);
695  PushCornerBlocks(a_BlockPos.x, h, a_BlockPos.z, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 1, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH);
696  h--;
697 
698  // Third and fourth layers - BigO2 and maybe 2 * Corners:
699  for (int Row = 0; Row < 2; Row++)
700  {
701  PushCoordBlocks (a_BlockPos.x, h, a_BlockPos.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH);
702  PushCornerBlocks(a_BlockPos.x, h, a_BlockPos.z, a_Seq, a_Noise, 0x3fffffff + Row * 0x10000000, a_OtherBlocks, 2, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH);
703  h--;
704  } // for Row - 2*
705 }
706 
707 
708 
709 
710 
711 void GetAcaciaTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
712 {
713  // Calculate a base height
714  int Height = 2 + (a_Noise.IntNoise3DInt(a_BlockPos) / 11 % 3);
715 
716  // Create the trunk
717  for (int i = 0; i < Height; i++)
718  {
719  a_LogBlocks.emplace_back(a_BlockPos.addedY(i), E_BLOCK_NEW_LOG, E_META_NEW_LOG_ACACIA_WOOD);
720  }
721 
722  // Array with possible directions for a branch to go to.
723  const Vector3i AvailableDirections[] =
724  {
725  { -1, 1, 0 }, { 0, 1, -1 },
726  { -1, 1, 1 }, { -1, 1, -1 },
727  { 1, 1, 1 }, { 1, 1, -1 },
728  { 1, 1, 0 }, { 0, 1, 1 },
729  };
730 
731  // Get a direction for the trunk to go to.
732  Vector3i BranchDirection = AvailableDirections[a_Noise.IntNoise3DInt(a_BlockPos) % 8];
733 
734  // Calculate a height for the branch between 1 and 3
735  int BranchHeight = a_Noise.IntNoise3DInt(a_BlockPos) % 3 + 1;
736 
737  Vector3i BranchPos = GetTreeBranch(E_BLOCK_NEW_LOG, E_META_NEW_LOG_ACACIA_WOOD, a_BlockPos.addedY(Height - 1), BranchHeight, Vector3i(BranchDirection), Vector3i(BranchDirection), a_LogBlocks).Floor();
738 
739  // Add the leaves to the top of the branch
740  PushCoordBlocks(BranchPos.x, BranchPos.y, BranchPos.z, a_OtherBlocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_ACACIA);
741  PushCoordBlocks(BranchPos.x, BranchPos.y + 1, BranchPos.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_ACACIA);
742  a_OtherBlocks.emplace_back(BranchPos.x, BranchPos.y + 1, BranchPos.z, E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_ACACIA);
743 
744  // Choose if we have to add another branch
745  bool TwoTop = (a_Noise.IntNoise3D(a_BlockPos) < 0);
746  if (!TwoTop)
747  {
748  return;
749  }
750 
751  // Invert the direction of the previous branch.
752  BranchDirection = Vector3d(-BranchDirection.x, 1, -BranchDirection.z);
753 
754  // Calculate a new height for the second branch
755  BranchHeight = a_Noise.IntNoise3DInt(a_BlockPos * a_Seq) % 3 + 1;
756 
757  BranchPos = GetTreeBranch(E_BLOCK_NEW_LOG, E_META_NEW_LOG_ACACIA_WOOD, a_BlockPos.addedY(Height - 1), BranchHeight, BranchDirection, BranchDirection, a_LogBlocks).Floor();
758 
759  // And add the leaves ontop of the second branch
760  PushCoordBlocks(BranchPos.x, BranchPos.y, BranchPos.z, a_OtherBlocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_ACACIA);
761  PushCoordBlocks(BranchPos.x, BranchPos.y + 1, BranchPos.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_ACACIA);
762  a_OtherBlocks.emplace_back(BranchPos.x, BranchPos.y + 1, BranchPos.z, E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_ACACIA);
763 }
764 
765 
766 
767 
768 
769 void GetDarkoakTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
770 {
771  // Pick a height
772  int Height = 5 + (a_Noise.IntNoise3DInt(a_BlockPos.addedX(32 * a_Seq).addedZ(32 * a_Seq)) / 11) % 4;
773 
774  // Create the trunk
775  for (int i = 0; i < Height; i++)
776  {
777  a_LogBlocks.emplace_back(a_BlockPos.addedY(i), E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD);
778  a_LogBlocks.emplace_back(a_BlockPos.addedX(1).addedY(i), E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD);
779  a_LogBlocks.emplace_back(a_BlockPos.addedY(i).addedZ(1), E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD);
780  a_LogBlocks.emplace_back(a_BlockPos.addedX(1).addedY(i).addedZ(1), E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD);
781  }
782 
783  // Prevent floating trees by placing dirt under them
784  for (int i = 1; i < 5; i++)
785  {
786  a_OtherBlocks.emplace_back(a_BlockPos.addedY(-i), E_BLOCK_DIRT, E_META_DIRT_NORMAL);
787  a_OtherBlocks.emplace_back(a_BlockPos.addedX(1).addedY(-i), E_BLOCK_DIRT, E_META_DIRT_NORMAL);
788  a_OtherBlocks.emplace_back(a_BlockPos.addedY(-i).addedZ(1), E_BLOCK_DIRT, E_META_DIRT_NORMAL);
789  a_OtherBlocks.emplace_back(a_BlockPos.addedX(1).addedY(-i).addedZ(1), E_BLOCK_DIRT, E_META_DIRT_NORMAL);
790  }
791 
792  // Create branches
793  for (int i = 0; i < 3; i++)
794  {
795  int x = (a_Noise.IntNoise3DInt(a_BlockPos.addedX(32 * a_Seq).addedZ(32 * a_Seq).addedY(i * a_Seq)) % 3) - 1;
796  int z = (a_Noise.IntNoise3DInt(a_BlockPos.addedX(-32 * a_Seq).addedZ(-32 * a_Seq).addedY(i * a_Seq)) % 3) - 1;
797 
798  // The branches would end up in the trunk.
799  if ((x >= a_BlockPos.x) && (x <= a_BlockPos.x + 1) && (z >= a_BlockPos.z) && (z <= a_BlockPos.z + 1))
800  {
801  NOISE_DATATYPE Val1 = a_Noise.IntNoise2D(x, z);
802  if (Val1 < 0)
803  {
804  x = a_BlockPos.x + ((Val1 < -0.5) ? -1 : 3);
805  }
806  else
807  {
808  z = a_BlockPos.z + ((Val1 < 0.5) ? -1 : 3);
809  }
810  }
811 
812  int y = Height - (a_Noise.IntNoise3DInt(a_BlockPos.addedX(x).addedZ(z).addedY(i * a_Seq)) % (Height - (Height / 4)));
813 
814  for (int Y = y; Y < Height; Y++)
815  {
816  a_LogBlocks.emplace_back(a_BlockPos.addedX(x).addedY(Y).addedZ(z), E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD);
817  }
818  }
819 
820  int hei = a_BlockPos.y + Height - 2;
821 
822  // The lower two leaves layers are BigO4 with log in the middle and possibly corners:
823  for (int i = 0; i < 2; i++)
824  {
825  PushCoordBlocks(a_BlockPos.x, hei, a_BlockPos.z, a_OtherBlocks, BigO4, ARRAYCOUNT(BigO4), E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_DARK_OAK);
826  PushCornerBlocks(a_BlockPos.x, hei, a_BlockPos.z, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 3, E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_DARK_OAK);
827  hei++;
828  } // for i < 2
829 
830  // The top leaves layer is a BigO3 with leaves in the middle and possibly corners:
831  PushCoordBlocks(a_BlockPos.x, hei, a_BlockPos.z, a_OtherBlocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_DARK_OAK);
832  PushCornerBlocks(a_BlockPos.x, hei, a_BlockPos.z, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 3, E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_DARK_OAK);
833  a_OtherBlocks.emplace_back(a_BlockPos.x, hei, a_BlockPos.z, E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_DARK_OAK);
834 }
835 
836 
837 
838 
839 
840 void GetTallBirchTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
841 {
842  HEIGHTTYPE Height = 9 + static_cast<HEIGHTTYPE>(a_Noise.IntNoise3DInt(a_BlockPos.addedX(64 * a_Seq)) % 3);
843 
844  // Prealloc, so that we don't realloc too often later:
845  a_LogBlocks.reserve(static_cast<size_t>(Height));
846  a_OtherBlocks.reserve(80);
847 
848  // The entire trunk, out of logs:
849  for (int i = Height - 1; i >= 0; --i)
850  {
851  a_LogBlocks.emplace_back(a_BlockPos.addedY(i), E_BLOCK_LOG, E_META_LOG_BIRCH);
852  }
853  int h = a_BlockPos.y + Height;
854 
855  // Top layer - just the Plus:
856  PushCoordBlocks(a_BlockPos.x, h, a_BlockPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH);
857  a_OtherBlocks.emplace_back(a_BlockPos.x, h, a_BlockPos.z, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); // There's no log at this layer
858  h--;
859 
860  // Second layer - log, Plus and maybe Corners:
861  PushCoordBlocks (a_BlockPos.x, h, a_BlockPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH);
862  PushCornerBlocks(a_BlockPos.x, h, a_BlockPos.z, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 1, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH);
863  h--;
864 
865  // Third and fourth layers - BigO2 and maybe 2 * Corners:
866  for (int Row = 0; Row < 2; Row++)
867  {
868  PushCoordBlocks (a_BlockPos.x, h, a_BlockPos.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH);
869  PushCornerBlocks(a_BlockPos.x, h, a_BlockPos.z, a_Seq, a_Noise, 0x3fffffff + Row * 0x10000000, a_OtherBlocks, 2, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH);
870  h--;
871  } // for Row - 2*
872 }
873 
874 
875 
876 
877 
878 void GetConiferTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks, bool a_Large)
879 {
880  // Half chance for a spruce, half for a pine and for the large ones 3 chances for a pine and one for spruce:
881  if (a_Noise.IntNoise3DInt(a_BlockPos.addedX(64 * a_Seq).addedZ(32 * a_Seq)) < (a_Large ? 0x20000000 : 0x40000000))
882  {
883  GetSpruceTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks, a_Large);
884  }
885  else
886  {
887  GetPineTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks, a_Large);
888  }
889 }
890 
891 
892 
893 
894 
895 void GetSpruceTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks, bool a_Large)
896 {
897  if (a_Large)
898  {
899  GetLargeSpruceTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
900  }
901  else
902  {
903  GetSmallSpruceTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
904  }
905 
906 }
907 
908 
909 
910 
911 
912 void GetPineTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks, bool a_Large)
913 {
914  if (a_Large)
915  {
916  GetLargePineTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
917  }
918  else
919  {
920  GetSmallPineTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
921  }
922 
923 }
924 
925 
926 
927 
928 
929 void GetSmallSpruceTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
930 {
931  // Spruces have a top section with layer sizes of (0, 1, 0) or only (1, 0),
932  // then 1 - 3 sections of ascending sizes (1, 2) [most often], (1, 3) or (1, 2, 3)
933  // and an optional bottom section of size 1, followed by 1 - 3 clear trunk blocks
934 
935  // We'll use bits from this number as partial random numbers; but the noise function has mod8 irregularities
936  // (each of the mod8 remainders has a very different chance of occurrence) - that's why we divide by 8
937  int MyRandom = a_Noise.IntNoise3DInt(a_BlockPos.addedX(32 * a_Seq).addedY(32 * a_Seq)) / 8;
938 
939  static const HEIGHTTYPE sHeights[] = {1, 2, 2, 3};
940  HEIGHTTYPE Height = sHeights[MyRandom & 3];
941  MyRandom >>= 2;
942 
943  // Prealloc, so that we don't realloc too often later:
944  a_LogBlocks.reserve(static_cast<size_t>(Height));
945  a_OtherBlocks.reserve(180);
946 
947  // Clear trunk blocks:
948  for (int i = 0; i < Height; i++)
949  {
950  a_LogBlocks.emplace_back(a_BlockPos.addedY(i), E_BLOCK_LOG, E_META_LOG_CONIFER);
951  }
952  Height += static_cast<HEIGHTTYPE>(a_BlockPos.y);
953 
954  // Optional size-1 bottom leaves layer:
955  if ((MyRandom & 1) == 0)
956  {
957  PushCoordBlocks(a_BlockPos.x, Height, a_BlockPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
958  a_OtherBlocks.emplace_back(a_BlockPos.x, Height, a_BlockPos.z, E_BLOCK_LOG, E_META_LOG_CONIFER);
959  Height++;
960  }
961  MyRandom >>= 1;
962 
963  // 1 to 3 sections of leaves layers:
964  static const int sNumSections[] = {1, 2, 2, 3};
965  int NumSections = sNumSections[MyRandom & 3];
966  MyRandom >>= 2;
967  for (int i = 0; i < NumSections; i++)
968  {
969  switch (MyRandom & 3) // SectionType; (1, 2) twice as often as the other two
970  {
971  case 0:
972  case 1:
973  {
974  PushCoordBlocks(a_BlockPos.x, Height, a_BlockPos.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
975  PushCoordBlocks(a_BlockPos.x, Height + 1, a_BlockPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
976  a_LogBlocks.emplace_back(a_BlockPos.x, Height, a_BlockPos.z, E_BLOCK_LOG, E_META_LOG_CONIFER);
977  a_LogBlocks.emplace_back(a_BlockPos.x, Height + 1, a_BlockPos.z, E_BLOCK_LOG, E_META_LOG_CONIFER);
978  Height += 2;
979  break;
980  }
981  case 2:
982  {
983  PushCoordBlocks(a_BlockPos.x, Height, a_BlockPos.z, a_OtherBlocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
984  PushCoordBlocks(a_BlockPos.x, Height + 1, a_BlockPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
985  a_LogBlocks.emplace_back(a_BlockPos.x, Height, a_BlockPos.z, E_BLOCK_LOG, E_META_LOG_CONIFER);
986  a_LogBlocks.emplace_back(a_BlockPos.x, Height + 1, a_BlockPos.z, E_BLOCK_LOG, E_META_LOG_CONIFER);
987  Height += 2;
988  break;
989  }
990  case 3:
991  {
992  PushCoordBlocks(a_BlockPos.x, Height, a_BlockPos.z, a_OtherBlocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
993  PushCoordBlocks(a_BlockPos.x, Height + 1, a_BlockPos.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
994  PushCoordBlocks(a_BlockPos.x, Height + 2, a_BlockPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
995  a_LogBlocks.emplace_back(a_BlockPos.x, Height, a_BlockPos.z, E_BLOCK_LOG, E_META_LOG_CONIFER);
996  a_LogBlocks.emplace_back(a_BlockPos.x, Height + 1, a_BlockPos.z, E_BLOCK_LOG, E_META_LOG_CONIFER);
997  a_LogBlocks.emplace_back(a_BlockPos.x, Height + 2, a_BlockPos.z, E_BLOCK_LOG, E_META_LOG_CONIFER);
998  Height += 3;
999  break;
1000  }
1001  } // switch (SectionType)
1002  MyRandom >>= 2;
1003  } // for i - Sections
1004 
1005  if ((MyRandom & 1) == 0)
1006  {
1007  // (0, 1, 0) top:
1008  a_LogBlocks.emplace_back (a_BlockPos.x, Height, a_BlockPos.z, E_BLOCK_LOG, E_META_LOG_CONIFER);
1009  PushCoordBlocks (a_BlockPos.x, Height + 1, a_BlockPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
1010  a_OtherBlocks.emplace_back(a_BlockPos.x, Height + 1, a_BlockPos.z, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
1011  a_OtherBlocks.emplace_back(a_BlockPos.x, Height + 2, a_BlockPos.z, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
1012  }
1013  else
1014  {
1015  // (1, 0) top:
1016  a_OtherBlocks.emplace_back(a_BlockPos.x, Height, a_BlockPos.z, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
1017  PushCoordBlocks (a_BlockPos.x, Height + 1, a_BlockPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
1018  a_OtherBlocks.emplace_back(a_BlockPos.x, Height + 1, a_BlockPos.z, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
1019  }
1020 }
1021 
1022 
1023 
1024 
1025 
1026 static void LargeSpruceAddRing(Vector3i a_BlockPos, int & a_Height, const sCoordsArr* const a_Ring, size_t a_RingCount, sSetBlockVector & a_OtherBlocks)
1027 {
1028  for (size_t i = 0; i < a_RingCount ; i++)
1029  {
1030  PushCoordBlocks(a_BlockPos.x, a_Height--, a_BlockPos.z, a_OtherBlocks, a_Ring[a_RingCount - 1 - i].Coords, a_Ring[a_RingCount - 1 - i].Count, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
1031  }
1032 }
1033 
1034 
1035 
1036 
1037 
1040 void GetLargeSpruceTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
1041 {
1042  int Height = 20 + (a_Noise.IntNoise3DInt(a_BlockPos.addedXZ(32 * a_Seq, 32 * a_Seq)) / 11) % 12;
1043  int LeavesRingCount =
1045  (a_Noise.IntNoise3DInt(a_BlockPos.addedXZ(32 * a_Seq, 32 * a_Seq)) / 13) % (1 + MAX_LARGE_SPRUCE_TREE_RINGS - MIN_LARGE_SPRUCE_TREE_RINGS);
1046 
1047  int RingRadius = 0;
1048 
1049  a_LogBlocks.reserve(static_cast<size_t>(Height) * 4);
1050  a_OtherBlocks.reserve(ARRAYCOUNT(BigO1Spruce) + ARRAYCOUNT(TopLargePine) +
1052 
1053  for (int i = 0; i < Height; i++)
1054  {
1055  a_LogBlocks.emplace_back(a_BlockPos.addedY(i), E_BLOCK_LOG, E_META_LOG_CONIFER);
1056  a_LogBlocks.emplace_back(a_BlockPos.addedY(i).addedX(1), E_BLOCK_LOG, E_META_LOG_CONIFER);
1057  a_LogBlocks.emplace_back(a_BlockPos.addedY(i).addedZ(1), E_BLOCK_LOG, E_META_LOG_CONIFER);
1058  a_LogBlocks.emplace_back(a_BlockPos.addedY(i).addedXZ(1, 1), E_BLOCK_LOG, E_META_LOG_CONIFER);
1059  }
1060  int hei = a_BlockPos.y + Height - 1;
1061 
1062  // Prevent floating trees by placing dirt under them
1063  for (int i = 1; i < 5; i++)
1064  {
1065  a_OtherBlocks.emplace_back(a_BlockPos.addedY(-i), E_BLOCK_DIRT, E_META_DIRT_NORMAL);
1066  a_OtherBlocks.emplace_back(a_BlockPos.addedY(-i).addedX(1), E_BLOCK_DIRT, E_META_DIRT_NORMAL);
1067  a_OtherBlocks.emplace_back(a_BlockPos.addedY(-i).addedZ(1), E_BLOCK_DIRT, E_META_DIRT_NORMAL);
1068  a_OtherBlocks.emplace_back(a_BlockPos.addedY(-i).addedXZ(1, 1), E_BLOCK_DIRT, E_META_DIRT_NORMAL);
1069  }
1070 
1071  // Place the top.
1072  for (size_t i = 0; i < ARRAYCOUNT(BigOSpruceTop); i++)
1073  {
1074  PushCoordBlocks(a_BlockPos.x, hei++, a_BlockPos.z, a_OtherBlocks, BigOSpruceTop[i].Coords, BigOSpruceTop[i].Count, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
1075  }
1076 
1077  hei = a_BlockPos.y + Height - 2;
1078 
1079  for (int i = 0; i < LeavesRingCount; i++)
1080  {
1081  unsigned int Val = static_cast<unsigned int>(a_Noise.IntNoise3DInt(a_BlockPos.addedXZ(32 * a_Seq, 32 * i)) / 23) % 8;
1082  if ((Val < 4) && RingRadius < 3)
1083  {
1084  RingRadius++;
1085  }
1086  else if ((Val == 7) && (RingRadius > 0))
1087  {
1088  RingRadius--;
1089  }
1090 
1091  switch (RingRadius)
1092  {
1093  case 0:
1094  {
1095  LargeSpruceAddRing(a_BlockPos, hei, BigOSpruceLayersV1, ARRAYCOUNT(BigOSpruceLayersV1), a_OtherBlocks);
1096  break;
1097  }
1098  case 1:
1099  {
1100  LargeSpruceAddRing(a_BlockPos, hei, BigOSpruceLayersV2, ARRAYCOUNT(BigOSpruceLayersV2), a_OtherBlocks);
1101  break;
1102  }
1103  case 2:
1104  {
1105  LargeSpruceAddRing(a_BlockPos, hei, BigOSpruceLayersV3, ARRAYCOUNT(BigOSpruceLayersV3), a_OtherBlocks);
1106  break;
1107  }
1108  case 3:
1109  {
1110  LargeSpruceAddRing(a_BlockPos, hei, BigOSpruceLayersV4, ARRAYCOUNT(BigOSpruceLayersV4), a_OtherBlocks);
1111  break;
1112  }
1113  default:
1114  {
1115  break;
1116  }
1117  }
1118 
1119  if (hei - a_BlockPos.y <= 2)
1120  {
1121  break;
1122  }
1123 
1124  }
1125 }
1126 
1127 
1128 
1129 
1130 
1131 void GetSmallPineTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
1132 {
1133  // Tall, little leaves on top. The top leaves are arranged in a shape of two cones joined by their bases.
1134  // There can be one or two layers representing the cone bases (SameSizeMax)
1135 
1136  int MyRandom = a_Noise.IntNoise3DInt(a_BlockPos.addedXZ(32 * a_Seq, 32 * a_Seq)) / 8;
1137  int TrunkHeight = 8 + (MyRandom % 3);
1138  int SameSizeMax = ((MyRandom & 8) == 0) ? 1 : 0;
1139  MyRandom >>= 3;
1140  int NumLeavesLayers = 2 + (MyRandom % 3); // Number of layers that have leaves in them
1141  if (NumLeavesLayers == 2)
1142  {
1143  SameSizeMax = 0;
1144  }
1145 
1146  // Pre-allocate the vector:
1147  a_LogBlocks.reserve(static_cast<size_t>(TrunkHeight));
1148  a_OtherBlocks.reserve(static_cast<size_t>(NumLeavesLayers * 25));
1149 
1150  // The entire trunk, out of logs:
1151  for (int i = TrunkHeight; i >= 0; --i)
1152  {
1153  a_LogBlocks.emplace_back(a_BlockPos.addedY(i), E_BLOCK_LOG, E_META_LOG_CONIFER);
1154  }
1155  int h = a_BlockPos.y + TrunkHeight + 2;
1156 
1157  // Top layer - just a single leaves block:
1158  a_OtherBlocks.emplace_back(a_BlockPos.x, h, a_BlockPos.z, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
1159  h--;
1160 
1161  // One more layer is above the trunk, push the central leaves:
1162  a_OtherBlocks.emplace_back(a_BlockPos.x, h, a_BlockPos.z, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
1163 
1164  // Layers expanding in size, then collapsing again:
1165  // LOGD("Generating %d layers of pine leaves, SameSizeMax = %d", NumLeavesLayers, SameSizeMax);
1166  for (int i = 0; i < NumLeavesLayers; ++i)
1167  {
1168  int LayerSize = std::min(i, NumLeavesLayers - i + SameSizeMax - 1);
1169  // LOGD("LayerSize %d: %d", i, LayerSize);
1170  if (LayerSize < 0)
1171  {
1172  break;
1173  }
1174  ASSERT(static_cast<size_t>(LayerSize) < ARRAYCOUNT(BigOLayers));
1175  PushCoordBlocks(a_BlockPos.x, h, a_BlockPos.z, a_OtherBlocks, BigOLayers[LayerSize].Coords, BigOLayers[LayerSize].Count, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
1176  h--;
1177  }
1178 }
1179 
1180 
1181 
1182 
1183 
1184 void GetLargePineTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
1185 {
1186  int Height = 20 + (a_Noise.IntNoise3DInt(a_BlockPos.addedXZ(32 * a_Seq, 32 * a_Seq)) / 11) % 12;
1187 
1188  a_LogBlocks.reserve(static_cast<size_t>(Height) * 4);
1190 
1191  for (int i = 0; i < Height; i++)
1192  {
1193  a_LogBlocks.emplace_back(a_BlockPos.addedY(i), E_BLOCK_LOG, E_META_LOG_CONIFER);
1194  a_LogBlocks.emplace_back(a_BlockPos.addedY(i).addedX(1), E_BLOCK_LOG, E_META_LOG_CONIFER);
1195  a_LogBlocks.emplace_back(a_BlockPos.addedY(i).addedZ(1), E_BLOCK_LOG, E_META_LOG_CONIFER);
1196  a_LogBlocks.emplace_back(a_BlockPos.addedY(i).addedXZ(1, 1), E_BLOCK_LOG, E_META_LOG_CONIFER);
1197  }
1198  int hei = a_BlockPos.y + Height - 2;
1199 
1200  // Prevent floating trees by placing dirt under them
1201  for (int i = 1; i < 5; i++)
1202  {
1203  a_OtherBlocks.emplace_back(a_BlockPos.addedY(-i), E_BLOCK_DIRT, E_META_DIRT_NORMAL);
1204  a_OtherBlocks.emplace_back(a_BlockPos.addedY(-i).addedX(1), E_BLOCK_DIRT, E_META_DIRT_NORMAL);
1205  a_OtherBlocks.emplace_back(a_BlockPos.addedY(-i).addedZ(1), E_BLOCK_DIRT, E_META_DIRT_NORMAL);
1206  a_OtherBlocks.emplace_back(a_BlockPos.addedY(-i).addedXZ(1, 1), E_BLOCK_DIRT, E_META_DIRT_NORMAL);
1207  }
1208 
1209  // Place the canopy.
1210  for (size_t i = 0; i < ARRAYCOUNT(BigOPineLayers); i++)
1211  {
1212  PushCoordBlocks(a_BlockPos.x, hei++, a_BlockPos.z, a_OtherBlocks, BigOPineLayers[i].Coords, BigOPineLayers[i].Count, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
1213  }
1214 }
1215 
1216 
1217 
1218 
1219 
1220 void GetSwampTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
1221 {
1222  // Vines are around the BigO3, but not in the corners; need proper meta for direction
1223  static const sMetaCoords Vines[] =
1224  {
1225  {-2, -4, 1}, {-1, -4, 1}, {0, -4, 1}, {1, -4, 1}, {2, -4, 1}, // North face
1226  {-2, 4, 4}, {-1, 4, 4}, {0, 4, 4}, {1, 4, 4}, {2, 4, 4}, // South face
1227  {4, -2, 2}, {4, -1, 2}, {4, 0, 2}, {4, 1, 2}, {4, 2, 2}, // East face
1228  {-4, -2, 8}, {-4, -1, 8}, {-4, 0, 8}, {-4, 1, 8}, {-4, 2, 8}, // West face
1229  } ;
1230 
1231  int Height = 3 + (a_Noise.IntNoise3DInt(a_BlockPos.addedXZ(32 * a_Seq, 32 * a_Seq)) / 8) % 3;
1232 
1233  a_LogBlocks.reserve(static_cast<size_t>(Height));
1234  a_OtherBlocks.reserve(2 * ARRAYCOUNT(BigO2) + 2 * ARRAYCOUNT(BigO3) + static_cast<size_t>(Height) * ARRAYCOUNT(Vines) + 20);
1235 
1236  for (int i = 0; i < Height; i++)
1237  {
1238  a_LogBlocks.emplace_back(a_BlockPos.addedY(i), E_BLOCK_LOG, E_META_LOG_APPLE);
1239  }
1240  int hei = a_BlockPos.y + Height - 2;
1241 
1242  // Put vines around the lowermost leaves layer:
1243  PushSomeColumns(a_BlockPos.x, hei, a_BlockPos.z, Height, a_Seq, a_Noise, 0x3fffffff, a_OtherBlocks, Vines, ARRAYCOUNT(Vines), E_BLOCK_VINES);
1244 
1245  // The lower two leaves layers are BigO3 with log in the middle and possibly corners:
1246  for (int i = 0; i < 2; i++)
1247  {
1248  PushCoordBlocks(a_BlockPos.x, hei, a_BlockPos.z, a_OtherBlocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
1249  PushCornerBlocks(a_BlockPos.x, hei, a_BlockPos.z, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 3, E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
1250  hei++;
1251  } // for i - 2*
1252 
1253  // The upper two leaves layers are BigO2 with leaves in the middle and possibly corners:
1254  for (int i = 0; i < 2; i++)
1255  {
1256  PushCoordBlocks(a_BlockPos.x, hei, a_BlockPos.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
1257  PushCornerBlocks(a_BlockPos.x, hei, a_BlockPos.z, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 3, E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
1258  a_OtherBlocks.emplace_back(a_BlockPos.x, hei, a_BlockPos.z, E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
1259  hei++;
1260  } // for i - 2*
1261 }
1262 
1263 
1264 
1265 
1266 
1267 void GetAppleBushImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
1268 {
1269  a_OtherBlocks.reserve(3 + ARRAYCOUNT(BigO2) + ARRAYCOUNT(BigO1));
1270 
1271  int hei = a_BlockPos.y;
1272  a_LogBlocks.emplace_back(a_BlockPos.x, hei, a_BlockPos.z, E_BLOCK_LOG, E_META_LOG_JUNGLE);
1273  PushCoordBlocks(a_BlockPos.x, hei, a_BlockPos.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
1274  hei++;
1275 
1276  a_OtherBlocks.emplace_back(a_BlockPos.x, hei, a_BlockPos.z, E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
1277  PushCoordBlocks(a_BlockPos.x, hei, a_BlockPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
1278  hei++;
1279 
1280  a_OtherBlocks.emplace_back(a_BlockPos.x, hei, a_BlockPos.z, E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
1281 }
1282 
1283 
1284 
1285 
1286 
1287 void GetJungleTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks, bool a_Large)
1288 {
1289  if (!a_Large)
1290  {
1291  GetSmallJungleTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
1292  }
1293  else
1294  {
1295  GetLargeJungleTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
1296  }
1297 }
1298 
1299 
1300 
1301 
1302 
1303 void GetLargeJungleTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
1304 {
1305  static const sMetaCoords VinesTrunk[] =
1306  {
1307  {0, -1, 1}, {1, -1, 1}, // North face
1308  {0, 2, 4}, {1, 2, 4}, // South face
1309  {-1, 1, 8}, {-1, 0, 8}, // West face
1310  {2, 1, 2}, {2, 0, 2}, // East face
1311  };
1312 
1313  int Height = 10 + ((a_Noise.IntNoise3DInt(a_BlockPos.addedXZ(32 * a_Seq, 32 * a_Seq)) / 11) % 20); // 10 < Height < 29
1314 
1315  a_LogBlocks.reserve(static_cast<size_t>(Height) * 4);
1316  a_OtherBlocks.reserve(2 * ARRAYCOUNT(BigO5Jungle) + ARRAYCOUNT(BigO4Jungle) + ARRAYCOUNT(BigO3Jungle) + static_cast<size_t>(Height) * 4 + 50);
1317 
1318  // Generates the main trunk
1319  for (int i = 0; i < Height; i++)
1320  {
1321  a_LogBlocks.emplace_back(a_BlockPos.addedY(i), E_BLOCK_LOG, E_META_LOG_JUNGLE);
1322  a_LogBlocks.emplace_back(a_BlockPos.addedY(i).addedX(1), E_BLOCK_LOG, E_META_LOG_JUNGLE);
1323  a_LogBlocks.emplace_back(a_BlockPos.addedY(i).addedZ(1), E_BLOCK_LOG, E_META_LOG_JUNGLE);
1324  a_LogBlocks.emplace_back(a_BlockPos.addedY(i).addedXZ(1, 1), E_BLOCK_LOG, E_META_LOG_JUNGLE);
1325 
1326  // Randomly place vines around the trunk
1327  for (size_t j = 0; j < ARRAYCOUNT(VinesTrunk); j++)
1328  {
1329  if (a_Noise.IntNoise3DInt(a_BlockPos.addedXZ(VinesTrunk[j].x, VinesTrunk[j].z).addedY(i)) % 3 != 0)
1330  {
1331  continue;
1332  }
1333  a_OtherBlocks.emplace_back(a_BlockPos.addedXZ(VinesTrunk[j].x, VinesTrunk[j].z).addedY(i), E_BLOCK_VINES, VinesTrunk[j].Meta);
1334  }
1335  }
1336 
1337  // Prevent floating trees by placing dirt under them
1338  for (int i = 1; i < 5; i++)
1339  {
1340  a_OtherBlocks.emplace_back(a_BlockPos.addedY(-i), E_BLOCK_DIRT, E_META_DIRT_NORMAL);
1341  a_OtherBlocks.emplace_back(a_BlockPos.addedY(-i).addedX(1), E_BLOCK_DIRT, E_META_DIRT_NORMAL);
1342  a_OtherBlocks.emplace_back(a_BlockPos.addedY(-i).addedZ(1), E_BLOCK_DIRT, E_META_DIRT_NORMAL);
1343  a_OtherBlocks.emplace_back(a_BlockPos.addedY(-i).addedXZ(1, 1), E_BLOCK_DIRT, E_META_DIRT_NORMAL);
1344  }
1345 
1346  int NumBranches = std::max(
1347  (a_Noise.IntNoise2DInt(a_BlockPos.x * a_Seq, a_BlockPos.z * a_Seq) / 10) % 4, // The Original Calculation
1348  FloorC(Height / 10.0f) // Just to assure that no massive trees spawn with just one branch
1349  );
1350  int BranchStartHeight = 6 + Height % 5; // 6 < BranchStartHeight < 10
1351  int BranchInterval = (Height - 6 - BranchStartHeight) / NumBranches;
1352  for (int i = BranchStartHeight; i < (Height - 6); i += BranchInterval) // Stop 6 blocks before reaching the top
1353  {
1354  // Get a direction for the trunk to go to.
1355  Vector3d BranchStartDirection = pickBranchDirection(a_Noise, a_BlockPos.addedY(i), a_Seq);
1356  Vector3d BranchDirection = pickBranchDirection(a_Noise, a_BlockPos.addedY(i * a_Seq), a_Seq) / 3;
1357  int BranchLength = 2 + a_Noise.IntNoise3DInt(a_BlockPos * a_Seq) % 2;
1358  Vector3i BranchEndPosition = GetTreeBranch(E_BLOCK_LOG, E_META_LOG_JUNGLE, a_BlockPos.addedY(i), BranchLength, BranchStartDirection, BranchDirection, a_LogBlocks).Floor();
1359 
1360  // There's a chance that there is a third leaf level on a branch
1361  if ((a_Noise.IntNoise3DInt(a_BlockPos.x * a_Seq, a_BlockPos.y * a_Seq, a_BlockPos.z * a_Seq) % 4) == 0) // A quarter chance
1362  {
1363  PushCoordBlocks(BranchEndPosition.x, BranchEndPosition.y, BranchEndPosition.z, a_OtherBlocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
1364  PushCoordBlocks(BranchEndPosition.x, BranchEndPosition.y + 1, BranchEndPosition.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
1365  PushCoordBlocks(BranchEndPosition.x, BranchEndPosition.y + 2, BranchEndPosition.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
1366  a_OtherBlocks.emplace_back(BranchEndPosition.x, BranchEndPosition.y + 2, BranchEndPosition.z, E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
1367  }
1368  else
1369  {
1370  PushCoordBlocks(BranchEndPosition.x, BranchEndPosition.y, BranchEndPosition.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
1371  PushCoordBlocks(BranchEndPosition.x, BranchEndPosition.y + 1, BranchEndPosition.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
1372  a_OtherBlocks.emplace_back(BranchEndPosition.x, BranchEndPosition.y + 1, BranchEndPosition.z, E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
1373  }
1374  }
1375 
1376  // Place the canopy.
1377  int CanopyHeight = a_BlockPos.y + Height - 2;
1378  for (size_t i = 0; i < ARRAYCOUNT(BigOJungleLayers); i++)
1379  {
1380  PushCoordBlocks(a_BlockPos.x, CanopyHeight++, a_BlockPos.z, a_OtherBlocks, BigOJungleLayers[i].Coords, BigOJungleLayers[i].Count, E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
1381  }
1382 }
1383 
1384 
1385 
1386 
1387 
1388 void GetSmallJungleTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
1389 {
1390  // Vines are around the BigO3, but not in the corners; need proper meta for direction
1391  static const sMetaCoords Vines[] =
1392  {
1393  {-2, -4, 1}, {-1, -4, 1}, {0, -4, 1}, {1, -4, 1}, {2, -4, 1}, // North face
1394  {-2, 4, 4}, {-1, 4, 4}, {0, 4, 4}, {1, 4, 4}, {2, 4, 4}, // South face
1395  {4, -2, 2}, {4, -1, 2}, {4, 0, 2}, {4, 1, 2}, {4, 2, 2}, // East face
1396  {-4, -2, 8}, {-4, -1, 8}, {-4, 0, 8}, {-4, 1, 8}, // West face
1397  // TODO: proper metas and height: {0, 1, 1}, {0, -1, 4}, {-1, 0, 2}, {1, 1, 8}, // Around the tunk
1398  } ;
1399 
1400  int Height = 7 + (a_Noise.IntNoise3DInt(a_BlockPos.addedXZ(5 * a_Seq, 5 * a_Seq)) / 5) % 3;
1401 
1402  a_LogBlocks.reserve(static_cast<size_t>(Height));
1403  a_OtherBlocks.reserve(
1404  2 * ARRAYCOUNT(BigO3) + // O3 layer, 2x
1405  2 * ARRAYCOUNT(BigO2) + // O2 layer, 2x
1406  ARRAYCOUNT(BigO1) + 1 + // Plus on the top
1407  static_cast<size_t>(Height) * ARRAYCOUNT(Vines) + // Vines
1408  50 // some safety
1409  );
1410 
1411  for (int i = 0; i < Height; i++)
1412  {
1413  a_LogBlocks.emplace_back(a_BlockPos.addedY(i), E_BLOCK_LOG, E_META_LOG_JUNGLE);
1414  }
1415  int hei = a_BlockPos.y + Height - 3;
1416 
1417  // Put vines around the lowermost leaves layer:
1418  PushSomeColumns(a_BlockPos.x, hei, a_BlockPos.z, Height, a_Seq, a_Noise, 0x3fffffff, a_OtherBlocks, Vines, ARRAYCOUNT(Vines), E_BLOCK_VINES);
1419 
1420  // The lower two leaves layers are BigO3 with log in the middle and possibly corners:
1421  for (int i = 0; i < 2; i++)
1422  {
1423  PushCoordBlocks(a_BlockPos.x, hei, a_BlockPos.z, a_OtherBlocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
1424  PushCornerBlocks(a_BlockPos.x, hei, a_BlockPos.z, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 3, E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
1425  hei++;
1426  } // for i - 2*
1427 
1428  // Two layers of BigO2 leaves, possibly with corners:
1429  for (int i = 0; i < 1; i++)
1430  {
1431  PushCoordBlocks(a_BlockPos.x, hei, a_BlockPos.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
1432  PushCornerBlocks(a_BlockPos.x, hei, a_BlockPos.z, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 2, E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
1433  hei++;
1434  } // for i - 2*
1435 
1436  // Top plus, all leaves:
1437  PushCoordBlocks(a_BlockPos.x, hei, a_BlockPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
1438  a_OtherBlocks.emplace_back(a_BlockPos.x, hei, a_BlockPos.z, E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
1439 }
1440 
1441 
1442 
1443 
1444 
1445 void GetRedMushroomTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
1446 {
1447  static constexpr int Height = 4;
1448 
1449  for (int i = 0; i < Height; i++)
1450  {
1451  a_LogBlocks.emplace_back(a_BlockPos.addedY(i), E_BLOCK_HUGE_RED_MUSHROOM, E_META_MUSHROOM_STEM);
1452 
1453  if (i != 0)
1454  {
1455  // NORTH SIDE
1456  a_LogBlocks.emplace_back(a_BlockPos.addedY(i).addedXZ(-1, -2), E_BLOCK_HUGE_RED_MUSHROOM, E_META_MUSHROOM_NORTH_WEST);
1457  a_LogBlocks.emplace_back(a_BlockPos.addedY(i).addedXZ(0, -2), E_BLOCK_HUGE_RED_MUSHROOM, E_META_MUSHROOM_NORTH);
1458  a_LogBlocks.emplace_back(a_BlockPos.addedY(i).addedXZ(1, -2), E_BLOCK_HUGE_RED_MUSHROOM, E_META_MUSHROOM_NORTH_EAST);
1459  // WEST SIDE
1460  a_LogBlocks.emplace_back(a_BlockPos.addedY(i).addedXZ(-2, -1), E_BLOCK_HUGE_RED_MUSHROOM, E_META_MUSHROOM_NORTH_WEST);
1461  a_LogBlocks.emplace_back(a_BlockPos.addedY(i).addedXZ(-2, 0), E_BLOCK_HUGE_RED_MUSHROOM, E_META_MUSHROOM_WEST);
1462  a_LogBlocks.emplace_back(a_BlockPos.addedY(i).addedXZ(-2, 1), E_BLOCK_HUGE_RED_MUSHROOM, E_META_MUSHROOM_SOUTH_WEST);
1463  // SOUTH SIDE
1464  a_LogBlocks.emplace_back(a_BlockPos.addedY(i).addedXZ(-1, 2), E_BLOCK_HUGE_RED_MUSHROOM, E_META_MUSHROOM_SOUTH_WEST);
1465  a_LogBlocks.emplace_back(a_BlockPos.addedY(i).addedXZ(0, 2), E_BLOCK_HUGE_RED_MUSHROOM, E_META_MUSHROOM_SOUTH);
1466  a_LogBlocks.emplace_back(a_BlockPos.addedY(i).addedXZ(1, 2), E_BLOCK_HUGE_RED_MUSHROOM, E_META_MUSHROOM_SOUTH_EAST);
1467  // EAST SIDE
1468  a_LogBlocks.emplace_back(a_BlockPos.addedY(i).addedXZ(2, -1), E_BLOCK_HUGE_RED_MUSHROOM, E_META_MUSHROOM_NORTH_EAST);
1469  a_LogBlocks.emplace_back(a_BlockPos.addedY(i).addedXZ(2, 0), E_BLOCK_HUGE_RED_MUSHROOM, E_META_MUSHROOM_EAST);
1470  a_LogBlocks.emplace_back(a_BlockPos.addedY(i).addedXZ(2, 1), E_BLOCK_HUGE_RED_MUSHROOM, E_META_MUSHROOM_SOUTH_EAST);
1471  }
1472  }
1473 
1474  // Top Layer
1475  a_LogBlocks.emplace_back(a_BlockPos.addedY(Height).addedXZ(-1, -1), E_BLOCK_HUGE_RED_MUSHROOM, E_META_MUSHROOM_NORTH_WEST);
1476  a_LogBlocks.emplace_back(a_BlockPos.addedY(Height).addedX(-1), E_BLOCK_HUGE_RED_MUSHROOM, E_META_MUSHROOM_WEST);
1477  a_LogBlocks.emplace_back(a_BlockPos.addedY(Height).addedXZ(-1, 1), E_BLOCK_HUGE_RED_MUSHROOM, E_META_MUSHROOM_SOUTH_WEST);
1478 
1479  a_LogBlocks.emplace_back(a_BlockPos.addedY(Height).addedZ(-1), E_BLOCK_HUGE_RED_MUSHROOM, E_META_MUSHROOM_NORTH);
1480  a_LogBlocks.emplace_back(a_BlockPos.addedY(Height), E_BLOCK_HUGE_RED_MUSHROOM, E_META_MUSHROOM_CENTER);
1481  a_LogBlocks.emplace_back(a_BlockPos.addedY(Height).addedZ(1), E_BLOCK_HUGE_RED_MUSHROOM, E_META_MUSHROOM_SOUTH);
1482 
1483  a_LogBlocks.emplace_back(a_BlockPos.addedY(Height).addedXZ(1, -1), E_BLOCK_HUGE_RED_MUSHROOM, E_META_MUSHROOM_NORTH_EAST);
1484  a_LogBlocks.emplace_back(a_BlockPos.addedY(Height).addedX(1), E_BLOCK_HUGE_RED_MUSHROOM, E_META_MUSHROOM_EAST);
1485  a_LogBlocks.emplace_back(a_BlockPos.addedY(Height).addedXZ(1, 1), E_BLOCK_HUGE_RED_MUSHROOM, E_META_MUSHROOM_SOUTH_EAST);
1486 }
1487 
1488 
1489 
1490 
1491 
1492 void GetBrownMushroomTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
1493 {
1494  static constexpr int Height = 4;
1495  static constexpr int Radius = 2;
1496  static constexpr int Border = 3;
1497 
1498  for (int i = 0; i < Height; i++)
1499  {
1500  a_LogBlocks.emplace_back(a_BlockPos.addedY(i), E_BLOCK_HUGE_BROWN_MUSHROOM, E_META_MUSHROOM_STEM);
1501  }
1502 
1503  for (int x = -Radius; x <= Radius; x++)
1504  {
1505  for (int z = -Radius; z <= Radius; z++)
1506  {
1507  a_LogBlocks.emplace_back(a_BlockPos.addedY(Height).addedXZ(x, z), E_BLOCK_HUGE_BROWN_MUSHROOM, E_META_MUSHROOM_CENTER);
1508  }
1509  }
1510 
1511  for (int i = 0; i < Border; i++)
1512  {
1513  // NORTH SIDE
1514  a_LogBlocks.emplace_back(a_BlockPos.addedY(Height).addedXZ(-1, -3).addedX(i), E_BLOCK_HUGE_BROWN_MUSHROOM, E_META_MUSHROOM_NORTH);
1515  // WEST SIDE
1516  a_LogBlocks.emplace_back(a_BlockPos.addedY(Height).addedXZ(-3, -1).addedZ(i), E_BLOCK_HUGE_BROWN_MUSHROOM, E_META_MUSHROOM_WEST);
1517  // SOUTH SIDE
1518  a_LogBlocks.emplace_back(a_BlockPos.addedY(Height).addedXZ(-1, 3).addedX(i), E_BLOCK_HUGE_BROWN_MUSHROOM, E_META_MUSHROOM_SOUTH);
1519  // EAST SIDE
1520  a_LogBlocks.emplace_back(a_BlockPos.addedY(Height).addedXZ(3, -1).addedZ(i), E_BLOCK_HUGE_BROWN_MUSHROOM, E_META_MUSHROOM_EAST);
1521  }
1522 
1523  // Corners
1524  a_LogBlocks.emplace_back(a_BlockPos.addedY(Height).addedXZ(3, 2), E_BLOCK_HUGE_BROWN_MUSHROOM, E_META_MUSHROOM_SOUTH_EAST);
1525  a_LogBlocks.emplace_back(a_BlockPos.addedY(Height).addedXZ(2, 3), E_BLOCK_HUGE_BROWN_MUSHROOM, E_META_MUSHROOM_SOUTH_EAST);
1526 
1527  a_LogBlocks.emplace_back(a_BlockPos.addedY(Height).addedXZ(-2, 3), E_BLOCK_HUGE_BROWN_MUSHROOM, E_META_MUSHROOM_SOUTH_WEST);
1528  a_LogBlocks.emplace_back(a_BlockPos.addedY(Height).addedXZ(-3, 2), E_BLOCK_HUGE_BROWN_MUSHROOM, E_META_MUSHROOM_SOUTH_WEST);
1529 
1530  a_LogBlocks.emplace_back(a_BlockPos.addedY(Height).addedXZ(-2, -3), E_BLOCK_HUGE_BROWN_MUSHROOM, E_META_MUSHROOM_NORTH_WEST);
1531  a_LogBlocks.emplace_back(a_BlockPos.addedY(Height).addedXZ(-3, -2), E_BLOCK_HUGE_BROWN_MUSHROOM, E_META_MUSHROOM_NORTH_WEST);
1532 
1533  a_LogBlocks.emplace_back(a_BlockPos.addedY(Height).addedXZ(2, -3), E_BLOCK_HUGE_BROWN_MUSHROOM, E_META_MUSHROOM_NORTH_EAST);
1534  a_LogBlocks.emplace_back(a_BlockPos.addedY(Height).addedXZ(3, -2), E_BLOCK_HUGE_BROWN_MUSHROOM, E_META_MUSHROOM_NORTH_EAST);
1535 }
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
@ 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
@ biHell
Definition: BiomeDef.h:30
@ 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
@ biIcePlainsSpikes
Definition: BiomeDef.h:83
@ biFrozenOcean
Definition: BiomeDef.h:34
@ biExtremeHills
Definition: BiomeDef.h:25
@ biColdTaiga
Definition: BiomeDef.h:57
@ biSky
Definition: BiomeDef.h:32
@ 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_LEAVES_CONIFER
Definition: BlockType.h:703
@ E_META_MUSHROOM_CENTER
Definition: BlockType.h:721
@ E_META_LOG_JUNGLE
Definition: BlockType.h:742
@ E_META_DIRT_NORMAL
Definition: BlockType.h:639
@ E_META_MUSHROOM_STEM
Definition: BlockType.h:726
@ E_META_MUSHROOM_EAST
Definition: BlockType.h:722
@ E_META_LOG_APPLE
Definition: BlockType.h:739
@ E_META_NEW_LOG_ACACIA_WOOD
Definition: BlockType.h:745
@ E_META_MUSHROOM_SOUTH_EAST
Definition: BlockType.h:725
@ E_META_MUSHROOM_SOUTH_WEST
Definition: BlockType.h:723
@ E_META_MUSHROOM_WEST
Definition: BlockType.h:720
@ E_META_LEAVES_APPLE
Definition: BlockType.h:702
@ E_META_MUSHROOM_NORTH
Definition: BlockType.h:718
@ E_META_MUSHROOM_NORTH_WEST
Definition: BlockType.h:717
@ E_META_LEAVES_BIRCH
Definition: BlockType.h:704
@ E_META_LEAVES_JUNGLE
Definition: BlockType.h:705
@ E_META_MUSHROOM_NORTH_EAST
Definition: BlockType.h:719
@ E_META_LOG_BIRCH
Definition: BlockType.h:741
@ E_META_MUSHROOM_SOUTH
Definition: BlockType.h:724
@ E_META_NEWLEAVES_ACACIA
Definition: BlockType.h:731
@ E_META_LOG_CONIFER
Definition: BlockType.h:740
@ E_META_NEW_LOG_DARK_OAK_WOOD
Definition: BlockType.h:746
@ E_META_NEWLEAVES_DARK_OAK
Definition: BlockType.h:732
@ E_BLOCK_NEW_LEAVES
Definition: BlockType.h:180
@ E_BLOCK_LEAVES
Definition: BlockType.h:28
@ E_BLOCK_NEW_LOG
Definition: BlockType.h:181
@ E_BLOCK_HUGE_BROWN_MUSHROOM
Definition: BlockType.h:114
@ E_BLOCK_HUGE_RED_MUSHROOM
Definition: BlockType.h:115
@ E_BLOCK_VINES
Definition: BlockType.h:121
@ E_BLOCK_DIRT
Definition: BlockType.h:13
@ E_BLOCK_LOG
Definition: BlockType.h:27
std::vector< sSetBlock > sSetBlockVector
Definition: ChunkDef.h:441
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
void GetSmallPineTreeImage(Vector3i a_BlockPos, cNoise &a_Noise, int a_Seq, sSetBlockVector &a_LogBlocks, sSetBlockVector &a_OtherBlocks)
Fills a_LogBlocks and a_OtherBlocks (dirt & leaves) with the blocks required to form a random small p...
Definition: Trees.cpp:1131
static const sCoordsArr BigOLayers[]
Definition: Trees.cpp:203
static const sCoords BigO2Pine[]
Definition: Trees.cpp:165
static const sCoordsArr BigOSpruceLayersV1[]
Definition: Trees.cpp:226
static const sCoordsArr BigOSpruceLayersV3[]
Definition: Trees.cpp:238
static const sCoordsArr BigOSpruceLayersV4[]
Definition: Trees.cpp:244
static const sCoords TopLargePine[]
Definition: Trees.cpp:151
static const sCoords BigO4Jungle[]
Definition: Trees.cpp:121
static const sCoords BigO2[]
Definition: Trees.cpp:75
void GetPineTreeImage(Vector3i a_BlockPos, cNoise &a_Noise, int a_Seq, sSetBlockVector &a_LogBlocks, sSetBlockVector &a_OtherBlocks, bool a_Large)
Fills a_LogBlocks and a_OtherBlocks (dirt & leaves) with the blocks required to form a random pine.
Definition: Trees.cpp:912
Vector3d GetTreeBranch(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_BlockPos, int a_BranchLength, Vector3d a_StartDirection, Vector3d a_Direction, sSetBlockVector &a_LogBlocks)
Fills a_LogBlocks with the logs of a tree branch of the provided log type.
Definition: Trees.cpp:633
void PushCornerBlocks(int a_BlockX, int a_Height, int a_BlockZ, int a_Seq, cNoise &a_Noise, int a_Chance, sSetBlockVector &a_Blocks, int a_CornersDist, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta)
Definition: Trees.cpp:273
void GetAppleTreeImage(Vector3i a_BlockPos, cNoise &a_Noise, int a_Seq, sSetBlockVector &a_LogBlocks, sSetBlockVector &a_OtherBlocks)
Fills a_LogBlocks and a_OtherBlocks (dirt & leaves) with the blocks required to form a random apple t...
Definition: Trees.cpp:522
void GetSwampTreeImage(Vector3i a_BlockPos, cNoise &a_Noise, int a_Seq, sSetBlockVector &a_LogBlocks, sSetBlockVector &a_OtherBlocks)
Fills a_LogBlocks and a_OtherBlocks (dirt & leaves) with the blocks required to form a random swampla...
Definition: Trees.cpp:1220
static const sCoords BigO3[]
Definition: Trees.cpp:84
void GetTallBirchTreeImage(Vector3i a_BlockPos, cNoise &a_Noise, int a_Seq, sSetBlockVector &a_LogBlocks, sSetBlockVector &a_OtherBlocks)
Fills a_LogBlocks and a_OtherBlocks (dirt & leaves) with the blocks required to form a random large b...
Definition: Trees.cpp:840
static const sCoordsArr BigOSpruceLayersV2[]
Definition: Trees.cpp:232
const int MAX_LARGE_SPRUCE_TREE_RINGS
Definition: Trees.cpp:1039
static const sCoords BigO3Pine[]
Definition: Trees.cpp:175
void GetDarkoakTreeImage(Vector3i a_BlockPos, cNoise &a_Noise, int a_Seq, sSetBlockVector &a_LogBlocks, sSetBlockVector &a_OtherBlocks)
Fills a_LogBlocks and a_OtherBlocks (dirt & leaves) with the blocks required to form a random darkoak...
Definition: Trees.cpp:769
void GetAppleBushImage(Vector3i a_BlockPos, cNoise &a_Noise, int a_Seq, sSetBlockVector &a_LogBlocks, sSetBlockVector &a_OtherBlocks)
Fills a_LogBlocks and a_OtherBlocks (dirt & leaves) with the blocks required to form a random apple b...
Definition: Trees.cpp:1267
static const sCoordsArr BigOSpruceTop[]
Definition: Trees.cpp:250
void GetLargePineTreeImage(Vector3i a_BlockPos, cNoise &a_Noise, int a_Seq, sSetBlockVector &a_LogBlocks, sSetBlockVector &a_OtherBlocks)
Fills a_LogBlocks and a_OtherBlocks (dirt & leaves) with the blocks required to form a random large p...
Definition: Trees.cpp:1184
static const sCoords BigO4[]
Definition: Trees.cpp:96
static const sCoords BigO5Jungle[]
Definition: Trees.cpp:135
void GetBrownMushroomTreeImage(Vector3i a_BlockPos, cNoise &a_Noise, int a_Seq, sSetBlockVector &a_LogBlocks, sSetBlockVector &a_OtherBlocks)
Fills a_LogBlocks and a_OtherBlocks with the blocks required to form the brown mushroom.
Definition: Trees.cpp:1492
static const sCoords BigO1Spruce[]
Definition: Trees.cpp:187
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
void PushSomeColumns(int a_BlockX, int a_Height, int a_BlockZ, int a_ColumnHeight, int a_Seq, cNoise &a_Noise, int a_Chance, sSetBlockVector &a_Blocks, const sMetaCoords *a_Coords, size_t a_NumCoords, BLOCKTYPE a_BlockType)
Definition: Trees.cpp:290
void GetRedMushroomTreeImage(Vector3i a_BlockPos, cNoise &a_Noise, int a_Seq, sSetBlockVector &a_LogBlocks, sSetBlockVector &a_OtherBlocks)
Fills a_LogBlocks and a_OtherBlocks with the blocks required to form the red mushroom.
Definition: Trees.cpp:1445
static const sCoords Corners[]
Definition: Trees.cpp:26
static const sCoordsArr BigOJungleLayers[]
Definition: Trees.cpp:211
void GetLargeSpruceTreeImage(Vector3i a_BlockPos, cNoise &a_Noise, int a_Seq, sSetBlockVector &a_LogBlocks, sSetBlockVector &a_OtherBlocks)
Fills a_LogBlocks and a_OtherBlocks (dirt & leaves) with the blocks required to form a random large s...
Definition: Trees.cpp:1040
static const sCoords BigOF2Pine[]
Definition: Trees.cpp:157
static const Vector3d & pickBranchDirection(const cNoise a_Noise, Vector3i a_BlockPos, int a_Seq)
Chooses a direction for a branch to go to based on the start position (a_BlockPos) and a_Seq.
Definition: Trees.cpp:35
void GetSmallAppleTreeImage(Vector3i a_BlockPos, cNoise &a_Noise, int a_Seq, sSetBlockVector &a_LogBlocks, sSetBlockVector &a_OtherBlocks)
Fills a_LogBlocks and a_OtherBlocks (dirt & leaves) with the blocks required to form a small (nonbran...
Definition: Trees.cpp:538
void GetSmallSpruceTreeImage(Vector3i a_BlockPos, cNoise &a_Noise, int a_Seq, sSetBlockVector &a_LogBlocks, sSetBlockVector &a_OtherBlocks)
Fills a_LogBlocks and a_OtherBlocks (dirt & leaves) with the blocks required to form a random small s...
Definition: Trees.cpp:929
const int MIN_LARGE_SPRUCE_TREE_RINGS
Definition: Trees.cpp:1038
void GetSmallJungleTreeImage(Vector3i a_BlockPos, cNoise &a_Noise, int a_Seq, sSetBlockVector &a_LogBlocks, sSetBlockVector &a_OtherBlocks)
Fills a_LogBlocks and a_OtherBlocks (dirt & leaves) with the blocks required to form a small jungle t...
Definition: Trees.cpp:1388
void GetJungleTreeImage(Vector3i a_BlockPos, cNoise &a_Noise, int a_Seq, sSetBlockVector &a_LogBlocks, sSetBlockVector &a_OtherBlocks, bool a_Large)
Fills a_LogBlocks and a_OtherBlocks (dirt & leaves) with the blocks required to form a random jungle ...
Definition: Trees.cpp:1287
static const sCoords BigO1[]
Definition: Trees.cpp:68
void GetLargeJungleTreeImage(Vector3i a_BlockPos, cNoise &a_Noise, int a_Seq, sSetBlockVector &a_LogBlocks, sSetBlockVector &a_OtherBlocks)
Fills a_LogBlocks and a_OtherBlocks (dirt & leaves) with the blocks required to form a large jungle t...
Definition: Trees.cpp:1303
static const sCoords BigO3Jungle[]
Definition: Trees.cpp:109
void GetSpruceTreeImage(Vector3i a_BlockPos, cNoise &a_Noise, int a_Seq, sSetBlockVector &a_LogBlocks, sSetBlockVector &a_OtherBlocks, bool a_Large)
Fills a_LogBlocks and a_OtherBlocks (dirt & leaves) with the blocks required to form a random spruce.
Definition: Trees.cpp:895
void PushCoordBlocks(int a_BlockX, int a_Height, int a_BlockZ, sSetBlockVector &a_Blocks, const sCoords *a_Coords, size_t a_NumCoords, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta)
Pushes a specified layer of blocks of the same type around (x, h, z) into a_Blocks.
Definition: Trees.cpp:261
void GetConiferTreeImage(Vector3i a_BlockPos, cNoise &a_Noise, int a_Seq, sSetBlockVector &a_LogBlocks, sSetBlockVector &a_OtherBlocks, bool a_Large)
Fills a_LogBlocks and a_OtherBlocks (dirt & leaves) with the blocks required to form a random conifer...
Definition: Trees.cpp:878
static const sCoordsArr BigOPineLayers[]
Definition: Trees.cpp:218
void GetAcaciaTreeImage(Vector3i a_BlockPos, cNoise &a_Noise, int a_Seq, sSetBlockVector &a_LogBlocks, sSetBlockVector &a_OtherBlocks)
Fills a_LogBlocks and a_OtherBlocks (dirt & leaves) with the blocks required to form a random acacia ...
Definition: Trees.cpp:711
void GetBirchTreeImage(Vector3i a_BlockPos, cNoise &a_Noise, int a_Seq, sSetBlockVector &a_LogBlocks, sSetBlockVector &a_OtherBlocks)
Fills a_LogBlocks and a_OtherBlocks (dirt & leaves) with the blocks required to form a random birch t...
Definition: Trees.cpp:673
void GetLargeAppleTreeImage(Vector3i a_BlockPos, cNoise &a_Noise, int a_Seq, sSetBlockVector &a_LogBlocks, sSetBlockVector &a_OtherBlocks)
Fills a_LogBlocks and a_OtherBlocks (dirt & leaves) with the blocks required to form a large (branchi...
Definition: Trees.cpp:590
NIBBLETYPE GetLogMetaFromDirection(NIBBLETYPE a_BlockMeta, Vector3d a_Direction)
Returns the meta for a log from the given direction.
Definition: Trees.cpp:651
static void LargeSpruceAddRing(Vector3i a_BlockPos, int &a_Height, const sCoordsArr *const a_Ring, size_t a_RingCount, sSetBlockVector &a_OtherBlocks)
Definition: Trees.cpp:1026
#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
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
Direction
Vector3< double > Vector3d
Definition: Vector3.h:485
Vector3< int > Vector3i
Definition: Vector3.h:487
int x
Definition: Trees.cpp:17
int z
Definition: Trees.cpp:17
NIBBLETYPE Meta
Definition: Trees.cpp:23
size_t Count
Definition: Trees.cpp:200
const sCoords * Coords
Definition: Trees.cpp:199
Definition: Noise.h:20
NOISE_DATATYPE IntNoise2D(int a_X, int a_Y) const
Definition: Noise.h:198
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
Vector3< T > addedY(T a_AddY) const
Returns a copy of this vector moved by the specified amount on the y axis.
Definition: Vector3.h:314
T x
Definition: Vector3.h:17
Vector3< int > Floor(void) const
Returns a new Vector3i with coords set to std::floor() of this vector's coords.
Definition: Vector3.h:177
Vector3< T > addedXZ(T a_AddX, T a_AddZ) const
Returns a copy of this vector moved by the specified amount on the X and Z axes.
Definition: Vector3.h:326
T y
Definition: Vector3.h:17
Vector3< T > addedZ(T a_AddZ) const
Returns a copy of this vector moved by the specified amount on the Z axis.
Definition: Vector3.h:320
void Clamp(T a_Min, T a_Max)
Clamps each coord into the specified range.
Definition: Vector3.h:124
void Abs()
Updates each coord to its absolute value.
Definition: Vector3.h:116
T z
Definition: Vector3.h:17
Vector3< T > addedX(T a_AddX) const
Returns a copy of this vector moved by the specified amount on the X axis.
Definition: Vector3.h:308