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 |
42 * |
44 * |
43 * @param tile the tile of interest |
45 * @param tile the tile of interest |
44 * @param allow_desert Allow planting trees on CLEAR_DESERT? |
46 * @param allow_desert Allow planting trees on CLEAR_DESERT? |
45 * @return true if trees can be built. |
47 * @return true if trees can be built. |
46 */ |
48 */ |
47 static inline bool CanPlantTreesOnTile(TileIndex tile, bool allow_desert) |
49 static bool CanPlantTreesOnTile(TileIndex tile, bool allow_desert) |
48 { |
50 { |
49 return IsTileType(tile, MP_CLEAR) && !IsBridgeAbove(tile) && |
51 switch (GetTileType(tile)) { |
50 !IsClearGround(tile, CLEAR_FIELDS) && !IsClearGround(tile, CLEAR_ROCKS) && |
52 case MP_WATER: |
51 (allow_desert || !IsClearGround(tile, CLEAR_DESERT)); |
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 } |
52 } |
61 } |
53 |
62 |
54 /** |
63 /** |
55 * Creates a tree tile |
64 * Creates a tree tile |
56 * Ground type and density is preserved. |
65 * Ground type and density is preserved. |
67 assert(treetype != TREE_INVALID); |
76 assert(treetype != TREE_INVALID); |
68 assert(CanPlantTreesOnTile(tile, true)); |
77 assert(CanPlantTreesOnTile(tile, true)); |
69 |
78 |
70 TreeGround ground; |
79 TreeGround ground; |
71 uint density = 3; |
80 uint density = 3; |
72 switch (GetClearGround(tile)) { |
81 |
73 case CLEAR_GRASS: ground = TREE_GROUND_GRASS; density = GetClearDensity(tile); break; |
82 switch (GetTileType(tile)) { |
74 case CLEAR_ROUGH: ground = TREE_GROUND_ROUGH; break; |
83 case MP_WATER: |
75 default: ground = TREE_GROUND_SNOW_DESERT; density = GetClearDensity(tile); break; |
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(); |
76 } |
96 } |
77 |
97 |
78 MakeTree(tile, treetype, count, growth, ground, density); |
98 MakeTree(tile, treetype, count, growth, ground, density); |
79 } |
99 } |
80 |
100 |
124 TreeType tree = GetRandomTreeType(tile, GB(r, 24, 8)); |
144 TreeType tree = GetRandomTreeType(tile, GB(r, 24, 8)); |
125 |
145 |
126 if (tree != TREE_INVALID) { |
146 if (tree != TREE_INVALID) { |
127 PlantTreesOnTile(tile, tree, GB(r, 22, 2), min(GB(r, 16, 3), 6)); |
147 PlantTreesOnTile(tile, tree, GB(r, 22, 2), min(GB(r, 16, 3), 6)); |
128 |
148 |
129 /* Rerandomize ground, if not snow */ |
149 /* Rerandomize ground, if neither snow nor shore */ |
130 if (GetTreeGround(tile) != TREE_GROUND_SNOW_DESERT) { |
150 TreeGround ground = GetTreeGround(tile); |
|
151 if (ground != TREE_GROUND_SNOW_DESERT && ground != TREE_GROUND_SHORE) { |
131 SetTreeGroundDensity(tile, (TreeGround)GB(r, 28, 1), 3); |
152 SetTreeGroundDensity(tile, (TreeGround)GB(r, 28, 1), 3); |
132 } |
153 } |
133 |
154 |
134 /* Set the counter to a random start value */ |
155 /* Set the counter to a random start value */ |
135 SetTreeCounter(tile, (TreeGround)GB(r, 24, 4)); |
156 SetTreeCounter(tile, (TreeGround)GB(r, 24, 4)); |
339 /* 2x as expensive to add more trees to an existing tile */ |
360 /* 2x as expensive to add more trees to an existing tile */ |
340 cost.AddCost(_price.build_trees * 2); |
361 cost.AddCost(_price.build_trees * 2); |
341 break; |
362 break; |
342 |
363 |
343 case MP_WATER: |
364 case MP_WATER: |
344 msg = STR_3807_CAN_T_BUILD_ON_WATER; |
365 if (!IsCoast(tile) || IsSlopeWithOneCornerRaised(GetTileSlope(tile, NULL))) { |
345 continue; |
366 msg = STR_3807_CAN_T_BUILD_ON_WATER; |
346 break; |
367 continue; |
347 |
368 } |
|
369 /* FALL THROUGH */ |
348 case MP_CLEAR: |
370 case MP_CLEAR: |
349 if (IsBridgeAbove(tile)) { |
371 if (IsBridgeAbove(tile)) { |
350 msg = STR_2804_SITE_UNSUITABLE; |
372 msg = STR_2804_SITE_UNSUITABLE; |
351 continue; |
373 continue; |
352 } |
374 } |
353 |
375 |
354 /* Remove fields or rocks. Note that the ground will get barrened */ |
376 if (IsTileType(tile, MP_CLEAR)) { |
355 switch (GetClearGround(tile)) { |
377 /* Remove fields or rocks. Note that the ground will get barrened */ |
356 case CLEAR_FIELDS: |
378 switch (GetClearGround(tile)) { |
357 case CLEAR_ROCKS: { |
379 case CLEAR_FIELDS: |
358 CommandCost ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); |
380 case CLEAR_ROCKS: { |
359 if (CmdFailed(ret)) return ret; |
381 CommandCost ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); |
360 cost.AddCost(ret); |
382 if (CmdFailed(ret)) return ret; |
361 break; |
383 cost.AddCost(ret); |
|
384 break; |
|
385 } |
|
386 |
|
387 default: break; |
362 } |
388 } |
363 |
|
364 default: break; |
|
365 } |
389 } |
366 |
390 |
367 if (_game_mode != GM_EDITOR && IsValidPlayer(_current_player)) { |
391 if (_game_mode != GM_EDITOR && IsValidPlayer(_current_player)) { |
368 Town *t = ClosestTownFromTile(tile, _patches.dist_local_authority); |
392 Town *t = ClosestTownFromTile(tile, _patches.dist_local_authority); |
369 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); |
414 const PalSpriteID *s; |
438 const PalSpriteID *s; |
415 const TreePos* d; |
439 const TreePos* d; |
416 byte z; |
440 byte z; |
417 |
441 |
418 switch (GetTreeGround(ti->tile)) { |
442 switch (GetTreeGround(ti->tile)) { |
|
443 case TREE_GROUND_SHORE: DrawShoreTile(ti->tileh); break; |
419 case TREE_GROUND_GRASS: DrawClearLandTile(ti, GetTreeDensity(ti->tile)); break; |
444 case TREE_GROUND_GRASS: DrawClearLandTile(ti, GetTreeDensity(ti->tile)); break; |
420 case TREE_GROUND_ROUGH: DrawHillyLandTile(ti); break; |
445 case TREE_GROUND_ROUGH: DrawHillyLandTile(ti); break; |
421 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; |
422 } |
447 } |
423 |
448 |
606 MarkTileDirtyByTile(tile); |
631 MarkTileDirtyByTile(tile); |
607 } |
632 } |
608 |
633 |
609 static void TileLoop_Trees(TileIndex tile) |
634 static void TileLoop_Trees(TileIndex tile) |
610 { |
635 { |
611 switch (_opt.landscape) { |
636 if (GetTreeGround(tile) == TREE_GROUND_SHORE) { |
612 case LT_TROPIC: TileLoopTreesDesert(tile); break; |
637 TileLoop_Water(tile); |
613 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 } |
614 } |
643 } |
615 |
644 |
616 TileLoopClearHelper(tile); |
645 TileLoopClearHelper(tile); |
617 |
646 |
618 uint treeCounter = GetTreeCounter(tile); |
647 uint treeCounter = GetTreeCounter(tile); |
658 |
687 |
659 /* Cacti don't spread */ |
688 /* Cacti don't spread */ |
660 if (!CanPlantTreesOnTile(tile, false)) return; |
689 if (!CanPlantTreesOnTile(tile, false)) return; |
661 |
690 |
662 /* Don't plant trees, if ground was freshly cleared */ |
691 /* Don't plant trees, if ground was freshly cleared */ |
663 if (GetClearGround(tile) == CLEAR_GRASS && GetClearDensity(tile) != 3) return; |
692 if (IsTileType(tile, MP_CLEAR) && GetClearGround(tile) == CLEAR_GRASS && GetClearDensity(tile) != 3) return; |
664 |
693 |
665 PlantTreesOnTile(tile, treetype, 0, 0); |
694 PlantTreesOnTile(tile, treetype, 0, 0); |
666 |
695 |
667 break; |
696 break; |
668 } |
697 } |
679 AddTreeCount(tile, -1); |
708 AddTreeCount(tile, -1); |
680 SetTreeGrowth(tile, 3); |
709 SetTreeGrowth(tile, 3); |
681 } else { |
710 } else { |
682 /* just one tree, change type into MP_CLEAR */ |
711 /* just one tree, change type into MP_CLEAR */ |
683 switch (GetTreeGround(tile)) { |
712 switch (GetTreeGround(tile)) { |
|
713 case TREE_GROUND_SHORE: MakeShore(tile); break; |
684 case TREE_GROUND_GRASS: MakeClear(tile, CLEAR_GRASS, GetTreeDensity(tile)); break; |
714 case TREE_GROUND_GRASS: MakeClear(tile, CLEAR_GRASS, GetTreeDensity(tile)); break; |
685 case TREE_GROUND_ROUGH: MakeClear(tile, CLEAR_ROUGH, 3); break; |
715 case TREE_GROUND_ROUGH: MakeClear(tile, CLEAR_ROUGH, 3); break; |
686 default: // snow or desert |
716 default: // snow or desert |
687 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)); |
688 break; |
718 break; |