Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifndef ROADVEH_H
00013 #define ROADVEH_H
00014
00015 #include "ground_vehicle.hpp"
00016 #include "engine_base.h"
00017 #include "cargotype.h"
00018 #include "track_func.h"
00019 #include "road_type.h"
00020 #include "newgrf_engine.h"
00021
00022 struct RoadVehicle;
00023
00025 enum RoadVehicleStates {
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 RVSB_IN_DEPOT = 0xFE,
00040 RVSB_WORMHOLE = 0xFF,
00041
00042
00043 RVS_USING_SECOND_BAY = 1,
00044 RVS_ENTERED_STOP = 2,
00045 RVS_DRIVE_SIDE = 4,
00046 RVS_IN_ROAD_STOP = 5,
00047 RVS_IN_DT_ROAD_STOP = 6,
00048
00049
00050 RVSB_IN_ROAD_STOP = 1 << RVS_IN_ROAD_STOP,
00051 RVSB_IN_ROAD_STOP_END = RVSB_IN_ROAD_STOP + TRACKDIR_END,
00052 RVSB_IN_DT_ROAD_STOP = 1 << RVS_IN_DT_ROAD_STOP,
00053 RVSB_IN_DT_ROAD_STOP_END = RVSB_IN_DT_ROAD_STOP + TRACKDIR_END,
00054
00055 RVSB_DRIVE_SIDE = 1 << RVS_DRIVE_SIDE,
00056
00057 RVSB_TRACKDIR_MASK = 0x0F,
00058 RVSB_ROAD_STOP_TRACKDIR_MASK = 0x09,
00059 };
00060
00062 static const uint RDE_NEXT_TILE = 0x80;
00063 static const uint RDE_TURNED = 0x40;
00064
00065
00066
00067
00068
00069
00070 static const uint RVC_DEFAULT_START_FRAME = 0;
00071 static const uint RVC_TURN_AROUND_START_FRAME = 1;
00072 static const uint RVC_DEPOT_START_FRAME = 6;
00073 static const uint RVC_START_FRAME_AFTER_LONG_TRAM = 21;
00074 static const uint RVC_TURN_AROUND_START_FRAME_SHORT_TRAM = 16;
00075
00076 static const uint RVC_DRIVE_THROUGH_STOP_FRAME = 11;
00077 static const uint RVC_DEPOT_STOP_FRAME = 11;
00078
00080 static const byte RV_OVERTAKE_TIMEOUT = 35;
00081
00082 void RoadVehUpdateCache(RoadVehicle *v, bool same_length = false);
00083 void GetRoadVehSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type);
00084
00088 struct RoadVehicle FINAL : public GroundVehicle<RoadVehicle, VEH_ROAD> {
00089 byte state;
00090 byte frame;
00091 uint16 blocked_ctr;
00092 byte overtaking;
00093 byte overtaking_ctr;
00094 uint16 crashed_ctr;
00095 byte reverse_ctr;
00096
00097 RoadType roadtype;
00098 RoadTypes compatible_roadtypes;
00099
00101 RoadVehicle() : GroundVehicleBase() {}
00103 virtual ~RoadVehicle() { this->PreDestructor(); }
00104
00105 friend struct GroundVehicle<RoadVehicle, VEH_ROAD>;
00106
00107 void MarkDirty();
00108 void UpdateDeltaXY(Direction direction);
00109 ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_ROADVEH_INC : EXPENSES_ROADVEH_RUN; }
00110 bool IsPrimaryVehicle() const { return this->IsFrontEngine(); }
00111 SpriteID GetImage(Direction direction, EngineImageType image_type) const;
00112 int GetDisplaySpeed() const { return this->gcache.last_speed / 2; }
00113 int GetDisplayMaxSpeed() const { return this->vcache.cached_max_speed / 2; }
00114 Money GetRunningCost() const;
00115 int GetDisplayImageWidth(Point *offset = NULL) const;
00116 bool IsInDepot() const { return this->state == RVSB_IN_DEPOT; }
00117 bool Tick();
00118 void OnNewDay();
00119 uint Crash(bool flooded = false);
00120 Trackdir GetVehicleTrackdir() const;
00121 TileIndex GetOrderStationLocation(StationID station);
00122 bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse);
00123
00124 bool IsBus() const;
00125
00126 int GetCurrentMaxSpeed() const;
00127 int UpdateSpeed();
00128
00129 protected:
00130
00135 inline uint16 GetPower() const
00136 {
00137
00138 if (!this->IsArticulatedPart()) {
00139
00140 return 10 * GetVehicleProperty(this, PROP_ROADVEH_POWER, RoadVehInfo(this->engine_type)->power);
00141 }
00142 return 0;
00143 }
00144
00149 inline uint16 GetPoweredPartPower(const RoadVehicle *head) const
00150 {
00151 return 0;
00152 }
00153
00158 inline uint16 GetWeight() const
00159 {
00160 uint16 weight = (CargoSpec::Get(this->cargo_type)->weight * this->cargo.Count()) / 16;
00161
00162
00163 if (!this->IsArticulatedPart()) {
00164
00165 weight += GetVehicleProperty(this, PROP_ROADVEH_WEIGHT, RoadVehInfo(this->engine_type)->weight) / 4;
00166 }
00167
00168 return weight;
00169 }
00170
00175 inline byte GetTractiveEffort() const
00176 {
00177
00178 return GetVehicleProperty(this, PROP_ROADVEH_TRACTIVE_EFFORT, RoadVehInfo(this->engine_type)->tractive_effort);
00179 }
00180
00185 inline byte GetAirDragArea() const
00186 {
00187 return 6;
00188 }
00189
00194 inline byte GetAirDrag() const
00195 {
00196 return RoadVehInfo(this->engine_type)->air_drag;
00197 }
00198
00203 inline AccelStatus GetAccelerationStatus() const
00204 {
00205 return (this->vehstatus & VS_STOPPED) ? AS_BRAKE : AS_ACCEL;
00206 }
00207
00212 inline uint16 GetCurrentSpeed() const
00213 {
00214 return this->cur_speed / 2;
00215 }
00216
00221 inline uint32 GetRollingFriction() const
00222 {
00223
00224
00225 uint32 coeff = (this->roadtype == ROADTYPE_TRAM) ? 40 : 75;
00226
00227
00228 return coeff * (128 + this->GetCurrentSpeed()) / 128;
00229 }
00230
00235 inline int GetAccelerationType() const
00236 {
00237 return 0;
00238 }
00239
00244 inline uint32 GetSlopeSteepness() const
00245 {
00246 return _settings_game.vehicle.roadveh_slope_steepness;
00247 }
00248
00253 inline uint16 GetMaxTrackSpeed() const
00254 {
00255 return 0;
00256 }
00257
00262 inline bool TileMayHaveSlopedTrack() const
00263 {
00264 TrackStatus ts = GetTileTrackStatus(this->tile, TRANSPORT_ROAD, this->compatible_roadtypes);
00265 TrackBits trackbits = TrackStatusToTrackBits(ts);
00266
00267 return trackbits == TRACK_BIT_X || trackbits == TRACK_BIT_Y;
00268 }
00269
00277 inline bool HasToUseGetSlopePixelZ()
00278 {
00279 const RoadVehicle *rv = this->First();
00280
00281
00282
00283
00284 if (rv->state <= RVSB_TRACKDIR_MASK && IsReversingRoadTrackdir((Trackdir)rv->state)) {
00285
00286
00287 return true;
00288 }
00289
00290 while (rv != this) {
00291
00292
00293 if (this->direction != rv->direction) return true;
00294 rv = rv->Next();
00295 }
00296
00297 return false;
00298 }
00299 };
00300
00301 #define FOR_ALL_ROADVEHICLES(var) FOR_ALL_VEHICLES_OF_TYPE(RoadVehicle, var)
00302
00303 #endif