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_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 /* Start frames for when a vehicle enters a tile/changes its state.
00064  * The start frame is different for vehicles that turned around or
00065  * are leaving the depot as the do not start at the edge of the tile.
00066  * For trams there are a few different start frames as there are two
00067  * places where trams can turn. */
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 /* Stop frame for a vehicle in a drive-through stop */
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>; // GroundVehicle needs to use the acceleration functions defined at RoadVehicle.
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: // These functions should not be called outside acceleration code.
00125 
00130   FORCEINLINE uint16 GetPower() const
00131   {
00132     /* Power is not added for articulated parts */
00133     if (!this->IsArticulatedPart()) {
00134       /* Road vehicle power is in units of 10 HP. */
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     /* Vehicle weight is not added for articulated parts. */
00158     if (!this->IsArticulatedPart()) {
00159       /* Road vehicle weight is in units of 1/4 t. */
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     /* The tractive effort coefficient is in units of 1/256.  */
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     /* Trams have a slightly greater friction coefficient than trains.
00219      * The rest of road vehicles have bigger values. */
00220     uint32 coeff = (this->roadtype == ROADTYPE_TRAM) ? 40 : 75;
00221     /* The friction coefficient increases with speed in a way that
00222      * it doubles at 128 km/h, triples at 256 km/h and so on. */
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     /* Check if this vehicle is in the same direction as the road under.
00277      * We already know it has either GVF_GOINGUP_BIT or GVF_GOINGDOWN_BIT set. */
00278 
00279     if (rv->state <= RVSB_TRACKDIR_MASK && IsReversingRoadTrackdir((Trackdir)rv->state)) {
00280       /* If the first vehicle is reversing, this vehicle may be reversing too
00281        * (especially if this is the first, and maybe the only, vehicle).*/
00282       return true;
00283     }
00284 
00285     while (rv != this) {
00286       /* If any previous vehicle has different direction,
00287        * we may be in the middle of reversing. */
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 /* ROADVEH_H */

Generated on Sun Jan 23 01:49:07 2011 for OpenTTD by  doxygen 1.6.1