00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "stdafx.h"
00013 #include "station_base.h"
00014 #include "table/strings.h"
00015 #include "table/airport_movement.h"
00016 #include "table/airporttile_ids.h"
00017
00018
00027 #define AIRPORT_GENERIC(name, terminals, num_helipads, flags, delta_z) \
00028 static AirportFTAClass _airportfta_ ## name(_airport_moving_data_ ## name, terminals, \
00029 num_helipads, _airport_entries_ ## name, flags, _airport_fta_ ## name, delta_z);
00030
00037 #define AIRPORT(name, num_helipads, short_strip) \
00038 AIRPORT_GENERIC(name, _airport_terminal_ ## name, num_helipads, AirportFTAClass::ALL | (short_strip ? AirportFTAClass::SHORT_STRIP : (AirportFTAClass::Flags)0), 0)
00039
00046 #define HELIPORT(name, num_helipads, delta_z) \
00047 AIRPORT_GENERIC(name, NULL, num_helipads, AirportFTAClass::HELICOPTERS, delta_z)
00048
00049 AIRPORT(country, 0, true)
00050 AIRPORT(city, 0, false)
00051 HELIPORT(heliport, 1, 60)
00052 AIRPORT(metropolitan, 0, false)
00053 AIRPORT(international, 2, false)
00054 AIRPORT(commuter, 2, true)
00055 HELIPORT(helidepot, 1, 0)
00056 AIRPORT(intercontinental, 2, false)
00057 HELIPORT(helistation, 3, 0)
00058 HELIPORT(oilrig, 1, 54)
00059 AIRPORT_GENERIC(dummy, NULL, 0, AirportFTAClass::ALL, 0)
00060
00061 #undef HELIPORT
00062 #undef AIRPORT
00063 #undef AIRPORT_GENERIC
00064
00065 #include "table/airport_defaults.h"
00066
00067
00068 static uint16 AirportGetNofElements(const AirportFTAbuildup *apFA);
00069 static AirportFTA *AirportBuildAutomata(uint nofelements, const AirportFTAbuildup *apFA);
00070
00071
00080 AirportMovingData RotateAirportMovingData(const AirportMovingData *orig, Direction rotation, uint num_tiles_x, uint num_tiles_y)
00081 {
00082 AirportMovingData amd;
00083 amd.flag = orig->flag;
00084 amd.direction = ChangeDir(orig->direction, (DirDiff)rotation);
00085 switch (rotation) {
00086 case DIR_N:
00087 amd.x = orig->x;
00088 amd.y = orig->y;
00089 break;
00090
00091 case DIR_E:
00092 amd.x = orig->y;
00093 amd.y = num_tiles_y * TILE_SIZE - orig->x - 1;
00094 break;
00095
00096 case DIR_S:
00097 amd.x = num_tiles_x * TILE_SIZE - orig->x - 1;
00098 amd.y = num_tiles_y * TILE_SIZE - orig->y - 1;
00099 break;
00100
00101 case DIR_W:
00102 amd.x = num_tiles_x * TILE_SIZE - orig->y - 1;
00103 amd.y = orig->x;
00104 break;
00105
00106 default: NOT_REACHED();
00107 }
00108 return amd;
00109 }
00110
00111 AirportFTAClass::AirportFTAClass(
00112 const AirportMovingData *moving_data_,
00113 const byte *terminals_,
00114 const byte num_helipads_,
00115 const byte *entry_points_,
00116 Flags flags_,
00117 const AirportFTAbuildup *apFA,
00118 byte delta_z_
00119 ) :
00120 moving_data(moving_data_),
00121 terminals(terminals_),
00122 num_helipads(num_helipads_),
00123 flags(flags_),
00124 nofelements(AirportGetNofElements(apFA)),
00125 entry_points(entry_points_),
00126 delta_z(delta_z_)
00127 {
00128
00129 this->layout = AirportBuildAutomata(this->nofelements, apFA);
00130 }
00131
00132 AirportFTAClass::~AirportFTAClass()
00133 {
00134 for (uint i = 0; i < nofelements; i++) {
00135 AirportFTA *current = layout[i].next;
00136 while (current != NULL) {
00137 AirportFTA *next = current->next;
00138 free(current);
00139 current = next;
00140 }
00141 }
00142 free(layout);
00143 }
00144
00150 static uint16 AirportGetNofElements(const AirportFTAbuildup *apFA)
00151 {
00152 uint16 nofelements = 0;
00153 int temp = apFA[0].position;
00154
00155 for (uint i = 0; i < MAX_ELEMENTS; i++) {
00156 if (temp != apFA[i].position) {
00157 nofelements++;
00158 temp = apFA[i].position;
00159 }
00160 if (apFA[i].position == MAX_ELEMENTS) break;
00161 }
00162 return nofelements;
00163 }
00164
00171 static AirportFTA *AirportBuildAutomata(uint nofelements, const AirportFTAbuildup *apFA)
00172 {
00173 AirportFTA *FAutomata = MallocT<AirportFTA>(nofelements);
00174 uint16 internalcounter = 0;
00175
00176 for (uint i = 0; i < nofelements; i++) {
00177 AirportFTA *current = &FAutomata[i];
00178 current->position = apFA[internalcounter].position;
00179 current->heading = apFA[internalcounter].heading;
00180 current->block = apFA[internalcounter].block;
00181 current->next_position = apFA[internalcounter].next;
00182
00183
00184 while (current->position == apFA[internalcounter + 1].position) {
00185 AirportFTA *newNode = MallocT<AirportFTA>(1);
00186
00187 newNode->position = apFA[internalcounter + 1].position;
00188 newNode->heading = apFA[internalcounter + 1].heading;
00189 newNode->block = apFA[internalcounter + 1].block;
00190 newNode->next_position = apFA[internalcounter + 1].next;
00191
00192 current->next = newNode;
00193 current = current->next;
00194 internalcounter++;
00195 }
00196 current->next = NULL;
00197 internalcounter++;
00198 }
00199 return FAutomata;
00200 }
00201
00207 const AirportFTAClass *GetAirport(const byte airport_type)
00208 {
00209 if (airport_type == AT_DUMMY) return &_airportfta_dummy;
00210 return AirportSpec::Get(airport_type)->fsm;
00211 }
00212
00218 byte GetVehiclePosOnBuild(TileIndex hangar_tile)
00219 {
00220 const Station *st = Station::GetByTile(hangar_tile);
00221 const AirportFTAClass *apc = st->airport.GetFTA();
00222
00223
00224
00225
00226 for (uint i = 0;; i++) {
00227 if (st->airport.GetHangarTile(i) == hangar_tile) {
00228 assert(apc->layout[i].heading == HANGAR);
00229 return apc->layout[i].position;
00230 }
00231 }
00232 NOT_REACHED();
00233 }