roadveh.h

Go to the documentation of this file.
00001 /* $Id$ */
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 
00087 struct RoadVehicle FINAL : public GroundVehicle<RoadVehicle, VEH_ROAD> {
00088   byte state;             
00089   byte frame;
00090   uint16 blocked_ctr;
00091   byte overtaking;        
00092   byte overtaking_ctr;    
00093   uint16 crashed_ctr;     
00094   byte reverse_ctr;
00095 
00096   RoadType roadtype;
00097   RoadTypes compatible_roadtypes;
00098 
00100   RoadVehicle() : GroundVehicleBase() {}
00102   virtual ~RoadVehicle() { this->PreDestructor(); }
00103 
00104   friend struct GroundVehicle<RoadVehicle, VEH_ROAD>; // GroundVehicle needs to use the acceleration functions defined at RoadVehicle.
00105 
00106   void MarkDirty();
00107   void UpdateDeltaXY(Direction direction);
00108   ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_ROADVEH_INC : EXPENSES_ROADVEH_RUN; }
00109   bool IsPrimaryVehicle() const { return this->IsFrontEngine(); }
00110   SpriteID GetImage(Direction direction, EngineImageType image_type) const;
00111   int GetDisplaySpeed() const { return this->gcache.last_speed / 2; }
00112   int GetDisplayMaxSpeed() const { return this->vcache.cached_max_speed / 2; }
00113   Money GetRunningCost() const;
00114   int GetDisplayImageWidth(Point *offset = NULL) const;
00115   bool IsInDepot() const { return this->state == RVSB_IN_DEPOT; }
00116   bool Tick();
00117   void OnNewDay();
00118   uint Crash(bool flooded = false);
00119   Trackdir GetVehicleTrackdir() const;
00120   TileIndex GetOrderStationLocation(StationID station);
00121   bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse);
00122 
00123   bool IsBus() const;
00124 
00125   int GetCurrentMaxSpeed() const;
00126   int UpdateSpeed();
00127 
00128 protected: // These functions should not be called outside acceleration code.
00129 
00134   inline uint16 GetPower() const
00135   {
00136     /* Power is not added for articulated parts */
00137     if (!this->IsArticulatedPart()) {
00138       /* Road vehicle power is in units of 10 HP. */
00139       return 10 * GetVehicleProperty(this, PROP_ROADVEH_POWER, RoadVehInfo(this->engine_type)->power);
00140     }
00141     return 0;
00142   }
00143 
00148   inline uint16 GetPoweredPartPower(const RoadVehicle *head) const
00149   {
00150     return 0;
00151   }
00152 
00157   inline uint16 GetWeight() const
00158   {
00159     uint16 weight = (CargoSpec::Get(this->cargo_type)->weight * this->cargo.Count()) / 16;
00160 
00161     /* Vehicle weight is not added for articulated parts. */
00162     if (!this->IsArticulatedPart()) {
00163       /* Road vehicle weight is in units of 1/4 t. */
00164       weight += GetVehicleProperty(this, PROP_ROADVEH_WEIGHT, RoadVehInfo(this->engine_type)->weight) / 4;
00165     }
00166 
00167     return weight;
00168   }
00169 
00174   inline byte GetTractiveEffort() const
00175   {
00176     /* The tractive effort coefficient is in units of 1/256.  */
00177     return GetVehicleProperty(this, PROP_ROADVEH_TRACTIVE_EFFORT, RoadVehInfo(this->engine_type)->tractive_effort);
00178   }
00179 
00184   inline byte GetAirDragArea() const
00185   {
00186     return 6;
00187   }
00188 
00193   inline byte GetAirDrag() const
00194   {
00195     return RoadVehInfo(this->engine_type)->air_drag;
00196   }
00197 
00202   inline AccelStatus GetAccelerationStatus() const
00203   {
00204     return (this->vehstatus & VS_STOPPED) ? AS_BRAKE : AS_ACCEL;
00205   }
00206 
00211   inline uint16 GetCurrentSpeed() const
00212   {
00213     return this->cur_speed / 2;
00214   }
00215 
00220   inline uint32 GetRollingFriction() const
00221   {
00222     /* Trams have a slightly greater friction coefficient than trains.
00223      * The rest of road vehicles have bigger values. */
00224     uint32 coeff = (this->roadtype == ROADTYPE_TRAM) ? 40 : 75;
00225     /* The friction coefficient increases with speed in a way that
00226      * it doubles at 128 km/h, triples at 256 km/h and so on. */
00227     return coeff * (128 + this->GetCurrentSpeed()) / 128;
00228   }
00229 
00234   inline int GetAccelerationType() const
00235   {
00236     return 0;
00237   }
00238 
00243   inline uint32 GetSlopeSteepness() const
00244   {
00245     return _settings_game.vehicle.roadveh_slope_steepness;
00246   }
00247 
00252   inline uint16 GetMaxTrackSpeed() const
00253   {
00254     return 0;
00255   }
00256 
00261   inline bool TileMayHaveSlopedTrack() const
00262   {
00263     TrackStatus ts = GetTileTrackStatus(this->tile, TRANSPORT_ROAD, this->compatible_roadtypes);
00264     TrackBits trackbits = TrackStatusToTrackBits(ts);
00265 
00266     return trackbits == TRACK_BIT_X || trackbits == TRACK_BIT_Y;
00267   }
00268 
00276   inline bool HasToUseGetSlopePixelZ()
00277   {
00278     const RoadVehicle *rv = this->First();
00279 
00280     /* Check if this vehicle is in the same direction as the road under.
00281      * We already know it has either GVF_GOINGUP_BIT or GVF_GOINGDOWN_BIT set. */
00282 
00283     if (rv->state <= RVSB_TRACKDIR_MASK && IsReversingRoadTrackdir((Trackdir)rv->state)) {
00284       /* If the first vehicle is reversing, this vehicle may be reversing too
00285        * (especially if this is the first, and maybe the only, vehicle).*/
00286       return true;
00287     }
00288 
00289     while (rv != this) {
00290       /* If any previous vehicle has different direction,
00291        * we may be in the middle of reversing. */
00292       if (this->direction != rv->direction) return true;
00293       rv = rv->Next();
00294     }
00295 
00296     return false;
00297   }
00298 };
00299 
00300 #define FOR_ALL_ROADVEHICLES(var) FOR_ALL_VEHICLES_OF_TYPE(RoadVehicle, var)
00301 
00302 #endif /* ROADVEH_H */