vehicle_base.h

Go to the documentation of this file.
00001 /* $Id$ */
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 "vehicle_type.h"
00016 #include "track_type.h"
00017 #include "cargo_type.h"
00018 #include "direction_type.h"
00019 #include "gfx_type.h"
00020 #include "command_type.h"
00021 #include "date_type.h"
00022 #include "company_base.h"
00023 #include "company_type.h"
00024 #include "core/pool_type.hpp"
00025 #include "order_base.h"
00026 #include "cargopacket.h"
00027 #include "texteff.hpp"
00028 #include "group_type.h"
00029 #include "engine_type.h"
00030 #include "order_func.h"
00031 #include "transport_type.h"
00032 
00033 enum VehStatus {
00034   VS_HIDDEN          = 0x01,
00035   VS_STOPPED         = 0x02,
00036   VS_UNCLICKABLE     = 0x04,
00037   VS_DEFPAL          = 0x08,
00038   VS_TRAIN_SLOWING   = 0x10,
00039   VS_SHADOW          = 0x20,
00040   VS_AIRCRAFT_BROKEN = 0x40,
00041   VS_CRASHED         = 0x80,
00042 };
00043 
00044 enum VehicleFlags {
00045   VF_LOADING_FINISHED,
00046   VF_CARGO_UNLOADING,
00047   VF_BUILT_AS_PROTOTYPE,
00048   VF_TIMETABLE_STARTED,       
00049   VF_AUTOFILL_TIMETABLE,      
00050   VF_AUTOFILL_PRES_WAIT_TIME, 
00051 };
00052 
00054 struct VehicleCache {
00055   uint8 cache_valid;   
00056   uint32 cached_var40; 
00057   uint32 cached_var41; 
00058   uint32 cached_var42; 
00059   uint32 cached_var43; 
00060 };
00061 
00062 typedef Pool<Vehicle, VehicleID, 512, 64000> VehiclePool;
00063 extern VehiclePool _vehicle_pool;
00064 
00065 /* Some declarations of functions, so we can make them friendly */
00066 struct SaveLoad;
00067 extern const SaveLoad *GetVehicleDescription(VehicleType vt);
00068 struct LoadgameState;
00069 extern bool LoadOldVehicle(LoadgameState *ls, int num);
00070 extern bool AfterLoadGame();
00071 extern void FixOldVehicles();
00072 
00073 struct Vehicle : VehiclePool::PoolItem<&_vehicle_pool>, BaseVehicle {
00074 private:
00075   Vehicle *next;           
00076   Vehicle *previous;       
00077   Vehicle *first;          
00078 
00079   Vehicle *next_shared;     
00080   Vehicle *previous_shared; 
00081 public:
00082   friend const SaveLoad *GetVehicleDescription(VehicleType vt); 
00083   friend bool AfterLoadGame();
00084   friend void FixOldVehicles();
00085   friend void AfterLoadVehicles(bool part_of_load);             
00086   friend bool LoadOldVehicle(LoadgameState *ls, int num);       
00087 
00088   char *name;              
00089 
00090   TileIndex tile;          
00091 
00097   TileIndex dest_tile;
00098 
00099   Money profit_this_year;        
00100   Money profit_last_year;        
00101   Money value;                   
00102 
00103   CargoPayment *cargo_payment;   
00104 
00105   /* Used for timetabling. */
00106   uint32 current_order_time;     
00107   int32 lateness_counter;        
00108   Date timetable_start;          
00109 
00110   /* Boundaries for the current position in the world and a next hash link.
00111    * NOSAVE: All of those can be updated with VehiclePositionChanged() */
00112   Rect coord;
00113   Vehicle *next_hash, **prev_hash;
00114   Vehicle *next_new_hash, **prev_new_hash;
00115   Vehicle **old_new_hash;
00116 
00117   SpriteID colourmap; // NOSAVE: cached colour mapping
00118 
00119   /* Related to age and service time */
00120   Year build_year;
00121   Date age;     // Age in days
00122   Date max_age; // Maximum age
00123   Date date_of_last_service;
00124   Date service_interval;
00125   uint16 reliability;
00126   uint16 reliability_spd_dec;
00127   byte breakdown_ctr;
00128   byte breakdown_delay;
00129   byte breakdowns_since_last_service;
00130   byte breakdown_chance;
00131 
00132   int32 x_pos;             // coordinates
00133   int32 y_pos;
00134   byte z_pos;
00135   DirectionByte direction; // facing
00136 
00137   OwnerByte owner;         // which company owns the vehicle?
00138   byte spritenum;          // currently displayed sprite index
00139                            // 0xfd == custom sprite, 0xfe == custom second head sprite
00140                            // 0xff == reserved for another custom sprite
00141   uint16 cur_image;        // sprite number for this vehicle
00142   byte x_extent;           // x-extent of vehicle bounding box
00143   byte y_extent;           // y-extent of vehicle bounding box
00144   byte z_extent;           // z-extent of vehicle bounding box
00145   int8 x_offs;             // x offset for vehicle sprite
00146   int8 y_offs;             // y offset for vehicle sprite
00147   EngineID engine_type;
00148 
00149   TextEffectID fill_percent_te_id; // a text-effect id to a loading indicator object
00150   UnitID unitnumber;       // unit number, for display purposes only
00151 
00152   uint16 max_speed;        
00153   uint16 cur_speed;        
00154   byte subspeed;           
00155   byte acceleration;       
00156   uint32 motion_counter;
00157   byte progress;
00158 
00159   /* for randomized variational spritegroups
00160    * bitmask used to resolve them; parts of it get reseeded when triggers
00161    * of corresponding spritegroups get matched */
00162   byte random_bits;
00163   byte waiting_triggers;   
00164 
00165   StationID last_station_visited;
00166 
00167   CargoID cargo_type;      
00168   byte cargo_subtype;      
00169   uint16 cargo_cap;        
00170   VehicleCargoList cargo;  
00171 
00172   byte day_counter;        
00173   byte tick_counter;       
00174   byte running_ticks;      
00175 
00176   byte vehstatus;                 
00177   Order current_order;            
00178   VehicleOrderID cur_order_index; 
00179 
00180   union {
00181     OrderList *list;              
00182     Order     *old;               
00183   } orders;
00184 
00185   byte vehicle_flags;             
00186 
00193   uint16 time_counter;
00194 
00195   GroupID group_id;               
00196 
00197   byte subtype;                   
00198 
00199   VehicleCache vcache;            
00200 
00202   Vehicle(VehicleType type = VEH_INVALID);
00203 
00205   void PreDestructor();
00207   virtual ~Vehicle();
00208 
00209   void BeginLoading();
00210   void LeaveStation();
00211 
00217   void HandleLoading(bool mode = false);
00218 
00223   virtual const char *GetTypeString() const { return "base vehicle"; }
00224 
00233   virtual void MarkDirty() {}
00234 
00240   virtual void UpdateDeltaXY(Direction direction) {}
00241 
00246   virtual ExpensesType GetExpenseType(bool income) const { return EXPENSES_OTHER; }
00247 
00251   virtual void PlayLeaveStationSound() const {}
00252 
00256   virtual bool IsPrimaryVehicle() const { return false; }
00257 
00263   virtual SpriteID GetImage(Direction direction) const { return 0; }
00264 
00269   FORCEINLINE void InvalidateNewGRFCache()
00270   {
00271     this->vcache.cache_valid = 0;
00272   }
00273 
00278   FORCEINLINE void InvalidateNewGRFCacheOfChain()
00279   {
00280     for (Vehicle *u = this; u != NULL; u = u->Next()) {
00281       u->InvalidateNewGRFCache();
00282     }
00283   }
00284 
00289   virtual int GetDisplaySpeed() const { return 0; }
00290 
00295   virtual int GetDisplayMaxSpeed() const { return 0; }
00296 
00301   virtual Money GetRunningCost() const { return 0; }
00302 
00307   virtual bool IsInDepot() const { return false; }
00308 
00313   virtual bool IsStoppedInDepot() const { return this->IsInDepot() && (this->vehstatus & VS_STOPPED) != 0; }
00314 
00319   virtual bool Tick() { return true; };
00320 
00324   virtual void OnNewDay() {};
00325 
00331   virtual uint Crash(bool flooded = false);
00332 
00338   inline void UpdateViewport(bool moved, bool turned)
00339   {
00340     extern void VehicleMove(Vehicle *v, bool update_viewport);
00341 
00342     if (turned) this->UpdateDeltaXY(this->direction);
00343     SpriteID old_image = this->cur_image;
00344     this->cur_image = this->GetImage(this->direction);
00345     if (moved || this->cur_image != old_image) VehicleMove(this, true);
00346   }
00347 
00360   virtual Trackdir GetVehicleTrackdir() const { return INVALID_TRACKDIR; }
00361 
00366   Money GetDisplayRunningCost() const { return (this->GetRunningCost() >> 8); }
00367 
00372   Money GetDisplayProfitThisYear() const { return (this->profit_this_year >> 8); }
00373 
00378   Money GetDisplayProfitLastYear() const { return (this->profit_last_year >> 8); }
00379 
00384   void SetNext(Vehicle *next);
00385 
00391   inline Vehicle *Next() const { return this->next; }
00392 
00398   inline Vehicle *Previous() const { return this->previous; }
00399 
00404   inline Vehicle *First() const { return this->first; }
00405 
00410   inline Vehicle *Last()
00411   {
00412     Vehicle *v = this;
00413     while (v->Next() != NULL) v = v->Next();
00414     return v;
00415   }
00416 
00421   inline const Vehicle *Last() const
00422   {
00423     const Vehicle *v = this;
00424     while (v->Next() != NULL) v = v->Next();
00425     return v;
00426   }
00427 
00432   inline Order *GetFirstOrder() const { return (this->orders.list == NULL) ? NULL : this->orders.list->GetFirstOrder(); }
00433 
00439   void AddToShared(Vehicle *shared_chain);
00440 
00444   void RemoveFromShared();
00445 
00450   inline Vehicle *NextShared() const { return this->next_shared; }
00451 
00456   inline Vehicle *PreviousShared() const { return this->previous_shared; }
00457 
00462   inline Vehicle *FirstShared() const { return (this->orders.list == NULL) ? this->First() : this->orders.list->GetFirstSharedVehicle(); }
00463 
00468   inline bool IsOrderListShared() const { return this->orders.list != NULL && this->orders.list->IsShared(); }
00469 
00474   inline VehicleOrderID GetNumOrders() const { return (this->orders.list == NULL) ? 0 : this->orders.list->GetNumOrders(); }
00475 
00482   inline void CopyVehicleConfigAndStatistics(const Vehicle *src)
00483   {
00484     this->unitnumber = src->unitnumber;
00485 
00486     this->cur_order_index = src->cur_order_index;
00487     this->current_order = src->current_order;
00488     this->dest_tile  = src->dest_tile;
00489 
00490     this->profit_this_year = src->profit_this_year;
00491     this->profit_last_year = src->profit_last_year;
00492 
00493     this->current_order_time = src->current_order_time;
00494     this->lateness_counter = src->lateness_counter;
00495     this->timetable_start = src->timetable_start;
00496 
00497     this->service_interval = src->service_interval;
00498   }
00499 
00500   bool NeedsAutorenewing(const Company *c) const;
00501 
00508   bool NeedsServicing() const;
00509 
00515   bool NeedsAutomaticServicing() const;
00516 
00524   virtual TileIndex GetOrderStationLocation(StationID station) { return INVALID_TILE; }
00525 
00534   virtual bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) { return false; }
00535 
00542   CommandCost SendToDepot(DoCommandFlag flags, DepotCommand command);
00543 
00548   void IncrementOrderIndex()
00549   {
00550     this->cur_order_index++;
00551     if (this->cur_order_index >= this->GetNumOrders()) this->cur_order_index = 0;
00552     InvalidateVehicleOrder(this, 0);
00553   }
00554 
00560   inline Order *GetOrder(int index) const
00561   {
00562     return (this->orders.list == NULL) ? NULL : this->orders.list->GetOrderAt(index);
00563   }
00564 
00569   inline Order *GetLastOrder() const
00570   {
00571     return (this->orders.list == NULL) ? NULL : this->orders.list->GetLastOrder();
00572   }
00573 
00574   bool IsEngineCountable() const;
00575 };
00576 
00577 #define FOR_ALL_VEHICLES_FROM(var, start) FOR_ALL_ITEMS_FROM(Vehicle, vehicle_index, var, start)
00578 #define FOR_ALL_VEHICLES(var) FOR_ALL_VEHICLES_FROM(var, 0)
00579 
00584 template <class T, VehicleType Type>
00585 struct SpecializedVehicle : public Vehicle {
00586   static const VehicleType EXPECTED_TYPE = Type; 
00587 
00591   FORCEINLINE SpecializedVehicle<T, Type>() : Vehicle(Type) { }
00592 
00597   FORCEINLINE T *First() const { return (T *)this->Vehicle::First(); }
00598 
00603   FORCEINLINE T *Last() { return (T *)this->Vehicle::Last(); }
00604 
00609   FORCEINLINE const T *Last() const { return (const T *)this->Vehicle::Last(); }
00610 
00615   FORCEINLINE T *Next() const { return (T *)this->Vehicle::Next(); }
00616 
00621   FORCEINLINE T *Previous() const { return (T *)this->Vehicle::Previous(); }
00622 
00623 
00629   static FORCEINLINE bool IsValidID(size_t index)
00630   {
00631     return Vehicle::IsValidID(index) && Vehicle::Get(index)->type == Type;
00632   }
00633 
00638   static FORCEINLINE T *Get(size_t index)
00639   {
00640     return (T *)Vehicle::Get(index);
00641   }
00642 
00647   static FORCEINLINE T *GetIfValid(size_t index)
00648   {
00649     return IsValidID(index) ? Get(index) : NULL;
00650   }
00651 
00657   static FORCEINLINE T *From(Vehicle *v)
00658   {
00659     assert(v->type == Type);
00660     return (T *)v;
00661   }
00662 
00668   static FORCEINLINE const T *From(const Vehicle *v)
00669   {
00670     assert(v->type == Type);
00671     return (const T *)v;
00672   }
00673 };
00674 
00675 #define FOR_ALL_VEHICLES_OF_TYPE(name, var) FOR_ALL_ITEMS_FROM(name, vehicle_index, var, 0) if (var->type == name::EXPECTED_TYPE)
00676 
00680 struct DisasterVehicle : public SpecializedVehicle<DisasterVehicle, VEH_DISASTER> {
00681   uint16 image_override;
00682   VehicleID big_ufo_destroyer_target;
00683 
00685   DisasterVehicle() : SpecializedVehicle<DisasterVehicle, VEH_DISASTER>() {}
00687   virtual ~DisasterVehicle() {}
00688 
00689   const char *GetTypeString() const { return "disaster vehicle"; }
00690   void UpdateDeltaXY(Direction direction);
00691   bool Tick();
00692 };
00693 
00694 #define FOR_ALL_DISASTERVEHICLES(var) FOR_ALL_VEHICLES_OF_TYPE(DisasterVehicle, var)
00695 
00697 struct FreeUnitIDGenerator {
00698   bool *cache;  
00699   UnitID maxid; 
00700   UnitID curid; 
00701 
00708   FreeUnitIDGenerator(VehicleType type, CompanyID owner);
00709 
00711   UnitID NextID();
00712 
00714   ~FreeUnitIDGenerator() { free(this->cache); }
00715 };
00716 
00717 static const int32 INVALID_COORD = 0x7fffffff;
00718 
00719 #endif /* VEHICLE_BASE_H */

Generated on Wed Dec 30 20:40:08 2009 for OpenTTD by  doxygen 1.5.6