| 828 | } |
| 829 | |
| 830 | static void TileLoop_Trees(TileIndex tile) |
| 831 | { |
| 832 | if (GetTreeGround(tile) == TREE_GROUND_SHORE) { |
| 833 | TileLoop_Water(tile); |
| 834 | } else { |
| 835 | switch (_settings_game.game_creation.landscape) { |
| 836 | case LandscapeType::Tropic: TileLoopTreesDesert(tile); break; |
| 837 | case LandscapeType::Arctic: TileLoopTreesAlps(tile); break; |
| 838 | default: break; |
| 839 | } |
| 840 | } |
| 841 | |
| 842 | AmbientSoundEffect(tile); |
| 843 | |
| 844 | /* TimerGameTick::counter is incremented by 256 between each call, so ignore lower 8 bits. |
| 845 | * Also, we use a simple hash to spread the updates evenly over the map. |
| 846 | * 11 and 9 are just some co-prime numbers for better spread. |
| 847 | */ |
| 848 | uint32_t cycle = 11 * TileX(tile) + 9 * TileY(tile) + (TimerGameTick::counter >> 8); |
| 849 | |
| 850 | /* Handle growth of grass (under trees/on MP_TREES tiles) at every 8th processings, like it's done for grass on MP_CLEAR tiles. */ |
| 851 | if ((cycle & 7) == 7 && GetTreeGround(tile) == TREE_GROUND_GRASS) { |
| 852 | uint density = GetTreeDensity(tile); |
| 853 | if (density < 3) { |
| 854 | SetTreeGroundDensity(tile, TREE_GROUND_GRASS, density + 1); |
| 855 | MarkTileDirtyByTile(tile); |
| 856 | } |
| 857 | } |
| 858 | |
| 859 | if (_settings_game.construction.extra_tree_placement == ETP_NO_GROWTH_NO_SPREAD) return; |
| 860 | |
| 861 | static const uint32_t TREE_UPDATE_FREQUENCY = 16; // How many tile updates happen for one tree update |
| 862 | if (cycle % TREE_UPDATE_FREQUENCY != TREE_UPDATE_FREQUENCY - 1) return; |
| 863 | |
| 864 | switch (GetTreeGrowth(tile)) { |
| 865 | case TreeGrowthStage::Grown: // regular sized tree |
| 866 | if (_settings_game.game_creation.landscape == LandscapeType::Tropic && |
| 867 | GetTreeType(tile) != TREE_CACTUS && |
| 868 | GetTropicZone(tile) == TROPICZONE_DESERT) { |
| 869 | AddTreeGrowth(tile, 1); |
| 870 | } else { |
| 871 | switch (GB(Random(), 0, 3)) { |
| 872 | case 0: // start destructing |
| 873 | AddTreeGrowth(tile, 1); |
| 874 | break; |
| 875 | |
| 876 | case 1: // add a tree |
| 877 | if (GetTreeCount(tile) < 4 && TreesOnTileCanSpread(tile)) { |
| 878 | AddTreeCount(tile, 1); |
| 879 | SetTreeGrowth(tile, TreeGrowthStage::Growing1); |
| 880 | break; |
| 881 | } |
| 882 | [[fallthrough]]; |
| 883 | |
| 884 | case 2: { // add a neighbouring tree |
| 885 | if (!TreesOnTileCanSpread(tile)) break; |
| 886 | |
| 887 | TreeType treetype = GetTreeType(tile); |
nothing calls this directly
no test coverage detected