00001
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
00124 }
00125
00126 static void AnimateTile_Clear(TileIndex tile)
00127 {
00128
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
00170 static void TileLoopClearAlps(TileIndex tile)
00171 {
00172 int k = GetTileZ(tile) - GetSnowLine() + TILE_HEIGHT;
00173
00174 if (k < 0) {
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
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
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
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
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
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 };