00001
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
00127 }
00128
00129 static void AnimateTile_Clear(TileIndex tile)
00130 {
00131
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
00173 static void TileLoopClearAlps(TileIndex tile)
00174 {
00175 int k = GetTileZ(tile) - GetSnowLine() + TILE_HEIGHT;
00176
00177 if (k < 0) {
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
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
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
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
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 };