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 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
00068 const struct SpriteGroup *cached_override;
00069
00070 uint16 last_speed;
00071
00072
00073 uint32 cached_power;
00074 uint16 cached_total_length;
00075 uint8 cached_veh_length;
00076 bool cached_tilt;
00077
00078
00079 uint32 cached_weight;
00080 uint32 cached_veh_weight;
00081 uint32 cached_max_te;
00082
00083
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
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
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