Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
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 uint GetPlatformLength(TileIndex tile, DiagDirection dir) const;
00244 uint GetPlatformLength(TileIndex tile) const;
00245 void RecomputeIndustriesNear();
00246 static void RecomputeIndustriesNearForAll();
00247
00248 uint GetCatchmentRadius() const;
00249 Rect GetCatchmentRect() const;
00250
00251 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 uint32 GetNewGRFVariable(const ResolverObject *object, byte variable, byte parameter, bool *available) const;
00262
00263 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