00001
00002
00003
00004
00005
00006
00007
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
00025 VRF_GOINGUP = 1,
00026 VRF_GOINGDOWN = 2,
00027
00028
00029 VRF_POWEREDWAGON = 3,
00030
00031
00032 VRF_REVERSE_DIRECTION = 4,
00033
00034
00035 VRF_NO_PATH_TO_DESTINATION = 5,
00036
00037
00038 VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL = 6,
00039
00040
00041 VRF_TOGGLE_REVERSE = 7,
00042
00043
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
00070 const struct SpriteGroup *cached_override;
00071
00072 uint16 last_speed;
00073
00074
00075 uint32 cached_power;
00076 uint16 cached_total_length;
00077 uint8 cached_veh_length;
00078 bool cached_tilt;
00079
00080
00081 uint32 cached_weight;
00082 uint32 cached_veh_weight;
00083 uint32 cached_max_te;
00084
00085
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
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
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