From 82fa5e716474f17bbbdfdfc3b071561582b456bb Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Thu, 29 Sep 2022 09:14:42 +0100 Subject: [PATCH] Change: Scale towns/industries by amount of land tiles. This stops a large map with lots of water being crammed with towns and industries even when set to Very Low. --- src/genworld.cpp | 2 ++ src/industry_cmd.cpp | 3 ++- src/map.cpp | 11 +++++++++++ src/map_func.h | 13 +++++++++++++ src/town_cmd.cpp | 3 ++- 5 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/genworld.cpp b/src/genworld.cpp index 4898567549..6374892d83 100644 --- a/src/genworld.cpp +++ b/src/genworld.cpp @@ -134,11 +134,13 @@ static void _GenerateWorld() if (_game_mode != GM_MENU) FlatEmptyWorld(_settings_game.game_creation.se_flat_world_height); ConvertGroundTilesIntoWaterTiles(); + Map::CountLandTiles(); IncreaseGeneratingWorldProgress(GWP_OBJECT); _settings_game.game_creation.snow_line_height = DEF_SNOWLINE_HEIGHT; } else { GenerateClearTile(); + Map::CountLandTiles(); /* Only generate towns, tree and industries in newgame mode. */ if (_game_mode != GM_EDITOR) { diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index b29e40a824..f4a16558ec 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -43,6 +43,7 @@ #include "industry_cmd.h" #include "landscape_cmd.h" #include "terraform_cmd.h" +#include "map_func.h" #include "timer/timer.h" #include "timer/timer_game_calendar.h" #include "timer/timer_game_economy.h" @@ -2356,7 +2357,7 @@ static uint GetNumberOfIndustries() if (difficulty == ID_CUSTOM) return std::min(IndustryPool::MAX_SIZE, _settings_game.game_creation.custom_industry_number); - return std::min(IndustryPool::MAX_SIZE, Map::ScaleBySize(numof_industry_table[difficulty])); + return std::min(IndustryPool::MAX_SIZE, Map::ScaleByLandProportion(Map::ScaleBySize(numof_industry_table[difficulty]))); } /** diff --git a/src/map.cpp b/src/map.cpp index 67fbd4da1e..7fdf42caec 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -24,6 +24,8 @@ /* static */ uint Map::size; ///< The number of tiles on the map /* static */ uint Map::tile_mask; ///< _map_size - 1 (to mask the mapsize) +/* static */ uint Map::initial_land_count; ///< Initial number of land tiles on the map. + /* static */ std::unique_ptr Tile::base_tiles; ///< Base tiles of the map /* static */ std::unique_ptr Tile::extended_tiles; ///< Extended tiles of the map @@ -59,6 +61,15 @@ AllocateWaterRegions(); } +/* static */ void Map::CountLandTiles() +{ + /* Count number of tiles that are land. */ + Map::initial_land_count = 0; + for (const auto tile : Map::Iterate()) { + Map::initial_land_count += IsWaterTile(tile) ? 0 : 1; + } +} + #ifdef _DEBUG TileIndex TileAdd(TileIndex tile, TileIndexDiff offset) diff --git a/src/map_func.h b/src/map_func.h index 370099b43f..3a917c7486 100644 --- a/src/map_func.h +++ b/src/map_func.h @@ -239,8 +239,11 @@ private: static uint size; ///< The number of tiles on the map static uint tile_mask; ///< _map_size - 1 (to mask the mapsize) + static uint initial_land_count; ///< Initial number of land tiles on the map. + public: static void Allocate(uint size_x, uint size_y); + static void CountLandTiles(); /** * Logarithm of the map size along the X side. @@ -307,6 +310,16 @@ public: return Map::SizeY() - 1; } + /** + * Scales the given value by the number of water tiles. + * @param n the value to scale + * @return the scaled size + */ + static inline uint ScaleByLandProportion(uint n) + { + /* Use 64-bit arithmetic to avoid overflow. */ + return static_cast(static_cast(n) * Map::initial_land_count / Map::size); + } /** * 'Wraps' the given "tile" so it is within the map. diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index c3278a3b93..ece9d155e8 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -53,6 +53,7 @@ #include "road_cmd.h" #include "terraform_cmd.h" #include "tunnelbridge_cmd.h" +#include "map_func.h" #include "timer/timer.h" #include "timer/timer_game_calendar.h" #include "timer/timer_game_economy.h" @@ -2424,7 +2425,7 @@ bool GenerateTowns(TownLayout layout) { uint current_number = 0; uint difficulty = (_game_mode != GM_EDITOR) ? _settings_game.difficulty.number_towns : 0; - uint total = (difficulty == (uint)CUSTOM_TOWN_NUMBER_DIFFICULTY) ? _settings_game.game_creation.custom_town_number : Map::ScaleBySize(_num_initial_towns[difficulty] + (Random() & 7)); + uint total = (difficulty == (uint)CUSTOM_TOWN_NUMBER_DIFFICULTY) ? _settings_game.game_creation.custom_town_number : Map::ScaleByLandProportion(Map::ScaleBySize(_num_initial_towns[difficulty] + (Random() & 7))); total = std::min(TownPool::MAX_SIZE, total); uint32_t townnameparts; TownNames town_names;