script_tile.cpp

Go to the documentation of this file.
00001 /* $Id: script_tile.cpp 23633 2011-12-19 21:05:36Z truebrain $ */
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 "../../stdafx.h"
00013 #include "script_tile.hpp"
00014 #include "script_map.hpp"
00015 #include "script_town.hpp"
00016 #include "script_cargo.hpp"
00017 #include "../../station_func.h"
00018 #include "../../company_func.h"
00019 #include "../../water_map.h"
00020 #include "../../clear_map.h"
00021 #include "../../tree_map.h"
00022 #include "../../town.h"
00023 #include "../../landscape.h"
00024 #include "../../economy_func.h"
00025 
00026 /* static */ bool ScriptTile::IsBuildable(TileIndex tile)
00027 {
00028   if (!::IsValidTile(tile)) return false;
00029 
00030   switch (::GetTileType(tile)) {
00031     default: return false;
00032     case MP_CLEAR: return true;
00033     case MP_TREES: return true;
00034     case MP_WATER: return IsCoast(tile);
00035     case MP_ROAD:
00036       /* Tram bits aren't considered buildable */
00037       if (::GetRoadTypes(tile) != ROADTYPES_ROAD) return false;
00038       /* Depots and crossings aren't considered buildable */
00039       if (::GetRoadTileType(tile) != ROAD_TILE_NORMAL) return false;
00040       if (!HasExactlyOneBit(::GetRoadBits(tile, ROADTYPE_ROAD))) return false;
00041       if (::IsRoadOwner(tile, ROADTYPE_ROAD, OWNER_TOWN)) return true;
00042       if (::IsRoadOwner(tile, ROADTYPE_ROAD, ScriptObject::GetCompany())) return true;
00043       return false;
00044   }
00045 }
00046 
00047 /* static */ bool ScriptTile::IsBuildableRectangle(TileIndex tile, uint width, uint height)
00048 {
00049   uint tx, ty;
00050 
00051   tx = ScriptMap::GetTileX(tile);
00052   ty = ScriptMap::GetTileY(tile);
00053 
00054   for (uint x = tx; x < width + tx; x++) {
00055     for (uint y = ty; y < height + ty; y++) {
00056       if (!IsBuildable(ScriptMap::GetTileIndex(x, y))) return false;
00057     }
00058   }
00059 
00060   return true;
00061 }
00062 
00063 /* static */ bool ScriptTile::IsWaterTile(TileIndex tile)
00064 {
00065   if (!::IsValidTile(tile)) return false;
00066 
00067   return ::IsTileType(tile, MP_WATER) && !::IsCoast(tile);
00068 }
00069 
00070 /* static */ bool ScriptTile::IsCoastTile(TileIndex tile)
00071 {
00072   if (!::IsValidTile(tile)) return false;
00073 
00074   return (::IsTileType(tile, MP_WATER) && ::IsCoast(tile)) ||
00075     (::IsTileType(tile, MP_TREES) && ::GetTreeGround(tile) == TREE_GROUND_SHORE);
00076 }
00077 
00078 /* static */ bool ScriptTile::IsStationTile(TileIndex tile)
00079 {
00080   if (!::IsValidTile(tile)) return false;
00081 
00082   return ::IsTileType(tile, MP_STATION);
00083 }
00084 
00085 /* static */ bool ScriptTile::IsSteepSlope(Slope slope)
00086 {
00087   if ((slope & ~(SLOPE_ELEVATED | SLOPE_STEEP | SLOPE_HALFTILE_MASK)) != 0) return false;
00088 
00089   return ::IsSteepSlope((::Slope)slope);
00090 }
00091 
00092 /* static */ bool ScriptTile::IsHalftileSlope(Slope slope)
00093 {
00094   if ((slope & ~(SLOPE_ELEVATED | SLOPE_STEEP | SLOPE_HALFTILE_MASK)) != 0) return false;
00095 
00096   return ::IsHalftileSlope((::Slope)slope);
00097 }
00098 
00099 /* static */ bool ScriptTile::HasTreeOnTile(TileIndex tile)
00100 {
00101   if (!::IsValidTile(tile)) return false;
00102 
00103   return ::IsTileType(tile, MP_TREES);
00104 }
00105 
00106 /* static */ bool ScriptTile::IsFarmTile(TileIndex tile)
00107 {
00108   if (!::IsValidTile(tile)) return false;
00109 
00110   return (::IsTileType(tile, MP_CLEAR) && ::IsClearGround(tile, CLEAR_FIELDS));
00111 }
00112 
00113 /* static */ bool ScriptTile::IsRockTile(TileIndex tile)
00114 {
00115   if (!::IsValidTile(tile)) return false;
00116 
00117   return (::IsTileType(tile, MP_CLEAR) && ::GetRawClearGround(tile) == ::CLEAR_ROCKS);
00118 }
00119 
00120 /* static */ bool ScriptTile::IsRoughTile(TileIndex tile)
00121 {
00122   if (!::IsValidTile(tile)) return false;
00123 
00124   return (::IsTileType(tile, MP_CLEAR) && ::GetRawClearGround(tile) == ::CLEAR_ROUGH);
00125 }
00126 
00127 /* static */ bool ScriptTile::IsSnowTile(TileIndex tile)
00128 {
00129   if (!::IsValidTile(tile)) return false;
00130 
00131   return (::IsTileType(tile, MP_CLEAR) && ::IsSnowTile(tile));
00132 }
00133 
00134 /* static */ bool ScriptTile::IsDesertTile(TileIndex tile)
00135 {
00136   if (!::IsValidTile(tile)) return false;
00137 
00138   return (::IsTileType(tile, MP_CLEAR) && ::IsClearGround(tile, CLEAR_DESERT));
00139 }
00140 
00141 /* static */ ScriptTile::Slope ScriptTile::GetSlope(TileIndex tile)
00142 {
00143   if (!::IsValidTile(tile)) return SLOPE_INVALID;
00144 
00145   return (Slope)::GetTileSlope(tile);
00146 }
00147 
00148 /* static */ ScriptTile::Slope ScriptTile::GetComplementSlope(Slope slope)
00149 {
00150   if ((slope & ~SLOPE_ELEVATED) != 0) return SLOPE_INVALID;
00151 
00152   return (Slope)::ComplementSlope((::Slope)slope);
00153 }
00154 
00155 /* static */ int32 ScriptTile::GetMinHeight(TileIndex tile)
00156 {
00157   if (!::IsValidTile(tile)) return -1;
00158 
00159   return ::GetTileZ(tile);
00160 }
00161 
00162 /* static */ int32 ScriptTile::GetMaxHeight(TileIndex tile)
00163 {
00164   if (!::IsValidTile(tile)) return -1;
00165 
00166   return ::GetTileMaxZ(tile);
00167 }
00168 
00169 /* static */ int32 ScriptTile::GetCornerHeight(TileIndex tile, Corner corner)
00170 {
00171   if (!::IsValidTile(tile) || !::IsValidCorner((::Corner)corner)) return -1;
00172 
00173   int z;
00174 	::Slope slope = ::GetTileSlope(tile, &z);
00175   return (z + ::GetSlopeZInCorner(slope, (::Corner)corner));
00176 }
00177 
00178 /* static */ ScriptCompany::CompanyID ScriptTile::GetOwner(TileIndex tile)
00179 {
00180   if (!::IsValidTile(tile)) return ScriptCompany::COMPANY_INVALID;
00181   if (::IsTileType(tile, MP_HOUSE)) return ScriptCompany::COMPANY_INVALID;
00182   if (::IsTileType(tile, MP_INDUSTRY)) return ScriptCompany::COMPANY_INVALID;
00183 
00184   return ScriptCompany::ResolveCompanyID((ScriptCompany::CompanyID)(byte)::GetTileOwner(tile));
00185 }
00186 
00187 /* static */ bool ScriptTile::HasTransportType(TileIndex tile, TransportType transport_type)
00188 {
00189   if (!::IsValidTile(tile)) return false;
00190 
00191   return ::TrackStatusToTrackdirBits(::GetTileTrackStatus(tile, (::TransportType)transport_type, UINT32_MAX)) != TRACKDIR_BIT_NONE;
00192 }
00193 
00194 /* static */ int32 ScriptTile::GetCargoAcceptance(TileIndex tile, CargoID cargo_type, int width, int height, int radius)
00195 {
00196   if (!::IsValidTile(tile) || width <= 0 || height <= 0 || radius < 0 || !ScriptCargo::IsValidCargo(cargo_type)) return -1;
00197 
00198   CargoArray acceptance = ::GetAcceptanceAroundTiles(tile, width, height, _settings_game.station.modified_catchment ? radius : (int)CA_UNMODIFIED);
00199   return acceptance[cargo_type];
00200 }
00201 
00202 /* static */ int32 ScriptTile::GetCargoProduction(TileIndex tile, CargoID cargo_type, int width, int height, int radius)
00203 {
00204   if (!::IsValidTile(tile) || width <= 0 || height <= 0 || radius < 0 || !ScriptCargo::IsValidCargo(cargo_type)) return -1;
00205 
00206   CargoArray produced = ::GetProductionAroundTiles(tile, width, height, _settings_game.station.modified_catchment ? radius : (int)CA_UNMODIFIED);
00207   return produced[cargo_type];
00208 }
00209 
00210 /* static */ int32 ScriptTile::GetDistanceManhattanToTile(TileIndex tile_from, TileIndex tile_to)
00211 {
00212   return ScriptMap::DistanceManhattan(tile_from, tile_to);
00213 }
00214 
00215 /* static */ int32 ScriptTile::GetDistanceSquareToTile(TileIndex tile_from, TileIndex tile_to)
00216 {
00217   return ScriptMap::DistanceSquare(tile_from, tile_to);
00218 }
00219 
00220 /* static */ bool ScriptTile::RaiseTile(TileIndex tile, int32 slope)
00221 {
00222   EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
00223   EnforcePrecondition(false, tile < ::MapSize());
00224 
00225   return ScriptObject::DoCommand(tile, slope, 1, CMD_TERRAFORM_LAND);
00226 }
00227 
00228 /* static */ bool ScriptTile::LowerTile(TileIndex tile, int32 slope)
00229 {
00230   EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
00231   EnforcePrecondition(false, tile < ::MapSize());
00232 
00233   return ScriptObject::DoCommand(tile, slope, 0, CMD_TERRAFORM_LAND);
00234 }
00235 
00236 /* static */ bool ScriptTile::LevelTiles(TileIndex start_tile, TileIndex end_tile)
00237 {
00238   EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
00239   EnforcePrecondition(false, start_tile < ::MapSize());
00240   EnforcePrecondition(false, end_tile < ::MapSize());
00241 
00242   return ScriptObject::DoCommand(end_tile, start_tile, LM_LEVEL << 1, CMD_LEVEL_LAND);
00243 }
00244 
00245 /* static */ bool ScriptTile::DemolishTile(TileIndex tile)
00246 {
00247   EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
00248   EnforcePrecondition(false, ::IsValidTile(tile));
00249 
00250   return ScriptObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR);
00251 }
00252 
00253 /* static */ bool ScriptTile::PlantTree(TileIndex tile)
00254 {
00255   EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
00256   EnforcePrecondition(false, ::IsValidTile(tile));
00257 
00258   return ScriptObject::DoCommand(tile, TREE_INVALID, tile, CMD_PLANT_TREE);
00259 }
00260 
00261 /* static */ bool ScriptTile::PlantTreeRectangle(TileIndex tile, uint width, uint height)
00262 {
00263   EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
00264   EnforcePrecondition(false, ::IsValidTile(tile));
00265   EnforcePrecondition(false, width >= 1 && width <= 20);
00266   EnforcePrecondition(false, height >= 1 && height <= 20);
00267   TileIndex end_tile = tile + ::TileDiffXY(width - 1, height - 1);
00268 
00269   return ScriptObject::DoCommand(tile, TREE_INVALID, end_tile, CMD_PLANT_TREE);
00270 }
00271 
00272 /* static */ bool ScriptTile::IsWithinTownInfluence(TileIndex tile, TownID town_id)
00273 {
00274   return ScriptTown::IsWithinTownInfluence(town_id, tile);
00275 }
00276 
00277 /* static */ TownID ScriptTile::GetTownAuthority(TileIndex tile)
00278 {
00279   if (!::IsValidTile(tile)) return INVALID_TOWN;
00280 
00281   Town *town = ::ClosestTownFromTile(tile, _settings_game.economy.dist_local_authority);
00282   if (town == NULL) return INVALID_TOWN;
00283 
00284   return town->index;
00285 }
00286 
00287 /* static */ TownID ScriptTile::GetClosestTown(TileIndex tile)
00288 {
00289   if (!::IsValidTile(tile)) return INVALID_TOWN;
00290 
00291   Town *town = ::ClosestTownFromTile(tile, UINT_MAX);
00292   if (town == NULL) return INVALID_TOWN;
00293 
00294   return town->index;
00295 }
00296 
00297 /* static */ Money ScriptTile::GetBuildCost(BuildType build_type)
00298 {
00299   switch (build_type) {
00300     case BT_FOUNDATION:   return ::GetPrice(PR_BUILD_FOUNDATION, 1, NULL);
00301     case BT_TERRAFORM:    return ::GetPrice(PR_TERRAFORM, 1, NULL);
00302     case BT_BUILD_TREES:  return ::GetPrice(PR_BUILD_TREES, 1, NULL);
00303     case BT_CLEAR_GRASS:  return ::GetPrice(PR_CLEAR_GRASS, 1, NULL);
00304     case BT_CLEAR_ROUGH:  return ::GetPrice(PR_CLEAR_ROUGH, 1, NULL);
00305     case BT_CLEAR_ROCKY:  return ::GetPrice(PR_CLEAR_ROCKS, 1, NULL);
00306     case BT_CLEAR_FIELDS: return ::GetPrice(PR_CLEAR_FIELDS, 1, NULL);
00307     case BT_CLEAR_HOUSE:  return ::GetPrice(PR_CLEAR_HOUSE, 1, NULL);
00308     default: return -1;
00309   }
00310 }