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