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 
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   /* Build the state machine itself */
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     /* outgoing nodes from the same position, create linked list */
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       /* create link */
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   /* When we click on hangar we know the tile it is on. By that we know
00210    * its position in the array of depots the airport has.....we can search
00211    * layout for #th position of depot. Since layout must start with a listing
00212    * of all depots, it is simple */
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 }

Generated on Thu Apr 14 00:48:11 2011 for OpenTTD by  doxygen 1.6.1