OpenTTD
roadveh.h
Go to the documentation of this file.
1 /* $Id: roadveh.h 27666 2016-10-16 14:57:56Z frosch $ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * 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.
6  * 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.
7  * 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/>.
8  */
9 
12 #ifndef ROADVEH_H
13 #define ROADVEH_H
14 
15 #include "ground_vehicle.hpp"
16 #include "engine_base.h"
17 #include "cargotype.h"
18 #include "track_func.h"
19 #include "road_type.h"
20 #include "newgrf_engine.h"
21 
22 struct RoadVehicle;
23 
26  /*
27  * Lower 4 bits are used for vehicle track direction. (Trackdirs)
28  * When in a road stop (bit 5 or bit 6 set) these bits give the
29  * track direction of the entry to the road stop.
30  * As the entry direction will always be a diagonal
31  * direction (X_NE, Y_SE, X_SW or Y_NW) only bits 0 and 3
32  * are needed to hold this direction. Bit 1 is then used to show
33  * that the vehicle is using the second road stop bay.
34  * Bit 2 is then used for drive-through stops to show the vehicle
35  * is stopping at this road stop.
36  */
37 
38  /* Numeric values */
39  RVSB_IN_DEPOT = 0xFE,
40  RVSB_WORMHOLE = 0xFF,
41 
42  /* Bit numbers */
48 
49  /* Bit sets of the above specified bits */
51  RVSB_IN_ROAD_STOP_END = RVSB_IN_ROAD_STOP + TRACKDIR_END,
53  RVSB_IN_DT_ROAD_STOP_END = RVSB_IN_DT_ROAD_STOP + TRACKDIR_END,
54 
56 
59 };
60 
62 static const uint RDE_NEXT_TILE = 0x80;
63 static const uint RDE_TURNED = 0x40;
64 
65 /* Start frames for when a vehicle enters a tile/changes its state.
66  * The start frame is different for vehicles that turned around or
67  * are leaving the depot as the do not start at the edge of the tile.
68  * For trams there are a few different start frames as there are two
69  * places where trams can turn. */
70 static const uint RVC_DEFAULT_START_FRAME = 0;
71 static const uint RVC_TURN_AROUND_START_FRAME = 1;
72 static const uint RVC_DEPOT_START_FRAME = 6;
73 static const uint RVC_START_FRAME_AFTER_LONG_TRAM = 21;
74 static const uint RVC_TURN_AROUND_START_FRAME_SHORT_TRAM = 16;
75 /* Stop frame for a vehicle in a drive-through stop */
76 static const uint RVC_DRIVE_THROUGH_STOP_FRAME = 11;
77 static const uint RVC_DEPOT_STOP_FRAME = 11;
78 
80 static const byte RV_OVERTAKE_TIMEOUT = 35;
81 
82 void RoadVehUpdateCache(RoadVehicle *v, bool same_length = false);
83 void GetRoadVehSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type);
84 
88 struct RoadVehicle FINAL : public GroundVehicle<RoadVehicle, VEH_ROAD> {
89  byte state;
90  byte frame;
91  uint16 blocked_ctr;
92  byte overtaking;
94  uint16 crashed_ctr;
95  byte reverse_ctr;
96 
97  RoadType roadtype;
98  RoadTypes compatible_roadtypes;
99 
103  virtual ~RoadVehicle() { this->PreDestructor(); }
104 
105  friend struct GroundVehicle<RoadVehicle, VEH_ROAD>; // GroundVehicle needs to use the acceleration functions defined at RoadVehicle.
106 
107  void MarkDirty();
109  ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_ROADVEH_INC : EXPENSES_ROADVEH_RUN; }
110  bool IsPrimaryVehicle() const { return this->IsFrontEngine(); }
111  void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const;
112  int GetDisplaySpeed() const { return this->gcache.last_speed / 2; }
113  int GetDisplayMaxSpeed() const { return this->vcache.cached_max_speed / 2; }
114  Money GetRunningCost() const;
115  int GetDisplayImageWidth(Point *offset = NULL) const;
116  bool IsInDepot() const { return this->state == RVSB_IN_DEPOT; }
117  bool Tick();
118  void OnNewDay();
119  uint Crash(bool flooded = false);
121  TileIndex GetOrderStationLocation(StationID station);
122  bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse);
123 
124  bool IsBus() const;
125 
126  int GetCurrentMaxSpeed() const;
127  int UpdateSpeed();
128 
129 protected: // These functions should not be called outside acceleration code.
130 
135  inline uint16 GetPower() const
136  {
137  /* Power is not added for articulated parts */
138  if (!this->IsArticulatedPart()) {
139  /* Road vehicle power is in units of 10 HP. */
140  return 10 * GetVehicleProperty(this, PROP_ROADVEH_POWER, RoadVehInfo(this->engine_type)->power);
141  }
142  return 0;
143  }
144 
149  inline uint16 GetPoweredPartPower(const RoadVehicle *head) const
150  {
151  return 0;
152  }
153 
158  inline uint16 GetWeight() const
159  {
160  uint16 weight = (CargoSpec::Get(this->cargo_type)->weight * this->cargo.StoredCount()) / 16;
161 
162  /* Vehicle weight is not added for articulated parts. */
163  if (!this->IsArticulatedPart()) {
164  /* Road vehicle weight is in units of 1/4 t. */
165  weight += GetVehicleProperty(this, PROP_ROADVEH_WEIGHT, RoadVehInfo(this->engine_type)->weight) / 4;
166  }
167 
168  return weight;
169  }
170 
175  inline byte GetTractiveEffort() const
176  {
177  /* The tractive effort coefficient is in units of 1/256. */
178  return GetVehicleProperty(this, PROP_ROADVEH_TRACTIVE_EFFORT, RoadVehInfo(this->engine_type)->tractive_effort);
179  }
180 
185  inline byte GetAirDragArea() const
186  {
187  return 6;
188  }
189 
194  inline byte GetAirDrag() const
195  {
196  return RoadVehInfo(this->engine_type)->air_drag;
197  }
198 
204  {
205  return (this->vehstatus & VS_STOPPED) ? AS_BRAKE : AS_ACCEL;
206  }
207 
212  inline uint16 GetCurrentSpeed() const
213  {
214  return this->cur_speed / 2;
215  }
216 
221  inline uint32 GetRollingFriction() const
222  {
223  /* Trams have a slightly greater friction coefficient than trains.
224  * The rest of road vehicles have bigger values. */
225  uint32 coeff = (this->roadtype == ROADTYPE_TRAM) ? 40 : 75;
226  /* The friction coefficient increases with speed in a way that
227  * it doubles at 128 km/h, triples at 256 km/h and so on. */
228  return coeff * (128 + this->GetCurrentSpeed()) / 128;
229  }
230 
235  inline int GetAccelerationType() const
236  {
237  return 0;
238  }
239 
244  inline uint32 GetSlopeSteepness() const
245  {
247  }
248 
253  inline uint16 GetMaxTrackSpeed() const
254  {
255  return 0;
256  }
257 
262  inline bool TileMayHaveSlopedTrack() const
263  {
264  TrackStatus ts = GetTileTrackStatus(this->tile, TRANSPORT_ROAD, this->compatible_roadtypes);
265  TrackBits trackbits = TrackStatusToTrackBits(ts);
266 
267  return trackbits == TRACK_BIT_X || trackbits == TRACK_BIT_Y;
268  }
269 
278  {
279  const RoadVehicle *rv = this->First();
280 
281  /* Check if this vehicle is in the same direction as the road under.
282  * We already know it has either GVF_GOINGUP_BIT or GVF_GOINGDOWN_BIT set. */
283 
285  /* If the first vehicle is reversing, this vehicle may be reversing too
286  * (especially if this is the first, and maybe the only, vehicle).*/
287  return true;
288  }
289 
290  while (rv != this) {
291  /* If any previous vehicle has different direction,
292  * we may be in the middle of reversing. */
293  if (this->direction != rv->direction) return true;
294  rv = rv->Next();
295  }
296 
297  return false;
298  }
299 };
300 
301 #define FOR_ALL_ROADVEHICLES(var) FOR_ALL_VEHICLES_OF_TYPE(RoadVehicle, var)
302 
303 #endif /* ROADVEH_H */