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