clear_cmd.cpp

Go to the documentation of this file.
00001 /* $Id: clear_cmd.cpp 18728 2010-01-04 22:26:25Z yexo $ */
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 
00012 #include "stdafx.h"
00013 #include "openttd.h"
00014 #include "clear_map.h"
00015 #include "command_func.h"
00016 #include "landscape.h"
00017 #include "variables.h"
00018 #include "genworld.h"
00019 #include "landscape_type.h"
00020 #include "functions.h"
00021 #include "economy_func.h"
00022 #include "viewport_func.h"
00023 #include "water.h"
00024 
00025 #include "table/strings.h"
00026 #include "table/sprites.h"
00027 #include "table/clear_land.h"
00028 
00029 static CommandCost ClearTile_Clear(TileIndex tile, DoCommandFlag flags)
00030 {
00031   static const Price clear_price_table[] = {
00032     PR_CLEAR_GRASS,
00033     PR_CLEAR_ROUGH,
00034     PR_CLEAR_ROCKS,
00035     PR_CLEAR_FILEDS,
00036     PR_CLEAR_ROUGH,
00037     PR_CLEAR_ROUGH,
00038   };
00039   CommandCost price(EXPENSES_CONSTRUCTION);
00040 
00041   if (!IsClearGround(tile, CLEAR_GRASS) || GetClearDensity(tile) != 0) {
00042     price.AddCost(_price[clear_price_table[GetClearGround(tile)]]);
00043   }
00044 
00045   if (flags & DC_EXEC) DoClearSquare(tile);
00046 
00047   return price;
00048 }
00049 
00050 void DrawClearLandTile(const TileInfo *ti, byte set)
00051 {
00052   DrawGroundSprite(SPR_FLAT_BARE_LAND + _tileh_to_sprite[ti->tileh] + set * 19, PAL_NONE);
00053 }
00054 
00055 void DrawHillyLandTile(const TileInfo *ti)
00056 {
00057   if (ti->tileh != SLOPE_FLAT) {
00058     DrawGroundSprite(SPR_FLAT_ROUGH_LAND + _tileh_to_sprite[ti->tileh], PAL_NONE);
00059   } else {
00060     DrawGroundSprite(_landscape_clear_sprites_rough[GB(ti->x ^ ti->y, 4, 3)], PAL_NONE);
00061   }
00062 }
00063 
00064 void DrawClearLandFence(const TileInfo *ti)
00065 {
00066   int z = GetSlopeZInCorner(ti->tileh, CORNER_S);
00067 
00068   if (GetFenceSW(ti->tile) != 0) {
00069     DrawGroundSpriteAt(_clear_land_fence_sprites[GetFenceSW(ti->tile) - 1] + _fence_mod_by_tileh_sw[ti->tileh], PAL_NONE, 0, 0, z);
00070   }
00071 
00072   if (GetFenceSE(ti->tile) != 0) {
00073     DrawGroundSpriteAt(_clear_land_fence_sprites[GetFenceSE(ti->tile) - 1] + _fence_mod_by_tileh_se[ti->tileh], PAL_NONE, 0, 0, z);
00074   }
00075 }
00076 
00077 static void DrawTile_Clear(TileInfo *ti)
00078 {
00079   switch (GetClearGround(ti->tile)) {
00080     case CLEAR_GRASS:
00081       DrawClearLandTile(ti, GetClearDensity(ti->tile));
00082       break;
00083 
00084     case CLEAR_ROUGH:
00085       DrawHillyLandTile(ti);
00086       break;
00087 
00088     case CLEAR_ROCKS:
00089       DrawGroundSprite(SPR_FLAT_ROCKY_LAND_1 + _tileh_to_sprite[ti->tileh], PAL_NONE);
00090       break;
00091 
00092     case CLEAR_FIELDS:
00093       DrawGroundSprite(_clear_land_sprites_farmland[GetFieldType(ti->tile)] + _tileh_to_sprite[ti->tileh], PAL_NONE);
00094       break;
00095 
00096     case CLEAR_SNOW:
00097     case CLEAR_DESERT:
00098       DrawGroundSprite(_clear_land_sprites_snow_desert[GetClearDensity(ti->tile)] + _tileh_to_sprite[ti->tileh], PAL_NONE);
00099       break;
00100   }
00101 
00102   DrawClearLandFence(ti);
00103   DrawBridgeMiddle(ti);
00104 }
00105 
00106 static uint GetSlopeZ_Clear(TileIndex tile, uint x, uint y)
00107 {
00108   uint z;
00109   Slope tileh = GetTileSlope(tile, &z);
00110 
00111   return z + GetPartialZ(x & 0xF, y & 0xF, tileh);
00112 }
00113 
00114 static Foundation GetFoundation_Clear(TileIndex tile, Slope tileh)
00115 {
00116   return FOUNDATION_NONE;
00117 }
00118 
00119 void TileLoopClearHelper(TileIndex tile)
00120 {
00121   bool self = (IsTileType(tile, MP_CLEAR) && IsClearGround(tile, CLEAR_FIELDS));
00122   bool dirty = false;
00123 
00124   bool neighbour = (IsTileType(TILE_ADDXY(tile, 1, 0), MP_CLEAR) && IsClearGround(TILE_ADDXY(tile, 1, 0), CLEAR_FIELDS));
00125   if (GetFenceSW(tile) == 0) {
00126     if (self != neighbour) {
00127       SetFenceSW(tile, 3);
00128       dirty = true;
00129     }
00130   } else {
00131     if (self == 0 && neighbour == 0) {
00132       SetFenceSW(tile, 0);
00133       dirty = true;
00134     }
00135   }
00136 
00137   neighbour = (IsTileType(TILE_ADDXY(tile, 0, 1), MP_CLEAR) && IsClearGround(TILE_ADDXY(tile, 0, 1), CLEAR_FIELDS));
00138   if (GetFenceSE(tile) == 0) {
00139     if (self != neighbour) {
00140       SetFenceSE(tile, 3);
00141       dirty = true;
00142     }
00143   } else {
00144     if (self == 0 && neighbour == 0) {
00145       SetFenceSE(tile, 0);
00146       dirty = true;
00147     }
00148   }
00149 
00150   if (dirty) MarkTileDirtyByTile(tile);
00151 }
00152 
00153 
00155 static void TileLoopClearAlps(TileIndex tile)
00156 {
00157   int k = GetTileZ(tile) - GetSnowLine() + TILE_HEIGHT;
00158 
00159   if (k < 0) {
00160     /* Below the snow line, do nothing if no snow. */
00161     if (!IsSnowTile(tile)) return;
00162   } else {
00163     /* At or above the snow line, make snow tile if needed. */
00164     if (!IsSnowTile(tile)) {
00165       MakeSnow(tile);
00166       MarkTileDirtyByTile(tile);
00167       return;
00168     }
00169   }
00170   /* Update snow density. */
00171   uint curent_density = GetClearDensity(tile);
00172   uint req_density = (k < 0) ? 0u : min((uint)k / TILE_HEIGHT, 3);
00173 
00174   if (curent_density < req_density) {
00175     AddClearDensity(tile, 1);
00176   } else if (curent_density > req_density) {
00177     AddClearDensity(tile, -1);
00178   } else {
00179     /* Density at the required level. */
00180     if (k >= 0) return;
00181     ClearSnow(tile);
00182   }
00183   MarkTileDirtyByTile(tile);
00184 }
00185 
00186 static void TileLoopClearDesert(TileIndex tile)
00187 {
00188   if (IsClearGround(tile, CLEAR_DESERT)) return;
00189 
00190   if (GetTropicZone(tile) == TROPICZONE_DESERT) {
00191     SetClearGroundDensity(tile, CLEAR_DESERT, 3);
00192   } else {
00193     if (GetTropicZone(tile + TileDiffXY( 1,  0)) != TROPICZONE_DESERT &&
00194         GetTropicZone(tile + TileDiffXY(-1,  0)) != TROPICZONE_DESERT &&
00195         GetTropicZone(tile + TileDiffXY( 0,  1)) != TROPICZONE_DESERT &&
00196         GetTropicZone(tile + TileDiffXY( 0, -1)) != TROPICZONE_DESERT)
00197       return;
00198     SetClearGroundDensity(tile, CLEAR_DESERT, 1);
00199   }
00200 
00201   MarkTileDirtyByTile(tile);
00202 }
00203 
00204 static void TileLoop_Clear(TileIndex tile)
00205 {
00206   /* If the tile is at any edge flood it to prevent maps without water. */
00207   if (_settings_game.construction.freeform_edges && DistanceFromEdge(tile) == 1) {
00208     uint z;
00209     Slope slope = GetTileSlope(tile, &z);
00210     if (z == 0 && slope == SLOPE_FLAT) {
00211       DoFloodTile(tile);
00212       MarkTileDirtyByTile(tile);
00213       return;
00214     }
00215   }
00216   TileLoopClearHelper(tile);
00217 
00218   switch (_settings_game.game_creation.landscape) {
00219     case LT_TROPIC: TileLoopClearDesert(tile); break;
00220     case LT_ARCTIC: TileLoopClearAlps(tile);   break;
00221   }
00222 
00223   switch (GetClearGround(tile)) {
00224     case CLEAR_GRASS:
00225       if (GetClearDensity(tile) == 3) return;
00226 
00227       if (_game_mode != GM_EDITOR) {
00228         if (GetClearCounter(tile) < 7) {
00229           AddClearCounter(tile, 1);
00230           return;
00231         } else {
00232           SetClearCounter(tile, 0);
00233           AddClearDensity(tile, 1);
00234         }
00235       } else {
00236         SetClearGroundDensity(tile, GB(Random(), 0, 8) > 21 ? CLEAR_GRASS : CLEAR_ROUGH, 3);
00237       }
00238       break;
00239 
00240     case CLEAR_FIELDS: {
00241       uint field_type;
00242 
00243       if (_game_mode == GM_EDITOR) return;
00244 
00245       if (GetClearCounter(tile) < 7) {
00246         AddClearCounter(tile, 1);
00247         return;
00248       } else {
00249         SetClearCounter(tile, 0);
00250       }
00251 
00252       if (GetIndustryIndexOfField(tile) == INVALID_INDUSTRY && GetFieldType(tile) >= 7) {
00253         /* This farmfield is no longer farmfield, so make it grass again */
00254         MakeClear(tile, CLEAR_GRASS, 2);
00255       } else {
00256         field_type = GetFieldType(tile);
00257         field_type = (field_type < 8) ? field_type + 1 : 0;
00258         SetFieldType(tile, field_type);
00259       }
00260       break;
00261     }
00262 
00263     default:
00264       return;
00265   }
00266 
00267   MarkTileDirtyByTile(tile);
00268 }
00269 
00270 void GenerateClearTile()
00271 {
00272   uint i, gi;
00273   TileIndex tile;
00274 
00275   /* add rough tiles */
00276   i = ScaleByMapSize(GB(Random(), 0, 10) + 0x400);
00277   gi = ScaleByMapSize(GB(Random(), 0, 7) + 0x80);
00278 
00279   SetGeneratingWorldProgress(GWP_ROUGH_ROCKY, gi + i);
00280   do {
00281     IncreaseGeneratingWorldProgress(GWP_ROUGH_ROCKY);
00282     tile = RandomTile();
00283     if (IsTileType(tile, MP_CLEAR) && !IsClearGround(tile, CLEAR_DESERT)) SetClearGroundDensity(tile, CLEAR_ROUGH, 3);
00284   } while (--i);
00285 
00286   /* add rocky tiles */
00287   i = gi;
00288   do {
00289     uint32 r = Random();
00290     tile = RandomTileSeed(r);
00291 
00292     IncreaseGeneratingWorldProgress(GWP_ROUGH_ROCKY);
00293     if (IsTileType(tile, MP_CLEAR) && !IsClearGround(tile, CLEAR_DESERT)) {
00294       uint j = GB(r, 16, 4) + 5;
00295       for (;;) {
00296         TileIndex tile_new;
00297 
00298         SetClearGroundDensity(tile, CLEAR_ROCKS, 3);
00299         do {
00300           if (--j == 0) goto get_out;
00301           tile_new = tile + TileOffsByDiagDir((DiagDirection)GB(Random(), 0, 2));
00302         } while (!IsTileType(tile_new, MP_CLEAR) || IsClearGround(tile_new, CLEAR_DESERT));
00303         tile = tile_new;
00304       }
00305 get_out:;
00306     }
00307   } while (--i);
00308 }
00309 
00310 static TrackStatus GetTileTrackStatus_Clear(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
00311 {
00312   return 0;
00313 }
00314 
00315 static const StringID _clear_land_str[] = {
00316   STR_LAI_CLEAR_DESCRIPTION_GRASS,
00317   STR_LAI_CLEAR_DESCRIPTION_ROUGH_LAND,
00318   STR_LAI_CLEAR_DESCRIPTION_ROCKS,
00319   STR_LAI_CLEAR_DESCRIPTION_FIELDS,
00320   STR_LAI_CLEAR_DESCRIPTION_SNOW_COVERED_LAND,
00321   STR_LAI_CLEAR_DESCRIPTION_DESERT
00322 };
00323 
00324 static void GetTileDesc_Clear(TileIndex tile, TileDesc *td)
00325 {
00326   if (IsClearGround(tile, CLEAR_GRASS) && GetClearDensity(tile) == 0) {
00327     td->str = STR_LAI_CLEAR_DESCRIPTION_BARE_LAND;
00328   } else {
00329     td->str = _clear_land_str[GetClearGround(tile)];
00330   }
00331   td->owner[0] = GetTileOwner(tile);
00332 }
00333 
00334 static void ChangeTileOwner_Clear(TileIndex tile, Owner old_owner, Owner new_owner)
00335 {
00336   return;
00337 }
00338 
00339 void InitializeClearLand()
00340 {
00341   _settings_game.game_creation.snow_line = _settings_game.game_creation.snow_line_height * TILE_HEIGHT;
00342 }
00343 
00344 static CommandCost TerraformTile_Clear(TileIndex tile, DoCommandFlag flags, uint z_new, Slope tileh_new)
00345 {
00346   return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
00347 }
00348 
00349 extern const TileTypeProcs _tile_type_clear_procs = {
00350   DrawTile_Clear,           
00351   GetSlopeZ_Clear,          
00352   ClearTile_Clear,          
00353   NULL,                     
00354   GetTileDesc_Clear,        
00355   GetTileTrackStatus_Clear, 
00356   NULL,                     
00357   NULL,                     
00358   TileLoop_Clear,           
00359   ChangeTileOwner_Clear,    
00360   NULL,                     
00361   NULL,                     
00362   GetFoundation_Clear,      
00363   TerraformTile_Clear,      
00364 };

Generated on Tue Jan 5 21:02:53 2010 for OpenTTD by  doxygen 1.5.6