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);
00083 
00087 struct RoadVehicle : 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) 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 IsStoppedInDepot() const;
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   FORCEINLINE 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   FORCEINLINE uint16 GetPoweredPartPower(const RoadVehicle *head) const
00150   {
00151     return 0;
00152   }
00153 
00158   FORCEINLINE 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   FORCEINLINE 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   FORCEINLINE byte GetAirDragArea() const
00186   {
00187     return 6;
00188   }
00189 
00194   FORCEINLINE byte GetAirDrag() const
00195   {
00196     return RoadVehInfo(this->engine_type)->air_drag;
00197   }
00198 
00203   FORCEINLINE AccelStatus GetAccelerationStatus() const
00204   {
00205     return (this->vehstatus & VS_STOPPED) ? AS_BRAKE : AS_ACCEL;
00206   }
00207 
00212   FORCEINLINE uint16 GetCurrentSpeed() const
00213   {
00214     return this->cur_speed / 2;
00215   }
00216 
00221   FORCEINLINE 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   FORCEINLINE int GetAccelerationType() const
00236   {
00237     return 0;
00238   }
00239 
00244   FORCEINLINE uint32 GetSlopeSteepness() const
00245   {
00246     return _settings_game.vehicle.roadveh_slope_steepness;
00247   }
00248 
00253   FORCEINLINE uint16 GetMaxTrackSpeed() const
00254   {
00255     return 0;
00256   }
00257 
00262   FORCEINLINE 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   FORCEINLINE bool HasToUseGetSlopeZ()
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 */

Generated on Mon May 9 05:18:59 2011 for OpenTTD by  doxygen 1.6.1