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