# ai_tile.cpp

Go to the documentation of this file.

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