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