diff --git a/src/lang/english.txt b/src/lang/english.txt index 881db7cfc7..2414bd5d91 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -1586,11 +1586,12 @@ STR_CONFIG_SETTING_RIVER_AMOUNT :River amount: { STR_CONFIG_SETTING_RIVER_AMOUNT_HELPTEXT :Choose how many rivers to generate STR_CONFIG_SETTING_TREE_PLACER :Tree placer algorithm: {STRING2} -STR_CONFIG_SETTING_TREE_PLACER_HELPTEXT :Choose the distribution of trees on the map: 'Original' plants trees uniformly scattered, 'Improved' plants them in groups +STR_CONFIG_SETTING_TREE_PLACER_HELPTEXT :Choose the distribution of trees on the map: 'Original' plants trees uniformly scattered, 'Improved' plants them in groups, 'Forest' plants them in forests ###length 3 STR_CONFIG_SETTING_TREE_PLACER_NONE :None STR_CONFIG_SETTING_TREE_PLACER_ORIGINAL :Original STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Improved +STR_CONFIG_SETTING_TREE_PLACER_FOREST :Forest STR_CONFIG_SETTING_ROAD_SIDE :Road vehicles: {STRING2} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Choose the driving side diff --git a/src/tree_cmd.cpp b/src/tree_cmd.cpp index 1a58c6c2e1..4dd618f720 100644 --- a/src/tree_cmd.cpp +++ b/src/tree_cmd.cpp @@ -41,6 +41,7 @@ enum TreePlacer { TP_NONE, ///< No tree placer algorithm TP_ORIGINAL, ///< The original algorithm TP_IMPROVED, ///< A 'improved' algorithm + TP_FOREST, ///< An algorithm trying to make only forests }; /** Where to place trees while in-game? */ @@ -80,6 +81,30 @@ static bool CanPlantTreesOnTile(TileIndex tile, bool allow_desert) } } +/** +* Tests if a tile is near an already existing forest. +* Trees won't spread if not placed near some other trees. +* +* @param tile the tile of interest +* @return true if the tile is near a forest +*/ +static bool IsNearbyForest(TileIndex tile) +{ + uint planted_tile_count = 0; + + for (int x = -2; x <= 2; x++) { + for (int y = -2; y <= 2; y++) { + TileIndex vincity = TileAddWrap(tile, x, y); + if (vincity != INVALID_TILE && + IsTileType(vincity, MP_TREES)) { + planted_tile_count++; + } + } + } + + return (planted_tile_count >= 6); +} + /** * Creates a tree tile * Ground type and density is preserved. @@ -257,7 +282,10 @@ void PlaceTreesRandomly() if (CanPlantTreesOnTile(tile, true)) { PlaceTree(tile, r); - if (_settings_game.game_creation.tree_placer != TP_IMPROVED) continue; + if (_settings_game.game_creation.tree_placer != TP_IMPROVED && + _settings_game.game_creation.tree_placer != TP_FOREST) { + continue; + } /* Place a number of trees based on the tile height. * This gives a cool effect of multiple trees close together. @@ -358,6 +386,7 @@ void GenerateTrees() switch (_settings_game.game_creation.tree_placer) { case TP_ORIGINAL: i = _settings_game.game_creation.landscape == LT_ARCTIC ? 15 : 6; break; + case TP_FOREST: /* FALL THROUGH */ case TP_IMPROVED: i = _settings_game.game_creation.landscape == LT_ARCTIC ? 4 : 2; break; default: NOT_REACHED(); } @@ -371,6 +400,8 @@ void GenerateTrees() if (num_groups != 0) PlaceTreeGroups(num_groups); + if (_settings_game.game_creation.tree_placer == TP_FOREST) return; + for (; i != 0; i--) { PlaceTreesRandomly(); } @@ -758,6 +789,9 @@ static void TileLoop_Trees(TileIndex tile) /* Don't plant trees, if ground was freshly cleared */ if (IsTileType(tile, MP_CLEAR) && GetClearGround(tile) == CLEAR_GRASS && GetClearDensity(tile) != 3) return; + /* Plants trees only near existing forests */ + if (_settings_game.game_creation.tree_placer == TP_FOREST && !IsNearbyForest(tile)) return; + PlantTreesOnTile(tile, treetype, 0, 0); break; @@ -859,6 +893,9 @@ void OnTick_Trees() r = Random(); tile = RandomTileSeed(r); if (CanPlantTreesOnTile(tile, false) && (tree = GetRandomTreeType(tile, GB(r, 24, 8))) != TREE_INVALID) { + /* Plants trees only near existing forests */ + if (_settings_game.game_creation.tree_placer == TP_FOREST && !IsNearbyForest(tile)) return; + PlantTreesOnTile(tile, tree, 0, 0); } }