1 /*
2  * This file is part of OpenTTD.
3  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6  */
7 
8 /** @file  vehicle_base.h Base class for all vehicles. */
9 
10 #ifndef VEHICLE_BASE_H
11 #define VEHICLE_BASE_H
12 
13 #include "core/smallmap_type.hpp"
14 #include "track_type.h"
15 #include "command_type.h"
16 #include "order_base.h"
17 #include "cargopacket.h"
18 #include "texteff.hpp"
19 #include "engine_type.h"
20 #include "order_func.h"
21 #include "transport_type.h"
22 #include "group_type.h"
23 #include "base_consist.h"
24 #include "network/network.h"
25 #include "saveload/saveload.h"
26 #include <list>
27 #include <map>
28 
29 /** Vehicle status bits in #Vehicle::vehstatus. */
30 enum VehStatus {
31 	VS_HIDDEN          = 0x01, ///< Vehicle is not visible.
32 	VS_STOPPED         = 0x02, ///< Vehicle is stopped by the player.
33 	VS_UNCLICKABLE     = 0x04, ///< Vehicle is not clickable by the user (shadow vehicles).
34 	VS_DEFPAL          = 0x08, ///< Use default vehicle palette. @see DoDrawVehicle
35 	VS_TRAIN_SLOWING   = 0x10, ///< Train is slowing down.
36 	VS_SHADOW          = 0x20, ///< Vehicle is a shadow vehicle.
37 	VS_AIRCRAFT_BROKEN = 0x40, ///< Aircraft is broken down.
38 	VS_CRASHED         = 0x80, ///< Vehicle is crashed.
39 };
40 
41 /** Bit numbers in #Vehicle::vehicle_flags. */
42 enum VehicleFlags {
43 	VF_LOADING_FINISHED,        ///< Vehicle has finished loading.
44 	VF_CARGO_UNLOADING,         ///< Vehicle is unloading cargo.
45 	VF_BUILT_AS_PROTOTYPE,      ///< Vehicle is a prototype (accepted as exclusive preview).
46 	VF_TIMETABLE_STARTED,       ///< Whether the vehicle has started running on the timetable yet.
47 	VF_AUTOFILL_TIMETABLE,      ///< Whether the vehicle should fill in the timetable automatically.
48 	VF_AUTOFILL_PRES_WAIT_TIME, ///< Whether non-destructive auto-fill should preserve waiting times
49 	VF_STOP_LOADING,            ///< Don't load anymore during the next load cycle.
50 	VF_PATHFINDER_LOST,         ///< Vehicle's pathfinder is lost.
51 	VF_SERVINT_IS_CUSTOM,       ///< Service interval is custom.
52 	VF_SERVINT_IS_PERCENT,      ///< Service interval is percent.
53 };
54 
55 /** Bit numbers used to indicate which of the #NewGRFCache values are valid. */
56 enum NewGRFCacheValidValues {
57 	NCVV_POSITION_CONSIST_LENGTH   = 0, ///< This bit will be set if the NewGRF var 40 currently stored is valid.
58 	NCVV_POSITION_SAME_ID_LENGTH   = 1, ///< This bit will be set if the NewGRF var 41 currently stored is valid.
59 	NCVV_CONSIST_CARGO_INFORMATION = 2, ///< This bit will be set if the NewGRF var 42 currently stored is valid.
60 	NCVV_COMPANY_INFORMATION       = 3, ///< This bit will be set if the NewGRF var 43 currently stored is valid.
61 	NCVV_POSITION_IN_VEHICLE       = 4, ///< This bit will be set if the NewGRF var 4D currently stored is valid.
62 	NCVV_END,                           ///< End of the bits.
63 };
64 
65 /** Cached often queried (NewGRF) values */
66 struct NewGRFCache {
67 	/* Values calculated when they are requested for the first time after invalidating the NewGRF cache. */
68 	uint32 position_consist_length;   ///< Cache for NewGRF var 40.
69 	uint32 position_same_id_length;   ///< Cache for NewGRF var 41.
70 	uint32 consist_cargo_information; ///< Cache for NewGRF var 42. (Note: The cargotype is untranslated in the cache because the accessing GRF is yet unknown.)
71 	uint32 company_information;       ///< Cache for NewGRF var 43.
72 	uint32 position_in_vehicle;       ///< Cache for NewGRF var 4D.
73 	uint8  cache_valid;               ///< Bitset that indicates which cache values are valid.
74 };
75 
76 /** Meaning of the various bits of the visual effect. */
77 enum VisualEffect {
78 	VE_OFFSET_START        = 0, ///< First bit that contains the offset (0 = front, 8 = centre, 15 = rear)
79 	VE_OFFSET_COUNT        = 4, ///< Number of bits used for the offset
80 	VE_OFFSET_CENTRE       = 8, ///< Value of offset corresponding to a position above the centre of the vehicle
81 
82 	VE_TYPE_START          = 4, ///< First bit used for the type of effect
83 	VE_TYPE_COUNT          = 2, ///< Number of bits used for the effect type
84 	VE_TYPE_DEFAULT        = 0, ///< Use default from engine class
85 	VE_TYPE_STEAM          = 1, ///< Steam plumes
86 	VE_TYPE_DIESEL         = 2, ///< Diesel fumes
87 	VE_TYPE_ELECTRIC       = 3, ///< Electric sparks
88 
89 	VE_DISABLE_EFFECT      = 6, ///< Flag to disable visual effect
90 	VE_ADVANCED_EFFECT     = VE_DISABLE_EFFECT, ///< Flag for advanced effects
91 	VE_DISABLE_WAGON_POWER = 7, ///< Flag to disable wagon power
92 
93 	VE_DEFAULT = 0xFF,          ///< Default value to indicate that visual effect should be based on engine class
94 };
95 
96 /** Models for spawning visual effects. */
97 enum VisualEffectSpawnModel {
98 	VESM_NONE              = 0, ///< No visual effect
99 	VESM_STEAM,                 ///< Steam model
100 	VESM_DIESEL,                ///< Diesel model
101 	VESM_ELECTRIC,              ///< Electric model
102 
103 	VESM_END
104 };
105 
106 /**
107  * Enum to handle ground vehicle subtypes.
108  * This is defined here instead of at #GroundVehicle because some common function require access to these flags.
109  * Do not access it directly unless you have to. Use the subtype access functions.
110  */
111 enum GroundVehicleSubtypeFlags {
112 	GVSF_FRONT            = 0, ///< Leading engine of a consist.
113 	GVSF_ARTICULATED_PART = 1, ///< Articulated part of an engine.
114 	GVSF_WAGON            = 2, ///< Wagon (not used for road vehicles).
115 	GVSF_ENGINE           = 3, ///< Engine that can be front engine, but might be placed behind another engine (not used for road vehicles).
116 	GVSF_FREE_WAGON       = 4, ///< First in a wagon chain (in depot) (not used for road vehicles).
117 	GVSF_MULTIHEADED      = 5, ///< Engine is multiheaded (not used for road vehicles).
118 };
119 
120 /** Cached often queried values common to all vehicles. */
121 struct VehicleCache {
122 	uint16 cached_max_speed;        ///< Maximum speed of the consist (minimum of the max speed of all vehicles in the consist).
123 	uint16 cached_cargo_age_period; ///< Number of ticks before carried cargo is aged.
124 
125 	byte cached_vis_effect;  ///< Visual effect to show (see #VisualEffect)
126 };
127 
128 /** Sprite sequence for a vehicle part. */
129 struct VehicleSpriteSeq {
130 	PalSpriteID seq[4];
131 	uint count;
132 
133 	bool operator==(const VehicleSpriteSeq &other) const
134 	{
135 		return this->count == other.count && MemCmpT<PalSpriteID>(this->seq, other.seq, this->count) == 0;
136 	}
137 
138 	bool operator!=(const VehicleSpriteSeq &other) const
139 	{
140 		return !this->operator==(other);
141 	}
142 
143 	/**
144 	 * Check whether the sequence contains any sprites.
145 	 */
IsValidVehicleSpriteSeq146 	bool IsValid() const
147 	{
148 		return this->count != 0;
149 	}
150 
151 	/**
152 	 * Clear all information.
153 	 */
ClearVehicleSpriteSeq154 	void Clear()
155 	{
156 		this->count = 0;
157 	}
158 
159 	/**
160 	 * Assign a single sprite to the sequence.
161 	 */
SetVehicleSpriteSeq162 	void Set(SpriteID sprite)
163 	{
164 		this->count = 1;
165 		this->seq[0].sprite = sprite;
166 		this->seq[0].pal = 0;
167 	}
168 
169 	/**
170 	 * Copy data from another sprite sequence, while dropping all recolouring information.
171 	 */
CopyWithoutPaletteVehicleSpriteSeq172 	void CopyWithoutPalette(const VehicleSpriteSeq &src)
173 	{
174 		this->count = src.count;
175 		for (uint i = 0; i < src.count; ++i) {
176 			this->seq[i].sprite = src.seq[i].sprite;
177 			this->seq[i].pal = 0;
178 		}
179 	}
180 
181 	void GetBounds(Rect *bounds) const;
182 	void Draw(int x, int y, PaletteID default_pal, bool force_pal) const;
183 };
184 
185 /**
186  * Cache for vehicle sprites and values relating to whether they should be updated before drawing,
187  * or calculating the viewport.
188  */
189 struct MutableSpriteCache {
190 	Direction last_direction;     ///< Last direction we obtained sprites for
191 	bool revalidate_before_draw;  ///< We need to do a GetImage() and check bounds before drawing this sprite
192 	Rect old_coord;               ///< Co-ordinates from the last valid bounding box
193 	bool is_viewport_candidate;   ///< This vehicle can potentially be drawn on a viewport
194 	VehicleSpriteSeq sprite_seq;  ///< Vehicle appearance.
195 };
196 
197 /** A vehicle pool for a little over 1 million vehicles. */
198 typedef Pool<Vehicle, VehicleID, 512, 0xFF000> VehiclePool;
199 extern VehiclePool _vehicle_pool;
200 
201 /* Some declarations of functions, so we can make them friendly */
202 struct GroundVehicleCache;
203 struct LoadgameState;
204 extern bool LoadOldVehicle(LoadgameState *ls, int num);
205 extern void FixOldVehicles();
206 
207 struct GRFFile;
208 
209 /**
210  * Simulated cargo type and capacity for prediction of future links.
211  */
212 struct RefitDesc {
213 	CargoID cargo;    ///< Cargo type the vehicle will be carrying.
214 	uint16 capacity;  ///< Capacity the vehicle will have.
215 	uint16 remaining; ///< Capacity remaining from before the previous refit.
RefitDescRefitDesc216 	RefitDesc(CargoID cargo, uint16 capacity, uint16 remaining) :
217 			cargo(cargo), capacity(capacity), remaining(remaining) {}
218 };
219 
220 /** %Vehicle data structure. */
221 struct Vehicle : VehiclePool::PoolItem<&_vehicle_pool>, BaseVehicle, BaseConsist {
222 private:
223 	typedef std::list<RefitDesc> RefitList;
224 	typedef std::map<CargoID, uint> CapacitiesMap;
225 
226 	Vehicle *next;                      ///< pointer to the next vehicle in the chain
227 	Vehicle *previous;                  ///< NOSAVE: pointer to the previous vehicle in the chain
228 	Vehicle *first;                     ///< NOSAVE: pointer to the first vehicle in the chain
229 
230 	Vehicle *next_shared;               ///< pointer to the next vehicle that shares the order
231 	Vehicle *previous_shared;           ///< NOSAVE: pointer to the previous vehicle in the shared order chain
232 
233 public:
234 	friend void FixOldVehicles();
235 	friend void AfterLoadVehicles(bool part_of_load);             ///< So we can set the #previous and #first pointers while loading
236 	friend bool LoadOldVehicle(LoadgameState *ls, int num);       ///< So we can set the proper next pointer while loading
237 	/* So we can use private/protected variables in the saveload code */
238 	friend class SlVehicleCommon;
239 	friend class SlVehicleDisaster;
240 	friend void Ptrs_VEHS();
241 
242 	TileIndex tile;                     ///< Current tile index
243 
244 	/**
245 	 * Heading for this tile.
246 	 * For airports and train stations this tile does not necessarily belong to the destination station,
247 	 * but it can be used for heuristic purposes to estimate the distance.
248 	 */
249 	TileIndex dest_tile;
250 
251 	Money profit_this_year;             ///< Profit this year << 8, low 8 bits are fract
252 	Money profit_last_year;             ///< Profit last year << 8, low 8 bits are fract
253 	Money value;                        ///< Value of the vehicle
254 
255 	CargoPayment *cargo_payment;        ///< The cargo payment we're currently in
256 
257 	mutable Rect coord;                 ///< NOSAVE: Graphical bounding box of the vehicle, i.e. what to redraw on moves.
258 
259 	Vehicle *hash_viewport_next;        ///< NOSAVE: Next vehicle in the visual location hash.
260 	Vehicle **hash_viewport_prev;       ///< NOSAVE: Previous vehicle in the visual location hash.
261 
262 	Vehicle *hash_tile_next;            ///< NOSAVE: Next vehicle in the tile location hash.
263 	Vehicle **hash_tile_prev;           ///< NOSAVE: Previous vehicle in the tile location hash.
264 	Vehicle **hash_tile_current;        ///< NOSAVE: Cache of the current hash chain.
265 
266 	SpriteID colourmap;                 ///< NOSAVE: cached colour mapping
267 
268 	/* Related to age and service time */
269 	Year build_year;                    ///< Year the vehicle has been built.
270 	Date age;                           ///< Age in days
271 	Date max_age;                       ///< Maximum age
272 	Date date_of_last_service;          ///< Last date the vehicle had a service at a depot.
273 	uint16 reliability;                 ///< Reliability.
274 	uint16 reliability_spd_dec;         ///< Reliability decrease speed.
275 	byte breakdown_ctr;                 ///< Counter for managing breakdown events. @see Vehicle::HandleBreakdown
276 	byte breakdown_delay;               ///< Counter for managing breakdown length.
277 	byte breakdowns_since_last_service; ///< Counter for the amount of breakdowns.
278 	byte breakdown_chance;              ///< Current chance of breakdowns.
279 
280 	int32 x_pos;                        ///< x coordinate.
281 	int32 y_pos;                        ///< y coordinate.
282 	int32 z_pos;                        ///< z coordinate.
283 	Direction direction;                ///< facing
284 
285 	Owner owner;                        ///< Which company owns the vehicle?
286 	/**
287 	 * currently displayed sprite index
288 	 * 0xfd == custom sprite, 0xfe == custom second head sprite
289 	 * 0xff == reserved for another custom sprite
290 	 */
291 	byte spritenum;
292 	byte x_extent;                      ///< x-extent of vehicle bounding box
293 	byte y_extent;                      ///< y-extent of vehicle bounding box
294 	byte z_extent;                      ///< z-extent of vehicle bounding box
295 	int8 x_bb_offs;                     ///< x offset of vehicle bounding box
296 	int8 y_bb_offs;                     ///< y offset of vehicle bounding box
297 	int8 x_offs;                        ///< x offset for vehicle sprite
298 	int8 y_offs;                        ///< y offset for vehicle sprite
299 	EngineID engine_type;               ///< The type of engine used for this vehicle.
300 
301 	TextEffectID fill_percent_te_id;    ///< a text-effect id to a loading indicator object
302 	UnitID unitnumber;                  ///< unit number, for display purposes only
303 
304 	uint16 cur_speed;                   ///< current speed
305 	byte subspeed;                      ///< fractional speed
306 	byte acceleration;                  ///< used by train & aircraft
307 	uint32 motion_counter;              ///< counter to occasionally play a vehicle sound.
308 	byte progress;                      ///< The percentage (if divided by 256) this vehicle already crossed the tile unit.
309 
310 	byte random_bits;                   ///< Bits used for determining which randomized variational spritegroups to use when drawing.
311 	byte waiting_triggers;              ///< Triggers to be yet matched before rerandomizing the random bits.
312 
313 	StationID last_station_visited;     ///< The last station we stopped at.
314 	StationID last_loading_station;     ///< Last station the vehicle has stopped at and could possibly leave from with any cargo loaded.
315 
316 	CargoID cargo_type;                 ///< type of cargo this vehicle is carrying
317 	byte cargo_subtype;                 ///< Used for livery refits (NewGRF variations)
318 	uint16 cargo_cap;                   ///< total capacity
319 	uint16 refit_cap;                   ///< Capacity left over from before last refit.
320 	VehicleCargoList cargo;             ///< The cargo this vehicle is carrying
321 	uint16 cargo_age_counter;           ///< Ticks till cargo is aged next.
322 	int8 trip_occupancy;                ///< NOSAVE: Occupancy of vehicle of the current trip (updated after leaving a station).
323 
324 	byte day_counter;                   ///< Increased by one for each day
325 	byte tick_counter;                  ///< Increased by one for each tick
326 	byte running_ticks;                 ///< Number of ticks this vehicle was not stopped this day
327 
328 	byte vehstatus;                     ///< Status
329 	Order current_order;                ///< The current order (+ status, like: loading)
330 
331 	union {
332 		OrderList *list;            ///< Pointer to the order list for this vehicle
333 		Order     *old;             ///< Only used during conversion of old save games
334 	} orders;                           ///< The orders currently assigned to the vehicle.
335 
336 	uint16 load_unload_ticks;           ///< Ticks to wait before starting next cycle.
337 	GroupID group_id;                   ///< Index of group Pool array
338 	byte subtype;                       ///< subtype (Filled with values from #AircraftSubType/#DisasterSubType/#EffectVehicleType/#GroundVehicleSubtypeFlags)
339 
340 	NewGRFCache grf_cache;              ///< Cache of often used calculated NewGRF values
341 	VehicleCache vcache;                ///< Cache of often used vehicle values.
342 
343 	mutable MutableSpriteCache sprite_cache; ///< Cache of sprites and values related to recalculating them, see #MutableSpriteCache
344 
345 	Vehicle(VehicleType type = VEH_INVALID);
346 
347 	void PreDestructor();
348 	/** We want to 'destruct' the right class. */
349 	virtual ~Vehicle();
350 
351 	void BeginLoading();
352 	void CancelReservation(StationID next, Station *st);
353 	void LeaveStation();
354 
355 	GroundVehicleCache *GetGroundVehicleCache();
356 	const GroundVehicleCache *GetGroundVehicleCache() const;
357 
358 	uint16 &GetGroundVehicleFlags();
359 	const uint16 &GetGroundVehicleFlags() const;
360 
361 	void DeleteUnreachedImplicitOrders();
362 
363 	void HandleLoading(bool mode = false);
364 
365 	void GetConsistFreeCapacities(SmallMap<CargoID, uint> &capacities) const;
366 
367 	uint GetConsistTotalCapacity() const;
368 
369 	/**
370 	 * Marks the vehicles to be redrawn and updates cached variables
371 	 *
372 	 * This method marks the area of the vehicle on the screen as dirty.
373 	 * It can be use to repaint the vehicle.
374 	 *
375 	 * @ingroup dirty
376 	 */
MarkDirtyVehicle377 	virtual void MarkDirty() {}
378 
379 	/**
380 	 * Updates the x and y offsets and the size of the sprite used
381 	 * for this vehicle.
382 	 */
UpdateDeltaXYVehicle383 	virtual void UpdateDeltaXY() {}
384 
385 	/**
386 	 * Determines the effective direction-specific vehicle movement speed.
387 	 *
388 	 * This method belongs to the old vehicle movement method:
389 	 * A vehicle moves a step every 256 progress units.
390 	 * The vehicle speed is scaled by 3/4 when moving in X or Y direction due to the longer distance.
391 	 *
392 	 * However, this method is slightly wrong in corners, as the leftover progress is not scaled correctly
393 	 * when changing movement direction. #GetAdvanceSpeed() and #GetAdvanceDistance() are better wrt. this.
394 	 *
395 	 * @param speed Direction-independent unscaled speed.
396 	 * @return speed scaled by movement direction. 256 units are required for each movement step.
397 	 */
GetOldAdvanceSpeedVehicle398 	inline uint GetOldAdvanceSpeed(uint speed)
399 	{
400 		return (this->direction & 1) ? speed : speed * 3 / 4;
401 	}
402 
403 	/**
404 	 * Determines the effective vehicle movement speed.
405 	 *
406 	 * Together with #GetAdvanceDistance() this function is a replacement for #GetOldAdvanceSpeed().
407 	 *
408 	 * A vehicle progresses independent of it's movement direction.
409 	 * However different amounts of "progress" are needed for moving a step in a specific direction.
410 	 * That way the leftover progress does not need any adaption when changing movement direction.
411 	 *
412 	 * @param speed Direction-independent unscaled speed.
413 	 * @return speed, scaled to match #GetAdvanceDistance().
414 	 */
GetAdvanceSpeedVehicle415 	static inline uint GetAdvanceSpeed(uint speed)
416 	{
417 		return speed * 3 / 4;
418 	}
419 
420 	/**
421 	 * Determines the vehicle "progress" needed for moving a step.
422 	 *
423 	 * Together with #GetAdvanceSpeed() this function is a replacement for #GetOldAdvanceSpeed().
424 	 *
425 	 * @return distance to drive for a movement step on the map.
426 	 */
GetAdvanceDistanceVehicle427 	inline uint GetAdvanceDistance()
428 	{
429 		return (this->direction & 1) ? 192 : 256;
430 	}
431 
432 	/**
433 	 * Sets the expense type associated to this vehicle type
434 	 * @param income whether this is income or (running) expenses of the vehicle
435 	 */
GetExpenseTypeVehicle436 	virtual ExpensesType GetExpenseType(bool income) const { return EXPENSES_OTHER; }
437 
438 	/**
439 	 * Play the sound associated with leaving the station
440 	 */
PlayLeaveStationSoundVehicle441 	virtual void PlayLeaveStationSound() const {}
442 
443 	/**
444 	 * Whether this is the primary vehicle in the chain.
445 	 */
IsPrimaryVehicleVehicle446 	virtual bool IsPrimaryVehicle() const { return false; }
447 
448 	const Engine *GetEngine() const;
449 
450 	/**
451 	 * Gets the sprite to show for the given direction
452 	 * @param direction the direction the vehicle is facing
453 	 * @param[out] result Vehicle sprite sequence.
454 	 */
GetImageVehicle455 	virtual void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const { result->Clear(); }
456 
457 	const GRFFile *GetGRF() const;
458 	uint32 GetGRFID() const;
459 
460 	/**
461 	 * Invalidates cached NewGRF variables
462 	 * @see InvalidateNewGRFCacheOfChain
463 	 */
InvalidateNewGRFCacheVehicle464 	inline void InvalidateNewGRFCache()
465 	{
466 		this->grf_cache.cache_valid = 0;
467 	}
468 
469 	/**
470 	 * Invalidates cached NewGRF variables of all vehicles in the chain (after the current vehicle)
471 	 * @see InvalidateNewGRFCache
472 	 */
InvalidateNewGRFCacheOfChainVehicle473 	inline void InvalidateNewGRFCacheOfChain()
474 	{
475 		for (Vehicle *u = this; u != nullptr; u = u->Next()) {
476 			u->InvalidateNewGRFCache();
477 		}
478 	}
479 
480 	/**
481 	 * Check if the vehicle is a ground vehicle.
482 	 * @return True iff the vehicle is a train or a road vehicle.
483 	 */
IsGroundVehicleVehicle484 	inline bool IsGroundVehicle() const
485 	{
486 		return this->type == VEH_TRAIN || this->type == VEH_ROAD;
487 	}
488 
489 	/**
490 	 * Gets the speed in km-ish/h that can be sent into SetDParam for string processing.
491 	 * @return the vehicle's speed
492 	 */
GetDisplaySpeedVehicle493 	virtual int GetDisplaySpeed() const { return 0; }
494 
495 	/**
496 	 * Gets the maximum speed in km-ish/h that can be sent into SetDParam for string processing.
497 	 * @return the vehicle's maximum speed
498 	 */
GetDisplayMaxSpeedVehicle499 	virtual int GetDisplayMaxSpeed() const { return 0; }
500 
501 	/**
502 	 * Calculates the maximum speed of the vehicle under its current conditions.
503 	 * @return Current maximum speed in native units.
504 	 */
GetCurrentMaxSpeedVehicle505 	virtual int GetCurrentMaxSpeed() const { return 0; }
506 
507 	/**
508 	 * Gets the running cost of a vehicle
509 	 * @return the vehicle's running cost
510 	 */
GetRunningCostVehicle511 	virtual Money GetRunningCost() const { return 0; }
512 
513 	/**
514 	 * Check whether the vehicle is in the depot.
515 	 * @return true if and only if the vehicle is in the depot.
516 	 */
IsInDepotVehicle517 	virtual bool IsInDepot() const { return false; }
518 
519 	/**
520 	 * Check whether the whole vehicle chain is in the depot.
521 	 * @return true if and only if the whole chain is in the depot.
522 	 */
IsChainInDepotVehicle523 	virtual bool IsChainInDepot() const { return this->IsInDepot(); }
524 
525 	/**
526 	 * Check whether the vehicle is in the depot *and* stopped.
527 	 * @return true if and only if the vehicle is in the depot and stopped.
528 	 */
IsStoppedInDepotVehicle529 	bool IsStoppedInDepot() const
530 	{
531 		assert(this == this->First());
532 		/* Free wagons have no VS_STOPPED state */
533 		if (this->IsPrimaryVehicle() && !(this->vehstatus & VS_STOPPED)) return false;
534 		return this->IsChainInDepot();
535 	}
536 
537 	/**
538 	 * Calls the tick handler of the vehicle
539 	 * @return is this vehicle still valid?
540 	 */
TickVehicle541 	virtual bool Tick() { return true; };
542 
543 	/**
544 	 * Calls the new day handler of the vehicle
545 	 */
OnNewDayVehicle546 	virtual void OnNewDay() {};
547 
548 	/**
549 	 * Crash the (whole) vehicle chain.
550 	 * @param flooded whether the cause of the crash is flooding or not.
551 	 * @return the number of lost souls.
552 	 */
553 	virtual uint Crash(bool flooded = false);
554 
555 	/**
556 	 * Returns the Trackdir on which the vehicle is currently located.
557 	 * Works for trains and ships.
558 	 * Currently works only sortof for road vehicles, since they have a fuzzy
559 	 * concept of being "on" a trackdir. Dunno really what it returns for a road
560 	 * vehicle that is halfway a tile, never really understood that part. For road
561 	 * vehicles that are at the beginning or end of the tile, should just return
562 	 * the diagonal trackdir on which they are driving. I _think_.
563 	 * For other vehicles types, or vehicles with no clear trackdir (such as those
564 	 * in depots), returns 0xFF.
565 	 * @return the trackdir of the vehicle
566 	 */
GetVehicleTrackdirVehicle567 	virtual Trackdir GetVehicleTrackdir() const { return INVALID_TRACKDIR; }
568 
569 	/**
570 	 * Gets the running cost of a vehicle  that can be sent into SetDParam for string processing.
571 	 * @return the vehicle's running cost
572 	 */
GetDisplayRunningCostVehicle573 	Money GetDisplayRunningCost() const { return (this->GetRunningCost() >> 8); }
574 
575 	/**
576 	 * Gets the profit vehicle had this year. It can be sent into SetDParam for string processing.
577 	 * @return the vehicle's profit this year
578 	 */
GetDisplayProfitThisYearVehicle579 	Money GetDisplayProfitThisYear() const { return (this->profit_this_year >> 8); }
580 
581 	/**
582 	 * Gets the profit vehicle had last year. It can be sent into SetDParam for string processing.
583 	 * @return the vehicle's profit last year
584 	 */
GetDisplayProfitLastYearVehicle585 	Money GetDisplayProfitLastYear() const { return (this->profit_last_year >> 8); }
586 
587 	void SetNext(Vehicle *next);
588 
589 	/**
590 	 * Get the next vehicle of this vehicle.
591 	 * @note articulated parts are also counted as vehicles.
592 	 * @return the next vehicle or nullptr when there isn't a next vehicle.
593 	 */
NextVehicle594 	inline Vehicle *Next() const { return this->next; }
595 
596 	/**
597 	 * Get the previous vehicle of this vehicle.
598 	 * @note articulated parts are also counted as vehicles.
599 	 * @return the previous vehicle or nullptr when there isn't a previous vehicle.
600 	 */
PreviousVehicle601 	inline Vehicle *Previous() const { return this->previous; }
602 
603 	/**
604 	 * Get the first vehicle of this vehicle chain.
605 	 * @return the first vehicle of the chain.
606 	 */
FirstVehicle607 	inline Vehicle *First() const { return this->first; }
608 
609 	/**
610 	 * Get the last vehicle of this vehicle chain.
611 	 * @return the last vehicle of the chain.
612 	 */
LastVehicle613 	inline Vehicle *Last()
614 	{
615 		Vehicle *v = this;
616 		while (v->Next() != nullptr) v = v->Next();
617 		return v;
618 	}
619 
620 	/**
621 	 * Get the last vehicle of this vehicle chain.
622 	 * @return the last vehicle of the chain.
623 	 */
LastVehicle624 	inline const Vehicle *Last() const
625 	{
626 		const Vehicle *v = this;
627 		while (v->Next() != nullptr) v = v->Next();
628 		return v;
629 	}
630 
631 	/**
632 	 * Get the vehicle at offset \a n of this vehicle chain.
633 	 * @param n Offset from the current vehicle.
634 	 * @return The new vehicle or nullptr if the offset is out-of-bounds.
635 	 */
MoveVehicle636 	inline Vehicle *Move(int n)
637 	{
638 		Vehicle *v = this;
639 		if (n < 0) {
640 			for (int i = 0; i != n && v != nullptr; i--) v = v->Previous();
641 		} else {
642 			for (int i = 0; i != n && v != nullptr; i++) v = v->Next();
643 		}
644 		return v;
645 	}
646 
647 	/**
648 	 * Get the vehicle at offset \a n of this vehicle chain.
649 	 * @param n Offset from the current vehicle.
650 	 * @return The new vehicle or nullptr if the offset is out-of-bounds.
651 	 */
MoveVehicle652 	inline const Vehicle *Move(int n) const
653 	{
654 		const Vehicle *v = this;
655 		if (n < 0) {
656 			for (int i = 0; i != n && v != nullptr; i--) v = v->Previous();
657 		} else {
658 			for (int i = 0; i != n && v != nullptr; i++) v = v->Next();
659 		}
660 		return v;
661 	}
662 
663 	/**
664 	 * Get the first order of the vehicles order list.
665 	 * @return first order of order list.
666 	 */
GetFirstOrderVehicle667 	inline Order *GetFirstOrder() const { return (this->orders.list == nullptr) ? nullptr : this->orders.list->GetFirstOrder(); }
668 
669 	void AddToShared(Vehicle *shared_chain);
670 	void RemoveFromShared();
671 
672 	/**
673 	 * Get the next vehicle of the shared vehicle chain.
674 	 * @return the next shared vehicle or nullptr when there isn't a next vehicle.
675 	 */
NextSharedVehicle676 	inline Vehicle *NextShared() const { return this->next_shared; }
677 
678 	/**
679 	 * Get the previous vehicle of the shared vehicle chain
680 	 * @return the previous shared vehicle or nullptr when there isn't a previous vehicle.
681 	 */
PreviousSharedVehicle682 	inline Vehicle *PreviousShared() const { return this->previous_shared; }
683 
684 	/**
685 	 * Get the first vehicle of this vehicle chain.
686 	 * @return the first vehicle of the chain.
687 	 */
FirstSharedVehicle688 	inline Vehicle *FirstShared() const { return (this->orders.list == nullptr) ? this->First() : this->orders.list->GetFirstSharedVehicle(); }
689 
690 	/**
691 	 * Check if we share our orders with another vehicle.
692 	 * @return true if there are other vehicles sharing the same order
693 	 */
IsOrderListSharedVehicle694 	inline bool IsOrderListShared() const { return this->orders.list != nullptr && this->orders.list->IsShared(); }
695 
696 	/**
697 	 * Get the number of orders this vehicle has.
698 	 * @return the number of orders this vehicle has.
699 	 */
GetNumOrdersVehicle700 	inline VehicleOrderID GetNumOrders() const { return (this->orders.list == nullptr) ? 0 : this->orders.list->GetNumOrders(); }
701 
702 	/**
703 	 * Get the number of manually added orders this vehicle has.
704 	 * @return the number of manually added orders this vehicle has.
705 	 */
GetNumManualOrdersVehicle706 	inline VehicleOrderID GetNumManualOrders() const { return (this->orders.list == nullptr) ? 0 : this->orders.list->GetNumManualOrders(); }
707 
708 	/**
709 	 * Get the next station the vehicle will stop at.
710 	 * @return ID of the next station the vehicle will stop at or INVALID_STATION.
711 	 */
GetNextStoppingStationVehicle712 	inline StationIDStack GetNextStoppingStation() const
713 	{
714 		return (this->orders.list == nullptr) ? INVALID_STATION : this->orders.list->GetNextStoppingStation(this);
715 	}
716 
717 	void ResetRefitCaps();
718 
719 	/**
720 	 * Copy certain configurations and statistics of a vehicle after successful autoreplace/renew
721 	 * The function shall copy everything that cannot be copied by a command (like orders / group etc),
722 	 * and that shall not be resetted for the new vehicle.
723 	 * @param src The old vehicle
724 	 */
CopyVehicleConfigAndStatisticsVehicle725 	inline void CopyVehicleConfigAndStatistics(const Vehicle *src)
726 	{
727 		this->CopyConsistPropertiesFrom(src);
728 
729 		this->unitnumber = src->unitnumber;
730 
731 		this->current_order = src->current_order;
732 		this->dest_tile  = src->dest_tile;
733 
734 		this->profit_this_year = src->profit_this_year;
735 		this->profit_last_year = src->profit_last_year;
736 	}
737 
738 
739 	bool HandleBreakdown();
740 
741 	bool NeedsAutorenewing(const Company *c, bool use_renew_setting = true) const;
742 
743 	bool NeedsServicing() const;
744 	bool NeedsAutomaticServicing() const;
745 
746 	/**
747 	 * Determine the location for the station where the vehicle goes to next.
748 	 * Things done for example are allocating slots in a road stop or exact
749 	 * location of the platform is determined for ships.
750 	 * @param station the station to make the next location of the vehicle.
751 	 * @return the location (tile) to aim for.
752 	 */
GetOrderStationLocationVehicle753 	virtual TileIndex GetOrderStationLocation(StationID station) { return INVALID_TILE; }
754 
755 	/**
756 	 * Find the closest depot for this vehicle and tell us the location,
757 	 * DestinationID and whether we should reverse.
758 	 * @param location    where do we go to?
759 	 * @param destination what hangar do we go to?
760 	 * @param reverse     should the vehicle be reversed?
761 	 * @return true if a depot could be found.
762 	 */
FindClosestDepotVehicle763 	virtual bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) { return false; }
764 
SetDestTileVehicle765 	virtual void SetDestTile(TileIndex tile) { this->dest_tile = tile; }
766 
767 	CommandCost SendToDepot(DoCommandFlag flags, DepotCommand command);
768 
769 	void UpdateVisualEffect(bool allow_power_change = true);
770 	void ShowVisualEffect() const;
771 
772 	void UpdatePosition();
773 	void UpdateViewport(bool dirty);
774 	void UpdateBoundingBoxCoordinates(bool update_cache) const;
775 	void UpdatePositionAndViewport();
776 	bool MarkAllViewportsDirty() const;
777 
GetServiceIntervalVehicle778 	inline uint16 GetServiceInterval() const { return this->service_interval; }
779 
SetServiceIntervalVehicle780 	inline void SetServiceInterval(uint16 interval) { this->service_interval = interval; }
781 
ServiceIntervalIsCustomVehicle782 	inline bool ServiceIntervalIsCustom() const { return HasBit(this->vehicle_flags, VF_SERVINT_IS_CUSTOM); }
783 
ServiceIntervalIsPercentVehicle784 	inline bool ServiceIntervalIsPercent() const { return HasBit(this->vehicle_flags, VF_SERVINT_IS_PERCENT); }
785 
SetServiceIntervalIsCustomVehicle786 	inline void SetServiceIntervalIsCustom(bool on) { SB(this->vehicle_flags, VF_SERVINT_IS_CUSTOM, 1, on); }
787 
SetServiceIntervalIsPercentVehicle788 	inline void SetServiceIntervalIsPercent(bool on) { SB(this->vehicle_flags, VF_SERVINT_IS_PERCENT, 1, on); }
789 
790 private:
791 	/**
792 	 * Advance cur_real_order_index to the next real order.
793 	 * cur_implicit_order_index is not touched.
794 	 */
SkipToNextRealOrderIndexVehicle795 	void SkipToNextRealOrderIndex()
796 	{
797 		if (this->GetNumManualOrders() > 0) {
798 			/* Advance to next real order */
799 			do {
800 				this->cur_real_order_index++;
801 				if (this->cur_real_order_index >= this->GetNumOrders()) this->cur_real_order_index = 0;
802 			} while (this->GetOrder(this->cur_real_order_index)->IsType(OT_IMPLICIT));
803 		} else {
804 			this->cur_real_order_index = 0;
805 		}
806 	}
807 
808 public:
809 	/**
810 	 * Increments cur_implicit_order_index, keeps care of the wrap-around and invalidates the GUI.
811 	 * cur_real_order_index is incremented as well, if needed.
812 	 * Note: current_order is not invalidated.
813 	 */
IncrementImplicitOrderIndexVehicle814 	void IncrementImplicitOrderIndex()
815 	{
816 		if (this->cur_implicit_order_index == this->cur_real_order_index) {
817 			/* Increment real order index as well */
818 			this->SkipToNextRealOrderIndex();
819 		}
820 
821 		assert(this->cur_real_order_index == 0 || this->cur_real_order_index < this->GetNumOrders());
822 
823 		/* Advance to next implicit order */
824 		do {
825 			this->cur_implicit_order_index++;
826 			if (this->cur_implicit_order_index >= this->GetNumOrders()) this->cur_implicit_order_index = 0;
827 		} while (this->cur_implicit_order_index != this->cur_real_order_index && !this->GetOrder(this->cur_implicit_order_index)->IsType(OT_IMPLICIT));
828 
829 		InvalidateVehicleOrder(this, 0);
830 	}
831 
832 	/**
833 	 * Advanced cur_real_order_index to the next real order, keeps care of the wrap-around and invalidates the GUI.
834 	 * cur_implicit_order_index is incremented as well, if it was equal to cur_real_order_index, i.e. cur_real_order_index is skipped
835 	 * but not any implicit orders.
836 	 * Note: current_order is not invalidated.
837 	 */
IncrementRealOrderIndexVehicle838 	void IncrementRealOrderIndex()
839 	{
840 		if (this->cur_implicit_order_index == this->cur_real_order_index) {
841 			/* Increment both real and implicit order */
842 			this->IncrementImplicitOrderIndex();
843 		} else {
844 			/* Increment real order only */
845 			this->SkipToNextRealOrderIndex();
846 			InvalidateVehicleOrder(this, 0);
847 		}
848 	}
849 
850 	/**
851 	 * Skip implicit orders until cur_real_order_index is a non-implicit order.
852 	 */
UpdateRealOrderIndexVehicle853 	void UpdateRealOrderIndex()
854 	{
855 		/* Make sure the index is valid */
856 		if (this->cur_real_order_index >= this->GetNumOrders()) this->cur_real_order_index = 0;
857 
858 		if (this->GetNumManualOrders() > 0) {
859 			/* Advance to next real order */
860 			while (this->GetOrder(this->cur_real_order_index)->IsType(OT_IMPLICIT)) {
861 				this->cur_real_order_index++;
862 				if (this->cur_real_order_index >= this->GetNumOrders()) this->cur_real_order_index = 0;
863 			}
864 		} else {
865 			this->cur_real_order_index = 0;
866 		}
867 	}
868 
869 	/**
870 	 * Returns order 'index' of a vehicle or nullptr when it doesn't exists
871 	 * @param index the order to fetch
872 	 * @return the found (or not) order
873 	 */
GetOrderVehicle874 	inline Order *GetOrder(int index) const
875 	{
876 		return (this->orders.list == nullptr) ? nullptr : this->orders.list->GetOrderAt(index);
877 	}
878 
879 	/**
880 	 * Returns the last order of a vehicle, or nullptr if it doesn't exists
881 	 * @return last order of a vehicle, if available
882 	 */
GetLastOrderVehicle883 	inline Order *GetLastOrder() const
884 	{
885 		return (this->orders.list == nullptr) ? nullptr : this->orders.list->GetLastOrder();
886 	}
887 
888 	bool IsEngineCountable() const;
889 	bool HasEngineType() const;
890 	bool HasDepotOrder() const;
891 	void HandlePathfindingResult(bool path_found);
892 
893 	/**
894 	 * Check if the vehicle is a front engine.
895 	 * @return Returns true if the vehicle is a front engine.
896 	 */
IsFrontEngineVehicle897 	inline bool IsFrontEngine() const
898 	{
899 		return this->IsGroundVehicle() && HasBit(this->subtype, GVSF_FRONT);
900 	}
901 
902 	/**
903 	 * Check if the vehicle is an articulated part of an engine.
904 	 * @return Returns true if the vehicle is an articulated part.
905 	 */
IsArticulatedPartVehicle906 	inline bool IsArticulatedPart() const
907 	{
908 		return this->IsGroundVehicle() && HasBit(this->subtype, GVSF_ARTICULATED_PART);
909 	}
910 
911 	/**
912 	 * Check if an engine has an articulated part.
913 	 * @return True if the engine has an articulated part.
914 	 */
HasArticulatedPartVehicle915 	inline bool HasArticulatedPart() const
916 	{
917 		return this->Next() != nullptr && this->Next()->IsArticulatedPart();
918 	}
919 
920 	/**
921 	 * Get the next part of an articulated engine.
922 	 * @return Next part of the articulated engine.
923 	 * @pre The vehicle is an articulated engine.
924 	 */
GetNextArticulatedPartVehicle925 	inline Vehicle *GetNextArticulatedPart() const
926 	{
927 		assert(this->HasArticulatedPart());
928 		return this->Next();
929 	}
930 
931 	/**
932 	 * Get the first part of an articulated engine.
933 	 * @return First part of the engine.
934 	 */
GetFirstEnginePartVehicle935 	inline Vehicle *GetFirstEnginePart()
936 	{
937 		Vehicle *v = this;
938 		while (v->IsArticulatedPart()) v = v->Previous();
939 		return v;
940 	}
941 
942 	/**
943 	 * Get the first part of an articulated engine.
944 	 * @return First part of the engine.
945 	 */
GetFirstEnginePartVehicle946 	inline const Vehicle *GetFirstEnginePart() const
947 	{
948 		const Vehicle *v = this;
949 		while (v->IsArticulatedPart()) v = v->Previous();
950 		return v;
951 	}
952 
953 	/**
954 	 * Get the last part of an articulated engine.
955 	 * @return Last part of the engine.
956 	 */
GetLastEnginePartVehicle957 	inline Vehicle *GetLastEnginePart()
958 	{
959 		Vehicle *v = this;
960 		while (v->HasArticulatedPart()) v = v->GetNextArticulatedPart();
961 		return v;
962 	}
963 
964 	/**
965 	 * Get the next real (non-articulated part) vehicle in the consist.
966 	 * @return Next vehicle in the consist.
967 	 */
GetNextVehicleVehicle968 	inline Vehicle *GetNextVehicle() const
969 	{
970 		const Vehicle *v = this;
971 		while (v->HasArticulatedPart()) v = v->GetNextArticulatedPart();
972 
973 		/* v now contains the last articulated part in the engine */
974 		return v->Next();
975 	}
976 
977 	/**
978 	 * Get the previous real (non-articulated part) vehicle in the consist.
979 	 * @return Previous vehicle in the consist.
980 	 */
GetPrevVehicleVehicle981 	inline Vehicle *GetPrevVehicle() const
982 	{
983 		Vehicle *v = this->Previous();
984 		while (v != nullptr && v->IsArticulatedPart()) v = v->Previous();
985 
986 		return v;
987 	}
988 
989 	/**
990 	 * Iterator to iterate orders
991 	 * Supports deletion of current order
992 	 */
993 	struct OrderIterator {
994 		typedef Order value_type;
995 		typedef Order* pointer;
996 		typedef Order& reference;
997 		typedef size_t difference_type;
998 		typedef std::forward_iterator_tag iterator_category;
999 
OrderIteratorVehicle::OrderIterator1000 		explicit OrderIterator(OrderList *list) : list(list), prev(nullptr)
1001 		{
1002 			this->order = (this->list == nullptr) ? nullptr : this->list->GetFirstOrder();
1003 		}
1004 
1005 		bool operator==(const OrderIterator &other) const { return this->order == other.order; }
1006 		bool operator!=(const OrderIterator &other) const { return !(*this == other); }
1007 		Order * operator*() const { return this->order; }
1008 		OrderIterator & operator++()
1009 		{
1010 			this->prev = (this->prev == nullptr) ? this->list->GetFirstOrder() : this->prev->next;
1011 			this->order = (this->prev == nullptr) ? nullptr : this->prev->next;
1012 			return *this;
1013 		}
1014 
1015 	private:
1016 		OrderList *list;
1017 		Order *order;
1018 		Order *prev;
1019 	};
1020 
1021 	/**
1022 	 * Iterable ensemble of orders
1023 	 */
1024 	struct IterateWrapper {
1025 		OrderList *list;
listVehicle::IterateWrapper1026 		IterateWrapper(OrderList *list = nullptr) : list(list) {}
beginVehicle::IterateWrapper1027 		OrderIterator begin() { return OrderIterator(this->list); }
endVehicle::IterateWrapper1028 		OrderIterator end() { return OrderIterator(nullptr); }
emptyVehicle::IterateWrapper1029 		bool empty() { return this->begin() == this->end(); }
1030 	};
1031 
1032 	/**
1033 	 * Returns an iterable ensemble of orders of a vehicle
1034 	 * @return an iterable ensemble of orders of a vehicle
1035 	 */
OrdersVehicle1036 	IterateWrapper Orders() const { return IterateWrapper(this->orders.list); }
1037 };
1038 
1039 /**
1040  * Class defining several overloaded accessors so we don't
1041  * have to cast vehicle types that often
1042  */
1043 template <class T, VehicleType Type>
1044 struct SpecializedVehicle : public Vehicle {
1045 	static const VehicleType EXPECTED_TYPE = Type; ///< Specialized type
1046 
1047 	typedef SpecializedVehicle<T, Type> SpecializedVehicleBase; ///< Our type
1048 
1049 	/**
1050 	 * Set vehicle type correctly
1051 	 */
VehicleSpecializedVehicle1052 	inline SpecializedVehicle<T, Type>() : Vehicle(Type)
1053 	{
1054 		this->sprite_cache.sprite_seq.count = 1;
1055 	}
1056 
1057 	/**
1058 	 * Get the first vehicle in the chain
1059 	 * @return first vehicle in the chain
1060 	 */
FirstSpecializedVehicle1061 	inline T *First() const { return (T *)this->Vehicle::First(); }
1062 
1063 	/**
1064 	 * Get the last vehicle in the chain
1065 	 * @return last vehicle in the chain
1066 	 */
LastSpecializedVehicle1067 	inline T *Last() { return (T *)this->Vehicle::Last(); }
1068 
1069 	/**
1070 	 * Get the last vehicle in the chain
1071 	 * @return last vehicle in the chain
1072 	 */
LastSpecializedVehicle1073 	inline const T *Last() const { return (const T *)this->Vehicle::Last(); }
1074 
1075 	/**
1076 	 * Get next vehicle in the chain
1077 	 * @return next vehicle in the chain
1078 	 */
NextSpecializedVehicle1079 	inline T *Next() const { return (T *)this->Vehicle::Next(); }
1080 
1081 	/**
1082 	 * Get previous vehicle in the chain
1083 	 * @return previous vehicle in the chain
1084 	 */
PreviousSpecializedVehicle1085 	inline T *Previous() const { return (T *)this->Vehicle::Previous(); }
1086 
1087 	/**
1088 	 * Get the next part of an articulated engine.
1089 	 * @return Next part of the articulated engine.
1090 	 * @pre The vehicle is an articulated engine.
1091 	 */
GetNextArticulatedPartSpecializedVehicle1092 	inline T *GetNextArticulatedPart() { return (T *)this->Vehicle::GetNextArticulatedPart(); }
1093 
1094 	/**
1095 	 * Get the next part of an articulated engine.
1096 	 * @return Next part of the articulated engine.
1097 	 * @pre The vehicle is an articulated engine.
1098 	 */
GetNextArticulatedPartSpecializedVehicle1099 	inline T *GetNextArticulatedPart() const { return (T *)this->Vehicle::GetNextArticulatedPart(); }
1100 
1101 	/**
1102 	 * Get the first part of an articulated engine.
1103 	 * @return First part of the engine.
1104 	 */
GetFirstEnginePartSpecializedVehicle1105 	inline T *GetFirstEnginePart() { return (T *)this->Vehicle::GetFirstEnginePart(); }
1106 
1107 	/**
1108 	 * Get the first part of an articulated engine.
1109 	 * @return First part of the engine.
1110 	 */
GetFirstEnginePartSpecializedVehicle1111 	inline const T *GetFirstEnginePart() const { return (const T *)this->Vehicle::GetFirstEnginePart(); }
1112 
1113 	/**
1114 	 * Get the last part of an articulated engine.
1115 	 * @return Last part of the engine.
1116 	 */
GetLastEnginePartSpecializedVehicle1117 	inline T *GetLastEnginePart() { return (T *)this->Vehicle::GetLastEnginePart(); }
1118 
1119 	/**
1120 	 * Get the next real (non-articulated part) vehicle in the consist.
1121 	 * @return Next vehicle in the consist.
1122 	 */
GetNextVehicleSpecializedVehicle1123 	inline T *GetNextVehicle() const { return (T *)this->Vehicle::GetNextVehicle(); }
1124 
1125 	/**
1126 	 * Get the previous real (non-articulated part) vehicle in the consist.
1127 	 * @return Previous vehicle in the consist.
1128 	 */
GetPrevVehicleSpecializedVehicle1129 	inline T *GetPrevVehicle() const { return (T *)this->Vehicle::GetPrevVehicle(); }
1130 
1131 	/**
1132 	 * Tests whether given index is a valid index for vehicle of this type
1133 	 * @param index tested index
1134 	 * @return is this index valid index of T?
1135 	 */
IsValidIDSpecializedVehicle1136 	static inline bool IsValidID(size_t index)
1137 	{
1138 		return Vehicle::IsValidID(index) && Vehicle::Get(index)->type == Type;
1139 	}
1140 
1141 	/**
1142 	 * Gets vehicle with given index
1143 	 * @return pointer to vehicle with given index casted to T *
1144 	 */
GetSpecializedVehicle1145 	static inline T *Get(size_t index)
1146 	{
1147 		return (T *)Vehicle::Get(index);
1148 	}
1149 
1150 	/**
1151 	 * Returns vehicle if the index is a valid index for this vehicle type
1152 	 * @return pointer to vehicle with given index if it's a vehicle of this type
1153 	 */
GetIfValidSpecializedVehicle1154 	static inline T *GetIfValid(size_t index)
1155 	{
1156 		return IsValidID(index) ? Get(index) : nullptr;
1157 	}
1158 
1159 	/**
1160 	 * Converts a Vehicle to SpecializedVehicle with type checking.
1161 	 * @param v Vehicle pointer
1162 	 * @return pointer to SpecializedVehicle
1163 	 */
FromSpecializedVehicle1164 	static inline T *From(Vehicle *v)
1165 	{
1166 		assert(v->type == Type);
1167 		return (T *)v;
1168 	}
1169 
1170 	/**
1171 	 * Converts a const Vehicle to const SpecializedVehicle with type checking.
1172 	 * @param v Vehicle pointer
1173 	 * @return pointer to SpecializedVehicle
1174 	 */
FromSpecializedVehicle1175 	static inline const T *From(const Vehicle *v)
1176 	{
1177 		assert(v->type == Type);
1178 		return (const T *)v;
1179 	}
1180 
1181 	/**
1182 	 * Update vehicle sprite- and position caches
1183 	 * @param force_update Force updating the vehicle on the viewport.
1184 	 * @param update_delta Also update the delta?
1185 	 */
UpdateViewportSpecializedVehicle1186 	inline void UpdateViewport(bool force_update, bool update_delta)
1187 	{
1188 		bool sprite_has_changed = false;
1189 
1190 		/* Skip updating sprites on dedicated servers without screen */
1191 		if (_network_dedicated) return;
1192 
1193 		/* Explicitly choose method to call to prevent vtable dereference -
1194 		 * it gives ~3% runtime improvements in games with many vehicles */
1195 		if (update_delta) ((T *)this)->T::UpdateDeltaXY();
1196 
1197 		/*
1198 		 * Only check for a new sprite sequence if the vehicle direction
1199 		 * has changed since we last checked it, assuming that otherwise
1200 		 * there won't be enough change in bounding box or offsets to need
1201 		 * to resolve a new sprite.
1202 		 */
1203 		if (this->direction != this->sprite_cache.last_direction || this->sprite_cache.is_viewport_candidate) {
1204 			VehicleSpriteSeq seq;
1205 
1206 			((T*)this)->T::GetImage(this->direction, EIT_ON_MAP, &seq);
1207 			if (this->sprite_cache.sprite_seq != seq) {
1208 				sprite_has_changed = true;
1209 				this->sprite_cache.sprite_seq = seq;
1210 			}
1211 
1212 			this->sprite_cache.last_direction = this->direction;
1213 			this->sprite_cache.revalidate_before_draw = false;
1214 		} else {
1215 			/*
1216 			 * A change that could potentially invalidate the sprite has been
1217 			 * made, signal that we should still resolve it before drawing on a
1218 			 * viewport.
1219 			 */
1220 			this->sprite_cache.revalidate_before_draw = true;
1221 		}
1222 
1223 		if (force_update || sprite_has_changed) {
1224 			this->Vehicle::UpdateViewport(true);
1225 		}
1226 	}
1227 
1228 	/**
1229 	 * Returns an iterable ensemble of all valid vehicles of type T
1230 	 * @param from index of the first vehicle to consider
1231 	 * @return an iterable ensemble of all valid vehicles of type T
1232 	 */
1233 	static Pool::IterateWrapper<T> Iterate(size_t from = 0) { return Pool::IterateWrapper<T>(from); }
1234 };
1235 
1236 /** Generates sequence of free UnitID numbers */
1237 struct FreeUnitIDGenerator {
1238 	bool *cache;  ///< array of occupied unit id numbers
1239 	UnitID maxid; ///< maximum ID at the moment of constructor call
1240 	UnitID curid; ///< last ID returned; 0 if none
1241 
1242 	FreeUnitIDGenerator(VehicleType type, CompanyID owner);
1243 	UnitID NextID();
1244 
1245 	/** Releases allocated memory */
~FreeUnitIDGeneratorFreeUnitIDGenerator1246 	~FreeUnitIDGenerator() { free(this->cache); }
1247 };
1248 
1249 /** Sentinel for an invalid coordinate. */
1250 static const int32 INVALID_COORD = 0x7fffffff;
1251 
1252 #endif /* VEHICLE_BASE_H */
1253