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/>.
10 /** @file airport.cpp Functions related to airports. */
13 #include "station_base.h"
14 #include "table/strings.h"
15 #include "table/airport_movement.h"
16 #include "table/airporttile_ids.h"
18 #include "safeguards.h"
22 * Define a generic airport.
23 * @param name Suffix of the names of the airport data.
24 * @param terminals The terminals.
25 * @param num_helipads Number of heli pads.
26 * @param flags Information about the class of FTA.
27 * @param delta_z Height of the airport above the land.
29 #define AIRPORT_GENERIC(name, terminals, num_helipads, flags, delta_z) \
30 static const AirportFTAClass _airportfta_ ## name(_airport_moving_data_ ## name, terminals, \
31 num_helipads, _airport_entries_ ## name, flags, _airport_fta_ ## name, delta_z);
35 * @param name Suffix of the names of the airport data.
36 * @param num_helipads Number of heli pads.
37 * @param short_strip Airport has a short land/take-off strip.
39 #define AIRPORT(name, num_helipads, short_strip) \
40 AIRPORT_GENERIC(name, _airport_terminal_ ## name, num_helipads, AirportFTAClass::ALL | (short_strip ? AirportFTAClass::SHORT_STRIP : (AirportFTAClass::Flags)0), 0)
44 * @param name Suffix of the names of the helipad data.
45 * @param num_helipads Number of heli pads.
46 * @param delta_z Height of the airport above the land.
48 #define HELIPORT(name, num_helipads, delta_z) \
49 AIRPORT_GENERIC(name, nullptr, num_helipads, AirportFTAClass::HELICOPTERS, delta_z)
51 AIRPORT(country
, 0, true)
52 AIRPORT(city
, 0, false)
53 HELIPORT(heliport
, 1, 60)
54 AIRPORT(metropolitan
, 0, false)
55 AIRPORT(international
, 2, false)
56 AIRPORT(commuter
, 2, true)
57 HELIPORT(helidepot
, 1, 0)
58 AIRPORT(intercontinental
, 2, false)
59 HELIPORT(helistation
, 3, 0)
60 HELIPORT(oilrig
, 1, 54)
61 AIRPORT_GENERIC(dummy
, nullptr, 0, AirportFTAClass::ALL
, 0)
65 #undef AIRPORT_GENERIC
67 #include "table/airport_defaults.h"
70 static uint16
AirportGetNofElements(const AirportFTAbuildup
*apFA
);
71 static AirportFTA
*AirportBuildAutomata(uint nofelements
, const AirportFTAbuildup
*apFA
);
75 * Rotate the airport moving data to another rotation.
76 * @param orig Pointer to the moving data to rotate.
77 * @param rotation How to rotate the moving data.
78 * @param num_tiles_x Number of tiles in x direction.
79 * @param num_tiles_y Number of tiles in y direction.
80 * @return The rotated moving data.
82 AirportMovingData
RotateAirportMovingData(const AirportMovingData
*orig
, Direction rotation
, uint num_tiles_x
, uint num_tiles_y
)
84 AirportMovingData amd
;
85 amd
.flag
= orig
->flag
;
86 amd
.direction
= ChangeDir(orig
->direction
, (DirDiff
)rotation
);
95 amd
.y
= num_tiles_y
* TILE_SIZE
- orig
->x
- 1;
99 amd
.x
= num_tiles_x
* TILE_SIZE
- orig
->x
- 1;
100 amd
.y
= num_tiles_y
* TILE_SIZE
- orig
->y
- 1;
104 amd
.x
= num_tiles_x
* TILE_SIZE
- orig
->y
- 1;
108 default: NOT_REACHED();
113 AirportFTAClass::AirportFTAClass(
114 const AirportMovingData
*moving_data_
,
115 const byte
*terminals_
,
116 const byte num_helipads_
,
117 const byte
*entry_points_
,
119 const AirportFTAbuildup
*apFA
,
122 moving_data(moving_data_
),
123 terminals(terminals_
),
124 num_helipads(num_helipads_
),
126 nofelements(AirportGetNofElements(apFA
)),
127 entry_points(entry_points_
),
130 /* Build the state machine itself */
131 this->layout
= AirportBuildAutomata(this->nofelements
, apFA
);
134 AirportFTAClass::~AirportFTAClass()
136 for (uint i
= 0; i
< nofelements
; i
++) {
137 AirportFTA
*current
= layout
[i
].next
;
138 while (current
!= nullptr) {
139 AirportFTA
*next
= current
->next
;
148 * Get the number of elements of a source Airport state automata
149 * Since it is actually just a big array of AirportFTA types, we only
150 * know one element from the other by differing 'position' identifiers
152 static uint16
AirportGetNofElements(const AirportFTAbuildup
*apFA
)
154 uint16 nofelements
= 0;
155 int temp
= apFA
[0].position
;
157 for (uint i
= 0; i
< MAX_ELEMENTS
; i
++) {
158 if (temp
!= apFA
[i
].position
) {
160 temp
= apFA
[i
].position
;
162 if (apFA
[i
].position
== MAX_ELEMENTS
) break;
168 * Construct the FTA given a description.
169 * @param nofelements The number of elements in the FTA.
170 * @param apFA The description of the FTA.
171 * @return The FTA describing the airport.
173 static AirportFTA
*AirportBuildAutomata(uint nofelements
, const AirportFTAbuildup
*apFA
)
175 AirportFTA
*FAutomata
= MallocT
<AirportFTA
>(nofelements
);
176 uint16 internalcounter
= 0;
178 for (uint i
= 0; i
< nofelements
; i
++) {
179 AirportFTA
*current
= &FAutomata
[i
];
180 current
->position
= apFA
[internalcounter
].position
;
181 current
->heading
= apFA
[internalcounter
].heading
;
182 current
->block
= apFA
[internalcounter
].block
;
183 current
->next_position
= apFA
[internalcounter
].next
;
185 /* outgoing nodes from the same position, create linked list */
186 while (current
->position
== apFA
[internalcounter
+ 1].position
) {
187 AirportFTA
*newNode
= MallocT
<AirportFTA
>(1);
189 newNode
->position
= apFA
[internalcounter
+ 1].position
;
190 newNode
->heading
= apFA
[internalcounter
+ 1].heading
;
191 newNode
->block
= apFA
[internalcounter
+ 1].block
;
192 newNode
->next_position
= apFA
[internalcounter
+ 1].next
;
194 current
->next
= newNode
;
195 current
= current
->next
;
198 current
->next
= nullptr;
205 * Get the finite state machine of an airport type.
206 * @param airport_type %Airport type to query FTA from. @see AirportTypes
207 * @return Finite state machine of the airport.
209 const AirportFTAClass
*GetAirport(const byte airport_type
)
211 if (airport_type
== AT_DUMMY
) return &_airportfta_dummy
;
212 return AirportSpec::Get(airport_type
)->fsm
;
216 * Get the vehicle position when an aircraft is build at the given tile
217 * @param hangar_tile The tile on which the vehicle is build
218 * @return The position (index in airport node array) where the aircraft ends up
220 byte
GetVehiclePosOnBuild(TileIndex hangar_tile
)
222 const Station
*st
= Station::GetByTile(hangar_tile
);
223 const AirportFTAClass
*apc
= st
->airport
.GetFTA();
224 /* When we click on hangar we know the tile it is on. By that we know
225 * its position in the array of depots the airport has.....we can search
226 * layout for #th position of depot. Since layout must start with a listing
227 * of all depots, it is simple */
228 for (uint i
= 0;; i
++) {
229 if (st
->airport
.GetHangarTile(i
) == hangar_tile
) {
230 assert(apc
->layout
[i
].heading
== HANGAR
);
231 return apc
->layout
[i
].position
;