clear_cmd.cpp

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

Generated on Wed Jun 3 19:05:09 2009 for OpenTTD by  doxygen 1.5.6