roadveh.h
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_TRACKDIR_MASK = 0x0F,
00056 RVSB_ROAD_STOP_TRACKDIR_MASK = 0x09
00057 };
00058
00060 static const uint RDE_NEXT_TILE = 0x80;
00061 static const uint RDE_TURNED = 0x40;
00062
00063
00064
00065
00066
00067
00068 static const uint RVC_DEFAULT_START_FRAME = 0;
00069 static const uint RVC_TURN_AROUND_START_FRAME = 1;
00070 static const uint RVC_DEPOT_START_FRAME = 6;
00071 static const uint RVC_START_FRAME_AFTER_LONG_TRAM = 21;
00072 static const uint RVC_TURN_AROUND_START_FRAME_SHORT_TRAM = 16;
00073
00074 static const uint RVC_DRIVE_THROUGH_STOP_FRAME = 11;
00075 static const uint RVC_DEPOT_STOP_FRAME = 11;
00076
00077 void RoadVehUpdateCache(RoadVehicle *v);
00078
00082 struct RoadVehicle : public GroundVehicle<RoadVehicle, VEH_ROAD> {
00083 byte state;
00084 byte frame;
00085 uint16 blocked_ctr;
00086 byte overtaking;
00087 byte overtaking_ctr;
00088 uint16 crashed_ctr;
00089 byte reverse_ctr;
00090
00091 RoadType roadtype;
00092 RoadTypes compatible_roadtypes;
00093
00095 RoadVehicle() : GroundVehicleBase() {}
00097 virtual ~RoadVehicle() { this->PreDestructor(); }
00098
00099 friend struct GroundVehicle<RoadVehicle, VEH_ROAD>;
00100
00101 const char *GetTypeString() const { return "road vehicle"; }
00102 void MarkDirty();
00103 void UpdateDeltaXY(Direction direction);
00104 ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_ROADVEH_INC : EXPENSES_ROADVEH_RUN; }
00105 bool IsPrimaryVehicle() const { return this->IsFrontEngine(); }
00106 SpriteID GetImage(Direction direction) const;
00107 int GetDisplaySpeed() const { return this->cur_speed / 2; }
00108 int GetDisplayMaxSpeed() const { return this->vcache.cached_max_speed / 2; }
00109 Money GetRunningCost() const;
00110 int GetDisplayImageWidth(Point *offset = NULL) const;
00111 bool IsInDepot() const { return this->state == RVSB_IN_DEPOT; }
00112 bool IsStoppedInDepot() const;
00113 bool Tick();
00114 void OnNewDay();
00115 uint Crash(bool flooded = false);
00116 Trackdir GetVehicleTrackdir() const;
00117 TileIndex GetOrderStationLocation(StationID station);
00118 bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse);
00119
00120 bool IsBus() const;
00121
00122 int GetCurrentMaxSpeed() const;
00123
00124 protected:
00125
00130 FORCEINLINE uint16 GetPower() const
00131 {
00132
00133 if (!this->IsArticulatedPart()) {
00134
00135 return 10 * GetVehicleProperty(this, PROP_ROADVEH_POWER, RoadVehInfo(this->engine_type)->power);
00136 }
00137 return 0;
00138 }
00139
00144 FORCEINLINE uint16 GetPoweredPartPower(const RoadVehicle *head) const
00145 {
00146 return 0;
00147 }
00148
00153 FORCEINLINE uint16 GetWeight() const
00154 {
00155 uint16 weight = (CargoSpec::Get(this->cargo_type)->weight * this->cargo.Count()) / 16;
00156
00157
00158 if (!this->IsArticulatedPart()) {
00159
00160 weight += GetVehicleProperty(this, PROP_ROADVEH_WEIGHT, RoadVehInfo(this->engine_type)->weight) / 4;
00161 }
00162
00163 return weight;
00164 }
00165
00170 FORCEINLINE byte GetTractiveEffort() const
00171 {
00172
00173 return GetVehicleProperty(this, PROP_ROADVEH_TRACTIVE_EFFORT, RoadVehInfo(this->engine_type)->tractive_effort);
00174 }
00175
00180 FORCEINLINE byte GetAirDragArea() const
00181 {
00182 return 6;
00183 }
00184
00189 FORCEINLINE byte GetAirDrag() const
00190 {
00191 return RoadVehInfo(this->engine_type)->air_drag;
00192 }
00193
00198 FORCEINLINE AccelStatus GetAccelerationStatus() const
00199 {
00200 return (this->vehstatus & VS_STOPPED) ? AS_BRAKE : AS_ACCEL;
00201 }
00202
00207 FORCEINLINE uint16 GetCurrentSpeed() const
00208 {
00209 return this->cur_speed / 2;
00210 }
00211
00216 FORCEINLINE uint32 GetRollingFriction() const
00217 {
00218
00219
00220 uint32 coeff = (this->roadtype == ROADTYPE_TRAM) ? 40 : 75;
00221
00222
00223 return coeff * (128 + this->GetCurrentSpeed()) / 128;
00224 }
00225
00230 FORCEINLINE int GetAccelerationType() const
00231 {
00232 return 0;
00233 }
00234
00239 FORCEINLINE uint32 GetSlopeSteepness() const
00240 {
00241 return _settings_game.vehicle.roadveh_slope_steepness;
00242 }
00243
00248 FORCEINLINE uint16 GetMaxTrackSpeed() const
00249 {
00250 return 0;
00251 }
00252
00257 FORCEINLINE bool TileMayHaveSlopedTrack() const
00258 {
00259 TrackStatus ts = GetTileTrackStatus(this->tile, TRANSPORT_ROAD, this->compatible_roadtypes);
00260 TrackBits trackbits = TrackStatusToTrackBits(ts);
00261
00262 return trackbits == TRACK_BIT_X || trackbits == TRACK_BIT_Y;
00263 }
00264
00272 FORCEINLINE bool HasToUseGetSlopeZ()
00273 {
00274 const RoadVehicle *rv = this->First();
00275
00276
00277
00278
00279 if (rv->state <= RVSB_TRACKDIR_MASK && IsReversingRoadTrackdir((Trackdir)rv->state)) {
00280
00281
00282 return true;
00283 }
00284
00285 while (rv != this) {
00286
00287
00288 if (this->direction != rv->direction) return true;
00289 rv = rv->Next();
00290 }
00291
00292 return false;
00293 }
00294 };
00295
00296 #define FOR_ALL_ROADVEHICLES(var) FOR_ALL_VEHICLES_OF_TYPE(RoadVehicle, var)
00297
00298 #endif