Cuberite
A lightweight, fast and extensible game server for Minecraft
ProtIntGen.h
Go to the documentation of this file.
1 
2 // ProtIntGen.h
3 
4 // Declares the prototyping integer generators - cProtIntGen class and its descendants
5 
6 /*
7 These classes generate 2D arrays of integers that have various interpretations. The main purpose of these
8 classes is to provide fast prototyping for cIntGen classes - unlike cIntGen classes, these are not
9 template-based and so they take care of the underlying sizes automatically. This makes them easier to chain
10 and re-chain, since the size parameters don't need to be adjusted after each such case. Their performance is,
11 however, slightly worse, which is why we use cIntGen classes in the final generator.
12 
13 Because there is no SizeX / SizeZ template param, the generators would have to either alloc memory for each
14 underlying generator's values, or use a maximum-size buffer. We chose the latter, to avoid memory allocation
15 overhead; this however means that there's (an arbitrary) limit to the size of the generated data.
16 */
17 
18 
19 
20 
21 
22 #pragma once
23 
24 // We need the biome group constants defined there:
25 #include "IntGen.h"
26 
27 
28 
29 
30 
35 #ifndef PROT_INT_BUFFER_SIZE
36  #define PROT_INT_BUFFER_SIZE 900
37 #endif
38 
39 
40 
41 
42 
45 {
46 protected:
49  static const int m_BufferSize = PROT_INT_BUFFER_SIZE;
50 
51 public:
52 
54  typedef std::shared_ptr<cProtIntGen> Underlying;
55 
56 
59  virtual ~cProtIntGen() {}
60 
62  virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) = 0;
63 };
64 
65 
66 
67 
68 
71  public cProtIntGen
72 {
73  typedef cProtIntGen super;
74 
75 public:
76  cProtIntGenWithNoise(int a_Seed) :
77  m_Noise(a_Seed)
78  {
79  }
80 
81 protected:
83 
85  int chooseRandomOne(int a_RndX, int a_RndZ, int a_Val1, int a_Val2)
86  {
87  int rnd = m_Noise.IntNoise2DInt(a_RndX, a_RndZ) / 7;
88  return ((rnd & 1) == 0) ? a_Val1 : a_Val2;
89  }
90 
92  int chooseRandomOne(int a_RndX, int a_RndZ, int a_Val1, int a_Val2, int a_Val3, int a_Val4)
93  {
94  int rnd = m_Noise.IntNoise2DInt(a_RndX, a_RndZ) / 7;
95  switch (rnd % 4)
96  {
97  case 0: return a_Val1;
98  case 1: return a_Val2;
99  case 2: return a_Val3;
100  default: return a_Val4;
101  }
102  }
103 };
104 
105 
106 
107 
108 
111  public cProtIntGenWithNoise
112 {
114 
115 public:
116  cProtIntGenChoice(int a_Seed, int a_Range) :
117  super(a_Seed),
118  m_Range(a_Range)
119  {
120  }
121 
122 
123  virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
124  {
125  for (size_t z = 0; z < a_SizeZ; z++)
126  {
127  int BaseZ = a_MinZ + static_cast<int>(z);
128  for (size_t x = 0; x < a_SizeX; x++)
129  {
130  a_Values[x + a_SizeX * z] = (super::m_Noise.IntNoise2DInt(a_MinX + static_cast<int>(x), BaseZ) / 7) % m_Range;
131  }
132  } // for z
133  }
134 
135 protected:
136  int m_Range;
137 };
138 
139 
140 
141 
142 
147  public cProtIntGenWithNoise
148 {
150 
151 public:
152  cProtIntGenLandOcean(int a_Seed, int a_Threshold) :
153  super(a_Seed),
154  m_Threshold(a_Threshold)
155  {
156  }
157 
158 
159  virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
160  {
161  for (size_t z = 0; z < a_SizeZ; z++)
162  {
163  int BaseZ = a_MinZ + static_cast<int>(z);
164  for (size_t x = 0; x < a_SizeX; x++)
165  {
166  int rnd = (super::m_Noise.IntNoise2DInt(a_MinX + static_cast<int>(x), BaseZ) / 7);
167  a_Values[x + a_SizeX * z] = ((rnd % 100) < m_Threshold) ? ((rnd / 101) % bgLandOceanMax + 1) : 0;
168  }
169  }
170 
171  // If the centerpoint of the world is within the area, set it to bgTemperate, always:
172  if ((a_MinX <= 0) && (a_MinZ <= 0) && (a_MinX + static_cast<int>(a_SizeX) > 0) && (a_MinZ + static_cast<int>(a_SizeZ) > 0))
173  {
174  a_Values[static_cast<size_t>(-a_MinX) - static_cast<size_t>(a_MinZ) * a_SizeX] = bgTemperate;
175  }
176  }
177 
178 protected:
180 };
181 
182 
183 
184 
185 
190  public cProtIntGenWithNoise
191 {
193 
194 public:
195  cProtIntGenZoom(int a_Seed, Underlying a_UnderlyingGen) :
196  super(a_Seed),
197  m_UnderlyingGen(a_UnderlyingGen)
198  {
199  }
200 
201 
202  virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
203  {
204  // Get the coords for the lower generator:
205  int lowerMinX = a_MinX >> 1;
206  int lowerMinZ = a_MinZ >> 1;
207  size_t lowerSizeX = a_SizeX / 2 + 2;
208  size_t lowerSizeZ = a_SizeZ / 2 + 2;
209  ASSERT(lowerSizeX * lowerSizeZ <= m_BufferSize);
210  ASSERT(lowerSizeX > 0);
211  ASSERT(lowerSizeZ > 0);
212 
213  // Generate the underlying data with half the resolution:
214  int lowerData[m_BufferSize];
215  m_UnderlyingGen->GetInts(lowerMinX, lowerMinZ, lowerSizeX, lowerSizeZ, lowerData);
216  const size_t lowStepX = (lowerSizeX - 1) * 2;
217  int cache[m_BufferSize];
218 
219  // Discreet-interpolate the values into twice the size:
220  for (size_t z = 0; z < lowerSizeZ - 1; ++z)
221  {
222  size_t idx = (z * 2) * lowStepX;
223  int PrevZ0 = lowerData[z * lowerSizeX];
224  int PrevZ1 = lowerData[(z + 1) * lowerSizeX];
225 
226  for (size_t x = 0; x < lowerSizeX - 1; ++x)
227  {
228  int ValX1Z0 = lowerData[x + 1 + z * lowerSizeX];
229  int ValX1Z1 = lowerData[x + 1 + (z + 1) * lowerSizeX];
230  int RndX = (static_cast<int>(x) + lowerMinX) * 2;
231  int RndZ = (static_cast<int>(z) + lowerMinZ) * 2;
232  cache[idx] = PrevZ0;
233  cache[idx + lowStepX] = super::chooseRandomOne(RndX, RndZ + 1, PrevZ0, PrevZ1);
234  cache[idx + 1] = super::chooseRandomOne(RndX, RndZ - 1, PrevZ0, ValX1Z0);
235  cache[idx + 1 + lowStepX] = super::chooseRandomOne(RndX, RndZ, PrevZ0, ValX1Z0, PrevZ1, ValX1Z1);
236  idx += 2;
237  PrevZ0 = ValX1Z0;
238  PrevZ1 = ValX1Z1;
239  }
240  }
241 
242  // Copy from Cache into a_Values; take into account the even / odd offsets in a_Min:
243  for (size_t z = 0; z < a_SizeZ; ++z)
244  {
245  memcpy(a_Values + z * a_SizeX, cache + (z + (a_MinZ & 1)) * lowStepX + (a_MinX & 1), a_SizeX * sizeof(int));
246  }
247  }
248 
249 protected:
251 };
252 
253 
254 
255 
256 
260  public cProtIntGenWithNoise
261 {
263 
264 public:
265  cProtIntGenSmooth(int a_Seed, Underlying a_Underlying) :
266  super(a_Seed),
267  m_Underlying(a_Underlying)
268  {
269  }
270 
271 
272  virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
273  {
274  // Generate the underlying values:
275  size_t lowerSizeX = a_SizeX + 2;
276  size_t lowerSizeZ = a_SizeZ + 2;
277  ASSERT(lowerSizeX * lowerSizeZ <= m_BufferSize);
278  int lowerData[m_BufferSize];
279  m_Underlying->GetInts(a_MinX - 1, a_MinZ - 1, lowerSizeX, lowerSizeZ, lowerData);
280 
281  // Smooth - for each square check if the surroundings are the same, if so, expand them diagonally.
282  // Also get rid of single-pixel irregularities (A-B-A):
283  for (size_t z = 0; z < a_SizeZ; z++)
284  {
285  int NoiseZ = a_MinZ + static_cast<int>(z);
286  for (size_t x = 0; x < a_SizeX; x++)
287  {
288  int val = lowerData[x + 1 + (z + 1) * lowerSizeX];
289  int above = lowerData[x + 1 + z * lowerSizeX];
290  int below = lowerData[x + 1 + (z + 2) * lowerSizeX];
291  int left = lowerData[x + (z + 1) * lowerSizeX];
292  int right = lowerData[x + 2 + (z + 1) * lowerSizeX];
293 
294  if ((left == right) && (above == below))
295  {
296  if (((super::m_Noise.IntNoise2DInt(a_MinX + static_cast<int>(x), NoiseZ) / 7) % 2) == 0)
297  {
298  val = left;
299  }
300  else
301  {
302  val = above;
303  }
304  }
305  else
306  {
307  if (left == right)
308  {
309  val = left;
310  }
311 
312  if (above == below)
313  {
314  val = above;
315  }
316  }
317 
318  a_Values[x + z * a_SizeX] = val;
319  }
320  }
321  }
322 
323 protected:
325 };
326 
327 
328 
329 
330 
333  public cProtIntGen
334 {
336 
337 public:
339  m_Underlying(a_Underlying)
340  {
341  }
342 
343 
344  virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
345  {
346  // Generate the underlying values:
347  size_t lowerSizeX = a_SizeX + 1;
348  size_t lowerSizeZ = a_SizeZ + 1;
349  ASSERT(lowerSizeX * lowerSizeZ <= m_BufferSize);
350  int lowerData[m_BufferSize];
351  m_Underlying->GetInts(a_MinX, a_MinZ, lowerSizeX, lowerSizeZ, lowerData);
352 
353  // Average - add all 4 "neighbors" and divide by 4:
354  for (size_t z = 0; z < a_SizeZ; z++)
355  {
356  for (size_t x = 0; x < a_SizeX; x++)
357  {
358  size_t idxLower = x + lowerSizeX * z;
359  a_Values[x + a_SizeX * z] = (
360  lowerData[idxLower] + lowerData[idxLower + 1] +
361  lowerData[idxLower + lowerSizeX] + lowerData[idxLower + lowerSizeX + 1]
362  ) / 4;
363  }
364  }
365  }
366 
367 protected:
369 };
370 
371 
372 
373 
374 
377  public cProtIntGen
378 {
380 
381 public:
383  m_Underlying(a_Underlying)
384  {
385  }
386 
387 
388  virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
389  {
390  // Generate the underlying values:
391  size_t lowerSizeX = a_SizeX + 4;
392  size_t lowerSizeZ = a_SizeZ + 4;
393  ASSERT(lowerSizeX * lowerSizeZ <= m_BufferSize);
394  int lowerData[m_BufferSize];
395  m_Underlying->GetInts(a_MinX - 1, a_MinZ - 1, lowerSizeX, lowerSizeZ, lowerData);
396 
397  // Calculate the weighted average of all 16 "neighbors":
398  for (size_t z = 0; z < a_SizeZ; z++)
399  {
400  for (size_t x = 0; x < a_SizeX; x++)
401  {
402  size_t idxLower1 = x + lowerSizeX * z;
403  size_t idxLower2 = idxLower1 + lowerSizeX;
404  size_t idxLower3 = idxLower1 + 2 * lowerSizeX;
405  size_t idxLower4 = idxLower1 + 3 * lowerSizeX;
406  a_Values[x + a_SizeX * z] = (
407  1 * lowerData[idxLower1] + 2 * lowerData[idxLower1 + 1] + 2 * lowerData[idxLower1 + 2] + 1 * lowerData[idxLower1 + 3] +
408  2 * lowerData[idxLower2] + 32 * lowerData[idxLower2 + 1] + 32 * lowerData[idxLower2 + 2] + 2 * lowerData[idxLower2 + 3] +
409  2 * lowerData[idxLower3] + 32 * lowerData[idxLower3 + 1] + 32 * lowerData[idxLower3 + 2] + 2 * lowerData[idxLower3 + 3] +
410  1 * lowerData[idxLower4] + 2 * lowerData[idxLower4 + 1] + 2 * lowerData[idxLower4 + 2] + 1 * lowerData[idxLower4 + 3]
411  ) / 148;
412  }
413  }
414  }
415 
416 protected:
418 };
419 
420 
421 
422 
423 
425 template <int WeightCenter, int WeightCardinal, int WeightDiagonal>
427  public cProtIntGen
428 {
430 
431 public:
433  m_Underlying(a_Underlying)
434  {
435  }
436 
437 
438  virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
439  {
440  // Generate the underlying values:
441  size_t lowerSizeX = a_SizeX + 3;
442  size_t lowerSizeZ = a_SizeZ + 3;
443  ASSERT(lowerSizeX * lowerSizeZ <= m_BufferSize);
444  int lowerData[m_BufferSize];
445  m_Underlying->GetInts(a_MinX, a_MinZ, lowerSizeX, lowerSizeZ, lowerData);
446 
447  // Calculate the weighted average the neighbors:
448  for (size_t z = 0; z < a_SizeZ; z++)
449  {
450  for (size_t x = 0; x < a_SizeX; x++)
451  {
452  size_t idxLower1 = x + lowerSizeX * z;
453  size_t idxLower2 = idxLower1 + lowerSizeX;
454  size_t idxLower3 = idxLower1 + 2 * lowerSizeX;
455  a_Values[x + a_SizeX * z] = (
456  WeightDiagonal * lowerData[idxLower1] + WeightCardinal * lowerData[idxLower1 + 1] + WeightDiagonal * lowerData[idxLower1 + 2] +
457  WeightCardinal * lowerData[idxLower2] + WeightCenter * lowerData[idxLower2 + 1] + WeightCardinal * lowerData[idxLower2 + 2] +
458  WeightDiagonal * lowerData[idxLower3] + WeightCardinal * lowerData[idxLower3 + 1] + WeightDiagonal * lowerData[idxLower3 + 2]
459  ) / (4 * WeightDiagonal + 4 * WeightCardinal + WeightCenter);
460  }
461  }
462  }
463 
464 protected:
466 };
467 
468 
469 
470 
471 
474  public cProtIntGenWithNoise
475 {
477 
478 public:
479  cProtIntGenRndChoice(int a_Seed, int a_ChancePct, int a_Min, int a_Range, Underlying a_Underlying) :
480  super(a_Seed),
481  m_ChancePct(a_ChancePct),
482  m_Min(a_Min),
483  m_Range(a_Range),
484  m_Underlying(a_Underlying)
485  {
486  }
487 
488 
489  virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
490  {
491  // Generate the underlying values:
492  m_Underlying->GetInts(a_MinX, a_MinZ, a_SizeX, a_SizeZ, a_Values);
493 
494  // Replace random values:
495  for (size_t z = 0; z < a_SizeZ; z++)
496  {
497  int BaseZ = a_MinZ + static_cast<int>(z);
498  for (size_t x = 0; x < a_SizeX; x++)
499  {
500  if (((super::m_Noise.IntNoise2DInt(BaseZ, a_MinX + static_cast<int>(x)) / 13) % 101) < m_ChancePct)
501  {
502  a_Values[x + a_SizeX * z] = m_Min + (super::m_Noise.IntNoise2DInt(a_MinX + static_cast<int>(x), BaseZ) / 7) % m_Range;
503  }
504  } // for x
505  } // for z
506  }
507 
508 protected:
510  int m_Min;
511  int m_Range;
513 };
514 
515 
516 
517 
518 
521  public cProtIntGenWithNoise
522 {
524 
525 public:
526  cProtIntGenAddRnd(int a_Seed, int a_HalfRange, Underlying a_Underlying) :
527  super(a_Seed),
528  m_Range(a_HalfRange * 2 + 1),
529  m_HalfRange(a_HalfRange),
530  m_Underlying(a_Underlying)
531  {
532  }
533 
534 
535  virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
536  {
537  // Generate the underlying values:
538  m_Underlying->GetInts(a_MinX, a_MinZ, a_SizeX, a_SizeZ, a_Values);
539 
540  // Add the random values:
541  for (size_t z = 0; z < a_SizeZ; z++)
542  {
543  int NoiseZ = a_MinZ + static_cast<int>(z);
544  for (size_t x = 0; x < a_SizeX; x++)
545  {
546  int noiseVal = ((super::m_Noise.IntNoise2DInt(a_MinX + static_cast<int>(x), NoiseZ) / 7) % m_Range) - m_HalfRange;
547  a_Values[x + z * a_SizeX] += noiseVal;
548  }
549  }
550  }
551 
552 protected:
553  int m_Range;
556 };
557 
558 
559 
560 
561 
564  public cProtIntGenWithNoise
565 {
567 
568 public:
569  cProtIntGenRndAvg(int a_Seed, int a_AvgChancePct, Underlying a_Underlying) :
570  super(a_Seed),
571  m_AvgChancePct(a_AvgChancePct),
572  m_Underlying(a_Underlying)
573  {
574  }
575 
576 
577  virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
578  {
579  // Generate the underlying values:
580  size_t lowerSizeX = a_SizeX + 2;
581  size_t lowerSizeZ = a_SizeZ + 2;
582  ASSERT(lowerSizeX * lowerSizeZ <= m_BufferSize);
583  int lowerData[m_BufferSize];
584  m_Underlying->GetInts(a_MinX - 1, a_MinZ - 1, lowerSizeX, lowerSizeZ, lowerData);
585 
586  // Average random values:
587  for (size_t z = 0; z < a_SizeZ; z++)
588  {
589  int NoiseZ = a_MinZ + static_cast<int>(z);
590  for (size_t x = 0; x < a_SizeX; x++)
591  {
592  size_t idxLower = x + 1 + lowerSizeX * (z + 1);
593  if (((super::m_Noise.IntNoise2DInt(a_MinX + static_cast<int>(x), NoiseZ) / 7) % 100) > m_AvgChancePct)
594  {
595  // Average the 4 neighbors:
596  a_Values[x + z * a_SizeX] = (
597  lowerData[idxLower - 1] + lowerData[idxLower + 1] +
598  lowerData[idxLower - lowerSizeX] + lowerData[idxLower + lowerSizeX]
599  ) / 4;
600  }
601  else
602  {
603  // Keep the underlying value:
604  a_Values[x + z * a_SizeX] = lowerData[idxLower];
605  }
606  }
607  }
608  }
609 
610 protected:
613 };
614 
615 
616 
617 
618 
621  public cProtIntGenWithNoise
622 {
624 
625 public:
626  cProtIntGenRndBetween(int a_Seed, int a_AvgChancePct, Underlying a_Underlying) :
627  super(a_Seed),
628  m_AvgChancePct(a_AvgChancePct),
629  m_Underlying(a_Underlying)
630  {
631  }
632 
633 
634  virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
635  {
636  // Generate the underlying values:
637  size_t lowerSizeX = a_SizeX + 2;
638  size_t lowerSizeZ = a_SizeZ + 2;
639  ASSERT(lowerSizeX * lowerSizeZ <= m_BufferSize);
640  int lowerData[m_BufferSize];
641  m_Underlying->GetInts(a_MinX - 1, a_MinZ - 1, lowerSizeX, lowerSizeZ, lowerData);
642 
643  // Average random values:
644  for (size_t z = 0; z < a_SizeZ; z++)
645  {
646  int NoiseZ = a_MinZ + static_cast<int>(z);
647  for (size_t x = 0; x < a_SizeX; x++)
648  {
649  size_t idxLower = x + 1 + lowerSizeX * (z + 1);
650  if (((super::m_Noise.IntNoise2DInt(a_MinX + static_cast<int>(x), NoiseZ) / 7) % 100) > m_AvgChancePct)
651  {
652  // Chose a value in between the min and max neighbor:
653  int min = std::min(std::min(lowerData[idxLower - 1], lowerData[idxLower + 1]), std::min(lowerData[idxLower - lowerSizeX], lowerData[idxLower + lowerSizeX]));
654  int max = std::max(std::max(lowerData[idxLower - 1], lowerData[idxLower + 1]), std::max(lowerData[idxLower - lowerSizeX], lowerData[idxLower + lowerSizeX]));
655  a_Values[x + z * a_SizeX] = min + ((super::m_Noise.IntNoise2DInt(a_MinX + static_cast<int>(x), NoiseZ + 10) / 7) % (max - min + 1));
656  }
657  else
658  {
659  // Keep the underlying value:
660  a_Values[x + z * a_SizeX] = lowerData[idxLower];
661  }
662  }
663  }
664  }
665 
666 protected:
669 };
670 
671 
672 
673 
674 
677  public cProtIntGen
678 {
680 
681 public:
683  m_Underlying(a_Underlying)
684  {
685  }
686 
687 
688  virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
689  {
690  // Map for biome -> its beach:
691  static const int ToBeach[] =
692  {
693  /* biOcean */ biOcean,
694  /* biPlains */ biBeach,
695  /* biDesert */ biBeach,
696  /* biExtremeHills */ biStoneBeach,
697  /* biForest */ biBeach,
698  /* biTaiga */ biColdBeach,
699  /* biSwampland */ biSwampland,
700  /* biRiver */ biRiver,
701  /* biNether */ biNether,
702  /* biEnd */ biEnd,
703  /* biFrozenOcean */ biColdBeach,
704  /* biFrozenRiver */ biColdBeach,
705  /* biIcePlains */ biColdBeach,
706  /* biIceMountains */ biColdBeach,
707  /* biMushroomIsland */ biMushroomShore,
708  /* biMushroomShore */ biMushroomShore,
709  /* biBeach */ biBeach,
710  /* biDesertHills */ biBeach,
711  /* biForestHills */ biBeach,
712  /* biTaigaHills */ biColdBeach,
713  /* biExtremeHillsEdge */ biStoneBeach,
714  /* biJungle */ biBeach,
715  /* biJungleHills */ biBeach,
716  /* biJungleEdge */ biBeach,
717  /* biDeepOcean */ biOcean,
718  /* biStoneBeach */ biStoneBeach,
719  /* biColdBeach */ biColdBeach,
720  /* biBirchForest */ biBeach,
721  /* biBirchForestHills */ biBeach,
722  /* biRoofedForest */ biBeach,
723  /* biColdTaiga */ biColdBeach,
724  /* biColdTaigaHills */ biColdBeach,
725  /* biMegaTaiga */ biStoneBeach,
726  /* biMegaTaigaHills */ biStoneBeach,
727  /* biExtremeHillsPlus */ biStoneBeach,
728  /* biSavanna */ biBeach,
729  /* biSavannaPlateau */ biBeach,
730  /* biMesa */ biMesa,
731  /* biMesaPlateauF */ biMesa,
732  /* biMesaPlateau */ biMesa,
733  };
734 
735  // Generate the underlying values:
736  size_t lowerSizeX = a_SizeX + 2;
737  size_t lowerSizeZ = a_SizeZ + 2;
738  ASSERT(lowerSizeX * lowerSizeZ <= m_BufferSize);
739  int lowerValues[m_BufferSize];
740  m_Underlying->GetInts(a_MinX - 1, a_MinZ - 1, lowerSizeX, lowerSizeZ, lowerValues);
741 
742  // Add beaches between ocean and biomes:
743  for (size_t z = 0; z < a_SizeZ; z++)
744  {
745  for (size_t x = 0; x < a_SizeX; x++)
746  {
747  int val = lowerValues[x + 1 + (z + 1) * lowerSizeX];
748  int above = lowerValues[x + 1 + z * lowerSizeX];
749  int below = lowerValues[x + 1 + (z + 2) * lowerSizeX];
750  int left = lowerValues[x + (z + 1) * lowerSizeX];
751  int right = lowerValues[x + 2 + (z + 1) * lowerSizeX];
752  if (!IsBiomeOcean(val))
753  {
754  if (IsBiomeOcean(above) || IsBiomeOcean(below) || IsBiomeOcean(left) || IsBiomeOcean(right))
755  {
756  // First convert the value to a regular biome (drop the M flag), then modulo by our biome count:
757  val = ToBeach[(val % 128) % ARRAYCOUNT(ToBeach)];
758  }
759  }
760  a_Values[x + z * a_SizeX] = val;
761  }
762  }
763  }
764 
765 protected:
767 };
768 
769 
770 
771 
772 
776  public cProtIntGenWithNoise
777 {
779 
780 public:
781  typedef std::shared_ptr<cProtIntGen> Underlying;
782 
783 
784  cProtIntGenAddIslands(int a_Seed, int a_Chance, Underlying a_Underlying) :
785  super(a_Seed),
786  m_Chance(a_Chance),
787  m_Underlying(a_Underlying)
788  {
789  }
790 
791 
792  virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
793  {
794  m_Underlying->GetInts(a_MinX, a_MinZ, a_SizeX, a_SizeZ, a_Values);
795  for (size_t z = 0; z < a_SizeZ; z++)
796  {
797  for (size_t x = 0; x < a_SizeX; x++)
798  {
799  if (a_Values[x + z * a_SizeX] == bgOcean)
800  {
801  int rnd = super::m_Noise.IntNoise2DInt(a_MinX + static_cast<int>(x), a_MinZ + static_cast<int>(z)) / 7;
802  if (rnd % 1000 < m_Chance)
803  {
804  a_Values[x + z * a_SizeX] = (rnd / 1003) % bgLandOceanMax;
805  }
806  }
807  }
808  }
809  }
810 
811 protected:
813  int m_Chance;
814 
815  Underlying m_Underlying;
816 };
817 
818 
819 
820 
821 
824  public cProtIntGen
825 {
827 
828 public:
830  m_Underlying(a_Underlying)
831  {
832  }
833 
834 
835  virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values)
836  {
837  // Generate the underlying biome groups:
838  size_t lowerSizeX = a_SizeX + 2;
839  size_t lowerSizeZ = a_SizeZ + 2;
840  ASSERT(lowerSizeX * lowerSizeZ <= m_BufferSize);
841  int lowerValues[m_BufferSize];
842  m_Underlying->GetInts(a_MinX, a_MinZ, lowerSizeX, lowerSizeZ, lowerValues);
843 
844  // Change the biomes on incompatible edges into an edge biome:
845  for (size_t z = 0; z < a_SizeZ; z++)
846  {
847  for (size_t x = 0; x < a_SizeX; x++)
848  {
849  int val = lowerValues[x + 1 + (z + 1) * lowerSizeX];
850  int Above = lowerValues[x + 1 + z * lowerSizeX];
851  int Below = lowerValues[x + 1 + (z + 2) * lowerSizeX];
852  int Left = lowerValues[x + (z + 1) * lowerSizeX];
853  int Right = lowerValues[x + 2 + (z + 1) * lowerSizeX];
854  switch (val)
855  {
856  // Desert should neighbor only oceans, desert and temperates; change to temperate when another:
857  case bgDesert:
858  {
859  if (
860  !isDesertCompatible(Above) ||
861  !isDesertCompatible(Below) ||
862  !isDesertCompatible(Left) ||
863  !isDesertCompatible(Right)
864  )
865  {
866  val = bgTemperate;
867  }
868  break;
869  } // case bgDesert
870 
871  // Ice should not neighbor deserts; change to temperate:
872  case bgIce:
873  {
874  if (
875  (Above == bgDesert) ||
876  (Below == bgDesert) ||
877  (Left == bgDesert) ||
878  (Right == bgDesert)
879  )
880  {
881  val = bgTemperate;
882  }
883  break;
884  } // case bgIce
885  }
886  a_Values[x + z * a_SizeX] = val;
887  } // for x
888  } // for z
889  }
890 
891 protected:
893 
894 
895  inline bool isDesertCompatible(int a_BiomeGroup)
896  {
897  switch (a_BiomeGroup)
898  {
899  case bgOcean:
900  case bgDesert:
901  case bgTemperate:
902  {
903  return true;
904  }
905  default:
906  {
907  return false;
908  }
909  }
910  }
911 };
912 
913 
914 
915 
916 
921  public cProtIntGenWithNoise
922 {
924 
925 public:
926  cProtIntGenBiomes(int a_Seed, Underlying a_Underlying) :
927  super(a_Seed),
928  m_Underlying(a_Underlying)
929  {
930  }
931 
932 
933  virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
934  {
935  // Define the per-biome-group biomes:
936  static const int oceanBiomes[] =
937  {
938  biOcean, // biDeepOcean,
939  };
940 
941  // Same as oceanBiomes, there are no rare oceanic biomes (mushroom islands are handled separately)
942  static const int rareOceanBiomes[] =
943  {
944  biOcean,
945  };
946 
947  static const int desertBiomes[] =
948  {
950  };
951 
952  static const int rareDesertBiomes[] =
953  {
955  };
956 
957  static const int temperateBiomes[] =
958  {
960  };
961 
962  static const int rareTemperateBiomes[] =
963  {
964  biJungle, // Jungle is not strictly temperate, but let's piggyback it here
965  };
966 
967  static const int mountainBiomes[] =
968  {
970  };
971 
972  static const int rareMountainBiomes[] =
973  {
974  biMegaTaiga,
975  };
976 
977  static const int iceBiomes[] =
978  {
980  };
981 
982  // Same as iceBiomes, there's no rare ice biome
983  static const int rareIceBiomes[] =
984  {
986  };
987 
988  static const cBiomesInGroups biomesInGroups[] =
989  {
990  /* bgOcean */ { static_cast<int>(ARRAYCOUNT(oceanBiomes)), oceanBiomes},
991  /* bgDesert */ { static_cast<int>(ARRAYCOUNT(desertBiomes)), desertBiomes},
992  /* bgTemperate */ { static_cast<int>(ARRAYCOUNT(temperateBiomes)), temperateBiomes},
993  /* bgMountains */ { static_cast<int>(ARRAYCOUNT(mountainBiomes)), mountainBiomes},
994  /* bgIce */ { static_cast<int>(ARRAYCOUNT(iceBiomes)), iceBiomes},
995  };
996 
997  static const cBiomesInGroups rareBiomesInGroups[] =
998  {
999  /* bgOcean */ { static_cast<int>(ARRAYCOUNT(rareOceanBiomes)), rareOceanBiomes},
1000  /* bgDesert */ { static_cast<int>(ARRAYCOUNT(rareDesertBiomes)), rareDesertBiomes},
1001  /* bgTemperate */ { static_cast<int>(ARRAYCOUNT(rareTemperateBiomes)), rareTemperateBiomes},
1002  /* bgMountains */ { static_cast<int>(ARRAYCOUNT(rareMountainBiomes)), rareMountainBiomes},
1003  /* bgIce */ { static_cast<int>(ARRAYCOUNT(rareIceBiomes)), rareIceBiomes},
1004  };
1005 
1006  // Generate the underlying values, representing biome groups:
1007  m_Underlying->GetInts(a_MinX, a_MinZ, a_SizeX, a_SizeZ, a_Values);
1008 
1009  // Overwrite each biome group with a random biome from that group:
1010  // Take care of the bgfRare flag
1011  for (size_t z = 0; z < a_SizeZ; z++)
1012  {
1013  size_t IdxZ = z * a_SizeX;
1014  for (size_t x = 0; x < a_SizeX; x++)
1015  {
1016  int val = a_Values[x + IdxZ];
1017  const cBiomesInGroups & Biomes = (val > bgfRare) ?
1018  rareBiomesInGroups[(val & (bgfRare - 1)) % ARRAYCOUNT(rareBiomesInGroups)] :
1019  biomesInGroups[static_cast<size_t>(val) % ARRAYCOUNT(biomesInGroups)];
1020  int rnd = (super::m_Noise.IntNoise2DInt(static_cast<int>(x) + a_MinX, static_cast<int>(z) + a_MinZ) / 7);
1021  a_Values[x + IdxZ] = Biomes.Biomes[rnd % Biomes.Count];
1022  }
1023  }
1024  }
1025 
1026 protected:
1027 
1029  {
1030  const int Count;
1031  const int * Biomes;
1032  };
1033 
1034 
1037 };
1038 
1039 
1040 
1041 
1042 
1045  public cProtIntGenWithNoise
1046 {
1048 
1049 public:
1050  typedef std::shared_ptr<cProtIntGen> Underlying;
1051 
1052 
1053  cProtIntGenReplaceRandomly(int a_Seed, int a_From, int a_To, int a_Chance, Underlying a_Underlying) :
1054  super(a_Seed),
1055  m_From(a_From),
1056  m_To(a_To),
1057  m_Chance(a_Chance),
1058  m_Underlying(a_Underlying)
1059  {
1060  }
1061 
1062 
1063  virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
1064  {
1065  // Generate the underlying values:
1066  m_Underlying->GetInts(a_MinX, a_MinZ, a_SizeX, a_SizeZ, a_Values);
1067 
1068  // Replace some of the values:
1069  for (size_t z = 0; z < a_SizeZ; z++)
1070  {
1071  size_t idxZ = z * a_SizeX;
1072  for (size_t x = 0; x < a_SizeX; x++)
1073  {
1074  size_t idx = x + idxZ;
1075  if (a_Values[idx] == m_From)
1076  {
1077  int rnd = super::m_Noise.IntNoise2DInt(static_cast<int>(x) + a_MinX, static_cast<int>(z) + a_MinZ) / 7;
1078  if (rnd % 1000 < m_Chance)
1079  {
1080  a_Values[idx] = m_To;
1081  }
1082  }
1083  }
1084  } // for z
1085  }
1086 
1087 
1088 protected:
1090  int m_From;
1091 
1093  int m_To;
1094 
1097 
1098  Underlying m_Underlying;
1099 };
1100 
1101 
1102 
1103 
1104 
1110  public cProtIntGen
1111 {
1113 
1114 public:
1116  m_Biomes(a_Biomes),
1117  m_Rivers(a_Rivers)
1118  {
1119  }
1120 
1121 
1122  virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
1123  {
1124  // Generate the underlying data:
1125  ASSERT(a_SizeX * a_SizeZ <= m_BufferSize);
1126  m_Biomes->GetInts(a_MinX, a_MinZ, a_SizeX, a_SizeZ, a_Values);
1127  int riverData[m_BufferSize];
1128  m_Rivers->GetInts(a_MinX, a_MinZ, a_SizeX, a_SizeZ, riverData);
1129 
1130  // Mix the values:
1131  for (size_t z = 0; z < a_SizeZ; z++)
1132  {
1133  size_t idxZ = z * a_SizeX;
1134  for (size_t x = 0; x < a_SizeX; x++)
1135  {
1136  size_t idx = x + idxZ;
1137  if (IsBiomeOcean(a_Values[idx]))
1138  {
1139  // Oceans are kept without any changes
1140  continue;
1141  }
1142  if (riverData[idx] != biRiver)
1143  {
1144  // There's no river, keep the current value
1145  continue;
1146  }
1147 
1148  // There's a river, change the output to a river or a frozen river, based on the original biome:
1149  if (IsBiomeVeryCold(static_cast<EMCSBiome>(a_Values[idx])))
1150  {
1151  a_Values[idx] = biFrozenRiver;
1152  }
1153  else
1154  {
1155  a_Values[idx] = biRiver;
1156  }
1157  } // for x
1158  } // for z
1159  }
1160 
1161 protected:
1164 };
1165 
1166 
1167 
1168 
1169 
1174  public cProtIntGenWithNoise
1175 {
1177 
1178 public:
1179  cProtIntGenRiver(int a_Seed, Underlying a_Underlying):
1180  super(a_Seed),
1181  m_Underlying(a_Underlying)
1182  {
1183  }
1184 
1185 
1186  virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
1187  {
1188  // Generate the underlying data:
1189  size_t lowerSizeX = a_SizeX + 2;
1190  size_t lowerSizeZ = a_SizeZ + 2;
1191  ASSERT(lowerSizeX * lowerSizeZ <= m_BufferSize);
1192  int lowerValues[m_BufferSize];
1193  m_Underlying->GetInts(a_MinX - 1, a_MinZ - 1, lowerSizeX, lowerSizeZ, lowerValues);
1194 
1195  // Detect the edges:
1196  for (size_t z = 0; z < a_SizeZ; z++)
1197  {
1198  for (size_t x = 0; x < a_SizeX; x++)
1199  {
1200  int Above = lowerValues[x + 1 + z * lowerSizeX];
1201  int Below = lowerValues[x + 1 + (z + 2) * lowerSizeX];
1202  int Left = lowerValues[x + (z + 1) * lowerSizeX];
1203  int Right = lowerValues[x + 2 + (z + 1) * lowerSizeX];
1204  int val = lowerValues[x + 1 + (z + 1) * lowerSizeX];
1205 
1206  if ((val == Above) && (val == Below) && (val == Left) && (val == Right))
1207  {
1208  val = 0;
1209  }
1210  else
1211  {
1212  val = biRiver;
1213  }
1214  a_Values[x + z * a_SizeX] = val;
1215  } // for x
1216  } // for z
1217  }
1218 
1219 protected:
1221 };
1222 
1223 
1224 
1225 
1226 
1230  public cProtIntGenWithNoise
1231 {
1233 
1234 public:
1235  cProtIntGenAddToOcean(int a_Seed, int a_Chance, int a_ToValue, Underlying a_Underlying):
1236  super(a_Seed),
1237  m_Chance(a_Chance),
1238  m_ToValue(a_ToValue),
1239  m_Underlying(a_Underlying)
1240  {
1241  }
1242 
1243 
1244  virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
1245  {
1246  // Generate the underlying data:
1247  size_t lowerSizeX = a_SizeX + 2;
1248  size_t lowerSizeZ = a_SizeZ + 2;
1249  ASSERT(lowerSizeX * lowerSizeZ <= m_BufferSize);
1250  int lowerValues[m_BufferSize];
1251  m_Underlying->GetInts(a_MinX - 1, a_MinZ - 1, lowerSizeX, lowerSizeZ, lowerValues);
1252 
1253  // Add the mushroom islands:
1254  for (size_t z = 0; z < a_SizeZ; z++)
1255  {
1256  for (size_t x = 0; x < a_SizeX; x++)
1257  {
1258  int val = lowerValues[x + 1 + (z + 1) * lowerSizeX];
1259  if (!IsBiomeOcean(val))
1260  {
1261  a_Values[x + z * a_SizeX] = val;
1262  continue;
1263  }
1264 
1265  // Count the ocean neighbors:
1266  int Above = lowerValues[x + 1 + z * lowerSizeX];
1267  int Below = lowerValues[x + 1 + (z + 2) * lowerSizeX];
1268  int Left = lowerValues[x + (z + 1) * lowerSizeX];
1269  int Right = lowerValues[x + 2 + (z + 1) * lowerSizeX];
1270  int NumOceanNeighbors = 0;
1271  if (IsBiomeOcean(Above))
1272  {
1273  NumOceanNeighbors += 1;
1274  }
1275  if (IsBiomeOcean(Below))
1276  {
1277  NumOceanNeighbors += 1;
1278  }
1279  if (IsBiomeOcean(Left))
1280  {
1281  NumOceanNeighbors += 1;
1282  }
1283  if (IsBiomeOcean(Right))
1284  {
1285  NumOceanNeighbors += 1;
1286  }
1287 
1288  // If at least 3 ocean neighbors and the chance is right, change:
1289  if (
1290  (NumOceanNeighbors >= 3) &&
1291  ((super::m_Noise.IntNoise2DInt(static_cast<int>(x) + a_MinX, static_cast<int>(z) + a_MinZ) / 7) % 1000 < m_Chance)
1292  )
1293  {
1294  a_Values[x + z * a_SizeX] = m_ToValue;
1295  }
1296  else
1297  {
1298  a_Values[x + z * a_SizeX] = val;
1299  }
1300  } // for x
1301  } // for z
1302  }
1303 
1304 protected:
1307 
1310 
1312 };
1313 
1314 
1315 
1316 
1317 
1320  public cProtIntGenWithNoise
1321 {
1323 
1324 public:
1325  cProtIntGenSetRandomly(int a_Seed, int a_Chance, int a_ToValue, Underlying a_Underlying) :
1326  super(a_Seed),
1327  m_Chance(a_Chance),
1328  m_ToValue(a_ToValue),
1329  m_Underlying(a_Underlying)
1330  {
1331  }
1332 
1333 
1334  virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
1335  {
1336  // Generate the underlying data:
1337  m_Underlying->GetInts(a_MinX, a_MinZ, a_SizeX, a_SizeZ, a_Values);
1338 
1339  // Change random pixels to bgOcean:
1340  for (size_t z = 0; z < a_SizeZ; z++)
1341  {
1342  for (size_t x = 0; x < a_SizeX; x++)
1343  {
1344  int rnd = super::m_Noise.IntNoise2DInt(static_cast<int>(x) + a_MinX, static_cast<int>(z) + a_MinZ) / 7;
1345  if (rnd % 1000 < m_Chance)
1346  {
1347  a_Values[x + z * a_SizeX] = m_ToValue;
1348  }
1349  }
1350  }
1351  }
1352 
1353 protected:
1356 
1359 
1361 };
1362 
1363 
1364 
1365 
1366 
1369  public cProtIntGenWithNoise
1370 {
1372 
1373 public:
1374  cProtIntGenRareBiomeGroups(int a_Seed, int a_Chance, Underlying a_Underlying):
1375  super(a_Seed),
1376  m_Chance(a_Chance),
1377  m_Underlying(a_Underlying)
1378  {
1379  }
1380 
1381 
1382  virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
1383  {
1384  // Generate the underlying data:
1385  m_Underlying->GetInts(a_MinX, a_MinZ, a_SizeX, a_SizeZ, a_Values);
1386 
1387  // Change some of the biome groups into rare biome groups:
1388  for (size_t z = 0; z < a_SizeZ; z++)
1389  {
1390  for (size_t x = 0; x < a_SizeX; x++)
1391  {
1392  int rnd = super::m_Noise.IntNoise2DInt(static_cast<int>(x) + a_MinX, static_cast<int>(z) + a_MinZ) / 7;
1393  if (rnd % 1000 < m_Chance)
1394  {
1395  size_t idx = x + a_SizeX * z;
1396  a_Values[idx] = a_Values[idx] | bgfRare;
1397  }
1398  }
1399  }
1400  }
1401 
1402 protected:
1405 
1408 };
1409 
1410 
1411 
1412 
1413 
1417  public cProtIntGenWithNoise
1418 {
1420 
1421 public:
1422  cProtIntGenAlternateBiomes(int a_Seed, Underlying a_Alterations, Underlying a_BaseBiomes):
1423  super(a_Seed),
1424  m_Alterations(a_Alterations),
1425  m_BaseBiomes(a_BaseBiomes)
1426  {
1427  }
1428 
1429 
1430  virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
1431  {
1432  // Generate the base biomes and the alterations:
1433  m_BaseBiomes->GetInts(a_MinX, a_MinZ, a_SizeX, a_SizeZ, a_Values);
1434  int alterations[m_BufferSize];
1435  m_Alterations->GetInts(a_MinX, a_MinZ, a_SizeX, a_SizeZ, alterations);
1436 
1437  // Change the biomes into their alternate versions:
1438  size_t len = a_SizeX * a_SizeZ;
1439  for (size_t idx = 0; idx < len; ++idx)
1440  {
1441  if (alterations[idx] == 0)
1442  {
1443  // No change
1444  continue;
1445  }
1446 
1447  // Change to alternate biomes:
1448  int val = a_Values[idx];
1449  switch (val)
1450  {
1451  case biBirchForest: val = biBirchForestHills; break;
1452  case biDesert: val = biDesertHills; break;
1453  case biExtremeHills: val = biExtremeHillsPlus; break;
1454  case biForest: val = biForestHills; break;
1455  case biIcePlains: val = biIceMountains; break;
1456  case biJungle: val = biJungleHills; break;
1457  case biMegaTaiga: val = biMegaTaigaHills; break;
1458  case biMesaPlateau: val = biMesa; break;
1459  case biMesaPlateauF: val = biMesa; break;
1460  case biMesaPlateauM: val = biMesa; break;
1461  case biMesaPlateauFM: val = biMesa; break;
1462  case biPlains: val = biForest; break;
1463  case biRoofedForest: val = biPlains; break;
1464  case biSavanna: val = biSavannaPlateau; break;
1465  case biTaiga: val = biTaigaHills; break;
1466  }
1467  a_Values[idx] = val;
1468  } // for idx - a_Values[]
1469  }
1470 
1471 protected:
1474 };
1475 
1476 
1477 
1478 
1479 
1482  public cProtIntGenWithNoise
1483 {
1485 
1486 public:
1487  cProtIntGenBiomeEdges(int a_Seed, Underlying a_Underlying):
1488  super(a_Seed),
1489  m_Underlying(a_Underlying)
1490  {
1491  }
1492 
1493 
1494  virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
1495  {
1496  // Generate the underlying biomes:
1497  size_t lowerSizeX = a_SizeX + 2;
1498  size_t lowerSizeZ = a_SizeZ + 2;
1499  ASSERT(lowerSizeX * lowerSizeZ <= m_BufferSize);
1500  int lowerValues[m_BufferSize];
1501  m_Underlying->GetInts(a_MinX - 1, a_MinZ - 1, lowerSizeX, lowerSizeZ, lowerValues);
1502 
1503  // Convert incompatible edges into neutral biomes:
1504  for (size_t z = 0; z < a_SizeZ; z++)
1505  {
1506  for (size_t x = 0; x < a_SizeX; x++)
1507  {
1508  int biome = lowerValues[x + 1 + (z + 1) * lowerSizeX];
1509  int above = lowerValues[x + 1 + z * lowerSizeX];
1510  int below = lowerValues[x + 1 + (z + 2) * lowerSizeX];
1511  int left = lowerValues[x + (z + 1) * lowerSizeX];
1512  int right = lowerValues[x + 2 + (z + 1) * lowerSizeX];
1513 
1514  switch (biome)
1515  {
1516  case biDesert:
1517  case biDesertM:
1518  case biDesertHills:
1519  {
1520  if (
1521  IsBiomeVeryCold(static_cast<EMCSBiome>(above)) ||
1522  IsBiomeVeryCold(static_cast<EMCSBiome>(below)) ||
1523  IsBiomeVeryCold(static_cast<EMCSBiome>(left)) ||
1524  IsBiomeVeryCold(static_cast<EMCSBiome>(right))
1525  )
1526  {
1527  biome = biPlains;
1528  }
1529  break;
1530  } // case biDesert
1531 
1532  case biMesaPlateau:
1533  case biMesaPlateauF:
1534  case biMesaPlateauFM:
1535  case biMesaPlateauM:
1536  {
1537  if (
1538  !isMesaCompatible(above) ||
1539  !isMesaCompatible(below) ||
1540  !isMesaCompatible(left) ||
1541  !isMesaCompatible(right)
1542  )
1543  {
1544  biome = biDesert;
1545  }
1546  break;
1547  } // Mesa biomes
1548 
1549  case biJungle:
1550  case biJungleM:
1551  {
1552  if (
1553  !isJungleCompatible(above) ||
1554  !isJungleCompatible(below) ||
1555  !isJungleCompatible(left) ||
1556  !isJungleCompatible(right)
1557  )
1558  {
1559  biome = (biome == biJungle) ? biJungleEdge : biJungleEdgeM;
1560  }
1561  break;
1562  } // Jungle biomes
1563 
1564  case biSwampland:
1565  case biSwamplandM:
1566  {
1567  if (
1568  IsBiomeNoDownfall(static_cast<EMCSBiome>(above)) ||
1569  IsBiomeNoDownfall(static_cast<EMCSBiome>(below)) ||
1570  IsBiomeNoDownfall(static_cast<EMCSBiome>(left)) ||
1571  IsBiomeNoDownfall(static_cast<EMCSBiome>(right))
1572  )
1573  {
1574  biome = biPlains;
1575  }
1576  break;
1577  } // Swampland biomes
1578  } // switch (biome)
1579 
1580  a_Values[x + z * a_SizeX] = biome;
1581  } // for x
1582  } // for z
1583  }
1584 
1585 
1586 protected:
1588 
1589 
1590  bool isMesaCompatible(int a_Biome)
1591  {
1592  switch (a_Biome)
1593  {
1594  case biDesert:
1595  case biMesa:
1596  case biMesaBryce:
1597  case biMesaPlateau:
1598  case biMesaPlateauF:
1599  case biMesaPlateauFM:
1600  case biMesaPlateauM:
1601  case biOcean:
1602  case biDeepOcean:
1603  {
1604  return true;
1605  }
1606  default:
1607  {
1608  return false;
1609  }
1610  }
1611  }
1612 
1613 
1614  bool isJungleCompatible(int a_Biome)
1615  {
1616  switch (a_Biome)
1617  {
1618  case biJungle:
1619  case biJungleM:
1620  case biJungleEdge:
1621  case biJungleEdgeM:
1622  case biJungleHills:
1623  {
1624  return true;
1625  }
1626  default:
1627  {
1628  return false;
1629  }
1630  }
1631  }
1632 };
1633 
1634 
1635 
1636 
1637 
1641  public cProtIntGenWithNoise
1642 {
1644 
1645 public:
1646  cProtIntGenMBiomes(int a_Seed, Underlying a_Alteration, Underlying a_Underlying):
1647  super(a_Seed),
1648  m_Underlying(a_Underlying),
1649  m_Alteration(a_Alteration)
1650  {
1651  }
1652 
1653 
1654  virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
1655  {
1656  // Generate the underlying biomes and the alterations:
1657  m_Underlying->GetInts(a_MinX, a_MinZ, a_SizeX, a_SizeZ, a_Values);
1658  int alterations[m_BufferSize];
1659  m_Alteration->GetInts(a_MinX, a_MinZ, a_SizeX, a_SizeZ, alterations);
1660 
1661  // Wherever alterations are nonzero, change into alternate biome, if available:
1662  size_t len = a_SizeX * a_SizeZ;
1663  for (size_t idx = 0; idx < len; ++idx)
1664  {
1665  if (alterations[idx] == 0)
1666  {
1667  continue;
1668  }
1669 
1670  // Ice spikes biome was removed from here, because it was generated way too often
1671  switch (a_Values[idx])
1672  {
1673  case biPlains: a_Values[idx] = biSunflowerPlains; break;
1674  case biDesert: a_Values[idx] = biDesertM; break;
1675  case biExtremeHills: a_Values[idx] = biExtremeHillsM; break;
1676  case biForest: a_Values[idx] = biFlowerForest; break;
1677  case biTaiga: a_Values[idx] = biTaigaM; break;
1678  case biSwampland: a_Values[idx] = biSwamplandM; break;
1679  case biJungle: a_Values[idx] = biJungleM; break;
1680  case biJungleEdge: a_Values[idx] = biJungleEdgeM; break;
1681  case biBirchForest: a_Values[idx] = biBirchForestM; break;
1682  case biBirchForestHills: a_Values[idx] = biBirchForestHillsM; break;
1683  case biRoofedForest: a_Values[idx] = biRoofedForestM; break;
1684  case biColdTaiga: a_Values[idx] = biColdTaigaM; break;
1685  case biMegaSpruceTaiga: a_Values[idx] = biMegaSpruceTaiga; break;
1686  case biMegaSpruceTaigaHills: a_Values[idx] = biMegaSpruceTaigaHills; break;
1687  case biExtremeHillsPlus: a_Values[idx] = biExtremeHillsPlusM; break;
1688  case biSavanna: a_Values[idx] = biSavannaM; break;
1689  case biSavannaPlateau: a_Values[idx] = biSavannaPlateauM; break;
1690  case biMesa: a_Values[idx] = biMesaBryce; break;
1691  case biMesaPlateauF: a_Values[idx] = biMesaPlateauFM; break;
1692  case biMesaPlateau: a_Values[idx] = biMesaBryce; break;
1693  }
1694  } // for idx - a_Values[] / alterations[]
1695  }
1696 
1697 protected:
1700 };
1701 
1702 
1703 
1704 
Underlying m_Underlying
Definition: ProtIntGen.h:668
Underlying m_Underlying
Definition: ProtIntGen.h:1587
Underlying m_Underlying
Definition: ProtIntGen.h:1311
cProtIntGen super
Definition: ProtIntGen.h:429
Underlying m_Underlying
Definition: ProtIntGen.h:1220
Changes biomes in the parent data into their alternate versions ("M" variants), in such places that h...
Definition: ProtIntGen.h:1640
cProtIntGenWithNoise super
Definition: ProtIntGen.h:1232
virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
Generates the array of specified size into a_Values, based on given min coords.
Definition: ProtIntGen.h:1122
cProtIntGenAvg4Values(Underlying a_Underlying)
Definition: ProtIntGen.h:382
Generates a 2D array of random integers in the specified range [0 .
Definition: ProtIntGen.h:110
cProtIntGenWithNoise super
Definition: ProtIntGen.h:1322
std::shared_ptr< cProtIntGen > Underlying
Type of the generic interface used for storing links to the underlying generators.
Definition: ProtIntGen.h:54
int m_From
The original value to be replaced.
Definition: ProtIntGen.h:1090
cProtIntGenWithNoise super
Definition: ProtIntGen.h:262
cProtIntGenRndAvg(int a_Seed, int a_AvgChancePct, Underlying a_Underlying)
Definition: ProtIntGen.h:569
int IntNoise2DInt(int a_X, int a_Y) const
Definition: Noise.h:243
static const int m_BufferSize
Maximum size of the generated area.
Definition: ProtIntGen.h:49
Averages the values of the underlying 3 * 3 neighbors with custom weight.
Definition: ProtIntGen.h:426
cProtIntGenWeightAvg(Underlying a_Underlying)
Definition: ProtIntGen.h:432
Underlying m_Underlying
Definition: ProtIntGen.h:324
Changes random pixels of the underlying data to the specified value.
Definition: ProtIntGen.h:1319
int chooseRandomOne(int a_RndX, int a_RndZ, int a_Val1, int a_Val2)
Chooses one of a_Val1 or a_Val2, based on m_Noise and the coordinates for querying the noise...
Definition: ProtIntGen.h:85
const int bgIce
Definition: IntGen.h:44
bool isJungleCompatible(int a_Biome)
Definition: ProtIntGen.h:1614
Adds an edge between two specifically incompatible biomes, such as mesa and forest.
Definition: ProtIntGen.h:1481
std::shared_ptr< cProtIntGen > Underlying
Definition: ProtIntGen.h:781
virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
Generates the array of specified size into a_Values, based on given min coords.
Definition: ProtIntGen.h:933
bool isMesaCompatible(int a_Biome)
Definition: ProtIntGen.h:1590
cProtIntGenBiomeEdges(int a_Seed, Underlying a_Underlying)
Definition: ProtIntGen.h:1487
Definition: BiomeDef.h:37
int m_Chance
Chance, in permille, of replacing the value.
Definition: ProtIntGen.h:1096
cProtIntGenAvgValues(Underlying a_Underlying)
Definition: ProtIntGen.h:338
int chooseRandomOne(int a_RndX, int a_RndZ, int a_Val1, int a_Val2, int a_Val3, int a_Val4)
Chooses one of a_ValN, based on m_Noise and the coordinates for querying the noise.
Definition: ProtIntGen.h:92
const int bgLandOceanMax
Definition: IntGen.h:45
Randomly replaces pixels of one value to another value, using the given chance.
Definition: ProtIntGen.h:1044
cProtIntGenSetRandomly(int a_Seed, int a_Chance, int a_ToValue, Underlying a_Underlying)
Definition: ProtIntGen.h:1325
virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
Generates the array of specified size into a_Values, based on given min coords.
Definition: ProtIntGen.h:159
Underlying m_Underlying
Definition: ProtIntGen.h:815
Changes biomes in the parent data into an alternate versions (usually "hill" variants), in such places that have their alterations set.
Definition: ProtIntGen.h:1416
cProtIntGenMixRivers(Underlying a_Biomes, Underlying a_Rivers)
Definition: ProtIntGen.h:1115
int m_Chance
Chance, in permille, of changing each pixel into the rare biome group.
Definition: ProtIntGen.h:1404
Adds a random value in range [-a_HalfRange, +a_HalfRange] to each of the underlying values...
Definition: ProtIntGen.h:520
virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values)
Generates the array of specified size into a_Values, based on given min coords.
Definition: ProtIntGen.h:835
Underlying m_Underlying
Definition: ProtIntGen.h:417
cProtIntGenWithNoise super
Definition: ProtIntGen.h:623
cProtIntGenAlternateBiomes(int a_Seed, Underlying a_Alterations, Underlying a_BaseBiomes)
Definition: ProtIntGen.h:1422
cProtIntGenAddRnd(int a_Seed, int a_HalfRange, Underlying a_Underlying)
Definition: ProtIntGen.h:526
const int bgTemperate
Definition: IntGen.h:42
std::shared_ptr< cProtIntGen > Underlying
Definition: ProtIntGen.h:1050
const int bgOcean
Constants representing the biome group designators.
Definition: IntGen.h:40
Underlying m_Underlying
The underlying generator.
Definition: ProtIntGen.h:1407
Replaces random underlying values with a random value in between the max and min of the neighbors...
Definition: ProtIntGen.h:620
virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
Generates the array of specified size into a_Values, based on given min coords.
Definition: ProtIntGen.h:489
cProtIntGenWithNoise super
Definition: ProtIntGen.h:778
virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values)=0
Generates the array of specified size into a_Values, based on given min coords.
cProtIntGenRareBiomeGroups(int a_Seed, int a_Chance, Underlying a_Underlying)
Definition: ProtIntGen.h:1374
cProtIntGenBiomes(int a_Seed, Underlying a_Underlying)
Definition: ProtIntGen.h:926
Converts land biomes at the edge of an ocean into the respective beach biome.
Definition: ProtIntGen.h:676
cProtIntGenWithNoise super
Definition: ProtIntGen.h:1419
virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
Generates the array of specified size into a_Values, based on given min coords.
Definition: ProtIntGen.h:1654
virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
Generates the array of specified size into a_Values, based on given min coords.
Definition: ProtIntGen.h:123
bool IsBiomeNoDownfall(EMCSBiome a_Biome)
Returns true if the biome has no downfall - deserts and savannas.
Definition: BiomeDef.cpp:140
cProtIntGenReplaceRandomly(int a_Seed, int a_From, int a_To, int a_Chance, Underlying a_Underlying)
Definition: ProtIntGen.h:1053
cProtIntGenWithNoise super
Definition: ProtIntGen.h:523
virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
Generates the array of specified size into a_Values, based on given min coords.
Definition: ProtIntGen.h:1063
Turns biome group indices into real biomes.
Definition: ProtIntGen.h:920
cProtIntGenWithNoise(int a_Seed)
Definition: ProtIntGen.h:76
virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
Generates the array of specified size into a_Values, based on given min coords.
Definition: ProtIntGen.h:1494
#define PROT_INT_BUFFER_SIZE
Maximum size of the generated area.
Definition: ProtIntGen.h:36
Underlying m_Underlying
Definition: ProtIntGen.h:368
cProtIntGenRndBetween(int a_Seed, int a_AvgChancePct, Underlying a_Underlying)
Definition: ProtIntGen.h:626
cProtIntGenRndChoice(int a_Seed, int a_ChancePct, int a_Min, int a_Range, Underlying a_Underlying)
Definition: ProtIntGen.h:479
virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
Generates the array of specified size into a_Values, based on given min coords.
Definition: ProtIntGen.h:344
cProtIntGenWithNoise super
Definition: ProtIntGen.h:923
virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
Generates the array of specified size into a_Values, based on given min coords.
Definition: ProtIntGen.h:634
cProtIntGenWithNoise super
Definition: ProtIntGen.h:566
Adds a "rare" flag to random biome groups, based on the given chance.
Definition: ProtIntGen.h:1368
virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
Generates the array of specified size into a_Values, based on given min coords.
Definition: ProtIntGen.h:1244
Replaces random values of the underlying data with random integers in the specified range [Min ...
Definition: ProtIntGen.h:473
Turns some of the oceans into the specified biome.
Definition: ProtIntGen.h:1229
Underlying m_Underlying
Definition: ProtIntGen.h:766
cProtIntGenWithNoise super
Definition: ProtIntGen.h:149
virtual ~cProtIntGen()
Force a virtual destructor in all descendants.
Definition: ProtIntGen.h:59
cProtIntGenBeaches(Underlying a_Underlying)
Definition: ProtIntGen.h:682
virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
Generates the array of specified size into a_Values, based on given min coords.
Definition: ProtIntGen.h:272
cProtIntGenMBiomes(int a_Seed, Underlying a_Alteration, Underlying a_Underlying)
Definition: ProtIntGen.h:1646
cProtIntGenWithNoise super
Definition: ProtIntGen.h:476
Generates the underlying numbers and then randomly changes some ocean group pixels into random land b...
Definition: ProtIntGen.h:775
cProtIntGenAddIslands(int a_Seed, int a_Chance, Underlying a_Underlying)
Definition: ProtIntGen.h:784
const int bgfRare
Definition: IntGen.h:46
int m_Chance
Chance of each ocean pixel being converted, in permille.
Definition: ProtIntGen.h:813
Zooms the underlying value array to twice the size.
Definition: ProtIntGen.h:189
cProtIntGenWithNoise super
Definition: ProtIntGen.h:1643
virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
Generates the array of specified size into a_Values, based on given min coords.
Definition: ProtIntGen.h:202
#define ASSERT(x)
Definition: Globals.h:335
cProtIntGenWithNoise super
Definition: ProtIntGen.h:113
virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
Generates the array of specified size into a_Values, based on given min coords.
Definition: ProtIntGen.h:438
cProtIntGen super
Definition: ProtIntGen.h:73
bool IsBiomeVeryCold(EMCSBiome a_Biome)
Returns true if the biome is very cold (has snow on ground everywhere, turns top water to ice...
Definition: BiomeDef.cpp:167
Definition: Noise.h:19
Underlying m_Underlying
Definition: ProtIntGen.h:465
virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
Generates the array of specified size into a_Values, based on given min coords.
Definition: ProtIntGen.h:792
cProtIntGenWithNoise super
Definition: ProtIntGen.h:1176
virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
Generates the array of specified size into a_Values, based on given min coords.
Definition: ProtIntGen.h:535
cProtIntGenWithNoise super
Definition: ProtIntGen.h:1371
cProtIntGenZoom(int a_Seed, Underlying a_UnderlyingGen)
Definition: ProtIntGen.h:195
cProtIntGenChoice(int a_Seed, int a_Range)
Definition: ProtIntGen.h:116
virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
Generates the array of specified size into a_Values, based on given min coords.
Definition: ProtIntGen.h:1334
cProtIntGen super
Definition: ProtIntGen.h:335
virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
Generates the array of specified size into a_Values, based on given min coords.
Definition: ProtIntGen.h:1382
Replaces random underlying values with the average of the neighbors.
Definition: ProtIntGen.h:563
bool IsBiomeOcean(int a_Biome)
Returns true if the biome is an ocean biome.
Definition: BiomeDef.h:139
cProtIntGen super
Definition: ProtIntGen.h:679
Underlying m_Underlying
Definition: ProtIntGen.h:555
virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
Generates the array of specified size into a_Values, based on given min coords.
Definition: ProtIntGen.h:388
Averages the values of the underlying 2 * 2 neighbors.
Definition: ProtIntGen.h:332
Underlying m_Underlying
Definition: ProtIntGen.h:512
const int bgDesert
Definition: IntGen.h:41
cProtIntGenWithNoise super
Definition: ProtIntGen.h:1047
bool isDesertCompatible(int a_BiomeGroup)
Definition: ProtIntGen.h:895
int m_To
The destination value to which to replace.
Definition: ProtIntGen.h:1093
A filter that adds an edge biome group between two biome groups that need an edge between them...
Definition: ProtIntGen.h:823
virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
Generates the array of specified size into a_Values, based on given min coords.
Definition: ProtIntGen.h:1430
cProtIntGenLandOcean(int a_Seed, int a_Threshold)
Definition: ProtIntGen.h:152
virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
Generates the array of specified size into a_Values, based on given min coords.
Definition: ProtIntGen.h:688
Mixer that joins together finalized biomes and rivers.
Definition: ProtIntGen.h:1109
int m_Chance
Chance, in permille, of changing the biome.
Definition: ProtIntGen.h:1306
cProtIntGenRiver(int a_Seed, Underlying a_Underlying)
Definition: ProtIntGen.h:1179
Decides between the ocean and landmass biomes.
Definition: ProtIntGen.h:146
Interface that all the generator classes provide.
Definition: ProtIntGen.h:44
Underlying m_UnderlyingGen
Definition: ProtIntGen.h:250
cProtIntGenBiomeGroupEdges(Underlying a_Underlying)
Definition: ProtIntGen.h:829
Underlying m_Underlying
Definition: ProtIntGen.h:612
int m_ToValue
The value to change the ocean into.
Definition: ProtIntGen.h:1309
virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
Generates the array of specified size into a_Values, based on given min coords.
Definition: ProtIntGen.h:577
Provides additional cNoise member and its helper functions.
Definition: ProtIntGen.h:70
#define ARRAYCOUNT(X)
Evaluates to the number of elements in an array (compile-time!)
Definition: Globals.h:290
Generates a river based on the underlying data.
Definition: ProtIntGen.h:1173
virtual void GetInts(int a_MinX, int a_MinZ, size_t a_SizeX, size_t a_SizeZ, int *a_Values) override
Generates the array of specified size into a_Values, based on given min coords.
Definition: ProtIntGen.h:1186
Smoothes out some artifacts generated by the zooming - mostly single-pixel values.
Definition: ProtIntGen.h:259
int m_ToValue
The value to which to set the pixel.
Definition: ProtIntGen.h:1358
int m_Chance
Chance, in permille, of changing each pixel.
Definition: ProtIntGen.h:1355
Underlying m_Underlying
Definition: ProtIntGen.h:1698
Underlying m_Alteration
Definition: ProtIntGen.h:1699
cProtIntGenAddToOcean(int a_Seed, int a_Chance, int a_ToValue, Underlying a_Underlying)
Definition: ProtIntGen.h:1235
Averages the values of the underlying 4 * 4 neighbors.
Definition: ProtIntGen.h:376
cProtIntGenSmooth(int a_Seed, Underlying a_Underlying)
Definition: ProtIntGen.h:265
Underlying m_Underlying
The underlying int generator.
Definition: ProtIntGen.h:1036
cProtIntGenWithNoise super
Definition: ProtIntGen.h:192
cProtIntGenWithNoise super
Definition: ProtIntGen.h:1484