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 */

Generated on Thu Sep 24 19:35:07 2009 for OpenTTD by  doxygen 1.5.6