00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "stdafx.h"
00013 #include "debug.h"
00014 #include "airport.h"
00015 #include "airport_movement.h"
00016 #include "core/alloc_func.hpp"
00017 #include "date_func.h"
00018 #include "settings_type.h"
00019
00020
00021
00022 enum AirportTiles {
00023 APT_APRON = 0,
00024 APT_APRON_FENCE_NW = 1,
00025 APT_APRON_FENCE_SW = 2,
00026 APT_STAND = 3,
00027 APT_APRON_W = 4,
00028 APT_APRON_S = 5,
00029 APT_APRON_VER_CROSSING_S = 6,
00030 APT_APRON_HOR_CROSSING_W = 7,
00031 APT_APRON_VER_CROSSING_N = 8,
00032 APT_APRON_HOR_CROSSING_E = 9,
00033 APT_APRON_E = 10,
00034 APT_ARPON_N = 11,
00035 APT_APRON_HOR = 12,
00036 APT_APRON_N_FENCE_SW = 13,
00037 APT_RUNWAY_1 = 14,
00038 APT_RUNWAY_2 = 15,
00039 APT_RUNWAY_3 = 16,
00040 APT_RUNWAY_4 = 17,
00041 APT_RUNWAY_END_FENCE_SE = 18,
00042 APT_BUILDING_2 = 19,
00043 APT_TOWER_FENCE_SW = 20,
00044 APT_ROUND_TERMINAL = 21,
00045 APT_BUILDING_3 = 22,
00046 APT_BUILDING_1 = 23,
00047 APT_DEPOT_SE = 24,
00048 APT_STAND_1 = 25,
00049 APT_STAND_PIER_NE = 26,
00050 APT_PIER_NW_NE = 27,
00051 APT_PIER = 28,
00052 APT_EMPTY = 29,
00053 APT_EMPTY_FENCE_NE = 30,
00054 APT_RADAR_GRASS_FENCE_SW = 31,
00055
00056 APT_RADIO_TOWER_FENCE_NE = 43,
00057 APT_SMALL_BUILDING_3 = 44,
00058 APT_SMALL_BUILDING_2 = 45,
00059 APT_SMALL_BUILDING_1 = 46,
00060 APT_GRASS_FENCE_SW = 47,
00061 APT_GRASS_2 = 48,
00062 APT_GRASS_1 = 49,
00063 APT_GRASS_FENCE_NE_FLAG = 50,
00064
00065 APT_RUNWAY_SMALL_NEAR_END = 54,
00066 APT_RUNWAY_SMALL_MIDDLE = 55,
00067 APT_RUNWAY_SMALL_FAR_END = 56,
00068 APT_SMALL_DEPOT_SE = 57,
00069 APT_HELIPORT = 58,
00070 APT_RUNWAY_END = 59,
00071 APT_RUNWAY_5 = 60,
00072 APT_TOWER = 61,
00073 APT_SMALL_DEPOT_SE_2 = 62,
00074 APT_APRON_FENCE_NE = 63,
00075 APT_RUNWAY_END_FENCE_NW = 64,
00076 APT_RUNWAY_FENCE_NW = 65,
00077 APT_RADAR_FENCE_SW = 66,
00078
00079 APT_RADAR_FENCE_NE = 78,
00080
00081 APT_HELIPAD_1 = 90,
00082 APT_HELIPAD_2_FENCE_NW = 91,
00083 APT_HELIPAD_2 = 92,
00084 APT_APRON_FENCE_NE_SW = 93,
00085 APT_RUNWAY_END_FENCE_NW_SW = 94,
00086 APT_RUNWAY_END_FENCE_SE_SW = 95,
00087 APT_RUNWAY_END_FENCE_NE_NW = 96,
00088 APT_RUNWAY_END_FENCE_NE_SE = 97,
00089 APT_HELIPAD_2_FENCE_NE_SE = 98,
00090 APT_APRON_FENCE_SE_SW = 99,
00091 APT_LOW_BUILDING_FENCE_N = 100,
00092 APT_ROT_RUNWAY_FENCE_NE = 101,
00093 APT_ROT_RUNWAY_END_FENCE_NE= 102,
00094 APT_ROT_RUNWAY_FENCE_SW = 103,
00095 APT_ROT_RUNWAY_END_FENCE_SW= 104,
00096 APT_DEPOT_SW = 105,
00097 APT_DEPOT_NW = 106,
00098 APT_DEPOT_NE = 107,
00099 APT_HELIPAD_2_FENCE_SE_SW = 108,
00100 APT_HELIPAD_2_FENCE_SE = 109,
00101 APT_LOW_BUILDING_FENCE_NW = 110,
00102 APT_LOW_BUILDING_FENCE_NE = 111,
00103 APT_LOW_BUILDING_FENCE_SW = 112,
00104 APT_LOW_BUILDING_FENCE_SE = 113,
00105 APT_STAND_FENCE_NE = 114,
00106 APT_STAND_FENCE_SE = 115,
00107 APT_STAND_FENCE_SW = 116,
00108 APT_APRON_FENCE_NE_2 = 117,
00109 APT_APRON_FENCE_SE = 118,
00110 APT_HELIPAD_2_FENCE_NW_SW = 119,
00111 APT_HELIPAD_2_FENCE_SW = 120,
00112 APT_RADAR_FENCE_SE = 121,
00113
00114 APT_HELIPAD_3_FENCE_SE_SW = 133,
00115 APT_HELIPAD_3_FENCE_NW_SW = 134,
00116 APT_HELIPAD_3_FENCE_NW = 135,
00117 APT_LOW_BUILDING = 136,
00118 APT_APRON_FENCE_NE_SE = 137,
00119 APT_APRON_HALF_EAST = 138,
00120 APT_APRON_HALF_WEST = 139,
00121 APT_GRASS_FENCE_NE_FLAG_2 = 140,
00122
00123 };
00124
00126 static const byte _airport_sections_country[] = {
00127 APT_SMALL_BUILDING_1, APT_SMALL_BUILDING_2, APT_SMALL_BUILDING_3, APT_SMALL_DEPOT_SE,
00128 APT_GRASS_FENCE_NE_FLAG, APT_GRASS_1, APT_GRASS_2, APT_GRASS_FENCE_SW,
00129 APT_RUNWAY_SMALL_FAR_END, APT_RUNWAY_SMALL_MIDDLE, APT_RUNWAY_SMALL_MIDDLE, APT_RUNWAY_SMALL_NEAR_END
00130 };
00131
00133 static const byte _airport_sections_town[] = {
00134 APT_BUILDING_1, APT_APRON_FENCE_NW, APT_STAND_1, APT_APRON_FENCE_NW, APT_APRON_FENCE_NW, APT_DEPOT_SE,
00135 APT_BUILDING_2, APT_PIER, APT_ROUND_TERMINAL, APT_STAND_PIER_NE, APT_APRON, APT_APRON_FENCE_SW,
00136 APT_BUILDING_3, APT_STAND, APT_PIER_NW_NE, APT_APRON_S, APT_APRON_HOR, APT_APRON_N_FENCE_SW,
00137 APT_RADIO_TOWER_FENCE_NE, APT_APRON_W, APT_APRON_VER_CROSSING_S, APT_APRON_HOR_CROSSING_E, APT_ARPON_N, APT_TOWER_FENCE_SW,
00138 APT_EMPTY_FENCE_NE, APT_APRON_S, APT_APRON_HOR_CROSSING_W, APT_APRON_VER_CROSSING_N, APT_APRON_E, APT_RADAR_GRASS_FENCE_SW,
00139 APT_RUNWAY_END_FENCE_SE, APT_RUNWAY_1, APT_RUNWAY_2, APT_RUNWAY_3, APT_RUNWAY_4, APT_RUNWAY_END_FENCE_SE
00140 };
00141
00143 static const byte _airport_sections_metropolitan[] = {
00144 APT_BUILDING_1, APT_APRON_FENCE_NW, APT_STAND_1, APT_APRON_FENCE_NW, APT_APRON_FENCE_NW, APT_DEPOT_SE,
00145 APT_BUILDING_2, APT_PIER, APT_ROUND_TERMINAL, APT_STAND_PIER_NE, APT_APRON, APT_APRON_FENCE_SW,
00146 APT_BUILDING_3, APT_STAND, APT_PIER_NW_NE, APT_APRON_S, APT_APRON_HOR, APT_APRON_N_FENCE_SW,
00147 APT_RADAR_FENCE_NE, APT_APRON, APT_APRON, APT_APRON, APT_APRON, APT_TOWER_FENCE_SW,
00148 APT_RUNWAY_END, APT_RUNWAY_5, APT_RUNWAY_5, APT_RUNWAY_5, APT_RUNWAY_5, APT_RUNWAY_END,
00149 APT_RUNWAY_END_FENCE_SE, APT_RUNWAY_2, APT_RUNWAY_2, APT_RUNWAY_2, APT_RUNWAY_2, APT_RUNWAY_END_FENCE_SE
00150 };
00151
00153 static const byte _airport_sections_international[] = {
00154 APT_RUNWAY_END_FENCE_NW, APT_RUNWAY_FENCE_NW, APT_RUNWAY_FENCE_NW, APT_RUNWAY_FENCE_NW, APT_RUNWAY_FENCE_NW, APT_RUNWAY_FENCE_NW, APT_RUNWAY_END_FENCE_NW,
00155 APT_RADIO_TOWER_FENCE_NE, APT_APRON, APT_APRON, APT_APRON, APT_APRON, APT_APRON, APT_DEPOT_SE,
00156 APT_BUILDING_3, APT_APRON, APT_STAND, APT_BUILDING_2, APT_STAND, APT_APRON, APT_APRON_FENCE_SW,
00157 APT_DEPOT_SE, APT_APRON, APT_STAND, APT_BUILDING_2, APT_STAND, APT_APRON, APT_HELIPAD_1,
00158 APT_APRON_FENCE_NE, APT_APRON, APT_STAND, APT_TOWER, APT_STAND, APT_APRON, APT_HELIPAD_1,
00159 APT_APRON_FENCE_NE, APT_APRON, APT_APRON, APT_APRON, APT_APRON, APT_APRON, APT_RADAR_FENCE_SW,
00160 APT_RUNWAY_END_FENCE_SE, APT_RUNWAY_2, APT_RUNWAY_2, APT_RUNWAY_2, APT_RUNWAY_2, APT_RUNWAY_2, APT_RUNWAY_END_FENCE_SE
00161 };
00162
00164 static const byte _airport_sections_intercontinental[] = {
00165 APT_RADAR_FENCE_NE, APT_RUNWAY_END_FENCE_NE_NW, APT_RUNWAY_FENCE_NW, APT_RUNWAY_FENCE_NW, APT_RUNWAY_FENCE_NW, APT_RUNWAY_FENCE_NW, APT_RUNWAY_FENCE_NW, APT_RUNWAY_FENCE_NW, APT_RUNWAY_END_FENCE_NW_SW,
00166 APT_RUNWAY_END_FENCE_NE_NW, APT_RUNWAY_2, APT_RUNWAY_2, APT_RUNWAY_2, APT_RUNWAY_2, APT_RUNWAY_2, APT_RUNWAY_2, APT_RUNWAY_END_FENCE_SE_SW, APT_APRON_FENCE_NE_SW,
00167 APT_APRON_FENCE_NE, APT_SMALL_BUILDING_1, APT_APRON_FENCE_NE, APT_APRON, APT_APRON, APT_APRON, APT_APRON, APT_RADIO_TOWER_FENCE_NE, APT_APRON_FENCE_NE_SW,
00168 APT_APRON_FENCE_NE, APT_APRON_HALF_EAST, APT_APRON_FENCE_NE, APT_TOWER, APT_HELIPAD_2, APT_HELIPAD_2, APT_APRON, APT_APRON_FENCE_NW, APT_APRON_FENCE_SW,
00169 APT_APRON_FENCE_NE, APT_APRON, APT_APRON, APT_STAND, APT_BUILDING_1, APT_STAND, APT_APRON, APT_LOW_BUILDING, APT_DEPOT_SE,
00170 APT_DEPOT_SE, APT_LOW_BUILDING, APT_APRON, APT_STAND, APT_BUILDING_2, APT_STAND, APT_APRON, APT_APRON, APT_APRON_FENCE_SW,
00171 APT_APRON_FENCE_NE, APT_APRON, APT_APRON, APT_STAND, APT_BUILDING_3, APT_STAND, APT_APRON, APT_APRON, APT_APRON_FENCE_SW,
00172 APT_APRON_FENCE_NE, APT_APRON_FENCE_SE, APT_APRON, APT_STAND, APT_ROUND_TERMINAL, APT_STAND, APT_APRON_FENCE_SW, APT_APRON_HALF_WEST, APT_APRON_FENCE_SW,
00173 APT_APRON_FENCE_NE, APT_GRASS_FENCE_NE_FLAG_2, APT_APRON_FENCE_NE, APT_APRON, APT_APRON, APT_APRON, APT_APRON_FENCE_SW, APT_EMPTY, APT_APRON_FENCE_NE_SW,
00174 APT_APRON_FENCE_NE, APT_RUNWAY_END_FENCE_NE_NW, APT_RUNWAY_FENCE_NW, APT_RUNWAY_FENCE_NW, APT_RUNWAY_FENCE_NW, APT_RUNWAY_FENCE_NW, APT_RUNWAY_FENCE_NW, APT_RUNWAY_FENCE_NW, APT_RUNWAY_END_FENCE_SE_SW,
00175 APT_RUNWAY_END_FENCE_NE_SE, APT_RUNWAY_2, APT_RUNWAY_2, APT_RUNWAY_2, APT_RUNWAY_2, APT_RUNWAY_2, APT_RUNWAY_2, APT_RUNWAY_END_FENCE_SE_SW, APT_EMPTY
00176 };
00177
00178
00180 static const byte _airport_sections_commuter[] = {
00181 APT_TOWER, APT_BUILDING_3, APT_HELIPAD_2_FENCE_NW, APT_HELIPAD_2_FENCE_NW, APT_DEPOT_SE,
00182 APT_APRON_FENCE_NE, APT_APRON, APT_APRON, APT_APRON, APT_APRON_FENCE_SW,
00183 APT_APRON_FENCE_NE, APT_STAND, APT_STAND, APT_STAND, APT_APRON_FENCE_SW,
00184 APT_RUNWAY_END_FENCE_SE, APT_RUNWAY_2, APT_RUNWAY_2, APT_RUNWAY_2, APT_RUNWAY_END_FENCE_SE
00185 };
00186
00188 static const byte _airport_sections_heliport[] = {
00189 APT_HELIPORT,
00190 };
00191
00193 static const byte _airport_sections_helidepot[] = {
00194 APT_LOW_BUILDING_FENCE_N, APT_DEPOT_SE,
00195 APT_HELIPAD_2_FENCE_NE_SE, APT_APRON_FENCE_SE_SW
00196 };
00197
00199 static const byte _airport_sections_helistation[] = {
00200 APT_DEPOT_SE, APT_LOW_BUILDING_FENCE_NW, APT_HELIPAD_3_FENCE_NW, APT_HELIPAD_3_FENCE_NW_SW,
00201 APT_APRON_FENCE_NE_SE, APT_APRON_FENCE_SE, APT_APRON_FENCE_SE, APT_HELIPAD_3_FENCE_SE_SW
00202 };
00203
00204 const byte * const _airport_sections[] = {
00205 _airport_sections_country,
00206 _airport_sections_town,
00207 _airport_sections_heliport,
00208 _airport_sections_metropolitan,
00209 _airport_sections_international,
00210 _airport_sections_commuter,
00211 _airport_sections_helidepot,
00212 _airport_sections_intercontinental,
00213 _airport_sections_helistation,
00214 };
00215
00216 assert_compile(NUM_AIRPORTS == lengthof(_airport_sections));
00217
00218
00219
00220
00221
00222
00223
00224
00225 static AirportFTAClass *_dummy_airport;
00226 static AirportFTAClass *_country_airport;
00227 static AirportFTAClass *_city_airport;
00228 static AirportFTAClass *_oilrig;
00229 static AirportFTAClass *_heliport;
00230 static AirportFTAClass *_metropolitan_airport;
00231 static AirportFTAClass *_international_airport;
00232 static AirportFTAClass *_commuter_airport;
00233 static AirportFTAClass *_heli_depot;
00234 static AirportFTAClass *_intercontinental_airport;
00235 static AirportFTAClass *_heli_station;
00236
00237
00238 void InitializeAirports()
00239 {
00240 _dummy_airport = new AirportFTAClass(
00241 _airport_moving_data_dummy,
00242 NULL,
00243 NULL,
00244 _airport_entries_dummy,
00245 AirportFTAClass::ALL,
00246 _airport_fta_dummy,
00247 NULL,
00248 0,
00249 0, 0, 0,
00250 0,
00251 0,
00252 MAX_YEAR + 1, MAX_YEAR + 1
00253 );
00254
00255 _country_airport = new AirportFTAClass(
00256 _airport_moving_data_country,
00257 _airport_terminal_country,
00258 NULL,
00259 _airport_entries_country,
00260 AirportFTAClass::ALL | AirportFTAClass::SHORT_STRIP,
00261 _airport_fta_country,
00262 _airport_depots_country,
00263 lengthof(_airport_depots_country),
00264 4, 3, 3,
00265 0,
00266 4,
00267 0, 1959
00268 );
00269
00270 _city_airport = new AirportFTAClass(
00271 _airport_moving_data_town,
00272 _airport_terminal_city,
00273 NULL,
00274 _airport_entries_city,
00275 AirportFTAClass::ALL,
00276 _airport_fta_city,
00277 _airport_depots_city,
00278 lengthof(_airport_depots_city),
00279 6, 6, 5,
00280 0,
00281 5,
00282 1955, MAX_YEAR
00283 );
00284
00285 _metropolitan_airport = new AirportFTAClass(
00286 _airport_moving_data_metropolitan,
00287 _airport_terminal_metropolitan,
00288 NULL,
00289 _airport_entries_metropolitan,
00290 AirportFTAClass::ALL,
00291 _airport_fta_metropolitan,
00292 _airport_depots_metropolitan,
00293 lengthof(_airport_depots_metropolitan),
00294 6, 6, 8,
00295 0,
00296 6,
00297 1980, MAX_YEAR
00298 );
00299
00300 _international_airport = new AirportFTAClass(
00301 _airport_moving_data_international,
00302 _airport_terminal_international,
00303 _airport_helipad_international,
00304 _airport_entries_international,
00305 AirportFTAClass::ALL,
00306 _airport_fta_international,
00307 _airport_depots_international,
00308 lengthof(_airport_depots_international),
00309 7, 7, 17,
00310 0,
00311 8,
00312 1990, MAX_YEAR
00313 );
00314
00315 _intercontinental_airport = new AirportFTAClass(
00316 _airport_moving_data_intercontinental,
00317 _airport_terminal_intercontinental,
00318 _airport_helipad_intercontinental,
00319 _airport_entries_intercontinental,
00320 AirportFTAClass::ALL,
00321 _airport_fta_intercontinental,
00322 _airport_depots_intercontinental,
00323 lengthof(_airport_depots_intercontinental),
00324 9, 11, 25,
00325 0,
00326 10,
00327 2002, MAX_YEAR
00328 );
00329
00330 _heliport = new AirportFTAClass(
00331 _airport_moving_data_heliport,
00332 NULL,
00333 _airport_helipad_heliport_oilrig,
00334 _airport_entries_heliport_oilrig,
00335 AirportFTAClass::HELICOPTERS,
00336 _airport_fta_heliport_oilrig,
00337 NULL,
00338 0,
00339 1, 1, 1,
00340 60,
00341 4,
00342 1963, MAX_YEAR
00343 );
00344
00345 _oilrig = new AirportFTAClass(
00346 _airport_moving_data_oilrig,
00347 NULL,
00348 _airport_helipad_heliport_oilrig,
00349 _airport_entries_heliport_oilrig,
00350 AirportFTAClass::HELICOPTERS,
00351 _airport_fta_heliport_oilrig,
00352 NULL,
00353 0,
00354 1, 1, 0,
00355 54,
00356 3,
00357 MAX_YEAR + 1, MAX_YEAR + 1
00358 );
00359
00360 _commuter_airport = new AirportFTAClass(
00361 _airport_moving_data_commuter,
00362 _airport_terminal_commuter,
00363 _airport_helipad_commuter,
00364 _airport_entries_commuter,
00365 AirportFTAClass::ALL | AirportFTAClass::SHORT_STRIP,
00366 _airport_fta_commuter,
00367 _airport_depots_commuter,
00368 lengthof(_airport_depots_commuter),
00369 5, 4, 4,
00370 0,
00371 4,
00372 1983, MAX_YEAR
00373 );
00374
00375 _heli_depot = new AirportFTAClass(
00376 _airport_moving_data_helidepot,
00377 NULL,
00378 _airport_helipad_helidepot,
00379 _airport_entries_helidepot,
00380 AirportFTAClass::HELICOPTERS,
00381 _airport_fta_helidepot,
00382 _airport_depots_helidepot,
00383 lengthof(_airport_depots_helidepot),
00384 2, 2, 2,
00385 0,
00386 4,
00387 1976, MAX_YEAR
00388 );
00389
00390 _heli_station = new AirportFTAClass(
00391 _airport_moving_data_helistation,
00392 NULL,
00393 _airport_helipad_helistation,
00394 _airport_entries_helistation,
00395 AirportFTAClass::HELICOPTERS,
00396 _airport_fta_helistation,
00397 _airport_depots_helistation,
00398 lengthof(_airport_depots_helistation),
00399 4, 2, 3,
00400 0,
00401 4,
00402 1980, MAX_YEAR
00403 );
00404 }
00405
00406 void UnInitializeAirports()
00407 {
00408 delete _dummy_airport;
00409 delete _country_airport;
00410 delete _city_airport;
00411 delete _heliport;
00412 delete _metropolitan_airport;
00413 delete _international_airport;
00414 delete _commuter_airport;
00415 delete _heli_depot;
00416 delete _intercontinental_airport;
00417 delete _heli_station;
00418 }
00419
00420
00421 static uint16 AirportGetNofElements(const AirportFTAbuildup *apFA);
00422 static AirportFTA *AirportBuildAutomata(uint nofelements, const AirportFTAbuildup *apFA);
00423 static byte AirportGetTerminalCount(const byte *terminals, byte *groups);
00424 static byte AirportTestFTA(uint nofelements, const AirportFTA *layout, const byte *terminals);
00425
00426 #ifdef DEBUG_AIRPORT
00427 static void AirportPrintOut(uint nofelements, const AirportFTA *layout, bool full_report);
00428 #endif
00429
00430
00431 AirportFTAClass::AirportFTAClass(
00432 const AirportMovingData *moving_data_,
00433 const byte *terminals_,
00434 const byte *helipads_,
00435 const byte *entry_points_,
00436 Flags flags_,
00437 const AirportFTAbuildup *apFA,
00438 const TileIndexDiffC *depots_,
00439 const byte nof_depots_,
00440 uint size_x_,
00441 uint size_y_,
00442 byte noise_level_,
00443 byte delta_z_,
00444 byte catchment_,
00445 Year first_available_,
00446 Year last_available_
00447 ) :
00448 moving_data(moving_data_),
00449 terminals(terminals_),
00450 helipads(helipads_),
00451 airport_depots(depots_),
00452 flags(flags_),
00453 nof_depots(nof_depots_),
00454 nofelements(AirportGetNofElements(apFA)),
00455 entry_points(entry_points_),
00456 size_x(size_x_),
00457 size_y(size_y_),
00458 noise_level(noise_level_),
00459 delta_z(delta_z_),
00460 catchment(catchment_),
00461 first_available(first_available_),
00462 last_available(last_available_)
00463 {
00464 byte nofterminalgroups, nofhelipadgroups;
00465
00466
00467
00468
00469 uint nofterminals = AirportGetTerminalCount(terminals, &nofterminalgroups);
00470 if (nofterminals > MAX_TERMINALS) {
00471 DEBUG(misc, 0, "[Ap] only a maximum of %d terminals are supported (requested %d)", MAX_TERMINALS, nofterminals);
00472 assert(nofterminals <= MAX_TERMINALS);
00473 }
00474
00475 uint nofhelipads = AirportGetTerminalCount(helipads, &nofhelipadgroups);
00476 if (nofhelipads > MAX_HELIPADS) {
00477 DEBUG(misc, 0, "[Ap] only a maximum of %d helipads are supported (requested %d)", MAX_HELIPADS, nofhelipads);
00478 assert(nofhelipads <= MAX_HELIPADS);
00479 }
00480
00481
00482
00483
00484 for (DiagDirection i = DIAGDIR_BEGIN; i < DIAGDIR_END; i++) {
00485 if (entry_points[i] >= nofelements) {
00486 DEBUG(misc, 0, "[Ap] entry (%d) must be within the airport (maximum %d)", entry_points[i], nofelements);
00487 assert(entry_points[i] < nofelements);
00488 }
00489 }
00490
00491
00492 layout = AirportBuildAutomata(nofelements, apFA);
00493 DEBUG(misc, 6, "[Ap] #count %3d; #term %2d (%dgrp); #helipad %2d (%dgrp); entries %3d, %3d, %3d, %3d",
00494 nofelements, nofterminals, nofterminalgroups, nofhelipads, nofhelipadgroups,
00495 entry_points[DIAGDIR_NE], entry_points[DIAGDIR_SE], entry_points[DIAGDIR_SW], entry_points[DIAGDIR_NW]);
00496
00497
00498
00499
00500 uint ret = AirportTestFTA(nofelements, layout, terminals);
00501 if (ret != MAX_ELEMENTS) DEBUG(misc, 0, "[Ap] problem with element: %d", ret - 1);
00502 assert(ret == MAX_ELEMENTS);
00503
00504 #ifdef DEBUG_AIRPORT
00505 AirportPrintOut(nofelements, layout, DEBUG_AIRPORT);
00506 #endif
00507 }
00508
00509 AirportFTAClass::~AirportFTAClass()
00510 {
00511 for (uint i = 0; i < nofelements; i++) {
00512 AirportFTA *current = layout[i].next;
00513 while (current != NULL) {
00514 AirportFTA *next = current->next;
00515 free(current);
00516 current = next;
00517 };
00518 }
00519 free(layout);
00520 }
00521
00522 bool AirportFTAClass::IsAvailable() const
00523 {
00524 if (_cur_year < this->first_available) return false;
00525 if (_settings_game.station.never_expire_airports) return true;
00526 return _cur_year <= this->last_available;
00527 }
00528
00532 static uint16 AirportGetNofElements(const AirportFTAbuildup *apFA)
00533 {
00534 uint16 nofelements = 0;
00535 int temp = apFA[0].position;
00536
00537 for (uint i = 0; i < MAX_ELEMENTS; i++) {
00538 if (temp != apFA[i].position) {
00539 nofelements++;
00540 temp = apFA[i].position;
00541 }
00542 if (apFA[i].position == MAX_ELEMENTS) break;
00543 }
00544 return nofelements;
00545 }
00546
00550 static byte AirportGetTerminalCount(const byte *terminals, byte *groups)
00551 {
00552 byte nof_terminals = 0;
00553 *groups = 0;
00554
00555 if (terminals != NULL) {
00556 uint i = terminals[0];
00557 *groups = i;
00558 while (i-- > 0) {
00559 terminals++;
00560 assert(*terminals != 0);
00561 nof_terminals += *terminals;
00562 }
00563 }
00564 return nof_terminals;
00565 }
00566
00567
00568 static AirportFTA *AirportBuildAutomata(uint nofelements, const AirportFTAbuildup *apFA)
00569 {
00570 AirportFTA *FAutomata = MallocT<AirportFTA>(nofelements);
00571 uint16 internalcounter = 0;
00572
00573 for (uint i = 0; i < nofelements; i++) {
00574 AirportFTA *current = &FAutomata[i];
00575 current->position = apFA[internalcounter].position;
00576 current->heading = apFA[internalcounter].heading;
00577 current->block = apFA[internalcounter].block;
00578 current->next_position = apFA[internalcounter].next;
00579
00580
00581 while (current->position == apFA[internalcounter + 1].position) {
00582 AirportFTA *newNode = MallocT<AirportFTA>(1);
00583
00584 newNode->position = apFA[internalcounter + 1].position;
00585 newNode->heading = apFA[internalcounter + 1].heading;
00586 newNode->block = apFA[internalcounter + 1].block;
00587 newNode->next_position = apFA[internalcounter + 1].next;
00588
00589 current->next = newNode;
00590 current = current->next;
00591 internalcounter++;
00592 }
00593 current->next = NULL;
00594 internalcounter++;
00595 }
00596 return FAutomata;
00597 }
00598
00599
00600 static byte AirportTestFTA(uint nofelements, const AirportFTA *layout, const byte *terminals)
00601 {
00602 uint next_position = 0;
00603
00604 for (uint i = 0; i < nofelements; i++) {
00605 uint position = layout[i].position;
00606 if (position != next_position) return i;
00607 const AirportFTA *first = &layout[i];
00608
00609 for (const AirportFTA *current = first; current != NULL; current = current->next) {
00610
00611
00612
00613 if (current->heading > MAX_HEADINGS) {
00614 if (current->heading != 255) return i;
00615 if (current == first && current->next == NULL) return i;
00616 if (current != first && current->next_position > terminals[0]) return i;
00617 }
00618
00619
00620 if (current->heading == 0 && current->next != NULL) return i;
00621
00622 if (position != current->position) return i;
00623
00624 if (current->next_position >= nofelements) return i;
00625 }
00626 next_position++;
00627 }
00628 return MAX_ELEMENTS;
00629 }
00630
00631 #ifdef DEBUG_AIRPORT
00632 static const char * const _airport_heading_strings[] = {
00633 "TO_ALL",
00634 "HANGAR",
00635 "TERM1",
00636 "TERM2",
00637 "TERM3",
00638 "TERM4",
00639 "TERM5",
00640 "TERM6",
00641 "HELIPAD1",
00642 "HELIPAD2",
00643 "TAKEOFF",
00644 "STARTTAKEOFF",
00645 "ENDTAKEOFF",
00646 "HELITAKEOFF",
00647 "FLYING",
00648 "LANDING",
00649 "ENDLANDING",
00650 "HELILANDING",
00651 "HELIENDLANDING",
00652 "TERM7",
00653 "TERM8",
00654 "HELIPAD3",
00655 "HELIPAD4",
00656 "DUMMY"
00657 };
00658
00659 static void AirportPrintOut(uint nofelements, const AirportFTA *layout, bool full_report)
00660 {
00661 if (!full_report) printf("(P = Current Position; NP = Next Position)\n");
00662
00663 for (uint i = 0; i < nofelements; i++) {
00664 for (const AirportFTA *current = &layout[i]; current != NULL; current = current->next) {
00665 if (full_report) {
00666 byte heading = (current->heading == 255) ? MAX_HEADINGS + 1 : current->heading;
00667 printf("\tPos:%2d NPos:%2d Heading:%15s Block:%2d\n", current->position,
00668 current->next_position, _airport_heading_strings[heading],
00669 FindLastBit(current->block));
00670 } else {
00671 printf("P:%2d NP:%2d", current->position, current->next_position);
00672 }
00673 }
00674 printf("\n");
00675 }
00676 }
00677 #endif
00678
00679 const AirportFTAClass *GetAirport(const byte airport_type)
00680 {
00681
00682
00683 switch (airport_type) {
00684 default: NOT_REACHED();
00685 case AT_SMALL: return _country_airport;
00686 case AT_LARGE: return _city_airport;
00687 case AT_METROPOLITAN: return _metropolitan_airport;
00688 case AT_HELIPORT: return _heliport;
00689 case AT_OILRIG: return _oilrig;
00690 case AT_INTERNATIONAL: return _international_airport;
00691 case AT_COMMUTER: return _commuter_airport;
00692 case AT_HELIDEPOT: return _heli_depot;
00693 case AT_INTERCON: return _intercontinental_airport;
00694 case AT_HELISTATION: return _heli_station;
00695 case AT_DUMMY: return _dummy_airport;
00696 }
00697 }