1 /* $Id$ */ |
|
2 |
|
3 /** @file station.h */ |
|
4 |
|
5 #ifndef STATION_H |
|
6 #define STATION_H |
|
7 |
|
8 #include "airport.h" |
|
9 #include "oldpool.h" |
|
10 #include "sprite.h" |
|
11 #include "road_type.h" |
|
12 #include "newgrf_station.h" |
|
13 #include "newgrf_fsmports.h" |
|
14 #include "cargopacket.h" |
|
15 #include "cargo_type.h" |
|
16 #include "town_type.h" |
|
17 #include "core/geometry_type.hpp" |
|
18 #include <list> |
|
19 #include <set> |
|
20 |
|
21 struct Station; |
|
22 struct RoadStop; |
|
23 |
|
24 DECLARE_OLD_POOL(Station, Station, 6, 1000) |
|
25 DECLARE_OLD_POOL(RoadStop, RoadStop, 5, 2000) |
|
26 |
|
27 static const byte INITIAL_STATION_RATING = 175; |
|
28 |
|
29 struct GoodsEntry { |
|
30 enum AcceptancePickup { |
|
31 ACCEPTANCE, |
|
32 PICKUP |
|
33 }; |
|
34 |
|
35 GoodsEntry() : |
|
36 acceptance_pickup(0), |
|
37 days_since_pickup(255), |
|
38 rating(INITIAL_STATION_RATING), |
|
39 last_speed(0), |
|
40 last_age(255) |
|
41 {} |
|
42 |
|
43 byte acceptance_pickup; |
|
44 byte days_since_pickup; |
|
45 byte rating; |
|
46 byte last_speed; |
|
47 byte last_age; |
|
48 CargoList cargo; ///< The cargo packets of cargo waiting in this station |
|
49 }; |
|
50 |
|
51 /** A Stop for a Road Vehicle */ |
|
52 struct RoadStop : PoolItem<RoadStop, RoadStopID, &_RoadStop_pool> { |
|
53 /** Types of RoadStops */ |
|
54 enum Type { |
|
55 BUS, ///< A standard stop for buses |
|
56 TRUCK ///< A standard stop for trucks |
|
57 }; |
|
58 |
|
59 static const int cDebugCtorLevel = 5; ///< Debug level on which Contructor / Destructor messages are printed |
|
60 static const uint LIMIT = 16; ///< The maximum amount of roadstops that are allowed at a single station |
|
61 static const uint MAX_BAY_COUNT = 2; ///< The maximum number of loading bays |
|
62 |
|
63 TileIndex xy; ///< Position on the map |
|
64 byte status; ///< Current status of the Stop. Like which spot is taken. Access using *Bay and *Busy functions. |
|
65 byte num_vehicles; ///< Number of vehicles currently slotted to this stop |
|
66 struct RoadStop *next; ///< Next stop of the given type at this station |
|
67 |
|
68 RoadStop(TileIndex tile = 0); |
|
69 virtual ~RoadStop(); |
|
70 |
|
71 /** |
|
72 * Determines whether a road stop exists |
|
73 * @return true if and only is the road stop exists |
|
74 */ |
|
75 inline bool IsValid() const { return this->xy != 0; } |
|
76 |
|
77 /* For accessing status */ |
|
78 bool HasFreeBay() const; |
|
79 bool IsFreeBay(uint nr) const; |
|
80 uint AllocateBay(); |
|
81 void AllocateDriveThroughBay(uint nr); |
|
82 void FreeBay(uint nr); |
|
83 bool IsEntranceBusy() const; |
|
84 void SetEntranceBusy(bool busy); |
|
85 |
|
86 RoadStop *GetNextRoadStop(const Vehicle *v) const; |
|
87 }; |
|
88 |
|
89 struct StationSpecList { |
|
90 const StationSpec *spec; |
|
91 uint32 grfid; ///< GRF ID of this custom station |
|
92 uint8 localidx; ///< Station ID within GRF of station |
|
93 }; |
|
94 |
|
95 struct FSMportsSpecList { |
|
96 const FSMportsSpec *spec; |
|
97 uint32 grfid; ///< GRF ID of this custom station |
|
98 uint8 localidx; ///< Station ID within GRF of station |
|
99 }; |
|
100 |
|
101 /** StationRect - used to track station spread out rectangle - cheaper than scanning whole map */ |
|
102 struct StationRect : public Rect { |
|
103 enum StationRectMode |
|
104 { |
|
105 ADD_TEST = 0, |
|
106 ADD_TRY, |
|
107 ADD_FORCE |
|
108 }; |
|
109 |
|
110 StationRect(); |
|
111 void MakeEmpty(); |
|
112 bool PtInExtendedRect(int x, int y, int distance = 0) const; |
|
113 bool IsEmpty() const; |
|
114 bool BeforeAddTile(TileIndex tile, StationRectMode mode); |
|
115 bool BeforeAddRect(TileIndex tile, int w, int h, StationRectMode mode); |
|
116 bool AfterRemoveTile(Station *st, TileIndex tile); |
|
117 bool AfterRemoveRect(Station *st, TileIndex tile, int w, int h); |
|
118 |
|
119 static bool ScanForStationTiles(StationID st_id, int left_a, int top_a, int right_a, int bottom_a); |
|
120 |
|
121 StationRect& operator = (Rect src); |
|
122 }; |
|
123 |
|
124 struct Station : PoolItem<Station, StationID, &_Station_pool> { |
|
125 public: |
|
126 RoadStop *GetPrimaryRoadStop(RoadStop::Type type) const |
|
127 { |
|
128 return type == RoadStop::BUS ? bus_stops : truck_stops; |
|
129 } |
|
130 |
|
131 RoadStop *GetPrimaryRoadStop(const Vehicle *v) const; |
|
132 |
|
133 const AirportFTAClass *Airport() const |
|
134 { |
|
135 return IsCustomFSMportsSpecIndex(airport_tile) ? fsmportsspeclist[1].spec->portFSM : AirportFTAClass::dummy; |
|
136 } |
|
137 |
|
138 TileIndex xy; |
|
139 RoadStop *bus_stops; |
|
140 RoadStop *truck_stops; |
|
141 TileIndex train_tile; |
|
142 TileIndex airport_tile; |
|
143 TileIndex dock_tile; |
|
144 Town *town; |
|
145 StringID string_id; ///< Default name (town area) of station |
|
146 char *name; ///< Custom name |
|
147 |
|
148 ViewportSign sign; |
|
149 |
|
150 uint16 had_vehicle_of_type; |
|
151 |
|
152 byte time_since_load; |
|
153 byte time_since_unload; |
|
154 byte delete_ctr; |
|
155 PlayerByte owner; |
|
156 byte facilities; |
|
157 byte airport_type; |
|
158 byte FSMport_layout_set; /* indicates which layout set (S) of several in an FSMport spec->layouts[S] to use */ |
|
159 byte FSMport_orientation; /* direction of orientation of station for use with FSMports */ |
|
160 bool FSMport_flood_protected; /* prevents flooding destroying water based FSMports */ |
|
161 |
|
162 /* trainstation width/height */ |
|
163 byte trainst_w, trainst_h; |
|
164 |
|
165 /** List of custom stations (StationSpecs) allocated to the station */ |
|
166 uint8 num_specs; |
|
167 StationSpecList *speclist; |
|
168 uint8 num_fsmportsspecs; |
|
169 FSMportsSpecList *fsmportsspeclist; |
|
170 |
|
171 Date build_date; |
|
172 |
|
173 FSMblockmap airport_flags; ///< stores which blocks on the port are taken |
|
174 |
|
175 byte last_vehicle_type; |
|
176 std::list<Vehicle *> loading_vehicles; |
|
177 GoodsEntry goods[NUM_CARGO]; |
|
178 |
|
179 uint16 random_bits; |
|
180 byte waiting_triggers; |
|
181 |
|
182 StationRect rect; ///< Station spread out rectangle (not saved) maintained by StationRect_xxx() functions |
|
183 |
|
184 static const int cDebugCtorLevel = 5; |
|
185 |
|
186 Station(TileIndex tile = 0); |
|
187 virtual ~Station(); |
|
188 |
|
189 void AddFacility(byte new_facility_bit, TileIndex facil_xy); |
|
190 |
|
191 /** |
|
192 * Mark the sign of a station dirty for repaint. |
|
193 * |
|
194 * @ingroup dirty |
|
195 */ |
|
196 void MarkDirty() const; |
|
197 |
|
198 /** |
|
199 * Marks the tiles of the station as dirty. |
|
200 * |
|
201 * @ingroup dirty |
|
202 */ |
|
203 void MarkTilesDirty(bool cargo_change) const; |
|
204 bool TileBelongsToRailStation(TileIndex tile) const; |
|
205 uint GetPlatformLength(TileIndex tile, DiagDirection dir) const; |
|
206 uint GetPlatformLength(TileIndex tile) const; |
|
207 bool IsBuoy() const; |
|
208 |
|
209 /** |
|
210 * Determines whether a station exists |
|
211 * @return true if and only is the station exists |
|
212 */ |
|
213 inline bool IsValid() const { return this->xy != 0; } |
|
214 }; |
|
215 |
|
216 enum StationType { |
|
217 STATION_RAIL, |
|
218 STATION_AIRPORT, |
|
219 STATION_TRUCK, |
|
220 STATION_BUS, |
|
221 STATION_OILRIG, |
|
222 STATION_DOCK, |
|
223 STATION_BUOY |
|
224 }; |
|
225 |
|
226 enum { |
|
227 FACIL_TRAIN = 0x01, |
|
228 FACIL_TRUCK_STOP = 0x02, |
|
229 FACIL_BUS_STOP = 0x04, |
|
230 FACIL_AIRPORT = 0x08, |
|
231 FACIL_DOCK = 0x10, |
|
232 }; |
|
233 |
|
234 enum { |
|
235 // HVOT_PENDING_DELETE = 1 << 0, // not needed anymore |
|
236 HVOT_TRAIN = 1 << 1, |
|
237 HVOT_BUS = 1 << 2, |
|
238 HVOT_TRUCK = 1 << 3, |
|
239 HVOT_AIRCRAFT = 1 << 4, |
|
240 HVOT_SHIP = 1 << 5, |
|
241 /* This bit is used to mark stations. No, it does not belong here, but what |
|
242 * can we do? ;-) */ |
|
243 HVOT_BUOY = 1 << 6 |
|
244 }; |
|
245 |
|
246 enum CatchmentArea { |
|
247 CA_NONE = 0, |
|
248 CA_BUS = 3, |
|
249 CA_TRUCK = 3, |
|
250 CA_TRAIN = 4, |
|
251 CA_DOCK = 5, |
|
252 |
|
253 CA_UNMODIFIED = 4, ///< Used when _patches.modified_catchment is false |
|
254 |
|
255 MAX_CATCHMENT = 10, ///< Airports have a catchment up to this number. |
|
256 }; |
|
257 |
|
258 void ModifyStationRatingAround(TileIndex tile, PlayerID owner, int amount, uint radius); |
|
259 |
|
260 /** A set of stations (\c const \c Station* ) */ |
|
261 typedef std::set<Station*> StationSet; |
|
262 |
|
263 StationSet FindStationsAroundIndustryTile(TileIndex tile, int w, int h); |
|
264 |
|
265 void ShowStationViewWindow(StationID station); |
|
266 void UpdateAllStationVirtCoord(); |
|
267 |
|
268 static inline StationID GetMaxStationIndex() |
|
269 { |
|
270 /* TODO - This isn't the real content of the function, but |
|
271 * with the new pool-system this will be replaced with one that |
|
272 * _really_ returns the highest index. Now it just returns |
|
273 * the next safe value we are sure about everything is below. |
|
274 */ |
|
275 return GetStationPoolSize() - 1; |
|
276 } |
|
277 |
|
278 static inline uint GetNumStations() |
|
279 { |
|
280 return GetStationPoolSize(); |
|
281 } |
|
282 |
|
283 static inline bool IsValidStationID(StationID index) |
|
284 { |
|
285 return index < GetStationPoolSize() && GetStation(index)->IsValid(); |
|
286 } |
|
287 |
|
288 #define FOR_ALL_STATIONS_FROM(st, start) for (st = GetStation(start); st != NULL; st = (st->index + 1U < GetStationPoolSize()) ? GetStation(st->index + 1U) : NULL) if (st->IsValid()) |
|
289 #define FOR_ALL_STATIONS(st) FOR_ALL_STATIONS_FROM(st, 0) |
|
290 |
|
291 |
|
292 /* Stuff for ROADSTOPS */ |
|
293 |
|
294 #define FOR_ALL_ROADSTOPS_FROM(rs, start) for (rs = GetRoadStop(start); rs != NULL; rs = (rs->index + 1U < GetRoadStopPoolSize()) ? GetRoadStop(rs->index + 1U) : NULL) if (rs->IsValid()) |
|
295 #define FOR_ALL_ROADSTOPS(rs) FOR_ALL_ROADSTOPS_FROM(rs, 0) |
|
296 |
|
297 /* End of stuff for ROADSTOPS */ |
|
298 |
|
299 |
|
300 void AfterLoadStations(); |
|
301 void GetProductionAroundTiles(AcceptedCargo produced, TileIndex tile, int w, int h, int rad); |
|
302 void GetAcceptanceAroundTiles(AcceptedCargo accepts, TileIndex tile, int w, int h, int rad); |
|
303 |
|
304 |
|
305 const DrawTileSprites *GetStationTileLayout(StationType st, byte gfx); |
|
306 void StationPickerDrawSprite(int x, int y, StationType st, RailType railtype, RoadType roadtype, int image); |
|
307 |
|
308 RoadStop * GetRoadStopByTile(TileIndex tile, RoadStop::Type type); |
|
309 uint GetNumRoadStops(const Station* st, RoadStop::Type type); |
|
310 RoadStop * AllocateRoadStop(); |
|
311 void ClearSlot(Vehicle *v); |
|
312 |
|
313 bool HasStationInUse(StationID station, PlayerID player); |
|
314 |
|
315 void DeleteOilRig(TileIndex t); |
|
316 |
|
317 #endif /* STATION_H */ |
|