00001
00002
00003
00004
00005
00006
00007
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
00161 if (!IsSnowTile(tile)) return;
00162 } else {
00163
00164 if (!IsSnowTile(tile)) {
00165 MakeSnow(tile);
00166 MarkTileDirtyByTile(tile);
00167 return;
00168 }
00169 }
00170
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
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
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
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
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
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 };