00001
00002
00003
00004
00005
00006
00007
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 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
00037 if (::GetRoadTypes(tile) != ROADTYPES_ROAD) return false;
00038
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, _current_company)) return true;
00043 return false;
00044 }
00045 }
00046
00047 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 bool ScriptTile::IsWaterTile(TileIndex tile)
00064 {
00065 if (!::IsValidTile(tile)) return false;
00066
00067 return ::IsTileType(tile, MP_WATER) && !::IsCoast(tile);
00068 }
00069
00070 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 bool ScriptTile::IsStationTile(TileIndex tile)
00079 {
00080 if (!::IsValidTile(tile)) return false;
00081
00082 return ::IsTileType(tile, MP_STATION);
00083 }
00084
00085 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 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 bool ScriptTile::HasTreeOnTile(TileIndex tile)
00100 {
00101 if (!::IsValidTile(tile)) return false;
00102
00103 return ::IsTileType(tile, MP_TREES);
00104 }
00105
00106 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 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 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 bool ScriptTile::IsSnowTile(TileIndex tile)
00128 {
00129 if (!::IsValidTile(tile)) return false;
00130
00131 return (::IsTileType(tile, MP_CLEAR) && ::IsSnowTile(tile));
00132 }
00133
00134 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 ScriptTile::Slope ScriptTile::GetSlope(TileIndex tile)
00142 {
00143 if (!::IsValidTile(tile)) return SLOPE_INVALID;
00144
00145 return (Slope)::GetTileSlope(tile);
00146 }
00147
00148 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 int32 ScriptTile::GetMinHeight(TileIndex tile)
00156 {
00157 if (!::IsValidTile(tile)) return -1;
00158
00159 return ::GetTileZ(tile);
00160 }
00161
00162 int32 ScriptTile::GetMaxHeight(TileIndex tile)
00163 {
00164 if (!::IsValidTile(tile)) return -1;
00165
00166 return ::GetTileMaxZ(tile);
00167 }
00168
00169 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 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 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 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 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 int32 ScriptTile::GetDistanceManhattanToTile(TileIndex tile_from, TileIndex tile_to)
00211 {
00212 return ScriptMap::DistanceManhattan(tile_from, tile_to);
00213 }
00214
00215 int32 ScriptTile::GetDistanceSquareToTile(TileIndex tile_from, TileIndex tile_to)
00216 {
00217 return ScriptMap::DistanceSquare(tile_from, tile_to);
00218 }
00219
00220 bool ScriptTile::RaiseTile(TileIndex tile, int32 slope)
00221 {
00222 EnforcePrecondition(false, tile < ::MapSize());
00223
00224 return ScriptObject::DoCommand(tile, slope, 1, CMD_TERRAFORM_LAND);
00225 }
00226
00227 bool ScriptTile::LowerTile(TileIndex tile, int32 slope)
00228 {
00229 EnforcePrecondition(false, tile < ::MapSize());
00230
00231 return ScriptObject::DoCommand(tile, slope, 0, CMD_TERRAFORM_LAND);
00232 }
00233
00234 bool ScriptTile::LevelTiles(TileIndex start_tile, TileIndex end_tile)
00235 {
00236 EnforcePrecondition(false, start_tile < ::MapSize());
00237 EnforcePrecondition(false, end_tile < ::MapSize());
00238
00239 return ScriptObject::DoCommand(end_tile, start_tile, LM_LEVEL << 1, CMD_LEVEL_LAND);
00240 }
00241
00242 bool ScriptTile::DemolishTile(TileIndex tile)
00243 {
00244 EnforcePrecondition(false, ::IsValidTile(tile));
00245
00246 return ScriptObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR);
00247 }
00248
00249 bool ScriptTile::PlantTree(TileIndex tile)
00250 {
00251 EnforcePrecondition(false, ::IsValidTile(tile));
00252
00253 return ScriptObject::DoCommand(tile, TREE_INVALID, tile, CMD_PLANT_TREE);
00254 }
00255
00256 bool ScriptTile::PlantTreeRectangle(TileIndex tile, uint width, uint height)
00257 {
00258 EnforcePrecondition(false, ::IsValidTile(tile));
00259 EnforcePrecondition(false, width >= 1 && width <= 20);
00260 EnforcePrecondition(false, height >= 1 && height <= 20);
00261 TileIndex end_tile = tile + ::TileDiffXY(width - 1, height - 1);
00262
00263 return ScriptObject::DoCommand(tile, TREE_INVALID, end_tile, CMD_PLANT_TREE);
00264 }
00265
00266 bool ScriptTile::IsWithinTownInfluence(TileIndex tile, TownID town_id)
00267 {
00268 return ScriptTown::IsWithinTownInfluence(town_id, tile);
00269 }
00270
00271 TownID ScriptTile::GetTownAuthority(TileIndex tile)
00272 {
00273 if (!::IsValidTile(tile)) return INVALID_TOWN;
00274
00275 Town *town = ::ClosestTownFromTile(tile, _settings_game.economy.dist_local_authority);
00276 if (town == NULL) return INVALID_TOWN;
00277
00278 return town->index;
00279 }
00280
00281 TownID ScriptTile::GetClosestTown(TileIndex tile)
00282 {
00283 if (!::IsValidTile(tile)) return INVALID_TOWN;
00284
00285 Town *town = ::ClosestTownFromTile(tile, UINT_MAX);
00286 if (town == NULL) return INVALID_TOWN;
00287
00288 return town->index;
00289 }
00290
00291 Money ScriptTile::GetBuildCost(BuildType build_type)
00292 {
00293 switch (build_type) {
00294 case BT_FOUNDATION: return ::GetPrice(PR_BUILD_FOUNDATION, 1, NULL);
00295 case BT_TERRAFORM: return ::GetPrice(PR_TERRAFORM, 1, NULL);
00296 case BT_BUILD_TREES: return ::GetPrice(PR_BUILD_TREES, 1, NULL);
00297 case BT_CLEAR_GRASS: return ::GetPrice(PR_CLEAR_GRASS, 1, NULL);
00298 case BT_CLEAR_ROUGH: return ::GetPrice(PR_CLEAR_ROUGH, 1, NULL);
00299 case BT_CLEAR_ROCKY: return ::GetPrice(PR_CLEAR_ROCKS, 1, NULL);
00300 case BT_CLEAR_FIELDS: return ::GetPrice(PR_CLEAR_FIELDS, 1, NULL);
00301 case BT_CLEAR_HOUSE: return ::GetPrice(PR_CLEAR_HOUSE, 1, NULL);
00302 default: return -1;
00303 }
00304 }