train.h

Go to the documentation of this file.
00001 /* $Id: train.h 18484 2009-12-13 17:13:20Z rubidium $ */
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 int GetTrainStopLocation(StationID station_id, TileIndex tile, const Train *v, int *station_ahead, int *station_length);
00059 
00060 void TrainConsistChanged(Train *v, bool same_length);
00061 void TrainPowerChanged(Train *v);
00062 int GetTrainCurveSpeedLimit(Train *v);
00063 Money GetTrainRunningCost(const Train *v);
00064 
00066 struct TrainCache {
00067   /* Cached wagon override spritegroup */
00068   const struct SpriteGroup *cached_override;
00069 
00070   uint16 last_speed; // NOSAVE: only used in UI
00071 
00072   /* cached values, recalculated on load and each time a vehicle is added to/removed from the consist. */
00073   uint32 cached_power;        
00074   uint16 cached_total_length; 
00075   uint8 cached_veh_length;    
00076   bool cached_tilt;           
00077 
00078   /* cached values, recalculated when the cargo on a train changes (in addition to the conditions above) */
00079   uint32 cached_weight;     
00080   uint32 cached_veh_weight; 
00081   uint32 cached_max_te;     
00082 
00083   /* cached max. speed / acceleration data */
00084   uint16 cached_max_speed;    
00085   int cached_max_curve_speed; 
00086 
00094   byte cached_vis_effect;
00095   byte user_def_data;
00096 
00097   EngineID first_engine;  
00098 };
00099 
00103 struct Train : public SpecializedVehicle<Train, VEH_TRAIN> {
00104   TrainCache tcache;
00105 
00106   /* Link between the two ends of a multiheaded engine */
00107   Train *other_multiheaded_part;
00108 
00109   uint16 crash_anim_pos;
00110 
00111   uint16 flags;
00112   TrackBitsByte track;
00113   byte force_proceed;
00114   RailTypeByte railtype;
00115   RailTypes compatible_railtypes;
00116 
00118   Train() : SpecializedVehicle<Train, VEH_TRAIN>() {}
00120   virtual ~Train() { this->PreDestructor(); }
00121 
00122   const char *GetTypeString() const { return "train"; }
00123   void MarkDirty();
00124   void UpdateDeltaXY(Direction direction);
00125   ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_TRAIN_INC : EXPENSES_TRAIN_RUN; }
00126   void PlayLeaveStationSound() const;
00127   bool IsPrimaryVehicle() const { return this->IsFrontEngine(); }
00128   SpriteID GetImage(Direction direction) const;
00129   int GetDisplaySpeed() const { return this->tcache.last_speed; }
00130   int GetDisplayMaxSpeed() const { return this->tcache.cached_max_speed; }
00131   Money GetRunningCost() const;
00132   int GetDisplayImageWidth(Point *offset = NULL) const;
00133   bool IsInDepot() const;
00134   bool IsStoppedInDepot() const;
00135   bool Tick();
00136   void OnNewDay();
00137   uint Crash(bool flooded = false);
00138   Trackdir GetVehicleTrackdir() const;
00139   TileIndex GetOrderStationLocation(StationID station);
00140   bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse);
00141 
00142   void ReserveTrackUnderConsist() const;
00143 
00149   enum TrainSubtype {
00150     TS_FRONT             = 0, 
00151     TS_ARTICULATED_PART  = 1, 
00152     TS_WAGON             = 2, 
00153     TS_ENGINE            = 3, 
00154     TS_FREE_WAGON        = 4, 
00155     TS_MULTIHEADED       = 5, 
00156   };
00157 
00161   FORCEINLINE void SetFrontEngine() { SetBit(this->subtype, TS_FRONT); }
00162 
00166   FORCEINLINE void ClearFrontEngine() { ClrBit(this->subtype, TS_FRONT); }
00167 
00171   FORCEINLINE void SetArticulatedPart() { SetBit(this->subtype, TS_ARTICULATED_PART); }
00172 
00176   FORCEINLINE void ClearArticulatedPart() { ClrBit(this->subtype, TS_ARTICULATED_PART); }
00177 
00181   FORCEINLINE void SetWagon() { SetBit(this->subtype, TS_WAGON); }
00182 
00186   FORCEINLINE void ClearWagon() { ClrBit(this->subtype, TS_WAGON); }
00187 
00191   FORCEINLINE void SetEngine() { SetBit(this->subtype, TS_ENGINE); }
00192 
00196   FORCEINLINE void ClearEngine() { ClrBit(this->subtype, TS_ENGINE); }
00197 
00201   FORCEINLINE void SetFreeWagon() { SetBit(this->subtype, TS_FREE_WAGON); }
00202 
00206   FORCEINLINE void ClearFreeWagon() { ClrBit(this->subtype, TS_FREE_WAGON); }
00207 
00211   FORCEINLINE void SetMultiheaded() { SetBit(this->subtype, TS_MULTIHEADED); }
00212 
00216   FORCEINLINE void ClearMultiheaded() { ClrBit(this->subtype, TS_MULTIHEADED); }
00217 
00218 
00223   FORCEINLINE bool IsFrontEngine() const { return HasBit(this->subtype, TS_FRONT); }
00224 
00229   FORCEINLINE bool IsFreeWagon() const { return HasBit(this->subtype, TS_FREE_WAGON); }
00230 
00235   FORCEINLINE bool IsEngine() const { return HasBit(this->subtype, TS_ENGINE); }
00236 
00241   FORCEINLINE bool IsWagon() const { return HasBit(this->subtype, TS_WAGON); }
00242 
00247   FORCEINLINE bool IsMultiheaded() const { return HasBit(this->subtype, TS_MULTIHEADED); }
00248 
00253   FORCEINLINE bool IsRearDualheaded() const { return this->IsMultiheaded() && !this->IsEngine(); }
00254 
00259   FORCEINLINE bool IsArticulatedPart() const { return HasBit(this->subtype, TS_ARTICULATED_PART); }
00260 
00265   FORCEINLINE bool HasArticulatedPart() const { return this->Next() != NULL && this->Next()->IsArticulatedPart(); }
00266 
00267 
00274   FORCEINLINE Train *GetNextArticPart() const
00275   {
00276     assert(this->HasArticulatedPart());
00277     return this->Next();
00278   }
00279 
00284   FORCEINLINE Train *GetFirstEnginePart()
00285   {
00286     Train *v = this;
00287     while (v->IsArticulatedPart()) v = v->Previous();
00288     return v;
00289   }
00290 
00295   FORCEINLINE const Train *GetFirstEnginePart() const
00296   {
00297     const Train *v = this;
00298     while (v->IsArticulatedPart()) v = v->Previous();
00299     return v;
00300   }
00301 
00306   FORCEINLINE Train *GetLastEnginePart()
00307   {
00308     Train *v = this;
00309     while (v->HasArticulatedPart()) v = v->GetNextArticPart();
00310     return v;
00311   }
00312 
00317   FORCEINLINE Train *GetNextVehicle() const
00318   {
00319     const Train *v = this;
00320     while (v->HasArticulatedPart()) v = v->GetNextArticPart();
00321 
00322     /* v now contains the last artic part in the engine */
00323     return v->Next();
00324   }
00325 
00330   FORCEINLINE Train *GetPrevVehicle() const
00331   {
00332     Train *v = this->Previous();
00333     while (v != NULL && v->IsArticulatedPart()) v = v->Previous();
00334 
00335     return v;
00336   }
00337 
00342   FORCEINLINE Train *GetNextUnit() const
00343   {
00344     Train *v = this->GetNextVehicle();
00345     if (v != NULL && v->IsRearDualheaded()) v = v->GetNextVehicle();
00346 
00347     return v;
00348   }
00349 
00354   FORCEINLINE Train *GetPrevUnit()
00355   {
00356     Train *v = this->GetPrevVehicle();
00357     if (v != NULL && v->IsRearDualheaded()) v = v->GetPrevVehicle();
00358 
00359     return v;
00360   }
00361 };
00362 
00363 #define FOR_ALL_TRAINS(var) FOR_ALL_VEHICLES_OF_TYPE(Train, var)
00364 
00365 #endif /* TRAIN_H */

Generated on Tue Jan 5 21:03:00 2010 for OpenTTD by  doxygen 1.5.6