OpenTTD
roadveh_cmd.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of OpenTTD.
3  * 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.
4  * 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.
5  * 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/>.
6  */
7 
10 #include "stdafx.h"
11 #include "roadveh.h"
12 #include "command_func.h"
13 #include "news_func.h"
15 #include "station_base.h"
16 #include "company_func.h"
17 #include "articulated_vehicles.h"
18 #include "newgrf_sound.h"
19 #include "pathfinder/yapf/yapf.h"
20 #include "strings_func.h"
21 #include "tunnelbridge_map.h"
22 #include "date_func.h"
23 #include "vehicle_func.h"
24 #include "sound_func.h"
25 #include "ai/ai.hpp"
26 #include "game/game.hpp"
27 #include "depot_map.h"
28 #include "effectvehicle_func.h"
29 #include "roadstop_base.h"
30 #include "spritecache.h"
31 #include "core/random_func.hpp"
32 #include "company_base.h"
33 #include "core/backup_type.hpp"
34 #include "newgrf.h"
35 #include "zoom_func.h"
36 #include "framerate_type.h"
37 
38 #include "table/strings.h"
39 
40 #include "safeguards.h"
41 
42 static const uint16 _roadveh_images[] = {
43  0xCD4, 0xCDC, 0xCE4, 0xCEC, 0xCF4, 0xCFC, 0xD0C, 0xD14,
44  0xD24, 0xD1C, 0xD2C, 0xD04, 0xD1C, 0xD24, 0xD6C, 0xD74,
45  0xD7C, 0xC14, 0xC1C, 0xC24, 0xC2C, 0xC34, 0xC3C, 0xC4C,
46  0xC54, 0xC64, 0xC5C, 0xC6C, 0xC44, 0xC5C, 0xC64, 0xCAC,
47  0xCB4, 0xCBC, 0xD94, 0xD9C, 0xDA4, 0xDAC, 0xDB4, 0xDBC,
48  0xDCC, 0xDD4, 0xDE4, 0xDDC, 0xDEC, 0xDC4, 0xDDC, 0xDE4,
49  0xE2C, 0xE34, 0xE3C, 0xC14, 0xC1C, 0xC2C, 0xC3C, 0xC4C,
50  0xC5C, 0xC64, 0xC6C, 0xC74, 0xC84, 0xC94, 0xCA4
51 };
52 
53 static const uint16 _roadveh_full_adder[] = {
54  0, 88, 0, 0, 0, 0, 48, 48,
55  48, 48, 0, 0, 64, 64, 0, 16,
56  16, 0, 88, 0, 0, 0, 0, 48,
57  48, 48, 48, 0, 0, 64, 64, 0,
58  16, 16, 0, 88, 0, 0, 0, 0,
59  48, 48, 48, 48, 0, 0, 64, 64,
60  0, 16, 16, 0, 8, 8, 8, 8,
61  0, 0, 0, 8, 8, 8, 8
62 };
63 assert_compile(lengthof(_roadveh_images) == lengthof(_roadveh_full_adder));
64 
65 template <>
66 bool IsValidImageIndex<VEH_ROAD>(uint8 image_index)
67 {
68  return image_index < lengthof(_roadveh_images);
69 }
70 
71 static const Trackdir _road_reverse_table[DIAGDIR_END] = {
73 };
74 
79 bool RoadVehicle::IsBus() const
80 {
81  assert(this->IsFrontEngine());
83 }
84 
91 {
92  int reference_width = ROADVEHINFO_DEFAULT_VEHICLE_WIDTH;
93 
94  if (offset != nullptr) {
95  offset->x = ScaleGUITrad(reference_width) / 2;
96  offset->y = 0;
97  }
98  return ScaleGUITrad(this->gcache.cached_veh_length * reference_width / VEHICLE_LENGTH);
99 }
100 
101 static void GetRoadVehIcon(EngineID engine, EngineImageType image_type, VehicleSpriteSeq *result)
102 {
103  const Engine *e = Engine::Get(engine);
104  uint8 spritenum = e->u.road.image_index;
105 
106  if (is_custom_sprite(spritenum)) {
107  GetCustomVehicleIcon(engine, DIR_W, image_type, result);
108  if (result->IsValid()) return;
109 
110  spritenum = e->original_image_index;
111  }
112 
113  assert(IsValidImageIndex<VEH_ROAD>(spritenum));
114  result->Set(DIR_W + _roadveh_images[spritenum]);
115 }
116 
118 {
119  uint8 spritenum = this->spritenum;
120 
121  if (is_custom_sprite(spritenum)) {
122  GetCustomVehicleSprite(this, (Direction)(direction + 4 * IS_CUSTOM_SECONDHEAD_SPRITE(spritenum)), image_type, result);
123  if (result->IsValid()) return;
124 
125  spritenum = this->GetEngine()->original_image_index;
126  }
127 
128  assert(IsValidImageIndex<VEH_ROAD>(spritenum));
129  SpriteID sprite = direction + _roadveh_images[spritenum];
130 
131  if (this->cargo.StoredCount() >= this->cargo_cap / 2U) sprite += _roadveh_full_adder[spritenum];
132 
133  result->Set(sprite);
134 }
135 
145 void DrawRoadVehEngine(int left, int right, int preferred_x, int y, EngineID engine, PaletteID pal, EngineImageType image_type)
146 {
147  VehicleSpriteSeq seq;
148  GetRoadVehIcon(engine, image_type, &seq);
149 
150  Rect rect;
151  seq.GetBounds(&rect);
152  preferred_x = Clamp(preferred_x,
153  left - UnScaleGUI(rect.left),
154  right - UnScaleGUI(rect.right));
155 
156  seq.Draw(preferred_x, y, pal, pal == PALETTE_CRASH);
157 }
158 
168 void GetRoadVehSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type)
169 {
170  VehicleSpriteSeq seq;
171  GetRoadVehIcon(engine, image_type, &seq);
172 
173  Rect rect;
174  seq.GetBounds(&rect);
175 
176  width = UnScaleGUI(rect.right - rect.left + 1);
177  height = UnScaleGUI(rect.bottom - rect.top + 1);
178  xoffs = UnScaleGUI(rect.left);
179  yoffs = UnScaleGUI(rect.top);
180 }
181 
187 static uint GetRoadVehLength(const RoadVehicle *v)
188 {
189  const Engine *e = v->GetEngine();
190  uint length = VEHICLE_LENGTH;
191 
192  uint16 veh_len = CALLBACK_FAILED;
193  if (e->GetGRF() != nullptr && e->GetGRF()->grf_version >= 8) {
194  /* Use callback 36 */
195  veh_len = GetVehicleProperty(v, PROP_ROADVEH_SHORTEN_FACTOR, CALLBACK_FAILED);
196  if (veh_len != CALLBACK_FAILED && veh_len >= VEHICLE_LENGTH) ErrorUnknownCallbackResult(e->GetGRFID(), CBID_VEHICLE_LENGTH, veh_len);
197  } else {
198  /* Use callback 11 */
199  veh_len = GetVehicleCallback(CBID_VEHICLE_LENGTH, 0, 0, v->engine_type, v);
200  }
201  if (veh_len == CALLBACK_FAILED) veh_len = e->u.road.shorten_factor;
202  if (veh_len != 0) {
203  length -= Clamp(veh_len, 0, VEHICLE_LENGTH - 1);
204  }
205 
206  return length;
207 }
208 
215 void RoadVehUpdateCache(RoadVehicle *v, bool same_length)
216 {
217  assert(v->type == VEH_ROAD);
218  assert(v->IsFrontEngine());
219 
221 
223 
224  for (RoadVehicle *u = v; u != nullptr; u = u->Next()) {
225  /* Check the v->first cache. */
226  assert(u->First() == v);
227 
228  /* Update the 'first engine' */
229  u->gcache.first_engine = (v == u) ? INVALID_ENGINE : v->engine_type;
230 
231  /* Update the length of the vehicle. */
232  uint veh_len = GetRoadVehLength(u);
233  /* Verify length hasn't changed. */
234  if (same_length && veh_len != u->gcache.cached_veh_length) VehicleLengthChanged(u);
235 
236  u->gcache.cached_veh_length = veh_len;
237  v->gcache.cached_total_length += u->gcache.cached_veh_length;
238 
239  /* Update visual effect */
240  u->UpdateVisualEffect();
241 
242  /* Update cargo aging period. */
243  u->vcache.cached_cargo_age_period = GetVehicleProperty(u, PROP_ROADVEH_CARGO_AGE_PERIOD, EngInfo(u->engine_type)->cargo_age_period);
244  }
245 
246  uint max_speed = GetVehicleProperty(v, PROP_ROADVEH_SPEED, 0);
247  v->vcache.cached_max_speed = (max_speed != 0) ? max_speed * 4 : RoadVehInfo(v->engine_type)->max_speed;
248 }
249 
260 {
261  /* Check that the vehicle can drive on the road in question */
262  RoadType rt = e->u.road.roadtype;
263  const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
264  if (!HasTileAnyRoadType(tile, rti->powered_roadtypes)) return_cmd_error(STR_ERROR_DEPOT_WRONG_DEPOT_TYPE);
265 
266  if (flags & DC_EXEC) {
267  const RoadVehicleInfo *rvi = &e->u.road;
268 
269  RoadVehicle *v = new RoadVehicle();
270  *ret = v;
272  v->owner = _current_company;
273 
274  v->tile = tile;
275  int x = TileX(tile) * TILE_SIZE + TILE_SIZE / 2;
276  int y = TileY(tile) * TILE_SIZE + TILE_SIZE / 2;
277  v->x_pos = x;
278  v->y_pos = y;
279  v->z_pos = GetSlopePixelZ(x, y);
280 
281  v->state = RVSB_IN_DEPOT;
283 
284  v->spritenum = rvi->image_index;
286  v->cargo_cap = rvi->capacity;
287  v->refit_cap = 0;
288 
289  v->last_station_visited = INVALID_STATION;
290  v->last_loading_station = INVALID_STATION;
291  v->engine_type = e->index;
292  v->gcache.first_engine = INVALID_ENGINE; // needs to be set before first callback
293 
294  v->reliability = e->reliability;
296  v->max_age = e->GetLifeLengthInDays();
297  _new_vehicle_id = v->index;
298 
299  v->SetServiceInterval(Company::Get(v->owner)->settings.vehicle.servint_roadveh);
300 
302  v->build_year = _cur_year;
303 
304  v->sprite_seq.Set(SPR_IMG_QUERY);
306  v->SetFrontEngine();
307 
308  v->roadtype = rt;
311 
313  v->SetServiceIntervalIsPercent(Company::Get(_current_company)->settings.vehicle.servint_ispercent);
314 
317 
318  /* Call various callbacks after the whole consist has been constructed */
319  for (RoadVehicle *u = v; u != nullptr; u = u->Next()) {
320  u->cargo_cap = u->GetEngine()->DetermineCapacity(u);
321  u->refit_cap = 0;
323  u->InvalidateNewGRFCache();
324  }
326  /* Initialize cached values for realistic acceleration. */
328 
329  v->UpdatePosition();
330 
332  }
333 
334  return CommandCost();
335 }
336 
337 static FindDepotData FindClosestRoadDepot(const RoadVehicle *v, int max_distance)
338 {
339  if (IsRoadDepotTile(v->tile)) return FindDepotData(v->tile, 0);
340 
342  case VPF_NPF: return NPFRoadVehicleFindNearestDepot(v, max_distance);
343  case VPF_YAPF: return YapfRoadVehicleFindNearestDepot(v, max_distance);
344 
345  default: NOT_REACHED();
346  }
347 }
348 
349 bool RoadVehicle::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse)
350 {
351  FindDepotData rfdd = FindClosestRoadDepot(this, 0);
352  if (rfdd.best_length == UINT_MAX) return false;
353 
354  if (location != nullptr) *location = rfdd.tile;
355  if (destination != nullptr) *destination = GetDepotIndex(rfdd.tile);
356 
357  return true;
358 }
359 
369 CommandCost CmdTurnRoadVeh(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
370 {
372  if (v == nullptr) return CMD_ERROR;
373 
374  if (!v->IsPrimaryVehicle()) return CMD_ERROR;
375 
376  CommandCost ret = CheckOwnership(v->owner);
377  if (ret.Failed()) return ret;
378 
379  if ((v->vehstatus & VS_STOPPED) ||
380  (v->vehstatus & VS_CRASHED) ||
381  v->breakdown_ctr != 0 ||
382  v->overtaking != 0 ||
383  v->state == RVSB_WORMHOLE ||
384  v->IsInDepot() ||
385  v->current_order.IsType(OT_LOADING)) {
386  return CMD_ERROR;
387  }
388 
390 
392 
393  if (flags & DC_EXEC) v->reverse_ctr = 180;
394 
395  return CommandCost();
396 }
397 
398 
400 {
401  for (RoadVehicle *v = this; v != nullptr; v = v->Next()) {
402  v->colourmap = PAL_NONE;
403  v->UpdateViewport(true, false);
404  }
405  this->CargoChanged();
406 }
407 
409 {
410  static const int8 _delta_xy_table[8][10] = {
411  /* y_extent, x_extent, y_offs, x_offs, y_bb_offs, x_bb_offs, y_extent_shorten, x_extent_shorten, y_bb_offs_shorten, x_bb_offs_shorten */
412  {3, 3, -1, -1, 0, 0, -1, -1, -1, -1}, // N
413  {3, 7, -1, -3, 0, -1, 0, -1, 0, 0}, // NE
414  {3, 3, -1, -1, 0, 0, 1, -1, 1, -1}, // E
415  {7, 3, -3, -1, -1, 0, 0, 0, 1, 0}, // SE
416  {3, 3, -1, -1, 0, 0, 1, 1, 1, 1}, // S
417  {3, 7, -1, -3, 0, -1, 0, 0, 0, 1}, // SW
418  {3, 3, -1, -1, 0, 0, -1, 1, -1, 1}, // W
419  {7, 3, -3, -1, -1, 0, -1, 0, 0, 0}, // NW
420  };
421 
422  int shorten = VEHICLE_LENGTH - this->gcache.cached_veh_length;
423  if (!IsDiagonalDirection(this->direction)) shorten >>= 1;
424 
425  const int8 *bb = _delta_xy_table[this->direction];
426  this->x_bb_offs = bb[5] + bb[9] * shorten;
427  this->y_bb_offs = bb[4] + bb[8] * shorten;;
428  this->x_offs = bb[3];
429  this->y_offs = bb[2];
430  this->x_extent = bb[1] + bb[7] * shorten;
431  this->y_extent = bb[0] + bb[6] * shorten;
432  this->z_extent = 6;
433 }
434 
440 {
441  int max_speed = this->gcache.cached_max_track_speed;
442 
443  /* Limit speed to 50% while reversing, 75% in curves. */
444  for (const RoadVehicle *u = this; u != nullptr; u = u->Next()) {
445  if (_settings_game.vehicle.roadveh_acceleration_model == AM_REALISTIC) {
447  max_speed = this->gcache.cached_max_track_speed / 2;
448  break;
449  } else if ((u->direction & 1) == 0) {
450  max_speed = this->gcache.cached_max_track_speed * 3 / 4;
451  }
452  }
453 
454  /* Vehicle is on the middle part of a bridge. */
455  if (u->state == RVSB_WORMHOLE && !(u->vehstatus & VS_HIDDEN)) {
456  max_speed = min(max_speed, GetBridgeSpec(GetBridgeType(u->tile))->speed * 2);
457  }
458  }
459 
460  return min(max_speed, this->current_order.GetMaxSpeed() * 2);
461 }
462 
468 {
469  RoadVehicle *first = v->First();
470  Vehicle *u = v;
471  for (; v->Next() != nullptr; v = v->Next()) u = v;
472  u->SetNext(nullptr);
473  v->last_station_visited = first->last_station_visited; // for PreDestructor
474 
475  /* Only leave the road stop when we're really gone. */
476  if (IsInsideMM(v->state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END)) RoadStop::GetByTile(v->tile, GetRoadStopType(v->tile))->Leave(v);
477 
478  delete v;
479 }
480 
481 static void RoadVehSetRandomDirection(RoadVehicle *v)
482 {
483  static const DirDiff delta[] = {
485  };
486 
487  do {
488  uint32 r = Random();
489 
490  v->direction = ChangeDir(v->direction, delta[r & 3]);
491  v->UpdateViewport(true, true);
492  } while ((v = v->Next()) != nullptr);
493 }
494 
501 {
502  v->crashed_ctr++;
503  if (v->crashed_ctr == 2) {
505  } else if (v->crashed_ctr <= 45) {
506  if ((v->tick_counter & 7) == 0) RoadVehSetRandomDirection(v);
507  } else if (v->crashed_ctr >= 2220 && !(v->tick_counter & 0x1F)) {
508  bool ret = v->Next() != nullptr;
510  return ret;
511  }
512 
513  return true;
514 }
515 
523 {
524  const Vehicle *u = (Vehicle*)data;
525 
526  return (v->type == VEH_TRAIN &&
527  abs(v->z_pos - u->z_pos) <= 6 &&
528  abs(v->x_pos - u->x_pos) <= 4 &&
529  abs(v->y_pos - u->y_pos) <= 4) ? v : nullptr;
530 }
531 
532 uint RoadVehicle::Crash(bool flooded)
533 {
534  uint pass = this->GroundVehicleBase::Crash(flooded);
535  if (this->IsFrontEngine()) {
536  pass += 1; // driver
537 
538  /* If we're in a drive through road stop we ought to leave it */
539  if (IsInsideMM(this->state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END)) {
540  RoadStop::GetByTile(this->tile, GetRoadStopType(this->tile))->Leave(this);
541  }
542  }
543  this->crashed_ctr = flooded ? 2000 : 1; // max 2220, disappear pretty fast when flooded
544  return pass;
545 }
546 
547 static void RoadVehCrash(RoadVehicle *v)
548 {
549  uint pass = v->Crash();
550 
551  AI::NewEvent(v->owner, new ScriptEventVehicleCrashed(v->index, v->tile, ScriptEventVehicleCrashed::CRASH_RV_LEVEL_CROSSING));
552  Game::NewEvent(new ScriptEventVehicleCrashed(v->index, v->tile, ScriptEventVehicleCrashed::CRASH_RV_LEVEL_CROSSING));
553 
554  SetDParam(0, pass);
556  (pass == 1) ?
557  STR_NEWS_ROAD_VEHICLE_CRASH_DRIVER : STR_NEWS_ROAD_VEHICLE_CRASH,
558  NT_ACCIDENT,
559  v->index
560  );
561 
562  ModifyStationRatingAround(v->tile, v->owner, -160, 22);
563  if (_settings_client.sound.disaster) SndPlayVehicleFx(SND_12_EXPLOSION, v);
564 }
565 
566 static bool RoadVehCheckTrainCrash(RoadVehicle *v)
567 {
568  for (RoadVehicle *u = v; u != nullptr; u = u->Next()) {
569  if (u->state == RVSB_WORMHOLE) continue;
570 
571  TileIndex tile = u->tile;
572 
573  if (!IsLevelCrossingTile(tile)) continue;
574 
576  RoadVehCrash(v);
577  return true;
578  }
579  }
580 
581  return false;
582 }
583 
585 {
586  if (station == this->last_station_visited) this->last_station_visited = INVALID_STATION;
587 
588  const Station *st = Station::Get(station);
589  if (!CanVehicleUseStation(this, st)) {
590  /* There is no stop left at the station, so don't even TRY to go there */
591  this->IncrementRealOrderIndex();
592  return 0;
593  }
594 
595  return st->xy;
596 }
597 
598 static void StartRoadVehSound(const RoadVehicle *v)
599 {
600  if (!PlayVehicleSound(v, VSE_START)) {
601  SoundID s = RoadVehInfo(v->engine_type)->sfx;
602  if (s == SND_19_BUS_START_PULL_AWAY && (v->tick_counter & 3) == 0) {
603  s = SND_1A_BUS_START_PULL_AWAY_WITH_HORN;
604  }
605  SndPlayVehicleFx(s, v);
606  }
607 }
608 
610  int x;
611  int y;
612  const Vehicle *veh;
613  Vehicle *best;
614  uint best_diff;
615  Direction dir;
616 };
617 
618 static Vehicle *EnumCheckRoadVehClose(Vehicle *v, void *data)
619 {
620  static const int8 dist_x[] = { -4, -8, -4, -1, 4, 8, 4, 1 };
621  static const int8 dist_y[] = { -4, -1, 4, 8, 4, 1, -4, -8 };
622 
623  RoadVehFindData *rvf = (RoadVehFindData*)data;
624 
625  short x_diff = v->x_pos - rvf->x;
626  short y_diff = v->y_pos - rvf->y;
627 
628  if (v->type == VEH_ROAD &&
629  !v->IsInDepot() &&
630  abs(v->z_pos - rvf->veh->z_pos) < 6 &&
631  v->direction == rvf->dir &&
632  rvf->veh->First() != v->First() &&
633  (dist_x[v->direction] >= 0 || (x_diff > dist_x[v->direction] && x_diff <= 0)) &&
634  (dist_x[v->direction] <= 0 || (x_diff < dist_x[v->direction] && x_diff >= 0)) &&
635  (dist_y[v->direction] >= 0 || (y_diff > dist_y[v->direction] && y_diff <= 0)) &&
636  (dist_y[v->direction] <= 0 || (y_diff < dist_y[v->direction] && y_diff >= 0))) {
637  uint diff = abs(x_diff) + abs(y_diff);
638 
639  if (diff < rvf->best_diff || (diff == rvf->best_diff && v->index < rvf->best->index)) {
640  rvf->best = v;
641  rvf->best_diff = diff;
642  }
643  }
644 
645  return nullptr;
646 }
647 
648 static RoadVehicle *RoadVehFindCloseTo(RoadVehicle *v, int x, int y, Direction dir, bool update_blocked_ctr = true)
649 {
650  RoadVehFindData rvf;
651  RoadVehicle *front = v->First();
652 
653  if (front->reverse_ctr != 0) return nullptr;
654 
655  rvf.x = x;
656  rvf.y = y;
657  rvf.dir = dir;
658  rvf.veh = v;
659  rvf.best_diff = UINT_MAX;
660 
661  if (front->state == RVSB_WORMHOLE) {
662  FindVehicleOnPos(v->tile, &rvf, EnumCheckRoadVehClose);
663  FindVehicleOnPos(GetOtherTunnelBridgeEnd(v->tile), &rvf, EnumCheckRoadVehClose);
664  } else {
665  FindVehicleOnPosXY(x, y, &rvf, EnumCheckRoadVehClose);
666  }
667 
668  /* This code protects a roadvehicle from being blocked for ever
669  * If more than 1480 / 74 days a road vehicle is blocked, it will
670  * drive just through it. The ultimate backup-code of TTD.
671  * It can be disabled. */
672  if (rvf.best_diff == UINT_MAX) {
673  front->blocked_ctr = 0;
674  return nullptr;
675  }
676 
677  if (update_blocked_ctr && ++front->blocked_ctr > 1480) return nullptr;
678 
679  return RoadVehicle::From(rvf.best);
680 }
681 
687 static void RoadVehArrivesAt(const RoadVehicle *v, Station *st)
688 {
689  if (v->IsBus()) {
690  /* Check if station was ever visited before */
691  if (!(st->had_vehicle_of_type & HVOT_BUS)) {
692  st->had_vehicle_of_type |= HVOT_BUS;
693  SetDParam(0, st->index);
695  RoadTypeIsRoad(v->roadtype) ? STR_NEWS_FIRST_BUS_ARRIVAL : STR_NEWS_FIRST_PASSENGER_TRAM_ARRIVAL,
697  v->index,
698  st->index
699  );
700  AI::NewEvent(v->owner, new ScriptEventStationFirstVehicle(st->index, v->index));
701  Game::NewEvent(new ScriptEventStationFirstVehicle(st->index, v->index));
702  }
703  } else {
704  /* Check if station was ever visited before */
705  if (!(st->had_vehicle_of_type & HVOT_TRUCK)) {
706  st->had_vehicle_of_type |= HVOT_TRUCK;
707  SetDParam(0, st->index);
709  RoadTypeIsRoad(v->roadtype) ? STR_NEWS_FIRST_TRUCK_ARRIVAL : STR_NEWS_FIRST_CARGO_TRAM_ARRIVAL,
711  v->index,
712  st->index
713  );
714  AI::NewEvent(v->owner, new ScriptEventStationFirstVehicle(st->index, v->index));
715  Game::NewEvent(new ScriptEventStationFirstVehicle(st->index, v->index));
716  }
717  }
718 }
719 
728 {
730  default: NOT_REACHED();
731  case AM_ORIGINAL:
732  return this->DoUpdateSpeed(this->overtaking != 0 ? 512 : 256, 0, this->GetCurrentMaxSpeed());
733 
734  case AM_REALISTIC:
735  return this->DoUpdateSpeed(this->GetAcceleration() + (this->overtaking != 0 ? 256 : 0), this->GetAccelerationStatus() == AS_BRAKE ? 0 : 4, this->GetCurrentMaxSpeed());
736  }
737 }
738 
739 static Direction RoadVehGetNewDirection(const RoadVehicle *v, int x, int y)
740 {
741  static const Direction _roadveh_new_dir[] = {
744  DIR_E , DIR_SE, DIR_S
745  };
746 
747  x = x - v->x_pos + 1;
748  y = y - v->y_pos + 1;
749 
750  if ((uint)x > 2 || (uint)y > 2) return v->direction;
751  return _roadveh_new_dir[y * 4 + x];
752 }
753 
754 static Direction RoadVehGetSlidingDirection(const RoadVehicle *v, int x, int y)
755 {
756  Direction new_dir = RoadVehGetNewDirection(v, x, y);
757  Direction old_dir = v->direction;
758  DirDiff delta;
759 
760  if (new_dir == old_dir) return old_dir;
761  delta = (DirDifference(new_dir, old_dir) > DIRDIFF_REVERSE ? DIRDIFF_45LEFT : DIRDIFF_45RIGHT);
762  return ChangeDir(old_dir, delta);
763 }
764 
765 struct OvertakeData {
766  const RoadVehicle *u;
767  const RoadVehicle *v;
768  TileIndex tile;
769  Trackdir trackdir;
770 };
771 
772 static Vehicle *EnumFindVehBlockingOvertake(Vehicle *v, void *data)
773 {
774  const OvertakeData *od = (OvertakeData*)data;
775 
776  return (v->type == VEH_ROAD && v->First() == v && v != od->u && v != od->v) ? v : nullptr;
777 }
778 
786 {
787  if (!HasTileAnyRoadType(od->tile, od->v->compatible_roadtypes)) return true;
788  TrackStatus ts = GetTileTrackStatus(od->tile, TRANSPORT_ROAD, GetRoadTramType(od->v->roadtype));
789  TrackdirBits trackdirbits = TrackStatusToTrackdirBits(ts);
790  TrackdirBits red_signals = TrackStatusToRedSignals(ts); // barred level crossing
791  TrackBits trackbits = TrackdirBitsToTrackBits(trackdirbits);
792 
793  /* Track does not continue along overtaking direction || track has junction || levelcrossing is barred */
794  if (!HasBit(trackdirbits, od->trackdir) || (trackbits & ~TRACK_BIT_CROSS) || (red_signals != TRACKDIR_BIT_NONE)) return true;
795 
796  /* Are there more vehicles on the tile except the two vehicles involved in overtaking */
797  return HasVehicleOnPos(od->tile, od, EnumFindVehBlockingOvertake);
798 }
799 
800 static void RoadVehCheckOvertake(RoadVehicle *v, RoadVehicle *u)
801 {
802  OvertakeData od;
803 
804  od.v = v;
805  od.u = u;
806 
807  /* Trams can't overtake other trams */
808  if (RoadTypeIsTram(v->roadtype)) return;
809 
810  /* Don't overtake in stations */
811  if (IsTileType(v->tile, MP_STATION) || IsTileType(u->tile, MP_STATION)) return;
812 
813  /* For now, articulated road vehicles can't overtake anything. */
814  if (v->HasArticulatedPart()) return;
815 
816  /* Vehicles are not driving in same direction || direction is not a diagonal direction */
817  if (v->direction != u->direction || !(v->direction & 1)) return;
818 
819  /* Check if vehicle is in a road stop, depot, tunnel or bridge or not on a straight road */
821 
822  /* Can't overtake a vehicle that is moving faster than us. If the vehicle in front is
823  * accelerating, take the maximum speed for the comparison, else the current speed.
824  * Original acceleration always accelerates, so always use the maximum speed. */
825  int u_speed = (_settings_game.vehicle.roadveh_acceleration_model == AM_ORIGINAL || u->GetAcceleration() > 0) ? u->GetCurrentMaxSpeed() : u->cur_speed;
826  if (u_speed >= v->GetCurrentMaxSpeed() &&
827  !(u->vehstatus & VS_STOPPED) &&
828  u->cur_speed != 0) {
829  return;
830  }
831 
832  od.trackdir = DiagDirToDiagTrackdir(DirToDiagDir(v->direction));
833 
834  /* Are the current and the next tile suitable for overtaking?
835  * - Does the track continue along od.trackdir
836  * - No junctions
837  * - No barred levelcrossing
838  * - No other vehicles in the way
839  */
840  od.tile = v->tile;
841  if (CheckRoadBlockedForOvertaking(&od)) return;
842 
843  od.tile = v->tile + TileOffsByDiagDir(DirToDiagDir(v->direction));
844  if (CheckRoadBlockedForOvertaking(&od)) return;
845 
846  /* When the vehicle in front of us is stopped we may only take
847  * half the time to pass it than when the vehicle is moving. */
848  v->overtaking_ctr = (od.u->cur_speed == 0 || (od.u->vehstatus & VS_STOPPED)) ? RV_OVERTAKE_TIMEOUT / 2 : 0;
850 }
851 
852 static void RoadZPosAffectSpeed(RoadVehicle *v, int old_z)
853 {
854  if (old_z == v->z_pos || _settings_game.vehicle.roadveh_acceleration_model != AM_ORIGINAL) return;
855 
856  if (old_z < v->z_pos) {
857  v->cur_speed = v->cur_speed * 232 / 256; // slow down by ~10%
858  } else {
859  uint16 spd = v->cur_speed + 2;
860  if (spd <= v->gcache.cached_max_track_speed) v->cur_speed = spd;
861  }
862 }
863 
864 static int PickRandomBit(uint bits)
865 {
866  uint i;
867  uint num = RandomRange(CountBits(bits));
868 
869  for (i = 0; !(bits & 1) || (int)--num >= 0; bits >>= 1, i++) {}
870  return i;
871 }
872 
882 {
883 #define return_track(x) { best_track = (Trackdir)x; goto found_best_track; }
884 
885  TileIndex desttile;
886  Trackdir best_track;
887  bool path_found = true;
888 
889  TrackStatus ts = GetTileTrackStatus(tile, TRANSPORT_ROAD, GetRoadTramType(v->roadtype));
890  TrackdirBits red_signals = TrackStatusToRedSignals(ts); // crossing
891  TrackdirBits trackdirs = TrackStatusToTrackdirBits(ts);
892 
893  if (IsTileType(tile, MP_ROAD)) {
894  if (IsRoadDepot(tile) && (!IsTileOwner(tile, v->owner) || GetRoadDepotDirection(tile) == enterdir)) {
895  /* Road depot owned by another company or with the wrong orientation */
896  trackdirs = TRACKDIR_BIT_NONE;
897  }
898  } else if (IsTileType(tile, MP_STATION) && IsStandardRoadStopTile(tile)) {
899  /* Standard road stop (drive-through stops are treated as normal road) */
900 
901  if (!IsTileOwner(tile, v->owner) || GetRoadStopDir(tile) == enterdir || v->HasArticulatedPart()) {
902  /* different station owner or wrong orientation or the vehicle has articulated parts */
903  trackdirs = TRACKDIR_BIT_NONE;
904  } else {
905  /* Our station */
906  RoadStopType rstype = v->IsBus() ? ROADSTOP_BUS : ROADSTOP_TRUCK;
907 
908  if (GetRoadStopType(tile) != rstype) {
909  /* Wrong station type */
910  trackdirs = TRACKDIR_BIT_NONE;
911  } else {
912  /* Proper station type, check if there is free loading bay */
914  !RoadStop::GetByTile(tile, rstype)->HasFreeBay()) {
915  /* Station is full and RV queuing is off */
916  trackdirs = TRACKDIR_BIT_NONE;
917  }
918  }
919  }
920  }
921  /* The above lookups should be moved to GetTileTrackStatus in the
922  * future, but that requires more changes to the pathfinder and other
923  * stuff, probably even more arguments to GTTS.
924  */
925 
926  /* Remove tracks unreachable from the enter dir */
927  trackdirs &= DiagdirReachesTrackdirs(enterdir);
928  if (trackdirs == TRACKDIR_BIT_NONE) {
929  /* If vehicle expected a path, it no longer exists, so invalidate it. */
930  if (!v->path.empty()) v->path.clear();
931  /* No reachable tracks, so we'll reverse */
932  return_track(_road_reverse_table[enterdir]);
933  }
934 
935  if (v->reverse_ctr != 0) {
936  bool reverse = true;
937  if (RoadTypeIsTram(v->roadtype)) {
938  /* Trams may only reverse on a tile if it contains at least the straight
939  * trackbits or when it is a valid turning tile (i.e. one roadbit) */
940  RoadBits rb = GetAnyRoadBits(tile, RTT_TRAM);
941  RoadBits straight = AxisToRoadBits(DiagDirToAxis(enterdir));
942  reverse = ((rb & straight) == straight) ||
943  (rb == DiagDirToRoadBits(enterdir));
944  }
945  if (reverse) {
946  v->reverse_ctr = 0;
947  if (v->tile != tile) {
948  return_track(_road_reverse_table[enterdir]);
949  }
950  }
951  }
952 
953  desttile = v->dest_tile;
954  if (desttile == 0) {
955  /* We've got no destination, pick a random track */
956  return_track(PickRandomBit(trackdirs));
957  }
958 
959  /* Only one track to choose between? */
960  if (KillFirstBit(trackdirs) == TRACKDIR_BIT_NONE) {
961  if (!v->path.empty() && v->path.tile.front() == tile) {
962  /* Vehicle expected a choice here, invalidate its path. */
963  v->path.clear();
964  }
965  return_track(FindFirstBit2x64(trackdirs));
966  }
967 
968  /* Attempt to follow cached path. */
969  if (!v->path.empty()) {
970  if (v->path.tile.front() != tile) {
971  /* Vehicle didn't expect a choice here, invalidate its path. */
972  v->path.clear();
973  } else {
974  Trackdir trackdir = v->path.td.front();
975 
976  if (HasBit(trackdirs, trackdir)) {
977  v->path.td.pop_front();
978  v->path.tile.pop_front();
979  return_track(trackdir);
980  }
981 
982  /* Vehicle expected a choice which is no longer available. */
983  v->path.clear();
984  }
985  }
986 
988  case VPF_NPF: best_track = NPFRoadVehicleChooseTrack(v, tile, enterdir, path_found); break;
989  case VPF_YAPF: best_track = YapfRoadVehicleChooseTrack(v, tile, enterdir, trackdirs, path_found, v->path); break;
990 
991  default: NOT_REACHED();
992  }
993  v->HandlePathfindingResult(path_found);
994 
995 found_best_track:;
996 
997  if (HasBit(red_signals, best_track)) return INVALID_TRACKDIR;
998 
999  return best_track;
1000 }
1001 
1003  byte x, y;
1004 };
1005 
1006 #include "table/roadveh_movement.h"
1007 
1008 static bool RoadVehLeaveDepot(RoadVehicle *v, bool first)
1009 {
1010  /* Don't leave unless v and following wagons are in the depot. */
1011  for (const RoadVehicle *u = v; u != nullptr; u = u->Next()) {
1012  if (u->state != RVSB_IN_DEPOT || u->tile != v->tile) return false;
1013  }
1014 
1016  v->direction = DiagDirToDir(dir);
1017 
1018  Trackdir tdir = DiagDirToDiagTrackdir(dir);
1019  const RoadDriveEntry *rdp = _road_drive_data[GetRoadTramType(v->roadtype)][(_settings_game.vehicle.road_side << RVS_DRIVE_SIDE) + tdir];
1020 
1021  int x = TileX(v->tile) * TILE_SIZE + (rdp[RVC_DEPOT_START_FRAME].x & 0xF);
1022  int y = TileY(v->tile) * TILE_SIZE + (rdp[RVC_DEPOT_START_FRAME].y & 0xF);
1023 
1024  if (first) {
1025  /* We are leaving a depot, but have to go to the exact same one; re-enter */
1026  if (v->current_order.IsType(OT_GOTO_DEPOT) && v->tile == v->dest_tile) {
1027  VehicleEnterDepot(v);
1028  return true;
1029  }
1030 
1031  if (RoadVehFindCloseTo(v, x, y, v->direction, false) != nullptr) return true;
1032 
1034 
1035  StartRoadVehSound(v);
1036 
1037  /* Vehicle is about to leave a depot */
1038  v->cur_speed = 0;
1039  }
1040 
1041  v->vehstatus &= ~VS_HIDDEN;
1042  v->state = tdir;
1043  v->frame = RVC_DEPOT_START_FRAME;
1044 
1045  v->x_pos = x;
1046  v->y_pos = y;
1047  v->UpdatePosition();
1048  v->UpdateInclination(true, true);
1049 
1051 
1052  return true;
1053 }
1054 
1055 static Trackdir FollowPreviousRoadVehicle(const RoadVehicle *v, const RoadVehicle *prev, TileIndex tile, DiagDirection entry_dir, bool already_reversed)
1056 {
1057  if (prev->tile == v->tile && !already_reversed) {
1058  /* If the previous vehicle is on the same tile as this vehicle is
1059  * then it must have reversed. */
1060  return _road_reverse_table[entry_dir];
1061  }
1062 
1063  byte prev_state = prev->state;
1064  Trackdir dir;
1065 
1066  if (prev_state == RVSB_WORMHOLE || prev_state == RVSB_IN_DEPOT) {
1067  DiagDirection diag_dir = INVALID_DIAGDIR;
1068 
1069  if (IsTileType(tile, MP_TUNNELBRIDGE)) {
1070  diag_dir = GetTunnelBridgeDirection(tile);
1071  } else if (IsRoadDepotTile(tile)) {
1072  diag_dir = ReverseDiagDir(GetRoadDepotDirection(tile));
1073  }
1074 
1075  if (diag_dir == INVALID_DIAGDIR) return INVALID_TRACKDIR;
1076  dir = DiagDirToDiagTrackdir(diag_dir);
1077  } else {
1078  if (already_reversed && prev->tile != tile) {
1079  /*
1080  * The vehicle has reversed, but did not go straight back.
1081  * It immediately turn onto another tile. This means that
1082  * the roadstate of the previous vehicle cannot be used
1083  * as the direction we have to go with this vehicle.
1084  *
1085  * Next table is build in the following way:
1086  * - first row for when the vehicle in front went to the northern or
1087  * western tile, second for southern and eastern.
1088  * - columns represent the entry direction.
1089  * - cell values are determined by the Trackdir one has to take from
1090  * the entry dir (column) to the tile in north or south by only
1091  * going over the trackdirs used for turning 90 degrees, i.e.
1092  * TRACKDIR_{UPPER,RIGHT,LOWER,LEFT}_{N,E,S,W}.
1093  */
1094  static const Trackdir reversed_turn_lookup[2][DIAGDIR_END] = {
1097  dir = reversed_turn_lookup[prev->tile < tile ? 0 : 1][ReverseDiagDir(entry_dir)];
1098  } else if (HasBit(prev_state, RVS_IN_DT_ROAD_STOP)) {
1099  dir = (Trackdir)(prev_state & RVSB_ROAD_STOP_TRACKDIR_MASK);
1100  } else if (prev_state < TRACKDIR_END) {
1101  dir = (Trackdir)prev_state;
1102  } else {
1103  return INVALID_TRACKDIR;
1104  }
1105  }
1106 
1107  /* Do some sanity checking. */
1108  static const RoadBits required_roadbits[] = {
1110  ROAD_NW | ROAD_SW, ROAD_NE | ROAD_SE, ROAD_X, ROAD_Y
1111  };
1112  RoadBits required = required_roadbits[dir & 0x07];
1113 
1114  if ((required & GetAnyRoadBits(tile, GetRoadTramType(v->roadtype), true)) == ROAD_NONE) {
1115  dir = INVALID_TRACKDIR;
1116  }
1117 
1118  return dir;
1119 }
1120 
1130 {
1131  /* The 'current' company is not necessarily the owner of the vehicle. */
1132  Backup<CompanyID> cur_company(_current_company, c, FILE_LINE);
1133 
1134  CommandCost ret = DoCommand(t, rt << 4 | r, 0, DC_NO_WATER, CMD_BUILD_ROAD);
1135 
1136  cur_company.Restore();
1137  return ret.Succeeded();
1138 }
1139 
1140 bool IndividualRoadVehicleController(RoadVehicle *v, const RoadVehicle *prev)
1141 {
1142  if (v->overtaking != 0) {
1143  if (IsTileType(v->tile, MP_STATION)) {
1144  /* Force us to be not overtaking! */
1145  v->overtaking = 0;
1146  } else if (++v->overtaking_ctr >= RV_OVERTAKE_TIMEOUT) {
1147  /* If overtaking just aborts at a random moment, we can have a out-of-bound problem,
1148  * if the vehicle started a corner. To protect that, only allow an abort of
1149  * overtake if we are on straight roads */
1151  v->overtaking = 0;
1152  }
1153  }
1154  }
1155 
1156  /* If this vehicle is in a depot and we've reached this point it must be
1157  * one of the articulated parts. It will stay in the depot until activated
1158  * by the previous vehicle in the chain when it gets to the right place. */
1159  if (v->IsInDepot()) return true;
1160 
1161  if (v->state == RVSB_WORMHOLE) {
1162  /* Vehicle is entering a depot or is on a bridge or in a tunnel */
1164 
1165  if (v->IsFrontEngine()) {
1166  const Vehicle *u = RoadVehFindCloseTo(v, gp.x, gp.y, v->direction);
1167  if (u != nullptr) {
1168  v->cur_speed = u->First()->cur_speed;
1169  return false;
1170  }
1171  }
1172 
1174  /* Vehicle has just entered a bridge or tunnel */
1175  v->x_pos = gp.x;
1176  v->y_pos = gp.y;
1177  v->UpdatePosition();
1178  v->UpdateInclination(true, true);
1179  return true;
1180  }
1181 
1182  v->x_pos = gp.x;
1183  v->y_pos = gp.y;
1184  v->UpdatePosition();
1185  if ((v->vehstatus & VS_HIDDEN) == 0) v->Vehicle::UpdateViewport(true);
1186  return true;
1187  }
1188 
1189  /* Get move position data for next frame.
1190  * For a drive-through road stop use 'straight road' move data.
1191  * In this case v->state is masked to give the road stop entry direction. */
1192  RoadDriveEntry rd = _road_drive_data[GetRoadTramType(v->roadtype)][(
1194  (_settings_game.vehicle.road_side << RVS_DRIVE_SIDE)) ^ v->overtaking][v->frame + 1];
1195 
1196  if (rd.x & RDE_NEXT_TILE) {
1197  TileIndex tile = v->tile + TileOffsByDiagDir((DiagDirection)(rd.x & 3));
1198  Trackdir dir;
1199 
1200  if (v->IsFrontEngine()) {
1201  /* If this is the front engine, look for the right path. */
1202  if (HasTileAnyRoadType(tile, v->compatible_roadtypes)) {
1203  dir = RoadFindPathToDest(v, tile, (DiagDirection)(rd.x & 3));
1204  } else {
1205  dir = _road_reverse_table[(DiagDirection)(rd.x & 3)];
1206  }
1207  } else {
1208  dir = FollowPreviousRoadVehicle(v, prev, tile, (DiagDirection)(rd.x & 3), false);
1209  }
1210 
1211  if (dir == INVALID_TRACKDIR) {
1212  if (!v->IsFrontEngine()) error("Disconnecting road vehicle.");
1213  v->cur_speed = 0;
1214  return false;
1215  }
1216 
1217 again:
1218  uint start_frame = RVC_DEFAULT_START_FRAME;
1219  if (IsReversingRoadTrackdir(dir)) {
1220  /* When turning around we can't be overtaking. */
1221  v->overtaking = 0;
1222 
1223  /* Turning around */
1224  if (RoadTypeIsTram(v->roadtype)) {
1225  /* Determine the road bits the tram needs to be able to turn around
1226  * using the 'big' corner loop. */
1227  RoadBits needed;
1228  switch (dir) {
1229  default: NOT_REACHED();
1230  case TRACKDIR_RVREV_NE: needed = ROAD_SW; break;
1231  case TRACKDIR_RVREV_SE: needed = ROAD_NW; break;
1232  case TRACKDIR_RVREV_SW: needed = ROAD_NE; break;
1233  case TRACKDIR_RVREV_NW: needed = ROAD_SE; break;
1234  }
1235  if ((v->Previous() != nullptr && v->Previous()->tile == tile) ||
1236  (v->IsFrontEngine() && IsNormalRoadTile(tile) && !HasRoadWorks(tile) &&
1238  (needed & GetRoadBits(tile, RTT_TRAM)) != ROAD_NONE)) {
1239  /*
1240  * Taking the 'big' corner for trams only happens when:
1241  * - The previous vehicle in this (articulated) tram chain is
1242  * already on the 'next' tile, we just follow them regardless of
1243  * anything. When it is NOT on the 'next' tile, the tram started
1244  * doing a reversing turn when the piece of tram track on the next
1245  * tile did not exist yet. Do not use the big tram loop as that is
1246  * going to cause the tram to split up.
1247  * - Or the front of the tram can drive over the next tile.
1248  */
1249  } else if (!v->IsFrontEngine() || !CanBuildTramTrackOnTile(v->owner, tile, v->roadtype, needed) || ((~needed & GetAnyRoadBits(v->tile, RTT_TRAM, false)) == ROAD_NONE)) {
1250  /*
1251  * Taking the 'small' corner for trams only happens when:
1252  * - We are not the from vehicle of an articulated tram.
1253  * - Or when the company cannot build on the next tile.
1254  *
1255  * The 'small' corner means that the vehicle is on the end of a
1256  * tram track and needs to start turning there. To do this properly
1257  * the tram needs to start at an offset in the tram turning 'code'
1258  * for 'big' corners. It furthermore does not go to the next tile,
1259  * so that needs to be fixed too.
1260  */
1261  tile = v->tile;
1262  start_frame = RVC_TURN_AROUND_START_FRAME_SHORT_TRAM;
1263  } else {
1264  /* The company can build on the next tile, so wait till (s)he does. */
1265  v->cur_speed = 0;
1266  return false;
1267  }
1268  } else if (IsNormalRoadTile(v->tile) && GetDisallowedRoadDirections(v->tile) != DRD_NONE) {
1269  v->cur_speed = 0;
1270  return false;
1271  } else {
1272  tile = v->tile;
1273  }
1274  }
1275 
1276  /* Get position data for first frame on the new tile */
1277  const RoadDriveEntry *rdp = _road_drive_data[GetRoadTramType(v->roadtype)][(dir + (_settings_game.vehicle.road_side << RVS_DRIVE_SIDE)) ^ v->overtaking];
1278 
1279  int x = TileX(tile) * TILE_SIZE + rdp[start_frame].x;
1280  int y = TileY(tile) * TILE_SIZE + rdp[start_frame].y;
1281 
1282  Direction new_dir = RoadVehGetSlidingDirection(v, x, y);
1283  if (v->IsFrontEngine()) {
1284  Vehicle *u = RoadVehFindCloseTo(v, x, y, new_dir);
1285  if (u != nullptr) {
1286  v->cur_speed = u->First()->cur_speed;
1287  return false;
1288  }
1289  }
1290 
1291  uint32 r = VehicleEnterTile(v, tile, x, y);
1292  if (HasBit(r, VETS_CANNOT_ENTER)) {
1293  if (!IsTileType(tile, MP_TUNNELBRIDGE)) {
1294  v->cur_speed = 0;
1295  return false;
1296  }
1297  /* Try an about turn to re-enter the previous tile */
1298  dir = _road_reverse_table[rd.x & 3];
1299  goto again;
1300  }
1301 
1302  if (IsInsideMM(v->state, RVSB_IN_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) && IsTileType(v->tile, MP_STATION)) {
1303  if (IsReversingRoadTrackdir(dir) && IsInsideMM(v->state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END)) {
1304  /* New direction is trying to turn vehicle around.
1305  * We can't turn at the exit of a road stop so wait.*/
1306  v->cur_speed = 0;
1307  return false;
1308  }
1309 
1310  /* If we are a drive through road stop and the next tile is of
1311  * the same road stop and the next tile isn't this one (i.e. we
1312  * are not reversing), then keep the reservation and state.
1313  * This way we will not be shortly unregister from the road
1314  * stop. It also makes it possible to load when on the edge of
1315  * two road stops; otherwise you could get vehicles that should
1316  * be loading but are not actually loading. */
1317  if (IsDriveThroughStopTile(v->tile) &&
1319  v->tile != tile) {
1320  /* So, keep 'our' state */
1321  dir = (Trackdir)v->state;
1322  } else if (IsRoadStop(v->tile)) {
1323  /* We're not continuing our drive through road stop, so leave. */
1325  }
1326  }
1327 
1328  if (!HasBit(r, VETS_ENTERED_WORMHOLE)) {
1329  TileIndex old_tile = v->tile;
1330 
1331  v->tile = tile;
1332  v->state = (byte)dir;
1333  v->frame = start_frame;
1334  RoadTramType rtt = GetRoadTramType(v->roadtype);
1335  if (GetRoadType(old_tile, rtt) != GetRoadType(tile, rtt)) {
1336  if (v->IsFrontEngine()) {
1337  RoadVehUpdateCache(v);
1338  }
1339  v->First()->CargoChanged();
1340  }
1341  }
1342  if (new_dir != v->direction) {
1343  v->direction = new_dir;
1344  if (_settings_game.vehicle.roadveh_acceleration_model == AM_ORIGINAL) v->cur_speed -= v->cur_speed >> 2;
1345  }
1346  v->x_pos = x;
1347  v->y_pos = y;
1348  v->UpdatePosition();
1349  RoadZPosAffectSpeed(v, v->UpdateInclination(true, true));
1350  return true;
1351  }
1352 
1353  if (rd.x & RDE_TURNED) {
1354  /* Vehicle has finished turning around, it will now head back onto the same tile */
1355  Trackdir dir;
1356  uint turn_around_start_frame = RVC_TURN_AROUND_START_FRAME;
1357 
1358  if (RoadTypeIsTram(v->roadtype) && !IsRoadDepotTile(v->tile) && HasExactlyOneBit(GetAnyRoadBits(v->tile, RTT_TRAM, true))) {
1359  /*
1360  * The tram is turning around with one tram 'roadbit'. This means that
1361  * it is using the 'big' corner 'drive data'. However, to support the
1362  * trams to take a small corner, there is a 'turned' marker in the middle
1363  * of the turning 'drive data'. When the tram took the long corner, we
1364  * will still use the 'big' corner drive data, but we advance it one
1365  * frame. We furthermore set the driving direction so the turning is
1366  * going to be properly shown.
1367  */
1368  turn_around_start_frame = RVC_START_FRAME_AFTER_LONG_TRAM;
1369  switch (rd.x & 0x3) {
1370  default: NOT_REACHED();
1371  case DIAGDIR_NW: dir = TRACKDIR_RVREV_SE; break;
1372  case DIAGDIR_NE: dir = TRACKDIR_RVREV_SW; break;
1373  case DIAGDIR_SE: dir = TRACKDIR_RVREV_NW; break;
1374  case DIAGDIR_SW: dir = TRACKDIR_RVREV_NE; break;
1375  }
1376  } else {
1377  if (v->IsFrontEngine()) {
1378  /* If this is the front engine, look for the right path. */
1379  dir = RoadFindPathToDest(v, v->tile, (DiagDirection)(rd.x & 3));
1380  } else {
1381  dir = FollowPreviousRoadVehicle(v, prev, v->tile, (DiagDirection)(rd.x & 3), true);
1382  }
1383  }
1384 
1385  if (dir == INVALID_TRACKDIR) {
1386  v->cur_speed = 0;
1387  return false;
1388  }
1389 
1390  const RoadDriveEntry *rdp = _road_drive_data[GetRoadTramType(v->roadtype)][(_settings_game.vehicle.road_side << RVS_DRIVE_SIDE) + dir];
1391 
1392  int x = TileX(v->tile) * TILE_SIZE + rdp[turn_around_start_frame].x;
1393  int y = TileY(v->tile) * TILE_SIZE + rdp[turn_around_start_frame].y;
1394 
1395  Direction new_dir = RoadVehGetSlidingDirection(v, x, y);
1396  if (v->IsFrontEngine() && RoadVehFindCloseTo(v, x, y, new_dir) != nullptr) return false;
1397 
1398  uint32 r = VehicleEnterTile(v, v->tile, x, y);
1399  if (HasBit(r, VETS_CANNOT_ENTER)) {
1400  v->cur_speed = 0;
1401  return false;
1402  }
1403 
1404  v->state = dir;
1405  v->frame = turn_around_start_frame;
1406 
1407  if (new_dir != v->direction) {
1408  v->direction = new_dir;
1409  if (_settings_game.vehicle.roadveh_acceleration_model == AM_ORIGINAL) v->cur_speed -= v->cur_speed >> 2;
1410  }
1411 
1412  v->x_pos = x;
1413  v->y_pos = y;
1414  v->UpdatePosition();
1415  RoadZPosAffectSpeed(v, v->UpdateInclination(true, true));
1416  return true;
1417  }
1418 
1419  /* This vehicle is not in a wormhole and it hasn't entered a new tile. If
1420  * it's on a depot tile, check if it's time to activate the next vehicle in
1421  * the chain yet. */
1422  if (v->Next() != nullptr && IsRoadDepotTile(v->tile)) {
1423  if (v->frame == v->gcache.cached_veh_length + RVC_DEPOT_START_FRAME) {
1424  RoadVehLeaveDepot(v->Next(), false);
1425  }
1426  }
1427 
1428  /* Calculate new position for the vehicle */
1429  int x = (v->x_pos & ~15) + (rd.x & 15);
1430  int y = (v->y_pos & ~15) + (rd.y & 15);
1431 
1432  Direction new_dir = RoadVehGetSlidingDirection(v, x, y);
1433 
1434  if (v->IsFrontEngine() && !IsInsideMM(v->state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END)) {
1435  /* Vehicle is not in a road stop.
1436  * Check for another vehicle to overtake */
1437  RoadVehicle *u = RoadVehFindCloseTo(v, x, y, new_dir);
1438 
1439  if (u != nullptr) {
1440  u = u->First();
1441  /* There is a vehicle in front overtake it if possible */
1442  if (v->overtaking == 0) RoadVehCheckOvertake(v, u);
1443  if (v->overtaking == 0) v->cur_speed = u->cur_speed;
1444 
1445  /* In case an RV is stopped in a road stop, why not try to load? */
1446  if (v->cur_speed == 0 && IsInsideMM(v->state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) &&
1448  v->owner == GetTileOwner(v->tile) && !v->current_order.IsType(OT_LEAVESTATION) &&
1450  Station *st = Station::GetByTile(v->tile);
1451  v->last_station_visited = st->index;
1452  RoadVehArrivesAt(v, st);
1453  v->BeginLoading();
1454  }
1455  return false;
1456  }
1457  }
1458 
1459  Direction old_dir = v->direction;
1460  if (new_dir != old_dir) {
1461  v->direction = new_dir;
1462  if (_settings_game.vehicle.roadveh_acceleration_model == AM_ORIGINAL) v->cur_speed -= v->cur_speed >> 2;
1463 
1464  /* Delay the vehicle in curves by making it require one additional frame per turning direction (two in total).
1465  * A vehicle has to spend at least 9 frames on a tile, so the following articulated part can follow.
1466  * (The following part may only be one tile behind, and the front part is moved before the following ones.)
1467  * The short (inner) curve has 8 frames, this elongates it to 10. */
1468  v->UpdateInclination(false, true);
1469  return true;
1470  }
1471 
1472  /* If the vehicle is in a normal road stop and the frame equals the stop frame OR
1473  * if the vehicle is in a drive-through road stop and this is the destination station
1474  * and it's the correct type of stop (bus or truck) and the frame equals the stop frame...
1475  * (the station test and stop type test ensure that other vehicles, using the road stop as
1476  * a through route, do not stop) */
1477  if (v->IsFrontEngine() && ((IsInsideMM(v->state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END) &&
1479  (IsInsideMM(v->state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) &&
1481  v->owner == GetTileOwner(v->tile) &&
1483  v->frame == RVC_DRIVE_THROUGH_STOP_FRAME))) {
1484 
1486  Station *st = Station::GetByTile(v->tile);
1487 
1488  /* Vehicle is at the stop position (at a bay) in a road stop.
1489  * Note, if vehicle is loading/unloading it has already been handled,
1490  * so if we get here the vehicle has just arrived or is just ready to leave. */
1491  if (!HasBit(v->state, RVS_ENTERED_STOP)) {
1492  /* Vehicle has arrived at a bay in a road stop */
1493 
1494  if (IsDriveThroughStopTile(v->tile)) {
1495  TileIndex next_tile = TileAddByDir(v->tile, v->direction);
1496 
1497  /* Check if next inline bay is free and has compatible road. */
1499  v->frame++;
1500  v->x_pos = x;
1501  v->y_pos = y;
1502  v->UpdatePosition();
1503  RoadZPosAffectSpeed(v, v->UpdateInclination(true, false));
1504  return true;
1505  }
1506  }
1507 
1508  rs->SetEntranceBusy(false);
1510 
1511  v->last_station_visited = st->index;
1512 
1513  if (IsDriveThroughStopTile(v->tile) || (v->current_order.IsType(OT_GOTO_STATION) && v->current_order.GetDestination() == st->index)) {
1514  RoadVehArrivesAt(v, st);
1515  v->BeginLoading();
1516  return false;
1517  }
1518  } else {
1519  /* Vehicle is ready to leave a bay in a road stop */
1520  if (rs->IsEntranceBusy()) {
1521  /* Road stop entrance is busy, so wait as there is nowhere else to go */
1522  v->cur_speed = 0;
1523  return false;
1524  }
1525  if (v->current_order.IsType(OT_LEAVESTATION)) v->current_order.Free();
1526  }
1527 
1528  if (IsStandardRoadStopTile(v->tile)) rs->SetEntranceBusy(true);
1529 
1530  StartRoadVehSound(v);
1532  }
1533 
1534  /* Check tile position conditions - i.e. stop position in depot,
1535  * entry onto bridge or into tunnel */
1536  uint32 r = VehicleEnterTile(v, v->tile, x, y);
1537  if (HasBit(r, VETS_CANNOT_ENTER)) {
1538  v->cur_speed = 0;
1539  return false;
1540  }
1541 
1542  if (v->current_order.IsType(OT_LEAVESTATION) && IsDriveThroughStopTile(v->tile)) {
1543  v->current_order.Free();
1544  }
1545 
1546  /* Move to next frame unless vehicle arrived at a stop position
1547  * in a depot or entered a tunnel/bridge */
1548  if (!HasBit(r, VETS_ENTERED_WORMHOLE)) v->frame++;
1549  v->x_pos = x;
1550  v->y_pos = y;
1551  v->UpdatePosition();
1552  RoadZPosAffectSpeed(v, v->UpdateInclination(false, true));
1553  return true;
1554 }
1555 
1556 static bool RoadVehController(RoadVehicle *v)
1557 {
1558  /* decrease counters */
1559  v->current_order_time++;
1560  if (v->reverse_ctr != 0) v->reverse_ctr--;
1561 
1562  /* handle crashed */
1563  if (v->vehstatus & VS_CRASHED || RoadVehCheckTrainCrash(v)) {
1564  return RoadVehIsCrashed(v);
1565  }
1566 
1567  /* road vehicle has broken down? */
1568  if (v->HandleBreakdown()) return true;
1569  if (v->vehstatus & VS_STOPPED) return true;
1570 
1571  ProcessOrders(v);
1572  v->HandleLoading();
1573 
1574  if (v->current_order.IsType(OT_LOADING)) return true;
1575 
1576  if (v->IsInDepot() && RoadVehLeaveDepot(v, true)) return true;
1577 
1578  v->ShowVisualEffect();
1579 
1580  /* Check how far the vehicle needs to proceed */
1581  int j = v->UpdateSpeed();
1582 
1583  int adv_spd = v->GetAdvanceDistance();
1584  bool blocked = false;
1585  while (j >= adv_spd) {
1586  j -= adv_spd;
1587 
1588  RoadVehicle *u = v;
1589  for (RoadVehicle *prev = nullptr; u != nullptr; prev = u, u = u->Next()) {
1590  if (!IndividualRoadVehicleController(u, prev)) {
1591  blocked = true;
1592  break;
1593  }
1594  }
1595  if (blocked) break;
1596 
1597  /* Determine distance to next map position */
1598  adv_spd = v->GetAdvanceDistance();
1599 
1600  /* Test for a collision, but only if another movement will occur. */
1601  if (j >= adv_spd && RoadVehCheckTrainCrash(v)) break;
1602  }
1603 
1604  v->SetLastSpeed();
1605 
1606  for (RoadVehicle *u = v; u != nullptr; u = u->Next()) {
1607  if ((u->vehstatus & VS_HIDDEN) != 0) continue;
1608 
1609  u->UpdateViewport(false, false);
1610  }
1611 
1612  /* If movement is blocked, set 'progress' to its maximum, so the roadvehicle does
1613  * not accelerate again before it can actually move. I.e. make sure it tries to advance again
1614  * on next tick to discover whether it is still blocked. */
1615  if (v->progress == 0) v->progress = blocked ? adv_spd - 1 : j;
1616 
1617  return true;
1618 }
1619 
1621 {
1622  const Engine *e = this->GetEngine();
1623  if (e->u.road.running_cost_class == INVALID_PRICE) return 0;
1624 
1625  uint cost_factor = GetVehicleProperty(this, PROP_ROADVEH_RUNNING_COST_FACTOR, e->u.road.running_cost);
1626  if (cost_factor == 0) return 0;
1627 
1628  return GetPrice(e->u.road.running_cost_class, cost_factor, e->GetGRF());
1629 }
1630 
1632 {
1634 
1635  this->tick_counter++;
1636 
1637  if (this->IsFrontEngine()) {
1638  if (!(this->vehstatus & VS_STOPPED)) this->running_ticks++;
1639  return RoadVehController(this);
1640  }
1641 
1642  return true;
1643 }
1644 
1645 void RoadVehicle::SetDestTile(TileIndex tile)
1646 {
1647  if (tile == this->dest_tile) return;
1648  this->path.clear();
1649  this->dest_tile = tile;
1650 }
1651 
1652 static void CheckIfRoadVehNeedsService(RoadVehicle *v)
1653 {
1654  /* If we already got a slot at a stop, use that FIRST, and go to a depot later */
1655  if (Company::Get(v->owner)->settings.vehicle.servint_roadveh == 0 || !v->NeedsAutomaticServicing()) return;
1656  if (v->IsChainInDepot()) {
1658  return;
1659  }
1660 
1661  uint max_penalty;
1663  case VPF_NPF: max_penalty = _settings_game.pf.npf.maximum_go_to_depot_penalty; break;
1664  case VPF_YAPF: max_penalty = _settings_game.pf.yapf.maximum_go_to_depot_penalty; break;
1665  default: NOT_REACHED();
1666  }
1667 
1668  FindDepotData rfdd = FindClosestRoadDepot(v, max_penalty);
1669  /* Only go to the depot if it is not too far out of our way. */
1670  if (rfdd.best_length == UINT_MAX || rfdd.best_length > max_penalty) {
1671  if (v->current_order.IsType(OT_GOTO_DEPOT)) {
1672  /* If we were already heading for a depot but it has
1673  * suddenly moved farther away, we continue our normal
1674  * schedule? */
1675  v->current_order.MakeDummy();
1677  }
1678  return;
1679  }
1680 
1681  DepotID depot = GetDepotIndex(rfdd.tile);
1682 
1683  if (v->current_order.IsType(OT_GOTO_DEPOT) &&
1685  !Chance16(1, 20)) {
1686  return;
1687  }
1688 
1691  v->SetDestTile(rfdd.tile);
1693 }
1694 
1696 {
1697  AgeVehicle(this);
1698 
1699  if (!this->IsFrontEngine()) return;
1700 
1701  if ((++this->day_counter & 7) == 0) DecreaseVehicleValue(this);
1702  if (this->blocked_ctr == 0) CheckVehicleBreakdown(this);
1703 
1704  CheckIfRoadVehNeedsService(this);
1705 
1706  CheckOrders(this);
1707 
1708  if (this->running_ticks == 0) return;
1709 
1711 
1712  this->profit_this_year -= cost.GetCost();
1713  this->running_ticks = 0;
1714 
1715  SubtractMoneyFromCompanyFract(this->owner, cost);
1716 
1719 }
1720 
1722 {
1723  if (this->vehstatus & VS_CRASHED) return INVALID_TRACKDIR;
1724 
1725  if (this->IsInDepot()) {
1726  /* We'll assume the road vehicle is facing outwards */
1727  return DiagDirToDiagTrackdir(GetRoadDepotDirection(this->tile));
1728  }
1729 
1730  if (IsStandardRoadStopTile(this->tile)) {
1731  /* We'll assume the road vehicle is facing outwards */
1732  return DiagDirToDiagTrackdir(GetRoadStopDir(this->tile)); // Road vehicle in a station
1733  }
1734 
1735  /* Drive through road stops / wormholes (tunnels) */
1737 
1738  /* If vehicle's state is a valid track direction (vehicle is not turning around) return it,
1739  * otherwise transform it into a valid track direction */
1740  return (Trackdir)((IsReversingRoadTrackdir((Trackdir)this->state)) ? (this->state - 6) : this->state);
1741 }
Functions related to OTTD&#39;s strings.
Owner
Enum for all companies/owners.
Definition: company_type.h:18
Road vehicle states.
bool HasVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
Checks whether a vehicle is on a specific location.
Definition: vehicle.cpp:511
void DrawRoadVehEngine(int left, int right, int preferred_x, int y, EngineID engine, PaletteID pal, EngineImageType image_type)
Draw a road vehicle engine.
VehicleSettings vehicle
options for vehicles
This vehicle is in the exclusive preview stage, either being used or being offered to a company...
Definition: engine_type.h:169
uint16 reliability
Current reliability of the engine.
Definition: engine_base.h:25
Date max_age
Maximum age.
Definition: vehicle_base.h:257
static bool HasTileAnyRoadType(TileIndex t, RoadTypes rts)
Check if a tile has one of the specified road types.
Definition: road_map.h:221
uint32 PaletteID
The number of the palette.
Definition: gfx_type.h:18
Vehicle is stopped by the player.
Definition: vehicle_base.h:31
First vehicle arrived for competitor.
Definition: news_type.h:23
int GetDisplayImageWidth(Point *offset=nullptr) const
Get the width of a road vehicle image in the GUI.
Definition: roadveh_cmd.cpp:90
VehicleCargoList cargo
The cargo this vehicle is carrying.
Definition: vehicle_base.h:307
byte state
Definition: roadveh.h:109
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition: settings.cpp:79
static void NewEvent(class ScriptEvent *event)
Queue a new event for a Game Script.
Definition: game_core.cpp:141
Definition of stuff that is very close to a company, like the company struct itself.
static bool IsDiagonalDirection(Direction dir)
Checks if a given Direction is diagonal.
uint16 DepotID
Type for the unique identifier of depots.
Definition: depot_type.h:13
static Vehicle * EnumCheckRoadVehCrashTrain(Vehicle *v, void *data)
Check routine whether a road and a train vehicle have collided.
int GetAcceleration() const
Calculates the acceleration of the vehicle under its current conditions.
void DecreaseVehicleValue(Vehicle *v)
Decrease the value of a vehicle.
Definition: vehicle.cpp:1199
static const int DAYS_IN_YEAR
days per year
Definition: date_type.h:29
TrackdirBits
Enumeration of bitmasks for the TrackDirs.
Definition: track_type.h:101
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
No track build.
Definition: track_type.h:102
bool IsEntranceBusy() const
Checks whether the entrance of the road stop is occupied by a vehicle.
A standard stop for trucks.
Definition: station_type.h:46
bool Tick()
Calls the tick handler of the vehicle.
Direction direction
facing
Definition: vehicle_base.h:269
void ShowVisualEffect() const
Draw visual effects (smoke and/or sparks) for a vehicle chain.
Definition: vehicle.cpp:2509
(Road vehicle) reverse direction south-west
Definition: track_type.h:86
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition: window.cpp:3215
static DiagDirection DirToDiagDir(Direction dir)
Convert a Direction to a DiagDirection.
static const uint RDE_TURNED
We just finished turning.
Definition: roadveh.h:63
Base class for roadstops.
static int UnScaleGUI(int value)
Short-hand to apply GUI zoom level.
Definition: zoom_func.h:66
static bool IsReversingRoadTrackdir(Trackdir dir)
Checks whether the trackdir means that we are reversing.
Definition: track_func.h:681
Yet Another PathFinder.
Definition: vehicle_type.h:61
uint32 maximum_go_to_depot_penalty
What is the maximum penalty that may be endured for going to a depot.
void CheckOrders(const Vehicle *v)
Check the orders of a vehicle, to see if there are invalid orders and stuff.
Definition: order_cmd.cpp:1724
void SetFrontEngine()
Set front engine state.
RoadBits GetAnyRoadBits(TileIndex tile, RoadTramType rtt, bool straight_tunnel_bridge_entrance)
Returns the RoadBits on an arbitrary tile Special behaviour:
Definition: road_map.cpp:33
static Trackdir RoadFindPathToDest(RoadVehicle *v, TileIndex tile, DiagDirection enterdir)
Returns direction to for a road vehicle to take or INVALID_TRACKDIR if the direction is currently blo...
Lower track and direction to west.
Definition: track_type.h:83
static RoadStopType GetRoadStopType(TileIndex t)
Get the road stop type of this tile.
Definition: station_map.h:56
The vehicle is at the opposite side of the road.
Definition: roadveh.h:55
Train vehicle type.
Definition: vehicle_type.h:24
static Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:291
Functions related to dates.
Angle of 45 degrees left.
Northwest.
uint DoUpdateSpeed(uint accel, int min_speed, int max_speed)
Update the speed of the vehicle.
int GetCurrentMaxSpeed() const
Calculates the maximum speed of the vehicle under its current conditions.
Use default vehicle palette.
Definition: vehicle_base.h:33
West.
The vehicle is in a drive-through road stop.
Definition: roadveh.h:47
void AddArticulatedParts(Vehicle *first)
Add the remaining articulated parts to the given vehicle.
Used for iterations.
static T SetBit(T &x, const uint8 y)
Set a bit in a variable.
AccelStatus GetAccelerationStatus() const
Checks the current acceleration status of this vehicle.
Definition: roadveh.h:224
void Leave(RoadVehicle *rv)
Leave the road stop.
Definition: roadstop.cpp:216
Trackdir
Enumeration for tracks and directions.
Definition: track_type.h:70
uint16 cur_speed
current speed
Definition: vehicle_base.h:291
A tile with road (or tram tracks)
Definition: tile_type.h:43
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
Definition: command_func.h:23
static int ScaleGUITrad(int value)
Scale traditional pixel dimensions to GUI zoom level.
Definition: zoom_func.h:76
Depot view; Window numbers:
Definition: window_type.h:344
Full road along the x-axis (south-west + north-east)
Definition: road_type.h:56
Types for recording game performance data.
byte spritenum
currently displayed sprite index 0xfd == custom sprite, 0xfe == custom second head sprite 0xff == res...
Definition: vehicle_base.h:277
Both directions faces to the same direction.
fluid_settings_t * settings
FluidSynth settings handle.
Definition: fluidsynth.cpp:20
StationID last_loading_station
Last station the vehicle has stopped at and could possibly leave from with any cargo loaded...
Definition: vehicle_base.h:301
TileIndex dest_tile
Heading for this tile.
Definition: vehicle_base.h:235
RoadVehicle()
We don&#39;t want GCC to zero our struct! It already is zeroed and has an index!
Definition: roadveh.h:121
static bool IsRoadStop(TileIndex t)
Is the station at t a road station?
Definition: station_map.h:202
NPFSettings npf
pathfinder settings for the new pathfinder
Functions related to vehicles.
void IncrementRealOrderIndex()
Advanced cur_real_order_index to the next real order, keeps care of the wrap-around and invalidates t...
Definition: vehicle_base.h:822
uint32 current_order_time
How many ticks have passed since this order started.
Definition: base_consist.h:21
static const uint RDE_NEXT_TILE
State information about the Road Vehicle controller.
Definition: roadveh.h:62
static uint TileX(TileIndex tile)
Get the X component of a tile.
Definition: map_func.h:205
void VehicleEnterDepot(Vehicle *v)
Vehicle entirely entered the depot, update its status, orders, vehicle windows, service it...
Definition: vehicle.cpp:1436
void Draw(int x, int y, PaletteID default_pal, bool force_pal) const
Draw the sprite sequence.
Definition: vehicle.cpp:126
South-west part.
Definition: road_type.h:53
A standard stop for buses.
Definition: station_type.h:45
PathfinderSettings pf
settings for all pathfinders
Only used when retrieving move data.
Definition: roadveh.h:45
Vehicle data structure.
Definition: vehicle_base.h:210
static uint GetRoadVehLength(const RoadVehicle *v)
Get length of a road vehicle.
void Set(SpriteID sprite)
Assign a single sprite to the sequence.
Definition: vehicle_base.h:161
Start or stop this vehicle, and show information about the current state.
Tindex index
Index of this pool item.
Definition: pool_type.hpp:189
static const int DAY_TICKS
1 day is 74 ticks; _date_fract used to be uint16 and incremented by 885.
Definition: date_type.h:28
uint16 speed
maximum travel speed (1 unit = 1/1.6 mph = 1 km-ish/h)
Definition: bridge.h:46
void SetNext(Vehicle *next)
Set the next vehicle of this vehicle.
Definition: vehicle.cpp:2659
T * First() const
Get the first vehicle in the chain.
Definition: vehicle_base.h:996
void UpdateViewport(bool force_update, bool update_delta)
Update vehicle sprite- and position caches.
build a "half" road
Definition: command_type.h:201
StationID last_station_visited
The last station we stopped at.
Definition: vehicle_base.h:300
uint16 reliability_spd_dec
Reliability decrease speed.
Definition: vehicle_base.h:260
Upper track and direction to west.
Definition: track_type.h:82
static DiagDirection GetRoadDepotDirection(TileIndex t)
Get the direction of the exit of a road depot.
Definition: road_map.h:565
Money GetCost() const
The costs as made up to this moment.
Definition: command_type.h:82
void HandlePathfindingResult(bool path_found)
Handle the pathfinding result, especially the lost status.
Definition: vehicle.cpp:773
bool IsChainInDepot() const override
Check whether the whole vehicle chain is in the depot.
Flag for an invalid DiagDirection.
void CargoChanged()
Recalculates the cached weight of a vehicle and its parts.
Common return value for all commands.
Definition: command_type.h:23
FindDepotData NPFRoadVehicleFindNearestDepot(const RoadVehicle *v, int max_penalty)
Used when user sends road vehicle to the nearest depot or if road vehicle needs servicing using NPF...
Definition: npf.cpp:1158
static TrackdirBits DiagdirReachesTrackdirs(DiagDirection diagdir)
Returns all trackdirs that can be reached when entering a tile from a given (diagonal) direction...
Definition: track_func.h:563
static bool IsStandardRoadStopTile(TileIndex t)
Is tile t a standard (non-drive through) road stop station?
Definition: station_map.h:223
static bool HasExactlyOneBit(T value)
Test whether value has exactly 1 bit set.
RoadType
The different roadtypes we support.
Definition: road_type.h:22
static bool IsDriveThroughStopTile(TileIndex t)
Is tile t a drive through road stop station?
Definition: station_map.h:233
byte vehstatus
Status.
Definition: vehicle_base.h:315
EngineImageType
Visualisation contexts of vehicles and engines.
Definition: vehicle_type.h:85
byte flags
Flags of the engine.
Definition: engine_base.h:33
Year _cur_year
Current year, starting at 0.
Definition: date.cpp:24
uint StoredCount() const
Returns sum of cargo on board the vehicle (ie not only reserved).
Definition: cargopacket.h:351
byte overtaking
Set to RVSB_DRIVE_SIDE when overtaking, otherwise 0.
Definition: roadveh.h:112
static RoadVehicle * From(Vehicle *v)
Converts a Vehicle to SpecializedVehicle with type checking.
uint16 cached_max_speed
Maximum speed of the consist (minimum of the max speed of all vehicles in the consist).
Definition: vehicle_base.h:121
bool NeedsAutomaticServicing() const
Checks if the current order should be interrupted for a service-in-depot order.
Definition: vehicle.cpp:251
const Engine * GetEngine() const
Retrieves the engine of the vehicle.
Definition: vehicle.cpp:741
CargoID GetDefaultCargoType() const
Determines the default cargo type of an engine.
Definition: engine_base.h:79
static const uint TILE_SIZE
Tile size in world coordinates.
Definition: tile_type.h:13
Entry point for OpenTTD to YAPF.
byte VehicleRandomBits()
Get a value for a vehicle&#39;s random_bits.
Definition: vehicle.cpp:361
Money GetPrice(Price index, uint cost_factor, const GRFFile *grf_file, int shift)
Determine a certain price.
Definition: economy.cpp:942
Southwest.
static uint32 RandomRange(uint32 limit)
Pick a random number between 0 and limit - 1, inclusive.
Definition: random_func.hpp:81
RoadStopType
Types of RoadStops.
Definition: station_type.h:44
VehicleSpriteSeq sprite_seq
Vehicle appearance.
Definition: vehicle_base.h:278
North.
Various explosions.
static bool IsStraightRoadTrackdir(Trackdir dir)
Checks whether the given trackdir is a straight road.
Definition: track_func.h:692
int8 x_bb_offs
x offset of vehicle bounding box
Definition: vehicle_base.h:282
uint32 GetGRFID() const
Retrieve the GRF ID of the NewGRF the engine is tied to.
Definition: engine.cpp:160
static bool HasRoadWorks(TileIndex t)
Check if a tile has road works.
Definition: road_map.h:513
EngineID first_engine
Cached EngineID of the front vehicle. INVALID_ENGINE for the front vehicle itself.
Class to backup a specific variable and restore it later.
Definition: backup_type.hpp:21
RoadType roadtype
Road type.
Definition: engine_type.h:125
Pseudo random number generator.
int8 y_bb_offs
y offset of vehicle bounding box
Definition: vehicle_base.h:283
X-Y-axis cross.
Definition: track_type.h:46
Angle of 45 degrees right.
byte breakdown_ctr
Counter for managing breakdown events.
Definition: vehicle_base.h:261
(Road vehicle) reverse direction north-east
Definition: track_type.h:78
static bool IsInsideMM(const T x, const size_t min, const size_t max)
Checks if a value is in an interval.
Definition: math_func.hpp:264
Buses, trucks and trams belong to this class.
Definition: roadveh.h:107
bool ShouldStopAtStation(const Vehicle *v, StationID station) const
Check whether the given vehicle should stop at the given station based on this order and the non-stop...
Definition: order_cmd.cpp:2229
CommandCost CmdBuildRoadVehicle(TileIndex tile, DoCommandFlag flags, const Engine *e, uint16 data, Vehicle **ret)
Build a road vehicle.
Station has seen a truck.
Definition: station_type.h:66
uint16 cargo_cap
total capacity
Definition: vehicle_base.h:305
RoadType roadtype
Roadtype of this vehicle.
Definition: roadveh.h:117
void VehicleLengthChanged(const Vehicle *u)
Logs a bug in GRF and shows a warning message if this is for the first time this happened.
Definition: vehicle.cpp:329
static bool IsTileOwner(TileIndex tile, Owner owner)
Checks if a tile belongs to the given owner.
Definition: tile_map.h:214
static const RoadTypeInfo * GetRoadTypeInfo(RoadType roadtype)
Returns a pointer to the Roadtype information for a given roadtype.
Definition: road.h:224
Map related accessors for depots.
static bool RoadVehIsCrashed(RoadVehicle *v)
Road vehicle chain has crashed.
static RoadBits DiagDirToRoadBits(DiagDirection d)
Create the road-part which belongs to the given DiagDirection.
Definition: road_func.h:96
Vehicle is crashed.
Definition: vehicle_base.h:37
Vehicle is a prototype (accepted as exclusive preview).
Definition: vehicle_base.h:44
None of the directions are disallowed.
Definition: road_map.h:286
static TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition: map_func.h:341
uint16 reliability_spd_dec
Speed of reliability decay between services (per day).
Definition: engine_base.h:26
void SubtractMoneyFromCompanyFract(CompanyID company, CommandCost cst)
Subtract money from a company, including the money fraction.
static bool IsTileType(TileIndex tile, TileType type)
Checks if a tile is a given tiletype.
Definition: tile_map.h:150
Southeast.
RoadTypes powered_roadtypes
bitmask to the OTHER roadtypes on which a vehicle of THIS roadtype generates power ...
Definition: road.h:119
int y
x and y position of the vehicle after moving
Definition: vehicle_func.h:76
CommandCost DoCommand(const CommandContainer *container, DoCommandFlag flags)
Shorthand for calling the long DoCommand with a container.
Definition: command.cpp:441
Used for iterations.
Definition: track_type.h:88
void AgeVehicle(Vehicle *v)
Update age of a vehicle.
Definition: vehicle.cpp:1327
bool IsValid() const
Check whether the sequence contains any sprites.
Definition: vehicle_base.h:145
static RoadBits GetRoadBits(TileIndex t, RoadTramType rtt)
Get the present road bits for a specific road type.
Definition: road_map.h:127
int UpdateSpeed()
This function looks at the vehicle and updates its speed (cur_speed and subspeed) variables...
SoundSettings sound
sound effect settings
YAPFSettings yapf
pathfinder settings for the yet another pathfinder
Right track and direction to south.
Definition: track_type.h:77
bool HasVehicleOnPosXY(int x, int y, void *data, VehicleFromPosProc *proc)
Checks whether a vehicle in on a specific location.
Definition: vehicle.cpp:452
void MakeDummy()
Makes this order a Dummy order.
Definition: order_cmd.cpp:132
byte road_side
the side of the road vehicles drive on
int8 y_offs
y offset for vehicle sprite
Definition: vehicle_base.h:285
void OnNewDay()
Calls the new day handler of the vehicle.
East.
We want to stop.
static DiagDirection GetRoadStopDir(TileIndex t)
Gets the direction the road stop entrance points towards.
Definition: station_map.h:257
Time spend processing road vehicles.
bool IsType(OrderType type) const
Check whether this order is of the given type.
Definition: order_base.h:61
The vehicle is in a tunnel and/or bridge.
Definition: roadveh.h:40
static Owner GetTileOwner(TileIndex tile)
Returns the owner of a tile.
Definition: tile_map.h:178
Southeast.
static DiagDirection ReverseDiagDir(DiagDirection d)
Returns the reverse direction of the given DiagDirection.
DoCommandFlag
List of flags for a command.
Definition: command_type.h:342
T * Next() const
Get next vehicle in the chain.
void GetRoadVehSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type)
Get the size of the sprite of a road vehicle sprite heading west (used for lists).
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:78
The vehicle either entered a bridge, tunnel or depot tile (this includes the last tile of the bridge/...
Definition: tile_cmd.h:22
bool Succeeded() const
Did this command succeed?
Definition: command_type.h:150
Definition of base types and functions in a cross-platform compatible way.
void SetEntranceBusy(bool busy)
Makes an entrance occupied or free.
static const BridgeSpec * GetBridgeSpec(BridgeType i)
Get the specification of a bridge type.
Definition: bridge.h:65
Trackdir GetVehicleTrackdir() const
Returns the Trackdir on which the vehicle is currently located.
static const uint VEHICLE_LENGTH
The length of a vehicle in tile units.
Definition: vehicle_type.h:76
A number of safeguards to prevent using unsafe methods.
byte x_extent
x-extent of vehicle bounding box
Definition: vehicle_base.h:279
uint best_length
The distance towards the depot in penalty, or UINT_MAX if not found.
void InvalidateNewGRFCacheOfChain()
Invalidates cached NewGRF variables of all vehicles in the chain (after the current vehicle) ...
Definition: vehicle_base.h:458
bool ProcessOrders(Vehicle *v)
Handle the orders of a vehicle and determine the next place to go to if needed.
Definition: order_cmd.cpp:2130
Direction
Defines the 8 directions on the map.
Flag for an invalid trackdir.
Definition: track_type.h:89
Max. speed: 1 unit = 1/0.8 mph = 2 km-ish/h.
DirDiff
Enumeration for the difference between two directions.
byte z_extent
z-extent of vehicle bounding box
Definition: vehicle_base.h:281
RoadBits
Enumeration for the road parts on a tile.
Definition: road_type.h:50
static bool IsRoadDepotTile(TileIndex t)
Return whether a tile is a road depot tile.
Definition: road_map.h:115
Vehicle starting, i.e. leaving, the station.
Definition: newgrf_sound.h:19
The vehicle is in a depot.
Definition: roadveh.h:39
static TrackdirBits TrackStatusToRedSignals(TrackStatus ts)
Returns the red-signal-information of a TrackStatus.
Definition: track_func.h:384
CargoID cargo_type
type of cargo this vehicle is carrying
Definition: vehicle_base.h:303
No road-part is build.
Definition: road_type.h:51
Vehicle view; Window numbers:
Definition: window_type.h:332
TrackBits
Bitfield corresponding to Track.
Definition: track_type.h:38
bool IsFrontEngine() const
Check if the vehicle is a front engine.
Definition: vehicle_base.h:881
don&#39;t allow building on water
Definition: command_type.h:347
Trackdir NPFRoadVehicleChooseTrack(const RoadVehicle *v, TileIndex tile, DiagDirection enterdir, bool &path_found)
Finds the best path for given road vehicle using NPF.
Definition: npf.cpp:1175
CommandCost CmdTurnRoadVeh(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Turn a roadvehicle around.
void FindVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
Find a vehicle from a specific location.
Definition: vehicle.cpp:496
TileIndex tile
Current tile index.
Definition: vehicle_base.h:228
North-east part.
Definition: road_type.h:55
Road vehicle list; Window numbers:
Definition: window_type.h:307
South.
New PathFinder.
Definition: vehicle_type.h:60
CommandCost CheckOwnership(Owner owner, TileIndex tile)
Check whether the current owner owns something.
Functions to access the new pathfinder.
bool HasArticulatedPart() const
Check if an engine has an articulated part.
Definition: vehicle_base.h:899
static Trackdir DiagDirToDiagTrackdir(DiagDirection diagdir)
Maps a (4-way) direction to the diagonal trackdir that runs in that direction.
Definition: track_func.h:545
bool CanVehicleUseStation(EngineID engine_type, const Station *st)
Can this station be used by the given engine type?
Definition: vehicle.cpp:2779
VehicleEnterTileStatus VehicleEnterTile(Vehicle *v, TileIndex tile, int x, int y)
Call the tile callback function for a vehicle entering a tile.
Definition: vehicle.cpp:1674
virtual bool IsInDepot() const
Check whether the vehicle is in the depot.
Definition: vehicle_base.h:502
const byte _road_stop_stop_frame[]
Table of road stop stop frames, when to stop at a road stop.
static DirDiff DirDifference(Direction d0, Direction d1)
Calculate the difference between two directions.
static Direction ChangeDir(Direction d, DirDiff delta)
Change a direction by a given difference.
int8 x_offs
x offset for vehicle sprite
Definition: vehicle_base.h:284
Owner owner
Which company owns the vehicle?
Definition: vehicle_base.h:271
Sprite sequence for a vehicle part.
Definition: vehicle_base.h:128
Left track and direction to south.
Definition: track_type.h:76
#define lengthof(x)
Return the length of an fixed size array.
Definition: depend.cpp:40
uint Crash(bool flooded=false)
Crash the (whole) vehicle chain.
static T min(const T a, const T b)
Returns the minimum of two values.
Definition: math_func.hpp:40
static bool IsCargoInClass(CargoID c, CargoClass cc)
Does cargo c have cargo class cc?
Definition: cargotype.h:148
(Road vehicle) reverse direction south-east
Definition: track_type.h:79
uint16 refit_cap
Capacity left over from before last refit.
Definition: vehicle_base.h:306
byte random_bits
Bits used for determining which randomized variational spritegroups to use when drawing.
Definition: vehicle_base.h:297
Functions related to sound.
uint16 reliability
Reliability.
Definition: vehicle_base.h:259
static DiagDirection GetTunnelBridgeDirection(TileIndex t)
Get the direction pointing to the other end.
bool roadveh_queue
buggy road vehicle queueing
Functions to cache sprites in memory.
bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse)
Find the closest depot for this vehicle and tell us the location, DestinationID and whether we should...
Vehicle * First() const
Get the first vehicle of this vehicle chain.
Definition: vehicle_base.h:592
bool Failed() const
Did this command fail?
Definition: command_type.h:159
byte tick_counter
Increased by one for each tick.
Definition: vehicle_base.h:312
EffectVehicle * CreateEffectVehicleRel(const Vehicle *v, int x, int y, int z, EffectVehicleType type)
Create an effect vehicle above a particular vehicle.
uint16 crashed_ctr
Animation counter when the vehicle has crashed.
Definition: roadveh.h:114
Upper track and direction to east.
Definition: track_type.h:74
static DepotID GetDepotIndex(TileIndex t)
Get the index of which depot is attached to the tile.
Definition: depot_map.h:52
Year build_year
Year the vehicle has been built.
Definition: vehicle_base.h:255
bool PlayVehicleSound(const Vehicle *v, VehicleSoundEvent event)
Checks whether a NewGRF wants to play a different vehicle sound effect.
#define return_cmd_error(errcode)
Returns from a function with a specific StringID as error.
Definition: command_func.h:33
TrackStatus GetTileTrackStatus(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
Returns information about trackdirs and signal states.
Definition: landscape.cpp:589
bool IsInDepot() const
Check whether the vehicle is in the depot.
Definition: roadveh.h:136
static void NewEvent(CompanyID company, ScriptEvent *event)
Queue a new event for an AI.
Definition: ai_core.cpp:234
static T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition: math_func.hpp:137
North-west part.
Definition: road_type.h:52
void MarkDirty()
Marks the vehicles to be redrawn and updates cached variables.
Flag for an invalid direction.
static bool Chance16(const uint a, const uint b)
Flips a coin with given probability.
South-east part.
Definition: road_type.h:54
static void DeleteLastRoadVeh(RoadVehicle *v)
Delete last vehicle of a chain road vehicles.
TileIndex tile
The tile of the depot.
static BridgeType GetBridgeType(TileIndex t)
Determines the type of bridge on a tile.
Definition: bridge_map.h:56
void UpdateDeltaXY()
Updates the x and y offsets and the size of the sprite used for this vehicle.
static const byte RV_OVERTAKE_TIMEOUT
The number of ticks a vehicle has for overtaking.
Definition: roadveh.h:80
The vehicle is in a drive-through road stop.
Definition: roadveh.h:52
static Axis DiagDirToAxis(DiagDirection d)
Convert a DiagDirection to the axis.
uint Crash(bool flooded) override
Common code executed for crashed ground vehicles.
static TileIndex GetOtherTunnelBridgeEnd(TileIndex t)
Determines type of the wormhole and returns its other end.
execute the given command
Definition: command_type.h:344
static const EngineID INVALID_ENGINE
Constant denoting an invalid engine.
Definition: engine_type.h:174
Functions related to companies.
GetNewVehiclePosResult GetNewVehiclePos(const Vehicle *v)
Get position information of a vehicle when moving one pixel in the direction it is facing...
Definition: vehicle.cpp:1620
void UpdatePosition()
Update the position of the vehicle.
Definition: vehicle.cpp:1559
static StationID GetStationIndex(TileIndex t)
Get StationID from a tile.
Definition: station_map.h:28
void CheckConsistencyOfArticulatedVehicle(const Vehicle *v)
Checks whether the specs of freshly build articulated vehicles are consistent with the information sp...
static T KillFirstBit(T value)
Clear the first bit in an integer.
bool IsBus() const
Check whether a roadvehicle is a bus.
Definition: roadveh_cmd.cpp:79
Functions related to articulated vehicles.
void ErrorUnknownCallbackResult(uint32 grfid, uint16 cbid, uint16 cb_res)
Record that a NewGRF returned an unknown/invalid callback result.
static bool IsNormalRoadTile(TileIndex t)
Return whether a tile is a normal road tile.
Definition: road_map.h:73
Information about a road vehicle.
Definition: engine_type.h:111
T * Previous() const
Get previous vehicle in the chain.
Tunnel entry/exit and bridge heads.
Definition: tile_type.h:50
DestinationID GetDestination() const
Gets the destination of this order.
Definition: order_base.h:94
const GRFFile * GetGRF() const
Retrieve the NewGRF the engine is tied to.
Definition: engine_base.h:138
void VehicleServiceInDepot(Vehicle *v)
Service a vehicle and all subsequent vehicles in the consist.
Definition: vehicle.cpp:162
Only bits 0 and 3 are used to encode the trackdir for road stops.
Definition: roadveh.h:58
void SetWindowWidgetDirty(WindowClass cls, WindowNumber number, byte widget_index)
Mark a particular widget in a particular window as dirty (in need of repainting)
Definition: window.cpp:3229
void MakeGoToDepot(DepotID destination, OrderDepotTypeFlags order, OrderNonStopFlags non_stop_type=ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS, OrderDepotActionFlags action=ODATF_SERVICE_ONLY, CargoID cargo=CT_NO_REFIT)
Makes this order a Go To Depot order.
Definition: order_cmd.cpp:89
bool HandleBreakdown()
Handle all of the aspects of a vehicle breakdown This includes adding smoke and sounds, and ending the breakdown when appropriate.
Definition: vehicle.cpp:1261
uint32 SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition: gfx_type.h:17
static bool CanBuildTramTrackOnTile(CompanyID c, TileIndex t, RoadType rt, RoadBits r)
Can a tram track build without destruction on the given tile?
uint16 EngineID
Unique identification number of an engine.
Definition: engine_type.h:21
Station has seen a bus.
Definition: station_type.h:65
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:78
static const PaletteID PALETTE_CRASH
Recolour sprite greying of crashed vehicles.
Definition: sprites.h:1587
uint GetAdvanceDistance()
Determines the vehicle "progress" needed for moving a step.
Definition: vehicle_base.h:412
Helper container to find a depot.
void BeginLoading()
Prepare everything to begin the loading when arriving at a station.
Definition: vehicle.cpp:2033
Date date_of_last_service
Last date the vehicle had a service at a depot.
Definition: vehicle_base.h:258
Position information of a vehicle after it moved.
Definition: vehicle_func.h:75
static bool IsLevelCrossingTile(TileIndex t)
Return whether a tile is a level crossing tile.
Definition: road_map.h:94
First vehicle arrived for company.
Definition: news_type.h:22
void FindVehicleOnPosXY(int x, int y, void *data, VehicleFromPosProc *proc)
Find a vehicle from a specific location.
Definition: vehicle.cpp:436
static uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition: map_func.h:215
Only set when a vehicle has entered the stop.
Definition: roadveh.h:44
Trackdir YapfRoadVehicleChooseTrack(const RoadVehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs, bool &path_found, RoadVehPathCache &path_cache)
Finds the best path for given road vehicle using YAPF.
Definition: yapf_road.cpp:511
void Free()
&#39;Free&#39; the order
Definition: order_cmd.cpp:62
void CDECL error(const char *s,...)
Error handling for fatal non-user errors.
Definition: openttd.cpp:112
void RoadVehUpdateCache(RoadVehicle *v, bool same_length)
Update the cache of a road vehicle.
static T abs(const T a)
Returns the absolute value of (scalar) variable.
Definition: math_func.hpp:81
TileIndex xy
Base tile of the station.
uint16 cached_total_length
Length of the whole vehicle (valid only for the first engine).
Functions related to zooming.
VehicleType type
Type of vehicle.
Definition: vehicle_type.h:52
A tile of a station.
Definition: tile_type.h:46
static uint8 FindFirstBit2x64(const int value)
Finds the position of the first non-zero bit in an integer.
RAII class for measuring multi-step elements of performance.
static Station * GetByTile(TileIndex tile)
Get the station belonging to a specific tile.
Money GetRunningCost() const
Gets the running cost of a vehicle.
Northwest.
bool disaster
Play disaster and accident sounds.
uint16 cached_max_track_speed
Maximum consist speed (in internal units) limited by track type (valid only for the first engine)...
TileIndex GetOrderStationLocation(StationID station)
Determine the location for the station where the vehicle goes to next.
Transport by road vehicle.
Number of ticks before carried cargo is aged.
The vehicle will not stop at any stations it passes except the destination.
Definition: order_type.h:74
The vehicle is in a road stop.
Definition: roadveh.h:50
int32 z_pos
z coordinate.
Definition: vehicle_base.h:268
Vehicle is not visible.
Definition: vehicle_base.h:30
Vehicle details; Window numbers:
Definition: window_type.h:193
static uint CountBits(T value)
Counts the number of set bits in a variable.
Base functions for all Games.
RoadTypes compatible_roadtypes
Roadtypes this consist is powered on.
Definition: roadveh.h:118
Functions related to commands.
Coordinates of a point in 2D.
A Stop for a Road Vehicle.
Definition: roadstop_base.h:22
An accident or disaster has occurred.
Definition: news_type.h:24
static bool IsDriveThroughRoadStopContinuation(TileIndex rs, TileIndex next)
Checks whether the &#39;next&#39; tile is still part of the road same drive through stop &#39;rs&#39; in the same dir...
Definition: roadstop.cpp:305
Northeast.
CompanyID _current_company
Company currently doing an action.
Definition: company_cmd.cpp:45
uint32 maximum_go_to_depot_penalty
What is the maximum penalty that may be endured for going to a depot.
byte shorten_factor
length on main map for this type is 8 - shorten_factor
Definition: engine_type.h:124
static bool CheckRoadBlockedForOvertaking(OvertakeData *od)
Check if overtaking is possible on a piece of track.
The mask used to extract track dirs.
Definition: roadveh.h:57
Functions that have tunnels and bridges in common.
uint16 GetVehicleCallback(CallbackID callback, uint32 param1, uint32 param2, EngineID engine, const Vehicle *v)
Evaluate a newgrf callback for vehicles.
static DisallowedRoadDirections GetDisallowedRoadDirections(TileIndex t)
Gets the disallowed directions.
Definition: road_map.h:301
static TileIndex TileAddByDir(TileIndex tile, Direction dir)
Adds a Direction to a tile.
Definition: map_func.h:370
void SetLastSpeed()
Update the GUI variant of the current speed of the vehicle.
uint8 cached_veh_length
Length of this vehicle in units of 1/VEHICLE_LENGTH of normal length. It is cached because this can b...
uint8 original_image_index
Original vehicle image index, thus the image index of the overridden vehicle.
Definition: engine_base.h:39
uint8 roadveh_acceleration_model
realistic acceleration for road vehicles
byte running_ticks
Number of ticks this vehicle was not stopped this day.
Definition: vehicle_base.h:313
RoadVehPathCache path
Cached path.
Definition: roadveh.h:108
byte y_extent
y-extent of vehicle bounding box
Definition: vehicle_base.h:280
(Road vehicle) reverse direction north-west
Definition: track_type.h:87
EngineID engine_type
The type of engine used for this vehicle.
Definition: vehicle_base.h:286
Passengers.
Definition: cargotype.h:39
int32 x_pos
x coordinate.
Definition: vehicle_base.h:266
uint16 vehicle_flags
Used for gradual loading and other miscellaneous things (.
Definition: base_consist.h:30
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
Functions related to NewGRF provided sounds.
void Restore()
Restore the variable.
DiagDirection
Enumeration for diagonal directions.
Base functions for all AIs.
byte progress
The percentage (if divided by 256) this vehicle already crossed the tile unit.
Definition: vehicle_base.h:295
The vehicle cannot enter the tile.
Definition: tile_cmd.h:23
Northeast, upper right on your monitor.
Specification of a rectangle with absolute coordinates of all edges.
Full road along the y-axis (north-west + south-east)
Definition: road_type.h:57
int32 y_pos
y coordinate.
Definition: vehicle_base.h:267
uint16 GetMaxSpeed() const
Get the maxmimum speed in km-ish/h a vehicle is allowed to reach on the way to the destination...
Definition: order_base.h:192
bool IsPrimaryVehicle() const
Whether this is the primary vehicle in the chain.
Definition: roadveh.h:130
static TrackBits TrackdirBitsToTrackBits(TrackdirBits bits)
Discards all directional information from a TrackdirBits value.
Definition: track_func.h:316
Vehicle length, returns the amount of 1/8&#39;s the vehicle is shorter for trains and RVs...
static void RoadVehArrivesAt(const RoadVehicle *v, Station *st)
A road vehicle arrives at a station.
One direction is the opposite of the other one.
FindDepotData YapfRoadVehicleFindNearestDepot(const RoadVehicle *v, int max_penalty)
Used when user sends road vehicle to the nearest depot or if road vehicle needs servicing using YAPF...
Definition: yapf_road.cpp:526
Left track and direction to north.
Definition: track_type.h:84
int UpdateInclination(bool new_tile, bool update_delta)
Checks if the vehicle is in a slope and sets the required flags in that case.
Right track and direction to north.
Definition: track_type.h:85
Money profit_this_year
Profit this year << 8, low 8 bits are fract.
Definition: vehicle_base.h:237
Running costs road vehicles.
Definition: economy_type.h:152
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting)
Definition: window.cpp:3243
Functions related to news.
Base classes/functions for stations.
VehicleCache vcache
Cache of often used vehicle values.
Definition: vehicle_base.h:328
static Station * Get(size_t index)
Gets station with given index.
Date _date
Current date in days (day counter)
Definition: date.cpp:26
TileIndex new_tile
Tile of the vehicle after moving.
Definition: vehicle_func.h:78
Vehicle * first
NOSAVE: pointer to the first vehicle in the chain.
Definition: vehicle_base.h:217
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition: company_cmd.cpp:44
Data about how a road vehicle must drive on a tile.
This depot order is because of the servicing limit.
Definition: order_type.h:95
void HandleLoading(bool mode=false)
Handle the loading of the vehicle; when not it skips through dummy orders and does nothing in all oth...
Definition: vehicle.cpp:2242
static TrackdirBits TrackStatusToTrackdirBits(TrackStatus ts)
Returns the present-trackdir-information of a TrackStatus.
Definition: track_func.h:360
void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const
Gets the sprite to show for the given direction.
Class for backupping variables and making sure they are restored later.
Station data structure.
Definition: station_base.h:450
Functions related to effect vehicles.
OrderNonStopFlags GetNonStopType() const
At which stations must we stop?
Definition: order_base.h:131
static bool IsRoadDepot(TileIndex t)
Return whether a tile is a road depot.
Definition: road_map.h:105
void InvalidateNewGRFCache()
Invalidates cached NewGRF variables.
Definition: vehicle_base.h:449
Disable insertion and removal of automatic orders until the vehicle completes the real order...
Road vehicle type.
Definition: vehicle_type.h:25
static RoadBits AxisToRoadBits(Axis a)
Create the road-part which belongs to the given Axis.
Definition: road_func.h:111
Lower track and direction to east.
Definition: track_type.h:75
void GetBounds(Rect *bounds) const
Determine shared bounds of all sprites.
Definition: vehicle.cpp:98
Date GetLifeLengthInDays() const
Returns the vehicle&#39;s (not model&#39;s!) life length in days.
Definition: engine.cpp:444
byte day_counter
Increased by one for each day.
Definition: vehicle_base.h:311
Order current_order
The current order (+ status, like: loading)
Definition: vehicle_base.h:316
static Direction DiagDirToDir(DiagDirection dir)
Convert a DiagDirection to a Direction.
static RoadStop * GetByTile(TileIndex tile, RoadStopType type)
Find a roadstop at given tile.
Definition: roadstop.cpp:266
void InvalidateWindowData(WindowClass cls, WindowNumber number, int data, bool gui_scope)
Mark window data of the window of a given class and specific window number as invalid (in need of re-...
Definition: window.cpp:3316
GroundVehicleCache gcache
Cache of often calculated values.
byte overtaking_ctr
The length of the current overtake attempt.
Definition: roadveh.h:113
SpriteID colourmap
NOSAVE: cached colour mapping.
Definition: vehicle_base.h:252
Southwest.
static RoadVehicle * GetIfValid(size_t index)
Returns vehicle if the index is a valid index for this vehicle type.
uint8 pathfinder_for_roadvehs
the pathfinder to use for roadvehicles
static void SetDParam(uint n, uint64 v)
Set a string parameter v at index n in the global string parameter array.
Definition: strings_func.h:199
static void AddVehicleNewsItem(StringID string, NewsType type, VehicleID vehicle, StationID station=INVALID_STATION)
Adds a newsitem referencing a vehicle.
Definition: news_func.h:30
Base for the NewGRF implementation.