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