station_base.h

Go to the documentation of this file.
00001 /* $Id: station_base.h 24718 2012-11-12 21:59:02Z frosch $ */
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 #ifndef STATION_BASE_H
00013 #define STATION_BASE_H
00014 
00015 #include "base_station_base.h"
00016 #include "newgrf_airport.h"
00017 #include "cargopacket.h"
00018 #include "industry_type.h"
00019 #include "newgrf_storage.h"
00020 
00021 typedef Pool<BaseStation, StationID, 32, 64000> StationPool;
00022 extern StationPool _station_pool;
00023 
00024 static const byte INITIAL_STATION_RATING = 175;
00025 
00029 struct GoodsEntry {
00031   enum GoodsEntryStatus {
00036     GES_ACCEPTANCE,
00037 
00045     GES_PICKUP,
00046 
00051     GES_EVER_ACCEPTED,
00052 
00057     GES_LAST_MONTH,
00058 
00063     GES_CURRENT_MONTH,
00064 
00069     GES_ACCEPTED_BIGTICK,
00070   };
00071 
00072   GoodsEntry() :
00073     acceptance_pickup(0),
00074     time_since_pickup(255),
00075     rating(INITIAL_STATION_RATING),
00076     last_speed(0),
00077     last_age(255)
00078   {}
00079 
00080   byte acceptance_pickup; 
00081 
00087   byte time_since_pickup;
00088 
00089   byte rating;            
00090 
00100   byte last_speed;
00101 
00106   byte last_age;
00107 
00108   byte amount_fract;      
00109   StationCargoList cargo; 
00110 
00116   bool HasVehicleEverTriedLoading() const { return this->last_speed != 0; }
00117 };
00118 
00120 struct Airport : public TileArea {
00121   Airport() : TileArea(INVALID_TILE, 0, 0) {}
00122 
00123   uint64 flags;       
00124   byte type;          
00125   byte layout;        
00126   Direction rotation; 
00127 
00128   PersistentStorage *psa; 
00129 
00135   const AirportSpec *GetSpec() const
00136   {
00137     if (this->tile == INVALID_TILE) return &AirportSpec::dummy;
00138     return AirportSpec::Get(this->type);
00139   }
00140 
00147   const AirportFTAClass *GetFTA() const
00148   {
00149     return this->GetSpec()->fsm;
00150   }
00151 
00153   inline bool HasHangar() const
00154   {
00155     return this->GetSpec()->nof_depots > 0;
00156   }
00157 
00166   inline TileIndex GetRotatedTileFromOffset(TileIndexDiffC tidc) const
00167   {
00168     const AirportSpec *as = this->GetSpec();
00169     switch (this->rotation) {
00170       case DIR_N: return this->tile + ToTileIndexDiff(tidc);
00171 
00172       case DIR_E: return this->tile + TileDiffXY(tidc.y, as->size_x - 1 - tidc.x);
00173 
00174       case DIR_S: return this->tile + TileDiffXY(as->size_x - 1 - tidc.x, as->size_y - 1 - tidc.y);
00175 
00176       case DIR_W: return this->tile + TileDiffXY(as->size_y - 1 - tidc.y, tidc.x);
00177 
00178       default: NOT_REACHED();
00179     }
00180   }
00181 
00188   inline TileIndex GetHangarTile(uint hangar_num) const
00189   {
00190     const AirportSpec *as = this->GetSpec();
00191     for (uint i = 0; i < as->nof_depots; i++) {
00192       if (as->depot_table[i].hangar_num == hangar_num) {
00193         return this->GetRotatedTileFromOffset(as->depot_table[i].ti);
00194       }
00195     }
00196     NOT_REACHED();
00197   }
00198 
00205   inline Direction GetHangarExitDirection(TileIndex tile) const
00206   {
00207     const AirportSpec *as = this->GetSpec();
00208     const HangarTileTable *htt = GetHangarDataByTile(tile);
00209     return ChangeDir(htt->dir, DirDifference(this->rotation, as->rotation[0]));
00210   }
00211 
00218   inline uint GetHangarNum(TileIndex tile) const
00219   {
00220     const HangarTileTable *htt = GetHangarDataByTile(tile);
00221     return htt->hangar_num;
00222   }
00223 
00225   inline uint GetNumHangars() const
00226   {
00227     uint num = 0;
00228     uint counted = 0;
00229     const AirportSpec *as = this->GetSpec();
00230     for (uint i = 0; i < as->nof_depots; i++) {
00231       if (!HasBit(counted, as->depot_table[i].hangar_num)) {
00232         num++;
00233         SetBit(counted, as->depot_table[i].hangar_num);
00234       }
00235     }
00236     return num;
00237   }
00238 
00239 private:
00246   inline const HangarTileTable *GetHangarDataByTile(TileIndex tile) const
00247   {
00248     const AirportSpec *as = this->GetSpec();
00249     for (uint i = 0; i < as->nof_depots; i++) {
00250       if (this->GetRotatedTileFromOffset(as->depot_table[i].ti) == tile) {
00251         return as->depot_table + i;
00252       }
00253     }
00254     NOT_REACHED();
00255   }
00256 };
00257 
00258 typedef SmallVector<Industry *, 2> IndustryVector;
00259 
00261 struct Station FINAL : SpecializedStation<Station, false> {
00262 public:
00263   RoadStop *GetPrimaryRoadStop(RoadStopType type) const
00264   {
00265     return type == ROADSTOP_BUS ? bus_stops : truck_stops;
00266   }
00267 
00268   RoadStop *GetPrimaryRoadStop(const struct RoadVehicle *v) const;
00269 
00270   RoadStop *bus_stops;    
00271   TileArea bus_station;   
00272   RoadStop *truck_stops;  
00273   TileArea truck_station; 
00274 
00275   Airport airport;        
00276   TileIndex dock_tile;    
00277 
00278   IndustryType indtype;   
00279 
00280   StationHadVehicleOfTypeByte had_vehicle_of_type;
00281 
00282   byte time_since_load;
00283   byte time_since_unload;
00284 
00285   byte last_vehicle_type;
00286   std::list<Vehicle *> loading_vehicles;
00287   GoodsEntry goods[NUM_CARGO];  
00288   uint32 always_accepted;       
00289 
00290   IndustryVector industries_near; 
00291 
00292   Station(TileIndex tile = INVALID_TILE);
00293   ~Station();
00294 
00295   void AddFacility(StationFacility new_facility_bit, TileIndex facil_xy);
00296 
00297   void MarkTilesDirty(bool cargo_change) const;
00298 
00299   void UpdateVirtCoord();
00300 
00301   /* virtual */ uint GetPlatformLength(TileIndex tile, DiagDirection dir) const;
00302   /* virtual */ uint GetPlatformLength(TileIndex tile) const;
00303   void RecomputeIndustriesNear();
00304   static void RecomputeIndustriesNearForAll();
00305 
00306   uint GetCatchmentRadius() const;
00307   Rect GetCatchmentRect() const;
00308 
00309   /* virtual */ inline bool TileBelongsToRailStation(TileIndex tile) const
00310   {
00311     return IsRailStationTile(tile) && GetStationIndex(tile) == this->index;
00312   }
00313 
00314   inline bool TileBelongsToAirport(TileIndex tile) const
00315   {
00316     return IsAirportTile(tile) && GetStationIndex(tile) == this->index;
00317   }
00318 
00319   /* virtual */ uint32 GetNewGRFVariable(const ResolverObject *object, byte variable, byte parameter, bool *available) const;
00320 
00321   /* virtual */ void GetTileArea(TileArea *ta, StationType type) const;
00322 };
00323 
00324 #define FOR_ALL_STATIONS(var) FOR_ALL_BASE_STATIONS_OF_TYPE(Station, var)
00325 
00327 class AirportTileIterator : public OrthogonalTileIterator {
00328 private:
00329   const Station *st; 
00330 
00331 public:
00336   AirportTileIterator(const Station *st) : OrthogonalTileIterator(st->airport), st(st)
00337   {
00338     if (!st->TileBelongsToAirport(this->tile)) ++(*this);
00339   }
00340 
00341   inline TileIterator& operator ++()
00342   {
00343     (*this).OrthogonalTileIterator::operator++();
00344     while (this->tile != INVALID_TILE && !st->TileBelongsToAirport(this->tile)) {
00345       (*this).OrthogonalTileIterator::operator++();
00346     }
00347     return *this;
00348   }
00349 
00350   virtual TileIterator *Clone() const
00351   {
00352     return new AirportTileIterator(*this);
00353   }
00354 };
00355 
00356 #endif /* STATION_BASE_H */