Merge branch 'everest_treeline-sx' into jgrpp

This commit is contained in:
Jonathan G Rennison
2015-08-22 01:29:53 +01:00
7 changed files with 109 additions and 10 deletions

View File

@@ -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);