Merge branch 'everest_treeline-sx' into jgrpp
This commit is contained in:
@@ -118,6 +118,50 @@ static void PlantTreesOnTile(TileIndex tile, TreeType treetype, uint count, uint
|
||||
MakeTree(tile, treetype, count, growth, ground, density);
|
||||
}
|
||||
|
||||
/**
|
||||
* Previous value of _settings_game.construction.trees_around_snow_line_range
|
||||
* used to calculate _arctic_tree_occurance
|
||||
*/
|
||||
static uint8 _previous_trees_around_snow_line_range = 255;
|
||||
|
||||
/**
|
||||
* Array of probabilities for artic trees to appear,
|
||||
* by normalised distance from snow line
|
||||
*/
|
||||
static uint8 _arctic_tree_occurance[24];
|
||||
|
||||
/** Recalculate _arctic_tree_occurance */
|
||||
static void RecalculateArcticTreeOccuranceArray()
|
||||
{
|
||||
/*
|
||||
* Approximate: 256 * exp(-3 * distance / range)
|
||||
* By using:
|
||||
* 256 * ((1 + (-3 * distance / range) / 6) ** 6)
|
||||
* ((256 - (128 * distance / range)) ** 6) >> (5 * 8);
|
||||
*/
|
||||
uint8 range = _settings_game.construction.trees_around_snow_line_range;
|
||||
_previous_trees_around_snow_line_range = range;
|
||||
_arctic_tree_occurance[0] = 255;
|
||||
uint i = 1;
|
||||
for (; i < lengthof(_arctic_tree_occurance); i++) {
|
||||
if (range == 0) break;
|
||||
uint x = 256 - ((128 * i) / range);
|
||||
uint32 output = x;
|
||||
output *= x;
|
||||
output *= x;
|
||||
output *= x;
|
||||
output >>= 16;
|
||||
output *= x;
|
||||
output *= x;
|
||||
output >>= 24;
|
||||
if (output == 0) break;
|
||||
_arctic_tree_occurance[i] = output;
|
||||
}
|
||||
for (; i < lengthof(_arctic_tree_occurance); i++) {
|
||||
_arctic_tree_occurance[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random TreeType for the given tile based on a given seed
|
||||
*
|
||||
@@ -135,9 +179,30 @@ static TreeType GetRandomTreeType(TileIndex tile, uint seed)
|
||||
case LT_TEMPERATE:
|
||||
return (TreeType)(seed * TREE_COUNT_TEMPERATE / 256 + TREE_TEMPERATE);
|
||||
|
||||
case LT_ARCTIC:
|
||||
return (TreeType)(seed * TREE_COUNT_SUB_ARCTIC / 256 + TREE_SUB_ARCTIC);
|
||||
case LT_ARCTIC: {
|
||||
if (!_settings_game.construction.trees_around_snow_line_enabled) {
|
||||
return (TreeType)(seed * TREE_COUNT_SUB_ARCTIC / 256 + TREE_SUB_ARCTIC);
|
||||
}
|
||||
|
||||
uint8 range = _settings_game.construction.trees_around_snow_line_range;
|
||||
if (range != _previous_trees_around_snow_line_range) RecalculateArcticTreeOccuranceArray();
|
||||
|
||||
int z = GetTileZ(tile);
|
||||
int height_above_snow_line = z - _settings_game.game_creation.snow_line_height;
|
||||
uint normalised_distance = (height_above_snow_line < 0) ? -height_above_snow_line : height_above_snow_line + 1;
|
||||
bool arctic_tree = false;
|
||||
if (normalised_distance < lengthof(_arctic_tree_occurance)) {
|
||||
uint adjusted_seed = (seed ^ tile) & 0xFF;
|
||||
arctic_tree = adjusted_seed < _arctic_tree_occurance[normalised_distance];
|
||||
}
|
||||
if (height_above_snow_line < 0) {
|
||||
/* Below snow level mixed forest. */
|
||||
return (arctic_tree) ? (TreeType)(seed * TREE_COUNT_SUB_ARCTIC / 256 + TREE_SUB_ARCTIC) : (TreeType)(seed * TREE_COUNT_TEMPERATE / 256 + TREE_TEMPERATE);
|
||||
} else {
|
||||
/* Above is Arctic trees and thinning out. */
|
||||
return (arctic_tree) ? (TreeType)(seed * TREE_COUNT_SUB_ARCTIC / 256 + TREE_SUB_ARCTIC) : TREE_INVALID;
|
||||
}
|
||||
}
|
||||
case LT_TROPIC:
|
||||
switch (GetTropicZone(tile)) {
|
||||
case TROPICZONE_NORMAL: return (TreeType)(seed * TREE_COUNT_SUB_TROPICAL / 256 + TREE_SUB_TROPICAL);
|
||||
|
Reference in New Issue
Block a user