|
1 /* $Id$ */ |
|
2 |
|
3 /** @file vehicle_base.h Base class for all vehicles. */ |
|
4 |
|
5 #ifndef VEHICLE_BASE_H |
|
6 #define VEHICLE_BASE_H |
|
7 |
|
8 #include "vehicle_type.h" |
|
9 #include "track_type.h" |
|
10 #include "rail_type.h" |
|
11 #include "road_type.h" |
|
12 #include "cargo_type.h" |
|
13 #include "direction_type.h" |
|
14 #include "window_type.h" |
|
15 #include "gfx_type.h" |
|
16 #include "command_type.h" |
|
17 #include "date_type.h" |
|
18 #include "player_type.h" |
|
19 #include "oldpool.h" |
|
20 #include "order.h" |
|
21 #include "cargopacket.h" |
|
22 #include "texteff.hpp" |
|
23 #include "fsmblockmap.h" |
|
24 |
|
25 /** Road vehicle states */ |
|
26 enum RoadVehicleStates { |
|
27 /* |
|
28 * Lower 4 bits are used for vehicle track direction. (Trackdirs) |
|
29 * When in a road stop (bit 5 or bit 6 set) these bits give the |
|
30 * track direction of the entry to the road stop. |
|
31 * As the entry direction will always be a diagonal |
|
32 * direction (X_NE, Y_SE, X_SW or Y_NW) only bits 0 and 3 |
|
33 * are needed to hold this direction. Bit 1 is then used to show |
|
34 * that the vehicle is using the second road stop bay. |
|
35 * Bit 2 is then used for drive-through stops to show the vehicle |
|
36 * is stopping at this road stop. |
|
37 */ |
|
38 |
|
39 /* Numeric values */ |
|
40 RVSB_IN_DEPOT = 0xFE, ///< The vehicle is in a depot |
|
41 RVSB_WORMHOLE = 0xFF, ///< The vehicle is in a tunnel and/or bridge |
|
42 |
|
43 /* Bit numbers */ |
|
44 RVS_USING_SECOND_BAY = 1, ///< Only used while in a road stop |
|
45 RVS_IS_STOPPING = 2, ///< Only used for drive-through stops. Vehicle will stop here |
|
46 RVS_DRIVE_SIDE = 4, ///< Only used when retrieving move data |
|
47 RVS_IN_ROAD_STOP = 5, ///< The vehicle is in a road stop |
|
48 RVS_IN_DT_ROAD_STOP = 6, ///< The vehicle is in a drive-through road stop |
|
49 |
|
50 /* Bit sets of the above specified bits */ |
|
51 RVSB_IN_ROAD_STOP = 1 << RVS_IN_ROAD_STOP, ///< The vehicle is in a road stop |
|
52 RVSB_IN_ROAD_STOP_END = RVSB_IN_ROAD_STOP + TRACKDIR_END, |
|
53 RVSB_IN_DT_ROAD_STOP = 1 << RVS_IN_DT_ROAD_STOP, ///< The vehicle is in a drive-through road stop |
|
54 RVSB_IN_DT_ROAD_STOP_END = RVSB_IN_DT_ROAD_STOP + TRACKDIR_END, |
|
55 |
|
56 RVSB_TRACKDIR_MASK = 0x0F, ///< The mask used to extract track dirs |
|
57 RVSB_ROAD_STOP_TRACKDIR_MASK = 0x09 ///< Only bits 0 and 3 are used to encode the trackdir for road stops |
|
58 }; |
|
59 |
|
60 enum VehStatus { |
|
61 VS_HIDDEN = 0x01, |
|
62 VS_STOPPED = 0x02, |
|
63 VS_UNCLICKABLE = 0x04, |
|
64 VS_DEFPAL = 0x08, |
|
65 VS_TRAIN_SLOWING = 0x10, |
|
66 VS_SHADOW = 0x20, |
|
67 VS_AIRCRAFT_BROKEN = 0x40, |
|
68 VS_CRASHED = 0x80, |
|
69 }; |
|
70 |
|
71 enum VehicleFlags { |
|
72 VF_LOADING_FINISHED, |
|
73 VF_CARGO_UNLOADING, |
|
74 VF_BUILT_AS_PROTOTYPE, |
|
75 VF_TIMETABLE_STARTED, ///< Whether the vehicle has started running on the timetable yet. |
|
76 VF_AUTOFILL_TIMETABLE, ///< Whether the vehicle should fill in the timetable automatically. |
|
77 }; |
|
78 |
|
79 struct VehicleRail { |
|
80 uint16 last_speed; // NOSAVE: only used in UI |
|
81 uint16 crash_anim_pos; |
|
82 |
|
83 /* cached values, recalculated on load and each time a vehicle is added to/removed from the consist. */ |
|
84 uint16 cached_max_speed; // max speed of the consist. (minimum of the max speed of all vehicles in the consist) |
|
85 uint32 cached_power; // total power of the consist. |
|
86 bool cached_tilt; // train can tilt; feature provides a bonus in curves |
|
87 uint8 cached_veh_length; // length of this vehicle in units of 1/8 of normal length, cached because this can be set by a callback |
|
88 uint16 cached_total_length; ///< Length of the whole train, valid only for first engine. |
|
89 |
|
90 /* cached values, recalculated when the cargo on a train changes (in addition to the conditions above) */ |
|
91 uint32 cached_weight; // total weight of the consist. |
|
92 uint32 cached_veh_weight; // weight of the vehicle. |
|
93 uint32 cached_max_te; // max tractive effort of consist |
|
94 /** |
|
95 * Position/type of visual effect. |
|
96 * bit 0 - 3 = position of effect relative to vehicle. (0 = front, 8 = centre, 15 = rear) |
|
97 * bit 4 - 5 = type of effect. (0 = default for engine class, 1 = steam, 2 = diesel, 3 = electric) |
|
98 * bit 6 = disable visual effect. |
|
99 * bit 7 = disable powered wagons. |
|
100 */ |
|
101 byte cached_vis_effect; |
|
102 byte user_def_data; |
|
103 |
|
104 /* NOSAVE: for wagon override - id of the first engine in train |
|
105 * 0xffff == not in train */ |
|
106 EngineID first_engine; |
|
107 |
|
108 TrackBitsByte track; |
|
109 byte force_proceed; |
|
110 RailTypeByte railtype; |
|
111 RailTypes compatible_railtypes; |
|
112 |
|
113 byte flags; |
|
114 |
|
115 /* Link between the two ends of a multiheaded engine */ |
|
116 Vehicle *other_multiheaded_part; |
|
117 |
|
118 /* Cached wagon override spritegroup */ |
|
119 const struct SpriteGroup *cached_override; |
|
120 }; |
|
121 |
|
122 enum { |
|
123 VRF_REVERSING = 0, |
|
124 |
|
125 /* used to calculate if train is going up or down */ |
|
126 VRF_GOINGUP = 1, |
|
127 VRF_GOINGDOWN = 2, |
|
128 |
|
129 /* used to store if a wagon is powered or not */ |
|
130 VRF_POWEREDWAGON = 3, |
|
131 |
|
132 /* used to reverse the visible direction of the vehicle */ |
|
133 VRF_REVERSE_DIRECTION = 4, |
|
134 |
|
135 /* used to mark train as lost because PF can't find the route */ |
|
136 VRF_NO_PATH_TO_DESTINATION = 5, |
|
137 |
|
138 /* used to mark that electric train engine is allowed to run on normal rail */ |
|
139 VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL = 6, |
|
140 }; |
|
141 |
|
142 struct VehicleAir { |
|
143 uint16 crashed_counter; |
|
144 uint16 cached_max_speed; |
|
145 byte pos; |
|
146 byte previous_pos; |
|
147 StationID targetairport; |
|
148 byte state; |
|
149 FSMblockmap owned_blocks; |
|
150 }; |
|
151 |
|
152 struct VehicleRoad { |
|
153 byte state; ///< @see RoadVehicleStates |
|
154 byte frame; |
|
155 uint16 blocked_ctr; |
|
156 byte overtaking; |
|
157 byte overtaking_ctr; |
|
158 uint16 crashed_ctr; |
|
159 byte reverse_ctr; |
|
160 struct RoadStop *slot; |
|
161 byte slot_age; |
|
162 EngineID first_engine; |
|
163 byte cached_veh_length; |
|
164 |
|
165 RoadType roadtype; |
|
166 RoadTypes compatible_roadtypes; |
|
167 }; |
|
168 |
|
169 struct VehicleSpecial { |
|
170 uint16 animation_state; |
|
171 byte animation_substate; |
|
172 }; |
|
173 |
|
174 struct VehicleDisaster { |
|
175 uint16 image_override; |
|
176 VehicleID big_ufo_destroyer_target; |
|
177 }; |
|
178 |
|
179 struct VehicleShip { |
|
180 TrackBitsByte state; |
|
181 }; |
|
182 |
|
183 DECLARE_OLD_POOL(Vehicle, Vehicle, 9, 125) |
|
184 |
|
185 /* Some declarations of functions, so we can make them friendly */ |
|
186 struct SaveLoad; |
|
187 extern const SaveLoad *GetVehicleDescription(VehicleType vt); |
|
188 extern void AfterLoadVehicles(bool clear_te_id); |
|
189 struct LoadgameState; |
|
190 extern bool LoadOldVehicle(LoadgameState *ls, int num); |
|
191 |
|
192 struct Vehicle : PoolItem<Vehicle, VehicleID, &_Vehicle_pool>, BaseVehicle { |
|
193 byte subtype; // subtype (Filled with values from EffectVehicles/TrainSubTypes/AircraftSubTypes) |
|
194 |
|
195 private: |
|
196 Vehicle *next; // pointer to the next vehicle in the chain |
|
197 Vehicle *previous; // NOSAVE: pointer to the previous vehicle in the chain |
|
198 Vehicle *first; // NOSAVE: pointer to the first vehicle in the chain |
|
199 public: |
|
200 friend const SaveLoad *GetVehicleDescription(VehicleType vt); // So we can use private/protected variables in the saveload code |
|
201 friend void AfterLoadVehicles(bool clear_te_id); // So we can set the previous and first pointers while loading |
|
202 friend bool LoadOldVehicle(LoadgameState *ls, int num); // So we can set the proper next pointer while loading |
|
203 |
|
204 Vehicle *depot_list; // NOSAVE: linked list to tell what vehicles entered a depot during the last tick. Used by autoreplace |
|
205 |
|
206 char *name; ///< Name of vehicle |
|
207 |
|
208 UnitID unitnumber; // unit number, for display purposes only |
|
209 PlayerByte owner; // which player owns the vehicle? |
|
210 |
|
211 TileIndex tile; // Current tile index |
|
212 TileIndex dest_tile; // Heading for this tile |
|
213 |
|
214 int32 x_pos; // coordinates |
|
215 int32 y_pos; |
|
216 byte z_pos; |
|
217 DirectionByte direction; // facing |
|
218 |
|
219 byte spritenum; // currently displayed sprite index |
|
220 // 0xfd == custom sprite, 0xfe == custom second head sprite |
|
221 // 0xff == reserved for another custom sprite |
|
222 uint16 cur_image; // sprite number for this vehicle |
|
223 byte sprite_width; // width of vehicle sprite |
|
224 byte sprite_height; // height of vehicle sprite |
|
225 byte z_height; // z-height of vehicle sprite |
|
226 int8 x_offs; // x offset for vehicle sprite |
|
227 int8 y_offs; // y offset for vehicle sprite |
|
228 EngineID engine_type; |
|
229 |
|
230 TextEffectID fill_percent_te_id; // a text-effect id to a loading indicator object |
|
231 |
|
232 /* for randomized variational spritegroups |
|
233 * bitmask used to resolve them; parts of it get reseeded when triggers |
|
234 * of corresponding spritegroups get matched */ |
|
235 byte random_bits; |
|
236 byte waiting_triggers; // triggers to be yet matched |
|
237 |
|
238 uint16 max_speed; // maximum speed |
|
239 uint16 cur_speed; // current speed |
|
240 byte subspeed; // fractional speed |
|
241 byte acceleration; // used by train & aircraft |
|
242 byte progress; |
|
243 uint32 motion_counter; |
|
244 |
|
245 byte vehstatus; // Status |
|
246 StationID last_station_visited; |
|
247 |
|
248 CargoID cargo_type; // type of cargo this vehicle is carrying |
|
249 uint16 cargo_cap; // total capacity |
|
250 byte cargo_subtype; ///< Used for livery refits (NewGRF variations) |
|
251 CargoList cargo; ///< The cargo this vehicle is carrying |
|
252 |
|
253 |
|
254 byte day_counter; // increased by one for each day |
|
255 byte tick_counter; // increased by one for each tick |
|
256 |
|
257 /* Begin Order-stuff */ |
|
258 Order current_order; ///< The current order (+ status, like: loading) |
|
259 VehicleOrderID cur_order_index; ///< The index to the current order |
|
260 |
|
261 Order *orders; ///< Pointer to the first order for this vehicle |
|
262 VehicleOrderID num_orders; ///< How many orders there are in the list |
|
263 |
|
264 Vehicle *next_shared; ///< If not NULL, this points to the next vehicle that shared the order |
|
265 Vehicle *prev_shared; ///< If not NULL, this points to the prev vehicle that shared the order |
|
266 /* End Order-stuff */ |
|
267 |
|
268 /* Boundaries for the current position in the world and a next hash link. |
|
269 * NOSAVE: All of those can be updated with VehiclePositionChanged() */ |
|
270 int32 left_coord; |
|
271 int32 top_coord; |
|
272 int32 right_coord; |
|
273 int32 bottom_coord; |
|
274 Vehicle *next_hash; |
|
275 Vehicle *next_new_hash; |
|
276 Vehicle **old_new_hash; |
|
277 |
|
278 /* Related to age and service time */ |
|
279 Date age; // Age in days |
|
280 Date max_age; // Maximum age |
|
281 Date date_of_last_service; |
|
282 Date service_interval; |
|
283 uint16 reliability; |
|
284 uint16 reliability_spd_dec; |
|
285 byte breakdown_ctr; |
|
286 byte breakdown_delay; |
|
287 byte breakdowns_since_last_service; |
|
288 byte breakdown_chance; |
|
289 Year build_year; |
|
290 |
|
291 bool leave_depot_instantly; // NOSAVE: stores if the vehicle needs to leave the depot it just entered. Used by autoreplace |
|
292 |
|
293 uint16 load_unload_time_rem; |
|
294 byte vehicle_flags; // Used for gradual loading and other miscellaneous things (@see VehicleFlags enum) |
|
295 |
|
296 Money profit_this_year; |
|
297 Money profit_last_year; |
|
298 Money value; |
|
299 |
|
300 GroupID group_id; ///< Index of group Pool array |
|
301 |
|
302 /* Used for timetabling. */ |
|
303 uint32 current_order_time; ///< How many ticks have passed since this order started. |
|
304 int32 lateness_counter; ///< How many ticks late (or early if negative) this vehicle is. |
|
305 |
|
306 SpriteID colormap; // NOSAVE: cached color mapping |
|
307 |
|
308 union { |
|
309 VehicleRail rail; |
|
310 VehicleAir air; |
|
311 VehicleRoad road; |
|
312 VehicleSpecial special; |
|
313 VehicleDisaster disaster; |
|
314 VehicleShip ship; |
|
315 } u; |
|
316 |
|
317 |
|
318 /** |
|
319 * Allocates a lot of vehicles. |
|
320 * @param vl pointer to an array of vehicles to get allocated. Can be NULL if the vehicles aren't needed (makes it test only) |
|
321 * @param num number of vehicles to allocate room for |
|
322 * @return true if there is room to allocate all the vehicles |
|
323 */ |
|
324 static bool AllocateList(Vehicle **vl, int num); |
|
325 |
|
326 /** Create a new vehicle */ |
|
327 Vehicle(); |
|
328 |
|
329 /** Destroy all stuff that (still) needs the virtual functions to work properly */ |
|
330 void PreDestructor(); |
|
331 /** We want to 'destruct' the right class. */ |
|
332 virtual ~Vehicle(); |
|
333 |
|
334 void BeginLoading(); |
|
335 void LeaveStation(); |
|
336 |
|
337 /** |
|
338 * Handle the loading of the vehicle; when not it skips through dummy |
|
339 * orders and does nothing in all other cases. |
|
340 * @param mode is the non-first call for this vehicle in this tick? |
|
341 */ |
|
342 void HandleLoading(bool mode = false); |
|
343 |
|
344 /** |
|
345 * Get a string 'representation' of the vehicle type. |
|
346 * @return the string representation. |
|
347 */ |
|
348 virtual const char* GetTypeString() const { return "base vehicle"; } |
|
349 |
|
350 /** |
|
351 * Marks the vehicles to be redrawn and updates cached variables |
|
352 * |
|
353 * This method marks the area of the vehicle on the screen as dirty. |
|
354 * It can be use to repaint the vehicle. |
|
355 * |
|
356 * @ingroup dirty |
|
357 */ |
|
358 virtual void MarkDirty() {} |
|
359 |
|
360 /** |
|
361 * Updates the x and y offsets and the size of the sprite used |
|
362 * for this vehicle. |
|
363 * @param direction the direction the vehicle is facing |
|
364 */ |
|
365 virtual void UpdateDeltaXY(Direction direction) {} |
|
366 |
|
367 /** |
|
368 * Sets the expense type associated to this vehicle type |
|
369 * @param income whether this is income or (running) expenses of the vehicle |
|
370 */ |
|
371 virtual ExpensesType GetExpenseType(bool income) const { return EXPENSES_OTHER; } |
|
372 |
|
373 /** |
|
374 * Invalidates the vehicle list window of this type of vehicle |
|
375 */ |
|
376 virtual WindowClass GetVehicleListWindowClass() const { return WC_NONE; } |
|
377 |
|
378 /** |
|
379 * Play the sound associated with leaving the station |
|
380 */ |
|
381 virtual void PlayLeaveStationSound() const {} |
|
382 |
|
383 /** |
|
384 * Whether this is the primary vehicle in the chain. |
|
385 */ |
|
386 virtual bool IsPrimaryVehicle() const { return false; } |
|
387 |
|
388 /** |
|
389 * Gets the sprite to show for the given direction |
|
390 * @param direction the direction the vehicle is facing |
|
391 * @return the sprite for the given vehicle in the given direction |
|
392 */ |
|
393 virtual int GetImage(Direction direction) const { return 0; } |
|
394 |
|
395 /** |
|
396 * Gets the speed in mph that can be sent into SetDParam for string processing. |
|
397 * @return the vehicle's speed |
|
398 */ |
|
399 virtual int GetDisplaySpeed() const { return 0; } |
|
400 |
|
401 /** |
|
402 * Gets the maximum speed in mph that can be sent into SetDParam for string processing. |
|
403 * @return the vehicle's maximum speed |
|
404 */ |
|
405 virtual int GetDisplayMaxSpeed() const { return 0; } |
|
406 |
|
407 /** |
|
408 * Gets the running cost of a vehicle |
|
409 * @return the vehicle's running cost |
|
410 */ |
|
411 virtual Money GetRunningCost() const { return 0; } |
|
412 |
|
413 /** |
|
414 * Check whether the vehicle is in the depot. |
|
415 * @return true if and only if the vehicle is in the depot. |
|
416 */ |
|
417 virtual bool IsInDepot() const { return false; } |
|
418 |
|
419 /** |
|
420 * Check whether the vehicle is in the depot *and* stopped. |
|
421 * @return true if and only if the vehicle is in the depot and stopped. |
|
422 */ |
|
423 virtual bool IsStoppedInDepot() const { return this->IsInDepot() && (this->vehstatus & VS_STOPPED) != 0; } |
|
424 |
|
425 /** |
|
426 * Calls the tick handler of the vehicle |
|
427 */ |
|
428 virtual void Tick() {}; |
|
429 |
|
430 /** |
|
431 * Gets the running cost of a vehicle that can be sent into SetDParam for string processing. |
|
432 * @return the vehicle's running cost |
|
433 */ |
|
434 Money GetDisplayRunningCost() const { return (this->GetRunningCost() >> 8); } |
|
435 |
|
436 /** |
|
437 * Set the next vehicle of this vehicle. |
|
438 * @param next the next vehicle. NULL removes the next vehicle. |
|
439 */ |
|
440 void SetNext(Vehicle *next); |
|
441 |
|
442 /** |
|
443 * Get the next vehicle of this vehicle. |
|
444 * @note articulated parts are also counted as vehicles. |
|
445 * @return the next vehicle or NULL when there isn't a next vehicle. |
|
446 */ |
|
447 inline Vehicle *Next() const { return this->next; } |
|
448 |
|
449 /** |
|
450 * Get the previous vehicle of this vehicle. |
|
451 * @note articulated parts are also counted as vehicles. |
|
452 * @return the previous vehicle or NULL when there isn't a previous vehicle. |
|
453 */ |
|
454 inline Vehicle *Previous() const { return this->previous; } |
|
455 |
|
456 /** |
|
457 * Get the first vehicle of this vehicle chain. |
|
458 * @return the first vehicle of the chain. |
|
459 */ |
|
460 inline Vehicle *First() const { return this->first; } |
|
461 }; |
|
462 |
|
463 /** |
|
464 * This class 'wraps' Vehicle; you do not actually instantiate this class. |
|
465 * You create a Vehicle using AllocateVehicle, so it is added to the pool |
|
466 * and you reinitialize that to a Train using: |
|
467 * v = new (v) Train(); |
|
468 * |
|
469 * As side-effect the vehicle type is set correctly. |
|
470 * |
|
471 * A special vehicle is one of the following: |
|
472 * - smoke |
|
473 * - electric sparks for trains |
|
474 * - explosions |
|
475 * - bulldozer (road works) |
|
476 * - bubbles (industry) |
|
477 */ |
|
478 struct SpecialVehicle : public Vehicle { |
|
479 /** Initializes the Vehicle to a special vehicle */ |
|
480 SpecialVehicle() { this->type = VEH_SPECIAL; } |
|
481 |
|
482 /** We want to 'destruct' the right class. */ |
|
483 virtual ~SpecialVehicle() {} |
|
484 |
|
485 const char *GetTypeString() const { return "special vehicle"; } |
|
486 void UpdateDeltaXY(Direction direction); |
|
487 void Tick(); |
|
488 }; |
|
489 |
|
490 /** |
|
491 * This class 'wraps' Vehicle; you do not actually instantiate this class. |
|
492 * You create a Vehicle using AllocateVehicle, so it is added to the pool |
|
493 * and you reinitialize that to a Train using: |
|
494 * v = new (v) Train(); |
|
495 * |
|
496 * As side-effect the vehicle type is set correctly. |
|
497 */ |
|
498 struct DisasterVehicle : public Vehicle { |
|
499 /** Initializes the Vehicle to a disaster vehicle */ |
|
500 DisasterVehicle() { this->type = VEH_DISASTER; } |
|
501 |
|
502 /** We want to 'destruct' the right class. */ |
|
503 virtual ~DisasterVehicle() {} |
|
504 |
|
505 const char *GetTypeString() const { return "disaster vehicle"; } |
|
506 void UpdateDeltaXY(Direction direction); |
|
507 void Tick(); |
|
508 }; |
|
509 |
|
510 /** |
|
511 * This class 'wraps' Vehicle; you do not actually instantiate this class. |
|
512 * You create a Vehicle using AllocateVehicle, so it is added to the pool |
|
513 * and you reinitialize that to a Train using: |
|
514 * v = new (v) Train(); |
|
515 * |
|
516 * As side-effect the vehicle type is set correctly. |
|
517 */ |
|
518 struct InvalidVehicle : public Vehicle { |
|
519 /** Initializes the Vehicle to a invalid vehicle */ |
|
520 InvalidVehicle() { this->type = VEH_INVALID; } |
|
521 |
|
522 /** We want to 'destruct' the right class. */ |
|
523 virtual ~InvalidVehicle() {} |
|
524 |
|
525 const char *GetTypeString() const { return "invalid vehicle"; } |
|
526 void Tick() {} |
|
527 }; |
|
528 |
|
529 #define BEGIN_ENUM_WAGONS(v) do { |
|
530 #define END_ENUM_WAGONS(v) } while ((v = v->Next()) != NULL); |
|
531 |
|
532 static inline VehicleID GetMaxVehicleIndex() |
|
533 { |
|
534 /* TODO - This isn't the real content of the function, but |
|
535 * with the new pool-system this will be replaced with one that |
|
536 * _really_ returns the highest index. Now it just returns |
|
537 * the next safe value we are sure about everything is below. |
|
538 */ |
|
539 return GetVehiclePoolSize() - 1; |
|
540 } |
|
541 |
|
542 static inline uint GetNumVehicles() |
|
543 { |
|
544 return GetVehiclePoolSize(); |
|
545 } |
|
546 |
|
547 #define FOR_ALL_VEHICLES_FROM(v, start) for (v = GetVehicle(start); v != NULL; v = (v->index + 1U < GetVehiclePoolSize()) ? GetVehicle(v->index + 1) : NULL) if (v->IsValid()) |
|
548 #define FOR_ALL_VEHICLES(v) FOR_ALL_VEHICLES_FROM(v, 0) |
|
549 |
|
550 /** |
|
551 * Check if an index is a vehicle-index (so between 0 and max-vehicles) |
|
552 * @param index of the vehicle to query |
|
553 * @return Returns true if the vehicle-id is in range |
|
554 */ |
|
555 static inline bool IsValidVehicleID(uint index) |
|
556 { |
|
557 return index < GetVehiclePoolSize() && GetVehicle(index)->IsValid(); |
|
558 } |
|
559 |
|
560 /* Returns order 'index' of a vehicle or NULL when it doesn't exists */ |
|
561 static inline Order *GetVehicleOrder(const Vehicle *v, int index) |
|
562 { |
|
563 Order *order = v->orders; |
|
564 |
|
565 if (index < 0) return NULL; |
|
566 |
|
567 while (order != NULL && index-- > 0) |
|
568 order = order->next; |
|
569 |
|
570 return order; |
|
571 } |
|
572 |
|
573 /** |
|
574 * Returns the last order of a vehicle, or NULL if it doesn't exists |
|
575 * @param v Vehicle to query |
|
576 * @return last order of a vehicle, if available |
|
577 */ |
|
578 static inline Order *GetLastVehicleOrder(const Vehicle *v) |
|
579 { |
|
580 Order *order = v->orders; |
|
581 |
|
582 if (order == NULL) return NULL; |
|
583 |
|
584 while (order->next != NULL) |
|
585 order = order->next; |
|
586 |
|
587 return order; |
|
588 } |
|
589 |
|
590 /** Get the first vehicle of a shared-list, so we only have to walk forwards |
|
591 * @param v Vehicle to query |
|
592 * @return first vehicle of a shared-list |
|
593 */ |
|
594 static inline Vehicle *GetFirstVehicleFromSharedList(const Vehicle *v) |
|
595 { |
|
596 Vehicle *u = (Vehicle *)v; |
|
597 while (u->prev_shared != NULL) u = u->prev_shared; |
|
598 |
|
599 return u; |
|
600 } |
|
601 |
|
602 /** |
|
603 * Returns the Trackdir on which the vehicle is currently located. |
|
604 * Works for trains and ships. |
|
605 * Currently works only sortof for road vehicles, since they have a fuzzy |
|
606 * concept of being "on" a trackdir. Dunno really what it returns for a road |
|
607 * vehicle that is halfway a tile, never really understood that part. For road |
|
608 * vehicles that are at the beginning or end of the tile, should just return |
|
609 * the diagonal trackdir on which they are driving. I _think_. |
|
610 * For other vehicles types, or vehicles with no clear trackdir (such as those |
|
611 * in depots), returns 0xFF. |
|
612 */ |
|
613 Trackdir GetVehicleTrackdir(const Vehicle* v); |
|
614 |
|
615 void CheckVehicle32Day(Vehicle *v); |
|
616 |
|
617 #endif /* VEHICLE_BASE_H */ |