OpenTTD Source: src/vehicle.cpp Source File

OpenTTD Source 15.0-beta1

vehicle.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
7
10#include "stdafx.h"
11#include "error.h"
12#include "roadveh.h"
13#include "ship.h"
14#include "spritecache.h"
15#include "timetable.h"
16#include "viewport_func.h"
17#include "news_func.h"
18#include "command_func.h"
19#include "company_func.h"
20#include "train.h"
21#include "aircraft.h"
22#include "newgrf_debug.h"
23#include "newgrf_sound.h"
24#include "newgrf_station.h"
25#include "group_gui.h"
26#include "strings_func.h"
27#include "zoom_func.h"
28#include "vehicle_func.h"
29#include "autoreplace_func.h"
30#include "autoreplace_gui.h"
31#include "station_base.h"
32#include "ai/ai.hpp"
33#include "depot_func.h"
34#include "network/network.h"
35#include "core/pool_func.hpp"
36#include "economy_base.h"
37#include "articulated_vehicles.h"
38#include "roadstop_base.h"
39#include "core/random_func.hpp"
40#include "core/backup_type.hpp"
41#include "core/container_func.hpp"
42#include "order_backup.h"
43#include "sound_func.h"
44#include "effectvehicle_func.h"
45#include "effectvehicle_base.h"
46#include "vehiclelist.h"
47#include "bridge_map.h"
48#include "tunnel_map.h"
49#include "depot_map.h"
50#include "gamelog.h"
51#include "linkgraph/linkgraph.h"
52#include "linkgraph/refresh.h"
53#include "framerate_type.h"
54#include "autoreplace_cmd.h"
55#include "misc_cmd.h"
56#include "train_cmd.h"
57#include "vehicle_cmd.h"
58#include "newgrf_roadstop.h"
59#include "timer/timer.h"
60#include "timer/timer_game_calendar.h"
61#include "timer/timer_game_economy.h"
62#include "timer/timer_game_tick.h"
63
64#include "table/strings.h"
65
66#include "safeguards.h"
67
68/* Number of bits in the hash to use from each vehicle coord */
69static const uint GEN_HASHX_BITS = 6;
70static const uint GEN_HASHY_BITS = 6;
71
72/* Size of each hash bucket */
73static const uint GEN_HASHX_BUCKET_BITS = 7;
74static const uint GEN_HASHY_BUCKET_BITS = 6;
75
76/* Compute hash for vehicle coord */
77#define GEN_HASHX(x) GB((x), GEN_HASHX_BUCKET_BITS + ZOOM_BASE_SHIFT, GEN_HASHX_BITS)
78#define GEN_HASHY(y) (GB((y), GEN_HASHY_BUCKET_BITS + ZOOM_BASE_SHIFT, GEN_HASHY_BITS) << GEN_HASHX_BITS)
79#define GEN_HASH(x, y) (GEN_HASHY(y) + GEN_HASHX(x))
80
81/* Maximum size until hash repeats */
82static const int GEN_HASHX_SIZE = 1 << (GEN_HASHX_BUCKET_BITS + GEN_HASHX_BITS + ZOOM_BASE_SHIFT);
83static const int GEN_HASHY_SIZE = 1 << (GEN_HASHY_BUCKET_BITS + GEN_HASHY_BITS + ZOOM_BASE_SHIFT);
84
85/* Increments to reach next bucket in hash table */
86static const int GEN_HASHX_INC = 1;
87static const int GEN_HASHY_INC = 1 << GEN_HASHX_BITS;
88
89/* Mask to wrap-around buckets */
90static const uint GEN_HASHX_MASK = (1 << GEN_HASHX_BITS) - 1;
91static const uint GEN_HASHY_MASK = ((1 << GEN_HASHY_BITS) - 1) << GEN_HASHX_BITS;
92
93
95 VehiclePool _vehicle_pool("Vehicle");
96 INSTANTIATE_POOL_METHODS(Vehicle)
97
98
99
103void VehicleSpriteSeq::GetBounds(Rect *bounds) const
104{
105 bounds->left = bounds->top = bounds->right = bounds->bottom = 0;
106 for (uint i = 0; i < this->count; ++i) {
107 const Sprite *spr = GetSprite(this->seq[i].sprite, SpriteType::Normal);
108 if (i == 0) {
109 bounds->left = spr->x_offs;
110 bounds->top = spr->y_offs;
111 bounds->right = spr->width + spr->x_offs - 1;
112 bounds->bottom = spr->height + spr->y_offs - 1;
113 } else {
114 if (spr->x_offs < bounds->left) bounds->left = spr->x_offs;
115 if (spr->y_offs < bounds->top) bounds->top = spr->y_offs;
116 int right = spr->width + spr->x_offs - 1;
117 int bottom = spr->height + spr->y_offs - 1;
118 if (right > bounds->right) bounds->right = right;
119 if (bottom > bounds->bottom) bounds->bottom = bottom;
120 }
121 }
122}
123
131 void VehicleSpriteSeq::Draw(int x, int y, PaletteID default_pal, bool force_pal) const
132{
133 for (uint i = 0; i < this->count; ++i) {
134 PaletteID pal = force_pal || !this->seq[i].pal ? default_pal : this->seq[i].pal;
135 DrawSprite(this->seq[i].sprite, pal, x, y);
136 }
137}
138
145 bool Vehicle::NeedsAutorenewing(const Company *c, bool use_renew_setting) const
146{
147 /* We can always generate the Company pointer when we have the vehicle.
148 * However this takes time and since the Company pointer is often present
149 * when this function is called then it's faster to pass the pointer as an
150 * argument rather than finding it again. */
151 assert(c == Company::Get(this->owner));
152
153 if (use_renew_setting && !c->settings.engine_renew) return false;
154 if (this->age - this->max_age < (c->settings.engine_renew_months * 30)) return false;
155
156 /* Only engines need renewing */
157 if (this->type == VEH_TRAIN && !Train::From(this)->IsEngine()) return false;
158
159 return true;
160}
161
167 void VehicleServiceInDepot(Vehicle *v)
168{
169 assert(v != nullptr);
170 SetWindowDirty(WC_VEHICLE_DETAILS, v->index); // ensure that last service date and reliability are updated
171
172 do {
173 v->date_of_last_service = TimerGameEconomy::date;
174 v->date_of_last_service_newgrf = TimerGameCalendar::date;
175 v->breakdowns_since_last_service = 0;
176 v->reliability = v->GetEngine()->reliability;
177 /* Prevent vehicles from breaking down directly after exiting the depot. */
178 v->breakdown_chance /= 4;
179 if (_settings_game.difficulty.vehicle_breakdowns == 1) v->breakdown_chance = 0; // on reduced breakdown
180 v = v->Next();
181 } while (v != nullptr && v->HasEngineType());
182}
183
190 bool Vehicle::NeedsServicing() const
191{
192 /* Stopped or crashed vehicles will not move, as such making unmovable
193 * vehicles to go for service is lame. */
194 if (this->vehstatus & (VS_STOPPED | VS_CRASHED)) return false;
195
196 /* Are we ready for the next service cycle? */
197 const Company *c = Company::Get(this->owner);
198
199 /* Service intervals can be measured in different units, which we handle individually. */
200 if (this->ServiceIntervalIsPercent()) {
201 /* Service interval is in percents. */
202 if (this->reliability >= this->GetEngine()->reliability * (100 - this->GetServiceInterval()) / 100) return false;
203 } else if (TimerGameEconomy::UsingWallclockUnits()) {
204 /* Service interval is in minutes. */
205 if (this->date_of_last_service + (this->GetServiceInterval() * EconomyTime::DAYS_IN_ECONOMY_MONTH) >= TimerGameEconomy::date) return false;
206 } else {
207 /* Service interval is in days. */
208 if (this->date_of_last_service + this->GetServiceInterval() >= TimerGameEconomy::date) return false;
209 }
210
211 /* If we're servicing anyway, because we have not disabled servicing when
212 * there are no breakdowns or we are playing with breakdowns, bail out. */
213 if (!_settings_game.order.no_servicing_if_no_breakdowns ||
214 _settings_game.difficulty.vehicle_breakdowns != 0) {
215 return true;
216 }
217
218 /* Test whether there is some pending autoreplace.
219 * Note: We do this after the service-interval test.
220 * There are a lot more reasons for autoreplace to fail than we can test here reasonably. */
221 bool pending_replace = false;
222 Money needed_money = c->settings.engine_renew_money;
223 if (needed_money > GetAvailableMoney(c->index)) return false;
224
225 for (const Vehicle *v = this; v != nullptr; v = (v->type == VEH_TRAIN) ? Train::From(v)->GetNextUnit() : nullptr) {
226 bool replace_when_old = false;
227 EngineID new_engine = EngineReplacementForCompany(c, v->engine_type, v->group_id, &replace_when_old);
228
229 /* Check engine availability */
230 if (new_engine == INVALID_ENGINE || !HasBit(Engine::Get(new_engine)->company_avail, v->owner)) continue;
231 /* Is the vehicle old if we are not always replacing? */
232 if (replace_when_old && !v->NeedsAutorenewing(c, false)) continue;
233
234 /* Check refittability */
235 CargoTypes available_cargo_types, union_mask;
236 GetArticulatedRefitMasks(new_engine, true, &union_mask, &available_cargo_types);
237 /* Is there anything to refit? */
238 if (union_mask != 0) {
239 CargoID cargo_type;
240 CargoTypes cargo_mask = GetCargoTypesOfArticulatedVehicle(v, &cargo_type);
241 if (!HasAtMostOneBit(cargo_mask)) {
242 CargoTypes new_engine_default_cargoes = GetCargoTypesOfArticulatedParts(new_engine);
243 if ((cargo_mask & new_engine_default_cargoes) != cargo_mask) {
244 /* We cannot refit to mixed cargoes in an automated way */
245 continue;
246 }
247 /* engine_type is already a mixed cargo type which matches the incoming vehicle by default, no refit required */
248 } else {
249 /* Did the old vehicle carry anything? */
250 if (IsValidCargoID(cargo_type)) {
251 /* We can't refit the vehicle to carry the cargo we want */
252 if (!HasBit(available_cargo_types, cargo_type)) continue;
253 }
254 }
255 }
256
257 /* Check money.
258 * We want 2*(the price of the new vehicle) without looking at the value of the vehicle we are going to sell. */
259 pending_replace = true;
260 needed_money += 2 * Engine::Get(new_engine)->GetCost();
261 if (needed_money > GetAvailableMoney(c->index)) return false;
262 }
263
264 return pending_replace;
265}
266
272 bool Vehicle::NeedsAutomaticServicing() const
273{
274 if (this->HasDepotOrder()) return false;
275 if (this->current_order.IsType(OT_LOADING)) return false;
276 if (this->current_order.IsType(OT_GOTO_DEPOT) && (this->current_order.GetDepotOrderType() & ODTFB_SERVICE) == 0) return false;
277 return NeedsServicing();
278}
279
280uint Vehicle::Crash(bool)
281{
282 assert((this->vehstatus & VS_CRASHED) == 0);
283 assert(this->Previous() == nullptr); // IsPrimaryVehicle fails for free-wagon-chains
284
285 uint pass = 0;
286 /* Stop the vehicle. */
287 if (this->IsPrimaryVehicle()) this->vehstatus |= VS_STOPPED;
288 /* crash all wagons, and count passengers */
289 for (Vehicle *v = this; v != nullptr; v = v->Next()) {
290 /* We do not transfer reserver cargo back, so TotalCount() instead of StoredCount() */
291 if (IsCargoInClass(v->cargo_type, CC_PASSENGERS)) pass += v->cargo.TotalCount();
292 v->vehstatus |= VS_CRASHED;
293 v->MarkAllViewportsDirty();
294 }
295
296 /* Dirty some windows */
297 InvalidateWindowClassesData(GetWindowClassForVehicleType(this->type), 0);
298 SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
299 SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
300 SetWindowDirty(WC_VEHICLE_DEPOT, this->tile);
301
302 delete this->cargo_payment;
303 assert(this->cargo_payment == nullptr); // cleared by ~CargoPayment
304
305 return RandomRange(pass + 1); // Randomise deceased passengers.
306}
307
308
317 void ShowNewGrfVehicleError(EngineID engine, StringID part1, StringID part2, GRFBugs bug_type, bool critical)
318{
319 const Engine *e = Engine::Get(engine);
320 GRFConfig *grfconfig = GetGRFConfig(e->GetGRFID());
321
322 /* Missing GRF. Nothing useful can be done in this situation. */
323 if (grfconfig == nullptr) return;
324
325 if (!HasBit(grfconfig->grf_bugs, bug_type)) {
326 SetBit(grfconfig->grf_bugs, bug_type);
327 SetDParamStr(0, grfconfig->GetName());
328 SetDParam(1, engine);
329 ShowErrorMessage(part1, part2, WL_CRITICAL);
330 if (!_networking) Command<CMD_PAUSE>::Do(DC_EXEC, critical ? PM_PAUSED_ERROR : PM_PAUSED_NORMAL, true);
331 }
332
333 /* debug output */
334 SetDParamStr(0, grfconfig->GetName());
335 Debug(grf, 0, "{}", StrMakeValid(GetString(part1)));
336
337 SetDParam(1, engine);
338 Debug(grf, 0, "{}", StrMakeValid(GetString(part2)));
339}
340
346 void VehicleLengthChanged(const Vehicle *u)
347{
348 /* show a warning once for each engine in whole game and once for each GRF after each game load */
349 const Engine *engine = u->GetEngine();
350 uint32_t grfid = engine->grf_prop.grfid;
351 GRFConfig *grfconfig = GetGRFConfig(grfid);
352 if (_gamelog.GRFBugReverse(grfid, engine->grf_prop.local_id) || !HasBit(grfconfig->grf_bugs, GBUG_VEH_LENGTH)) {
353 ShowNewGrfVehicleError(u->engine_type, STR_NEWGRF_BROKEN, STR_NEWGRF_BROKEN_VEHICLE_LENGTH, GBUG_VEH_LENGTH, true);
354 }
355}
356
361Vehicle::Vehicle(VehicleType type)
362{
363 this->type = type;
364 this->coord.left = INVALID_COORD;
365 this->sprite_cache.old_coord.left = INVALID_COORD;
366 this->group_id = DEFAULT_GROUP;
367 this->fill_percent_te_id = INVALID_TE_ID;
368 this->first = this;
369 this->colourmap = PAL_NONE;
370 this->cargo_age_counter = 1;
371 this->last_station_visited = INVALID_STATION;
372 this->last_loading_station = INVALID_STATION;
373}
374
375/* Size of the hash, 6 = 64 x 64, 7 = 128 x 128. Larger sizes will (in theory) reduce hash
376 * lookup times at the expense of memory usage. */
377const int HASH_BITS = 7;
378const int HASH_SIZE = 1 << HASH_BITS;
379const int HASH_MASK = HASH_SIZE - 1;
380const int TOTAL_HASH_SIZE = 1 << (HASH_BITS * 2);
381const int TOTAL_HASH_MASK = TOTAL_HASH_SIZE - 1;
382
383/* Resolution of the hash, 0 = 1*1 tile, 1 = 2*2 tiles, 2 = 4*4 tiles, etc.
384 * Profiling results show that 0 is fastest. */
385const int HASH_RES = 0;
386
387static Vehicle *_vehicle_tile_hash[TOTAL_HASH_SIZE];
388
389static Vehicle *VehicleFromTileHash(int xl, int yl, int xu, int yu, void *data, VehicleFromPosProc *proc, bool find_first)
390{
391 for (int y = yl; ; y = (y + (1 << HASH_BITS)) & (HASH_MASK << HASH_BITS)) {
392 for (int x = xl; ; x = (x + 1) & HASH_MASK) {
393 Vehicle *v = _vehicle_tile_hash[(x + y) & TOTAL_HASH_MASK];
394 for (; v != nullptr; v = v->hash_tile_next) {
395 Vehicle *a = proc(v, data);
396 if (find_first && a != nullptr) return a;
397 }
398 if (x == xu) break;
399 }
400 if (y == yu) break;
401 }
402
403 return nullptr;
404}
405
406
418 static Vehicle *VehicleFromPosXY(int x, int y, void *data, VehicleFromPosProc *proc, bool find_first)
419{
420 const int COLL_DIST = 6;
421
422 /* Hash area to scan is from xl,yl to xu,yu */
423 int xl = GB((x - COLL_DIST) / TILE_SIZE, HASH_RES, HASH_BITS);
424 int xu = GB((x + COLL_DIST) / TILE_SIZE, HASH_RES, HASH_BITS);
425 int yl = GB((y - COLL_DIST) / TILE_SIZE, HASH_RES, HASH_BITS) << HASH_BITS;
426 int yu = GB((y + COLL_DIST) / TILE_SIZE, HASH_RES, HASH_BITS) << HASH_BITS;
427
428 return VehicleFromTileHash(xl, yl, xu, yu, data, proc, find_first);
429}
430
445 void FindVehicleOnPosXY(int x, int y, void *data, VehicleFromPosProc *proc)
446{
447 VehicleFromPosXY(x, y, data, proc, false);
448}
449
461 bool HasVehicleOnPosXY(int x, int y, void *data, VehicleFromPosProc *proc)
462{
463 return VehicleFromPosXY(x, y, data, proc, true) != nullptr;
464}
465
476 static Vehicle *VehicleFromPos(TileIndex tile, void *data, VehicleFromPosProc *proc, bool find_first)
477{
478 int x = GB(TileX(tile), HASH_RES, HASH_BITS);
479 int y = GB(TileY(tile), HASH_RES, HASH_BITS) << HASH_BITS;
480
481 Vehicle *v = _vehicle_tile_hash[(x + y) & TOTAL_HASH_MASK];
482 for (; v != nullptr; v = v->hash_tile_next) {
483 if (v->tile != tile) continue;
484
485 Vehicle *a = proc(v, data);
486 if (find_first && a != nullptr) return a;
487 }
488
489 return nullptr;
490}
491
505 void FindVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
506{
507 VehicleFromPos(tile, data, proc, false);
508}
509
520 bool HasVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
521{
522 return VehicleFromPos(tile, data, proc, true) != nullptr;
523}
524
531 static Vehicle *EnsureNoVehicleProcZ(Vehicle *v, void *data)
532{
533 int z = *(int*)data;
534
535 if (v->type == VEH_DISASTER || (v->type == VEH_AIRCRAFT && v->subtype == AIR_SHADOW)) return nullptr;
536 if (v->z_pos > z) return nullptr;
537
538 return v;
539}
540
546 CommandCost EnsureNoVehicleOnGround(TileIndex tile)
547{
548 int z = GetTileMaxPixelZ(tile);
549
550 /* Value v is not safe in MP games, however, it is used to generate a local
551 * error message only (which may be different for different machines).
552 * Such a message does not affect MP synchronisation.
553 */
554 Vehicle *v = VehicleFromPos(tile, &z, &EnsureNoVehicleProcZ, true);
555 if (v != nullptr) return CommandCost(STR_ERROR_TRAIN_IN_THE_WAY + v->type);
556 return CommandCost();
557}
558
560 static Vehicle *GetVehicleTunnelBridgeProc(Vehicle *v, void *data)
561{
562 if (v->type != VEH_TRAIN && v->type != VEH_ROAD && v->type != VEH_SHIP) return nullptr;
563 if (v == (const Vehicle *)data) return nullptr;
564
565 return v;
566}
567
575 CommandCost TunnelBridgeIsFree(TileIndex tile, TileIndex endtile, const Vehicle *ignore)
576{
577 /* Value v is not safe in MP games, however, it is used to generate a local
578 * error message only (which may be different for different machines).
579 * Such a message does not affect MP synchronisation.
580 */
581 Vehicle *v = VehicleFromPos(tile, const_cast<Vehicle *>(ignore), &GetVehicleTunnelBridgeProc, true);
582 if (v == nullptr) v = VehicleFromPos(endtile, const_cast<Vehicle *>(ignore), &GetVehicleTunnelBridgeProc, true);
583
584 if (v != nullptr) return CommandCost(STR_ERROR_TRAIN_IN_THE_WAY + v->type);
585 return CommandCost();
586}
587
588static Vehicle *EnsureNoTrainOnTrackProc(Vehicle *v, void *data)
589{
590 TrackBits rail_bits = *(TrackBits *)data;
591
592 if (v->type != VEH_TRAIN) return nullptr;
593
594 Train *t = Train::From(v);
595 if ((t->track != rail_bits) && !TracksOverlap(t->track | rail_bits)) return nullptr;
596
597 return v;
598}
599
608 CommandCost EnsureNoTrainOnTrackBits(TileIndex tile, TrackBits track_bits)
609{
610 /* Value v is not safe in MP games, however, it is used to generate a local
611 * error message only (which may be different for different machines).
612 * Such a message does not affect MP synchronisation.
613 */
614 Vehicle *v = VehicleFromPos(tile, &track_bits, &EnsureNoTrainOnTrackProc, true);
615 if (v != nullptr) return CommandCost(STR_ERROR_TRAIN_IN_THE_WAY + v->type);
616 return CommandCost();
617}
618
619static void UpdateVehicleTileHash(Vehicle *v, bool remove)
620{
621 Vehicle **old_hash = v->hash_tile_current;
622 Vehicle **new_hash;
623
624 if (remove) {
625 new_hash = nullptr;
626 } else {
627 int x = GB(TileX(v->tile), HASH_RES, HASH_BITS);
628 int y = GB(TileY(v->tile), HASH_RES, HASH_BITS) << HASH_BITS;
629 new_hash = &_vehicle_tile_hash[(x + y) & TOTAL_HASH_MASK];
630 }
631
632 if (old_hash == new_hash) return;
633
634 /* Remove from the old position in the hash table */
635 if (old_hash != nullptr) {
636 if (v->hash_tile_next != nullptr) v->hash_tile_next->hash_tile_prev = v->hash_tile_prev;
637 *v->hash_tile_prev = v->hash_tile_next;
638 }
639
640 /* Insert vehicle at beginning of the new position in the hash table */
641 if (new_hash != nullptr) {
642 v->hash_tile_next = *new_hash;
643 if (v->hash_tile_next != nullptr) v->hash_tile_next->hash_tile_prev = &v->hash_tile_next;
644 v->hash_tile_prev = new_hash;
645 *new_hash = v;
646 }
647
648 /* Remember current hash position */
649 v->hash_tile_current = new_hash;
650}
651
652static Vehicle *_vehicle_viewport_hash[1 << (GEN_HASHX_BITS + GEN_HASHY_BITS)];
653
654static void UpdateVehicleViewportHash(Vehicle *v, int x, int y, int old_x, int old_y)
655{
656 Vehicle **old_hash, **new_hash;
657
658 new_hash = (x == INVALID_COORD) ? nullptr : &_vehicle_viewport_hash[GEN_HASH(x, y)];
659 old_hash = (old_x == INVALID_COORD) ? nullptr : &_vehicle_viewport_hash[GEN_HASH(old_x, old_y)];
660
661 if (old_hash == new_hash) return;
662
663 /* remove from hash table? */
664 if (old_hash != nullptr) {
665 if (v->hash_viewport_next != nullptr) v->hash_viewport_next->hash_viewport_prev = v->hash_viewport_prev;
666 *v->hash_viewport_prev = v->hash_viewport_next;
667 }
668
669 /* insert into hash table? */
670 if (new_hash != nullptr) {
671 v->hash_viewport_next = *new_hash;
672 if (v->hash_viewport_next != nullptr) v->hash_viewport_next->hash_viewport_prev = &v->hash_viewport_next;
673 v->hash_viewport_prev = new_hash;
674 *new_hash = v;
675 }
676}
677
678void ResetVehicleHash()
679{
680 for (Vehicle *v : Vehicle::Iterate()) { v->hash_tile_current = nullptr; }
681 memset(_vehicle_viewport_hash, 0, sizeof(_vehicle_viewport_hash));
682 memset(_vehicle_tile_hash, 0, sizeof(_vehicle_tile_hash));
683}
684
685void ResetVehicleColourMap()
686{
687 for (Vehicle *v : Vehicle::Iterate()) { v->colourmap = PAL_NONE; }
688}
689
694 using AutoreplaceMap = std::map<VehicleID, bool>;
695static AutoreplaceMap _vehicles_to_autoreplace;
696
697void InitializeVehicles()
698{
699 _vehicles_to_autoreplace.clear();
700 ResetVehicleHash();
701}
702
703uint CountVehiclesInChain(const Vehicle *v)
704{
705 uint count = 0;
706 do count++; while ((v = v->Next()) != nullptr);
707 return count;
708}
709
714 bool Vehicle::IsEngineCountable() const
715{
716 switch (this->type) {
717 case VEH_AIRCRAFT: return Aircraft::From(this)->IsNormalAircraft(); // don't count plane shadows and helicopter rotors
718 case VEH_TRAIN:
719 return !this->IsArticulatedPart() && // tenders and other articulated parts
720 !Train::From(this)->IsRearDualheaded(); // rear parts of multiheaded engines
721 case VEH_ROAD: return RoadVehicle::From(this)->IsFrontEngine();
722 case VEH_SHIP: return true;
723 default: return false; // Only count company buildable vehicles
724 }
725}
726
731 bool Vehicle::HasEngineType() const
732{
733 switch (this->type) {
734 case VEH_AIRCRAFT: return Aircraft::From(this)->IsNormalAircraft();
735 case VEH_TRAIN:
736 case VEH_ROAD:
737 case VEH_SHIP: return true;
738 default: return false;
739 }
740}
741
747 const Engine *Vehicle::GetEngine() const
748{
749 return Engine::Get(this->engine_type);
750}
751
757 const GRFFile *Vehicle::GetGRF() const
758{
759 return this->GetEngine()->GetGRF();
760}
761
767uint32_t Vehicle::GetGRFID() const
768{
769 return this->GetEngine()->GetGRFID();
770}
771
777 void Vehicle::ShiftDates(TimerGameEconomy::Date interval)
778{
779 this->date_of_last_service = std::max(this->date_of_last_service + interval, TimerGameEconomy::Date(0));
780 /* date_of_last_service_newgrf is not updated here as it must stay stable
781 * for vehicles outside of a depot. */
782}
783
791 void Vehicle::HandlePathfindingResult(bool path_found)
792{
793 if (path_found) {
794 /* Route found, is the vehicle marked with "lost" flag? */
795 if (!HasBit(this->vehicle_flags, VF_PATHFINDER_LOST)) return;
796
797 /* Clear the flag as the PF's problem was solved. */
798 ClrBit(this->vehicle_flags, VF_PATHFINDER_LOST);
799 SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
800 InvalidateWindowClassesData(GetWindowClassForVehicleType(this->type));
801 /* Delete the news item. */
802 DeleteVehicleNews(this->index, STR_NEWS_VEHICLE_IS_LOST);
803 return;
804 }
805
806 /* Were we already lost? */
807 if (HasBit(this->vehicle_flags, VF_PATHFINDER_LOST)) return;
808
809 /* It is first time the problem occurred, set the "lost" flag. */
810 SetBit(this->vehicle_flags, VF_PATHFINDER_LOST);
811 SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
812 InvalidateWindowClassesData(GetWindowClassForVehicleType(this->type));
813
814 /* Unbunching data is no longer valid. */
815 this->ResetDepotUnbunching();
816
817 /* Notify user about the event. */
818 AI::NewEvent(this->owner, new ScriptEventVehicleLost(this->index));
819 if (_settings_client.gui.lost_vehicle_warn && this->owner == _local_company) {
820 SetDParam(0, this->index);
821 AddVehicleAdviceNewsItem(STR_NEWS_VEHICLE_IS_LOST, this->index);
822 }
823}
824
826 void Vehicle::PreDestructor()
827{
828 if (CleaningPool()) return;
829
830 if (Station::IsValidID(this->last_station_visited)) {
831 Station *st = Station::Get(this->last_station_visited);
832 st->loading_vehicles.remove(this);
833
834 HideFillingPercent(&this->fill_percent_te_id);
835 this->CancelReservation(INVALID_STATION, st);
836 delete this->cargo_payment;
837 assert(this->cargo_payment == nullptr); // cleared by ~CargoPayment
838 }
839
840 if (this->IsEngineCountable()) {
841 GroupStatistics::CountEngine(this, -1);
842 if (this->IsPrimaryVehicle()) GroupStatistics::CountVehicle(this, -1);
843 GroupStatistics::UpdateAutoreplace(this->owner);
844
845 if (this->owner == _local_company) InvalidateAutoreplaceWindow(this->engine_type, this->group_id);
846 DeleteGroupHighlightOfVehicle(this);
847 }
848
849 Company::Get(this->owner)->freeunits[this->type].ReleaseID(this->unitnumber);
850
851 if (this->type == VEH_AIRCRAFT && this->IsPrimaryVehicle()) {
852 Aircraft *a = Aircraft::From(this);
853 Station *st = GetTargetAirportIfValid(a);
854 if (st != nullptr) {
855 const AirportFTA *layout = st->airport.GetFTA()->layout;
856 CLRBITS(st->airport.flags, layout[a->previous_pos].block | layout[a->pos].block);
857 }
858 }
859
860
861 if (this->type == VEH_ROAD && this->IsPrimaryVehicle()) {
862 RoadVehicle *v = RoadVehicle::From(this);
863 if (!(v->vehstatus & VS_CRASHED) && IsInsideMM(v->state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END)) {
864 /* Leave the drive through roadstop, when you have not already left it. */
865 RoadStop::GetByTile(v->tile, GetRoadStopType(v->tile))->Leave(v);
866 }
867
868 if (v->disaster_vehicle != INVALID_VEHICLE) ReleaseDisasterVehicle(v->disaster_vehicle);
869 }
870
871 if (this->Previous() == nullptr) {
872 InvalidateWindowData(WC_VEHICLE_DEPOT, this->tile);
873 }
874
875 if (this->IsPrimaryVehicle()) {
876 CloseWindowById(WC_VEHICLE_VIEW, this->index);
877 CloseWindowById(WC_VEHICLE_ORDERS, this->index);
878 CloseWindowById(WC_VEHICLE_REFIT, this->index);
879 CloseWindowById(WC_VEHICLE_DETAILS, this->index);
880 CloseWindowById(WC_VEHICLE_TIMETABLE, this->index);
881 SetWindowDirty(WC_COMPANY, this->owner);
882 OrderBackup::ClearVehicle(this);
883 }
884 InvalidateWindowClassesData(GetWindowClassForVehicleType(this->type), 0);
885
886 this->cargo.Truncate();
887 DeleteVehicleOrders(this);
888 DeleteDepotHighlightOfVehicle(this);
889
890 StopGlobalFollowVehicle(this);
891}
892
893Vehicle::~Vehicle()
894{
895 if (CleaningPool()) {
896 this->cargo.OnCleanPool();
897 return;
898 }
899
900 /* sometimes, eg. for disaster vehicles, when company bankrupts, when removing crashed/flooded vehicles,
901 * it may happen that vehicle chain is deleted when visible */
902 if (!(this->vehstatus & VS_HIDDEN)) this->MarkAllViewportsDirty();
903
904 Vehicle *v = this->Next();
905 this->SetNext(nullptr);
906
907 delete v;
908
909 UpdateVehicleTileHash(this, true);
910 UpdateVehicleViewportHash(this, INVALID_COORD, 0, this->sprite_cache.old_coord.left, this->sprite_cache.old_coord.top);
911 if (this->type != VEH_EFFECT) {
912 DeleteVehicleNews(this->index, INVALID_STRING_ID);
913 DeleteNewGRFInspectWindow(GetGrfSpecFeature(this->type), this->index);
914 }
915}
916
921 void VehicleEnteredDepotThisTick(Vehicle *v)
922{
923 /* Vehicle should stop in the depot if it was in 'stopping' state */
924 _vehicles_to_autoreplace[v->index] = !(v->vehstatus & VS_STOPPED);
925
926 /* We ALWAYS set the stopped state. Even when the vehicle does not plan on
927 * stopping in the depot, so we stop it to ensure that it will not reserve
928 * the path out of the depot before we might autoreplace it to a different
929 * engine. The new engine would not own the reserved path we store that we
930 * stopped the vehicle, so autoreplace can start it again */
931 v->vehstatus |= VS_STOPPED;
932}
933
937 void RunVehicleCalendarDayProc()
938{
939 if (_game_mode != GM_NORMAL) return;
940
941 /* Run the calendar day proc for every DAY_TICKS vehicle starting at TimerGameCalendar::date_fract. */
942 for (size_t i = TimerGameCalendar::date_fract; i < Vehicle::GetPoolSize(); i += Ticks::DAY_TICKS) {
943 Vehicle *v = Vehicle::Get(i);
944 if (v == nullptr) continue;
945 v->OnNewCalendarDay();
946 }
947}
948
954 static void RunEconomyVehicleDayProc()
955{
956 if (_game_mode != GM_NORMAL) return;
957
958 /* Run the economy day proc for every DAY_TICKS vehicle starting at TimerGameEconomy::date_fract. */
959 for (size_t i = TimerGameEconomy::date_fract; i < Vehicle::GetPoolSize(); i += Ticks::DAY_TICKS) {
960 Vehicle *v = Vehicle::Get(i);
961 if (v == nullptr) continue;
962
963 /* Call the 32-day callback if needed */
964 if ((v->day_counter & 0x1F) == 0 && v->HasEngineType()) {
965 uint16_t callback = GetVehicleCallback(CBID_VEHICLE_32DAY_CALLBACK, 0, 0, v->engine_type, v);
966 if (callback != CALLBACK_FAILED) {
967 if (HasBit(callback, 0)) {
968 TriggerVehicle(v, VEHICLE_TRIGGER_CALLBACK_32); // Trigger vehicle trigger 10
969 }
970
971 /* After a vehicle trigger, the graphics and properties of the vehicle could change.
972 * Note: MarkDirty also invalidates the palette, which is the meaning of bit 1. So, nothing special there. */
973 if (callback != 0) v->First()->MarkDirty();
974
975 if (callback & ~3) ErrorUnknownCallbackResult(v->GetGRFID(), CBID_VEHICLE_32DAY_CALLBACK, callback);
976 }
977 }
978
979 /* This is called once per day for each vehicle, but not in the first tick of the day */
980 v->OnNewEconomyDay();
981 }
982}
983
984void CallVehicleTicks()
985{
986 _vehicles_to_autoreplace.clear();
987
988 RunEconomyVehicleDayProc();
989
990 {
991 PerformanceMeasurer framerate(PFE_GL_ECONOMY);
992 for (Station *st : Station::Iterate()) LoadUnloadStation(st);
993 }
994 PerformanceAccumulator::Reset(PFE_GL_TRAINS);
995 PerformanceAccumulator::Reset(PFE_GL_ROADVEHS);
996 PerformanceAccumulator::Reset(PFE_GL_SHIPS);
997 PerformanceAccumulator::Reset(PFE_GL_AIRCRAFT);
998
999 for (Vehicle *v : Vehicle::Iterate()) {
1000 [[maybe_unused]] size_t vehicle_index = v->index;
1001
1002 /* Vehicle could be deleted in this tick */
1003 if (!v->Tick()) {
1004 assert(Vehicle::Get(vehicle_index) == nullptr);
1005 continue;
1006 }
1007
1008 assert(Vehicle::Get(vehicle_index) == v);
1009
1010 switch (v->type) {
1011 default: break;
1012
1013 case VEH_TRAIN:
1014 case VEH_ROAD:
1015 case VEH_AIRCRAFT:
1016 case VEH_SHIP: {
1017 Vehicle *front = v->First();
1018
1019 if (v->vcache.cached_cargo_age_period != 0) {
1020 v->cargo_age_counter = std::min(v->cargo_age_counter, v->vcache.cached_cargo_age_period);
1021 if (--v->cargo_age_counter == 0) {
1022 v->cargo.AgeCargo();
1023 v->cargo_age_counter = v->vcache.cached_cargo_age_period;
1024 }
1025 }
1026
1027 /* Do not play any sound when crashed */
1028 if (front->vehstatus & VS_CRASHED) continue;
1029
1030 /* Do not play any sound when in depot or tunnel */
1031 if (v->vehstatus & VS_HIDDEN) continue;
1032
1033 /* Do not play any sound when stopped */
1034 if ((front->vehstatus & VS_STOPPED) && (front->type != VEH_TRAIN || front->cur_speed == 0)) continue;
1035
1036 /* Update motion counter for animation purposes. */
1037 v->motion_counter += front->cur_speed;
1038
1039 /* Check vehicle type specifics */
1040 switch (v->type) {
1041 case VEH_TRAIN:
1042 if (!Train::From(v)->IsEngine()) continue;
1043 break;
1044
1045 case VEH_ROAD:
1046 if (!RoadVehicle::From(v)->IsFrontEngine()) continue;
1047 break;
1048
1049 case VEH_AIRCRAFT:
1050 if (!Aircraft::From(v)->IsNormalAircraft()) continue;
1051 break;
1052
1053 default:
1054 break;
1055 }
1056
1057 /* Play a running sound if the motion counter passes 256 (Do we not skip sounds?) */
1058 if (GB(v->motion_counter, 0, 8) < front->cur_speed) PlayVehicleSound(v, VSE_RUNNING);
1059
1060 /* Play an alternating running sound every 16 ticks */
1061 if (GB(v->tick_counter, 0, 4) == 0) {
1062 /* Play running sound when speed > 0 and not braking */
1063 bool running = (front->cur_speed > 0) && !(front->vehstatus & (VS_STOPPED | VS_TRAIN_SLOWING));
1064 PlayVehicleSound(v, running ? VSE_RUNNING_16 : VSE_STOPPED_16);
1065 }
1066
1067 break;
1068 }
1069 }
1070 }
1071
1072 Backup<CompanyID> cur_company(_current_company);
1073 for (auto &it : _vehicles_to_autoreplace) {
1074 Vehicle *v = Vehicle::Get(it.first);
1075 /* Autoreplace needs the current company set as the vehicle owner */
1076 cur_company.Change(v->owner);
1077
1078 /* Start vehicle if we stopped them in VehicleEnteredDepotThisTick()
1079 * We need to stop them between VehicleEnteredDepotThisTick() and here or we risk that
1080 * they are already leaving the depot again before being replaced. */
1081 if (it.second) v->vehstatus &= ~VS_STOPPED;
1082
1083 /* Store the position of the effect as the vehicle pointer will become invalid later */
1084 int x = v->x_pos;
1085 int y = v->y_pos;
1086 int z = v->z_pos;
1087
1088 const Company *c = Company::Get(_current_company);
1089 SubtractMoneyFromCompany(CommandCost(EXPENSES_NEW_VEHICLES, (Money)c->settings.engine_renew_money));
1090 CommandCost res = Command<CMD_AUTOREPLACE_VEHICLE>::Do(DC_EXEC, v->index);
1091 SubtractMoneyFromCompany(CommandCost(EXPENSES_NEW_VEHICLES, -(Money)c->settings.engine_renew_money));
1092
1093 if (!IsLocalCompany()) continue;
1094
1095 if (res.Succeeded()) {
1096 ShowCostOrIncomeAnimation(x, y, z, res.GetCost());
1097 continue;
1098 }
1099
1100 StringID error_message = res.GetErrorMessage();
1101 if (error_message == STR_ERROR_AUTOREPLACE_NOTHING_TO_DO || error_message == INVALID_STRING_ID) continue;
1102
1103 if (error_message == STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY) error_message = STR_ERROR_AUTOREPLACE_MONEY_LIMIT;
1104
1105 StringID message;
1106 if (error_message == STR_ERROR_TRAIN_TOO_LONG_AFTER_REPLACEMENT) {
1107 message = error_message;
1108 } else {
1109 message = STR_NEWS_VEHICLE_AUTORENEW_FAILED;
1110 }
1111
1112 SetDParam(0, v->index);
1113 SetDParam(1, error_message);
1114 AddVehicleAdviceNewsItem(message, v->index);
1115 }
1116
1117 cur_company.Restore();
1118}
1119
1124 static void DoDrawVehicle(const Vehicle *v)
1125{
1126 PaletteID pal = PAL_NONE;
1127
1128 if (v->vehstatus & VS_DEFPAL) pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
1129
1130 /* Check whether the vehicle shall be transparent due to the game state */
1131 bool shadowed = (v->vehstatus & VS_SHADOW) != 0;
1132
1133 if (v->type == VEH_EFFECT) {
1134 /* Check whether the vehicle shall be transparent/invisible due to GUI settings.
1135 * However, transparent smoke and bubbles look weird, so always hide them. */
1136 TransparencyOption to = EffectVehicle::From(v)->GetTransparencyOption();
1137 if (to != TO_INVALID && (IsTransparencySet(to) || IsInvisibilitySet(to))) return;
1138 }
1139
1140 StartSpriteCombine();
1141 for (uint i = 0; i < v->sprite_cache.sprite_seq.count; ++i) {
1142 PaletteID pal2 = v->sprite_cache.sprite_seq.seq[i].pal;
1143 if (!pal2 || (v->vehstatus & VS_CRASHED)) pal2 = pal;
1144 AddSortableSpriteToDraw(v->sprite_cache.sprite_seq.seq[i].sprite, pal2, v->x_pos + v->x_offs, v->y_pos + v->y_offs,
1145 v->x_extent, v->y_extent, v->z_extent, v->z_pos, shadowed, v->x_bb_offs, v->y_bb_offs);
1146 }
1147 EndSpriteCombine();
1148}
1149
1154 void ViewportAddVehicles(DrawPixelInfo *dpi)
1155{
1156 /* The bounding rectangle */
1157 const int l = dpi->left;
1158 const int r = dpi->left + dpi->width;
1159 const int t = dpi->top;
1160 const int b = dpi->top + dpi->height;
1161
1162 /* Border size of MAX_VEHICLE_PIXEL_xy */
1163 const int xb = MAX_VEHICLE_PIXEL_X * ZOOM_BASE;
1164 const int yb = MAX_VEHICLE_PIXEL_Y * ZOOM_BASE;
1165
1166 /* The hash area to scan */
1167 int xl, xu, yl, yu;
1168
1169 if (dpi->width + xb < GEN_HASHX_SIZE) {
1170 xl = GEN_HASHX(l - xb);
1171 xu = GEN_HASHX(r);
1172 } else {
1173 /* scan whole hash row */
1174 xl = 0;
1175 xu = GEN_HASHX_MASK;
1176 }
1177
1178 if (dpi->height + yb < GEN_HASHY_SIZE) {
1179 yl = GEN_HASHY(t - yb);
1180 yu = GEN_HASHY(b);
1181 } else {
1182 /* scan whole column */
1183 yl = 0;
1184 yu = GEN_HASHY_MASK;
1185 }
1186
1187 for (int y = yl;; y = (y + GEN_HASHY_INC) & GEN_HASHY_MASK) {
1188 for (int x = xl;; x = (x + GEN_HASHX_INC) & GEN_HASHX_MASK) {
1189 const Vehicle *v = _vehicle_viewport_hash[x + y]; // already masked & 0xFFF
1190
1191 while (v != nullptr) {
1192
1193 if (!(v->vehstatus & VS_HIDDEN) &&
1194 l <= v->coord.right + xb &&
1195 t <= v->coord.bottom + yb &&
1196 r >= v->coord.left - xb &&
1197 b >= v->coord.top - yb)
1198 {
1199 /*
1200 * This vehicle can potentially be drawn as part of this viewport and
1201 * needs to be revalidated, as the sprite may not be correct.
1202 */
1203 if (v->sprite_cache.revalidate_before_draw) {
1204 VehicleSpriteSeq seq;
1205 v->GetImage(v->direction, EIT_ON_MAP, &seq);
1206
1207 if (seq.IsValid() && v->sprite_cache.sprite_seq != seq) {
1208 v->sprite_cache.sprite_seq = seq;
1209 /*
1210 * A sprite change may also result in a bounding box change,
1211 * so we need to update the bounding box again before we
1212 * check to see if the vehicle should be drawn. Note that
1213 * we can't interfere with the viewport hash at this point,
1214 * so we keep the original hash on the assumption there will
1215 * not be a significant change in the top and left coordinates
1216 * of the vehicle.
1217 */
1218 v->UpdateBoundingBoxCoordinates(false);
1219
1220 }
1221
1222 v->sprite_cache.revalidate_before_draw = false;
1223 }
1224
1225 if (l <= v->coord.right &&
1226 t <= v->coord.bottom &&
1227 r >= v->coord.left &&
1228 b >= v->coord.top) DoDrawVehicle(v);
1229 }
1230
1231 v = v->hash_viewport_next;
1232 }
1233
1234 if (x == xu) break;
1235 }
1236
1237 if (y == yu) break;
1238 }
1239}
1240
1248 Vehicle *CheckClickOnVehicle(const Viewport *vp, int x, int y)
1249{
1250 Vehicle *found = nullptr;
1251 uint dist, best_dist = UINT_MAX;
1252
1253 if ((uint)(x -= vp->left) >= (uint)vp->width || (uint)(y -= vp->top) >= (uint)vp->height) return nullptr;
1254
1255 x = ScaleByZoom(x, vp->zoom) + vp->virtual_left;
1256 y = ScaleByZoom(y, vp->zoom) + vp->virtual_top;
1257
1258 /* Border size of MAX_VEHICLE_PIXEL_xy */
1259 const int xb = MAX_VEHICLE_PIXEL_X * ZOOM_BASE;
1260 const int yb = MAX_VEHICLE_PIXEL_Y * ZOOM_BASE;
1261
1262 /* The hash area to scan */
1263 int xl = GEN_HASHX(x - xb);
1264 int xu = GEN_HASHX(x);
1265 int yl = GEN_HASHY(y - yb);
1266 int yu = GEN_HASHY(y);
1267
1268 for (int hy = yl;; hy = (hy + GEN_HASHY_INC) & GEN_HASHY_MASK) {
1269 for (int hx = xl;; hx = (hx + GEN_HASHX_INC) & GEN_HASHX_MASK) {
1270 Vehicle *v = _vehicle_viewport_hash[hx + hy]; // already masked & 0xFFF
1271
1272 while (v != nullptr) {
1273 if ((v->vehstatus & (VS_HIDDEN | VS_UNCLICKABLE)) == 0 &&
1274 x >= v->coord.left && x <= v->coord.right &&
1275 y >= v->coord.top && y <= v->coord.bottom) {
1276
1277 dist = std::max(
1278 abs(((v->coord.left + v->coord.right) >> 1) - x),
1279 abs(((v->coord.top + v->coord.bottom) >> 1) - y)
1280 );
1281
1282 if (dist < best_dist) {
1283 found = v;
1284 best_dist = dist;
1285 }
1286 }
1287 v = v->hash_viewport_next;
1288 }
1289 if (hx == xu) break;
1290 }
1291 if (hy == yu) break;
1292 }
1293
1294 return found;
1295}
1296
1301 void DecreaseVehicleValue(Vehicle *v)
1302{
1303 v->value -= v->value >> 8;
1304 SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
1305}
1306
1307static const uint8_t _breakdown_chance[64] = {
1308 3, 3, 3, 3, 3, 3, 3, 3,
1309 4, 4, 5, 5, 6, 6, 7, 7,
1310 8, 8, 9, 9, 10, 10, 11, 11,
1311 12, 13, 13, 13, 13, 14, 15, 16,
1312 17, 19, 21, 25, 28, 31, 34, 37,
1313 40, 44, 48, 52, 56, 60, 64, 68,
1314 72, 80, 90, 100, 110, 120, 130, 140,
1315 150, 170, 190, 210, 230, 250, 250, 250,
1316};
1317
1318void CheckVehicleBreakdown(Vehicle *v)
1319{
1320 int rel, rel_old;
1321
1322 /* decrease reliability */
1323 if (!_settings_game.order.no_servicing_if_no_breakdowns ||
1324 _settings_game.difficulty.vehicle_breakdowns != 0) {
1325 v->reliability = rel = std::max((rel_old = v->reliability) - v->reliability_spd_dec, 0);
1326 if ((rel_old >> 8) != (rel >> 8)) SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
1327 }
1328
1329 if (v->breakdown_ctr != 0 || (v->vehstatus & VS_STOPPED) ||
1330 _settings_game.difficulty.vehicle_breakdowns < 1 ||
1331 v->cur_speed < 5 || _game_mode == GM_MENU) {
1332 return;
1333 }
1334
1335 uint32_t r = Random();
1336
1337 /* increase chance of failure */
1338 int chance = v->breakdown_chance + 1;
1339 if (Chance16I(1, 25, r)) chance += 25;
1340 v->breakdown_chance = ClampTo<uint8_t>(chance);
1341
1342 /* calculate reliability value to use in comparison */
1343 rel = v->reliability;
1344 if (v->type == VEH_SHIP) rel += 0x6666;
1345
1346 /* reduced breakdowns? */
1347 if (_settings_game.difficulty.vehicle_breakdowns == 1) rel += 0x6666;
1348
1349 /* check if to break down */
1350 if (_breakdown_chance[ClampTo<uint16_t>(rel) >> 10] <= v->breakdown_chance) {
1351 v->breakdown_ctr = GB(r, 16, 6) + 0x3F;
1352 v->breakdown_delay = GB(r, 24, 7) + 0x80;
1353 v->breakdown_chance = 0;
1354 }
1355}
1356
1363 bool Vehicle::HandleBreakdown()
1364{
1365 /* Possible states for Vehicle::breakdown_ctr
1366 * 0 - vehicle is running normally
1367 * 1 - vehicle is currently broken down
1368 * 2 - vehicle is going to break down now
1369 * >2 - vehicle is counting down to the actual breakdown event */
1370 switch (this->breakdown_ctr) {
1371 case 0:
1372 return false;
1373
1374 case 2:
1375 this->breakdown_ctr = 1;
1376
1377 if (this->breakdowns_since_last_service != 255) {
1378 this->breakdowns_since_last_service++;
1379 }
1380
1381 if (this->type == VEH_AIRCRAFT) {
1382 /* Aircraft just need this flag, the rest is handled elsewhere */
1383 this->vehstatus |= VS_AIRCRAFT_BROKEN;
1384 } else {
1385 this->cur_speed = 0;
1386
1387 if (!PlayVehicleSound(this, VSE_BREAKDOWN)) {
1388 bool train_or_ship = this->type == VEH_TRAIN || this->type == VEH_SHIP;
1389 SndPlayVehicleFx((_settings_game.game_creation.landscape != LT_TOYLAND) ?
1390 (train_or_ship ? SND_10_BREAKDOWN_TRAIN_SHIP : SND_0F_BREAKDOWN_ROADVEHICLE) :
1391 (train_or_ship ? SND_3A_BREAKDOWN_TRAIN_SHIP_TOYLAND : SND_35_BREAKDOWN_ROADVEHICLE_TOYLAND), this);
1392 }
1393
1394 if (!(this->vehstatus & VS_HIDDEN) && !HasBit(EngInfo(this->engine_type)->misc_flags, EF_NO_BREAKDOWN_SMOKE)) {
1395 EffectVehicle *u = CreateEffectVehicleRel(this, 4, 4, 5, EV_BREAKDOWN_SMOKE);
1396 if (u != nullptr) u->animation_state = this->breakdown_delay * 2;
1397 }
1398 }
1399
1400 this->MarkDirty(); // Update graphics after speed is zeroed
1401 SetWindowDirty(WC_VEHICLE_VIEW, this->index);
1402 SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
1403
1404 [[fallthrough]];
1405 case 1:
1406 /* Aircraft breakdowns end only when arriving at the airport */
1407 if (this->type == VEH_AIRCRAFT) return false;
1408
1409 /* For trains this function is called twice per tick, so decrease v->breakdown_delay at half the rate */
1410 if ((this->tick_counter & (this->type == VEH_TRAIN ? 3 : 1)) == 0) {
1411 if (--this->breakdown_delay == 0) {
1412 this->breakdown_ctr = 0;
1413 this->MarkDirty();
1414 SetWindowDirty(WC_VEHICLE_VIEW, this->index);
1415 }
1416 }
1417 return true;
1418
1419 default:
1420 if (!this->current_order.IsType(OT_LOADING)) this->breakdown_ctr--;
1421 return false;
1422 }
1423}
1424
1429 void EconomyAgeVehicle(Vehicle *v)
1430{
1431 if (v->economy_age < EconomyTime::MAX_DATE) {
1432 v->economy_age++;
1433 if (v->IsPrimaryVehicle() && v->economy_age == VEHICLE_PROFIT_MIN_AGE + 1) GroupStatistics::VehicleReachedMinAge(v);
1434 }
1435}
1436
1441 void AgeVehicle(Vehicle *v)
1442{
1443 if (v->age < CalendarTime::MAX_DATE) v->age++;
1444
1445 if (!v->IsPrimaryVehicle() && (v->type != VEH_TRAIN || !Train::From(v)->IsEngine())) return;
1446
1447 auto age = v->age - v->max_age;
1448 for (int32_t i = 0; i <= 4; i++) {
1449 if (age == TimerGameCalendar::DateAtStartOfYear(i)) {
1450 v->reliability_spd_dec <<= 1;
1451 break;
1452 }
1453 }
1454
1455 SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
1456
1457 /* Don't warn if warnings are disabled */
1458 if (!_settings_client.gui.old_vehicle_warn) return;
1459
1460 /* Don't warn about vehicles which are non-primary (e.g., part of an articulated vehicle), don't belong to us, are crashed, or are stopped */
1461 if (v->Previous() != nullptr || v->owner != _local_company || (v->vehstatus & VS_CRASHED) != 0 || (v->vehstatus & VS_STOPPED) != 0) return;
1462
1463 const Company *c = Company::Get(v->owner);
1464 /* Don't warn if a renew is active */
1465 if (c->settings.engine_renew && v->GetEngine()->company_avail != 0) return;
1466 /* Don't warn if a replacement is active */
1467 if (EngineHasReplacementForCompany(c, v->engine_type, v->group_id)) return;
1468
1469 StringID str;
1470 if (age == TimerGameCalendar::DateAtStartOfYear(-1)) {
1471 str = STR_NEWS_VEHICLE_IS_GETTING_OLD;
1472 } else if (age == TimerGameCalendar::DateAtStartOfYear(0)) {
1473 str = STR_NEWS_VEHICLE_IS_GETTING_VERY_OLD;
1474 } else if (age > TimerGameCalendar::DateAtStartOfYear(0) && (age.base() % CalendarTime::DAYS_IN_LEAP_YEAR) == 0) {
1475 str = STR_NEWS_VEHICLE_IS_GETTING_VERY_OLD_AND;
1476 } else {
1477 return;
1478 }
1479
1480 SetDParam(0, v->index);
1481 AddVehicleAdviceNewsItem(str, v->index);
1482}
1483
1493uint8_t CalcPercentVehicleFilled(const Vehicle *front, StringID *colour)
1494{
1495 int count = 0;
1496 int max = 0;
1497 int cars = 0;
1498 int unloading = 0;
1499 bool loading = false;
1500
1501 bool is_loading = front->current_order.IsType(OT_LOADING);
1502
1503 /* The station may be nullptr when the (colour) string does not need to be set. */
1504 const Station *st = Station::GetIfValid(front->last_station_visited);
1505 assert(colour == nullptr || (st != nullptr && is_loading));
1506
1507 bool order_no_load = is_loading && (front->current_order.GetLoadType() & OLFB_NO_LOAD);
1508 bool order_full_load = is_loading && (front->current_order.GetLoadType() & OLFB_FULL_LOAD);
1509
1510 /* Count up max and used */
1511 for (const Vehicle *v = front; v != nullptr; v = v->Next()) {
1512 count += v->cargo.StoredCount();
1513 max += v->cargo_cap;
1514 if (v->cargo_cap != 0 && colour != nullptr) {
1515 unloading += HasBit(v->vehicle_flags, VF_CARGO_UNLOADING) ? 1 : 0;
1516 loading |= !order_no_load &&
1517 (order_full_load || st->goods[v->cargo_type].HasRating()) &&
1518 !HasBit(front->vehicle_flags, VF_LOADING_FINISHED) && !HasBit(front->vehicle_flags, VF_STOP_LOADING);
1519 cars++;
1520 }
1521 }
1522
1523 if (colour != nullptr) {
1524 if (unloading == 0 && loading) {
1525 *colour = STR_PERCENT_UP;
1526 } else if (unloading == 0 && !loading) {
1527 *colour = STR_PERCENT_NONE;
1528 } else if (cars == unloading || !loading) {
1529 *colour = STR_PERCENT_DOWN;
1530 } else {
1531 *colour = STR_PERCENT_UP_DOWN;
1532 }
1533 }
1534
1535 /* Train without capacity */
1536 if (max == 0) return 100;
1537
1538 /* Return the percentage */
1539 if (count * 2 < max) {
1540 /* Less than 50%; round up, so that 0% means really empty. */
1541 return CeilDiv(count * 100, max);
1542 } else {
1543 /* More than 50%; round down, so that 100% means really full. */
1544 return (count * 100) / max;
1545 }
1546}
1547
1552 void VehicleEnterDepot(Vehicle *v)
1553{
1554 /* Always work with the front of the vehicle */
1555 assert(v == v->First());
1556
1557 switch (v->type) {
1558 case VEH_TRAIN: {
1559 Train *t = Train::From(v);
1560 SetWindowClassesDirty(WC_TRAINS_LIST);
1561 /* Clear path reservation */
1562 SetDepotReservation(t->tile, false);
1563 if (_settings_client.gui.show_track_reservation) MarkTileDirtyByTile(t->tile);
1564
1565 UpdateSignalsOnSegment(t->tile, INVALID_DIAGDIR, t->owner);
1566 t->wait_counter = 0;
1567 t->force_proceed = TFP_NONE;
1568 ClrBit(t->flags, VRF_TOGGLE_REVERSE);
1569 t->ConsistChanged(CCF_ARRANGE);
1570 break;
1571 }
1572
1573 case VEH_ROAD:
1574 SetWindowClassesDirty(WC_ROADVEH_LIST);
1575 break;
1576
1577 case VEH_SHIP: {
1578 SetWindowClassesDirty(WC_SHIPS_LIST);
1579 Ship *ship = Ship::From(v);
1580 ship->state = TRACK_BIT_DEPOT;
1581 ship->UpdateCache();
1582 ship->UpdateViewport(true, true);
1583 SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
1584 break;
1585 }
1586
1587 case VEH_AIRCRAFT:
1588 SetWindowClassesDirty(WC_AIRCRAFT_LIST);
1589 HandleAircraftEnterHangar(Aircraft::From(v));
1590 break;
1591 default: NOT_REACHED();
1592 }
1593 SetWindowDirty(WC_VEHICLE_VIEW, v->index);
1594
1595 if (v->type != VEH_TRAIN) {
1596 /* Trains update the vehicle list when the first unit enters the depot and calls VehicleEnterDepot() when the last unit enters.
1597 * We only increase the number of vehicles when the first one enters, so we will not need to search for more vehicles in the depot */
1598 InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
1599 }
1600 SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
1601
1602 v->vehstatus |= VS_HIDDEN;
1603 v->cur_speed = 0;
1604
1605 VehicleServiceInDepot(v);
1606
1607 /* After a vehicle trigger, the graphics and properties of the vehicle could change. */
1608 TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT);
1609 v->MarkDirty();
1610
1611 InvalidateWindowData(WC_VEHICLE_VIEW, v->index);
1612
1613 if (v->current_order.IsType(OT_GOTO_DEPOT)) {
1614 SetWindowDirty(WC_VEHICLE_VIEW, v->index);
1615
1616 const Order *real_order = v->GetOrder(v->cur_real_order_index);
1617
1618 /* Test whether we are heading for this depot. If not, do nothing.
1619 * Note: The target depot for nearest-/manual-depot-orders is only updated on junctions, but we want to accept every depot. */
1620 if ((v->current_order.GetDepotOrderType() & ODTFB_PART_OF_ORDERS) &&
1621 real_order != nullptr && !(real_order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) &&
1622 (v->type == VEH_AIRCRAFT ? v->current_order.GetDestination() != GetStationIndex(v->tile) : v->dest_tile != v->tile)) {
1623 /* We are heading for another depot, keep driving. */
1624 return;
1625 }
1626
1627 if (v->current_order.IsRefit()) {
1628 Backup<CompanyID> cur_company(_current_company, v->owner);
1629 CommandCost cost = std::get<0>(Command<CMD_REFIT_VEHICLE>::Do(DC_EXEC, v->index, v->current_order.GetRefitCargo(), 0xFF, false, false, 0));
1630 cur_company.Restore();
1631
1632 if (cost.Failed()) {
1633 _vehicles_to_autoreplace[v->index] = false;
1634 if (v->owner == _local_company) {
1635 /* Notify the user that we stopped the vehicle */
1636 SetDParam(0, v->index);
1637 AddVehicleAdviceNewsItem(STR_NEWS_ORDER_REFIT_FAILED, v->index);
1638 }
1639 } else if (cost.GetCost() != 0) {
1640 v->profit_this_year -= cost.GetCost() << 8;
1641 if (v->owner == _local_company) {
1642 ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost.GetCost());
1643 }
1644 }
1645 }
1646
1647 if (v->current_order.GetDepotOrderType() & ODTFB_PART_OF_ORDERS) {
1648 /* Part of orders */
1649 v->DeleteUnreachedImplicitOrders();
1650 UpdateVehicleTimetable(v, true);
1651 v->IncrementImplicitOrderIndex();
1652 }
1653 if (v->current_order.GetDepotActionType() & ODATFB_HALT) {
1654 /* Vehicles are always stopped on entering depots. Do not restart this one. */
1655 _vehicles_to_autoreplace[v->index] = false;
1656 /* Invalidate last_loading_station. As the link from the station
1657 * before the stop to the station after the stop can't be predicted
1658 * we shouldn't construct it when the vehicle visits the next stop. */
1659 v->last_loading_station = INVALID_STATION;
1660
1661 /* Clear unbunching data. */
1662 v->ResetDepotUnbunching();
1663
1664 /* Announce that the vehicle is waiting to players and AIs. */
1665 if (v->owner == _local_company) {
1666 SetDParam(0, v->index);
1667 AddVehicleAdviceNewsItem(STR_NEWS_TRAIN_IS_WAITING + v->type, v->index);
1668 }
1669 AI::NewEvent(v->owner, new ScriptEventVehicleWaitingInDepot(v->index));
1670 }
1671
1672 /* If we've entered our unbunching depot, record the round trip duration. */
1673 if (v->current_order.GetDepotActionType() & ODATFB_UNBUNCH && v->depot_unbunching_last_departure > 0) {
1674 TimerGameTick::Ticks measured_round_trip = TimerGameTick::counter - v->depot_unbunching_last_departure;
1675 if (v->round_trip_time == 0) {
1676 /* This might be our first round trip. */
1677 v->round_trip_time = measured_round_trip;
1678 } else {
1679 /* If we have a previous trip, smooth the effects of outlier trip calculations caused by jams or other interference. */
1680 v->round_trip_time = Clamp(measured_round_trip, (v->round_trip_time / 2), ClampTo<TimerGameTick::Ticks>(v->round_trip_time * 2));
1681 }
1682 }
1683
1684 v->current_order.MakeDummy();
1685 }
1686}
1687
1688
1693 void Vehicle::UpdatePosition()
1694{
1695 UpdateVehicleTileHash(this, false);
1696}
1697
1702 void Vehicle::UpdateBoundingBoxCoordinates(bool update_cache) const
1703{
1704 Rect new_coord;
1705 this->sprite_cache.sprite_seq.GetBounds(&new_coord);
1706
1707 Point pt = RemapCoords(this->x_pos + this->x_offs, this->y_pos + this->y_offs, this->z_pos);
1708 new_coord.left += pt.x;
1709 new_coord.top += pt.y;
1710 new_coord.right += pt.x + 2 * ZOOM_BASE;
1711 new_coord.bottom += pt.y + 2 * ZOOM_BASE;
1712
1713 if (update_cache) {
1714 /*
1715 * If the old coordinates are invalid, set the cache to the new coordinates for correct
1716 * behaviour the next time the coordinate cache is checked.
1717 */
1718 this->sprite_cache.old_coord = this->coord.left == INVALID_COORD ? new_coord : this->coord;
1719 }
1720 else {
1721 /* Extend the bounds of the existing cached bounding box so the next dirty window is correct */
1722 this->sprite_cache.old_coord.left = std::min(this->sprite_cache.old_coord.left, this->coord.left);
1723 this->sprite_cache.old_coord.top = std::min(this->sprite_cache.old_coord.top, this->coord.top);
1724 this->sprite_cache.old_coord.right = std::max(this->sprite_cache.old_coord.right, this->coord.right);
1725 this->sprite_cache.old_coord.bottom = std::max(this->sprite_cache.old_coord.bottom, this->coord.bottom);
1726 }
1727
1728 this->coord = new_coord;
1729}
1730
1735 void Vehicle::UpdateViewport(bool dirty)
1736{
1737 /* If the existing cache is invalid we should ignore it, as it will be set to the current coords by UpdateBoundingBoxCoordinates */
1738 bool ignore_cached_coords = this->sprite_cache.old_coord.left == INVALID_COORD;
1739
1740 this->UpdateBoundingBoxCoordinates(true);
1741
1742 if (ignore_cached_coords) {
1743 UpdateVehicleViewportHash(this, this->coord.left, this->coord.top, INVALID_COORD, INVALID_COORD);
1744 } else {
1745 UpdateVehicleViewportHash(this, this->coord.left, this->coord.top, this->sprite_cache.old_coord.left, this->sprite_cache.old_coord.top);
1746 }
1747
1748 if (dirty) {
1749 if (ignore_cached_coords) {
1750 this->sprite_cache.is_viewport_candidate = this->MarkAllViewportsDirty();
1751 } else {
1752 this->sprite_cache.is_viewport_candidate = ::MarkAllViewportsDirty(
1753 std::min(this->sprite_cache.old_coord.left, this->coord.left),
1754 std::min(this->sprite_cache.old_coord.top, this->coord.top),
1755 std::max(this->sprite_cache.old_coord.right, this->coord.right),
1756 std::max(this->sprite_cache.old_coord.bottom, this->coord.bottom));
1757 }
1758 }
1759}
1760
1764 void Vehicle::UpdatePositionAndViewport()
1765{
1766 this->UpdatePosition();
1767 this->UpdateViewport(true);
1768}
1769
1774 bool Vehicle::MarkAllViewportsDirty() const
1775{
1776 return ::MarkAllViewportsDirty(this->coord.left, this->coord.top, this->coord.right, this->coord.bottom);
1777}
1778
1784 GetNewVehiclePosResult GetNewVehiclePos(const Vehicle *v)
1785{
1786 static const int8_t _delta_coord[16] = {
1787 -1,-1,-1, 0, 1, 1, 1, 0, /* x */
1788 -1, 0, 1, 1, 1, 0,-1,-1, /* y */
1789 };
1790
1791 int x = v->x_pos + _delta_coord[v->direction];
1792 int y = v->y_pos + _delta_coord[v->direction + 8];
1793
1794 GetNewVehiclePosResult gp;
1795 gp.x = x;
1796 gp.y = y;
1797 gp.old_tile = v->tile;
1798 gp.new_tile = TileVirtXY(x, y);
1799 return gp;
1800}
1801
1802static const Direction _new_direction_table[] = {
1803 DIR_N, DIR_NW, DIR_W,
1804 DIR_NE, DIR_SE, DIR_SW,
1805 DIR_E, DIR_SE, DIR_S
1806};
1807
1808 Direction GetDirectionTowards(const Vehicle *v, int x, int y)
1809{
1810 int i = 0;
1811
1812 if (y >= v->y_pos) {
1813 if (y != v->y_pos) i += 3;
1814 i += 3;
1815 }
1816
1817 if (x >= v->x_pos) {
1818 if (x != v->x_pos) i++;
1819 i++;
1820 }
1821
1822 Direction dir = v->direction;
1823
1824 DirDiff dirdiff = DirDifference(_new_direction_table[i], dir);
1825 if (dirdiff == DIRDIFF_SAME) return dir;
1826 return ChangeDir(dir, dirdiff > DIRDIFF_REVERSE ? DIRDIFF_45LEFT : DIRDIFF_45RIGHT);
1827}
1828
1838 VehicleEnterTileStatus VehicleEnterTile(Vehicle *v, TileIndex tile, int x, int y)
1839{
1840 return _tile_type_procs[GetTileType(tile)]->vehicle_enter_tile_proc(v, tile, x, y);
1841}
1842
1848 UnitID FreeUnitIDGenerator::NextID() const
1849{
1850 for (auto it = std::begin(this->used_bitmap); it != std::end(this->used_bitmap); ++it) {
1851 BitmapStorage available = ~(*it);
1852 if (available == 0) continue;
1853 return static_cast<UnitID>(std::distance(std::begin(this->used_bitmap), it) * BITMAP_SIZE + FindFirstBit(available) + 1);
1854 }
1855 return static_cast<UnitID>(this->used_bitmap.size() * BITMAP_SIZE + 1);
1856}
1857
1863 UnitID FreeUnitIDGenerator::UseID(UnitID index)
1864{
1865 if (index == 0 || index == UINT16_MAX) return index;
1866
1867 index--;
1868
1869 size_t slot = index / BITMAP_SIZE;
1870 if (slot >= this->used_bitmap.size()) this->used_bitmap.resize(slot + 1);
1871 SetBit(this->used_bitmap[index / BITMAP_SIZE], index % BITMAP_SIZE);
1872
1873 return index + 1;
1874}
1875
1880 void FreeUnitIDGenerator::ReleaseID(UnitID index)
1881{
1882 if (index == 0 || index == UINT16_MAX) return;
1883
1884 index--;
1885
1886 assert(index / BITMAP_SIZE < this->used_bitmap.size());
1887 ClrBit(this->used_bitmap[index / BITMAP_SIZE], index % BITMAP_SIZE);
1888}
1889
1895 UnitID GetFreeUnitNumber(VehicleType type)
1896{
1897 /* Check whether it is allowed to build another vehicle. */
1898 uint max_veh;
1899 switch (type) {
1900 case VEH_TRAIN: max_veh = _settings_game.vehicle.max_trains; break;
1901 case VEH_ROAD: max_veh = _settings_game.vehicle.max_roadveh; break;
1902 case VEH_SHIP: max_veh = _settings_game.vehicle.max_ships; break;
1903 case VEH_AIRCRAFT: max_veh = _settings_game.vehicle.max_aircraft; break;
1904 default: NOT_REACHED();
1905 }
1906
1907 const Company *c = Company::Get(_current_company);
1908 if (c->group_all[type].num_vehicle >= max_veh) return UINT16_MAX; // Currently already at the limit, no room to make a new one.
1909
1910 return c->freeunits[type].NextID();
1911}
1912
1913
1922 bool CanBuildVehicleInfrastructure(VehicleType type, uint8_t subtype)
1923{
1924 assert(IsCompanyBuildableVehicleType(type));
1925
1926 if (!Company::IsValidID(_local_company)) return false;
1927
1928 UnitID max;
1929 switch (type) {
1930 case VEH_TRAIN:
1931 if (!HasAnyRailTypesAvail(_local_company)) return false;
1932 max = _settings_game.vehicle.max_trains;
1933 break;
1934 case VEH_ROAD:
1935 if (!HasAnyRoadTypesAvail(_local_company, (RoadTramType)subtype)) return false;
1936 max = _settings_game.vehicle.max_roadveh;
1937 break;
1938 case VEH_SHIP: max = _settings_game.vehicle.max_ships; break;
1939 case VEH_AIRCRAFT: max = _settings_game.vehicle.max_aircraft; break;
1940 default: NOT_REACHED();
1941 }
1942
1943 /* We can build vehicle infrastructure when we may build the vehicle type */
1944 if (max > 0) {
1945 /* Can we actually build the vehicle type? */
1946 for (const Engine *e : Engine::IterateType(type)) {
1947 if (type == VEH_ROAD && GetRoadTramType(e->u.road.roadtype) != (RoadTramType)subtype) continue;
1948 if (HasBit(e->company_avail, _local_company)) return true;
1949 }
1950 return false;
1951 }
1952
1953 /* We should be able to build infrastructure when we have the actual vehicle type */
1954 for (const Vehicle *v : Vehicle::Iterate()) {
1955 if (v->type == VEH_ROAD && GetRoadTramType(RoadVehicle::From(v)->roadtype) != (RoadTramType)subtype) continue;
1956 if (v->owner == _local_company && v->type == type) return true;
1957 }
1958
1959 return false;
1960}
1961
1962
1970 LiveryScheme GetEngineLiveryScheme(EngineID engine_type, EngineID parent_engine_type, const Vehicle *v)
1971{
1972 CargoID cargo_type = v == nullptr ? INVALID_CARGO : v->cargo_type;
1973 const Engine *e = Engine::Get(engine_type);
1974 switch (e->type) {
1975 default: NOT_REACHED();
1976 case VEH_TRAIN:
1977 if (v != nullptr && parent_engine_type != INVALID_ENGINE && (UsesWagonOverride(v) || (v->IsArticulatedPart() && e->u.rail.railveh_type != RAILVEH_WAGON))) {
1978 /* Wagonoverrides use the colour scheme of the front engine.
1979 * Articulated parts use the colour scheme of the first part. (Not supported for articulated wagons) */
1980 engine_type = parent_engine_type;
1981 e = Engine::Get(engine_type);
1982 /* Note: Luckily cargo_type is not needed for engines */
1983 }
1984
1985 if (!IsValidCargoID(cargo_type)) cargo_type = e->GetDefaultCargoType();
1986 if (!IsValidCargoID(cargo_type)) cargo_type = GetCargoIDByLabel(CT_GOODS); // The vehicle does not carry anything, let's pick some freight cargo
1987 assert(IsValidCargoID(cargo_type));
1988 if (e->u.rail.railveh_type == RAILVEH_WAGON) {
1989 if (!CargoSpec::Get(cargo_type)->is_freight) {
1990 if (parent_engine_type == INVALID_ENGINE) {
1991 return LS_PASSENGER_WAGON_STEAM;
1992 } else {
1993 bool is_mu = HasBit(EngInfo(parent_engine_type)->misc_flags, EF_RAIL_IS_MU);
1994 switch (RailVehInfo(parent_engine_type)->engclass) {
1995 default: NOT_REACHED();
1996 case EC_STEAM: return LS_PASSENGER_WAGON_STEAM;
1997 case EC_DIESEL: return is_mu ? LS_DMU : LS_PASSENGER_WAGON_DIESEL;
1998 case EC_ELECTRIC: return is_mu ? LS_EMU : LS_PASSENGER_WAGON_ELECTRIC;
1999 case EC_MONORAIL: return LS_PASSENGER_WAGON_MONORAIL;
2000 case EC_MAGLEV: return LS_PASSENGER_WAGON_MAGLEV;
2001 }
2002 }
2003 } else {
2004 return LS_FREIGHT_WAGON;
2005 }
2006 } else {
2007 bool is_mu = HasBit(e->info.misc_flags, EF_RAIL_IS_MU);
2008
2009 switch (e->u.rail.engclass) {
2010 default: NOT_REACHED();
2011 case EC_STEAM: return LS_STEAM;
2012 case EC_DIESEL: return is_mu ? LS_DMU : LS_DIESEL;
2013 case EC_ELECTRIC: return is_mu ? LS_EMU : LS_ELECTRIC;
2014 case EC_MONORAIL: return LS_MONORAIL;
2015 case EC_MAGLEV: return LS_MAGLEV;
2016 }
2017 }
2018
2019 case VEH_ROAD:
2020 /* Always use the livery of the front */
2021 if (v != nullptr && parent_engine_type != INVALID_ENGINE) {
2022 engine_type = parent_engine_type;
2023 e = Engine::Get(engine_type);
2024 cargo_type = v->First()->cargo_type;
2025 }
2026 if (!IsValidCargoID(cargo_type)) cargo_type = e->GetDefaultCargoType();
2027 if (!IsValidCargoID(cargo_type)) cargo_type = GetCargoIDByLabel(CT_GOODS); // The vehicle does not carry anything, let's pick some freight cargo
2028 assert(IsValidCargoID(cargo_type));
2029
2030 /* Important: Use Tram Flag of front part. Luckily engine_type refers to the front part here. */
2031 if (HasBit(e->info.misc_flags, EF_ROAD_TRAM)) {
2032 /* Tram */
2033 return IsCargoInClass(cargo_type, CC_PASSENGERS) ? LS_PASSENGER_TRAM : LS_FREIGHT_TRAM;
2034 } else {
2035 /* Bus or truck */
2036 return IsCargoInClass(cargo_type, CC_PASSENGERS) ? LS_BUS : LS_TRUCK;
2037 }
2038
2039 case VEH_SHIP:
2040 if (!IsValidCargoID(cargo_type)) cargo_type = e->GetDefaultCargoType();
2041 if (!IsValidCargoID(cargo_type)) cargo_type = GetCargoIDByLabel(CT_GOODS); // The vehicle does not carry anything, let's pick some freight cargo
2042 assert(IsValidCargoID(cargo_type));
2043 return IsCargoInClass(cargo_type, CC_PASSENGERS) ? LS_PASSENGER_SHIP : LS_FREIGHT_SHIP;
2044
2045 case VEH_AIRCRAFT:
2046 switch (e->u.air.subtype) {
2047 case AIR_HELI: return LS_HELICOPTER;
2048 case AIR_CTOL: return LS_SMALL_PLANE;
2049 case AIR_CTOL | AIR_FAST: return LS_LARGE_PLANE;
2050 default: NOT_REACHED();
2051 }
2052 }
2053}
2054
2064 const Livery *GetEngineLivery(EngineID engine_type, CompanyID company, EngineID parent_engine_type, const Vehicle *v, uint8_t livery_setting)
2065{
2066 const Company *c = Company::Get(company);
2067 LiveryScheme scheme = LS_DEFAULT;
2068
2069 if (livery_setting == LIT_ALL || (livery_setting == LIT_COMPANY && company == _local_company)) {
2070 if (v != nullptr) {
2071 const Group *g = Group::GetIfValid(v->First()->group_id);
2072 if (g != nullptr) {
2073 /* Traverse parents until we find a livery or reach the top */
2074 while (g->livery.in_use == 0 && g->parent != INVALID_GROUP) {
2075 g = Group::Get(g->parent);
2076 }
2077 if (g->livery.in_use != 0) return &g->livery;
2078 }
2079 }
2080
2081 /* The default livery is always available for use, but its in_use flag determines
2082 * whether any _other_ liveries are in use. */
2083 if (c->livery[LS_DEFAULT].in_use != 0) {
2084 /* Determine the livery scheme to use */
2085 scheme = GetEngineLiveryScheme(engine_type, parent_engine_type, v);
2086 }
2087 }
2088
2089 return &c->livery[scheme];
2090}
2091
2092
2093static PaletteID GetEngineColourMap(EngineID engine_type, CompanyID company, EngineID parent_engine_type, const Vehicle *v)
2094{
2095 PaletteID map = (v != nullptr) ? v->colourmap : PAL_NONE;
2096
2097 /* Return cached value if any */
2098 if (map != PAL_NONE) return map;
2099
2100 const Engine *e = Engine::Get(engine_type);
2101
2102 /* Check if we should use the colour map callback */
2103 if (HasBit(e->info.callback_mask, CBM_VEHICLE_COLOUR_REMAP)) {
2104 uint16_t callback = GetVehicleCallback(CBID_VEHICLE_COLOUR_MAPPING, 0, 0, engine_type, v);
2105 /* Failure means "use the default two-colour" */
2106 if (callback != CALLBACK_FAILED) {
2107 static_assert(PAL_NONE == 0); // Returning 0x4000 (resp. 0xC000) coincidences with default value (PAL_NONE)
2108 map = GB(callback, 0, 14);
2109 /* If bit 14 is set, then the company colours are applied to the
2110 * map else it's returned as-is. */
2111 if (!HasBit(callback, 14)) {
2112 /* Update cache */
2113 if (v != nullptr) const_cast<Vehicle *>(v)->colourmap = map;
2114 return map;
2115 }
2116 }
2117 }
2118
2119 bool twocc = HasBit(e->info.misc_flags, EF_USES_2CC);
2120
2121 if (map == PAL_NONE) map = twocc ? (PaletteID)SPR_2CCMAP_BASE : (PaletteID)PALETTE_RECOLOUR_START;
2122
2123 /* Spectator has news shown too, but has invalid company ID - as well as dedicated server */
2124 if (!Company::IsValidID(company)) return map;
2125
2126 const Livery *livery = GetEngineLivery(engine_type, company, parent_engine_type, v, _settings_client.gui.liveries);
2127
2128 map += livery->colour1;
2129 if (twocc) map += livery->colour2 * 16;
2130
2131 /* Update cache */
2132 if (v != nullptr) const_cast<Vehicle *>(v)->colourmap = map;
2133 return map;
2134}
2135
2142 PaletteID GetEnginePalette(EngineID engine_type, CompanyID company)
2143{
2144 return GetEngineColourMap(engine_type, company, INVALID_ENGINE, nullptr);
2145}
2146
2152 PaletteID GetVehiclePalette(const Vehicle *v)
2153{
2154 if (v->IsGroundVehicle()) {
2155 return GetEngineColourMap(v->engine_type, v->owner, v->GetGroundVehicleCache()->first_engine, v);
2156 }
2157
2158 return GetEngineColourMap(v->engine_type, v->owner, INVALID_ENGINE, v);
2159}
2160
2164 void Vehicle::DeleteUnreachedImplicitOrders()
2165{
2166 if (this->IsGroundVehicle()) {
2167 uint16_t &gv_flags = this->GetGroundVehicleFlags();
2168 if (HasBit(gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS)) {
2169 /* Do not delete orders, only skip them */
2170 ClrBit(gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS);
2171 this->cur_implicit_order_index = this->cur_real_order_index;
2172 InvalidateVehicleOrder(this, 0);
2173 return;
2174 }
2175 }
2176
2177 const Order *order = this->GetOrder(this->cur_implicit_order_index);
2178 while (order != nullptr) {
2179 if (this->cur_implicit_order_index == this->cur_real_order_index) break;
2180
2181 if (order->IsType(OT_IMPLICIT)) {
2182 DeleteOrder(this, this->cur_implicit_order_index);
2183 /* DeleteOrder does various magic with order_indices, so resync 'order' with 'cur_implicit_order_index' */
2184 order = this->GetOrder(this->cur_implicit_order_index);
2185 } else {
2186 /* Skip non-implicit orders, e.g. service-orders */
2187 order = order->next;
2188 this->cur_implicit_order_index++;
2189 }
2190
2191 /* Wrap around */
2192 if (order == nullptr) {
2193 order = this->GetOrder(0);
2194 this->cur_implicit_order_index = 0;
2195 }
2196 }
2197}
2198
2203 void Vehicle::BeginLoading()
2204{
2205 assert(IsTileType(this->tile, MP_STATION) || this->type == VEH_SHIP);
2206
2207 TimerGameTick::Ticks travel_time = TimerGameTick::counter - this->last_loading_tick;
2208 if (this->current_order.IsType(OT_GOTO_STATION) &&
2209 this->current_order.GetDestination() == this->last_station_visited) {
2210 this->DeleteUnreachedImplicitOrders();
2211
2212 /* Now both order indices point to the destination station, and we can start loading */
2213 this->current_order.MakeLoading(true);
2214 UpdateVehicleTimetable(this, true);
2215
2216 /* Furthermore add the Non Stop flag to mark that this station
2217 * is the actual destination of the vehicle, which is (for example)
2218 * necessary to be known for HandleTrainLoading to determine
2219 * whether the train is lost or not; not marking a train lost
2220 * that arrives at random stations is bad. */
2221 this->current_order.SetNonStopType(ONSF_NO_STOP_AT_ANY_STATION);
2222
2223 } else {
2224 /* We weren't scheduled to stop here. Insert an implicit order
2225 * to show that we are stopping here.
2226 * While only groundvehicles have implicit orders, e.g. aircraft might still enter
2227 * the 'wrong' terminal when skipping orders etc. */
2228 Order *in_list = this->GetOrder(this->cur_implicit_order_index);
2229 if (this->IsGroundVehicle() &&
2230 (in_list == nullptr || !in_list->IsType(OT_IMPLICIT) ||
2231 in_list->GetDestination() != this->last_station_visited)) {
2232 bool suppress_implicit_orders = HasBit(this->GetGroundVehicleFlags(), GVF_SUPPRESS_IMPLICIT_ORDERS);
2233 /* Do not create consecutive duplicates of implicit orders */
2234 Order *prev_order = this->cur_implicit_order_index > 0 ? this->GetOrder(this->cur_implicit_order_index - 1) : (this->GetNumOrders() > 1 ? this->GetLastOrder() : nullptr);
2235 if (prev_order == nullptr ||
2236 (!prev_order->IsType(OT_IMPLICIT) && !prev_order->IsType(OT_GOTO_STATION)) ||
2237 prev_order->GetDestination() != this->last_station_visited) {
2238
2239 /* Prefer deleting implicit orders instead of inserting new ones,
2240 * so test whether the right order follows later. In case of only
2241 * implicit orders treat the last order in the list like an
2242 * explicit one, except if the overall number of orders surpasses
2243 * IMPLICIT_ORDER_ONLY_CAP. */
2244 int target_index = this->cur_implicit_order_index;
2245 bool found = false;
2246 while (target_index != this->cur_real_order_index || this->GetNumManualOrders() == 0) {
2247 const Order *order = this->GetOrder(target_index);
2248 if (order == nullptr) break; // No orders.
2249 if (order->IsType(OT_IMPLICIT) && order->GetDestination() == this->last_station_visited) {
2250 found = true;
2251 break;
2252 }
2253 target_index++;
2254 if (target_index >= this->orders->GetNumOrders()) {
2255 if (this->GetNumManualOrders() == 0 &&
2256 this->GetNumOrders() < IMPLICIT_ORDER_ONLY_CAP) {
2257 break;
2258 }
2259 target_index = 0;
2260 }
2261 if (target_index == this->cur_implicit_order_index) break; // Avoid infinite loop.
2262 }
2263
2264 if (found) {
2265 if (suppress_implicit_orders) {
2266 /* Skip to the found order */
2267 this->cur_implicit_order_index = target_index;
2268 InvalidateVehicleOrder(this, 0);
2269 } else {
2270 /* Delete all implicit orders up to the station we just reached */
2271 const Order *order = this->GetOrder(this->cur_implicit_order_index);
2272 while (!order->IsType(OT_IMPLICIT) || order->GetDestination() != this->last_station_visited) {
2273 if (order->IsType(OT_IMPLICIT)) {
2274 DeleteOrder(this, this->cur_implicit_order_index);
2275 /* DeleteOrder does various magic with order_indices, so resync 'order' with 'cur_implicit_order_index' */
2276 order = this->GetOrder(this->cur_implicit_order_index);
2277 } else {
2278 /* Skip non-implicit orders, e.g. service-orders */
2279 order = order->next;
2280 this->cur_implicit_order_index++;
2281 }
2282
2283 /* Wrap around */
2284 if (order == nullptr) {
2285 order = this->GetOrder(0);
2286 this->cur_implicit_order_index = 0;
2287 }
2288 assert(order != nullptr);
2289 }
2290 }
2291 } else if (!suppress_implicit_orders &&
2292 ((this->orders == nullptr ? OrderList::CanAllocateItem() : this->orders->GetNumOrders() < MAX_VEH_ORDER_ID)) &&
2293 Order::CanAllocateItem()) {
2294 /* Insert new implicit order */
2295 Order *implicit_order = new Order();
2296 implicit_order->MakeImplicit(this->last_station_visited);
2297 InsertOrder(this, implicit_order, this->cur_implicit_order_index);
2298 if (this->cur_implicit_order_index > 0) --this->cur_implicit_order_index;
2299
2300 /* InsertOrder disabled creation of implicit orders for all vehicles with the same implicit order.
2301 * Reenable it for this vehicle */
2302 uint16_t &gv_flags = this->GetGroundVehicleFlags();
2303 ClrBit(gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS);
2304 }
2305 }
2306 }
2307 this->current_order.MakeLoading(false);
2308 }
2309
2310 if (this->last_loading_station != INVALID_STATION &&
2311 this->last_loading_station != this->last_station_visited &&
2312 ((this->current_order.GetLoadType() & OLFB_NO_LOAD) == 0 ||
2313 (this->current_order.GetUnloadType() & OUFB_NO_UNLOAD) == 0)) {
2314 IncreaseStats(Station::Get(this->last_loading_station), this, this->last_station_visited, travel_time);
2315 }
2316
2317 PrepareUnload(this);
2318
2319 SetWindowDirty(GetWindowClassForVehicleType(this->type), this->owner);
2320 SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
2321 SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
2322 SetWindowDirty(WC_STATION_VIEW, this->last_station_visited);
2323
2324 Station::Get(this->last_station_visited)->MarkTilesDirty(true);
2325 this->cur_speed = 0;
2326 this->MarkDirty();
2327}
2328
2334 void Vehicle::CancelReservation(StationID next, Station *st)
2335{
2336 for (Vehicle *v = this; v != nullptr; v = v->next) {
2337 VehicleCargoList &cargo = v->cargo;
2338 if (cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0) {
2339 Debug(misc, 1, "cancelling cargo reservation");
2340 cargo.Return(UINT_MAX, &st->goods[v->cargo_type].cargo, next, v->tile);
2341 }
2342 cargo.KeepAll();
2343 }
2344}
2345
2350 void Vehicle::LeaveStation()
2351{
2352 assert(this->current_order.IsType(OT_LOADING));
2353
2354 delete this->cargo_payment;
2355 assert(this->cargo_payment == nullptr); // cleared by ~CargoPayment
2356
2357 /* Only update the timetable if the vehicle was supposed to stop here. */
2358 if (this->current_order.GetNonStopType() != ONSF_STOP_EVERYWHERE) UpdateVehicleTimetable(this, false);
2359
2360 if ((this->current_order.GetLoadType() & OLFB_NO_LOAD) == 0 ||
2361 (this->current_order.GetUnloadType() & OUFB_NO_UNLOAD) == 0) {
2362 if (this->current_order.CanLeaveWithCargo(this->last_loading_station != INVALID_STATION)) {
2363 /* Refresh next hop stats to make sure we've done that at least once
2364 * during the stop and that refit_cap == cargo_cap for each vehicle in
2365 * the consist. */
2366 this->ResetRefitCaps();
2367 LinkRefresher::Run(this);
2368
2369 /* if the vehicle could load here or could stop with cargo loaded set the last loading station */
2370 this->last_loading_station = this->last_station_visited;
2371 this->last_loading_tick = TimerGameTick::counter;
2372 } else {
2373 /* if the vehicle couldn't load and had to unload or transfer everything
2374 * set the last loading station to invalid as it will leave empty. */
2375 this->last_loading_station = INVALID_STATION;
2376 }
2377 }
2378
2379 this->current_order.MakeLeaveStation();
2380 Station *st = Station::Get(this->last_station_visited);
2381 this->CancelReservation(INVALID_STATION, st);
2382 st->loading_vehicles.remove(this);
2383
2384 HideFillingPercent(&this->fill_percent_te_id);
2385 trip_occupancy = CalcPercentVehicleFilled(this, nullptr);
2386
2387 if (this->type == VEH_TRAIN && !(this->vehstatus & VS_CRASHED)) {
2388 /* Trigger station animation (trains only) */
2389 if (IsTileType(this->tile, MP_STATION)) {
2390 TriggerStationRandomisation(st, this->tile, SRT_TRAIN_DEPARTS);
2391 TriggerStationAnimation(st, this->tile, SAT_TRAIN_DEPARTS);
2392 }
2393
2394 SetBit(Train::From(this)->flags, VRF_LEAVING_STATION);
2395 }
2396 if (this->type == VEH_ROAD && !(this->vehstatus & VS_CRASHED)) {
2397 /* Trigger road stop animation */
2398 if (IsStationRoadStopTile(this->tile)) {
2399 TriggerRoadStopRandomisation(st, this->tile, RSRT_VEH_DEPARTS);
2400 TriggerRoadStopAnimation(st, this->tile, SAT_TRAIN_DEPARTS);
2401 }
2402 }
2403
2404
2405 this->MarkDirty();
2406}
2407
2411 void Vehicle::ResetRefitCaps()
2412{
2413 for (Vehicle *v = this; v != nullptr; v = v->Next()) v->refit_cap = v->cargo_cap;
2414}
2415
2419 void Vehicle::ReleaseUnitNumber()
2420{
2421 Company::Get(this->owner)->freeunits[this->type].ReleaseID(this->unitnumber);
2422 this->unitnumber = 0;
2423}
2424
2430 void Vehicle::HandleLoading(bool mode)
2431{
2432 switch (this->current_order.GetType()) {
2433 case OT_LOADING: {
2434 TimerGameTick::Ticks wait_time = std::max(this->current_order.GetTimetabledWait() - this->lateness_counter, 0);
2435
2436 /* Not the first call for this tick, or still loading */
2437 if (mode || !HasBit(this->vehicle_flags, VF_LOADING_FINISHED) || this->current_order_time < wait_time) return;
2438
2439 this->PlayLeaveStationSound();
2440
2441 this->LeaveStation();
2442
2443 /* Only advance to next order if we just loaded at the current one */
2444 const Order *order = this->GetOrder(this->cur_implicit_order_index);
2445 if (order == nullptr ||
2446 (!order->IsType(OT_IMPLICIT) && !order->IsType(OT_GOTO_STATION)) ||
2447 order->GetDestination() != this->last_station_visited) {
2448 return;
2449 }
2450 break;
2451 }
2452
2453 case OT_DUMMY: break;
2454
2455 default: return;
2456 }
2457
2458 this->IncrementImplicitOrderIndex();
2459}
2460
2465 bool Vehicle::HasFullLoadOrder() const
2466{
2467 for (Order *o : this->Orders()) {
2468 if (o->IsType(OT_GOTO_STATION) && o->GetLoadType() & (OLFB_FULL_LOAD | OLF_FULL_LOAD_ANY)) return true;
2469 }
2470 return false;
2471}
2472
2477 bool Vehicle::HasConditionalOrder() const
2478{
2479 for (Order *o : this->Orders()) {
2480 if (o->IsType(OT_CONDITIONAL)) return true;
2481 }
2482 return false;
2483}
2484
2489 bool Vehicle::HasUnbunchingOrder() const
2490{
2491 for (Order *o : this->Orders()) {
2492 if (o->IsType(OT_GOTO_DEPOT) && o->GetDepotActionType() & ODATFB_UNBUNCH) return true;
2493 }
2494 return false;
2495}
2496
2501 static bool PreviousOrderIsUnbunching(const Vehicle *v)
2502{
2503 /* If we are headed for the first order, we must wrap around back to the last order. */
2504 bool is_first_order = (v->GetOrder(v->cur_implicit_order_index) == v->GetFirstOrder());
2505 Order *previous_order = (is_first_order) ? v->GetLastOrder() : v->GetOrder(v->cur_implicit_order_index - 1);
2506
2507 if (previous_order == nullptr || !previous_order->IsType(OT_GOTO_DEPOT)) return false;
2508 return (previous_order->GetDepotActionType() & ODATFB_UNBUNCH) != 0;
2509}
2510
2514 void Vehicle::LeaveUnbunchingDepot()
2515{
2516 /* Don't do anything if this is not our unbunching order. */
2517 if (!PreviousOrderIsUnbunching(this)) return;
2518
2519 /* Set the start point for this round trip time. */
2520 this->depot_unbunching_last_departure = TimerGameTick::counter;
2521
2522 /* Tell the timetable we are now "on time." */
2523 this->lateness_counter = 0;
2524 SetWindowDirty(WC_VEHICLE_TIMETABLE, this->index);
2525
2526 /* Find the average travel time of vehicles that we share orders with. */
2527 int num_vehicles = 0;
2528 TimerGameTick::Ticks total_travel_time = 0;
2529
2530 Vehicle *u = this->FirstShared();
2531 for (; u != nullptr; u = u->NextShared()) {
2532 /* Ignore vehicles that are manually stopped or crashed. */
2533 if (u->vehstatus & (VS_STOPPED | VS_CRASHED)) continue;
2534
2535 num_vehicles++;
2536 total_travel_time += u->round_trip_time;
2537 }
2538
2539 /* Make sure we cannot divide by 0. */
2540 num_vehicles = std::max(num_vehicles, 1);
2541
2542 /* Calculate the separation by finding the average travel time, then calculating equal separation (minimum 1 tick) between vehicles. */
2543 TimerGameTick::Ticks separation = std::max((total_travel_time / num_vehicles / num_vehicles), 1);
2544 TimerGameTick::TickCounter next_departure = TimerGameTick::counter + separation;
2545
2546 /* Set the departure time of all vehicles that we share orders with. */
2547 u = this->FirstShared();
2548 for (; u != nullptr; u = u->NextShared()) {
2549 /* Ignore vehicles that are manually stopped or crashed. */
2550 if (u->vehstatus & (VS_STOPPED | VS_CRASHED)) continue;
2551
2552 u->depot_unbunching_next_departure = next_departure;
2553 SetWindowDirty(WC_VEHICLE_VIEW, u->index);
2554 }
2555}
2556
2561 bool Vehicle::IsWaitingForUnbunching() const
2562{
2563 assert(this->IsInDepot());
2564
2565 /* Don't bother if there are no vehicles sharing orders. */
2566 if (!this->IsOrderListShared()) return false;
2567
2568 /* Don't do anything if there aren't enough orders. */
2569 if (this->GetNumOrders() <= 1) return false;
2570
2571 /* Don't do anything if this is not our unbunching order. */
2572 if (!PreviousOrderIsUnbunching(this)) return false;
2573
2574 return (this->depot_unbunching_next_departure > TimerGameTick::counter);
2575};
2576
2583 CommandCost Vehicle::SendToDepot(DoCommandFlag flags, DepotCommand command)
2584{
2585 CommandCost ret = CheckOwnership(this->owner);
2586 if (ret.Failed()) return ret;
2587
2588 if (this->vehstatus & VS_CRASHED) return CMD_ERROR;
2589 if (this->IsStoppedInDepot()) return CMD_ERROR;
2590
2591 /* No matter why we're headed to the depot, unbunching data is no longer valid. */
2592 if (flags & DC_EXEC) this->ResetDepotUnbunching();
2593
2594 if (this->current_order.IsType(OT_GOTO_DEPOT)) {
2595 bool halt_in_depot = (this->current_order.GetDepotActionType() & ODATFB_HALT) != 0;
2596 if (HasFlag(command, DepotCommand::Service) == halt_in_depot) {
2597 /* We called with a different DEPOT_SERVICE setting.
2598 * Now we change the setting to apply the new one and let the vehicle head for the same depot.
2599 * Note: the if is (true for requesting service == true for ordered to stop in depot) */
2600 if (flags & DC_EXEC) {
2601 this->current_order.SetDepotOrderType(ODTF_MANUAL);
2602 this->current_order.SetDepotActionType(halt_in_depot ? ODATF_SERVICE_ONLY : ODATFB_HALT);
2603 SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
2604 }
2605 return CommandCost();
2606 }
2607
2608 if (HasFlag(command, DepotCommand::DontCancel)) return CMD_ERROR; // Requested no cancellation of depot orders
2609 if (flags & DC_EXEC) {
2610 /* If the orders to 'goto depot' are in the orders list (forced servicing),
2611 * then skip to the next order; effectively cancelling this forced service */
2612 if (this->current_order.GetDepotOrderType() & ODTFB_PART_OF_ORDERS) this->IncrementRealOrderIndex();
2613
2614 if (this->IsGroundVehicle()) {
2615 uint16_t &gv_flags = this->GetGroundVehicleFlags();
2616 SetBit(gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS);
2617 }
2618
2619 this->current_order.MakeDummy();
2620 SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
2621 }
2622 return CommandCost();
2623 }
2624
2625 ClosestDepot closestDepot = this->FindClosestDepot();
2626 static const StringID no_depot[] = {STR_ERROR_UNABLE_TO_FIND_ROUTE_TO, STR_ERROR_UNABLE_TO_FIND_LOCAL_DEPOT, STR_ERROR_UNABLE_TO_FIND_LOCAL_DEPOT, STR_ERROR_CAN_T_SEND_AIRCRAFT_TO_HANGAR};
2627 if (!closestDepot.found) return CommandCost(no_depot[this->type]);
2628
2629 if (flags & DC_EXEC) {
2630 if (this->current_order.IsType(OT_LOADING)) this->LeaveStation();
2631
2632 if (this->IsGroundVehicle() && this->GetNumManualOrders() > 0) {
2633 uint16_t &gv_flags = this->GetGroundVehicleFlags();
2634 SetBit(gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS);
2635 }
2636
2637 this->SetDestTile(closestDepot.location);
2638 this->current_order.MakeGoToDepot(closestDepot.destination, ODTF_MANUAL);
2639 if (!HasFlag(command, DepotCommand::Service)) this->current_order.SetDepotActionType(ODATFB_HALT);
2640 SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
2641
2642 /* If there is no depot in front and the train is not already reversing, reverse automatically (trains only) */
2643 if (this->type == VEH_TRAIN && (closestDepot.reverse ^ HasBit(Train::From(this)->flags, VRF_REVERSING))) {
2644 Command<CMD_REVERSE_TRAIN_DIRECTION>::Do(DC_EXEC, this->index, false);
2645 }
2646
2647 if (this->type == VEH_AIRCRAFT) {
2648 Aircraft *a = Aircraft::From(this);
2649 if (a->state == FLYING && a->targetairport != closestDepot.destination) {
2650 /* The aircraft is now heading for a different hangar than the next in the orders */
2651 AircraftNextAirportPos_and_Order(a);
2652 }
2653 }
2654 }
2655
2656 return CommandCost();
2657
2658}
2659
2664 void Vehicle::UpdateVisualEffect(bool allow_power_change)
2665{
2666 bool powered_before = HasBit(this->vcache.cached_vis_effect, VE_DISABLE_WAGON_POWER);
2667 const Engine *e = this->GetEngine();
2668
2669 /* Evaluate properties */
2670 uint8_t visual_effect;
2671 switch (e->type) {
2672 case VEH_TRAIN: visual_effect = e->u.rail.visual_effect; break;
2673 case VEH_ROAD: visual_effect = e->u.road.visual_effect; break;
2674 case VEH_SHIP: visual_effect = e->u.ship.visual_effect; break;
2675 default: visual_effect = 1 << VE_DISABLE_EFFECT; break;
2676 }
2677
2678 /* Check powered wagon / visual effect callback */
2679 if (HasBit(e->info.callback_mask, CBM_VEHICLE_VISUAL_EFFECT)) {
2680 uint16_t callback = GetVehicleCallback(CBID_VEHICLE_VISUAL_EFFECT, 0, 0, this->engine_type, this);
2681
2682 if (callback != CALLBACK_FAILED) {
2683 if (callback >= 0x100 && e->GetGRF()->grf_version >= 8) ErrorUnknownCallbackResult(e->GetGRFID(), CBID_VEHICLE_VISUAL_EFFECT, callback);
2684
2685 callback = GB(callback, 0, 8);
2686 /* Avoid accidentally setting 'visual_effect' to the default value
2687 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
2688 if (callback == VE_DEFAULT) {
2689 assert(HasBit(callback, VE_DISABLE_EFFECT));
2690 SB(callback, VE_TYPE_START, VE_TYPE_COUNT, 0);
2691 }
2692 visual_effect = callback;
2693 }
2694 }
2695
2696 /* Apply default values */
2697 if (visual_effect == VE_DEFAULT ||
2698 (!HasBit(visual_effect, VE_DISABLE_EFFECT) && GB(visual_effect, VE_TYPE_START, VE_TYPE_COUNT) == VE_TYPE_DEFAULT)) {
2699 /* Only train engines have default effects.
2700 * Note: This is independent of whether the engine is a front engine or articulated part or whatever. */
2701 if (e->type != VEH_TRAIN || e->u.rail.railveh_type == RAILVEH_WAGON || !IsInsideMM(e->u.rail.engclass, EC_STEAM, EC_MONORAIL)) {
2702 if (visual_effect == VE_DEFAULT) {
2703 visual_effect = 1 << VE_DISABLE_EFFECT;
2704 } else {
2705 SetBit(visual_effect, VE_DISABLE_EFFECT);
2706 }
2707 } else {
2708 if (visual_effect == VE_DEFAULT) {
2709 /* Also set the offset */
2710 visual_effect = (VE_OFFSET_CENTRE - (e->u.rail.engclass == EC_STEAM ? 4 : 0)) << VE_OFFSET_START;
2711 }
2712 SB(visual_effect, VE_TYPE_START, VE_TYPE_COUNT, e->u.rail.engclass - EC_STEAM + VE_TYPE_STEAM);
2713 }
2714 }
2715
2716 this->vcache.cached_vis_effect = visual_effect;
2717
2718 if (!allow_power_change && powered_before != HasBit(this->vcache.cached_vis_effect, VE_DISABLE_WAGON_POWER)) {
2719 ToggleBit(this->vcache.cached_vis_effect, VE_DISABLE_WAGON_POWER);
2720 ShowNewGrfVehicleError(this->engine_type, STR_NEWGRF_BROKEN, STR_NEWGRF_BROKEN_POWERED_WAGON, GBUG_VEH_POWERED_WAGON, false);
2721 }
2722}
2723
2724static const int8_t _vehicle_smoke_pos[8] = {
2725 1, 1, 1, 0, -1, -1, -1, 0
2726};
2727
2732 static void SpawnAdvancedVisualEffect(const Vehicle *v)
2733{
2734 uint16_t callback = GetVehicleCallback(CBID_VEHICLE_SPAWN_VISUAL_EFFECT, 0, Random(), v->engine_type, v);
2735 if (callback == CALLBACK_FAILED) return;
2736
2737 uint count = GB(callback, 0, 2);
2738 bool auto_center = HasBit(callback, 13);
2739 bool auto_rotate = !HasBit(callback, 14);
2740
2741 int8_t l_center = 0;
2742 if (auto_center) {
2743 /* For road vehicles: Compute offset from vehicle position to vehicle center */
2744 if (v->type == VEH_ROAD) l_center = -(int)(VEHICLE_LENGTH - RoadVehicle::From(v)->gcache.cached_veh_length) / 2;
2745 } else {
2746 /* For trains: Compute offset from vehicle position to sprite position */
2747 if (v->type == VEH_TRAIN) l_center = (VEHICLE_LENGTH - Train::From(v)->gcache.cached_veh_length) / 2;
2748 }
2749
2750 Direction l_dir = v->direction;
2751 if (v->type == VEH_TRAIN && HasBit(Train::From(v)->flags, VRF_REVERSE_DIRECTION)) l_dir = ReverseDir(l_dir);
2752 Direction t_dir = ChangeDir(l_dir, DIRDIFF_90RIGHT);
2753
2754 int8_t x_center = _vehicle_smoke_pos[l_dir] * l_center;
2755 int8_t y_center = _vehicle_smoke_pos[t_dir] * l_center;
2756
2757 for (uint i = 0; i < count; i++) {
2758 uint32_t reg = GetRegister(0x100 + i);
2759 uint type = GB(reg, 0, 8);
2760 int8_t x = GB(reg, 8, 8);
2761 int8_t y = GB(reg, 16, 8);
2762 int8_t z = GB(reg, 24, 8);
2763
2764 if (auto_rotate) {
2765 int8_t l = x;
2766 int8_t t = y;
2767 x = _vehicle_smoke_pos[l_dir] * l + _vehicle_smoke_pos[t_dir] * t;
2768 y = _vehicle_smoke_pos[t_dir] * l - _vehicle_smoke_pos[l_dir] * t;
2769 }
2770
2771 if (type >= 0xF0) {
2772 switch (type) {
2773 case 0xF1: CreateEffectVehicleRel(v, x_center + x, y_center + y, z, EV_STEAM_SMOKE); break;
2774 case 0xF2: CreateEffectVehicleRel(v, x_center + x, y_center + y, z, EV_DIESEL_SMOKE); break;
2775 case 0xF3: CreateEffectVehicleRel(v, x_center + x, y_center + y, z, EV_ELECTRIC_SPARK); break;
2776 case 0xFA: CreateEffectVehicleRel(v, x_center + x, y_center + y, z, EV_BREAKDOWN_SMOKE_AIRCRAFT); break;
2777 default: break;
2778 }
2779 }
2780 }
2781}
2782
2787 void Vehicle::ShowVisualEffect() const
2788{
2789 assert(this->IsPrimaryVehicle());
2790 bool sound = false;
2791
2792 /* Do not show any smoke when:
2793 * - vehicle smoke is disabled by the player
2794 * - the vehicle is slowing down or stopped (by the player)
2795 * - the vehicle is moving very slowly
2796 */
2797 if (_settings_game.vehicle.smoke_amount == 0 ||
2798 this->vehstatus & (VS_TRAIN_SLOWING | VS_STOPPED) ||
2799 this->cur_speed < 2) {
2800 return;
2801 }
2802
2803 /* Use the speed as limited by underground and orders. */
2804 uint max_speed = this->GetCurrentMaxSpeed();
2805
2806 if (this->type == VEH_TRAIN) {
2807 const Train *t = Train::From(this);
2808 /* For trains, do not show any smoke when:
2809 * - the train is reversing
2810 * - is entering a station with an order to stop there and its speed is equal to maximum station entering speed
2811 */
2812 if (HasBit(t->flags, VRF_REVERSING) ||
2813 (IsRailStationTile(t->tile) && t->IsFrontEngine() && t->current_order.ShouldStopAtStation(t, GetStationIndex(t->tile)) &&
2814 t->cur_speed >= max_speed)) {
2815 return;
2816 }
2817 }
2818
2819 const Vehicle *v = this;
2820
2821 do {
2822 bool advanced = HasBit(v->vcache.cached_vis_effect, VE_ADVANCED_EFFECT);
2823 int effect_offset = GB(v->vcache.cached_vis_effect, VE_OFFSET_START, VE_OFFSET_COUNT) - VE_OFFSET_CENTRE;
2824 VisualEffectSpawnModel effect_model = VESM_NONE;
2825 if (advanced) {
2826 effect_offset = VE_OFFSET_CENTRE;
2827 effect_model = (VisualEffectSpawnModel)GB(v->vcache.cached_vis_effect, 0, VE_ADVANCED_EFFECT);
2828 if (effect_model >= VESM_END) effect_model = VESM_NONE; // unknown spawning model
2829 } else {
2830 effect_model = (VisualEffectSpawnModel)GB(v->vcache.cached_vis_effect, VE_TYPE_START, VE_TYPE_COUNT);
2831 assert(effect_model != (VisualEffectSpawnModel)VE_TYPE_DEFAULT); // should have been resolved by UpdateVisualEffect
2832 static_assert((uint)VESM_STEAM == (uint)VE_TYPE_STEAM);
2833 static_assert((uint)VESM_DIESEL == (uint)VE_TYPE_DIESEL);
2834 static_assert((uint)VESM_ELECTRIC == (uint)VE_TYPE_ELECTRIC);
2835 }
2836
2837 /* Show no smoke when:
2838 * - Smoke has been disabled for this vehicle
2839 * - The vehicle is not visible
2840 * - The vehicle is under a bridge
2841 * - The vehicle is on a depot tile
2842 * - The vehicle is on a tunnel tile
2843 * - The vehicle is a train engine that is currently unpowered */
2844 if (effect_model == VESM_NONE ||
2845 v->vehstatus & VS_HIDDEN ||
2846 IsBridgeAbove(v->tile) ||
2847 IsDepotTile(v->tile) ||
2848 IsTunnelTile(v->tile) ||
2849 (v->type == VEH_TRAIN &&
2850 !HasPowerOnRail(Train::From(v)->railtype, GetTileRailType(v->tile)))) {
2851 continue;
2852 }
2853
2854 EffectVehicleType evt = EV_END;
2855 switch (effect_model) {
2856 case VESM_STEAM:
2857 /* Steam smoke - amount is gradually falling until vehicle reaches its maximum speed, after that it's normal.
2858 * Details: while vehicle's current speed is gradually increasing, steam plumes' density decreases by one third each
2859 * third of its maximum speed spectrum. Steam emission finally normalises at very close to vehicle's maximum speed.
2860 * REGULATION:
2861 * - instead of 1, 4 / 2^smoke_amount (max. 2) is used to provide sufficient regulation to steam puffs' amount. */
2862 if (GB(v->tick_counter, 0, ((4 >> _settings_game.vehicle.smoke_amount) + ((this->cur_speed * 3) / max_speed))) == 0) {
2863 evt = EV_STEAM_SMOKE;
2864 }
2865 break;
2866
2867 case VESM_DIESEL: {
2868 /* Diesel smoke - thicker when vehicle is starting, gradually subsiding till it reaches its maximum speed
2869 * when smoke emission stops.
2870 * Details: Vehicle's (max.) speed spectrum is divided into 32 parts. When max. speed is reached, chance for smoke
2871 * emission erodes by 32 (1/4). For trains, power and weight come in handy too to either increase smoke emission in
2872 * 6 steps (1000HP each) if the power is low or decrease smoke emission in 6 steps (512 tonnes each) if the train
2873 * isn't overweight. Power and weight contributions are expressed in a way that neither extreme power, nor
2874 * extreme weight can ruin the balance (e.g. FreightWagonMultiplier) in the formula. When the vehicle reaches
2875 * maximum speed no diesel_smoke is emitted.
2876 * REGULATION:
2877 * - up to which speed a diesel vehicle is emitting smoke (with reduced/small setting only until 1/2 of max_speed),
2878 * - in Chance16 - the last value is 512 / 2^smoke_amount (max. smoke when 128 = smoke_amount of 2). */
2879 int power_weight_effect = 0;
2880 if (v->type == VEH_TRAIN) {
2881 power_weight_effect = (32 >> (Train::From(this)->gcache.cached_power >> 10)) - (32 >> (Train::From(this)->gcache.cached_weight >> 9));
2882 }
2883 if (this->cur_speed < (max_speed >> (2 >> _settings_game.vehicle.smoke_amount)) &&
2884 Chance16((64 - ((this->cur_speed << 5) / max_speed) + power_weight_effect), (512 >> _settings_game.vehicle.smoke_amount))) {
2885 evt = EV_DIESEL_SMOKE;
2886 }
2887 break;
2888 }
2889
2890 case VESM_ELECTRIC:
2891 /* Electric train's spark - more often occurs when train is departing (more load)
2892 * Details: Electric locomotives are usually at least twice as powerful as their diesel counterparts, so spark
2893 * emissions are kept simple. Only when starting, creating huge force are sparks more likely to happen, but when
2894 * reaching its max. speed, quarter by quarter of it, chance decreases until the usual 2,22% at train's top speed.
2895 * REGULATION:
2896 * - in Chance16 the last value is 360 / 2^smoke_amount (max. sparks when 90 = smoke_amount of 2). */
2897 if (GB(v->tick_counter, 0, 2) == 0 &&
2898 Chance16((6 - ((this->cur_speed << 2) / max_speed)), (360 >> _settings_game.vehicle.smoke_amount))) {
2899 evt = EV_ELECTRIC_SPARK;
2900 }
2901 break;
2902
2903 default:
2904 NOT_REACHED();
2905 }
2906
2907 if (evt != EV_END && advanced) {
2908 sound = true;
2909 SpawnAdvancedVisualEffect(v);
2910 } else if (evt != EV_END) {
2911 sound = true;
2912
2913 /* The effect offset is relative to a point 4 units behind the vehicle's
2914 * front (which is the center of an 8/8 vehicle). Shorter vehicles need a
2915 * correction factor. */
2916 if (v->type == VEH_TRAIN) effect_offset += (VEHICLE_LENGTH - Train::From(v)->gcache.cached_veh_length) / 2;
2917
2918 int x = _vehicle_smoke_pos[v->direction] * effect_offset;
2919 int y = _vehicle_smoke_pos[(v->direction + 2) % 8] * effect_offset;
2920
2921 if (v->type == VEH_TRAIN && HasBit(Train::From(v)->flags, VRF_REVERSE_DIRECTION)) {
2922 x = -x;
2923 y = -y;
2924 }
2925
2926 CreateEffectVehicleRel(v, x, y, 10, evt);
2927 }
2928 } while ((v = v->Next()) != nullptr);
2929
2930 if (sound) PlayVehicleSound(this, VSE_VISUAL_EFFECT);
2931}
2932
2937 void Vehicle::SetNext(Vehicle *next)
2938{
2939 assert(this != next);
2940
2941 if (this->next != nullptr) {
2942 /* We had an old next vehicle. Update the first and previous pointers */
2943 for (Vehicle *v = this->next; v != nullptr; v = v->Next()) {
2944 v->first = this->next;
2945 }
2946 this->next->previous = nullptr;
2947 }
2948
2949 this->next = next;
2950
2951 if (this->next != nullptr) {
2952 /* A new next vehicle. Update the first and previous pointers */
2953 if (this->next->previous != nullptr) this->next->previous->next = nullptr;
2954 this->next->previous = this;
2955 for (Vehicle *v = this->next; v != nullptr; v = v->Next()) {
2956 v->first = this->first;
2957 }
2958 }
2959}
2960
2966 void Vehicle::AddToShared(Vehicle *shared_chain)
2967{
2968 assert(this->previous_shared == nullptr && this->next_shared == nullptr);
2969
2970 if (shared_chain->orders == nullptr) {
2971 assert(shared_chain->previous_shared == nullptr);
2972 assert(shared_chain->next_shared == nullptr);
2973 this->orders = shared_chain->orders = new OrderList(nullptr, shared_chain);
2974 }
2975
2976 this->next_shared = shared_chain->next_shared;
2977 this->previous_shared = shared_chain;
2978
2979 shared_chain->next_shared = this;
2980
2981 if (this->next_shared != nullptr) this->next_shared->previous_shared = this;
2982
2983 shared_chain->orders->AddVehicle(this);
2984}
2985
2989 void Vehicle::RemoveFromShared()
2990{
2991 /* Remember if we were first and the old window number before RemoveVehicle()
2992 * as this changes first if needed. */
2993 bool were_first = (this->FirstShared() == this);
2994 VehicleListIdentifier vli(VL_SHARED_ORDERS, this->type, this->owner, this->FirstShared()->index);
2995
2996 this->orders->RemoveVehicle(this);
2997
2998 if (!were_first) {
2999 /* We are not the first shared one, so only relink our previous one. */
3000 this->previous_shared->next_shared = this->NextShared();
3001 }
3002
3003 if (this->next_shared != nullptr) this->next_shared->previous_shared = this->previous_shared;
3004
3005
3006 if (this->orders->GetNumVehicles() == 1) {
3007 /* When there is only one vehicle, remove the shared order list window. */
3008 CloseWindowById(GetWindowClassForVehicleType(this->type), vli.Pack());
3009 InvalidateVehicleOrder(this->FirstShared(), VIWD_MODIFY_ORDERS);
3010 } else if (were_first) {
3011 /* If we were the first one, update to the new first one.
3012 * Note: FirstShared() is already the new first */
3013 InvalidateWindowData(GetWindowClassForVehicleType(this->type), vli.Pack(), this->FirstShared()->index | (1U << 31));
3014 }
3015
3016 this->next_shared = nullptr;
3017 this->previous_shared = nullptr;
3018}
3019
3020static IntervalTimer<TimerGameEconomy> _economy_vehicles_yearly({TimerGameEconomy::YEAR, TimerGameEconomy::Priority::VEHICLE}, [](auto)
3021{
3022 for (Vehicle *v : Vehicle::Iterate()) {
3023 if (v->IsPrimaryVehicle()) {
3024 /* show warning if vehicle is not generating enough income last 2 years (corresponds to a red icon in the vehicle list) */
3025 Money profit = v->GetDisplayProfitThisYear();
3026 if (v->economy_age >= VEHICLE_PROFIT_MIN_AGE && profit < 0) {
3027 if (_settings_client.gui.vehicle_income_warn && v->owner == _local_company) {
3028 SetDParam(0, v->index);
3029 SetDParam(1, profit);
3030 AddVehicleAdviceNewsItem(
3031 TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_VEHICLE_UNPROFITABLE_PERIOD : STR_NEWS_VEHICLE_UNPROFITABLE_YEAR,
3032 v->index);
3033 }
3034 AI::NewEvent(v->owner, new ScriptEventVehicleUnprofitable(v->index));
3035 }
3036
3037 v->profit_last_year = v->profit_this_year;
3038 v->profit_this_year = 0;
3039 SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
3040 }
3041 }
3042 GroupStatistics::UpdateProfits();
3043 SetWindowClassesDirty(WC_TRAINS_LIST);
3044 SetWindowClassesDirty(WC_SHIPS_LIST);
3045 SetWindowClassesDirty(WC_ROADVEH_LIST);
3046 SetWindowClassesDirty(WC_AIRCRAFT_LIST);
3047});
3048
3058 bool CanVehicleUseStation(EngineID engine_type, const Station *st)
3059{
3060 const Engine *e = Engine::GetIfValid(engine_type);
3061 assert(e != nullptr);
3062
3063 switch (e->type) {
3064 case VEH_TRAIN:
3065 return (st->facilities & FACIL_TRAIN) != 0;
3066
3067 case VEH_ROAD:
3068 /* For road vehicles we need the vehicle to know whether it can actually
3069 * use the station, but if it doesn't have facilities for RVs it is
3070 * certainly not possible that the station can be used. */
3071 return (st->facilities & (FACIL_BUS_STOP | FACIL_TRUCK_STOP)) != 0;
3072
3073 case VEH_SHIP:
3074 return (st->facilities & FACIL_DOCK) != 0;
3075
3076 case VEH_AIRCRAFT:
3077 return (st->facilities & FACIL_AIRPORT) != 0 &&
3078 (st->airport.GetFTA()->flags & (e->u.air.subtype & AIR_CTOL ? AirportFTAClass::AIRPLANES : AirportFTAClass::HELICOPTERS)) != 0;
3079
3080 default:
3081 return false;
3082 }
3083}
3084
3091 bool CanVehicleUseStation(const Vehicle *v, const Station *st)
3092{
3093 if (v->type == VEH_ROAD) return st->GetPrimaryRoadStop(RoadVehicle::From(v)) != nullptr;
3094
3095 return CanVehicleUseStation(v->engine_type, st);
3096}
3097
3104 StringID GetVehicleCannotUseStationReason(const Vehicle *v, const Station *st)
3105{
3106 switch (v->type) {
3107 case VEH_TRAIN:
3108 return STR_ERROR_NO_RAIL_STATION;
3109
3110 case VEH_ROAD: {
3111 const RoadVehicle *rv = RoadVehicle::From(v);
3112 RoadStop *rs = st->GetPrimaryRoadStop(rv->IsBus() ? ROADSTOP_BUS : ROADSTOP_TRUCK);
3113
3114 StringID err = rv->IsBus() ? STR_ERROR_NO_BUS_STATION : STR_ERROR_NO_TRUCK_STATION;
3115
3116 for (; rs != nullptr; rs = rs->next) {
3117 /* Articulated vehicles cannot use bay road stops, only drive-through. Make sure the vehicle can actually use this bay stop */
3118 if (HasTileAnyRoadType(rs->xy, rv->compatible_roadtypes) && IsBayRoadStopTile(rs->xy) && rv->HasArticulatedPart()) {
3119 err = STR_ERROR_NO_STOP_ARTICULATED_VEHICLE;
3120 continue;
3121 }
3122
3123 /* Bay stop errors take precedence, but otherwise the vehicle may not be compatible with the roadtype/tramtype of this station tile.
3124 * We give bay stop errors precedence because they are usually a bus sent to a tram station or vice versa. */
3125 if (!HasTileAnyRoadType(rs->xy, rv->compatible_roadtypes) && err != STR_ERROR_NO_STOP_ARTICULATED_VEHICLE) {
3126 err = RoadTypeIsRoad(rv->roadtype) ? STR_ERROR_NO_STOP_COMPATIBLE_ROAD_TYPE : STR_ERROR_NO_STOP_COMPATIBLE_TRAM_TYPE;
3127 continue;
3128 }
3129 }
3130
3131 return err;
3132 }
3133
3134 case VEH_SHIP:
3135 return STR_ERROR_NO_DOCK;
3136
3137 case VEH_AIRCRAFT:
3138 if ((st->facilities & FACIL_AIRPORT) == 0) return STR_ERROR_NO_AIRPORT;
3139 if (v->GetEngine()->u.air.subtype & AIR_CTOL) {
3140 return STR_ERROR_AIRPORT_NO_PLANES;
3141 } else {
3142 return STR_ERROR_AIRPORT_NO_HELICOPTERS;
3143 }
3144
3145 default:
3146 return INVALID_STRING_ID;
3147 }
3148}
3149
3155 GroundVehicleCache *Vehicle::GetGroundVehicleCache()
3156{
3157 assert(this->IsGroundVehicle());
3158 if (this->type == VEH_TRAIN) {
3159 return &Train::From(this)->gcache;
3160 } else {
3161 return &RoadVehicle::From(this)->gcache;
3162 }
3163}
3164
3170 const GroundVehicleCache *Vehicle::GetGroundVehicleCache() const
3171{
3172 assert(this->IsGroundVehicle());
3173 if (this->type == VEH_TRAIN) {
3174 return &Train::From(this)->gcache;
3175 } else {
3176 return &RoadVehicle::From(this)->gcache;
3177 }
3178}
3179
3185uint16_t &Vehicle::GetGroundVehicleFlags()
3186{
3187 assert(this->IsGroundVehicle());
3188 if (this->type == VEH_TRAIN) {
3189 return Train::From(this)->gv_flags;
3190 } else {
3191 return RoadVehicle::From(this)->gv_flags;
3192 }
3193}
3194
3200 const uint16_t &Vehicle::GetGroundVehicleFlags() const
3201{
3202 assert(this->IsGroundVehicle());
3203 if (this->type == VEH_TRAIN) {
3204 return Train::From(this)->gv_flags;
3205 } else {
3206 return RoadVehicle::From(this)->gv_flags;
3207 }
3208}
3209
3218 void GetVehicleSet(VehicleSet &set, Vehicle *v, uint8_t num_vehicles)
3219{
3220 if (v->type == VEH_TRAIN) {
3221 Train *u = Train::From(v);
3222 /* Only include whole vehicles, so start with the first articulated part */
3223 u = u->GetFirstEnginePart();
3224
3225 /* Include num_vehicles vehicles, not counting articulated parts */
3226 for (; u != nullptr && num_vehicles > 0; num_vehicles--) {
3227 do {
3228 /* Include current vehicle in the selection. */
3229 include(set, u->index);
3230
3231 /* If the vehicle is multiheaded, add the other part too. */
3232 if (u->IsMultiheaded()) include(set, u->other_multiheaded_part->index);
3233
3234 u = u->Next();
3235 } while (u != nullptr && u->IsArticulatedPart());
3236 }
3237 }
3238}
3239
3244uint32_t Vehicle::GetDisplayMaxWeight() const
3245{
3246 uint32_t max_weight = 0;
3247
3248 for (const Vehicle *u = this; u != nullptr; u = u->Next()) {
3249 max_weight += u->GetMaxWeight();
3250 }
3251
3252 return max_weight;
3253}
3254
3259uint32_t Vehicle::GetDisplayMinPowerToWeight() const
3260{
3261 uint32_t max_weight = GetDisplayMaxWeight();
3262 if (max_weight == 0) return 0;
3263 return GetGroundVehicleCache()->cached_power * 10u / max_weight;
3264}
3265
3272 bool VehiclesHaveSameEngineList(const Vehicle *v1, const Vehicle *v2)
3273{
3274 while (true) {
3275 if (v1 == nullptr && v2 == nullptr) return true;
3276 if (v1 == nullptr || v2 == nullptr) return false;
3277 if (v1->GetEngine() != v2->GetEngine()) return false;
3278 v1 = v1->GetNextVehicle();
3279 v2 = v2->GetNextVehicle();
3280 }
3281}
3282
3289 bool VehiclesHaveSameOrderList(const Vehicle *v1, const Vehicle *v2)
3290{
3291 const Order *o1 = v1->GetFirstOrder();
3292 const Order *o2 = v2->GetFirstOrder();
3293 while (true) {
3294 if (o1 == nullptr && o2 == nullptr) return true;
3295 if (o1 == nullptr || o2 == nullptr) return false;
3296 if (!o1->Equals(*o2)) return false;
3297 o1 = o1->next;
3298 o2 = o2->next;
3299 }
3300}
ai.hpp
Base functions for all AIs.
aircraft.h
Base for aircraft.
AircraftNextAirportPos_and_Order
void AircraftNextAirportPos_and_Order(Aircraft *v)
set the right pos when heading to other airports after takeoff
Definition aircraft_cmd.cpp:1447
GetTargetAirportIfValid
Station * GetTargetAirportIfValid(const Aircraft *v)
Returns aircraft's target station if v->target_airport is a valid station with airport.
Definition aircraft_cmd.cpp:2146
AIR_SHADOW
@ AIR_SHADOW
shadow of the aircraft
Definition aircraft.h:31
HandleAircraftEnterHangar
void HandleAircraftEnterHangar(Aircraft *v)
Handle Aircraft specific tasks when an Aircraft enters a hangar.
Definition aircraft_cmd.cpp:573
FLYING
@ FLYING
Vehicle is flying in the air.
Definition airport.h:75
GetCargoTypesOfArticulatedVehicle
CargoTypes GetCargoTypesOfArticulatedVehicle(const Vehicle *v, CargoID *cargo_type)
Get cargo mask of all cargoes carried by an articulated vehicle.
Definition articulated_vehicles.cpp:264
GetArticulatedRefitMasks
void GetArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type, CargoTypes *union_mask, CargoTypes *intersection_mask)
Merges the refit_masks of all articulated parts.
Definition articulated_vehicles.cpp:224
GetCargoTypesOfArticulatedParts
CargoTypes GetCargoTypesOfArticulatedParts(EngineID engine)
Get the cargo mask of the parts of a given engine.
Definition articulated_vehicles.cpp:168
articulated_vehicles.h
Functions related to articulated vehicles.
autoreplace_cmd.h
Command definitions related to autoreplace.
autoreplace_func.h
Functions related to autoreplacing.
EngineReplacementForCompany
EngineID EngineReplacementForCompany(const Company *c, EngineID engine, GroupID group, bool *replace_when_old=nullptr)
Retrieve the engine replacement for the given company and original engine type.
Definition autoreplace_func.h:39
EngineHasReplacementForCompany
bool EngineHasReplacementForCompany(const Company *c, EngineID engine, GroupID group)
Check if a company has a replacement set up for the given engine.
Definition autoreplace_func.h:51
InvalidateAutoreplaceWindow
void InvalidateAutoreplaceWindow(EngineID e, GroupID id_g)
Rebuild the left autoreplace list if an engine is removed or added.
Definition autoreplace_gui.cpp:51
autoreplace_gui.h
Functions related to the autoreplace GUIs.
backup_type.hpp
Class for backupping variables and making sure they are restored later.
HasBit
debug_inline constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
Definition bitmath_func.hpp:103
SB
constexpr T SB(T &x, const uint8_t s, const uint8_t n, const U d)
Set n bits in x starting at bit s to d.
Definition bitmath_func.hpp:58
CLRBITS
#define CLRBITS(x, y)
Clears several bits in a variable.
Definition bitmath_func.hpp:166
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:213
HasAtMostOneBit
constexpr bool HasAtMostOneBit(T value)
Test whether value has at most 1 bit set.
Definition bitmath_func.hpp:290
GB
debug_inline static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
Definition bitmath_func.hpp:32
ToggleBit
constexpr T ToggleBit(T &x, const uint8_t y)
Toggles a bit in a variable.
Definition bitmath_func.hpp:181
ClrBit
constexpr T ClrBit(T &x, const uint8_t y)
Clears a bit in a variable.
Definition bitmath_func.hpp:151
bridge_map.h
Map accessor functions for bridges.
IsBridgeAbove
bool IsBridgeAbove(Tile t)
checks if a bridge is set above the ground of this tile
Definition bridge_map.h:45
CargoID
uint8_t CargoID
Cargo slots to indicate a cargo type within a game.
Definition cargo_type.h:22
IsValidCargoID
bool IsValidCargoID(CargoID t)
Test whether cargo type is not INVALID_CARGO.
Definition cargo_type.h:107
IsCargoInClass
bool IsCargoInClass(CargoID c, CargoClass cc)
Does cargo c have cargo class cc?
Definition cargotype.h:239
CC_PASSENGERS
@ CC_PASSENGERS
Passengers.
Definition cargotype.h:50
AI::NewEvent
static void NewEvent(CompanyID company, ScriptEvent *event)
Queue a new event for an AI.
Definition ai_core.cpp:243
CargoList::OnCleanPool
void OnCleanPool()
Empty the cargo list, but don't free the cargo packets; the cargo packets are cleaned by CargoPacket'...
Definition cargopacket.cpp:177
CargoList< VehicleCargoList, CargoPacketList >::MTA_LOAD
@ MTA_LOAD
Load the cargo from the station.
Definition cargopacket.h:300
CommandCost
Common return value for all commands.
Definition command_type.h:23
CommandCost::Succeeded
bool Succeeded() const
Did this command succeed?
Definition command_type.h:162
CommandCost::GetCost
Money GetCost() const
The costs as made up to this moment.
Definition command_type.h:83
CommandCost::Failed
bool Failed() const
Did this command fail?
Definition command_type.h:171
CommandCost::GetErrorMessage
StringID GetErrorMessage() const
Returns the error message of a command.
Definition command_type.h:142
EconomyTime::DAYS_IN_ECONOMY_MONTH
static constexpr int DAYS_IN_ECONOMY_MONTH
Days in an economy month, when in wallclock timekeeping mode.
Definition timer_game_economy.h:52
FreeUnitIDGenerator::UseID
UnitID UseID(UnitID index)
Use a unit number.
Definition vehicle.cpp:1863
FreeUnitIDGenerator::ReleaseID
void ReleaseID(UnitID index)
Release a unit number.
Definition vehicle.cpp:1880
FreeUnitIDGenerator::NextID
UnitID NextID() const
Find first unused unit number.
Definition vehicle.cpp:1848
Gamelog::GRFBugReverse
bool GRFBugReverse(uint32_t grfid, uint16_t internal_id)
Logs GRF bug - rail vehicle has different length after reversing.
Definition gamelog.cpp:482
IntervalTimer
An interval timer will fire every interval, and will continue to fire until it is deleted.
Definition timer.h:76
LinkRefresher::Run
static void Run(Vehicle *v, bool allow_merge=true, bool is_full_loading=false)
Refresh all links the given vehicle will visit.
Definition refresh.cpp:26
OverflowSafeInt< int64_t >
PerformanceAccumulator::Reset
static void Reset(PerformanceElement elem)
Store the previous accumulator value and reset for a new cycle of accumulating measurements.
Definition framerate_gui.cpp:328
PerformanceMeasurer
RAII class for measuring simple elements of performance.
Definition framerate_type.h:92
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::date_fract
static DateFract date_fract
Fractional part of the day.
Definition timer_game_calendar.h:34
TimerGameConst< struct Economy >::MAX_DATE
static constexpr TimerGame< struct Economy >::Date MAX_DATE
The date of the last day of the max year.
Definition timer_game_common.h:187
TimerGameConst< struct Calendar >::DAYS_IN_LEAP_YEAR
static constexpr int DAYS_IN_LEAP_YEAR
sometimes, you need one day more...
Definition timer_game_common.h:150
TimerGameEconomy::date
static Date date
Current date in days (day counter).
Definition timer_game_economy.h:38
TimerGameEconomy::UsingWallclockUnits
static bool UsingWallclockUnits(bool newgame=false)
Check if we are using wallclock units.
Definition timer_game_economy.cpp:97
TimerGameEconomy::date_fract
static DateFract date_fract
Fractional part of the day.
Definition timer_game_economy.h:39
TimerGameTick::TickCounter
uint64_t TickCounter
The type that the tick counter is stored in.
Definition timer_game_tick.h:25
TimerGameTick::counter
static TickCounter counter
Monotonic counter, in ticks, since start of game.
Definition timer_game_tick.h:60
TimerGameTick::Ticks
int32_t Ticks
The type to store ticks in.
Definition timer_game_tick.h:24
TimerGame< struct Calendar >::DateAtStartOfYear
static constexpr Date DateAtStartOfYear(Year year)
Calculate the date of the first day of a given year.
Definition timer_game_common.h:88
VehicleCargoList
CargoList that is used for vehicles.
Definition cargopacket.h:351
VehicleCargoList::ActionCount
uint ActionCount(MoveToAction action) const
Returns the amount of cargo designated for a given purpose.
Definition cargopacket.h:424
VehicleCargoList::Truncate
uint Truncate(uint max_move=UINT_MAX)
Truncates the cargo in this list to the given amount.
Definition cargopacket.cpp:650
VehicleCargoList::Return
uint Return(uint max_move, StationCargoList *dest, StationID next_station, TileIndex current_tile)
Returns reserved cargo to the station and removes it from the cache.
Definition cargopacket.cpp:598
VehicleCargoList::KeepAll
void KeepAll()
Marks all cargo in the vehicle as to be kept.
Definition cargopacket.h:488
VehicleCargoList::AgeCargo
void AgeCargo()
Ages the all cargo in this list.
Definition cargopacket.cpp:391
VehicleCargoList::StoredCount
uint StoredCount() const
Returns sum of cargo on board the vehicle (ie not only reserved).
Definition cargopacket.h:434
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
DoCommandFlag
List of flags for a command.
Definition command_type.h:374
DC_EXEC
@ DC_EXEC
execute the given command
Definition command_type.h:376
CheckOwnership
CommandCost CheckOwnership(Owner owner, TileIndex tile)
Check whether the current owner owns something.
Definition company_cmd.cpp:363
SubtractMoneyFromCompany
void SubtractMoneyFromCompany(const CommandCost &cost)
Subtract money from the _current_company, if the company is valid.
Definition company_cmd.cpp:289
GetAvailableMoney
Money GetAvailableMoney(CompanyID company)
Get the amount of money that a company has available, or INT64_MAX if there is no such valid company.
Definition company_cmd.cpp:216
_local_company
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition company_cmd.cpp:52
_current_company
CompanyID _current_company
Company currently doing an action.
Definition company_cmd.cpp:53
company_func.h
Functions related to companies.
IsLocalCompany
bool IsLocalCompany()
Is the current company the local company?
Definition company_func.h:47
Owner
Owner
Enum for all companies/owners.
Definition company_type.h:18
container_func.hpp
Some simple functions to help with accessing containers.
include
bool include(Container &container, typename Container::const_reference &item)
Helper function to append an item to a container if it is not already contained.
Definition container_func.hpp:24
Debug
#define Debug(category, level, format_string,...)
Ouptut a line of debugging information.
Definition debug.h:37
depot_func.h
Functions related to depots.
DeleteDepotHighlightOfVehicle
void DeleteDepotHighlightOfVehicle(const Vehicle *v)
Removes the highlight of a vehicle in a depot window.
Definition depot_gui.cpp:1181
depot_map.h
Map related accessors for depots.
IsDepotTile
bool IsDepotTile(Tile tile)
Is the given tile a tile with a depot on it?
Definition depot_map.h:41
DirDifference
DirDiff DirDifference(Direction d0, Direction d1)
Calculate the difference between two directions.
Definition direction_func.h:68
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
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
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
INVALID_DIAGDIR
@ INVALID_DIAGDIR
Flag for an invalid DiagDirection.
Definition direction_type.h:80
DirDiff
DirDiff
Allow incrementing of Direction variables.
Definition direction_type.h:58
DIRDIFF_45LEFT
@ DIRDIFF_45LEFT
Angle of 45 degrees left.
Definition direction_type.h:64
DIRDIFF_REVERSE
@ DIRDIFF_REVERSE
One direction is the opposite of the other one.
Definition direction_type.h:62
DIRDIFF_45RIGHT
@ DIRDIFF_45RIGHT
Angle of 45 degrees right.
Definition direction_type.h:60
DIRDIFF_SAME
@ DIRDIFF_SAME
Both directions faces to the same direction.
Definition direction_type.h:59
DIRDIFF_90RIGHT
@ DIRDIFF_90RIGHT
Angle of 90 degrees right.
Definition direction_type.h:61
ReleaseDisasterVehicle
void ReleaseDisasterVehicle(VehicleID vehicle)
Notify disasters that we are about to delete a vehicle.
Definition disaster_vehicle.cpp:981
LoadUnloadStation
void LoadUnloadStation(Station *st)
Load/unload the vehicles in this station according to the order they entered.
Definition economy.cpp:1950
PrepareUnload
void PrepareUnload(Vehicle *front_v)
Prepare the vehicle to be unloaded.
Definition economy.cpp:1278
economy_base.h
Base classes related to the economy.
EXPENSES_NEW_VEHICLES
@ EXPENSES_NEW_VEHICLES
New vehicles.
Definition economy_type.h:174
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_base.h
Base class for all effect vehicles.
effectvehicle_func.h
Functions related to effect vehicles.
EffectVehicleType
EffectVehicleType
Effect vehicle types.
Definition effectvehicle_func.h:16
EV_BREAKDOWN_SMOKE
@ EV_BREAKDOWN_SMOKE
Smoke of broken vehicles except aircraft.
Definition effectvehicle_func.h:23
EV_STEAM_SMOKE
@ EV_STEAM_SMOKE
Smoke of steam engines.
Definition effectvehicle_func.h:18
EV_DIESEL_SMOKE
@ EV_DIESEL_SMOKE
Smoke of diesel engines.
Definition effectvehicle_func.h:19
EV_BREAKDOWN_SMOKE_AIRCRAFT
@ EV_BREAKDOWN_SMOKE_AIRCRAFT
Smoke of broken aircraft.
Definition effectvehicle_func.h:27
EV_ELECTRIC_SPARK
@ EV_ELECTRIC_SPARK
Sparcs of electric engines.
Definition effectvehicle_func.h:20
INVALID_ENGINE
static const EngineID INVALID_ENGINE
Constant denoting an invalid engine.
Definition engine_type.h:210
EngineID
uint16_t EngineID
Unique identification number of an engine.
Definition engine_type.h:21
AIR_CTOL
@ AIR_CTOL
Conventional Take Off and Landing, i.e. planes.
Definition engine_type.h:95
EC_DIESEL
@ EC_DIESEL
Diesel rail engine.
Definition engine_type.h:35
EC_STEAM
@ EC_STEAM
Steam rail engine.
Definition engine_type.h:34
EC_MAGLEV
@ EC_MAGLEV
Maglev engine.
Definition engine_type.h:38
EC_ELECTRIC
@ EC_ELECTRIC
Electric rail engine.
Definition engine_type.h:36
EC_MONORAIL
@ EC_MONORAIL
Mono rail engine.
Definition engine_type.h:37
EF_USES_2CC
@ EF_USES_2CC
Vehicle uses two company colours.
Definition engine_type.h:174
EF_ROAD_TRAM
@ EF_ROAD_TRAM
Road vehicle is a tram/light rail vehicle.
Definition engine_type.h:173
EF_RAIL_IS_MU
@ EF_RAIL_IS_MU
Rail vehicle is a multiple-unit (DMU/EMU)
Definition engine_type.h:175
EF_NO_BREAKDOWN_SMOKE
@ EF_NO_BREAKDOWN_SMOKE
Do not show black smoke during a breakdown.
Definition engine_type.h:179
RAILVEH_WAGON
@ RAILVEH_WAGON
simple wagon, not motorized
Definition engine_type.h:29
HasFlag
debug_inline constexpr bool HasFlag(const T x, const T y)
Checks if a value in a bitset enum is set.
Definition enum_type.hpp:58
error.h
Functions related to errors.
ShowErrorMessage
void ShowErrorMessage(StringID summary_msg, int x, int y, CommandCost cc)
Display an error message in a window.
Definition error_gui.cpp:367
WL_CRITICAL
@ WL_CRITICAL
Critical errors, the MessageBox is shown in all cases.
Definition error.h:27
framerate_type.h
Types for recording game performance data.
PFE_GL_SHIPS
@ PFE_GL_SHIPS
Time spent processing ships.
Definition framerate_type.h:53
PFE_GL_AIRCRAFT
@ PFE_GL_AIRCRAFT
Time spent processing aircraft.
Definition framerate_type.h:54
PFE_GL_ECONOMY
@ PFE_GL_ECONOMY
Time spent processing cargo movement.
Definition framerate_type.h:50
PFE_GL_ROADVEHS
@ PFE_GL_ROADVEHS
Time spend processing road vehicles.
Definition framerate_type.h:52
PFE_GL_TRAINS
@ PFE_GL_TRAINS
Time spent processing trains.
Definition framerate_type.h:51
_gamelog
Gamelog _gamelog
Gamelog instance.
Definition gamelog.cpp:31
gamelog.h
Functions to be called to log fundamental changes to the game.
DrawSprite
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, ZoomLevel zoom)
Draw a sprite, not in a viewport.
Definition gfx.cpp:988
SpriteType::Normal
@ Normal
The most basic (normal) sprite.
PaletteID
uint32_t PaletteID
The number of the palette.
Definition gfx_type.h:19
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
Station::MarkTilesDirty
void MarkTilesDirty(bool cargo_change) const
Marks the tiles of the station as dirty.
Definition station.cpp:243
MarkTileDirtyByTile
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset, int tile_height_override)
Mark a tile given by its index dirty for repaint.
Definition viewport.cpp:2057
Vehicle::MarkDirty
virtual void MarkDirty()
Marks the vehicles to be redrawn and updates cached variables.
Definition vehicle_base.h:407
DeleteGroupHighlightOfVehicle
void DeleteGroupHighlightOfVehicle(const Vehicle *v)
Removes the highlight of a vehicle in a group window.
Definition group_gui.cpp:1252
group_gui.h
Functions/definitions that have something to do with groups.
DEFAULT_GROUP
static const GroupID DEFAULT_GROUP
Ungrouped vehicles are in this group.
Definition group_type.h:17
INVALID_GROUP
static const GroupID INVALID_GROUP
Sentinel for invalid groups.
Definition group_type.h:18
_tile_type_procs
const TileTypeProcs *const _tile_type_procs[16]
Tile callback functions for each type of tile.
Definition landscape.cpp:65
RemapCoords
Point RemapCoords(int x, int y, int z)
Map 3D world or tile coordinate to equivalent 2D coordinate as used in the viewports and smallmap.
Definition landscape.h:79
linkgraph.h
Declaration of link graph classes used for cargo distribution.
LIT_ALL
static const uint8_t LIT_ALL
Show the liveries of all companies.
Definition livery.h:18
LiveryScheme
LiveryScheme
List of different livery schemes.
Definition livery.h:21
LIT_COMPANY
static const uint8_t LIT_COMPANY
Show the liveries of your own company.
Definition livery.h:17
TileY
static debug_inline uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition map_func.h:425
TileX
static debug_inline uint TileX(TileIndex tile)
Get the X component of a tile.
Definition map_func.h:415
TileVirtXY
static debug_inline TileIndex TileVirtXY(uint x, uint y)
Get a tile from the virtual XY-coordinate.
Definition map_func.h:404
abs
constexpr T abs(const T a)
Returns the absolute value of (scalar) variable.
Definition math_func.hpp:23
CeilDiv
constexpr uint CeilDiv(uint a, uint b)
Computes ceil(a / b) for non-negative a and b.
Definition math_func.hpp:320
Clamp
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition math_func.hpp:79
IsInsideMM
constexpr bool IsInsideMM(const T x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
Definition math_func.hpp:268
misc_cmd.h
Miscellaneous command definitions.
HideFillingPercent
void HideFillingPercent(TextEffectID *te_id)
Hide vehicle loading indicators.
Definition misc_gui.cpp:628
ShowCostOrIncomeAnimation
void ShowCostOrIncomeAnimation(int x, int y, int z, Money cost)
Display animated income or costs on the map.
Definition misc_gui.cpp:550
_networking
bool _networking
are we in networking mode?
Definition network.cpp:65
network.h
Basic functions/variables used all over the place.
SAT_TRAIN_DEPARTS
@ SAT_TRAIN_DEPARTS
Trigger platform when train leaves.
Definition newgrf_animation_type.h:31
CBID_VEHICLE_SPAWN_VISUAL_EFFECT
@ CBID_VEHICLE_SPAWN_VISUAL_EFFECT
Called to spawn visual effects for vehicles.
Definition newgrf_callbacks.h:281
CBID_VEHICLE_COLOUR_MAPPING
@ CBID_VEHICLE_COLOUR_MAPPING
Called to determine if a specific colour map should be used for a vehicle instead of the default live...
Definition newgrf_callbacks.h:126
CBID_VEHICLE_32DAY_CALLBACK
@ CBID_VEHICLE_32DAY_CALLBACK
Called for every vehicle every 32 days (not all on same date though).
Definition newgrf_callbacks.h:144
CBID_VEHICLE_VISUAL_EFFECT
@ CBID_VEHICLE_VISUAL_EFFECT
Visual effects and wagon power.
Definition newgrf_callbacks.h:30
CBM_VEHICLE_COLOUR_REMAP
@ CBM_VEHICLE_COLOUR_REMAP
Change colour mapping of vehicle.
Definition newgrf_callbacks.h:307
CBM_VEHICLE_VISUAL_EFFECT
@ CBM_VEHICLE_VISUAL_EFFECT
Visual effects and wagon power (trains, road vehicles and ships)
Definition newgrf_callbacks.h:301
CALLBACK_FAILED
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
Definition newgrf_callbacks.h:427
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:505
GetGRFConfig
GRFConfig * GetGRFConfig(uint32_t grfid, uint32_t mask)
Retrieve a NewGRF from the current config by its grfid.
Definition newgrf_config.cpp:696
GRFBugs
GRFBugs
Encountered GRF bugs.
Definition newgrf_config.h:42
GBUG_VEH_POWERED_WAGON
@ GBUG_VEH_POWERED_WAGON
Powered wagon changed poweredness state when not inside a depot.
Definition newgrf_config.h:45
GBUG_VEH_LENGTH
@ GBUG_VEH_LENGTH
Length of rail vehicle changes when not inside a depot.
Definition newgrf_config.h:43
newgrf_debug.h
Functions/types related to NewGRF debugging.
GetGrfSpecFeature
GrfSpecFeature GetGrfSpecFeature(TileIndex tile)
Get the GrfSpecFeature associated with the tile.
Definition newgrf_debug_gui.cpp:763
DeleteNewGRFInspectWindow
void DeleteNewGRFInspectWindow(GrfSpecFeature feature, uint index)
Delete inspect window for a given feature and index.
Definition newgrf_debug_gui.cpp:729
UsesWagonOverride
bool UsesWagonOverride(const Vehicle *v)
Check if a wagon is currently using a wagon override.
Definition newgrf_engine.cpp:1135
GetVehicleCallback
uint16_t GetVehicleCallback(CallbackID callback, uint32_t param1, uint32_t param2, EngineID engine, const Vehicle *v)
Evaluate a newgrf callback for vehicles.
Definition newgrf_engine.cpp:1150
newgrf_roadstop.h
NewGRF definitions and structures for road stops.
RSRT_VEH_DEPARTS
@ RSRT_VEH_DEPARTS
Trigger roadstop when road vehicle leaves.
Definition newgrf_roadstop.h:41
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_VISUAL_EFFECT
@ VSE_VISUAL_EFFECT
Vehicle visual effect (steam, diesel smoke or electric spark) is shown.
Definition newgrf_sound.h:24
VSE_RUNNING
@ VSE_RUNNING
Vehicle running normally.
Definition newgrf_sound.h:22
VSE_STOPPED_16
@ VSE_STOPPED_16
Every 16 ticks while the vehicle is stopped (speed == 0).
Definition newgrf_sound.h:26
VSE_RUNNING_16
@ VSE_RUNNING_16
Every 16 ticks while the vehicle is running (speed > 0).
Definition newgrf_sound.h:25
VSE_BREAKDOWN
@ VSE_BREAKDOWN
Vehicle breaking down.
Definition newgrf_sound.h:21
GetRegister
uint32_t GetRegister(uint i)
Gets the value of a so-called newgrf "register".
Definition newgrf_spritegroup.h:29
TriggerStationRandomisation
void TriggerStationRandomisation(Station *st, TileIndex trigger_tile, StationRandomTrigger trigger, CargoID cargo_type)
Trigger station randomisation.
Definition newgrf_station.cpp:919
newgrf_station.h
Header file for NewGRF stations.
SRT_TRAIN_DEPARTS
@ SRT_TRAIN_DEPARTS
Trigger platform when train leaves.
Definition newgrf_station.h:109
news_func.h
Functions related to news.
DeleteVehicleNews
void DeleteVehicleNews(VehicleID vid, StringID news)
Delete a news item type about a vehicle.
Definition news_gui.cpp:998
AddVehicleAdviceNewsItem
void AddVehicleAdviceNewsItem(StringID string, VehicleID vehicle)
Adds a vehicle-advice news item.
Definition news_func.h:40
PM_PAUSED_ERROR
@ PM_PAUSED_ERROR
A game paused because a (critical) error.
Definition openttd.h:73
PM_PAUSED_NORMAL
@ PM_PAUSED_NORMAL
A game normally paused.
Definition openttd.h:70
order_backup.h
Functions related to order backups.
InsertOrder
void InsertOrder(Vehicle *v, Order *new_o, VehicleOrderID sel_ord)
Insert a new order but skip the validation.
Definition order_cmd.cpp:912
DeleteOrder
void DeleteOrder(Vehicle *v, VehicleOrderID sel_ord)
Delete an order but skip the parameter validation.
Definition order_cmd.cpp:1037
InvalidateVehicleOrder
void InvalidateVehicleOrder(const Vehicle *v, int data)
Updates the widgets of a vehicle which contains the order-data.
Definition order_cmd.cpp:235
DeleteVehicleOrders
void DeleteVehicleOrders(Vehicle *v, bool keep_orderlist, bool reset_order_indices)
Delete all orders from a vehicle.
Definition order_cmd.cpp:1869
ODATFB_UNBUNCH
@ ODATFB_UNBUNCH
Service the vehicle and then unbunch it.
Definition order_type.h:106
ODATFB_NEAREST_DEPOT
@ ODATFB_NEAREST_DEPOT
Send the vehicle to the nearest depot.
Definition order_type.h:105
ODATFB_HALT
@ ODATFB_HALT
Service the vehicle and then halt it.
Definition order_type.h:104
ODATF_SERVICE_ONLY
@ ODATF_SERVICE_ONLY
Only service the vehicle.
Definition order_type.h:103
OLFB_FULL_LOAD
@ OLFB_FULL_LOAD
Full load all cargoes of the consist.
Definition order_type.h:64
OLFB_NO_LOAD
@ OLFB_NO_LOAD
Do not load anything.
Definition order_type.h:66
OLF_FULL_LOAD_ANY
@ OLF_FULL_LOAD_ANY
Full load a single cargo of the consist.
Definition order_type.h:65
OUFB_NO_UNLOAD
@ OUFB_NO_UNLOAD
Totally no unloading will be done.
Definition order_type.h:56
MAX_VEH_ORDER_ID
static const VehicleOrderID MAX_VEH_ORDER_ID
Last valid VehicleOrderID.
Definition order_type.h:23
ONSF_NO_STOP_AT_ANY_STATION
@ ONSF_NO_STOP_AT_ANY_STATION
The vehicle will not stop at any stations it passes including the destination.
Definition order_type.h:76
ONSF_STOP_EVERYWHERE
@ ONSF_STOP_EVERYWHERE
The vehicle will stop at any station it passes and the destination.
Definition order_type.h:73
ODTFB_PART_OF_ORDERS
@ ODTFB_PART_OF_ORDERS
This depot order is because of a regular order.
Definition order_type.h:96
ODTFB_SERVICE
@ ODTFB_SERVICE
This depot order is because of the servicing limit.
Definition order_type.h:95
ODTF_MANUAL
@ ODTF_MANUAL
Manually initiated order.
Definition order_type.h:94
IMPLICIT_ORDER_ONLY_CAP
static const uint IMPLICIT_ORDER_ONLY_CAP
Maximum number of orders in implicit-only lists before we start searching harder for duplicates.
Definition order_type.h:32
pool_func.hpp
Some methods of Pool are placed here in order to reduce compilation time and binary size.
INSTANTIATE_POOL_METHODS
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don't get linker errors.
Definition pool_func.hpp:237
HasAnyRailTypesAvail
bool HasAnyRailTypesAvail(const CompanyID company)
Test if any buildable railtype is available for a company.
Definition rail.cpp:196
GetTileRailType
RailType GetTileRailType(Tile tile)
Return the rail type of tile, or INVALID_RAILTYPE if this is no rail tile.
Definition rail.cpp:155
HasPowerOnRail
bool HasPowerOnRail(RailType enginetype, RailType tiletype)
Checks if an engine of the given RailType got power on a tile with a given RailType.
Definition rail.h:335
SetDepotReservation
void SetDepotReservation(Tile t, bool b)
Set the reservation state of the depot.
Definition rail_map.h:270
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
Chance16I
bool Chance16I(const uint32_t a, const uint32_t b, const uint32_t r)
Checks if a given randomize-number is below a given probability.
Definition random_func.hpp:118
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
refresh.h
Definition of link refreshing utility.
HasAnyRoadTypesAvail
bool HasAnyRoadTypesAvail(CompanyID company, RoadTramType rtt)
Test if any buildable RoadType is available for a company.
Definition road.cpp:143
HasTileAnyRoadType
bool HasTileAnyRoadType(Tile t, RoadTypes rts)
Check if a tile has one of the specified road types.
Definition road_map.h:222
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
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:57
_settings_client
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:56
ship.h
Base for ships.
UpdateSignalsOnSegment
SigSegState UpdateSignalsOnSegment(TileIndex tile, DiagDirection side, Owner owner)
Update signals, starting at one side of a tile Will check tile next to this at opposite side too.
Definition signal.cpp:650
sound_func.h
Functions related to sound.
SND_3A_BREAKDOWN_TRAIN_SHIP_TOYLAND
@ SND_3A_BREAKDOWN_TRAIN_SHIP_TOYLAND
58 == 0x3A Breakdown: train or ship (toyland)
Definition sound_type.h:105
SND_10_BREAKDOWN_TRAIN_SHIP
@ SND_10_BREAKDOWN_TRAIN_SHIP
14 == 0x0E Breakdown: train or ship (non-toyland)
Definition sound_type.h:61
SND_0F_BREAKDOWN_ROADVEHICLE
@ SND_0F_BREAKDOWN_ROADVEHICLE
13 == 0x0D Breakdown: road vehicle (non-toyland)
Definition sound_type.h:60
SND_35_BREAKDOWN_ROADVEHICLE_TOYLAND
@ SND_35_BREAKDOWN_ROADVEHICLE_TOYLAND
53 == 0x35 Breakdown: road vehicle (toyland)
Definition sound_type.h:100
spritecache.h
Functions to cache sprites in memory.
PALETTE_RECOLOUR_START
static const PaletteID PALETTE_RECOLOUR_START
First recolour sprite for company colours.
Definition sprites.h:1574
PALETTE_CRASH
static const PaletteID PALETTE_CRASH
Recolour sprite greying of crashed vehicles.
Definition sprites.h:1605
station_base.h
Base classes/functions for stations.
IncreaseStats
void IncreaseStats(Station *st, CargoID cargo, StationID next_station_id, uint capacity, uint usage, uint32_t time, EdgeUpdateMode mode)
Increase capacity for a link stat given by station cargo and next hop.
Definition station_cmd.cpp:4118
IsStationRoadStopTile
bool IsStationRoadStopTile(Tile t)
Is tile t a road stop station?
Definition station_map.h:234
IsBayRoadStopTile
bool IsBayRoadStopTile(Tile t)
Is tile t a bay (non-drive through) road stop station?
Definition station_map.h:266
IsRailStationTile
bool IsRailStationTile(Tile t)
Is this tile a station tile and a rail station?
Definition station_map.h:102
GetStationIndex
StationID GetStationIndex(Tile t)
Get StationID from a tile.
Definition station_map.h:28
GetRoadStopType
RoadStopType GetRoadStopType(Tile t)
Get the road stop type of this tile.
Definition station_map.h:56
ROADSTOP_BUS
@ ROADSTOP_BUS
A standard stop for buses.
Definition station_type.h:46
ROADSTOP_TRUCK
@ ROADSTOP_TRUCK
A standard stop for trucks.
Definition station_type.h:47
FACIL_DOCK
@ FACIL_DOCK
Station with a dock.
Definition station_type.h:58
FACIL_BUS_STOP
@ FACIL_BUS_STOP
Station with bus stops.
Definition station_type.h:56
FACIL_AIRPORT
@ FACIL_AIRPORT
Station with an airport.
Definition station_type.h:57
FACIL_TRUCK_STOP
@ FACIL_TRUCK_STOP
Station with truck stops.
Definition station_type.h:55
FACIL_TRAIN
@ FACIL_TRAIN
Station with train station.
Definition station_type.h:54
stdafx.h
Definition of base types and functions in a cross-platform compatible way.
StrMakeValid
static void StrMakeValid(T &dst, const char *str, const char *last, StringValidationSettings settings)
Copies the valid (UTF-8) characters from str up to last to the dst.
Definition string.cpp:107
SetDParam
void SetDParam(size_t n, uint64_t v)
Set a string parameter v at index n in the global string parameter array.
Definition strings.cpp:104
GetString
std::string GetString(StringID string)
Resolve the given StringID into a std::string with all the associated DParam lookups and formatting.
Definition strings.cpp:333
SetDParamStr
void SetDParamStr(size_t n, const char *str)
This function is used to "bind" a C string to a OpenTTD dparam slot.
Definition strings.cpp:371
strings_func.h
Functions related to OTTD's strings.
StringID
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
Definition strings_type.h:16
INVALID_STRING_ID
static const StringID INVALID_STRING_ID
Constant representing an invalid string (16bit in case it is used in savegames)
Definition strings_type.h:17
AircraftVehicleInfo::subtype
uint8_t subtype
Type of aircraft.
Definition engine_type.h:104
Aircraft
Aircraft, helicopters, rotors and their shadows belong to this class.
Definition aircraft.h:72
Aircraft::pos
uint8_t pos
Next desired position of the aircraft.
Definition aircraft.h:74
Aircraft::state
uint8_t state
State of the airport.
Definition aircraft.h:77
Aircraft::IsNormalAircraft
bool IsNormalAircraft() const
Check if the aircraft type is a normal flying device; eg not a rotor or a shadow.
Definition aircraft.h:121
Aircraft::previous_pos
uint8_t previous_pos
Previous desired position of the aircraft.
Definition aircraft.h:75
Aircraft::targetairport
StationID targetairport
Airport to go to next.
Definition aircraft.h:76
AirportFTAClass::layout
struct AirportFTA * layout
state machine for airport
Definition airport.h:177
AirportFTAClass::flags
Flags flags
Flags for this airport type.
Definition airport.h:180
AirportFTAClass::AIRPLANES
@ AIRPLANES
Can planes land on this airport type?
Definition airport.h:147
AirportFTAClass::HELICOPTERS
@ HELICOPTERS
Can helicopters land on this airport type?
Definition airport.h:148
AirportFTA
Internal structure used in openttd - Finite sTate mAchine --> FTA.
Definition airport.h:190
AirportFTA::block
uint64_t block
64 bit blocks (st->airport.flags), should be enough for the most complex airports
Definition airport.h:192
Airport::flags
uint64_t flags
stores which blocks on the airport are taken. was 16 bit earlier on, then 32
Definition station_base.h:293
Airport::GetFTA
const AirportFTAClass * GetFTA() const
Get the finite-state machine for this airport or the finite-state machine for the dummy airport in ca...
Definition station_base.h:317
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:21
BaseConsist::depot_unbunching_next_departure
TimerGameTick::TickCounter depot_unbunching_next_departure
When the vehicle will next try to leave its unbunching depot.
Definition base_consist.h:26
BaseConsist::cur_real_order_index
VehicleOrderID cur_real_order_index
The index to the current real (non-implicit) order.
Definition base_consist.h:31
BaseConsist::round_trip_time
TimerGameTick::Ticks round_trip_time
How many ticks for a single circumnavigation of the orders.
Definition base_consist.h:27
BaseConsist::depot_unbunching_last_departure
TimerGameTick::TickCounter depot_unbunching_last_departure
When the vehicle last left its unbunching depot.
Definition base_consist.h:25
BaseConsist::cur_implicit_order_index
VehicleOrderID cur_implicit_order_index
The index to the current implicit order.
Definition base_consist.h:32
BaseConsist::lateness_counter
TimerGameTick::Ticks lateness_counter
How many ticks late (or early if negative) this vehicle is.
Definition base_consist.h:22
BaseConsist::vehicle_flags
uint16_t vehicle_flags
Used for gradual loading and other miscellaneous things (.
Definition base_consist.h:34
BaseConsist::ResetDepotUnbunching
void ResetDepotUnbunching()
Resets all the data used for depot unbunching.
Definition base_consist.cpp:49
BaseStation::facilities
StationFacility facilities
The facilities that this station has.
Definition base_station_base.h:70
BaseVehicle::type
VehicleType type
Type of vehicle.
Definition vehicle_type.h:51
CargoSpec::Get
static CargoSpec * Get(size_t index)
Retrieve cargo details for the given cargo ID.
Definition cargotype.h:139
ClientSettings::gui
GUISettings gui
settings related to the GUI
Definition settings_type.h:610
ClosestDepot
Structure to return information about the closest depot location, and whether it could be found.
Definition vehicle_base.h:230
ClosestDepot::destination
DestinationID destination
The DestinationID as used for orders.
Definition vehicle_base.h:232
CommandHelper
Definition command_func.h:83
CompanyProperties::settings
CompanySettings settings
settings specific for each company
Definition company_base.h:122
CompanySettings::engine_renew_money
uint32_t engine_renew_money
minimum amount of money before autorenew is used
Definition settings_type.h:585
CompanySettings::engine_renew_months
int16_t engine_renew_months
months before/after the maximum vehicle age a vehicle should be renewed
Definition settings_type.h:584
CompanySettings::engine_renew
bool engine_renew
is autorenew enabled
Definition settings_type.h:583
Company
Definition company_base.h:133
Company::group_all
GroupStatistics group_all[VEH_COMPANY_END]
NOSAVE: Statistics for the ALL_GROUP group.
Definition company_base.h:144
DifficultySettings::vehicle_breakdowns
uint8_t vehicle_breakdowns
likelihood of vehicles breaking down
Definition settings_type.h:107
DrawPixelInfo
Data about how and where to blit pixels.
Definition gfx_type.h:157
EffectVehicle
A special vehicle is one of the following:
Definition effectvehicle_base.h:24
EffectVehicle::GetTransparencyOption
TransparencyOption GetTransparencyOption() const
Determines the transparency option affecting the effect.
Definition effectvehicle.cpp:633
EffectVehicle::animation_state
uint16_t animation_state
State primarily used to change the graphics/behaviour.
Definition effectvehicle_base.h:25
EngineInfo::misc_flags
uint8_t misc_flags
Miscellaneous flags.
Definition engine_type.h:159
EngineInfo::callback_mask
uint16_t callback_mask
Bitmask of vehicle callbacks that have to be called.
Definition engine_type.h:160
Engine
Definition engine_base.h:37
Engine::GetDefaultCargoType
CargoID GetDefaultCargoType() const
Determines the default cargo type of an engine.
Definition engine_base.h:100
Engine::grf_prop
GRFFilePropsBase< NUM_CARGO+2 > grf_prop
Properties related the the grf file.
Definition engine_base.h:82
Engine::GetGRFID
uint32_t GetGRFID() const
Retrieve the GRF ID of the NewGRF the engine is tied to.
Definition engine.cpp:157
Engine::GetGRF
const GRFFile * GetGRF() const
Retrieve the NewGRF the engine is tied to.
Definition engine_base.h:171
Engine::IterateType
static Pool::IterateWrapperFiltered< Engine, EngineTypeFilter > IterateType(VehicleType vt, size_t from=0)
Returns an iterable ensemble of all valid engines of the given type.
Definition engine_base.h:190
Engine::company_avail
CompanyMask company_avail
Bit for each company whether the engine is available for that company.
Definition engine_base.h:38
Engine::type
VehicleType type
Vehicle type, ie VEH_ROAD, VEH_TRAIN, etc.
Definition engine_base.h:60
Engine::reliability
uint16_t reliability
Current reliability of the engine.
Definition engine_base.h:47
GRFConfig
Information about GRF, used in the game and (part of it) in savegames.
Definition newgrf_config.h:154
GRFConfig::grf_bugs
uint32_t grf_bugs
NOSAVE: bugs in this GRF in this run,.
Definition newgrf_config.h:175
GRFConfig::GetName
const char * GetName() const
Get the name of this grf.
Definition newgrf_config.cpp:92
GRFFilePropsBase::local_id
uint16_t local_id
id defined by the grf file for this entity
Definition newgrf_commons.h:311
GRFFilePropsBase::grfid
uint32_t grfid
grfid that introduced this entity.
Definition newgrf_commons.h:312
GRFFile
Dynamic data of a loaded NewGRF.
Definition newgrf.h:108
GUISettings::lost_vehicle_warn
bool lost_vehicle_warn
if a vehicle can't find its destination, show a warning
Definition settings_type.h:139
GUISettings::vehicle_income_warn
bool vehicle_income_warn
if a vehicle isn't generating income, show a warning
Definition settings_type.h:141
GUISettings::show_track_reservation
bool show_track_reservation
highlight reserved tracks.
Definition settings_type.h:193
GUISettings::liveries
uint8_t liveries
options for displaying company liveries, 0=none, 1=self, 2=all
Definition settings_type.h:156
GUISettings::old_vehicle_warn
bool old_vehicle_warn
if a vehicle is getting old, show a warning
Definition settings_type.h:142
GameCreationSettings::landscape
uint8_t landscape
the landscape we're currently in
Definition settings_type.h:368
GameSettings::difficulty
DifficultySettings difficulty
settings related to the difficulty
Definition settings_type.h:592
GameSettings::game_creation
GameCreationSettings game_creation
settings used during the creation of a game (map)
Definition settings_type.h:593
GameSettings::vehicle
VehicleSettings vehicle
options for vehicles
Definition settings_type.h:601
GameSettings::order
OrderSettings order
settings related to orders
Definition settings_type.h:600
GetNewVehiclePosResult
Position information of a vehicle after it moved.
Definition vehicle_func.h:77
GetNewVehiclePosResult::new_tile
TileIndex new_tile
Tile of the vehicle after moving.
Definition vehicle_func.h:80
GetNewVehiclePosResult::y
int y
x and y position of the vehicle after moving
Definition vehicle_func.h:78
GetNewVehiclePosResult::old_tile
TileIndex old_tile
Current tile of the vehicle.
Definition vehicle_func.h:79
GoodsEntry::HasRating
bool HasRating() const
Does this cargo have a rating at this station?
Definition station_base.h:258
GoodsEntry::cargo
StationCargoList cargo
The cargo packets of cargo waiting in this station.
Definition station_base.h:210
GroundVehicleCache
Cached, frequently calculated values.
Definition ground_vehicle.hpp:30
GroundVehicleCache::first_engine
EngineID first_engine
Cached EngineID of the front vehicle. INVALID_ENGINE for the front vehicle itself.
Definition ground_vehicle.hpp:44
GroundVehicleCache::cached_power
uint32_t cached_power
Total power of the consist (valid only for the first engine).
Definition ground_vehicle.hpp:39
GroundVehicle::IsMultiheaded
bool IsMultiheaded() const
Check if the vehicle is a multiheaded engine.
Definition ground_vehicle.hpp:330
GroupStatistics::CountVehicle
static void CountVehicle(const Vehicle *v, int delta)
Update num_vehicle when adding or removing a vehicle.
Definition group_cmd.cpp:133
GroupStatistics::VehicleReachedMinAge
static void VehicleReachedMinAge(const Vehicle *v)
Add a vehicle to the profit sum of its group.
Definition group_cmd.cpp:180
GroupStatistics::CountEngine
static void CountEngine(const Vehicle *v, int delta)
Update num_engines when adding/removing an engine.
Definition group_cmd.cpp:158
GroupStatistics::num_vehicle
uint16_t num_vehicle
Number of vehicles.
Definition group.h:28
GroupStatistics::UpdateAutoreplace
static void UpdateAutoreplace(CompanyID company)
Update autoreplace_defined and autoreplace_finished of all statistics of a company.
Definition group_cmd.cpp:221
GroupStatistics::UpdateProfits
static void UpdateProfits()
Recompute the profits for all groups.
Definition group_cmd.cpp:194
Group
Group data.
Definition group.h:72
Group::livery
Livery livery
Custom colour scheme for vehicles in this group.
Definition group.h:78
Group::parent
GroupID parent
Parent group.
Definition group.h:83
Livery
Information about a particular livery.
Definition livery.h:78
Livery::colour2
Colours colour2
Second colour, for vehicles with 2CC support.
Definition livery.h:81
Livery::colour1
Colours colour1
First colour, for all vehicles.
Definition livery.h:80
Livery::in_use
uint8_t in_use
Bit 0 set if this livery should override the default livery first colour, Bit 1 for the second colour...
Definition livery.h:79
MutableSpriteCache::revalidate_before_draw
bool revalidate_before_draw
We need to do a GetImage() and check bounds before drawing this sprite.
Definition vehicle_base.h:197
MutableSpriteCache::sprite_seq
VehicleSpriteSeq sprite_seq
Vehicle appearance.
Definition vehicle_base.h:200
MutableSpriteCache::is_viewport_candidate
bool is_viewport_candidate
This vehicle can potentially be drawn on a viewport.
Definition vehicle_base.h:198
MutableSpriteCache::old_coord
Rect old_coord
Co-ordinates from the last valid bounding box.
Definition vehicle_base.h:199
OrderBackup::ClearVehicle
static void ClearVehicle(const Vehicle *v)
Clear/update the (clone) vehicle from an order backup.
Definition order_backup.cpp:232
OrderList
Shared order list linking together the linked list of orders and the list of vehicles sharing this or...
Definition order_base.h:259
OrderList::GetNumVehicles
uint GetNumVehicles() const
Return the number of vehicles that share this orders list.
Definition order_base.h:350
OrderList::RemoveVehicle
void RemoveVehicle(Vehicle *v)
Removes the vehicle from the shared order list.
Definition order_cmd.cpp:552
OrderList::AddVehicle
void AddVehicle(Vehicle *v)
Adds the given vehicle to this shared order list.
Definition order_base.h:358
OrderList::GetNumOrders
VehicleOrderID GetNumOrders() const
Get number of orders in the order list.
Definition order_base.h:319
OrderSettings::no_servicing_if_no_breakdowns
bool no_servicing_if_no_breakdowns
don't send vehicles to depot when breakdowns are disabled
Definition settings_type.h:484
Order
Definition order_base.h:36
Order::GetDepotOrderType
OrderDepotTypeFlags GetDepotOrderType() const
What caused us going to the depot?
Definition order_base.h:144
Order::GetRefitCargo
CargoID GetRefitCargo() const
Get the cargo to to refit to.
Definition order_base.h:131
Order::Equals
bool Equals(const Order &other) const
Does this order have the same type, flags and destination?
Definition order_cmd.cpp:175
Order::GetDestination
DestinationID GetDestination() const
Gets the destination of this order.
Definition order_base.h:103
Order::IsType
bool IsType(OrderType type) const
Check whether this order is of the given type.
Definition order_base.h:70
Order::SetNonStopType
void SetNonStopType(OrderNonStopFlags non_stop_type)
Set whether we must stop at stations or not.
Definition order_base.h:161
Order::GetType
OrderType GetType() const
Get the type of order of this order.
Definition order_base.h:76
Order::SetDepotOrderType
void SetDepotOrderType(OrderDepotTypeFlags depot_order_type)
Set the cause to go to the depot.
Definition order_base.h:165
Order::GetLoadType
OrderLoadFlags GetLoadType() const
How must the consist be loaded?
Definition order_base.h:136
Order::MakeDummy
void MakeDummy()
Makes this order a Dummy order.
Definition order_cmd.cpp:133
Order::MakeGoToDepot
void MakeGoToDepot(DepotID destination, OrderDepotTypeFlags order, OrderNonStopFlags non_stop_type=ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS, OrderDepotActionFlags action=ODATF_SERVICE_ONLY, CargoID cargo=CARGO_NO_REFIT)
Makes this order a Go To Depot order.
Definition order_cmd.cpp:90
Order::next
Order * next
Pointer to next order. If nullptr, end of list.
Definition order_base.h:59
Order::SetDepotActionType
void SetDepotActionType(OrderDepotActionFlags depot_service_type)
Set what we are going to do in the depot.
Definition order_base.h:167
Order::GetDepotActionType
OrderDepotActionFlags GetDepotActionType() const
What are we going to do when in the depot.
Definition order_base.h:146
Order::MakeLeaveStation
void MakeLeaveStation()
Makes this order a Leave Station order.
Definition order_cmd.cpp:124
Order::CanLeaveWithCargo
bool CanLeaveWithCargo(bool has_cargo) const
A vehicle can leave the current station with cargo if:
Definition order_cmd.cpp:2249
Order::GetTimetabledWait
uint16_t GetTimetabledWait() const
Get the time in ticks a vehicle should wait at the destination or 0 if it's not timetabled.
Definition order_base.h:188
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:2225
Order::MakeImplicit
void MakeImplicit(StationID destination)
Makes this order an implicit order.
Definition order_cmd.cpp:154
Order::GetNonStopType
OrderNonStopFlags GetNonStopType() const
At which stations must we stop?
Definition order_base.h:140
Order::IsRefit
bool IsRefit() const
Is this order a refit order.
Definition order_base.h:117
Order::MakeLoading
void MakeLoading(bool ordered)
Makes this order a Loading order.
Definition order_cmd.cpp:115
PalSpriteID::sprite
SpriteID sprite
The 'real' sprite.
Definition gfx_type.h:24
PalSpriteID::pal
PaletteID pal
The palette (use PAL_NONE) if not needed)
Definition gfx_type.h:25
Point
Coordinates of a point in 2D.
Definition geometry_type.hpp:21
Pool::PoolItem<&_vehicle_pool >::GetPoolSize
static size_t GetPoolSize()
Returns first unused index.
Definition pool_type.hpp:360
Pool::PoolItem::index
Tindex index
Index of this pool item.
Definition pool_type.hpp:238
Pool::PoolItem<&_vehicle_pool >::CleaningPool
static bool CleaningPool()
Returns current state of pool cleaning - yes or no.
Definition pool_type.hpp:318
Pool::PoolItem<&_company_pool >::IsValidID
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
Definition pool_type.hpp:328
Pool::PoolItem<&_vehicle_pool >::Iterate
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
Definition pool_type.hpp:388
Pool::PoolItem<&_group_pool >::GetIfValid
static Titem * GetIfValid(size_t index)
Returns Titem with given index.
Definition pool_type.hpp:350
Pool::PoolItem<&_orderlist_pool >::CanAllocateItem
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function()
Definition pool_type.hpp:309
Pool::PoolItem<&_company_pool >::Get
static Titem * Get(size_t index)
Returns Titem with given index.
Definition pool_type.hpp:339
Pool
Base class for all pools.
Definition pool_type.hpp:80
RailVehicleInfo::visual_effect
uint8_t visual_effect
Bitstuffed NewGRF visual effect data.
Definition engine_type.h:58
RailVehicleInfo::engclass
EngineClass engclass
Class of engine for this vehicle.
Definition engine_type.h:54
Rect
Specification of a rectangle with absolute coordinates of all edges.
Definition geometry_type.hpp:75
RoadStop
A Stop for a Road Vehicle.
Definition roadstop_base.h:22
RoadStop::Leave
void Leave(RoadVehicle *rv)
Leave the road stop.
Definition roadstop.cpp:214
RoadStop::next
RoadStop * next
Next stop of the given type at this station.
Definition roadstop_base.h:70
RoadStop::xy
TileIndex xy
Position on the map.
Definition roadstop_base.h:69
RoadStop::GetByTile
static RoadStop * GetByTile(TileIndex tile, RoadStopType type)
Find a roadstop at given tile.
Definition roadstop.cpp:264
RoadVehicleInfo::visual_effect
uint8_t visual_effect
Bitstuffed NewGRF visual effect data.
Definition engine_type.h:126
RoadVehicle
Buses, trucks and trams belong to this class.
Definition roadveh.h:98
RoadVehicle::state
uint8_t state
Definition roadveh.h:100
RoadVehicle::compatible_roadtypes
RoadTypes compatible_roadtypes
NOSAVE: Roadtypes this consist is powered on.
Definition roadveh.h:110
RoadVehicle::IsBus
bool IsBus() const
Check whether a roadvehicle is a bus.
Definition roadveh_cmd.cpp:82
RoadVehicle::roadtype
RoadType roadtype
NOSAVE: Roadtype of this vehicle.
Definition roadveh.h:108
RoadVehicle::disaster_vehicle
VehicleID disaster_vehicle
NOSAVE: Disaster vehicle targetting this vehicle.
Definition roadveh.h:109
ShipVehicleInfo::visual_effect
uint8_t visual_effect
Bitstuffed NewGRF visual effect data.
Definition engine_type.h:76
Ship
All ships have this type.
Definition ship.h:32
Ship::state
TrackBits state
The "track" the ship is following.
Definition ship.h:34
Ship::UpdateCache
void UpdateCache()
Update the caches of this ship.
Definition ship_cmd.cpp:232
SpecializedStation< Station, false >::Get
static Station * Get(size_t index)
Gets station with given index.
Definition base_station_base.h:254
SpecializedStation< Station, false >::GetIfValid
static Station * GetIfValid(size_t index)
Returns station if the index is a valid index for this station type.
Definition base_station_base.h:263
SpecializedStation< Station, false >::IsValidID
static bool IsValidID(size_t index)
Tests whether given index is a valid index for station of this type.
Definition base_station_base.h:245
SpecializedVehicle::Next
T * Next() const
Get next vehicle in the chain.
Definition vehicle_base.h:1130
SpecializedVehicle::From
static T * From(Vehicle *v)
Converts a Vehicle to SpecializedVehicle with type checking.
Definition vehicle_base.h:1215
SpecializedVehicle::UpdateViewport
void UpdateViewport(bool force_update, bool update_delta)
Update vehicle sprite- and position caches.
Definition vehicle_base.h:1237
SpecializedVehicle::GetFirstEnginePart
T * GetFirstEnginePart()
Get the first part of an articulated engine.
Definition vehicle_base.h:1156
Sprite
Data structure describing a sprite.
Definition spritecache.h:17
Sprite::width
uint16_t width
Width of the sprite.
Definition spritecache.h:19
Sprite::height
uint16_t height
Height of the sprite.
Definition spritecache.h:18
Sprite::y_offs
int16_t y_offs
Number of pixels to shift the sprite downwards.
Definition spritecache.h:21
Sprite::x_offs
int16_t x_offs
Number of pixels to shift the sprite to the right.
Definition spritecache.h:20
Station
Station data structure.
Definition station_base.h:439
Station::goods
GoodsEntry goods[NUM_CARGO]
Goods at this station.
Definition station_base.h:468
Station::airport
Airport airport
Tile area the airport covers.
Definition station_base.h:453
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > >
TileTypeProcs::vehicle_enter_tile_proc
VehicleEnterTileProc * vehicle_enter_tile_proc
Called when a vehicle enters a tile.
Definition tile_cmd.h:170
Train
'Train' is either a loco or a wagon.
Definition train.h:89
Train::ConsistChanged
void ConsistChanged(ConsistChangeFlags allowed_changes)
Recalculates the cached stuff of a train.
Definition train_cmd.cpp:110
Train::wait_counter
uint16_t wait_counter
Ticks waiting in front of a signal, ticks being stuck or a counter for forced proceeding through sign...
Definition train.h:92
VehicleCache::cached_vis_effect
uint8_t cached_vis_effect
Visual effect to show (see VisualEffect)
Definition vehicle_base.h:129
VehicleCache::cached_cargo_age_period
uint16_t cached_cargo_age_period
Number of ticks before carried cargo is aged.
Definition vehicle_base.h:127
VehicleListIdentifier
The information about a vehicle list.
Definition vehiclelist.h:28
VehicleListIdentifier::Pack
uint32_t Pack() const
Pack a VehicleListIdentifier in a single uint32.
Definition vehiclelist.cpp:23
VehicleSettings::max_ships
UnitID max_ships
max ships in game per company
Definition settings_type.h:502
VehicleSettings::max_trains
UnitID max_trains
max trains in game per company
Definition settings_type.h:499
VehicleSettings::smoke_amount
uint8_t smoke_amount
amount of smoke/sparks locomotives produce
Definition settings_type.h:492
VehicleSettings::max_aircraft
UnitID max_aircraft
max planes in game per company
Definition settings_type.h:501
VehicleSettings::max_roadveh
UnitID max_roadveh
max trucks in game per company
Definition settings_type.h:500
VehicleSpriteSeq
Sprite sequence for a vehicle part.
Definition vehicle_base.h:135
VehicleSpriteSeq::IsValid
bool IsValid() const
Check whether the sequence contains any sprites.
Definition vehicle_base.h:152
VehicleSpriteSeq::GetBounds
void GetBounds(Rect *bounds) const
Determine shared bounds of all sprites.
Definition vehicle.cpp:103
VehicleSpriteSeq::Draw
void Draw(int x, int y, PaletteID default_pal, bool force_pal) const
Draw the sprite sequence.
Definition vehicle.cpp:131
Vehicle
Vehicle data structure.
Definition vehicle_base.h:244
Vehicle::GetDisplayProfitThisYear
Money GetDisplayProfitThisYear() const
Gets the profit vehicle had this year.
Definition vehicle_base.h:617
Vehicle::cargo_payment
CargoPayment * cargo_payment
The cargo payment we're currently in.
Definition vehicle_base.h:277
Vehicle::engine_type
EngineID engine_type
The type of engine used for this vehicle.
Definition vehicle_base.h:323
Vehicle::cargo_age_counter
uint16_t cargo_age_counter
Ticks till cargo is aged next.
Definition vehicle_base.h:346
Vehicle::z_pos
int32_t z_pos
z coordinate.
Definition vehicle_base.h:306
Vehicle::GetGroundVehicleFlags
uint16_t & GetGroundVehicleFlags()
Access the ground vehicle flags of the vehicle.
Definition vehicle.cpp:3185
Vehicle::direction
Direction direction
facing
Definition vehicle_base.h:307
Vehicle::ShiftDates
void ShiftDates(TimerGameEconomy::Date interval)
Shift all dates by given interval.
Definition vehicle.cpp:777
Vehicle::economy_age
TimerGameEconomy::Date economy_age
Age in economy days.
Definition vehicle_base.h:293
Vehicle::IsOrderListShared
bool IsOrderListShared() const
Check if we share our orders with another vehicle.
Definition vehicle_base.h:732
Vehicle::GetEngine
const Engine * GetEngine() const
Retrieves the engine of the vehicle.
Definition vehicle.cpp:747
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:886
Vehicle::Crash
virtual uint Crash(bool flooded=false)
Crash the (whole) vehicle chain.
Definition vehicle.cpp:280
Vehicle::IsStoppedInDepot
bool IsStoppedInDepot() const
Check whether the vehicle is in the depot and stopped.
Definition vehicle_base.h:560
Vehicle::GetOrder
Order * GetOrder(int index) const
Returns order 'index' of a vehicle or nullptr when it doesn't exists.
Definition vehicle_base.h:922
Vehicle::HasDepotOrder
bool HasDepotOrder() const
Checks if a vehicle has a depot in its order list.
Definition order_cmd.cpp:1851
Vehicle::LeaveStation
void LeaveStation()
Perform all actions when leaving a station.
Definition vehicle.cpp:2350
Vehicle::AddToShared
void AddToShared(Vehicle *shared_chain)
Adds this vehicle to a shared vehicle chain.
Definition vehicle.cpp:2966
Vehicle::cargo
VehicleCargoList cargo
The cargo this vehicle is carrying.
Definition vehicle_base.h:341
Vehicle::x_extent
uint8_t x_extent
x-extent of vehicle bounding box
Definition vehicle_base.h:316
Vehicle::hash_tile_prev
Vehicle ** hash_tile_prev
NOSAVE: Previous vehicle in the tile location hash.
Definition vehicle_base.h:285
Vehicle::HasUnbunchingOrder
bool HasUnbunchingOrder() const
Check if the current vehicle has an unbunching order.
Definition vehicle.cpp:2489
Vehicle::date_of_last_service
TimerGameEconomy::Date date_of_last_service
Last economy date the vehicle had a service at a depot.
Definition vehicle_base.h:295
Vehicle::cargo_cap
uint16_t cargo_cap
total capacity
Definition vehicle_base.h:344
Vehicle::last_loading_station
StationID last_loading_station
Last station the vehicle has stopped at and could possibly leave from with any cargo loaded.
Definition vehicle_base.h:338
Vehicle::GetNumOrders
VehicleOrderID GetNumOrders() const
Get the number of orders this vehicle has.
Definition vehicle_base.h:738
Vehicle::subtype
uint8_t subtype
subtype (Filled with values from AircraftSubType/DisasterSubType/EffectVehicleType/GroundVehicleSubty...
Definition vehicle_base.h:355
Vehicle::ReleaseUnitNumber
void ReleaseUnitNumber()
Release the vehicle's unit number.
Definition vehicle.cpp:2419
Vehicle::UpdateBoundingBoxCoordinates
void UpdateBoundingBoxCoordinates(bool update_cache) const
Update the bounding box co-ordinates of the vehicle.
Definition vehicle.cpp:1702
Vehicle::day_counter
uint8_t day_counter
Increased by one for each day.
Definition vehicle_base.h:349
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:2430
Vehicle::profit_this_year
Money profit_this_year
Profit this year << 8, low 8 bits are fract.
Definition vehicle_base.h:273
Vehicle::HasArticulatedPart
bool HasArticulatedPart() const
Check if an engine has an articulated part.
Definition vehicle_base.h:963
Vehicle::colourmap
SpriteID colourmap
NOSAVE: cached colour mapping.
Definition vehicle_base.h:288
Vehicle::breakdown_ctr
uint8_t breakdown_ctr
Counter for managing breakdown events.
Definition vehicle_base.h:299
Vehicle::breakdown_delay
uint8_t breakdown_delay
Counter for managing breakdown length.
Definition vehicle_base.h:300
Vehicle::GetNextVehicle
Vehicle * GetNextVehicle() const
Get the next real (non-articulated part) vehicle in the consist.
Definition vehicle_base.h:1016
Vehicle::group_id
GroupID group_id
Index of group Pool array.
Definition vehicle_base.h:366
Vehicle::SendToDepot
CommandCost SendToDepot(DoCommandFlag flags, DepotCommand command)
Send this vehicle to the depot using the given command(s).
Definition vehicle.cpp:2583
Vehicle::IncrementImplicitOrderIndex
void IncrementImplicitOrderIndex()
Increments cur_implicit_order_index, keeps care of the wrap-around and invalidates the GUI.
Definition vehicle_base.h:862
Vehicle::z_extent
uint8_t z_extent
z-extent of vehicle bounding box
Definition vehicle_base.h:318
Vehicle::date_of_last_service_newgrf
TimerGameCalendar::Date date_of_last_service_newgrf
Last calendar date the vehicle had a service at a depot, unchanged by the date cheat to protect again...
Definition vehicle_base.h:296
Vehicle::first
Vehicle * first
NOSAVE: pointer to the first vehicle in the chain.
Definition vehicle_base.h:250
Vehicle::CancelReservation
void CancelReservation(StationID next, Station *st)
Return all reserved cargo packets to the station and reset all packets staged for transfer.
Definition vehicle.cpp:2334
Vehicle::profit_last_year
Money profit_last_year
Profit last year << 8, low 8 bits are fract.
Definition vehicle_base.h:274
Vehicle::GetFirstOrder
Order * GetFirstOrder() const
Get the first order of the vehicles order list.
Definition vehicle_base.h:705
Vehicle::IsEngineCountable
bool IsEngineCountable() const
Check if a vehicle is counted in num_engines in each company struct.
Definition vehicle.cpp:714
Vehicle::~Vehicle
virtual ~Vehicle()
We want to 'destruct' the right class.
Definition vehicle.cpp:893
Vehicle::IsArticulatedPart
bool IsArticulatedPart() const
Check if the vehicle is an articulated part of an engine.
Definition vehicle_base.h:954
Vehicle::NeedsAutorenewing
bool NeedsAutorenewing(const Company *c, bool use_renew_setting=true) const
Function to tell if a vehicle needs to be autorenewed.
Definition vehicle.cpp:145
Vehicle::UpdateVisualEffect
void UpdateVisualEffect(bool allow_power_change=true)
Update the cached visual effect.
Definition vehicle.cpp:2664
Vehicle::LeaveUnbunchingDepot
void LeaveUnbunchingDepot()
Leave an unbunching depot and calculate the next departure time for shared order vehicles.
Definition vehicle.cpp:2514
Vehicle::y_offs
int8_t y_offs
y offset for vehicle sprite
Definition vehicle_base.h:322
Vehicle::IsFrontEngine
debug_inline bool IsFrontEngine() const
Check if the vehicle is a front engine.
Definition vehicle_base.h:945
Vehicle::previous_shared
Vehicle * previous_shared
NOSAVE: pointer to the previous vehicle in the shared order chain.
Definition vehicle_base.h:253
Vehicle::GetNumManualOrders
VehicleOrderID GetNumManualOrders() const
Get the number of manually added orders this vehicle has.
Definition vehicle_base.h:744
Vehicle::First
Vehicle * First() const
Get the first vehicle of this vehicle chain.
Definition vehicle_base.h:645
Vehicle::trip_occupancy
int8_t trip_occupancy
NOSAVE: Occupancy of vehicle of the current trip (updated after leaving a station).
Definition vehicle_base.h:347
Vehicle::x_bb_offs
int8_t x_bb_offs
x offset of vehicle bounding box
Definition vehicle_base.h:319
Vehicle::current_order
Order current_order
The current order (+ status, like: loading)
Definition vehicle_base.h:356
Vehicle::PreDestructor
void PreDestructor()
Destroy all stuff that (still) needs the virtual functions to work properly.
Definition vehicle.cpp:826
Vehicle::last_loading_tick
TimerGameTick::TickCounter last_loading_tick
Last TimerGameTick::counter tick that the vehicle has stopped at a station and could possibly leave w...
Definition vehicle_base.h:339
Vehicle::cargo_type
CargoID cargo_type
type of cargo this vehicle is carrying
Definition vehicle_base.h:342
Vehicle::HandlePathfindingResult
void HandlePathfindingResult(bool path_found)
Handle the pathfinding result, especially the lost status.
Definition vehicle.cpp:791
Vehicle::Next
Vehicle * Next() const
Get the next vehicle of this vehicle.
Definition vehicle_base.h:632
Vehicle::x_offs
int8_t x_offs
x offset for vehicle sprite
Definition vehicle_base.h:321
Vehicle::y_pos
int32_t y_pos
y coordinate.
Definition vehicle_base.h:305
Vehicle::x_pos
int32_t x_pos
x coordinate.
Definition vehicle_base.h:304
Vehicle::GetGRF
const GRFFile * GetGRF() const
Retrieve the NewGRF the vehicle is tied to.
Definition vehicle.cpp:757
Vehicle::orders
OrderList * orders
Pointer to the order list for this vehicle.
Definition vehicle_base.h:359
Vehicle::GetDisplayMinPowerToWeight
uint32_t GetDisplayMinPowerToWeight() const
Calculates the minimum power-to-weight ratio using the maximum weight of the ground vehicle.
Definition vehicle.cpp:3259
Vehicle::y_extent
uint8_t y_extent
y-extent of vehicle bounding box
Definition vehicle_base.h:317
Vehicle::FindClosestDepot
virtual ClosestDepot FindClosestDepot()
Find the closest depot for this vehicle and tell us the location, DestinationID and whether we should...
Definition vehicle_base.h:805
Vehicle::UpdateViewport
void UpdateViewport(bool dirty)
Update the vehicle on the viewport, updating the right hash and setting the new coordinates.
Definition vehicle.cpp:1735
Vehicle::value
Money value
Value of the vehicle.
Definition vehicle_base.h:275
Vehicle::MarkAllViewportsDirty
bool MarkAllViewportsDirty() const
Marks viewports dirty where the vehicle's image is.
Definition vehicle.cpp:1774
Vehicle::refit_cap
uint16_t refit_cap
Capacity left over from before last refit.
Definition vehicle_base.h:345
Vehicle::vehstatus
uint8_t vehstatus
Status.
Definition vehicle_base.h:354
Vehicle::vcache
VehicleCache vcache
Cache of often used vehicle values.
Definition vehicle_base.h:364
Vehicle::motion_counter
uint32_t motion_counter
counter to occasionally play a vehicle sound.
Definition vehicle_base.h:331
Vehicle::GetGRFID
uint32_t GetGRFID() const
Retrieve the GRF ID of the NewGRF the vehicle is tied to.
Definition vehicle.cpp:767
Vehicle::GetGroundVehicleCache
GroundVehicleCache * GetGroundVehicleCache()
Access the ground vehicle cache of the vehicle.
Definition vehicle.cpp:3155
Vehicle::OnNewEconomyDay
virtual void OnNewEconomyDay()
Calls the new economy day handler of the vehicle.
Definition vehicle_base.h:582
Vehicle::hash_tile_current
Vehicle ** hash_tile_current
NOSAVE: Cache of the current hash chain.
Definition vehicle_base.h:286
Vehicle::OnNewCalendarDay
virtual void OnNewCalendarDay()
Calls the new calendar day handler of the vehicle.
Definition vehicle_base.h:577
Vehicle::NextShared
Vehicle * NextShared() const
Get the next vehicle of the shared vehicle chain.
Definition vehicle_base.h:714
Vehicle::y_bb_offs
int8_t y_bb_offs
y offset of vehicle bounding box
Definition vehicle_base.h:320
Vehicle::GetCurrentMaxSpeed
virtual int GetCurrentMaxSpeed() const
Calculates the maximum speed of the vehicle under its current conditions.
Definition vehicle_base.h:536
Vehicle::HasFullLoadOrder
bool HasFullLoadOrder() const
Check if the current vehicle has a full load order.
Definition vehicle.cpp:2465
Vehicle::IsPrimaryVehicle
virtual bool IsPrimaryVehicle() const
Whether this is the primary vehicle in the chain.
Definition vehicle_base.h:477
Vehicle::BeginLoading
void BeginLoading()
Prepare everything to begin the loading when arriving at a station.
Definition vehicle.cpp:2203
Vehicle::GetLastOrder
Order * GetLastOrder() const
Returns the last order of a vehicle, or nullptr if it doesn't exists.
Definition vehicle_base.h:931
Vehicle::hash_tile_next
Vehicle * hash_tile_next
NOSAVE: Next vehicle in the tile location hash.
Definition vehicle_base.h:284
Vehicle::cur_speed
uint16_t cur_speed
current speed
Definition vehicle_base.h:328
Vehicle::previous
Vehicle * previous
NOSAVE: pointer to the previous vehicle in the chain.
Definition vehicle_base.h:249
Vehicle::HasEngineType
bool HasEngineType() const
Check whether Vehicle::engine_type has any meaning.
Definition vehicle.cpp:731
Vehicle::age
TimerGameCalendar::Date age
Age in calendar days.
Definition vehicle_base.h:292
Vehicle::IsWaitingForUnbunching
bool IsWaitingForUnbunching() const
Check whether a vehicle inside a depot is waiting for unbunching.
Definition vehicle.cpp:2561
Vehicle::fill_percent_te_id
TextEffectID fill_percent_te_id
a text-effect id to a loading indicator object
Definition vehicle_base.h:325
Vehicle::Orders
IterateWrapper Orders() const
Returns an iterable ensemble of orders of a vehicle.
Definition vehicle_base.h:1084
Vehicle::SetNext
void SetNext(Vehicle *next)
Set the next vehicle of this vehicle.
Definition vehicle.cpp:2937
Vehicle::breakdowns_since_last_service
uint8_t breakdowns_since_last_service
Counter for the amount of breakdowns.
Definition vehicle_base.h:301
Vehicle::next
Vehicle * next
pointer to the next vehicle in the chain
Definition vehicle_base.h:248
Vehicle::max_age
TimerGameCalendar::Date max_age
Maximum age.
Definition vehicle_base.h:294
Vehicle::sprite_cache
MutableSpriteCache sprite_cache
Cache of sprites and values related to recalculating them, see MutableSpriteCache.
Definition vehicle_base.h:368
Vehicle::reliability
uint16_t reliability
Reliability.
Definition vehicle_base.h:297
Vehicle::GetDisplayMaxWeight
uint32_t GetDisplayMaxWeight() const
Calculates the maximum weight of the ground vehicle when loaded.
Definition vehicle.cpp:3244
Vehicle::FirstShared
Vehicle * FirstShared() const
Get the first vehicle of this vehicle chain.
Definition vehicle_base.h:726
Vehicle::RemoveFromShared
void RemoveFromShared()
Removes the vehicle from the shared order list.
Definition vehicle.cpp:2989
Vehicle::HandleBreakdown
bool HandleBreakdown()
Handle all of the aspects of a vehicle breakdown This includes adding smoke and sounds,...
Definition vehicle.cpp:1363
Vehicle::IsGroundVehicle
debug_inline bool IsGroundVehicle() const
Check if the vehicle is a ground vehicle.
Definition vehicle_base.h:515
Vehicle::UpdatePositionAndViewport
void UpdatePositionAndViewport()
Update the position of the vehicle, and update the viewport.
Definition vehicle.cpp:1764
Vehicle::Vehicle
Vehicle(VehicleType type=VEH_INVALID)
Vehicle constructor.
Definition vehicle.cpp:361
Vehicle::Previous
Vehicle * Previous() const
Get the previous vehicle of this vehicle.
Definition vehicle_base.h:639
Vehicle::PlayLeaveStationSound
virtual void PlayLeaveStationSound(bool force=false) const
Play the sound associated with leaving the station.
Definition vehicle_base.h:472
Vehicle::coord
Rect coord
NOSAVE: Graphical bounding box of the vehicle, i.e. what to redraw on moves.
Definition vehicle_base.h:279
Vehicle::reliability_spd_dec
uint16_t reliability_spd_dec
Reliability decrease speed.
Definition vehicle_base.h:298
Vehicle::tick_counter
uint8_t tick_counter
Increased by one for each tick.
Definition vehicle_base.h:350
Vehicle::IsInDepot
virtual bool IsInDepot() const
Check whether the vehicle is in the depot.
Definition vehicle_base.h:548
Vehicle::tile
TileIndex tile
Current tile index.
Definition vehicle_base.h:264
Vehicle::Tick
virtual bool Tick()
Calls the tick handler of the vehicle.
Definition vehicle_base.h:572
Vehicle::dest_tile
TileIndex dest_tile
Heading for this tile.
Definition vehicle_base.h:271
Vehicle::NeedsServicing
bool NeedsServicing() const
Check if the vehicle needs to go to a depot in near future (if a opportunity presents itself) for ser...
Definition vehicle.cpp:190
Vehicle::HasConditionalOrder
bool HasConditionalOrder() const
Check if the current vehicle has a conditional order.
Definition vehicle.cpp:2477
Vehicle::UpdatePosition
void UpdatePosition()
Update the position of the vehicle.
Definition vehicle.cpp:1693
Vehicle::last_station_visited
StationID last_station_visited
The last station we stopped at.
Definition vehicle_base.h:337
Vehicle::ResetRefitCaps
void ResetRefitCaps()
Reset all refit_cap in the consist to cargo_cap.
Definition vehicle.cpp:2411
Vehicle::breakdown_chance
uint8_t breakdown_chance
Current chance of breakdowns.
Definition vehicle_base.h:302
Vehicle::ShowVisualEffect
void ShowVisualEffect() const
Draw visual effects (smoke and/or sparks) for a vehicle chain.
Definition vehicle.cpp:2787
Vehicle::owner
Owner owner
Which company owns the vehicle?
Definition vehicle_base.h:309
Vehicle::unitnumber
UnitID unitnumber
unit number, for display purposes only
Definition vehicle_base.h:326
Vehicle::next_shared
Vehicle * next_shared
pointer to the next vehicle that shares the order
Definition vehicle_base.h:252
Vehicle::NeedsAutomaticServicing
bool NeedsAutomaticServicing() const
Checks if the current order should be interrupted for a service-in-depot order.
Definition vehicle.cpp:272
Vehicle::DeleteUnreachedImplicitOrders
void DeleteUnreachedImplicitOrders()
Delete all implicit orders which were not reached.
Definition vehicle.cpp:2164
Vehicle::hash_viewport_prev
Vehicle ** hash_viewport_prev
NOSAVE: Previous vehicle in the visual location hash.
Definition vehicle_base.h:282
Vehicle::GetImage
virtual void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const
Gets the sprite to show for the given direction.
Definition vehicle_base.h:486
Vehicle::hash_viewport_next
Vehicle * hash_viewport_next
NOSAVE: Next vehicle in the visual location hash.
Definition vehicle_base.h:281
Viewport
Data structure for viewport, display of a part of the world.
Definition viewport_type.h:22
Viewport::top
int top
Screen coordinate top edge of the viewport.
Definition viewport_type.h:24
Viewport::width
int width
Screen width of the viewport.
Definition viewport_type.h:25
Viewport::zoom
ZoomLevel zoom
The zoom level of the viewport.
Definition viewport_type.h:33
Viewport::virtual_top
int virtual_top
Virtual top coordinate.
Definition viewport_type.h:29
Viewport::virtual_left
int virtual_left
Virtual left coordinate.
Definition viewport_type.h:28
Viewport::left
int left
Screen coordinate left edge of the viewport.
Definition viewport_type.h:23
Viewport::height
int height
Screen height of the viewport.
Definition viewport_type.h:26
VehicleEnterTileStatus
VehicleEnterTileStatus
The returned bits of VehicleEnterTile.
Definition tile_cmd.h:21
GetTileMaxPixelZ
int GetTileMaxPixelZ(TileIndex tile)
Get top height of the tile.
Definition tile_map.h:312
GetTileType
static debug_inline TileType GetTileType(Tile tile)
Get the tiletype of a given tile.
Definition tile_map.h:96
IsTileType
static debug_inline bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
Definition tile_map.h:150
MAX_VEHICLE_PIXEL_Y
static const int MAX_VEHICLE_PIXEL_Y
Maximum height of a vehicle in pixels in ZOOM_BASE.
Definition tile_type.h:22
TILE_SIZE
static const uint TILE_SIZE
Tile size in world coordinates.
Definition tile_type.h:15
MP_STATION
@ MP_STATION
A tile of a station.
Definition tile_type.h:53
MAX_VEHICLE_PIXEL_X
static const int MAX_VEHICLE_PIXEL_X
Maximum width of a vehicle in pixels in ZOOM_BASE.
Definition tile_type.h:21
timer.h
Definition of Interval and OneShot timers.
timer_game_calendar.h
Definition of the game-calendar-timer.
timer_game_economy.h
Definition of the game-economy-timer.
timer_game_tick.h
Definition of the tick-based game-timer.
timetable.h
Functions related to time tabling.
UpdateVehicleTimetable
void UpdateVehicleTimetable(Vehicle *v, bool travelling)
Update the timetable for the vehicle.
Definition timetable_cmd.cpp:469
TracksOverlap
bool TracksOverlap(TrackBits bits)
Checks if the given tracks overlap, ie form a crossing.
Definition track_func.h:645
TrackBits
TrackBits
Allow incrementing of Track variables.
Definition track_type.h:35
TRACK_BIT_DEPOT
@ TRACK_BIT_DEPOT
Bitflag for a depot.
Definition track_type.h:53
train.h
Base for the train class.
VRF_LEAVING_STATION
@ VRF_LEAVING_STATION
Train is just leaving a station.
Definition train.h:33
VRF_TOGGLE_REVERSE
@ VRF_TOGGLE_REVERSE
Used for vehicle var 0xFE bit 8 (toggled each time the train is reversed, accurate for first vehicle ...
Definition train.h:31
VRF_REVERSE_DIRECTION
@ VRF_REVERSE_DIRECTION
Reverse the visible direction of the vehicle.
Definition train.h:28
CCF_ARRANGE
@ CCF_ARRANGE
Valid changes for arranging the consist in a depot.
Definition train.h:52
TFP_NONE
@ TFP_NONE
Normal operation.
Definition train.h:38
train_cmd.h
Command definitions related to trains.
TransparencyOption
TransparencyOption
Transparency option bits: which position in _transparency_opt stands for which transparency.
Definition transparency.h:22
TO_INVALID
@ TO_INVALID
Invalid transparency option.
Definition transparency.h:33
IsTransparencySet
bool IsTransparencySet(TransparencyOption to)
Check if the transparency option bit is set and if we aren't in the game menu (there's never transpar...
Definition transparency.h:48
IsInvisibilitySet
bool IsInvisibilitySet(TransparencyOption to)
Check if the invisibility option bit is set and if we aren't in the game menu (there's never transpar...
Definition transparency.h:59
UnitID
uint16_t UnitID
Type for the company global vehicle unit number.
Definition transport_type.h:16
tunnel_map.h
Map accessors for tunnels.
IsTunnelTile
bool IsTunnelTile(Tile t)
Is this a tunnel (entrance)?
Definition tunnel_map.h:34
GetVehiclePalette
PaletteID GetVehiclePalette(const Vehicle *v)
Get the colour map for a vehicle.
Definition vehicle.cpp:2152
CanBuildVehicleInfrastructure
bool CanBuildVehicleInfrastructure(VehicleType type, uint8_t subtype)
Check whether we can build infrastructure for the given vehicle type.
Definition vehicle.cpp:1922
EnsureNoVehicleOnGround
CommandCost EnsureNoVehicleOnGround(TileIndex tile)
Ensure there is no vehicle at the ground at the given position.
Definition vehicle.cpp:546
VehiclesHaveSameEngineList
bool VehiclesHaveSameEngineList(const Vehicle *v1, const Vehicle *v2)
Checks if two vehicle chains have the same list of engines.
Definition vehicle.cpp:3272
VehiclesHaveSameOrderList
bool VehiclesHaveSameOrderList(const Vehicle *v1, const Vehicle *v2)
Checks if two vehicles have the same list of orders.
Definition vehicle.cpp:3289
SpawnAdvancedVisualEffect
static void SpawnAdvancedVisualEffect(const Vehicle *v)
Call CBID_VEHICLE_SPAWN_VISUAL_EFFECT and spawn requested effects.
Definition vehicle.cpp:2732
GetVehicleTunnelBridgeProc
static Vehicle * GetVehicleTunnelBridgeProc(Vehicle *v, void *data)
Procedure called for every vehicle found in tunnel/bridge in the hash map.
Definition vehicle.cpp:560
VehicleEnterDepot
void VehicleEnterDepot(Vehicle *v)
Vehicle entirely entered the depot, update its status, orders, vehicle windows, service it,...
Definition vehicle.cpp:1552
GetVehicleSet
void GetVehicleSet(VehicleSet &set, Vehicle *v, uint8_t num_vehicles)
Calculates the set of vehicles that will be affected by a given selection.
Definition vehicle.cpp:3218
HasVehicleOnPosXY
bool HasVehicleOnPosXY(int x, int y, void *data, VehicleFromPosProc *proc)
Checks whether a vehicle in on a specific location.
Definition vehicle.cpp:461
GetFreeUnitNumber
UnitID GetFreeUnitNumber(VehicleType type)
Get an unused unit number for a vehicle (if allowed).
Definition vehicle.cpp:1895
RunVehicleCalendarDayProc
void RunVehicleCalendarDayProc()
Age all vehicles, spreading out the action using the current TimerGameCalendar::date_fract.
Definition vehicle.cpp:937
VehicleFromPos
static Vehicle * VehicleFromPos(TileIndex tile, void *data, VehicleFromPosProc *proc, bool find_first)
Helper function for FindVehicleOnPos/HasVehicleOnPos.
Definition vehicle.cpp:476
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:346
GetEngineLivery
const Livery * GetEngineLivery(EngineID engine_type, CompanyID company, EngineID parent_engine_type, const Vehicle *v, uint8_t livery_setting)
Determines the livery for a vehicle.
Definition vehicle.cpp:2064
_vehicle_pool
VehiclePool _vehicle_pool("Vehicle")
The pool with all our precious vehicles.
VehicleServiceInDepot
void VehicleServiceInDepot(Vehicle *v)
Service a vehicle and all subsequent vehicles in the consist.
Definition vehicle.cpp:167
EnsureNoTrainOnTrackBits
CommandCost EnsureNoTrainOnTrackBits(TileIndex tile, TrackBits track_bits)
Tests if a vehicle interacts with the specified track bits.
Definition vehicle.cpp:608
FindVehicleOnPosXY
void FindVehicleOnPosXY(int x, int y, void *data, VehicleFromPosProc *proc)
Find a vehicle from a specific location.
Definition vehicle.cpp:445
RunEconomyVehicleDayProc
static void RunEconomyVehicleDayProc()
Increases the day counter for all vehicles and calls 1-day and 32-day handlers.
Definition vehicle.cpp:954
GetEngineLiveryScheme
LiveryScheme GetEngineLiveryScheme(EngineID engine_type, EngineID parent_engine_type, const Vehicle *v)
Determines the LiveryScheme for a vehicle.
Definition vehicle.cpp:1970
VehicleEnterTile
VehicleEnterTileStatus VehicleEnterTile(Vehicle *v, TileIndex tile, int x, int y)
Call the tile callback function for a vehicle entering a tile.
Definition vehicle.cpp:1838
ViewportAddVehicles
void ViewportAddVehicles(DrawPixelInfo *dpi)
Add the vehicle sprites that should be drawn at a part of the screen.
Definition vehicle.cpp:1154
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:1784
HasVehicleOnPos
bool HasVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
Checks whether a vehicle is on a specific location.
Definition vehicle.cpp:520
FindVehicleOnPos
void FindVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
Find a vehicle from a specific location.
Definition vehicle.cpp:505
GetVehicleCannotUseStationReason
StringID GetVehicleCannotUseStationReason(const Vehicle *v, const Station *st)
Get reason string why this station can't be used by the given vehicle.
Definition vehicle.cpp:3104
DecreaseVehicleValue
void DecreaseVehicleValue(Vehicle *v)
Decrease the value of a vehicle.
Definition vehicle.cpp:1301
EconomyAgeVehicle
void EconomyAgeVehicle(Vehicle *v)
Update economy age of a vehicle.
Definition vehicle.cpp:1429
EnsureNoVehicleProcZ
static Vehicle * EnsureNoVehicleProcZ(Vehicle *v, void *data)
Callback that returns 'real' vehicles lower or at height *(int*)data .
Definition vehicle.cpp:531
CalcPercentVehicleFilled
uint8_t CalcPercentVehicleFilled(const Vehicle *front, StringID *colour)
Calculates how full a vehicle is.
Definition vehicle.cpp:1493
CheckClickOnVehicle
Vehicle * CheckClickOnVehicle(const Viewport *vp, int x, int y)
Find the vehicle close to the clicked coordinates.
Definition vehicle.cpp:1248
TunnelBridgeIsFree
CommandCost TunnelBridgeIsFree(TileIndex tile, TileIndex endtile, const Vehicle *ignore)
Finds vehicle in tunnel / bridge.
Definition vehicle.cpp:575
GetEnginePalette
PaletteID GetEnginePalette(EngineID engine_type, CompanyID company)
Get the colour map for an engine.
Definition vehicle.cpp:2142
ShowNewGrfVehicleError
void ShowNewGrfVehicleError(EngineID engine, StringID part1, StringID part2, GRFBugs bug_type, bool critical)
Displays a "NewGrf Bug" error message for a engine, and pauses the game if not networking.
Definition vehicle.cpp:317
CanVehicleUseStation
bool CanVehicleUseStation(EngineID engine_type, const Station *st)
Can this station be used by the given engine type?
Definition vehicle.cpp:3058
AgeVehicle
void AgeVehicle(Vehicle *v)
Update age of a vehicle.
Definition vehicle.cpp:1441
VehicleFromPosXY
static Vehicle * VehicleFromPosXY(int x, int y, void *data, VehicleFromPosProc *proc, bool find_first)
Helper function for FindVehicleOnPos/HasVehicleOnPos.
Definition vehicle.cpp:418
VehicleEnteredDepotThisTick
void VehicleEnteredDepotThisTick(Vehicle *v)
Adds a vehicle to the list of vehicles that visited a depot this tick.
Definition vehicle.cpp:921
AutoreplaceMap
std::map< VehicleID, bool > AutoreplaceMap
List of vehicles that should check for autoreplace this tick.
Definition vehicle.cpp:694
PreviousOrderIsUnbunching
static bool PreviousOrderIsUnbunching(const Vehicle *v)
Check if the previous order is a depot unbunching order.
Definition vehicle.cpp:2501
DoDrawVehicle
static void DoDrawVehicle(const Vehicle *v)
Add vehicle sprite for drawing to the screen.
Definition vehicle.cpp:1124
VF_STOP_LOADING
@ VF_STOP_LOADING
Don't load anymore during the next load cycle.
Definition vehicle_base.h:51
VF_CARGO_UNLOADING
@ VF_CARGO_UNLOADING
Vehicle is unloading cargo.
Definition vehicle_base.h:46
VF_PATHFINDER_LOST
@ VF_PATHFINDER_LOST
Vehicle's pathfinder is lost.
Definition vehicle_base.h:52
VF_LOADING_FINISHED
@ VF_LOADING_FINISHED
Vehicle has finished loading.
Definition vehicle_base.h:45
VisualEffectSpawnModel
VisualEffectSpawnModel
Models for spawning visual effects.
Definition vehicle_base.h:101
VESM_ELECTRIC
@ VESM_ELECTRIC
Electric model.
Definition vehicle_base.h:105
VESM_STEAM
@ VESM_STEAM
Steam model.
Definition vehicle_base.h:103
VESM_DIESEL
@ VESM_DIESEL
Diesel model.
Definition vehicle_base.h:104
VESM_NONE
@ VESM_NONE
No visual effect.
Definition vehicle_base.h:102
VS_UNCLICKABLE
@ VS_UNCLICKABLE
Vehicle is not clickable by the user (shadow vehicles).
Definition vehicle_base.h:35
VS_TRAIN_SLOWING
@ VS_TRAIN_SLOWING
Train is slowing down.
Definition vehicle_base.h:37
VS_AIRCRAFT_BROKEN
@ VS_AIRCRAFT_BROKEN
Aircraft is broken down.
Definition vehicle_base.h:39
VS_SHADOW
@ VS_SHADOW
Vehicle is a shadow vehicle.
Definition vehicle_base.h:38
VS_STOPPED
@ VS_STOPPED
Vehicle is stopped by the player.
Definition vehicle_base.h:34
VS_HIDDEN
@ VS_HIDDEN
Vehicle is not visible.
Definition vehicle_base.h:33
VS_CRASHED
@ VS_CRASHED
Vehicle is crashed.
Definition vehicle_base.h:40
VS_DEFPAL
@ VS_DEFPAL
Use default vehicle palette.
Definition vehicle_base.h:36
VE_TYPE_DEFAULT
@ VE_TYPE_DEFAULT
Use default from engine class.
Definition vehicle_base.h:88
VE_TYPE_COUNT
@ VE_TYPE_COUNT
Number of bits used for the effect type.
Definition vehicle_base.h:87
VE_OFFSET_CENTRE
@ VE_OFFSET_CENTRE
Value of offset corresponding to a position above the centre of the vehicle.
Definition vehicle_base.h:84
VE_TYPE_ELECTRIC
@ VE_TYPE_ELECTRIC
Electric sparks.
Definition vehicle_base.h:91
VE_TYPE_START
@ VE_TYPE_START
First bit used for the type of effect.
Definition vehicle_base.h:86
VE_OFFSET_COUNT
@ VE_OFFSET_COUNT
Number of bits used for the offset.
Definition vehicle_base.h:83
VE_ADVANCED_EFFECT
@ VE_ADVANCED_EFFECT
Flag for advanced effects.
Definition vehicle_base.h:94
VE_DISABLE_EFFECT
@ VE_DISABLE_EFFECT
Flag to disable visual effect.
Definition vehicle_base.h:93
VE_TYPE_STEAM
@ VE_TYPE_STEAM
Steam plumes.
Definition vehicle_base.h:89
VE_TYPE_DIESEL
@ VE_TYPE_DIESEL
Diesel fumes.
Definition vehicle_base.h:90
VE_DEFAULT
@ VE_DEFAULT
Default value to indicate that visual effect should be based on engine class.
Definition vehicle_base.h:97
VE_OFFSET_START
@ VE_OFFSET_START
First bit that contains the offset (0 = front, 8 = centre, 15 = rear)
Definition vehicle_base.h:82
VE_DISABLE_WAGON_POWER
@ VE_DISABLE_WAGON_POWER
Flag to disable wagon power.
Definition vehicle_base.h:95
INVALID_COORD
static const int32_t INVALID_COORD
Sentinel for an invalid coordinate.
Definition vehicle_base.h:1288
vehicle_cmd.h
Command definitions for vehicles.
vehicle_func.h
Functions related to vehicles.
VEHICLE_PROFIT_MIN_AGE
static const TimerGameEconomy::Date VEHICLE_PROFIT_MIN_AGE
Only vehicles older than this have a meaningful profit.
Definition vehicle_func.h:28
IsCompanyBuildableVehicleType
bool IsCompanyBuildableVehicleType(VehicleType type)
Is the given vehicle type buildable by a company?
Definition vehicle_func.h:91
VIWD_MODIFY_ORDERS
@ VIWD_MODIFY_ORDERS
Other order modifications.
Definition vehicle_gui.h:36
GetWindowClassForVehicleType
WindowClass GetWindowClassForVehicleType(VehicleType vt)
Get WindowClass for vehicle list of given vehicle type.
Definition vehicle_gui.h:97
EIT_ON_MAP
@ EIT_ON_MAP
Vehicle drawn in viewport.
Definition vehicle_type.h:79
VehicleType
VehicleType
Available vehicle types.
Definition vehicle_type.h:21
VEH_ROAD
@ VEH_ROAD
Road vehicle type.
Definition vehicle_type.h:25
VEH_DISASTER
@ VEH_DISASTER
Disaster vehicle type.
Definition vehicle_type.h:32
VEH_AIRCRAFT
@ VEH_AIRCRAFT
Aircraft vehicle type.
Definition vehicle_type.h:27
VEH_SHIP
@ VEH_SHIP
Ship vehicle type.
Definition vehicle_type.h:26
VEH_EFFECT
@ VEH_EFFECT
Effect vehicle type (smoke, explosions, sparks, bubbles)
Definition vehicle_type.h:31
VEH_TRAIN
@ VEH_TRAIN
Train vehicle type.
Definition vehicle_type.h:24
INVALID_VEHICLE
static const VehicleID INVALID_VEHICLE
Constant representing a non-existing vehicle.
Definition vehicle_type.h:54
VEHICLE_LENGTH
static const uint VEHICLE_LENGTH
The length of a vehicle in tile units.
Definition vehicle_type.h:69
DepotCommand
DepotCommand
Flags for goto depot commands.
Definition vehicle_type.h:57
DepotCommand::DontCancel
@ DontCancel
Don't cancel current goto depot command if any.
DepotCommand::Service
@ Service
The vehicle will leave the depot right after arrival (service only)
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
vehiclelist.h
Functions and type for generating vehicle lists.
StartSpriteCombine
void StartSpriteCombine()
Starts a block of sprites, which are "combined" into a single bounding box.
Definition viewport.cpp:767
AddSortableSpriteToDraw
void AddSortableSpriteToDraw(SpriteID image, PaletteID pal, int x, int y, int w, int h, int dz, int z, bool transparent, int bb_offset_x, int bb_offset_y, int bb_offset_z, const SubSprite *sub)
Draw a (transparent) sprite at given coordinates with a given bounding box.
Definition viewport.cpp:671
EndSpriteCombine
void EndSpriteCombine()
Terminates a block of sprites started by StartSpriteCombine.
Definition viewport.cpp:777
viewport_func.h
Functions related to (drawing on) viewports.
CloseWindowById
void CloseWindowById(WindowClass cls, WindowNumber number, bool force, int data)
Close a window by its class and window number (if it is open).
Definition window.cpp:1140
SetWindowClassesDirty
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting)
Definition window.cpp:3127
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:3219
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:3114
SetWindowDirty
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition window.cpp:3101
InvalidateWindowClassesData
void InvalidateWindowClassesData(WindowClass cls, int data, bool gui_scope)
Mark window data of all windows of a given class as invalid (in need of re-computing) Note that by de...
Definition window.cpp:3236
WC_ROADVEH_LIST
@ WC_ROADVEH_LIST
Road vehicle list; Window numbers:
Definition window_type.h:314
WC_VEHICLE_ORDERS
@ WC_VEHICLE_ORDERS
Vehicle orders; Window numbers:
Definition window_type.h:212
WC_VEHICLE_DEPOT
@ WC_VEHICLE_DEPOT
Depot view; Window numbers:
Definition window_type.h:351
WC_SHIPS_LIST
@ WC_SHIPS_LIST
Ships list; Window numbers:
Definition window_type.h:320
WC_STATION_VIEW
@ WC_STATION_VIEW
Station view; Window numbers:
Definition window_type.h:345
WC_TRAINS_LIST
@ WC_TRAINS_LIST
Trains list; Window numbers:
Definition window_type.h:308
WC_VEHICLE_REFIT
@ WC_VEHICLE_REFIT
Vehicle refit; Window numbers:
Definition window_type.h:206
WC_VEHICLE_DETAILS
@ WC_VEHICLE_DETAILS
Vehicle details; Window numbers:
Definition window_type.h:200
WC_COMPANY
@ WC_COMPANY
Company view; Window numbers:
Definition window_type.h:369
WC_VEHICLE_VIEW
@ WC_VEHICLE_VIEW
Vehicle view; Window numbers:
Definition window_type.h:339
WC_VEHICLE_TIMETABLE
@ WC_VEHICLE_TIMETABLE
Vehicle timetable; Window numbers:
Definition window_type.h:224
WC_AIRCRAFT_LIST
@ WC_AIRCRAFT_LIST
Aircraft list; Window numbers:
Definition window_type.h:326
zoom_func.h
Functions related to zooming.
ScaleByZoom
int ScaleByZoom(int value, ZoomLevel zoom)
Scale by zoom level, usually shift left (when zoom > ZOOM_LVL_MIN) When shifting right,...
Definition zoom_func.h:22