# ai_tile.cpp

Go to the documentation of this file.

    00001 /* $Id: ai_tile.cpp 17693 2009-10-04 17:16:41Z rubidium $ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
    00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
    00008  */
    00009
    00012 #include "ai_tile.hpp"
    00013 #include "ai_map.hpp"
    00014 #include "ai_town.hpp"
    00015 #include "../../station_func.h"
    00016 #include "../../company_func.h"
    00017 #include "../../road_map.h"
    00018 #include "../../water_map.h"
    00019 #include "../../clear_map.h"
    00020 #include "../../town.h"
    00021 #include "../../landscape.h"
    00022
    00023 /* static */ bool AITile::IsBuildable(TileIndex tile)
    00024 {
    00025   if (!::IsValidTile(tile)) return false;
    00026
    00027   switch (::GetTileType(tile)) {
    00028     default: return false;
    00029     case MP_CLEAR: return true;
    00030     case MP_TREES: return true;
    00031     case MP_WATER: return IsCoast(tile);
    00032     case MP_ROAD:
    00033       /* Tram bits aren't considered buildable */
    00034       if (::GetRoadTypes(tile) != ROADTYPES_ROAD) return false;
    00035       /* Depots and crossings aren't considered buildable */
    00036       if (::GetRoadTileType(tile) != ROAD_TILE_NORMAL) return false;
    00037       if (CountBits(::GetRoadBits(tile, ROADTYPE_ROAD)) != 1) return false;
    00038       if (::IsRoadOwner(tile, ROADTYPE_ROAD, OWNER_TOWN)) return true;
    00039       if (::IsRoadOwner(tile, ROADTYPE_ROAD, _current_company)) return true;
    00040       return false;
    00041   }
    00042 }
    00043
    00044 /* static */ bool AITile::IsBuildableRectangle(TileIndex tile, uint width, uint height)
    00045 {
    00046   uint tx, ty;
    00047
    00048   tx = AIMap::GetTileX(tile);
    00049   ty = AIMap::GetTileY(tile);
    00050
    00051   for (uint x = tx; x < width + tx; x++) {
    00052     for (uint y = ty; y < height + ty; y++) {
    00053       if (!IsBuildable(AIMap::GetTileIndex(x, y))) return false;
    00054     }
    00055   }
    00056
    00057   return true;
    00058 }
    00059
    00060 /* static */ bool AITile::IsWaterTile(TileIndex tile)
    00061 {
    00062   if (!::IsValidTile(tile)) return false;
    00063
    00064   return ::IsTileType(tile, MP_WATER) && !::IsCoast(tile);
    00065 }
    00066
    00067 /* static */ bool AITile::IsCoastTile(TileIndex tile)
    00068 {
    00069   if (!::IsValidTile(tile)) return false;
    00070
    00071   return ::IsTileType(tile, MP_WATER) && ::IsCoast(tile);
    00072 }
    00073
    00074 /* static */ bool AITile::IsStationTile(TileIndex tile)
    00075 {
    00076   if (!::IsValidTile(tile)) return false;
    00077
    00078   return ::IsTileType(tile, MP_STATION);
    00079 }
    00080
    00081 /* static */ bool AITile::IsSteepSlope(Slope slope)
    00082 {
    00083   if ((slope & ~(SLOPE_ELEVATED | SLOPE_STEEP | SLOPE_HALFTILE_MASK)) != 0) return false;
    00084
    00085   return ::IsSteepSlope((::Slope)slope);
    00086 }
    00087
    00088 /* static */ bool AITile::IsHalftileSlope(Slope slope)
    00089 {
    00090   if ((slope & ~(SLOPE_ELEVATED | SLOPE_STEEP | SLOPE_HALFTILE_MASK)) != 0) return false;
    00091
    00092   return ::IsHalftileSlope((::Slope)slope);
    00093 }
    00094
    00095 /* static */ bool AITile::HasTreeOnTile(TileIndex tile)
    00096 {
    00097   if (!::IsValidTile(tile)) return false;
    00098
    00099   return ::IsTileType(tile, MP_TREES);
    00100 }
    00101
    00102 /* static */ bool AITile::IsFarmTile(TileIndex tile)
    00103 {
    00104   if (!::IsValidTile(tile)) return false;
    00105
    00106   return (::IsTileType(tile, MP_CLEAR) && ::IsClearGround(tile, CLEAR_FIELDS));
    00107 }
    00108
    00109 /* static */ bool AITile::IsRockTile(TileIndex tile)
    00110 {
    00111   if (!::IsValidTile(tile)) return false;
    00112
    00113   return (::IsTileType(tile, MP_CLEAR) && ::IsClearGround(tile, CLEAR_ROCKS));
    00114 }
    00115
    00116 /* static */ bool AITile::IsRoughTile(TileIndex tile)
    00117 {
    00118   if (!::IsValidTile(tile)) return false;
    00119
    00120   return (::IsTileType(tile, MP_CLEAR) && ::IsClearGround(tile, CLEAR_ROUGH));
    00121 }
    00122
    00123 /* static */ bool AITile::IsSnowTile(TileIndex tile)
    00124 {
    00125   if (!::IsValidTile(tile)) return false;
    00126
    00127   return (::IsTileType(tile, MP_CLEAR) && ::IsClearGround(tile, CLEAR_SNOW));
    00128 }
    00129
    00130 /* static */ bool AITile::IsDesertTile(TileIndex tile)
    00131 {
    00132   if (!::IsValidTile(tile)) return false;
    00133
    00134   return (::IsTileType(tile, MP_CLEAR) && ::IsClearGround(tile, CLEAR_DESERT));
    00135 }
    00136
    00137 /* static */ AITile::Slope AITile::GetSlope(TileIndex tile)
    00138 {
    00139   if (!::IsValidTile(tile)) return SLOPE_INVALID;
    00140
    00141   return (Slope)::GetTileSlope(tile, NULL);
    00142 }
    00143
    00144 /* static */ AITile::Slope AITile::GetComplementSlope(Slope slope)
    00145 {
    00146   if ((slope & ~SLOPE_ELEVATED) != 0) return SLOPE_INVALID;
    00147
    00148   return (Slope)::ComplementSlope((::Slope)slope);
    00149 }
    00150
    00151 /* static */ int32 AITile::GetMinHeight(TileIndex tile)
    00152 {
    00153   if (!::IsValidTile(tile)) return -1;
    00154
    00155   return ::GetTileZ(tile) / ::TILE_HEIGHT;
    00156 }
    00157
    00158 /* static */ int32 AITile::GetMaxHeight(TileIndex tile)
    00159 {
    00160   if (!::IsValidTile(tile)) return -1;
    00161
    00162   return ::GetTileMaxZ(tile) / ::TILE_HEIGHT;
    00163 }
    00164
    00165 /* static */ int32 AITile::GetCornerHeight(TileIndex tile, Corner corner)
    00166 {
    00167   if (!::IsValidTile(tile) || !::IsValidCorner((::Corner)corner)) return -1;
    00168
    00169   uint z;
    00170 	::Slope slope = ::GetTileSlope(tile, &z);
    00171   return (z + ::GetSlopeZInCorner(slope, (::Corner)corner)) / ::TILE_HEIGHT;
    00172 }
    00173
    00174 /* static */ AICompany::CompanyID AITile::GetOwner(TileIndex tile)
    00175 {
    00176   if (!::IsValidTile(tile)) return AICompany::COMPANY_INVALID;
    00177   if (::IsTileType(tile, MP_HOUSE)) return AICompany::COMPANY_INVALID;
    00178   if (::IsTileType(tile, MP_INDUSTRY)) return AICompany::COMPANY_INVALID;
    00179
    00180   return AICompany::ResolveCompanyID((AICompany::CompanyID)(byte)::GetTileOwner(tile));
    00181 }
    00182
    00183 /* static */ bool AITile::HasTransportType(TileIndex tile, TransportType transport_type)
    00184 {
    00185   if (!::IsValidTile(tile)) return false;
    00186
    00187   return ::TrackStatusToTrackdirBits(::GetTileTrackStatus(tile, (::TransportType)transport_type, UINT32_MAX)) != TRACKDIR_BIT_NONE;
    00188 }
    00189
    00190 /* static */ int32 AITile::GetCargoAcceptance(TileIndex tile, CargoID cargo_type, int width, int height, int radius)
    00191 {
    00192   if (!::IsValidTile(tile) || width <= 0 || height <= 0 || radius < 0) return -1;
    00193
    00194   CargoArray acceptance = ::GetAcceptanceAroundTiles(tile, width, height, _settings_game.station.modified_catchment ? radius : (int)CA_UNMODIFIED);
    00195   return acceptance[cargo_type];
    00196 }
    00197
    00198 /* static */ int32 AITile::GetCargoProduction(TileIndex tile, CargoID cargo_type, int width, int height, int radius)
    00199 {
    00200   if (!::IsValidTile(tile) || width <= 0 || height <= 0 || radius < 0) return -1;
    00201
    00202   CargoArray produced = ::GetProductionAroundTiles(tile, width, height, _settings_game.station.modified_catchment ? radius : (int)CA_UNMODIFIED);
    00203   return produced[cargo_type];
    00204 }
    00205
    00206 /* static */ int32 AITile::GetDistanceManhattanToTile(TileIndex tile_from, TileIndex tile_to)
    00207 {
    00208   return AIMap::DistanceManhattan(tile_from, tile_to);
    00209 }
    00210
    00211 /* static */ int32 AITile::GetDistanceSquareToTile(TileIndex tile_from, TileIndex tile_to)
    00212 {
    00213   return AIMap::DistanceSquare(tile_from, tile_to);
    00214 }
    00215
    00216 /* static */ bool AITile::RaiseTile(TileIndex tile, int32 slope)
    00217 {
    00218   EnforcePrecondition(false, tile < ::MapSize());
    00219
    00220   return AIObject::DoCommand(tile, slope, 1, CMD_TERRAFORM_LAND);
    00221 }
    00222
    00223 /* static */ bool AITile::LowerTile(TileIndex tile, int32 slope)
    00224 {
    00225   EnforcePrecondition(false, tile < ::MapSize());
    00226
    00227   return AIObject::DoCommand(tile, slope, 0, CMD_TERRAFORM_LAND);
    00228 }
    00229
    00230 /* static */ bool AITile::LevelTiles(TileIndex start_tile, TileIndex end_tile)
    00231 {
    00232   EnforcePrecondition(false, start_tile < ::MapSize());
    00233   EnforcePrecondition(false, end_tile < ::MapSize());
    00234
    00235   return AIObject::DoCommand(end_tile, start_tile, 0, CMD_LEVEL_LAND);
    00236 }
    00237
    00238 /* static */ bool AITile::DemolishTile(TileIndex tile)
    00239 {
    00240   EnforcePrecondition(false, ::IsValidTile(tile));
    00241
    00242   return AIObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR);
    00243 }
    00244
    00245 /* static */ bool AITile::PlantTree(TileIndex tile)
    00246 {
    00247   EnforcePrecondition(false, ::IsValidTile(tile));
    00248
    00249   return AIObject::DoCommand(tile, UINT_MAX, tile, CMD_PLANT_TREE);
    00250 }
    00251
    00252 /* static */ bool AITile::PlantTreeRectangle(TileIndex tile, uint width, uint height)
    00253 {
    00254   EnforcePrecondition(false, ::IsValidTile(tile));
    00255   EnforcePrecondition(false, width >= 1 && width <= 20);
    00256   EnforcePrecondition(false, height >= 1 && height <= 20);
    00257   TileIndex end_tile = tile + ::TileDiffXY(width - 1, height - 1);
    00258
    00259   return AIObject::DoCommand(tile, UINT_MAX, end_tile, CMD_PLANT_TREE);
    00260 }
    00261
    00262 /* static */ bool AITile::IsWithinTownInfluence(TileIndex tile, TownID town_id)
    00263 {
    00264   return AITown::IsWithinTownInfluence(town_id, tile);
    00265 }
    00266
    00267 /* static */ TownID AITile::GetClosestTown(TileIndex tile)
    00268 {
    00269   if (!::IsValidTile(tile)) return INVALID_TOWN;
    00270
    00271   return ::ClosestTownFromTile(tile, UINT_MAX)->index;
    00272 }