OpenTTD Source: src/vehicle.cpp Source File

OpenTTD Source 12.2

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 "date_func.h"
29 #include "vehicle_func.h"
30 #include "autoreplace_func.h"
31 #include "autoreplace_gui.h"
32 #include "station_base.h"
33 #include "ai/ai.hpp"
34 #include "depot_func.h"
35 #include "network/network.h"
36 #include "core/pool_func.hpp"
37 #include "economy_base.h"
38 #include "articulated_vehicles.h"
39 #include "roadstop_base.h"
40 #include "core/random_func.hpp"
41 #include "core/backup_type.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
55 #include "table/strings.h"
56
57 #include "safeguards.h"
58
59 /* Number of bits in the hash to use from each vehicle coord */
60 static const uint GEN_HASHX_BITS = 6;
61 static const uint GEN_HASHY_BITS = 6;
62
63 /* Size of each hash bucket */
64 static const uint GEN_HASHX_BUCKET_BITS = 7;
65 static const uint GEN_HASHY_BUCKET_BITS = 6;
66
67 /* Compute hash for vehicle coord */
68 #define GEN_HASHX(x) GB((x), GEN_HASHX_BUCKET_BITS + ZOOM_LVL_SHIFT, GEN_HASHX_BITS)
69 #define GEN_HASHY(y) (GB((y), GEN_HASHY_BUCKET_BITS + ZOOM_LVL_SHIFT, GEN_HASHY_BITS) << GEN_HASHX_BITS)
70 #define GEN_HASH(x, y) (GEN_HASHY(y) + GEN_HASHX(x))
71
72 /* Maximum size until hash repeats */
73 static const int GEN_HASHX_SIZE = 1 << (GEN_HASHX_BUCKET_BITS + GEN_HASHX_BITS + ZOOM_LVL_SHIFT);
74 static const int GEN_HASHY_SIZE = 1 << (GEN_HASHY_BUCKET_BITS + GEN_HASHY_BITS + ZOOM_LVL_SHIFT);
75
76 /* Increments to reach next bucket in hash table */
77 static const int GEN_HASHX_INC = 1;
78 static const int GEN_HASHY_INC = 1 << GEN_HASHX_BITS;
79
80 /* Mask to wrap-around buckets */
81 static const uint GEN_HASHX_MASK = (1 << GEN_HASHX_BITS) - 1;
82 static const uint GEN_HASHY_MASK = ((1 << GEN_HASHY_BITS) - 1) << GEN_HASHX_BITS;
83
84 VehicleID _new_vehicle_id;
85 uint _returned_refit_capacity;
86 uint16 _returned_mail_refit_capacity;
87
88
90 VehiclePool _vehicle_pool("Vehicle");
91 INSTANTIATE_POOL_METHODS(Vehicle)
92
93
94
98 void VehicleSpriteSeq::GetBounds(Rect *bounds) const
99 {
100 bounds->left = bounds->top = bounds->right = bounds->bottom = 0;
101 for (uint i = 0; i < this->count; ++i) {
102 const Sprite *spr = GetSprite(this->seq[i].sprite, ST_NORMAL);
103 if (i == 0) {
104 bounds->left = spr->x_offs;
105 bounds->top = spr->y_offs;
106 bounds->right = spr->width + spr->x_offs - 1;
107 bounds->bottom = spr->height + spr->y_offs - 1;
108 } else {
109 if (spr->x_offs < bounds->left) bounds->left = spr->x_offs;
110 if (spr->y_offs < bounds->top) bounds->top = spr->y_offs;
111 int right = spr->width + spr->x_offs - 1;
112 int bottom = spr->height + spr->y_offs - 1;
113 if (right > bounds->right) bounds->right = right;
114 if (bottom > bounds->bottom) bounds->bottom = bottom;
115 }
116 }
117 }
118
126 void VehicleSpriteSeq::Draw(int x, int y, PaletteID default_pal, bool force_pal) const
127 {
128 for (uint i = 0; i < this->count; ++i) {
129 PaletteID pal = force_pal || !this->seq[i].pal ? default_pal : this->seq[i].pal;
130 DrawSprite(this->seq[i].sprite, pal, x, y);
131 }
132 }
133
140 bool Vehicle::NeedsAutorenewing(const Company *c, bool use_renew_setting) const
141 {
142 /* We can always generate the Company pointer when we have the vehicle.
143 * However this takes time and since the Company pointer is often present
144 * when this function is called then it's faster to pass the pointer as an
145 * argument rather than finding it again. */
146 assert(c == Company::Get(this->owner));
147
148 if (use_renew_setting && !c->settings.engine_renew) return false;
149 if (this->age - this->max_age < (c->settings.engine_renew_months * 30)) return false;
150
151 /* Only engines need renewing */
152 if (this->type == VEH_TRAIN && !Train::From(this)->IsEngine()) return false;
153
154 return true;
155 }
156
162 void VehicleServiceInDepot(Vehicle *v)
163 {
164 assert(v != nullptr);
165 SetWindowDirty(WC_VEHICLE_DETAILS, v->index); // ensure that last service date and reliability are updated
166
167 do {
168 v->date_of_last_service = _date;
169 v->breakdowns_since_last_service = 0;
170 v->reliability = v->GetEngine()->reliability;
171 /* Prevent vehicles from breaking down directly after exiting the depot. */
172 v->breakdown_chance /= 4;
173 if (_settings_game.difficulty.vehicle_breakdowns == 1) v->breakdown_chance = 0; // on reduced breakdown
174 v = v->Next();
175 } while (v != nullptr && v->HasEngineType());
176 }
177
184 bool Vehicle::NeedsServicing() const
185 {
186 /* Stopped or crashed vehicles will not move, as such making unmovable
187 * vehicles to go for service is lame. */
188 if (this->vehstatus & (VS_STOPPED | VS_CRASHED)) return false;
189
190 /* Are we ready for the next service cycle? */
191 const Company *c = Company::Get(this->owner);
192 if (this->ServiceIntervalIsPercent() ?
193 (this->reliability >= this->GetEngine()->reliability * (100 - this->GetServiceInterval()) / 100) :
194 (this->date_of_last_service + this->GetServiceInterval() >= _date)) {
195 return false;
196 }
197
198 /* If we're servicing anyway, because we have not disabled servicing when
199 * there are no breakdowns or we are playing with breakdowns, bail out. */
200 if (!_settings_game.order.no_servicing_if_no_breakdowns ||
201 _settings_game.difficulty.vehicle_breakdowns != 0) {
202 return true;
203 }
204
205 /* Test whether there is some pending autoreplace.
206 * Note: We do this after the service-interval test.
207 * There are a lot more reasons for autoreplace to fail than we can test here reasonably. */
208 bool pending_replace = false;
209 Money needed_money = c->settings.engine_renew_money;
210 if (needed_money > c->money) return false;
211
212 for (const Vehicle *v = this; v != nullptr; v = (v->type == VEH_TRAIN) ? Train::From(v)->GetNextUnit() : nullptr) {
213 bool replace_when_old = false;
214 EngineID new_engine = EngineReplacementForCompany(c, v->engine_type, v->group_id, &replace_when_old);
215
216 /* Check engine availability */
217 if (new_engine == INVALID_ENGINE || !HasBit(Engine::Get(new_engine)->company_avail, v->owner)) continue;
218 /* Is the vehicle old if we are not always replacing? */
219 if (replace_when_old && !v->NeedsAutorenewing(c, false)) continue;
220
221 /* Check refittability */
222 CargoTypes available_cargo_types, union_mask;
223 GetArticulatedRefitMasks(new_engine, true, &union_mask, &available_cargo_types);
224 /* Is there anything to refit? */
225 if (union_mask != 0) {
226 CargoID cargo_type;
227 /* We cannot refit to mixed cargoes in an automated way */
228 if (IsArticulatedVehicleCarryingDifferentCargoes(v, &cargo_type)) continue;
229
230 /* Did the old vehicle carry anything? */
231 if (cargo_type != CT_INVALID) {
232 /* We can't refit the vehicle to carry the cargo we want */
233 if (!HasBit(available_cargo_types, cargo_type)) continue;
234 }
235 }
236
237 /* Check money.
238 * We want 2*(the price of the new vehicle) without looking at the value of the vehicle we are going to sell. */
239 pending_replace = true;
240 needed_money += 2 * Engine::Get(new_engine)->GetCost();
241 if (needed_money > c->money) return false;
242 }
243
244 return pending_replace;
245 }
246
252 bool Vehicle::NeedsAutomaticServicing() const
253 {
254 if (this->HasDepotOrder()) return false;
255 if (this->current_order.IsType(OT_LOADING)) return false;
256 if (this->current_order.IsType(OT_GOTO_DEPOT) && this->current_order.GetDepotOrderType() != ODTFB_SERVICE) return false;
257 return NeedsServicing();
258 }
259
260 uint Vehicle::Crash(bool flooded)
261 {
262 assert((this->vehstatus & VS_CRASHED) == 0);
263 assert(this->Previous() == nullptr); // IsPrimaryVehicle fails for free-wagon-chains
264
265 uint pass = 0;
266 /* Stop the vehicle. */
267 if (this->IsPrimaryVehicle()) this->vehstatus |= VS_STOPPED;
268 /* crash all wagons, and count passengers */
269 for (Vehicle *v = this; v != nullptr; v = v->Next()) {
270 /* We do not transfer reserver cargo back, so TotalCount() instead of StoredCount() */
271 if (IsCargoInClass(v->cargo_type, CC_PASSENGERS)) pass += v->cargo.TotalCount();
272 v->vehstatus |= VS_CRASHED;
273 v->MarkAllViewportsDirty();
274 }
275
276 /* Dirty some windows */
277 InvalidateWindowClassesData(GetWindowClassForVehicleType(this->type), 0);
278 SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
279 SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
280 SetWindowDirty(WC_VEHICLE_DEPOT, this->tile);
281
282 delete this->cargo_payment;
283 assert(this->cargo_payment == nullptr); // cleared by ~CargoPayment
284
285 return RandomRange(pass + 1); // Randomise deceased passengers.
286 }
287
288
297 void ShowNewGrfVehicleError(EngineID engine, StringID part1, StringID part2, GRFBugs bug_type, bool critical)
298 {
299 const Engine *e = Engine::Get(engine);
300 GRFConfig *grfconfig = GetGRFConfig(e->GetGRFID());
301
302 /* Missing GRF. Nothing useful can be done in this situation. */
303 if (grfconfig == nullptr) return;
304
305 if (!HasBit(grfconfig->grf_bugs, bug_type)) {
306 SetBit(grfconfig->grf_bugs, bug_type);
307 SetDParamStr(0, grfconfig->GetName());
308 SetDParam(1, engine);
309 ShowErrorMessage(part1, part2, WL_CRITICAL);
310 if (!_networking) DoCommand(0, critical ? PM_PAUSED_ERROR : PM_PAUSED_NORMAL, 1, DC_EXEC, CMD_PAUSE);
311 }
312
313 /* debug output */
314 char buffer[512];
315
316 SetDParamStr(0, grfconfig->GetName());
317 GetString(buffer, part1, lastof(buffer));
318 Debug(grf, 0, "{}", buffer + 3);
319
320 SetDParam(1, engine);
321 GetString(buffer, part2, lastof(buffer));
322 Debug(grf, 0, "{}", buffer + 3);
323 }
324
330 void VehicleLengthChanged(const Vehicle *u)
331 {
332 /* show a warning once for each engine in whole game and once for each GRF after each game load */
333 const Engine *engine = u->GetEngine();
334 uint32 grfid = engine->grf_prop.grffile->grfid;
335 GRFConfig *grfconfig = GetGRFConfig(grfid);
336 if (GamelogGRFBugReverse(grfid, engine->grf_prop.local_id) || !HasBit(grfconfig->grf_bugs, GBUG_VEH_LENGTH)) {
337 ShowNewGrfVehicleError(u->engine_type, STR_NEWGRF_BROKEN, STR_NEWGRF_BROKEN_VEHICLE_LENGTH, GBUG_VEH_LENGTH, true);
338 }
339 }
340
345 Vehicle::Vehicle(VehicleType type)
346 {
347 this->type = type;
348 this->coord.left = INVALID_COORD;
349 this->sprite_cache.old_coord.left = INVALID_COORD;
350 this->group_id = DEFAULT_GROUP;
351 this->fill_percent_te_id = INVALID_TE_ID;
352 this->first = this;
353 this->colourmap = PAL_NONE;
354 this->cargo_age_counter = 1;
355 this->last_station_visited = INVALID_STATION;
356 this->last_loading_station = INVALID_STATION;
357 }
358
363 byte VehicleRandomBits()
364 {
365 return GB(Random(), 0, 8);
366 }
367
368 /* Size of the hash, 6 = 64 x 64, 7 = 128 x 128. Larger sizes will (in theory) reduce hash
369 * lookup times at the expense of memory usage. */
370 const int HASH_BITS = 7;
371 const int HASH_SIZE = 1 << HASH_BITS;
372 const int HASH_MASK = HASH_SIZE - 1;
373 const int TOTAL_HASH_SIZE = 1 << (HASH_BITS * 2);
374 const int TOTAL_HASH_MASK = TOTAL_HASH_SIZE - 1;
375
376 /* Resolution of the hash, 0 = 1*1 tile, 1 = 2*2 tiles, 2 = 4*4 tiles, etc.
377 * Profiling results show that 0 is fastest. */
378 const int HASH_RES = 0;
379
380 static Vehicle *_vehicle_tile_hash[TOTAL_HASH_SIZE];
381
382 static Vehicle *VehicleFromTileHash(int xl, int yl, int xu, int yu, void *data, VehicleFromPosProc *proc, bool find_first)
383 {
384 for (int y = yl; ; y = (y + (1 << HASH_BITS)) & (HASH_MASK << HASH_BITS)) {
385 for (int x = xl; ; x = (x + 1) & HASH_MASK) {
386 Vehicle *v = _vehicle_tile_hash[(x + y) & TOTAL_HASH_MASK];
387 for (; v != nullptr; v = v->hash_tile_next) {
388 Vehicle *a = proc(v, data);
389 if (find_first && a != nullptr) return a;
390 }
391 if (x == xu) break;
392 }
393 if (y == yu) break;
394 }
395
396 return nullptr;
397 }
398
399
411 static Vehicle *VehicleFromPosXY(int x, int y, void *data, VehicleFromPosProc *proc, bool find_first)
412 {
413 const int COLL_DIST = 6;
414
415 /* Hash area to scan is from xl,yl to xu,yu */
416 int xl = GB((x - COLL_DIST) / TILE_SIZE, HASH_RES, HASH_BITS);
417 int xu = GB((x + COLL_DIST) / TILE_SIZE, HASH_RES, HASH_BITS);
418 int yl = GB((y - COLL_DIST) / TILE_SIZE, HASH_RES, HASH_BITS) << HASH_BITS;
419 int yu = GB((y + COLL_DIST) / TILE_SIZE, HASH_RES, HASH_BITS) << HASH_BITS;
420
421 return VehicleFromTileHash(xl, yl, xu, yu, data, proc, find_first);
422 }
423
438 void FindVehicleOnPosXY(int x, int y, void *data, VehicleFromPosProc *proc)
439 {
440 VehicleFromPosXY(x, y, data, proc, false);
441 }
442
454 bool HasVehicleOnPosXY(int x, int y, void *data, VehicleFromPosProc *proc)
455 {
456 return VehicleFromPosXY(x, y, data, proc, true) != nullptr;
457 }
458
469 static Vehicle *VehicleFromPos(TileIndex tile, void *data, VehicleFromPosProc *proc, bool find_first)
470 {
471 int x = GB(TileX(tile), HASH_RES, HASH_BITS);
472 int y = GB(TileY(tile), HASH_RES, HASH_BITS) << HASH_BITS;
473
474 Vehicle *v = _vehicle_tile_hash[(x + y) & TOTAL_HASH_MASK];
475 for (; v != nullptr; v = v->hash_tile_next) {
476 if (v->tile != tile) continue;
477
478 Vehicle *a = proc(v, data);
479 if (find_first && a != nullptr) return a;
480 }
481
482 return nullptr;
483 }
484
498 void FindVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
499 {
500 VehicleFromPos(tile, data, proc, false);
501 }
502
513 bool HasVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
514 {
515 return VehicleFromPos(tile, data, proc, true) != nullptr;
516 }
517
524 static Vehicle *EnsureNoVehicleProcZ(Vehicle *v, void *data)
525 {
526 int z = *(int*)data;
527
528 if (v->type == VEH_DISASTER || (v->type == VEH_AIRCRAFT && v->subtype == AIR_SHADOW)) return nullptr;
529 if (v->z_pos > z) return nullptr;
530
531 return v;
532 }
533
539 CommandCost EnsureNoVehicleOnGround(TileIndex tile)
540 {
541 int z = GetTileMaxPixelZ(tile);
542
543 /* Value v is not safe in MP games, however, it is used to generate a local
544 * error message only (which may be different for different machines).
545 * Such a message does not affect MP synchronisation.
546 */
547 Vehicle *v = VehicleFromPos(tile, &z, &EnsureNoVehicleProcZ, true);
548 if (v != nullptr) return_cmd_error(STR_ERROR_TRAIN_IN_THE_WAY + v->type);
549 return CommandCost();
550 }
551
553 static Vehicle *GetVehicleTunnelBridgeProc(Vehicle *v, void *data)
554 {
555 if (v->type != VEH_TRAIN && v->type != VEH_ROAD && v->type != VEH_SHIP) return nullptr;
556 if (v == (const Vehicle *)data) return nullptr;
557
558 return v;
559 }
560
568 CommandCost TunnelBridgeIsFree(TileIndex tile, TileIndex endtile, const Vehicle *ignore)
569 {
570 /* Value v is not safe in MP games, however, it is used to generate a local
571 * error message only (which may be different for different machines).
572 * Such a message does not affect MP synchronisation.
573 */
574 Vehicle *v = VehicleFromPos(tile, const_cast<Vehicle *>(ignore), &GetVehicleTunnelBridgeProc, true);
575 if (v == nullptr) v = VehicleFromPos(endtile, const_cast<Vehicle *>(ignore), &GetVehicleTunnelBridgeProc, true);
576
577 if (v != nullptr) return_cmd_error(STR_ERROR_TRAIN_IN_THE_WAY + v->type);
578 return CommandCost();
579 }
580
581 static Vehicle *EnsureNoTrainOnTrackProc(Vehicle *v, void *data)
582 {
583 TrackBits rail_bits = *(TrackBits *)data;
584
585 if (v->type != VEH_TRAIN) return nullptr;
586
587 Train *t = Train::From(v);
588 if ((t->track != rail_bits) && !TracksOverlap(t->track | rail_bits)) return nullptr;
589
590 return v;
591 }
592
601 CommandCost EnsureNoTrainOnTrackBits(TileIndex tile, TrackBits track_bits)
602 {
603 /* Value v is not safe in MP games, however, it is used to generate a local
604 * error message only (which may be different for different machines).
605 * Such a message does not affect MP synchronisation.
606 */
607 Vehicle *v = VehicleFromPos(tile, &track_bits, &EnsureNoTrainOnTrackProc, true);
608 if (v != nullptr) return_cmd_error(STR_ERROR_TRAIN_IN_THE_WAY + v->type);
609 return CommandCost();
610 }
611
612 static void UpdateVehicleTileHash(Vehicle *v, bool remove)
613 {
614 Vehicle **old_hash = v->hash_tile_current;
615 Vehicle **new_hash;
616
617 if (remove) {
618 new_hash = nullptr;
619 } else {
620 int x = GB(TileX(v->tile), HASH_RES, HASH_BITS);
621 int y = GB(TileY(v->tile), HASH_RES, HASH_BITS) << HASH_BITS;
622 new_hash = &_vehicle_tile_hash[(x + y) & TOTAL_HASH_MASK];
623 }
624
625 if (old_hash == new_hash) return;
626
627 /* Remove from the old position in the hash table */
628 if (old_hash != nullptr) {
629 if (v->hash_tile_next != nullptr) v->hash_tile_next->hash_tile_prev = v->hash_tile_prev;
630 *v->hash_tile_prev = v->hash_tile_next;
631 }
632
633 /* Insert vehicle at beginning of the new position in the hash table */
634 if (new_hash != nullptr) {
635 v->hash_tile_next = *new_hash;
636 if (v->hash_tile_next != nullptr) v->hash_tile_next->hash_tile_prev = &v->hash_tile_next;
637 v->hash_tile_prev = new_hash;
638 *new_hash = v;
639 }
640
641 /* Remember current hash position */
642 v->hash_tile_current = new_hash;
643 }
644
645 static Vehicle *_vehicle_viewport_hash[1 << (GEN_HASHX_BITS + GEN_HASHY_BITS)];
646
647 static void UpdateVehicleViewportHash(Vehicle *v, int x, int y, int old_x, int old_y)
648 {
649 Vehicle **old_hash, **new_hash;
650
651 new_hash = (x == INVALID_COORD) ? nullptr : &_vehicle_viewport_hash[GEN_HASH(x, y)];
652 old_hash = (old_x == INVALID_COORD) ? nullptr : &_vehicle_viewport_hash[GEN_HASH(old_x, old_y)];
653
654 if (old_hash == new_hash) return;
655
656 /* remove from hash table? */
657 if (old_hash != nullptr) {
658 if (v->hash_viewport_next != nullptr) v->hash_viewport_next->hash_viewport_prev = v->hash_viewport_prev;
659 *v->hash_viewport_prev = v->hash_viewport_next;
660 }
661
662 /* insert into hash table? */
663 if (new_hash != nullptr) {
664 v->hash_viewport_next = *new_hash;
665 if (v->hash_viewport_next != nullptr) v->hash_viewport_next->hash_viewport_prev = &v->hash_viewport_next;
666 v->hash_viewport_prev = new_hash;
667 *new_hash = v;
668 }
669 }
670
671 void ResetVehicleHash()
672 {
673 for (Vehicle *v : Vehicle::Iterate()) { v->hash_tile_current = nullptr; }
674 memset(_vehicle_viewport_hash, 0, sizeof(_vehicle_viewport_hash));
675 memset(_vehicle_tile_hash, 0, sizeof(_vehicle_tile_hash));
676 }
677
678 void ResetVehicleColourMap()
679 {
680 for (Vehicle *v : Vehicle::Iterate()) { v->colourmap = PAL_NONE; }
681 }
682
687 typedef SmallMap<Vehicle *, bool> AutoreplaceMap;
688 static AutoreplaceMap _vehicles_to_autoreplace;
689
690 void InitializeVehicles()
691 {
692 _vehicles_to_autoreplace.clear();
693 _vehicles_to_autoreplace.shrink_to_fit();
694 ResetVehicleHash();
695 }
696
697 uint CountVehiclesInChain(const Vehicle *v)
698 {
699 uint count = 0;
700 do count++; while ((v = v->Next()) != nullptr);
701 return count;
702 }
703
708 bool Vehicle::IsEngineCountable() const
709 {
710 switch (this->type) {
711 case VEH_AIRCRAFT: return Aircraft::From(this)->IsNormalAircraft(); // don't count plane shadows and helicopter rotors
712 case VEH_TRAIN:
713 return !this->IsArticulatedPart() && // tenders and other articulated parts
714 !Train::From(this)->IsRearDualheaded(); // rear parts of multiheaded engines
715 case VEH_ROAD: return RoadVehicle::From(this)->IsFrontEngine();
716 case VEH_SHIP: return true;
717 default: return false; // Only count company buildable vehicles
718 }
719 }
720
725 bool Vehicle::HasEngineType() const
726 {
727 switch (this->type) {
728 case VEH_AIRCRAFT: return Aircraft::From(this)->IsNormalAircraft();
729 case VEH_TRAIN:
730 case VEH_ROAD:
731 case VEH_SHIP: return true;
732 default: return false;
733 }
734 }
735
741 const Engine *Vehicle::GetEngine() const
742 {
743 return Engine::Get(this->engine_type);
744 }
745
751 const GRFFile *Vehicle::GetGRF() const
752 {
753 return this->GetEngine()->GetGRF();
754 }
755
761 uint32 Vehicle::GetGRFID() const
762 {
763 return this->GetEngine()->GetGRFID();
764 }
765
771 void Vehicle::ShiftDates(int interval)
772 {
773 this->date_of_last_service += interval;
774 }
775
783 void Vehicle::HandlePathfindingResult(bool path_found)
784 {
785 if (path_found) {
786 /* Route found, is the vehicle marked with "lost" flag? */
787 if (!HasBit(this->vehicle_flags, VF_PATHFINDER_LOST)) return;
788
789 /* Clear the flag as the PF's problem was solved. */
790 ClrBit(this->vehicle_flags, VF_PATHFINDER_LOST);
791 SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
792 InvalidateWindowClassesData(GetWindowClassForVehicleType(this->type));
793 /* Delete the news item. */
794 DeleteVehicleNews(this->index, STR_NEWS_VEHICLE_IS_LOST);
795 return;
796 }
797
798 /* Were we already lost? */
799 if (HasBit(this->vehicle_flags, VF_PATHFINDER_LOST)) return;
800
801 /* It is first time the problem occurred, set the "lost" flag. */
802 SetBit(this->vehicle_flags, VF_PATHFINDER_LOST);
803 SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
804 InvalidateWindowClassesData(GetWindowClassForVehicleType(this->type));
805 /* Notify user about the event. */
806 AI::NewEvent(this->owner, new ScriptEventVehicleLost(this->index));
807 if (_settings_client.gui.lost_vehicle_warn && this->owner == _local_company) {
808 SetDParam(0, this->index);
809 AddVehicleAdviceNewsItem(STR_NEWS_VEHICLE_IS_LOST, this->index);
810 }
811 }
812
814 void Vehicle::PreDestructor()
815 {
816 if (CleaningPool()) return;
817
818 if (Station::IsValidID(this->last_station_visited)) {
819 Station *st = Station::Get(this->last_station_visited);
820 st->loading_vehicles.remove(this);
821
822 HideFillingPercent(&this->fill_percent_te_id);
823 this->CancelReservation(INVALID_STATION, st);
824 delete this->cargo_payment;
825 assert(this->cargo_payment == nullptr); // cleared by ~CargoPayment
826 }
827
828 if (this->IsEngineCountable()) {
829 GroupStatistics::CountEngine(this, -1);
830 if (this->IsPrimaryVehicle()) GroupStatistics::CountVehicle(this, -1);
831 GroupStatistics::UpdateAutoreplace(this->owner);
832
833 if (this->owner == _local_company) InvalidateAutoreplaceWindow(this->engine_type, this->group_id);
834 DeleteGroupHighlightOfVehicle(this);
835 }
836
837 if (this->type == VEH_AIRCRAFT && this->IsPrimaryVehicle()) {
838 Aircraft *a = Aircraft::From(this);
839 Station *st = GetTargetAirportIfValid(a);
840 if (st != nullptr) {
841 const AirportFTA *layout = st->airport.GetFTA()->layout;
842 CLRBITS(st->airport.flags, layout[a->previous_pos].block | layout[a->pos].block);
843 }
844 }
845
846
847 if (this->type == VEH_ROAD && this->IsPrimaryVehicle()) {
848 RoadVehicle *v = RoadVehicle::From(this);
849 if (!(v->vehstatus & VS_CRASHED) && IsInsideMM(v->state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END)) {
850 /* Leave the drive through roadstop, when you have not already left it. */
851 RoadStop::GetByTile(v->tile, GetRoadStopType(v->tile))->Leave(v);
852 }
853 }
854
855 if (this->Previous() == nullptr) {
856 InvalidateWindowData(WC_VEHICLE_DEPOT, this->tile);
857 }
858
859 if (this->IsPrimaryVehicle()) {
860 CloseWindowById(WC_VEHICLE_VIEW, this->index);
861 CloseWindowById(WC_VEHICLE_ORDERS, this->index);
862 CloseWindowById(WC_VEHICLE_REFIT, this->index);
863 CloseWindowById(WC_VEHICLE_DETAILS, this->index);
864 CloseWindowById(WC_VEHICLE_TIMETABLE, this->index);
865 SetWindowDirty(WC_COMPANY, this->owner);
866 OrderBackup::ClearVehicle(this);
867 }
868 InvalidateWindowClassesData(GetWindowClassForVehicleType(this->type), 0);
869
870 this->cargo.Truncate();
871 DeleteVehicleOrders(this);
872 DeleteDepotHighlightOfVehicle(this);
873
874 extern void StopGlobalFollowVehicle(const Vehicle *v);
875 StopGlobalFollowVehicle(this);
876
877 ReleaseDisastersTargetingVehicle(this->index);
878 }
879
880 Vehicle::~Vehicle()
881 {
882 if (CleaningPool()) {
883 this->cargo.OnCleanPool();
884 return;
885 }
886
887 /* sometimes, eg. for disaster vehicles, when company bankrupts, when removing crashed/flooded vehicles,
888 * it may happen that vehicle chain is deleted when visible */
889 if (!(this->vehstatus & VS_HIDDEN)) this->MarkAllViewportsDirty();
890
891 Vehicle *v = this->Next();
892 this->SetNext(nullptr);
893
894 delete v;
895
896 UpdateVehicleTileHash(this, true);
897 UpdateVehicleViewportHash(this, INVALID_COORD, 0, this->sprite_cache.old_coord.left, this->sprite_cache.old_coord.top);
898 DeleteVehicleNews(this->index, INVALID_STRING_ID);
899 DeleteNewGRFInspectWindow(GetGrfSpecFeature(this->type), this->index);
900 }
901
906 void VehicleEnteredDepotThisTick(Vehicle *v)
907 {
908 /* Vehicle should stop in the depot if it was in 'stopping' state */
909 _vehicles_to_autoreplace[v] = !(v->vehstatus & VS_STOPPED);
910
911 /* We ALWAYS set the stopped state. Even when the vehicle does not plan on
912 * stopping in the depot, so we stop it to ensure that it will not reserve
913 * the path out of the depot before we might autoreplace it to a different
914 * engine. The new engine would not own the reserved path we store that we
915 * stopped the vehicle, so autoreplace can start it again */
916 v->vehstatus |= VS_STOPPED;
917 }
918
924 static void RunVehicleDayProc()
925 {
926 if (_game_mode != GM_NORMAL) return;
927
928 /* Run the day_proc for every DAY_TICKS vehicle starting at _date_fract. */
929 for (size_t i = _date_fract; i < Vehicle::GetPoolSize(); i += DAY_TICKS) {
930 Vehicle *v = Vehicle::Get(i);
931 if (v == nullptr) continue;
932
933 /* Call the 32-day callback if needed */
934 if ((v->day_counter & 0x1F) == 0 && v->HasEngineType()) {
935 uint16 callback = GetVehicleCallback(CBID_VEHICLE_32DAY_CALLBACK, 0, 0, v->engine_type, v);
936 if (callback != CALLBACK_FAILED) {
937 if (HasBit(callback, 0)) {
938 TriggerVehicle(v, VEHICLE_TRIGGER_CALLBACK_32); // Trigger vehicle trigger 10
939 }
940
941 /* After a vehicle trigger, the graphics and properties of the vehicle could change.
942 * Note: MarkDirty also invalidates the palette, which is the meaning of bit 1. So, nothing special there. */
943 if (callback != 0) v->First()->MarkDirty();
944
945 if (callback & ~3) ErrorUnknownCallbackResult(v->GetGRFID(), CBID_VEHICLE_32DAY_CALLBACK, callback);
946 }
947 }
948
949 /* This is called once per day for each vehicle, but not in the first tick of the day */
950 v->OnNewDay();
951 }
952 }
953
954 void CallVehicleTicks()
955 {
956 _vehicles_to_autoreplace.clear();
957
958 RunVehicleDayProc();
959
960 {
961 PerformanceMeasurer framerate(PFE_GL_ECONOMY);
962 for (Station *st : Station::Iterate()) LoadUnloadStation(st);
963 }
964 PerformanceAccumulator::Reset(PFE_GL_TRAINS);
965 PerformanceAccumulator::Reset(PFE_GL_ROADVEHS);
966 PerformanceAccumulator::Reset(PFE_GL_SHIPS);
967 PerformanceAccumulator::Reset(PFE_GL_AIRCRAFT);
968
969 for (Vehicle *v : Vehicle::Iterate()) {
970 [[maybe_unused]] size_t vehicle_index = v->index;
971
972 /* Vehicle could be deleted in this tick */
973 if (!v->Tick()) {
974 assert(Vehicle::Get(vehicle_index) == nullptr);
975 continue;
976 }
977
978 assert(Vehicle::Get(vehicle_index) == v);
979
980 switch (v->type) {
981 default: break;
982
983 case VEH_TRAIN:
984 case VEH_ROAD:
985 case VEH_AIRCRAFT:
986 case VEH_SHIP: {
987 Vehicle *front = v->First();
988
989 if (v->vcache.cached_cargo_age_period != 0) {
990 v->cargo_age_counter = std::min(v->cargo_age_counter, v->vcache.cached_cargo_age_period);
991 if (--v->cargo_age_counter == 0) {
992 v->cargo.AgeCargo();
993 v->cargo_age_counter = v->vcache.cached_cargo_age_period;
994 }
995 }
996
997 /* Do not play any sound when crashed */
998 if (front->vehstatus & VS_CRASHED) continue;
999
1000 /* Do not play any sound when in depot or tunnel */
1001 if (v->vehstatus & VS_HIDDEN) continue;
1002
1003 /* Do not play any sound when stopped */
1004 if ((front->vehstatus & VS_STOPPED) && (front->type != VEH_TRAIN || front->cur_speed == 0)) continue;
1005
1006 /* Check vehicle type specifics */
1007 switch (v->type) {
1008 case VEH_TRAIN:
1009 if (Train::From(v)->IsWagon()) continue;
1010 break;
1011
1012 case VEH_ROAD:
1013 if (!RoadVehicle::From(v)->IsFrontEngine()) continue;
1014 break;
1015
1016 case VEH_AIRCRAFT:
1017 if (!Aircraft::From(v)->IsNormalAircraft()) continue;
1018 break;
1019
1020 default:
1021 break;
1022 }
1023
1024 v->motion_counter += front->cur_speed;
1025 /* Play a running sound if the motion counter passes 256 (Do we not skip sounds?) */
1026 if (GB(v->motion_counter, 0, 8) < front->cur_speed) PlayVehicleSound(v, VSE_RUNNING);
1027
1028 /* Play an alternating running sound every 16 ticks */
1029 if (GB(v->tick_counter, 0, 4) == 0) {
1030 /* Play running sound when speed > 0 and not braking */
1031 bool running = (front->cur_speed > 0) && !(front->vehstatus & (VS_STOPPED | VS_TRAIN_SLOWING));
1032 PlayVehicleSound(v, running ? VSE_RUNNING_16 : VSE_STOPPED_16);
1033 }
1034
1035 break;
1036 }
1037 }
1038 }
1039
1040 Backup<CompanyID> cur_company(_current_company, FILE_LINE);
1041 for (auto &it : _vehicles_to_autoreplace) {
1042 Vehicle *v = it.first;
1043 /* Autoreplace needs the current company set as the vehicle owner */
1044 cur_company.Change(v->owner);
1045
1046 /* Start vehicle if we stopped them in VehicleEnteredDepotThisTick()
1047 * We need to stop them between VehicleEnteredDepotThisTick() and here or we risk that
1048 * they are already leaving the depot again before being replaced. */
1049 if (it.second) v->vehstatus &= ~VS_STOPPED;
1050
1051 /* Store the position of the effect as the vehicle pointer will become invalid later */
1052 int x = v->x_pos;
1053 int y = v->y_pos;
1054 int z = v->z_pos;
1055
1056 const Company *c = Company::Get(_current_company);
1057 SubtractMoneyFromCompany(CommandCost(EXPENSES_NEW_VEHICLES, (Money)c->settings.engine_renew_money));
1058 CommandCost res = DoCommand(0, v->index, 0, DC_EXEC, CMD_AUTOREPLACE_VEHICLE);
1059 SubtractMoneyFromCompany(CommandCost(EXPENSES_NEW_VEHICLES, -(Money)c->settings.engine_renew_money));
1060
1061 if (!IsLocalCompany()) continue;
1062
1063 if (res.Succeeded() && res.GetCost() != 0) {
1064 ShowCostOrIncomeAnimation(x, y, z, res.GetCost());
1065 continue;
1066 }
1067
1068 StringID error_message = res.GetErrorMessage();
1069 if (error_message == STR_ERROR_AUTOREPLACE_NOTHING_TO_DO || error_message == INVALID_STRING_ID) continue;
1070
1071 if (error_message == STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY) error_message = STR_ERROR_AUTOREPLACE_MONEY_LIMIT;
1072
1073 StringID message;
1074 if (error_message == STR_ERROR_TRAIN_TOO_LONG_AFTER_REPLACEMENT) {
1075 message = error_message;
1076 } else {
1077 message = STR_NEWS_VEHICLE_AUTORENEW_FAILED;
1078 }
1079
1080 SetDParam(0, v->index);
1081 SetDParam(1, error_message);
1082 AddVehicleAdviceNewsItem(message, v->index);
1083 }
1084
1085 cur_company.Restore();
1086 }
1087
1092 static void DoDrawVehicle(const Vehicle *v)
1093 {
1094 PaletteID pal = PAL_NONE;
1095
1096 if (v->vehstatus & VS_DEFPAL) pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
1097
1098 /* Check whether the vehicle shall be transparent due to the game state */
1099 bool shadowed = (v->vehstatus & VS_SHADOW) != 0;
1100
1101 if (v->type == VEH_EFFECT) {
1102 /* Check whether the vehicle shall be transparent/invisible due to GUI settings.
1103 * However, transparent smoke and bubbles look weird, so always hide them. */
1104 TransparencyOption to = EffectVehicle::From(v)->GetTransparencyOption();
1105 if (to != TO_INVALID && (IsTransparencySet(to) || IsInvisibilitySet(to))) return;
1106 }
1107
1108 StartSpriteCombine();
1109 for (uint i = 0; i < v->sprite_cache.sprite_seq.count; ++i) {
1110 PaletteID pal2 = v->sprite_cache.sprite_seq.seq[i].pal;
1111 if (!pal2 || (v->vehstatus & VS_CRASHED)) pal2 = pal;
1112 AddSortableSpriteToDraw(v->sprite_cache.sprite_seq.seq[i].sprite, pal2, v->x_pos + v->x_offs, v->y_pos + v->y_offs,
1113 v->x_extent, v->y_extent, v->z_extent, v->z_pos, shadowed, v->x_bb_offs, v->y_bb_offs);
1114 }
1115 EndSpriteCombine();
1116 }
1117
1122 void ViewportAddVehicles(DrawPixelInfo *dpi)
1123 {
1124 /* The bounding rectangle */
1125 const int l = dpi->left;
1126 const int r = dpi->left + dpi->width;
1127 const int t = dpi->top;
1128 const int b = dpi->top + dpi->height;
1129
1130 /* Border size of MAX_VEHICLE_PIXEL_xy */
1131 const int xb = MAX_VEHICLE_PIXEL_X * ZOOM_LVL_BASE;
1132 const int yb = MAX_VEHICLE_PIXEL_Y * ZOOM_LVL_BASE;
1133
1134 /* The hash area to scan */
1135 int xl, xu, yl, yu;
1136
1137 if (dpi->width + xb < GEN_HASHX_SIZE) {
1138 xl = GEN_HASHX(l - xb);
1139 xu = GEN_HASHX(r);
1140 } else {
1141 /* scan whole hash row */
1142 xl = 0;
1143 xu = GEN_HASHX_MASK;
1144 }
1145
1146 if (dpi->height + yb < GEN_HASHY_SIZE) {
1147 yl = GEN_HASHY(t - yb);
1148 yu = GEN_HASHY(b);
1149 } else {
1150 /* scan whole column */
1151 yl = 0;
1152 yu = GEN_HASHY_MASK;
1153 }
1154
1155 for (int y = yl;; y = (y + GEN_HASHY_INC) & GEN_HASHY_MASK) {
1156 for (int x = xl;; x = (x + GEN_HASHX_INC) & GEN_HASHX_MASK) {
1157 const Vehicle *v = _vehicle_viewport_hash[x + y]; // already masked & 0xFFF
1158
1159 while (v != nullptr) {
1160
1161 if (!(v->vehstatus & VS_HIDDEN) &&
1162 l <= v->coord.right + xb &&
1163 t <= v->coord.bottom + yb &&
1164 r >= v->coord.left - xb &&
1165 b >= v->coord.top - yb)
1166 {
1167 /*
1168 * This vehicle can potentially be drawn as part of this viewport and
1169 * needs to be revalidated, as the sprite may not be correct.
1170 */
1171 if (v->sprite_cache.revalidate_before_draw) {
1172 VehicleSpriteSeq seq;
1173 v->GetImage(v->direction, EIT_ON_MAP, &seq);
1174
1175 if (seq.IsValid() && v->sprite_cache.sprite_seq != seq) {
1176 v->sprite_cache.sprite_seq = seq;
1177 /*
1178 * A sprite change may also result in a bounding box change,
1179 * so we need to update the bounding box again before we
1180 * check to see if the vehicle should be drawn. Note that
1181 * we can't interfere with the viewport hash at this point,
1182 * so we keep the original hash on the assumption there will
1183 * not be a significant change in the top and left coordinates
1184 * of the vehicle.
1185 */
1186 v->UpdateBoundingBoxCoordinates(false);
1187
1188 }
1189
1190 v->sprite_cache.revalidate_before_draw = false;
1191 }
1192
1193 if (l <= v->coord.right &&
1194 t <= v->coord.bottom &&
1195 r >= v->coord.left &&
1196 b >= v->coord.top) DoDrawVehicle(v);
1197 }
1198
1199 v = v->hash_viewport_next;
1200 }
1201
1202 if (x == xu) break;
1203 }
1204
1205 if (y == yu) break;
1206 }
1207 }
1208
1216 Vehicle *CheckClickOnVehicle(const Viewport *vp, int x, int y)
1217 {
1218 Vehicle *found = nullptr;
1219 uint dist, best_dist = UINT_MAX;
1220
1221 if ((uint)(x -= vp->left) >= (uint)vp->width || (uint)(y -= vp->top) >= (uint)vp->height) return nullptr;
1222
1223 x = ScaleByZoom(x, vp->zoom) + vp->virtual_left;
1224 y = ScaleByZoom(y, vp->zoom) + vp->virtual_top;
1225
1226 for (Vehicle *v : Vehicle::Iterate()) {
1227 if ((v->vehstatus & (VS_HIDDEN | VS_UNCLICKABLE)) == 0 &&
1228 x >= v->coord.left && x <= v->coord.right &&
1229 y >= v->coord.top && y <= v->coord.bottom) {
1230
1231 dist = std::max(
1232 abs(((v->coord.left + v->coord.right) >> 1) - x),
1233 abs(((v->coord.top + v->coord.bottom) >> 1) - y)
1234 );
1235
1236 if (dist < best_dist) {
1237 found = v;
1238 best_dist = dist;
1239 }
1240 }
1241 }
1242
1243 return found;
1244 }
1245
1250 void DecreaseVehicleValue(Vehicle *v)
1251 {
1252 v->value -= v->value >> 8;
1253 SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
1254 }
1255
1256 static const byte _breakdown_chance[64] = {
1257 3, 3, 3, 3, 3, 3, 3, 3,
1258 4, 4, 5, 5, 6, 6, 7, 7,
1259 8, 8, 9, 9, 10, 10, 11, 11,
1260 12, 13, 13, 13, 13, 14, 15, 16,
1261 17, 19, 21, 25, 28, 31, 34, 37,
1262 40, 44, 48, 52, 56, 60, 64, 68,
1263 72, 80, 90, 100, 110, 120, 130, 140,
1264 150, 170, 190, 210, 230, 250, 250, 250,
1265 };
1266
1267 void CheckVehicleBreakdown(Vehicle *v)
1268 {
1269 int rel, rel_old;
1270
1271 /* decrease reliability */
1272 if (!_settings_game.order.no_servicing_if_no_breakdowns ||
1273 _settings_game.difficulty.vehicle_breakdowns != 0) {
1274 v->reliability = rel = std::max((rel_old = v->reliability) - v->reliability_spd_dec, 0);
1275 if ((rel_old >> 8) != (rel >> 8)) SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
1276 }
1277
1278 if (v->breakdown_ctr != 0 || (v->vehstatus & VS_STOPPED) ||
1279 _settings_game.difficulty.vehicle_breakdowns < 1 ||
1280 v->cur_speed < 5 || _game_mode == GM_MENU) {
1281 return;
1282 }
1283
1284 uint32 r = Random();
1285
1286 /* increase chance of failure */
1287 int chance = v->breakdown_chance + 1;
1288 if (Chance16I(1, 25, r)) chance += 25;
1289 v->breakdown_chance = std::min(255, chance);
1290
1291 /* calculate reliability value to use in comparison */
1292 rel = v->reliability;
1293 if (v->type == VEH_SHIP) rel += 0x6666;
1294
1295 /* reduced breakdowns? */
1296 if (_settings_game.difficulty.vehicle_breakdowns == 1) rel += 0x6666;
1297
1298 /* check if to break down */
1299 if (_breakdown_chance[(uint)std::min(rel, 0xffff) >> 10] <= v->breakdown_chance) {
1300 v->breakdown_ctr = GB(r, 16, 6) + 0x3F;
1301 v->breakdown_delay = GB(r, 24, 7) + 0x80;
1302 v->breakdown_chance = 0;
1303 }
1304 }
1305
1312 bool Vehicle::HandleBreakdown()
1313 {
1314 /* Possible states for Vehicle::breakdown_ctr
1315 * 0 - vehicle is running normally
1316 * 1 - vehicle is currently broken down
1317 * 2 - vehicle is going to break down now
1318 * >2 - vehicle is counting down to the actual breakdown event */
1319 switch (this->breakdown_ctr) {
1320 case 0:
1321 return false;
1322
1323 case 2:
1324 this->breakdown_ctr = 1;
1325
1326 if (this->breakdowns_since_last_service != 255) {
1327 this->breakdowns_since_last_service++;
1328 }
1329
1330 if (this->type == VEH_AIRCRAFT) {
1331 /* Aircraft just need this flag, the rest is handled elsewhere */
1332 this->vehstatus |= VS_AIRCRAFT_BROKEN;
1333 } else {
1334 this->cur_speed = 0;
1335
1336 if (!PlayVehicleSound(this, VSE_BREAKDOWN)) {
1337 bool train_or_ship = this->type == VEH_TRAIN || this->type == VEH_SHIP;
1338 SndPlayVehicleFx((_settings_game.game_creation.landscape != LT_TOYLAND) ?
1339 (train_or_ship ? SND_10_BREAKDOWN_TRAIN_SHIP : SND_0F_BREAKDOWN_ROADVEHICLE) :
1340 (train_or_ship ? SND_3A_BREAKDOWN_TRAIN_SHIP_TOYLAND : SND_35_BREAKDOWN_ROADVEHICLE_TOYLAND), this);
1341 }
1342
1343 if (!(this->vehstatus & VS_HIDDEN) && !HasBit(EngInfo(this->engine_type)->misc_flags, EF_NO_BREAKDOWN_SMOKE)) {
1344 EffectVehicle *u = CreateEffectVehicleRel(this, 4, 4, 5, EV_BREAKDOWN_SMOKE);
1345 if (u != nullptr) u->animation_state = this->breakdown_delay * 2;
1346 }
1347 }
1348
1349 this->MarkDirty(); // Update graphics after speed is zeroed
1350 SetWindowDirty(WC_VEHICLE_VIEW, this->index);
1351 SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
1352
1353 FALLTHROUGH;
1354 case 1:
1355 /* Aircraft breakdowns end only when arriving at the airport */
1356 if (this->type == VEH_AIRCRAFT) return false;
1357
1358 /* For trains this function is called twice per tick, so decrease v->breakdown_delay at half the rate */
1359 if ((this->tick_counter & (this->type == VEH_TRAIN ? 3 : 1)) == 0) {
1360 if (--this->breakdown_delay == 0) {
1361 this->breakdown_ctr = 0;
1362 this->MarkDirty();
1363 SetWindowDirty(WC_VEHICLE_VIEW, this->index);
1364 }
1365 }
1366 return true;
1367
1368 default:
1369 if (!this->current_order.IsType(OT_LOADING)) this->breakdown_ctr--;
1370 return false;
1371 }
1372 }
1373
1378 void AgeVehicle(Vehicle *v)
1379 {
1380 if (v->age < MAX_DAY) {
1381 v->age++;
1382 if (v->IsPrimaryVehicle() && v->age == VEHICLE_PROFIT_MIN_AGE + 1) GroupStatistics::VehicleReachedProfitAge(v);
1383 }
1384
1385 if (!v->IsPrimaryVehicle() && (v->type != VEH_TRAIN || !Train::From(v)->IsEngine())) return;
1386
1387 int age = v->age - v->max_age;
1388 if (age == DAYS_IN_LEAP_YEAR * 0 || age == DAYS_IN_LEAP_YEAR * 1 ||
1389 age == DAYS_IN_LEAP_YEAR * 2 || age == DAYS_IN_LEAP_YEAR * 3 || age == DAYS_IN_LEAP_YEAR * 4) {
1390 v->reliability_spd_dec <<= 1;
1391 }
1392
1393 SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
1394
1395 /* Don't warn about non-primary or not ours vehicles or vehicles that are crashed */
1396 if (v->Previous() != nullptr || v->owner != _local_company || (v->vehstatus & VS_CRASHED) != 0) return;
1397
1398 const Company *c = Company::Get(v->owner);
1399 /* Don't warn if a renew is active */
1400 if (c->settings.engine_renew && v->GetEngine()->company_avail != 0) return;
1401 /* Don't warn if a replacement is active */
1402 if (EngineHasReplacementForCompany(c, v->engine_type, v->group_id)) return;
1403
1404 StringID str;
1405 if (age == -DAYS_IN_LEAP_YEAR) {
1406 str = STR_NEWS_VEHICLE_IS_GETTING_OLD;
1407 } else if (age == 0) {
1408 str = STR_NEWS_VEHICLE_IS_GETTING_VERY_OLD;
1409 } else if (age > 0 && (age % DAYS_IN_LEAP_YEAR) == 0) {
1410 str = STR_NEWS_VEHICLE_IS_GETTING_VERY_OLD_AND;
1411 } else {
1412 return;
1413 }
1414
1415 SetDParam(0, v->index);
1416 AddVehicleAdviceNewsItem(str, v->index);
1417 }
1418
1428 uint8 CalcPercentVehicleFilled(const Vehicle *front, StringID *colour)
1429 {
1430 int count = 0;
1431 int max = 0;
1432 int cars = 0;
1433 int unloading = 0;
1434 bool loading = false;
1435
1436 bool is_loading = front->current_order.IsType(OT_LOADING);
1437
1438 /* The station may be nullptr when the (colour) string does not need to be set. */
1439 const Station *st = Station::GetIfValid(front->last_station_visited);
1440 assert(colour == nullptr || (st != nullptr && is_loading));
1441
1442 bool order_no_load = is_loading && (front->current_order.GetLoadType() & OLFB_NO_LOAD);
1443 bool order_full_load = is_loading && (front->current_order.GetLoadType() & OLFB_FULL_LOAD);
1444
1445 /* Count up max and used */
1446 for (const Vehicle *v = front; v != nullptr; v = v->Next()) {
1447 count += v->cargo.StoredCount();
1448 max += v->cargo_cap;
1449 if (v->cargo_cap != 0 && colour != nullptr) {
1450 unloading += HasBit(v->vehicle_flags, VF_CARGO_UNLOADING) ? 1 : 0;
1451 loading |= !order_no_load &&
1452 (order_full_load || st->goods[v->cargo_type].HasRating()) &&
1453 !HasBit(v->vehicle_flags, VF_LOADING_FINISHED) && !HasBit(v->vehicle_flags, VF_STOP_LOADING);
1454 cars++;
1455 }
1456 }
1457
1458 if (colour != nullptr) {
1459 if (unloading == 0 && loading) {
1460 *colour = STR_PERCENT_UP;
1461 } else if (unloading == 0 && !loading) {
1462 *colour = STR_PERCENT_NONE;
1463 } else if (cars == unloading || !loading) {
1464 *colour = STR_PERCENT_DOWN;
1465 } else {
1466 *colour = STR_PERCENT_UP_DOWN;
1467 }
1468 }
1469
1470 /* Train without capacity */
1471 if (max == 0) return 100;
1472
1473 /* Return the percentage */
1474 if (count * 2 < max) {
1475 /* Less than 50%; round up, so that 0% means really empty. */
1476 return CeilDiv(count * 100, max);
1477 } else {
1478 /* More than 50%; round down, so that 100% means really full. */
1479 return (count * 100) / max;
1480 }
1481 }
1482
1487 void VehicleEnterDepot(Vehicle *v)
1488 {
1489 /* Always work with the front of the vehicle */
1490 assert(v == v->First());
1491
1492 switch (v->type) {
1493 case VEH_TRAIN: {
1494 Train *t = Train::From(v);
1495 SetWindowClassesDirty(WC_TRAINS_LIST);
1496 /* Clear path reservation */
1497 SetDepotReservation(t->tile, false);
1498 if (_settings_client.gui.show_track_reservation) MarkTileDirtyByTile(t->tile);
1499
1500 UpdateSignalsOnSegment(t->tile, INVALID_DIAGDIR, t->owner);
1501 t->wait_counter = 0;
1502 t->force_proceed = TFP_NONE;
1503 ClrBit(t->flags, VRF_TOGGLE_REVERSE);
1504 t->ConsistChanged(CCF_ARRANGE);
1505 break;
1506 }
1507
1508 case VEH_ROAD:
1509 SetWindowClassesDirty(WC_ROADVEH_LIST);
1510 break;
1511
1512 case VEH_SHIP: {
1513 SetWindowClassesDirty(WC_SHIPS_LIST);
1514 Ship *ship = Ship::From(v);
1515 ship->state = TRACK_BIT_DEPOT;
1516 ship->UpdateCache();
1517 ship->UpdateViewport(true, true);
1518 SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
1519 break;
1520 }
1521
1522 case VEH_AIRCRAFT:
1523 SetWindowClassesDirty(WC_AIRCRAFT_LIST);
1524 HandleAircraftEnterHangar(Aircraft::From(v));
1525 break;
1526 default: NOT_REACHED();
1527 }
1528 SetWindowDirty(WC_VEHICLE_VIEW, v->index);
1529
1530 if (v->type != VEH_TRAIN) {
1531 /* Trains update the vehicle list when the first unit enters the depot and calls VehicleEnterDepot() when the last unit enters.
1532 * 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 */
1533 InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
1534 }
1535 SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
1536
1537 v->vehstatus |= VS_HIDDEN;
1538 v->cur_speed = 0;
1539
1540 VehicleServiceInDepot(v);
1541
1542 /* After a vehicle trigger, the graphics and properties of the vehicle could change. */
1543 TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT);
1544 v->MarkDirty();
1545
1546 InvalidateWindowData(WC_VEHICLE_VIEW, v->index);
1547
1548 if (v->current_order.IsType(OT_GOTO_DEPOT)) {
1549 SetWindowDirty(WC_VEHICLE_VIEW, v->index);
1550
1551 const Order *real_order = v->GetOrder(v->cur_real_order_index);
1552
1553 /* Test whether we are heading for this depot. If not, do nothing.
1554 * Note: The target depot for nearest-/manual-depot-orders is only updated on junctions, but we want to accept every depot. */
1555 if ((v->current_order.GetDepotOrderType() & ODTFB_PART_OF_ORDERS) &&
1556 real_order != nullptr && !(real_order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) &&
1557 (v->type == VEH_AIRCRAFT ? v->current_order.GetDestination() != GetStationIndex(v->tile) : v->dest_tile != v->tile)) {
1558 /* We are heading for another depot, keep driving. */
1559 return;
1560 }
1561
1562 if (v->current_order.IsRefit()) {
1563 Backup<CompanyID> cur_company(_current_company, v->owner, FILE_LINE);
1564 CommandCost cost = DoCommand(v->tile, v->index, v->current_order.GetRefitCargo() | 0xFF << 8, DC_EXEC, GetCmdRefitVeh(v));
1565 cur_company.Restore();
1566
1567 if (cost.Failed()) {
1568 _vehicles_to_autoreplace[v] = false;
1569 if (v->owner == _local_company) {
1570 /* Notify the user that we stopped the vehicle */
1571 SetDParam(0, v->index);
1572 AddVehicleAdviceNewsItem(STR_NEWS_ORDER_REFIT_FAILED, v->index);
1573 }
1574 } else if (cost.GetCost() != 0) {
1575 v->profit_this_year -= cost.GetCost() << 8;
1576 if (v->owner == _local_company) {
1577 ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost.GetCost());
1578 }
1579 }
1580 }
1581
1582 if (v->current_order.GetDepotOrderType() & ODTFB_PART_OF_ORDERS) {
1583 /* Part of orders */
1584 v->DeleteUnreachedImplicitOrders();
1585 UpdateVehicleTimetable(v, true);
1586 v->IncrementImplicitOrderIndex();
1587 }
1588 if (v->current_order.GetDepotActionType() & ODATFB_HALT) {
1589 /* Vehicles are always stopped on entering depots. Do not restart this one. */
1590 _vehicles_to_autoreplace[v] = false;
1591 /* Invalidate last_loading_station. As the link from the station
1592 * before the stop to the station after the stop can't be predicted
1593 * we shouldn't construct it when the vehicle visits the next stop. */
1594 v->last_loading_station = INVALID_STATION;
1595 if (v->owner == _local_company) {
1596 SetDParam(0, v->index);
1597 AddVehicleAdviceNewsItem(STR_NEWS_TRAIN_IS_WAITING + v->type, v->index);
1598 }
1599 AI::NewEvent(v->owner, new ScriptEventVehicleWaitingInDepot(v->index));
1600 }
1601 v->current_order.MakeDummy();
1602 }
1603 }
1604
1605
1610 void Vehicle::UpdatePosition()
1611 {
1612 UpdateVehicleTileHash(this, false);
1613 }
1614
1619 void Vehicle::UpdateBoundingBoxCoordinates(bool update_cache) const
1620 {
1621 Rect new_coord;
1622 this->sprite_cache.sprite_seq.GetBounds(&new_coord);
1623
1624 Point pt = RemapCoords(this->x_pos + this->x_offs, this->y_pos + this->y_offs, this->z_pos);
1625 new_coord.left += pt.x;
1626 new_coord.top += pt.y;
1627 new_coord.right += pt.x + 2 * ZOOM_LVL_BASE;
1628 new_coord.bottom += pt.y + 2 * ZOOM_LVL_BASE;
1629
1630 if (update_cache) {
1631 /*
1632 * If the old coordinates are invalid, set the cache to the new coordinates for correct
1633 * behaviour the next time the coordinate cache is checked.
1634 */
1635 this->sprite_cache.old_coord = this->coord.left == INVALID_COORD ? new_coord : this->coord;
1636 }
1637 else {
1638 /* Extend the bounds of the existing cached bounding box so the next dirty window is correct */
1639 this->sprite_cache.old_coord.left = std::min(this->sprite_cache.old_coord.left, this->coord.left);
1640 this->sprite_cache.old_coord.top = std::min(this->sprite_cache.old_coord.top, this->coord.top);
1641 this->sprite_cache.old_coord.right = std::max(this->sprite_cache.old_coord.right, this->coord.right);
1642 this->sprite_cache.old_coord.bottom = std::max(this->sprite_cache.old_coord.bottom, this->coord.bottom);
1643 }
1644
1645 this->coord = new_coord;
1646 }
1647
1652 void Vehicle::UpdateViewport(bool dirty)
1653 {
1654 /* If the existing cache is invalid we should ignore it, as it will be set to the current coords by UpdateBoundingBoxCoordinates */
1655 bool ignore_cached_coords = this->sprite_cache.old_coord.left == INVALID_COORD;
1656
1657 this->UpdateBoundingBoxCoordinates(true);
1658
1659 if (ignore_cached_coords) {
1660 UpdateVehicleViewportHash(this, this->coord.left, this->coord.top, INVALID_COORD, INVALID_COORD);
1661 } else {
1662 UpdateVehicleViewportHash(this, this->coord.left, this->coord.top, this->sprite_cache.old_coord.left, this->sprite_cache.old_coord.top);
1663 }
1664
1665 if (dirty) {
1666 if (ignore_cached_coords) {
1667 this->sprite_cache.is_viewport_candidate = this->MarkAllViewportsDirty();
1668 } else {
1669 this->sprite_cache.is_viewport_candidate = ::MarkAllViewportsDirty(
1670 std::min(this->sprite_cache.old_coord.left, this->coord.left),
1671 std::min(this->sprite_cache.old_coord.top, this->coord.top),
1672 std::max(this->sprite_cache.old_coord.right, this->coord.right),
1673 std::max(this->sprite_cache.old_coord.bottom, this->coord.bottom));
1674 }
1675 }
1676 }
1677
1681 void Vehicle::UpdatePositionAndViewport()
1682 {
1683 this->UpdatePosition();
1684 this->UpdateViewport(true);
1685 }
1686
1691 bool Vehicle::MarkAllViewportsDirty() const
1692 {
1693 return ::MarkAllViewportsDirty(this->coord.left, this->coord.top, this->coord.right, this->coord.bottom);
1694 }
1695
1701 GetNewVehiclePosResult GetNewVehiclePos(const Vehicle *v)
1702 {
1703 static const int8 _delta_coord[16] = {
1704 -1,-1,-1, 0, 1, 1, 1, 0, /* x */
1705 -1, 0, 1, 1, 1, 0,-1,-1, /* y */
1706 };
1707
1708 int x = v->x_pos + _delta_coord[v->direction];
1709 int y = v->y_pos + _delta_coord[v->direction + 8];
1710
1711 GetNewVehiclePosResult gp;
1712 gp.x = x;
1713 gp.y = y;
1714 gp.old_tile = v->tile;
1715 gp.new_tile = TileVirtXY(x, y);
1716 return gp;
1717 }
1718
1719 static const Direction _new_direction_table[] = {
1720 DIR_N, DIR_NW, DIR_W,
1721 DIR_NE, DIR_SE, DIR_SW,
1722 DIR_E, DIR_SE, DIR_S
1723 };
1724
1725 Direction GetDirectionTowards(const Vehicle *v, int x, int y)
1726 {
1727 int i = 0;
1728
1729 if (y >= v->y_pos) {
1730 if (y != v->y_pos) i += 3;
1731 i += 3;
1732 }
1733
1734 if (x >= v->x_pos) {
1735 if (x != v->x_pos) i++;
1736 i++;
1737 }
1738
1739 Direction dir = v->direction;
1740
1741 DirDiff dirdiff = DirDifference(_new_direction_table[i], dir);
1742 if (dirdiff == DIRDIFF_SAME) return dir;
1743 return ChangeDir(dir, dirdiff > DIRDIFF_REVERSE ? DIRDIFF_45LEFT : DIRDIFF_45RIGHT);
1744 }
1745
1755 VehicleEnterTileStatus VehicleEnterTile(Vehicle *v, TileIndex tile, int x, int y)
1756 {
1757 return _tile_type_procs[GetTileType(tile)]->vehicle_enter_tile_proc(v, tile, x, y);
1758 }
1759
1767 FreeUnitIDGenerator::FreeUnitIDGenerator(VehicleType type, CompanyID owner) : cache(nullptr), maxid(0), curid(0)
1768 {
1769 /* Find maximum */
1770 for (const Vehicle *v : Vehicle::Iterate()) {
1771 if (v->type == type && v->owner == owner) {
1772 this->maxid = std::max<UnitID>(this->maxid, v->unitnumber);
1773 }
1774 }
1775
1776 if (this->maxid == 0) return;
1777
1778 /* Reserving 'maxid + 2' because we need:
1779 * - space for the last item (with v->unitnumber == maxid)
1780 * - one free slot working as loop terminator in FreeUnitIDGenerator::NextID() */
1781 this->cache = CallocT<bool>(this->maxid + 2);
1782
1783 /* Fill the cache */
1784 for (const Vehicle *v : Vehicle::Iterate()) {
1785 if (v->type == type && v->owner == owner) {
1786 this->cache[v->unitnumber] = true;
1787 }
1788 }
1789 }
1790
1792 UnitID FreeUnitIDGenerator::NextID()
1793 {
1794 if (this->maxid <= this->curid) return ++this->curid;
1795
1796 while (this->cache[++this->curid]) { } // it will stop, we reserved more space than needed
1797
1798 return this->curid;
1799 }
1800
1806 UnitID GetFreeUnitNumber(VehicleType type)
1807 {
1808 /* Check whether it is allowed to build another vehicle. */
1809 uint max_veh;
1810 switch (type) {
1811 case VEH_TRAIN: max_veh = _settings_game.vehicle.max_trains; break;
1812 case VEH_ROAD: max_veh = _settings_game.vehicle.max_roadveh; break;
1813 case VEH_SHIP: max_veh = _settings_game.vehicle.max_ships; break;
1814 case VEH_AIRCRAFT: max_veh = _settings_game.vehicle.max_aircraft; break;
1815 default: NOT_REACHED();
1816 }
1817
1818 const Company *c = Company::Get(_current_company);
1819 if (c->group_all[type].num_vehicle >= max_veh) return UINT16_MAX; // Currently already at the limit, no room to make a new one.
1820
1821 FreeUnitIDGenerator gen(type, _current_company);
1822
1823 return gen.NextID();
1824 }
1825
1826
1835 bool CanBuildVehicleInfrastructure(VehicleType type, byte subtype)
1836 {
1837 assert(IsCompanyBuildableVehicleType(type));
1838
1839 if (!Company::IsValidID(_local_company)) return false;
1840
1841 UnitID max;
1842 switch (type) {
1843 case VEH_TRAIN:
1844 if (!HasAnyRailtypesAvail(_local_company)) return false;
1845 max = _settings_game.vehicle.max_trains;
1846 break;
1847 case VEH_ROAD:
1848 if (!HasAnyRoadTypesAvail(_local_company, (RoadTramType)subtype)) return false;
1849 max = _settings_game.vehicle.max_roadveh;
1850 break;
1851 case VEH_SHIP: max = _settings_game.vehicle.max_ships; break;
1852 case VEH_AIRCRAFT: max = _settings_game.vehicle.max_aircraft; break;
1853 default: NOT_REACHED();
1854 }
1855
1856 /* We can build vehicle infrastructure when we may build the vehicle type */
1857 if (max > 0) {
1858 /* Can we actually build the vehicle type? */
1859 for (const Engine *e : Engine::IterateType(type)) {
1860 if (type == VEH_ROAD && GetRoadTramType(e->u.road.roadtype) != (RoadTramType)subtype) continue;
1861 if (HasBit(e->company_avail, _local_company)) return true;
1862 }
1863 return false;
1864 }
1865
1866 /* We should be able to build infrastructure when we have the actual vehicle type */
1867 for (const Vehicle *v : Vehicle::Iterate()) {
1868 if (v->type == VEH_ROAD && GetRoadTramType(RoadVehicle::From(v)->roadtype) != (RoadTramType)subtype) continue;
1869 if (v->owner == _local_company && v->type == type) return true;
1870 }
1871
1872 return false;
1873 }
1874
1875
1883 LiveryScheme GetEngineLiveryScheme(EngineID engine_type, EngineID parent_engine_type, const Vehicle *v)
1884 {
1885 CargoID cargo_type = v == nullptr ? (CargoID)CT_INVALID : v->cargo_type;
1886 const Engine *e = Engine::Get(engine_type);
1887 switch (e->type) {
1888 default: NOT_REACHED();
1889 case VEH_TRAIN:
1890 if (v != nullptr && parent_engine_type != INVALID_ENGINE && (UsesWagonOverride(v) || (v->IsArticulatedPart() && e->u.rail.railveh_type != RAILVEH_WAGON))) {
1891 /* Wagonoverrides use the colour scheme of the front engine.
1892 * Articulated parts use the colour scheme of the first part. (Not supported for articulated wagons) */
1893 engine_type = parent_engine_type;
1894 e = Engine::Get(engine_type);
1895 /* Note: Luckily cargo_type is not needed for engines */
1896 }
1897
1898 if (cargo_type == CT_INVALID) cargo_type = e->GetDefaultCargoType();
1899 if (cargo_type == CT_INVALID) cargo_type = CT_GOODS; // The vehicle does not carry anything, let's pick some freight cargo
1900 if (e->u.rail.railveh_type == RAILVEH_WAGON) {
1901 if (!CargoSpec::Get(cargo_type)->is_freight) {
1902 if (parent_engine_type == INVALID_ENGINE) {
1903 return LS_PASSENGER_WAGON_STEAM;
1904 } else {
1905 bool is_mu = HasBit(EngInfo(parent_engine_type)->misc_flags, EF_RAIL_IS_MU);
1906 switch (RailVehInfo(parent_engine_type)->engclass) {
1907 default: NOT_REACHED();
1908 case EC_STEAM: return LS_PASSENGER_WAGON_STEAM;
1909 case EC_DIESEL: return is_mu ? LS_DMU : LS_PASSENGER_WAGON_DIESEL;
1910 case EC_ELECTRIC: return is_mu ? LS_EMU : LS_PASSENGER_WAGON_ELECTRIC;
1911 case EC_MONORAIL: return LS_PASSENGER_WAGON_MONORAIL;
1912 case EC_MAGLEV: return LS_PASSENGER_WAGON_MAGLEV;
1913 }
1914 }
1915 } else {
1916 return LS_FREIGHT_WAGON;
1917 }
1918 } else {
1919 bool is_mu = HasBit(e->info.misc_flags, EF_RAIL_IS_MU);
1920
1921 switch (e->u.rail.engclass) {
1922 default: NOT_REACHED();
1923 case EC_STEAM: return LS_STEAM;
1924 case EC_DIESEL: return is_mu ? LS_DMU : LS_DIESEL;
1925 case EC_ELECTRIC: return is_mu ? LS_EMU : LS_ELECTRIC;
1926 case EC_MONORAIL: return LS_MONORAIL;
1927 case EC_MAGLEV: return LS_MAGLEV;
1928 }
1929 }
1930
1931 case VEH_ROAD:
1932 /* Always use the livery of the front */
1933 if (v != nullptr && parent_engine_type != INVALID_ENGINE) {
1934 engine_type = parent_engine_type;
1935 e = Engine::Get(engine_type);
1936 cargo_type = v->First()->cargo_type;
1937 }
1938 if (cargo_type == CT_INVALID) cargo_type = e->GetDefaultCargoType();
1939 if (cargo_type == CT_INVALID) cargo_type = CT_GOODS; // The vehicle does not carry anything, let's pick some freight cargo
1940
1941 /* Important: Use Tram Flag of front part. Luckily engine_type refers to the front part here. */
1942 if (HasBit(e->info.misc_flags, EF_ROAD_TRAM)) {
1943 /* Tram */
1944 return IsCargoInClass(cargo_type, CC_PASSENGERS) ? LS_PASSENGER_TRAM : LS_FREIGHT_TRAM;
1945 } else {
1946 /* Bus or truck */
1947 return IsCargoInClass(cargo_type, CC_PASSENGERS) ? LS_BUS : LS_TRUCK;
1948 }
1949
1950 case VEH_SHIP:
1951 if (cargo_type == CT_INVALID) cargo_type = e->GetDefaultCargoType();
1952 if (cargo_type == CT_INVALID) cargo_type = CT_GOODS; // The vehicle does not carry anything, let's pick some freight cargo
1953 return IsCargoInClass(cargo_type, CC_PASSENGERS) ? LS_PASSENGER_SHIP : LS_FREIGHT_SHIP;
1954
1955 case VEH_AIRCRAFT:
1956 switch (e->u.air.subtype) {
1957 case AIR_HELI: return LS_HELICOPTER;
1958 case AIR_CTOL: return LS_SMALL_PLANE;
1959 case AIR_CTOL | AIR_FAST: return LS_LARGE_PLANE;
1960 default: NOT_REACHED();
1961 }
1962 }
1963 }
1964
1974 const Livery *GetEngineLivery(EngineID engine_type, CompanyID company, EngineID parent_engine_type, const Vehicle *v, byte livery_setting)
1975 {
1976 const Company *c = Company::Get(company);
1977 LiveryScheme scheme = LS_DEFAULT;
1978
1979 if (livery_setting == LIT_ALL || (livery_setting == LIT_COMPANY && company == _local_company)) {
1980 if (v != nullptr) {
1981 const Group *g = Group::GetIfValid(v->First()->group_id);
1982 if (g != nullptr) {
1983 /* Traverse parents until we find a livery or reach the top */
1984 while (g->livery.in_use == 0 && g->parent != INVALID_GROUP) {
1985 g = Group::Get(g->parent);
1986 }
1987 if (g->livery.in_use != 0) return &g->livery;
1988 }
1989 }
1990
1991 /* The default livery is always available for use, but its in_use flag determines
1992 * whether any _other_ liveries are in use. */
1993 if (c->livery[LS_DEFAULT].in_use != 0) {
1994 /* Determine the livery scheme to use */
1995 scheme = GetEngineLiveryScheme(engine_type, parent_engine_type, v);
1996 }
1997 }
1998
1999 return &c->livery[scheme];
2000 }
2001
2002
2003 static PaletteID GetEngineColourMap(EngineID engine_type, CompanyID company, EngineID parent_engine_type, const Vehicle *v)
2004 {
2005 PaletteID map = (v != nullptr) ? v->colourmap : PAL_NONE;
2006
2007 /* Return cached value if any */
2008 if (map != PAL_NONE) return map;
2009
2010 const Engine *e = Engine::Get(engine_type);
2011
2012 /* Check if we should use the colour map callback */
2013 if (HasBit(e->info.callback_mask, CBM_VEHICLE_COLOUR_REMAP)) {
2014 uint16 callback = GetVehicleCallback(CBID_VEHICLE_COLOUR_MAPPING, 0, 0, engine_type, v);
2015 /* Failure means "use the default two-colour" */
2016 if (callback != CALLBACK_FAILED) {
2017 static_assert(PAL_NONE == 0); // Returning 0x4000 (resp. 0xC000) coincidences with default value (PAL_NONE)
2018 map = GB(callback, 0, 14);
2019 /* If bit 14 is set, then the company colours are applied to the
2020 * map else it's returned as-is. */
2021 if (!HasBit(callback, 14)) {
2022 /* Update cache */
2023 if (v != nullptr) const_cast<Vehicle *>(v)->colourmap = map;
2024 return map;
2025 }
2026 }
2027 }
2028
2029 bool twocc = HasBit(e->info.misc_flags, EF_USES_2CC);
2030
2031 if (map == PAL_NONE) map = twocc ? (PaletteID)SPR_2CCMAP_BASE : (PaletteID)PALETTE_RECOLOUR_START;
2032
2033 /* Spectator has news shown too, but has invalid company ID - as well as dedicated server */
2034 if (!Company::IsValidID(company)) return map;
2035
2036 const Livery *livery = GetEngineLivery(engine_type, company, parent_engine_type, v, _settings_client.gui.liveries);
2037
2038 map += livery->colour1;
2039 if (twocc) map += livery->colour2 * 16;
2040
2041 /* Update cache */
2042 if (v != nullptr) const_cast<Vehicle *>(v)->colourmap = map;
2043 return map;
2044 }
2045
2052 PaletteID GetEnginePalette(EngineID engine_type, CompanyID company)
2053 {
2054 return GetEngineColourMap(engine_type, company, INVALID_ENGINE, nullptr);
2055 }
2056
2062 PaletteID GetVehiclePalette(const Vehicle *v)
2063 {
2064 if (v->IsGroundVehicle()) {
2065 return GetEngineColourMap(v->engine_type, v->owner, v->GetGroundVehicleCache()->first_engine, v);
2066 }
2067
2068 return GetEngineColourMap(v->engine_type, v->owner, INVALID_ENGINE, v);
2069 }
2070
2074 void Vehicle::DeleteUnreachedImplicitOrders()
2075 {
2076 if (this->IsGroundVehicle()) {
2077 uint16 &gv_flags = this->GetGroundVehicleFlags();
2078 if (HasBit(gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS)) {
2079 /* Do not delete orders, only skip them */
2080 ClrBit(gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS);
2081 this->cur_implicit_order_index = this->cur_real_order_index;
2082 InvalidateVehicleOrder(this, 0);
2083 return;
2084 }
2085 }
2086
2087 const Order *order = this->GetOrder(this->cur_implicit_order_index);
2088 while (order != nullptr) {
2089 if (this->cur_implicit_order_index == this->cur_real_order_index) break;
2090
2091 if (order->IsType(OT_IMPLICIT)) {
2092 DeleteOrder(this, this->cur_implicit_order_index);
2093 /* DeleteOrder does various magic with order_indices, so resync 'order' with 'cur_implicit_order_index' */
2094 order = this->GetOrder(this->cur_implicit_order_index);
2095 } else {
2096 /* Skip non-implicit orders, e.g. service-orders */
2097 order = order->next;
2098 this->cur_implicit_order_index++;
2099 }
2100
2101 /* Wrap around */
2102 if (order == nullptr) {
2103 order = this->GetOrder(0);
2104 this->cur_implicit_order_index = 0;
2105 }
2106 }
2107 }
2108
2113 void Vehicle::BeginLoading()
2114 {
2115 assert(IsTileType(this->tile, MP_STATION) || this->type == VEH_SHIP);
2116
2117 uint32 travel_time = this->current_order_time;
2118 if (this->current_order.IsType(OT_GOTO_STATION) &&
2119 this->current_order.GetDestination() == this->last_station_visited) {
2120 this->DeleteUnreachedImplicitOrders();
2121
2122 /* Now both order indices point to the destination station, and we can start loading */
2123 this->current_order.MakeLoading(true);
2124 UpdateVehicleTimetable(this, true);
2125
2126 /* Furthermore add the Non Stop flag to mark that this station
2127 * is the actual destination of the vehicle, which is (for example)
2128 * necessary to be known for HandleTrainLoading to determine
2129 * whether the train is lost or not; not marking a train lost
2130 * that arrives at random stations is bad. */
2131 this->current_order.SetNonStopType(ONSF_NO_STOP_AT_ANY_STATION);
2132
2133 } else {
2134 /* We weren't scheduled to stop here. Insert an implicit order
2135 * to show that we are stopping here.
2136 * While only groundvehicles have implicit orders, e.g. aircraft might still enter
2137 * the 'wrong' terminal when skipping orders etc. */
2138 Order *in_list = this->GetOrder(this->cur_implicit_order_index);
2139 if (this->IsGroundVehicle() &&
2140 (in_list == nullptr || !in_list->IsType(OT_IMPLICIT) ||
2141 in_list->GetDestination() != this->last_station_visited)) {
2142 bool suppress_implicit_orders = HasBit(this->GetGroundVehicleFlags(), GVF_SUPPRESS_IMPLICIT_ORDERS);
2143 /* Do not create consecutive duplicates of implicit orders */
2144 Order *prev_order = this->cur_implicit_order_index > 0 ? this->GetOrder(this->cur_implicit_order_index - 1) : (this->GetNumOrders() > 1 ? this->GetLastOrder() : nullptr);
2145 if (prev_order == nullptr ||
2146 (!prev_order->IsType(OT_IMPLICIT) && !prev_order->IsType(OT_GOTO_STATION)) ||
2147 prev_order->GetDestination() != this->last_station_visited) {
2148
2149 /* Prefer deleting implicit orders instead of inserting new ones,
2150 * so test whether the right order follows later. In case of only
2151 * implicit orders treat the last order in the list like an
2152 * explicit one, except if the overall number of orders surpasses
2153 * IMPLICIT_ORDER_ONLY_CAP. */
2154 int target_index = this->cur_implicit_order_index;
2155 bool found = false;
2156 while (target_index != this->cur_real_order_index || this->GetNumManualOrders() == 0) {
2157 const Order *order = this->GetOrder(target_index);
2158 if (order == nullptr) break; // No orders.
2159 if (order->IsType(OT_IMPLICIT) && order->GetDestination() == this->last_station_visited) {
2160 found = true;
2161 break;
2162 }
2163 target_index++;
2164 if (target_index >= this->orders.list->GetNumOrders()) {
2165 if (this->GetNumManualOrders() == 0 &&
2166 this->GetNumOrders() < IMPLICIT_ORDER_ONLY_CAP) {
2167 break;
2168 }
2169 target_index = 0;
2170 }
2171 if (target_index == this->cur_implicit_order_index) break; // Avoid infinite loop.
2172 }
2173
2174 if (found) {
2175 if (suppress_implicit_orders) {
2176 /* Skip to the found order */
2177 this->cur_implicit_order_index = target_index;
2178 InvalidateVehicleOrder(this, 0);
2179 } else {
2180 /* Delete all implicit orders up to the station we just reached */
2181 const Order *order = this->GetOrder(this->cur_implicit_order_index);
2182 while (!order->IsType(OT_IMPLICIT) || order->GetDestination() != this->last_station_visited) {
2183 if (order->IsType(OT_IMPLICIT)) {
2184 DeleteOrder(this, this->cur_implicit_order_index);
2185 /* DeleteOrder does various magic with order_indices, so resync 'order' with 'cur_implicit_order_index' */
2186 order = this->GetOrder(this->cur_implicit_order_index);
2187 } else {
2188 /* Skip non-implicit orders, e.g. service-orders */
2189 order = order->next;
2190 this->cur_implicit_order_index++;
2191 }
2192
2193 /* Wrap around */
2194 if (order == nullptr) {
2195 order = this->GetOrder(0);
2196 this->cur_implicit_order_index = 0;
2197 }
2198 assert(order != nullptr);
2199 }
2200 }
2201 } else if (!suppress_implicit_orders &&
2202 ((this->orders.list == nullptr ? OrderList::CanAllocateItem() : this->orders.list->GetNumOrders() < MAX_VEH_ORDER_ID)) &&
2203 Order::CanAllocateItem()) {
2204 /* Insert new implicit order */
2205 Order *implicit_order = new Order();
2206 implicit_order->MakeImplicit(this->last_station_visited);
2207 InsertOrder(this, implicit_order, this->cur_implicit_order_index);
2208 if (this->cur_implicit_order_index > 0) --this->cur_implicit_order_index;
2209
2210 /* InsertOrder disabled creation of implicit orders for all vehicles with the same implicit order.
2211 * Reenable it for this vehicle */
2212 uint16 &gv_flags = this->GetGroundVehicleFlags();
2213 ClrBit(gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS);
2214 }
2215 }
2216 }
2217 this->current_order.MakeLoading(false);
2218 }
2219
2220 if (this->last_loading_station != INVALID_STATION &&
2221 this->last_loading_station != this->last_station_visited &&
2222 ((this->current_order.GetLoadType() & OLFB_NO_LOAD) == 0 ||
2223 (this->current_order.GetUnloadType() & OUFB_NO_UNLOAD) == 0)) {
2224 IncreaseStats(Station::Get(this->last_loading_station), this, this->last_station_visited, travel_time);
2225 }
2226
2227 PrepareUnload(this);
2228
2229 SetWindowDirty(GetWindowClassForVehicleType(this->type), this->owner);
2230 SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
2231 SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
2232 SetWindowDirty(WC_STATION_VIEW, this->last_station_visited);
2233
2234 Station::Get(this->last_station_visited)->MarkTilesDirty(true);
2235 this->cur_speed = 0;
2236 this->MarkDirty();
2237 }
2238
2244 void Vehicle::CancelReservation(StationID next, Station *st)
2245 {
2246 for (Vehicle *v = this; v != nullptr; v = v->next) {
2247 VehicleCargoList &cargo = v->cargo;
2248 if (cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0) {
2249 Debug(misc, 1, "cancelling cargo reservation");
2250 cargo.Return(UINT_MAX, &st->goods[v->cargo_type].cargo, next);
2251 cargo.SetTransferLoadPlace(st->xy);
2252 }
2253 cargo.KeepAll();
2254 }
2255 }
2256
2261 void Vehicle::LeaveStation()
2262 {
2263 assert(this->current_order.IsType(OT_LOADING));
2264
2265 delete this->cargo_payment;
2266 assert(this->cargo_payment == nullptr); // cleared by ~CargoPayment
2267
2268 /* Only update the timetable if the vehicle was supposed to stop here. */
2269 if (this->current_order.GetNonStopType() != ONSF_STOP_EVERYWHERE) UpdateVehicleTimetable(this, false);
2270
2271 if ((this->current_order.GetLoadType() & OLFB_NO_LOAD) == 0 ||
2272 (this->current_order.GetUnloadType() & OUFB_NO_UNLOAD) == 0) {
2273 if (this->current_order.CanLeaveWithCargo(this->last_loading_station != INVALID_STATION)) {
2274 /* Refresh next hop stats to make sure we've done that at least once
2275 * during the stop and that refit_cap == cargo_cap for each vehicle in
2276 * the consist. */
2277 this->ResetRefitCaps();
2278 LinkRefresher::Run(this);
2279
2280 /* if the vehicle could load here or could stop with cargo loaded set the last loading station */
2281 this->last_loading_station = this->last_station_visited;
2282 } else {
2283 /* if the vehicle couldn't load and had to unload or transfer everything
2284 * set the last loading station to invalid as it will leave empty. */
2285 this->last_loading_station = INVALID_STATION;
2286 }
2287 }
2288
2289 this->current_order.MakeLeaveStation();
2290 Station *st = Station::Get(this->last_station_visited);
2291 this->CancelReservation(INVALID_STATION, st);
2292 st->loading_vehicles.remove(this);
2293
2294 HideFillingPercent(&this->fill_percent_te_id);
2295 trip_occupancy = CalcPercentVehicleFilled(this, nullptr);
2296
2297 if (this->type == VEH_TRAIN && !(this->vehstatus & VS_CRASHED)) {
2298 /* Trigger station animation (trains only) */
2299 if (IsTileType(this->tile, MP_STATION)) {
2300 TriggerStationRandomisation(st, this->tile, SRT_TRAIN_DEPARTS);
2301 TriggerStationAnimation(st, this->tile, SAT_TRAIN_DEPARTS);
2302 }
2303
2304 SetBit(Train::From(this)->flags, VRF_LEAVING_STATION);
2305 }
2306
2307 this->MarkDirty();
2308 }
2309
2313 void Vehicle::ResetRefitCaps()
2314 {
2315 for (Vehicle *v = this; v != nullptr; v = v->Next()) v->refit_cap = v->cargo_cap;
2316 }
2317
2323 void Vehicle::HandleLoading(bool mode)
2324 {
2325 switch (this->current_order.GetType()) {
2326 case OT_LOADING: {
2327 uint wait_time = std::max(this->current_order.GetTimetabledWait() - this->lateness_counter, 0);
2328
2329 /* Not the first call for this tick, or still loading */
2330 if (mode || !HasBit(this->vehicle_flags, VF_LOADING_FINISHED) || this->current_order_time < wait_time) return;
2331
2332 this->PlayLeaveStationSound();
2333
2334 this->LeaveStation();
2335
2336 /* Only advance to next order if we just loaded at the current one */
2337 const Order *order = this->GetOrder(this->cur_implicit_order_index);
2338 if (order == nullptr ||
2339 (!order->IsType(OT_IMPLICIT) && !order->IsType(OT_GOTO_STATION)) ||
2340 order->GetDestination() != this->last_station_visited) {
2341 return;
2342 }
2343 break;
2344 }
2345
2346 case OT_DUMMY: break;
2347
2348 default: return;
2349 }
2350
2351 this->IncrementImplicitOrderIndex();
2352 }
2353
2358 void Vehicle::GetConsistFreeCapacities(SmallMap<CargoID, uint> &capacities) const
2359 {
2360 for (const Vehicle *v = this; v != nullptr; v = v->Next()) {
2361 if (v->cargo_cap == 0) continue;
2362 std::pair<CargoID, uint> *pair = capacities.Find(v->cargo_type);
2363 if (pair == capacities.End()) {
2364 capacities.push_back({v->cargo_type, v->cargo_cap - v->cargo.StoredCount()});
2365 } else {
2366 pair->second += v->cargo_cap - v->cargo.StoredCount();
2367 }
2368 }
2369 }
2370
2371 uint Vehicle::GetConsistTotalCapacity() const
2372 {
2373 uint result = 0;
2374 for (const Vehicle *v = this; v != nullptr; v = v->Next()) {
2375 result += v->cargo_cap;
2376 }
2377 return result;
2378 }
2379
2386 CommandCost Vehicle::SendToDepot(DoCommandFlag flags, DepotCommand command)
2387 {
2388 CommandCost ret = CheckOwnership(this->owner);
2389 if (ret.Failed()) return ret;
2390
2391 if (this->vehstatus & VS_CRASHED) return CMD_ERROR;
2392 if (this->IsStoppedInDepot()) return CMD_ERROR;
2393
2394 if (this->current_order.IsType(OT_GOTO_DEPOT)) {
2395 bool halt_in_depot = (this->current_order.GetDepotActionType() & ODATFB_HALT) != 0;
2396 if (!!(command & DEPOT_SERVICE) == halt_in_depot) {
2397 /* We called with a different DEPOT_SERVICE setting.
2398 * Now we change the setting to apply the new one and let the vehicle head for the same depot.
2399 * Note: the if is (true for requesting service == true for ordered to stop in depot) */
2400 if (flags & DC_EXEC) {
2401 this->current_order.SetDepotOrderType(ODTF_MANUAL);
2402 this->current_order.SetDepotActionType(halt_in_depot ? ODATF_SERVICE_ONLY : ODATFB_HALT);
2403 SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
2404 }
2405 return CommandCost();
2406 }
2407
2408 if (command & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancellation of depot orders
2409 if (flags & DC_EXEC) {
2410 /* If the orders to 'goto depot' are in the orders list (forced servicing),
2411 * then skip to the next order; effectively cancelling this forced service */
2412 if (this->current_order.GetDepotOrderType() & ODTFB_PART_OF_ORDERS) this->IncrementRealOrderIndex();
2413
2414 if (this->IsGroundVehicle()) {
2415 uint16 &gv_flags = this->GetGroundVehicleFlags();
2416 SetBit(gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS);
2417 }
2418
2419 this->current_order.MakeDummy();
2420 SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
2421 }
2422 return CommandCost();
2423 }
2424
2425 TileIndex location;
2426 DestinationID destination;
2427 bool reverse;
2428 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};
2429 if (!this->FindClosestDepot(&location, &destination, &reverse)) return_cmd_error(no_depot[this->type]);
2430
2431 if (flags & DC_EXEC) {
2432 if (this->current_order.IsType(OT_LOADING)) this->LeaveStation();
2433
2434 if (this->IsGroundVehicle() && this->GetNumManualOrders() > 0) {
2435 uint16 &gv_flags = this->GetGroundVehicleFlags();
2436 SetBit(gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS);
2437 }
2438
2439 this->SetDestTile(location);
2440 this->current_order.MakeGoToDepot(destination, ODTF_MANUAL);
2441 if (!(command & DEPOT_SERVICE)) this->current_order.SetDepotActionType(ODATFB_HALT);
2442 SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
2443
2444 /* If there is no depot in front and the train is not already reversing, reverse automatically (trains only) */
2445 if (this->type == VEH_TRAIN && (reverse ^ HasBit(Train::From(this)->flags, VRF_REVERSING))) {
2446 DoCommand(this->tile, this->index, 0, DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION);
2447 }
2448
2449 if (this->type == VEH_AIRCRAFT) {
2450 Aircraft *a = Aircraft::From(this);
2451 if (a->state == FLYING && a->targetairport != destination) {
2452 /* The aircraft is now heading for a different hangar than the next in the orders */
2453 extern void AircraftNextAirportPos_and_Order(Aircraft *a);
2454 AircraftNextAirportPos_and_Order(a);
2455 }
2456 }
2457 }
2458
2459 return CommandCost();
2460
2461 }
2462
2467 void Vehicle::UpdateVisualEffect(bool allow_power_change)
2468 {
2469 bool powered_before = HasBit(this->vcache.cached_vis_effect, VE_DISABLE_WAGON_POWER);
2470 const Engine *e = this->GetEngine();
2471
2472 /* Evaluate properties */
2473 byte visual_effect;
2474 switch (e->type) {
2475 case VEH_TRAIN: visual_effect = e->u.rail.visual_effect; break;
2476 case VEH_ROAD: visual_effect = e->u.road.visual_effect; break;
2477 case VEH_SHIP: visual_effect = e->u.ship.visual_effect; break;
2478 default: visual_effect = 1 << VE_DISABLE_EFFECT; break;
2479 }
2480
2481 /* Check powered wagon / visual effect callback */
2482 if (HasBit(e->info.callback_mask, CBM_VEHICLE_VISUAL_EFFECT)) {
2483 uint16 callback = GetVehicleCallback(CBID_VEHICLE_VISUAL_EFFECT, 0, 0, this->engine_type, this);
2484
2485 if (callback != CALLBACK_FAILED) {
2486 if (callback >= 0x100 && e->GetGRF()->grf_version >= 8) ErrorUnknownCallbackResult(e->GetGRFID(), CBID_VEHICLE_VISUAL_EFFECT, callback);
2487
2488 callback = GB(callback, 0, 8);
2489 /* Avoid accidentally setting 'visual_effect' to the default value
2490 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
2491 if (callback == VE_DEFAULT) {
2492 assert(HasBit(callback, VE_DISABLE_EFFECT));
2493 SB(callback, VE_TYPE_START, VE_TYPE_COUNT, 0);
2494 }
2495 visual_effect = callback;
2496 }
2497 }
2498
2499 /* Apply default values */
2500 if (visual_effect == VE_DEFAULT ||
2501 (!HasBit(visual_effect, VE_DISABLE_EFFECT) && GB(visual_effect, VE_TYPE_START, VE_TYPE_COUNT) == VE_TYPE_DEFAULT)) {
2502 /* Only train engines have default effects.
2503 * Note: This is independent of whether the engine is a front engine or articulated part or whatever. */
2504 if (e->type != VEH_TRAIN || e->u.rail.railveh_type == RAILVEH_WAGON || !IsInsideMM(e->u.rail.engclass, EC_STEAM, EC_MONORAIL)) {
2505 if (visual_effect == VE_DEFAULT) {
2506 visual_effect = 1 << VE_DISABLE_EFFECT;
2507 } else {
2508 SetBit(visual_effect, VE_DISABLE_EFFECT);
2509 }
2510 } else {
2511 if (visual_effect == VE_DEFAULT) {
2512 /* Also set the offset */
2513 visual_effect = (VE_OFFSET_CENTRE - (e->u.rail.engclass == EC_STEAM ? 4 : 0)) << VE_OFFSET_START;
2514 }
2515 SB(visual_effect, VE_TYPE_START, VE_TYPE_COUNT, e->u.rail.engclass - EC_STEAM + VE_TYPE_STEAM);
2516 }
2517 }
2518
2519 this->vcache.cached_vis_effect = visual_effect;
2520
2521 if (!allow_power_change && powered_before != HasBit(this->vcache.cached_vis_effect, VE_DISABLE_WAGON_POWER)) {
2522 ToggleBit(this->vcache.cached_vis_effect, VE_DISABLE_WAGON_POWER);
2523 ShowNewGrfVehicleError(this->engine_type, STR_NEWGRF_BROKEN, STR_NEWGRF_BROKEN_POWERED_WAGON, GBUG_VEH_POWERED_WAGON, false);
2524 }
2525 }
2526
2527 static const int8 _vehicle_smoke_pos[8] = {
2528 1, 1, 1, 0, -1, -1, -1, 0
2529 };
2530
2535 static void SpawnAdvancedVisualEffect(const Vehicle *v)
2536 {
2537 uint16 callback = GetVehicleCallback(CBID_VEHICLE_SPAWN_VISUAL_EFFECT, 0, Random(), v->engine_type, v);
2538 if (callback == CALLBACK_FAILED) return;
2539
2540 uint count = GB(callback, 0, 2);
2541 bool auto_center = HasBit(callback, 13);
2542 bool auto_rotate = !HasBit(callback, 14);
2543
2544 int8 l_center = 0;
2545 if (auto_center) {
2546 /* For road vehicles: Compute offset from vehicle position to vehicle center */
2547 if (v->type == VEH_ROAD) l_center = -(int)(VEHICLE_LENGTH - RoadVehicle::From(v)->gcache.cached_veh_length) / 2;
2548 } else {
2549 /* For trains: Compute offset from vehicle position to sprite position */
2550 if (v->type == VEH_TRAIN) l_center = (VEHICLE_LENGTH - Train::From(v)->gcache.cached_veh_length) / 2;
2551 }
2552
2553 Direction l_dir = v->direction;
2554 if (v->type == VEH_TRAIN && HasBit(Train::From(v)->flags, VRF_REVERSE_DIRECTION)) l_dir = ReverseDir(l_dir);
2555 Direction t_dir = ChangeDir(l_dir, DIRDIFF_90RIGHT);
2556
2557 int8 x_center = _vehicle_smoke_pos[l_dir] * l_center;
2558 int8 y_center = _vehicle_smoke_pos[t_dir] * l_center;
2559
2560 for (uint i = 0; i < count; i++) {
2561 uint32 reg = GetRegister(0x100 + i);
2562 uint type = GB(reg, 0, 8);
2563 int8 x = GB(reg, 8, 8);
2564 int8 y = GB(reg, 16, 8);
2565 int8 z = GB(reg, 24, 8);
2566
2567 if (auto_rotate) {
2568 int8 l = x;
2569 int8 t = y;
2570 x = _vehicle_smoke_pos[l_dir] * l + _vehicle_smoke_pos[t_dir] * t;
2571 y = _vehicle_smoke_pos[t_dir] * l - _vehicle_smoke_pos[l_dir] * t;
2572 }
2573
2574 if (type >= 0xF0) {
2575 switch (type) {
2576 case 0xF1: CreateEffectVehicleRel(v, x_center + x, y_center + y, z, EV_STEAM_SMOKE); break;
2577 case 0xF2: CreateEffectVehicleRel(v, x_center + x, y_center + y, z, EV_DIESEL_SMOKE); break;
2578 case 0xF3: CreateEffectVehicleRel(v, x_center + x, y_center + y, z, EV_ELECTRIC_SPARK); break;
2579 case 0xFA: CreateEffectVehicleRel(v, x_center + x, y_center + y, z, EV_BREAKDOWN_SMOKE_AIRCRAFT); break;
2580 default: break;
2581 }
2582 }
2583 }
2584 }
2585
2590 void Vehicle::ShowVisualEffect() const
2591 {
2592 assert(this->IsPrimaryVehicle());
2593 bool sound = false;
2594
2595 /* Do not show any smoke when:
2596 * - vehicle smoke is disabled by the player
2597 * - the vehicle is slowing down or stopped (by the player)
2598 * - the vehicle is moving very slowly
2599 */
2600 if (_settings_game.vehicle.smoke_amount == 0 ||
2601 this->vehstatus & (VS_TRAIN_SLOWING | VS_STOPPED) ||
2602 this->cur_speed < 2) {
2603 return;
2604 }
2605
2606 /* Use the speed as limited by underground and orders. */
2607 uint max_speed = this->GetCurrentMaxSpeed();
2608
2609 if (this->type == VEH_TRAIN) {
2610 const Train *t = Train::From(this);
2611 /* For trains, do not show any smoke when:
2612 * - the train is reversing
2613 * - is entering a station with an order to stop there and its speed is equal to maximum station entering speed
2614 */
2615 if (HasBit(t->flags, VRF_REVERSING) ||
2616 (IsRailStationTile(t->tile) && t->IsFrontEngine() && t->current_order.ShouldStopAtStation(t, GetStationIndex(t->tile)) &&
2617 t->cur_speed >= max_speed)) {
2618 return;
2619 }
2620 }
2621
2622 const Vehicle *v = this;
2623
2624 do {
2625 bool advanced = HasBit(v->vcache.cached_vis_effect, VE_ADVANCED_EFFECT);
2626 int effect_offset = GB(v->vcache.cached_vis_effect, VE_OFFSET_START, VE_OFFSET_COUNT) - VE_OFFSET_CENTRE;
2627 VisualEffectSpawnModel effect_model = VESM_NONE;
2628 if (advanced) {
2629 effect_offset = VE_OFFSET_CENTRE;
2630 effect_model = (VisualEffectSpawnModel)GB(v->vcache.cached_vis_effect, 0, VE_ADVANCED_EFFECT);
2631 if (effect_model >= VESM_END) effect_model = VESM_NONE; // unknown spawning model
2632 } else {
2633 effect_model = (VisualEffectSpawnModel)GB(v->vcache.cached_vis_effect, VE_TYPE_START, VE_TYPE_COUNT);
2634 assert(effect_model != (VisualEffectSpawnModel)VE_TYPE_DEFAULT); // should have been resolved by UpdateVisualEffect
2635 static_assert((uint)VESM_STEAM == (uint)VE_TYPE_STEAM);
2636 static_assert((uint)VESM_DIESEL == (uint)VE_TYPE_DIESEL);
2637 static_assert((uint)VESM_ELECTRIC == (uint)VE_TYPE_ELECTRIC);
2638 }
2639
2640 /* Show no smoke when:
2641 * - Smoke has been disabled for this vehicle
2642 * - The vehicle is not visible
2643 * - The vehicle is under a bridge
2644 * - The vehicle is on a depot tile
2645 * - The vehicle is on a tunnel tile
2646 * - The vehicle is a train engine that is currently unpowered */
2647 if (effect_model == VESM_NONE ||
2648 v->vehstatus & VS_HIDDEN ||
2649 IsBridgeAbove(v->tile) ||
2650 IsDepotTile(v->tile) ||
2651 IsTunnelTile(v->tile) ||
2652 (v->type == VEH_TRAIN &&
2653 !HasPowerOnRail(Train::From(v)->railtype, GetTileRailType(v->tile)))) {
2654 continue;
2655 }
2656
2657 EffectVehicleType evt = EV_END;
2658 switch (effect_model) {
2659 case VESM_STEAM:
2660 /* Steam smoke - amount is gradually falling until vehicle reaches its maximum speed, after that it's normal.
2661 * Details: while vehicle's current speed is gradually increasing, steam plumes' density decreases by one third each
2662 * third of its maximum speed spectrum. Steam emission finally normalises at very close to vehicle's maximum speed.
2663 * REGULATION:
2664 * - instead of 1, 4 / 2^smoke_amount (max. 2) is used to provide sufficient regulation to steam puffs' amount. */
2665 if (GB(v->tick_counter, 0, ((4 >> _settings_game.vehicle.smoke_amount) + ((this->cur_speed * 3) / max_speed))) == 0) {
2666 evt = EV_STEAM_SMOKE;
2667 }
2668 break;
2669
2670 case VESM_DIESEL: {
2671 /* Diesel smoke - thicker when vehicle is starting, gradually subsiding till it reaches its maximum speed
2672 * when smoke emission stops.
2673 * Details: Vehicle's (max.) speed spectrum is divided into 32 parts. When max. speed is reached, chance for smoke
2674 * emission erodes by 32 (1/4). For trains, power and weight come in handy too to either increase smoke emission in
2675 * 6 steps (1000HP each) if the power is low or decrease smoke emission in 6 steps (512 tonnes each) if the train
2676 * isn't overweight. Power and weight contributions are expressed in a way that neither extreme power, nor
2677 * extreme weight can ruin the balance (e.g. FreightWagonMultiplier) in the formula. When the vehicle reaches
2678 * maximum speed no diesel_smoke is emitted.
2679 * REGULATION:
2680 * - up to which speed a diesel vehicle is emitting smoke (with reduced/small setting only until 1/2 of max_speed),
2681 * - in Chance16 - the last value is 512 / 2^smoke_amount (max. smoke when 128 = smoke_amount of 2). */
2682 int power_weight_effect = 0;
2683 if (v->type == VEH_TRAIN) {
2684 power_weight_effect = (32 >> (Train::From(this)->gcache.cached_power >> 10)) - (32 >> (Train::From(this)->gcache.cached_weight >> 9));
2685 }
2686 if (this->cur_speed < (max_speed >> (2 >> _settings_game.vehicle.smoke_amount)) &&
2687 Chance16((64 - ((this->cur_speed << 5) / max_speed) + power_weight_effect), (512 >> _settings_game.vehicle.smoke_amount))) {
2688 evt = EV_DIESEL_SMOKE;
2689 }
2690 break;
2691 }
2692
2693 case VESM_ELECTRIC:
2694 /* Electric train's spark - more often occurs when train is departing (more load)
2695 * Details: Electric locomotives are usually at least twice as powerful as their diesel counterparts, so spark
2696 * emissions are kept simple. Only when starting, creating huge force are sparks more likely to happen, but when
2697 * reaching its max. speed, quarter by quarter of it, chance decreases until the usual 2,22% at train's top speed.
2698 * REGULATION:
2699 * - in Chance16 the last value is 360 / 2^smoke_amount (max. sparks when 90 = smoke_amount of 2). */
2700 if (GB(v->tick_counter, 0, 2) == 0 &&
2701 Chance16((6 - ((this->cur_speed << 2) / max_speed)), (360 >> _settings_game.vehicle.smoke_amount))) {
2702 evt = EV_ELECTRIC_SPARK;
2703 }
2704 break;
2705
2706 default:
2707 NOT_REACHED();
2708 }
2709
2710 if (evt != EV_END && advanced) {
2711 sound = true;
2712 SpawnAdvancedVisualEffect(v);
2713 } else if (evt != EV_END) {
2714 sound = true;
2715
2716 /* The effect offset is relative to a point 4 units behind the vehicle's
2717 * front (which is the center of an 8/8 vehicle). Shorter vehicles need a
2718 * correction factor. */
2719 if (v->type == VEH_TRAIN) effect_offset += (VEHICLE_LENGTH - Train::From(v)->gcache.cached_veh_length) / 2;
2720
2721 int x = _vehicle_smoke_pos[v->direction] * effect_offset;
2722 int y = _vehicle_smoke_pos[(v->direction + 2) % 8] * effect_offset;
2723
2724 if (v->type == VEH_TRAIN && HasBit(Train::From(v)->flags, VRF_REVERSE_DIRECTION)) {
2725 x = -x;
2726 y = -y;
2727 }
2728
2729 CreateEffectVehicleRel(v, x, y, 10, evt);
2730 }
2731 } while ((v = v->Next()) != nullptr);
2732
2733 if (sound) PlayVehicleSound(this, VSE_VISUAL_EFFECT);
2734 }
2735
2740 void Vehicle::SetNext(Vehicle *next)
2741 {
2742 assert(this != next);
2743
2744 if (this->next != nullptr) {
2745 /* We had an old next vehicle. Update the first and previous pointers */
2746 for (Vehicle *v = this->next; v != nullptr; v = v->Next()) {
2747 v->first = this->next;
2748 }
2749 this->next->previous = nullptr;
2750 }
2751
2752 this->next = next;
2753
2754 if (this->next != nullptr) {
2755 /* A new next vehicle. Update the first and previous pointers */
2756 if (this->next->previous != nullptr) this->next->previous->next = nullptr;
2757 this->next->previous = this;
2758 for (Vehicle *v = this->next; v != nullptr; v = v->Next()) {
2759 v->first = this->first;
2760 }
2761 }
2762 }
2763
2769 void Vehicle::AddToShared(Vehicle *shared_chain)
2770 {
2771 assert(this->previous_shared == nullptr && this->next_shared == nullptr);
2772
2773 if (shared_chain->orders.list == nullptr) {
2774 assert(shared_chain->previous_shared == nullptr);
2775 assert(shared_chain->next_shared == nullptr);
2776 this->orders.list = shared_chain->orders.list = new OrderList(nullptr, shared_chain);
2777 }
2778
2779 this->next_shared = shared_chain->next_shared;
2780 this->previous_shared = shared_chain;
2781
2782 shared_chain->next_shared = this;
2783
2784 if (this->next_shared != nullptr) this->next_shared->previous_shared = this;
2785
2786 shared_chain->orders.list->AddVehicle(this);
2787 }
2788
2792 void Vehicle::RemoveFromShared()
2793 {
2794 /* Remember if we were first and the old window number before RemoveVehicle()
2795 * as this changes first if needed. */
2796 bool were_first = (this->FirstShared() == this);
2797 VehicleListIdentifier vli(VL_SHARED_ORDERS, this->type, this->owner, this->FirstShared()->index);
2798
2799 this->orders.list->RemoveVehicle(this);
2800
2801 if (!were_first) {
2802 /* We are not the first shared one, so only relink our previous one. */
2803 this->previous_shared->next_shared = this->NextShared();
2804 }
2805
2806 if (this->next_shared != nullptr) this->next_shared->previous_shared = this->previous_shared;
2807
2808
2809 if (this->orders.list->GetNumVehicles() == 1) {
2810 /* When there is only one vehicle, remove the shared order list window. */
2811 CloseWindowById(GetWindowClassForVehicleType(this->type), vli.Pack());
2812 InvalidateVehicleOrder(this->FirstShared(), VIWD_MODIFY_ORDERS);
2813 } else if (were_first) {
2814 /* If we were the first one, update to the new first one.
2815 * Note: FirstShared() is already the new first */
2816 InvalidateWindowData(GetWindowClassForVehicleType(this->type), vli.Pack(), this->FirstShared()->index | (1U << 31));
2817 }
2818
2819 this->next_shared = nullptr;
2820 this->previous_shared = nullptr;
2821 }
2822
2823 void VehiclesYearlyLoop()
2824 {
2825 for (Vehicle *v : Vehicle::Iterate()) {
2826 if (v->IsPrimaryVehicle()) {
2827 /* show warning if vehicle is not generating enough income last 2 years (corresponds to a red icon in the vehicle list) */
2828 Money profit = v->GetDisplayProfitThisYear();
2829 if (v->age >= 730 && profit < 0) {
2830 if (_settings_client.gui.vehicle_income_warn && v->owner == _local_company) {
2831 SetDParam(0, v->index);
2832 SetDParam(1, profit);
2833 AddVehicleAdviceNewsItem(STR_NEWS_VEHICLE_IS_UNPROFITABLE, v->index);
2834 }
2835 AI::NewEvent(v->owner, new ScriptEventVehicleUnprofitable(v->index));
2836 }
2837
2838 v->profit_last_year = v->profit_this_year;
2839 v->profit_this_year = 0;
2840 SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
2841 }
2842 }
2843 GroupStatistics::UpdateProfits();
2844 SetWindowClassesDirty(WC_TRAINS_LIST);
2845 SetWindowClassesDirty(WC_SHIPS_LIST);
2846 SetWindowClassesDirty(WC_ROADVEH_LIST);
2847 SetWindowClassesDirty(WC_AIRCRAFT_LIST);
2848 }
2849
2850
2860 bool CanVehicleUseStation(EngineID engine_type, const Station *st)
2861 {
2862 const Engine *e = Engine::GetIfValid(engine_type);
2863 assert(e != nullptr);
2864
2865 switch (e->type) {
2866 case VEH_TRAIN:
2867 return (st->facilities & FACIL_TRAIN) != 0;
2868
2869 case VEH_ROAD:
2870 /* For road vehicles we need the vehicle to know whether it can actually
2871 * use the station, but if it doesn't have facilities for RVs it is
2872 * certainly not possible that the station can be used. */
2873 return (st->facilities & (FACIL_BUS_STOP | FACIL_TRUCK_STOP)) != 0;
2874
2875 case VEH_SHIP:
2876 return (st->facilities & FACIL_DOCK) != 0;
2877
2878 case VEH_AIRCRAFT:
2879 return (st->facilities & FACIL_AIRPORT) != 0 &&
2880 (st->airport.GetFTA()->flags & (e->u.air.subtype & AIR_CTOL ? AirportFTAClass::AIRPLANES : AirportFTAClass::HELICOPTERS)) != 0;
2881
2882 default:
2883 return false;
2884 }
2885 }
2886
2893 bool CanVehicleUseStation(const Vehicle *v, const Station *st)
2894 {
2895 if (v->type == VEH_ROAD) return st->GetPrimaryRoadStop(RoadVehicle::From(v)) != nullptr;
2896
2897 return CanVehicleUseStation(v->engine_type, st);
2898 }
2899
2905 GroundVehicleCache *Vehicle::GetGroundVehicleCache()
2906 {
2907 assert(this->IsGroundVehicle());
2908 if (this->type == VEH_TRAIN) {
2909 return &Train::From(this)->gcache;
2910 } else {
2911 return &RoadVehicle::From(this)->gcache;
2912 }
2913 }
2914
2920 const GroundVehicleCache *Vehicle::GetGroundVehicleCache() const
2921 {
2922 assert(this->IsGroundVehicle());
2923 if (this->type == VEH_TRAIN) {
2924 return &Train::From(this)->gcache;
2925 } else {
2926 return &RoadVehicle::From(this)->gcache;
2927 }
2928 }
2929
2935 uint16 &Vehicle::GetGroundVehicleFlags()
2936 {
2937 assert(this->IsGroundVehicle());
2938 if (this->type == VEH_TRAIN) {
2939 return Train::From(this)->gv_flags;
2940 } else {
2941 return RoadVehicle::From(this)->gv_flags;
2942 }
2943 }
2944
2950 const uint16 &Vehicle::GetGroundVehicleFlags() const
2951 {
2952 assert(this->IsGroundVehicle());
2953 if (this->type == VEH_TRAIN) {
2954 return Train::From(this)->gv_flags;
2955 } else {
2956 return RoadVehicle::From(this)->gv_flags;
2957 }
2958 }
2959
2968 void GetVehicleSet(VehicleSet &set, Vehicle *v, uint8 num_vehicles)
2969 {
2970 if (v->type == VEH_TRAIN) {
2971 Train *u = Train::From(v);
2972 /* Only include whole vehicles, so start with the first articulated part */
2973 u = u->GetFirstEnginePart();
2974
2975 /* Include num_vehicles vehicles, not counting articulated parts */
2976 for (; u != nullptr && num_vehicles > 0; num_vehicles--) {
2977 do {
2978 /* Include current vehicle in the selection. */
2979 include(set, u->index);
2980
2981 /* If the vehicle is multiheaded, add the other part too. */
2982 if (u->IsMultiheaded()) include(set, u->other_multiheaded_part->index);
2983
2984 u = u->Next();
2985 } while (u != nullptr && u->IsArticulatedPart());
2986 }
2987 }
2988 }
VEH_AIRCRAFT
@ VEH_AIRCRAFT
Aircraft vehicle type.
Definition: vehicle_type.h:27
GUISettings::lost_vehicle_warn
bool lost_vehicle_warn
if a vehicle can't find its destination, show a warning
Definition: settings_type.h:107
RoadVehicle
Buses, trucks and trams belong to this class.
Definition: roadveh.h:107
Vehicle::GetGroundVehicleCache
GroundVehicleCache * GetGroundVehicleCache()
Access the ground vehicle cache of the vehicle.
Definition: vehicle.cpp:2905
DeleteNewGRFInspectWindow
void DeleteNewGRFInspectWindow(GrfSpecFeature feature, uint index)
Delete inspect window for a given feature and index.
Definition: newgrf_debug_gui.cpp:734
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
IsTunnelTile
static bool IsTunnelTile(TileIndex t)
Is this a tunnel (entrance)?
Definition: tunnel_map.h:34
BaseStation::facilities
StationFacility facilities
The facilities that this station has.
Definition: base_station_base.h:63
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:29
INVALID_ENGINE
static const EngineID INVALID_ENGINE
Constant denoting an invalid engine.
Definition: engine_type.h:175
IsCompanyBuildableVehicleType
static bool IsCompanyBuildableVehicleType(VehicleType type)
Is the given vehicle type buildable by a company?
Definition: vehicle_func.h:89
PlayVehicleSound
bool PlayVehicleSound(const Vehicle *v, VehicleSoundEvent event)
Checks whether a NewGRF wants to play a different vehicle sound effect.
Definition: newgrf_sound.cpp:186
tunnel_map.h
Order::IsRefit
bool IsRefit() const
Is this order a refit order.
Definition: order_base.h:111
VehicleSettings::max_aircraft
UnitID max_aircraft
max planes in game per company
Definition: settings_type.h:487
WC_ROADVEH_LIST
@ WC_ROADVEH_LIST
Road vehicle list; Window numbers:
Definition: window_type.h:306
Engine::GetGRFID
uint32 GetGRFID() const
Retrieve the GRF ID of the NewGRF the engine is tied to.
Definition: engine.cpp:147
MutableSpriteCache::is_viewport_candidate
bool is_viewport_candidate
This vehicle can potentially be drawn on a viewport.
Definition: vehicle_base.h:193
TileIndex
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:83
VehicleCargoList::StoredCount
uint StoredCount() const
Returns sum of cargo on board the vehicle (ie not only reserved).
Definition: cargopacket.h:352
RoadVehicle::state
byte state
Definition: roadveh.h:109
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:1974
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:3234
Order::MakeDummy
void MakeDummy()
Makes this order a Dummy order.
Definition: order_cmd.cpp:132
sound_func.h
UpdateVehicleTimetable
void UpdateVehicleTimetable(Vehicle *v, bool travelling)
Update the timetable for the vehicle.
Definition: timetable_cmd.cpp:372
Station::goods
GoodsEntry goods[NUM_CARGO]
Goods at this station.
Definition: station_base.h:476
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:66
VE_OFFSET_COUNT
@ VE_OFFSET_COUNT
Number of bits used for the offset.
Definition: vehicle_base.h:79
AircraftNextAirportPos_and_Order
void AircraftNextAirportPos_and_Order(Aircraft *v)
set the right pos when heading to other airports after takeoff
Definition: aircraft_cmd.cpp:1431
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:161
VE_DISABLE_EFFECT
@ VE_DISABLE_EFFECT
Flag to disable visual effect.
Definition: vehicle_base.h:89
newgrf_station.h
Chance16
static bool Chance16(const uint a, const uint b)
Flips a coin with given probability.
Definition: random_func.hpp:131
DoCommand
CommandCost DoCommand(const CommandContainer *container, DoCommandFlag flags)
Shorthand for calling the long DoCommand with a container.
Definition: command.cpp:450
CMD_REVERSE_TRAIN_DIRECTION
@ CMD_REVERSE_TRAIN_DIRECTION
turn a train around
Definition: command_type.h:222
Order::IsType
bool IsType(OrderType type) const
Check whether this order is of the given type.
Definition: order_base.h:64
Vehicle::PreDestructor
void PreDestructor()
Destroy all stuff that (still) needs the virtual functions to work properly.
Definition: vehicle.cpp:814
Pool::PoolItem<&_company_pool >::Get
static Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:337
PrepareUnload
void PrepareUnload(Vehicle *front_v)
Prepare the vehicle to be unloaded.
Definition: economy.cpp:1250
Direction
Direction
Defines the 8 directions on the map.
Definition: direction_type.h:24
Order::GetTimetabledWait
uint16 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:182
Vehicle::y_pos
int32 y_pos
y coordinate.
Definition: vehicle_base.h:281
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:167
SetWindowDirty
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition: window.cpp:3136
MutableSpriteCache::sprite_seq
VehicleSpriteSeq sprite_seq
Vehicle appearance.
Definition: vehicle_base.h:194
GroupStatistics::CountEngine
static void CountEngine(const Vehicle *v, int delta)
Update num_engines when adding/removing an engine.
Definition: group_cmd.cpp:156
Company::group_all
GroupStatistics group_all[VEH_COMPANY_END]
NOSAVE: Statistics for the ALL_GROUP group.
Definition: company_base.h:125
GB
static uint GB(const T x, const uint8 s, const uint8 n)
Fetch n bits from x, started at bit s.
Definition: bitmath_func.hpp:32
Vehicle::GetNumManualOrders
VehicleOrderID GetNumManualOrders() const
Get the number of manually added orders this vehicle has.
Definition: vehicle_base.h:708
Vehicle::value
Money value
Value of the vehicle.
Definition: vehicle_base.h:253
Vehicle::x_pos
int32 x_pos
x coordinate.
Definition: vehicle_base.h:280
DIRDIFF_45LEFT
@ DIRDIFF_45LEFT
Angle of 45 degrees left.
Definition: direction_type.h:68
train.h
AircraftVehicleInfo::subtype
byte subtype
Type of aircraft.
Definition: engine_type.h:102
ChangeDir
static Direction ChangeDir(Direction d, DirDiff delta)
Change a direction by a given difference.
Definition: direction_func.h:104
command_func.h
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:61
Vehicle::HasEngineType
bool HasEngineType() const
Check whether Vehicle::engine_type has any meaning.
Definition: vehicle.cpp:725
Pool::PoolItem<&_group_pool >::GetIfValid
static Titem * GetIfValid(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:348
CMD_ERROR
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
Definition: command_func.h:23
ODTFB_SERVICE
@ ODTFB_SERVICE
This depot order is because of the servicing limit.
Definition: order_type.h:95
EffectVehicle::animation_state
uint16 animation_state
State primarily used to change the graphics/behaviour.
Definition: effectvehicle_base.h:25
GBUG_VEH_POWERED_WAGON
@ GBUG_VEH_POWERED_WAGON
Powered wagon changed poweredness state when not inside a depot.
Definition: newgrf_config.h:46
Vehicle::GetGroundVehicleFlags
uint16 & GetGroundVehicleFlags()
Access the ground vehicle flags of the vehicle.
Definition: vehicle.cpp:2935
Vehicle::IsEngineCountable
bool IsEngineCountable() const
Check if a vehicle is counted in num_engines in each company struct.
Definition: vehicle.cpp:708
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:29
Vehicle::Previous
Vehicle * Previous() const
Get the previous vehicle of this vehicle.
Definition: vehicle_base.h:603
HasVehicleOnPos
bool HasVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
Checks whether a vehicle is on a specific location.
Definition: vehicle.cpp:513
GameCreationSettings::landscape
byte landscape
the landscape we're currently in
Definition: settings_type.h:321
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
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:114
Order::MakeLeaveStation
void MakeLeaveStation()
Makes this order a Leave Station order.
Definition: order_cmd.cpp:123
Vehicle::LeaveStation
void LeaveStation()
Perform all actions when leaving a station.
Definition: vehicle.cpp:2261
IsWagon
static bool IsWagon(EngineID index)
Determine whether an engine type is a wagon (and not a loco).
Definition: engine.cpp:553
IsTransparencySet
static 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
Vehicle::Next
Vehicle * Next() const
Get the next vehicle of this vehicle.
Definition: vehicle_base.h:596
SpecializedVehicle::Next
T * Next() const
Get next vehicle in the chain.
Definition: vehicle_base.h:1081
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:63
Vehicle::y_extent
byte y_extent
y-extent of vehicle bounding box
Definition: vehicle_base.h:293
OLFB_FULL_LOAD
@ OLFB_FULL_LOAD
Full load all cargoes of the consist.
Definition: order_type.h:64
UnitID
uint16 UnitID
Type for the company global vehicle unit number.
Definition: transport_type.h:16
Station
Station data structure.
Definition: station_base.h:447
Order::GetDestination
DestinationID GetDestination() const
Gets the destination of this order.
Definition: order_base.h:97
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:252
Vehicle::z_pos
int32 z_pos
z coordinate.
Definition: vehicle_base.h:282
_date_fract
DateFract _date_fract
Fractional part of the day.
Definition: date.cpp:29
SpawnAdvancedVisualEffect
static void SpawnAdvancedVisualEffect(const Vehicle *v)
Call CBID_VEHICLE_SPAWN_VISUAL_EFFECT and spawn requested effects.
Definition: vehicle.cpp:2535
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:229
Engine::company_avail
CompanyMask company_avail
Bit for each company whether the engine is available for that company.
Definition: engine_base.h:43
DIR_NW
@ DIR_NW
Northwest.
Definition: direction_type.h:33
RemapCoords
static 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
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
vehiclelist.h
GetVehicleSet
void GetVehicleSet(VehicleSet &set, Vehicle *v, uint8 num_vehicles)
Calculates the set of vehicles that will be affected by a given selection.
Definition: vehicle.cpp:2968
FreeUnitIDGenerator::curid
UnitID curid
last ID returned; 0 if none
Definition: vehicle_base.h:1242
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:328
group_gui.h
VE_DEFAULT
@ VE_DEFAULT
Default value to indicate that visual effect should be based on engine class.
Definition: vehicle_base.h:93
Group::parent
GroupID parent
Parent group.
Definition: group.h:83
VS_DEFPAL
@ VS_DEFPAL
Use default vehicle palette.
Definition: vehicle_base.h:34
depot_func.h
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:235
Vehicle::SetNext
void SetNext(Vehicle *next)
Set the next vehicle of this vehicle.
Definition: vehicle.cpp:2740
CargoSpec::Get
static CargoSpec * Get(size_t index)
Retrieve cargo details for the given cargo ID.
Definition: cargotype.h:119
Vehicle::Crash
virtual uint Crash(bool flooded=false)
Crash the (whole) vehicle chain.
Definition: vehicle.cpp:260
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:20
HasPowerOnRail
static 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:332
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:337
EngineReplacementForCompany
static 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
Vehicle::Vehicle
Vehicle(VehicleType type=VEH_INVALID)
Vehicle constructor.
Definition: vehicle.cpp:345
EF_NO_BREAKDOWN_SMOKE
@ EF_NO_BREAKDOWN_SMOKE
Do not show black smoke during a breakdown.
Definition: engine_type.h:161
DeleteVehicleNews
void DeleteVehicleNews(VehicleID vid, StringID news)
Delete a news item type about a vehicle.
Definition: news_gui.cpp:905
GameSettings::difficulty
DifficultySettings difficulty
settings related to the difficulty
Definition: settings_type.h:576
HasBit
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
Definition: bitmath_func.hpp:103
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
_returned_mail_refit_capacity
uint16 _returned_mail_refit_capacity
Stores the mail capacity after a refit operation (Aircraft only).
Definition: vehicle.cpp:86
PerformanceMeasurer
RAII class for measuring simple elements of performance.
Definition: framerate_type.h:92
include
bool include(std::vector< T > &vec, const T &item)
Helper function to append an item to a vector if it is not already contained Consider using std::set,...
Definition: smallvec_type.hpp:27
ClrBit
static T ClrBit(T &x, const uint8 y)
Clears a bit in a variable.
Definition: bitmath_func.hpp:151
GetRoadStopType
static RoadStopType GetRoadStopType(TileIndex t)
Get the road stop type of this tile.
Definition: station_map.h:56
HideFillingPercent
void HideFillingPercent(TextEffectID *te_id)
Hide vehicle loading indicators.
Definition: misc_gui.cpp:649
VE_TYPE_ELECTRIC
@ VE_TYPE_ELECTRIC
Electric sparks.
Definition: vehicle_base.h:87
Sprite::height
uint16 height
Height of the sprite.
Definition: spritecache.h:18
TracksOverlap
static bool TracksOverlap(TrackBits bits)
Checks if the given tracks overlap, ie form a crossing.
Definition: track_func.h:644
Vehicle::next
Vehicle * next
pointer to the next vehicle in the chain
Definition: vehicle_base.h:226
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:751
RoadStop::GetByTile
static RoadStop * GetByTile(TileIndex tile, RoadStopType type)
Find a roadstop at given tile.
Definition: roadstop.cpp:266
VF_LOADING_FINISHED
@ VF_LOADING_FINISHED
Vehicle has finished loading.
Definition: vehicle_base.h:43
zoom_func.h
autoreplace_gui.h
aircraft.h
Group::livery
Livery livery
Custom colour scheme for vehicles in this group.
Definition: group.h:78
Sprite::x_offs
int16 x_offs
Number of pixels to shift the sprite to the right.
Definition: spritecache.h:20
TILE_SIZE
static const uint TILE_SIZE
Tile size in world coordinates.
Definition: tile_type.h:13
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
SpecializedStation< Station, false >::Get
static Station * Get(size_t index)
Gets station with given index.
Definition: base_station_base.h:219
EV_STEAM_SMOKE
@ EV_STEAM_SMOKE
Smoke of steam engines.
Definition: effectvehicle_func.h:18
DirDifference
static DirDiff DirDifference(Direction d0, Direction d1)
Calculate the difference between two directions.
Definition: direction_func.h:68
Vehicle::~Vehicle
virtual ~Vehicle()
We want to 'destruct' the right class.
Definition: vehicle.cpp:880
_settings_client
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:52
GetRegister
static uint32 GetRegister(uint i)
Gets the value of a so-called newgrf "register".
Definition: newgrf_spritegroup.h:29
VehicleEnterDepot
void VehicleEnterDepot(Vehicle *v)
Vehicle entirely entered the depot, update its status, orders, vehicle windows, service it,...
Definition: vehicle.cpp:1487
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:330
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:210
WC_VEHICLE_TIMETABLE
@ WC_VEHICLE_TIMETABLE
Vehicle timetable; Window numbers:
Definition: window_type.h:216
VE_TYPE_COUNT
@ VE_TYPE_COUNT
Number of bits used for the effect type.
Definition: vehicle_base.h:83
newgrf_debug.h
TileY
static uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition: map_func.h:215
Vehicle::GetConsistFreeCapacities
void GetConsistFreeCapacities(SmallMap< CargoID, uint > &capacities) const
Get a map of cargoes and free capacities in the consist.
Definition: vehicle.cpp:2358
ST_NORMAL
@ ST_NORMAL
The most basic (normal) sprite.
Definition: gfx_type.h:302
effectvehicle_base.h
GroundVehicle::IsRearDualheaded
bool IsRearDualheaded() const
Tell if we are dealing with the rear end of a multiheaded engine.
Definition: ground_vehicle.hpp:334
VS_TRAIN_SLOWING
@ VS_TRAIN_SLOWING
Train is slowing down.
Definition: vehicle_base.h:35
RandomRange
static uint32 RandomRange(uint32 limit)
Pick a random number between 0 and limit - 1, inclusive.
Definition: random_func.hpp:81
SND_3A_BREAKDOWN_TRAIN_SHIP_TOYLAND
@ SND_3A_BREAKDOWN_TRAIN_SHIP_TOYLAND
58 == 0x3A Breakdown: train or ship (toyland)
Definition: sound_type.h:97
Chance16I
static bool Chance16I(const uint a, const uint b, const uint32 r)
Checks if a given randomize-number is below a given probability.
Definition: random_func.hpp:112
WC_COMPANY
@ WC_COMPANY
Company view; Window numbers:
Definition: window_type.h:361
WC_STATION_VIEW
@ WC_STATION_VIEW
Station view; Window numbers:
Definition: window_type.h:337
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:228
Vehicle::orders
union Vehicle::@49 orders
The orders currently assigned to the vehicle.
Engine
Definition: engine_base.h:27
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:19
MAX_DAY
#define MAX_DAY
The number of days till the last day.
Definition: date_type.h:98
VEH_ROAD
@ VEH_ROAD
Road vehicle type.
Definition: vehicle_type.h:25
CC_PASSENGERS
@ CC_PASSENGERS
Passengers.
Definition: cargotype.h:41
Vehicle::cur_speed
uint16 cur_speed
current speed
Definition: vehicle_base.h:304
Vehicle
Vehicle data structure.
Definition: vehicle_base.h:221
Vehicle::IsPrimaryVehicle
virtual bool IsPrimaryVehicle() const
Whether this is the primary vehicle in the chain.
Definition: vehicle_base.h:446
Vehicle::IsGroundVehicle
bool IsGroundVehicle() const
Check if the vehicle is a ground vehicle.
Definition: vehicle_base.h:484
VehicleSpriteSeq::Draw
void Draw(int x, int y, PaletteID default_pal, bool force_pal) const
Draw the sprite sequence.
Definition: vehicle.cpp:126
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:285
gamelog.h
Owner
Owner
Enum for all companies/owners.
Definition: company_type.h:18
VehicleCache::cached_cargo_age_period
uint16 cached_cargo_age_period
Number of ticks before carried cargo is aged.
Definition: vehicle_base.h:123
GetVehicleCallback
uint16 GetVehicleCallback(CallbackID callback, uint32 param1, uint32 param2, EngineID engine, const Vehicle *v)
Evaluate a newgrf callback for vehicles.
Definition: newgrf_engine.cpp:1155
DC_EXEC
@ DC_EXEC
execute the given command
Definition: command_type.h:348
VSE_VISUAL_EFFECT
@ VSE_VISUAL_EFFECT
Vehicle visual effect (steam, diesel smoke or electric spark) is shown.
Definition: newgrf_sound.h:24
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:2052
CommandCost::GetErrorMessage
StringID GetErrorMessage() const
Returns the error message of a command.
Definition: command_type.h:140
IsLocalCompany
static bool IsLocalCompany()
Is the current company the local company?
Definition: company_func.h:43
DeleteVehicleOrders
void DeleteVehicleOrders(Vehicle *v, bool keep_orderlist, bool reset_order_indices)
Delete all orders from a vehicle.
Definition: order_cmd.cpp:1892
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:2125
SetDParam
static void SetDParam(uint n, uint64 v)
Set a string parameter v at index n in the global string parameter array.
Definition: strings_func.h:196
VS_AIRCRAFT_BROKEN
@ VS_AIRCRAFT_BROKEN
Aircraft is broken down.
Definition: vehicle_base.h:37
DoCommandFlag
DoCommandFlag
List of flags for a command.
Definition: command_type.h:346
VehicleServiceInDepot
void VehicleServiceInDepot(Vehicle *v)
Service a vehicle and all subsequent vehicles in the consist.
Definition: vehicle.cpp:162
VE_OFFSET_START
@ VE_OFFSET_START
First bit that contains the offset (0 = front, 8 = centre, 15 = rear)
Definition: vehicle_base.h:78
EnsureNoVehicleOnGround
CommandCost EnsureNoVehicleOnGround(TileIndex tile)
Ensure there is no vehicle at the ground at the given position.
Definition: vehicle.cpp:539
Vehicle::breakdowns_since_last_service
byte breakdowns_since_last_service
Counter for the amount of breakdowns.
Definition: vehicle_base.h:277
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:52
GRFBugs
GRFBugs
Encountered GRF bugs.
Definition: newgrf_config.h:43
CommandCost::Succeeded
bool Succeeded() const
Did this command succeed?
Definition: command_type.h:150
SND_35_BREAKDOWN_ROADVEHICLE_TOYLAND
@ SND_35_BREAKDOWN_ROADVEHICLE_TOYLAND
53 == 0x35 Breakdown: road vehicle (toyland)
Definition: sound_type.h:92
TileX
static uint TileX(TileIndex tile)
Get the X component of a tile.
Definition: map_func.h:205
HandleAircraftEnterHangar
void HandleAircraftEnterHangar(Aircraft *v)
Handle Aircraft specific tasks when an Aircraft enters a hangar.
Definition: aircraft_cmd.cpp:561
GUISettings::vehicle_income_warn
bool vehicle_income_warn
if a vehicle isn't generating income, show a warning
Definition: settings_type.h:109
GroupStatistics::num_vehicle
uint16 num_vehicle
Number of vehicles.
Definition: group.h:26
SmallMap
Implementation of simple mapping class.
Definition: smallmap_type.hpp:26
ShowErrorMessage
void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel wl, int x=0, int y=0, const GRFFile *textref_stack_grffile=nullptr, uint textref_stack_size=0, const uint32 *textref_stack=nullptr)
Display an error message in a window.
Definition: error_gui.cpp:383
IsDepotTile
static bool IsDepotTile(TileIndex tile)
Is the given tile a tile with a depot on it?
Definition: depot_map.h:41
GameSettings::game_creation
GameCreationSettings game_creation
settings used during the creation of a game (map)
Definition: settings_type.h:577
CheckClickOnVehicle
Vehicle * CheckClickOnVehicle(const Viewport *vp, int x, int y)
Find the vehicle close to the clicked coordinates.
Definition: vehicle.cpp:1216
Vehicle::IsArticulatedPart
bool IsArticulatedPart() const
Check if the vehicle is an articulated part of an engine.
Definition: vehicle_base.h:908
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:270
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:329
ai.hpp
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=CT_NO_REFIT)
Makes this order a Go To Depot order.
Definition: order_cmd.cpp:89
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:70
IsInsideMM
static bool IsInsideMM(const T x, const size_t min, const size_t max)
Checks if a value is in an interval.
Definition: math_func.hpp:204
VehicleCargoList
CargoList that is used for vehicles.
Definition: cargopacket.h:269
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:929
Ship::UpdateCache
void UpdateCache()
Update the caches of this ship.
Definition: ship_cmd.cpp:202
VF_STOP_LOADING
@ VF_STOP_LOADING
Don't load anymore during the next load cycle.
Definition: vehicle_base.h:49
VE_TYPE_DIESEL
@ VE_TYPE_DIESEL
Diesel fumes.
Definition: vehicle_base.h:86
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:768
Engine::GetGRF
const GRFFile * GetGRF() const
Retrieve the NewGRF the engine is tied to.
Definition: engine_base.h:142
GoodsEntry::cargo
StationCargoList cargo
The cargo packets of cargo waiting in this station.
Definition: station_base.h:252
ShipVehicleInfo::visual_effect
byte visual_effect
Bitstuffed NewGRF visual effect data.
Definition: engine_type.h:74
VESM_STEAM
@ VESM_STEAM
Steam model.
Definition: vehicle_base.h:99
Group
Group data.
Definition: group.h:72
SetWindowWidgetDirty
void SetWindowWidgetDirty(WindowClass cls, WindowNumber number, byte widget_index)
Mark a particular widget in a particular window as dirty (in need of repainting)
Definition: window.cpp:3149
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:584
Pool::PoolItem<&_vehicle_pool >::GetPoolSize
static size_t GetPoolSize()
Returns first unused index.
Definition: pool_type.hpp:358
Order::GetNonStopType
OrderNonStopFlags GetNonStopType() const
At which stations must we stop?
Definition: order_base.h:134
Vehicle::BeginLoading
void BeginLoading()
Prepare everything to begin the loading when arriving at a station.
Definition: vehicle.cpp:2113
FACIL_BUS_STOP
@ FACIL_BUS_STOP
Station with bus stops.
Definition: station_type.h:54
GRFConfig::grf_bugs
uint32 grf_bugs
NOSAVE: bugs in this GRF in this run,.
Definition: newgrf_config.h:175
RailVehicleInfo::visual_effect
byte visual_effect
Bitstuffed NewGRF visual effect data.
Definition: engine_type.h:57
Vehicle::breakdown_ctr
byte breakdown_ctr
Counter for managing breakdown events.
Definition: vehicle_base.h:275
VS_HIDDEN
@ VS_HIDDEN
Vehicle is not visible.
Definition: vehicle_base.h:31
EngineID
uint16 EngineID
Unique identification number of an engine.
Definition: engine_type.h:21
Vehicle::UpdateVisualEffect
void UpdateVisualEffect(bool allow_power_change=true)
Update the cached visual effect.
Definition: vehicle.cpp:2467
Viewport
Data structure for viewport, display of a part of the world.
Definition: viewport_type.h:22
RailVehicleInfo::engclass
EngineClass engclass
Class of engine for this vehicle.
Definition: engine_type.h:52
CheckOwnership
CommandCost CheckOwnership(Owner owner, TileIndex tile)
Check whether the current owner owns something.
Definition: company_cmd.cpp:311
VehicleSpriteSeq::IsValid
bool IsValid() const
Check whether the sequence contains any sprites.
Definition: vehicle_base.h:146
Vehicle::dest_tile
TileIndex dest_tile
Heading for this tile.
Definition: vehicle_base.h:249
Vehicle::HandlePathfindingResult
void HandlePathfindingResult(bool path_found)
Handle the pathfinding result, especially the lost status.
Definition: vehicle.cpp:783
Vehicle::GetDisplayProfitThisYear
Money GetDisplayProfitThisYear() const
Gets the profit vehicle had this year.
Definition: vehicle_base.h:581
return_cmd_error
#define return_cmd_error(errcode)
Returns from a function with a specific StringID as error.
Definition: command_func.h:33
VE_TYPE_START
@ VE_TYPE_START
First bit used for the type of effect.
Definition: vehicle_base.h:82
TO_INVALID
@ TO_INVALID
Invalid transparency option.
Definition: transparency.h:33
GroundVehicleCache
Cached, frequently calculated values.
Definition: ground_vehicle.hpp:29
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:567
Order::GetRefitCargo
CargoID GetRefitCargo() const
Get the cargo to to refit to.
Definition: order_base.h:125
timetable.h
AI::NewEvent
static void NewEvent(CompanyID company, ScriptEvent *event)
Queue a new event for an AI.
Definition: ai_core.cpp:234
CalcPercentVehicleFilled
uint8 CalcPercentVehicleFilled(const Vehicle *front, StringID *colour)
Calculates how full a vehicle is.
Definition: vehicle.cpp:1428
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
_date
Date _date
Current date in days (day counter)
Definition: date.cpp:28
Vehicle::UpdateBoundingBoxCoordinates
void UpdateBoundingBoxCoordinates(bool update_cache) const
Update the bounding box co-ordinates of the vehicle.
Definition: vehicle.cpp:1619
VehicleCargoList::Truncate
uint Truncate(uint max_move=UINT_MAX)
Truncates the cargo in this list to the given amount.
Definition: cargopacket.cpp:654
Vehicle::GetCurrentMaxSpeed
virtual int GetCurrentMaxSpeed() const
Calculates the maximum speed of the vehicle under its current conditions.
Definition: vehicle_base.h:505
WC_VEHICLE_VIEW
@ WC_VEHICLE_VIEW
Vehicle view; Window numbers:
Definition: window_type.h:331
FreeUnitIDGenerator::NextID
UnitID NextID()
Returns next free UnitID.
Definition: vehicle.cpp:1792
Vehicle::AddToShared
void AddToShared(Vehicle *shared_chain)
Adds this vehicle to a shared vehicle chain.
Definition: vehicle.cpp:2769
GRFConfig
Information about GRF, used in the game and (part of it) in savegames.
Definition: newgrf_config.h:155
LIT_ALL
static const byte LIT_ALL
Show the liveries of all companies.
Definition: livery.h:17
CMD_PAUSE
@ CMD_PAUSE
pause the game
Definition: command_type.h:256
VehicleCargoList::AgeCargo
void AgeCargo()
Ages the all cargo in this list.
Definition: cargopacket.cpp:381
EngineInfo::callback_mask
byte callback_mask
Bitmask of vehicle callbacks that have to be called.
Definition: engine_type.h:144
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:2792
VF_CARGO_UNLOADING
@ VF_CARGO_UNLOADING
Vehicle is unloading cargo.
Definition: vehicle_base.h:44
VehicleSettings::max_ships
UnitID max_ships
max ships in game per company
Definition: settings_type.h:488
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:270
Vehicle::tile
TileIndex tile
Current tile index.
Definition: vehicle_base.h:242
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:2244
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:217
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:299
HasAnyRailtypesAvail
bool HasAnyRailtypesAvail(const CompanyID company)
Test if any buildable railtype is available for a company.
Definition: rail.cpp:196
DoDrawVehicle
static void DoDrawVehicle(const Vehicle *v)
Add vehicle sprite for drawing to the screen.
Definition: vehicle.cpp:1092
GroundVehicleCache::cached_veh_length
uint8 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
VS_CRASHED
@ VS_CRASHED
Vehicle is crashed.
Definition: vehicle_base.h:38
VehicleSpriteSeq
Sprite sequence for a vehicle part.
Definition: vehicle_base.h:129
SB
static T SB(T &x, const uint8 s, const uint8 n, const U d)
Set n bits in x starting at bit s to d.
Definition: bitmath_func.hpp:58
RoadVehicleInfo::visual_effect
byte visual_effect
Bitstuffed NewGRF visual effect data.
Definition: engine_type.h:124
Vehicle::last_station_visited
StationID last_station_visited
The last station we stopped at.
Definition: vehicle_base.h:313
CompanyProperties::money
Money money
Money owned by the company.
Definition: company_base.h:66
GetFreeUnitNumber
UnitID GetFreeUnitNumber(VehicleType type)
Get an unused unit number for a vehicle (if allowed).
Definition: vehicle.cpp:1806
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:156
Vehicle::cargo
VehicleCargoList cargo
The cargo this vehicle is carrying.
Definition: vehicle_base.h:320
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:159
Vehicle::hash_tile_current
Vehicle ** hash_tile_current
NOSAVE: Cache of the current hash chain.
Definition: vehicle_base.h:264
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:329
IsInvisibilitySet
static 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
IncreaseStats
void IncreaseStats(Station *st, CargoID cargo, StationID next_station_id, uint capacity, uint usage, uint32 time, EdgeUpdateMode mode)
Increase capacity for a link stat given by station cargo and next hop.
Definition: station_cmd.cpp:3749
Vehicle::max_age
Date max_age
Maximum age.
Definition: vehicle_base.h:271
Station::airport
Airport airport
Tile area the airport covers.
Definition: station_base.h:461
HasAnyRoadTypesAvail
bool HasAnyRoadTypesAvail(CompanyID company, RoadTramType rtt)
Test if any buildable RoadType is available for a company.
Definition: road.cpp:132
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
EndSpriteCombine
void EndSpriteCombine()
Terminates a block of sprites started by StartSpriteCombine.
Definition: viewport.cpp:771
VehicleListIdentifier::Pack
uint32 Pack() const
Pack a VehicleListIdentifier in a single uint32.
Definition: vehiclelist.cpp:21
CompanySettings::engine_renew_months
int16 engine_renew_months
months before/after the maximum vehicle age a vehicle should be renewed
Definition: settings_type.h:568
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:16
Vehicle::IsFrontEngine
bool IsFrontEngine() const
Check if the vehicle is a front engine.
Definition: vehicle_base.h:899
DeleteOrder
void DeleteOrder(Vehicle *v, VehicleOrderID sel_ord)
Delete an order but skip the parameter validation.
Definition: order_cmd.cpp:1056
Vehicle::GetLastOrder
Order * GetLastOrder() const
Returns the last order of a vehicle, or nullptr if it doesn't exists.
Definition: vehicle_base.h:885
ODATFB_NEAREST_DEPOT
@ ODATFB_NEAREST_DEPOT
Send the vehicle to the nearest depot.
Definition: order_type.h:105
FreeUnitIDGenerator
Generates sequence of free UnitID numbers.
Definition: vehicle_base.h:1239
_settings_game
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition: settings.cpp:53
VehicleFromPos
static Vehicle * VehicleFromPos(TileIndex tile, void *data, VehicleFromPosProc *proc, bool find_first)
Helper function for FindVehicleOnPos/HasVehicleOnPos.
Definition: vehicle.cpp:469
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:104
WC_VEHICLE_DETAILS
@ WC_VEHICLE_DETAILS
Vehicle details; Window numbers:
Definition: window_type.h:192
AirportFTA
Internal structure used in openttd - Finite sTate mAchine --> FTA.
Definition: airport.h:190
CompanySettings::engine_renew_money
uint32 engine_renew_money
minimum amount of money before autorenew is used
Definition: settings_type.h:569
VS_STOPPED
@ VS_STOPPED
Vehicle is stopped by the player.
Definition: vehicle_base.h:32
Vehicle::trip_occupancy
int8 trip_occupancy
NOSAVE: Occupancy of vehicle of the current trip (updated after leaving a station).
Definition: vehicle_base.h:322
Vehicle::GetGRFID
uint32 GetGRFID() const
Retrieve the GRF ID of the NewGRF the vehicle is tied to.
Definition: vehicle.cpp:761
IsArticulatedVehicleCarryingDifferentCargoes
bool IsArticulatedVehicleCarryingDifferentCargoes(const Vehicle *v, CargoID *cargo_type)
Tests if all parts of an articulated vehicle are refitted to the same cargo.
Definition: articulated_vehicles.cpp:283
Vehicle::ShowVisualEffect
void ShowVisualEffect() const
Draw visual effects (smoke and/or sparks) for a vehicle chain.
Definition: vehicle.cpp:2590
_local_company
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition: company_cmd.cpp:46
Vehicle::GetEngine
const Engine * GetEngine() const
Retrieves the engine of the vehicle.
Definition: vehicle.cpp:741
VisualEffectSpawnModel
VisualEffectSpawnModel
Models for spawning visual effects.
Definition: vehicle_base.h:97
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:204
VehicleFromPosXY
static Vehicle * VehicleFromPosXY(int x, int y, void *data, VehicleFromPosProc *proc, bool find_first)
Helper function for FindVehicleOnPos/HasVehicleOnPos.
Definition: vehicle.cpp:411
GetNewVehiclePosResult::new_tile
TileIndex new_tile
Tile of the vehicle after moving.
Definition: vehicle_func.h:78
EF_RAIL_IS_MU
@ EF_RAIL_IS_MU
Rail vehicle is a multiple-unit (DMU/EMU)
Definition: engine_type.h:157
Sprite::width
uint16 width
Width of the sprite.
Definition: spritecache.h:19
Vehicle::ResetRefitCaps
void ResetRefitCaps()
Reset all refit_cap in the consist to cargo_cap.
Definition: vehicle.cpp:2313
Vehicle::reliability_spd_dec
uint16 reliability_spd_dec
Reliability decrease speed.
Definition: vehicle_base.h:274
Vehicle::UpdateViewport
void UpdateViewport(bool dirty)
Update the vehicle on the viewport, updating the right hash and setting the new coordinates.
Definition: vehicle.cpp:1652
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:314
Train
'Train' is either a loco or a wagon.
Definition: train.h:86
Airport::flags
uint64 flags
stores which blocks on the airport are taken. was 16 bit earlier on, then 32
Definition: station_base.h:305
CommandCost::GetCost
Money GetCost() const
The costs as made up to this moment.
Definition: command_type.h:82
DEFAULT_GROUP
static const GroupID DEFAULT_GROUP
Ungrouped vehicles are in this group.
Definition: group_type.h:17
VehicleCargoList::SetTransferLoadPlace
void SetTransferLoadPlace(TileIndex xy)
Sets loaded_at_xy to the current station for all cargo to be transferred.
Definition: cargopacket.cpp:400
Vehicle::previous_shared
Vehicle * previous_shared
NOSAVE: pointer to the previous vehicle in the shared order chain.
Definition: vehicle_base.h:231
DeleteDepotHighlightOfVehicle
void DeleteDepotHighlightOfVehicle(const Vehicle *v)
Removes the highlight of a vehicle in a depot window.
Definition: depot_gui.cpp:1123
WC_SHIPS_LIST
@ WC_SHIPS_LIST
Ships list; Window numbers:
Definition: window_type.h:312
DIR_S
@ DIR_S
South.
Definition: direction_type.h:30
DepotCommand
DepotCommand
Flags to add to p1 for goto depot commands.
Definition: vehicle_type.h:65
Vehicle::profit_this_year
Money profit_this_year
Profit this year << 8, low 8 bits are fract.
Definition: vehicle_base.h:251
ODTFB_PART_OF_ORDERS
@ ODTFB_PART_OF_ORDERS
This depot order is because of a regular order.
Definition: order_type.h:96
_networking
bool _networking
are we in networking mode?
Definition: network.cpp:57
StartSpriteCombine
void StartSpriteCombine()
Starts a block of sprites, which are "combined" into a single bounding box.
Definition: viewport.cpp:761
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:84
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:1042
Vehicle::MarkAllViewportsDirty
bool MarkAllViewportsDirty() const
Marks viewports dirty where the vehicle's image is.
Definition: vehicle.cpp:1691
Vehicle::PlayLeaveStationSound
virtual void PlayLeaveStationSound() const
Play the sound associated with leaving the station.
Definition: vehicle_base.h:441
VehicleCargoList::KeepAll
void KeepAll()
Marks all cargo in the vehicle as to be kept.
Definition: cargopacket.h:408
GroupStatistics::VehicleReachedProfitAge
static void VehicleReachedProfitAge(const Vehicle *v)
Add a vehicle to the profit sum of its group.
Definition: group_cmd.cpp:166
SRT_TRAIN_DEPARTS
@ SRT_TRAIN_DEPARTS
Trigger platform when train leaves.
Definition: newgrf_station.h:107
VehicleCache::cached_vis_effect
byte cached_vis_effect
Visual effect to show (see VisualEffect)
Definition: vehicle_base.h:125
Vehicle::FindClosestDepot
virtual bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse)
Find the closest depot for this vehicle and tell us the location, DestinationID and whether we should...
Definition: vehicle_base.h:765
Point
Coordinates of a point in 2D.
Definition: geometry_type.hpp:21
error.h
DirDiff
DirDiff
Enumeration for the difference between two directions.
Definition: direction_type.h:62
WC_TRAINS_LIST
@ WC_TRAINS_LIST
Trains list; Window numbers:
Definition: window_type.h:300
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:2323
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
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:1874
DAYS_IN_LEAP_YEAR
static const int DAYS_IN_LEAP_YEAR
sometimes, you need one day more...
Definition: date_type.h:30
date_func.h
IsRailStationTile
static bool IsRailStationTile(TileIndex t)
Is this tile a station tile and a rail station?
Definition: station_map.h:102
GUISettings::show_track_reservation
bool show_track_reservation
highlight reserved tracks.
Definition: settings_type.h:159
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:297
ShowCostOrIncomeAnimation
void ShowCostOrIncomeAnimation(int x, int y, int z, Money cost)
Display animated income or costs on the map.
Definition: misc_gui.cpp:574
BaseConsist::vehicle_flags
uint16 vehicle_flags
Used for gradual loading and other miscellaneous things (.
Definition: base_consist.h:31
Vehicle::SendToDepot
CommandCost SendToDepot(DoCommandFlag flags, DepotCommand command)
Send this vehicle to the depot using the given command(s).
Definition: vehicle.cpp:2386
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
Vehicle::sprite_cache
MutableSpriteCache sprite_cache
Cache of sprites and values related to recalculating them, see MutableSpriteCache.
Definition: vehicle_base.h:343
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::ShiftDates
void ShiftDates(int interval)
Shift all dates by given interval.
Definition: vehicle.cpp:771
VE_TYPE_DEFAULT
@ VE_TYPE_DEFAULT
Use default from engine class.
Definition: vehicle_base.h:84
EngineInfo::misc_flags
byte misc_flags
Miscellaneous flags.
Definition: engine_type.h:143
Vehicle::y_offs
int8 y_offs
y offset for vehicle sprite
Definition: vehicle_base.h:298
viewport_func.h
Vehicle::colourmap
SpriteID colourmap
NOSAVE: cached colour mapping.
Definition: vehicle_base.h:266
GetVehicleTunnelBridgeProc
static Vehicle * GetVehicleTunnelBridgeProc(Vehicle *v, void *data)
Procedure called for every vehicle found in tunnel/bridge in the hash map.
Definition: vehicle.cpp:553
CanBuildVehicleInfrastructure
bool CanBuildVehicleInfrastructure(VehicleType type, byte subtype)
Check whether we can build infrastructure for the given vehicle type.
Definition: vehicle.cpp:1835
bridge_map.h
IsTileType
static bool IsTileType(TileIndex tile, TileType type)
Checks if a tile is a given tiletype.
Definition: tile_map.h:150
VESM_DIESEL
@ VESM_DIESEL
Diesel model.
Definition: vehicle_base.h:100
RAILVEH_WAGON
@ RAILVEH_WAGON
simple wagon, not motorized
Definition: engine_type.h:29
SetDepotReservation
static void SetDepotReservation(TileIndex t, bool b)
Set the reservation state of the depot.
Definition: rail_map.h:270
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:198
_returned_refit_capacity
uint _returned_refit_capacity
Stores the capacity after a refit operation.
Definition: vehicle.cpp:85
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:840
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:665
DifficultySettings::vehicle_breakdowns
byte vehicle_breakdowns
likelihood of vehicles breaking down
Definition: settings_type.h:83
Vehicle::direction
Direction direction
facing
Definition: vehicle_base.h:283
FreeUnitIDGenerator::cache
bool * cache
array of occupied unit id numbers
Definition: vehicle_base.h:1240
TRACK_BIT_DEPOT
@ TRACK_BIT_DEPOT
Bitflag for a depot.
Definition: track_type.h:56
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:1952
Vehicle::list
OrderList * list
Pointer to the order list for this vehicle.
Definition: vehicle_base.h:332
VehicleEnteredDepotThisTick
void VehicleEnteredDepotThisTick(Vehicle *v)
Adds a vehicle to the list of vehicles that visited a depot this tick.
Definition: vehicle.cpp:906
BaseConsist::cur_real_order_index
VehicleOrderID cur_real_order_index
The index to the current real (non-implicit) order.
Definition: base_consist.h:28
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
GetWindowClassForVehicleType
static WindowClass GetWindowClassForVehicleType(VehicleType vt)
Get WindowClass for vehicle list of given vehicle type.
Definition: vehicle_gui.h:91
RunVehicleDayProc
static void RunVehicleDayProc()
Increases the day counter for all vehicles and calls 1-day and 32-day handlers.
Definition: vehicle.cpp:924
Vehicle::next_shared
Vehicle * next_shared
pointer to the next vehicle that shares the order
Definition: vehicle_base.h:230
spritecache.h
ReverseDir
static Direction ReverseDir(Direction d)
Return the reverse of a direction.
Definition: direction_func.h:54
Vehicle::FirstShared
Vehicle * FirstShared() const
Get the first vehicle of this vehicle chain.
Definition: vehicle_base.h:690
Vehicle::x_extent
byte x_extent
x-extent of vehicle bounding box
Definition: vehicle_base.h:292
Train::wait_counter
uint16 wait_counter
Ticks waiting in front of a signal, ticks being stuck or a counter for forced proceeding through sign...
Definition: train.h:101
CALLBACK_FAILED
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
Definition: newgrf_callbacks.h:404
StringID
uint32 StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:16
Vehicle::vcache
VehicleCache vcache
Cache of often used vehicle values.
Definition: vehicle_base.h:341
Ship
All ships have this type.
Definition: ship.h:26
PALETTE_RECOLOUR_START
static const PaletteID PALETTE_RECOLOUR_START
First recolour sprite for company colours.
Definition: sprites.h:1569
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:1918
Vehicle::motion_counter
uint32 motion_counter
counter to occasionally play a vehicle sound.
Definition: vehicle_base.h:307
_current_company
CompanyID _current_company
Company currently doing an action.
Definition: company_cmd.cpp:47
vehicle_func.h
DEPOT_SERVICE
@ DEPOT_SERVICE
The vehicle will leave the depot right after arrival (service only)
Definition: vehicle_type.h:66
station_base.h
newgrf_sound.h
VESM_NONE
@ VESM_NONE
No visual effect.
Definition: vehicle_base.h:98
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:191
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:1178
PALETTE_CRASH
static const PaletteID PALETTE_CRASH
Recolour sprite greying of crashed vehicles.
Definition: sprites.h:1600
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:386
strings_func.h
Vehicle::hash_viewport_next
Vehicle * hash_viewport_next
NOSAVE: Next vehicle in the visual location hash.
Definition: vehicle_base.h:259
Pool
Base class for all pools.
Definition: pool_type.hpp:81
Vehicle::First
Vehicle * First() const
Get the first vehicle of this vehicle chain.
Definition: vehicle_base.h:609
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:471
ScaleByZoom
static 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
Vehicle::cargo_age_counter
uint16 cargo_age_counter
Ticks till cargo is aged next.
Definition: vehicle_base.h:321
Vehicle::tick_counter
byte tick_counter
Increased by one for each tick.
Definition: vehicle_base.h:325
EnsureNoTrainOnTrackBits
CommandCost EnsureNoTrainOnTrackBits(TileIndex tile, TrackBits track_bits)
Tests if a vehicle interacts with the specified track bits.
Definition: vehicle.cpp:601
Vehicle::cargo_cap
uint16 cargo_cap
total capacity
Definition: vehicle_base.h:318
GroundVehicleCache::cached_power
uint32 cached_power
Total power of the consist (valid only for the first engine).
Definition: ground_vehicle.hpp:38
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:485
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:816
Vehicle::x_offs
int8 x_offs
x offset for vehicle sprite
Definition: vehicle_base.h:297
CBM_VEHICLE_VISUAL_EFFECT
@ CBM_VEHICLE_VISUAL_EFFECT
Visual effects and wagon power (trains, road vehicles and ships)
Definition: newgrf_callbacks.h:289
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:180
FACIL_TRAIN
@ FACIL_TRAIN
Station with train station.
Definition: station_type.h:52
SpecializedVehicle< Train, Type >::From
static Train * From(Vehicle *v)
Converts a Vehicle to SpecializedVehicle with type checking.
Definition: vehicle_base.h:1166
OrderList::AddVehicle
void AddVehicle(Vehicle *v)
Adds the given vehicle to this shared order list.
Definition: order_base.h:357
DIRDIFF_45RIGHT
@ DIRDIFF_45RIGHT
Angle of 45 degrees right.
Definition: direction_type.h:64
GetVehiclePalette
PaletteID GetVehiclePalette(const Vehicle *v)
Get the colour map for a vehicle.
Definition: vehicle.cpp:2062
Train::ConsistChanged
void ConsistChanged(ConsistChangeFlags allowed_changes)
Recalculates the cached stuff of a train.
Definition: train_cmd.cpp:106
Vehicle::z_extent
byte z_extent
z-extent of vehicle bounding box
Definition: vehicle_base.h:294
VehicleRandomBits
byte VehicleRandomBits()
Get a value for a vehicle's random_bits.
Definition: vehicle.cpp:363
OUFB_NO_UNLOAD
@ OUFB_NO_UNLOAD
Totally no unloading will be done.
Definition: order_type.h:56
PaletteID
uint32 PaletteID
The number of the palette.
Definition: gfx_type.h:18
FreeUnitIDGenerator::maxid
UnitID maxid
maximum ID at the moment of constructor call
Definition: vehicle_base.h:1241
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:3251
EffectVehicleType
EffectVehicleType
Effect vehicle types.
Definition: effectvehicle_func.h:16
Aircraft::IsNormalAircraft
bool IsNormalAircraft() const
Check if the aircraft type is a normal flying device; eg not a rotor or a shadow.
Definition: aircraft.h:121
OrderList
Shared order list linking together the linked list of orders and the list of vehicles sharing this or...
Definition: order_base.h:253
GroundVehicle::IsEngine
bool IsEngine() const
Check if a vehicle is an engine (can be first in a consist).
Definition: ground_vehicle.hpp:316
CMD_AUTOREPLACE_VEHICLE
@ CMD_AUTOREPLACE_VEHICLE
replace/renew a vehicle while it is in a depot
Definition: command_type.h:317
SAT_TRAIN_DEPARTS
@ SAT_TRAIN_DEPARTS
Trigger platform when train leaves.
Definition: newgrf_animation_type.h:31
Vehicle::cargo_payment
CargoPayment * cargo_payment
The cargo payment we're currently in.
Definition: vehicle_base.h:255
Pool::PoolItem<&_vehicle_pool >::CleaningPool
static bool CleaningPool()
Returns current state of pool cleaning - yes or no.
Definition: pool_type.hpp:316
GetEngineLiveryScheme
LiveryScheme GetEngineLiveryScheme(EngineID engine_type, EngineID parent_engine_type, const Vehicle *v)
Determines the LiveryScheme for a vehicle.
Definition: vehicle.cpp:1883
BaseConsist::current_order_time
uint32 current_order_time
How many ticks have passed since this order started.
Definition: base_consist.h:22
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:1987
Vehicle::NextShared
Vehicle * NextShared() const
Get the next vehicle of the shared vehicle chain.
Definition: vehicle_base.h:678
ReleaseDisastersTargetingVehicle
void ReleaseDisastersTargetingVehicle(VehicleID vehicle)
Notify disasters that we are about to delete a vehicle.
Definition: disaster_vehicle.cpp:953
PM_PAUSED_NORMAL
@ PM_PAUSED_NORMAL
A game normally paused.
Definition: openttd.h:62
CargoList< VehicleCargoList, CargoPacketList >::MTA_LOAD
@ MTA_LOAD
Load the cargo from the station.
Definition: cargopacket.h:218
Ship::state
TrackBits state
The "track" the ship is following.
Definition: ship.h:27
GetNewVehiclePosResult
Position information of a vehicle after it moved.
Definition: vehicle_func.h:75
WC_VEHICLE_DEPOT
@ WC_VEHICLE_DEPOT
Depot view; Window numbers:
Definition: window_type.h:343
VE_DISABLE_WAGON_POWER
@ VE_DISABLE_WAGON_POWER
Flag to disable wagon power.
Definition: vehicle_base.h:91
MP_STATION
@ MP_STATION
A tile of a station.
Definition: tile_type.h:51
Vehicle::age
Date age
Age in days.
Definition: vehicle_base.h:270
GetStationIndex
static StationID GetStationIndex(TileIndex t)
Get StationID from a tile.
Definition: station_map.h:28
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:498
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:307
UsesWagonOverride
bool UsesWagonOverride(const Vehicle *v)
Check if a wagon is currently using a wagon override.
Definition: newgrf_engine.cpp:1140
Vehicle::profit_last_year
Money profit_last_year
Profit last year << 8, low 8 bits are fract.
Definition: vehicle_base.h:252
Vehicle::breakdown_chance
byte breakdown_chance
Current chance of breakdowns.
Definition: vehicle_base.h:278
EV_DIESEL_SMOKE
@ EV_DIESEL_SMOKE
Smoke of diesel engines.
Definition: effectvehicle_func.h:19
linkgraph.h
Sprite::y_offs
int16 y_offs
Number of pixels to shift the sprite downwards.
Definition: spritecache.h:21
Order::SetDepotOrderType
void SetDepotOrderType(OrderDepotTypeFlags depot_order_type)
Set the cause to go to the depot.
Definition: order_base.h:159
GroundVehicle::gv_flags
uint16 gv_flags
Definition: ground_vehicle.hpp:81
DIRDIFF_90RIGHT
@ DIRDIFF_90RIGHT
Angle of 90 degrees right.
Definition: direction_type.h:65
BaseStation::xy
TileIndex xy
Base tile of the station.
Definition: base_station_base.h:53
Vehicle::unitnumber
UnitID unitnumber
unit number, for display purposes only
Definition: vehicle_base.h:302
depot_map.h
GetTileMaxPixelZ
static int GetTileMaxPixelZ(TileIndex tile)
Get top height of the tile.
Definition: tile_map.h:304
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
Order::SetDepotActionType
void SetDepotActionType(OrderDepotActionFlags depot_service_type)
Set what we are going to do in the depot.
Definition: order_base.h:161
company_func.h
VehicleSettings::max_roadveh
UnitID max_roadveh
max trucks in game per company
Definition: settings_type.h:486
GetNewVehiclePosResult::old_tile
TileIndex old_tile
Current tile of the vehicle.
Definition: vehicle_func.h:77
VE_ADVANCED_EFFECT
@ VE_ADVANCED_EFFECT
Flag for advanced effects.
Definition: vehicle_base.h:90
Vehicle::x_bb_offs
int8 x_bb_offs
x offset of vehicle bounding box
Definition: vehicle_base.h:295
EXPENSES_NEW_VEHICLES
@ EXPENSES_NEW_VEHICLES
New vehicles.
Definition: economy_type.h:159
Vehicle::hash_viewport_prev
Vehicle ** hash_viewport_prev
NOSAVE: Previous vehicle in the visual location hash.
Definition: vehicle_base.h:260
INSTANTIATE_POOL_METHODS
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don't get linker errors.
Definition: pool_func.hpp:224
VEH_DISASTER
@ VEH_DISASTER
Disaster vehicle type.
Definition: vehicle_type.h:32
abs
static T abs(const T a)
Returns the absolute value of (scalar) variable.
Definition: math_func.hpp:21
Vehicle::breakdown_delay
byte breakdown_delay
Counter for managing breakdown length.
Definition: vehicle_base.h:276
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:2231
TriggerStationRandomisation
void TriggerStationRandomisation(Station *st, TileIndex trigger_tile, StationRandomTrigger trigger, CargoID cargo_type)
Trigger station randomisation.
Definition: newgrf_station.cpp:964
VehicleID
uint32 VehicleID
The type all our vehicle IDs have.
Definition: vehicle_type.h:16
AirportFTA::block
uint64 block
64 bit blocks (st->airport.flags), should be enough for the most complex airports
Definition: airport.h:192
InvalidateAutoreplaceWindow
void InvalidateAutoreplaceWindow(EngineID e, GroupID id_g)
Rebuild the left autoreplace list if an engine is removed or added.
Definition: autoreplace_gui.cpp:49
Vehicle::coord
Rect coord
NOSAVE: Graphical bounding box of the vehicle, i.e. what to redraw on moves.
Definition: vehicle_base.h:257
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:184
Order::GetDepotOrderType
OrderDepotTypeFlags GetDepotOrderType() const
What caused us going to the depot?
Definition: order_base.h:138
Aircraft::pos
byte pos
Next desired position of the aircraft.
Definition: aircraft.h:76
network.h
AddVehicleAdviceNewsItem
static void AddVehicleAdviceNewsItem(StringID string, VehicleID vehicle)
Adds a vehicle-advice news item.
Definition: news_func.h:40
AIR_CTOL
@ AIR_CTOL
Conventional Take Off and Landing, i.e. planes.
Definition: engine_type.h:93
TrackBits
TrackBits
Bitfield corresponding to Track.
Definition: track_type.h:38
Vehicle::subtype
byte subtype
subtype (Filled with values from AircraftSubType/DisasterSubType/EffectVehicleType/GroundVehicleSubty...
Definition: vehicle_base.h:338
SmallMap::Find
std::vector< Pair >::const_iterator Find(const T &key) const
Finds given key in this map.
Definition: smallmap_type.hpp:41
Vehicle::day_counter
byte day_counter
Increased by one for each day.
Definition: vehicle_base.h:324
VS_UNCLICKABLE
@ VS_UNCLICKABLE
Vehicle is not clickable by the user (shadow vehicles).
Definition: vehicle_base.h:33
FindVehicleOnPosXY
void FindVehicleOnPosXY(int x, int y, void *data, VehicleFromPosProc *proc)
Find a vehicle from a specific location.
Definition: vehicle.cpp:438
ToggleBit
static T ToggleBit(T &x, const uint8 y)
Toggles a bit in a variable.
Definition: bitmath_func.hpp:181
Debug
#define Debug(name, level, format_string,...)
Ouptut a line of debugging information.
Definition: debug.h:37
SetBit
static T SetBit(T &x, const uint8 y)
Set a bit in a variable.
Definition: bitmath_func.hpp:121
HasVehicleOnPosXY
bool HasVehicleOnPosXY(int x, int y, void *data, VehicleFromPosProc *proc)
Checks whether a vehicle in on a specific location.
Definition: vehicle.cpp:454
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::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:140
VF_PATHFINDER_LOST
@ VF_PATHFINDER_LOST
Vehicle's pathfinder is lost.
Definition: vehicle_base.h:50
AgeVehicle
void AgeVehicle(Vehicle *v)
Update age of a vehicle.
Definition: vehicle.cpp:1378
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:228
OverflowSafeInt< int64 >
CargoID
byte CargoID
Cargo slots to indicate a cargo type within a game.
Definition: cargo_type.h:20
_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:529
CloseWindowById
void CloseWindowById(WindowClass cls, WindowNumber number, bool force)
Close a window by its class and window number (if it is open).
Definition: window.cpp:1176
VehicleCargoList::ActionCount
uint ActionCount(MoveToAction action) const
Returns the amount of cargo designated for a given purpose.
Definition: cargopacket.h:342
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:227
GetTileRailType
RailType GetTileRailType(TileIndex tile)
Return the rail type of tile, or INVALID_RAILTYPE if this is no rail tile.
Definition: rail.cpp:155
LiveryScheme
LiveryScheme
List of different livery schemes.
Definition: livery.h:20
Vehicle::cargo_type
CargoID cargo_type
type of cargo this vehicle is carrying
Definition: vehicle_base.h:316
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:305
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:64
EnsureNoVehicleProcZ
static Vehicle * EnsureNoVehicleProcZ(Vehicle *v, void *data)
Callback that returns 'real' vehicles lower or at height *(int*)data .
Definition: vehicle.cpp:524
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:144
FreeUnitIDGenerator::FreeUnitIDGenerator
FreeUnitIDGenerator(VehicleType type, CompanyID owner)
Initializes the structure.
Definition: vehicle.cpp:1767
Vehicle::OnNewDay
virtual void OnNewDay()
Calls the new day handler of the vehicle.
Definition: vehicle_base.h:546
EF_ROAD_TRAM
@ EF_ROAD_TRAM
Road vehicle is a tram/light rail vehicle.
Definition: engine_type.h:155
CeilDiv
static uint CeilDiv(uint a, uint b)
Computes ceil(a / b) for non-negative a and b.
Definition: math_func.hpp:254
GRFFilePropsBase::local_id
uint16 local_id
id defined by the grf file for this entity
Definition: newgrf_commons.h:319
PalSpriteID::pal
PaletteID pal
The palette (use PAL_NONE) if not needed)
Definition: gfx_type.h:24
Aircraft::state
byte state
State of the airport.
Definition: aircraft.h:79
articulated_vehicles.h
GameSettings::vehicle
VehicleSettings vehicle
options for vehicles
Definition: settings_type.h:585
ErrorUnknownCallbackResult
void ErrorUnknownCallbackResult(uint32 grfid, uint16 cbid, uint16 cb_res)
Record that a NewGRF returned an unknown/invalid callback result.
Definition: newgrf_commons.cpp:516
TFP_NONE
@ TFP_NONE
Normal operation.
Definition: train.h:38
VehicleSettings::smoke_amount
uint8 smoke_amount
amount of smoke/sparks locomotives produce
Definition: settings_type.h:478
GetTileType
static TileType GetTileType(TileIndex tile)
Get the tiletype of a given tile.
Definition: tile_map.h:96
CBM_VEHICLE_COLOUR_REMAP
@ CBM_VEHICLE_COLOUR_REMAP
Change colour mapping of vehicle.
Definition: newgrf_callbacks.h:295
VEH_TRAIN
@ VEH_TRAIN
Train vehicle type.
Definition: vehicle_type.h:24
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:326
Vehicle::GetOrder
Order * GetOrder(int index) const
Returns order 'index' of a vehicle or nullptr when it doesn't exists.
Definition: vehicle_base.h:876
BaseVehicle::type
VehicleType type
Type of vehicle.
Definition: vehicle_type.h:52
SubtractMoneyFromCompany
void SubtractMoneyFromCompany(const CommandCost &cost)
Subtract money from the _current_company, if the company is valid.
Definition: company_cmd.cpp:243
AirportFTAClass::HELICOPTERS
@ HELICOPTERS
Can helicopters land on this airport type?
Definition: airport.h:148
Vehicle::Tick
virtual bool Tick()
Calls the tick handler of the vehicle.
Definition: vehicle_base.h:541
Vehicle::UpdatePositionAndViewport
void UpdatePositionAndViewport()
Update the position of the vehicle, and update the viewport.
Definition: vehicle.cpp:1681
GRFFilePropsBase::grffile
const struct GRFFile * grffile
grf file that introduced this entity
Definition: newgrf_commons.h:320
FACIL_AIRPORT
@ FACIL_AIRPORT
Station with an airport.
Definition: station_type.h:55
Vehicle::reliability
uint16 reliability
Reliability.
Definition: vehicle_base.h:273
VIWD_MODIFY_ORDERS
@ VIWD_MODIFY_ORDERS
Other order modifications.
Definition: vehicle_gui.h:33
Vehicle::UpdatePosition
void UpdatePosition()
Update the position of the vehicle.
Definition: vehicle.cpp:1610
autoreplace_func.h
Vehicle::hash_tile_prev
Vehicle ** hash_tile_prev
NOSAVE: Previous vehicle in the tile location hash.
Definition: vehicle_base.h:263
CanVehicleUseStation
bool CanVehicleUseStation(EngineID engine_type, const Station *st)
Can this station be used by the given engine type?
Definition: vehicle.cpp:2860
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:1312
DecreaseVehicleValue
void DecreaseVehicleValue(Vehicle *v)
Decrease the value of a vehicle.
Definition: vehicle.cpp:1250
Vehicle::y_bb_offs
int8 y_bb_offs
y offset of vehicle bounding box
Definition: vehicle_base.h:296
GetNewVehiclePosResult::y
int y
x and y position of the vehicle after moving
Definition: vehicle_func.h:76
order_backup.h
CT_INVALID
@ CT_INVALID
Invalid cargo type.
Definition: cargo_type.h:69
IsCargoInClass
static bool IsCargoInClass(CargoID c, CargoClass cc)
Does cargo c have cargo class cc?
Definition: cargotype.h:194
GUISettings::liveries
byte liveries
options for displaying company liveries, 0=none, 1=self, 2=all
Definition: settings_type.h:122
Order::CanLeaveWithCargo
bool CanLeaveWithCargo(bool has_cargo) const
A vehicle can leave the current station with cargo if:
Definition: order_cmd.cpp:2255
VehicleCargoList::Return
uint Return(uint max_move, StationCargoList *dest, StationID next_station)
Returns reserved cargo to the station and removes it from the cache.
Definition: cargopacket.cpp:604
VEH_SHIP
@ VEH_SHIP
Ship vehicle type.
Definition: vehicle_type.h:26
VESM_ELECTRIC
@ VESM_ELECTRIC
Electric model.
Definition: vehicle_base.h:101
Rect
Specification of a rectangle with absolute coordinates of all edges.
Definition: geometry_type.hpp:47
PM_PAUSED_ERROR
@ PM_PAUSED_ERROR
A game paused because a (critical) error.
Definition: openttd.h:65
Company
Definition: company_base.h:115
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
Vehicle::GetNumOrders
VehicleOrderID GetNumOrders() const
Get the number of orders this vehicle has.
Definition: vehicle_base.h:702
InvalidateVehicleOrder
void InvalidateVehicleOrder(const Vehicle *v, int data)
Updates the widgets of a vehicle which contains the order-data.
Definition: order_cmd.cpp:250
SetWindowClassesDirty
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting)
Definition: window.cpp:3162
VehicleSpriteSeq::GetBounds
void GetBounds(Rect *bounds) const
Determine shared bounds of all sprites.
Definition: vehicle.cpp:98
Order::GetDepotActionType
OrderDepotActionFlags GetDepotActionType() const
What are we going to do when in the depot.
Definition: order_base.h:140
WC_AIRCRAFT_LIST
@ WC_AIRCRAFT_LIST
Aircraft list; Window numbers:
Definition: window_type.h:318
Vehicle::hash_tile_next
Vehicle * hash_tile_next
NOSAVE: Next vehicle in the tile location hash.
Definition: vehicle_base.h:262
Sprite
Data structure describing a sprite.
Definition: spritecache.h:17
AutoreplaceMap
SmallMap< Vehicle *, bool > AutoreplaceMap
List of vehicles that should check for autoreplace this tick.
Definition: vehicle.cpp:687
CLRBITS
#define CLRBITS(x, y)
Clears several bits in a variable.
Definition: bitmath_func.hpp:166
EngineHasReplacementForCompany
static 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
lastof
#define lastof(x)
Get the last element of an fixed size array.
Definition: stdafx.h:394
Vehicle::DeleteUnreachedImplicitOrders
void DeleteUnreachedImplicitOrders()
Delete all implicit orders which were not reached.
Definition: vehicle.cpp:2074
Vehicle::first
Vehicle * first
NOSAVE: pointer to the first vehicle in the chain.
Definition: vehicle_base.h:228
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:52
SpecializedVehicle::UpdateViewport
void UpdateViewport(bool force_update, bool update_delta)
Update vehicle sprite- and position caches.
Definition: vehicle_base.h:1188
Vehicle::fill_percent_te_id
TextEffectID fill_percent_te_id
a text-effect id to a loading indicator object
Definition: vehicle_base.h:301
Order
Definition: order_base.h:33
VS_SHADOW
@ VS_SHADOW
Vehicle is a shadow vehicle.
Definition: vehicle_base.h:36
Livery
Information about a particular livery.
Definition: livery.h:78
GroundVehicleCache::cached_weight
uint32 cached_weight
Total weight of the consist (valid only for the first engine).
Definition: ground_vehicle.hpp:31
EffectVehicle::GetTransparencyOption
TransparencyOption GetTransparencyOption() const
Determines the transparency option affecting the effect.
Definition: effectvehicle.cpp:661
INVALID_COORD
static const int32 INVALID_COORD
Sentinel for an invalid coordinate.
Definition: vehicle_base.h:1252
MutableSpriteCache::old_coord
Rect old_coord
Co-ordinates from the last valid bounding box.
Definition: vehicle_base.h:192
DAY_TICKS
static const int DAY_TICKS
1 day is 74 ticks; _date_fract used to be uint16 and incremented by 885.
Definition: date_type.h:28
ViewportAddVehicles
void ViewportAddVehicles(DrawPixelInfo *dpi)
Add the vehicle sprites that should be drawn at a part of the screen.
Definition: vehicle.cpp:1122
VE_OFFSET_CENTRE
@ VE_OFFSET_CENTRE
Value of offset corresponding to a position above the centre of the vehicle.
Definition: vehicle_base.h:80
Order::SetNonStopType
void SetNonStopType(OrderNonStopFlags non_stop_type)
Set whether we must stop at stations or not.
Definition: order_base.h:155
VehicleEnterTileStatus
VehicleEnterTileStatus
The returned bits of VehicleEnterTile.
Definition: tile_cmd.h:20
GetGRFConfig
GRFConfig * GetGRFConfig(uint32 grfid, uint32 mask)
Retrieve a NewGRF from the current config by its grfid.
Definition: newgrf_config.cpp:762
Order::MakeImplicit
void MakeImplicit(StationID destination)
Makes this order an implicit order.
Definition: order_cmd.cpp:153
SpecializedVehicle::GetFirstEnginePart
T * GetFirstEnginePart()
Get the first part of an articulated engine.
Definition: vehicle_base.h:1107
FLYING
@ FLYING
Vehicle is flying in the air.
Definition: airport.h:75
VE_TYPE_STEAM
@ VE_TYPE_STEAM
Steam plumes.
Definition: vehicle_base.h:85
SetDParamStr
void SetDParamStr(uint n, const char *str)
This function is used to "bind" a C string to a OpenTTD dparam slot.
Definition: strings.cpp:296
TunnelBridgeIsFree
CommandCost TunnelBridgeIsFree(TileIndex tile, TileIndex endtile, const Vehicle *ignore)
Finds vehicle in tunnel / bridge.
Definition: vehicle.cpp:568
EV_BREAKDOWN_SMOKE
@ EV_BREAKDOWN_SMOKE
Smoke of broken vehicles except aircraft.
Definition: effectvehicle_func.h:23
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:377
WC_VEHICLE_ORDERS
@ WC_VEHICLE_ORDERS
Vehicle orders; Window numbers:
Definition: window_type.h:204
GRFFile
Dynamic data of a loaded NewGRF.
Definition: newgrf.h:105
ClientSettings::gui
GUISettings gui
settings related to the GUI
Definition: settings_type.h:594
Engine::reliability
uint16 reliability
Current reliability of the engine.
Definition: engine_base.h:31
WL_CRITICAL
@ WL_CRITICAL
Critical errors, the MessageBox is shown in all cases.
Definition: error.h:25
Engine::type
VehicleType type
Vehicle type, ie VEH_ROAD, VEH_TRAIN, etc.
Definition: engine_base.h:46
SND_0F_BREAKDOWN_ROADVEHICLE
@ SND_0F_BREAKDOWN_ROADVEHICLE
13 == 0x0D Breakdown: road vehicle (non-toyland)
Definition: sound_type.h:52
Vehicle::refit_cap
uint16 refit_cap
Capacity left over from before last refit.
Definition: vehicle_base.h:319
GroundVehicle::IsMultiheaded
bool IsMultiheaded() const
Check if the vehicle is a multiheaded engine.
Definition: ground_vehicle.hpp:328
OLFB_NO_LOAD
@ OLFB_NO_LOAD
Do not load anything.
Definition: order_type.h:66
Vehicle::date_of_last_service
Date date_of_last_service
Last date the vehicle had a service at a depot.
Definition: vehicle_base.h:272
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:1701
GRFConfig::GetName
const char * GetName() const
Get the name of this grf.
Definition: newgrf_config.cpp:105
DrawPixelInfo
Data about how and where to blit pixels.
Definition: gfx_type.h:155
VEHICLE_PROFIT_MIN_AGE
static const int VEHICLE_PROFIT_MIN_AGE
Only vehicles older than this have a meaningful profit.
Definition: vehicle_func.h:27
Order::GetLoadType
OrderLoadFlags GetLoadType() const
How must the consist be loaded?
Definition: order_base.h:130
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:1755
TileVirtXY
static TileIndex TileVirtXY(uint x, uint y)
Get a tile from the virtual XY-coordinate.
Definition: map_func.h:194
news_func.h
EC_MONORAIL
@ EC_MONORAIL
Mono rail engine.
Definition: engine_type.h:37
IsBridgeAbove
static bool IsBridgeAbove(TileIndex t)
checks if a bridge is set above the ground of this tile
Definition: bridge_map.h:45
VSE_RUNNING_16
@ VSE_RUNNING_16
Every 16 ticks while the vehicle is running (speed > 0).
Definition: newgrf_sound.h:25
roadveh.h
Livery::colour2
byte colour2
Second colour, for vehicles with 2CC support.
Definition: livery.h:81
GamelogGRFBugReverse
bool GamelogGRFBugReverse(uint32 grfid, uint16 internal_id)
Logs GRF bug - rail vehicle has different length after reversing.
Definition: gamelog.cpp:569
Livery::colour1
byte colour1
First colour, for all vehicles.
Definition: livery.h:80
TileTypeProcs::vehicle_enter_tile_proc
VehicleEnterTileProc * vehicle_enter_tile_proc
Called when a vehicle enters a tile.
Definition: tile_cmd.h:157
DEPOT_DONT_CANCEL
@ DEPOT_DONT_CANCEL
Don't cancel current goto depot command if any.
Definition: vehicle_type.h:68
backup_type.hpp
Vehicle::GetImage
virtual void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const
Gets the sprite to show for the given direction.
Definition: vehicle_base.h:455