# vehicle_base.h

Go to the documentation of this file.

    00001 /* $Id: vehicle_base.h 13017 2008-05-08 17:30:02Z rubidium $ */
    00002
    00005 #ifndef VEHICLE_BASE_H
    00006 #define VEHICLE_BASE_H
    00007
    00008 #include "vehicle_type.h"
    00009 #include "track_type.h"
    00010 #include "rail_type.h"
    00011 #include "road_type.h"
    00012 #include "cargo_type.h"
    00013 #include "direction_type.h"
    00014 #include "window_type.h"
    00015 #include "gfx_type.h"
    00016 #include "command_type.h"
    00017 #include "date_type.h"
    00018 #include "player_type.h"
    00019 #include "oldpool.h"
    00020 #include "order.h"
    00021 #include "cargopacket.h"
    00022 #include "texteff.hpp"
    00023
    00025 enum RoadVehicleStates {
    00026   /*
    00027    * Lower 4 bits are used for vehicle track direction. (Trackdirs)
    00028    * When in a road stop (bit 5 or bit 6 set) these bits give the
    00029    * track direction of the entry to the road stop.
    00030    * As the entry direction will always be a diagonal
    00031    * direction (X_NE, Y_SE, X_SW or Y_NW) only bits 0 and 3
    00032    * are needed to hold this direction. Bit 1 is then used to show
    00033    * that the vehicle is using the second road stop bay.
    00034    * Bit 2 is then used for drive-through stops to show the vehicle
    00035    * is stopping at this road stop.
    00036    */
    00037
    00038   /* Numeric values */
    00039   RVSB_IN_DEPOT                = 0xFE,
    00040   RVSB_WORMHOLE                = 0xFF,
    00041
    00042   /* Bit numbers */
    00043   RVS_USING_SECOND_BAY         =    1,
    00044   RVS_IS_STOPPING              =    2,
    00045   RVS_DRIVE_SIDE               =    4,
    00046   RVS_IN_ROAD_STOP             =    5,
    00047   RVS_IN_DT_ROAD_STOP          =    6,
    00048
    00049   /* Bit sets of the above specified bits */
    00050   RVSB_IN_ROAD_STOP            = 1 << RVS_IN_ROAD_STOP,
    00051   RVSB_IN_ROAD_STOP_END        = RVSB_IN_ROAD_STOP + TRACKDIR_END,
    00052   RVSB_IN_DT_ROAD_STOP         = 1 << RVS_IN_DT_ROAD_STOP,
    00053   RVSB_IN_DT_ROAD_STOP_END     = RVSB_IN_DT_ROAD_STOP + TRACKDIR_END,
    00054
    00055   RVSB_TRACKDIR_MASK           = 0x0F,
    00056   RVSB_ROAD_STOP_TRACKDIR_MASK = 0x09
    00057 };
    00058
    00059 enum VehStatus {
    00060   VS_HIDDEN          = 0x01,
    00061   VS_STOPPED         = 0x02,
    00062   VS_UNCLICKABLE     = 0x04,
    00063   VS_DEFPAL          = 0x08,
    00064   VS_TRAIN_SLOWING   = 0x10,
    00065   VS_SHADOW          = 0x20,
    00066   VS_AIRCRAFT_BROKEN = 0x40,
    00067   VS_CRASHED         = 0x80,
    00068 };
    00069
    00070 enum VehicleFlags {
    00071   VF_LOADING_FINISHED,
    00072   VF_CARGO_UNLOADING,
    00073   VF_BUILT_AS_PROTOTYPE,
    00074   VF_TIMETABLE_STARTED,
    00075   VF_AUTOFILL_TIMETABLE,
    00076 };
    00077
    00078 struct VehicleRail {
    00079   uint16 last_speed; // NOSAVE: only used in UI
    00080   uint16 crash_anim_pos;
    00081
    00082   /* cached values, recalculated on load and each time a vehicle is added to/removed from the consist. */
    00083   uint16 cached_max_speed;  // max speed of the consist. (minimum of the max speed of all vehicles in the consist)
    00084   uint32 cached_power;      // total power of the consist.
    00085   bool cached_tilt;         // train can tilt; feature provides a bonus in curves
    00086   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
    00087   uint16 cached_total_length;
    00088
    00089   /* cached values, recalculated when the cargo on a train changes (in addition to the conditions above) */
    00090   uint32 cached_weight;     // total weight of the consist.
    00091   uint32 cached_veh_weight; // weight of the vehicle.
    00092   uint32 cached_max_te;     // max tractive effort of consist
    00100   byte cached_vis_effect;
    00101   byte user_def_data;
    00102
    00103   /* NOSAVE: for wagon override - id of the first engine in train
    00104    * 0xffff == not in train */
    00105   EngineID first_engine;
    00106
    00107   TrackBitsByte track;
    00108   byte force_proceed;
    00109   RailTypeByte railtype;
    00110   RailTypes compatible_railtypes;
    00111
    00112   byte flags;
    00113
    00114   /* Link between the two ends of a multiheaded engine */
    00115   Vehicle *other_multiheaded_part;
    00116
    00117   /* Cached wagon override spritegroup */
    00118   const struct SpriteGroup *cached_override;
    00119 };
    00120
    00121 enum VehicleRailFlags {
    00122   VRF_REVERSING         = 0,
    00123
    00124   /* used to calculate if train is going up or down */
    00125   VRF_GOINGUP           = 1,
    00126   VRF_GOINGDOWN         = 2,
    00127
    00128   /* used to store if a wagon is powered or not */
    00129   VRF_POWEREDWAGON      = 3,
    00130
    00131   /* used to reverse the visible direction of the vehicle */
    00132   VRF_REVERSE_DIRECTION = 4,
    00133
    00134   /* used to mark train as lost because PF can't find the route */
    00135   VRF_NO_PATH_TO_DESTINATION = 5,
    00136
    00137   /* used to mark that electric train engine is allowed to run on normal rail */
    00138   VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL = 6,
    00139
    00140   /* used for vehicle var 0xFE bit 8 (toggled each time the train is reversed) */
    00141   VRF_TOGGLE_REVERSE = 7,
    00142 };
    00143
    00144 struct VehicleAir {
    00145   uint16 crashed_counter;
    00146   uint16 cached_max_speed;
    00147   byte pos;
    00148   byte previous_pos;
    00149   StationID targetairport;
    00150   byte state;
    00151 };
    00152
    00153 struct VehicleRoad {
    00154   byte state;
    00155   byte frame;
    00156   uint16 blocked_ctr;
    00157   byte overtaking;
    00158   byte overtaking_ctr;
    00159   uint16 crashed_ctr;
    00160   byte reverse_ctr;
    00161   struct RoadStop *slot;
    00162   byte slot_age;
    00163   EngineID first_engine;
    00164   byte cached_veh_length;
    00165
    00166   RoadType roadtype;
    00167   RoadTypes compatible_roadtypes;
    00168 };
    00169
    00170 struct VehicleSpecial {
    00171   uint16 animation_state;
    00172   byte animation_substate;
    00173 };
    00174
    00175 struct VehicleDisaster {
    00176   uint16 image_override;
    00177   VehicleID big_ufo_destroyer_target;
    00178 };
    00179
    00180 struct VehicleShip {
    00181   TrackBitsByte state;
    00182 };
    00183
    00184 DECLARE_OLD_POOL(Vehicle, Vehicle, 9, 125)
    00185
    00186 /* Some declarations of functions, so we can make them friendly */
    00187 struct SaveLoad;
    00188 extern const SaveLoad *GetVehicleDescription(VehicleType vt);
    00189 extern void AfterLoadVehicles(bool clear_te_id);
    00190 struct LoadgameState;
    00191 extern bool LoadOldVehicle(LoadgameState *ls, int num);
    00192
    00193 struct Vehicle : PoolItem<Vehicle, VehicleID, &_Vehicle_pool>, BaseVehicle {
    00194   byte subtype;            // subtype (Filled with values from EffectVehicles/TrainSubTypes/AircraftSubTypes)
    00195
    00196 private:
    00197   Vehicle *next;           // pointer to the next vehicle in the chain
    00198   Vehicle *previous;       // NOSAVE: pointer to the previous vehicle in the chain
    00199   Vehicle *first;          // NOSAVE: pointer to the first vehicle in the chain
    00200 public:
    00201   friend const SaveLoad *GetVehicleDescription(VehicleType vt); // So we can use private/protected variables in the saveload code
    00202   friend void AfterLoadVehicles(bool clear_te_id);              // So we can set the previous and first pointers while loading
    00203   friend bool LoadOldVehicle(LoadgameState *ls, int num);       // So we can set the proper next pointer while loading
    00204
    00205   Vehicle *depot_list;     // NOSAVE: linked list to tell what vehicles entered a depot during the last tick. Used by autoreplace
    00206
    00207   char *name;
    00208
    00209   UnitID unitnumber;       // unit number, for display purposes only
    00210   PlayerByte owner;        // which player owns the vehicle?
    00211
    00212   TileIndex tile;          // Current tile index
    00213   TileIndex dest_tile;     // Heading for this tile
    00214
    00215   int32 x_pos;             // coordinates
    00216   int32 y_pos;
    00217   byte z_pos;
    00218   DirectionByte direction; // facing
    00219
    00220   byte spritenum;          // currently displayed sprite index
    00221                            // 0xfd == custom sprite, 0xfe == custom second head sprite
    00222                            // 0xff == reserved for another custom sprite
    00223   uint16 cur_image;        // sprite number for this vehicle
    00224   byte sprite_width;       // width of vehicle sprite
    00225   byte sprite_height;      // height of vehicle sprite
    00226   byte z_height;           // z-height of vehicle sprite
    00227   int8 x_offs;             // x offset for vehicle sprite
    00228   int8 y_offs;             // y offset for vehicle sprite
    00229   EngineID engine_type;
    00230
    00231   TextEffectID fill_percent_te_id; // a text-effect id to a loading indicator object
    00232
    00233   /* for randomized variational spritegroups
    00234    * bitmask used to resolve them; parts of it get reseeded when triggers
    00235    * of corresponding spritegroups get matched */
    00236   byte random_bits;
    00237   byte waiting_triggers;   // triggers to be yet matched
    00238
    00239   uint16 max_speed;        // maximum speed
    00240   uint16 cur_speed;        // current speed
    00241   byte subspeed;           // fractional speed
    00242   byte acceleration;       // used by train & aircraft
    00243   byte progress;
    00244   uint32 motion_counter;
    00245
    00246   byte vehstatus;          // Status
    00247   StationID last_station_visited;
    00248
    00249   CargoID cargo_type;      // type of cargo this vehicle is carrying
    00250   uint16 cargo_cap;        // total capacity
    00251   byte cargo_subtype;
    00252   CargoList cargo;
    00253
    00254
    00255   byte day_counter;
    00256   byte tick_counter;
    00257   byte running_ticks;
    00258
    00259   /* Begin Order-stuff */
    00260   Order current_order;
    00261   VehicleOrderID cur_order_index;
    00262
    00263   Order *orders;
    00264   VehicleOrderID num_orders;
    00265
    00266   Vehicle *next_shared;
    00267   Vehicle *prev_shared;
    00268   /* End Order-stuff */
    00269
    00270   /* Boundaries for the current position in the world and a next hash link.
    00271    * NOSAVE: All of those can be updated with VehiclePositionChanged() */
    00272   int32 left_coord;
    00273   int32 top_coord;
    00274   int32 right_coord;
    00275   int32 bottom_coord;
    00276   Vehicle *next_hash;
    00277   Vehicle *next_new_hash;
    00278   Vehicle **old_new_hash;
    00279
    00280   /* Related to age and service time */
    00281   Date age;     // Age in days
    00282   Date max_age; // Maximum age
    00283   Date date_of_last_service;
    00284   Date service_interval;
    00285   uint16 reliability;
    00286   uint16 reliability_spd_dec;
    00287   byte breakdown_ctr;
    00288   byte breakdown_delay;
    00289   byte breakdowns_since_last_service;
    00290   byte breakdown_chance;
    00291   Year build_year;
    00292
    00293   bool leave_depot_instantly; // NOSAVE: stores if the vehicle needs to leave the depot it just entered. Used by autoreplace
    00294
    00295   uint16 load_unload_time_rem;
    00296   byte vehicle_flags;         // Used for gradual loading and other miscellaneous things (@see VehicleFlags enum)
    00297
    00298   Money profit_this_year;
    00299   Money profit_last_year;
    00300   Money value;
    00301
    00302   GroupID group_id;
    00303
    00304   /* Used for timetabling. */
    00305   uint32 current_order_time;
    00306   int32 lateness_counter;
    00307
    00308   SpriteID colormap; // NOSAVE: cached color mapping
    00309
    00310   union {
    00311     VehicleRail rail;
    00312     VehicleAir air;
    00313     VehicleRoad road;
    00314     VehicleSpecial special;
    00315     VehicleDisaster disaster;
    00316     VehicleShip ship;
    00317   } u;
    00318
    00319
    00326   static bool AllocateList(Vehicle **vl, int num);
    00327
    00329   Vehicle();
    00330
    00332   void PreDestructor();
    00334   virtual ~Vehicle();
    00335
    00336   void BeginLoading();
    00337   void LeaveStation();
    00338
    00344   void HandleLoading(bool mode = false);
    00345
    00350   virtual const char* GetTypeString() const { return "base vehicle"; }
    00351
    00360   virtual void MarkDirty() {}
    00361
    00367   virtual void UpdateDeltaXY(Direction direction) {}
    00368
    00373   virtual ExpensesType GetExpenseType(bool income) const { return EXPENSES_OTHER; }
    00374
    00378   virtual WindowClass GetVehicleListWindowClass() const { return WC_NONE; }
    00379
    00383   virtual void PlayLeaveStationSound() const {}
    00384
    00388   virtual bool IsPrimaryVehicle() const { return false; }
    00389
    00395   virtual int GetImage(Direction direction) const { return 0; }
    00396
    00401   virtual int GetDisplaySpeed() const { return 0; }
    00402
    00407   virtual int GetDisplayMaxSpeed() const { return 0; }
    00408
    00413   virtual Money GetRunningCost() const { return 0; }
    00414
    00419   virtual bool IsInDepot() const { return false; }
    00420
    00425   virtual bool IsStoppedInDepot() const { return this->IsInDepot() && (this->vehstatus & VS_STOPPED) != 0; }
    00426
    00430   virtual void Tick() {};
    00431
    00435   virtual void OnNewDay() {};
    00436
    00441   Money GetDisplayRunningCost() const { return (this->GetRunningCost() >> 8); }
    00442
    00447   Money GetDisplayProfitThisYear() const { return (this->profit_this_year >> 8); }
    00448
    00453   Money GetDisplayProfitLastYear() const { return (this->profit_last_year >> 8); }
    00454
    00459   void SetNext(Vehicle *next);
    00460
    00466   inline Vehicle *Next() const { return this->next; }
    00467
    00473   inline Vehicle *Previous() const { return this->previous; }
    00474
    00479   inline Vehicle *First() const { return this->first; }
    00480
    00486   inline bool IsOrderListShared() const { return this->next_shared != NULL || this->prev_shared != NULL; };
    00487
    00488   bool NeedsAutorenewing(const Player *p) const;
    00489
    00496   bool NeedsServicing() const;
    00497
    00503   bool NeedsAutomaticServicing() const;
    00504 };
    00505
    00521 struct SpecialVehicle : public Vehicle {
    00523   SpecialVehicle() { this->type = VEH_SPECIAL; }
    00524
    00526   virtual ~SpecialVehicle() {}
    00527
    00528   const char *GetTypeString() const { return "special vehicle"; }
    00529   void UpdateDeltaXY(Direction direction);
    00530   void Tick();
    00531 };
    00532
    00541 struct DisasterVehicle : public Vehicle {
    00543   DisasterVehicle() { this->type = VEH_DISASTER; }
    00544
    00546   virtual ~DisasterVehicle() {}
    00547
    00548   const char *GetTypeString() const { return "disaster vehicle"; }
    00549   void UpdateDeltaXY(Direction direction);
    00550   void Tick();
    00551 };
    00552
    00561 struct InvalidVehicle : public Vehicle {
    00563   InvalidVehicle() { this->type = VEH_INVALID; }
    00564
    00566   virtual ~InvalidVehicle() {}
    00567
    00568   const char *GetTypeString() const { return "invalid vehicle"; }
    00569   void Tick() {}
    00570 };
    00571
    00572 #define BEGIN_ENUM_WAGONS(v) do {
    00573 #define END_ENUM_WAGONS(v) } while ((v = v->Next()) != NULL);
    00574
    00575 static inline VehicleID GetMaxVehicleIndex()
    00576 {
    00577   /* TODO - This isn't the real content of the function, but
    00578    *  with the new pool-system this will be replaced with one that
    00579    *  _really_ returns the highest index. Now it just returns
    00580    *  the next safe value we are sure about everything is below.
    00581    */
    00582   return GetVehiclePoolSize() - 1;
    00583 }
    00584
    00585 static inline uint GetNumVehicles()
    00586 {
    00587   return GetVehiclePoolSize();
    00588 }
    00589
    00590 #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())
    00591 #define FOR_ALL_VEHICLES(v) FOR_ALL_VEHICLES_FROM(v, 0)
    00592
    00598 static inline bool IsValidVehicleID(uint index)
    00599 {
    00600   return index < GetVehiclePoolSize() && GetVehicle(index)->IsValid();
    00601 }
    00602
    00603 /* Returns order 'index' of a vehicle or NULL when it doesn't exists */
    00604 static inline Order *GetVehicleOrder(const Vehicle *v, int index)
    00605 {
    00606   Order *order = v->orders;
    00607
    00608   if (index < 0) return NULL;
    00609
    00610   while (order != NULL && index-- > 0)
    00611     order = order->next;
    00612
    00613   return order;
    00614 }
    00615
    00621 static inline Order *GetLastVehicleOrder(const Vehicle *v)
    00622 {
    00623   Order *order = v->orders;
    00624
    00625   if (order == NULL) return NULL;
    00626
    00627   while (order->next != NULL)
    00628     order = order->next;
    00629
    00630   return order;
    00631 }
    00632
    00637 static inline Vehicle *GetFirstVehicleFromSharedList(const Vehicle *v)
    00638 {
    00639   Vehicle *u = (Vehicle *)v;
    00640   while (u->prev_shared != NULL) u = u->prev_shared;
    00641
    00642   return u;
    00643 }
    00644
    00656 Trackdir GetVehicleTrackdir(const Vehicle* v);
    00657
    00658 void CheckVehicle32Day(Vehicle *v);
    00659
    00660 #endif /* VEHICLE_BASE_H */