station_base.h

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 #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 {
00032     GES_ACCEPTANCE,       
00033     GES_PICKUP,           
00034     GES_EVER_ACCEPTED,    
00035     GES_LAST_MONTH,       
00036     GES_CURRENT_MONTH,    
00037     GES_ACCEPTED_BIGTICK, 
00038   };
00039 
00040   GoodsEntry() :
00041     acceptance_pickup(0),
00042     days_since_pickup(255),
00043     rating(INITIAL_STATION_RATING),
00044     last_speed(0),
00045     last_age(255)
00046   {}
00047 
00048   byte acceptance_pickup; 
00049   byte days_since_pickup; 
00050   byte rating;            
00051   byte last_speed;        
00052   byte last_age;          
00053   byte amount_fract;      
00054   StationCargoList cargo; 
00055 };
00056 
00057 extern uint8 _head_to_head;
00058 
00060 struct Airport : public TileArea {
00061   Airport() : TileArea(INVALID_TILE, 0, 0) {}
00062 
00063   uint64 flags;       
00064   byte type;          
00065   byte layout;        
00066   Direction rotation; 
00067 
00068   PersistentStorage *psa; 
00069 
00075   const AirportSpec *GetSpec() const
00076   {
00077     if (this->tile == INVALID_TILE) return &AirportSpec::dummy;
00078     return AirportSpec::Get(this->type);
00079   }
00080 
00087   const AirportFTAClass *GetFTA() const
00088   {
00089     return this->GetSpec()->fsm;
00090   }
00091 
00093   inline bool HasHangar() const
00094   {
00095     return this->GetSpec()->nof_depots > 0;
00096   }
00097 
00106   inline TileIndex GetRotatedTileFromOffset(TileIndexDiffC tidc) const
00107   {
00108     const AirportSpec *as = this->GetSpec();
00109     switch (this->rotation) {
00110       case DIR_N: return this->tile + ToTileIndexDiff(tidc);
00111 
00112       case DIR_E: return this->tile + TileDiffXY(tidc.y, as->size_x - 1 - tidc.x);
00113 
00114       case DIR_S: return this->tile + TileDiffXY(as->size_x - 1 - tidc.x, as->size_y - 1 - tidc.y);
00115 
00116       case DIR_W: return this->tile + TileDiffXY(as->size_y - 1 - tidc.y, tidc.x);
00117 
00118       default: NOT_REACHED();
00119     }
00120   }
00121 
00128   inline TileIndex GetHangarTile(uint hangar_num) const
00129   {
00130     const AirportSpec *as = this->GetSpec();
00131     for (uint i = 0; i < as->nof_depots; i++) {
00132       if (as->depot_table[i].hangar_num == hangar_num) {
00133         return this->GetRotatedTileFromOffset(as->depot_table[i].ti);
00134       }
00135     }
00136     NOT_REACHED();
00137   }
00138 
00145   inline Direction GetHangarExitDirection(TileIndex tile) const
00146   {
00147     const AirportSpec *as = this->GetSpec();
00148     const HangarTileTable *htt = GetHangarDataByTile(tile);
00149     return ChangeDir(htt->dir, DirDifference(this->rotation, as->rotation[0]));
00150   }
00151 
00158   inline uint GetHangarNum(TileIndex tile) const
00159   {
00160     const HangarTileTable *htt = GetHangarDataByTile(tile);
00161     return htt->hangar_num;
00162   }
00163 
00165   inline uint GetNumHangars() const
00166   {
00167     uint num = 0;
00168     uint counted = 0;
00169     const AirportSpec *as = this->GetSpec();
00170     for (uint i = 0; i < as->nof_depots; i++) {
00171       if (!HasBit(counted, as->depot_table[i].hangar_num)) {
00172         num++;
00173         SetBit(counted, as->depot_table[i].hangar_num);
00174       }
00175     }
00176     return num;
00177   }
00178 
00179 private:
00186   inline const HangarTileTable *GetHangarDataByTile(TileIndex tile) const
00187   {
00188     const AirportSpec *as = this->GetSpec();
00189     for (uint i = 0; i < as->nof_depots; i++) {
00190       if (this->GetRotatedTileFromOffset(as->depot_table[i].ti) == tile) {
00191         return as->depot_table + i;
00192       }
00193     }
00194     NOT_REACHED();
00195   }
00196 };
00197 
00198 typedef SmallVector<Industry *, 2> IndustryVector;
00199 
00201 struct Station FINAL : SpecializedStation<Station, false> {
00202 public:
00203   RoadStop *GetPrimaryRoadStop(RoadStopType type) const
00204   {
00205     return type == ROADSTOP_BUS ? bus_stops : truck_stops;
00206   }
00207 
00208   RoadStop *GetPrimaryRoadStop(const struct RoadVehicle *v) const;
00209 
00210   RoadStop *bus_stops;    
00211   TileArea bus_station;   
00212   RoadStop *truck_stops;  
00213   TileArea truck_station; 
00214 
00215   Airport airport;        
00216   TileIndex dock_tile;    
00217 
00218   IndustryType indtype;   
00219 
00220   StationHadVehicleOfTypeByte had_vehicle_of_type;
00221 
00222   byte time_since_load;
00223   byte time_since_unload;
00224 
00225   byte last_vehicle_type;
00226   std::list<Vehicle *> loading_vehicles;
00227   GoodsEntry goods[NUM_CARGO];  
00228   uint32 always_accepted;       
00229 
00230   IndustryVector industries_near; 
00231 
00232   uint8 head_to_head;
00233 
00234   Station(TileIndex tile = INVALID_TILE);
00235   ~Station();
00236 
00237   void AddFacility(StationFacility new_facility_bit, TileIndex facil_xy);
00238 
00239   void MarkTilesDirty(bool cargo_change) const;
00240 
00241   void UpdateVirtCoord();
00242 
00243   /* virtual */ uint GetPlatformLength(TileIndex tile, DiagDirection dir) const;
00244   /* virtual */ uint GetPlatformLength(TileIndex tile) const;
00245   void RecomputeIndustriesNear();
00246   static void RecomputeIndustriesNearForAll();
00247 
00248   uint GetCatchmentRadius() const;
00249   Rect GetCatchmentRect() const;
00250 
00251   /* virtual */ inline bool TileBelongsToRailStation(TileIndex tile) const
00252   {
00253     return IsRailStationTile(tile) && GetStationIndex(tile) == this->index;
00254   }
00255 
00256   inline bool TileBelongsToAirport(TileIndex tile) const
00257   {
00258     return IsAirportTile(tile) && GetStationIndex(tile) == this->index;
00259   }
00260 
00261   /* virtual */ uint32 GetNewGRFVariable(const ResolverObject *object, byte variable, byte parameter, bool *available) const;
00262 
00263   /* virtual */ void GetTileArea(TileArea *ta, StationType type) const;
00264 };
00265 
00266 #define FOR_ALL_STATIONS(var) FOR_ALL_BASE_STATIONS_OF_TYPE(Station, var) if (_head_to_head == 0 || Station::From(var)->head_to_head == _head_to_head)
00267 
00269 class AirportTileIterator : public OrthogonalTileIterator {
00270 private:
00271   const Station *st; 
00272 
00273 public:
00278   AirportTileIterator(const Station *st) : OrthogonalTileIterator(st->airport), st(st)
00279   {
00280     if (!st->TileBelongsToAirport(this->tile)) ++(*this);
00281   }
00282 
00283   inline TileIterator& operator ++()
00284   {
00285     (*this).OrthogonalTileIterator::operator++();
00286     while (this->tile != INVALID_TILE && !st->TileBelongsToAirport(this->tile)) {
00287       (*this).OrthogonalTileIterator::operator++();
00288     }
00289     return *this;
00290   }
00291 
00292   virtual TileIterator *Clone() const
00293   {
00294     return new AirportTileIterator(*this);
00295   }
00296 };
00297 
00298 #endif /* STATION_BASE_H */