# 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 */