# ai_tile.cpp

Go to the documentation of this file.

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