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 #include "town.h"
00021
00022 typedef Pool<BaseStation, StationID, 32, 64000> StationPool;
00023 extern StationPool _station_pool;
00024
00025 static const byte INITIAL_STATION_RATING = 175;
00026
00030 struct GoodsEntry {
00032 enum GoodsEntryStatus {
00033 GES_ACCEPTANCE,
00034 GES_PICKUP,
00035 GES_EVER_ACCEPTED,
00036 GES_LAST_MONTH,
00037 GES_CURRENT_MONTH,
00038 GES_ACCEPTED_BIGTICK,
00039 };
00040
00041 GoodsEntry() :
00042 acceptance_pickup(0),
00043 days_since_pickup(255),
00044 rating(INITIAL_STATION_RATING),
00045 last_speed(0),
00046 last_age(255)
00047 {}
00048
00049 byte acceptance_pickup;
00050 byte days_since_pickup;
00051 byte rating;
00052 byte last_speed;
00053 byte last_age;
00054 byte amount_fract;
00055 StationCargoList cargo;
00056 };
00057
00059 struct Airport : public TileArea {
00060 Airport() : TileArea(INVALID_TILE, 0, 0) {}
00061
00062 uint64 flags;
00063 byte type;
00064 byte layout;
00065 Direction rotation;
00066
00067 PersistentStorage *psa;
00068
00074 const AirportSpec *GetSpec() const
00075 {
00076 if (this->tile == INVALID_TILE) return &AirportSpec::dummy;
00077 return AirportSpec::Get(this->type);
00078 }
00079
00086 const AirportFTAClass *GetFTA() const
00087 {
00088 return this->GetSpec()->fsm;
00089 }
00090
00092 inline bool HasHangar() const
00093 {
00094 return this->GetSpec()->nof_depots > 0;
00095 }
00096
00105 inline TileIndex GetRotatedTileFromOffset(TileIndexDiffC tidc) const
00106 {
00107 const AirportSpec *as = this->GetSpec();
00108 switch (this->rotation) {
00109 case DIR_N: return this->tile + ToTileIndexDiff(tidc);
00110
00111 case DIR_E: return this->tile + TileDiffXY(tidc.y, as->size_x - 1 - tidc.x);
00112
00113 case DIR_S: return this->tile + TileDiffXY(as->size_x - 1 - tidc.x, as->size_y - 1 - tidc.y);
00114
00115 case DIR_W: return this->tile + TileDiffXY(as->size_y - 1 - tidc.y, tidc.x);
00116
00117 default: NOT_REACHED();
00118 }
00119 }
00120
00127 inline TileIndex GetHangarTile(uint hangar_num) const
00128 {
00129 const AirportSpec *as = this->GetSpec();
00130 for (uint i = 0; i < as->nof_depots; i++) {
00131 if (as->depot_table[i].hangar_num == hangar_num) {
00132 return this->GetRotatedTileFromOffset(as->depot_table[i].ti);
00133 }
00134 }
00135 NOT_REACHED();
00136 }
00137
00144 inline Direction GetHangarExitDirection(TileIndex tile) const
00145 {
00146 const AirportSpec *as = this->GetSpec();
00147 const HangarTileTable *htt = GetHangarDataByTile(tile);
00148 return ChangeDir(htt->dir, DirDifference(this->rotation, as->rotation[0]));
00149 }
00150
00157 inline uint GetHangarNum(TileIndex tile) const
00158 {
00159 const HangarTileTable *htt = GetHangarDataByTile(tile);
00160 return htt->hangar_num;
00161 }
00162
00164 inline uint GetNumHangars() const
00165 {
00166 uint num = 0;
00167 uint counted = 0;
00168 const AirportSpec *as = this->GetSpec();
00169 for (uint i = 0; i < as->nof_depots; i++) {
00170 if (!HasBit(counted, as->depot_table[i].hangar_num)) {
00171 num++;
00172 SetBit(counted, as->depot_table[i].hangar_num);
00173 }
00174 }
00175 return num;
00176 }
00177
00178 private:
00185 inline const HangarTileTable *GetHangarDataByTile(TileIndex tile) const
00186 {
00187 const AirportSpec *as = this->GetSpec();
00188 for (uint i = 0; i < as->nof_depots; i++) {
00189 if (this->GetRotatedTileFromOffset(as->depot_table[i].ti) == tile) {
00190 return as->depot_table + i;
00191 }
00192 }
00193 NOT_REACHED();
00194 }
00195 };
00196
00197 typedef SmallVector<Industry *, 2> IndustryVector;
00198
00200 struct Station FINAL : SpecializedStation<Station, false> {
00201 public:
00202 RoadStop *GetPrimaryRoadStop(RoadStopType type) const
00203 {
00204 return type == ROADSTOP_BUS ? bus_stops : truck_stops;
00205 }
00206
00207 RoadStop *GetPrimaryRoadStop(const struct RoadVehicle *v) const;
00208
00209 RoadStop *bus_stops;
00210 TileArea bus_station;
00211 RoadStop *truck_stops;
00212 TileArea truck_station;
00213
00214 Airport airport;
00215 TileIndex dock_tile;
00216
00217 IndustryType indtype;
00218
00219 StationHadVehicleOfTypeByte had_vehicle_of_type;
00220
00221 byte time_since_load;
00222 byte time_since_unload;
00223
00224 byte last_vehicle_type;
00225 std::list<Vehicle *> loading_vehicles;
00226 GoodsEntry goods[NUM_CARGO];
00227 uint32 always_accepted;
00228
00229 IndustryVector industries_near;
00230
00231 Station(TileIndex tile = INVALID_TILE);
00232 ~Station();
00233
00234 void AddFacility(StationFacility new_facility_bit, TileIndex facil_xy);
00235
00236 void MarkTilesDirty(bool cargo_change) const;
00237
00238 void UpdateVirtCoord();
00239
00240 uint GetPlatformLength(TileIndex tile, DiagDirection dir) const;
00241 uint GetPlatformLength(TileIndex tile) const;
00242 void RecomputeIndustriesNear();
00243 static void RecomputeIndustriesNearForAll();
00244
00245 uint GetCatchmentRadius() const;
00246 Rect GetCatchmentRect() const;
00247
00248 inline bool TileBelongsToRailStation(TileIndex tile) const
00249 {
00250 return IsRailStationTile(tile) && GetStationIndex(tile) == this->index;
00251 }
00252
00253 inline bool TileBelongsToAirport(TileIndex tile) const
00254 {
00255 return IsAirportTile(tile) && GetStationIndex(tile) == this->index;
00256 }
00257
00258 uint32 GetNewGRFVariable(const ResolverObject *object, byte variable, byte parameter, bool *available) const;
00259
00260 void GetTileArea(TileArea *ta, StationType type) const;
00261 };
00262
00263 #define FOR_ALL_STATIONS(var) FOR_ALL_BASE_STATIONS_OF_TYPE(Station, var)
00264
00266 class AirportTileIterator : public OrthogonalTileIterator {
00267 private:
00268 const Station *st;
00269
00270 public:
00275 AirportTileIterator(const Station *st) : OrthogonalTileIterator(st->airport), st(st)
00276 {
00277 if (!st->TileBelongsToAirport(this->tile)) ++(*this);
00278 }
00279
00280 inline TileIterator& operator ++()
00281 {
00282 (*this).OrthogonalTileIterator::operator++();
00283 while (this->tile != INVALID_TILE && !st->TileBelongsToAirport(this->tile)) {
00284 (*this).OrthogonalTileIterator::operator++();
00285 }
00286 return *this;
00287 }
00288
00289 virtual TileIterator *Clone() const
00290 {
00291 return new AirportTileIterator(*this);
00292 }
00293 };
00294
00295 #endif