train.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 TRAIN_H
00013 #define TRAIN_H
00014 
00015 #include "stdafx.h"
00016 #include "core/bitmath_func.hpp"
00017 #include "vehicle_base.h"
00018 
00019 struct Train;
00020 
00021 enum VehicleRailFlags {
00022   VRF_REVERSING         = 0,
00023 
00024   /* used to calculate if train is going up or down */
00025   VRF_GOINGUP           = 1,
00026   VRF_GOINGDOWN         = 2,
00027 
00028   /* used to store if a wagon is powered or not */
00029   VRF_POWEREDWAGON      = 3,
00030 
00031   /* used to reverse the visible direction of the vehicle */
00032   VRF_REVERSE_DIRECTION = 4,
00033 
00034   /* used to mark train as lost because PF can't find the route */
00035   VRF_NO_PATH_TO_DESTINATION = 5,
00036 
00037   /* used to mark that electric train engine is allowed to run on normal rail */
00038   VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL = 6,
00039 
00040   /* used for vehicle var 0xFE bit 8 (toggled each time the train is reversed, accurate for first vehicle only) */
00041   VRF_TOGGLE_REVERSE = 7,
00042 
00043   /* used to mark a train that can't get a path reservation */
00044   VRF_TRAIN_STUCK    = 8,
00045 };
00046 
00047 void CcBuildLoco(bool success, TileIndex tile, uint32 p1, uint32 p2);
00048 void CcBuildWagon(bool success, TileIndex tile, uint32 p1, uint32 p2);
00049 
00050 byte FreightWagonMult(CargoID cargo);
00051 
00052 void UpdateTrainAcceleration(Train *v);
00053 void CheckTrainsLengths();
00054 
00055 void FreeTrainTrackReservation(const Train *v, TileIndex origin = INVALID_TILE, Trackdir orig_td = INVALID_TRACKDIR);
00056 bool TryPathReserve(Train *v, bool mark_as_stuck = false, bool first_tile_okay = false);
00057 
00058 void DeleteVisibleTrain(Train *v);
00059 
00060 int GetTrainStopLocation(StationID station_id, TileIndex tile, const Train *v, int *station_ahead, int *station_length);
00061 
00062 void TrainConsistChanged(Train *v, bool same_length);
00063 void TrainPowerChanged(Train *v);
00064 int GetTrainCurveSpeedLimit(Train *v);
00065 Money GetTrainRunningCost(const Train *v);
00066 
00068 struct TrainCache {
00069   /* Cached wagon override spritegroup */
00070   const struct SpriteGroup *cached_override;
00071 
00072   uint16 last_speed; // NOSAVE: only used in UI
00073 
00074   /* cached values, recalculated on load and each time a vehicle is added to/removed from the consist. */
00075   uint32 cached_power;        
00076   uint16 cached_total_length; 
00077   uint8 cached_veh_length;    
00078   bool cached_tilt;           
00079 
00080   /* cached values, recalculated when the cargo on a train changes (in addition to the conditions above) */
00081   uint32 cached_weight;     
00082   uint32 cached_veh_weight; 
00083   uint32 cached_max_te;     
00084 
00085   /* cached max. speed / acceleration data */
00086   uint16 cached_max_speed;    
00087   int cached_max_curve_speed; 
00088 
00096   byte cached_vis_effect;
00097   byte user_def_data;
00098 
00099   EngineID first_engine;  
00100 };
00101 
00105 struct Train : public SpecializedVehicle<Train, VEH_TRAIN> {
00106   TrainCache tcache;
00107 
00108   /* Link between the two ends of a multiheaded engine */
00109   Train *other_multiheaded_part;
00110 
00111   uint16 crash_anim_pos;
00112 
00113   uint16 flags;
00114   TrackBitsByte track;
00115   byte force_proceed;
00116   RailTypeByte railtype;
00117   RailTypes compatible_railtypes;
00118 
00120   Train() : SpecializedVehicle<Train, VEH_TRAIN>() {}
00122   virtual ~Train() { this->PreDestructor(); }
00123 
00124   const char *GetTypeString() const { return "train"; }
00125   void MarkDirty();
00126   void UpdateDeltaXY(Direction direction);
00127   ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_TRAIN_INC : EXPENSES_TRAIN_RUN; }
00128   void PlayLeaveStationSound() const;
00129   bool IsPrimaryVehicle() const { return this->IsFrontEngine(); }
00130   SpriteID GetImage(Direction direction) const;
00131   int GetDisplaySpeed() const { return this->tcache.last_speed; }
00132   int GetDisplayMaxSpeed() const { return this->tcache.cached_max_speed; }
00133   Money GetRunningCost() const;
00134   int GetDisplayImageWidth(Point *offset = NULL) const;
00135   bool IsInDepot() const;
00136   bool IsStoppedInDepot() const;
00137   bool Tick();
00138   void OnNewDay();
00139   uint Crash(bool flooded = false);
00140   Trackdir GetVehicleTrackdir() const;
00141   TileIndex GetOrderStationLocation(StationID station);
00142   bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse);
00143 
00144   void ReserveTrackUnderConsist() const;
00145 
00151   enum TrainSubtype {
00152     TS_FRONT             = 0, 
00153     TS_ARTICULATED_PART  = 1, 
00154     TS_WAGON             = 2, 
00155     TS_ENGINE            = 3, 
00156     TS_FREE_WAGON        = 4, 
00157     TS_MULTIHEADED       = 5, 
00158   };
00159 
00163   FORCEINLINE void SetFrontEngine() { SetBit(this->subtype, TS_FRONT); }
00164 
00168   FORCEINLINE void ClearFrontEngine() { ClrBit(this->subtype, TS_FRONT); }
00169 
00173   FORCEINLINE void SetArticulatedPart() { SetBit(this->subtype, TS_ARTICULATED_PART); }
00174 
00178   FORCEINLINE void ClearArticulatedPart() { ClrBit(this->subtype, TS_ARTICULATED_PART); }
00179 
00183   FORCEINLINE void SetWagon() { SetBit(this->subtype, TS_WAGON); }
00184 
00188   FORCEINLINE void ClearWagon() { ClrBit(this->subtype, TS_WAGON); }
00189 
00193   FORCEINLINE void SetEngine() { SetBit(this->subtype, TS_ENGINE); }
00194 
00198   FORCEINLINE void ClearEngine() { ClrBit(this->subtype, TS_ENGINE); }
00199 
00203   FORCEINLINE void SetFreeWagon() { SetBit(this->subtype, TS_FREE_WAGON); }
00204 
00208   FORCEINLINE void ClearFreeWagon() { ClrBit(this->subtype, TS_FREE_WAGON); }
00209 
00213   FORCEINLINE void SetMultiheaded() { SetBit(this->subtype, TS_MULTIHEADED); }
00214 
00218   FORCEINLINE void ClearMultiheaded() { ClrBit(this->subtype, TS_MULTIHEADED); }
00219 
00220 
00225   FORCEINLINE bool IsFrontEngine() const { return HasBit(this->subtype, TS_FRONT); }
00226 
00231   FORCEINLINE bool IsFreeWagon() const { return HasBit(this->subtype, TS_FREE_WAGON); }
00232 
00237   FORCEINLINE bool IsEngine() const { return HasBit(this->subtype, TS_ENGINE); }
00238 
00243   FORCEINLINE bool IsWagon() const { return HasBit(this->subtype, TS_WAGON); }
00244 
00249   FORCEINLINE bool IsMultiheaded() const { return HasBit(this->subtype, TS_MULTIHEADED); }
00250 
00255   FORCEINLINE bool IsRearDualheaded() const { return this->IsMultiheaded() && !this->IsEngine(); }
00256 
00261   FORCEINLINE bool IsArticulatedPart() const { return HasBit(this->subtype, TS_ARTICULATED_PART); }
00262 
00267   FORCEINLINE bool HasArticulatedPart() const { return this->Next() != NULL && this->Next()->IsArticulatedPart(); }
00268 
00269 
00276   FORCEINLINE Train *GetNextArticPart() const
00277   {
00278     assert(this->HasArticulatedPart());
00279     return this->Next();
00280   }
00281 
00286   FORCEINLINE Train *GetFirstEnginePart()
00287   {
00288     Train *v = this;
00289     while (v->IsArticulatedPart()) v = v->Previous();
00290     return v;
00291   }
00292 
00297   FORCEINLINE const Train *GetFirstEnginePart() const
00298   {
00299     const Train *v = this;
00300     while (v->IsArticulatedPart()) v = v->Previous();
00301     return v;
00302   }
00303 
00308   FORCEINLINE Train *GetLastEnginePart()
00309   {
00310     Train *v = this;
00311     while (v->HasArticulatedPart()) v = v->GetNextArticPart();
00312     return v;
00313   }
00314 
00319   FORCEINLINE Train *GetNextVehicle() const
00320   {
00321     const Train *v = this;
00322     while (v->HasArticulatedPart()) v = v->GetNextArticPart();
00323 
00324     /* v now contains the last artic part in the engine */
00325     return v->Next();
00326   }
00327 
00332   FORCEINLINE Train *GetPrevVehicle() const
00333   {
00334     Train *v = this->Previous();
00335     while (v != NULL && v->IsArticulatedPart()) v = v->Previous();
00336 
00337     return v;
00338   }
00339 
00344   FORCEINLINE Train *GetNextUnit() const
00345   {
00346     Train *v = this->GetNextVehicle();
00347     if (v != NULL && v->IsRearDualheaded()) v = v->GetNextVehicle();
00348 
00349     return v;
00350   }
00351 
00356   FORCEINLINE Train *GetPrevUnit()
00357   {
00358     Train *v = this->GetPrevVehicle();
00359     if (v != NULL && v->IsRearDualheaded()) v = v->GetPrevVehicle();
00360 
00361     return v;
00362   }
00363 };
00364 
00365 #define FOR_ALL_TRAINS(var) FOR_ALL_VEHICLES_OF_TYPE(Train, var)
00366 
00367 #endif /* TRAIN_H */

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