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 
9 
10 
11 
12 
13 typedef struct
14 {
15  int x, z;
16 } sCoords;
17 
18 typedef struct
19 {
20  int x, z;
22 } sMetaCoords;
23 
24 static const sCoords Corners[] =
25 {
26  {-1, -1},
27  {-1, 1},
28  {1, -1},
29  {1, 1},
30 } ;
31 
33 static const Vector3d & pickBranchDirection(const cNoise a_Noise, Vector3i a_BlockPos, int a_Seq)
34 {
35  static const std::array<Vector3d, 32> directions =
36  {
37  {
38  { -1, 0, 0 }, { 0, 0, -1 },
39  { -1, 0, 1 }, { -1, 0, -1 },
40  { 1, 0, 1 }, { 1, 0, -1 },
41  { 1, 0, 0 }, { 0, 0, 1 },
42 
43  { -0.5, 0, 0 }, { 0, 0, -0.5 },
44  { -0.5, 0, 0.5 }, { -0.5, 0, -0.5 },
45  { 0.5, 0, 0.5 }, { 0.5, 0, -0.5 },
46  { 0.5, 0, 0 }, { 0, 0, 0.5 },
47 
48  { -1, 0.5, 0 }, { 0, 0.5, -1 },
49  { -1, 0.5, 1 }, { -1, 0.5, -1 },
50  { 1, 0.5, 1 }, { 1, 0.5, -1 },
51  { 1, 0.5, 0 }, { 0, 0.5, 1 },
52 
53  { -0.5, 0.5, 0 }, { 0, 0.5, -0.5 },
54  { -0.5, 0.5, 0.5 }, { -0.5, 0.5, -0.5 },
55  { 0.5, 0.5, 0.5 }, { 0.5, 0.5, -0.5 },
56  { 0.5, 0.5, 0 }, { 0, 0.5, 0.5 },
57  }
58  };
59 
60  size_t index = static_cast<size_t>(a_Noise.IntNoise3DInt(a_BlockPos.x, a_BlockPos.y + a_Seq, a_BlockPos.z)) % directions.size();
61  return directions[index];
62 }
63 
64 // BigO = a big ring of blocks, used for generating horz slices of treetops, the number indicates the radius
65 
66 static const sCoords BigO1[] =
67 {
68  /* -1 */ {0, -1},
69  /* 0 */ {-1, 0}, {1, 0},
70  /* 1 */ {0, 1},
71 } ;
72 
73 static const sCoords BigO2[] =
74 {
75  /* -2 */ {-1, -2}, {0, -2}, {1, -2},
76  /* -1 */ {-2, -1}, {-1, -1}, {0, -1}, {1, -1}, {2, -1},
77  /* 0 */ {-2, 0}, {-1, 0}, {1, 0}, {2, 0},
78  /* 1 */ {-2, 1}, {-1, 1}, {0, 1}, {1, 1}, {2, 1},
79  /* 2 */ {-1, 2}, {0, 2}, {1, 2},
80 } ;
81 
82 static const sCoords BigO3[] =
83 {
84  /* -3 */ {-2, -3}, {-1, -3}, {0, -3}, {1, -3}, {2, -3},
85  /* -2 */ {-3, -2}, {-2, -2}, {-1, -2}, {0, -2}, {1, -2}, {2, -2}, {3, -2},
86  /* -1 */ {-3, -1}, {-2, -1}, {-1, -1}, {0, -1}, {1, -1}, {2, -1}, {3, -1},
87  /* 0 */ {-3, 0}, {-2, 0}, {-1, 0}, {1, 0}, {2, 0}, {3, 0},
88  /* 1 */ {-3, 1}, {-2, 1}, {-1, 1}, {0, 1}, {1, 1}, {2, 1}, {3, 1},
89  /* 2 */ {-3, 2}, {-2, 2}, {-1, 2}, {0, 2}, {1, 2}, {2, 2}, {3, 2},
90  /* 3 */ {-2, 3}, {-1, 3}, {0, 3}, {1, 3}, {2, 3},
91 } ;
92 
93 
94 static const sCoords BigO4[] = // Part of dark oak tree
95 {
96  /* -4 */ {-2, -4}, {-1, -4}, {0, -4}, {1, -4}, {2, -4},
97  /* -3 */ {-3, -3}, {-2, -3}, {-1, -3}, {0, -3}, {1, -3}, {2, -3}, {3, -3},
98  /* -2 */ {-4, -2}, {-3, -2}, {-2, -2}, {-1, -2}, {0, -2}, {1, -2}, {2, -2}, {3, -2}, {4, -2},
99  /* -1 */ {-4, -1}, {-3, -1}, {-2, -1}, {-1, -1}, {0, -1}, {1, -1}, {2, -1}, {3, -1}, {4, -1},
100  /* 0 */ {-4, 0}, {-3, 0}, {-2, 0}, {-1, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0},
101  /* 1 */ {-4, 1}, {-3, 1}, {-2, 1}, {-1, 1}, {0, 1}, {1, 1}, {2, 1}, {3, 1}, {4, 1},
102  /* 2 */ {-4, 2}, {-3, 2}, {-2, 2}, {-1, 2}, {0, 2}, {1, 2}, {2, 2}, {3, 2}, {4, 2},
103  /* 3 */ {-3, 3}, {-2, 3}, {-1, 3}, {0, 3}, {1, 3}, {2, 3}, {3, 3},
104  /* 4 */ {-2, 4}, {-1, 4}, {0, 4}, {1, 4}, {2, 4},
105 };
106 
107 static const sCoords BigO3Jungle[] =
108 {
109  /* -3 */ {0, -3}, {1, -3},
110  /* -2 */ {-1, -2}, {0, -2}, {1, -2}, {2, -2},
111  /* -1 */ {-2, -1}, {-1, -1}, {0, -1}, {1, -1}, {2, -1}, {3, -1},
112  /* 0 */ {-3, 0}, {-2, 0}, {-1, 0}, {0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0},
113  /* 1 */ {-3, 1}, {-2, 1}, {-1, 1}, {0, 1}, {1, 1}, {2, 1}, {3, 1}, {4, 1},
114  /* 2 */ {-2, 2}, {-1, 2}, {0, 2}, {1, 2}, {2, 2}, {3, 2},
115  /* 3 */ {-1, 3}, {0, 3}, {1, 3}, {2, 3},
116  /* 4 */ {0, 4}, {1, 4},
117 };
118 
119 static const sCoords BigO4Jungle[] =
120 {
121  /* -4 */ {0, -4}, {1, -4},
122  /* -3 */ {-2, -3}, {-1, -3}, {0, -3}, {1, -3}, {2, -3}, {3, -3},
123  /* -2 */ {-3, -2}, {-2, -2}, {-1, -2}, {0, -2}, {1, -2}, {2, -2}, {3, -2}, {4, -2},
124  /* -1 */ {-3, -1}, {-2, -1}, {-1, -1}, {0, -1}, {1, -1}, {2, -1}, {3, -1}, {4, -1},
125  /* 0 */ {-4, 0}, {-3, 0}, {-2, 0}, {-1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0},
126  /* 1 */ {-4, 1}, {-3, 1}, {-2, 1}, {-1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1},
127  /* 2 */ {-3, 2}, {-2, 2}, {-1, 2}, {0, 2}, {1, 2}, {2, 2}, {3, 2}, {4, 2},
128  /* 3 */ {-3, 3}, {-2, 3}, {-1, 3}, {0, 3}, {1, 3}, {2, 3}, {3, 3}, {4, 3},
129  /* 4 */ {-2, 4}, {-1, 4}, {0, 4}, {1, 4}, {2, 4}, {3, 4},
130  /* 5 */ {0, 5}, {1, 5},
131 };
132 
133 static const sCoords BigO5Jungle[] =
134 {
135  /* -5 */ {0, -5}, {1, -5},
136  /* -4 */ {-2, -4}, {-1, -4}, {0, -4}, {1, -4}, {2, -4}, {3, -4},
137  /* -3 */ {-3, -3}, {-2, -3}, {-1, -3}, {0, -3}, {1, -3}, {2, -3}, {3, -3}, {4, -3},
138  /* -2 */ {-4, -2}, {-3, -2}, {-2, -2}, {-1, -2}, {0, -2}, {1, -2}, {2, -2}, {3, -2}, {4, -2}, {5, -2},
139  /* -1 */ {-4, -1}, {-3, -1}, {-2, -1}, {-1, -1}, {0, -1}, {1, -1}, {2, -1}, {3, -1}, {4, -1}, {5, -1},
140  /* 0 */ {-5, 0}, {-4, 0}, {-3, 0}, {-2, 0}, {-1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0},
141  /* 1 */ {-5, 1}, {-4, 1}, {-3, 1}, {-2, 1}, {-1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1}, {6, 1},
142  /* 2 */ {-4, 2}, {-3, 2}, {-2, 2}, {-1, 2}, {0, 2}, {1, 2}, {2, 2}, {3, 2}, {4, 2}, {5, 2},
143  /* 3 */ {-4, 3}, {-3, 3}, {-2, 3}, {-1, 3}, {0, 3}, {1, 3}, {2, 3}, {3, 3}, {4, 3}, {5, 3},
144  /* 4 */ {-3, 4}, {-2, 4}, {-1, 4}, {0, 4}, {1, 4}, {2, 4}, {3, 4}, {4, 4},
145  /* 5 */ {-2, 5}, {-1, 5}, {0, 5}, {1, 5}, {2, 5}, {3, 5},
146  /* 6 */ {0, 6}, {1, 6},
147 } ;
148 
149 
150 
151 
152 
153 typedef struct
154 {
155  const sCoords * Coords;
156  size_t Count;
157 } sCoordsArr;
158 
159 static const sCoordsArr BigOLayers[] =
160 {
161  {BigO1, ARRAYCOUNT(BigO1)},
162  {BigO2, ARRAYCOUNT(BigO2)},
163  {BigO3, ARRAYCOUNT(BigO3)},
164  {BigO4, ARRAYCOUNT(BigO4)},
165 } ;
166 
167 static const sCoordsArr BigOJungleLayers[] =
168 {
169  {BigO5Jungle, ARRAYCOUNT(BigO5Jungle)},
170  {BigO4Jungle, ARRAYCOUNT(BigO4Jungle)},
171  {BigO3Jungle, ARRAYCOUNT(BigO3Jungle)},
172 };
173 
174 
175 
176 
178 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)
179 {
180  for (size_t i = 0; i < a_NumCoords; i++)
181  {
182  a_Blocks.push_back(sSetBlock(a_BlockX + a_Coords[i].x, a_Height, a_BlockZ + a_Coords[i].z, a_BlockType, a_Meta));
183  }
184 }
185 
186 
187 
188 
189 
190 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)
191 {
192  for (size_t i = 0; i < ARRAYCOUNT(Corners); i++)
193  {
194  int x = a_BlockX + Corners[i].x;
195  int z = a_BlockZ + Corners[i].z;
196  if (a_Noise.IntNoise3DInt(x + 64 * a_Seq, a_Height, z + 64 * a_Seq) <= a_Chance)
197  {
198  a_Blocks.push_back(sSetBlock(x, a_Height, z, a_BlockType, a_Meta));
199  }
200  } // for i - Corners[]
201 }
202 
203 
204 
205 
206 
207 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)
208 {
209  for (size_t i = 0; i < a_NumCoords; i++)
210  {
211  int x = a_BlockX + a_Coords[i].x;
212  int z = a_BlockZ + a_Coords[i].z;
213  if (a_Noise.IntNoise3DInt(x + 64 * a_Seq, a_Height + static_cast<int>(i), z + 64 * a_Seq) <= a_Chance)
214  {
215  for (int j = 0; j < a_ColumnHeight; j++)
216  {
217  a_Blocks.push_back(sSetBlock(x, a_Height - j, z, a_BlockType, a_Coords[i].Meta));
218  }
219  }
220  } // for i - a_Coords[]
221 }
222 
223 
224 
225 
226 
227 void GetTreeImageByBiome(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, EMCSBiome a_Biome, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
228 {
229  switch (a_Biome)
230  {
231  case biPlains:
232  case biExtremeHills:
233  case biExtremeHillsEdge:
234  case biForest:
235  case biMushroomIsland:
236  case biMushroomShore:
237  case biForestHills:
238  case biDeepOcean:
239  case biStoneBeach:
240  case biColdBeach:
241  {
242  // Apple or birch trees:
243  if (a_Noise.IntNoise3DInt(a_BlockPos.addedY(16 * a_Seq).addedZ(16 * a_Seq)) < 0x5fffffff)
244  {
245  GetAppleTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
246  }
247  else
248  {
249  GetBirchTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
250  }
251  return;
252  }
253 
254  case biTaiga:
255  case biIcePlains:
256  case biIceMountains:
257  case biTaigaHills:
258  {
259  // Conifers
260  GetConiferTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
261  return;
262  }
263 
264  case biSwamplandM:
265  case biSwampland:
266  {
267  // Swamp trees:
268  GetSwampTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
269  return;
270  }
271 
272  case biJungle:
273  case biJungleHills:
274  case biJungleEdge:
275  {
276  // Apple bushes, large jungle trees, small jungle trees
277  if (a_Noise.IntNoise3DInt(a_BlockPos.addedY(16 * a_Seq).addedZ(16 * a_Seq)) < 0x6fffffff)
278  {
279  GetAppleBushImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
280  }
281  else
282  {
283  bool IsLarge = a_Noise.IntNoise3DInt(a_BlockPos.addedX(32 * a_Seq).addedY(32 * a_Seq)) < 0x60000000;
284  GetJungleTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks, IsLarge);
285  }
286  return;
287  }
288 
289  case biBirchForest:
290  case biBirchForestHills:
291  {
292  GetBirchTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
293  return;
294  }
295 
296  case biBirchForestM:
297  case biBirchForestHillsM:
298  {
299  GetTallBirchTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
300  return;
301  }
302 
303  case biColdTaiga:
304  case biColdTaigaHills:
305  case biMegaTaiga:
306  case biMegaTaigaHills:
307  case biExtremeHillsPlus:
308  case biSunflowerPlains:
309  case biDesertM:
310  case biExtremeHillsM:
311  case biFlowerForest:
312  case biTaigaM:
313  case biIcePlainsSpikes:
314  case biJungleM:
315  case biJungleEdgeM:
316  case biColdTaigaM:
317  case biMegaSpruceTaiga:
319  case biExtremeHillsPlusM:
320  {
321  // TODO: These need their special trees
322  GetBirchTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
323  return;
324  }
325 
326  case biSavanna:
327  case biSavannaPlateau:
328  case biSavannaM:
329  case biSavannaPlateauM:
330  {
331  GetAcaciaTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
332  return;
333  }
334 
335  case biRoofedForest:
336  case biRoofedForestM:
337  {
338  GetDarkoakTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
339  return;
340  }
341 
342  case biMesa:
343  case biMesaPlateauF:
344  case biMesaPlateau:
345  case biMesaBryce:
346  case biMesaPlateauFM:
347  case biMesaPlateauM:
348  {
349  GetSmallAppleTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
350  }
351 
352  case biDesert:
353  case biDesertHills:
354  case biRiver:
355  case biBeach:
356  case biHell:
357  case biSky:
358  case biOcean:
359  case biFrozenOcean:
360  case biFrozenRiver:
361  case biVariant:
362  case biNumBiomes:
363  case biNumVariantBiomes:
364  case biInvalidBiome:
365  {
366  // These biomes have no trees, or are non-biome members of the enum.
367  return;
368  }
369  }
370 
371  ASSERT(!"Invalid biome type!");
372 }
373 
374 
375 
376 
377 
378 void GetAppleTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
379 {
380  if (a_Noise.IntNoise3DInt(a_BlockPos.addedX(32 * a_Seq).addedY(32 * a_Seq)) < 0x60000000)
381  {
382  GetSmallAppleTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
383  }
384  else
385  {
386  GetLargeAppleTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
387  }
388 }
389 
390 
391 
392 
393 
394 void GetSmallAppleTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
395 {
396  /* Small apple tree has:
397  - a top plus (no log)
398  - optional BigO1 + random corners (log)
399  - 2 layers of BigO2 + random corners (log)
400  - 1 to 3 blocks of trunk
401  */
402 
403  int Random = a_Noise.IntNoise3DInt(a_BlockPos.addedX(64 * a_Seq)) >> 3;
404  HEIGHTTYPE Heights[] = {1, 2, 2, 3} ;
405  HEIGHTTYPE Height = 1 + Heights[Random & 3];
406  Random >>= 2;
407 
408  // Pre-alloc so that we don't realloc too often later:
409  a_LogBlocks.reserve(static_cast<size_t>(Height + 5));
410  a_OtherBlocks.reserve(ARRAYCOUNT(BigO2) * 2 + ARRAYCOUNT(BigO1) + ARRAYCOUNT(Corners) * 3 + 3 + 5);
411 
412  // Trunk:
413  for (int i = 0; i < Height; i++)
414  {
415  a_LogBlocks.push_back(sSetBlock(a_BlockPos.addedY(i), E_BLOCK_LOG, E_META_LOG_APPLE));
416  }
417  int Hei = a_BlockPos.y + Height;
418 
419  // 2 BigO2 + corners layers:
420  for (int i = 0; i < 2; i++)
421  {
422  PushCoordBlocks (a_BlockPos.x, Hei, a_BlockPos.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
423  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);
424  a_LogBlocks.push_back(sSetBlock(a_BlockPos.x, Hei, a_BlockPos.z, E_BLOCK_LOG, E_META_LOG_APPLE));
425  Hei++;
426  } // for i - 2*
427 
428  // Optional BigO1 + corners layer:
429  if ((Random & 1) == 0)
430  {
431  PushCoordBlocks (a_BlockPos.x, Hei, a_BlockPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
432  PushCornerBlocks(a_BlockPos.x, Hei, a_BlockPos.z, a_Seq, a_Noise, 0x6000000, a_OtherBlocks, 1, E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
433  a_LogBlocks.push_back(sSetBlock(a_BlockPos.x, Hei, a_BlockPos.z, E_BLOCK_LOG, E_META_LOG_APPLE));
434  Hei++;
435  }
436 
437  // Top plus:
438  PushCoordBlocks(a_BlockPos.x, Hei, a_BlockPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
439  a_OtherBlocks.push_back(sSetBlock(a_BlockPos.x, Hei, a_BlockPos.z, E_BLOCK_LEAVES, E_META_LEAVES_APPLE));
440 }
441 
442 
443 
444 
445 
446 void GetLargeAppleTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
447 {
448  int Height = 7 + a_Noise.IntNoise3DInt(a_BlockPos) % 4;
449 
450  // Create branches
451  for (int i = 4; i < Height; i++)
452  {
453  // Get a direction for the trunk to go to.
454  Vector3d BranchStartDirection = pickBranchDirection(a_Noise, a_BlockPos.addedY(i), a_Seq);
455  Vector3d BranchDirection = pickBranchDirection(a_Noise, a_BlockPos.addedY(i * a_Seq), a_Seq) / 3;
456 
457  int BranchLength = 2 + a_Noise.IntNoise3DInt(a_BlockPos * a_Seq) % 3;
458  GetTreeBranch(E_BLOCK_LOG, E_META_LOG_APPLE, a_BlockPos.addedY(i), BranchLength, BranchStartDirection, BranchDirection, a_LogBlocks);
459  }
460 
461  // Place leaves around each log block
462  for (auto itr : a_LogBlocks)
463  {
464  // Get the log's X and Z coordinates
465  int X = itr.GetX();
466  int Z = itr.GetZ();
467 
468  a_OtherBlocks.push_back(sSetBlock(X, itr.m_RelY - 2, Z, E_BLOCK_LEAVES, E_META_LEAVES_APPLE));
469  PushCoordBlocks(X, itr.m_RelY - 2, Z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
470  for (int y = -1; y <= 1; y++)
471  {
472  PushCoordBlocks (X, itr.m_RelY + y, Z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
473  }
474  PushCoordBlocks(X, itr.m_RelY + 2, Z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
475  a_OtherBlocks.push_back(sSetBlock(X, itr.m_RelY + 2, Z, E_BLOCK_LEAVES, E_META_LEAVES_APPLE));
476  }
477 
478  // Trunk:
479  for (int i = 0; i < Height; i++)
480  {
481  a_LogBlocks.push_back(sSetBlock(a_BlockPos.addedY(i), E_BLOCK_LOG, E_META_LOG_APPLE));
482  }
483 }
484 
485 
486 
487 
488 
489 Vector3d GetTreeBranch(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_BlockPos, int a_BranchLength, Vector3d a_StartDirection, Vector3d a_Direction, sSetBlockVector & a_LogBlocks)
490 {
491  Vector3d CurrentPos = Vector3d(a_BlockPos);
492  Vector3d Direction = a_StartDirection;
493  for (int i = 0; i < a_BranchLength; i++)
494  {
495  CurrentPos += Direction;
496  Direction += a_Direction;
497  Direction.Clamp(-1.0, 1.0);
498  a_LogBlocks.push_back(sSetBlock(CurrentPos.Floor(), a_BlockType, GetLogMetaFromDirection(a_BlockMeta, Direction)));
499  }
500  return CurrentPos;
501 }
502 
503 
504 
505 
506 
508 {
509  a_Direction.Abs();
510 
511  if ((a_Direction.y > a_Direction.x) && (a_Direction.y > a_Direction.z))
512  {
513  return a_BlockMeta;
514  }
515  else if (a_Direction.x > a_Direction.z)
516  {
517  return a_BlockMeta + 4;
518  }
519  else
520  {
521  return a_BlockMeta + 8;
522  }
523 }
524 
525 
526 
527 
528 
529 void GetBirchTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
530 {
531  HEIGHTTYPE Height = 5 + (a_Noise.IntNoise3DInt(a_BlockPos.addedX(64 * a_Seq)) % 3);
532 
533  // Prealloc, so that we don't realloc too often later:
534  a_LogBlocks.reserve(static_cast<size_t>(Height));
535  a_OtherBlocks.reserve(80);
536 
537  // The entire trunk, out of logs:
538  for (int i = Height - 1; i >= 0; --i)
539  {
540  a_LogBlocks.push_back(sSetBlock(a_BlockPos.addedY(i), E_BLOCK_LOG, E_META_LOG_BIRCH));
541  }
542  int h = a_BlockPos.y + Height;
543 
544  // Top layer - just the Plus:
545  PushCoordBlocks(a_BlockPos.x, h, a_BlockPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH);
546  a_OtherBlocks.push_back(sSetBlock(a_BlockPos.x, h, a_BlockPos.z, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH)); // There's no log at this layer
547  h--;
548 
549  // Second layer - log, Plus and maybe Corners:
550  PushCoordBlocks (a_BlockPos.x, h, a_BlockPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH);
551  PushCornerBlocks(a_BlockPos.x, h, a_BlockPos.z, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 1, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH);
552  h--;
553 
554  // Third and fourth layers - BigO2 and maybe 2 * Corners:
555  for (int Row = 0; Row < 2; Row++)
556  {
557  PushCoordBlocks (a_BlockPos.x, h, a_BlockPos.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH);
558  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);
559  h--;
560  } // for Row - 2*
561 }
562 
563 
564 
565 
566 
567 void GetAcaciaTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
568 {
569  // Calculate a base height
570  int Height = 2 + (a_Noise.IntNoise3DInt(a_BlockPos) / 11 % 3);
571 
572  // Create the trunk
573  for (int i = 0; i < Height; i++)
574  {
575  a_LogBlocks.push_back(sSetBlock(a_BlockPos.addedY(i), E_BLOCK_NEW_LOG, E_META_NEW_LOG_ACACIA_WOOD));
576  }
577 
578  // Array with possible directions for a branch to go to.
579  const Vector3i AvailableDirections[] =
580  {
581  { -1, 1, 0 }, { 0, 1, -1 },
582  { -1, 1, 1 }, { -1, 1, -1 },
583  { 1, 1, 1 }, { 1, 1, -1 },
584  { 1, 1, 0 }, { 0, 1, 1 },
585  };
586 
587  // Get a direction for the trunk to go to.
588  Vector3i BranchDirection = AvailableDirections[a_Noise.IntNoise3DInt(a_BlockPos) % 8];
589 
590  // Calculate a height for the branch between 1 and 3
591  int BranchHeight = a_Noise.IntNoise3DInt(a_BlockPos) % 3 + 1;
592 
593  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();
594 
595  // Add the leaves to the top of the branch
596  PushCoordBlocks(BranchPos.x, BranchPos.y, BranchPos.z, a_OtherBlocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_ACACIA);
597  PushCoordBlocks(BranchPos.x, BranchPos.y + 1, BranchPos.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_ACACIA);
598  a_OtherBlocks.push_back(sSetBlock(BranchPos.x, BranchPos.y + 1, BranchPos.z, E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_ACACIA));
599 
600  // Choose if we have to add another branch
601  bool TwoTop = (a_Noise.IntNoise3D(a_BlockPos) < 0 ? true : false);
602  if (!TwoTop)
603  {
604  return;
605  }
606 
607  // Invert the direction of the previous branch.
608  BranchDirection = Vector3d(-BranchDirection.x, 1, -BranchDirection.z);
609 
610  // Calculate a new height for the second branch
611  BranchHeight = a_Noise.IntNoise3DInt(a_BlockPos * a_Seq) % 3 + 1;
612 
613  BranchPos = GetTreeBranch(E_BLOCK_NEW_LOG, E_META_NEW_LOG_ACACIA_WOOD, a_BlockPos.addedY(Height - 1), BranchHeight, BranchDirection, BranchDirection, a_LogBlocks).Floor();
614 
615  // And add the leaves ontop of the second branch
616  PushCoordBlocks(BranchPos.x, BranchPos.y, BranchPos.z, a_OtherBlocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_ACACIA);
617  PushCoordBlocks(BranchPos.x, BranchPos.y + 1, BranchPos.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_ACACIA);
618  a_OtherBlocks.push_back(sSetBlock(BranchPos.x, BranchPos.y + 1, BranchPos.z, E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_ACACIA));
619 }
620 
621 
622 
623 
624 
625 void GetDarkoakTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
626 {
627  // Pick a height
628  int Height = 5 + (a_Noise.IntNoise3DInt(a_BlockPos.addedX(32 * a_Seq).addedZ(32 * a_Seq)) / 11) % 4;
629 
630  // Create the trunk
631  for (int i = 0; i < Height; i++)
632  {
633  a_LogBlocks.push_back(sSetBlock(a_BlockPos.addedY(i), E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD));
634  a_LogBlocks.push_back(sSetBlock(a_BlockPos.addedX(1).addedY(i), E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD));
635  a_LogBlocks.push_back(sSetBlock(a_BlockPos.addedY(i).addedZ(1), E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD));
636  a_LogBlocks.push_back(sSetBlock(a_BlockPos.addedX(1).addedY(i).addedZ(1), E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD));
637  }
638 
639  // Prevent floating trees by placing dirt under them
640  for (int i = 1; i < 5; i++)
641  {
642  a_OtherBlocks.push_back(sSetBlock(a_BlockPos.addedY(-i), E_BLOCK_DIRT, E_META_DIRT_NORMAL));
643  a_OtherBlocks.push_back(sSetBlock(a_BlockPos.addedX(1).addedY(-i), E_BLOCK_DIRT, E_META_DIRT_NORMAL));
644  a_OtherBlocks.push_back(sSetBlock(a_BlockPos.addedY(-i).addedZ(1), E_BLOCK_DIRT, E_META_DIRT_NORMAL));
645  a_OtherBlocks.push_back(sSetBlock(a_BlockPos.addedX(1).addedY(-i).addedZ(1), E_BLOCK_DIRT, E_META_DIRT_NORMAL));
646  }
647 
648  // Create branches
649  for (int i = 0; i < 3; i++)
650  {
651  int x = (a_Noise.IntNoise3DInt(a_BlockPos.addedX(32 * a_Seq).addedZ(32 * a_Seq).addedY(i * a_Seq)) % 3) - 1;
652  int z = (a_Noise.IntNoise3DInt(a_BlockPos.addedX(-32 * a_Seq).addedZ(-32 * a_Seq).addedY(i * a_Seq)) % 3) - 1;
653 
654  // The branches would end up in the trunk.
655  if ((x >= a_BlockPos.x) && (x <= a_BlockPos.x + 1) && (z >= a_BlockPos.z) && (z <= a_BlockPos.z + 1))
656  {
657  NOISE_DATATYPE Val1 = a_Noise.IntNoise2D(x, z);
658  if (Val1 < 0)
659  {
660  x = a_BlockPos.x + ((Val1 < -0.5) ? -1 : 3);
661  }
662  else
663  {
664  z = a_BlockPos.z + ((Val1 < 0.5) ? -1 : 3);
665  }
666  }
667 
668  int y = Height - (a_Noise.IntNoise3DInt(a_BlockPos.addedX(x).addedZ(z).addedY(i * a_Seq)) % (Height - (Height / 4)));
669 
670  for (int Y = y; Y < Height; Y++)
671  {
672  a_LogBlocks.push_back(sSetBlock(a_BlockPos.addedX(x).addedY(Y).addedZ(z), E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD));
673  }
674  }
675 
676  int hei = a_BlockPos.y + Height - 2;
677 
678  // The lower two leaves layers are BigO4 with log in the middle and possibly corners:
679  for (int i = 0; i < 2; i++)
680  {
681  PushCoordBlocks(a_BlockPos.x, hei, a_BlockPos.z, a_OtherBlocks, BigO4, ARRAYCOUNT(BigO4), E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_DARK_OAK);
682  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);
683  hei++;
684  } // for i < 2
685 
686  // The top leaves layer is a BigO3 with leaves in the middle and possibly corners:
687  PushCoordBlocks(a_BlockPos.x, hei, a_BlockPos.z, a_OtherBlocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_DARK_OAK);
688  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);
689  a_OtherBlocks.push_back(sSetBlock(a_BlockPos.x, hei, a_BlockPos.z, E_BLOCK_NEW_LEAVES, E_META_NEWLEAVES_DARK_OAK));
690 }
691 
692 
693 
694 
695 
696 void GetTallBirchTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
697 {
698  HEIGHTTYPE Height = 9 + (a_Noise.IntNoise3DInt(a_BlockPos.addedX(64 * a_Seq)) % 3);
699 
700  // Prealloc, so that we don't realloc too often later:
701  a_LogBlocks.reserve(static_cast<size_t>(Height));
702  a_OtherBlocks.reserve(80);
703 
704  // The entire trunk, out of logs:
705  for (int i = Height - 1; i >= 0; --i)
706  {
707  a_LogBlocks.push_back(sSetBlock(a_BlockPos.addedY(i), E_BLOCK_LOG, E_META_LOG_BIRCH));
708  }
709  int h = a_BlockPos.y + Height;
710 
711  // Top layer - just the Plus:
712  PushCoordBlocks(a_BlockPos.x, h, a_BlockPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH);
713  a_OtherBlocks.push_back(sSetBlock(a_BlockPos.x, h, a_BlockPos.z, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH)); // There's no log at this layer
714  h--;
715 
716  // Second layer - log, Plus and maybe Corners:
717  PushCoordBlocks (a_BlockPos.x, h, a_BlockPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH);
718  PushCornerBlocks(a_BlockPos.x, h, a_BlockPos.z, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 1, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH);
719  h--;
720 
721  // Third and fourth layers - BigO2 and maybe 2 * Corners:
722  for (int Row = 0; Row < 2; Row++)
723  {
724  PushCoordBlocks (a_BlockPos.x, h, a_BlockPos.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH);
725  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);
726  h--;
727  } // for Row - 2*
728 }
729 
730 
731 
732 
733 
734 void GetConiferTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
735 {
736  // Half chance for a spruce, half for a pine:
737  if (a_Noise.IntNoise3DInt(a_BlockPos.addedX(64 * a_Seq).addedZ(32 * a_Seq)) < 0x40000000)
738  {
739  GetSpruceTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
740  }
741  else
742  {
743  GetPineTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
744  }
745 }
746 
747 
748 
749 
750 
751 void GetSpruceTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
752 {
753  // Spruces have a top section with layer sizes of (0, 1, 0) or only (1, 0),
754  // then 1 - 3 sections of ascending sizes (1, 2) [most often], (1, 3) or (1, 2, 3)
755  // and an optional bottom section of size 1, followed by 1 - 3 clear trunk blocks
756 
757  // We'll use bits from this number as partial random numbers; but the noise function has mod8 irregularities
758  // (each of the mod8 remainders has a very different chance of occurrence) - that's why we divide by 8
759  int MyRandom = a_Noise.IntNoise3DInt(a_BlockPos.addedX(32 * a_Seq).addedY(32 * a_Seq)) / 8;
760 
761  static const HEIGHTTYPE sHeights[] = {1, 2, 2, 3};
762  HEIGHTTYPE Height = sHeights[MyRandom & 3];
763  MyRandom >>= 2;
764 
765  // Prealloc, so that we don't realloc too often later:
766  a_LogBlocks.reserve(static_cast<size_t>(Height));
767  a_OtherBlocks.reserve(180);
768 
769  // Clear trunk blocks:
770  for (int i = 0; i < Height; i++)
771  {
772  a_LogBlocks.push_back(sSetBlock(a_BlockPos.addedY(i), E_BLOCK_LOG, E_META_LOG_CONIFER));
773  }
774  Height += a_BlockPos.y;
775 
776  // Optional size-1 bottom leaves layer:
777  if ((MyRandom & 1) == 0)
778  {
779  PushCoordBlocks(a_BlockPos.x, Height, a_BlockPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
780  a_OtherBlocks.push_back(sSetBlock(a_BlockPos.x, Height, a_BlockPos.z, E_BLOCK_LOG, E_META_LOG_CONIFER));
781  Height++;
782  }
783  MyRandom >>= 1;
784 
785  // 1 to 3 sections of leaves layers:
786  static const int sNumSections[] = {1, 2, 2, 3};
787  int NumSections = sNumSections[MyRandom & 3];
788  MyRandom >>= 2;
789  for (int i = 0; i < NumSections; i++)
790  {
791  switch (MyRandom & 3) // SectionType; (1, 2) twice as often as the other two
792  {
793  case 0:
794  case 1:
795  {
796  PushCoordBlocks(a_BlockPos.x, Height, a_BlockPos.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
797  PushCoordBlocks(a_BlockPos.x, Height + 1, a_BlockPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
798  a_LogBlocks.push_back(sSetBlock(a_BlockPos.x, Height, a_BlockPos.z, E_BLOCK_LOG, E_META_LOG_CONIFER));
799  a_LogBlocks.push_back(sSetBlock(a_BlockPos.x, Height + 1, a_BlockPos.z, E_BLOCK_LOG, E_META_LOG_CONIFER));
800  Height += 2;
801  break;
802  }
803  case 2:
804  {
805  PushCoordBlocks(a_BlockPos.x, Height, a_BlockPos.z, a_OtherBlocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
806  PushCoordBlocks(a_BlockPos.x, Height + 1, a_BlockPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
807  a_LogBlocks.push_back(sSetBlock(a_BlockPos.x, Height, a_BlockPos.z, E_BLOCK_LOG, E_META_LOG_CONIFER));
808  a_LogBlocks.push_back(sSetBlock(a_BlockPos.x, Height + 1, a_BlockPos.z, E_BLOCK_LOG, E_META_LOG_CONIFER));
809  Height += 2;
810  break;
811  }
812  case 3:
813  {
814  PushCoordBlocks(a_BlockPos.x, Height, a_BlockPos.z, a_OtherBlocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
815  PushCoordBlocks(a_BlockPos.x, Height + 1, a_BlockPos.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
816  PushCoordBlocks(a_BlockPos.x, Height + 2, a_BlockPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
817  a_LogBlocks.push_back(sSetBlock(a_BlockPos.x, Height, a_BlockPos.z, E_BLOCK_LOG, E_META_LOG_CONIFER));
818  a_LogBlocks.push_back(sSetBlock(a_BlockPos.x, Height + 1, a_BlockPos.z, E_BLOCK_LOG, E_META_LOG_CONIFER));
819  a_LogBlocks.push_back(sSetBlock(a_BlockPos.x, Height + 2, a_BlockPos.z, E_BLOCK_LOG, E_META_LOG_CONIFER));
820  Height += 3;
821  break;
822  }
823  } // switch (SectionType)
824  MyRandom >>= 2;
825  } // for i - Sections
826 
827  if ((MyRandom & 1) == 0)
828  {
829  // (0, 1, 0) top:
830  a_LogBlocks.push_back (sSetBlock(a_BlockPos.x, Height, a_BlockPos.z, E_BLOCK_LOG, E_META_LOG_CONIFER));
831  PushCoordBlocks (a_BlockPos.x, Height + 1, a_BlockPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
832  a_OtherBlocks.push_back(sSetBlock(a_BlockPos.x, Height + 1, a_BlockPos.z, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER));
833  a_OtherBlocks.push_back(sSetBlock(a_BlockPos.x, Height + 2, a_BlockPos.z, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER));
834  }
835  else
836  {
837  // (1, 0) top:
838  a_OtherBlocks.push_back(sSetBlock(a_BlockPos.x, Height, a_BlockPos.z, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER));
839  PushCoordBlocks (a_BlockPos.x, Height + 1, a_BlockPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
840  a_OtherBlocks.push_back(sSetBlock(a_BlockPos.x, Height + 1, a_BlockPos.z, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER));
841  }
842 }
843 
844 
845 
846 
847 
848 void GetPineTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
849 {
850  // Tall, little leaves on top. The top leaves are arranged in a shape of two cones joined by their bases.
851  // There can be one or two layers representing the cone bases (SameSizeMax)
852 
853  int MyRandom = a_Noise.IntNoise3DInt(a_BlockPos.addedXZ(32 * a_Seq, 32 * a_Seq)) / 8;
854  int TrunkHeight = 8 + (MyRandom % 3);
855  int SameSizeMax = ((MyRandom & 8) == 0) ? 1 : 0;
856  MyRandom >>= 3;
857  int NumLeavesLayers = 2 + (MyRandom % 3); // Number of layers that have leaves in them
858  if (NumLeavesLayers == 2)
859  {
860  SameSizeMax = 0;
861  }
862 
863  // Pre-allocate the vector:
864  a_LogBlocks.reserve(static_cast<size_t>(TrunkHeight));
865  a_OtherBlocks.reserve(static_cast<size_t>(NumLeavesLayers * 25));
866 
867  // The entire trunk, out of logs:
868  for (int i = TrunkHeight; i >= 0; --i)
869  {
870  a_LogBlocks.push_back(sSetBlock(a_BlockPos.addedY(i), E_BLOCK_LOG, E_META_LOG_CONIFER));
871  }
872  int h = a_BlockPos.y + TrunkHeight + 2;
873 
874  // Top layer - just a single leaves block:
875  a_OtherBlocks.push_back(sSetBlock(a_BlockPos.x, h, a_BlockPos.z, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER));
876  h--;
877 
878  // One more layer is above the trunk, push the central leaves:
879  a_OtherBlocks.push_back(sSetBlock(a_BlockPos.x, h, a_BlockPos.z, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER));
880 
881  // Layers expanding in size, then collapsing again:
882  // LOGD("Generating %d layers of pine leaves, SameSizeMax = %d", NumLeavesLayers, SameSizeMax);
883  for (int i = 0; i < NumLeavesLayers; ++i)
884  {
885  int LayerSize = std::min(i, NumLeavesLayers - i + SameSizeMax - 1);
886  // LOGD("LayerSize %d: %d", i, LayerSize);
887  if (LayerSize < 0)
888  {
889  break;
890  }
891  ASSERT(static_cast<size_t>(LayerSize) < ARRAYCOUNT(BigOLayers));
892  PushCoordBlocks(a_BlockPos.x, h, a_BlockPos.z, a_OtherBlocks, BigOLayers[LayerSize].Coords, BigOLayers[LayerSize].Count, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
893  h--;
894  }
895 }
896 
897 
898 
899 
900 
901 void GetSwampTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
902 {
903  // Vines are around the BigO3, but not in the corners; need proper meta for direction
904  static const sMetaCoords Vines[] =
905  {
906  {-2, -4, 1}, {-1, -4, 1}, {0, -4, 1}, {1, -4, 1}, {2, -4, 1}, // North face
907  {-2, 4, 4}, {-1, 4, 4}, {0, 4, 4}, {1, 4, 4}, {2, 4, 4}, // South face
908  {4, -2, 2}, {4, -1, 2}, {4, 0, 2}, {4, 1, 2}, {4, 2, 2}, // East face
909  {-4, -2, 8}, {-4, -1, 8}, {-4, 0, 8}, {-4, 1, 8}, {-4, 2, 8}, // West face
910  } ;
911 
912  int Height = 3 + (a_Noise.IntNoise3DInt(a_BlockPos.addedXZ(32 * a_Seq, 32 * a_Seq)) / 8) % 3;
913 
914  a_LogBlocks.reserve(static_cast<size_t>(Height));
915  a_OtherBlocks.reserve(2 * ARRAYCOUNT(BigO2) + 2 * ARRAYCOUNT(BigO3) + static_cast<size_t>(Height) * ARRAYCOUNT(Vines) + 20);
916 
917  for (int i = 0; i < Height; i++)
918  {
919  a_LogBlocks.push_back(sSetBlock(a_BlockPos.addedY(i), E_BLOCK_LOG, E_META_LOG_APPLE));
920  }
921  int hei = a_BlockPos.y + Height - 2;
922 
923  // Put vines around the lowermost leaves layer:
924  PushSomeColumns(a_BlockPos.x, hei, a_BlockPos.z, Height, a_Seq, a_Noise, 0x3fffffff, a_OtherBlocks, Vines, ARRAYCOUNT(Vines), E_BLOCK_VINES);
925 
926  // The lower two leaves layers are BigO3 with log in the middle and possibly corners:
927  for (int i = 0; i < 2; i++)
928  {
929  PushCoordBlocks(a_BlockPos.x, hei, a_BlockPos.z, a_OtherBlocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
930  PushCornerBlocks(a_BlockPos.x, hei, a_BlockPos.z, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 3, E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
931  hei++;
932  } // for i - 2*
933 
934  // The upper two leaves layers are BigO2 with leaves in the middle and possibly corners:
935  for (int i = 0; i < 2; i++)
936  {
937  PushCoordBlocks(a_BlockPos.x, hei, a_BlockPos.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
938  PushCornerBlocks(a_BlockPos.x, hei, a_BlockPos.z, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 3, E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
939  a_OtherBlocks.push_back(sSetBlock(a_BlockPos.x, hei, a_BlockPos.z, E_BLOCK_LEAVES, E_META_LEAVES_APPLE));
940  hei++;
941  } // for i - 2*
942 }
943 
944 
945 
946 
947 
948 void GetAppleBushImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
949 {
950  a_OtherBlocks.reserve(3 + ARRAYCOUNT(BigO2) + ARRAYCOUNT(BigO1));
951 
952  int hei = a_BlockPos.y;
953  a_LogBlocks.push_back(sSetBlock(a_BlockPos.x, hei, a_BlockPos.z, E_BLOCK_LOG, E_META_LOG_JUNGLE));
954  PushCoordBlocks(a_BlockPos.x, hei, a_BlockPos.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
955  hei++;
956 
957  a_OtherBlocks.push_back(sSetBlock(a_BlockPos.x, hei, a_BlockPos.z, E_BLOCK_LEAVES, E_META_LEAVES_APPLE));
958  PushCoordBlocks(a_BlockPos.x, hei, a_BlockPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
959  hei++;
960 
961  a_OtherBlocks.push_back(sSetBlock(a_BlockPos.x, hei, a_BlockPos.z, E_BLOCK_LEAVES, E_META_LEAVES_APPLE));
962 }
963 
964 
965 
966 
967 
968 void GetJungleTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks, bool a_Large)
969 {
970  if (!a_Large)
971  {
972  GetSmallJungleTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
973  }
974  else
975  {
976  GetLargeJungleTreeImage(a_BlockPos, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
977  }
978 }
979 
980 
981 
982 
983 
984 void GetLargeJungleTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
985 {
986  static const sMetaCoords VinesTrunk[] =
987  {
988  {0, -1, 1}, {1, -1, 1}, // North face
989  {0, 2, 4}, {1, 2, 4}, // South face
990  {-1, 1, 8}, {-1, 0, 8}, // West face
991  {2, 1, 2}, {2, 0, 2}, // East face
992  };
993 
994  int Height = 20 + (a_Noise.IntNoise3DInt(a_BlockPos.addedXZ(32 * a_Seq, 32 * a_Seq)) / 11) % 12;
995 
996  a_LogBlocks.reserve(static_cast<size_t>(Height) * 4);
997  a_OtherBlocks.reserve(2 * ARRAYCOUNT(BigO5Jungle) + ARRAYCOUNT(BigO4Jungle) + ARRAYCOUNT(BigO3Jungle) + static_cast<size_t>(Height) * 4 + 50);
998 
999  for (int i = 0; i < Height; i++)
1000  {
1001  a_LogBlocks.push_back(sSetBlock(a_BlockPos.addedY(i), E_BLOCK_LOG, E_META_LOG_JUNGLE));
1002  a_LogBlocks.push_back(sSetBlock(a_BlockPos.addedY(i).addedX(1), E_BLOCK_LOG, E_META_LOG_JUNGLE));
1003  a_LogBlocks.push_back(sSetBlock(a_BlockPos.addedY(i).addedZ(1), E_BLOCK_LOG, E_META_LOG_JUNGLE));
1004  a_LogBlocks.push_back(sSetBlock(a_BlockPos.addedY(i).addedXZ(1, 1), E_BLOCK_LOG, E_META_LOG_JUNGLE));
1005 
1006  // Randomly place vines around the trunk
1007  for (size_t j = 0; j < ARRAYCOUNT(VinesTrunk); j++)
1008  {
1009  if (a_Noise.IntNoise3DInt(a_BlockPos.addedXZ(VinesTrunk[j].x, VinesTrunk[j].z).addedY(i)) % 3 != 0)
1010  {
1011  continue;
1012  }
1013  a_OtherBlocks.push_back(sSetBlock(a_BlockPos.addedXZ(VinesTrunk[j].x, VinesTrunk[j].z).addedY(i), E_BLOCK_VINES, VinesTrunk[j].Meta));
1014  }
1015  }
1016  int hei = a_BlockPos.y + Height - 2;
1017 
1018  // Prevent floating trees by placing dirt under them
1019  for (int i = 1; i < 5; i++)
1020  {
1021  a_OtherBlocks.push_back(sSetBlock(a_BlockPos.addedY(-i), E_BLOCK_DIRT, E_META_DIRT_NORMAL));
1022  a_OtherBlocks.push_back(sSetBlock(a_BlockPos.addedY(-i).addedX(1), E_BLOCK_DIRT, E_META_DIRT_NORMAL));
1023  a_OtherBlocks.push_back(sSetBlock(a_BlockPos.addedY(-i).addedZ(1), E_BLOCK_DIRT, E_META_DIRT_NORMAL));
1024  a_OtherBlocks.push_back(sSetBlock(a_BlockPos.addedY(-i).addedXZ(1, 1), E_BLOCK_DIRT, E_META_DIRT_NORMAL));
1025  }
1026 
1027  int numBranches = (a_Noise.IntNoise2DInt(a_BlockPos.x * a_Seq, a_BlockPos.z * a_Seq) / 11) % 3 + 1;
1028  int branchStartHeight = 8 + Height % 11;
1029  int branchInterval = (Height - branchStartHeight) / numBranches;
1030  for (int i = branchStartHeight; i < (Height - 6); i += branchInterval)
1031  {
1032  // Get a direction for the trunk to go to.
1033  Vector3d BranchStartDirection = pickBranchDirection(a_Noise, a_BlockPos.addedY(i), a_Seq);
1034  Vector3d BranchDirection = pickBranchDirection(a_Noise, a_BlockPos.addedY(i * a_Seq), a_Seq) / 3;
1035 
1036  int BranchLength = 2 + a_Noise.IntNoise3DInt(a_BlockPos * a_Seq) % 2;
1037  Vector3i BranchEndPosition = GetTreeBranch(E_BLOCK_LOG, E_META_LOG_JUNGLE, a_BlockPos.addedY(i), BranchLength, BranchStartDirection, BranchDirection, a_LogBlocks).Floor();
1038  PushCoordBlocks(BranchEndPosition.x, BranchEndPosition.y, BranchEndPosition.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
1039  PushCoordBlocks(BranchEndPosition.x, BranchEndPosition.y + 1, BranchEndPosition.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
1040  a_OtherBlocks.push_back(sSetBlock(BranchEndPosition.x, BranchEndPosition.y + 1, BranchEndPosition.z, E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE));
1041  }
1042 
1043  // Place the canopy.
1044  for (size_t i = 0; i < ARRAYCOUNT(BigOJungleLayers); i++)
1045  {
1046  PushCoordBlocks(a_BlockPos.x, hei++, a_BlockPos.z, a_OtherBlocks, BigOJungleLayers[i].Coords, BigOJungleLayers[i].Count, E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
1047  }
1048 }
1049 
1050 
1051 
1052 
1053 
1054 void GetSmallJungleTreeImage(Vector3i a_BlockPos, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
1055 {
1056  // Vines are around the BigO3, but not in the corners; need proper meta for direction
1057  static const sMetaCoords Vines[] =
1058  {
1059  {-2, -4, 1}, {-1, -4, 1}, {0, -4, 1}, {1, -4, 1}, {2, -4, 1}, // North face
1060  {-2, 4, 4}, {-1, 4, 4}, {0, 4, 4}, {1, 4, 4}, {2, 4, 4}, // South face
1061  {4, -2, 2}, {4, -1, 2}, {4, 0, 2}, {4, 1, 2}, {4, 2, 2}, // East face
1062  {-4, -2, 8}, {-4, -1, 8}, {-4, 0, 8}, {-4, 1, 8}, // West face
1063  // TODO: proper metas and height: {0, 1, 1}, {0, -1, 4}, {-1, 0, 2}, {1, 1, 8}, // Around the tunk
1064  } ;
1065 
1066  int Height = 7 + (a_Noise.IntNoise3DInt(a_BlockPos.addedXZ(5 * a_Seq, 5 * a_Seq)) / 5) % 3;
1067 
1068  a_LogBlocks.reserve(static_cast<size_t>(Height));
1069  a_OtherBlocks.reserve(
1070  2 * ARRAYCOUNT(BigO3) + // O3 layer, 2x
1071  2 * ARRAYCOUNT(BigO2) + // O2 layer, 2x
1072  ARRAYCOUNT(BigO1) + 1 + // Plus on the top
1073  static_cast<size_t>(Height) * ARRAYCOUNT(Vines) + // Vines
1074  50 // some safety
1075  );
1076 
1077  for (int i = 0; i < Height; i++)
1078  {
1079  a_LogBlocks.push_back(sSetBlock(a_BlockPos.addedY(i), E_BLOCK_LOG, E_META_LOG_JUNGLE));
1080  }
1081  int hei = a_BlockPos.y + Height - 3;
1082 
1083  // Put vines around the lowermost leaves layer:
1084  PushSomeColumns(a_BlockPos.x, hei, a_BlockPos.z, Height, a_Seq, a_Noise, 0x3fffffff, a_OtherBlocks, Vines, ARRAYCOUNT(Vines), E_BLOCK_VINES);
1085 
1086  // The lower two leaves layers are BigO3 with log in the middle and possibly corners:
1087  for (int i = 0; i < 2; i++)
1088  {
1089  PushCoordBlocks(a_BlockPos.x, hei, a_BlockPos.z, a_OtherBlocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
1090  PushCornerBlocks(a_BlockPos.x, hei, a_BlockPos.z, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 3, E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
1091  hei++;
1092  } // for i - 2*
1093 
1094  // Two layers of BigO2 leaves, possibly with corners:
1095  for (int i = 0; i < 1; i++)
1096  {
1097  PushCoordBlocks(a_BlockPos.x, hei, a_BlockPos.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
1098  PushCornerBlocks(a_BlockPos.x, hei, a_BlockPos.z, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 2, E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
1099  hei++;
1100  } // for i - 2*
1101 
1102  // Top plus, all leaves:
1103  PushCoordBlocks(a_BlockPos.x, hei, a_BlockPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
1104  a_OtherBlocks.push_back(sSetBlock(a_BlockPos.x, hei, a_BlockPos.z, E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE));
1105 }
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:446
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:190
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:529
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:489
T x
Definition: Vector3.h:17
int x
Definition: Trees.cpp:15
Vector3< int > Floor(void) const
Returns a new Vector3i with coords set to std::floor() of this vector&#39;s coords.
Definition: Vector3.h:172
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:207
size_t Count
Definition: Trees.cpp:156
int IntNoise2DInt(int a_X, int a_Y) const
Definition: Noise.h:243
unsigned char BLOCKTYPE
The datatype used by blockdata.
Definition: ChunkDef.h:42
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:901
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:311
static const sCoords BigO2[]
Definition: Trees.cpp:73
static const sCoords BigO3[]
Definition: Trees.cpp:82
int IntNoise3DInt(int a_X, int a_Y, int a_Z) const
Definition: Noise.h:254
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:33
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
Definition: ChunkDef.h:45
void GetSpruceTreeImage(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 spruce ...
Definition: Trees.cpp:751
EMCSBiome
Biome IDs The first batch corresponds to the clientside biomes, used by MineCraft.
Definition: BiomeDef.h:21
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:948
unsigned char HEIGHTTYPE
The type used by the heightmap.
Definition: ChunkDef.h:48
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:1054
T y
Definition: Vector3.h:17
NIBBLETYPE Meta
Definition: Trees.cpp:21
T z
Definition: Vector3.h:17
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:984
static const sCoords Corners[]
Definition: Trees.cpp:24
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:299
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:293
void GetConiferTreeImage(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 conifer...
Definition: Trees.cpp:734
void Clamp(T a_Min, T a_Max)
Clamps each coord into the specified range.
Definition: Vector3.h:119
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:227
Direction
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:696
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:178
Vector3< double > Vector3d
Definition: Vector3.h:445
NOISE_DATATYPE IntNoise3D(int a_X, int a_Y, int a_Z) const
Definition: Noise.h:210
static const sCoords BigO5Jungle[]
Definition: Trees.cpp:133
float NOISE_DATATYPE
The datatype used by all the noise generators.
Definition: Noise.h:9
NIBBLETYPE GetLogMetaFromDirection(NIBBLETYPE a_BlockMeta, Vector3d a_Direction)
Returns the meta for a log from the given direction.
Definition: Trees.cpp:507
static const sCoords BigO3Jungle[]
Definition: Trees.cpp:107
#define ASSERT(x)
Definition: Globals.h:335
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:394
Definition: Noise.h:19
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:968
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:567
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:378
Definition: BiomeDef.h:36
static const sCoords BigO4Jungle[]
Definition: Trees.cpp:119
static const sCoordsArr BigOJungleLayers[]
Definition: Trees.cpp:167
static const sCoords BigO1[]
Definition: Trees.cpp:66
int z
Definition: Trees.cpp:15
Vector3< int > Vector3i
Definition: Vector3.h:447
void GetPineTreeImage(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 pine (t...
Definition: Trees.cpp:848
void Abs()
Updates each coord to its absolute value.
Definition: Vector3.h:111
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:625
NOISE_DATATYPE IntNoise2D(int a_X, int a_Y) const
Definition: Noise.h:198
#define ARRAYCOUNT(X)
Evaluates to the number of elements in an array (compile-time!)
Definition: Globals.h:290
std::vector< sSetBlock > sSetBlockVector
Definition: ChunkDef.h:564
const sCoords * Coords
Definition: Trees.cpp:155
static const sCoords BigO4[]
Definition: Trees.cpp:94
static const sCoordsArr BigOLayers[]
Definition: Trees.cpp:159