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
00019 #define AIRPORT_GENERIC(name, terminals, num_helipads, flags, delta_z) \
00020 static AirportFTAClass _airportfta_ ## name(_airport_moving_data_ ## name, terminals, \
00021 num_helipads, _airport_entries_ ## name, flags, _airport_fta_ ## name, delta_z);
00022
00029 #define AIRPORT(name, num_helipads, short_strip) \
00030 AIRPORT_GENERIC(name, _airport_terminal_ ## name, num_helipads, AirportFTAClass::ALL | (short_strip ? AirportFTAClass::SHORT_STRIP : (AirportFTAClass::Flags)0), 0)
00031
00038 #define HELIPORT(name, num_helipads, delta_z) \
00039 AIRPORT_GENERIC(name, NULL, num_helipads, AirportFTAClass::HELICOPTERS, delta_z)
00040
00041 AIRPORT(country, 0, true)
00042 AIRPORT(city, 0, false)
00043 HELIPORT(heliport, 1, 60)
00044 AIRPORT(metropolitan, 0, false)
00045 AIRPORT(international, 2, false)
00046 AIRPORT(commuter, 2, true)
00047 HELIPORT(helidepot, 1, 0)
00048 AIRPORT(intercontinental, 2, false)
00049 HELIPORT(helistation, 3, 0)
00050 HELIPORT(oilrig, 1, 54)
00051 AIRPORT_GENERIC(dummy, NULL, 0, AirportFTAClass::ALL, 0)
00052
00053 #undef HELIPORT
00054 #undef AIRPORT
00055 #undef AIRPORT_GENERIC
00056
00057 #include "table/airport_defaults.h"
00058
00059
00060 static uint16 AirportGetNofElements(const AirportFTAbuildup *apFA);
00061 static AirportFTA *AirportBuildAutomata(uint nofelements, const AirportFTAbuildup *apFA);
00062
00063
00072 AirportMovingData RotateAirportMovingData(const AirportMovingData *orig, Direction rotation, uint num_tiles_x, uint num_tiles_y)
00073 {
00074 AirportMovingData amd;
00075 amd.flag = orig->flag;
00076 amd.direction = ChangeDir(orig->direction, (DirDiff)rotation);
00077 switch (rotation) {
00078 case DIR_N:
00079 amd.x = orig->x;
00080 amd.y = orig->y;
00081 break;
00082
00083 case DIR_E:
00084 amd.x = orig->y;
00085 amd.y = num_tiles_y * TILE_SIZE - orig->x - 1;
00086 break;
00087
00088 case DIR_S:
00089 amd.x = num_tiles_x * TILE_SIZE - orig->x - 1;
00090 amd.y = num_tiles_y * TILE_SIZE - orig->y - 1;
00091 break;
00092
00093 case DIR_W:
00094 amd.x = num_tiles_x * TILE_SIZE - orig->y - 1;
00095 amd.y = orig->x;
00096 break;
00097
00098 default: NOT_REACHED();
00099 }
00100 return amd;
00101 }
00102
00103 AirportFTAClass::AirportFTAClass(
00104 const AirportMovingData *moving_data_,
00105 const byte *terminals_,
00106 const byte num_helipads_,
00107 const byte *entry_points_,
00108 Flags flags_,
00109 const AirportFTAbuildup *apFA,
00110 byte delta_z_
00111 ) :
00112 moving_data(moving_data_),
00113 terminals(terminals_),
00114 num_helipads(num_helipads_),
00115 flags(flags_),
00116 nofelements(AirportGetNofElements(apFA)),
00117 entry_points(entry_points_),
00118 delta_z(delta_z_)
00119 {
00120
00121 this->layout = AirportBuildAutomata(this->nofelements, apFA);
00122 }
00123
00124 AirportFTAClass::~AirportFTAClass()
00125 {
00126 for (uint i = 0; i < nofelements; i++) {
00127 AirportFTA *current = layout[i].next;
00128 while (current != NULL) {
00129 AirportFTA *next = current->next;
00130 free(current);
00131 current = next;
00132 };
00133 }
00134 free(layout);
00135 }
00136
00142 static uint16 AirportGetNofElements(const AirportFTAbuildup *apFA)
00143 {
00144 uint16 nofelements = 0;
00145 int temp = apFA[0].position;
00146
00147 for (uint i = 0; i < MAX_ELEMENTS; i++) {
00148 if (temp != apFA[i].position) {
00149 nofelements++;
00150 temp = apFA[i].position;
00151 }
00152 if (apFA[i].position == MAX_ELEMENTS) break;
00153 }
00154 return nofelements;
00155 }
00156
00157
00158 static AirportFTA *AirportBuildAutomata(uint nofelements, const AirportFTAbuildup *apFA)
00159 {
00160 AirportFTA *FAutomata = MallocT<AirportFTA>(nofelements);
00161 uint16 internalcounter = 0;
00162
00163 for (uint i = 0; i < nofelements; i++) {
00164 AirportFTA *current = &FAutomata[i];
00165 current->position = apFA[internalcounter].position;
00166 current->heading = apFA[internalcounter].heading;
00167 current->block = apFA[internalcounter].block;
00168 current->next_position = apFA[internalcounter].next;
00169
00170
00171 while (current->position == apFA[internalcounter + 1].position) {
00172 AirportFTA *newNode = MallocT<AirportFTA>(1);
00173
00174 newNode->position = apFA[internalcounter + 1].position;
00175 newNode->heading = apFA[internalcounter + 1].heading;
00176 newNode->block = apFA[internalcounter + 1].block;
00177 newNode->next_position = apFA[internalcounter + 1].next;
00178
00179 current->next = newNode;
00180 current = current->next;
00181 internalcounter++;
00182 }
00183 current->next = NULL;
00184 internalcounter++;
00185 }
00186 return FAutomata;
00187 }
00188
00194 const AirportFTAClass *GetAirport(const byte airport_type)
00195 {
00196 if (airport_type == AT_DUMMY) return &_airportfta_dummy;
00197 return AirportSpec::Get(airport_type)->fsm;
00198 }
00199
00205 byte GetVehiclePosOnBuild(TileIndex hangar_tile)
00206 {
00207 const Station *st = Station::GetByTile(hangar_tile);
00208 const AirportFTAClass *apc = st->airport.GetFTA();
00209
00210
00211
00212
00213 for (uint i = 0;; i++) {
00214 if (st->airport.GetHangarTile(i) == hangar_tile) {
00215 assert(apc->layout[i].heading == HANGAR);
00216 return apc->layout[i].position;
00217 }
00218 }
00219 NOT_REACHED();
00220 }