153static const int HEIGHT_DECIMAL_BITS = 4;
157static const int AMPLITUDE_DECIMAL_BITS = 10;
162 std::vector<Height>
h;
187 return i << HEIGHT_DECIMAL_BITS;
193 return i >> HEIGHT_DECIMAL_BITS;
199 return i >> (AMPLITUDE_DECIMAL_BITS - HEIGHT_DECIMAL_BITS);
205static constexpr int WATER_PERCENT_FACTOR = 1024;
237 { 3, 3, 3, 3, 4, 5, 7 },
238 { 5, 7, 8, 9, 14, 19, 31 },
239 { 8, 9, 10, 15, 23, 37, 61 },
240 { 10, 11, 17, 19, 49, 63, 73 },
241 { 12, 19, 25, 31, 67, 75, 87 },
252 return I2H(max_height_from_table);
272 static const Amplitude amplitudes[][7] = {
274 {16000, 5600, 1968, 688, 240, 16, 16},
275 {24000, 12800, 6400, 2700, 1024, 128, 16},
276 {32000, 19200, 12800, 8000, 3200, 256, 64},
277 {48000, 24000, 19200, 16000, 8000, 512, 320},
289 static const double extrapolation_factors[] = { 3.3, 2.8, 2.3, 1.8 };
294 int index = frequency -
MAX_TGP_FREQUENCIES +
static_cast<int>(std::size(amplitudes[smoothness]));
295 Amplitude amplitude = amplitudes[smoothness][std::max(0, index)];
296 if (index >= 0)
return amplitude;
299 double extrapolation_factor = extrapolation_factors[smoothness];
300 int height_range =
I2H(16);
302 amplitude = (
Amplitude)(extrapolation_factor * (
double)amplitude);
375 if (amplitude == 0)
continue;
397 Height h01 = (h00 + h02) / 2;
407 Height h10 = (h00 + h20) / 2;
424 Height h_min, h_max, h_avg;
430 if (h < h_min) h_min = h;
431 if (h > h_max) h_max = h;
439 if (min_ptr !=
nullptr) *min_ptr = h_min;
440 if (max_ptr !=
nullptr) *max_ptr = h_max;
441 if (avg_ptr !=
nullptr) *avg_ptr = h_avg;
447 int *hist = hist_buf - h_min;
464 if (h < h_min)
continue;
467 fheight = (double)(h - h_min) / (double)(h_max - h_min);
470 case LandscapeType::Toyland:
471 case LandscapeType::Temperate:
473 fheight = 2 * fheight - 1;
475 fheight = sin(fheight * M_PI_2);
477 fheight = 0.5 * (fheight + 1);
480 case LandscapeType::Arctic:
484 double sine_upper_limit = 0.75;
485 double linear_compression = 2;
486 if (fheight >= sine_upper_limit) {
488 fheight = 1.0 - (1.0 - fheight) / linear_compression;
490 double m = 1.0 - (1.0 - sine_upper_limit) / linear_compression;
492 fheight = 2.0 * fheight / sine_upper_limit - 1.0;
494 fheight = sin(fheight * M_PI_2);
496 fheight = 0.5 * (fheight + 1.0) * m;
501 case LandscapeType::Tropic:
505 double sine_lower_limit = 0.5;
506 double linear_compression = 2;
507 if (fheight <= sine_lower_limit) {
509 fheight = fheight / linear_compression;
511 double m = sine_lower_limit / linear_compression;
513 fheight = 2.0 * ((fheight - sine_lower_limit) / (1.0 - sine_lower_limit)) - 1.0;
515 fheight = sin(fheight * M_PI_2);
517 fheight = 0.5 * ((1.0 - m) * fheight + (1.0 + m));
527 h = (
Height)(fheight * (h_max - h_min) + h_min);
528 if (h < 0) h =
I2H(0);
529 if (h >= h_max) h = h_max - 1;
554 struct ControlPoint {
559#define F(fraction) ((Height)(fraction * mh))
560 const ControlPoint curve_map_1[] = { { F(0.0), F(0.0) }, { F(0.8), F(0.13) }, { F(1.0), F(0.4) } };
561 const ControlPoint curve_map_2[] = { { F(0.0), F(0.0) }, { F(0.53), F(0.13) }, { F(0.8), F(0.27) }, { F(1.0), F(0.6) } };
562 const ControlPoint curve_map_3[] = { { F(0.0), F(0.0) }, { F(0.53), F(0.27) }, { F(0.8), F(0.57) }, { F(1.0), F(0.8) } };
563 const ControlPoint curve_map_4[] = { { F(0.0), F(0.0) }, { F(0.4), F(0.3) }, { F(0.7), F(0.8) }, { F(0.92), F(0.99) }, { F(1.0), F(0.99) } };
566 const std::span<const ControlPoint> curve_maps[] = { curve_map_1, curve_map_2, curve_map_3, curve_map_4 };
568 std::array<
Height, std::size(curve_maps)> ht{};
572 uint sx =
Clamp((
int)(((1 << level) * factor) + 0.5), 1, 128);
573 uint sy =
Clamp((
int)(((1 << level) / factor) + 0.5), 1, 128);
574 std::vector<uint8_t> c(
static_cast<size_t>(sx) * sy);
576 for (uint i = 0; i < sx * sy; i++) {
577 c[i] =
RandomRange(
static_cast<uint32_t
>(std::size(curve_maps)));
587 float xr = 2.0f * (fx - x1) - 1.0f;
588 xr = sin(xr * M_PI_2);
589 xr = sin(xr * M_PI_2);
590 xr = 0.5f * (xr + 1.0f);
591 float xri = 1.0f - xr;
604 float yr = 2.0f * (fy - y1) - 1.0f;
605 yr = sin(yr * M_PI_2);
606 yr = sin(yr * M_PI_2);
607 yr = 0.5f * (yr + 1.0f);
608 float yri = 1.0f - yr;
615 uint corner_a = c[x1 + sx * y1];
616 uint corner_b = c[x1 + sx * y2];
617 uint corner_c = c[x2 + sx * y1];
618 uint corner_d = c[x2 + sx * y2];
622 uint corner_bits = 0;
623 corner_bits |= 1 << corner_a;
624 corner_bits |= 1 << corner_b;
625 corner_bits |= 1 << corner_c;
626 corner_bits |= 1 << corner_d;
631 if (*h <
I2H(1))
continue;
637 for (
size_t t = 0; t < std::size(curve_maps); t++) {
638 if (!
HasBit(corner_bits,
static_cast<uint8_t
>(t)))
continue;
640 [[maybe_unused]]
bool found =
false;
641 auto &cm = curve_maps[t];
642 for (
size_t i = 0; i < cm.size() - 1; i++) {
643 const ControlPoint &p1 = cm[i];
644 const ControlPoint &p2 = cm[i + 1];
646 if (*h >= p1.x && *h < p2.x) {
647 ht[t] = p1.y + (*h - p1.x) * (p2.y - p1.y) / (p2.x - p1.x);
658 *h = (
Height)((ht[corner_a] * yri + ht[corner_b] * yr) * xri + (ht[corner_c] * yri + ht[corner_d] * yr) * xr);
669 Height h_min, h_max, h_avg, h_water_level;
670 int64_t water_tiles, desired_water_tiles;
676 std::vector<int> hist_buf(h_max - h_min + 1);
684 for (h_water_level = h_min, water_tiles = 0; h_water_level < h_max; h_water_level++) {
685 water_tiles += hist[h_water_level];
686 if (water_tiles >= desired_water_tiles)
break;
697 h = (
Height)(((
int)h_max_new) * (h - h_water_level) / (h_max - h_water_level)) +
I2H(1);
699 if (h < 0) h =
I2H(0);
700 if (h >= h_max_new) h = h_max_new - 1;
729 const int margin = 4;
739 max_x = std::max((smallest_size * smallest_size / 64) + max_x, (smallest_size * smallest_size / 64) + margin - max_x);
740 if (smallest_size < 8 && max_x > 5) max_x /= 1.5;
741 for (x = 0; x < max_x; x++) {
749 max_x = std::max((smallest_size * smallest_size / 64) + max_x, (smallest_size * smallest_size / 64) + margin - max_x);
750 if (smallest_size < 8 && max_x > 5) max_x /= 1.5;
762 max_y = std::max((smallest_size * smallest_size / 64) + max_y, (smallest_size * smallest_size / 64) + margin - max_y);
763 if (smallest_size < 8 && max_y > 5) max_y /= 1.5;
764 for (y = 0; y < max_y; y++) {
772 max_y = std::max((smallest_size * smallest_size / 64) + max_y, (smallest_size * smallest_size / 64) + margin - max_y);
773 if (smallest_size < 8 && max_y > 5) max_y /= 1.5;
784 const int max_coast_dist_from_edge = 35;
785 const int max_coast_smooth_depth = 35;
797 for (x = org_x, y = org_y, ed = 0;
IsValidXY(x, y) && ed < max_coast_dist_from_edge; x += dir_x, y += dir_y, ed++) {
810 for (depth = 0;
IsValidXY(x, y) && depth <= max_coast_smooth_depth; depth++, x += dir_x, y += dir_y) {
812 h =
static_cast<Height>(std::min<uint>(h, h_prev + (4 + depth)));
895static double int_noise(
const long x,
const long y,
const int prime)
902 return 1.0 - (double)((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0;
911 return a + x * (b - a);
921 const int integer_x = (int)x;
922 const int integer_y = (int)y;
924 const double fractional_x = x - (double)integer_x;
925 const double fractional_y = y - (double)integer_y;
927 const double v1 =
int_noise(integer_x, integer_y, prime);
928 const double v2 =
int_noise(integer_x + 1, integer_y, prime);
929 const double v3 =
int_noise(integer_x, integer_y + 1, prime);
930 const double v4 =
int_noise(integer_x + 1, integer_y + 1, prime);
947 constexpr int OCTAVES = 6;
948 constexpr double INITIAL_FREQUENCY = 1 << OCTAVES;
951 double frequency = 1.0 / INITIAL_FREQUENCY;
952 double amplitude = 1.0;
953 for (
int i = 0; i < OCTAVES; i++) {
static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
Map accessors for 'clear' tiles.
void MakeClear(Tile t, ClearGround g, uint density)
Make a clear tile.
void GenerateWorldSetAbortCallback(GWAbortProc *proc)
Set here the function, if any, that you want to be called when landscape generation is aborted.
Functions related to world/map generation.
void IncreaseGeneratingWorldProgress(GenWorldProgress cls)
Increases the current stage of the world generation with one.
static const uint CUSTOM_SEA_LEVEL_NUMBER_DIFFICULTY
Value for custom sea level in difficulty settings.
@ GWP_LANDSCAPE
Create the landscape.
static const uint CUSTOM_TERRAIN_TYPE_NUMBER_DIFFICULTY
Value for custom terrain type in difficulty settings.
Types related to the landscape.
static constexpr BorderFlags BORDERFLAGS_ALL
Border on all sides.
@ NorthWest
Border on North West.
@ Random
Randomise borders.
@ NorthEast
Border on North East.
@ SouthEast
Border on South East.
@ SouthWest
Border on South West.
static TileIndex TileXY(uint x, uint y)
Returns the TileIndex of a coordinate.
static const uint MIN_MAP_SIZE_BITS
Minimal and maximal map width and height.
static const uint MAX_MAP_SIZE_BITS
Maximal size of map is equal to 2 ^ MAX_MAP_SIZE_BITS.
constexpr T abs(const T a)
Returns the absolute value of (scalar) variable.
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Pseudo random number generator.
uint32_t RandomRange(uint32_t limit, const std::source_location location=std::source_location::current())
Pick a random number between 0 and limit - 1, inclusive.
A number of safeguards to prevent using unsafe methods.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition of base types and functions in a cross-platform compatible way.
bool freeform_edges
allow terraforming the tiles at the map edges
uint8_t map_height_limit
the maximum allowed heightlevel
uint8_t terrain_type
the mountainousness of the landscape
uint8_t quantity_sea_lakes
the amount of seas/lakes
uint8_t custom_sea_level
manually entered percentage of water in the map
uint8_t variety
variety level applied to TGP
uint8_t custom_terrain_type
manually entered height for TGP to aim for
LandscapeType landscape
the landscape we're currently in
uint8_t map_x
X size of map.
uint8_t tgen_smoothness
how rough is the terrain from 0-3
uint8_t map_y
Y size of map.
BorderFlags water_borders
bitset of the borders that are water
uint32_t generation_seed
noise seed for world generation
ConstructionSettings construction
construction of things in-game
DifficultySettings difficulty
settings related to the difficulty
GameCreationSettings game_creation
settings used during the creation of a game (map)
Height map - allocated array of heights (Map::SizeX() + 1) * (Map::SizeY() + 1)
std::vector< Height > h
array of heights
int dim_x
height map size_x Map::SizeX() + 1
Height & height(uint x, uint y)
Height map accessor.
static uint SizeX()
Get the size of the map along the X.
static uint SizeY()
Get the size of the map along the Y.
static uint LogX()
Logarithm of the map size along the X side.
static uint LogY()
Logarithm of the map size along the y side.
static Height RandomHeight(Amplitude r_max)
Generates new random height in given amplitude (generated numbers will range from - amplitude to + am...
static void HeightMapSmoothCoastInDirection(int org_x, int org_y, int dir_x, int dir_y)
Start at given point, move in given direction, find and Smooth coast in that direction.
static Height A2H(Amplitude i)
Conversion: Amplitude to Height.
static void HeightMapGenerate()
Base Perlin noise generator - fills height map with raw Perlin noise.
static double linear_interpolate(const double a, const double b, const double x)
This routine determines the interpolated value between a and b.
static Height TGPGetMaxHeight()
Gets the maximum allowed height while generating a map based on mapsize, terraintype,...
static void HeightMapCoastLines(BorderFlags water_borders)
This routine sculpts in from the edge a random amount, again a Perlin sequence, to avoid the rigid fl...
static Height I2H(int i)
Conversion: int to Height.
static int H2I(Height i)
Conversion: Height to int.
static void HeightMapGetMinMaxAvg(Height *min_ptr, Height *max_ptr, Height *avg_ptr)
Returns min, max and average height from height map.
static void HeightMapSmoothSlopes(Height dh_max)
This routine provides the essential cleanup necessary before OTTD can display the terrain.
static const int64_t _water_percent[4]
Desired water percentage (100% == 1024) - indexed by _settings_game.difficulty.quantity_sea_lakes.
int16_t Height
Fixed point type for heights.
static Amplitude GetAmplitude(int frequency)
Get the amplitude associated with the currently selected smoothness and maximum height level.
static int * HeightMapMakeHistogram(Height h_min, Height h_max, int *hist_buf)
Dill histogram and return pointer to its base point - to the count of zero heights.
static void FreeHeightMap()
Free height map.
int Amplitude
Fixed point array for amplitudes.
uint GetEstimationTGPMapHeight()
Get an overestimation of the highest peak TGP wants to generate.
static void HeightMapAdjustWaterLevel(int64_t water_percent, Height h_max_new)
Adjusts heights in height map to contain required amount of water tiles.
static void HeightMapSineTransform(Height h_min, Height h_max)
Applies sine wave redistribution onto height map.
static HeightMap _height_map
Global height map instance.
static void HeightMapNormalize()
Height map terraform post processing:
static void HeightMapSmoothCoasts(BorderFlags water_borders)
Smooth coasts by modulating height of tiles close to map edges with cosine of distance from edge.
static bool IsValidXY(int x, int y)
Check if a X/Y set are within the map.
static const int MAX_TGP_FREQUENCIES
Maximum number of TGP noise frequencies.
static double perlin_coast_noise_2D(const double x, const double y, const double p, const int prime)
This is a similar function to the main perlin noise calculation, but uses the value p passed as a par...
static void TgenSetTileHeight(TileIndex tile, int height)
A small helper function to initialize the terrain.
void GenerateTerrainPerlin()
The main new land generator using Perlin noise.
static double interpolated_noise(const double x, const double y, const int prime)
This routine returns the smoothed interpolated noise for an x and y, using the values from the surrou...
static double int_noise(const long x, const long y, const int prime)
The Perlin Noise calculation using large primes The initial number is adjusted by two values; the gen...
static void HeightMapCurves(uint level)
Additional map variety is provided by applying different curve maps to different parts of the map.
static void AllocHeightMap()
Allocate array of (Map::SizeX() + 1) * (Map::SizeY() + 1) heights and init the _height_map structure ...
bool IsInnerTile(Tile tile)
Check if a tile is within the map (not a border)
void SetTileHeight(Tile tile, uint height)
Sets the height of a tile.
Map accessors for void tiles.
void MakeVoid(Tile t)
Make a nice void tile ;)