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 {
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 uint GetPlatformLength(TileIndex tile, DiagDirection dir) const;
00302 uint GetPlatformLength(TileIndex tile) const;
00303 void RecomputeIndustriesNear();
00304 static void RecomputeIndustriesNearForAll();
00305
00306 uint GetCatchmentRadius() const;
00307 Rect GetCatchmentRect() const;
00308
00309 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 uint32 GetNewGRFVariable(const ResolverObject *object, byte variable, byte parameter, bool *available) const;
00320
00321 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