Fix some daylength issues, possible division by zero in main menu.
[openttd-joker.git] / src / script / api / script_tile.cpp
blobfee89f0d4daa162a4246e6ba297f979543881746
1 /* $Id: script_tile.cpp 25815 2013-10-06 11:16:00Z frosch $ */
3 /*
4 * This file is part of OpenTTD.
5 * 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.
6 * 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.
7 * 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/>.
8 */
10 /** @file script_tile.cpp Implementation of ScriptTile. */
12 #include "../../stdafx.h"
13 #include "script_tile.hpp"
14 #include "script_map.hpp"
15 #include "script_town.hpp"
16 #include "../../station_func.h"
17 #include "../../water_map.h"
18 #include "../../clear_map.h"
19 #include "../../tree_map.h"
20 #include "../../town.h"
21 #include "../../landscape.h"
23 #include "../../safeguards.h"
25 /* static */ bool ScriptTile::IsBuildable(TileIndex tile)
27 if (!::IsValidTile(tile)) return false;
29 switch (::GetTileType(tile)) {
30 default: return false;
31 case MP_CLEAR: return true;
32 case MP_TREES: return true;
33 case MP_WATER: return IsCoast(tile);
34 case MP_ROAD:
35 /* Tram bits aren't considered buildable */
36 if (::GetRoadTypes(tile) != ROADTYPES_ROAD) return false;
37 /* Depots and crossings aren't considered buildable */
38 if (::GetRoadTileType(tile) != ROAD_TILE_NORMAL) return false;
39 if (!HasExactlyOneBit(::GetRoadBits(tile, ROADTYPE_ROAD))) return false;
40 if (::IsRoadOwner(tile, ROADTYPE_ROAD, OWNER_TOWN)) return true;
41 if (::IsRoadOwner(tile, ROADTYPE_ROAD, ScriptObject::GetCompany())) return true;
42 return false;
46 /* static */ bool ScriptTile::IsBuildableRectangle(TileIndex tile, uint width, uint height)
48 /* Check whether we can extract valid X and Y */
49 if (!::IsValidTile(tile)) return false;
51 uint tx = ScriptMap::GetTileX(tile);
52 uint ty = ScriptMap::GetTileY(tile);
54 for (uint x = tx; x < width + tx; x++) {
55 for (uint y = ty; y < height + ty; y++) {
56 if (!IsBuildable(ScriptMap::GetTileIndex(x, y))) return false;
60 return true;
63 /* static */ bool ScriptTile::IsWaterTile(TileIndex tile)
65 if (!::IsValidTile(tile)) return false;
67 return ::IsTileType(tile, MP_WATER) && !::IsCoast(tile);
70 /* static */ bool ScriptTile::IsCoastTile(TileIndex tile)
72 if (!::IsValidTile(tile)) return false;
74 return (::IsTileType(tile, MP_WATER) && ::IsCoast(tile)) ||
75 (::IsTileType(tile, MP_TREES) && ::GetTreeGround(tile) == TREE_GROUND_SHORE);
78 /* static */ bool ScriptTile::IsStationTile(TileIndex tile)
80 if (!::IsValidTile(tile)) return false;
82 return ::IsTileType(tile, MP_STATION);
85 /* static */ bool ScriptTile::IsSteepSlope(Slope slope)
87 if ((slope & ~(SLOPE_ELEVATED | SLOPE_STEEP | SLOPE_HALFTILE_MASK)) != 0) return false;
89 return ::IsSteepSlope((::Slope)slope);
92 /* static */ bool ScriptTile::IsHalftileSlope(Slope slope)
94 if ((slope & ~(SLOPE_ELEVATED | SLOPE_STEEP | SLOPE_HALFTILE_MASK)) != 0) return false;
96 return ::IsHalftileSlope((::Slope)slope);
99 /* static */ bool ScriptTile::HasTreeOnTile(TileIndex tile)
101 if (!::IsValidTile(tile)) return false;
103 return ::IsTileType(tile, MP_TREES);
106 /* static */ bool ScriptTile::IsFarmTile(TileIndex tile)
108 if (!::IsValidTile(tile)) return false;
110 return (::IsTileType(tile, MP_CLEAR) && ::IsClearGround(tile, CLEAR_FIELDS));
113 /* static */ bool ScriptTile::IsRockTile(TileIndex tile)
115 if (!::IsValidTile(tile)) return false;
117 return (::IsTileType(tile, MP_CLEAR) && ::GetRawClearGround(tile) == ::CLEAR_ROCKS);
120 /* static */ bool ScriptTile::IsRoughTile(TileIndex tile)
122 if (!::IsValidTile(tile)) return false;
124 return (::IsTileType(tile, MP_CLEAR) && ::GetRawClearGround(tile) == ::CLEAR_ROUGH);
127 /* static */ bool ScriptTile::IsSnowTile(TileIndex tile)
129 if (!::IsValidTile(tile)) return false;
131 return (::IsTileType(tile, MP_CLEAR) && ::IsSnowTile(tile));
134 /* static */ bool ScriptTile::IsDesertTile(TileIndex tile)
136 if (!::IsValidTile(tile)) return false;
138 return (::IsTileType(tile, MP_CLEAR) && ::IsClearGround(tile, CLEAR_DESERT));
141 /* static */ ScriptTile::TerrainType ScriptTile::GetTerrainType(TileIndex tile)
143 if (!::IsValidTile(tile)) return TERRAIN_NORMAL;
145 switch (::GetTerrainType(tile)) {
146 default:
147 case 0: return TERRAIN_NORMAL;
148 case 1: return TERRAIN_DESERT;
149 case 2: return TERRAIN_RAINFOREST;
150 case 4: return TERRAIN_SNOW;
154 /* static */ ScriptTile::Slope ScriptTile::GetSlope(TileIndex tile)
156 if (!::IsValidTile(tile)) return SLOPE_INVALID;
158 return (Slope)::GetTileSlope(tile);
161 /* static */ ScriptTile::Slope ScriptTile::GetComplementSlope(Slope slope)
163 if ((slope & ~SLOPE_ELEVATED) != 0) return SLOPE_INVALID;
165 return (Slope)::ComplementSlope((::Slope)slope);
168 /* static */ int32 ScriptTile::GetMinHeight(TileIndex tile)
170 if (!::IsValidTile(tile)) return -1;
172 return ::GetTileZ(tile);
175 /* static */ int32 ScriptTile::GetMaxHeight(TileIndex tile)
177 if (!::IsValidTile(tile)) return -1;
179 return ::GetTileMaxZ(tile);
182 /* static */ int32 ScriptTile::GetCornerHeight(TileIndex tile, Corner corner)
184 if (!::IsValidTile(tile) || !::IsValidCorner((::Corner)corner)) return -1;
186 int z;
187 ::Slope slope = ::GetTileSlope(tile, &z);
188 return (z + ::GetSlopeZInCorner(slope, (::Corner)corner));
191 /* static */ ScriptCompany::CompanyID ScriptTile::GetOwner(TileIndex tile)
193 if (!::IsValidTile(tile)) return ScriptCompany::COMPANY_INVALID;
194 if (::IsTileType(tile, MP_HOUSE)) return ScriptCompany::COMPANY_INVALID;
195 if (::IsTileType(tile, MP_INDUSTRY)) return ScriptCompany::COMPANY_INVALID;
197 return ScriptCompany::ResolveCompanyID((ScriptCompany::CompanyID)(byte)::GetTileOwner(tile));
200 /* static */ bool ScriptTile::HasTransportType(TileIndex tile, TransportType transport_type)
202 if (!::IsValidTile(tile)) return false;
204 return ::TrackStatusToTrackdirBits(::GetTileTrackStatus(tile, (::TransportType)transport_type, UINT32_MAX)) != TRACKDIR_BIT_NONE;
207 /* static */ int32 ScriptTile::GetCargoAcceptance(TileIndex tile, CargoID cargo_type, int width, int height, int radius)
209 if (!::IsValidTile(tile) || width <= 0 || height <= 0 || radius < 0 || !ScriptCargo::IsValidCargo(cargo_type)) return -1;
211 CargoArray acceptance = ::GetAcceptanceAroundTiles(tile, width, height, _settings_game.station.modified_catchment ? radius : (int)CA_UNMODIFIED);
212 return acceptance[cargo_type];
215 /* static */ int32 ScriptTile::GetCargoProduction(TileIndex tile, CargoID cargo_type, int width, int height, int radius)
217 if (!::IsValidTile(tile) || width <= 0 || height <= 0 || radius < 0 || !ScriptCargo::IsValidCargo(cargo_type)) return -1;
219 CargoArray produced = ::GetProductionAroundTiles(tile, width, height, _settings_game.station.modified_catchment ? radius : (int)CA_UNMODIFIED);
220 return produced[cargo_type];
223 /* static */ int32 ScriptTile::GetDistanceManhattanToTile(TileIndex tile_from, TileIndex tile_to)
225 return ScriptMap::DistanceManhattan(tile_from, tile_to);
228 /* static */ int32 ScriptTile::GetDistanceSquareToTile(TileIndex tile_from, TileIndex tile_to)
230 return ScriptMap::DistanceSquare(tile_from, tile_to);
233 /* static */ bool ScriptTile::RaiseTile(TileIndex tile, int32 slope)
235 EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
236 EnforcePrecondition(false, tile < ::MapSize());
238 return ScriptObject::DoCommand(tile, slope, 1, CMD_TERRAFORM_LAND);
241 /* static */ bool ScriptTile::LowerTile(TileIndex tile, int32 slope)
243 EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
244 EnforcePrecondition(false, tile < ::MapSize());
246 return ScriptObject::DoCommand(tile, slope, 0, CMD_TERRAFORM_LAND);
249 /* static */ bool ScriptTile::LevelTiles(TileIndex start_tile, TileIndex end_tile)
251 EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
252 EnforcePrecondition(false, start_tile < ::MapSize());
253 EnforcePrecondition(false, end_tile < ::MapSize());
255 return ScriptObject::DoCommand(end_tile, start_tile, LM_LEVEL << 1, CMD_LEVEL_LAND);
258 /* static */ bool ScriptTile::DemolishTile(TileIndex tile)
260 EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
261 EnforcePrecondition(false, ::IsValidTile(tile));
263 return ScriptObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR);
266 /* static */ bool ScriptTile::PlantTree(TileIndex tile)
268 EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
269 EnforcePrecondition(false, ::IsValidTile(tile));
271 return ScriptObject::DoCommand(tile, TREE_INVALID, tile, CMD_PLANT_TREE);
274 /* static */ bool ScriptTile::PlantTreeRectangle(TileIndex tile, uint width, uint height)
276 EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
277 EnforcePrecondition(false, ::IsValidTile(tile));
278 EnforcePrecondition(false, width >= 1 && width <= 20);
279 EnforcePrecondition(false, height >= 1 && height <= 20);
280 TileIndex end_tile = tile + ::TileDiffXY(width - 1, height - 1);
282 return ScriptObject::DoCommand(tile, TREE_INVALID, end_tile, CMD_PLANT_TREE);
285 /* static */ bool ScriptTile::IsWithinTownInfluence(TileIndex tile, TownID town_id)
287 return ScriptTown::IsWithinTownInfluence(town_id, tile);
290 /* static */ TownID ScriptTile::GetTownAuthority(TileIndex tile)
292 if (!::IsValidTile(tile)) return INVALID_TOWN;
294 Town *town = ::ClosestTownFromTile(tile, _settings_game.economy.dist_local_authority);
295 if (town == NULL) return INVALID_TOWN;
297 return town->index;
300 /* static */ TownID ScriptTile::GetClosestTown(TileIndex tile)
302 if (!::IsValidTile(tile)) return INVALID_TOWN;
304 Town *town = ::ClosestTownFromTile(tile, UINT_MAX);
305 if (town == NULL) return INVALID_TOWN;
307 return town->index;
310 /* static */ Money ScriptTile::GetBuildCost(BuildType build_type)
312 switch (build_type) {
313 case BT_FOUNDATION: return ::GetPrice(PR_BUILD_FOUNDATION, 1, NULL);
314 case BT_TERRAFORM: return ::GetPrice(PR_TERRAFORM, 1, NULL);
315 case BT_BUILD_TREES: return ::GetPrice(PR_BUILD_TREES, 1, NULL);
316 case BT_CLEAR_GRASS: return ::GetPrice(PR_CLEAR_GRASS, 1, NULL);
317 case BT_CLEAR_ROUGH: return ::GetPrice(PR_CLEAR_ROUGH, 1, NULL);
318 case BT_CLEAR_ROCKY: return ::GetPrice(PR_CLEAR_ROCKS, 1, NULL);
319 case BT_CLEAR_FIELDS: return ::GetPrice(PR_CLEAR_FIELDS, 1, NULL);
320 case BT_CLEAR_HOUSE: return ::GetPrice(PR_CLEAR_HOUSE, 1, NULL);
321 default: return -1;