# 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 "core/random_func.hpp"
    00016 #include "base_station_base.h"
    00017 #include "newgrf_airport.h"
    00018 #include "cargopacket.h"
    00019 #include "industry_type.h"
    00020 #include "linkgraph/linkgraph_type.h"
    00021 #include "newgrf_storage.h"
    00022 #include <map>
    00023
    00024 typedef Pool<BaseStation, StationID, 32, 64000> StationPool;
    00025 extern StationPool _station_pool;
    00026
    00027 static const byte INITIAL_STATION_RATING = 175;
    00028
    00036 class FlowStat {
    00037 public:
    00038   typedef std::map<uint32, StationID> SharesMap;
    00039
    00040   inline FlowStat() {NOT_REACHED();}
    00041
    00042   inline FlowStat(StationID st, uint flow)
    00043   {
    00044     assert(flow > 0);
    00045     this->shares[flow] = st;
    00046   }
    00047
    00055   inline void AppendShare(StationID st, uint flow)
    00056   {
    00057     assert(flow > 0);
    00058     this->shares[(--this->shares.end())->first + flow] = st;
    00059   }
    00060
    00061   uint GetShare(StationID st) const;
    00062
    00063   void ChangeShare(StationID st, int flow);
    00064
    00065   inline const SharesMap *GetShares() const { return &this->shares; }
    00066
    00074   inline StationID GetVia() const
    00075   {
    00076     assert(!this->shares.empty());
    00077     return this->shares.upper_bound(RandomRange((--this->shares.end())->first - 1))->second;
    00078   }
    00079
    00080   StationID GetVia(StationID excluded, StationID excluded2 = INVALID_STATION) const;
    00081
    00082 private:
    00083   SharesMap shares;
    00084 };
    00085
    00087 class FlowStatMap : public std::map<StationID, FlowStat> {
    00088 public:
    00089   void AddFlow(StationID origin, StationID via, uint amount);
    00090   void PassOnFlow(StationID origin, StationID via, uint amount);
    00091   void DeleteFlows(StationID via);
    00092   void FinalizeLocalConsumption(StationID self);
    00093 };
    00094
    00098 struct GoodsEntry {
    00100   enum GoodsEntryStatus {
    00105     GES_ACCEPTANCE,
    00106
    00114     GES_PICKUP,
    00115
    00120     GES_EVER_ACCEPTED,
    00121
    00126     GES_LAST_MONTH,
    00127
    00132     GES_CURRENT_MONTH,
    00133
    00138     GES_ACCEPTED_BIGTICK,
    00139   };
    00140
    00141   GoodsEntry() :
    00142     acceptance_pickup(0),
    00143     time_since_pickup(255),
    00144     rating(INITIAL_STATION_RATING),
    00145     last_speed(0),
    00146     last_age(255),
    00147     link_graph(INVALID_LINK_GRAPH),
    00148     node(INVALID_NODE),
    00149     max_waiting_cargo(0)
    00150   {}
    00151
    00152   byte acceptance_pickup;
    00153
    00159   byte time_since_pickup;
    00160
    00161   byte rating;
    00162
    00172   byte last_speed;
    00173
    00178   byte last_age;
    00179
    00180   byte amount_fract;
    00181   StationCargoList cargo;
    00182
    00183   LinkGraphID link_graph;
    00184   NodeID node;
    00185   FlowStatMap flows;
    00186   uint max_waiting_cargo;
    00187
    00193   bool HasVehicleEverTriedLoading() const { return this->last_speed != 0; }
    00194   uint GetSumFlowVia(StationID via) const;
    00195
    00202   inline StationID GetVia(StationID source) const
    00203   {
    00204     FlowStatMap::const_iterator flow_it(this->flows.find(source));
    00205     return flow_it != this->flows.end() ? flow_it->second.GetVia() : INVALID_STATION;
    00206   }
    00207
    00216   inline StationID GetVia(StationID source, StationID excluded, StationID excluded2 = INVALID_STATION) const
    00217   {
    00218     FlowStatMap::const_iterator flow_it(this->flows.find(source));
    00219     return flow_it != this->flows.end() ? flow_it->second.GetVia(excluded, excluded2) : INVALID_STATION;
    00220   }
    00221 };
    00222
    00224 struct Airport : public TileArea {
    00225   Airport() : TileArea(INVALID_TILE, 0, 0) {}
    00226
    00227   uint64 flags;
    00228   byte type;
    00229   byte layout;
    00230   Direction rotation;
    00231
    00232   PersistentStorage *psa;
    00233
    00239   const AirportSpec *GetSpec() const
    00240   {
    00241     if (this->tile == INVALID_TILE) return &AirportSpec::dummy;
    00242     return AirportSpec::Get(this->type);
    00243   }
    00244
    00251   const AirportFTAClass *GetFTA() const
    00252   {
    00253     return this->GetSpec()->fsm;
    00254   }
    00255
    00257   inline bool HasHangar() const
    00258   {
    00259     return this->GetSpec()->nof_depots > 0;
    00260   }
    00261
    00270   inline TileIndex GetRotatedTileFromOffset(TileIndexDiffC tidc) const
    00271   {
    00272     const AirportSpec *as = this->GetSpec();
    00273     switch (this->rotation) {
    00274       case DIR_N: return this->tile + ToTileIndexDiff(tidc);
    00275
    00276       case DIR_E: return this->tile + TileDiffXY(tidc.y, as->size_x - 1 - tidc.x);
    00277
    00278       case DIR_S: return this->tile + TileDiffXY(as->size_x - 1 - tidc.x, as->size_y - 1 - tidc.y);
    00279
    00280       case DIR_W: return this->tile + TileDiffXY(as->size_y - 1 - tidc.y, tidc.x);
    00281
    00282       default: NOT_REACHED();
    00283     }
    00284   }
    00285
    00292   inline TileIndex GetHangarTile(uint hangar_num) const
    00293   {
    00294     const AirportSpec *as = this->GetSpec();
    00295     for (uint i = 0; i < as->nof_depots; i++) {
    00296       if (as->depot_table[i].hangar_num == hangar_num) {
    00297         return this->GetRotatedTileFromOffset(as->depot_table[i].ti);
    00298       }
    00299     }
    00300     NOT_REACHED();
    00301   }
    00302
    00309   inline Direction GetHangarExitDirection(TileIndex tile) const
    00310   {
    00311     const AirportSpec *as = this->GetSpec();
    00312     const HangarTileTable *htt = GetHangarDataByTile(tile);
    00313     return ChangeDir(htt->dir, DirDifference(this->rotation, as->rotation[0]));
    00314   }
    00315
    00322   inline uint GetHangarNum(TileIndex tile) const
    00323   {
    00324     const HangarTileTable *htt = GetHangarDataByTile(tile);
    00325     return htt->hangar_num;
    00326   }
    00327
    00329   inline uint GetNumHangars() const
    00330   {
    00331     uint num = 0;
    00332     uint counted = 0;
    00333     const AirportSpec *as = this->GetSpec();
    00334     for (uint i = 0; i < as->nof_depots; i++) {
    00335       if (!HasBit(counted, as->depot_table[i].hangar_num)) {
    00336         num++;
    00337         SetBit(counted, as->depot_table[i].hangar_num);
    00338       }
    00339     }
    00340     return num;
    00341   }
    00342
    00343 private:
    00350   inline const HangarTileTable *GetHangarDataByTile(TileIndex tile) const
    00351   {
    00352     const AirportSpec *as = this->GetSpec();
    00353     for (uint i = 0; i < as->nof_depots; i++) {
    00354       if (this->GetRotatedTileFromOffset(as->depot_table[i].ti) == tile) {
    00355         return as->depot_table + i;
    00356       }
    00357     }
    00358     NOT_REACHED();
    00359   }
    00360 };
    00361
    00362 typedef SmallVector<Industry *, 2> IndustryVector;
    00363
    00365 struct Station FINAL : SpecializedStation<Station, false> {
    00366 public:
    00367   RoadStop *GetPrimaryRoadStop(RoadStopType type) const
    00368   {
    00369     return type == ROADSTOP_BUS ? bus_stops : truck_stops;
    00370   }
    00371
    00372   RoadStop *GetPrimaryRoadStop(const struct RoadVehicle *v) const;
    00373
    00374   RoadStop *bus_stops;
    00375   TileArea bus_station;
    00376   RoadStop *truck_stops;
    00377   TileArea truck_station;
    00378
    00379   Airport airport;
    00380   TileIndex dock_tile;
    00381
    00382   IndustryType indtype;
    00383
    00384   StationHadVehicleOfTypeByte had_vehicle_of_type;
    00385
    00386   byte time_since_load;
    00387   byte time_since_unload;
    00388
    00389   byte last_vehicle_type;
    00390   std::list<Vehicle *> loading_vehicles;
    00391   GoodsEntry goods[NUM_CARGO];
    00392   uint32 always_accepted;
    00393
    00394   IndustryVector industries_near;
    00395
    00396   Station(TileIndex tile = INVALID_TILE);
    00397   ~Station();
    00398
    00399   void AddFacility(StationFacility new_facility_bit, TileIndex facil_xy);
    00400
    00401   void MarkTilesDirty(bool cargo_change) const;
    00402
    00403   void UpdateVirtCoord();
    00404
    00405   /* virtual */ uint GetPlatformLength(TileIndex tile, DiagDirection dir) const;
    00406   /* virtual */ uint GetPlatformLength(TileIndex tile) const;
    00407   void RecomputeIndustriesNear();
    00408   static void RecomputeIndustriesNearForAll();
    00409
    00410   uint GetCatchmentRadius() const;
    00411   Rect GetCatchmentRect() const;
    00412
    00413   /* virtual */ inline bool TileBelongsToRailStation(TileIndex tile) const
    00414   {
    00415     return IsRailStationTile(tile) && GetStationIndex(tile) == this->index;
    00416   }
    00417
    00418   inline bool TileBelongsToAirport(TileIndex tile) const
    00419   {
    00420     return IsAirportTile(tile) && GetStationIndex(tile) == this->index;
    00421   }
    00422
    00423   /* virtual */ uint32 GetNewGRFVariable(const ResolverObject *object, byte variable, byte parameter, bool *available) const;
    00424
    00425   /* virtual */ void GetTileArea(TileArea *ta, StationType type) const;
    00426
    00427   void RunAverages();
    00428 };
    00429
    00430 #define FOR_ALL_STATIONS(var) FOR_ALL_BASE_STATIONS_OF_TYPE(Station, var)
    00431
    00433 class AirportTileIterator : public OrthogonalTileIterator {
    00434 private:
    00435   const Station *st;
    00436
    00437 public:
    00442   AirportTileIterator(const Station *st) : OrthogonalTileIterator(st->airport), st(st)
    00443   {
    00444     if (!st->TileBelongsToAirport(this->tile)) ++(*this);
    00445   }
    00446
    00447   inline TileIterator& operator ++()
    00448   {
    00449     (*this).OrthogonalTileIterator::operator++();
    00450     while (this->tile != INVALID_TILE && !st->TileBelongsToAirport(this->tile)) {
    00451       (*this).OrthogonalTileIterator::operator++();
    00452     }
    00453     return *this;
    00454   }
    00455
    00456   virtual TileIterator *Clone() const
    00457   {
    00458     return new AirportTileIterator(*this);
    00459   }
    00460 };
    00461
    00462 #endif /* STATION_BASE_H */