# vehicle_base.h

Go to the documentation of this file.

    00001 /* $Id: vehicle_base.h 17160 2009-08-12 15:51:35Z 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 "gfx_type.h"
    00015 #include "command_type.h"
    00016 #include "date_type.h"
    00017 #include "company_base.h"
    00018 #include "company_type.h"
    00019 #include "oldpool.h"
    00020 #include "order_base.h"
    00021 #include "cargopacket.h"
    00022 #include "texteff.hpp"
    00023 #include "group_type.h"
    00024 #include "engine_type.h"
    00025 #include "order_func.h"
    00026 #include "transport_type.h"
    00027
    00029 enum RoadVehicleStates {
    00030   /*
    00031    * Lower 4 bits are used for vehicle track direction. (Trackdirs)
    00032    * When in a road stop (bit 5 or bit 6 set) these bits give the
    00033    * track direction of the entry to the road stop.
    00034    * As the entry direction will always be a diagonal
    00035    * direction (X_NE, Y_SE, X_SW or Y_NW) only bits 0 and 3
    00036    * are needed to hold this direction. Bit 1 is then used to show
    00037    * that the vehicle is using the second road stop bay.
    00038    * Bit 2 is then used for drive-through stops to show the vehicle
    00039    * is stopping at this road stop.
    00040    */
    00041
    00042   /* Numeric values */
    00043   RVSB_IN_DEPOT                = 0xFE,
    00044   RVSB_WORMHOLE                = 0xFF,
    00045
    00046   /* Bit numbers */
    00047   RVS_USING_SECOND_BAY         =    1,
    00048   RVS_IS_STOPPING              =    2,
    00049   RVS_DRIVE_SIDE               =    4,
    00050   RVS_IN_ROAD_STOP             =    5,
    00051   RVS_IN_DT_ROAD_STOP          =    6,
    00052
    00053   /* Bit sets of the above specified bits */
    00054   RVSB_IN_ROAD_STOP            = 1 << RVS_IN_ROAD_STOP,
    00055   RVSB_IN_ROAD_STOP_END        = RVSB_IN_ROAD_STOP + TRACKDIR_END,
    00056   RVSB_IN_DT_ROAD_STOP         = 1 << RVS_IN_DT_ROAD_STOP,
    00057   RVSB_IN_DT_ROAD_STOP_END     = RVSB_IN_DT_ROAD_STOP + TRACKDIR_END,
    00058
    00059   RVSB_TRACKDIR_MASK           = 0x0F,
    00060   RVSB_ROAD_STOP_TRACKDIR_MASK = 0x09
    00061 };
    00062
    00063 enum VehStatus {
    00064   VS_HIDDEN          = 0x01,
    00065   VS_STOPPED         = 0x02,
    00066   VS_UNCLICKABLE     = 0x04,
    00067   VS_DEFPAL          = 0x08,
    00068   VS_TRAIN_SLOWING   = 0x10,
    00069   VS_SHADOW          = 0x20,
    00070   VS_AIRCRAFT_BROKEN = 0x40,
    00071   VS_CRASHED         = 0x80,
    00072 };
    00073
    00074 enum VehicleFlags {
    00075   VF_LOADING_FINISHED,
    00076   VF_CARGO_UNLOADING,
    00077   VF_BUILT_AS_PROTOTYPE,
    00078   VF_TIMETABLE_STARTED,
    00079   VF_AUTOFILL_TIMETABLE,
    00080   VF_AUTOFILL_PRES_WAIT_TIME,
    00081 };
    00082
    00083 struct VehicleRail {
    00084   /* Link between the two ends of a multiheaded engine */
    00085   Vehicle *other_multiheaded_part;
    00086
    00087   /* Cached wagon override spritegroup */
    00088   const struct SpriteGroup *cached_override;
    00089
    00090   uint16 last_speed; // NOSAVE: only used in UI
    00091   uint16 crash_anim_pos;
    00092
    00093   /* cached values, recalculated on load and each time a vehicle is added to/removed from the consist. */
    00094   uint32 cached_power;
    00095   uint16 cached_max_speed;
    00096   uint16 cached_total_length;
    00097   uint8 cached_veh_length;
    00098   bool cached_tilt;
    00099
    00100   /* cached values, recalculated when the cargo on a train changes (in addition to the conditions above) */
    00101   uint32 cached_weight;
    00102   uint32 cached_veh_weight;
    00103   uint32 cached_max_te;
    00104
    00112   byte cached_vis_effect;
    00113   byte user_def_data;
    00114
    00115   /* NOSAVE: for wagon override - id of the first engine in train
    00116    * 0xffff == not in train */
    00117   EngineID first_engine;
    00118
    00119   uint16 flags;
    00120   TrackBitsByte track;
    00121   byte force_proceed;
    00122   RailTypeByte railtype;
    00123   RailTypes compatible_railtypes;
    00124 };
    00125
    00126 enum VehicleRailFlags {
    00127   VRF_REVERSING         = 0,
    00128
    00129   /* used to calculate if train is going up or down */
    00130   VRF_GOINGUP           = 1,
    00131   VRF_GOINGDOWN         = 2,
    00132
    00133   /* used to store if a wagon is powered or not */
    00134   VRF_POWEREDWAGON      = 3,
    00135
    00136   /* used to reverse the visible direction of the vehicle */
    00137   VRF_REVERSE_DIRECTION = 4,
    00138
    00139   /* used to mark train as lost because PF can't find the route */
    00140   VRF_NO_PATH_TO_DESTINATION = 5,
    00141
    00142   /* used to mark that electric train engine is allowed to run on normal rail */
    00143   VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL = 6,
    00144
    00145   /* used for vehicle var 0xFE bit 8 (toggled each time the train is reversed, accurate for first vehicle only) */
    00146   VRF_TOGGLE_REVERSE = 7,
    00147
    00148   /* used to mark a train that can't get a path reservation */
    00149   VRF_TRAIN_STUCK    = 8,
    00150 };
    00151
    00152 struct VehicleAir {
    00153   uint16 crashed_counter;
    00154   uint16 cached_max_speed;
    00155   byte pos;
    00156   byte previous_pos;
    00157   StationID targetairport;
    00158   byte state;
    00159 };
    00160
    00161 struct VehicleRoad {
    00162   byte state;
    00163   byte frame;
    00164   uint16 blocked_ctr;
    00165   byte overtaking;
    00166   byte overtaking_ctr;
    00167   uint16 crashed_ctr;
    00168   byte reverse_ctr;
    00169   struct RoadStop *slot;
    00170   byte slot_age;
    00171   EngineID first_engine;
    00172   byte cached_veh_length;
    00173
    00174   RoadType roadtype;
    00175   RoadTypes compatible_roadtypes;
    00176 };
    00177
    00178 struct VehicleEffect {
    00179   uint16 animation_state;
    00180   byte animation_substate;
    00181 };
    00182
    00183 struct VehicleDisaster {
    00184   uint16 image_override;
    00185   VehicleID big_ufo_destroyer_target;
    00186 };
    00187
    00188 struct VehicleShip {
    00189   TrackBitsByte state;
    00190 };
    00191
    00192 DECLARE_OLD_POOL(Vehicle, Vehicle, 9, 125)
    00193
    00194 /* Some declarations of functions, so we can make them friendly */
    00195 struct SaveLoad;
    00196 extern const SaveLoad *GetVehicleDescription(VehicleType vt);
    00197 struct LoadgameState;
    00198 extern bool LoadOldVehicle(LoadgameState *ls, int num);
    00199
    00200 struct Vehicle : PoolItem<Vehicle, VehicleID, &_Vehicle_pool>, BaseVehicle {
    00201 private:
    00202   Vehicle *next;
    00203   Vehicle *previous;
    00204   Vehicle *first;
    00205
    00206   Vehicle *next_shared;
    00207   Vehicle *previous_shared;
    00208 public:
    00209   friend const SaveLoad *GetVehicleDescription(VehicleType vt);
    00210   friend void AfterLoadVehicles(bool part_of_load);
    00211   friend bool LoadOldVehicle(LoadgameState *ls, int num);
    00212
    00213   char *name;
    00214
    00215   TileIndex tile;
    00216
    00222   TileIndex dest_tile;
    00223
    00224   Money profit_this_year;
    00225   Money profit_last_year;
    00226   Money value;
    00227
    00228   CargoPayment *cargo_payment;
    00229
    00230   /* Used for timetabling. */
    00231   uint32 current_order_time;
    00232   int32 lateness_counter;
    00233
    00234   /* Boundaries for the current position in the world and a next hash link.
    00235    * NOSAVE: All of those can be updated with VehiclePositionChanged() */
    00236   Rect coord;
    00237   Vehicle *next_hash;
    00238   Vehicle *next_new_hash;
    00239   Vehicle **old_new_hash;
    00240
    00241   SpriteID colourmap; // NOSAVE: cached colour mapping
    00242
    00243   /* Related to age and service time */
    00244   Year build_year;
    00245   Date age;     // Age in days
    00246   Date max_age; // Maximum age
    00247   Date date_of_last_service;
    00248   Date service_interval;
    00249   uint16 reliability;
    00250   uint16 reliability_spd_dec;
    00251   byte breakdown_ctr;
    00252   byte breakdown_delay;
    00253   byte breakdowns_since_last_service;
    00254   byte breakdown_chance;
    00255
    00256   int32 x_pos;             // coordinates
    00257   int32 y_pos;
    00258   byte z_pos;
    00259   DirectionByte direction; // facing
    00260
    00261   OwnerByte owner;         // which company owns the vehicle?
    00262   byte spritenum;          // currently displayed sprite index
    00263                            // 0xfd == custom sprite, 0xfe == custom second head sprite
    00264                            // 0xff == reserved for another custom sprite
    00265   uint16 cur_image;        // sprite number for this vehicle
    00266   byte x_extent;           // x-extent of vehicle bounding box
    00267   byte y_extent;           // y-extent of vehicle bounding box
    00268   byte z_extent;           // z-extent of vehicle bounding box
    00269   int8 x_offs;             // x offset for vehicle sprite
    00270   int8 y_offs;             // y offset for vehicle sprite
    00271   EngineID engine_type;
    00272
    00273   TextEffectID fill_percent_te_id; // a text-effect id to a loading indicator object
    00274   UnitID unitnumber;       // unit number, for display purposes only
    00275
    00276   uint16 max_speed;
    00277   uint16 cur_speed;
    00278   byte subspeed;
    00279   byte acceleration;
    00280   uint32 motion_counter;
    00281   byte progress;
    00282
    00283   /* for randomized variational spritegroups
    00284    * bitmask used to resolve them; parts of it get reseeded when triggers
    00285    * of corresponding spritegroups get matched */
    00286   byte random_bits;
    00287   byte waiting_triggers;
    00288
    00289   StationID last_station_visited;
    00290
    00291   CargoID cargo_type;
    00292   byte cargo_subtype;
    00293   uint16 cargo_cap;
    00294   CargoList cargo;
    00295
    00296   byte day_counter;
    00297   byte tick_counter;
    00298   byte running_ticks;
    00299
    00300   byte vehstatus;
    00301   Order current_order;
    00302   VehicleOrderID cur_order_index;
    00303
    00304   union {
    00305     OrderList *list;
    00306     Order     *old;
    00307   } orders;
    00308
    00309   byte vehicle_flags;
    00310   uint16 load_unload_time_rem;
    00311
    00312   GroupID group_id;
    00313
    00314   byte subtype;
    00315
    00316   union {
    00317     VehicleRail rail;
    00318     VehicleAir air;
    00319     VehicleRoad road;
    00320     VehicleEffect effect;
    00321     VehicleDisaster disaster;
    00322     VehicleShip ship;
    00323   } u;
    00324
    00325   /* cached oftenly queried NewGRF values */
    00326   uint8 cache_valid;
    00327   uint32 cached_var40;
    00328   uint32 cached_var41;
    00329   uint32 cached_var42;
    00330   uint32 cached_var43;
    00331
    00338   static bool AllocateList(Vehicle **vl, int num);
    00339
    00341   Vehicle();
    00342
    00344   void PreDestructor();
    00346   virtual ~Vehicle();
    00347
    00348   void BeginLoading();
    00349   void LeaveStation();
    00350
    00356   void HandleLoading(bool mode = false);
    00357
    00362   virtual const char *GetTypeString() const { return "base vehicle"; }
    00363
    00372   virtual void MarkDirty() {}
    00373
    00379   virtual void UpdateDeltaXY(Direction direction) {}
    00380
    00385   virtual ExpensesType GetExpenseType(bool income) const { return EXPENSES_OTHER; }
    00386
    00390   virtual void PlayLeaveStationSound() const {}
    00391
    00395   virtual bool IsPrimaryVehicle() const { return false; }
    00396
    00402   virtual SpriteID GetImage(Direction direction) const { return 0; }
    00403
    00408   FORCEINLINE void InvalidateNewGRFCache()
    00409   {
    00410     this->cache_valid = 0;
    00411   }
    00412
    00417   FORCEINLINE void InvalidateNewGRFCacheOfChain()
    00418   {
    00419     for (Vehicle *u = this; u != NULL; u = u->Next()) {
    00420       u->InvalidateNewGRFCache();
    00421     }
    00422   }
    00423
    00428   virtual int GetDisplaySpeed() const { return 0; }
    00429
    00434   virtual int GetDisplayMaxSpeed() const { return 0; }
    00435
    00440   virtual Money GetRunningCost() const { return 0; }
    00441
    00446   virtual bool IsInDepot() const { return false; }
    00447
    00452   virtual bool IsStoppedInDepot() const { return this->IsInDepot() && (this->vehstatus & VS_STOPPED) != 0; }
    00453
    00457   virtual void Tick() {};
    00458
    00462   virtual void OnNewDay() {};
    00463
    00469   inline void UpdateViewport(bool moved, bool turned)
    00470   {
    00471     extern void VehicleMove(Vehicle *v, bool update_viewport);
    00472
    00473     if (turned) this->UpdateDeltaXY(this->direction);
    00474     SpriteID old_image = this->cur_image;
    00475     this->cur_image = this->GetImage(this->direction);
    00476     if (moved || this->cur_image != old_image) VehicleMove(this, true);
    00477   }
    00478
    00483   Money GetDisplayRunningCost() const { return (this->GetRunningCost() >> 8); }
    00484
    00489   Money GetDisplayProfitThisYear() const { return (this->profit_this_year >> 8); }
    00490
    00495   Money GetDisplayProfitLastYear() const { return (this->profit_last_year >> 8); }
    00496
    00501   void SetNext(Vehicle *next);
    00502
    00508   inline Vehicle *Next() const { return this->next; }
    00509
    00515   inline Vehicle *Previous() const { return this->previous; }
    00516
    00521   inline Vehicle *First() const { return this->first; }
    00522
    00523
    00528   inline Order *GetFirstOrder() const { return (this->orders.list == NULL) ? NULL : this->orders.list->GetFirstOrder(); }
    00529
    00535   void AddToShared(Vehicle *shared_chain);
    00536
    00540   void RemoveFromShared();
    00541
    00546   inline Vehicle *NextShared() const { return this->next_shared; }
    00547
    00552   inline Vehicle *PreviousShared() const { return this->previous_shared; }
    00553
    00558   inline Vehicle *FirstShared() const { return (this->orders.list == NULL) ? this->First() : this->orders.list->GetFirstSharedVehicle(); }
    00559
    00564   inline bool IsOrderListShared() const { return this->orders.list != NULL && this->orders.list->IsShared(); }
    00565
    00570   inline VehicleOrderID GetNumOrders() const { return (this->orders.list == NULL) ? 0 : this->orders.list->GetNumOrders(); }
    00571
    00578   inline void CopyVehicleConfigAndStatistics(const Vehicle *src)
    00579   {
    00580     this->unitnumber = src->unitnumber;
    00581
    00582     this->cur_order_index = src->cur_order_index;
    00583     this->current_order = src->current_order;
    00584     this->dest_tile  = src->dest_tile;
    00585
    00586     this->profit_this_year = src->profit_this_year;
    00587     this->profit_last_year = src->profit_last_year;
    00588
    00589     this->current_order_time = src->current_order_time;
    00590     this->lateness_counter = src->lateness_counter;
    00591
    00592     this->service_interval = src->service_interval;
    00593   }
    00594
    00595   bool NeedsAutorenewing(const Company *c) const;
    00596
    00603   bool NeedsServicing() const;
    00604
    00610   bool NeedsAutomaticServicing() const;
    00611
    00619   virtual TileIndex GetOrderStationLocation(StationID station) { return INVALID_TILE; }
    00620
    00629   virtual bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) { return false; }
    00630
    00637   CommandCost SendToDepot(DoCommandFlag flags, DepotCommand command);
    00638 };
    00639
    00648 struct DisasterVehicle : public Vehicle {
    00650   DisasterVehicle() { this->type = VEH_DISASTER; }
    00651
    00653   virtual ~DisasterVehicle() {}
    00654
    00655   const char *GetTypeString() const { return "disaster vehicle"; }
    00656   void UpdateDeltaXY(Direction direction);
    00657   void Tick();
    00658 };
    00659
    00668 struct InvalidVehicle : public Vehicle {
    00670   InvalidVehicle() { this->type = VEH_INVALID; }
    00671
    00673   virtual ~InvalidVehicle() {}
    00674
    00675   const char *GetTypeString() const { return "invalid vehicle"; }
    00676   void Tick() {}
    00677 };
    00678
    00679 static inline VehicleID GetMaxVehicleIndex()
    00680 {
    00681   /* TODO - This isn't the real content of the function, but
    00682    *  with the new pool-system this will be replaced with one that
    00683    *  _really_ returns the highest index. Now it just returns
    00684    *  the next safe value we are sure about everything is below.
    00685    */
    00686   return GetVehiclePoolSize() - 1;
    00687 }
    00688
    00689 static inline uint GetNumVehicles()
    00690 {
    00691   return GetVehiclePoolSize();
    00692 }
    00693
    00694 #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())
    00695 #define FOR_ALL_VEHICLES(v) FOR_ALL_VEHICLES_FROM(v, 0)
    00696
    00702 static inline bool IsValidVehicleID(uint index)
    00703 {
    00704   return index < GetVehiclePoolSize() && GetVehicle(index)->IsValid();
    00705 }
    00706
    00707
    00709 struct FreeUnitIDGenerator {
    00710   bool *cache;
    00711   UnitID maxid;
    00712   UnitID curid;
    00713
    00720   FreeUnitIDGenerator(VehicleType type, CompanyID owner);
    00721
    00723   UnitID NextID();
    00724
    00726   ~FreeUnitIDGenerator() { free(this->cache); }
    00727 };
    00728
    00729 /* Returns order 'index' of a vehicle or NULL when it doesn't exists */
    00730 static inline Order *GetVehicleOrder(const Vehicle *v, int index) { return (v->orders.list == NULL) ? NULL : v->orders.list->GetOrderAt(index); }
    00731
    00737 static inline Order *GetLastVehicleOrder(const Vehicle *v) { return (v->orders.list == NULL) ? NULL : v->orders.list->GetLastOrder(); }
    00738
    00750 Trackdir GetVehicleTrackdir(const Vehicle *v);
    00751
    00752 void CheckVehicle32Day(Vehicle *v);
    00753
    00754 static const int32 INVALID_COORD = 0x7fffffff;
    00755
    00756 #endif /* VEHICLE_BASE_H */