train.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifndef TRAIN_H
00013 #define TRAIN_H
00014
00015 #include "newgrf_engine.h"
00016 #include "cargotype.h"
00017 #include "rail.h"
00018 #include "engine_base.h"
00019 #include "rail_map.h"
00020 #include "ground_vehicle.hpp"
00021
00022 struct Train;
00023
00025 enum VehicleRailFlags {
00026 VRF_REVERSING = 0,
00027 VRF_POWEREDWAGON = 3,
00028 VRF_REVERSE_DIRECTION = 4,
00029
00030 VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL = 6,
00031 VRF_TOGGLE_REVERSE = 7,
00032 VRF_TRAIN_STUCK = 8,
00033 VRF_LEAVING_STATION = 9,
00034 };
00035
00037 enum TrainForceProceeding {
00038 TFP_NONE = 0,
00039 TFP_STUCK = 1,
00040 TFP_SIGNAL = 2,
00041 };
00042 typedef SimpleTinyEnumT<TrainForceProceeding, byte> TrainForceProceedingByte;
00043
00044 byte FreightWagonMult(CargoID cargo);
00045
00046 void CheckTrainsLengths();
00047
00048 void FreeTrainTrackReservation(const Train *v, TileIndex origin = INVALID_TILE, Trackdir orig_td = INVALID_TRACKDIR);
00049 bool TryPathReserve(Train *v, bool mark_as_stuck = false, bool first_tile_okay = false);
00050
00051 int GetTrainStopLocation(StationID station_id, TileIndex tile, const Train *v, int *station_ahead, int *station_length);
00052
00054 struct TrainCache {
00055
00056 const struct SpriteGroup *cached_override;
00057
00058
00059 bool cached_tilt;
00060
00061 byte user_def_data;
00062
00063
00064 int cached_max_curve_speed;
00065 };
00066
00070 struct Train : public GroundVehicle<Train, VEH_TRAIN> {
00071 TrainCache tcache;
00072
00073
00074 Train *other_multiheaded_part;
00075
00076 uint16 crash_anim_pos;
00077
00078 uint16 flags;
00079 TrackBitsByte track;
00080 TrainForceProceedingByte force_proceed;
00081 RailTypeByte railtype;
00082 RailTypes compatible_railtypes;
00083
00085 uint16 wait_counter;
00086
00088 Train() : GroundVehicleBase() {}
00090 virtual ~Train() { this->PreDestructor(); }
00091
00092 friend struct GroundVehicle<Train, VEH_TRAIN>;
00093
00094 void MarkDirty();
00095 void UpdateDeltaXY(Direction direction);
00096 ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_TRAIN_INC : EXPENSES_TRAIN_RUN; }
00097 void PlayLeaveStationSound() const;
00098 bool IsPrimaryVehicle() const { return this->IsFrontEngine(); }
00099 SpriteID GetImage(Direction direction) const;
00100 int GetDisplaySpeed() const { return this->gcache.last_speed; }
00101 int GetDisplayMaxSpeed() const { return this->vcache.cached_max_speed; }
00102 Money GetRunningCost() const;
00103 int GetDisplayImageWidth(Point *offset = NULL) const;
00104 bool IsInDepot() const;
00105 bool IsStoppedInDepot() const;
00106 bool Tick();
00107 void OnNewDay();
00108 uint Crash(bool flooded = false);
00109 Trackdir GetVehicleTrackdir() const;
00110 TileIndex GetOrderStationLocation(StationID station);
00111 bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse);
00112
00113 void ReserveTrackUnderConsist() const;
00114
00115 int GetCurveSpeedLimit() const;
00116
00117 void ConsistChanged(bool same_length);
00118
00119 void RailtypeChanged();
00120
00121 int UpdateSpeed();
00122
00123 void UpdateAcceleration();
00124
00125 int GetCurrentMaxSpeed() const;
00126
00131 FORCEINLINE Train *GetNextUnit() const
00132 {
00133 Train *v = this->GetNextVehicle();
00134 if (v != NULL && v->IsRearDualheaded()) v = v->GetNextVehicle();
00135
00136 return v;
00137 }
00138
00143 FORCEINLINE Train *GetPrevUnit()
00144 {
00145 Train *v = this->GetPrevVehicle();
00146 if (v != NULL && v->IsRearDualheaded()) v = v->GetPrevVehicle();
00147
00148 return v;
00149 }
00150
00151
00152 protected:
00153
00158 FORCEINLINE uint16 GetPower() const
00159 {
00160
00161 if (!this->IsArticulatedPart() && HasPowerOnRail(this->railtype, GetRailType(this->tile))) {
00162 uint16 power = GetVehicleProperty(this, PROP_TRAIN_POWER, RailVehInfo(this->engine_type)->power);
00163
00164 if (this->IsMultiheaded()) power /= 2;
00165 return power;
00166 }
00167
00168 return 0;
00169 }
00170
00175 FORCEINLINE uint16 GetPoweredPartPower(const Train *head) const
00176 {
00177
00178 if (HasBit(this->flags, VRF_POWEREDWAGON) && HasPowerOnRail(head->railtype, GetRailType(this->tile))) {
00179 return RailVehInfo(this->gcache.first_engine)->pow_wag_power;
00180 }
00181
00182 return 0;
00183 }
00184
00189 FORCEINLINE uint16 GetWeight() const
00190 {
00191 uint16 weight = (CargoSpec::Get(this->cargo_type)->weight * this->cargo.Count() * FreightWagonMult(this->cargo_type)) / 16;
00192
00193
00194 if (!this->IsArticulatedPart()) {
00195 weight += GetVehicleProperty(this, PROP_TRAIN_WEIGHT, RailVehInfo(this->engine_type)->weight);
00196 }
00197
00198
00199 if (HasBit(this->flags, VRF_POWEREDWAGON)) {
00200 weight += RailVehInfo(this->gcache.first_engine)->pow_wag_weight;
00201 }
00202
00203 return weight;
00204 }
00205
00210 FORCEINLINE byte GetTractiveEffort() const
00211 {
00212 return GetVehicleProperty(this, PROP_TRAIN_TRACTIVE_EFFORT, RailVehInfo(this->engine_type)->tractive_effort);
00213 }
00214
00219 FORCEINLINE byte GetAirDragArea() const
00220 {
00221
00222 return (this->track == TRACK_BIT_WORMHOLE && this->vehstatus & VS_HIDDEN) ? 28 : 14;
00223 }
00224
00229 FORCEINLINE byte GetAirDrag() const
00230 {
00231 return RailVehInfo(this->engine_type)->air_drag;
00232 }
00233
00238 FORCEINLINE AccelStatus GetAccelerationStatus() const
00239 {
00240 return (this->vehstatus & VS_STOPPED) || HasBit(this->flags, VRF_REVERSING) || HasBit(this->flags, VRF_TRAIN_STUCK) ? AS_BRAKE : AS_ACCEL;
00241 }
00242
00247 FORCEINLINE uint16 GetCurrentSpeed() const
00248 {
00249 return this->cur_speed;
00250 }
00251
00256 FORCEINLINE uint32 GetRollingFriction() const
00257 {
00258
00259
00260
00261 return 15 * (512 + this->GetCurrentSpeed()) / 512;
00262 }
00263
00268 FORCEINLINE int GetAccelerationType() const
00269 {
00270 return GetRailTypeInfo(this->railtype)->acceleration_type;
00271 }
00272
00277 FORCEINLINE uint32 GetSlopeSteepness() const
00278 {
00279 return _settings_game.vehicle.train_slope_steepness;
00280 }
00281
00286 FORCEINLINE uint16 GetMaxTrackSpeed() const
00287 {
00288 return GetRailTypeInfo(GetRailType(this->tile))->max_speed;
00289 }
00290
00295 FORCEINLINE bool TileMayHaveSlopedTrack() const
00296 {
00297
00298 return this->track == TRACK_BIT_X || this->track == TRACK_BIT_Y;
00299 }
00300
00306 FORCEINLINE bool HasToUseGetSlopeZ()
00307 {
00308 return false;
00309 }
00310 };
00311
00312 #define FOR_ALL_TRAINS(var) FOR_ALL_VEHICLES_OF_TYPE(Train, var)
00313
00314 #endif