vehicle_base.h

Go to the documentation of this file.
00001 /* $Id: vehicle_base.h 18929 2010-01-27 20:07:29Z frosch $ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
00008  */
00009 
00012 #ifndef VEHICLE_BASE_H
00013 #define VEHICLE_BASE_H
00014 
00015 #include "track_type.h"
00016 #include "direction_type.h"
00017 #include "command_type.h"
00018 #include "order_base.h"
00019 #include "cargopacket.h"
00020 #include "texteff.hpp"
00021 #include "engine_type.h"
00022 #include "order_func.h"
00023 #include "transport_type.h"
00024 
00025 enum VehStatus {
00026   VS_HIDDEN          = 0x01,
00027   VS_STOPPED         = 0x02,
00028   VS_UNCLICKABLE     = 0x04,
00029   VS_DEFPAL          = 0x08,
00030   VS_TRAIN_SLOWING   = 0x10,
00031   VS_SHADOW          = 0x20,
00032   VS_AIRCRAFT_BROKEN = 0x40,
00033   VS_CRASHED         = 0x80,
00034 };
00035 
00036 enum VehicleFlags {
00037   VF_LOADING_FINISHED,
00038   VF_CARGO_UNLOADING,
00039   VF_BUILT_AS_PROTOTYPE,
00040   VF_TIMETABLE_STARTED,       
00041   VF_AUTOFILL_TIMETABLE,      
00042   VF_AUTOFILL_PRES_WAIT_TIME, 
00043 };
00044 
00046 struct VehicleCache {
00047   uint8 cache_valid;   
00048   uint32 cached_var40; 
00049   uint32 cached_var41; 
00050   uint32 cached_var42; 
00051   uint32 cached_var43; 
00052 };
00053 
00054 typedef Pool<Vehicle, VehicleID, 512, 64000> VehiclePool;
00055 extern VehiclePool _vehicle_pool;
00056 
00057 /* Some declarations of functions, so we can make them friendly */
00058 struct SaveLoad;
00059 extern const SaveLoad *GetVehicleDescription(VehicleType vt);
00060 struct LoadgameState;
00061 extern bool LoadOldVehicle(LoadgameState *ls, int num);
00062 extern bool AfterLoadGame();
00063 extern void FixOldVehicles();
00064 
00065 struct Vehicle : VehiclePool::PoolItem<&_vehicle_pool>, BaseVehicle {
00066 private:
00067   Vehicle *next;           
00068   Vehicle *previous;       
00069   Vehicle *first;          
00070 
00071   Vehicle *next_shared;     
00072   Vehicle *previous_shared; 
00073 public:
00074   friend const SaveLoad *GetVehicleDescription(VehicleType vt); 
00075   friend bool AfterLoadGame();
00076   friend void FixOldVehicles();
00077   friend void AfterLoadVehicles(bool part_of_load);             
00078   friend bool LoadOldVehicle(LoadgameState *ls, int num);       
00079 
00080   char *name;              
00081 
00082   TileIndex tile;          
00083 
00089   TileIndex dest_tile;
00090 
00091   Money profit_this_year;        
00092   Money profit_last_year;        
00093   Money value;                   
00094 
00095   CargoPayment *cargo_payment;   
00096 
00097   /* Used for timetabling. */
00098   uint32 current_order_time;     
00099   int32 lateness_counter;        
00100   Date timetable_start;          
00101 
00102   /* Boundaries for the current position in the world and a next hash link.
00103    * NOSAVE: All of those can be updated with VehiclePositionChanged() */
00104   Rect coord;
00105   Vehicle *next_hash, **prev_hash;
00106   Vehicle *next_new_hash, **prev_new_hash;
00107   Vehicle **old_new_hash;
00108 
00109   SpriteID colourmap; // NOSAVE: cached colour mapping
00110 
00111   /* Related to age and service time */
00112   Year build_year;
00113   Date age;     // Age in days
00114   Date max_age; // Maximum age
00115   Date date_of_last_service;
00116   Date service_interval;
00117   uint16 reliability;
00118   uint16 reliability_spd_dec;
00119   byte breakdown_ctr;
00120   byte breakdown_delay;
00121   byte breakdowns_since_last_service;
00122   byte breakdown_chance;
00123 
00124   int32 x_pos;             // coordinates
00125   int32 y_pos;
00126   byte z_pos;
00127   DirectionByte direction; // facing
00128 
00129   OwnerByte owner;         // which company owns the vehicle?
00130   byte spritenum;          // currently displayed sprite index
00131                            // 0xfd == custom sprite, 0xfe == custom second head sprite
00132                            // 0xff == reserved for another custom sprite
00133   uint16 cur_image;        // sprite number for this vehicle
00134   byte x_extent;           // x-extent of vehicle bounding box
00135   byte y_extent;           // y-extent of vehicle bounding box
00136   byte z_extent;           // z-extent of vehicle bounding box
00137   int8 x_offs;             // x offset for vehicle sprite
00138   int8 y_offs;             // y offset for vehicle sprite
00139   EngineID engine_type;
00140 
00141   TextEffectID fill_percent_te_id; // a text-effect id to a loading indicator object
00142   UnitID unitnumber;       // unit number, for display purposes only
00143 
00144   uint16 max_speed;        
00145   uint16 cur_speed;        
00146   byte subspeed;           
00147   byte acceleration;       
00148   uint32 motion_counter;
00149   byte progress;
00150 
00151   /* for randomized variational spritegroups
00152    * bitmask used to resolve them; parts of it get reseeded when triggers
00153    * of corresponding spritegroups get matched */
00154   byte random_bits;
00155   byte waiting_triggers;   
00156 
00157   StationID last_station_visited;
00158 
00159   CargoID cargo_type;      
00160   byte cargo_subtype;      
00161   uint16 cargo_cap;        
00162   VehicleCargoList cargo;  
00163 
00164   byte day_counter;        
00165   byte tick_counter;       
00166   byte running_ticks;      
00167 
00168   byte vehstatus;                 
00169   Order current_order;            
00170   VehicleOrderID cur_order_index; 
00171 
00172   union {
00173     OrderList *list;              
00174     Order     *old;               
00175   } orders;
00176 
00177   byte vehicle_flags;             
00178 
00180   uint16 load_unload_ticks;
00181 
00182   GroupID group_id;               
00183 
00184   byte subtype;                   
00185 
00186   VehicleCache vcache;            
00187 
00189   Vehicle(VehicleType type = VEH_INVALID);
00190 
00192   void PreDestructor();
00194   virtual ~Vehicle();
00195 
00196   void BeginLoading();
00197   void LeaveStation();
00198 
00204   void HandleLoading(bool mode = false);
00205 
00210   virtual const char *GetTypeString() const { return "base vehicle"; }
00211 
00220   virtual void MarkDirty() {}
00221 
00227   virtual void UpdateDeltaXY(Direction direction) {}
00228 
00233   virtual ExpensesType GetExpenseType(bool income) const { return EXPENSES_OTHER; }
00234 
00238   virtual void PlayLeaveStationSound() const {}
00239 
00243   virtual bool IsPrimaryVehicle() const { return false; }
00244 
00250   virtual SpriteID GetImage(Direction direction) const { return 0; }
00251 
00256   FORCEINLINE void InvalidateNewGRFCache()
00257   {
00258     this->vcache.cache_valid = 0;
00259   }
00260 
00265   FORCEINLINE void InvalidateNewGRFCacheOfChain()
00266   {
00267     for (Vehicle *u = this; u != NULL; u = u->Next()) {
00268       u->InvalidateNewGRFCache();
00269     }
00270   }
00271 
00276   virtual int GetDisplaySpeed() const { return 0; }
00277 
00282   virtual int GetDisplayMaxSpeed() const { return 0; }
00283 
00288   virtual Money GetRunningCost() const { return 0; }
00289 
00294   virtual bool IsInDepot() const { return false; }
00295 
00300   virtual bool IsStoppedInDepot() const { return this->IsInDepot() && (this->vehstatus & VS_STOPPED) != 0; }
00301 
00306   virtual bool Tick() { return true; };
00307 
00311   virtual void OnNewDay() {};
00312 
00318   virtual uint Crash(bool flooded = false);
00319 
00325   inline void UpdateViewport(bool moved, bool turned)
00326   {
00327     extern void VehicleMove(Vehicle *v, bool update_viewport);
00328 
00329     if (turned) this->UpdateDeltaXY(this->direction);
00330     SpriteID old_image = this->cur_image;
00331     this->cur_image = this->GetImage(this->direction);
00332     if (moved || this->cur_image != old_image) VehicleMove(this, true);
00333   }
00334 
00347   virtual Trackdir GetVehicleTrackdir() const { return INVALID_TRACKDIR; }
00348 
00353   Money GetDisplayRunningCost() const { return (this->GetRunningCost() >> 8); }
00354 
00359   Money GetDisplayProfitThisYear() const { return (this->profit_this_year >> 8); }
00360 
00365   Money GetDisplayProfitLastYear() const { return (this->profit_last_year >> 8); }
00366 
00371   void SetNext(Vehicle *next);
00372 
00378   inline Vehicle *Next() const { return this->next; }
00379 
00385   inline Vehicle *Previous() const { return this->previous; }
00386 
00391   inline Vehicle *First() const { return this->first; }
00392 
00397   inline Vehicle *Last()
00398   {
00399     Vehicle *v = this;
00400     while (v->Next() != NULL) v = v->Next();
00401     return v;
00402   }
00403 
00408   inline const Vehicle *Last() const
00409   {
00410     const Vehicle *v = this;
00411     while (v->Next() != NULL) v = v->Next();
00412     return v;
00413   }
00414 
00419   inline Order *GetFirstOrder() const { return (this->orders.list == NULL) ? NULL : this->orders.list->GetFirstOrder(); }
00420 
00426   void AddToShared(Vehicle *shared_chain);
00427 
00431   void RemoveFromShared();
00432 
00437   inline Vehicle *NextShared() const { return this->next_shared; }
00438 
00443   inline Vehicle *PreviousShared() const { return this->previous_shared; }
00444 
00449   inline Vehicle *FirstShared() const { return (this->orders.list == NULL) ? this->First() : this->orders.list->GetFirstSharedVehicle(); }
00450 
00455   inline bool IsOrderListShared() const { return this->orders.list != NULL && this->orders.list->IsShared(); }
00456 
00461   inline VehicleOrderID GetNumOrders() const { return (this->orders.list == NULL) ? 0 : this->orders.list->GetNumOrders(); }
00462 
00469   inline void CopyVehicleConfigAndStatistics(const Vehicle *src)
00470   {
00471     this->unitnumber = src->unitnumber;
00472 
00473     this->cur_order_index = src->cur_order_index;
00474     this->current_order = src->current_order;
00475     this->dest_tile  = src->dest_tile;
00476 
00477     this->profit_this_year = src->profit_this_year;
00478     this->profit_last_year = src->profit_last_year;
00479 
00480     this->current_order_time = src->current_order_time;
00481     this->lateness_counter = src->lateness_counter;
00482     this->timetable_start = src->timetable_start;
00483 
00484     if (HasBit(src->vehicle_flags, VF_TIMETABLE_STARTED)) SetBit(this->vehicle_flags, VF_TIMETABLE_STARTED);
00485     if (HasBit(src->vehicle_flags, VF_AUTOFILL_TIMETABLE)) SetBit(this->vehicle_flags, VF_AUTOFILL_TIMETABLE);
00486     if (HasBit(src->vehicle_flags, VF_AUTOFILL_PRES_WAIT_TIME)) SetBit(this->vehicle_flags, VF_AUTOFILL_PRES_WAIT_TIME);
00487 
00488     this->service_interval = src->service_interval;
00489   }
00490 
00491   bool NeedsAutorenewing(const Company *c) const;
00492 
00499   bool NeedsServicing() const;
00500 
00506   bool NeedsAutomaticServicing() const;
00507 
00515   virtual TileIndex GetOrderStationLocation(StationID station) { return INVALID_TILE; }
00516 
00525   virtual bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) { return false; }
00526 
00533   CommandCost SendToDepot(DoCommandFlag flags, DepotCommand command);
00534 
00539   void IncrementOrderIndex()
00540   {
00541     this->cur_order_index++;
00542     if (this->cur_order_index >= this->GetNumOrders()) this->cur_order_index = 0;
00543     InvalidateVehicleOrder(this, 0);
00544   }
00545 
00551   inline Order *GetOrder(int index) const
00552   {
00553     return (this->orders.list == NULL) ? NULL : this->orders.list->GetOrderAt(index);
00554   }
00555 
00560   inline Order *GetLastOrder() const
00561   {
00562     return (this->orders.list == NULL) ? NULL : this->orders.list->GetLastOrder();
00563   }
00564 
00565   bool IsEngineCountable() const;
00566 };
00567 
00568 #define FOR_ALL_VEHICLES_FROM(var, start) FOR_ALL_ITEMS_FROM(Vehicle, vehicle_index, var, start)
00569 #define FOR_ALL_VEHICLES(var) FOR_ALL_VEHICLES_FROM(var, 0)
00570 
00575 template <class T, VehicleType Type>
00576 struct SpecializedVehicle : public Vehicle {
00577   static const VehicleType EXPECTED_TYPE = Type; 
00578 
00582   FORCEINLINE SpecializedVehicle<T, Type>() : Vehicle(Type) { }
00583 
00588   FORCEINLINE T *First() const { return (T *)this->Vehicle::First(); }
00589 
00594   FORCEINLINE T *Last() { return (T *)this->Vehicle::Last(); }
00595 
00600   FORCEINLINE const T *Last() const { return (const T *)this->Vehicle::Last(); }
00601 
00606   FORCEINLINE T *Next() const { return (T *)this->Vehicle::Next(); }
00607 
00612   FORCEINLINE T *Previous() const { return (T *)this->Vehicle::Previous(); }
00613 
00614 
00620   static FORCEINLINE bool IsValidID(size_t index)
00621   {
00622     return Vehicle::IsValidID(index) && Vehicle::Get(index)->type == Type;
00623   }
00624 
00629   static FORCEINLINE T *Get(size_t index)
00630   {
00631     return (T *)Vehicle::Get(index);
00632   }
00633 
00638   static FORCEINLINE T *GetIfValid(size_t index)
00639   {
00640     return IsValidID(index) ? Get(index) : NULL;
00641   }
00642 
00648   static FORCEINLINE T *From(Vehicle *v)
00649   {
00650     assert(v->type == Type);
00651     return (T *)v;
00652   }
00653 
00659   static FORCEINLINE const T *From(const Vehicle *v)
00660   {
00661     assert(v->type == Type);
00662     return (const T *)v;
00663   }
00664 };
00665 
00666 #define FOR_ALL_VEHICLES_OF_TYPE(name, var) FOR_ALL_ITEMS_FROM(name, vehicle_index, var, 0) if (var->type == name::EXPECTED_TYPE)
00667 
00671 struct DisasterVehicle : public SpecializedVehicle<DisasterVehicle, VEH_DISASTER> {
00672   uint16 image_override;
00673   VehicleID big_ufo_destroyer_target;
00674 
00676   DisasterVehicle() : SpecializedVehicle<DisasterVehicle, VEH_DISASTER>() {}
00678   virtual ~DisasterVehicle() {}
00679 
00680   const char *GetTypeString() const { return "disaster vehicle"; }
00681   void UpdateDeltaXY(Direction direction);
00682   bool Tick();
00683 };
00684 
00685 #define FOR_ALL_DISASTERVEHICLES(var) FOR_ALL_VEHICLES_OF_TYPE(DisasterVehicle, var)
00686 
00688 struct FreeUnitIDGenerator {
00689   bool *cache;  
00690   UnitID maxid; 
00691   UnitID curid; 
00692 
00699   FreeUnitIDGenerator(VehicleType type, CompanyID owner);
00700 
00702   UnitID NextID();
00703 
00705   ~FreeUnitIDGenerator() { free(this->cache); }
00706 };
00707 
00708 static const int32 INVALID_COORD = 0x7fffffff;
00709 
00710 #endif /* VEHICLE_BASE_H */

Generated on Thu Feb 4 17:20:30 2010 for OpenTTD by  doxygen 1.5.6