1 /* $Id$ */ |
|
2 |
|
3 /** @vehicle.h */ |
|
4 |
|
5 #ifndef VEHICLE_H |
|
6 #define VEHICLE_H |
|
7 |
|
8 #include "oldpool.h" |
|
9 #include "order.h" |
|
10 #include "rail.h" |
|
11 #include "road.h" |
|
12 #include "cargopacket.h" |
|
13 #include "texteff.hpp" |
|
14 |
|
15 /** The returned bits of VehicleEnterTile. */ |
|
16 enum VehicleEnterTileStatus { |
|
17 VETS_ENTERED_STATION = 1, ///< The vehicle entered a station |
|
18 VETS_ENTERED_WORMHOLE = 2, ///< The vehicle either entered a bridge, tunnel or depot tile (this includes the last tile of the bridge/tunnel) |
|
19 VETS_CANNOT_ENTER = 3, ///< The vehicle cannot enter the tile |
|
20 |
|
21 /** |
|
22 * Shift the VehicleEnterTileStatus this many bits |
|
23 * to the right to get the station ID when |
|
24 * VETS_ENTERED_STATION is set |
|
25 */ |
|
26 VETS_STATION_ID_OFFSET = 8, |
|
27 |
|
28 /** Bit sets of the above specified bits */ |
|
29 VETSB_CONTINUE = 0, ///< The vehicle can continue normally |
|
30 VETSB_ENTERED_STATION = 1 << VETS_ENTERED_STATION, ///< The vehicle entered a station |
|
31 VETSB_ENTERED_WORMHOLE = 1 << VETS_ENTERED_WORMHOLE, ///< The vehicle either entered a bridge, tunnel or depot tile (this includes the last tile of the bridge/tunnel) |
|
32 VETSB_CANNOT_ENTER = 1 << VETS_CANNOT_ENTER, ///< The vehicle cannot enter the tile |
|
33 }; |
|
34 |
|
35 /** Road vehicle states */ |
|
36 enum RoadVehicleStates { |
|
37 /* |
|
38 * Lower 4 bits are used for vehicle track direction. (Trackdirs) |
|
39 * When in a road stop (bit 5 or bit 6 set) these bits give the |
|
40 * track direction of the entry to the road stop. |
|
41 * As the entry direction will always be a diagonal |
|
42 * direction (X_NE, Y_SE, X_SW or Y_NW) only bits 0 and 3 |
|
43 * are needed to hold this direction. Bit 1 is then used to show |
|
44 * that the vehicle is using the second road stop bay. |
|
45 * Bit 2 is then used for drive-through stops to show the vehicle |
|
46 * is stopping at this road stop. |
|
47 */ |
|
48 |
|
49 /* Numeric values */ |
|
50 RVSB_IN_DEPOT = 0xFE, ///< The vehicle is in a depot |
|
51 RVSB_WORMHOLE = 0xFF, ///< The vehicle is in a tunnel and/or bridge |
|
52 |
|
53 /* Bit numbers */ |
|
54 RVS_USING_SECOND_BAY = 1, ///< Only used while in a road stop |
|
55 RVS_IS_STOPPING = 2, ///< Only used for drive-through stops. Vehicle will stop here |
|
56 RVS_DRIVE_SIDE = 4, ///< Only used when retrieving move data |
|
57 RVS_IN_ROAD_STOP = 5, ///< The vehicle is in a road stop |
|
58 RVS_IN_DT_ROAD_STOP = 6, ///< The vehicle is in a drive-through road stop |
|
59 |
|
60 /* Bit sets of the above specified bits */ |
|
61 RVSB_IN_ROAD_STOP = 1 << RVS_IN_ROAD_STOP, ///< The vehicle is in a road stop |
|
62 RVSB_IN_ROAD_STOP_END = RVSB_IN_ROAD_STOP + TRACKDIR_END, |
|
63 RVSB_IN_DT_ROAD_STOP = 1 << RVS_IN_DT_ROAD_STOP, ///< The vehicle is in a drive-through road stop |
|
64 RVSB_IN_DT_ROAD_STOP_END = RVSB_IN_DT_ROAD_STOP + TRACKDIR_END, |
|
65 |
|
66 RVSB_TRACKDIR_MASK = 0x0F, ///< The mask used to extract track dirs |
|
67 RVSB_ROAD_STOP_TRACKDIR_MASK = 0x09 ///< Only bits 0 and 3 are used to encode the trackdir for road stops |
|
68 }; |
|
69 |
|
70 enum VehicleType { |
|
71 VEH_TRAIN, |
|
72 VEH_ROAD, |
|
73 VEH_SHIP, |
|
74 VEH_AIRCRAFT, |
|
75 VEH_SPECIAL, |
|
76 VEH_DISASTER, |
|
77 VEH_END, |
|
78 VEH_INVALID = 0xFF, |
|
79 }; |
|
80 DECLARE_POSTFIX_INCREMENT(VehicleType); |
|
81 template <> struct EnumPropsT<VehicleType> : MakeEnumPropsT<VehicleType, byte, VEH_TRAIN, VEH_END, VEH_INVALID> {}; |
|
82 typedef TinyEnumT<VehicleType> VehicleTypeByte; |
|
83 |
|
84 enum VehStatus { |
|
85 VS_HIDDEN = 0x01, |
|
86 VS_STOPPED = 0x02, |
|
87 VS_UNCLICKABLE = 0x04, |
|
88 VS_DEFPAL = 0x08, |
|
89 VS_TRAIN_SLOWING = 0x10, |
|
90 VS_SHADOW = 0x20, |
|
91 VS_AIRCRAFT_BROKEN = 0x40, |
|
92 VS_CRASHED = 0x80, |
|
93 }; |
|
94 |
|
95 enum VehicleFlags { |
|
96 VF_LOADING_FINISHED, |
|
97 VF_CARGO_UNLOADING, |
|
98 VF_BUILT_AS_PROTOTYPE, |
|
99 VF_TIMETABLE_STARTED, ///< Whether the vehicle has started running on the timetable yet. |
|
100 VF_AUTOFILL_TIMETABLE, ///< Whether the vehicle should fill in the timetable automatically. |
|
101 }; |
|
102 |
|
103 /* Effect vehicle types */ |
|
104 enum EffectVehicle { |
|
105 EV_CHIMNEY_SMOKE = 0, |
|
106 EV_STEAM_SMOKE = 1, |
|
107 EV_DIESEL_SMOKE = 2, |
|
108 EV_ELECTRIC_SPARK = 3, |
|
109 EV_SMOKE = 4, |
|
110 EV_EXPLOSION_LARGE = 5, |
|
111 EV_BREAKDOWN_SMOKE = 6, |
|
112 EV_EXPLOSION_SMALL = 7, |
|
113 EV_BULLDOZER = 8, |
|
114 EV_BUBBLE = 9 |
|
115 }; |
|
116 |
|
117 struct VehicleRail { |
|
118 uint16 last_speed; // NOSAVE: only used in UI |
|
119 uint16 crash_anim_pos; |
|
120 |
|
121 /* cached values, recalculated on load and each time a vehicle is added to/removed from the consist. */ |
|
122 uint16 cached_max_speed; // max speed of the consist. (minimum of the max speed of all vehicles in the consist) |
|
123 uint32 cached_power; // total power of the consist. |
|
124 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 |
|
125 uint16 cached_total_length; ///< Length of the whole train, valid only for first engine. |
|
126 |
|
127 /* cached values, recalculated when the cargo on a train changes (in addition to the conditions above) */ |
|
128 uint32 cached_weight; // total weight of the consist. |
|
129 uint32 cached_veh_weight; // weight of the vehicle. |
|
130 uint32 cached_max_te; // max tractive effort of consist |
|
131 /** |
|
132 * Position/type of visual effect. |
|
133 * bit 0 - 3 = position of effect relative to vehicle. (0 = front, 8 = centre, 15 = rear) |
|
134 * bit 4 - 5 = type of effect. (0 = default for engine class, 1 = steam, 2 = diesel, 3 = electric) |
|
135 * bit 6 = disable visual effect. |
|
136 * bit 7 = disable powered wagons. |
|
137 */ |
|
138 byte cached_vis_effect; |
|
139 byte user_def_data; |
|
140 |
|
141 /* NOSAVE: for wagon override - id of the first engine in train |
|
142 * 0xffff == not in train */ |
|
143 EngineID first_engine; |
|
144 |
|
145 TrackBitsByte track; |
|
146 byte force_proceed; |
|
147 RailTypeByte railtype; |
|
148 RailTypeMask compatible_railtypes; |
|
149 |
|
150 byte flags; |
|
151 |
|
152 /* Link between the two ends of a multiheaded engine */ |
|
153 Vehicle *other_multiheaded_part; |
|
154 |
|
155 /* Cached wagon override spritegroup */ |
|
156 const struct SpriteGroup *cached_override; |
|
157 }; |
|
158 |
|
159 enum { |
|
160 VRF_REVERSING = 0, |
|
161 |
|
162 /* used to calculate if train is going up or down */ |
|
163 VRF_GOINGUP = 1, |
|
164 VRF_GOINGDOWN = 2, |
|
165 |
|
166 /* used to store if a wagon is powered or not */ |
|
167 VRF_POWEREDWAGON = 3, |
|
168 |
|
169 /* used to reverse the visible direction of the vehicle */ |
|
170 VRF_REVERSE_DIRECTION = 4, |
|
171 |
|
172 /* used to mark train as lost because PF can't find the route */ |
|
173 VRF_NO_PATH_TO_DESTINATION = 5, |
|
174 |
|
175 /* used to mark that electric train engine is allowed to run on normal rail */ |
|
176 VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL = 6, |
|
177 }; |
|
178 |
|
179 struct VehicleAir { |
|
180 uint16 crashed_counter; |
|
181 uint16 cached_max_speed; |
|
182 byte pos; |
|
183 byte previous_pos; |
|
184 StationID targetairport; |
|
185 byte state; |
|
186 }; |
|
187 |
|
188 struct VehicleRoad { |
|
189 byte state; ///< @see RoadVehicleStates |
|
190 byte frame; |
|
191 uint16 blocked_ctr; |
|
192 byte overtaking; |
|
193 byte overtaking_ctr; |
|
194 uint16 crashed_ctr; |
|
195 byte reverse_ctr; |
|
196 struct RoadStop *slot; |
|
197 byte slot_age; |
|
198 EngineID first_engine; |
|
199 byte cached_veh_length; |
|
200 |
|
201 RoadType roadtype; |
|
202 RoadTypes compatible_roadtypes; |
|
203 }; |
|
204 |
|
205 struct VehicleSpecial { |
|
206 uint16 animation_state; |
|
207 byte animation_substate; |
|
208 }; |
|
209 |
|
210 struct VehicleDisaster { |
|
211 uint16 image_override; |
|
212 VehicleID big_ufo_destroyer_target; |
|
213 }; |
|
214 |
|
215 struct VehicleShip { |
|
216 TrackBitsByte state; |
|
217 }; |
|
218 |
|
219 struct Vehicle; |
|
220 DECLARE_OLD_POOL(Vehicle, Vehicle, 9, 125) |
|
221 |
|
222 /* Some declarations of functions, so we can make them friendly */ |
|
223 struct SaveLoad; |
|
224 extern const SaveLoad *GetVehicleDescription(VehicleType vt); |
|
225 extern void AfterLoadVehicles(); |
|
226 struct LoadgameState; |
|
227 extern bool LoadOldVehicle(LoadgameState *ls, int num); |
|
228 |
|
229 struct Vehicle : PoolItem<Vehicle, VehicleID, &_Vehicle_pool> { |
|
230 VehicleTypeByte type; ///< Type of vehicle |
|
231 byte subtype; // subtype (Filled with values from EffectVehicles/TrainSubTypes/AircraftSubTypes) |
|
232 |
|
233 private: |
|
234 Vehicle *next; // pointer to the next vehicle in the chain |
|
235 Vehicle *previous; // NOSAVE: pointer to the previous vehicle in the chain |
|
236 Vehicle *first; // NOSAVE: pointer to the first vehicle in the chain |
|
237 public: |
|
238 friend const SaveLoad *GetVehicleDescription(VehicleType vt); // So we can use private/protected variables in the saveload code |
|
239 friend void AfterLoadVehicles(); // So we can set the previous and first pointers while loading |
|
240 friend bool LoadOldVehicle(LoadgameState *ls, int num); // So we can set the proper next pointer while loading |
|
241 |
|
242 Vehicle *depot_list; // NOSAVE: linked list to tell what vehicles entered a depot during the last tick. Used by autoreplace |
|
243 |
|
244 StringID string_id; // Displayed string |
|
245 |
|
246 UnitID unitnumber; // unit number, for display purposes only |
|
247 PlayerByte owner; // which player owns the vehicle? |
|
248 |
|
249 TileIndex tile; // Current tile index |
|
250 TileIndex dest_tile; // Heading for this tile |
|
251 |
|
252 int32 x_pos; // coordinates |
|
253 int32 y_pos; |
|
254 byte z_pos; |
|
255 DirectionByte direction; // facing |
|
256 |
|
257 byte spritenum; // currently displayed sprite index |
|
258 // 0xfd == custom sprite, 0xfe == custom second head sprite |
|
259 // 0xff == reserved for another custom sprite |
|
260 uint16 cur_image; // sprite number for this vehicle |
|
261 byte sprite_width; // width of vehicle sprite |
|
262 byte sprite_height; // height of vehicle sprite |
|
263 byte z_height; // z-height of vehicle sprite |
|
264 int8 x_offs; // x offset for vehicle sprite |
|
265 int8 y_offs; // y offset for vehicle sprite |
|
266 EngineID engine_type; |
|
267 |
|
268 TextEffectID fill_percent_te_id; // a text-effect id to a loading indicator object |
|
269 |
|
270 /* for randomized variational spritegroups |
|
271 * bitmask used to resolve them; parts of it get reseeded when triggers |
|
272 * of corresponding spritegroups get matched */ |
|
273 byte random_bits; |
|
274 byte waiting_triggers; // triggers to be yet matched |
|
275 |
|
276 uint16 max_speed; // maximum speed |
|
277 uint16 cur_speed; // current speed |
|
278 byte subspeed; // fractional speed |
|
279 byte acceleration; // used by train & aircraft |
|
280 byte progress; |
|
281 uint32 motion_counter; |
|
282 |
|
283 byte vehstatus; // Status |
|
284 StationID last_station_visited; |
|
285 |
|
286 CargoID cargo_type; // type of cargo this vehicle is carrying |
|
287 uint16 cargo_cap; // total capacity |
|
288 byte cargo_subtype; ///< Used for livery refits (NewGRF variations) |
|
289 CargoList cargo; ///< The cargo this vehicle is carrying |
|
290 |
|
291 |
|
292 byte day_counter; // increased by one for each day |
|
293 byte tick_counter; // increased by one for each tick |
|
294 |
|
295 /* Begin Order-stuff */ |
|
296 Order current_order; ///< The current order (+ status, like: loading) |
|
297 VehicleOrderID cur_order_index; ///< The index to the current order |
|
298 |
|
299 Order *orders; ///< Pointer to the first order for this vehicle |
|
300 VehicleOrderID num_orders; ///< How many orders there are in the list |
|
301 |
|
302 Vehicle *next_shared; ///< If not NULL, this points to the next vehicle that shared the order |
|
303 Vehicle *prev_shared; ///< If not NULL, this points to the prev vehicle that shared the order |
|
304 /* End Order-stuff */ |
|
305 |
|
306 /* Boundaries for the current position in the world and a next hash link. |
|
307 * NOSAVE: All of those can be updated with VehiclePositionChanged() */ |
|
308 int32 left_coord; |
|
309 int32 top_coord; |
|
310 int32 right_coord; |
|
311 int32 bottom_coord; |
|
312 Vehicle *next_hash; |
|
313 Vehicle *next_new_hash; |
|
314 Vehicle **old_new_hash; |
|
315 |
|
316 /* Related to age and service time */ |
|
317 Date age; // Age in days |
|
318 Date max_age; // Maximum age |
|
319 Date date_of_last_service; |
|
320 Date service_interval; |
|
321 uint16 reliability; |
|
322 uint16 reliability_spd_dec; |
|
323 byte breakdown_ctr; |
|
324 byte breakdown_delay; |
|
325 byte breakdowns_since_last_service; |
|
326 byte breakdown_chance; |
|
327 Year build_year; |
|
328 |
|
329 bool leave_depot_instantly; // NOSAVE: stores if the vehicle needs to leave the depot it just entered. Used by autoreplace |
|
330 |
|
331 uint16 load_unload_time_rem; |
|
332 byte vehicle_flags; // Used for gradual loading and other miscellaneous things (@see VehicleFlags enum) |
|
333 |
|
334 Money profit_this_year; |
|
335 Money profit_last_year; |
|
336 Money value; |
|
337 |
|
338 GroupID group_id; ///< Index of group Pool array |
|
339 |
|
340 /* Used for timetabling. */ |
|
341 uint32 current_order_time; ///< How many ticks have passed since this order started. |
|
342 int32 lateness_counter; ///< How many ticks late (or early if negative) this vehicle is. |
|
343 |
|
344 SpriteID colormap; // NOSAVE: cached color mapping |
|
345 |
|
346 union { |
|
347 VehicleRail rail; |
|
348 VehicleAir air; |
|
349 VehicleRoad road; |
|
350 VehicleSpecial special; |
|
351 VehicleDisaster disaster; |
|
352 VehicleShip ship; |
|
353 } u; |
|
354 |
|
355 |
|
356 /** |
|
357 * Allocates a lot of vehicles. |
|
358 * @param vl pointer to an array of vehicles to get allocated. Can be NULL if the vehicles aren't needed (makes it test only) |
|
359 * @param num number of vehicles to allocate room for |
|
360 * @return true if there is room to allocate all the vehicles |
|
361 */ |
|
362 static bool AllocateList(Vehicle **vl, int num); |
|
363 |
|
364 /** Create a new vehicle */ |
|
365 Vehicle(); |
|
366 |
|
367 /** Destroy all stuff that (still) needs the virtual functions to work properly */ |
|
368 void PreDestructor(); |
|
369 /** We want to 'destruct' the right class. */ |
|
370 virtual ~Vehicle(); |
|
371 |
|
372 void BeginLoading(); |
|
373 void LeaveStation(); |
|
374 |
|
375 /** |
|
376 * Handle the loading of the vehicle; when not it skips through dummy |
|
377 * orders and does nothing in all other cases. |
|
378 * @param mode is the non-first call for this vehicle in this tick? |
|
379 */ |
|
380 void HandleLoading(bool mode = false); |
|
381 |
|
382 /** |
|
383 * Get a string 'representation' of the vehicle type. |
|
384 * @return the string representation. |
|
385 */ |
|
386 virtual const char* GetTypeString() const { return "base vehicle"; } |
|
387 |
|
388 /** |
|
389 * Marks the vehicles to be redrawn and updates cached variables |
|
390 * |
|
391 * This method marks the area of the vehicle on the screen as dirty. |
|
392 * It can be use to repaint the vehicle. |
|
393 * |
|
394 * @ingroup dirty |
|
395 */ |
|
396 virtual void MarkDirty() {} |
|
397 |
|
398 /** |
|
399 * Updates the x and y offsets and the size of the sprite used |
|
400 * for this vehicle. |
|
401 * @param direction the direction the vehicle is facing |
|
402 */ |
|
403 virtual void UpdateDeltaXY(Direction direction) {} |
|
404 |
|
405 /** |
|
406 * Sets the expense type associated to this vehicle type |
|
407 * @param income whether this is income or (running) expenses of the vehicle |
|
408 */ |
|
409 virtual ExpensesType GetExpenseType(bool income) const { return EXPENSES_OTHER; } |
|
410 |
|
411 /** |
|
412 * Invalidates the vehicle list window of this type of vehicle |
|
413 */ |
|
414 virtual WindowClass GetVehicleListWindowClass() const { return WC_NONE; } |
|
415 |
|
416 /** |
|
417 * Play the sound associated with leaving the station |
|
418 */ |
|
419 virtual void PlayLeaveStationSound() const {} |
|
420 |
|
421 /** |
|
422 * Whether this is the primary vehicle in the chain. |
|
423 */ |
|
424 virtual bool IsPrimaryVehicle() const { return false; } |
|
425 |
|
426 /** |
|
427 * Gets the sprite to show for the given direction |
|
428 * @param direction the direction the vehicle is facing |
|
429 * @return the sprite for the given vehicle in the given direction |
|
430 */ |
|
431 virtual int GetImage(Direction direction) const { return 0; } |
|
432 |
|
433 /** |
|
434 * Gets the speed in mph that can be sent into SetDParam for string processing. |
|
435 * @return the vehicle's speed |
|
436 */ |
|
437 virtual int GetDisplaySpeed() const { return 0; } |
|
438 |
|
439 /** |
|
440 * Gets the maximum speed in mph that can be sent into SetDParam for string processing. |
|
441 * @return the vehicle's maximum speed |
|
442 */ |
|
443 virtual int GetDisplayMaxSpeed() const { return 0; } |
|
444 |
|
445 /** |
|
446 * Gets the running cost of a vehicle |
|
447 * @return the vehicle's running cost |
|
448 */ |
|
449 virtual Money GetRunningCost() const { return 0; } |
|
450 |
|
451 /** |
|
452 * Check whether the vehicle is in the depot. |
|
453 * @return true if and only if the vehicle is in the depot. |
|
454 */ |
|
455 virtual bool IsInDepot() const { return false; } |
|
456 |
|
457 /** |
|
458 * Check whether the vehicle is in the depot *and* stopped. |
|
459 * @return true if and only if the vehicle is in the depot and stopped. |
|
460 */ |
|
461 virtual bool IsStoppedInDepot() const { return this->IsInDepot() && (this->vehstatus & VS_STOPPED) != 0; } |
|
462 |
|
463 /** |
|
464 * Calls the tick handler of the vehicle |
|
465 */ |
|
466 virtual void Tick() {}; |
|
467 |
|
468 /** |
|
469 * Gets the running cost of a vehicle that can be sent into SetDParam for string processing. |
|
470 * @return the vehicle's running cost |
|
471 */ |
|
472 Money GetDisplayRunningCost() const { return (this->GetRunningCost() >> 8); } |
|
473 |
|
474 /** |
|
475 * Is this vehicle a valid vehicle? |
|
476 * @return true if and only if the vehicle is valid. |
|
477 */ |
|
478 inline bool IsValid() const { return this->type != VEH_INVALID; } |
|
479 |
|
480 /** |
|
481 * Set the next vehicle of this vehicle. |
|
482 * @param next the next vehicle. NULL removes the next vehicle. |
|
483 */ |
|
484 void SetNext(Vehicle *next); |
|
485 |
|
486 /** |
|
487 * Get the next vehicle of this vehicle. |
|
488 * @note articulated parts are also counted as vehicles. |
|
489 * @return the next vehicle or NULL when there isn't a next vehicle. |
|
490 */ |
|
491 inline Vehicle *Next() const { return this->next; } |
|
492 |
|
493 /** |
|
494 * Get the previous vehicle of this vehicle. |
|
495 * @note articulated parts are also counted as vehicles. |
|
496 * @return the previous vehicle or NULL when there isn't a previous vehicle. |
|
497 */ |
|
498 inline Vehicle *Previous() const { return this->previous; } |
|
499 |
|
500 /** |
|
501 * Get the first vehicle of this vehicle chain. |
|
502 * @return the first vehicle of the chain. |
|
503 */ |
|
504 inline Vehicle *First() const { return this->first; } |
|
505 }; |
|
506 |
|
507 /** |
|
508 * This class 'wraps' Vehicle; you do not actually instantiate this class. |
|
509 * You create a Vehicle using AllocateVehicle, so it is added to the pool |
|
510 * and you reinitialize that to a Train using: |
|
511 * v = new (v) Train(); |
|
512 * |
|
513 * As side-effect the vehicle type is set correctly. |
|
514 * |
|
515 * A special vehicle is one of the following: |
|
516 * - smoke |
|
517 * - electric sparks for trains |
|
518 * - explosions |
|
519 * - bulldozer (road works) |
|
520 * - bubbles (industry) |
|
521 */ |
|
522 struct SpecialVehicle : public Vehicle { |
|
523 /** Initializes the Vehicle to a special vehicle */ |
|
524 SpecialVehicle() { this->type = VEH_SPECIAL; } |
|
525 |
|
526 /** We want to 'destruct' the right class. */ |
|
527 virtual ~SpecialVehicle() {} |
|
528 |
|
529 const char *GetTypeString() const { return "special vehicle"; } |
|
530 void UpdateDeltaXY(Direction direction); |
|
531 void Tick(); |
|
532 }; |
|
533 |
|
534 /** |
|
535 * This class 'wraps' Vehicle; you do not actually instantiate this class. |
|
536 * You create a Vehicle using AllocateVehicle, so it is added to the pool |
|
537 * and you reinitialize that to a Train using: |
|
538 * v = new (v) Train(); |
|
539 * |
|
540 * As side-effect the vehicle type is set correctly. |
|
541 */ |
|
542 struct DisasterVehicle : public Vehicle { |
|
543 /** Initializes the Vehicle to a disaster vehicle */ |
|
544 DisasterVehicle() { this->type = VEH_DISASTER; } |
|
545 |
|
546 /** We want to 'destruct' the right class. */ |
|
547 virtual ~DisasterVehicle() {} |
|
548 |
|
549 const char *GetTypeString() const { return "disaster vehicle"; } |
|
550 void UpdateDeltaXY(Direction direction); |
|
551 void Tick(); |
|
552 }; |
|
553 |
|
554 /** |
|
555 * This class 'wraps' Vehicle; you do not actually instantiate this class. |
|
556 * You create a Vehicle using AllocateVehicle, so it is added to the pool |
|
557 * and you reinitialize that to a Train using: |
|
558 * v = new (v) Train(); |
|
559 * |
|
560 * As side-effect the vehicle type is set correctly. |
|
561 */ |
|
562 struct InvalidVehicle : public Vehicle { |
|
563 /** Initializes the Vehicle to a invalid vehicle */ |
|
564 InvalidVehicle() { this->type = VEH_INVALID; } |
|
565 |
|
566 /** We want to 'destruct' the right class. */ |
|
567 virtual ~InvalidVehicle() {} |
|
568 |
|
569 const char *GetTypeString() const { return "invalid vehicle"; } |
|
570 void Tick() {} |
|
571 }; |
|
572 |
|
573 #define is_custom_sprite(x) (x >= 0xFD) |
|
574 #define IS_CUSTOM_FIRSTHEAD_SPRITE(x) (x == 0xFD) |
|
575 #define IS_CUSTOM_SECONDHEAD_SPRITE(x) (x == 0xFE) |
|
576 |
|
577 typedef void *VehicleFromPosProc(Vehicle *v, void *data); |
|
578 |
|
579 void VehicleServiceInDepot(Vehicle *v); |
|
580 void VehiclePositionChanged(Vehicle *v); |
|
581 Vehicle *GetLastVehicleInChain(Vehicle *v); |
|
582 uint CountVehiclesInChain(const Vehicle *v); |
|
583 bool IsEngineCountable(const Vehicle *v); |
|
584 void DeleteVehicleChain(Vehicle *v); |
|
585 void *VehicleFromPos(TileIndex tile, void *data, VehicleFromPosProc *proc); |
|
586 void *VehicleFromPosXY(int x, int y, void *data, VehicleFromPosProc *proc); |
|
587 void CallVehicleTicks(); |
|
588 Vehicle *FindVehicleOnTileZ(TileIndex tile, byte z); |
|
589 uint8 CalcPercentVehicleFilled(Vehicle *v, StringID *color); |
|
590 |
|
591 void InitializeTrains(); |
|
592 byte VehicleRandomBits(); |
|
593 void ResetVehiclePosHash(); |
|
594 void ResetVehicleColorMap(); |
|
595 void CheckVehicle32Day(Vehicle *v); |
|
596 |
|
597 bool CanRefitTo(EngineID engine_type, CargoID cid_to); |
|
598 CargoID FindFirstRefittableCargo(EngineID engine_type); |
|
599 CommandCost GetRefitCost(EngineID engine_type); |
|
600 |
|
601 void ViewportAddVehicles(DrawPixelInfo *dpi); |
|
602 |
|
603 SpriteID GetRotorImage(const Vehicle *v); |
|
604 |
|
605 Vehicle *CreateEffectVehicle(int x, int y, int z, EffectVehicle type); |
|
606 Vehicle *CreateEffectVehicleAbove(int x, int y, int z, EffectVehicle type); |
|
607 Vehicle *CreateEffectVehicleRel(const Vehicle *v, int x, int y, int z, EffectVehicle type); |
|
608 |
|
609 uint32 VehicleEnterTile(Vehicle *v, TileIndex tile, int x, int y); |
|
610 |
|
611 StringID VehicleInTheWayErrMsg(const Vehicle* v); |
|
612 Vehicle *FindVehicleBetween(TileIndex from, TileIndex to, byte z, bool without_crashed = false); |
|
613 |
|
614 bool UpdateSignalsOnSegment(TileIndex tile, DiagDirection direction); |
|
615 void SetSignalsOnBothDir(TileIndex tile, byte track); |
|
616 |
|
617 Vehicle *CheckClickOnVehicle(const ViewPort *vp, int x, int y); |
|
618 |
|
619 void DecreaseVehicleValue(Vehicle *v); |
|
620 void CheckVehicleBreakdown(Vehicle *v); |
|
621 void AgeVehicle(Vehicle *v); |
|
622 void VehicleEnteredDepotThisTick(Vehicle *v); |
|
623 |
|
624 void BeginVehicleMove(Vehicle *v); |
|
625 void EndVehicleMove(Vehicle *v); |
|
626 |
|
627 UnitID GetFreeUnitNumber(VehicleType type); |
|
628 |
|
629 void TrainConsistChanged(Vehicle *v); |
|
630 void TrainPowerChanged(Vehicle *v); |
|
631 Money GetTrainRunningCost(const Vehicle *v); |
|
632 |
|
633 bool VehicleNeedsService(const Vehicle *v); |
|
634 |
|
635 uint GenerateVehicleSortList(const Vehicle*** sort_list, uint16 *length_of_array, VehicleType type, PlayerID owner, uint32 index, uint16 window_type); |
|
636 void BuildDepotVehicleList(VehicleType type, TileIndex tile, Vehicle ***engine_list, uint16 *engine_list_length, uint16 *engine_count, Vehicle ***wagon_list, uint16 *wagon_list_length, uint16 *wagon_count); |
|
637 CommandCost SendAllVehiclesToDepot(VehicleType type, uint32 flags, bool service, PlayerID owner, uint16 vlw_flag, uint32 id); |
|
638 void VehicleEnterDepot(Vehicle *v); |
|
639 |
|
640 void InvalidateAutoreplaceWindow(EngineID e, GroupID id_g); |
|
641 |
|
642 CommandCost MaybeReplaceVehicle(Vehicle *v, bool check, bool display_costs); |
|
643 bool CanBuildVehicleInfrastructure(VehicleType type); |
|
644 |
|
645 void CcCloneVehicle(bool success, TileIndex tile, uint32 p1, uint32 p2); |
|
646 |
|
647 /* Flags to add to p2 for goto depot commands */ |
|
648 /* Note: bits 8-10 are used for VLW flags */ |
|
649 enum { |
|
650 DEPOT_SERVICE = (1 << 0), // The vehicle will leave the depot right after arrival (serivce only) |
|
651 DEPOT_MASS_SEND = (1 << 1), // Tells that it's a mass send to depot command (type in VLW flag) |
|
652 DEPOT_DONT_CANCEL = (1 << 2), // Don't cancel current goto depot command if any |
|
653 DEPOT_LOCATE_HANGAR = (1 << 3), // Find another airport if the target one lacks a hangar |
|
654 }; |
|
655 |
|
656 struct GetNewVehiclePosResult { |
|
657 int x, y; |
|
658 TileIndex old_tile; |
|
659 TileIndex new_tile; |
|
660 }; |
|
661 |
|
662 /** |
|
663 * Returns the Trackdir on which the vehicle is currently located. |
|
664 * Works for trains and ships. |
|
665 * Currently works only sortof for road vehicles, since they have a fuzzy |
|
666 * concept of being "on" a trackdir. Dunno really what it returns for a road |
|
667 * vehicle that is halfway a tile, never really understood that part. For road |
|
668 * vehicles that are at the beginning or end of the tile, should just return |
|
669 * the diagonal trackdir on which they are driving. I _think_. |
|
670 * For other vehicles types, or vehicles with no clear trackdir (such as those |
|
671 * in depots), returns 0xFF. |
|
672 */ |
|
673 Trackdir GetVehicleTrackdir(const Vehicle* v); |
|
674 |
|
675 /* returns true if staying in the same tile */ |
|
676 GetNewVehiclePosResult GetNewVehiclePos(const Vehicle *v); |
|
677 Direction GetDirectionTowards(const Vehicle *v, int x, int y); |
|
678 |
|
679 #define BEGIN_ENUM_WAGONS(v) do { |
|
680 #define END_ENUM_WAGONS(v) } while ((v = v->Next()) != NULL); |
|
681 |
|
682 static inline VehicleID GetMaxVehicleIndex() |
|
683 { |
|
684 /* TODO - This isn't the real content of the function, but |
|
685 * with the new pool-system this will be replaced with one that |
|
686 * _really_ returns the highest index. Now it just returns |
|
687 * the next safe value we are sure about everything is below. |
|
688 */ |
|
689 return GetVehiclePoolSize() - 1; |
|
690 } |
|
691 |
|
692 static inline uint GetNumVehicles() |
|
693 { |
|
694 return GetVehiclePoolSize(); |
|
695 } |
|
696 |
|
697 static inline bool IsPlayerBuildableVehicleType(VehicleType type) |
|
698 { |
|
699 switch (type) { |
|
700 case VEH_TRAIN: |
|
701 case VEH_ROAD: |
|
702 case VEH_SHIP: |
|
703 case VEH_AIRCRAFT: |
|
704 return true; |
|
705 |
|
706 default: return false; |
|
707 } |
|
708 } |
|
709 |
|
710 static inline bool IsPlayerBuildableVehicleType(const Vehicle *v) |
|
711 { |
|
712 return IsPlayerBuildableVehicleType(v->type); |
|
713 } |
|
714 |
|
715 #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()) |
|
716 #define FOR_ALL_VEHICLES(v) FOR_ALL_VEHICLES_FROM(v, 0) |
|
717 |
|
718 /** |
|
719 * Check if an index is a vehicle-index (so between 0 and max-vehicles) |
|
720 * @param index of the vehicle to query |
|
721 * @return Returns true if the vehicle-id is in range |
|
722 */ |
|
723 static inline bool IsValidVehicleID(uint index) |
|
724 { |
|
725 return index < GetVehiclePoolSize() && GetVehicle(index)->IsValid(); |
|
726 } |
|
727 |
|
728 /* Returns order 'index' of a vehicle or NULL when it doesn't exists */ |
|
729 static inline Order *GetVehicleOrder(const Vehicle *v, int index) |
|
730 { |
|
731 Order *order = v->orders; |
|
732 |
|
733 if (index < 0) return NULL; |
|
734 |
|
735 while (order != NULL && index-- > 0) |
|
736 order = order->next; |
|
737 |
|
738 return order; |
|
739 } |
|
740 |
|
741 /** |
|
742 * Returns the last order of a vehicle, or NULL if it doesn't exists |
|
743 * @param v Vehicle to query |
|
744 * @return last order of a vehicle, if available |
|
745 */ |
|
746 static inline Order *GetLastVehicleOrder(const Vehicle *v) |
|
747 { |
|
748 Order *order = v->orders; |
|
749 |
|
750 if (order == NULL) return NULL; |
|
751 |
|
752 while (order->next != NULL) |
|
753 order = order->next; |
|
754 |
|
755 return order; |
|
756 } |
|
757 |
|
758 /** Get the first vehicle of a shared-list, so we only have to walk forwards |
|
759 * @param v Vehicle to query |
|
760 * @return first vehicle of a shared-list |
|
761 */ |
|
762 static inline Vehicle *GetFirstVehicleFromSharedList(const Vehicle *v) |
|
763 { |
|
764 Vehicle *u = (Vehicle *)v; |
|
765 while (u->prev_shared != NULL) u = u->prev_shared; |
|
766 |
|
767 return u; |
|
768 } |
|
769 |
|
770 /* NOSAVE: Return values from various commands. */ |
|
771 VARDEF VehicleID _new_vehicle_id; |
|
772 VARDEF uint16 _returned_refit_capacity; |
|
773 |
|
774 static const VehicleID INVALID_VEHICLE = 0xFFFF; |
|
775 |
|
776 const struct Livery *GetEngineLivery(EngineID engine_type, PlayerID player, EngineID parent_engine_type, const Vehicle *v); |
|
777 |
|
778 /** |
|
779 * Get the colour map for an engine. This used for unbuilt engines in the user interface. |
|
780 * @param engine_type ID of engine |
|
781 * @param player ID of player |
|
782 * @return A ready-to-use palette modifier |
|
783 */ |
|
784 SpriteID GetEnginePalette(EngineID engine_type, PlayerID player); |
|
785 |
|
786 /** |
|
787 * Get the colour map for a vehicle. |
|
788 * @param v Vehicle to get colour map for |
|
789 * @return A ready-to-use palette modifier |
|
790 */ |
|
791 SpriteID GetVehiclePalette(const Vehicle *v); |
|
792 |
|
793 /* A lot of code calls for the invalidation of the status bar, which is widget 5. |
|
794 * Best is to have a virtual value for it when it needs to change again */ |
|
795 #define STATUS_BAR 5 |
|
796 |
|
797 extern const uint32 _veh_build_proc_table[]; |
|
798 extern const uint32 _veh_sell_proc_table[]; |
|
799 extern const uint32 _veh_refit_proc_table[]; |
|
800 extern const uint32 _send_to_depot_proc_table[]; |
|
801 |
|
802 /* Functions to find the right command for certain vehicle type */ |
|
803 static inline uint32 GetCmdBuildVeh(VehicleType type) |
|
804 { |
|
805 return _veh_build_proc_table[type]; |
|
806 } |
|
807 |
|
808 static inline uint32 GetCmdBuildVeh(const Vehicle *v) |
|
809 { |
|
810 return GetCmdBuildVeh(v->type); |
|
811 } |
|
812 |
|
813 static inline uint32 GetCmdSellVeh(VehicleType type) |
|
814 { |
|
815 return _veh_sell_proc_table[type]; |
|
816 } |
|
817 |
|
818 static inline uint32 GetCmdSellVeh(const Vehicle *v) |
|
819 { |
|
820 return GetCmdSellVeh(v->type); |
|
821 } |
|
822 |
|
823 static inline uint32 GetCmdRefitVeh(VehicleType type) |
|
824 { |
|
825 return _veh_refit_proc_table[type]; |
|
826 } |
|
827 |
|
828 static inline uint32 GetCmdRefitVeh(const Vehicle *v) |
|
829 { |
|
830 return GetCmdRefitVeh(v->type); |
|
831 } |
|
832 |
|
833 static inline uint32 GetCmdSendToDepot(VehicleType type) |
|
834 { |
|
835 return _send_to_depot_proc_table[type]; |
|
836 } |
|
837 |
|
838 static inline uint32 GetCmdSendToDepot(const Vehicle *v) |
|
839 { |
|
840 return GetCmdSendToDepot(v->type); |
|
841 } |
|
842 |
|
843 #endif /* VEHICLE_H */ |
|