# station_base.h

Go to the documentation of this file.

    00001 /* $Id: station_base.h 23735 2012-01-03 20:26:05Z rubidium $ */
    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
    00058 struct Airport : public TileArea {
    00059   Airport() : TileArea(INVALID_TILE, 0, 0) {}
    00060
    00061   uint64 flags;
    00062   byte type;
    00063   byte layout;
    00064   Direction rotation;
    00065
    00066   PersistentStorage *psa;
    00067
    00073   const AirportSpec *GetSpec() const
    00074   {
    00075     if (this->tile == INVALID_TILE) return &AirportSpec::dummy;
    00076     return AirportSpec::Get(this->type);
    00077   }
    00078
    00085   const AirportFTAClass *GetFTA() const
    00086   {
    00087     return this->GetSpec()->fsm;
    00088   }
    00089
    00091   inline bool HasHangar() const
    00092   {
    00093     return this->GetSpec()->nof_depots > 0;
    00094   }
    00095
    00104   inline TileIndex GetRotatedTileFromOffset(TileIndexDiffC tidc) const
    00105   {
    00106     const AirportSpec *as = this->GetSpec();
    00107     switch (this->rotation) {
    00108       case DIR_N: return this->tile + ToTileIndexDiff(tidc);
    00109
    00110       case DIR_E: return this->tile + TileDiffXY(tidc.y, as->size_x - 1 - tidc.x);
    00111
    00112       case DIR_S: return this->tile + TileDiffXY(as->size_x - 1 - tidc.x, as->size_y - 1 - tidc.y);
    00113
    00114       case DIR_W: return this->tile + TileDiffXY(as->size_y - 1 - tidc.y, tidc.x);
    00115
    00116       default: NOT_REACHED();
    00117     }
    00118   }
    00119
    00126   inline TileIndex GetHangarTile(uint hangar_num) const
    00127   {
    00128     const AirportSpec *as = this->GetSpec();
    00129     for (uint i = 0; i < as->nof_depots; i++) {
    00130       if (as->depot_table[i].hangar_num == hangar_num) {
    00131         return this->GetRotatedTileFromOffset(as->depot_table[i].ti);
    00132       }
    00133     }
    00134     NOT_REACHED();
    00135   }
    00136
    00143   inline Direction GetHangarExitDirection(TileIndex tile) const
    00144   {
    00145     const AirportSpec *as = this->GetSpec();
    00146     const HangarTileTable *htt = GetHangarDataByTile(tile);
    00147     return ChangeDir(htt->dir, DirDifference(this->rotation, as->rotation[0]));
    00148   }
    00149
    00156   inline uint GetHangarNum(TileIndex tile) const
    00157   {
    00158     const HangarTileTable *htt = GetHangarDataByTile(tile);
    00159     return htt->hangar_num;
    00160   }
    00161
    00163   inline uint GetNumHangars() const
    00164   {
    00165     uint num = 0;
    00166     uint counted = 0;
    00167     const AirportSpec *as = this->GetSpec();
    00168     for (uint i = 0; i < as->nof_depots; i++) {
    00169       if (!HasBit(counted, as->depot_table[i].hangar_num)) {
    00170         num++;
    00171         SetBit(counted, as->depot_table[i].hangar_num);
    00172       }
    00173     }
    00174     return num;
    00175   }
    00176
    00177 private:
    00184   inline const HangarTileTable *GetHangarDataByTile(TileIndex tile) const
    00185   {
    00186     const AirportSpec *as = this->GetSpec();
    00187     for (uint i = 0; i < as->nof_depots; i++) {
    00188       if (this->GetRotatedTileFromOffset(as->depot_table[i].ti) == tile) {
    00189         return as->depot_table + i;
    00190       }
    00191     }
    00192     NOT_REACHED();
    00193   }
    00194 };
    00195
    00196 typedef SmallVector<Industry *, 2> IndustryVector;
    00197
    00199 struct Station FINAL : SpecializedStation<Station, false> {
    00200 public:
    00201   RoadStop *GetPrimaryRoadStop(RoadStopType type) const
    00202   {
    00203     return type == ROADSTOP_BUS ? bus_stops : truck_stops;
    00204   }
    00205
    00206   RoadStop *GetPrimaryRoadStop(const struct RoadVehicle *v) const;
    00207
    00208   RoadStop *bus_stops;
    00209   TileArea bus_station;
    00210   RoadStop *truck_stops;
    00211   TileArea truck_station;
    00212
    00213   Airport airport;
    00214   TileIndex dock_tile;
    00215
    00216   IndustryType indtype;
    00217
    00218   StationHadVehicleOfTypeByte had_vehicle_of_type;
    00219
    00220   byte time_since_load;
    00221   byte time_since_unload;
    00222
    00223   byte last_vehicle_type;
    00224   std::list<Vehicle *> loading_vehicles;
    00225   GoodsEntry goods[NUM_CARGO];
    00226   uint32 always_accepted;
    00227
    00228   IndustryVector industries_near;
    00229
    00230   Station(TileIndex tile = INVALID_TILE);
    00231   ~Station();
    00232
    00233   void AddFacility(StationFacility new_facility_bit, TileIndex facil_xy);
    00234
    00235   void MarkTilesDirty(bool cargo_change) const;
    00236
    00237   void UpdateVirtCoord();
    00238
    00239   /* virtual */ uint GetPlatformLength(TileIndex tile, DiagDirection dir) const;
    00240   /* virtual */ uint GetPlatformLength(TileIndex tile) const;
    00241   void RecomputeIndustriesNear();
    00242   static void RecomputeIndustriesNearForAll();
    00243
    00244   uint GetCatchmentRadius() const;
    00245   Rect GetCatchmentRect() const;
    00246
    00247   /* virtual */ inline bool TileBelongsToRailStation(TileIndex tile) const
    00248   {
    00249     return IsRailStationTile(tile) && GetStationIndex(tile) == this->index;
    00250   }
    00251
    00252   inline bool TileBelongsToAirport(TileIndex tile) const
    00253   {
    00254     return IsAirportTile(tile) && GetStationIndex(tile) == this->index;
    00255   }
    00256
    00257   /* virtual */ uint32 GetNewGRFVariable(const ResolverObject *object, byte variable, byte parameter, bool *available) const;
    00258
    00259   /* virtual */ void GetTileArea(TileArea *ta, StationType type) const;
    00260 };
    00261
    00262 #define FOR_ALL_STATIONS(var) FOR_ALL_BASE_STATIONS_OF_TYPE(Station, var)
    00263
    00265 class AirportTileIterator : public OrthogonalTileIterator {
    00266 private:
    00267   const Station *st;
    00268
    00269 public:
    00274   AirportTileIterator(const Station *st) : OrthogonalTileIterator(st->airport), st(st)
    00275   {
    00276     if (!st->TileBelongsToAirport(this->tile)) ++(*this);
    00277   }
    00278
    00279   inline TileIterator& operator ++()
    00280   {
    00281     (*this).OrthogonalTileIterator::operator++();
    00282     while (this->tile != INVALID_TILE && !st->TileBelongsToAirport(this->tile)) {
    00283       (*this).OrthogonalTileIterator::operator++();
    00284     }
    00285     return *this;
    00286   }
    00287
    00288   virtual TileIterator *Clone() const
    00289   {
    00290     return new AirportTileIterator(*this);
    00291   }
    00292 };
    00293
    00294 #endif /* STATION_BASE_H */