# roadveh.h

Go to the documentation of this file.

    00001 /* $Id: roadveh.h 24839 2012-12-23 01:00:25Z michi_cc $ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
    00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
    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    * Lower 4 bits are used for vehicle track direction. (Trackdirs)
    00028    * When in a road stop (bit 5 or bit 6 set) these bits give the
    00029    * track direction of the entry to the road stop.
    00030    * As the entry direction will always be a diagonal
    00031    * direction (X_NE, Y_SE, X_SW or Y_NW) only bits 0 and 3
    00032    * are needed to hold this direction. Bit 1 is then used to show
    00033    * that the vehicle is using the second road stop bay.
    00034    * Bit 2 is then used for drive-through stops to show the vehicle
    00035    * is stopping at this road stop.
    00036    */
    00037
    00038   /* Numeric values */
    00039   RVSB_IN_DEPOT                = 0xFE,
    00040   RVSB_WORMHOLE                = 0xFF,
    00041
    00042   /* Bit numbers */
    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   /* Bit sets of the above specified bits */
    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 /* Start frames for when a vehicle enters a tile/changes its state.
    00066  * The start frame is different for vehicles that turned around or
    00067  * are leaving the depot as the do not start at the edge of the tile.
    00068  * For trams there are a few different start frames as there are two
    00069  * places where trams can turn. */
    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 /* Stop frame for a vehicle in a drive-through stop */
    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>; // GroundVehicle needs to use the acceleration functions defined at RoadVehicle.
    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: // These functions should not be called outside acceleration code.
    00130
    00135   inline uint16 GetPower() const
    00136   {
    00137     /* Power is not added for articulated parts */
    00138     if (!this->IsArticulatedPart()) {
    00139       /* Road vehicle power is in units of 10 HP. */
    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     /* Vehicle weight is not added for articulated parts. */
    00163     if (!this->IsArticulatedPart()) {
    00164       /* Road vehicle weight is in units of 1/4 t. */
    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     /* The tractive effort coefficient is in units of 1/256.  */
    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     /* Trams have a slightly greater friction coefficient than trains.
    00224      * The rest of road vehicles have bigger values. */
    00225     uint32 coeff = (this->roadtype == ROADTYPE_TRAM) ? 40 : 75;
    00226     /* The friction coefficient increases with speed in a way that
    00227      * it doubles at 128 km/h, triples at 256 km/h and so on. */
    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     /* Check if this vehicle is in the same direction as the road under.
    00282      * We already know it has either GVF_GOINGUP_BIT or GVF_GOINGDOWN_BIT set. */
    00283
    00284     if (rv->state <= RVSB_TRACKDIR_MASK && IsReversingRoadTrackdir((Trackdir)rv->state)) {
    00285       /* If the first vehicle is reversing, this vehicle may be reversing too
    00286        * (especially if this is the first, and maybe the only, vehicle).*/
    00287       return true;
    00288     }
    00289
    00290     while (rv != this) {
    00291       /* If any previous vehicle has different direction,
    00292        * we may be in the middle of reversing. */
    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 /* ROADVEH_H */