landscape.cpp

Go to the documentation of this file.
00001 /* $Id: landscape.cpp 26290 2014-02-02 14:53:52Z fonsinchen $ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
00008  */
00009 
00014 #include "stdafx.h"
00015 #include "heightmap.h"
00016 #include "clear_map.h"
00017 #include "spritecache.h"
00018 #include "viewport_func.h"
00019 #include "command_func.h"
00020 #include "landscape.h"
00021 #include "void_map.h"
00022 #include "tgp.h"
00023 #include "genworld.h"
00024 #include "fios.h"
00025 #include "date_func.h"
00026 #include "water.h"
00027 #include "effectvehicle_func.h"
00028 #include "landscape_type.h"
00029 #include "animated_tile_func.h"
00030 #include "core/random_func.hpp"
00031 #include "object_base.h"
00032 #include "company_func.h"
00033 #include "pathfinder/npf/aystar.h"
00034 #include <list>
00035 
00036 #include "table/strings.h"
00037 #include "table/sprites.h"
00038 
00039 extern const TileTypeProcs
00040   _tile_type_clear_procs,
00041   _tile_type_rail_procs,
00042   _tile_type_road_procs,
00043   _tile_type_town_procs,
00044   _tile_type_trees_procs,
00045   _tile_type_station_procs,
00046   _tile_type_water_procs,
00047   _tile_type_void_procs,
00048   _tile_type_industry_procs,
00049   _tile_type_tunnelbridge_procs,
00050   _tile_type_object_procs;
00051 
00057 const TileTypeProcs * const _tile_type_procs[16] = {
00058   &_tile_type_clear_procs,        
00059   &_tile_type_rail_procs,         
00060   &_tile_type_road_procs,         
00061   &_tile_type_town_procs,         
00062   &_tile_type_trees_procs,        
00063   &_tile_type_station_procs,      
00064   &_tile_type_water_procs,        
00065   &_tile_type_void_procs,         
00066   &_tile_type_industry_procs,     
00067   &_tile_type_tunnelbridge_procs, 
00068   &_tile_type_object_procs,       
00069 };
00070 
00072 extern const byte _slope_to_sprite_offset[32] = {
00073   0, 1, 2, 3, 4, 5, 6,  7, 8, 9, 10, 11, 12, 13, 14, 0,
00074   0, 0, 0, 0, 0, 0, 0, 16, 0, 0,  0, 17,  0, 15, 18, 0,
00075 };
00076 
00085 static SnowLine *_snow_line = NULL;
00086 
00095 uint ApplyFoundationToSlope(Foundation f, Slope *s)
00096 {
00097   if (!IsFoundation(f)) return 0;
00098 
00099   if (IsLeveledFoundation(f)) {
00100     uint dz = 1 + (IsSteepSlope(*s) ? 1 : 0);
00101     *s = SLOPE_FLAT;
00102     return dz;
00103   }
00104 
00105   if (f != FOUNDATION_STEEP_BOTH && IsNonContinuousFoundation(f)) {
00106     *s = HalftileSlope(*s, GetHalftileFoundationCorner(f));
00107     return 0;
00108   }
00109 
00110   if (IsSpecialRailFoundation(f)) {
00111     *s = SlopeWithThreeCornersRaised(OppositeCorner(GetRailFoundationCorner(f)));
00112     return 0;
00113   }
00114 
00115   uint dz = IsSteepSlope(*s) ? 1 : 0;
00116   Corner highest_corner = GetHighestSlopeCorner(*s);
00117 
00118   switch (f) {
00119     case FOUNDATION_INCLINED_X:
00120       *s = (((highest_corner == CORNER_W) || (highest_corner == CORNER_S)) ? SLOPE_SW : SLOPE_NE);
00121       break;
00122 
00123     case FOUNDATION_INCLINED_Y:
00124       *s = (((highest_corner == CORNER_S) || (highest_corner == CORNER_E)) ? SLOPE_SE : SLOPE_NW);
00125       break;
00126 
00127     case FOUNDATION_STEEP_LOWER:
00128       *s = SlopeWithOneCornerRaised(highest_corner);
00129       break;
00130 
00131     case FOUNDATION_STEEP_BOTH:
00132       *s = HalftileSlope(SlopeWithOneCornerRaised(highest_corner), highest_corner);
00133       break;
00134 
00135     default: NOT_REACHED();
00136   }
00137   return dz;
00138 }
00139 
00140 
00148 uint GetPartialPixelZ(int x, int y, Slope corners)
00149 {
00150   if (IsHalftileSlope(corners)) {
00151     switch (GetHalftileSlopeCorner(corners)) {
00152       case CORNER_W:
00153         if (x - y >= 0) return GetSlopeMaxPixelZ(corners);
00154         break;
00155 
00156       case CORNER_S:
00157         if (x - (y ^ 0xF) >= 0) return GetSlopeMaxPixelZ(corners);
00158         break;
00159 
00160       case CORNER_E:
00161         if (y - x >= 0) return GetSlopeMaxPixelZ(corners);
00162         break;
00163 
00164       case CORNER_N:
00165         if ((y ^ 0xF) - x >= 0) return GetSlopeMaxPixelZ(corners);
00166         break;
00167 
00168       default: NOT_REACHED();
00169     }
00170   }
00171 
00172   int z = 0;
00173 
00174   switch (RemoveHalftileSlope(corners)) {
00175     case SLOPE_W:
00176       if (x - y >= 0) {
00177         z = (x - y) >> 1;
00178       }
00179       break;
00180 
00181     case SLOPE_S:
00182       y ^= 0xF;
00183       if ((x - y) >= 0) {
00184         z = (x - y) >> 1;
00185       }
00186       break;
00187 
00188     case SLOPE_SW:
00189       z = (x >> 1) + 1;
00190       break;
00191 
00192     case SLOPE_E:
00193       if (y - x >= 0) {
00194         z = (y - x) >> 1;
00195       }
00196       break;
00197 
00198     case SLOPE_EW:
00199     case SLOPE_NS:
00200     case SLOPE_ELEVATED:
00201       z = 4;
00202       break;
00203 
00204     case SLOPE_SE:
00205       z = (y >> 1) + 1;
00206       break;
00207 
00208     case SLOPE_WSE:
00209       z = 8;
00210       y ^= 0xF;
00211       if (x - y < 0) {
00212         z += (x - y) >> 1;
00213       }
00214       break;
00215 
00216     case SLOPE_N:
00217       y ^= 0xF;
00218       if (y - x >= 0) {
00219         z = (y - x) >> 1;
00220       }
00221       break;
00222 
00223     case SLOPE_NW:
00224       z = (y ^ 0xF) >> 1;
00225       break;
00226 
00227     case SLOPE_NWS:
00228       z = 8;
00229       if (x - y < 0) {
00230         z += (x - y) >> 1;
00231       }
00232       break;
00233 
00234     case SLOPE_NE:
00235       z = (x ^ 0xF) >> 1;
00236       break;
00237 
00238     case SLOPE_ENW:
00239       z = 8;
00240       y ^= 0xF;
00241       if (y - x < 0) {
00242         z += (y - x) >> 1;
00243       }
00244       break;
00245 
00246     case SLOPE_SEN:
00247       z = 8;
00248       if (y - x < 0) {
00249         z += (y - x) >> 1;
00250       }
00251       break;
00252 
00253     case SLOPE_STEEP_S:
00254       z = 1 + ((x + y) >> 1);
00255       break;
00256 
00257     case SLOPE_STEEP_W:
00258       z = 1 + ((x + (y ^ 0xF)) >> 1);
00259       break;
00260 
00261     case SLOPE_STEEP_N:
00262       z = 1 + (((x ^ 0xF) + (y ^ 0xF)) >> 1);
00263       break;
00264 
00265     case SLOPE_STEEP_E:
00266       z = 1 + (((x ^ 0xF) + y) >> 1);
00267       break;
00268 
00269     default: break;
00270   }
00271 
00272   return z;
00273 }
00274 
00275 int GetSlopePixelZ(int x, int y)
00276 {
00277   TileIndex tile = TileVirtXY(x, y);
00278 
00279   return _tile_type_procs[GetTileType(tile)]->get_slope_z_proc(tile, x, y);
00280 }
00281 
00291 int GetSlopeZInCorner(Slope tileh, Corner corner)
00292 {
00293   assert(!IsHalftileSlope(tileh));
00294   return ((tileh & SlopeWithOneCornerRaised(corner)) != 0 ? 1 : 0) + (tileh == SteepSlope(corner) ? 1 : 0);
00295 }
00296 
00309 void GetSlopePixelZOnEdge(Slope tileh, DiagDirection edge, int *z1, int *z2)
00310 {
00311   static const Slope corners[4][4] = {
00312     /*    corner     |          steep slope
00313      *  z1      z2   |       z1             z2        */
00314     {SLOPE_E, SLOPE_N, SLOPE_STEEP_E, SLOPE_STEEP_N}, // DIAGDIR_NE, z1 = E, z2 = N
00315     {SLOPE_S, SLOPE_E, SLOPE_STEEP_S, SLOPE_STEEP_E}, // DIAGDIR_SE, z1 = S, z2 = E
00316     {SLOPE_S, SLOPE_W, SLOPE_STEEP_S, SLOPE_STEEP_W}, // DIAGDIR_SW, z1 = S, z2 = W
00317     {SLOPE_W, SLOPE_N, SLOPE_STEEP_W, SLOPE_STEEP_N}, // DIAGDIR_NW, z1 = W, z2 = N
00318   };
00319 
00320   int halftile_test = (IsHalftileSlope(tileh) ? SlopeWithOneCornerRaised(GetHalftileSlopeCorner(tileh)) : 0);
00321   if (halftile_test == corners[edge][0]) *z2 += TILE_HEIGHT; // The slope is non-continuous in z2. z2 is on the upper side.
00322   if (halftile_test == corners[edge][1]) *z1 += TILE_HEIGHT; // The slope is non-continuous in z1. z1 is on the upper side.
00323 
00324   if ((tileh & corners[edge][0]) != 0) *z1 += TILE_HEIGHT; // z1 is raised
00325   if ((tileh & corners[edge][1]) != 0) *z2 += TILE_HEIGHT; // z2 is raised
00326   if (RemoveHalftileSlope(tileh) == corners[edge][2]) *z1 += TILE_HEIGHT; // z1 is highest corner of a steep slope
00327   if (RemoveHalftileSlope(tileh) == corners[edge][3]) *z2 += TILE_HEIGHT; // z2 is highest corner of a steep slope
00328 }
00329 
00338 Slope GetFoundationSlope(TileIndex tile, int *z)
00339 {
00340   Slope tileh = GetTileSlope(tile, z);
00341   Foundation f = _tile_type_procs[GetTileType(tile)]->get_foundation_proc(tile, tileh);
00342   uint z_inc = ApplyFoundationToSlope(f, &tileh);
00343   if (z != NULL) *z += z_inc;
00344   return tileh;
00345 }
00346 
00347 
00348 bool HasFoundationNW(TileIndex tile, Slope slope_here, uint z_here)
00349 {
00350   int z;
00351 
00352   int z_W_here = z_here;
00353   int z_N_here = z_here;
00354   GetSlopePixelZOnEdge(slope_here, DIAGDIR_NW, &z_W_here, &z_N_here);
00355 
00356   Slope slope = GetFoundationPixelSlope(TILE_ADDXY(tile, 0, -1), &z);
00357   int z_W = z;
00358   int z_N = z;
00359   GetSlopePixelZOnEdge(slope, DIAGDIR_SE, &z_W, &z_N);
00360 
00361   return (z_N_here > z_N) || (z_W_here > z_W);
00362 }
00363 
00364 
00365 bool HasFoundationNE(TileIndex tile, Slope slope_here, uint z_here)
00366 {
00367   int z;
00368 
00369   int z_E_here = z_here;
00370   int z_N_here = z_here;
00371   GetSlopePixelZOnEdge(slope_here, DIAGDIR_NE, &z_E_here, &z_N_here);
00372 
00373   Slope slope = GetFoundationPixelSlope(TILE_ADDXY(tile, -1, 0), &z);
00374   int z_E = z;
00375   int z_N = z;
00376   GetSlopePixelZOnEdge(slope, DIAGDIR_SW, &z_E, &z_N);
00377 
00378   return (z_N_here > z_N) || (z_E_here > z_E);
00379 }
00380 
00386 void DrawFoundation(TileInfo *ti, Foundation f)
00387 {
00388   if (!IsFoundation(f)) return;
00389 
00390   /* Two part foundations must be drawn separately */
00391   assert(f != FOUNDATION_STEEP_BOTH);
00392 
00393   uint sprite_block = 0;
00394   int z;
00395   Slope slope = GetFoundationPixelSlope(ti->tile, &z);
00396 
00397   /* Select the needed block of foundations sprites
00398    * Block 0: Walls at NW and NE edge
00399    * Block 1: Wall  at        NE edge
00400    * Block 2: Wall  at NW        edge
00401    * Block 3: No walls at NW or NE edge
00402    */
00403   if (!HasFoundationNW(ti->tile, slope, z)) sprite_block += 1;
00404   if (!HasFoundationNE(ti->tile, slope, z)) sprite_block += 2;
00405 
00406   /* Use the original slope sprites if NW and NE borders should be visible */
00407   SpriteID leveled_base = (sprite_block == 0 ? (int)SPR_FOUNDATION_BASE : (SPR_SLOPES_VIRTUAL_BASE + sprite_block * SPR_TRKFOUND_BLOCK_SIZE));
00408   SpriteID inclined_base = SPR_SLOPES_VIRTUAL_BASE + SPR_SLOPES_INCLINED_OFFSET + sprite_block * SPR_TRKFOUND_BLOCK_SIZE;
00409   SpriteID halftile_base = SPR_HALFTILE_FOUNDATION_BASE + sprite_block * SPR_HALFTILE_BLOCK_SIZE;
00410 
00411   if (IsSteepSlope(ti->tileh)) {
00412     if (!IsNonContinuousFoundation(f)) {
00413       /* Lower part of foundation */
00414       AddSortableSpriteToDraw(
00415         leveled_base + (ti->tileh & ~SLOPE_STEEP), PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z
00416       );
00417     }
00418 
00419     Corner highest_corner = GetHighestSlopeCorner(ti->tileh);
00420     ti->z += ApplyPixelFoundationToSlope(f, &ti->tileh);
00421 
00422     if (IsInclinedFoundation(f)) {
00423       /* inclined foundation */
00424       byte inclined = highest_corner * 2 + (f == FOUNDATION_INCLINED_Y ? 1 : 0);
00425 
00426       AddSortableSpriteToDraw(inclined_base + inclined, PAL_NONE, ti->x, ti->y,
00427         f == FOUNDATION_INCLINED_X ? 16 : 1,
00428         f == FOUNDATION_INCLINED_Y ? 16 : 1,
00429         TILE_HEIGHT, ti->z
00430       );
00431       OffsetGroundSprite(31, 9);
00432     } else if (IsLeveledFoundation(f)) {
00433       AddSortableSpriteToDraw(leveled_base + SlopeWithOneCornerRaised(highest_corner), PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z - TILE_HEIGHT);
00434       OffsetGroundSprite(31, 1);
00435     } else if (f == FOUNDATION_STEEP_LOWER) {
00436       /* one corner raised */
00437       OffsetGroundSprite(31, 1);
00438     } else {
00439       /* halftile foundation */
00440       int x_bb = (((highest_corner == CORNER_W) || (highest_corner == CORNER_S)) ? 8 : 0);
00441       int y_bb = (((highest_corner == CORNER_S) || (highest_corner == CORNER_E)) ? 8 : 0);
00442 
00443       AddSortableSpriteToDraw(halftile_base + highest_corner, PAL_NONE, ti->x + x_bb, ti->y + y_bb, 8, 8, 7, ti->z + TILE_HEIGHT);
00444       OffsetGroundSprite(31, 9);
00445     }
00446   } else {
00447     if (IsLeveledFoundation(f)) {
00448       /* leveled foundation */
00449       AddSortableSpriteToDraw(leveled_base + ti->tileh, PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z);
00450       OffsetGroundSprite(31, 1);
00451     } else if (IsNonContinuousFoundation(f)) {
00452       /* halftile foundation */
00453       Corner halftile_corner = GetHalftileFoundationCorner(f);
00454       int x_bb = (((halftile_corner == CORNER_W) || (halftile_corner == CORNER_S)) ? 8 : 0);
00455       int y_bb = (((halftile_corner == CORNER_S) || (halftile_corner == CORNER_E)) ? 8 : 0);
00456 
00457       AddSortableSpriteToDraw(halftile_base + halftile_corner, PAL_NONE, ti->x + x_bb, ti->y + y_bb, 8, 8, 7, ti->z);
00458       OffsetGroundSprite(31, 9);
00459     } else if (IsSpecialRailFoundation(f)) {
00460       /* anti-zig-zag foundation */
00461       SpriteID spr;
00462       if (ti->tileh == SLOPE_NS || ti->tileh == SLOPE_EW) {
00463         /* half of leveled foundation under track corner */
00464         spr = leveled_base + SlopeWithThreeCornersRaised(GetRailFoundationCorner(f));
00465       } else {
00466         /* tile-slope = sloped along X/Y, foundation-slope = three corners raised */
00467         spr = inclined_base + 2 * GetRailFoundationCorner(f) + ((ti->tileh == SLOPE_SW || ti->tileh == SLOPE_NE) ? 1 : 0);
00468       }
00469       AddSortableSpriteToDraw(spr, PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z);
00470       OffsetGroundSprite(31, 9);
00471     } else {
00472       /* inclined foundation */
00473       byte inclined = GetHighestSlopeCorner(ti->tileh) * 2 + (f == FOUNDATION_INCLINED_Y ? 1 : 0);
00474 
00475       AddSortableSpriteToDraw(inclined_base + inclined, PAL_NONE, ti->x, ti->y,
00476         f == FOUNDATION_INCLINED_X ? 16 : 1,
00477         f == FOUNDATION_INCLINED_Y ? 16 : 1,
00478         TILE_HEIGHT, ti->z
00479       );
00480       OffsetGroundSprite(31, 9);
00481     }
00482     ti->z += ApplyPixelFoundationToSlope(f, &ti->tileh);
00483   }
00484 }
00485 
00486 void DoClearSquare(TileIndex tile)
00487 {
00488   /* If the tile can have animation and we clear it, delete it from the animated tile list. */
00489   if (_tile_type_procs[GetTileType(tile)]->animate_tile_proc != NULL) DeleteAnimatedTile(tile);
00490 
00491   MakeClear(tile, CLEAR_GRASS, _generating_world ? 3 : 0);
00492   MarkTileDirtyByTile(tile);
00493 }
00494 
00505 TrackStatus GetTileTrackStatus(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
00506 {
00507   return _tile_type_procs[GetTileType(tile)]->get_tile_track_status_proc(tile, mode, sub_mode, side);
00508 }
00509 
00516 void ChangeTileOwner(TileIndex tile, Owner old_owner, Owner new_owner)
00517 {
00518   _tile_type_procs[GetTileType(tile)]->change_tile_owner_proc(tile, old_owner, new_owner);
00519 }
00520 
00521 void GetTileDesc(TileIndex tile, TileDesc *td)
00522 {
00523   _tile_type_procs[GetTileType(tile)]->get_tile_desc_proc(tile, td);
00524 }
00525 
00531 bool IsSnowLineSet()
00532 {
00533   return _snow_line != NULL;
00534 }
00535 
00541 void SetSnowLine(byte table[SNOW_LINE_MONTHS][SNOW_LINE_DAYS])
00542 {
00543   _snow_line = CallocT<SnowLine>(1);
00544   _snow_line->lowest_value = 0xFF;
00545   memcpy(_snow_line->table, table, sizeof(_snow_line->table));
00546 
00547   for (uint i = 0; i < SNOW_LINE_MONTHS; i++) {
00548     for (uint j = 0; j < SNOW_LINE_DAYS; j++) {
00549       _snow_line->highest_value = max(_snow_line->highest_value, table[i][j]);
00550       _snow_line->lowest_value = min(_snow_line->lowest_value, table[i][j]);
00551     }
00552   }
00553 }
00554 
00560 byte GetSnowLine()
00561 {
00562   if (_snow_line == NULL) return _settings_game.game_creation.snow_line_height;
00563 
00564   YearMonthDay ymd;
00565   ConvertDateToYMD(_date, &ymd);
00566   return _snow_line->table[ymd.month][ymd.day];
00567 }
00568 
00574 byte HighestSnowLine()
00575 {
00576   return _snow_line == NULL ? _settings_game.game_creation.snow_line_height : _snow_line->highest_value;
00577 }
00578 
00584 byte LowestSnowLine()
00585 {
00586   return _snow_line == NULL ? _settings_game.game_creation.snow_line_height : _snow_line->lowest_value;
00587 }
00588 
00593 void ClearSnowLine()
00594 {
00595   free(_snow_line);
00596   _snow_line = NULL;
00597 }
00598 
00608 CommandCost CmdLandscapeClear(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
00609 {
00610   CommandCost cost(EXPENSES_CONSTRUCTION);
00611   bool do_clear = false;
00612   /* Test for stuff which results in water when cleared. Then add the cost to also clear the water. */
00613   if ((flags & DC_FORCE_CLEAR_TILE) && HasTileWaterClass(tile) && IsTileOnWater(tile) && !IsWaterTile(tile) && !IsCoastTile(tile)) {
00614     if ((flags & DC_AUTO) && GetWaterClass(tile) == WATER_CLASS_CANAL) return_cmd_error(STR_ERROR_MUST_DEMOLISH_CANAL_FIRST);
00615     do_clear = true;
00616     cost.AddCost(GetWaterClass(tile) == WATER_CLASS_CANAL ? _price[PR_CLEAR_CANAL] : _price[PR_CLEAR_WATER]);
00617   }
00618 
00619   Company *c = (flags & (DC_AUTO | DC_BANKRUPT)) ? NULL : Company::GetIfValid(_current_company);
00620   if (c != NULL && (int)GB(c->clear_limit, 16, 16) < 1) {
00621     return_cmd_error(STR_ERROR_CLEARING_LIMIT_REACHED);
00622   }
00623 
00624   const ClearedObjectArea *coa = FindClearedObject(tile);
00625 
00626   /* If this tile was the first tile which caused object destruction, always
00627    * pass it on to the tile_type_proc. That way multiple test runs and the exec run stay consistent. */
00628   if (coa != NULL && coa->first_tile != tile) {
00629     /* If this tile belongs to an object which was already cleared via another tile, pretend it has been
00630      * already removed.
00631      * However, we need to check stuff, which is not the same for all object tiles. (e.g. being on water or not) */
00632 
00633     /* If a object is removed, it leaves either bare land or water. */
00634     if ((flags & DC_NO_WATER) && HasTileWaterClass(tile) && IsTileOnWater(tile)) {
00635       return_cmd_error(STR_ERROR_CAN_T_BUILD_ON_WATER);
00636     }
00637   } else {
00638     cost.AddCost(_tile_type_procs[GetTileType(tile)]->clear_tile_proc(tile, flags));
00639   }
00640 
00641   if (flags & DC_EXEC) {
00642     if (c != NULL) c->clear_limit -= 1 << 16;
00643     if (do_clear) DoClearSquare(tile);
00644   }
00645   return cost;
00646 }
00647 
00658 CommandCost CmdClearArea(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
00659 {
00660   if (p1 >= MapSize()) return CMD_ERROR;
00661 
00662   Money money = GetAvailableMoneyForCommand();
00663   CommandCost cost(EXPENSES_CONSTRUCTION);
00664   CommandCost last_error = CMD_ERROR;
00665   bool had_success = false;
00666 
00667   const Company *c = (flags & (DC_AUTO | DC_BANKRUPT)) ? NULL : Company::GetIfValid(_current_company);
00668   int limit = (c == NULL ? INT32_MAX : GB(c->clear_limit, 16, 16));
00669 
00670   TileIterator *iter = HasBit(p2, 0) ? (TileIterator *)new DiagonalTileIterator(tile, p1) : new OrthogonalTileIterator(tile, p1);
00671   for (; *iter != INVALID_TILE; ++(*iter)) {
00672     TileIndex t = *iter;
00673     CommandCost ret = DoCommand(t, 0, 0, flags & ~DC_EXEC, CMD_LANDSCAPE_CLEAR);
00674     if (ret.Failed()) {
00675       last_error = ret;
00676 
00677       /* We may not clear more tiles. */
00678       if (c != NULL && GB(c->clear_limit, 16, 16) < 1) break;
00679       continue;
00680     }
00681 
00682     had_success = true;
00683     if (flags & DC_EXEC) {
00684       money -= ret.GetCost();
00685       if (ret.GetCost() > 0 && money < 0) {
00686         _additional_cash_required = ret.GetCost();
00687         delete iter;
00688         return cost;
00689       }
00690       DoCommand(t, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
00691 
00692       /* draw explosion animation...
00693        * Disable explosions when game is paused. Looks silly and blocks the view. */
00694       if ((t == tile || t == p1) && _pause_mode == PM_UNPAUSED) {
00695         /* big explosion in two corners, or small explosion for single tiles */
00696         CreateEffectVehicleAbove(TileX(t) * TILE_SIZE + TILE_SIZE / 2, TileY(t) * TILE_SIZE + TILE_SIZE / 2, 2,
00697           TileX(tile) == TileX(p1) && TileY(tile) == TileY(p1) ? EV_EXPLOSION_SMALL : EV_EXPLOSION_LARGE
00698         );
00699       }
00700     } else {
00701       /* When we're at the clearing limit we better bail (unneed) testing as well. */
00702       if (ret.GetCost() != 0 && --limit <= 0) break;
00703     }
00704     cost.AddCost(ret);
00705   }
00706 
00707   delete iter;
00708   return had_success ? cost : last_error;
00709 }
00710 
00711 
00712 TileIndex _cur_tileloop_tile;
00713 
00717 void RunTileLoop()
00718 {
00719   /* The pseudorandom sequence of tiles is generated using a Galois linear feedback
00720    * shift register (LFSR). This allows a deterministic pseudorandom ordering, but
00721    * still with minimal state and fast iteration. */
00722 
00723   /* Maximal length LFSR feedback terms, from 12-bit (for 64x64 maps) to 22-bit (for 2048x2048 maps).
00724    * Extracted from http://www.ece.cmu.edu/~koopman/lfsr/ */
00725   static const uint32 feedbacks[] = {
00726     0xD8F, 0x1296, 0x2496, 0x4357, 0x8679, 0x1030E, 0x206CD, 0x403FE, 0x807B8, 0x1004B2, 0x2006A8
00727   };
00728   const uint32 feedback = feedbacks[MapLogX() + MapLogY() - 12];
00729 
00730   /* We update every tile every 256 ticks, so divide the map size by 2^8 = 256 */
00731   uint count = 1 << (MapLogX() + MapLogY() - 8);
00732 
00733   TileIndex tile = _cur_tileloop_tile;
00734   /* The LFSR cannot have a zeroed state. */
00735   assert(tile != 0);
00736 
00737   /* Manually update tile 0 every 256 ticks - the LFSR never iterates over it itself.  */
00738   if (_tick_counter % 256 == 0) {
00739     _tile_type_procs[GetTileType(0)]->tile_loop_proc(0);
00740     count--;
00741   }
00742 
00743   while (count--) {
00744     _tile_type_procs[GetTileType(tile)]->tile_loop_proc(tile);
00745 
00746     /* Get the next tile in sequence using a Galois LFSR. */
00747     tile = (tile >> 1) ^ (-(int32)(tile & 1) & feedback);
00748   }
00749 
00750   _cur_tileloop_tile = tile;
00751 }
00752 
00753 void InitializeLandscape()
00754 {
00755   uint maxx = MapMaxX();
00756   uint maxy = MapMaxY();
00757   uint sizex = MapSizeX();
00758 
00759   uint y;
00760   for (y = _settings_game.construction.freeform_edges ? 1 : 0; y < maxy; y++) {
00761     uint x;
00762     for (x = _settings_game.construction.freeform_edges ? 1 : 0; x < maxx; x++) {
00763       MakeClear(sizex * y + x, CLEAR_GRASS, 3);
00764       SetTileHeight(sizex * y + x, 0);
00765       SetTropicZone(sizex * y + x, TROPICZONE_NORMAL);
00766       ClearBridgeMiddle(sizex * y + x);
00767     }
00768     MakeVoid(sizex * y + x);
00769   }
00770   for (uint x = 0; x < sizex; x++) MakeVoid(sizex * y + x);
00771 }
00772 
00773 static const byte _genterrain_tbl_1[5] = { 10, 22, 33, 37, 4  };
00774 static const byte _genterrain_tbl_2[5] = {  0,  0,  0,  0, 33 };
00775 
00776 static void GenerateTerrain(int type, uint flag)
00777 {
00778   uint32 r = Random();
00779 
00780   const Sprite *templ = GetSprite((((r >> 24) * _genterrain_tbl_1[type]) >> 8) + _genterrain_tbl_2[type] + 4845, ST_MAPGEN);
00781   if (templ == NULL) usererror("Map generator sprites could not be loaded");
00782 
00783   uint x = r & MapMaxX();
00784   uint y = (r >> MapLogX()) & MapMaxY();
00785 
00786   if (x < 2 || y < 2) return;
00787 
00788   DiagDirection direction = (DiagDirection)GB(r, 22, 2);
00789   uint w = templ->width;
00790   uint h = templ->height;
00791 
00792   if (DiagDirToAxis(direction) == AXIS_Y) Swap(w, h);
00793 
00794   const byte *p = templ->data;
00795 
00796   if ((flag & 4) != 0) {
00797     uint xw = x * MapSizeY();
00798     uint yw = y * MapSizeX();
00799     uint bias = (MapSizeX() + MapSizeY()) * 16;
00800 
00801     switch (flag & 3) {
00802       default: NOT_REACHED();
00803       case 0:
00804         if (xw + yw > MapSize() - bias) return;
00805         break;
00806 
00807       case 1:
00808         if (yw < xw + bias) return;
00809         break;
00810 
00811       case 2:
00812         if (xw + yw < MapSize() + bias) return;
00813         break;
00814 
00815       case 3:
00816         if (xw < yw + bias) return;
00817         break;
00818     }
00819   }
00820 
00821   if (x + w >= MapMaxX() - 1) return;
00822   if (y + h >= MapMaxY() - 1) return;
00823 
00824   TileIndex tile = TileXY(x, y);
00825 
00826   switch (direction) {
00827     default: NOT_REACHED();
00828     case DIAGDIR_NE:
00829       do {
00830         TileIndex tile_cur = tile;
00831 
00832         for (uint w_cur = w; w_cur != 0; --w_cur) {
00833           if (GB(*p, 0, 4) >= TileHeight(tile_cur)) SetTileHeight(tile_cur, GB(*p, 0, 4));
00834           p++;
00835           tile_cur++;
00836         }
00837         tile += TileDiffXY(0, 1);
00838       } while (--h != 0);
00839       break;
00840 
00841     case DIAGDIR_SE:
00842       do {
00843         TileIndex tile_cur = tile;
00844 
00845         for (uint h_cur = h; h_cur != 0; --h_cur) {
00846           if (GB(*p, 0, 4) >= TileHeight(tile_cur)) SetTileHeight(tile_cur, GB(*p, 0, 4));
00847           p++;
00848           tile_cur += TileDiffXY(0, 1);
00849         }
00850         tile += TileDiffXY(1, 0);
00851       } while (--w != 0);
00852       break;
00853 
00854     case DIAGDIR_SW:
00855       tile += TileDiffXY(w - 1, 0);
00856       do {
00857         TileIndex tile_cur = tile;
00858 
00859         for (uint w_cur = w; w_cur != 0; --w_cur) {
00860           if (GB(*p, 0, 4) >= TileHeight(tile_cur)) SetTileHeight(tile_cur, GB(*p, 0, 4));
00861           p++;
00862           tile_cur--;
00863         }
00864         tile += TileDiffXY(0, 1);
00865       } while (--h != 0);
00866       break;
00867 
00868     case DIAGDIR_NW:
00869       tile += TileDiffXY(0, h - 1);
00870       do {
00871         TileIndex tile_cur = tile;
00872 
00873         for (uint h_cur = h; h_cur != 0; --h_cur) {
00874           if (GB(*p, 0, 4) >= TileHeight(tile_cur)) SetTileHeight(tile_cur, GB(*p, 0, 4));
00875           p++;
00876           tile_cur -= TileDiffXY(0, 1);
00877         }
00878         tile += TileDiffXY(1, 0);
00879       } while (--w != 0);
00880       break;
00881   }
00882 }
00883 
00884 
00885 #include "table/genland.h"
00886 
00887 static void CreateDesertOrRainForest()
00888 {
00889   TileIndex update_freq = MapSize() / 4;
00890   const TileIndexDiffC *data;
00891 
00892   for (TileIndex tile = 0; tile != MapSize(); ++tile) {
00893     if ((tile % update_freq) == 0) IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
00894 
00895     if (!IsValidTile(tile)) continue;
00896 
00897     for (data = _make_desert_or_rainforest_data;
00898         data != endof(_make_desert_or_rainforest_data); ++data) {
00899       TileIndex t = AddTileIndexDiffCWrap(tile, *data);
00900       if (t != INVALID_TILE && (TileHeight(t) >= 4 || IsTileType(t, MP_WATER))) break;
00901     }
00902     if (data == endof(_make_desert_or_rainforest_data)) {
00903       SetTropicZone(tile, TROPICZONE_DESERT);
00904     }
00905   }
00906 
00907   for (uint i = 0; i != 256; i++) {
00908     if ((i % 64) == 0) IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
00909 
00910     RunTileLoop();
00911   }
00912 
00913   for (TileIndex tile = 0; tile != MapSize(); ++tile) {
00914     if ((tile % update_freq) == 0) IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
00915 
00916     if (!IsValidTile(tile)) continue;
00917 
00918     for (data = _make_desert_or_rainforest_data;
00919         data != endof(_make_desert_or_rainforest_data); ++data) {
00920       TileIndex t = AddTileIndexDiffCWrap(tile, *data);
00921       if (t != INVALID_TILE && IsTileType(t, MP_CLEAR) && IsClearGround(t, CLEAR_DESERT)) break;
00922     }
00923     if (data == endof(_make_desert_or_rainforest_data)) {
00924       SetTropicZone(tile, TROPICZONE_RAINFOREST);
00925     }
00926   }
00927 }
00928 
00935 static bool FindSpring(TileIndex tile, void *user_data)
00936 {
00937   int referenceHeight;
00938   if (!IsTileFlat(tile, &referenceHeight) || IsWaterTile(tile)) return false;
00939 
00940   /* In the tropics rivers start in the rainforest. */
00941   if (_settings_game.game_creation.landscape == LT_TROPIC && GetTropicZone(tile) != TROPICZONE_RAINFOREST) return false;
00942 
00943   /* Are there enough higher tiles to warrant a 'spring'? */
00944   uint num = 0;
00945   for (int dx = -1; dx <= 1; dx++) {
00946     for (int dy = -1; dy <= 1; dy++) {
00947       TileIndex t = TileAddWrap(tile, dx, dy);
00948       if (t != INVALID_TILE && GetTileMaxZ(t) > referenceHeight) num++;
00949     }
00950   }
00951 
00952   if (num < 4) return false;
00953 
00954   /* Are we near the top of a hill? */
00955   for (int dx = -16; dx <= 16; dx++) {
00956     for (int dy = -16; dy <= 16; dy++) {
00957       TileIndex t = TileAddWrap(tile, dx, dy);
00958       if (t != INVALID_TILE && GetTileMaxZ(t) > referenceHeight + 2) return false;
00959     }
00960   }
00961 
00962   return true;
00963 }
00964 
00971 static bool MakeLake(TileIndex tile, void *user_data)
00972 {
00973   uint height = *(uint*)user_data;
00974   if (!IsValidTile(tile) || TileHeight(tile) != height || !IsTileFlat(tile)) return false;
00975   if (_settings_game.game_creation.landscape == LT_TROPIC && GetTropicZone(tile) == TROPICZONE_DESERT) return false;
00976 
00977   for (DiagDirection d = DIAGDIR_BEGIN; d < DIAGDIR_END; d++) {
00978     TileIndex t2 = tile + TileOffsByDiagDir(d);
00979     if (IsWaterTile(t2)) {
00980       MakeRiver(tile, Random());
00981       return false;
00982     }
00983   }
00984 
00985   return false;
00986 }
00987 
00994 static bool FlowsDown(TileIndex begin, TileIndex end)
00995 {
00996   assert(DistanceManhattan(begin, end) == 1);
00997 
00998   int heightBegin;
00999   int heightEnd;
01000   Slope slopeBegin = GetTileSlope(begin, &heightBegin);
01001   Slope slopeEnd   = GetTileSlope(end, &heightEnd);
01002 
01003   return heightEnd <= heightBegin &&
01004       /* Slope either is inclined or flat; rivers don't support other slopes. */
01005       (slopeEnd == SLOPE_FLAT || IsInclinedSlope(slopeEnd)) &&
01006       /* Slope continues, then it must be lower... or either end must be flat. */
01007       ((slopeEnd == slopeBegin && heightEnd < heightBegin) || slopeEnd == SLOPE_FLAT || slopeBegin == SLOPE_FLAT);
01008 }
01009 
01010 /* AyStar callback for checking whether we reached our destination. */
01011 static int32 River_EndNodeCheck(AyStar *aystar, OpenListNode *current)
01012 {
01013   return current->path.node.tile == *(TileIndex*)aystar->user_target ? AYSTAR_FOUND_END_NODE : AYSTAR_DONE;
01014 }
01015 
01016 /* AyStar callback for getting the cost of the current node. */
01017 static int32 River_CalculateG(AyStar *aystar, AyStarNode *current, OpenListNode *parent)
01018 {
01019   return 1 + RandomRange(_settings_game.game_creation.river_route_random);
01020 }
01021 
01022 /* AyStar callback for getting the estimated cost to the destination. */
01023 static int32 River_CalculateH(AyStar *aystar, AyStarNode *current, OpenListNode *parent)
01024 {
01025   return DistanceManhattan(*(TileIndex*)aystar->user_target, current->tile);
01026 }
01027 
01028 /* AyStar callback for getting the neighbouring nodes of the given node. */
01029 static void River_GetNeighbours(AyStar *aystar, OpenListNode *current)
01030 {
01031   TileIndex tile = current->path.node.tile;
01032 
01033   aystar->num_neighbours = 0;
01034   for (DiagDirection d = DIAGDIR_BEGIN; d < DIAGDIR_END; d++) {
01035     TileIndex t2 = tile + TileOffsByDiagDir(d);
01036     if (IsValidTile(t2) && FlowsDown(tile, t2)) {
01037       aystar->neighbours[aystar->num_neighbours].tile = t2;
01038       aystar->neighbours[aystar->num_neighbours].direction = INVALID_TRACKDIR;
01039       aystar->num_neighbours++;
01040     }
01041   }
01042 }
01043 
01044 /* AyStar callback when an route has been found. */
01045 static void River_FoundEndNode(AyStar *aystar, OpenListNode *current)
01046 {
01047   for (PathNode *path = &current->path; path != NULL; path = path->parent) {
01048     TileIndex tile = path->node.tile;
01049     if (!IsWaterTile(tile)) {
01050       MakeRiver(tile, Random());
01051       /* Remove desert directly around the river tile. */
01052       CircularTileSearch(&tile, 5, RiverModifyDesertZone, NULL);
01053     }
01054   }
01055 }
01056 
01057 static const uint RIVER_HASH_SIZE = 8; 
01058 
01065 static uint River_Hash(uint tile, uint dir)
01066 {
01067   return GB(TileHash(TileX(tile), TileY(tile)), 0, RIVER_HASH_SIZE);
01068 }
01069 
01075 static void BuildRiver(TileIndex begin, TileIndex end)
01076 {
01077   AyStar finder;
01078   MemSetT(&finder, 0);
01079   finder.CalculateG = River_CalculateG;
01080   finder.CalculateH = River_CalculateH;
01081   finder.GetNeighbours = River_GetNeighbours;
01082   finder.EndNodeCheck = River_EndNodeCheck;
01083   finder.FoundEndNode = River_FoundEndNode;
01084   finder.user_target = &end;
01085 
01086   finder.Init(River_Hash, 1 << RIVER_HASH_SIZE);
01087 
01088   AyStarNode start;
01089   start.tile = begin;
01090   start.direction = INVALID_TRACKDIR;
01091   finder.AddStartNode(&start, 0);
01092   finder.Main();
01093   finder.Free();
01094 }
01095 
01103 static bool FlowRiver(bool *marks, TileIndex spring, TileIndex begin)
01104 {
01105   uint height = TileHeight(begin);
01106   if (IsWaterTile(begin)) return DistanceManhattan(spring, begin) > _settings_game.game_creation.min_river_length;
01107 
01108   MemSetT(marks, 0, MapSize());
01109   marks[begin] = true;
01110 
01111   /* Breadth first search for the closest tile we can flow down to. */
01112   std::list<TileIndex> queue;
01113   queue.push_back(begin);
01114 
01115   bool found = false;
01116   uint count = 0; // Number of tiles considered; to be used for lake location guessing.
01117   TileIndex end;
01118   do {
01119     end = queue.front();
01120     queue.pop_front();
01121 
01122     uint height2 = TileHeight(end);
01123     if (IsTileFlat(end) && (height2 < height || (height2 == height && IsWaterTile(end)))) {
01124       found = true;
01125       break;
01126     }
01127 
01128     for (DiagDirection d = DIAGDIR_BEGIN; d < DIAGDIR_END; d++) {
01129       TileIndex t2 = end + TileOffsByDiagDir(d);
01130       if (IsValidTile(t2) && !marks[t2] && FlowsDown(end, t2)) {
01131         marks[t2] = true;
01132         count++;
01133         queue.push_back(t2);
01134       }
01135     }
01136   } while (!queue.empty());
01137 
01138   if (found) {
01139     /* Flow further down hill. */
01140     found = FlowRiver(marks, spring, end);
01141   } else if (count > 32) {
01142     /* Maybe we can make a lake. Find the Nth of the considered tiles. */
01143     TileIndex lakeCenter = 0;
01144     for (int i = RandomRange(count - 1); i != 0; lakeCenter++) {
01145       if (marks[lakeCenter]) i--;
01146     }
01147 
01148     if (IsValidTile(lakeCenter) &&
01149         /* A river, or lake, can only be built on flat slopes. */
01150         IsTileFlat(lakeCenter) &&
01151         /* We want the lake to be built at the height of the river. */
01152         TileHeight(begin) == TileHeight(lakeCenter) &&
01153         /* We don't want the lake at the entry of the valley. */
01154         lakeCenter != begin &&
01155         /* We don't want lakes in the desert. */
01156         (_settings_game.game_creation.landscape != LT_TROPIC || GetTropicZone(lakeCenter) != TROPICZONE_DESERT) &&
01157         /* We only want a lake if the river is long enough. */
01158         DistanceManhattan(spring, lakeCenter) > _settings_game.game_creation.min_river_length) {
01159       end = lakeCenter;
01160       MakeRiver(lakeCenter, Random());
01161       uint range = RandomRange(8) + 3;
01162       CircularTileSearch(&lakeCenter, range, MakeLake, &height);
01163       /* Call the search a second time so artefacts from going circular in one direction get (mostly) hidden. */
01164       lakeCenter = end;
01165       CircularTileSearch(&lakeCenter, range, MakeLake, &height);
01166       found = true;
01167     }
01168   }
01169 
01170   if (found) BuildRiver(begin, end);
01171   return found;
01172 }
01173 
01177 static void CreateRivers()
01178 {
01179   int amount = _settings_game.game_creation.amount_of_rivers;
01180   if (amount == 0) return;
01181 
01182   uint wells = ScaleByMapSize(4 << _settings_game.game_creation.amount_of_rivers);
01183   SetGeneratingWorldProgress(GWP_RIVER, wells + 256 / 64); // Include the tile loop calls below.
01184   bool *marks = CallocT<bool>(MapSize());
01185 
01186   for (; wells != 0; wells--) {
01187     IncreaseGeneratingWorldProgress(GWP_RIVER);
01188     for (int tries = 0; tries < 128; tries++) {
01189       TileIndex t = RandomTile();
01190       if (!CircularTileSearch(&t, 8, FindSpring, NULL)) continue;
01191       if (FlowRiver(marks, t, t)) break;
01192     }
01193   }
01194 
01195   free(marks);
01196 
01197   /* Run tile loop to update the ground density. */
01198   for (uint i = 0; i != 256; i++) {
01199     if (i % 64 == 0) IncreaseGeneratingWorldProgress(GWP_RIVER);
01200     RunTileLoop();
01201   }
01202 }
01203 
01204 void GenerateLandscape(byte mode)
01205 {
01207   enum GenLandscapeSteps {
01208     GLS_HEIGHTMAP    =  3, 
01209     GLS_TERRAGENESIS =  5, 
01210     GLS_ORIGINAL     =  2, 
01211     GLS_TROPIC       = 12, 
01212     GLS_OTHER        =  0, 
01213   };
01214   uint steps = (_settings_game.game_creation.landscape == LT_TROPIC) ? GLS_TROPIC : GLS_OTHER;
01215 
01216   if (mode == GWM_HEIGHTMAP) {
01217     SetGeneratingWorldProgress(GWP_LANDSCAPE, steps + GLS_HEIGHTMAP);
01218     LoadHeightmap(_file_to_saveload.name);
01219     IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
01220   } else if (_settings_game.game_creation.land_generator == LG_TERRAGENESIS) {
01221     SetGeneratingWorldProgress(GWP_LANDSCAPE, steps + GLS_TERRAGENESIS);
01222     GenerateTerrainPerlin();
01223   } else {
01224     SetGeneratingWorldProgress(GWP_LANDSCAPE, steps + GLS_ORIGINAL);
01225     if (_settings_game.construction.freeform_edges) {
01226       for (uint x = 0; x < MapSizeX(); x++) MakeVoid(TileXY(x, 0));
01227       for (uint y = 0; y < MapSizeY(); y++) MakeVoid(TileXY(0, y));
01228     }
01229     switch (_settings_game.game_creation.landscape) {
01230       case LT_ARCTIC: {
01231         uint32 r = Random();
01232 
01233         for (uint i = ScaleByMapSize(GB(r, 0, 7) + 950); i != 0; --i) {
01234           GenerateTerrain(2, 0);
01235         }
01236 
01237         uint flag = GB(r, 7, 2) | 4;
01238         for (uint i = ScaleByMapSize(GB(r, 9, 7) + 450); i != 0; --i) {
01239           GenerateTerrain(4, flag);
01240         }
01241         break;
01242       }
01243 
01244       case LT_TROPIC: {
01245         uint32 r = Random();
01246 
01247         for (uint i = ScaleByMapSize(GB(r, 0, 7) + 170); i != 0; --i) {
01248           GenerateTerrain(0, 0);
01249         }
01250 
01251         uint flag = GB(r, 7, 2) | 4;
01252         for (uint i = ScaleByMapSize(GB(r, 9, 8) + 1700); i != 0; --i) {
01253           GenerateTerrain(0, flag);
01254         }
01255 
01256         flag ^= 2;
01257 
01258         for (uint i = ScaleByMapSize(GB(r, 17, 7) + 410); i != 0; --i) {
01259           GenerateTerrain(3, flag);
01260         }
01261         break;
01262       }
01263 
01264       default: {
01265         uint32 r = Random();
01266 
01267         assert(_settings_game.difficulty.quantity_sea_lakes != CUSTOM_SEA_LEVEL_NUMBER_DIFFICULTY);
01268         uint i = ScaleByMapSize(GB(r, 0, 7) + (3 - _settings_game.difficulty.quantity_sea_lakes) * 256 + 100);
01269         for (; i != 0; --i) {
01270           GenerateTerrain(_settings_game.difficulty.terrain_type, 0);
01271         }
01272         break;
01273       }
01274     }
01275   }
01276 
01277   /* Do not call IncreaseGeneratingWorldProgress() before FixSlopes(),
01278    * it allows screen redraw. Drawing of broken slopes crashes the game */
01279   FixSlopes();
01280   IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
01281   ConvertGroundTilesIntoWaterTiles();
01282   IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
01283 
01284   if (_settings_game.game_creation.landscape == LT_TROPIC) CreateDesertOrRainForest();
01285 
01286   CreateRivers();
01287 }
01288 
01289 void OnTick_Town();
01290 void OnTick_Trees();
01291 void OnTick_Station();
01292 void OnTick_Industry();
01293 
01294 void OnTick_Companies();
01295 void OnTick_LinkGraph();
01296 
01297 void CallLandscapeTick()
01298 {
01299   OnTick_Town();
01300   OnTick_Trees();
01301   OnTick_Station();
01302   OnTick_Industry();
01303 
01304   OnTick_Companies();
01305   OnTick_LinkGraph();
01306 }