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
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 uint GetPlatformLength(TileIndex tile, DiagDirection dir) const;
00240 uint GetPlatformLength(TileIndex tile) const;
00241 void RecomputeIndustriesNear();
00242 static void RecomputeIndustriesNearForAll();
00243
00244 uint GetCatchmentRadius() const;
00245 Rect GetCatchmentRect() const;
00246
00247 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 uint32 GetNewGRFVariable(const ResolverObject *object, byte variable, byte parameter, bool *available) const;
00258
00259 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