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
00026 struct GoodsEntry {
00027 enum AcceptancePickup {
00028 ACCEPTANCE,
00029 PICKUP
00030 };
00031
00032 GoodsEntry() :
00033 acceptance_pickup(0),
00034 days_since_pickup(255),
00035 rating(INITIAL_STATION_RATING),
00036 last_speed(0),
00037 last_age(255)
00038 {}
00039
00040 byte acceptance_pickup;
00041 byte days_since_pickup;
00042 byte rating;
00043 byte last_speed;
00044 byte last_age;
00045 byte amount_fract;
00046 StationCargoList cargo;
00047 };
00048
00050 struct Airport : public TileArea {
00051 typedef PersistentStorageArray<int32, 16> PersistentStorage;
00052
00053 Airport() : TileArea(INVALID_TILE, 0, 0) {}
00054
00055 uint64 flags;
00056 byte type;
00057 byte layout;
00058 Direction rotation;
00059 PersistentStorage psa;
00060
00066 const AirportSpec *GetSpec() const
00067 {
00068 if (this->tile == INVALID_TILE) return &AirportSpec::dummy;
00069 return AirportSpec::Get(this->type);
00070 }
00071
00078 const AirportFTAClass *GetFTA() const
00079 {
00080 return this->GetSpec()->fsm;
00081 }
00082
00084 FORCEINLINE bool HasHangar() const
00085 {
00086 return this->GetSpec()->nof_depots > 0;
00087 }
00088
00097 FORCEINLINE TileIndex GetRotatedTileFromOffset(TileIndexDiffC tidc) const
00098 {
00099 const AirportSpec *as = this->GetSpec();
00100 switch (this->rotation) {
00101 case DIR_N: return this->tile + ToTileIndexDiff(tidc);
00102
00103 case DIR_E: return this->tile + TileDiffXY(tidc.y, as->size_x - 1 - tidc.x);
00104
00105 case DIR_S: return this->tile + TileDiffXY(as->size_x - 1 - tidc.x, as->size_y - 1 - tidc.y);
00106
00107 case DIR_W: return this->tile + TileDiffXY(as->size_y - 1 - tidc.y, tidc.x);
00108
00109 default: NOT_REACHED();
00110 }
00111 }
00112
00119 FORCEINLINE TileIndex GetHangarTile(uint hangar_num) const
00120 {
00121 const AirportSpec *as = this->GetSpec();
00122 for (uint i = 0; i < as->nof_depots; i++) {
00123 if (as->depot_table[i].hangar_num == hangar_num) {
00124 return this->GetRotatedTileFromOffset(as->depot_table[i].ti);
00125 }
00126 }
00127 NOT_REACHED();
00128 }
00129
00136 FORCEINLINE Direction GetHangarExitDirection(TileIndex tile) const
00137 {
00138 const AirportSpec *as = this->GetSpec();
00139 const HangarTileTable *htt = GetHangarDataByTile(tile);
00140 return ChangeDir(htt->dir, DirDifference(this->rotation, as->rotation[0]));
00141 }
00142
00149 FORCEINLINE uint GetHangarNum(TileIndex tile) const
00150 {
00151 const HangarTileTable *htt = GetHangarDataByTile(tile);
00152 return htt->hangar_num;
00153 }
00154
00156 FORCEINLINE uint GetNumHangars() const
00157 {
00158 uint num = 0;
00159 uint counted = 0;
00160 const AirportSpec *as = this->GetSpec();
00161 for (uint i = 0; i < as->nof_depots; i++) {
00162 if (!HasBit(counted, as->depot_table[i].hangar_num)) {
00163 num++;
00164 SetBit(counted, as->depot_table[i].hangar_num);
00165 }
00166 }
00167 return num;
00168 }
00169
00170 private:
00177 FORCEINLINE const HangarTileTable *GetHangarDataByTile(TileIndex tile) const
00178 {
00179 const AirportSpec *as = this->GetSpec();
00180 for (uint i = 0; i < as->nof_depots; i++) {
00181 if (this->GetRotatedTileFromOffset(as->depot_table[i].ti) == tile) {
00182 return as->depot_table + i;
00183 }
00184 }
00185 NOT_REACHED();
00186 }
00187 };
00188
00189 typedef SmallVector<Industry *, 2> IndustryVector;
00190
00192 struct Station : SpecializedStation<Station, false> {
00193 public:
00194 RoadStop *GetPrimaryRoadStop(RoadStopType type) const
00195 {
00196 return type == ROADSTOP_BUS ? bus_stops : truck_stops;
00197 }
00198
00199 RoadStop *GetPrimaryRoadStop(const struct RoadVehicle *v) const;
00200
00201 RoadStop *bus_stops;
00202 TileArea bus_station;
00203 RoadStop *truck_stops;
00204 TileArea truck_station;
00205
00206 Airport airport;
00207 TileIndex dock_tile;
00208
00209 IndustryType indtype;
00210
00211 StationHadVehicleOfTypeByte had_vehicle_of_type;
00212
00213 byte time_since_load;
00214 byte time_since_unload;
00215
00216 byte last_vehicle_type;
00217 std::list<Vehicle *> loading_vehicles;
00218 GoodsEntry goods[NUM_CARGO];
00219 uint32 always_accepted;
00220
00221 IndustryVector industries_near;
00222
00223 Station(TileIndex tile = INVALID_TILE);
00224 ~Station();
00225
00226 void AddFacility(StationFacility new_facility_bit, TileIndex facil_xy);
00227
00228 void MarkTilesDirty(bool cargo_change) const;
00229
00230 void UpdateVirtCoord();
00231
00232 uint GetPlatformLength(TileIndex tile, DiagDirection dir) const;
00233 uint GetPlatformLength(TileIndex tile) const;
00234 void RecomputeIndustriesNear();
00235 static void RecomputeIndustriesNearForAll();
00236
00237 uint GetCatchmentRadius() const;
00238 Rect GetCatchmentRect() const;
00239
00240 FORCEINLINE bool TileBelongsToRailStation(TileIndex tile) const
00241 {
00242 return IsRailStationTile(tile) && GetStationIndex(tile) == this->index;
00243 }
00244
00245 FORCEINLINE bool TileBelongsToAirport(TileIndex tile) const
00246 {
00247 return IsAirportTile(tile) && GetStationIndex(tile) == this->index;
00248 }
00249
00250 uint32 GetNewGRFVariable(const ResolverObject *object, byte variable, byte parameter, bool *available) const;
00251
00252 void GetTileArea(TileArea *ta, StationType type) const;
00253 };
00254
00255 #define FOR_ALL_STATIONS(var) FOR_ALL_BASE_STATIONS_OF_TYPE(Station, var)
00256
00257 #endif