src/tree_cmd.cpp
branchNewGRF_ports
changeset 6877 889301acc299
parent 6872 1c4a4a609f85
child 6878 7d1ff2f621c7
equal deleted inserted replaced
6876:2c40faeef7a5 6877:889301acc299
    18 #include "transparency.h"
    18 #include "transparency.h"
    19 #include "functions.h"
    19 #include "functions.h"
    20 #include "player_func.h"
    20 #include "player_func.h"
    21 #include "sound_func.h"
    21 #include "sound_func.h"
    22 #include "settings_type.h"
    22 #include "settings_type.h"
       
    23 #include "water_map.h"
       
    24 #include "water.h"
    23 
    25 
    24 #include "table/strings.h"
    26 #include "table/strings.h"
    25 #include "table/sprites.h"
    27 #include "table/sprites.h"
    26 #include "table/tree_land.h"
    28 #include "table/tree_land.h"
    27 
    29 
    35 	TP_ORIGINAL, ///< The original algorithm
    37 	TP_ORIGINAL, ///< The original algorithm
    36 	TP_IMPROVED, ///< A 'improved' algorithm
    38 	TP_IMPROVED, ///< A 'improved' algorithm
    37 };
    39 };
    38 
    40 
    39 /**
    41 /**
       
    42  * Tests if a tile can be converted to MP_TREES
       
    43  * This is true for clear ground without farms or rocks.
       
    44  *
       
    45  * @param tile the tile of interest
       
    46  * @param allow_desert Allow planting trees on CLEAR_DESERT?
       
    47  * @return true if trees can be built.
       
    48  */
       
    49 static bool CanPlantTreesOnTile(TileIndex tile, bool allow_desert)
       
    50 {
       
    51 	switch (GetTileType(tile)) {
       
    52 		case MP_WATER:
       
    53 			return !IsBridgeAbove(tile) && IsCoast(tile) && !IsSlopeWithOneCornerRaised(GetTileSlope(tile, NULL));
       
    54 
       
    55 		case MP_CLEAR:
       
    56 			return !IsBridgeAbove(tile) && !IsClearGround(tile, CLEAR_FIELDS) && !IsClearGround(tile, CLEAR_ROCKS) &&
       
    57 			       (allow_desert || !IsClearGround(tile, CLEAR_DESERT));
       
    58 
       
    59 		default: return false;
       
    60 	}
       
    61 }
       
    62 
       
    63 /**
       
    64  * Creates a tree tile
       
    65  * Ground type and density is preserved.
       
    66  *
       
    67  * @pre the tile must be suitable for trees.
       
    68  *
       
    69  * @param tile where to plant the trees.
       
    70  * @param type The type of the tree
       
    71  * @param count the number of trees (minus 1)
       
    72  * @param growth the growth status
       
    73  */
       
    74 static void PlantTreesOnTile(TileIndex tile, TreeType treetype, uint count, uint growth)
       
    75 {
       
    76 	assert(treetype != TREE_INVALID);
       
    77 	assert(CanPlantTreesOnTile(tile, true));
       
    78 
       
    79 	TreeGround ground;
       
    80 	uint density = 3;
       
    81 
       
    82 	switch (GetTileType(tile)) {
       
    83 		case MP_WATER:
       
    84 			ground = TREE_GROUND_SHORE;
       
    85 			break;
       
    86 
       
    87 		case MP_CLEAR:
       
    88 			switch (GetClearGround(tile)) {
       
    89 				case CLEAR_GRASS:  ground = TREE_GROUND_GRASS;       density = GetClearDensity(tile); break;
       
    90 				case CLEAR_ROUGH:  ground = TREE_GROUND_ROUGH;                                        break;
       
    91 				default:           ground = TREE_GROUND_SNOW_DESERT; density = GetClearDensity(tile); break;
       
    92 			}
       
    93 			break;
       
    94 
       
    95 		default: NOT_REACHED();
       
    96 	}
       
    97 
       
    98 	MakeTree(tile, treetype, count, growth, ground, density);
       
    99 }
       
   100 
       
   101 /**
    40  * Get a random TreeType for the given tile based on a given seed
   102  * Get a random TreeType for the given tile based on a given seed
    41  *
   103  *
    42  * This function returns a random TreeType which can be placed on the given tile.
   104  * This function returns a random TreeType which can be placed on the given tile.
    43  * The seed for randomness must be less or equal 256, use #GB on the value of Random()
   105  * The seed for randomness must be less or equal 256, use #GB on the value of Random()
    44  * to get such a value.
   106  * to get such a value.
    56 		case LT_ARCTIC:
   118 		case LT_ARCTIC:
    57 			return (TreeType)(seed * TREE_COUNT_SUB_ARCTIC / 256 + TREE_SUB_ARCTIC);
   119 			return (TreeType)(seed * TREE_COUNT_SUB_ARCTIC / 256 + TREE_SUB_ARCTIC);
    58 
   120 
    59 		case LT_TROPIC:
   121 		case LT_TROPIC:
    60 			switch (GetTropicZone(tile)) {
   122 			switch (GetTropicZone(tile)) {
    61 				case TROPICZONE_INVALID: return (TreeType)(seed * TREE_COUNT_SUB_TROPICAL / 256 + TREE_SUB_TROPICAL);
   123 				case TROPICZONE_NORMAL:  return (TreeType)(seed * TREE_COUNT_SUB_TROPICAL / 256 + TREE_SUB_TROPICAL);
    62 				case TROPICZONE_DESERT:  return (TreeType)((seed > 12) ? TREE_INVALID : TREE_CACTUS);
   124 				case TROPICZONE_DESERT:  return (TreeType)((seed > 12) ? TREE_INVALID : TREE_CACTUS);
    63 				default:                 return (TreeType)(seed * TREE_COUNT_RAINFOREST / 256 + TREE_RAINFOREST);
   125 				default:                 return (TreeType)(seed * TREE_COUNT_RAINFOREST / 256 + TREE_RAINFOREST);
    64 			}
   126 			}
    65 
   127 
    66 		default:
   128 		default:
    80 static void PlaceTree(TileIndex tile, uint32 r)
   142 static void PlaceTree(TileIndex tile, uint32 r)
    81 {
   143 {
    82 	TreeType tree = GetRandomTreeType(tile, GB(r, 24, 8));
   144 	TreeType tree = GetRandomTreeType(tile, GB(r, 24, 8));
    83 
   145 
    84 	if (tree != TREE_INVALID) {
   146 	if (tree != TREE_INVALID) {
    85 		MakeTree(tile, tree, GB(r, 22, 2), min(GB(r, 16, 3), 6), TREE_GROUND_GRASS, 0);
   147 		PlantTreesOnTile(tile, tree, GB(r, 22, 2), min(GB(r, 16, 3), 6));
    86 
   148 
    87 		/* above snowline? */
   149 		/* Rerandomize ground, if neither snow nor shore */
    88 		if (_opt.landscape == LT_ARCTIC && GetTileZ(tile) > GetSnowLine()) {
   150 		TreeGround ground = GetTreeGround(tile);
    89 			SetTreeGroundDensity(tile, TREE_GROUND_SNOW_DESERT, 3);
   151 		if (ground != TREE_GROUND_SNOW_DESERT && ground != TREE_GROUND_SHORE) {
    90 			SetTreeCounter(tile, (TreeGround)GB(r, 24, 3));
       
    91 		} else {
       
    92 			SetTreeGroundDensity(tile, (TreeGround)GB(r, 28, 1), 3);
   152 			SetTreeGroundDensity(tile, (TreeGround)GB(r, 28, 1), 3);
    93 			SetTreeCounter(tile, (TreeGround)GB(r, 24, 4));
   153 		}
    94 		}
   154 
       
   155 		/* Set the counter to a random start value */
       
   156 		SetTreeCounter(tile, (TreeGround)GB(r, 24, 4));
    95 	}
   157 	}
    96 }
   158 }
    97 
   159 
    98 /**
   160 /**
    99  * Place some amount of trees around a given tile.
   161  * Place some amount of trees around a given tile.
   113 		int x = GB(r, 0, 5) - 16;
   175 		int x = GB(r, 0, 5) - 16;
   114 		int y = GB(r, 8, 5) - 16;
   176 		int y = GB(r, 8, 5) - 16;
   115 		uint dist = abs(x) + abs(y);
   177 		uint dist = abs(x) + abs(y);
   116 		TileIndex cur_tile = TILE_MASK(tile + TileDiffXY(x, y));
   178 		TileIndex cur_tile = TILE_MASK(tile + TileDiffXY(x, y));
   117 
   179 
   118 		if (dist <= 13 &&
   180 		if (dist <= 13 && CanPlantTreesOnTile(cur_tile, true)) {
   119 				IsTileType(cur_tile, MP_CLEAR) &&
       
   120 				!IsBridgeAbove(cur_tile) &&
       
   121 				!IsClearGround(cur_tile, CLEAR_FIELDS) &&
       
   122 				!IsClearGround(cur_tile, CLEAR_ROCKS)) {
       
   123 			PlaceTree(cur_tile, r);
   181 			PlaceTree(cur_tile, r);
   124 		}
   182 		}
   125 	}
   183 	}
   126 }
   184 }
   127 
   185 
   145  * height or at some offset (2 units) of it.
   203  * height or at some offset (2 units) of it.
   146  *
   204  *
   147  * @param tile The base tile to add a new tree somewhere around
   205  * @param tile The base tile to add a new tree somewhere around
   148  * @param height The height (like the one from the tile)
   206  * @param height The height (like the one from the tile)
   149  */
   207  */
   150 void PlaceTreeAtSameHeight(TileIndex tile, uint height)
   208 static void PlaceTreeAtSameHeight(TileIndex tile, uint height)
   151 {
   209 {
   152 	uint i;
   210 	uint i;
   153 
   211 
   154 	for (i = 0; i < 1000; i++) {
   212 	for (i = 0; i < 1000; i++) {
   155 		uint32 r = Random();
   213 		uint32 r = Random();
   159 
   217 
   160 		/* Keep in range of the existing tree */
   218 		/* Keep in range of the existing tree */
   161 		if (abs(x) + abs(y) > 16) continue;
   219 		if (abs(x) + abs(y) > 16) continue;
   162 
   220 
   163 		/* Clear tile, no farm-tiles or rocks */
   221 		/* Clear tile, no farm-tiles or rocks */
   164 		if (!IsTileType(cur_tile, MP_CLEAR) ||
   222 		if (!CanPlantTreesOnTile(cur_tile, true)) continue;
   165 				IsClearGround(cur_tile, CLEAR_FIELDS) ||
       
   166 				IsClearGround(cur_tile, CLEAR_ROCKS))
       
   167 			continue;
       
   168 
   223 
   169 		/* Not too much height difference */
   224 		/* Not too much height difference */
   170 		if (Delta(GetTileZ(cur_tile), height) > 2) continue;
   225 		if (Delta(GetTileZ(cur_tile), height) > 2) continue;
   171 
   226 
   172 		/* Place one tree and quit */
   227 		/* Place one tree and quit */
   189 		uint32 r = Random();
   244 		uint32 r = Random();
   190 		TileIndex tile = RandomTileSeed(r);
   245 		TileIndex tile = RandomTileSeed(r);
   191 
   246 
   192 		IncreaseGeneratingWorldProgress(GWP_TREE);
   247 		IncreaseGeneratingWorldProgress(GWP_TREE);
   193 
   248 
   194 		if (IsTileType(tile, MP_CLEAR) &&
   249 		if (CanPlantTreesOnTile(tile, true)) {
   195 				!IsBridgeAbove(tile) &&
       
   196 				!IsClearGround(tile, CLEAR_FIELDS) &&
       
   197 				!IsClearGround(tile, CLEAR_ROCKS)) {
       
   198 			PlaceTree(tile, r);
   250 			PlaceTree(tile, r);
   199 			if (_patches.tree_placer != TP_IMPROVED) continue;
   251 			if (_patches.tree_placer != TP_IMPROVED) continue;
   200 
   252 
   201 			/* Place a number of trees based on the tile height.
   253 			/* Place a number of trees based on the tile height.
   202 			 *  This gives a cool effect of multiple trees close together.
   254 			 *  This gives a cool effect of multiple trees close together.
   224 			uint32 r = Random();
   276 			uint32 r = Random();
   225 			TileIndex tile = RandomTileSeed(r);
   277 			TileIndex tile = RandomTileSeed(r);
   226 
   278 
   227 			IncreaseGeneratingWorldProgress(GWP_TREE);
   279 			IncreaseGeneratingWorldProgress(GWP_TREE);
   228 
   280 
   229 			if (IsTileType(tile, MP_CLEAR) &&
   281 			if (GetTropicZone(tile) == TROPICZONE_RAINFOREST && CanPlantTreesOnTile(tile, false)) {
   230 					!IsBridgeAbove(tile) &&
       
   231 					!IsClearGround(tile, CLEAR_FIELDS) &&
       
   232 					GetTropicZone(tile) == TROPICZONE_RAINFOREST) {
       
   233 				PlaceTree(tile, r);
   282 				PlaceTree(tile, r);
   234 			}
   283 			}
   235 		} while (--i);
   284 		} while (--i);
   236 	}
   285 	}
   237 }
   286 }
   311 					/* 2x as expensive to add more trees to an existing tile */
   360 					/* 2x as expensive to add more trees to an existing tile */
   312 					cost.AddCost(_price.build_trees * 2);
   361 					cost.AddCost(_price.build_trees * 2);
   313 					break;
   362 					break;
   314 
   363 
   315 				case MP_WATER:
   364 				case MP_WATER:
   316 					msg = STR_3807_CAN_T_BUILD_ON_WATER;
   365 					if (!IsCoast(tile) || IsSlopeWithOneCornerRaised(GetTileSlope(tile, NULL))) {
   317 					continue;
   366 						msg = STR_3807_CAN_T_BUILD_ON_WATER;
   318 					break;
   367 						continue;
   319 
   368 					}
       
   369 				/* FALL THROUGH */
   320 				case MP_CLEAR:
   370 				case MP_CLEAR:
   321 					if (!IsTileOwner(tile, OWNER_NONE) ||
   371 					if (IsBridgeAbove(tile)) {
   322 							IsBridgeAbove(tile)) {
       
   323 						msg = STR_2804_SITE_UNSUITABLE;
   372 						msg = STR_2804_SITE_UNSUITABLE;
   324 						continue;
   373 						continue;
   325 					}
   374 					}
   326 
   375 
   327 					switch (GetClearGround(tile)) {
   376 					if (IsTileType(tile, MP_CLEAR)) {
   328 						case CLEAR_FIELDS: cost.AddCost(_price.clear_fields); break;
   377 						/* Remove fields or rocks. Note that the ground will get barrened */
   329 						case CLEAR_ROCKS:  cost.AddCost(_price.clear_rocks); break;
   378 						switch (GetClearGround(tile)) {
   330 						default: break;
   379 							case CLEAR_FIELDS:
       
   380 							case CLEAR_ROCKS: {
       
   381 								CommandCost ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
       
   382 								if (CmdFailed(ret)) return ret;
       
   383 								cost.AddCost(ret);
       
   384 								break;
       
   385 							}
       
   386 
       
   387 							default: break;
       
   388 						}
   331 					}
   389 					}
   332 
   390 
   333 					if (_game_mode != GM_EDITOR && IsValidPlayer(_current_player)) {
   391 					if (_game_mode != GM_EDITOR && IsValidPlayer(_current_player)) {
   334 						Town *t = ClosestTownFromTile(tile, _patches.dist_local_authority);
   392 						Town *t = ClosestTownFromTile(tile, _patches.dist_local_authority);
   335 						if (t != NULL) ChangeTownRating(t, RATING_TREE_UP_STEP, RATING_TREE_MAXIMUM);
   393 						if (t != NULL) ChangeTownRating(t, RATING_TREE_UP_STEP, RATING_TREE_MAXIMUM);
   336 					}
   394 					}
   337 
   395 
   338 					if (flags & DC_EXEC) {
   396 					if (flags & DC_EXEC) {
   339 						TreeType treetype;
   397 						TreeType treetype;
   340 						uint growth;
       
   341 
   398 
   342 						treetype = (TreeType)p1;
   399 						treetype = (TreeType)p1;
   343 						if (treetype == TREE_INVALID) {
   400 						if (treetype == TREE_INVALID) {
   344 							treetype = GetRandomTreeType(tile, GB(Random(), 24, 8));
   401 							treetype = GetRandomTreeType(tile, GB(Random(), 24, 8));
   345 							if (treetype == TREE_INVALID) treetype = TREE_CACTUS;
   402 							if (treetype == TREE_INVALID) treetype = TREE_CACTUS;
   346 						}
   403 						}
   347 
   404 
   348 						growth = _game_mode == GM_EDITOR ? 3 : 0;
   405 						/* Plant full grown trees in scenario editor */
   349 						switch (GetClearGround(tile)) {
   406 						PlantTreesOnTile(tile, treetype, 0, _game_mode == GM_EDITOR ? 3 : 0);
   350 							case CLEAR_ROUGH:  MakeTree(tile, treetype, 0, growth, TREE_GROUND_ROUGH, 3); break;
       
   351 							case CLEAR_SNOW:
       
   352 							case CLEAR_DESERT: MakeTree(tile, treetype, 0, growth, TREE_GROUND_SNOW_DESERT, GetClearDensity(tile)); break;
       
   353 							default:           MakeTree(tile, treetype, 0, growth, TREE_GROUND_GRASS, GetClearDensity(tile)); break;
       
   354 						}
       
   355 						MarkTileDirtyByTile(tile);
   407 						MarkTileDirtyByTile(tile);
   356 
   408 
       
   409 						/* When planting rainforest-trees, set tropiczone to rainforest in editor. */
   357 						if (_game_mode == GM_EDITOR && IsInsideMM(treetype, TREE_RAINFOREST, TREE_CACTUS))
   410 						if (_game_mode == GM_EDITOR && IsInsideMM(treetype, TREE_RAINFOREST, TREE_CACTUS))
   358 							SetTropicZone(tile, TROPICZONE_RAINFOREST);
   411 							SetTropicZone(tile, TROPICZONE_RAINFOREST);
   359 					}
   412 					}
   360 					cost.AddCost(_price.build_trees);
   413 					cost.AddCost(_price.build_trees);
   361 					break;
   414 					break;
   385 	const PalSpriteID *s;
   438 	const PalSpriteID *s;
   386 	const TreePos* d;
   439 	const TreePos* d;
   387 	byte z;
   440 	byte z;
   388 
   441 
   389 	switch (GetTreeGround(ti->tile)) {
   442 	switch (GetTreeGround(ti->tile)) {
       
   443 		case TREE_GROUND_SHORE: DrawShoreTile(ti->tileh); break;
   390 		case TREE_GROUND_GRASS: DrawClearLandTile(ti, GetTreeDensity(ti->tile)); break;
   444 		case TREE_GROUND_GRASS: DrawClearLandTile(ti, GetTreeDensity(ti->tile)); break;
   391 		case TREE_GROUND_ROUGH: DrawHillyLandTile(ti); break;
   445 		case TREE_GROUND_ROUGH: DrawHillyLandTile(ti); break;
   392 		default: DrawGroundSprite(_tree_sprites_1[GetTreeDensity(ti->tile)] + _tileh_to_sprite[ti->tileh], PAL_NONE); break;
   446 		default: DrawGroundSprite(_tree_sprites_1[GetTreeDensity(ti->tile)] + _tileh_to_sprite[ti->tileh], PAL_NONE); break;
   393 	}
   447 	}
   394 
   448 
   426 		s = _tree_layout_sprite[index];
   480 		s = _tree_layout_sprite[index];
   427 	}
   481 	}
   428 
   482 
   429 	StartSpriteCombine();
   483 	StartSpriteCombine();
   430 
   484 
       
   485 	/* Do not draw trees when the invisible trees patch and transparency tree are set */
   431 	if (!(IsTransparencySet(TO_TREES) && _patches.invisible_trees)) {
   486 	if (!(IsTransparencySet(TO_TREES) && _patches.invisible_trees)) {
   432 		TreeListEnt te[4];
   487 		TreeListEnt te[4];
   433 		uint i;
   488 		uint i;
   434 
   489 
   435 		/* put the trees to draw in a list */
   490 		/* put the trees to draw in a list */
   576 	MarkTileDirtyByTile(tile);
   631 	MarkTileDirtyByTile(tile);
   577 }
   632 }
   578 
   633 
   579 static void TileLoop_Trees(TileIndex tile)
   634 static void TileLoop_Trees(TileIndex tile)
   580 {
   635 {
   581 	switch (_opt.landscape) {
   636 	if (GetTreeGround(tile) == TREE_GROUND_SHORE) {
   582 		case LT_TROPIC: TileLoopTreesDesert(tile); break;
   637 		TileLoop_Water(tile);
   583 		case LT_ARCTIC: TileLoopTreesAlps(tile);   break;
   638 	} else {
       
   639 		switch (_opt.landscape) {
       
   640 			case LT_TROPIC: TileLoopTreesDesert(tile); break;
       
   641 			case LT_ARCTIC: TileLoopTreesAlps(tile);   break;
       
   642 		}
   584 	}
   643 	}
   585 
   644 
   586 	TileLoopClearHelper(tile);
   645 	TileLoopClearHelper(tile);
   587 
   646 
   588 	uint treeCounter = GetTreeCounter(tile);
   647 	uint treeCounter = GetTreeCounter(tile);
   624 					case 2: { /* add a neighbouring tree */
   683 					case 2: { /* add a neighbouring tree */
   625 						TreeType treetype = GetTreeType(tile);
   684 						TreeType treetype = GetTreeType(tile);
   626 
   685 
   627 						tile += TileOffsByDir((Direction)(Random() & 7));
   686 						tile += TileOffsByDir((Direction)(Random() & 7));
   628 
   687 
   629 						if (!IsTileType(tile, MP_CLEAR) || IsBridgeAbove(tile)) return;
   688 						/* Cacti don't spread */
   630 
   689 						if (!CanPlantTreesOnTile(tile, false)) return;
   631 						switch (GetClearGround(tile)) {
   690 
   632 							case CLEAR_GRASS:
   691 						/* Don't plant trees, if ground was freshly cleared */
   633 								if (GetClearDensity(tile) != 3) return;
   692 						if (IsTileType(tile, MP_CLEAR) && GetClearGround(tile) == CLEAR_GRASS && GetClearDensity(tile) != 3) return;
   634 								MakeTree(tile, treetype, 0, 0, TREE_GROUND_GRASS, 3);
   693 
   635 								break;
   694 						PlantTreesOnTile(tile, treetype, 0, 0);
   636 
   695 
   637 							case CLEAR_ROUGH: MakeTree(tile, treetype, 0, 0, TREE_GROUND_ROUGH, 3); break;
       
   638 							case CLEAR_DESERT: return; // Cacti don't spread
       
   639 							case CLEAR_SNOW: MakeTree(tile, treetype, 0, 0, TREE_GROUND_SNOW_DESERT, GetClearDensity(tile)); break;
       
   640 							default: return;
       
   641 						}
       
   642 						break;
   696 						break;
   643 					}
   697 					}
   644 
   698 
   645 					default:
   699 					default:
   646 						return;
   700 						return;
   654 				AddTreeCount(tile, -1);
   708 				AddTreeCount(tile, -1);
   655 				SetTreeGrowth(tile, 3);
   709 				SetTreeGrowth(tile, 3);
   656 			} else {
   710 			} else {
   657 				/* just one tree, change type into MP_CLEAR */
   711 				/* just one tree, change type into MP_CLEAR */
   658 				switch (GetTreeGround(tile)) {
   712 				switch (GetTreeGround(tile)) {
       
   713 					case TREE_GROUND_SHORE: MakeShore(tile); break;
   659 					case TREE_GROUND_GRASS: MakeClear(tile, CLEAR_GRASS, GetTreeDensity(tile)); break;
   714 					case TREE_GROUND_GRASS: MakeClear(tile, CLEAR_GRASS, GetTreeDensity(tile)); break;
   660 					case TREE_GROUND_ROUGH: MakeClear(tile, CLEAR_ROUGH, 3); break;
   715 					case TREE_GROUND_ROUGH: MakeClear(tile, CLEAR_ROUGH, 3); break;
   661 					default: // snow or desert
   716 					default: // snow or desert
   662 						MakeClear(tile, _opt.landscape == LT_TROPIC ? CLEAR_DESERT : CLEAR_SNOW, GetTreeDensity(tile));
   717 						MakeClear(tile, _opt.landscape == LT_TROPIC ? CLEAR_DESERT : CLEAR_SNOW, GetTreeDensity(tile));
   663 						break;
   718 						break;
   675 
   730 
   676 void OnTick_Trees()
   731 void OnTick_Trees()
   677 {
   732 {
   678 	uint32 r;
   733 	uint32 r;
   679 	TileIndex tile;
   734 	TileIndex tile;
   680 	ClearGround ct;
       
   681 	TreeType tree;
   735 	TreeType tree;
   682 
   736 
   683 	/* place a tree at a random rainforest spot */
   737 	/* place a tree at a random rainforest spot */
   684 	if (_opt.landscape == LT_TROPIC &&
   738 	if (_opt.landscape == LT_TROPIC &&
   685 			(r = Random(), tile = RandomTileSeed(r), GetTropicZone(tile) == TROPICZONE_RAINFOREST) &&
   739 			(r = Random(), tile = RandomTileSeed(r), GetTropicZone(tile) == TROPICZONE_RAINFOREST) &&
   686 			IsTileType(tile, MP_CLEAR) &&
   740 			CanPlantTreesOnTile(tile, false) &&
   687 			!IsBridgeAbove(tile) &&
       
   688 			(ct = GetClearGround(tile), ct == CLEAR_GRASS || ct == CLEAR_ROUGH) &&
       
   689 			(tree = GetRandomTreeType(tile, GB(r, 24, 8))) != TREE_INVALID) {
   741 			(tree = GetRandomTreeType(tile, GB(r, 24, 8))) != TREE_INVALID) {
   690 		MakeTree(tile, tree, 0, 0, ct == CLEAR_ROUGH ? TREE_GROUND_ROUGH : TREE_GROUND_GRASS, GetClearDensity(tile));
   742 		PlantTreesOnTile(tile, tree, 0, 0);
   691 	}
   743 	}
   692 
   744 
   693 	/* byte underflow */
   745 	/* byte underflow */
   694 	if (--_trees_tick_ctr != 0) return;
   746 	if (--_trees_tick_ctr != 0) return;
   695 
   747 
   696 	/* place a tree at a random spot */
   748 	/* place a tree at a random spot */
   697 	r = Random();
   749 	r = Random();
   698 	tile = TILE_MASK(r);
   750 	tile = TILE_MASK(r);
   699 	if (IsTileType(tile, MP_CLEAR) &&
   751 	if (CanPlantTreesOnTile(tile, false) && (tree = GetRandomTreeType(tile, GB(r, 24, 8))) != TREE_INVALID) {
   700 			!IsBridgeAbove(tile) &&
   752 		PlantTreesOnTile(tile, tree, 0, 0);
   701 			(ct = GetClearGround(tile), ct == CLEAR_GRASS || ct == CLEAR_ROUGH || ct == CLEAR_SNOW) &&
       
   702 			(tree = GetRandomTreeType(tile, GB(r, 24, 8))) != TREE_INVALID) {
       
   703 		switch (ct) {
       
   704 			case CLEAR_GRASS: MakeTree(tile, tree, 0, 0, TREE_GROUND_GRASS, GetClearDensity(tile)); break;
       
   705 			case CLEAR_ROUGH: MakeTree(tile, tree, 0, 0, TREE_GROUND_ROUGH, 3); break;
       
   706 			default: MakeTree(tile, tree, 0, 0, TREE_GROUND_SNOW_DESERT, GetClearDensity(tile)); break;
       
   707 		}
       
   708 	}
   753 	}
   709 }
   754 }
   710 
   755 
   711 static void ClickTile_Trees(TileIndex tile)
   756 static void ClickTile_Trees(TileIndex tile)
   712 {
   757 {