OpenTTD Source: src/roadveh_cmd.cpp Source File

OpenTTD Source 15.0-RC2

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