station_base.h

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