1 /*
2  * This file is part of OpenTTD.
3  * 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.
4  * 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.
5  * 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/>.
6  */
7 
8 /** @file script_airport.cpp Implementation of ScriptAirport. */
9 
10 #include "../../stdafx.h"
11 #include "script_airport.hpp"
12 #include "script_station.hpp"
13 #include "../../station_base.h"
14 #include "../../town.h"
15 
16 #include "../../safeguards.h"
17 
IsValidAirportType(AirportType type)18 /* static */ bool ScriptAirport::IsValidAirportType(AirportType type)
19 {
20 	return IsAirportInformationAvailable(type) && ::AirportSpec::Get(type)->IsAvailable();
21 }
22 
IsAirportInformationAvailable(AirportType type)23 /* static */ bool ScriptAirport::IsAirportInformationAvailable(AirportType type)
24 {
25 	return type >= 0 && type < (AirportType)NUM_AIRPORTS && AirportSpec::Get(type)->enabled;
26 }
27 
GetPrice(AirportType type)28 /* static */ Money ScriptAirport::GetPrice(AirportType type)
29 {
30 	if (!IsValidAirportType(type)) return -1;
31 
32 	const AirportSpec *as = ::AirportSpec::Get(type);
33 	return _price[PR_BUILD_STATION_AIRPORT] * as->size_x * as->size_y;
34 }
35 
IsHangarTile(TileIndex tile)36 /* static */ bool ScriptAirport::IsHangarTile(TileIndex tile)
37 {
38 	if (!::IsValidTile(tile)) return false;
39 
40 	return ::IsTileType(tile, MP_STATION) && ::IsHangar(tile);
41 }
42 
IsAirportTile(TileIndex tile)43 /* static */ bool ScriptAirport::IsAirportTile(TileIndex tile)
44 {
45 	if (!::IsValidTile(tile)) return false;
46 
47 	return ::IsTileType(tile, MP_STATION) && ::IsAirport(tile);
48 }
49 
GetAirportWidth(AirportType type)50 /* static */ int32 ScriptAirport::GetAirportWidth(AirportType type)
51 {
52 	if (!IsAirportInformationAvailable(type)) return -1;
53 
54 	return ::AirportSpec::Get(type)->size_x;
55 }
56 
GetAirportHeight(AirportType type)57 /* static */ int32 ScriptAirport::GetAirportHeight(AirportType type)
58 {
59 	if (!IsAirportInformationAvailable(type)) return -1;
60 
61 	return ::AirportSpec::Get(type)->size_y;
62 }
63 
GetAirportCoverageRadius(AirportType type)64 /* static */ int32 ScriptAirport::GetAirportCoverageRadius(AirportType type)
65 {
66 	if (!IsAirportInformationAvailable(type)) return -1;
67 
68 	return _settings_game.station.modified_catchment ? ::AirportSpec::Get(type)->catchment : (uint)CA_UNMODIFIED;
69 }
70 
BuildAirport(TileIndex tile,AirportType type,StationID station_id)71 /* static */ bool ScriptAirport::BuildAirport(TileIndex tile, AirportType type, StationID station_id)
72 {
73 	EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
74 	EnforcePrecondition(false, ::IsValidTile(tile));
75 	EnforcePrecondition(false, IsValidAirportType(type));
76 	EnforcePrecondition(false, station_id == ScriptStation::STATION_NEW || station_id == ScriptStation::STATION_JOIN_ADJACENT || ScriptStation::IsValidStation(station_id));
77 
78 	uint p2 = station_id == ScriptStation::STATION_JOIN_ADJACENT ? 0 : 1;
79 	p2 |= (ScriptStation::IsValidStation(station_id) ? station_id : INVALID_STATION) << 16;
80 	return ScriptObject::DoCommand(tile, type, p2, CMD_BUILD_AIRPORT);
81 }
82 
RemoveAirport(TileIndex tile)83 /* static */ bool ScriptAirport::RemoveAirport(TileIndex tile)
84 {
85 	EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY);
86 	EnforcePrecondition(false, ::IsValidTile(tile))
87 	EnforcePrecondition(false, IsAirportTile(tile) || IsHangarTile(tile));
88 
89 	return ScriptObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR);
90 }
91 
GetNumHangars(TileIndex tile)92 /* static */ int32 ScriptAirport::GetNumHangars(TileIndex tile)
93 {
94 	if (!::IsValidTile(tile)) return -1;
95 	if (!::IsTileType(tile, MP_STATION)) return -1;
96 
97 	const Station *st = ::Station::GetByTile(tile);
98 	if (st->owner != ScriptObject::GetCompany() && ScriptObject::GetCompany() != OWNER_DEITY) return -1;
99 	if ((st->facilities & FACIL_AIRPORT) == 0) return -1;
100 
101 	return st->airport.GetNumHangars();
102 }
103 
GetHangarOfAirport(TileIndex tile)104 /* static */ TileIndex ScriptAirport::GetHangarOfAirport(TileIndex tile)
105 {
106 	if (!::IsValidTile(tile)) return INVALID_TILE;
107 	if (!::IsTileType(tile, MP_STATION)) return INVALID_TILE;
108 	if (GetNumHangars(tile) < 1) return INVALID_TILE;
109 
110 	const Station *st = ::Station::GetByTile(tile);
111 	if (st->owner != ScriptObject::GetCompany() && ScriptObject::GetCompany() != OWNER_DEITY) return INVALID_TILE;
112 	if ((st->facilities & FACIL_AIRPORT) == 0) return INVALID_TILE;
113 
114 	return st->airport.GetHangarTile(0);
115 }
116 
GetAirportType(TileIndex tile)117 /* static */ ScriptAirport::AirportType ScriptAirport::GetAirportType(TileIndex tile)
118 {
119 	if (!ScriptTile::IsStationTile(tile)) return AT_INVALID;
120 
121 	StationID station_id = ::GetStationIndex(tile);
122 
123 	if (!ScriptStation::HasStationType(station_id, ScriptStation::STATION_AIRPORT)) return AT_INVALID;
124 
125 	return (AirportType)::Station::Get(station_id)->airport.type;
126 }
127 
128 
GetNoiseLevelIncrease(TileIndex tile,AirportType type)129 /* static */ int ScriptAirport::GetNoiseLevelIncrease(TileIndex tile, AirportType type)
130 {
131 	extern Town *AirportGetNearestTown(const AirportSpec *as, const TileIterator &it, uint &mindist);
132 	extern uint8 GetAirportNoiseLevelForDistance(const AirportSpec *as, uint distance);
133 
134 	if (!::IsValidTile(tile)) return -1;
135 	if (!IsAirportInformationAvailable(type)) return -1;
136 
137 	const AirportSpec *as = ::AirportSpec::Get(type);
138 	if (!as->IsWithinMapBounds(0, tile)) return -1;
139 
140 	if (_settings_game.economy.station_noise_level) {
141 		AirportTileTableIterator it(as->table[0], tile);
142 		uint dist;
143 		AirportGetNearestTown(as, it, dist);
144 		return GetAirportNoiseLevelForDistance(as, dist);
145 	}
146 
147 	return 1;
148 }
149 
GetNearestTown(TileIndex tile,AirportType type)150 /* static */ TownID ScriptAirport::GetNearestTown(TileIndex tile, AirportType type)
151 {
152 	extern Town *AirportGetNearestTown(const AirportSpec *as, const TileIterator &it, uint &mindist);
153 
154 	if (!::IsValidTile(tile)) return INVALID_TOWN;
155 	if (!IsAirportInformationAvailable(type)) return INVALID_TOWN;
156 
157 	const AirportSpec *as = AirportSpec::Get(type);
158 	if (!as->IsWithinMapBounds(0, tile)) return INVALID_TOWN;
159 
160 	uint dist;
161 	return AirportGetNearestTown(as, AirportTileTableIterator(as->table[0], tile), dist)->index;
162 }
163 
GetMaintenanceCostFactor(AirportType type)164 /* static */ uint16 ScriptAirport::GetMaintenanceCostFactor(AirportType type)
165 {
166 	if (!IsAirportInformationAvailable(type)) return INVALID_TOWN;
167 
168 	return AirportSpec::Get(type)->maintenance_cost;
169 }
170 
GetMonthlyMaintenanceCost(AirportType type)171 /* static */ Money ScriptAirport::GetMonthlyMaintenanceCost(AirportType type)
172 {
173 	if (!IsAirportInformationAvailable(type)) return -1;
174 
175 	return (int64)GetMaintenanceCostFactor(type) * _price[PR_INFRASTRUCTURE_AIRPORT] >> 3;
176 }
177