airport.cpp

Go to the documentation of this file.
00001 /* $Id$ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * 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.
00006  * 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.
00007  * 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/>.
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   /* Build the state machine itself */
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     /* outgoing nodes from the same position, create linked list */
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       /* create link */
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   /* When we click on hangar we know the tile it is on. By that we know
00223    * its position in the array of depots the airport has.....we can search
00224    * layout for #th position of depot. Since layout must start with a listing
00225    * of all depots, it is simple */
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 }

Generated on Sun Jun 5 04:19:54 2011 for OpenTTD by  doxygen 1.6.1