OpenTTD Source 20241224-master-gf74b0cf984
airport.cpp
Go to the documentation of this file.
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
10#include "stdafx.h"
11#include "station_base.h"
12#include "table/strings.h"
15
16#include "safeguards.h"
17
18
27#define AIRPORT_GENERIC(name, terminals, num_helipads, flags, delta_z) \
28 static const AirportFTAClass _airportfta_ ## name(_airport_moving_data_ ## name, terminals, \
29 num_helipads, _airport_entries_ ## name, flags, _airport_fta_ ## name, delta_z);
30
37#define AIRPORT(name, num_helipads, short_strip) \
38 AIRPORT_GENERIC(name, _airport_terminal_ ## name, num_helipads, AirportFTAClass::ALL | (short_strip ? AirportFTAClass::SHORT_STRIP : (AirportFTAClass::Flags)0), 0)
39
46#define HELIPORT(name, num_helipads, delta_z) \
47 AIRPORT_GENERIC(name, nullptr, num_helipads, AirportFTAClass::HELICOPTERS, delta_z)
48
49AIRPORT(country, 0, true)
50AIRPORT(city, 0, false)
51HELIPORT(heliport, 1, 60)
52AIRPORT(metropolitan, 0, false)
53AIRPORT(international, 2, false)
54AIRPORT(commuter, 2, true)
55HELIPORT(helidepot, 1, 0)
56AIRPORT(intercontinental, 2, false)
57HELIPORT(helistation, 3, 0)
58HELIPORT(oilrig, 1, 54)
59AIRPORT_GENERIC(dummy, nullptr, 0, AirportFTAClass::ALL, 0)
60
61#undef HELIPORT
62#undef AIRPORT
63#undef AIRPORT_GENERIC
64
66
67
68static uint16_t AirportGetNofElements(const AirportFTAbuildup *apFA);
69static AirportFTA *AirportBuildAutomata(uint nofelements, const AirportFTAbuildup *apFA);
70
71
80AirportMovingData RotateAirportMovingData(const AirportMovingData *orig, Direction rotation, uint num_tiles_x, uint num_tiles_y)
81{
83 amd.flag = orig->flag;
84 amd.direction = ChangeDir(orig->direction, (DirDiff)rotation);
85 switch (rotation) {
86 case DIR_N:
87 amd.x = orig->x;
88 amd.y = orig->y;
89 break;
90
91 case DIR_E:
92 amd.x = orig->y;
93 amd.y = num_tiles_y * TILE_SIZE - orig->x - 1;
94 break;
95
96 case DIR_S:
97 amd.x = num_tiles_x * TILE_SIZE - orig->x - 1;
98 amd.y = num_tiles_y * TILE_SIZE - orig->y - 1;
99 break;
100
101 case DIR_W:
102 amd.x = num_tiles_x * TILE_SIZE - orig->y - 1;
103 amd.y = orig->x;
104 break;
105
106 default: NOT_REACHED();
107 }
108 return amd;
109}
110
111AirportFTAClass::AirportFTAClass(
112 const AirportMovingData *moving_data_,
113 const uint8_t *terminals_,
114 const uint8_t num_helipads_,
115 const uint8_t *entry_points_,
116 Flags flags_,
117 const AirportFTAbuildup *apFA,
118 uint8_t delta_z_
119) :
120 moving_data(moving_data_),
121 terminals(terminals_),
122 num_helipads(num_helipads_),
123 flags(flags_),
124 nofelements(AirportGetNofElements(apFA)),
125 entry_points(entry_points_),
126 delta_z(delta_z_)
127{
128 /* Build the state machine itself */
129 this->layout = AirportBuildAutomata(this->nofelements, apFA);
130}
131
132AirportFTAClass::~AirportFTAClass()
133{
134 for (uint i = 0; i < nofelements; i++) {
135 AirportFTA *current = layout[i].next;
136 while (current != nullptr) {
137 AirportFTA *next = current->next;
138 free(current);
139 current = next;
140 }
141 }
142 free(layout);
143}
144
150static uint16_t AirportGetNofElements(const AirportFTAbuildup *apFA)
151{
152 uint16_t nofelements = 0;
153 int temp = apFA[0].position;
154
155 for (uint i = 0; i < MAX_ELEMENTS; i++) {
156 if (temp != apFA[i].position) {
157 nofelements++;
158 temp = apFA[i].position;
159 }
160 if (apFA[i].position == MAX_ELEMENTS) break;
161 }
162 return nofelements;
163}
164
171static AirportFTA *AirportBuildAutomata(uint nofelements, const AirportFTAbuildup *apFA)
172{
173 AirportFTA *FAutomata = MallocT<AirportFTA>(nofelements);
174 uint16_t internalcounter = 0;
175
176 for (uint i = 0; i < nofelements; i++) {
177 AirportFTA *current = &FAutomata[i];
178 current->position = apFA[internalcounter].position;
179 current->heading = apFA[internalcounter].heading;
180 current->block = apFA[internalcounter].block;
181 current->next_position = apFA[internalcounter].next;
182
183 /* outgoing nodes from the same position, create linked list */
184 while (current->position == apFA[internalcounter + 1].position) {
185 AirportFTA *newNode = MallocT<AirportFTA>(1);
186
187 newNode->position = apFA[internalcounter + 1].position;
188 newNode->heading = apFA[internalcounter + 1].heading;
189 newNode->block = apFA[internalcounter + 1].block;
190 newNode->next_position = apFA[internalcounter + 1].next;
191 /* create link */
192 current->next = newNode;
193 current = current->next;
194 internalcounter++;
195 }
196 current->next = nullptr;
197 internalcounter++;
198 }
199 return FAutomata;
200}
201
207const AirportFTAClass *GetAirport(const uint8_t airport_type)
208{
209 if (airport_type == AT_DUMMY) return &_airportfta_dummy;
210 return AirportSpec::Get(airport_type)->fsm;
211}
212
218uint8_t GetVehiclePosOnBuild(TileIndex hangar_tile)
219{
220 const Station *st = Station::GetByTile(hangar_tile);
221 const AirportFTAClass *apc = st->airport.GetFTA();
222 /* When we click on hangar we know the tile it is on. By that we know
223 * its position in the array of depots the airport has.....we can search
224 * layout for #th position of depot. Since layout must start with a listing
225 * of all depots, it is simple */
226 for (uint i = 0;; i++) {
227 if (st->airport.GetHangarTile(i) == hangar_tile) {
228 assert(apc->layout[i].heading == HANGAR);
229 return apc->layout[i].position;
230 }
231 }
232 NOT_REACHED();
233}
#define AIRPORT(name, num_helipads, short_strip)
Define an airport.
Definition airport.cpp:37
#define AIRPORT_GENERIC(name, terminals, num_helipads, flags, delta_z)
Define a generic airport.
Definition airport.cpp:27
static uint16_t AirportGetNofElements(const AirportFTAbuildup *apFA)
Get the number of elements of a source Airport state automata Since it is actually just a big array o...
Definition airport.cpp:150
uint8_t GetVehiclePosOnBuild(TileIndex hangar_tile)
Get the vehicle position when an aircraft is build at the given tile.
Definition airport.cpp:218
const AirportFTAClass * GetAirport(const uint8_t airport_type)
Get the finite state machine of an airport type.
Definition airport.cpp:207
AirportMovingData RotateAirportMovingData(const AirportMovingData *orig, Direction rotation, uint num_tiles_x, uint num_tiles_y)
Rotate the airport moving data to another rotation.
Definition airport.cpp:80
static AirportFTA * AirportBuildAutomata(uint nofelements, const AirportFTAbuildup *apFA)
Construct the FTA given a description.
Definition airport.cpp:171
#define HELIPORT(name, num_helipads, delta_z)
Define a heliport.
Definition airport.cpp:46
static const uint MAX_ELEMENTS
maximum number of aircraft positions at airport
Definition airport.h:19
@ AT_DUMMY
Dummy airport.
Definition airport.h:43
@ HANGAR
Heading for hangar.
Definition airport.h:62
Tables with default values for airports and airport tiles.
Heart of the airports and their finite state machines.
Enum of the default airport tiles.
Direction ChangeDir(Direction d, DirDiff delta)
Change a direction by a given difference.
Direction
Defines the 8 directions on the map.
@ DIR_N
North.
@ DIR_S
South.
@ DIR_W
West.
@ DIR_E
East.
DirDiff
Allow incrementing of Direction variables.
A number of safeguards to prevent using unsafe methods.
Base classes/functions for stations.
Definition of base types and functions in a cross-platform compatible way.
void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition stdafx.h:334
Finite sTate mAchine (FTA) of an airport.
Definition airport.h:143
struct AirportFTA * layout
state machine for airport
Definition airport.h:177
uint8_t nofelements
number of positions the airport consists of
Definition airport.h:181
Internal structure used in openttd - Finite sTate mAchine --> FTA.
Definition airport.h:190
AirportFTA * next
possible extra movement choices from this position
Definition airport.h:191
uint8_t heading
heading (current orders), guiding an airplane to its target on an airport
Definition airport.h:195
uint64_t block
64 bit blocks (st->airport.flags), should be enough for the most complex airports
Definition airport.h:192
uint8_t position
the position that an airplane is at
Definition airport.h:193
uint8_t next_position
next position from this position
Definition airport.h:194
State machine input struct (from external file, etc.) Finite sTate mAchine --> FTA.
uint8_t heading
The current orders (eg. TAKEOFF, HANGAR, ENDLANDING, etc.).
uint8_t next
Next position from this position.
uint8_t position
The position that an airplane is at.
uint64_t block
The block this position is on on the airport (st->airport.flags).
A single location on an airport where aircraft can move to.
Definition airport.h:131
uint16_t flag
special flags when moving towards the destination.
Definition airport.h:134
int16_t x
x-coordinate of the destination.
Definition airport.h:132
int16_t y
y-coordinate of the destination.
Definition airport.h:133
Direction direction
Direction to turn the aircraft after reaching the destination.
Definition airport.h:135
const struct AirportFTAClass * fsm
the finite statemachine for the default airports
static const AirportSpec * Get(uint8_t type)
Retrieve airport spec for the given airport.
const AirportFTAClass * GetFTA() const
Get the finite-state machine for this airport or the finite-state machine for the dummy airport in ca...
TileIndex GetHangarTile(uint hangar_num) const
Get the first tile of the given hangar.
static BaseStation * GetByTile(TileIndex tile)
Get the base station belonging to a specific tile.
Station data structure.
Airport airport
Tile area the airport covers.
static const uint TILE_SIZE
Tile size in world coordinates.
Definition tile_type.h:15