clear_cmd.cpp

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

Generated on Mon Sep 22 20:34:15 2008 for openttd by  doxygen 1.5.6