From cafe4eed6e482149eefe75393ad3a13e0f6e7ffe Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Wed, 24 Mar 2021 14:48:12 +0100 Subject: Feature: setting to indicate snow coverage for arctic climate (replaces snow line height) Setting the snow coverage (in % of the map) makes a lot more sense to the human, while still allowing the niche player to set (by finding the correct %) a snow line height they like. This makes for easier defaults, as it decoupled terrain height from amount of snow. Maps can never be 100% snow, as we do not have sprites for coastal tiles. Internally, this calculates the best snow line height to approach this coverage as close as possible. --- src/landscape.cpp | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) (limited to 'src/landscape.cpp') diff --git a/src/landscape.cpp b/src/landscape.cpp index ab6ba59f0..98ff6fdbc 100644 --- a/src/landscape.cpp +++ b/src/landscape.cpp @@ -31,6 +31,7 @@ #include "pathfinder/npf/aystar.h" #include "saveload/saveload.h" #include "framerate_type.h" +#include #include #include @@ -1294,6 +1295,43 @@ static void CreateRivers() } } +/** + * Calculate the line from which snow begins. + */ +static void CalculateSnowLine() +{ + /* Build a histogram of the map height. */ + std::array histogram = {}; + for (TileIndex tile = 0; tile < MapSize(); tile++) { + uint h = TileHeight(tile); + histogram[h]++; + } + + /* The amount of land we have is the map size minus the first (sea) layer. */ + uint land_tiles = MapSizeX() * MapSizeY() - histogram[0]; + int best_score = land_tiles; + + /* Our goal is the coverage amount of the land-mass. */ + int goal_tiles = land_tiles * _settings_game.game_creation.snow_coverage / 100; + + /* We scan from top to bottom. */ + uint h = MAX_TILE_HEIGHT; + uint best_h = h; + + int current_tiles = 0; + for (; h > 0; h--) { + current_tiles += histogram[h]; + int current_score = goal_tiles - current_tiles; + + if (std::abs(current_score) < std::abs(best_score)) { + best_score = current_score; + best_h = h; + } + } + + _settings_game.game_creation.snow_line_height = std::max(best_h, 2u); +} + void GenerateLandscape(byte mode) { /** Number of steps of landscape generation */ @@ -1378,7 +1416,18 @@ void GenerateLandscape(byte mode) MarkWholeScreenDirty(); IncreaseGeneratingWorldProgress(GWP_LANDSCAPE); - if (_settings_game.game_creation.landscape == LT_TROPIC) CreateDesertOrRainForest(); + switch (_settings_game.game_creation.landscape) { + case LT_ARCTIC: + CalculateSnowLine(); + break; + + case LT_TROPIC: + CreateDesertOrRainForest(); + break; + + default: + break; + } CreateRivers(); } -- cgit v1.2.3-54-g00ecf