OpenTTD Source: src/vehicle.cpp Source File

OpenTTD Source 14.1

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 */
69 static const uint GEN_HASHX_BITS = 6;
70 static const uint GEN_HASHY_BITS = 6;
71
72 /* Size of each hash bucket */
73 static const uint GEN_HASHX_BUCKET_BITS = 7;
74 static 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_LVL_SHIFT, GEN_HASHX_BITS)
78 #define GEN_HASHY(y) (GB((y), GEN_HASHY_BUCKET_BITS + ZOOM_LVL_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 */
82 static const int GEN_HASHX_SIZE = 1 << (GEN_HASHX_BUCKET_BITS + GEN_HASHX_BITS + ZOOM_LVL_SHIFT);
83 static const int GEN_HASHY_SIZE = 1 << (GEN_HASHY_BUCKET_BITS + GEN_HASHY_BITS + ZOOM_LVL_SHIFT);
84
85 /* Increments to reach next bucket in hash table */
86 static const int GEN_HASHX_INC = 1;
87 static const int GEN_HASHY_INC = 1 << GEN_HASHX_BITS;
88
89 /* Mask to wrap-around buckets */
90 static const uint GEN_HASHX_MASK = (1 << GEN_HASHX_BITS) - 1;
91 static 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
103 void 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) return false;
277 return NeedsServicing();
278 }
279
280 uint 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.grffile->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
361 Vehicle::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. */
377 const int HASH_BITS = 7;
378 const int HASH_SIZE = 1 << HASH_BITS;
379 const int HASH_MASK = HASH_SIZE - 1;
380 const int TOTAL_HASH_SIZE = 1 << (HASH_BITS * 2);
381 const 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. */
385 const int HASH_RES = 0;
386
387 static Vehicle *_vehicle_tile_hash[TOTAL_HASH_SIZE];
388
389 static 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_cmd_error(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_cmd_error(STR_ERROR_TRAIN_IN_THE_WAY + v->type);
585 return CommandCost();
586 }
587
588 static 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_cmd_error(STR_ERROR_TRAIN_IN_THE_WAY + v->type);
616 return CommandCost();
617 }
618
619 static 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
652 static Vehicle *_vehicle_viewport_hash[1 << (GEN_HASHX_BITS + GEN_HASHY_BITS)];
653
654 static 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
678 void 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
685 void ResetVehicleColourMap()
686 {
687 for (Vehicle *v : Vehicle::Iterate()) { v->colourmap = PAL_NONE; }
688 }
689
694 using AutoreplaceMap = std::map<VehicleID, bool>;
695 static AutoreplaceMap _vehicles_to_autoreplace;
696
697 void InitializeVehicles()
698 {
699 _vehicles_to_autoreplace.clear();
700 ResetVehicleHash();
701 }
702
703 uint 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
767 uint32_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
893 Vehicle::~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 DeleteVehicleNews(this->index, INVALID_STRING_ID);
912 DeleteNewGRFInspectWindow(GetGrfSpecFeature(this->type), this->index);
913 }
914
919 void VehicleEnteredDepotThisTick(Vehicle *v)
920 {
921 /* Vehicle should stop in the depot if it was in 'stopping' state */
922 _vehicles_to_autoreplace[v->index] = !(v->vehstatus & VS_STOPPED);
923
924 /* We ALWAYS set the stopped state. Even when the vehicle does not plan on
925 * stopping in the depot, so we stop it to ensure that it will not reserve
926 * the path out of the depot before we might autoreplace it to a different
927 * engine. The new engine would not own the reserved path we store that we
928 * stopped the vehicle, so autoreplace can start it again */
929 v->vehstatus |= VS_STOPPED;
930 }
931
935 void RunVehicleCalendarDayProc()
936 {
937 if (_game_mode != GM_NORMAL) return;
938
939 /* Run the calendar day proc for every DAY_TICKS vehicle starting at TimerGameCalendar::date_fract. */
940 for (size_t i = TimerGameCalendar::date_fract; i < Vehicle::GetPoolSize(); i += Ticks::DAY_TICKS) {
941 Vehicle *v = Vehicle::Get(i);
942 if (v == nullptr) continue;
943 v->OnNewCalendarDay();
944 }
945 }
946
952 static void RunEconomyVehicleDayProc()
953 {
954 if (_game_mode != GM_NORMAL) return;
955
956 /* Run the economy day proc for every DAY_TICKS vehicle starting at TimerGameEconomy::date_fract. */
957 for (size_t i = TimerGameEconomy::date_fract; i < Vehicle::GetPoolSize(); i += Ticks::DAY_TICKS) {
958 Vehicle *v = Vehicle::Get(i);
959 if (v == nullptr) continue;
960
961 /* Call the 32-day callback if needed */
962 if ((v->day_counter & 0x1F) == 0 && v->HasEngineType()) {
963 uint16_t callback = GetVehicleCallback(CBID_VEHICLE_32DAY_CALLBACK, 0, 0, v->engine_type, v);
964 if (callback != CALLBACK_FAILED) {
965 if (HasBit(callback, 0)) {
966 TriggerVehicle(v, VEHICLE_TRIGGER_CALLBACK_32); // Trigger vehicle trigger 10
967 }
968
969 /* After a vehicle trigger, the graphics and properties of the vehicle could change.
970 * Note: MarkDirty also invalidates the palette, which is the meaning of bit 1. So, nothing special there. */
971 if (callback != 0) v->First()->MarkDirty();
972
973 if (callback & ~3) ErrorUnknownCallbackResult(v->GetGRFID(), CBID_VEHICLE_32DAY_CALLBACK, callback);
974 }
975 }
976
977 /* This is called once per day for each vehicle, but not in the first tick of the day */
978 v->OnNewEconomyDay();
979 }
980 }
981
982 void CallVehicleTicks()
983 {
984 _vehicles_to_autoreplace.clear();
985
986 RunEconomyVehicleDayProc();
987
988 {
989 PerformanceMeasurer framerate(PFE_GL_ECONOMY);
990 for (Station *st : Station::Iterate()) LoadUnloadStation(st);
991 }
992 PerformanceAccumulator::Reset(PFE_GL_TRAINS);
993 PerformanceAccumulator::Reset(PFE_GL_ROADVEHS);
994 PerformanceAccumulator::Reset(PFE_GL_SHIPS);
995 PerformanceAccumulator::Reset(PFE_GL_AIRCRAFT);
996
997 for (Vehicle *v : Vehicle::Iterate()) {
998 [[maybe_unused]] size_t vehicle_index = v->index;
999
1000 /* Vehicle could be deleted in this tick */
1001 if (!v->Tick()) {
1002 assert(Vehicle::Get(vehicle_index) == nullptr);
1003 continue;
1004 }
1005
1006 assert(Vehicle::Get(vehicle_index) == v);
1007
1008 switch (v->type) {
1009 default: break;
1010
1011 case VEH_TRAIN:
1012 case VEH_ROAD:
1013 case VEH_AIRCRAFT:
1014 case VEH_SHIP: {
1015 Vehicle *front = v->First();
1016
1017 if (v->vcache.cached_cargo_age_period != 0) {
1018 v->cargo_age_counter = std::min(v->cargo_age_counter, v->vcache.cached_cargo_age_period);
1019 if (--v->cargo_age_counter == 0) {
1020 v->cargo.AgeCargo();
1021 v->cargo_age_counter = v->vcache.cached_cargo_age_period;
1022 }
1023 }
1024
1025 /* Do not play any sound when crashed */
1026 if (front->vehstatus & VS_CRASHED) continue;
1027
1028 /* Do not play any sound when in depot or tunnel */
1029 if (v->vehstatus & VS_HIDDEN) continue;
1030
1031 /* Do not play any sound when stopped */
1032 if ((front->vehstatus & VS_STOPPED) && (front->type != VEH_TRAIN || front->cur_speed == 0)) continue;
1033
1034 /* Check vehicle type specifics */
1035 switch (v->type) {
1036 case VEH_TRAIN:
1037 if (Train::From(v)->IsWagon()) continue;
1038 break;
1039
1040 case VEH_ROAD:
1041 if (!RoadVehicle::From(v)->IsFrontEngine()) continue;
1042 break;
1043
1044 case VEH_AIRCRAFT:
1045 if (!Aircraft::From(v)->IsNormalAircraft()) continue;
1046 break;
1047
1048 default:
1049 break;
1050 }
1051
1052 v->motion_counter += front->cur_speed;
1053 /* Play a running sound if the motion counter passes 256 (Do we not skip sounds?) */
1054 if (GB(v->motion_counter, 0, 8) < front->cur_speed) PlayVehicleSound(v, VSE_RUNNING);
1055
1056 /* Play an alternating running sound every 16 ticks */
1057 if (GB(v->tick_counter, 0, 4) == 0) {
1058 /* Play running sound when speed > 0 and not braking */
1059 bool running = (front->cur_speed > 0) && !(front->vehstatus & (VS_STOPPED | VS_TRAIN_SLOWING));
1060 PlayVehicleSound(v, running ? VSE_RUNNING_16 : VSE_STOPPED_16);
1061 }
1062
1063 break;
1064 }
1065 }
1066 }
1067
1068 Backup<CompanyID> cur_company(_current_company, FILE_LINE);
1069 for (auto &it : _vehicles_to_autoreplace) {
1070 Vehicle *v = Vehicle::Get(it.first);
1071 /* Autoreplace needs the current company set as the vehicle owner */
1072 cur_company.Change(v->owner);
1073
1074 /* Start vehicle if we stopped them in VehicleEnteredDepotThisTick()
1075 * We need to stop them between VehicleEnteredDepotThisTick() and here or we risk that
1076 * they are already leaving the depot again before being replaced. */
1077 if (it.second) v->vehstatus &= ~VS_STOPPED;
1078
1079 /* Store the position of the effect as the vehicle pointer will become invalid later */
1080 int x = v->x_pos;
1081 int y = v->y_pos;
1082 int z = v->z_pos;
1083
1084 const Company *c = Company::Get(_current_company);
1085 SubtractMoneyFromCompany(CommandCost(EXPENSES_NEW_VEHICLES, (Money)c->settings.engine_renew_money));
1086 CommandCost res = Command<CMD_AUTOREPLACE_VEHICLE>::Do(DC_EXEC, v->index);
1087 SubtractMoneyFromCompany(CommandCost(EXPENSES_NEW_VEHICLES, -(Money)c->settings.engine_renew_money));
1088
1089 if (!IsLocalCompany()) continue;
1090
1091 if (res.Succeeded()) {
1092 ShowCostOrIncomeAnimation(x, y, z, res.GetCost());
1093 continue;
1094 }
1095
1096 StringID error_message = res.GetErrorMessage();
1097 if (error_message == STR_ERROR_AUTOREPLACE_NOTHING_TO_DO || error_message == INVALID_STRING_ID) continue;
1098
1099 if (error_message == STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY) error_message = STR_ERROR_AUTOREPLACE_MONEY_LIMIT;
1100
1101 StringID message;
1102 if (error_message == STR_ERROR_TRAIN_TOO_LONG_AFTER_REPLACEMENT) {
1103 message = error_message;
1104 } else {
1105 message = STR_NEWS_VEHICLE_AUTORENEW_FAILED;
1106 }
1107
1108 SetDParam(0, v->index);
1109 SetDParam(1, error_message);
1110 AddVehicleAdviceNewsItem(message, v->index);
1111 }
1112
1113 cur_company.Restore();
1114 }
1115
1120 static void DoDrawVehicle(const Vehicle *v)
1121 {
1122 PaletteID pal = PAL_NONE;
1123
1124 if (v->vehstatus & VS_DEFPAL) pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
1125
1126 /* Check whether the vehicle shall be transparent due to the game state */
1127 bool shadowed = (v->vehstatus & VS_SHADOW) != 0;
1128
1129 if (v->type == VEH_EFFECT) {
1130 /* Check whether the vehicle shall be transparent/invisible due to GUI settings.
1131 * However, transparent smoke and bubbles look weird, so always hide them. */
1132 TransparencyOption to = EffectVehicle::From(v)->GetTransparencyOption();
1133 if (to != TO_INVALID && (IsTransparencySet(to) || IsInvisibilitySet(to))) return;
1134 }
1135
1136 StartSpriteCombine();
1137 for (uint i = 0; i < v->sprite_cache.sprite_seq.count; ++i) {
1138 PaletteID pal2 = v->sprite_cache.sprite_seq.seq[i].pal;
1139 if (!pal2 || (v->vehstatus & VS_CRASHED)) pal2 = pal;
1140 AddSortableSpriteToDraw(v->sprite_cache.sprite_seq.seq[i].sprite, pal2, v->x_pos + v->x_offs, v->y_pos + v->y_offs,
1141 v->x_extent, v->y_extent, v->z_extent, v->z_pos, shadowed, v->x_bb_offs, v->y_bb_offs);
1142 }
1143 EndSpriteCombine();
1144 }
1145
1150 void ViewportAddVehicles(DrawPixelInfo *dpi)
1151 {
1152 /* The bounding rectangle */
1153 const int l = dpi->left;
1154 const int r = dpi->left + dpi->width;
1155 const int t = dpi->top;
1156 const int b = dpi->top + dpi->height;
1157
1158 /* Border size of MAX_VEHICLE_PIXEL_xy */
1159 const int xb = MAX_VEHICLE_PIXEL_X * ZOOM_LVL_BASE;
1160 const int yb = MAX_VEHICLE_PIXEL_Y * ZOOM_LVL_BASE;
1161
1162 /* The hash area to scan */
1163 int xl, xu, yl, yu;
1164
1165 if (dpi->width + xb < GEN_HASHX_SIZE) {
1166 xl = GEN_HASHX(l - xb);
1167 xu = GEN_HASHX(r);
1168 } else {
1169 /* scan whole hash row */
1170 xl = 0;
1171 xu = GEN_HASHX_MASK;
1172 }
1173
1174 if (dpi->height + yb < GEN_HASHY_SIZE) {
1175 yl = GEN_HASHY(t - yb);
1176 yu = GEN_HASHY(b);
1177 } else {
1178 /* scan whole column */
1179 yl = 0;
1180 yu = GEN_HASHY_MASK;
1181 }
1182
1183 for (int y = yl;; y = (y + GEN_HASHY_INC) & GEN_HASHY_MASK) {
1184 for (int x = xl;; x = (x + GEN_HASHX_INC) & GEN_HASHX_MASK) {
1185 const Vehicle *v = _vehicle_viewport_hash[x + y]; // already masked & 0xFFF
1186
1187 while (v != nullptr) {
1188
1189 if (!(v->vehstatus & VS_HIDDEN) &&
1190 l <= v->coord.right + xb &&
1191 t <= v->coord.bottom + yb &&
1192 r >= v->coord.left - xb &&
1193 b >= v->coord.top - yb)
1194 {
1195 /*
1196 * This vehicle can potentially be drawn as part of this viewport and
1197 * needs to be revalidated, as the sprite may not be correct.
1198 */
1199 if (v->sprite_cache.revalidate_before_draw) {
1200 VehicleSpriteSeq seq;
1201 v->GetImage(v->direction, EIT_ON_MAP, &seq);
1202
1203 if (seq.IsValid() && v->sprite_cache.sprite_seq != seq) {
1204 v->sprite_cache.sprite_seq = seq;
1205 /*
1206 * A sprite change may also result in a bounding box change,
1207 * so we need to update the bounding box again before we
1208 * check to see if the vehicle should be drawn. Note that
1209 * we can't interfere with the viewport hash at this point,
1210 * so we keep the original hash on the assumption there will
1211 * not be a significant change in the top and left coordinates
1212 * of the vehicle.
1213 */
1214 v->UpdateBoundingBoxCoordinates(false);
1215
1216 }
1217
1218 v->sprite_cache.revalidate_before_draw = false;
1219 }
1220
1221 if (l <= v->coord.right &&
1222 t <= v->coord.bottom &&
1223 r >= v->coord.left &&
1224 b >= v->coord.top) DoDrawVehicle(v);
1225 }
1226
1227 v = v->hash_viewport_next;
1228 }
1229
1230 if (x == xu) break;
1231 }
1232
1233 if (y == yu) break;
1234 }
1235 }
1236
1244 Vehicle *CheckClickOnVehicle(const Viewport *vp, int x, int y)
1245 {
1246 Vehicle *found = nullptr;
1247 uint dist, best_dist = UINT_MAX;
1248
1249 if ((uint)(x -= vp->left) >= (uint)vp->width || (uint)(y -= vp->top) >= (uint)vp->height) return nullptr;
1250
1251 x = ScaleByZoom(x, vp->zoom) + vp->virtual_left;
1252 y = ScaleByZoom(y, vp->zoom) + vp->virtual_top;
1253
1254 /* Border size of MAX_VEHICLE_PIXEL_xy */
1255 const int xb = MAX_VEHICLE_PIXEL_X * ZOOM_LVL_BASE;
1256 const int yb = MAX_VEHICLE_PIXEL_Y * ZOOM_LVL_BASE;
1257
1258 /* The hash area to scan */
1259 int xl = GEN_HASHX(x - xb);
1260 int xu = GEN_HASHX(x);
1261 int yl = GEN_HASHY(y - yb);
1262 int yu = GEN_HASHY(y);
1263
1264 for (int hy = yl;; hy = (hy + GEN_HASHY_INC) & GEN_HASHY_MASK) {
1265 for (int hx = xl;; hx = (hx + GEN_HASHX_INC) & GEN_HASHX_MASK) {
1266 Vehicle *v = _vehicle_viewport_hash[hx + hy]; // already masked & 0xFFF
1267
1268 while (v != nullptr) {
1269 if ((v->vehstatus & (VS_HIDDEN | VS_UNCLICKABLE)) == 0 &&
1270 x >= v->coord.left && x <= v->coord.right &&
1271 y >= v->coord.top && y <= v->coord.bottom) {
1272
1273 dist = std::max(
1274 abs(((v->coord.left + v->coord.right) >> 1) - x),
1275 abs(((v->coord.top + v->coord.bottom) >> 1) - y)
1276 );
1277
1278 if (dist < best_dist) {
1279 found = v;
1280 best_dist = dist;
1281 }
1282 }
1283 v = v->hash_viewport_next;
1284 }
1285 if (hx == xu) break;
1286 }
1287 if (hy == yu) break;
1288 }
1289
1290 return found;
1291 }
1292
1297 void DecreaseVehicleValue(Vehicle *v)
1298 {
1299 v->value -= v->value >> 8;
1300 SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
1301 }
1302
1303 static const byte _breakdown_chance[64] = {
1304 3, 3, 3, 3, 3, 3, 3, 3,
1305 4, 4, 5, 5, 6, 6, 7, 7,
1306 8, 8, 9, 9, 10, 10, 11, 11,
1307 12, 13, 13, 13, 13, 14, 15, 16,
1308 17, 19, 21, 25, 28, 31, 34, 37,
1309 40, 44, 48, 52, 56, 60, 64, 68,
1310 72, 80, 90, 100, 110, 120, 130, 140,
1311 150, 170, 190, 210, 230, 250, 250, 250,
1312 };
1313
1314 void CheckVehicleBreakdown(Vehicle *v)
1315 {
1316 int rel, rel_old;
1317
1318 /* decrease reliability */
1319 if (!_settings_game.order.no_servicing_if_no_breakdowns ||
1320 _settings_game.difficulty.vehicle_breakdowns != 0) {
1321 v->reliability = rel = std::max((rel_old = v->reliability) - v->reliability_spd_dec, 0);
1322 if ((rel_old >> 8) != (rel >> 8)) SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
1323 }
1324
1325 if (v->breakdown_ctr != 0 || (v->vehstatus & VS_STOPPED) ||
1326 _settings_game.difficulty.vehicle_breakdowns < 1 ||
1327 v->cur_speed < 5 || _game_mode == GM_MENU) {
1328 return;
1329 }
1330
1331 uint32_t r = Random();
1332
1333 /* increase chance of failure */
1334 int chance = v->breakdown_chance + 1;
1335 if (Chance16I(1, 25, r)) chance += 25;
1336 v->breakdown_chance = ClampTo<uint8_t>(chance);
1337
1338 /* calculate reliability value to use in comparison */
1339 rel = v->reliability;
1340 if (v->type == VEH_SHIP) rel += 0x6666;
1341
1342 /* reduced breakdowns? */
1343 if (_settings_game.difficulty.vehicle_breakdowns == 1) rel += 0x6666;
1344
1345 /* check if to break down */
1346 if (_breakdown_chance[ClampTo<uint16_t>(rel) >> 10] <= v->breakdown_chance) {
1347 v->breakdown_ctr = GB(r, 16, 6) + 0x3F;
1348 v->breakdown_delay = GB(r, 24, 7) + 0x80;
1349 v->breakdown_chance = 0;
1350 }
1351 }
1352
1359 bool Vehicle::HandleBreakdown()
1360 {
1361 /* Possible states for Vehicle::breakdown_ctr
1362 * 0 - vehicle is running normally
1363 * 1 - vehicle is currently broken down
1364 * 2 - vehicle is going to break down now
1365 * >2 - vehicle is counting down to the actual breakdown event */
1366 switch (this->breakdown_ctr) {
1367 case 0:
1368 return false;
1369
1370 case 2:
1371 this->breakdown_ctr = 1;
1372
1373 if (this->breakdowns_since_last_service != 255) {
1374 this->breakdowns_since_last_service++;
1375 }
1376
1377 if (this->type == VEH_AIRCRAFT) {
1378 /* Aircraft just need this flag, the rest is handled elsewhere */
1379 this->vehstatus |= VS_AIRCRAFT_BROKEN;
1380 } else {
1381 this->cur_speed = 0;
1382
1383 if (!PlayVehicleSound(this, VSE_BREAKDOWN)) {
1384 bool train_or_ship = this->type == VEH_TRAIN || this->type == VEH_SHIP;
1385 SndPlayVehicleFx((_settings_game.game_creation.landscape != LT_TOYLAND) ?
1386 (train_or_ship ? SND_10_BREAKDOWN_TRAIN_SHIP : SND_0F_BREAKDOWN_ROADVEHICLE) :
1387 (train_or_ship ? SND_3A_BREAKDOWN_TRAIN_SHIP_TOYLAND : SND_35_BREAKDOWN_ROADVEHICLE_TOYLAND), this);
1388 }
1389
1390 if (!(this->vehstatus & VS_HIDDEN) && !HasBit(EngInfo(this->engine_type)->misc_flags, EF_NO_BREAKDOWN_SMOKE)) {
1391 EffectVehicle *u = CreateEffectVehicleRel(this, 4, 4, 5, EV_BREAKDOWN_SMOKE);
1392 if (u != nullptr) u->animation_state = this->breakdown_delay * 2;
1393 }
1394 }
1395
1396 this->MarkDirty(); // Update graphics after speed is zeroed
1397 SetWindowDirty(WC_VEHICLE_VIEW, this->index);
1398 SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
1399
1400 [[fallthrough]];
1401 case 1:
1402 /* Aircraft breakdowns end only when arriving at the airport */
1403 if (this->type == VEH_AIRCRAFT) return false;
1404
1405 /* For trains this function is called twice per tick, so decrease v->breakdown_delay at half the rate */
1406 if ((this->tick_counter & (this->type == VEH_TRAIN ? 3 : 1)) == 0) {
1407 if (--this->breakdown_delay == 0) {
1408 this->breakdown_ctr = 0;
1409 this->MarkDirty();
1410 SetWindowDirty(WC_VEHICLE_VIEW, this->index);
1411 }
1412 }
1413 return true;
1414
1415 default:
1416 if (!this->current_order.IsType(OT_LOADING)) this->breakdown_ctr--;
1417 return false;
1418 }
1419 }
1420
1425 void EconomyAgeVehicle(Vehicle *v)
1426 {
1427 if (v->economy_age < EconomyTime::MAX_DATE) {
1428 v->economy_age++;
1429 if (v->IsPrimaryVehicle() && v->economy_age == VEHICLE_PROFIT_MIN_AGE + 1) GroupStatistics::VehicleReachedMinAge(v);
1430 }
1431 }
1432
1437 void AgeVehicle(Vehicle *v)
1438 {
1439 if (v->age < CalendarTime::MAX_DATE) v->age++;
1440
1441 if (!v->IsPrimaryVehicle() && (v->type != VEH_TRAIN || !Train::From(v)->IsEngine())) return;
1442
1443 auto age = v->age - v->max_age;
1444 for (int32_t i = 0; i <= 4; i++) {
1445 if (age == TimerGameCalendar::DateAtStartOfYear(i)) {
1446 v->reliability_spd_dec <<= 1;
1447 break;
1448 }
1449 }
1450
1451 SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
1452
1453 /* 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 */
1454 if (v->Previous() != nullptr || v->owner != _local_company || (v->vehstatus & VS_CRASHED) != 0 || (v->vehstatus & VS_STOPPED) != 0) return;
1455
1456 const Company *c = Company::Get(v->owner);
1457 /* Don't warn if a renew is active */
1458 if (c->settings.engine_renew && v->GetEngine()->company_avail != 0) return;
1459 /* Don't warn if a replacement is active */
1460 if (EngineHasReplacementForCompany(c, v->engine_type, v->group_id)) return;
1461
1462 StringID str;
1463 if (age == TimerGameCalendar::DateAtStartOfYear(-1)) {
1464 str = STR_NEWS_VEHICLE_IS_GETTING_OLD;
1465 } else if (age == TimerGameCalendar::DateAtStartOfYear(0)) {
1466 str = STR_NEWS_VEHICLE_IS_GETTING_VERY_OLD;
1467 } else if (age > TimerGameCalendar::DateAtStartOfYear(0) && (age.base() % CalendarTime::DAYS_IN_LEAP_YEAR) == 0) {
1468 str = STR_NEWS_VEHICLE_IS_GETTING_VERY_OLD_AND;
1469 } else {
1470 return;
1471 }
1472
1473 SetDParam(0, v->index);
1474 AddVehicleAdviceNewsItem(str, v->index);
1475 }
1476
1486 uint8_t CalcPercentVehicleFilled(const Vehicle *front, StringID *colour)
1487 {
1488 int count = 0;
1489 int max = 0;
1490 int cars = 0;
1491 int unloading = 0;
1492 bool loading = false;
1493
1494 bool is_loading = front->current_order.IsType(OT_LOADING);
1495
1496 /* The station may be nullptr when the (colour) string does not need to be set. */
1497 const Station *st = Station::GetIfValid(front->last_station_visited);
1498 assert(colour == nullptr || (st != nullptr && is_loading));
1499
1500 bool order_no_load = is_loading && (front->current_order.GetLoadType() & OLFB_NO_LOAD);
1501 bool order_full_load = is_loading && (front->current_order.GetLoadType() & OLFB_FULL_LOAD);
1502
1503 /* Count up max and used */
1504 for (const Vehicle *v = front; v != nullptr; v = v->Next()) {
1505 count += v->cargo.StoredCount();
1506 max += v->cargo_cap;
1507 if (v->cargo_cap != 0 && colour != nullptr) {
1508 unloading += HasBit(v->vehicle_flags, VF_CARGO_UNLOADING) ? 1 : 0;
1509 loading |= !order_no_load &&
1510 (order_full_load || st->goods[v->cargo_type].HasRating()) &&
1511 !HasBit(v->vehicle_flags, VF_LOADING_FINISHED) && !HasBit(v->vehicle_flags, VF_STOP_LOADING);
1512 cars++;
1513 }
1514 }
1515
1516 if (colour != nullptr) {
1517 if (unloading == 0 && loading) {
1518 *colour = STR_PERCENT_UP;
1519 } else if (unloading == 0 && !loading) {
1520 *colour = STR_PERCENT_NONE;
1521 } else if (cars == unloading || !loading) {
1522 *colour = STR_PERCENT_DOWN;
1523 } else {
1524 *colour = STR_PERCENT_UP_DOWN;
1525 }
1526 }
1527
1528 /* Train without capacity */
1529 if (max == 0) return 100;
1530
1531 /* Return the percentage */
1532 if (count * 2 < max) {
1533 /* Less than 50%; round up, so that 0% means really empty. */
1534 return CeilDiv(count * 100, max);
1535 } else {
1536 /* More than 50%; round down, so that 100% means really full. */
1537 return (count * 100) / max;
1538 }
1539 }
1540
1545 void VehicleEnterDepot(Vehicle *v)
1546 {
1547 /* Always work with the front of the vehicle */
1548 assert(v == v->First());
1549
1550 switch (v->type) {
1551 case VEH_TRAIN: {
1552 Train *t = Train::From(v);
1553 SetWindowClassesDirty(WC_TRAINS_LIST);
1554 /* Clear path reservation */
1555 SetDepotReservation(t->tile, false);
1556 if (_settings_client.gui.show_track_reservation) MarkTileDirtyByTile(t->tile);
1557
1558 UpdateSignalsOnSegment(t->tile, INVALID_DIAGDIR, t->owner);
1559 t->wait_counter = 0;
1560 t->force_proceed = TFP_NONE;
1561 ClrBit(t->flags, VRF_TOGGLE_REVERSE);
1562 t->ConsistChanged(CCF_ARRANGE);
1563 break;
1564 }
1565
1566 case VEH_ROAD:
1567 SetWindowClassesDirty(WC_ROADVEH_LIST);
1568 break;
1569
1570 case VEH_SHIP: {
1571 SetWindowClassesDirty(WC_SHIPS_LIST);
1572 Ship *ship = Ship::From(v);
1573 ship->state = TRACK_BIT_DEPOT;
1574 ship->UpdateCache();
1575 ship->UpdateViewport(true, true);
1576 SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
1577 break;
1578 }
1579
1580 case VEH_AIRCRAFT:
1581 SetWindowClassesDirty(WC_AIRCRAFT_LIST);
1582 HandleAircraftEnterHangar(Aircraft::From(v));
1583 break;
1584 default: NOT_REACHED();
1585 }
1586 SetWindowDirty(WC_VEHICLE_VIEW, v->index);
1587
1588 if (v->type != VEH_TRAIN) {
1589 /* Trains update the vehicle list when the first unit enters the depot and calls VehicleEnterDepot() when the last unit enters.
1590 * 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 */
1591 InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
1592 }
1593 SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
1594
1595 v->vehstatus |= VS_HIDDEN;
1596 v->cur_speed = 0;
1597
1598 VehicleServiceInDepot(v);
1599
1600 /* After a vehicle trigger, the graphics and properties of the vehicle could change. */
1601 TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT);
1602 v->MarkDirty();
1603
1604 InvalidateWindowData(WC_VEHICLE_VIEW, v->index);
1605
1606 if (v->current_order.IsType(OT_GOTO_DEPOT)) {
1607 SetWindowDirty(WC_VEHICLE_VIEW, v->index);
1608
1609 const Order *real_order = v->GetOrder(v->cur_real_order_index);
1610
1611 /* Test whether we are heading for this depot. If not, do nothing.
1612 * Note: The target depot for nearest-/manual-depot-orders is only updated on junctions, but we want to accept every depot. */
1613 if ((v->current_order.GetDepotOrderType() & ODTFB_PART_OF_ORDERS) &&
1614 real_order != nullptr && !(real_order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) &&
1615 (v->type == VEH_AIRCRAFT ? v->current_order.GetDestination() != GetStationIndex(v->tile) : v->dest_tile != v->tile)) {
1616 /* We are heading for another depot, keep driving. */
1617 return;
1618 }
1619
1620 if (v->current_order.IsRefit()) {
1621 Backup<CompanyID> cur_company(_current_company, v->owner, FILE_LINE);
1622 CommandCost cost = std::get<0>(Command<CMD_REFIT_VEHICLE>::Do(DC_EXEC, v->index, v->current_order.GetRefitCargo(), 0xFF, false, false, 0));
1623 cur_company.Restore();
1624
1625 if (cost.Failed()) {
1626 _vehicles_to_autoreplace[v->index] = false;
1627 if (v->owner == _local_company) {
1628 /* Notify the user that we stopped the vehicle */
1629 SetDParam(0, v->index);
1630 AddVehicleAdviceNewsItem(STR_NEWS_ORDER_REFIT_FAILED, v->index);
1631 }
1632 } else if (cost.GetCost() != 0) {
1633 v->profit_this_year -= cost.GetCost() << 8;
1634 if (v->owner == _local_company) {
1635 ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost.GetCost());
1636 }
1637 }
1638 }
1639
1640 if (v->current_order.GetDepotOrderType() & ODTFB_PART_OF_ORDERS) {
1641 /* Part of orders */
1642 v->DeleteUnreachedImplicitOrders();
1643 UpdateVehicleTimetable(v, true);
1644 v->IncrementImplicitOrderIndex();
1645 }
1646 if (v->current_order.GetDepotActionType() & ODATFB_HALT) {
1647 /* Vehicles are always stopped on entering depots. Do not restart this one. */
1648 _vehicles_to_autoreplace[v->index] = false;
1649 /* Invalidate last_loading_station. As the link from the station
1650 * before the stop to the station after the stop can't be predicted
1651 * we shouldn't construct it when the vehicle visits the next stop. */
1652 v->last_loading_station = INVALID_STATION;
1653
1654 /* Clear unbunching data. */
1655 v->ResetDepotUnbunching();
1656
1657 /* Announce that the vehicle is waiting to players and AIs. */
1658 if (v->owner == _local_company) {
1659 SetDParam(0, v->index);
1660 AddVehicleAdviceNewsItem(STR_NEWS_TRAIN_IS_WAITING + v->type, v->index);
1661 }
1662 AI::NewEvent(v->owner, new ScriptEventVehicleWaitingInDepot(v->index));
1663 }
1664
1665 /* If we've entered our unbunching depot, record the round trip duration. */
1666 if (v->current_order.GetDepotActionType() & ODATFB_UNBUNCH && v->depot_unbunching_last_departure > 0) {
1667 TimerGameTick::Ticks measured_round_trip = TimerGameTick::counter - v->depot_unbunching_last_departure;
1668 if (v->round_trip_time == 0) {
1669 /* This might be our first round trip. */
1670 v->round_trip_time = measured_round_trip;
1671 } else {
1672 /* If we have a previous trip, smooth the effects of outlier trip calculations caused by jams or other interference. */
1673 v->round_trip_time = Clamp(measured_round_trip, (v->round_trip_time / 2), ClampTo<TimerGameTick::Ticks>(v->round_trip_time * 2));
1674 }
1675 }
1676
1677 v->current_order.MakeDummy();
1678 }
1679 }
1680
1681
1686 void Vehicle::UpdatePosition()
1687 {
1688 UpdateVehicleTileHash(this, false);
1689 }
1690
1695 void Vehicle::UpdateBoundingBoxCoordinates(bool update_cache) const
1696 {
1697 Rect new_coord;
1698 this->sprite_cache.sprite_seq.GetBounds(&new_coord);
1699
1700 Point pt = RemapCoords(this->x_pos + this->x_offs, this->y_pos + this->y_offs, this->z_pos);
1701 new_coord.left += pt.x;
1702 new_coord.top += pt.y;
1703 new_coord.right += pt.x + 2 * ZOOM_LVL_BASE;
1704 new_coord.bottom += pt.y + 2 * ZOOM_LVL_BASE;
1705
1706 if (update_cache) {
1707 /*
1708 * If the old coordinates are invalid, set the cache to the new coordinates for correct
1709 * behaviour the next time the coordinate cache is checked.
1710 */
1711 this->sprite_cache.old_coord = this->coord.left == INVALID_COORD ? new_coord : this->coord;
1712 }
1713 else {
1714 /* Extend the bounds of the existing cached bounding box so the next dirty window is correct */
1715 this->sprite_cache.old_coord.left = std::min(this->sprite_cache.old_coord.left, this->coord.left);
1716 this->sprite_cache.old_coord.top = std::min(this->sprite_cache.old_coord.top, this->coord.top);
1717 this->sprite_cache.old_coord.right = std::max(this->sprite_cache.old_coord.right, this->coord.right);
1718 this->sprite_cache.old_coord.bottom = std::max(this->sprite_cache.old_coord.bottom, this->coord.bottom);
1719 }
1720
1721 this->coord = new_coord;
1722 }
1723
1728 void Vehicle::UpdateViewport(bool dirty)
1729 {
1730 /* If the existing cache is invalid we should ignore it, as it will be set to the current coords by UpdateBoundingBoxCoordinates */
1731 bool ignore_cached_coords = this->sprite_cache.old_coord.left == INVALID_COORD;
1732
1733 this->UpdateBoundingBoxCoordinates(true);
1734
1735 if (ignore_cached_coords) {
1736 UpdateVehicleViewportHash(this, this->coord.left, this->coord.top, INVALID_COORD, INVALID_COORD);
1737 } else {
1738 UpdateVehicleViewportHash(this, this->coord.left, this->coord.top, this->sprite_cache.old_coord.left, this->sprite_cache.old_coord.top);
1739 }
1740
1741 if (dirty) {
1742 if (ignore_cached_coords) {
1743 this->sprite_cache.is_viewport_candidate = this->MarkAllViewportsDirty();
1744 } else {
1745 this->sprite_cache.is_viewport_candidate = ::MarkAllViewportsDirty(
1746 std::min(this->sprite_cache.old_coord.left, this->coord.left),
1747 std::min(this->sprite_cache.old_coord.top, this->coord.top),
1748 std::max(this->sprite_cache.old_coord.right, this->coord.right),
1749 std::max(this->sprite_cache.old_coord.bottom, this->coord.bottom));
1750 }
1751 }
1752 }
1753
1757 void Vehicle::UpdatePositionAndViewport()
1758 {
1759 this->UpdatePosition();
1760 this->UpdateViewport(true);
1761 }
1762
1767 bool Vehicle::MarkAllViewportsDirty() const
1768 {
1769 return ::MarkAllViewportsDirty(this->coord.left, this->coord.top, this->coord.right, this->coord.bottom);
1770 }
1771
1777 GetNewVehiclePosResult GetNewVehiclePos(const Vehicle *v)
1778 {
1779 static const int8_t _delta_coord[16] = {
1780 -1,-1,-1, 0, 1, 1, 1, 0, /* x */
1781 -1, 0, 1, 1, 1, 0,-1,-1, /* y */
1782 };
1783
1784 int x = v->x_pos + _delta_coord[v->direction];
1785 int y = v->y_pos + _delta_coord[v->direction + 8];
1786
1787 GetNewVehiclePosResult gp;
1788 gp.x = x;
1789 gp.y = y;
1790 gp.old_tile = v->tile;
1791 gp.new_tile = TileVirtXY(x, y);
1792 return gp;
1793 }
1794
1795 static const Direction _new_direction_table[] = {
1796 DIR_N, DIR_NW, DIR_W,
1797 DIR_NE, DIR_SE, DIR_SW,
1798 DIR_E, DIR_SE, DIR_S
1799 };
1800
1801 Direction GetDirectionTowards(const Vehicle *v, int x, int y)
1802 {
1803 int i = 0;
1804
1805 if (y >= v->y_pos) {
1806 if (y != v->y_pos) i += 3;
1807 i += 3;
1808 }
1809
1810 if (x >= v->x_pos) {
1811 if (x != v->x_pos) i++;
1812 i++;
1813 }
1814
1815 Direction dir = v->direction;
1816
1817 DirDiff dirdiff = DirDifference(_new_direction_table[i], dir);
1818 if (dirdiff == DIRDIFF_SAME) return dir;
1819 return ChangeDir(dir, dirdiff > DIRDIFF_REVERSE ? DIRDIFF_45LEFT : DIRDIFF_45RIGHT);
1820 }
1821
1831 VehicleEnterTileStatus VehicleEnterTile(Vehicle *v, TileIndex tile, int x, int y)
1832 {
1833 return _tile_type_procs[GetTileType(tile)]->vehicle_enter_tile_proc(v, tile, x, y);
1834 }
1835
1841 UnitID FreeUnitIDGenerator::NextID() const
1842 {
1843 for (auto it = std::begin(this->used_bitmap); it != std::end(this->used_bitmap); ++it) {
1844 BitmapStorage available = ~(*it);
1845 if (available == 0) continue;
1846 return static_cast<UnitID>(std::distance(std::begin(this->used_bitmap), it) * BITMAP_SIZE + FindFirstBit(available) + 1);
1847 }
1848 return static_cast<UnitID>(this->used_bitmap.size() * BITMAP_SIZE + 1);
1849 }
1850
1856 UnitID FreeUnitIDGenerator::UseID(UnitID index)
1857 {
1858 if (index == 0 || index == UINT16_MAX) return index;
1859
1860 index--;
1861
1862 size_t slot = index / BITMAP_SIZE;
1863 if (slot >= this->used_bitmap.size()) this->used_bitmap.resize(slot + 1);
1864 SetBit(this->used_bitmap[index / BITMAP_SIZE], index % BITMAP_SIZE);
1865
1866 return index + 1;
1867 }
1868
1873 void FreeUnitIDGenerator::ReleaseID(UnitID index)
1874 {
1875 if (index == 0 || index == UINT16_MAX) return;
1876
1877 index--;
1878
1879 assert(index / BITMAP_SIZE < this->used_bitmap.size());
1880 ClrBit(this->used_bitmap[index / BITMAP_SIZE], index % BITMAP_SIZE);
1881 }
1882
1888 UnitID GetFreeUnitNumber(VehicleType type)
1889 {
1890 /* Check whether it is allowed to build another vehicle. */
1891 uint max_veh;
1892 switch (type) {
1893 case VEH_TRAIN: max_veh = _settings_game.vehicle.max_trains; break;
1894 case VEH_ROAD: max_veh = _settings_game.vehicle.max_roadveh; break;
1895 case VEH_SHIP: max_veh = _settings_game.vehicle.max_ships; break;
1896 case VEH_AIRCRAFT: max_veh = _settings_game.vehicle.max_aircraft; break;
1897 default: NOT_REACHED();
1898 }
1899
1900 const Company *c = Company::Get(_current_company);
1901 if (c->group_all[type].num_vehicle >= max_veh) return UINT16_MAX; // Currently already at the limit, no room to make a new one.
1902
1903 return c->freeunits[type].NextID();
1904 }
1905
1906
1915 bool CanBuildVehicleInfrastructure(VehicleType type, byte subtype)
1916 {
1917 assert(IsCompanyBuildableVehicleType(type));
1918
1919 if (!Company::IsValidID(_local_company)) return false;
1920
1921 UnitID max;
1922 switch (type) {
1923 case VEH_TRAIN:
1924 if (!HasAnyRailTypesAvail(_local_company)) return false;
1925 max = _settings_game.vehicle.max_trains;
1926 break;
1927 case VEH_ROAD:
1928 if (!HasAnyRoadTypesAvail(_local_company, (RoadTramType)subtype)) return false;
1929 max = _settings_game.vehicle.max_roadveh;
1930 break;
1931 case VEH_SHIP: max = _settings_game.vehicle.max_ships; break;
1932 case VEH_AIRCRAFT: max = _settings_game.vehicle.max_aircraft; break;
1933 default: NOT_REACHED();
1934 }
1935
1936 /* We can build vehicle infrastructure when we may build the vehicle type */
1937 if (max > 0) {
1938 /* Can we actually build the vehicle type? */
1939 for (const Engine *e : Engine::IterateType(type)) {
1940 if (type == VEH_ROAD && GetRoadTramType(e->u.road.roadtype) != (RoadTramType)subtype) continue;
1941 if (HasBit(e->company_avail, _local_company)) return true;
1942 }
1943 return false;
1944 }
1945
1946 /* We should be able to build infrastructure when we have the actual vehicle type */
1947 for (const Vehicle *v : Vehicle::Iterate()) {
1948 if (v->type == VEH_ROAD && GetRoadTramType(RoadVehicle::From(v)->roadtype) != (RoadTramType)subtype) continue;
1949 if (v->owner == _local_company && v->type == type) return true;
1950 }
1951
1952 return false;
1953 }
1954
1955
1963 LiveryScheme GetEngineLiveryScheme(EngineID engine_type, EngineID parent_engine_type, const Vehicle *v)
1964 {
1965 CargoID cargo_type = v == nullptr ? INVALID_CARGO : v->cargo_type;
1966 const Engine *e = Engine::Get(engine_type);
1967 switch (e->type) {
1968 default: NOT_REACHED();
1969 case VEH_TRAIN:
1970 if (v != nullptr && parent_engine_type != INVALID_ENGINE && (UsesWagonOverride(v) || (v->IsArticulatedPart() && e->u.rail.railveh_type != RAILVEH_WAGON))) {
1971 /* Wagonoverrides use the colour scheme of the front engine.
1972 * Articulated parts use the colour scheme of the first part. (Not supported for articulated wagons) */
1973 engine_type = parent_engine_type;
1974 e = Engine::Get(engine_type);
1975 /* Note: Luckily cargo_type is not needed for engines */
1976 }
1977
1978 if (!IsValidCargoID(cargo_type)) cargo_type = e->GetDefaultCargoType();
1979 if (!IsValidCargoID(cargo_type)) cargo_type = GetCargoIDByLabel(CT_GOODS); // The vehicle does not carry anything, let's pick some freight cargo
1980 assert(IsValidCargoID(cargo_type));
1981 if (e->u.rail.railveh_type == RAILVEH_WAGON) {
1982 if (!CargoSpec::Get(cargo_type)->is_freight) {
1983 if (parent_engine_type == INVALID_ENGINE) {
1984 return LS_PASSENGER_WAGON_STEAM;
1985 } else {
1986 bool is_mu = HasBit(EngInfo(parent_engine_type)->misc_flags, EF_RAIL_IS_MU);
1987 switch (RailVehInfo(parent_engine_type)->engclass) {
1988 default: NOT_REACHED();
1989 case EC_STEAM: return LS_PASSENGER_WAGON_STEAM;
1990 case EC_DIESEL: return is_mu ? LS_DMU : LS_PASSENGER_WAGON_DIESEL;
1991 case EC_ELECTRIC: return is_mu ? LS_EMU : LS_PASSENGER_WAGON_ELECTRIC;
1992 case EC_MONORAIL: return LS_PASSENGER_WAGON_MONORAIL;
1993 case EC_MAGLEV: return LS_PASSENGER_WAGON_MAGLEV;
1994 }
1995 }
1996 } else {
1997 return LS_FREIGHT_WAGON;
1998 }
1999 } else {
2000 bool is_mu = HasBit(e->info.misc_flags, EF_RAIL_IS_MU);
2001
2002 switch (e->u.rail.engclass) {
2003 default: NOT_REACHED();
2004 case EC_STEAM: return LS_STEAM;
2005 case EC_DIESEL: return is_mu ? LS_DMU : LS_DIESEL;
2006 case EC_ELECTRIC: return is_mu ? LS_EMU : LS_ELECTRIC;
2007 case EC_MONORAIL: return LS_MONORAIL;
2008 case EC_MAGLEV: return LS_MAGLEV;
2009 }
2010 }
2011
2012 case VEH_ROAD:
2013 /* Always use the livery of the front */
2014 if (v != nullptr && parent_engine_type != INVALID_ENGINE) {
2015 engine_type = parent_engine_type;
2016 e = Engine::Get(engine_type);
2017 cargo_type = v->First()->cargo_type;
2018 }
2019 if (!IsValidCargoID(cargo_type)) cargo_type = e->GetDefaultCargoType();
2020 if (!IsValidCargoID(cargo_type)) cargo_type = GetCargoIDByLabel(CT_GOODS); // The vehicle does not carry anything, let's pick some freight cargo
2021 assert(IsValidCargoID(cargo_type));
2022
2023 /* Important: Use Tram Flag of front part. Luckily engine_type refers to the front part here. */
2024 if (HasBit(e->info.misc_flags, EF_ROAD_TRAM)) {
2025 /* Tram */
2026 return IsCargoInClass(cargo_type, CC_PASSENGERS) ? LS_PASSENGER_TRAM : LS_FREIGHT_TRAM;
2027 } else {
2028 /* Bus or truck */
2029 return IsCargoInClass(cargo_type, CC_PASSENGERS) ? LS_BUS : LS_TRUCK;
2030 }
2031
2032 case VEH_SHIP:
2033 if (!IsValidCargoID(cargo_type)) cargo_type = e->GetDefaultCargoType();
2034 if (!IsValidCargoID(cargo_type)) cargo_type = GetCargoIDByLabel(CT_GOODS); // The vehicle does not carry anything, let's pick some freight cargo
2035 assert(IsValidCargoID(cargo_type));
2036 return IsCargoInClass(cargo_type, CC_PASSENGERS) ? LS_PASSENGER_SHIP : LS_FREIGHT_SHIP;
2037
2038 case VEH_AIRCRAFT:
2039 switch (e->u.air.subtype) {
2040 case AIR_HELI: return LS_HELICOPTER;
2041 case AIR_CTOL: return LS_SMALL_PLANE;
2042 case AIR_CTOL | AIR_FAST: return LS_LARGE_PLANE;
2043 default: NOT_REACHED();
2044 }
2045 }
2046 }
2047
2057 const Livery *GetEngineLivery(EngineID engine_type, CompanyID company, EngineID parent_engine_type, const Vehicle *v, byte livery_setting)
2058 {
2059 const Company *c = Company::Get(company);
2060 LiveryScheme scheme = LS_DEFAULT;
2061
2062 if (livery_setting == LIT_ALL || (livery_setting == LIT_COMPANY && company == _local_company)) {
2063 if (v != nullptr) {
2064 const Group *g = Group::GetIfValid(v->First()->group_id);
2065 if (g != nullptr) {
2066 /* Traverse parents until we find a livery or reach the top */
2067 while (g->livery.in_use == 0 && g->parent != INVALID_GROUP) {
2068 g = Group::Get(g->parent);
2069 }
2070 if (g->livery.in_use != 0) return &g->livery;
2071 }
2072 }
2073
2074 /* The default livery is always available for use, but its in_use flag determines
2075 * whether any _other_ liveries are in use. */
2076 if (c->livery[LS_DEFAULT].in_use != 0) {
2077 /* Determine the livery scheme to use */
2078 scheme = GetEngineLiveryScheme(engine_type, parent_engine_type, v);
2079 }
2080 }
2081
2082 return &c->livery[scheme];
2083 }
2084
2085
2086 static PaletteID GetEngineColourMap(EngineID engine_type, CompanyID company, EngineID parent_engine_type, const Vehicle *v)
2087 {
2088 PaletteID map = (v != nullptr) ? v->colourmap : PAL_NONE;
2089
2090 /* Return cached value if any */
2091 if (map != PAL_NONE) return map;
2092
2093 const Engine *e = Engine::Get(engine_type);
2094
2095 /* Check if we should use the colour map callback */
2096 if (HasBit(e->info.callback_mask, CBM_VEHICLE_COLOUR_REMAP)) {
2097 uint16_t callback = GetVehicleCallback(CBID_VEHICLE_COLOUR_MAPPING, 0, 0, engine_type, v);
2098 /* Failure means "use the default two-colour" */
2099 if (callback != CALLBACK_FAILED) {
2100 static_assert(PAL_NONE == 0); // Returning 0x4000 (resp. 0xC000) coincidences with default value (PAL_NONE)
2101 map = GB(callback, 0, 14);
2102 /* If bit 14 is set, then the company colours are applied to the
2103 * map else it's returned as-is. */
2104 if (!HasBit(callback, 14)) {
2105 /* Update cache */
2106 if (v != nullptr) const_cast<Vehicle *>(v)->colourmap = map;
2107 return map;
2108 }
2109 }
2110 }
2111
2112 bool twocc = HasBit(e->info.misc_flags, EF_USES_2CC);
2113
2114 if (map == PAL_NONE) map = twocc ? (PaletteID)SPR_2CCMAP_BASE : (PaletteID)PALETTE_RECOLOUR_START;
2115
2116 /* Spectator has news shown too, but has invalid company ID - as well as dedicated server */
2117 if (!Company::IsValidID(company)) return map;
2118
2119 const Livery *livery = GetEngineLivery(engine_type, company, parent_engine_type, v, _settings_client.gui.liveries);
2120
2121 map += livery->colour1;
2122 if (twocc) map += livery->colour2 * 16;
2123
2124 /* Update cache */
2125 if (v != nullptr) const_cast<Vehicle *>(v)->colourmap = map;
2126 return map;
2127 }
2128
2135 PaletteID GetEnginePalette(EngineID engine_type, CompanyID company)
2136 {
2137 return GetEngineColourMap(engine_type, company, INVALID_ENGINE, nullptr);
2138 }
2139
2145 PaletteID GetVehiclePalette(const Vehicle *v)
2146 {
2147 if (v->IsGroundVehicle()) {
2148 return GetEngineColourMap(v->engine_type, v->owner, v->GetGroundVehicleCache()->first_engine, v);
2149 }
2150
2151 return GetEngineColourMap(v->engine_type, v->owner, INVALID_ENGINE, v);
2152 }
2153
2157 void Vehicle::DeleteUnreachedImplicitOrders()
2158 {
2159 if (this->IsGroundVehicle()) {
2160 uint16_t &gv_flags = this->GetGroundVehicleFlags();
2161 if (HasBit(gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS)) {
2162 /* Do not delete orders, only skip them */
2163 ClrBit(gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS);
2164 this->cur_implicit_order_index = this->cur_real_order_index;
2165 InvalidateVehicleOrder(this, 0);
2166 return;
2167 }
2168 }
2169
2170 const Order *order = this->GetOrder(this->cur_implicit_order_index);
2171 while (order != nullptr) {
2172 if (this->cur_implicit_order_index == this->cur_real_order_index) break;
2173
2174 if (order->IsType(OT_IMPLICIT)) {
2175 DeleteOrder(this, this->cur_implicit_order_index);
2176 /* DeleteOrder does various magic with order_indices, so resync 'order' with 'cur_implicit_order_index' */
2177 order = this->GetOrder(this->cur_implicit_order_index);
2178 } else {
2179 /* Skip non-implicit orders, e.g. service-orders */
2180 order = order->next;
2181 this->cur_implicit_order_index++;
2182 }
2183
2184 /* Wrap around */
2185 if (order == nullptr) {
2186 order = this->GetOrder(0);
2187 this->cur_implicit_order_index = 0;
2188 }
2189 }
2190 }
2191
2196 void Vehicle::BeginLoading()
2197 {
2198 assert(IsTileType(this->tile, MP_STATION) || this->type == VEH_SHIP);
2199
2200 TimerGameTick::Ticks travel_time = TimerGameTick::counter - this->last_loading_tick;
2201 if (this->current_order.IsType(OT_GOTO_STATION) &&
2202 this->current_order.GetDestination() == this->last_station_visited) {
2203 this->DeleteUnreachedImplicitOrders();
2204
2205 /* Now both order indices point to the destination station, and we can start loading */
2206 this->current_order.MakeLoading(true);
2207 UpdateVehicleTimetable(this, true);
2208
2209 /* Furthermore add the Non Stop flag to mark that this station
2210 * is the actual destination of the vehicle, which is (for example)
2211 * necessary to be known for HandleTrainLoading to determine
2212 * whether the train is lost or not; not marking a train lost
2213 * that arrives at random stations is bad. */
2214 this->current_order.SetNonStopType(ONSF_NO_STOP_AT_ANY_STATION);
2215
2216 } else {
2217 /* We weren't scheduled to stop here. Insert an implicit order
2218 * to show that we are stopping here.
2219 * While only groundvehicles have implicit orders, e.g. aircraft might still enter
2220 * the 'wrong' terminal when skipping orders etc. */
2221 Order *in_list = this->GetOrder(this->cur_implicit_order_index);
2222 if (this->IsGroundVehicle() &&
2223 (in_list == nullptr || !in_list->IsType(OT_IMPLICIT) ||
2224 in_list->GetDestination() != this->last_station_visited)) {
2225 bool suppress_implicit_orders = HasBit(this->GetGroundVehicleFlags(), GVF_SUPPRESS_IMPLICIT_ORDERS);
2226 /* Do not create consecutive duplicates of implicit orders */
2227 Order *prev_order = this->cur_implicit_order_index > 0 ? this->GetOrder(this->cur_implicit_order_index - 1) : (this->GetNumOrders() > 1 ? this->GetLastOrder() : nullptr);
2228 if (prev_order == nullptr ||
2229 (!prev_order->IsType(OT_IMPLICIT) && !prev_order->IsType(OT_GOTO_STATION)) ||
2230 prev_order->GetDestination() != this->last_station_visited) {
2231
2232 /* Prefer deleting implicit orders instead of inserting new ones,
2233 * so test whether the right order follows later. In case of only
2234 * implicit orders treat the last order in the list like an
2235 * explicit one, except if the overall number of orders surpasses
2236 * IMPLICIT_ORDER_ONLY_CAP. */
2237 int target_index = this->cur_implicit_order_index;
2238 bool found = false;
2239 while (target_index != this->cur_real_order_index || this->GetNumManualOrders() == 0) {
2240 const Order *order = this->GetOrder(target_index);
2241 if (order == nullptr) break; // No orders.
2242 if (order->IsType(OT_IMPLICIT) && order->GetDestination() == this->last_station_visited) {
2243 found = true;
2244 break;
2245 }
2246 target_index++;
2247 if (target_index >= this->orders->GetNumOrders()) {
2248 if (this->GetNumManualOrders() == 0 &&
2249 this->GetNumOrders() < IMPLICIT_ORDER_ONLY_CAP) {
2250 break;
2251 }
2252 target_index = 0;
2253 }
2254 if (target_index == this->cur_implicit_order_index) break; // Avoid infinite loop.
2255 }
2256
2257 if (found) {
2258 if (suppress_implicit_orders) {
2259 /* Skip to the found order */
2260 this->cur_implicit_order_index = target_index;
2261 InvalidateVehicleOrder(this, 0);
2262 } else {
2263 /* Delete all implicit orders up to the station we just reached */
2264 const Order *order = this->GetOrder(this->cur_implicit_order_index);
2265 while (!order->IsType(OT_IMPLICIT) || order->GetDestination() != this->last_station_visited) {
2266 if (order->IsType(OT_IMPLICIT)) {
2267 DeleteOrder(this, this->cur_implicit_order_index);
2268 /* DeleteOrder does various magic with order_indices, so resync 'order' with 'cur_implicit_order_index' */
2269 order = this->GetOrder(this->cur_implicit_order_index);
2270 } else {
2271 /* Skip non-implicit orders, e.g. service-orders */
2272 order = order->next;
2273 this->cur_implicit_order_index++;
2274 }
2275
2276 /* Wrap around */
2277 if (order == nullptr) {
2278 order = this->GetOrder(0);
2279 this->cur_implicit_order_index = 0;
2280 }
2281 assert(order != nullptr);
2282 }
2283 }
2284 } else if (!suppress_implicit_orders &&
2285 ((this->orders == nullptr ? OrderList::CanAllocateItem() : this->orders->GetNumOrders() < MAX_VEH_ORDER_ID)) &&
2286 Order::CanAllocateItem()) {
2287 /* Insert new implicit order */
2288 Order *implicit_order = new Order();
2289 implicit_order->MakeImplicit(this->last_station_visited);
2290 InsertOrder(this, implicit_order, this->cur_implicit_order_index);
2291 if (this->cur_implicit_order_index > 0) --this->cur_implicit_order_index;
2292
2293 /* InsertOrder disabled creation of implicit orders for all vehicles with the same implicit order.
2294 * Reenable it for this vehicle */
2295 uint16_t &gv_flags = this->GetGroundVehicleFlags();
2296 ClrBit(gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS);
2297 }
2298 }
2299 }
2300 this->current_order.MakeLoading(false);
2301 }
2302
2303 if (this->last_loading_station != INVALID_STATION &&
2304 this->last_loading_station != this->last_station_visited &&
2305 ((this->current_order.GetLoadType() & OLFB_NO_LOAD) == 0 ||
2306 (this->current_order.GetUnloadType() & OUFB_NO_UNLOAD) == 0)) {
2307 IncreaseStats(Station::Get(this->last_loading_station), this, this->last_station_visited, travel_time);
2308 }
2309
2310 PrepareUnload(this);
2311
2312 SetWindowDirty(GetWindowClassForVehicleType(this->type), this->owner);
2313 SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
2314 SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
2315 SetWindowDirty(WC_STATION_VIEW, this->last_station_visited);
2316
2317 Station::Get(this->last_station_visited)->MarkTilesDirty(true);
2318 this->cur_speed = 0;
2319 this->MarkDirty();
2320 }
2321
2327 void Vehicle::CancelReservation(StationID next, Station *st)
2328 {
2329 for (Vehicle *v = this; v != nullptr; v = v->next) {
2330 VehicleCargoList &cargo = v->cargo;
2331 if (cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0) {
2332 Debug(misc, 1, "cancelling cargo reservation");
2333 cargo.Return(UINT_MAX, &st->goods[v->cargo_type].cargo, next, v->tile);
2334 }
2335 cargo.KeepAll();
2336 }
2337 }
2338
2343 void Vehicle::LeaveStation()
2344 {
2345 assert(this->current_order.IsType(OT_LOADING));
2346
2347 delete this->cargo_payment;
2348 assert(this->cargo_payment == nullptr); // cleared by ~CargoPayment
2349
2350 /* Only update the timetable if the vehicle was supposed to stop here. */
2351 if (this->current_order.GetNonStopType() != ONSF_STOP_EVERYWHERE) UpdateVehicleTimetable(this, false);
2352
2353 if ((this->current_order.GetLoadType() & OLFB_NO_LOAD) == 0 ||
2354 (this->current_order.GetUnloadType() & OUFB_NO_UNLOAD) == 0) {
2355 if (this->current_order.CanLeaveWithCargo(this->last_loading_station != INVALID_STATION)) {
2356 /* Refresh next hop stats to make sure we've done that at least once
2357 * during the stop and that refit_cap == cargo_cap for each vehicle in
2358 * the consist. */
2359 this->ResetRefitCaps();
2360 LinkRefresher::Run(this);
2361
2362 /* if the vehicle could load here or could stop with cargo loaded set the last loading station */
2363 this->last_loading_station = this->last_station_visited;
2364 this->last_loading_tick = TimerGameTick::counter;
2365 } else {
2366 /* if the vehicle couldn't load and had to unload or transfer everything
2367 * set the last loading station to invalid as it will leave empty. */
2368 this->last_loading_station = INVALID_STATION;
2369 }
2370 }
2371
2372 this->current_order.MakeLeaveStation();
2373 Station *st = Station::Get(this->last_station_visited);
2374 this->CancelReservation(INVALID_STATION, st);
2375 st->loading_vehicles.remove(this);
2376
2377 HideFillingPercent(&this->fill_percent_te_id);
2378 trip_occupancy = CalcPercentVehicleFilled(this, nullptr);
2379
2380 if (this->type == VEH_TRAIN && !(this->vehstatus & VS_CRASHED)) {
2381 /* Trigger station animation (trains only) */
2382 if (IsTileType(this->tile, MP_STATION)) {
2383 TriggerStationRandomisation(st, this->tile, SRT_TRAIN_DEPARTS);
2384 TriggerStationAnimation(st, this->tile, SAT_TRAIN_DEPARTS);
2385 }
2386
2387 SetBit(Train::From(this)->flags, VRF_LEAVING_STATION);
2388 }
2389 if (this->type == VEH_ROAD && !(this->vehstatus & VS_CRASHED)) {
2390 /* Trigger road stop animation */
2391 if (IsRoadStopTile(this->tile)) {
2392 TriggerRoadStopRandomisation(st, this->tile, RSRT_VEH_DEPARTS);
2393 TriggerRoadStopAnimation(st, this->tile, SAT_TRAIN_DEPARTS);
2394 }
2395 }
2396
2397
2398 this->MarkDirty();
2399 }
2400
2404 void Vehicle::ResetRefitCaps()
2405 {
2406 for (Vehicle *v = this; v != nullptr; v = v->Next()) v->refit_cap = v->cargo_cap;
2407 }
2408
2412 void Vehicle::ReleaseUnitNumber()
2413 {
2414 Company::Get(this->owner)->freeunits[this->type].ReleaseID(this->unitnumber);
2415 this->unitnumber = 0;
2416 }
2417
2423 void Vehicle::HandleLoading(bool mode)
2424 {
2425 switch (this->current_order.GetType()) {
2426 case OT_LOADING: {
2427 TimerGameTick::Ticks wait_time = std::max(this->current_order.GetTimetabledWait() - this->lateness_counter, 0);
2428
2429 /* Not the first call for this tick, or still loading */
2430 if (mode || !HasBit(this->vehicle_flags, VF_LOADING_FINISHED) || this->current_order_time < wait_time) return;
2431
2432 this->PlayLeaveStationSound();
2433
2434 this->LeaveStation();
2435
2436 /* Only advance to next order if we just loaded at the current one */
2437 const Order *order = this->GetOrder(this->cur_implicit_order_index);
2438 if (order == nullptr ||
2439 (!order->IsType(OT_IMPLICIT) && !order->IsType(OT_GOTO_STATION)) ||
2440 order->GetDestination() != this->last_station_visited) {
2441 return;
2442 }
2443 break;
2444 }
2445
2446 case OT_DUMMY: break;
2447
2448 default: return;
2449 }
2450
2451 this->IncrementImplicitOrderIndex();
2452 }
2453
2458 bool Vehicle::HasFullLoadOrder() const
2459 {
2460 for (Order *o : this->Orders()) {
2461 if (o->IsType(OT_GOTO_STATION) && o->GetLoadType() & (OLFB_FULL_LOAD | OLF_FULL_LOAD_ANY)) return true;
2462 }
2463 return false;
2464 }
2465
2470 bool Vehicle::HasConditionalOrder() const
2471 {
2472 for (Order *o : this->Orders()) {
2473 if (o->IsType(OT_CONDITIONAL)) return true;
2474 }
2475 return false;
2476 }
2477
2482 bool Vehicle::HasUnbunchingOrder() const
2483 {
2484 for (Order *o : this->Orders()) {
2485 if (o->IsType(OT_GOTO_DEPOT) && o->GetDepotActionType() & ODATFB_UNBUNCH) return true;
2486 }
2487 return false;
2488 }
2489
2494 static bool PreviousOrderIsUnbunching(const Vehicle *v)
2495 {
2496 /* If we are headed for the first order, we must wrap around back to the last order. */
2497 bool is_first_order = (v->GetOrder(v->cur_implicit_order_index) == v->GetFirstOrder());
2498 Order *previous_order = (is_first_order) ? v->GetLastOrder() : v->GetOrder(v->cur_implicit_order_index - 1);
2499
2500 if (previous_order == nullptr || !previous_order->IsType(OT_GOTO_DEPOT)) return false;
2501 return (previous_order->GetDepotActionType() & ODATFB_UNBUNCH) != 0;
2502 }
2503
2507 void Vehicle::LeaveUnbunchingDepot()
2508 {
2509 /* Don't do anything if this is not our unbunching order. */
2510 if (!PreviousOrderIsUnbunching(this)) return;
2511
2512 /* Set the start point for this round trip time. */
2513 this->depot_unbunching_last_departure = TimerGameTick::counter;
2514
2515 /* Tell the timetable we are now "on time." */
2516 this->lateness_counter = 0;
2517 SetWindowDirty(WC_VEHICLE_TIMETABLE, this->index);
2518
2519 /* Find the average travel time of vehicles that we share orders with. */
2520 int num_vehicles = 0;
2521 TimerGameTick::Ticks total_travel_time = 0;
2522
2523 Vehicle *u = this->FirstShared();
2524 for (; u != nullptr; u = u->NextShared()) {
2525 /* Ignore vehicles that are manually stopped or crashed. */
2526 if (u->vehstatus & (VS_STOPPED | VS_CRASHED)) continue;
2527
2528 num_vehicles++;
2529 total_travel_time += u->round_trip_time;
2530 }
2531
2532 /* Make sure we cannot divide by 0. */
2533 num_vehicles = std::max(num_vehicles, 1);
2534
2535 /* Calculate the separation by finding the average travel time, then calculating equal separation (minimum 1 tick) between vehicles. */
2536 TimerGameTick::Ticks separation = std::max((total_travel_time / num_vehicles / num_vehicles), 1);
2537 TimerGameTick::TickCounter next_departure = TimerGameTick::counter + separation;
2538
2539 /* Set the departure time of all vehicles that we share orders with. */
2540 u = this->FirstShared();
2541 for (; u != nullptr; u = u->NextShared()) {
2542 /* Ignore vehicles that are manually stopped or crashed. */
2543 if (u->vehstatus & (VS_STOPPED | VS_CRASHED)) continue;
2544
2545 u->depot_unbunching_next_departure = next_departure;
2546 SetWindowDirty(WC_VEHICLE_VIEW, u->index);
2547 }
2548 }
2549
2554 bool Vehicle::IsWaitingForUnbunching() const
2555 {
2556 assert(this->IsInDepot());
2557
2558 /* Don't bother if there are no vehicles sharing orders. */
2559 if (!this->IsOrderListShared()) return false;
2560
2561 /* Don't do anything if there aren't enough orders. */
2562 if (this->GetNumOrders() <= 1) return false;
2563
2564 /* Don't do anything if this is not our unbunching order. */
2565 if (!PreviousOrderIsUnbunching(this)) return false;
2566
2567 return (this->depot_unbunching_next_departure > TimerGameTick::counter);
2568 };
2569
2576 CommandCost Vehicle::SendToDepot(DoCommandFlag flags, DepotCommand command)
2577 {
2578 CommandCost ret = CheckOwnership(this->owner);
2579 if (ret.Failed()) return ret;
2580
2581 if (this->vehstatus & VS_CRASHED) return CMD_ERROR;
2582 if (this->IsStoppedInDepot()) return CMD_ERROR;
2583
2584 /* No matter why we're headed to the depot, unbunching data is no longer valid. */
2585 if (flags & DC_EXEC) this->ResetDepotUnbunching();
2586
2587 if (this->current_order.IsType(OT_GOTO_DEPOT)) {
2588 bool halt_in_depot = (this->current_order.GetDepotActionType() & ODATFB_HALT) != 0;
2589 if (((command & DepotCommand::Service) != DepotCommand::None) == halt_in_depot) {
2590 /* We called with a different DEPOT_SERVICE setting.
2591 * Now we change the setting to apply the new one and let the vehicle head for the same depot.
2592 * Note: the if is (true for requesting service == true for ordered to stop in depot) */
2593 if (flags & DC_EXEC) {
2594 this->current_order.SetDepotOrderType(ODTF_MANUAL);
2595 this->current_order.SetDepotActionType(halt_in_depot ? ODATF_SERVICE_ONLY : ODATFB_HALT);
2596 SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
2597 }
2598 return CommandCost();
2599 }
2600
2601 if ((command & DepotCommand::DontCancel) != DepotCommand::None) return CMD_ERROR; // Requested no cancellation of depot orders
2602 if (flags & DC_EXEC) {
2603 /* If the orders to 'goto depot' are in the orders list (forced servicing),
2604 * then skip to the next order; effectively cancelling this forced service */
2605 if (this->current_order.GetDepotOrderType() & ODTFB_PART_OF_ORDERS) this->IncrementRealOrderIndex();
2606
2607 if (this->IsGroundVehicle()) {
2608 uint16_t &gv_flags = this->GetGroundVehicleFlags();
2609 SetBit(gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS);
2610 }
2611
2612 this->current_order.MakeDummy();
2613 SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
2614 }
2615 return CommandCost();
2616 }
2617
2618 ClosestDepot closestDepot = this->FindClosestDepot();
2619 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};
2620 if (!closestDepot.found) return_cmd_error(no_depot[this->type]);
2621
2622 if (flags & DC_EXEC) {
2623 if (this->current_order.IsType(OT_LOADING)) this->LeaveStation();
2624
2625 if (this->IsGroundVehicle() && this->GetNumManualOrders() > 0) {
2626 uint16_t &gv_flags = this->GetGroundVehicleFlags();
2627 SetBit(gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS);
2628 }
2629
2630 this->SetDestTile(closestDepot.location);
2631 this->current_order.MakeGoToDepot(closestDepot.destination, ODTF_MANUAL);
2632 if ((command & DepotCommand::Service) == DepotCommand::None) this->current_order.SetDepotActionType(ODATFB_HALT);
2633 SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
2634
2635 /* If there is no depot in front and the train is not already reversing, reverse automatically (trains only) */
2636 if (this->type == VEH_TRAIN && (closestDepot.reverse ^ HasBit(Train::From(this)->flags, VRF_REVERSING))) {
2637 Command<CMD_REVERSE_TRAIN_DIRECTION>::Do(DC_EXEC, this->index, false);
2638 }
2639
2640 if (this->type == VEH_AIRCRAFT) {
2641 Aircraft *a = Aircraft::From(this);
2642 if (a->state == FLYING && a->targetairport != closestDepot.destination) {
2643 /* The aircraft is now heading for a different hangar than the next in the orders */
2644 AircraftNextAirportPos_and_Order(a);
2645 }
2646 }
2647 }
2648
2649 return CommandCost();
2650
2651 }
2652
2657 void Vehicle::UpdateVisualEffect(bool allow_power_change)
2658 {
2659 bool powered_before = HasBit(this->vcache.cached_vis_effect, VE_DISABLE_WAGON_POWER);
2660 const Engine *e = this->GetEngine();
2661
2662 /* Evaluate properties */
2663 byte visual_effect;
2664 switch (e->type) {
2665 case VEH_TRAIN: visual_effect = e->u.rail.visual_effect; break;
2666 case VEH_ROAD: visual_effect = e->u.road.visual_effect; break;
2667 case VEH_SHIP: visual_effect = e->u.ship.visual_effect; break;
2668 default: visual_effect = 1 << VE_DISABLE_EFFECT; break;
2669 }
2670
2671 /* Check powered wagon / visual effect callback */
2672 if (HasBit(e->info.callback_mask, CBM_VEHICLE_VISUAL_EFFECT)) {
2673 uint16_t callback = GetVehicleCallback(CBID_VEHICLE_VISUAL_EFFECT, 0, 0, this->engine_type, this);
2674
2675 if (callback != CALLBACK_FAILED) {
2676 if (callback >= 0x100 && e->GetGRF()->grf_version >= 8) ErrorUnknownCallbackResult(e->GetGRFID(), CBID_VEHICLE_VISUAL_EFFECT, callback);
2677
2678 callback = GB(callback, 0, 8);
2679 /* Avoid accidentally setting 'visual_effect' to the default value
2680 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
2681 if (callback == VE_DEFAULT) {
2682 assert(HasBit(callback, VE_DISABLE_EFFECT));
2683 SB(callback, VE_TYPE_START, VE_TYPE_COUNT, 0);
2684 }
2685 visual_effect = callback;
2686 }
2687 }
2688
2689 /* Apply default values */
2690 if (visual_effect == VE_DEFAULT ||
2691 (!HasBit(visual_effect, VE_DISABLE_EFFECT) && GB(visual_effect, VE_TYPE_START, VE_TYPE_COUNT) == VE_TYPE_DEFAULT)) {
2692 /* Only train engines have default effects.
2693 * Note: This is independent of whether the engine is a front engine or articulated part or whatever. */
2694 if (e->type != VEH_TRAIN || e->u.rail.railveh_type == RAILVEH_WAGON || !IsInsideMM(e->u.rail.engclass, EC_STEAM, EC_MONORAIL)) {
2695 if (visual_effect == VE_DEFAULT) {
2696 visual_effect = 1 << VE_DISABLE_EFFECT;
2697 } else {
2698 SetBit(visual_effect, VE_DISABLE_EFFECT);
2699 }
2700 } else {
2701 if (visual_effect == VE_DEFAULT) {
2702 /* Also set the offset */
2703 visual_effect = (VE_OFFSET_CENTRE - (e->u.rail.engclass == EC_STEAM ? 4 : 0)) << VE_OFFSET_START;
2704 }
2705 SB(visual_effect, VE_TYPE_START, VE_TYPE_COUNT, e->u.rail.engclass - EC_STEAM + VE_TYPE_STEAM);
2706 }
2707 }
2708
2709 this->vcache.cached_vis_effect = visual_effect;
2710
2711 if (!allow_power_change && powered_before != HasBit(this->vcache.cached_vis_effect, VE_DISABLE_WAGON_POWER)) {
2712 ToggleBit(this->vcache.cached_vis_effect, VE_DISABLE_WAGON_POWER);
2713 ShowNewGrfVehicleError(this->engine_type, STR_NEWGRF_BROKEN, STR_NEWGRF_BROKEN_POWERED_WAGON, GBUG_VEH_POWERED_WAGON, false);
2714 }
2715 }
2716
2717 static const int8_t _vehicle_smoke_pos[8] = {
2718 1, 1, 1, 0, -1, -1, -1, 0
2719 };
2720
2725 static void SpawnAdvancedVisualEffect(const Vehicle *v)
2726 {
2727 uint16_t callback = GetVehicleCallback(CBID_VEHICLE_SPAWN_VISUAL_EFFECT, 0, Random(), v->engine_type, v);
2728 if (callback == CALLBACK_FAILED) return;
2729
2730 uint count = GB(callback, 0, 2);
2731 bool auto_center = HasBit(callback, 13);
2732 bool auto_rotate = !HasBit(callback, 14);
2733
2734 int8_t l_center = 0;
2735 if (auto_center) {
2736 /* For road vehicles: Compute offset from vehicle position to vehicle center */
2737 if (v->type == VEH_ROAD) l_center = -(int)(VEHICLE_LENGTH - RoadVehicle::From(v)->gcache.cached_veh_length) / 2;
2738 } else {
2739 /* For trains: Compute offset from vehicle position to sprite position */
2740 if (v->type == VEH_TRAIN) l_center = (VEHICLE_LENGTH - Train::From(v)->gcache.cached_veh_length) / 2;
2741 }
2742
2743 Direction l_dir = v->direction;
2744 if (v->type == VEH_TRAIN && HasBit(Train::From(v)->flags, VRF_REVERSE_DIRECTION)) l_dir = ReverseDir(l_dir);
2745 Direction t_dir = ChangeDir(l_dir, DIRDIFF_90RIGHT);
2746
2747 int8_t x_center = _vehicle_smoke_pos[l_dir] * l_center;
2748 int8_t y_center = _vehicle_smoke_pos[t_dir] * l_center;
2749
2750 for (uint i = 0; i < count; i++) {
2751 uint32_t reg = GetRegister(0x100 + i);
2752 uint type = GB(reg, 0, 8);
2753 int8_t x = GB(reg, 8, 8);
2754 int8_t y = GB(reg, 16, 8);
2755 int8_t z = GB(reg, 24, 8);
2756
2757 if (auto_rotate) {
2758 int8_t l = x;
2759 int8_t t = y;
2760 x = _vehicle_smoke_pos[l_dir] * l + _vehicle_smoke_pos[t_dir] * t;
2761 y = _vehicle_smoke_pos[t_dir] * l - _vehicle_smoke_pos[l_dir] * t;
2762 }
2763
2764 if (type >= 0xF0) {
2765 switch (type) {
2766 case 0xF1: CreateEffectVehicleRel(v, x_center + x, y_center + y, z, EV_STEAM_SMOKE); break;
2767 case 0xF2: CreateEffectVehicleRel(v, x_center + x, y_center + y, z, EV_DIESEL_SMOKE); break;
2768 case 0xF3: CreateEffectVehicleRel(v, x_center + x, y_center + y, z, EV_ELECTRIC_SPARK); break;
2769 case 0xFA: CreateEffectVehicleRel(v, x_center + x, y_center + y, z, EV_BREAKDOWN_SMOKE_AIRCRAFT); break;
2770 default: break;
2771 }
2772 }
2773 }
2774 }
2775
2780 void Vehicle::ShowVisualEffect() const
2781 {
2782 assert(this->IsPrimaryVehicle());
2783 bool sound = false;
2784
2785 /* Do not show any smoke when:
2786 * - vehicle smoke is disabled by the player
2787 * - the vehicle is slowing down or stopped (by the player)
2788 * - the vehicle is moving very slowly
2789 */
2790 if (_settings_game.vehicle.smoke_amount == 0 ||
2791 this->vehstatus & (VS_TRAIN_SLOWING | VS_STOPPED) ||
2792 this->cur_speed < 2) {
2793 return;
2794 }
2795
2796 /* Use the speed as limited by underground and orders. */
2797 uint max_speed = this->GetCurrentMaxSpeed();
2798
2799 if (this->type == VEH_TRAIN) {
2800 const Train *t = Train::From(this);
2801 /* For trains, do not show any smoke when:
2802 * - the train is reversing
2803 * - is entering a station with an order to stop there and its speed is equal to maximum station entering speed
2804 */
2805 if (HasBit(t->flags, VRF_REVERSING) ||
2806 (IsRailStationTile(t->tile) && t->IsFrontEngine() && t->current_order.ShouldStopAtStation(t, GetStationIndex(t->tile)) &&
2807 t->cur_speed >= max_speed)) {
2808 return;
2809 }
2810 }
2811
2812 const Vehicle *v = this;
2813
2814 do {
2815 bool advanced = HasBit(v->vcache.cached_vis_effect, VE_ADVANCED_EFFECT);
2816 int effect_offset = GB(v->vcache.cached_vis_effect, VE_OFFSET_START, VE_OFFSET_COUNT) - VE_OFFSET_CENTRE;
2817 VisualEffectSpawnModel effect_model = VESM_NONE;
2818 if (advanced) {
2819 effect_offset = VE_OFFSET_CENTRE;
2820 effect_model = (VisualEffectSpawnModel)GB(v->vcache.cached_vis_effect, 0, VE_ADVANCED_EFFECT);
2821 if (effect_model >= VESM_END) effect_model = VESM_NONE; // unknown spawning model
2822 } else {
2823 effect_model = (VisualEffectSpawnModel)GB(v->vcache.cached_vis_effect, VE_TYPE_START, VE_TYPE_COUNT);
2824 assert(effect_model != (VisualEffectSpawnModel)VE_TYPE_DEFAULT); // should have been resolved by UpdateVisualEffect
2825 static_assert((uint)VESM_STEAM == (uint)VE_TYPE_STEAM);
2826 static_assert((uint)VESM_DIESEL == (uint)VE_TYPE_DIESEL);
2827 static_assert((uint)VESM_ELECTRIC == (uint)VE_TYPE_ELECTRIC);
2828 }
2829
2830 /* Show no smoke when:
2831 * - Smoke has been disabled for this vehicle
2832 * - The vehicle is not visible
2833 * - The vehicle is under a bridge
2834 * - The vehicle is on a depot tile
2835 * - The vehicle is on a tunnel tile
2836 * - The vehicle is a train engine that is currently unpowered */
2837 if (effect_model == VESM_NONE ||
2838 v->vehstatus & VS_HIDDEN ||
2839 IsBridgeAbove(v->tile) ||
2840 IsDepotTile(v->tile) ||
2841 IsTunnelTile(v->tile) ||
2842 (v->type == VEH_TRAIN &&
2843 !HasPowerOnRail(Train::From(v)->railtype, GetTileRailType(v->tile)))) {
2844 continue;
2845 }
2846
2847 EffectVehicleType evt = EV_END;
2848 switch (effect_model) {
2849 case VESM_STEAM:
2850 /* Steam smoke - amount is gradually falling until vehicle reaches its maximum speed, after that it's normal.
2851 * Details: while vehicle's current speed is gradually increasing, steam plumes' density decreases by one third each
2852 * third of its maximum speed spectrum. Steam emission finally normalises at very close to vehicle's maximum speed.
2853 * REGULATION:
2854 * - instead of 1, 4 / 2^smoke_amount (max. 2) is used to provide sufficient regulation to steam puffs' amount. */
2855 if (GB(v->tick_counter, 0, ((4 >> _settings_game.vehicle.smoke_amount) + ((this->cur_speed * 3) / max_speed))) == 0) {
2856 evt = EV_STEAM_SMOKE;
2857 }
2858 break;
2859
2860 case VESM_DIESEL: {
2861 /* Diesel smoke - thicker when vehicle is starting, gradually subsiding till it reaches its maximum speed
2862 * when smoke emission stops.
2863 * Details: Vehicle's (max.) speed spectrum is divided into 32 parts. When max. speed is reached, chance for smoke
2864 * emission erodes by 32 (1/4). For trains, power and weight come in handy too to either increase smoke emission in
2865 * 6 steps (1000HP each) if the power is low or decrease smoke emission in 6 steps (512 tonnes each) if the train
2866 * isn't overweight. Power and weight contributions are expressed in a way that neither extreme power, nor
2867 * extreme weight can ruin the balance (e.g. FreightWagonMultiplier) in the formula. When the vehicle reaches
2868 * maximum speed no diesel_smoke is emitted.
2869 * REGULATION:
2870 * - up to which speed a diesel vehicle is emitting smoke (with reduced/small setting only until 1/2 of max_speed),
2871 * - in Chance16 - the last value is 512 / 2^smoke_amount (max. smoke when 128 = smoke_amount of 2). */
2872 int power_weight_effect = 0;
2873 if (v->type == VEH_TRAIN) {
2874 power_weight_effect = (32 >> (Train::From(this)->gcache.cached_power >> 10)) - (32 >> (Train::From(this)->gcache.cached_weight >> 9));
2875 }
2876 if (this->cur_speed < (max_speed >> (2 >> _settings_game.vehicle.smoke_amount)) &&
2877 Chance16((64 - ((this->cur_speed << 5) / max_speed) + power_weight_effect), (512 >> _settings_game.vehicle.smoke_amount))) {
2878 evt = EV_DIESEL_SMOKE;
2879 }
2880 break;
2881 }
2882
2883 case VESM_ELECTRIC:
2884 /* Electric train's spark - more often occurs when train is departing (more load)
2885 * Details: Electric locomotives are usually at least twice as powerful as their diesel counterparts, so spark
2886 * emissions are kept simple. Only when starting, creating huge force are sparks more likely to happen, but when
2887 * reaching its max. speed, quarter by quarter of it, chance decreases until the usual 2,22% at train's top speed.
2888 * REGULATION:
2889 * - in Chance16 the last value is 360 / 2^smoke_amount (max. sparks when 90 = smoke_amount of 2). */
2890 if (GB(v->tick_counter, 0, 2) == 0 &&
2891 Chance16((6 - ((this->cur_speed << 2) / max_speed)), (360 >> _settings_game.vehicle.smoke_amount))) {
2892 evt = EV_ELECTRIC_SPARK;
2893 }
2894 break;
2895
2896 default:
2897 NOT_REACHED();
2898 }
2899
2900 if (evt != EV_END && advanced) {
2901 sound = true;
2902 SpawnAdvancedVisualEffect(v);
2903 } else if (evt != EV_END) {
2904 sound = true;
2905
2906 /* The effect offset is relative to a point 4 units behind the vehicle's
2907 * front (which is the center of an 8/8 vehicle). Shorter vehicles need a
2908 * correction factor. */
2909 if (v->type == VEH_TRAIN) effect_offset += (VEHICLE_LENGTH - Train::From(v)->gcache.cached_veh_length) / 2;
2910
2911 int x = _vehicle_smoke_pos[v->direction] * effect_offset;
2912 int y = _vehicle_smoke_pos[(v->direction + 2) % 8] * effect_offset;
2913
2914 if (v->type == VEH_TRAIN && HasBit(Train::From(v)->flags, VRF_REVERSE_DIRECTION)) {
2915 x = -x;
2916 y = -y;
2917 }
2918
2919 CreateEffectVehicleRel(v, x, y, 10, evt);
2920 }
2921 } while ((v = v->Next()) != nullptr);
2922
2923 if (sound) PlayVehicleSound(this, VSE_VISUAL_EFFECT);
2924 }
2925
2930 void Vehicle::SetNext(Vehicle *next)
2931 {
2932 assert(this != next);
2933
2934 if (this->next != nullptr) {
2935 /* We had an old next vehicle. Update the first and previous pointers */
2936 for (Vehicle *v = this->next; v != nullptr; v = v->Next()) {
2937 v->first = this->next;
2938 }
2939 this->next->previous = nullptr;
2940 }
2941
2942 this->next = next;
2943
2944 if (this->next != nullptr) {
2945 /* A new next vehicle. Update the first and previous pointers */
2946 if (this->next->previous != nullptr) this->next->previous->next = nullptr;
2947 this->next->previous = this;
2948 for (Vehicle *v = this->next; v != nullptr; v = v->Next()) {
2949 v->first = this->first;
2950 }
2951 }
2952 }
2953
2959 void Vehicle::AddToShared(Vehicle *shared_chain)
2960 {
2961 assert(this->previous_shared == nullptr && this->next_shared == nullptr);
2962
2963 if (shared_chain->orders == nullptr) {
2964 assert(shared_chain->previous_shared == nullptr);
2965 assert(shared_chain->next_shared == nullptr);
2966 this->orders = shared_chain->orders = new OrderList(nullptr, shared_chain);
2967 }
2968
2969 this->next_shared = shared_chain->next_shared;
2970 this->previous_shared = shared_chain;
2971
2972 shared_chain->next_shared = this;
2973
2974 if (this->next_shared != nullptr) this->next_shared->previous_shared = this;
2975
2976 shared_chain->orders->AddVehicle(this);
2977 }
2978
2982 void Vehicle::RemoveFromShared()
2983 {
2984 /* Remember if we were first and the old window number before RemoveVehicle()
2985 * as this changes first if needed. */
2986 bool were_first = (this->FirstShared() == this);
2987 VehicleListIdentifier vli(VL_SHARED_ORDERS, this->type, this->owner, this->FirstShared()->index);
2988
2989 this->orders->RemoveVehicle(this);
2990
2991 if (!were_first) {
2992 /* We are not the first shared one, so only relink our previous one. */
2993 this->previous_shared->next_shared = this->NextShared();
2994 }
2995
2996 if (this->next_shared != nullptr) this->next_shared->previous_shared = this->previous_shared;
2997
2998
2999 if (this->orders->GetNumVehicles() == 1) {
3000 /* When there is only one vehicle, remove the shared order list window. */
3001 CloseWindowById(GetWindowClassForVehicleType(this->type), vli.Pack());
3002 InvalidateVehicleOrder(this->FirstShared(), VIWD_MODIFY_ORDERS);
3003 } else if (were_first) {
3004 /* If we were the first one, update to the new first one.
3005 * Note: FirstShared() is already the new first */
3006 InvalidateWindowData(GetWindowClassForVehicleType(this->type), vli.Pack(), this->FirstShared()->index | (1U << 31));
3007 }
3008
3009 this->next_shared = nullptr;
3010 this->previous_shared = nullptr;
3011 }
3012
3013 static IntervalTimer<TimerGameEconomy> _economy_vehicles_yearly({TimerGameEconomy::YEAR, TimerGameEconomy::Priority::VEHICLE}, [](auto)
3014 {
3015 for (Vehicle *v : Vehicle::Iterate()) {
3016 if (v->IsPrimaryVehicle()) {
3017 /* show warning if vehicle is not generating enough income last 2 years (corresponds to a red icon in the vehicle list) */
3018 Money profit = v->GetDisplayProfitThisYear();
3019 if (v->economy_age >= VEHICLE_PROFIT_MIN_AGE && profit < 0) {
3020 if (_settings_client.gui.vehicle_income_warn && v->owner == _local_company) {
3021 SetDParam(0, v->index);
3022 SetDParam(1, profit);
3023 AddVehicleAdviceNewsItem(
3024 TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_VEHICLE_UNPROFITABLE_PERIOD : STR_NEWS_VEHICLE_UNPROFITABLE_YEAR,
3025 v->index);
3026 }
3027 AI::NewEvent(v->owner, new ScriptEventVehicleUnprofitable(v->index));
3028 }
3029
3030 v->profit_last_year = v->profit_this_year;
3031 v->profit_this_year = 0;
3032 SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
3033 }
3034 }
3035 GroupStatistics::UpdateProfits();
3036 SetWindowClassesDirty(WC_TRAINS_LIST);
3037 SetWindowClassesDirty(WC_SHIPS_LIST);
3038 SetWindowClassesDirty(WC_ROADVEH_LIST);
3039 SetWindowClassesDirty(WC_AIRCRAFT_LIST);
3040 });
3041
3051 bool CanVehicleUseStation(EngineID engine_type, const Station *st)
3052 {
3053 const Engine *e = Engine::GetIfValid(engine_type);
3054 assert(e != nullptr);
3055
3056 switch (e->type) {
3057 case VEH_TRAIN:
3058 return (st->facilities & FACIL_TRAIN) != 0;
3059
3060 case VEH_ROAD:
3061 /* For road vehicles we need the vehicle to know whether it can actually
3062 * use the station, but if it doesn't have facilities for RVs it is
3063 * certainly not possible that the station can be used. */
3064 return (st->facilities & (FACIL_BUS_STOP | FACIL_TRUCK_STOP)) != 0;
3065
3066 case VEH_SHIP:
3067 return (st->facilities & FACIL_DOCK) != 0;
3068
3069 case VEH_AIRCRAFT:
3070 return (st->facilities & FACIL_AIRPORT) != 0 &&
3071 (st->airport.GetFTA()->flags & (e->u.air.subtype & AIR_CTOL ? AirportFTAClass::AIRPLANES : AirportFTAClass::HELICOPTERS)) != 0;
3072
3073 default:
3074 return false;
3075 }
3076 }
3077
3084 bool CanVehicleUseStation(const Vehicle *v, const Station *st)
3085 {
3086 if (v->type == VEH_ROAD) return st->GetPrimaryRoadStop(RoadVehicle::From(v)) != nullptr;
3087
3088 return CanVehicleUseStation(v->engine_type, st);
3089 }
3090
3097 StringID GetVehicleCannotUseStationReason(const Vehicle *v, const Station *st)
3098 {
3099 switch (v->type) {
3100 case VEH_TRAIN:
3101 return STR_ERROR_NO_RAIL_STATION;
3102
3103 case VEH_ROAD: {
3104 const RoadVehicle *rv = RoadVehicle::From(v);
3105 RoadStop *rs = st->GetPrimaryRoadStop(rv->IsBus() ? ROADSTOP_BUS : ROADSTOP_TRUCK);
3106
3107 StringID err = rv->IsBus() ? STR_ERROR_NO_BUS_STATION : STR_ERROR_NO_TRUCK_STATION;
3108
3109 for (; rs != nullptr; rs = rs->next) {
3110 /* Articulated vehicles cannot use bay road stops, only drive-through. Make sure the vehicle can actually use this bay stop */
3111 if (HasTileAnyRoadType(rs->xy, rv->compatible_roadtypes) && IsBayRoadStopTile(rs->xy) && rv->HasArticulatedPart()) {
3112 err = STR_ERROR_NO_STOP_ARTICULATED_VEHICLE;
3113 continue;
3114 }
3115
3116 /* Bay stop errors take precedence, but otherwise the vehicle may not be compatible with the roadtype/tramtype of this station tile.
3117 * We give bay stop errors precedence because they are usually a bus sent to a tram station or vice versa. */
3118 if (!HasTileAnyRoadType(rs->xy, rv->compatible_roadtypes) && err != STR_ERROR_NO_STOP_ARTICULATED_VEHICLE) {
3119 err = RoadTypeIsRoad(rv->roadtype) ? STR_ERROR_NO_STOP_COMPATIBLE_ROAD_TYPE : STR_ERROR_NO_STOP_COMPATIBLE_TRAM_TYPE;
3120 continue;
3121 }
3122 }
3123
3124 return err;
3125 }
3126
3127 case VEH_SHIP:
3128 return STR_ERROR_NO_DOCK;
3129
3130 case VEH_AIRCRAFT:
3131 if ((st->facilities & FACIL_AIRPORT) == 0) return STR_ERROR_NO_AIRPORT;
3132 if (v->GetEngine()->u.air.subtype & AIR_CTOL) {
3133 return STR_ERROR_AIRPORT_NO_PLANES;
3134 } else {
3135 return STR_ERROR_AIRPORT_NO_HELICOPTERS;
3136 }
3137
3138 default:
3139 return INVALID_STRING_ID;
3140 }
3141 }
3142
3148 GroundVehicleCache *Vehicle::GetGroundVehicleCache()
3149 {
3150 assert(this->IsGroundVehicle());
3151 if (this->type == VEH_TRAIN) {
3152 return &Train::From(this)->gcache;
3153 } else {
3154 return &RoadVehicle::From(this)->gcache;
3155 }
3156 }
3157
3163 const GroundVehicleCache *Vehicle::GetGroundVehicleCache() const
3164 {
3165 assert(this->IsGroundVehicle());
3166 if (this->type == VEH_TRAIN) {
3167 return &Train::From(this)->gcache;
3168 } else {
3169 return &RoadVehicle::From(this)->gcache;
3170 }
3171 }
3172
3178 uint16_t &Vehicle::GetGroundVehicleFlags()
3179 {
3180 assert(this->IsGroundVehicle());
3181 if (this->type == VEH_TRAIN) {
3182 return Train::From(this)->gv_flags;
3183 } else {
3184 return RoadVehicle::From(this)->gv_flags;
3185 }
3186 }
3187
3193 const uint16_t &Vehicle::GetGroundVehicleFlags() const
3194 {
3195 assert(this->IsGroundVehicle());
3196 if (this->type == VEH_TRAIN) {
3197 return Train::From(this)->gv_flags;
3198 } else {
3199 return RoadVehicle::From(this)->gv_flags;
3200 }
3201 }
3202
3211 void GetVehicleSet(VehicleSet &set, Vehicle *v, uint8_t num_vehicles)
3212 {
3213 if (v->type == VEH_TRAIN) {
3214 Train *u = Train::From(v);
3215 /* Only include whole vehicles, so start with the first articulated part */
3216 u = u->GetFirstEnginePart();
3217
3218 /* Include num_vehicles vehicles, not counting articulated parts */
3219 for (; u != nullptr && num_vehicles > 0; num_vehicles--) {
3220 do {
3221 /* Include current vehicle in the selection. */
3222 include(set, u->index);
3223
3224 /* If the vehicle is multiheaded, add the other part too. */
3225 if (u->IsMultiheaded()) include(set, u->other_multiheaded_part->index);
3226
3227 u = u->Next();
3228 } while (u != nullptr && u->IsArticulatedPart());
3229 }
3230 }
3231 }
3232
3237 uint32_t Vehicle::GetDisplayMaxWeight() const
3238 {
3239 uint32_t max_weight = 0;
3240
3241 for (const Vehicle *u = this; u != nullptr; u = u->Next()) {
3242 max_weight += u->GetMaxWeight();
3243 }
3244
3245 return max_weight;
3246 }
3247
3252 uint32_t Vehicle::GetDisplayMinPowerToWeight() const
3253 {
3254 uint32_t max_weight = GetDisplayMaxWeight();
3255 if (max_weight == 0) return 0;
3256 return GetGroundVehicleCache()->cached_power * 10u / max_weight;
3257 }
3258
3265 bool VehiclesHaveSameEngineList(const Vehicle *v1, const Vehicle *v2)
3266 {
3267 while (true) {
3268 if (v1 == nullptr && v2 == nullptr) return true;
3269 if (v1 == nullptr || v2 == nullptr) return false;
3270 if (v1->GetEngine() != v2->GetEngine()) return false;
3271 v1 = v1->GetNextVehicle();
3272 v2 = v2->GetNextVehicle();
3273 }
3274 }
3275
3282 bool VehiclesHaveSameOrderList(const Vehicle *v1, const Vehicle *v2)
3283 {
3284 const Order *o1 = v1->GetFirstOrder();
3285 const Order *o2 = v2->GetFirstOrder();
3286 while (true) {
3287 if (o1 == nullptr && o2 == nullptr) return true;
3288 if (o1 == nullptr || o2 == nullptr) return false;
3289 if (!o1->Equals(*o2)) return false;
3290 o1 = o1->next;
3291 o2 = o2->next;
3292 }
3293 }
VEH_AIRCRAFT
@ VEH_AIRCRAFT
Aircraft vehicle type.
Definition: vehicle_type.h:27
Sprite::height
uint16_t height
Height of the sprite.
Definition: spritecache.h:18
GUISettings::lost_vehicle_warn
bool lost_vehicle_warn
if a vehicle can't find its destination, show a warning
Definition: settings_type.h:132
RoadVehicle
Buses, trucks and trams belong to this class.
Definition: roadveh.h:106
Vehicle::GetGroundVehicleCache
GroundVehicleCache * GetGroundVehicleCache()
Access the ground vehicle cache of the vehicle.
Definition: vehicle.cpp:3148
TileY
static debug_inline uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition: map_func.h:437
Vehicle::IsFrontEngine
debug_inline bool IsFrontEngine() const
Check if the vehicle is a front engine.
Definition: vehicle_base.h:941
DeleteNewGRFInspectWindow
void DeleteNewGRFInspectWindow(GrfSpecFeature feature, uint index)
Delete inspect window for a given feature and index.
Definition: newgrf_debug_gui.cpp:739
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
AutoreplaceMap
std::map< VehicleID, bool > AutoreplaceMap
List of vehicles that should check for autoreplace this tick.
Definition: vehicle.cpp:694
BaseStation::facilities
StationFacility facilities
The facilities that this station has.
Definition: base_station_base.h:75
Aircraft::targetairport
StationID targetairport
Airport to go to next.
Definition: aircraft.h:78
BaseConsist::cur_implicit_order_index
VehicleOrderID cur_implicit_order_index
The index to the current implicit order.
Definition: base_consist.h:32
INVALID_ENGINE
static const EngineID INVALID_ENGINE
Constant denoting an invalid engine.
Definition: engine_type.h:206
tunnel_map.h
Vehicle::x_bb_offs
int8_t x_bb_offs
x offset of vehicle bounding box
Definition: vehicle_base.h:315
EffectVehicle::animation_state
uint16_t animation_state
State primarily used to change the graphics/behaviour.
Definition: effectvehicle_base.h:25
Order::IsRefit
bool IsRefit() const
Is this order a refit order.
Definition: order_base.h:118
VehicleSettings::max_aircraft
UnitID max_aircraft
max planes in game per company
Definition: settings_type.h:525
WC_ROADVEH_LIST
@ WC_ROADVEH_LIST
Road vehicle list; Window numbers:
Definition: window_type.h:314
MutableSpriteCache::is_viewport_candidate
bool is_viewport_candidate
This vehicle can potentially be drawn on a viewport.
Definition: vehicle_base.h:195
VehicleCargoList::StoredCount
uint StoredCount() const
Returns sum of cargo on board the vehicle (ie not only reserved).
Definition: cargopacket.h:434
RoadVehicle::state
byte state
Definition: roadveh.h:108
GetEngineLivery
const Livery * GetEngineLivery(EngineID engine_type, CompanyID company, EngineID parent_engine_type, const Vehicle *v, byte livery_setting)
Determines the livery for a vehicle.
Definition: vehicle.cpp:2057
ReverseDir
Direction ReverseDir(Direction d)
Return the reverse of a direction.
Definition: direction_func.h:54
DIR_SW
@ DIR_SW
Southwest.
Definition: direction_type.h:31
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:3204
Order::MakeDummy
void MakeDummy()
Makes this order a Dummy order.
Definition: order_cmd.cpp:133
sound_func.h
UpdateVehicleTimetable
void UpdateVehicleTimetable(Vehicle *v, bool travelling)
Update the timetable for the vehicle.
Definition: timetable_cmd.cpp:469
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
Station::goods
GoodsEntry goods[NUM_CARGO]
Goods at this station.
Definition: station_base.h:471
EV_ELECTRIC_SPARK
@ EV_ELECTRIC_SPARK
Sparcs of electric engines.
Definition: effectvehicle_func.h:20
DIRDIFF_REVERSE
@ DIRDIFF_REVERSE
One direction is the opposite of the other one.
Definition: direction_type.h:62
VE_OFFSET_COUNT
@ VE_OFFSET_COUNT
Number of bits used for the offset.
Definition: vehicle_base.h:81
VehicleCache::cached_cargo_age_period
uint16_t cached_cargo_age_period
Number of ticks before carried cargo is aged.
Definition: vehicle_base.h:125
AircraftNextAirportPos_and_Order
void AircraftNextAirportPos_and_Order(Aircraft *v)
set the right pos when heading to other airports after takeoff
Definition: aircraft_cmd.cpp:1449
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:186
SetBit
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
Definition: bitmath_func.hpp:121
VE_DISABLE_EFFECT
@ VE_DISABLE_EFFECT
Flag to disable visual effect.
Definition: vehicle_base.h:91
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
newgrf_station.h
Order::IsType
bool IsType(OrderType type) const
Check whether this order is of the given type.
Definition: order_base.h:71
Vehicle::PreDestructor
void PreDestructor()
Destroy all stuff that (still) needs the virtual functions to work properly.
Definition: vehicle.cpp:826
UnitID
uint16_t UnitID
Type for the company global vehicle unit number.
Definition: transport_type.h:16
Pool::PoolItem<&_company_pool >::Get
static Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:339
PrepareUnload
void PrepareUnload(Vehicle *front_v)
Prepare the vehicle to be unloaded.
Definition: economy.cpp:1275
TimerGameTick::counter
static TickCounter counter
Monotonic counter, in ticks, since start of game.
Definition: timer_game_tick.h:60
Direction
Direction
Defines the 8 directions on the map.
Definition: direction_type.h:24
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
SetWindowDirty
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition: window.cpp:3086
MutableSpriteCache::sprite_seq
VehicleSpriteSeq sprite_seq
Vehicle appearance.
Definition: vehicle_base.h:196
Sprite::x_offs
int16_t x_offs
Number of pixels to shift the sprite to the right.
Definition: spritecache.h:20
GroupStatistics::CountEngine
static void CountEngine(const Vehicle *v, int delta)
Update num_engines when adding/removing an engine.
Definition: group_cmd.cpp:158
Company::group_all
GroupStatistics group_all[VEH_COMPANY_END]
NOSAVE: Statistics for the ALL_GROUP group.
Definition: company_base.h:140
Vehicle::GetNumManualOrders
VehicleOrderID GetNumManualOrders() const
Get the number of manually added orders this vehicle has.
Definition: vehicle_base.h:740
Vehicle::reliability_spd_dec
uint16_t reliability_spd_dec
Reliability decrease speed.
Definition: vehicle_base.h:294
Vehicle::value
Money value
Value of the vehicle.
Definition: vehicle_base.h:271
DIRDIFF_45LEFT
@ DIRDIFF_45LEFT
Angle of 45 degrees left.
Definition: direction_type.h:64
train.h
AircraftVehicleInfo::subtype
byte subtype
Type of aircraft.
Definition: engine_type.h:104
ROADSTOP_TRUCK
@ ROADSTOP_TRUCK
A standard stop for trucks.
Definition: station_type.h:45
BaseConsist::round_trip_time
TimerGameTick::Ticks round_trip_time
How many ticks for a single circumnavigation of the orders.
Definition: base_consist.h:27
command_func.h
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
DIR_SE
@ DIR_SE
Southeast.
Definition: direction_type.h:29
_tile_type_procs
const TileTypeProcs *const _tile_type_procs[16]
Tile callback functions for each type of tile.
Definition: landscape.cpp:64
Vehicle::HasEngineType
bool HasEngineType() const
Check whether Vehicle::engine_type has any meaning.
Definition: vehicle.cpp:731
IsTunnelTile
bool IsTunnelTile(Tile t)
Is this a tunnel (entrance)?
Definition: tunnel_map.h:34
ShowErrorMessage
void ShowErrorMessage(StringID summary_msg, int x, int y, CommandCost cc)
Display an error message in a window.
Definition: error_gui.cpp:367
Pool::PoolItem<&_group_pool >::GetIfValid
static Titem * GetIfValid(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:350
CMD_ERROR
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
Definition: command_func.h:28
ODTFB_SERVICE
@ ODTFB_SERVICE
This depot order is because of the servicing limit.
Definition: order_type.h:95
GBUG_VEH_POWERED_WAGON
@ GBUG_VEH_POWERED_WAGON
Powered wagon changed poweredness state when not inside a depot.
Definition: newgrf_config.h:46
Vehicle::IsEngineCountable
bool IsEngineCountable() const
Check if a vehicle is counted in num_engines in each company struct.
Definition: vehicle.cpp:714
CBID_VEHICLE_VISUAL_EFFECT
@ CBID_VEHICLE_VISUAL_EFFECT
Visual effects and wagon power.
Definition: newgrf_callbacks.h:30
VehicleListIdentifier
The information about a vehicle list.
Definition: vehiclelist.h:28
Vehicle::cargo_cap
uint16_t cargo_cap
total capacity
Definition: vehicle_base.h:339
INVALID_COORD
static const int32_t INVALID_COORD
Sentinel for an invalid coordinate.
Definition: vehicle_base.h:1284
TimerGameCalendar::date_fract
static DateFract date_fract
Fractional part of the day.
Definition: timer_game_calendar.h:35
Vehicle::Previous
Vehicle * Previous() const
Get the previous vehicle of this vehicle.
Definition: vehicle_base.h:635
HasVehicleOnPos
bool HasVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
Checks whether a vehicle is on a specific location.
Definition: vehicle.cpp:520
Vehicle::GetNextVehicle
Vehicle * GetNextVehicle() const
Get the next real (non-articulated part) vehicle in the consist.
Definition: vehicle_base.h:1012
GameCreationSettings::landscape
byte landscape
the landscape we're currently in
Definition: settings_type.h:355
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:54
HasAnyRailTypesAvail
bool HasAnyRailTypesAvail(const CompanyID company)
Test if any buildable railtype is available for a company.
Definition: rail.cpp:196
GroundVehicleCache::first_engine
EngineID first_engine
Cached EngineID of the front vehicle. INVALID_ENGINE for the front vehicle itself.
Definition: ground_vehicle.hpp:43
Backup
Class to backup a specific variable and restore it later.
Definition: backup_type.hpp:21
Order::MakeLoading
void MakeLoading(bool ordered)
Makes this order a Loading order.
Definition: order_cmd.cpp:115
Order::MakeLeaveStation
void MakeLeaveStation()
Makes this order a Leave Station order.
Definition: order_cmd.cpp:124
Vehicle::LeaveStation
void LeaveStation()
Perform all actions when leaving a station.
Definition: vehicle.cpp:2343
IsWagon
static bool IsWagon(EngineID index)
Determine whether an engine type is a wagon (and not a loco).
Definition: engine.cpp:589
Vehicle::Next
Vehicle * Next() const
Get the next vehicle of this vehicle.
Definition: vehicle_base.h:628
SpecializedVehicle::Next
T * Next() const
Get next vehicle in the chain.
Definition: vehicle_base.h:1126
RoadStop::xy
TileIndex xy
Position on the map.
Definition: roadstop_base.h:67
GetCargoTypesOfArticulatedVehicle
CargoTypes GetCargoTypesOfArticulatedVehicle(const Vehicle *v, CargoID *cargo_type)
Get cargo mask of all cargoes carried by an articulated vehicle.
Definition: articulated_vehicles.cpp:265
timer_game_calendar.h
FACIL_TRUCK_STOP
@ FACIL_TRUCK_STOP
Station with truck stops.
Definition: station_type.h:53
DIRDIFF_SAME
@ DIRDIFF_SAME
Both directions faces to the same direction.
Definition: direction_type.h:59
Vehicle::y_extent
byte y_extent
y-extent of vehicle bounding box
Definition: vehicle_base.h:313
OLFB_FULL_LOAD
@ OLFB_FULL_LOAD
Full load all cargoes of the consist.
Definition: order_type.h:64
_gamelog
Gamelog _gamelog
Gamelog instance.
Definition: gamelog.cpp:31
Station
Station data structure.
Definition: station_base.h:442
Order::GetDestination
DestinationID GetDestination() const
Gets the destination of this order.
Definition: order_base.h:104
Viewport::width
int width
Screen width of the viewport.
Definition: viewport_type.h:25
economy_base.h
Vehicle::NeedsAutomaticServicing
bool NeedsAutomaticServicing() const
Checks if the current order should be interrupted for a service-in-depot order.
Definition: vehicle.cpp:272
StringID
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:16
SpawnAdvancedVisualEffect
static void SpawnAdvancedVisualEffect(const Vehicle *v)
Call CBID_VEHICLE_SPAWN_VISUAL_EFFECT and spawn requested effects.
Definition: vehicle.cpp:2725
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:225
Engine::company_avail
CompanyMask company_avail
Bit for each company whether the engine is available for that company.
Definition: engine_base.h:53
DIR_NW
@ DIR_NW
Northwest.
Definition: direction_type.h:33
GroundVehicleCache::cached_weight
uint32_t cached_weight
Total weight of the consist (valid only for the first engine).
Definition: ground_vehicle.hpp:31
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
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:1141
vehiclelist.h
Viewport::height
int height
Screen height of the viewport.
Definition: viewport_type.h:26
EC_STEAM
@ EC_STEAM
Steam rail engine.
Definition: engine_type.h:34
Vehicle::vehstatus
byte vehstatus
Status.
Definition: vehicle_base.h:349
IntervalTimer
An interval timer will fire every interval, and will continue to fire until it is deleted.
Definition: timer.h:76
group_gui.h
GB
constexpr static debug_inline 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
VE_DEFAULT
@ VE_DEFAULT
Default value to indicate that visual effect should be based on engine class.
Definition: vehicle_base.h:95
Group::parent
GroupID parent
Parent group.
Definition: group.h:83
VehiclesHaveSameOrderList
bool VehiclesHaveSameOrderList(const Vehicle *v1, const Vehicle *v2)
Checks if two vehicles have the same list of orders.
Definition: vehicle.cpp:3282
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
VS_DEFPAL
@ VS_DEFPAL
Use default vehicle palette.
Definition: vehicle_base.h:36
depot_func.h
GetRegister
uint32_t GetRegister(uint i)
Gets the value of a so-called newgrf "register".
Definition: newgrf_spritegroup.h:29
VSE_BREAKDOWN
@ VSE_BREAKDOWN
Vehicle breaking down.
Definition: newgrf_sound.h:21
Pool::PoolItem::index
Tindex index
Index of this pool item.
Definition: pool_type.hpp:238
Vehicle::SetNext
void SetNext(Vehicle *next)
Set the next vehicle of this vehicle.
Definition: vehicle.cpp:2930
AddVehicleAdviceNewsItem
void AddVehicleAdviceNewsItem(StringID string, VehicleID vehicle)
Adds a vehicle-advice news item.
Definition: news_func.h:40
CargoSpec::Get
static CargoSpec * Get(size_t index)
Retrieve cargo details for the given cargo ID.
Definition: cargotype.h:131
Vehicle::GetGRFID
uint32_t GetGRFID() const
Retrieve the GRF ID of the NewGRF the vehicle is tied to.
Definition: vehicle.cpp:767
Vehicle::Crash
virtual uint Crash(bool flooded=false)
Crash the (whole) vehicle chain.
Definition: vehicle.cpp:280
MAX_VEHICLE_PIXEL_Y
static const int MAX_VEHICLE_PIXEL_Y
Maximum height of a vehicle in pixels in #ZOOM_LVL_BASE.
Definition: tile_type.h:22
Viewport::top
int top
Screen coordinate top edge of the viewport.
Definition: viewport_type.h:24
PFE_GL_ROADVEHS
@ PFE_GL_ROADVEHS
Time spend processing road vehicles.
Definition: framerate_type.h:52
PalSpriteID::sprite
SpriteID sprite
The 'real' sprite.
Definition: gfx_type.h:23
Vehicle::group_id
GroupID group_id
Index of group Pool array.
Definition: vehicle_base.h:358
Vehicle::Vehicle
Vehicle(VehicleType type=VEH_INVALID)
Vehicle constructor.
Definition: vehicle.cpp:361
EF_NO_BREAKDOWN_SMOKE
@ EF_NO_BREAKDOWN_SMOKE
Do not show black smoke during a breakdown.
Definition: engine_type.h:175
DeleteVehicleNews
void DeleteVehicleNews(VehicleID vid, StringID news)
Delete a news item type about a vehicle.
Definition: news_gui.cpp:919
misc_cmd.h
GameSettings::difficulty
DifficultySettings difficulty
settings related to the difficulty
Definition: settings_type.h:617
GRFConfig::grf_bugs
uint32_t grf_bugs
NOSAVE: bugs in this GRF in this run,.
Definition: newgrf_config.h:166
GroupStatistics::CountVehicle
static void CountVehicle(const Vehicle *v, int delta)
Update num_vehicle when adding or removing a vehicle.
Definition: group_cmd.cpp:133
ship.h
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
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:114
PerformanceMeasurer
RAII class for measuring simple elements of performance.
Definition: framerate_type.h:92
BaseConsist::vehicle_flags
uint16_t vehicle_flags
Used for gradual loading and other miscellaneous things (.
Definition: base_consist.h:34
Vehicle::trip_occupancy
int8_t trip_occupancy
NOSAVE: Occupancy of vehicle of the current trip (updated after leaving a station).
Definition: vehicle_base.h:343
HideFillingPercent
void HideFillingPercent(TextEffectID *te_id)
Hide vehicle loading indicators.
Definition: misc_gui.cpp:646
VE_TYPE_ELECTRIC
@ VE_TYPE_ELECTRIC
Electric sparks.
Definition: vehicle_base.h:89
GroupStatistics::VehicleReachedMinAge
static void VehicleReachedMinAge(const Vehicle *v)
Add a vehicle to the profit sum of its group.
Definition: group_cmd.cpp:180
Vehicle::next
Vehicle * next
pointer to the next vehicle in the chain
Definition: vehicle_base.h:244
ODTF_MANUAL
@ ODTF_MANUAL
Manually initiated order.
Definition: order_type.h:94
Vehicle::GetGRF
const GRFFile * GetGRF() const
Retrieve the NewGRF the vehicle is tied to.
Definition: vehicle.cpp:757
BaseConsist::lateness_counter
TimerGameTick::Ticks lateness_counter
How many ticks late (or early if negative) this vehicle is.
Definition: base_consist.h:22
RoadStop::GetByTile
static RoadStop * GetByTile(TileIndex tile, RoadStopType type)
Find a roadstop at given tile.
Definition: roadstop.cpp:266
IsRailStationTile
bool IsRailStationTile(Tile t)
Is this tile a station tile and a rail station?
Definition: station_map.h:102
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:335
VF_LOADING_FINISHED
@ VF_LOADING_FINISHED
Vehicle has finished loading.
Definition: vehicle_base.h:45
zoom_func.h
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
autoreplace_gui.h
aircraft.h
Group::livery
Livery livery
Custom colour scheme for vehicles in this group.
Definition: group.h:78
TILE_SIZE
static const uint TILE_SIZE
Tile size in world coordinates.
Definition: tile_type.h:15
RSRT_VEH_DEPARTS
@ RSRT_VEH_DEPARTS
Trigger roadstop when road vehicle leaves.
Definition: newgrf_roadstop.h:38
CeilDiv
constexpr uint CeilDiv(uint a, uint b)
Computes ceil(a / b) for non-negative a and b.
Definition: math_func.hpp:320
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:636
TimerGameEconomy::date_fract
static DateFract date_fract
Fractional part of the day.
Definition: timer_game_economy.h:38
SpecializedStation< Station, false >::Get
static Station * Get(size_t index)
Gets station with given index.
Definition: base_station_base.h:259
EV_STEAM_SMOKE
@ EV_STEAM_SMOKE
Smoke of steam engines.
Definition: effectvehicle_func.h:18
Vehicle::~Vehicle
virtual ~Vehicle()
We want to 'destruct' the right class.
Definition: vehicle.cpp:893
_settings_client
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:54
LiveryScheme
LiveryScheme
List of different livery schemes.
Definition: livery.h:21
VehicleEnterDepot
void VehicleEnterDepot(Vehicle *v)
Vehicle entirely entered the depot, update its status, orders, vehicle windows, service it,...
Definition: vehicle.cpp:1545
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
BaseConsist::current_order_time
TimerGameTick::Ticks current_order_time
How many ticks have passed since this order started.
Definition: base_consist.h:21
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:250
WC_VEHICLE_TIMETABLE
@ WC_VEHICLE_TIMETABLE
Vehicle timetable; Window numbers:
Definition: window_type.h:224
VE_TYPE_COUNT
@ VE_TYPE_COUNT
Number of bits used for the effect type.
Definition: vehicle_base.h:85
TimerGameEconomy::UsingWallclockUnits
static bool UsingWallclockUnits(bool newgame=false)
Check if we are using wallclock units.
Definition: timer_game_economy.cpp:97
newgrf_debug.h
GetGRFConfig
GRFConfig * GetGRFConfig(uint32_t grfid, uint32_t mask)
Retrieve a NewGRF from the current config by its grfid.
Definition: newgrf_config.cpp:716
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > >
effectvehicle_base.h
RunVehicleCalendarDayProc
void RunVehicleCalendarDayProc()
Age all vehicles, spreading out the action using the current TimerGameCalendar::date_fract.
Definition: vehicle.cpp:935
GroundVehicle::IsRearDualheaded
bool IsRearDualheaded() const
Tell if we are dealing with the rear end of a multiheaded engine.
Definition: ground_vehicle.hpp:333
VS_TRAIN_SLOWING
@ VS_TRAIN_SLOWING
Train is slowing down.
Definition: vehicle_base.h:37
SND_3A_BREAKDOWN_TRAIN_SHIP_TOYLAND
@ SND_3A_BREAKDOWN_TRAIN_SHIP_TOYLAND
58 == 0x3A Breakdown: train or ship (toyland)
Definition: sound_type.h:97
WC_COMPANY
@ WC_COMPANY
Company view; Window numbers:
Definition: window_type.h:369
FreeUnitIDGenerator::ReleaseID
void ReleaseID(UnitID index)
Release a unit number.
Definition: vehicle.cpp:1873
WC_STATION_VIEW
@ WC_STATION_VIEW
Station view; Window numbers:
Definition: window_type.h:345
DIR_W
@ DIR_W
West.
Definition: direction_type.h:32
OrderBackup::ClearVehicle
static void ClearVehicle(const Vehicle *v)
Clear/update the (clone) vehicle from an order backup.
Definition: order_backup.cpp:232
RoadVehicle::roadtype
RoadType roadtype
Roadtype of this vehicle.
Definition: roadveh.h:116
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:597
ChangeDir
Direction ChangeDir(Direction d, DirDiff delta)
Change a direction by a given difference.
Definition: direction_func.h:104
Engine
Definition: engine_base.h:37
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:801
MAX_VEHICLE_PIXEL_X
static const int MAX_VEHICLE_PIXEL_X
Maximum width of a vehicle in pixels in #ZOOM_LVL_BASE.
Definition: tile_type.h:21
VEH_ROAD
@ VEH_ROAD
Road vehicle type.
Definition: vehicle_type.h:25
CC_PASSENGERS
@ CC_PASSENGERS
Passengers.
Definition: cargotype.h:50
Vehicle
Vehicle data structure.
Definition: vehicle_base.h:240
Vehicle::IsPrimaryVehicle
virtual bool IsPrimaryVehicle() const
Whether this is the primary vehicle in the chain.
Definition: vehicle_base.h:473
Engine::GetDefaultCargoType
CargoID GetDefaultCargoType() const
Determines the default cargo type of an engine.
Definition: engine_base.h:96
VehicleSpriteSeq::Draw
void Draw(int x, int y, PaletteID default_pal, bool force_pal) const
Draw the sprite sequence.
Definition: vehicle.cpp:131
Chance16
bool Chance16(const uint a, const uint b)
Flips a coin with given probability.
Definition: random_func.hpp:131
Viewport::virtual_top
int virtual_top
Virtual top coordinate.
Definition: viewport_type.h:29
Vehicle::owner
Owner owner
Which company owns the vehicle?
Definition: vehicle_base.h:305
gamelog.h
Owner
Owner
Enum for all companies/owners.
Definition: company_type.h:18
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:3211
TimerGameTick::TickCounter
uint64_t TickCounter
The type that the tick counter is stored in.
Definition: timer_game_tick.h:25
Vehicle::IsInDepot
virtual bool IsInDepot() const
Check whether the vehicle is in the depot.
Definition: vehicle_base.h:544
DC_EXEC
@ DC_EXEC
execute the given command
Definition: command_type.h:371
Engine::GetGRFID
uint32_t GetGRFID() const
Retrieve the GRF ID of the NewGRF the engine is tied to.
Definition: engine.cpp:157
PaletteID
uint32_t PaletteID
The number of the palette.
Definition: gfx_type.h:18
VSE_VISUAL_EFFECT
@ VSE_VISUAL_EFFECT
Vehicle visual effect (steam, diesel smoke or electric spark) is shown.
Definition: newgrf_sound.h:24
TriggerRoadStopRandomisation
void TriggerRoadStopRandomisation(Station *st, TileIndex tile, RoadStopRandomTrigger trigger, CargoID cargo_type=INVALID_CARGO)
Trigger road stop randomisation.
Definition: newgrf_roadstop.cpp:392
DIR_N
@ DIR_N
North.
Definition: direction_type.h:26
GetEnginePalette
PaletteID GetEnginePalette(EngineID engine_type, CompanyID company)
Get the colour map for an engine.
Definition: vehicle.cpp:2135
Vehicle::IsGroundVehicle
debug_inline bool IsGroundVehicle() const
Check if the vehicle is a ground vehicle.
Definition: vehicle_base.h:511
OrderList::RemoveVehicle
void RemoveVehicle(Vehicle *v)
Removes the vehicle from the shared order list.
Definition: order_cmd.cpp:568
CommandCost::GetErrorMessage
StringID GetErrorMessage() const
Returns the error message of a command.
Definition: command_type.h:142
DeleteVehicleOrders
void DeleteVehicleOrders(Vehicle *v, bool keep_orderlist, bool reset_order_indices)
Delete all orders from a vehicle.
Definition: order_cmd.cpp:1877
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:2148
VS_AIRCRAFT_BROKEN
@ VS_AIRCRAFT_BROKEN
Aircraft is broken down.
Definition: vehicle_base.h:39
Vehicle::motion_counter
uint32_t motion_counter
counter to occasionally play a vehicle sound.
Definition: vehicle_base.h:327
DoCommandFlag
DoCommandFlag
List of flags for a command.
Definition: command_type.h:369
VehicleServiceInDepot
void VehicleServiceInDepot(Vehicle *v)
Service a vehicle and all subsequent vehicles in the consist.
Definition: vehicle.cpp:167
VE_OFFSET_START
@ VE_OFFSET_START
First bit that contains the offset (0 = front, 8 = centre, 15 = rear)
Definition: vehicle_base.h:80
EnsureNoVehicleOnGround
CommandCost EnsureNoVehicleOnGround(TileIndex tile)
Ensure there is no vehicle at the ground at the given position.
Definition: vehicle.cpp:546
Vehicle::breakdowns_since_last_service
byte breakdowns_since_last_service
Counter for the amount of breakdowns.
Definition: vehicle_base.h:297
ODATFB_UNBUNCH
@ ODATFB_UNBUNCH
Service the vehicle and then unbunch it.
Definition: order_type.h:106
AIR_SHADOW
@ AIR_SHADOW
shadow of the aircraft
Definition: aircraft.h:33
RVSB_IN_DT_ROAD_STOP
@ RVSB_IN_DT_ROAD_STOP
The vehicle is in a drive-through road stop.
Definition: roadveh.h:51
BaseConsist::depot_unbunching_last_departure
TimerGameTick::TickCounter depot_unbunching_last_departure
When the vehicle last left its unbunching depot.
Definition: base_consist.h:25
GRFBugs
GRFBugs
Encountered GRF bugs.
Definition: newgrf_config.h:43
Debug
#define Debug(category, level, format_string,...)
Ouptut a line of debugging information.
Definition: debug.h:37
CommandCost::Succeeded
bool Succeeded() const
Did this command succeed?
Definition: command_type.h:162
SND_35_BREAKDOWN_ROADVEHICLE_TOYLAND
@ SND_35_BREAKDOWN_ROADVEHICLE_TOYLAND
53 == 0x35 Breakdown: road vehicle (toyland)
Definition: sound_type.h:92
TracksOverlap
bool TracksOverlap(TrackBits bits)
Checks if the given tracks overlap, ie form a crossing.
Definition: track_func.h:645
RandomRange
static uint32_t RandomRange(uint32_t limit)
Pick a random number between 0 and limit - 1, inclusive.
Definition: random_func.hpp:81
HandleAircraftEnterHangar
void HandleAircraftEnterHangar(Aircraft *v)
Handle Aircraft specific tasks when an Aircraft enters a hangar.
Definition: aircraft_cmd.cpp:573
Vehicle::x_pos
int32_t x_pos
x coordinate.
Definition: vehicle_base.h:300
GUISettings::vehicle_income_warn
bool vehicle_income_warn
if a vehicle isn't generating income, show a warning
Definition: settings_type.h:134
train_cmd.h
GroundVehicle::gv_flags
uint16_t gv_flags
Definition: ground_vehicle.hpp:81
GameSettings::game_creation
GameCreationSettings game_creation
settings used during the creation of a game (map)
Definition: settings_type.h:618
CheckClickOnVehicle
Vehicle * CheckClickOnVehicle(const Viewport *vp, int x, int y)
Find the vehicle close to the clicked coordinates.
Definition: vehicle.cpp:1244
Vehicle::IsArticulatedPart
bool IsArticulatedPart() const
Check if the vehicle is an articulated part of an engine.
Definition: vehicle_base.h:950
effectvehicle_func.h
SpecializedStation< Station, false >::Iterate
static Pool::IterateWrapper< Station > Iterate(size_t from=0)
Returns an iterable ensemble of all valid stations of type T.
Definition: base_station_base.h:310
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
ai.hpp
PFE_GL_TRAINS
@ PFE_GL_TRAINS
Time spent processing trains.
Definition: framerate_type.h:51
EC_ELECTRIC
@ EC_ELECTRIC
Electric rail engine.
Definition: engine_type.h:36
Order::GetType
OrderType GetType() const
Get the type of order of this order.
Definition: order_base.h:77
VehicleCargoList
CargoList that is used for vehicles.
Definition: cargopacket.h:351
DepotCommand::Service
@ Service
The vehicle will leave the depot right after arrival (service only)
Aircraft
Aircraft, helicopters, rotors and their shadows belong to this class.
Definition: aircraft.h:74
InsertOrder
void InsertOrder(Vehicle *v, Order *new_o, VehicleOrderID sel_ord)
Insert a new order but skip the validation.
Definition: order_cmd.cpp:920
Ship::UpdateCache
void UpdateCache()
Update the caches of this ship.
Definition: ship_cmd.cpp:238
GetTileType
static debug_inline TileType GetTileType(Tile tile)
Get the tiletype of a given tile.
Definition: tile_map.h:96
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
VF_STOP_LOADING
@ VF_STOP_LOADING
Don't load anymore during the next load cycle.
Definition: vehicle_base.h:51
VE_TYPE_DIESEL
@ VE_TYPE_DIESEL
Diesel fumes.
Definition: vehicle_base.h:88
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
GetGrfSpecFeature
GrfSpecFeature GetGrfSpecFeature(TileIndex tile)
Get the GrfSpecFeature associated with the tile.
Definition: newgrf_debug_gui.cpp:773
Engine::GetGRF
const GRFFile * GetGRF() const
Retrieve the NewGRF the engine is tied to.
Definition: engine_base.h:167
GoodsEntry::cargo
StationCargoList cargo
The cargo packets of cargo waiting in this station.
Definition: station_base.h:210
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:291
Vehicle::GetImage
virtual void GetImage([[maybe_unused]] Direction direction, [[maybe_unused]] EngineImageType image_type, [[maybe_unused]] VehicleSpriteSeq *result) const
Gets the sprite to show for the given direction.
Definition: vehicle_base.h:482
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
ShipVehicleInfo::visual_effect
byte visual_effect
Bitstuffed NewGRF visual effect data.
Definition: engine_type.h:76
VESM_STEAM
@ VESM_STEAM
Steam model.
Definition: vehicle_base.h:101
Group
Group data.
Definition: group.h:72
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
FreeUnitIDGenerator::UseID
UnitID UseID(UnitID index)
Use a unit number.
Definition: vehicle.cpp:1856
EC_MAGLEV
@ EC_MAGLEV
Maglev engine.
Definition: engine_type.h:38
SND_10_BREAKDOWN_TRAIN_SHIP
@ SND_10_BREAKDOWN_TRAIN_SHIP
14 == 0x0E Breakdown: train or ship (non-toyland)
Definition: sound_type.h:53
VRF_LEAVING_STATION
@ VRF_LEAVING_STATION
Train is just leaving a station.
Definition: train.h:33
GameSettings::order
OrderSettings order
settings related to orders
Definition: settings_type.h:625
Pool::PoolItem<&_vehicle_pool >::GetPoolSize
static size_t GetPoolSize()
Returns first unused index.
Definition: pool_type.hpp:360
Order::GetNonStopType
OrderNonStopFlags GetNonStopType() const
At which stations must we stop?
Definition: order_base.h:141
Vehicle::Orders
IterateWrapper Orders() const
Returns an iterable ensemble of orders of a vehicle.
Definition: vehicle_base.h:1080
Vehicle::BeginLoading
void BeginLoading()
Prepare everything to begin the loading when arriving at a station.
Definition: vehicle.cpp:2196
RoadStop::next
struct RoadStop * next
Next stop of the given type at this station.
Definition: roadstop_base.h:69
FACIL_BUS_STOP
@ FACIL_BUS_STOP
Station with bus stops.
Definition: station_type.h:54
RailVehicleInfo::visual_effect
byte visual_effect
Bitstuffed NewGRF visual effect data.
Definition: engine_type.h:58
Vehicle::breakdown_ctr
byte breakdown_ctr
Counter for managing breakdown events.
Definition: vehicle_base.h:295
VS_HIDDEN
@ VS_HIDDEN
Vehicle is not visible.
Definition: vehicle_base.h:33
Vehicle::UpdateVisualEffect
void UpdateVisualEffect(bool allow_power_change=true)
Update the cached visual effect.
Definition: vehicle.cpp:2657
DirDifference
DirDiff DirDifference(Direction d0, Direction d1)
Calculate the difference between two directions.
Definition: direction_func.h:68
Viewport
Data structure for viewport, display of a part of the world.
Definition: viewport_type.h:22
DepotCommand
DepotCommand
Flags for goto depot commands.
Definition: vehicle_type.h:64
RailVehicleInfo::engclass
EngineClass engclass
Class of engine for this vehicle.
Definition: engine_type.h:53
CheckOwnership
CommandCost CheckOwnership(Owner owner, TileIndex tile)
Check whether the current owner owns something.
Definition: company_cmd.cpp:361
VehicleSpriteSeq::IsValid
bool IsValid() const
Check whether the sequence contains any sprites.
Definition: vehicle_base.h:148
OLF_FULL_LOAD_ANY
@ OLF_FULL_LOAD_ANY
Full load a single cargo of the consist.
Definition: order_type.h:65
Vehicle::dest_tile
TileIndex dest_tile
Heading for this tile.
Definition: vehicle_base.h:267
Vehicle::HandlePathfindingResult
void HandlePathfindingResult(bool path_found)
Handle the pathfinding result, especially the lost status.
Definition: vehicle.cpp:791
Vehicle::GetDisplayProfitThisYear
Money GetDisplayProfitThisYear() const
Gets the profit vehicle had this year.
Definition: vehicle_base.h:613
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
return_cmd_error
#define return_cmd_error(errcode)
Returns from a function with a specific StringID as error.
Definition: command_func.h:38
EngineInfo::callback_mask
uint16_t callback_mask
Bitmask of vehicle callbacks that have to be called.
Definition: engine_type.h:156
RoadVehicle::disaster_vehicle
VehicleID disaster_vehicle
NOSAVE: Disaster vehicle targetting this vehicle.
Definition: roadveh.h:119
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:609
VE_TYPE_START
@ VE_TYPE_START
First bit used for the type of effect.
Definition: vehicle_base.h:84
TO_INVALID
@ TO_INVALID
Invalid transparency option.
Definition: transparency.h:33
GroundVehicleCache
Cached, frequently calculated values.
Definition: ground_vehicle.hpp:29
IsBayRoadStopTile
bool IsBayRoadStopTile(Tile t)
Is tile t a bay (non-drive through) road stop station?
Definition: station_map.h:223
INVALID_GROUP
static const GroupID INVALID_GROUP
Sentinel for invalid groups.
Definition: group_type.h:18
CompanySettings::engine_renew
bool engine_renew
is autorenew enabled
Definition: settings_type.h:608
Order::GetRefitCargo
CargoID GetRefitCargo() const
Get the cargo to to refit to.
Definition: order_base.h:132
timetable.h
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
AI::NewEvent
static void NewEvent(CompanyID company, ScriptEvent *event)
Queue a new event for an AI.
Definition: ai_core.cpp:244
CommandCost
Common return value for all commands.
Definition: command_type.h:23
ONSF_STOP_EVERYWHERE
@ ONSF_STOP_EVERYWHERE
The vehicle will stop at any station it passes and the destination.
Definition: order_type.h:73
Vehicle::UpdateBoundingBoxCoordinates
void UpdateBoundingBoxCoordinates(bool update_cache) const
Update the bounding box co-ordinates of the vehicle.
Definition: vehicle.cpp:1695
VehicleCargoList::Truncate
uint Truncate(uint max_move=UINT_MAX)
Truncates the cargo in this list to the given amount.
Definition: cargopacket.cpp:648
Vehicle::GetCurrentMaxSpeed
virtual int GetCurrentMaxSpeed() const
Calculates the maximum speed of the vehicle under its current conditions.
Definition: vehicle_base.h:532
WC_VEHICLE_VIEW
@ WC_VEHICLE_VIEW
Vehicle view; Window numbers:
Definition: window_type.h:339
Vehicle::AddToShared
void AddToShared(Vehicle *shared_chain)
Adds this vehicle to a shared vehicle chain.
Definition: vehicle.cpp:2959
GRFConfig
Information about GRF, used in the game and (part of it) in savegames.
Definition: newgrf_config.h:147
Vehicle::IsWaitingForUnbunching
bool IsWaitingForUnbunching() const
Check whether a vehicle inside a depot is waiting for unbunching.
Definition: vehicle.cpp:2554
LIT_ALL
static const byte LIT_ALL
Show the liveries of all companies.
Definition: livery.h:18
VehicleCargoList::AgeCargo
void AgeCargo()
Ages the all cargo in this list.
Definition: cargopacket.cpp:391
DIR_E
@ DIR_E
East.
Definition: direction_type.h:28
Viewport::virtual_left
int virtual_left
Virtual left coordinate.
Definition: viewport_type.h:28
Vehicle::RemoveFromShared
void RemoveFromShared()
Removes the vehicle from the shared order list.
Definition: vehicle.cpp:2982
VF_CARGO_UNLOADING
@ VF_CARGO_UNLOADING
Vehicle is unloading cargo.
Definition: vehicle_base.h:46
VehicleSettings::max_ships
UnitID max_ships
max ships in game per company
Definition: settings_type.h:526
roadstop_base.h
EV_BREAKDOWN_SMOKE_AIRCRAFT
@ EV_BREAKDOWN_SMOKE_AIRCRAFT
Smoke of broken aircraft.
Definition: effectvehicle_func.h:27
GoodsEntry::HasRating
bool HasRating() const
Does this cargo have a rating at this station?
Definition: station_base.h:258
Vehicle::tile
TileIndex tile
Current tile index.
Definition: vehicle_base.h:260
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:2327
INVALID_VEHICLE
static const VehicleID INVALID_VEHICLE
Constant representing a non-existing vehicle.
Definition: vehicle_type.h:54
EIT_ON_MAP
@ EIT_ON_MAP
Vehicle drawn in viewport.
Definition: vehicle_type.h:86
Station::MarkTilesDirty
void MarkTilesDirty(bool cargo_change) const
Marks the tiles of the station as dirty.
Definition: station.cpp:244
Viewport::left
int left
Screen coordinate left edge of the viewport.
Definition: viewport_type.h:23
Vehicle::engine_type
EngineID engine_type
The type of engine used for this vehicle.
Definition: vehicle_base.h:319
DoDrawVehicle
static void DoDrawVehicle(const Vehicle *v)
Add vehicle sprite for drawing to the screen.
Definition: vehicle.cpp:1120
VS_CRASHED
@ VS_CRASHED
Vehicle is crashed.
Definition: vehicle_base.h:40
VehicleSpriteSeq
Sprite sequence for a vehicle part.
Definition: vehicle_base.h:131
RoadVehicleInfo::visual_effect
byte visual_effect
Bitstuffed NewGRF visual effect data.
Definition: engine_type.h:126
Vehicle::last_station_visited
StationID last_station_visited
The last station we stopped at.
Definition: vehicle_base.h:333
GetFreeUnitNumber
UnitID GetFreeUnitNumber(VehicleType type)
Get an unused unit number for a vehicle (if allowed).
Definition: vehicle.cpp:1888
PFE_GL_SHIPS
@ PFE_GL_SHIPS
Time spent processing ships.
Definition: framerate_type.h:53
EF_USES_2CC
@ EF_USES_2CC
Vehicle uses two company colours.
Definition: engine_type.h:170
Vehicle::cargo
VehicleCargoList cargo
The cargo this vehicle is carrying.
Definition: vehicle_base.h:341
CBID_VEHICLE_SPAWN_VISUAL_EFFECT
@ CBID_VEHICLE_SPAWN_VISUAL_EFFECT
Called to spawn visual effects for vehicles.
Definition: newgrf_callbacks.h:281
CommandCost::Failed
bool Failed() const
Did this command fail?
Definition: command_type.h:171
Sprite::width
uint16_t width
Width of the sprite.
Definition: spritecache.h:19
Vehicle::hash_tile_current
Vehicle ** hash_tile_current
NOSAVE: Cache of the current hash chain.
Definition: vehicle_base.h:282
CCF_ARRANGE
@ CCF_ARRANGE
Valid changes for arranging the consist in a depot.
Definition: train.h:52
Vehicle::current_order
Order current_order
The current order (+ status, like: loading)
Definition: vehicle_base.h:350
CompanySettings::engine_renew_money
uint32_t engine_renew_money
minimum amount of money before autorenew is used
Definition: settings_type.h:610
Station::airport
Airport airport
Tile area the airport covers.
Definition: station_base.h:456
HasAnyRoadTypesAvail
bool HasAnyRoadTypesAvail(CompanyID company, RoadTramType rtt)
Test if any buildable RoadType is available for a company.
Definition: road.cpp:143
GroundVehicle::gcache
GroundVehicleCache gcache
Cache of often calculated values.
Definition: ground_vehicle.hpp:80
EC_DIESEL
@ EC_DIESEL
Diesel rail engine.
Definition: engine_type.h:35
AirportFTAClass::layout
struct AirportFTA * layout
state machine for airport
Definition: airport.h:177
DIR_NE
@ DIR_NE
Northeast.
Definition: direction_type.h:27
VEH_EFFECT
@ VEH_EFFECT
Effect vehicle type (smoke, explosions, sparks, bubbles)
Definition: vehicle_type.h:31
autoreplace_cmd.h
EndSpriteCombine
void EndSpriteCombine()
Terminates a block of sprites started by StartSpriteCombine.
Definition: viewport.cpp:779
Vehicle::cur_speed
uint16_t cur_speed
current speed
Definition: vehicle_base.h:324
AirportFTAClass::flags
Flags flags
Flags for this airport type.
Definition: airport.h:180
LIT_COMPANY
static const byte LIT_COMPANY
Show the liveries of your own company.
Definition: livery.h:17
DeleteOrder
void DeleteOrder(Vehicle *v, VehicleOrderID sel_ord)
Delete an order but skip the parameter validation.
Definition: order_cmd.cpp:1045
Vehicle::GetLastOrder
Order * GetLastOrder() const
Returns the last order of a vehicle, or nullptr if it doesn't exists.
Definition: vehicle_base.h:927
ODATFB_NEAREST_DEPOT
@ ODATFB_NEAREST_DEPOT
Send the vehicle to the nearest depot.
Definition: order_type.h:105
_settings_game
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition: settings.cpp:55
IsCompanyBuildableVehicleType
bool IsCompanyBuildableVehicleType(VehicleType type)
Is the given vehicle type buildable by a company?
Definition: vehicle_func.h:91
VehicleFromPos
static Vehicle * VehicleFromPos(TileIndex tile, void *data, VehicleFromPosProc *proc, bool find_first)
Helper function for FindVehicleOnPos/HasVehicleOnPos.
Definition: vehicle.cpp:476
Livery::in_use
byte 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
CompanyProperties::settings
CompanySettings settings
settings specific for each company
Definition: company_base.h:118
timer_game_tick.h
WC_VEHICLE_DETAILS
@ WC_VEHICLE_DETAILS
Vehicle details; Window numbers:
Definition: window_type.h:200
AirportFTA
Internal structure used in openttd - Finite sTate mAchine --> FTA.
Definition: airport.h:190
VehicleListIdentifier::Pack
uint32_t Pack() const
Pack a VehicleListIdentifier in a single uint32.
Definition: vehiclelist.cpp:22
VS_STOPPED
@ VS_STOPPED
Vehicle is stopped by the player.
Definition: vehicle_base.h:34
Vehicle::ShowVisualEffect
void ShowVisualEffect() const
Draw visual effects (smoke and/or sparks) for a vehicle chain.
Definition: vehicle.cpp:2780
_local_company
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition: company_cmd.cpp:50
Vehicle::GetEngine
const Engine * GetEngine() const
Retrieves the engine of the vehicle.
Definition: vehicle.cpp:747
VisualEffectSpawnModel
VisualEffectSpawnModel
Models for spawning visual effects.
Definition: vehicle_base.h:99
safeguards.h
GroupStatistics::UpdateAutoreplace
static void UpdateAutoreplace(CompanyID company)
Update autoreplace_defined and autoreplace_finished of all statistics of a company.
Definition: group_cmd.cpp:221
VehicleFromPosXY
static Vehicle * VehicleFromPosXY(int x, int y, void *data, VehicleFromPosProc *proc, bool find_first)
Helper function for FindVehicleOnPos/HasVehicleOnPos.
Definition: vehicle.cpp:418
timer.h
GetNewVehiclePosResult::new_tile
TileIndex new_tile
Tile of the vehicle after moving.
Definition: vehicle_func.h:80
EF_RAIL_IS_MU
@ EF_RAIL_IS_MU
Rail vehicle is a multiple-unit (DMU/EMU)
Definition: engine_type.h:171
Vehicle::ResetRefitCaps
void ResetRefitCaps()
Reset all refit_cap in the consist to cargo_cap.
Definition: vehicle.cpp:2404
PreviousOrderIsUnbunching
static bool PreviousOrderIsUnbunching(const Vehicle *v)
Check if the previous order is a depot unbunching order.
Definition: vehicle.cpp:2494
Vehicle::UpdateViewport
void UpdateViewport(bool dirty)
Update the vehicle on the viewport, updating the right hash and setting the new coordinates.
Definition: vehicle.cpp:1728
VehiclesHaveSameEngineList
bool VehiclesHaveSameEngineList(const Vehicle *v1, const Vehicle *v2)
Checks if two vehicle chains have the same list of engines.
Definition: vehicle.cpp:3265
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:334
Train
'Train' is either a loco or a wagon.
Definition: train.h:89
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
vehicle_cmd.h
CommandCost::GetCost
Money GetCost() const
The costs as made up to this moment.
Definition: command_type.h:83
DEFAULT_GROUP
static const GroupID DEFAULT_GROUP
Ungrouped vehicles are in this group.
Definition: group_type.h:17
Vehicle::previous_shared
Vehicle * previous_shared
NOSAVE: pointer to the previous vehicle in the shared order chain.
Definition: vehicle_base.h:249
DeleteDepotHighlightOfVehicle
void DeleteDepotHighlightOfVehicle(const Vehicle *v)
Removes the highlight of a vehicle in a depot window.
Definition: depot_gui.cpp:1161
WC_SHIPS_LIST
@ WC_SHIPS_LIST
Ships list; Window numbers:
Definition: window_type.h:320
DIR_S
@ DIR_S
South.
Definition: direction_type.h:30
AirportFTA::block
uint64_t block
64 bit blocks (st->airport.flags), should be enough for the most complex airports
Definition: airport.h:192
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:3097
Vehicle::profit_this_year
Money profit_this_year
Profit this year << 8, low 8 bits are fract.
Definition: vehicle_base.h:269
Vehicle::PlayLeaveStationSound
virtual void PlayLeaveStationSound([[maybe_unused]] bool force=false) const
Play the sound associated with leaving the station.
Definition: vehicle_base.h:468
ODTFB_PART_OF_ORDERS
@ ODTFB_PART_OF_ORDERS
This depot order is because of a regular order.
Definition: order_type.h:96
Vehicle::y_bb_offs
int8_t y_bb_offs
y offset of vehicle bounding box
Definition: vehicle_base.h:316
_networking
bool _networking
are we in networking mode?
Definition: network.cpp:65
VehicleSettings::smoke_amount
uint8_t smoke_amount
amount of smoke/sparks locomotives produce
Definition: settings_type.h:516
StartSpriteCombine
void StartSpriteCombine()
Starts a block of sprites, which are "combined" into a single bounding box.
Definition: viewport.cpp:769
VRF_REVERSE_DIRECTION
@ VRF_REVERSE_DIRECTION
Reverse the visible direction of the vehicle.
Definition: train.h:28
INVALID_DIAGDIR
@ INVALID_DIAGDIR
Flag for an invalid DiagDirection.
Definition: direction_type.h:80
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:1003
Vehicle::MarkAllViewportsDirty
bool MarkAllViewportsDirty() const
Marks viewports dirty where the vehicle's image is.
Definition: vehicle.cpp:1767
RoadVehicle::compatible_roadtypes
RoadTypes compatible_roadtypes
Roadtypes this consist is powered on.
Definition: roadveh.h:117
VehicleCargoList::KeepAll
void KeepAll()
Marks all cargo in the vehicle as to be kept.
Definition: cargopacket.h:488
Vehicle::OnNewEconomyDay
virtual void OnNewEconomyDay()
Calls the new economy day handler of the vehicle.
Definition: vehicle_base.h:578
SRT_TRAIN_DEPARTS
@ SRT_TRAIN_DEPARTS
Trigger platform when train leaves.
Definition: newgrf_station.h:106
VehicleCache::cached_vis_effect
byte cached_vis_effect
Visual effect to show (see VisualEffect)
Definition: vehicle_base.h:127
CargoID
byte CargoID
Cargo slots to indicate a cargo type within a game.
Definition: cargo_type.h:22
Point
Coordinates of a point in 2D.
Definition: geometry_type.hpp:21
IsDepotTile
bool IsDepotTile(Tile tile)
Is the given tile a tile with a depot on it?
Definition: depot_map.h:41
error.h
DirDiff
DirDiff
Allow incrementing of Direction variables.
Definition: direction_type.h:58
WC_TRAINS_LIST
@ WC_TRAINS_LIST
Trains list; Window numbers:
Definition: window_type.h:308
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:2423
PFE_GL_AIRCRAFT
@ PFE_GL_AIRCRAFT
Time spent processing aircraft.
Definition: framerate_type.h:54
FACIL_DOCK
@ FACIL_DOCK
Station with a dock.
Definition: station_type.h:56
newgrf_roadstop.h
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:638
Vehicle::HasDepotOrder
bool HasDepotOrder() const
Checks if a vehicle has a depot in its order list.
Definition: order_cmd.cpp:1859
Vehicle::cargo_age_counter
uint16_t cargo_age_counter
Ticks till cargo is aged next.
Definition: vehicle_base.h:342
GUISettings::show_track_reservation
bool show_track_reservation
highlight reserved tracks.
Definition: settings_type.h:185
stdafx.h
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
ShowCostOrIncomeAnimation
void ShowCostOrIncomeAnimation(int x, int y, int z, Money cost)
Display animated income or costs on the map.
Definition: misc_gui.cpp:568
Vehicle::SendToDepot
CommandCost SendToDepot(DoCommandFlag flags, DepotCommand command)
Send this vehicle to the depot using the given command(s).
Definition: vehicle.cpp:2576
Vehicle::sprite_cache
MutableSpriteCache sprite_cache
Cache of sprites and values related to recalculating them, see MutableSpriteCache.
Definition: vehicle_base.h:364
VehicleType
VehicleType
Available vehicle types.
Definition: vehicle_type.h:21
RoadStop::Leave
void Leave(RoadVehicle *rv)
Leave the road stop.
Definition: roadstop.cpp:216
Vehicle::IsOrderListShared
bool IsOrderListShared() const
Check if we share our orders with another vehicle.
Definition: vehicle_base.h:728
GroupStatistics::num_vehicle
uint16_t num_vehicle
Number of vehicles.
Definition: group.h:28
Engine::reliability
uint16_t reliability
Current reliability of the engine.
Definition: engine_base.h:41
VE_TYPE_DEFAULT
@ VE_TYPE_DEFAULT
Use default from engine class.
Definition: vehicle_base.h:86
EngineInfo::misc_flags
byte misc_flags
Miscellaneous flags.
Definition: engine_type.h:155
viewport_func.h
Vehicle::colourmap
SpriteID colourmap
NOSAVE: cached colour mapping.
Definition: vehicle_base.h:284
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
CanBuildVehicleInfrastructure
bool CanBuildVehicleInfrastructure(VehicleType type, byte subtype)
Check whether we can build infrastructure for the given vehicle type.
Definition: vehicle.cpp:1915
bridge_map.h
VESM_DIESEL
@ VESM_DIESEL
Diesel model.
Definition: vehicle_base.h:102
RAILVEH_WAGON
@ RAILVEH_WAGON
simple wagon, not motorized
Definition: engine_type.h:29
BaseConsist::ResetDepotUnbunching
void ResetDepotUnbunching()
Resets all the data used for depot unbunching.
Definition: base_consist.cpp:49
ODATFB_HALT
@ ODATFB_HALT
Service the vehicle and then halt it.
Definition: order_type.h:104
WC_VEHICLE_REFIT
@ WC_VEHICLE_REFIT
Vehicle refit; Window numbers:
Definition: window_type.h:206
Chance16I
bool Chance16I(const uint a, const uint b, const uint32_t r)
Checks if a given randomize-number is below a given probability.
Definition: random_func.hpp:112
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:882
Vehicle::z_pos
int32_t z_pos
z coordinate.
Definition: vehicle_base.h:302
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:673
GRFFilePropsBase::local_id
uint16_t local_id
id defined by the grf file for this entity
Definition: newgrf_commons.h:318
DifficultySettings::vehicle_breakdowns
byte vehicle_breakdowns
likelihood of vehicles breaking down
Definition: settings_type.h:107
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:3914
Vehicle::direction
Direction direction
facing
Definition: vehicle_base.h:303
TRACK_BIT_DEPOT
@ TRACK_BIT_DEPOT
Bitflag for a depot.
Definition: track_type.h:53
MarkAllViewportsDirty
bool MarkAllViewportsDirty(int left, int top, int right, int bottom)
Mark all viewports that display an area as dirty (in need of repaint).
Definition: viewport.cpp:2016
VehicleEnteredDepotThisTick
void VehicleEnteredDepotThisTick(Vehicle *v)
Adds a vehicle to the list of vehicles that visited a depot this tick.
Definition: vehicle.cpp:919
BaseConsist::cur_real_order_index
VehicleOrderID cur_real_order_index
The index to the current real (non-implicit) order.
Definition: base_consist.h:31
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
Vehicle::next_shared
Vehicle * next_shared
pointer to the next vehicle that shares the order
Definition: vehicle_base.h:248
spritecache.h
Vehicle::FirstShared
Vehicle * FirstShared() const
Get the first vehicle of this vehicle chain.
Definition: vehicle_base.h:722
Vehicle::x_extent
byte x_extent
x-extent of vehicle bounding box
Definition: vehicle_base.h:312
CALLBACK_FAILED
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
Definition: newgrf_callbacks.h:420
ROADSTOP_BUS
@ ROADSTOP_BUS
A standard stop for buses.
Definition: station_type.h:44
TimerGameTick::Ticks
int32_t Ticks
The type to store ticks in.
Definition: timer_game_tick.h:24
Vehicle::vcache
VehicleCache vcache
Cache of often used vehicle values.
Definition: vehicle_base.h:362
Ship
All ships have this type.
Definition: ship.h:24
PALETTE_RECOLOUR_START
static const PaletteID PALETTE_RECOLOUR_START
First recolour sprite for company colours.
Definition: sprites.h:1571
TransparencyOption
TransparencyOption
Transparency option bits: which position in _transparency_opt stands for which transparency.
Definition: transparency.h:22
LoadUnloadStation
void LoadUnloadStation(Station *st)
Load/unload the vehicles in this station according to the order they entered.
Definition: economy.cpp:1949
_current_company
CompanyID _current_company
Company currently doing an action.
Definition: company_cmd.cpp:51
vehicle_func.h
station_base.h
newgrf_sound.h
VESM_NONE
@ VESM_NONE
No visual effect.
Definition: vehicle_base.h:100
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:193
VEHICLE_LENGTH
static const uint VEHICLE_LENGTH
The length of a vehicle in tile units.
Definition: vehicle_type.h:76
DeleteGroupHighlightOfVehicle
void DeleteGroupHighlightOfVehicle(const Vehicle *v)
Removes the highlight of a vehicle in a group window.
Definition: group_gui.cpp:1201
PALETTE_CRASH
static const PaletteID PALETTE_CRASH
Recolour sprite greying of crashed vehicles.
Definition: sprites.h:1602
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
strings_func.h
Vehicle::hash_viewport_next
Vehicle * hash_viewport_next
NOSAVE: Next vehicle in the visual location hash.
Definition: vehicle_base.h:277
Pool
Base class for all pools.
Definition: pool_type.hpp:80
Vehicle::First
Vehicle * First() const
Get the first vehicle of this vehicle chain.
Definition: vehicle_base.h:641
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:508
Vehicle::max_age
TimerGameCalendar::Date max_age
Maximum age.
Definition: vehicle_base.h:290
Vehicle::tick_counter
byte tick_counter
Increased by one for each tick.
Definition: vehicle_base.h:346
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
EnsureNoTrainOnTrackBits
CommandCost EnsureNoTrainOnTrackBits(TileIndex tile, TrackBits track_bits)
Tests if a vehicle interacts with the specified track bits.
Definition: vehicle.cpp:608
PFE_GL_ECONOMY
@ PFE_GL_ECONOMY
Time spent processing cargo movement.
Definition: framerate_type.h:50
VehicleSettings::max_trains
UnitID max_trains
max trains in game per company
Definition: settings_type.h:523
refresh.h
Vehicle::IncrementImplicitOrderIndex
void IncrementImplicitOrderIndex()
Increments cur_implicit_order_index, keeps care of the wrap-around and invalidates the GUI.
Definition: vehicle_base.h:858
CBM_VEHICLE_VISUAL_EFFECT
@ CBM_VEHICLE_VISUAL_EFFECT
Visual effects and wagon power (trains, road vehicles and ships)
Definition: newgrf_callbacks.h:295
Backup::Restore
void Restore()
Restore the variable.
Definition: backup_type.hpp:112
GroupStatistics::UpdateProfits
static void UpdateProfits()
Recompute the profits for all groups.
Definition: group_cmd.cpp:194
FACIL_TRAIN
@ FACIL_TRAIN
Station with train station.
Definition: station_type.h:52
Vehicle::GetFirstOrder
Order * GetFirstOrder() const
Get the first order of the vehicles order list.
Definition: vehicle_base.h:701
Vehicle::x_offs
int8_t x_offs
x offset for vehicle sprite
Definition: vehicle_base.h:317
SpecializedVehicle< Train, Type >::From
static Train * From(Vehicle *v)
Converts a Vehicle to SpecializedVehicle with type checking.
Definition: vehicle_base.h:1211
DIRDIFF_45RIGHT
@ DIRDIFF_45RIGHT
Angle of 45 degrees right.
Definition: direction_type.h:60
GetVehiclePalette
PaletteID GetVehiclePalette(const Vehicle *v)
Get the colour map for a vehicle.
Definition: vehicle.cpp:2145
abs
constexpr T abs(const T a)
Returns the absolute value of (scalar) variable.
Definition: math_func.hpp:23
Train::ConsistChanged
void ConsistChanged(ConsistChangeFlags allowed_changes)
Recalculates the cached stuff of a train.
Definition: train_cmd.cpp:111
Vehicle::z_extent
byte z_extent
z-extent of vehicle bounding box
Definition: vehicle_base.h:314
SetDepotReservation
void SetDepotReservation(Tile t, bool b)
Set the reservation state of the depot.
Definition: rail_map.h:270
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:292
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
GetStationIndex
StationID GetStationIndex(Tile t)
Get StationID from a tile.
Definition: station_map.h:28
Vehicle::economy_age
TimerGameEconomy::Date economy_age
Age in economy days.
Definition: vehicle_base.h:289
OUFB_NO_UNLOAD
@ OUFB_NO_UNLOAD
Totally no unloading will be done.
Definition: order_type.h:56
Vehicle::HasFullLoadOrder
bool HasFullLoadOrder() const
Check if the current vehicle has a full load order.
Definition: vehicle.cpp:2458
framerate_type.h
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:3221
EffectVehicleType
EffectVehicleType
Effect vehicle types.
Definition: effectvehicle_func.h:16
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:189
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:123
HasAtMostOneBit
constexpr bool HasAtMostOneBit(T value)
Test whether value has at most 1 bit set.
Definition: bitmath_func.hpp:271
Sprite::y_offs
int16_t y_offs
Number of pixels to shift the sprite downwards.
Definition: spritecache.h:21
OrderList
Shared order list linking together the linked list of orders and the list of vehicles sharing this or...
Definition: order_base.h:260
GroundVehicle::IsEngine
bool IsEngine() const
Check if a vehicle is an engine (can be first in a consist).
Definition: ground_vehicle.hpp:315
SAT_TRAIN_DEPARTS
@ SAT_TRAIN_DEPARTS
Trigger platform when train leaves.
Definition: newgrf_animation_type.h:31
Livery::colour1
Colours colour1
First colour, for all vehicles.
Definition: livery.h:80
Vehicle::cargo_payment
CargoPayment * cargo_payment
The cargo payment we're currently in.
Definition: vehicle_base.h:273
Pool::PoolItem<&_vehicle_pool >::CleaningPool
static bool CleaningPool()
Returns current state of pool cleaning - yes or no.
Definition: pool_type.hpp:318
GetEngineLiveryScheme
LiveryScheme GetEngineLiveryScheme(EngineID engine_type, EngineID parent_engine_type, const Vehicle *v)
Determines the LiveryScheme for a vehicle.
Definition: vehicle.cpp:1963
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:2051
Vehicle::reliability
uint16_t reliability
Reliability.
Definition: vehicle_base.h:293
Vehicle::NextShared
Vehicle * NextShared() const
Get the next vehicle of the shared vehicle chain.
Definition: vehicle_base.h:710
PM_PAUSED_NORMAL
@ PM_PAUSED_NORMAL
A game normally paused.
Definition: openttd.h:70
CargoList< VehicleCargoList, CargoPacketList >::MTA_LOAD
@ MTA_LOAD
Load the cargo from the station.
Definition: cargopacket.h:300
GetTileRailType
RailType GetTileRailType(Tile tile)
Return the rail type of tile, or INVALID_RAILTYPE if this is no rail tile.
Definition: rail.cpp:155
Ship::state
TrackBits state
The "track" the ship is following.
Definition: ship.h:25
GetNewVehiclePosResult
Position information of a vehicle after it moved.
Definition: vehicle_func.h:77
WC_VEHICLE_DEPOT
@ WC_VEHICLE_DEPOT
Depot view; Window numbers:
Definition: window_type.h:351
VE_DISABLE_WAGON_POWER
@ VE_DISABLE_WAGON_POWER
Flag to disable wagon power.
Definition: vehicle_base.h:93
MP_STATION
@ MP_STATION
A tile of a station.
Definition: tile_type.h:53
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:327
Vehicle::age
TimerGameCalendar::Date age
Age in calendar days.
Definition: vehicle_base.h:288
Vehicle::HasArticulatedPart
bool HasArticulatedPart() const
Check if an engine has an articulated part.
Definition: vehicle_base.h:959
Aircraft::previous_pos
byte previous_pos
Previous desired position of the aircraft.
Definition: aircraft.h:77
FindVehicleOnPos
void FindVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
Find a vehicle from a specific location.
Definition: vehicle.cpp:505
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
FreeUnitIDGenerator::NextID
UnitID NextID() const
Find first unused unit number.
Definition: vehicle.cpp:1841
UsesWagonOverride
bool UsesWagonOverride(const Vehicle *v)
Check if a wagon is currently using a wagon override.
Definition: newgrf_engine.cpp:1134
RunEconomyVehicleDayProc
static void RunEconomyVehicleDayProc()
Increases the day counter for all vehicles and calls 1-day and 32-day handlers.
Definition: vehicle.cpp:952
Vehicle::profit_last_year
Money profit_last_year
Profit last year << 8, low 8 bits are fract.
Definition: vehicle_base.h:270
Vehicle::breakdown_chance
byte breakdown_chance
Current chance of breakdowns.
Definition: vehicle_base.h:298
EV_DIESEL_SMOKE
@ EV_DIESEL_SMOKE
Smoke of diesel engines.
Definition: effectvehicle_func.h:19
linkgraph.h
Order::SetDepotOrderType
void SetDepotOrderType(OrderDepotTypeFlags depot_order_type)
Set the cause to go to the depot.
Definition: order_base.h:166
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:352
IsBridgeAbove
bool IsBridgeAbove(Tile t)
checks if a bridge is set above the ground of this tile
Definition: bridge_map.h:45
DepotCommand::DontCancel
@ DontCancel
Don't cancel current goto depot command if any.
DIRDIFF_90RIGHT
@ DIRDIFF_90RIGHT
Angle of 90 degrees right.
Definition: direction_type.h:61
Vehicle::unitnumber
UnitID unitnumber
unit number, for display purposes only
Definition: vehicle_base.h:322
ClosestDepot::destination
DestinationID destination
The DestinationID as used for orders.
Definition: vehicle_base.h:228
depot_map.h
container_func.hpp
EffectVehicle
A special vehicle is one of the following:
Definition: effectvehicle_base.h:24
MAX_VEH_ORDER_ID
static const VehicleOrderID MAX_VEH_ORDER_ID
Last valid VehicleOrderID.
Definition: order_type.h:23
Vehicle::HasUnbunchingOrder
bool HasUnbunchingOrder() const
Check if the current vehicle has an unbunching order.
Definition: vehicle.cpp:2482
Order::SetDepotActionType
void SetDepotActionType(OrderDepotActionFlags depot_service_type)
Set what we are going to do in the depot.
Definition: order_base.h:168
company_func.h
VehicleSettings::max_roadveh
UnitID max_roadveh
max trucks in game per company
Definition: settings_type.h:524
GetNewVehiclePosResult::old_tile
TileIndex old_tile
Current tile of the vehicle.
Definition: vehicle_func.h:79
VE_ADVANCED_EFFECT
@ VE_ADVANCED_EFFECT
Flag for advanced effects.
Definition: vehicle_base.h:92
EXPENSES_NEW_VEHICLES
@ EXPENSES_NEW_VEHICLES
New vehicles.
Definition: economy_type.h:174
Vehicle::hash_viewport_prev
Vehicle ** hash_viewport_prev
NOSAVE: Previous vehicle in the visual location hash.
Definition: vehicle_base.h:278
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
Vehicle::y_pos
int32_t y_pos
y coordinate.
Definition: vehicle_base.h:301
ClosestDepot
Structure to return information about the closest depot location, and whether it could be found.
Definition: vehicle_base.h:226
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:187
VEH_DISASTER
@ VEH_DISASTER
Disaster vehicle type.
Definition: vehicle_type.h:32
Vehicle::breakdown_delay
byte breakdown_delay
Counter for managing breakdown length.
Definition: vehicle_base.h:296
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:2233
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:499
TriggerStationRandomisation
void TriggerStationRandomisation(Station *st, TileIndex trigger_tile, StationRandomTrigger trigger, CargoID cargo_type)
Trigger station randomisation.
Definition: newgrf_station.cpp:923
Vehicle::GetDisplayMaxWeight
uint32_t GetDisplayMaxWeight() const
Calculates the maximum weight of the ground vehicle when loaded.
Definition: vehicle.cpp:3237
InvalidateAutoreplaceWindow
void InvalidateAutoreplaceWindow(EngineID e, GroupID id_g)
Rebuild the left autoreplace list if an engine is removed or added.
Definition: autoreplace_gui.cpp:52
Vehicle::coord
Rect coord
NOSAVE: Graphical bounding box of the vehicle, i.e. what to redraw on moves.
Definition: vehicle_base.h:275
GroundVehicleCache::cached_power
uint32_t cached_power
Total power of the consist (valid only for the first engine).
Definition: ground_vehicle.hpp:38
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
Order::GetDepotOrderType
OrderDepotTypeFlags GetDepotOrderType() const
What caused us going to the depot?
Definition: order_base.h:145
Aircraft::pos
byte pos
Next desired position of the aircraft.
Definition: aircraft.h:76
network.h
AIR_CTOL
@ AIR_CTOL
Conventional Take Off and Landing, i.e. planes.
Definition: engine_type.h:95
TrackBits
TrackBits
Allow incrementing of Track variables.
Definition: track_type.h:35
Vehicle::subtype
byte subtype
subtype (Filled with values from AircraftSubType/DisasterSubType/EffectVehicleType/GroundVehicleSubty...
Definition: vehicle_base.h:359
GetRoadStopType
RoadStopType GetRoadStopType(Tile t)
Get the road stop type of this tile.
Definition: station_map.h:56
CommandHelper
Definition: command_func.h:93
Vehicle::day_counter
byte day_counter
Increased by one for each day.
Definition: vehicle_base.h:345
VS_UNCLICKABLE
@ VS_UNCLICKABLE
Vehicle is not clickable by the user (shadow vehicles).
Definition: vehicle_base.h:35
FindVehicleOnPosXY
void FindVehicleOnPosXY(int x, int y, void *data, VehicleFromPosProc *proc)
Find a vehicle from a specific location.
Definition: vehicle.cpp:445
OrderList::AddVehicle
void AddVehicle([[maybe_unused]] Vehicle *v)
Adds the given vehicle to this shared order list.
Definition: order_base.h:359
HasVehicleOnPosXY
bool HasVehicleOnPosXY(int x, int y, void *data, VehicleFromPosProc *proc)
Checks whether a vehicle in on a specific location.
Definition: vehicle.cpp:461
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
Viewport::zoom
ZoomLevel zoom
The zoom level of the viewport.
Definition: viewport_type.h:33
random_func.hpp
Vehicle::HasConditionalOrder
bool HasConditionalOrder() const
Check if the current vehicle has a conditional order.
Definition: vehicle.cpp:2470
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
VF_PATHFINDER_LOST
@ VF_PATHFINDER_LOST
Vehicle's pathfinder is lost.
Definition: vehicle_base.h:52
GetTileMaxPixelZ
int GetTileMaxPixelZ(TileIndex tile)
Get top height of the tile.
Definition: tile_map.h:304
Vehicle::ReleaseUnitNumber
void ReleaseUnitNumber()
Release the vehicle's unit number.
Definition: vehicle.cpp:2412
AgeVehicle
void AgeVehicle(Vehicle *v)
Update age of a vehicle.
Definition: vehicle.cpp:1437
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:268
GetCargoTypesOfArticulatedParts
CargoTypes GetCargoTypesOfArticulatedParts(EngineID engine)
Get the cargo mask of the parts of a given engine.
Definition: articulated_vehicles.cpp:170
OverflowSafeInt< int64_t >
_vehicle_pool
VehiclePool _vehicle_pool("Vehicle")
The pool with all our precious vehicles.
Vehicle::IsStoppedInDepot
bool IsStoppedInDepot() const
Check whether the vehicle is in the depot and stopped.
Definition: vehicle_base.h:556
VehicleCargoList::ActionCount
uint ActionCount(MoveToAction action) const
Returns the amount of cargo designated for a given purpose.
Definition: cargopacket.h:424
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
Vehicle::previous
Vehicle * previous
NOSAVE: pointer to the previous vehicle in the chain.
Definition: vehicle_base.h:245
RoadVehicle::IsBus
bool IsBus() const
Check whether a roadvehicle is a bus.
Definition: roadveh_cmd.cpp:83
OrderList::GetNumVehicles
uint GetNumVehicles() const
Return the number of vehicles that share this orders list.
Definition: order_base.h:351
Vehicle::cargo_type
CargoID cargo_type
type of cargo this vehicle is carrying
Definition: vehicle_base.h:337
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:327
TileVirtXY
static debug_inline TileIndex TileVirtXY(uint x, uint y)
Get a tile from the virtual XY-coordinate.
Definition: map_func.h:416
IsValidCargoID
bool IsValidCargoID(CargoID t)
Test whether cargo type is not INVALID_CARGO.
Definition: cargo_type.h:107
ODATF_SERVICE_ONLY
@ ODATF_SERVICE_ONLY
Only service the vehicle.
Definition: order_type.h:103
Engine::grf_prop
GRFFilePropsBase< NUM_CARGO+2 > grf_prop
Properties related the the grf file.
Definition: engine_base.h:77
EnsureNoVehicleProcZ
static Vehicle * EnsureNoVehicleProcZ(Vehicle *v, void *data)
Callback that returns 'real' vehicles lower or at height *(int*)data .
Definition: vehicle.cpp:531
VSE_RUNNING
@ VSE_RUNNING
Vehicle running normally.
Definition: newgrf_sound.h:22
Train::GetNextUnit
Train * GetNextUnit() const
Get the next real (non-articulated part and non rear part of dualheaded engine) vehicle in the consis...
Definition: train.h:149
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
EF_ROAD_TRAM
@ EF_ROAD_TRAM
Road vehicle is a tram/light rail vehicle.
Definition: engine_type.h:169
Vehicle::OnNewCalendarDay
virtual void OnNewCalendarDay()
Calls the new calendar day handler of the vehicle.
Definition: vehicle_base.h:573
PalSpriteID::pal
PaletteID pal
The palette (use PAL_NONE) if not needed)
Definition: gfx_type.h:24
TimerGameCalendar::date
static Date date
Current date in days (day counter).
Definition: timer_game_calendar.h:34
Aircraft::state
byte state
State of the airport.
Definition: aircraft.h:79
Vehicle::GetGroundVehicleFlags
uint16_t & GetGroundVehicleFlags()
Access the ground vehicle flags of the vehicle.
Definition: vehicle.cpp:3178
articulated_vehicles.h
GameSettings::vehicle
VehicleSettings vehicle
options for vehicles
Definition: settings_type.h:626
EngineID
uint16_t EngineID
Unique identification number of an engine.
Definition: engine_type.h:21
CalcPercentVehicleFilled
uint8_t CalcPercentVehicleFilled(const Vehicle *front, StringID *colour)
Calculates how full a vehicle is.
Definition: vehicle.cpp:1486
TFP_NONE
@ TFP_NONE
Normal operation.
Definition: train.h:38
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
CBM_VEHICLE_COLOUR_REMAP
@ CBM_VEHICLE_COLOUR_REMAP
Change colour mapping of vehicle.
Definition: newgrf_callbacks.h:301
IsTileType
static debug_inline bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
Definition: tile_map.h:150
VEH_TRAIN
@ VEH_TRAIN
Train vehicle type.
Definition: vehicle_type.h:24
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:214
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
RoadStop
A Stop for a Road Vehicle.
Definition: roadstop_base.h:22
Vehicle::GetOrder
Order * GetOrder(int index) const
Returns order 'index' of a vehicle or nullptr when it doesn't exists.
Definition: vehicle_base.h:918
BaseVehicle::type
VehicleType type
Type of vehicle.
Definition: vehicle_type.h:51
SubtractMoneyFromCompany
void SubtractMoneyFromCompany(const CommandCost &cost)
Subtract money from the _current_company, if the company is valid.
Definition: company_cmd.cpp:287
AirportFTAClass::HELICOPTERS
@ HELICOPTERS
Can helicopters land on this airport type?
Definition: airport.h:148
ReleaseDisasterVehicle
void ReleaseDisasterVehicle(VehicleID vehicle)
Notify disasters that we are about to delete a vehicle.
Definition: disaster_vehicle.cpp:980
Clamp
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition: math_func.hpp:79
Vehicle::Tick
virtual bool Tick()
Calls the tick handler of the vehicle.
Definition: vehicle_base.h:568
Vehicle::UpdatePositionAndViewport
void UpdatePositionAndViewport()
Update the position of the vehicle, and update the viewport.
Definition: vehicle.cpp:1757
GRFFilePropsBase::grffile
const struct GRFFile * grffile
grf file that introduced this entity
Definition: newgrf_commons.h:319
FACIL_AIRPORT
@ FACIL_AIRPORT
Station with an airport.
Definition: station_type.h:55
TileX
static debug_inline uint TileX(TileIndex tile)
Get the X component of a tile.
Definition: map_func.h:427
VIWD_MODIFY_ORDERS
@ VIWD_MODIFY_ORDERS
Other order modifications.
Definition: vehicle_gui.h:36
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
Vehicle::UpdatePosition
void UpdatePosition()
Update the position of the vehicle.
Definition: vehicle.cpp:1686
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
autoreplace_func.h
Vehicle::hash_tile_prev
Vehicle ** hash_tile_prev
NOSAVE: Previous vehicle in the tile location hash.
Definition: vehicle_base.h:281
CanVehicleUseStation
bool CanVehicleUseStation(EngineID engine_type, const Station *st)
Can this station be used by the given engine type?
Definition: vehicle.cpp:3051
pool_func.hpp
Vehicle::HandleBreakdown
bool HandleBreakdown()
Handle all of the aspects of a vehicle breakdown This includes adding smoke and sounds,...
Definition: vehicle.cpp:1359
DecreaseVehicleValue
void DecreaseVehicleValue(Vehicle *v)
Decrease the value of a vehicle.
Definition: vehicle.cpp:1297
GetNewVehiclePosResult::y
int y
x and y position of the vehicle after moving
Definition: vehicle_func.h:78
IsRoadStopTile
bool IsRoadStopTile(Tile t)
Is tile t a road stop station?
Definition: station_map.h:213
order_backup.h
EconomyAgeVehicle
void EconomyAgeVehicle(Vehicle *v)
Update economy age of a vehicle.
Definition: vehicle.cpp:1425
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:1149
HasTileAnyRoadType
bool HasTileAnyRoadType(Tile t, RoadTypes rts)
Check if a tile has one of the specified road types.
Definition: road_map.h:222
GUISettings::liveries
byte liveries
options for displaying company liveries, 0=none, 1=self, 2=all
Definition: settings_type.h:148
Order::CanLeaveWithCargo
bool CanLeaveWithCargo(bool has_cargo) const
A vehicle can leave the current station with cargo if:
Definition: order_cmd.cpp:2257
VEH_SHIP
@ VEH_SHIP
Ship vehicle type.
Definition: vehicle_type.h:26
VESM_ELECTRIC
@ VESM_ELECTRIC
Electric model.
Definition: vehicle_base.h:103
IsCargoInClass
bool IsCargoInClass(CargoID c, CargoClass cc)
Does cargo c have cargo class cc?
Definition: cargotype.h:230
Rect
Specification of a rectangle with absolute coordinates of all edges.
Definition: geometry_type.hpp:75
PM_PAUSED_ERROR
@ PM_PAUSED_ERROR
A game paused because a (critical) error.
Definition: openttd.h:73
Company
Definition: company_base.h:129
IsLocalCompany
bool IsLocalCompany()
Is the current company the local company?
Definition: company_func.h:47
ScaleByZoom
int ScaleByZoom(int value, ZoomLevel zoom)
Scale by zoom level, usually shift left (when zoom > ZOOM_LVL_NORMAL) When shifting right,...
Definition: zoom_func.h:22
VSE_STOPPED_16
@ VSE_STOPPED_16
Every 16 ticks while the vehicle is stopped (speed == 0).
Definition: newgrf_sound.h:26
AirportFTAClass::AIRPLANES
@ AIRPLANES
Can planes land on this airport type?
Definition: airport.h:147
DepotCommand::None
@ None
No special flags.
Vehicle::GetNumOrders
VehicleOrderID GetNumOrders() const
Get the number of orders this vehicle has.
Definition: vehicle_base.h:734
GroundVehicleCache::cached_veh_length
uint8_t cached_veh_length
Length of this vehicle in units of 1/VEHICLE_LENGTH of normal length. It is cached because this can b...
Definition: ground_vehicle.hpp:44
Livery::colour2
Colours colour2
Second colour, for vehicles with 2CC support.
Definition: livery.h:81
InvalidateVehicleOrder
void InvalidateVehicleOrder(const Vehicle *v, int data)
Updates the widgets of a vehicle which contains the order-data.
Definition: order_cmd.cpp:251
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:104
ClrBit
constexpr T ClrBit(T &x, const uint8_t y)
Clears a bit in a variable.
Definition: bitmath_func.hpp:151
Vehicle::orders
OrderList * orders
Pointer to the order list for this vehicle.
Definition: vehicle_base.h:353
SetWindowClassesDirty
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting)
Definition: window.cpp:3112
VehicleSpriteSeq::GetBounds
void GetBounds(Rect *bounds) const
Determine shared bounds of all sprites.
Definition: vehicle.cpp:103
Order::GetDepotActionType
OrderDepotActionFlags GetDepotActionType() const
What are we going to do when in the depot.
Definition: order_base.h:147
WC_AIRCRAFT_LIST
@ WC_AIRCRAFT_LIST
Aircraft list; Window numbers:
Definition: window_type.h:326
Vehicle::hash_tile_next
Vehicle * hash_tile_next
NOSAVE: Next vehicle in the tile location hash.
Definition: vehicle_base.h:280
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:3099
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
Sprite
Data structure describing a sprite.
Definition: spritecache.h:17
CLRBITS
#define CLRBITS(x, y)
Clears several bits in a variable.
Definition: bitmath_func.hpp:166
Vehicle::DeleteUnreachedImplicitOrders
void DeleteUnreachedImplicitOrders()
Delete all implicit orders which were not reached.
Definition: vehicle.cpp:2157
Vehicle::first
Vehicle * first
NOSAVE: pointer to the first vehicle in the chain.
Definition: vehicle_base.h:246
GBUG_VEH_LENGTH
@ GBUG_VEH_LENGTH
Length of rail vehicle changes when not inside a depot.
Definition: newgrf_config.h:44
Order::next
Order * next
Pointer to next order. If nullptr, end of list.
Definition: order_base.h:59
SpecializedVehicle::UpdateViewport
void UpdateViewport(bool force_update, bool update_delta)
Update vehicle sprite- and position caches.
Definition: vehicle_base.h:1233
Vehicle::fill_percent_te_id
TextEffectID fill_percent_te_id
a text-effect id to a loading indicator object
Definition: vehicle_base.h:321
Order
Definition: order_base.h:36
VS_SHADOW
@ VS_SHADOW
Vehicle is a shadow vehicle.
Definition: vehicle_base.h:38
Livery
Information about a particular livery.
Definition: livery.h:78
Vehicle::LeaveUnbunchingDepot
void LeaveUnbunchingDepot()
Leave an unbunching depot and calculate the next departure time for shared order vehicles.
Definition: vehicle.cpp:2507
EffectVehicle::GetTransparencyOption
TransparencyOption GetTransparencyOption() const
Determines the transparency option affecting the effect.
Definition: effectvehicle.cpp:661
MutableSpriteCache::old_coord
Rect old_coord
Co-ordinates from the last valid bounding box.
Definition: vehicle_base.h:194
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
OrderList::GetNumOrders
VehicleOrderID GetNumOrders() const
Get number of orders in the order list.
Definition: order_base.h:320
ViewportAddVehicles
void ViewportAddVehicles(DrawPixelInfo *dpi)
Add the vehicle sprites that should be drawn at a part of the screen.
Definition: vehicle.cpp:1150
Order::Equals
bool Equals(const Order &other) const
Does this order have the same type, flags and destination?
Definition: order_cmd.cpp:175
VE_OFFSET_CENTRE
@ VE_OFFSET_CENTRE
Value of offset corresponding to a position above the centre of the vehicle.
Definition: vehicle_base.h:82
Vehicle::ShiftDates
void ShiftDates(TimerGameEconomy::Date interval)
Shift all dates by given interval.
Definition: vehicle.cpp:777
ToggleBit
constexpr T ToggleBit(T &x, const uint8_t y)
Toggles a bit in a variable.
Definition: bitmath_func.hpp:181
Order::SetNonStopType
void SetNonStopType(OrderNonStopFlags non_stop_type)
Set whether we must stop at stations or not.
Definition: order_base.h:162
VehicleEnterTileStatus
VehicleEnterTileStatus
The returned bits of VehicleEnterTile.
Definition: tile_cmd.h:21
Order::MakeImplicit
void MakeImplicit(StationID destination)
Makes this order an implicit order.
Definition: order_cmd.cpp:154
SpecializedVehicle::GetFirstEnginePart
T * GetFirstEnginePart()
Get the first part of an articulated engine.
Definition: vehicle_base.h:1152
FLYING
@ FLYING
Vehicle is flying in the air.
Definition: airport.h:75
SpriteType::Normal
@ Normal
The most basic (normal) sprite.
VE_TYPE_STEAM
@ VE_TYPE_STEAM
Steam plumes.
Definition: vehicle_base.h:87
TunnelBridgeIsFree
CommandCost TunnelBridgeIsFree(TileIndex tile, TileIndex endtile, const Vehicle *ignore)
Finds vehicle in tunnel / bridge.
Definition: vehicle.cpp:575
timer_game_economy.h
EV_BREAKDOWN_SMOKE
@ EV_BREAKDOWN_SMOKE
Smoke of broken vehicles except aircraft.
Definition: effectvehicle_func.h:23
Vehicle::y_offs
int8_t y_offs
y offset for vehicle sprite
Definition: vehicle_base.h:318
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
Vehicle::MarkDirty
virtual void MarkDirty()
Marks the vehicles to be redrawn and updates cached variables.
Definition: vehicle_base.h:403
WC_VEHICLE_ORDERS
@ WC_VEHICLE_ORDERS
Vehicle orders; Window numbers:
Definition: window_type.h:212
GRFFile
Dynamic data of a loaded NewGRF.
Definition: newgrf.h:107
ClientSettings::gui
GUISettings gui
settings related to the GUI
Definition: settings_type.h:635
WL_CRITICAL
@ WL_CRITICAL
Critical errors, the MessageBox is shown in all cases.
Definition: error.h:27
Engine::type
VehicleType type
Vehicle type, ie VEH_ROAD, VEH_TRAIN, etc.
Definition: engine_base.h:56
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:82
SND_0F_BREAKDOWN_ROADVEHICLE
@ SND_0F_BREAKDOWN_ROADVEHICLE
13 == 0x0D Breakdown: road vehicle (non-toyland)
Definition: sound_type.h:52
GetWindowClassForVehicleType
WindowClass GetWindowClassForVehicleType(VehicleType vt)
Get WindowClass for vehicle list of given vehicle type.
Definition: vehicle_gui.h:97
Vehicle::refit_cap
uint16_t refit_cap
Capacity left over from before last refit.
Definition: vehicle_base.h:340
GroundVehicle::IsMultiheaded
bool IsMultiheaded() const
Check if the vehicle is a multiheaded engine.
Definition: ground_vehicle.hpp:327
OLFB_NO_LOAD
@ OLFB_NO_LOAD
Do not load anything.
Definition: order_type.h:66
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:1777
GRFConfig::GetName
const char * GetName() const
Get the name of this grf.
Definition: newgrf_config.cpp:98
DrawPixelInfo
Data about how and where to blit pixels.
Definition: gfx_type.h:151
Order::GetLoadType
OrderLoadFlags GetLoadType() const
How must the consist be loaded?
Definition: order_base.h:137
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:1831
news_func.h
EC_MONORAIL
@ EC_MONORAIL
Mono rail engine.
Definition: engine_type.h:37
VSE_RUNNING_16
@ VSE_RUNNING_16
Every 16 ticks while the vehicle is running (speed > 0).
Definition: newgrf_sound.h:25
roadveh.h
TileTypeProcs::vehicle_enter_tile_proc
VehicleEnterTileProc * vehicle_enter_tile_proc
Called when a vehicle enters a tile.
Definition: tile_cmd.h:170
backup_type.hpp
TimerGameEconomy::date
static Date date
Current date in days (day counter).
Definition: timer_game_economy.h:37
Vehicle::GetDisplayMinPowerToWeight
uint32_t GetDisplayMinPowerToWeight() const
Calculates the minimum power-to-weight ratio using the maximum weight of the ground vehicle.
Definition: vehicle.cpp:3252
FindFirstBit
constexpr uint8_t FindFirstBit(T x)
Search the first set bit in a value.
Definition: bitmath_func.hpp:194
HasBit
constexpr debug_inline bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
Definition: bitmath_func.hpp:103