OpenTTD
vehicle.cpp
Go to the documentation of this file.
1 /* $Id$ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
6  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
8  */
9 
12 #include "stdafx.h"
13 #include "error.h"
14 #include "roadveh.h"
15 #include "ship.h"
16 #include "spritecache.h"
17 #include "timetable.h"
18 #include "viewport_func.h"
19 #include "news_func.h"
20 #include "command_func.h"
21 #include "company_func.h"
22 #include "train.h"
23 #include "aircraft.h"
24 #include "newgrf_debug.h"
25 #include "newgrf_sound.h"
26 #include "newgrf_station.h"
27 #include "group_gui.h"
28 #include "strings_func.h"
29 #include "zoom_func.h"
30 #include "date_func.h"
31 #include "vehicle_func.h"
32 #include "autoreplace_func.h"
33 #include "autoreplace_gui.h"
34 #include "station_base.h"
35 #include "ai/ai.hpp"
36 #include "depot_func.h"
37 #include "network/network.h"
38 #include "core/pool_func.hpp"
39 #include "economy_base.h"
40 #include "articulated_vehicles.h"
41 #include "roadstop_base.h"
42 #include "core/random_func.hpp"
43 #include "core/backup_type.hpp"
44 #include "order_backup.h"
45 #include "sound_func.h"
46 #include "effectvehicle_func.h"
47 #include "effectvehicle_base.h"
48 #include "vehiclelist.h"
49 #include "bridge_map.h"
50 #include "tunnel_map.h"
51 #include "depot_map.h"
52 #include "gamelog.h"
53 #include "linkgraph/linkgraph.h"
54 #include "linkgraph/refresh.h"
55 #include "framerate_type.h"
56 
57 #include "table/strings.h"
58 
59 #include "safeguards.h"
60 
61 /* Number of bits in the hash to use from each vehicle coord */
62 static const uint GEN_HASHX_BITS = 6;
63 static const uint GEN_HASHY_BITS = 6;
64 
65 /* Size of each hash bucket */
66 static const uint GEN_HASHX_BUCKET_BITS = 7;
67 static const uint GEN_HASHY_BUCKET_BITS = 6;
68 
69 /* Compute hash for vehicle coord */
70 #define GEN_HASHX(x) GB((x), GEN_HASHX_BUCKET_BITS + ZOOM_LVL_SHIFT, GEN_HASHX_BITS)
71 #define GEN_HASHY(y) (GB((y), GEN_HASHY_BUCKET_BITS + ZOOM_LVL_SHIFT, GEN_HASHY_BITS) << GEN_HASHX_BITS)
72 #define GEN_HASH(x, y) (GEN_HASHY(y) + GEN_HASHX(x))
73 
74 /* Maximum size until hash repeats */
75 static const int GEN_HASHX_SIZE = 1 << (GEN_HASHX_BUCKET_BITS + GEN_HASHX_BITS + ZOOM_LVL_SHIFT);
76 static const int GEN_HASHY_SIZE = 1 << (GEN_HASHY_BUCKET_BITS + GEN_HASHY_BITS + ZOOM_LVL_SHIFT);
77 
78 /* Increments to reach next bucket in hash table */
79 static const int GEN_HASHX_INC = 1;
80 static const int GEN_HASHY_INC = 1 << GEN_HASHX_BITS;
81 
82 /* Mask to wrap-around buckets */
83 static const uint GEN_HASHX_MASK = (1 << GEN_HASHX_BITS) - 1;
84 static const uint GEN_HASHY_MASK = ((1 << GEN_HASHY_BITS) - 1) << GEN_HASHX_BITS;
85 
86 VehicleID _new_vehicle_id;
89 
90 
92 VehiclePool _vehicle_pool("Vehicle");
94 
95 
96 
100 void VehicleSpriteSeq::GetBounds(Rect *bounds) const
101 {
102  bounds->left = bounds->top = bounds->right = bounds->bottom = 0;
103  for (uint i = 0; i < this->count; ++i) {
104  const Sprite *spr = GetSprite(this->seq[i].sprite, ST_NORMAL);
105  if (i == 0) {
106  bounds->left = spr->x_offs;
107  bounds->top = spr->y_offs;
108  bounds->right = spr->width + spr->x_offs - 1;
109  bounds->bottom = spr->height + spr->y_offs - 1;
110  } else {
111  if (spr->x_offs < bounds->left) bounds->left = spr->x_offs;
112  if (spr->y_offs < bounds->top) bounds->top = spr->y_offs;
113  int right = spr->width + spr->x_offs - 1;
114  int bottom = spr->height + spr->y_offs - 1;
115  if (right > bounds->right) bounds->right = right;
116  if (bottom > bounds->bottom) bounds->bottom = bottom;
117  }
118  }
119 }
120 
128 void VehicleSpriteSeq::Draw(int x, int y, PaletteID default_pal, bool force_pal) const
129 {
130  for (uint i = 0; i < this->count; ++i) {
131  PaletteID pal = force_pal || !this->seq[i].pal ? default_pal : this->seq[i].pal;
132  DrawSprite(this->seq[i].sprite, pal, x, y);
133  }
134 }
135 
142 bool Vehicle::NeedsAutorenewing(const Company *c, bool use_renew_setting) const
143 {
144  /* We can always generate the Company pointer when we have the vehicle.
145  * However this takes time and since the Company pointer is often present
146  * when this function is called then it's faster to pass the pointer as an
147  * argument rather than finding it again. */
148  assert(c == Company::Get(this->owner));
149 
150  if (use_renew_setting && !c->settings.engine_renew) return false;
151  if (this->age - this->max_age < (c->settings.engine_renew_months * 30)) return false;
152 
153  /* Only engines need renewing */
154  if (this->type == VEH_TRAIN && !Train::From(this)->IsEngine()) return false;
155 
156  return true;
157 }
158 
165 {
166  assert(v != NULL);
167  SetWindowDirty(WC_VEHICLE_DETAILS, v->index); // ensure that last service date and reliability are updated
168 
169  do {
172  v->reliability = v->GetEngine()->reliability;
173  /* Prevent vehicles from breaking down directly after exiting the depot. */
174  v->breakdown_chance /= 4;
175  v = v->Next();
176  } while (v != NULL && v->HasEngineType());
177 }
178 
186 {
187  /* Stopped or crashed vehicles will not move, as such making unmovable
188  * vehicles to go for service is lame. */
189  if (this->vehstatus & (VS_STOPPED | VS_CRASHED)) return false;
190 
191  /* Are we ready for the next service cycle? */
192  const Company *c = Company::Get(this->owner);
193  if (this->ServiceIntervalIsPercent() ?
194  (this->reliability >= this->GetEngine()->reliability * (100 - this->GetServiceInterval()) / 100) :
195  (this->date_of_last_service + this->GetServiceInterval() >= _date)) {
196  return false;
197  }
198 
199  /* If we're servicing anyway, because we have not disabled servicing when
200  * there are no breakdowns or we are playing with breakdowns, bail out. */
203  return true;
204  }
205 
206  /* Test whether there is some pending autoreplace.
207  * Note: We do this after the service-interval test.
208  * There are a lot more reasons for autoreplace to fail than we can test here reasonably. */
209  bool pending_replace = false;
210  Money needed_money = c->settings.engine_renew_money;
211  if (needed_money > c->money) return false;
212 
213  for (const Vehicle *v = this; v != NULL; v = (v->type == VEH_TRAIN) ? Train::From(v)->GetNextUnit() : NULL) {
214  bool replace_when_old = false;
215  EngineID new_engine = EngineReplacementForCompany(c, v->engine_type, v->group_id, &replace_when_old);
216 
217  /* Check engine availability */
218  if (new_engine == INVALID_ENGINE || !HasBit(Engine::Get(new_engine)->company_avail, v->owner)) continue;
219  /* Is the vehicle old if we are not always replacing? */
220  if (replace_when_old && !v->NeedsAutorenewing(c, false)) continue;
221 
222  /* Check refittability */
223  CargoTypes available_cargo_types, union_mask;
224  GetArticulatedRefitMasks(new_engine, true, &union_mask, &available_cargo_types);
225  /* Is there anything to refit? */
226  if (union_mask != 0) {
227  CargoID cargo_type;
228  /* We cannot refit to mixed cargoes in an automated way */
229  if (IsArticulatedVehicleCarryingDifferentCargoes(v, &cargo_type)) continue;
230 
231  /* Did the old vehicle carry anything? */
232  if (cargo_type != CT_INVALID) {
233  /* We can't refit the vehicle to carry the cargo we want */
234  if (!HasBit(available_cargo_types, cargo_type)) continue;
235  }
236  }
237 
238  /* Check money.
239  * We want 2*(the price of the new vehicle) without looking at the value of the vehicle we are going to sell. */
240  pending_replace = true;
241  needed_money += 2 * Engine::Get(new_engine)->GetCost();
242  if (needed_money > c->money) return false;
243  }
244 
245  return pending_replace;
246 }
247 
254 {
255  if (this->HasDepotOrder()) return false;
256  if (this->current_order.IsType(OT_LOADING)) return false;
257  if (this->current_order.IsType(OT_GOTO_DEPOT) && this->current_order.GetDepotOrderType() != ODTFB_SERVICE) return false;
258  return NeedsServicing();
259 }
260 
261 uint Vehicle::Crash(bool flooded)
262 {
263  assert((this->vehstatus & VS_CRASHED) == 0);
264  assert(this->Previous() == NULL); // IsPrimaryVehicle fails for free-wagon-chains
265 
266  uint pass = 0;
267  /* Stop the vehicle. */
268  if (this->IsPrimaryVehicle()) this->vehstatus |= VS_STOPPED;
269  /* crash all wagons, and count passengers */
270  for (Vehicle *v = this; v != NULL; v = v->Next()) {
271  /* We do not transfer reserver cargo back, so TotalCount() instead of StoredCount() */
272  if (IsCargoInClass(v->cargo_type, CC_PASSENGERS)) pass += v->cargo.TotalCount();
273  v->vehstatus |= VS_CRASHED;
274  v->MarkAllViewportsDirty();
275  }
276 
277  /* Dirty some windows */
280  SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
281  SetWindowDirty(WC_VEHICLE_DEPOT, this->tile);
282 
283  delete this->cargo_payment;
284  assert(this->cargo_payment == NULL); // cleared by ~CargoPayment
285 
286  return RandomRange(pass + 1); // Randomise deceased passengers.
287 }
288 
289 
298 void ShowNewGrfVehicleError(EngineID engine, StringID part1, StringID part2, GRFBugs bug_type, bool critical)
299 {
300  const Engine *e = Engine::Get(engine);
301  GRFConfig *grfconfig = GetGRFConfig(e->GetGRFID());
302 
303  /* Missing GRF. Nothing useful can be done in this situation. */
304  if (grfconfig == NULL) return;
305 
306  if (!HasBit(grfconfig->grf_bugs, bug_type)) {
307  SetBit(grfconfig->grf_bugs, bug_type);
308  SetDParamStr(0, grfconfig->GetName());
309  SetDParam(1, engine);
310  ShowErrorMessage(part1, part2, WL_CRITICAL);
312  }
313 
314  /* debug output */
315  char buffer[512];
316 
317  SetDParamStr(0, grfconfig->GetName());
318  GetString(buffer, part1, lastof(buffer));
319  DEBUG(grf, 0, "%s", buffer + 3);
320 
321  SetDParam(1, engine);
322  GetString(buffer, part2, lastof(buffer));
323  DEBUG(grf, 0, "%s", buffer + 3);
324 }
325 
332 {
333  /* show a warning once for each engine in whole game and once for each GRF after each game load */
334  const Engine *engine = u->GetEngine();
335  uint32 grfid = engine->grf_prop.grffile->grfid;
336  GRFConfig *grfconfig = GetGRFConfig(grfid);
337  if (GamelogGRFBugReverse(grfid, engine->grf_prop.local_id) || !HasBit(grfconfig->grf_bugs, GBUG_VEH_LENGTH)) {
338  ShowNewGrfVehicleError(u->engine_type, STR_NEWGRF_BROKEN, STR_NEWGRF_BROKEN_VEHICLE_LENGTH, GBUG_VEH_LENGTH, true);
339  }
340 }
341 
347 {
348  this->type = type;
349  this->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 
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 != NULL; v = v->hash_tile_next) {
388  Vehicle *a = proc(v, data);
389  if (find_first && a != NULL) return a;
390  }
391  if (x == xu) break;
392  }
393  if (y == yu) break;
394  }
395 
396  return NULL;
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) != NULL;
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 != NULL; v = v->hash_tile_next) {
476  if (v->tile != tile) continue;
477 
478  Vehicle *a = proc(v, data);
479  if (find_first && a != NULL) return a;
480  }
481 
482  return NULL;
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) != NULL;
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 NULL;
529  if (v->z_pos > z) return NULL;
530 
531  return v;
532 }
533 
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 != NULL) return_cmd_error(STR_ERROR_TRAIN_IN_THE_WAY + v->type);
549  return CommandCost();
550 }
551 
554 {
555  if (v->type != VEH_TRAIN && v->type != VEH_ROAD && v->type != VEH_SHIP) return NULL;
556  if (v == (const Vehicle *)data) return NULL;
557 
558  return v;
559 }
560 
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 == NULL) v = VehicleFromPos(endtile, const_cast<Vehicle *>(ignore), &GetVehicleTunnelBridgeProc, true);
576 
577  if (v != NULL) 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 NULL;
586 
587  Train *t = Train::From(v);
588  if ((t->track != rail_bits) && !TracksOverlap(t->track | rail_bits)) return NULL;
589 
590  return v;
591 }
592 
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 != NULL) 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 = NULL;
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 != NULL) {
631  }
632 
633  /* Insert vehicle at beginning of the new position in the hash table */
634  if (new_hash != NULL) {
635  v->hash_tile_next = *new_hash;
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)
648 {
649  Vehicle **old_hash, **new_hash;
650  int old_x = v->coord.left;
651  int old_y = v->coord.top;
652 
653  new_hash = (x == INVALID_COORD) ? NULL : &_vehicle_viewport_hash[GEN_HASH(x, y)];
654  old_hash = (old_x == INVALID_COORD) ? NULL : &_vehicle_viewport_hash[GEN_HASH(old_x, old_y)];
655 
656  if (old_hash == new_hash) return;
657 
658  /* remove from hash table? */
659  if (old_hash != NULL) {
662  }
663 
664  /* insert into hash table? */
665  if (new_hash != NULL) {
666  v->hash_viewport_next = *new_hash;
668  v->hash_viewport_prev = new_hash;
669  *new_hash = v;
670  }
671 }
672 
673 void ResetVehicleHash()
674 {
675  Vehicle *v;
676  FOR_ALL_VEHICLES(v) { v->hash_tile_current = NULL; }
677  memset(_vehicle_viewport_hash, 0, sizeof(_vehicle_viewport_hash));
678  memset(_vehicle_tile_hash, 0, sizeof(_vehicle_tile_hash));
679 }
680 
681 void ResetVehicleColourMap()
682 {
683  Vehicle *v;
684  FOR_ALL_VEHICLES(v) { v->colourmap = PAL_NONE; }
685 }
686 
692 static AutoreplaceMap _vehicles_to_autoreplace;
693 
694 void InitializeVehicles()
695 {
696  _vehicles_to_autoreplace.Reset();
697  ResetVehicleHash();
698 }
699 
700 uint CountVehiclesInChain(const Vehicle *v)
701 {
702  uint count = 0;
703  do count++; while ((v = v->Next()) != NULL);
704  return count;
705 }
706 
712 {
713  switch (this->type) {
714  case VEH_AIRCRAFT: return Aircraft::From(this)->IsNormalAircraft(); // don't count plane shadows and helicopter rotors
715  case VEH_TRAIN:
716  return !this->IsArticulatedPart() && // tenders and other articulated parts
717  !Train::From(this)->IsRearDualheaded(); // rear parts of multiheaded engines
718  case VEH_ROAD: return RoadVehicle::From(this)->IsFrontEngine();
719  case VEH_SHIP: return true;
720  default: return false; // Only count company buildable vehicles
721  }
722 }
723 
729 {
730  switch (this->type) {
731  case VEH_AIRCRAFT: return Aircraft::From(this)->IsNormalAircraft();
732  case VEH_TRAIN:
733  case VEH_ROAD:
734  case VEH_SHIP: return true;
735  default: return false;
736  }
737 }
738 
745 {
746  return Engine::Get(this->engine_type);
747 }
748 
754 const GRFFile *Vehicle::GetGRF() const
755 {
756  return this->GetEngine()->GetGRF();
757 }
758 
764 uint32 Vehicle::GetGRFID() const
765 {
766  return this->GetEngine()->GetGRFID();
767 }
768 
776 void Vehicle::HandlePathfindingResult(bool path_found)
777 {
778  if (path_found) {
779  /* Route found, is the vehicle marked with "lost" flag? */
780  if (!HasBit(this->vehicle_flags, VF_PATHFINDER_LOST)) return;
781 
782  /* Clear the flag as the PF's problem was solved. */
783  ClrBit(this->vehicle_flags, VF_PATHFINDER_LOST);
784  /* Delete the news item. */
785  DeleteVehicleNews(this->index, STR_NEWS_VEHICLE_IS_LOST);
786  return;
787  }
788 
789  /* Were we already lost? */
790  if (HasBit(this->vehicle_flags, VF_PATHFINDER_LOST)) return;
791 
792  /* It is first time the problem occurred, set the "lost" flag. */
793  SetBit(this->vehicle_flags, VF_PATHFINDER_LOST);
794  /* Notify user about the event. */
795  AI::NewEvent(this->owner, new ScriptEventVehicleLost(this->index));
796  if (_settings_client.gui.lost_vehicle_warn && this->owner == _local_company) {
797  SetDParam(0, this->index);
798  AddVehicleAdviceNewsItem(STR_NEWS_VEHICLE_IS_LOST, this->index);
799  }
800 }
801 
804 {
805  if (CleaningPool()) return;
806 
807  if (Station::IsValidID(this->last_station_visited)) {
808  Station *st = Station::Get(this->last_station_visited);
809  st->loading_vehicles.remove(this);
810 
811  HideFillingPercent(&this->fill_percent_te_id);
812  this->CancelReservation(INVALID_STATION, st);
813  delete this->cargo_payment;
814  assert(this->cargo_payment == NULL); // cleared by ~CargoPayment
815  }
816 
817  if (this->IsEngineCountable()) {
819  if (this->IsPrimaryVehicle()) GroupStatistics::CountVehicle(this, -1);
821 
822  if (this->owner == _local_company) InvalidateAutoreplaceWindow(this->engine_type, this->group_id);
824  }
825 
826  if (this->type == VEH_AIRCRAFT && this->IsPrimaryVehicle()) {
827  Aircraft *a = Aircraft::From(this);
829  if (st != NULL) {
830  const AirportFTA *layout = st->airport.GetFTA()->layout;
831  CLRBITS(st->airport.flags, layout[a->previous_pos].block | layout[a->pos].block);
832  }
833  }
834 
835 
836  if (this->type == VEH_ROAD && this->IsPrimaryVehicle()) {
837  RoadVehicle *v = RoadVehicle::From(this);
838  if (!(v->vehstatus & VS_CRASHED) && IsInsideMM(v->state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END)) {
839  /* Leave the drive through roadstop, when you have not already left it. */
841  }
842  }
843 
844  if (this->Previous() == NULL) {
846  }
847 
848  if (this->IsPrimaryVehicle()) {
849  DeleteWindowById(WC_VEHICLE_VIEW, this->index);
850  DeleteWindowById(WC_VEHICLE_ORDERS, this->index);
851  DeleteWindowById(WC_VEHICLE_REFIT, this->index);
852  DeleteWindowById(WC_VEHICLE_DETAILS, this->index);
854  SetWindowDirty(WC_COMPANY, this->owner);
856  }
858 
859  this->cargo.Truncate();
860  DeleteVehicleOrders(this);
862 
863  extern void StopGlobalFollowVehicle(const Vehicle *v);
864  StopGlobalFollowVehicle(this);
865 
867 }
868 
870 {
871  if (CleaningPool()) {
872  this->cargo.OnCleanPool();
873  return;
874  }
875 
876  /* sometimes, eg. for disaster vehicles, when company bankrupts, when removing crashed/flooded vehicles,
877  * it may happen that vehicle chain is deleted when visible */
878  if (!(this->vehstatus & VS_HIDDEN)) this->MarkAllViewportsDirty();
879 
880  Vehicle *v = this->Next();
881  this->SetNext(NULL);
882 
883  delete v;
884 
885  UpdateVehicleTileHash(this, true);
886  UpdateVehicleViewportHash(this, INVALID_COORD, 0);
887  DeleteVehicleNews(this->index, INVALID_STRING_ID);
888  DeleteNewGRFInspectWindow(GetGrfSpecFeature(this->type), this->index);
889 }
890 
896 {
897  /* Vehicle should stop in the depot if it was in 'stopping' state */
898  _vehicles_to_autoreplace[v] = !(v->vehstatus & VS_STOPPED);
899 
900  /* We ALWAYS set the stopped state. Even when the vehicle does not plan on
901  * stopping in the depot, so we stop it to ensure that it will not reserve
902  * the path out of the depot before we might autoreplace it to a different
903  * engine. The new engine would not own the reserved path we store that we
904  * stopped the vehicle, so autoreplace can start it again */
905  v->vehstatus |= VS_STOPPED;
906 }
907 
913 static void RunVehicleDayProc()
914 {
915  if (_game_mode != GM_NORMAL) return;
916 
917  /* Run the day_proc for every DAY_TICKS vehicle starting at _date_fract. */
918  for (size_t i = _date_fract; i < Vehicle::GetPoolSize(); i += DAY_TICKS) {
919  Vehicle *v = Vehicle::Get(i);
920  if (v == NULL) continue;
921 
922  /* Call the 32-day callback if needed */
923  if ((v->day_counter & 0x1F) == 0 && v->HasEngineType()) {
924  uint16 callback = GetVehicleCallback(CBID_VEHICLE_32DAY_CALLBACK, 0, 0, v->engine_type, v);
925  if (callback != CALLBACK_FAILED) {
926  if (HasBit(callback, 0)) {
927  TriggerVehicle(v, VEHICLE_TRIGGER_CALLBACK_32); // Trigger vehicle trigger 10
928  }
929 
930  /* After a vehicle trigger, the graphics and properties of the vehicle could change.
931  * Note: MarkDirty also invalidates the palette, which is the meaning of bit 1. So, nothing special there. */
932  if (callback != 0) v->First()->MarkDirty();
933 
934  if (callback & ~3) ErrorUnknownCallbackResult(v->GetGRFID(), CBID_VEHICLE_32DAY_CALLBACK, callback);
935  }
936  }
937 
938  /* This is called once per day for each vehicle, but not in the first tick of the day */
939  v->OnNewDay();
940  }
941 }
942 
943 void CallVehicleTicks()
944 {
945  _vehicles_to_autoreplace.Clear();
946 
948 
949  {
951  Station *st;
952  FOR_ALL_STATIONS(st) LoadUnloadStation(st);
953  }
958 
959  Vehicle *v;
960  FOR_ALL_VEHICLES(v) {
961  /* Vehicle could be deleted in this tick */
962  if (!v->Tick()) {
963  assert(Vehicle::Get(vehicle_index) == NULL);
964  continue;
965  }
966 
967  assert(Vehicle::Get(vehicle_index) == v);
968 
969  switch (v->type) {
970  default: break;
971 
972  case VEH_TRAIN:
973  case VEH_ROAD:
974  case VEH_AIRCRAFT:
975  case VEH_SHIP: {
976  Vehicle *front = v->First();
977 
978  if (v->vcache.cached_cargo_age_period != 0) {
980  if (--v->cargo_age_counter == 0) {
981  v->cargo.AgeCargo();
983  }
984  }
985 
986  /* Do not play any sound when crashed */
987  if (front->vehstatus & VS_CRASHED) continue;
988 
989  /* Do not play any sound when in depot or tunnel */
990  if (v->vehstatus & VS_HIDDEN) continue;
991 
992  /* Do not play any sound when stopped */
993  if ((front->vehstatus & VS_STOPPED) && (front->type != VEH_TRAIN || front->cur_speed == 0)) continue;
994 
995  /* Check vehicle type specifics */
996  switch (v->type) {
997  case VEH_TRAIN:
998  if (Train::From(v)->IsWagon()) continue;
999  break;
1000 
1001  case VEH_ROAD:
1002  if (!RoadVehicle::From(v)->IsFrontEngine()) continue;
1003  break;
1004 
1005  case VEH_AIRCRAFT:
1006  if (!Aircraft::From(v)->IsNormalAircraft()) continue;
1007  break;
1008 
1009  default:
1010  break;
1011  }
1012 
1013  v->motion_counter += front->cur_speed;
1014  /* Play a running sound if the motion counter passes 256 (Do we not skip sounds?) */
1015  if (GB(v->motion_counter, 0, 8) < front->cur_speed) PlayVehicleSound(v, VSE_RUNNING);
1016 
1017  /* Play an alternating running sound every 16 ticks */
1018  if (GB(v->tick_counter, 0, 4) == 0) {
1019  /* Play running sound when speed > 0 and not braking */
1020  bool running = (front->cur_speed > 0) && !(front->vehstatus & (VS_STOPPED | VS_TRAIN_SLOWING));
1022  }
1023 
1024  break;
1025  }
1026  }
1027  }
1028 
1029  Backup<CompanyByte> cur_company(_current_company, FILE_LINE);
1030  for (AutoreplaceMap::iterator it = _vehicles_to_autoreplace.Begin(); it != _vehicles_to_autoreplace.End(); it++) {
1031  v = it->first;
1032  /* Autoreplace needs the current company set as the vehicle owner */
1033  cur_company.Change(v->owner);
1034 
1035  /* Start vehicle if we stopped them in VehicleEnteredDepotThisTick()
1036  * We need to stop them between VehicleEnteredDepotThisTick() and here or we risk that
1037  * they are already leaving the depot again before being replaced. */
1038  if (it->second) v->vehstatus &= ~VS_STOPPED;
1039 
1040  /* Store the position of the effect as the vehicle pointer will become invalid later */
1041  int x = v->x_pos;
1042  int y = v->y_pos;
1043  int z = v->z_pos;
1044 
1049 
1050  if (!IsLocalCompany()) continue;
1051 
1052  if (res.Succeeded()) {
1053  ShowCostOrIncomeAnimation(x, y, z, res.GetCost());
1054  continue;
1055  }
1056 
1057  StringID error_message = res.GetErrorMessage();
1058  if (error_message == STR_ERROR_AUTOREPLACE_NOTHING_TO_DO || error_message == INVALID_STRING_ID) continue;
1059 
1060  if (error_message == STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY) error_message = STR_ERROR_AUTOREPLACE_MONEY_LIMIT;
1061 
1062  StringID message;
1063  if (error_message == STR_ERROR_TRAIN_TOO_LONG_AFTER_REPLACEMENT) {
1064  message = error_message;
1065  } else {
1066  message = STR_NEWS_VEHICLE_AUTORENEW_FAILED;
1067  }
1068 
1069  SetDParam(0, v->index);
1070  SetDParam(1, error_message);
1071  AddVehicleAdviceNewsItem(message, v->index);
1072  }
1073 
1074  cur_company.Restore();
1075 }
1076 
1081 static void DoDrawVehicle(const Vehicle *v)
1082 {
1083  PaletteID pal = PAL_NONE;
1084 
1086 
1087  /* Check whether the vehicle shall be transparent due to the game state */
1088  bool shadowed = (v->vehstatus & VS_SHADOW) != 0;
1089 
1090  if (v->type == VEH_EFFECT) {
1091  /* Check whether the vehicle shall be transparent/invisible due to GUI settings.
1092  * However, transparent smoke and bubbles look weird, so always hide them. */
1094  if (to != TO_INVALID && (IsTransparencySet(to) || IsInvisibilitySet(to))) return;
1095  }
1096 
1098  for (uint i = 0; i < v->sprite_seq.count; ++i) {
1099  PaletteID pal2 = v->sprite_seq.seq[i].pal;
1100  if (!pal2 || (v->vehstatus & VS_CRASHED)) pal2 = pal;
1101  AddSortableSpriteToDraw(v->sprite_seq.seq[i].sprite, pal2, v->x_pos + v->x_offs, v->y_pos + v->y_offs,
1102  v->x_extent, v->y_extent, v->z_extent, v->z_pos, shadowed, v->x_bb_offs, v->y_bb_offs);
1103  }
1104  EndSpriteCombine();
1105 }
1106 
1112 {
1113  /* The bounding rectangle */
1114  const int l = dpi->left;
1115  const int r = dpi->left + dpi->width;
1116  const int t = dpi->top;
1117  const int b = dpi->top + dpi->height;
1118 
1119  /* The hash area to scan */
1120  int xl, xu, yl, yu;
1121 
1122  if (dpi->width + (MAX_VEHICLE_PIXEL_X * ZOOM_LVL_BASE) < GEN_HASHX_SIZE) {
1123  xl = GEN_HASHX(l - MAX_VEHICLE_PIXEL_X * ZOOM_LVL_BASE);
1124  xu = GEN_HASHX(r);
1125  } else {
1126  /* scan whole hash row */
1127  xl = 0;
1128  xu = GEN_HASHX_MASK;
1129  }
1130 
1131  if (dpi->height + (MAX_VEHICLE_PIXEL_Y * ZOOM_LVL_BASE) < GEN_HASHY_SIZE) {
1132  yl = GEN_HASHY(t - MAX_VEHICLE_PIXEL_Y * ZOOM_LVL_BASE);
1133  yu = GEN_HASHY(b);
1134  } else {
1135  /* scan whole column */
1136  yl = 0;
1137  yu = GEN_HASHY_MASK;
1138  }
1139 
1140  for (int y = yl;; y = (y + GEN_HASHY_INC) & GEN_HASHY_MASK) {
1141  for (int x = xl;; x = (x + GEN_HASHX_INC) & GEN_HASHX_MASK) {
1142  const Vehicle *v = _vehicle_viewport_hash[x + y]; // already masked & 0xFFF
1143 
1144  while (v != NULL) {
1145  if (!(v->vehstatus & VS_HIDDEN) &&
1146  l <= v->coord.right &&
1147  t <= v->coord.bottom &&
1148  r >= v->coord.left &&
1149  b >= v->coord.top) {
1150  DoDrawVehicle(v);
1151  }
1152  v = v->hash_viewport_next;
1153  }
1154 
1155  if (x == xu) break;
1156  }
1157 
1158  if (y == yu) break;
1159  }
1160 }
1161 
1169 Vehicle *CheckClickOnVehicle(const ViewPort *vp, int x, int y)
1170 {
1171  Vehicle *found = NULL, *v;
1172  uint dist, best_dist = UINT_MAX;
1173 
1174  if ((uint)(x -= vp->left) >= (uint)vp->width || (uint)(y -= vp->top) >= (uint)vp->height) return NULL;
1175 
1176  x = ScaleByZoom(x, vp->zoom) + vp->virtual_left;
1177  y = ScaleByZoom(y, vp->zoom) + vp->virtual_top;
1178 
1179  FOR_ALL_VEHICLES(v) {
1180  if ((v->vehstatus & (VS_HIDDEN | VS_UNCLICKABLE)) == 0 &&
1181  x >= v->coord.left && x <= v->coord.right &&
1182  y >= v->coord.top && y <= v->coord.bottom) {
1183 
1184  dist = max(
1185  abs(((v->coord.left + v->coord.right) >> 1) - x),
1186  abs(((v->coord.top + v->coord.bottom) >> 1) - y)
1187  );
1188 
1189  if (dist < best_dist) {
1190  found = v;
1191  best_dist = dist;
1192  }
1193  }
1194  }
1195 
1196  return found;
1197 }
1198 
1204 {
1205  v->value -= v->value >> 8;
1207 }
1208 
1209 static const byte _breakdown_chance[64] = {
1210  3, 3, 3, 3, 3, 3, 3, 3,
1211  4, 4, 5, 5, 6, 6, 7, 7,
1212  8, 8, 9, 9, 10, 10, 11, 11,
1213  12, 13, 13, 13, 13, 14, 15, 16,
1214  17, 19, 21, 25, 28, 31, 34, 37,
1215  40, 44, 48, 52, 56, 60, 64, 68,
1216  72, 80, 90, 100, 110, 120, 130, 140,
1217  150, 170, 190, 210, 230, 250, 250, 250,
1218 };
1219 
1220 void CheckVehicleBreakdown(Vehicle *v)
1221 {
1222  int rel, rel_old;
1223 
1224  /* decrease reliability */
1225  v->reliability = rel = max((rel_old = v->reliability) - v->reliability_spd_dec, 0);
1226  if ((rel_old >> 8) != (rel >> 8)) SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
1227 
1228  if (v->breakdown_ctr != 0 || (v->vehstatus & VS_STOPPED) ||
1230  v->cur_speed < 5 || _game_mode == GM_MENU) {
1231  return;
1232  }
1233 
1234  uint32 r = Random();
1235 
1236  /* increase chance of failure */
1237  int chance = v->breakdown_chance + 1;
1238  if (Chance16I(1, 25, r)) chance += 25;
1239  v->breakdown_chance = min(255, chance);
1240 
1241  /* calculate reliability value to use in comparison */
1242  rel = v->reliability;
1243  if (v->type == VEH_SHIP) rel += 0x6666;
1244 
1245  /* reduced breakdowns? */
1246  if (_settings_game.difficulty.vehicle_breakdowns == 1) rel += 0x6666;
1247 
1248  /* check if to break down */
1249  if (_breakdown_chance[(uint)min(rel, 0xffff) >> 10] <= v->breakdown_chance) {
1250  v->breakdown_ctr = GB(r, 16, 6) + 0x3F;
1251  v->breakdown_delay = GB(r, 24, 7) + 0x80;
1252  v->breakdown_chance = 0;
1253  }
1254 }
1255 
1263 {
1264  /* Possible states for Vehicle::breakdown_ctr
1265  * 0 - vehicle is running normally
1266  * 1 - vehicle is currently broken down
1267  * 2 - vehicle is going to break down now
1268  * >2 - vehicle is counting down to the actual breakdown event */
1269  switch (this->breakdown_ctr) {
1270  case 0:
1271  return false;
1272 
1273  case 2:
1274  this->breakdown_ctr = 1;
1275 
1276  if (this->breakdowns_since_last_service != 255) {
1277  this->breakdowns_since_last_service++;
1278  }
1279 
1280  if (this->type == VEH_AIRCRAFT) {
1281  /* Aircraft just need this flag, the rest is handled elsewhere */
1282  this->vehstatus |= VS_AIRCRAFT_BROKEN;
1283  } else {
1284  this->cur_speed = 0;
1285 
1286  if (!PlayVehicleSound(this, VSE_BREAKDOWN)) {
1287  bool train_or_ship = this->type == VEH_TRAIN || this->type == VEH_SHIP;
1288  SndPlayVehicleFx((_settings_game.game_creation.landscape != LT_TOYLAND) ?
1289  (train_or_ship ? SND_10_TRAIN_BREAKDOWN : SND_0F_VEHICLE_BREAKDOWN) :
1290  (train_or_ship ? SND_3A_COMEDY_BREAKDOWN_2 : SND_35_COMEDY_BREAKDOWN), this);
1291  }
1292 
1293  if (!(this->vehstatus & VS_HIDDEN) && !HasBit(EngInfo(this->engine_type)->misc_flags, EF_NO_BREAKDOWN_SMOKE)) {
1295  if (u != NULL) u->animation_state = this->breakdown_delay * 2;
1296  }
1297  }
1298 
1299  this->MarkDirty(); // Update graphics after speed is zeroed
1300  SetWindowDirty(WC_VEHICLE_VIEW, this->index);
1301  SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
1302 
1303  FALLTHROUGH;
1304  case 1:
1305  /* Aircraft breakdowns end only when arriving at the airport */
1306  if (this->type == VEH_AIRCRAFT) return false;
1307 
1308  /* For trains this function is called twice per tick, so decrease v->breakdown_delay at half the rate */
1309  if ((this->tick_counter & (this->type == VEH_TRAIN ? 3 : 1)) == 0) {
1310  if (--this->breakdown_delay == 0) {
1311  this->breakdown_ctr = 0;
1312  this->MarkDirty();
1313  SetWindowDirty(WC_VEHICLE_VIEW, this->index);
1314  }
1315  }
1316  return true;
1317 
1318  default:
1319  if (!this->current_order.IsType(OT_LOADING)) this->breakdown_ctr--;
1320  return false;
1321  }
1322 }
1323 
1329 {
1330  if (v->age < MAX_DAY) {
1331  v->age++;
1333  }
1334 
1335  if (!v->IsPrimaryVehicle() && (v->type != VEH_TRAIN || !Train::From(v)->IsEngine())) return;
1336 
1337  int age = v->age - v->max_age;
1338  if (age == DAYS_IN_LEAP_YEAR * 0 || age == DAYS_IN_LEAP_YEAR * 1 ||
1339  age == DAYS_IN_LEAP_YEAR * 2 || age == DAYS_IN_LEAP_YEAR * 3 || age == DAYS_IN_LEAP_YEAR * 4) {
1340  v->reliability_spd_dec <<= 1;
1341  }
1342 
1344 
1345  /* Don't warn about non-primary or not ours vehicles or vehicles that are crashed */
1346  if (v->Previous() != NULL || v->owner != _local_company || (v->vehstatus & VS_CRASHED) != 0) return;
1347 
1348  /* Don't warn if a renew is active */
1349  if (Company::Get(v->owner)->settings.engine_renew && v->GetEngine()->company_avail != 0) return;
1350 
1351  StringID str;
1352  if (age == -DAYS_IN_LEAP_YEAR) {
1353  str = STR_NEWS_VEHICLE_IS_GETTING_OLD;
1354  } else if (age == 0) {
1355  str = STR_NEWS_VEHICLE_IS_GETTING_VERY_OLD;
1356  } else if (age > 0 && (age % DAYS_IN_LEAP_YEAR) == 0) {
1357  str = STR_NEWS_VEHICLE_IS_GETTING_VERY_OLD_AND;
1358  } else {
1359  return;
1360  }
1361 
1362  SetDParam(0, v->index);
1364 }
1365 
1375 uint8 CalcPercentVehicleFilled(const Vehicle *front, StringID *colour)
1376 {
1377  int count = 0;
1378  int max = 0;
1379  int cars = 0;
1380  int unloading = 0;
1381  bool loading = false;
1382 
1383  bool is_loading = front->current_order.IsType(OT_LOADING);
1384 
1385  /* The station may be NULL when the (colour) string does not need to be set. */
1386  const Station *st = Station::GetIfValid(front->last_station_visited);
1387  assert(colour == NULL || (st != NULL && is_loading));
1388 
1389  bool order_no_load = is_loading && (front->current_order.GetLoadType() & OLFB_NO_LOAD);
1390  bool order_full_load = is_loading && (front->current_order.GetLoadType() & OLFB_FULL_LOAD);
1391 
1392  /* Count up max and used */
1393  for (const Vehicle *v = front; v != NULL; v = v->Next()) {
1394  count += v->cargo.StoredCount();
1395  max += v->cargo_cap;
1396  if (v->cargo_cap != 0 && colour != NULL) {
1397  unloading += HasBit(v->vehicle_flags, VF_CARGO_UNLOADING) ? 1 : 0;
1398  loading |= !order_no_load &&
1399  (order_full_load || st->goods[v->cargo_type].HasRating()) &&
1401  cars++;
1402  }
1403  }
1404 
1405  if (colour != NULL) {
1406  if (unloading == 0 && loading) {
1407  *colour = STR_PERCENT_UP;
1408  } else if (unloading == 0 && !loading) {
1409  *colour = STR_PERCENT_NONE;
1410  } else if (cars == unloading || !loading) {
1411  *colour = STR_PERCENT_DOWN;
1412  } else {
1413  *colour = STR_PERCENT_UP_DOWN;
1414  }
1415  }
1416 
1417  /* Train without capacity */
1418  if (max == 0) return 100;
1419 
1420  /* Return the percentage */
1421  if (count * 2 < max) {
1422  /* Less than 50%; round up, so that 0% means really empty. */
1423  return CeilDiv(count * 100, max);
1424  } else {
1425  /* More than 50%; round down, so that 100% means really full. */
1426  return (count * 100) / max;
1427  }
1428 }
1429 
1435 {
1436  /* Always work with the front of the vehicle */
1437  assert(v == v->First());
1438 
1439  switch (v->type) {
1440  case VEH_TRAIN: {
1441  Train *t = Train::From(v);
1443  /* Clear path reservation */
1444  SetDepotReservation(t->tile, false);
1446 
1448  t->wait_counter = 0;
1449  t->force_proceed = TFP_NONE;
1450  ClrBit(t->flags, VRF_TOGGLE_REVERSE);
1452  break;
1453  }
1454 
1455  case VEH_ROAD:
1457  break;
1458 
1459  case VEH_SHIP: {
1461  Ship *ship = Ship::From(v);
1462  ship->state = TRACK_BIT_DEPOT;
1463  ship->UpdateCache();
1464  ship->UpdateViewport(true, true);
1466  break;
1467  }
1468 
1469  case VEH_AIRCRAFT:
1472  break;
1473  default: NOT_REACHED();
1474  }
1476 
1477  if (v->type != VEH_TRAIN) {
1478  /* Trains update the vehicle list when the first unit enters the depot and calls VehicleEnterDepot() when the last unit enters.
1479  * 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 */
1481  }
1483 
1484  v->vehstatus |= VS_HIDDEN;
1485  v->cur_speed = 0;
1486 
1488 
1489  /* After a vehicle trigger, the graphics and properties of the vehicle could change. */
1490  TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT);
1491  v->MarkDirty();
1492 
1493  if (v->current_order.IsType(OT_GOTO_DEPOT)) {
1495 
1496  const Order *real_order = v->GetOrder(v->cur_real_order_index);
1497 
1498  /* Test whether we are heading for this depot. If not, do nothing.
1499  * Note: The target depot for nearest-/manual-depot-orders is only updated on junctions, but we want to accept every depot. */
1501  real_order != NULL && !(real_order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) &&
1502  (v->type == VEH_AIRCRAFT ? v->current_order.GetDestination() != GetStationIndex(v->tile) : v->dest_tile != v->tile)) {
1503  /* We are heading for another depot, keep driving. */
1504  return;
1505  }
1506 
1507  if (v->current_order.IsRefit()) {
1508  Backup<CompanyByte> cur_company(_current_company, v->owner, FILE_LINE);
1509  CommandCost cost = DoCommand(v->tile, v->index, v->current_order.GetRefitCargo() | 0xFF << 8, DC_EXEC, GetCmdRefitVeh(v));
1510  cur_company.Restore();
1511 
1512  if (cost.Failed()) {
1513  _vehicles_to_autoreplace[v] = false;
1514  if (v->owner == _local_company) {
1515  /* Notify the user that we stopped the vehicle */
1516  SetDParam(0, v->index);
1517  AddVehicleAdviceNewsItem(STR_NEWS_ORDER_REFIT_FAILED, v->index);
1518  }
1519  } else if (cost.GetCost() != 0) {
1520  v->profit_this_year -= cost.GetCost() << 8;
1521  if (v->owner == _local_company) {
1522  ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost.GetCost());
1523  }
1524  }
1525  }
1526 
1528  /* Part of orders */
1530  UpdateVehicleTimetable(v, true);
1532  }
1534  /* Vehicles are always stopped on entering depots. Do not restart this one. */
1535  _vehicles_to_autoreplace[v] = false;
1536  /* Invalidate last_loading_station. As the link from the station
1537  * before the stop to the station after the stop can't be predicted
1538  * we shouldn't construct it when the vehicle visits the next stop. */
1539  v->last_loading_station = INVALID_STATION;
1540  if (v->owner == _local_company) {
1541  SetDParam(0, v->index);
1542  AddVehicleAdviceNewsItem(STR_NEWS_TRAIN_IS_WAITING + v->type, v->index);
1543  }
1544  AI::NewEvent(v->owner, new ScriptEventVehicleWaitingInDepot(v->index));
1545  }
1546  v->current_order.MakeDummy();
1547  }
1548 }
1549 
1550 
1556 {
1557  UpdateVehicleTileHash(this, false);
1558 }
1559 
1565 void Vehicle::UpdateViewport(bool dirty)
1566 {
1567  Rect new_coord;
1568  this->sprite_seq.GetBounds(&new_coord);
1569 
1570  Point pt = RemapCoords(this->x_pos + this->x_offs, this->y_pos + this->y_offs, this->z_pos);
1571  new_coord.left += pt.x;
1572  new_coord.top += pt.y;
1573  new_coord.right += pt.x + 2 * ZOOM_LVL_BASE;
1574  new_coord.bottom += pt.y + 2 * ZOOM_LVL_BASE;
1575 
1576  UpdateVehicleViewportHash(this, new_coord.left, new_coord.top);
1577 
1578  Rect old_coord = this->coord;
1579  this->coord = new_coord;
1580 
1581  if (dirty) {
1582  if (old_coord.left == INVALID_COORD) {
1583  this->MarkAllViewportsDirty();
1584  } else {
1586  min(old_coord.left, this->coord.left),
1587  min(old_coord.top, this->coord.top),
1588  max(old_coord.right, this->coord.right),
1589  max(old_coord.bottom, this->coord.bottom));
1590  }
1591  }
1592 }
1593 
1598 {
1599  this->UpdatePosition();
1600  this->UpdateViewport(true);
1601 }
1602 
1607 {
1608  ::MarkAllViewportsDirty(this->coord.left, this->coord.top, this->coord.right, this->coord.bottom);
1609 }
1610 
1617 {
1618  static const int8 _delta_coord[16] = {
1619  -1,-1,-1, 0, 1, 1, 1, 0, /* x */
1620  -1, 0, 1, 1, 1, 0,-1,-1, /* y */
1621  };
1622 
1623  int x = v->x_pos + _delta_coord[v->direction];
1624  int y = v->y_pos + _delta_coord[v->direction + 8];
1625 
1627  gp.x = x;
1628  gp.y = y;
1629  gp.old_tile = v->tile;
1630  gp.new_tile = TileVirtXY(x, y);
1631  return gp;
1632 }
1633 
1634 static const Direction _new_direction_table[] = {
1635  DIR_N, DIR_NW, DIR_W,
1636  DIR_NE, DIR_SE, DIR_SW,
1637  DIR_E, DIR_SE, DIR_S
1638 };
1639 
1640 Direction GetDirectionTowards(const Vehicle *v, int x, int y)
1641 {
1642  int i = 0;
1643 
1644  if (y >= v->y_pos) {
1645  if (y != v->y_pos) i += 3;
1646  i += 3;
1647  }
1648 
1649  if (x >= v->x_pos) {
1650  if (x != v->x_pos) i++;
1651  i++;
1652  }
1653 
1654  Direction dir = v->direction;
1655 
1656  DirDiff dirdiff = DirDifference(_new_direction_table[i], dir);
1657  if (dirdiff == DIRDIFF_SAME) return dir;
1658  return ChangeDir(dir, dirdiff > DIRDIFF_REVERSE ? DIRDIFF_45LEFT : DIRDIFF_45RIGHT);
1659 }
1660 
1671 {
1672  return _tile_type_procs[GetTileType(tile)]->vehicle_enter_tile_proc(v, tile, x, y);
1673 }
1674 
1682 FreeUnitIDGenerator::FreeUnitIDGenerator(VehicleType type, CompanyID owner) : cache(NULL), maxid(0), curid(0)
1683 {
1684  /* Find maximum */
1685  const Vehicle *v;
1686  FOR_ALL_VEHICLES(v) {
1687  if (v->type == type && v->owner == owner) {
1688  this->maxid = max<UnitID>(this->maxid, v->unitnumber);
1689  }
1690  }
1691 
1692  if (this->maxid == 0) return;
1693 
1694  /* Reserving 'maxid + 2' because we need:
1695  * - space for the last item (with v->unitnumber == maxid)
1696  * - one free slot working as loop terminator in FreeUnitIDGenerator::NextID() */
1697  this->cache = CallocT<bool>(this->maxid + 2);
1698 
1699  /* Fill the cache */
1700  FOR_ALL_VEHICLES(v) {
1701  if (v->type == type && v->owner == owner) {
1702  this->cache[v->unitnumber] = true;
1703  }
1704  }
1705 }
1706 
1709 {
1710  if (this->maxid <= this->curid) return ++this->curid;
1711 
1712  while (this->cache[++this->curid]) { } // it will stop, we reserved more space than needed
1713 
1714  return this->curid;
1715 }
1716 
1723 {
1724  /* Check whether it is allowed to build another vehicle. */
1725  uint max_veh;
1726  switch (type) {
1727  case VEH_TRAIN: max_veh = _settings_game.vehicle.max_trains; break;
1728  case VEH_ROAD: max_veh = _settings_game.vehicle.max_roadveh; break;
1729  case VEH_SHIP: max_veh = _settings_game.vehicle.max_ships; break;
1730  case VEH_AIRCRAFT: max_veh = _settings_game.vehicle.max_aircraft; break;
1731  default: NOT_REACHED();
1732  }
1733 
1735  if (c->group_all[type].num_vehicle >= max_veh) return UINT16_MAX; // Currently already at the limit, no room to make a new one.
1736 
1738 
1739  return gen.NextID();
1740 }
1741 
1742 
1752 {
1753  assert(IsCompanyBuildableVehicleType(type));
1754 
1755  if (!Company::IsValidID(_local_company)) return false;
1757 
1758  UnitID max;
1759  switch (type) {
1760  case VEH_TRAIN:
1761  if (!HasAnyRailtypesAvail(_local_company)) return false;
1763  break;
1764  case VEH_ROAD: max = _settings_game.vehicle.max_roadveh; break;
1765  case VEH_SHIP: max = _settings_game.vehicle.max_ships; break;
1766  case VEH_AIRCRAFT: max = _settings_game.vehicle.max_aircraft; break;
1767  default: NOT_REACHED();
1768  }
1769 
1770  /* We can build vehicle infrastructure when we may build the vehicle type */
1771  if (max > 0) {
1772  /* Can we actually build the vehicle type? */
1773  const Engine *e;
1774  FOR_ALL_ENGINES_OF_TYPE(e, type) {
1775  if (HasBit(e->company_avail, _local_company)) return true;
1776  }
1777  return false;
1778  }
1779 
1780  /* We should be able to build infrastructure when we have the actual vehicle type */
1781  const Vehicle *v;
1782  FOR_ALL_VEHICLES(v) {
1783  if (v->owner == _local_company && v->type == type) return true;
1784  }
1785 
1786  return false;
1787 }
1788 
1789 
1797 LiveryScheme GetEngineLiveryScheme(EngineID engine_type, EngineID parent_engine_type, const Vehicle *v)
1798 {
1799  CargoID cargo_type = v == NULL ? (CargoID)CT_INVALID : v->cargo_type;
1800  const Engine *e = Engine::Get(engine_type);
1801  switch (e->type) {
1802  default: NOT_REACHED();
1803  case VEH_TRAIN:
1804  if (v != NULL && parent_engine_type != INVALID_ENGINE && (UsesWagonOverride(v) || (v->IsArticulatedPart() && e->u.rail.railveh_type != RAILVEH_WAGON))) {
1805  /* Wagonoverrides use the colour scheme of the front engine.
1806  * Articulated parts use the colour scheme of the first part. (Not supported for articulated wagons) */
1807  engine_type = parent_engine_type;
1808  e = Engine::Get(engine_type);
1809  /* Note: Luckily cargo_type is not needed for engines */
1810  }
1811 
1812  if (cargo_type == CT_INVALID) cargo_type = e->GetDefaultCargoType();
1813  if (cargo_type == CT_INVALID) cargo_type = CT_GOODS; // The vehicle does not carry anything, let's pick some freight cargo
1814  if (e->u.rail.railveh_type == RAILVEH_WAGON) {
1815  if (!CargoSpec::Get(cargo_type)->is_freight) {
1816  if (parent_engine_type == INVALID_ENGINE) {
1817  return LS_PASSENGER_WAGON_STEAM;
1818  } else {
1819  bool is_mu = HasBit(EngInfo(parent_engine_type)->misc_flags, EF_RAIL_IS_MU);
1820  switch (RailVehInfo(parent_engine_type)->engclass) {
1821  default: NOT_REACHED();
1822  case EC_STEAM: return LS_PASSENGER_WAGON_STEAM;
1823  case EC_DIESEL: return is_mu ? LS_DMU : LS_PASSENGER_WAGON_DIESEL;
1824  case EC_ELECTRIC: return is_mu ? LS_EMU : LS_PASSENGER_WAGON_ELECTRIC;
1825  case EC_MONORAIL: return LS_PASSENGER_WAGON_MONORAIL;
1826  case EC_MAGLEV: return LS_PASSENGER_WAGON_MAGLEV;
1827  }
1828  }
1829  } else {
1830  return LS_FREIGHT_WAGON;
1831  }
1832  } else {
1833  bool is_mu = HasBit(e->info.misc_flags, EF_RAIL_IS_MU);
1834 
1835  switch (e->u.rail.engclass) {
1836  default: NOT_REACHED();
1837  case EC_STEAM: return LS_STEAM;
1838  case EC_DIESEL: return is_mu ? LS_DMU : LS_DIESEL;
1839  case EC_ELECTRIC: return is_mu ? LS_EMU : LS_ELECTRIC;
1840  case EC_MONORAIL: return LS_MONORAIL;
1841  case EC_MAGLEV: return LS_MAGLEV;
1842  }
1843  }
1844 
1845  case VEH_ROAD:
1846  /* Always use the livery of the front */
1847  if (v != NULL && parent_engine_type != INVALID_ENGINE) {
1848  engine_type = parent_engine_type;
1849  e = Engine::Get(engine_type);
1850  cargo_type = v->First()->cargo_type;
1851  }
1852  if (cargo_type == CT_INVALID) cargo_type = e->GetDefaultCargoType();
1853  if (cargo_type == CT_INVALID) cargo_type = CT_GOODS; // The vehicle does not carry anything, let's pick some freight cargo
1854 
1855  /* Important: Use Tram Flag of front part. Luckily engine_type refers to the front part here. */
1856  if (HasBit(e->info.misc_flags, EF_ROAD_TRAM)) {
1857  /* Tram */
1858  return IsCargoInClass(cargo_type, CC_PASSENGERS) ? LS_PASSENGER_TRAM : LS_FREIGHT_TRAM;
1859  } else {
1860  /* Bus or truck */
1861  return IsCargoInClass(cargo_type, CC_PASSENGERS) ? LS_BUS : LS_TRUCK;
1862  }
1863 
1864  case VEH_SHIP:
1865  if (cargo_type == CT_INVALID) cargo_type = e->GetDefaultCargoType();
1866  if (cargo_type == CT_INVALID) cargo_type = CT_GOODS; // The vehicle does not carry anything, let's pick some freight cargo
1867  return IsCargoInClass(cargo_type, CC_PASSENGERS) ? LS_PASSENGER_SHIP : LS_FREIGHT_SHIP;
1868 
1869  case VEH_AIRCRAFT:
1870  switch (e->u.air.subtype) {
1871  case AIR_HELI: return LS_HELICOPTER;
1872  case AIR_CTOL: return LS_SMALL_PLANE;
1873  case AIR_CTOL | AIR_FAST: return LS_LARGE_PLANE;
1874  default: NOT_REACHED();
1875  }
1876  }
1877 }
1878 
1888 const Livery *GetEngineLivery(EngineID engine_type, CompanyID company, EngineID parent_engine_type, const Vehicle *v, byte livery_setting)
1889 {
1890  const Company *c = Company::Get(company);
1891  LiveryScheme scheme = LS_DEFAULT;
1892 
1893  if (livery_setting == LIT_ALL || (livery_setting == LIT_COMPANY && company == _local_company)) {
1894  if (v != NULL) {
1895  const Group *g = Group::GetIfValid(v->First()->group_id);
1896  if (g != NULL) {
1897  /* Traverse parents until we find a livery or reach the top */
1898  while (g->livery.in_use == 0 && g->parent != INVALID_GROUP) {
1899  g = Group::Get(g->parent);
1900  }
1901  if (g->livery.in_use != 0) return &g->livery;
1902  }
1903  }
1904 
1905  /* The default livery is always available for use, but its in_use flag determines
1906  * whether any _other_ liveries are in use. */
1907  if (c->livery[LS_DEFAULT].in_use != 0) {
1908  /* Determine the livery scheme to use */
1909  scheme = GetEngineLiveryScheme(engine_type, parent_engine_type, v);
1910  }
1911  }
1912 
1913  return &c->livery[scheme];
1914 }
1915 
1916 
1917 static PaletteID GetEngineColourMap(EngineID engine_type, CompanyID company, EngineID parent_engine_type, const Vehicle *v)
1918 {
1919  PaletteID map = (v != NULL) ? v->colourmap : PAL_NONE;
1920 
1921  /* Return cached value if any */
1922  if (map != PAL_NONE) return map;
1923 
1924  const Engine *e = Engine::Get(engine_type);
1925 
1926  /* Check if we should use the colour map callback */
1928  uint16 callback = GetVehicleCallback(CBID_VEHICLE_COLOUR_MAPPING, 0, 0, engine_type, v);
1929  /* Failure means "use the default two-colour" */
1930  if (callback != CALLBACK_FAILED) {
1931  assert_compile(PAL_NONE == 0); // Returning 0x4000 (resp. 0xC000) coincidences with default value (PAL_NONE)
1932  map = GB(callback, 0, 14);
1933  /* If bit 14 is set, then the company colours are applied to the
1934  * map else it's returned as-is. */
1935  if (!HasBit(callback, 14)) {
1936  /* Update cache */
1937  if (v != NULL) const_cast<Vehicle *>(v)->colourmap = map;
1938  return map;
1939  }
1940  }
1941  }
1942 
1943  bool twocc = HasBit(e->info.misc_flags, EF_USES_2CC);
1944 
1945  if (map == PAL_NONE) map = twocc ? (PaletteID)SPR_2CCMAP_BASE : (PaletteID)PALETTE_RECOLOUR_START;
1946 
1947  /* Spectator has news shown too, but has invalid company ID - as well as dedicated server */
1948  if (!Company::IsValidID(company)) return map;
1949 
1950  const Livery *livery = GetEngineLivery(engine_type, company, parent_engine_type, v, _settings_client.gui.liveries);
1951 
1952  map += livery->colour1;
1953  if (twocc) map += livery->colour2 * 16;
1954 
1955  /* Update cache */
1956  if (v != NULL) const_cast<Vehicle *>(v)->colourmap = map;
1957  return map;
1958 }
1959 
1967 {
1968  return GetEngineColourMap(engine_type, company, INVALID_ENGINE, NULL);
1969 }
1970 
1977 {
1978  if (v->IsGroundVehicle()) {
1979  return GetEngineColourMap(v->engine_type, v->owner, v->GetGroundVehicleCache()->first_engine, v);
1980  }
1981 
1982  return GetEngineColourMap(v->engine_type, v->owner, INVALID_ENGINE, v);
1983 }
1984 
1989 {
1990  if (this->IsGroundVehicle()) {
1991  uint16 &gv_flags = this->GetGroundVehicleFlags();
1992  if (HasBit(gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS)) {
1993  /* Do not delete orders, only skip them */
1995  this->cur_implicit_order_index = this->cur_real_order_index;
1996  InvalidateVehicleOrder(this, 0);
1997  return;
1998  }
1999  }
2000 
2001  const Order *order = this->GetOrder(this->cur_implicit_order_index);
2002  while (order != NULL) {
2003  if (this->cur_implicit_order_index == this->cur_real_order_index) break;
2004 
2005  if (order->IsType(OT_IMPLICIT)) {
2006  DeleteOrder(this, this->cur_implicit_order_index);
2007  /* DeleteOrder does various magic with order_indices, so resync 'order' with 'cur_implicit_order_index' */
2008  order = this->GetOrder(this->cur_implicit_order_index);
2009  } else {
2010  /* Skip non-implicit orders, e.g. service-orders */
2011  order = order->next;
2012  this->cur_implicit_order_index++;
2013  }
2014 
2015  /* Wrap around */
2016  if (order == NULL) {
2017  order = this->GetOrder(0);
2018  this->cur_implicit_order_index = 0;
2019  }
2020  }
2021 }
2022 
2028 {
2029  assert(IsTileType(this->tile, MP_STATION) || this->type == VEH_SHIP);
2030 
2031  if (this->current_order.IsType(OT_GOTO_STATION) &&
2032  this->current_order.GetDestination() == this->last_station_visited) {
2033  this->DeleteUnreachedImplicitOrders();
2034 
2035  /* Now both order indices point to the destination station, and we can start loading */
2036  this->current_order.MakeLoading(true);
2037  UpdateVehicleTimetable(this, true);
2038 
2039  /* Furthermore add the Non Stop flag to mark that this station
2040  * is the actual destination of the vehicle, which is (for example)
2041  * necessary to be known for HandleTrainLoading to determine
2042  * whether the train is lost or not; not marking a train lost
2043  * that arrives at random stations is bad. */
2044  this->current_order.SetNonStopType(ONSF_NO_STOP_AT_ANY_STATION);
2045 
2046  } else {
2047  /* We weren't scheduled to stop here. Insert an implicit order
2048  * to show that we are stopping here.
2049  * While only groundvehicles have implicit orders, e.g. aircraft might still enter
2050  * the 'wrong' terminal when skipping orders etc. */
2051  Order *in_list = this->GetOrder(this->cur_implicit_order_index);
2052  if (this->IsGroundVehicle() &&
2053  (in_list == NULL || !in_list->IsType(OT_IMPLICIT) ||
2054  in_list->GetDestination() != this->last_station_visited)) {
2055  bool suppress_implicit_orders = HasBit(this->GetGroundVehicleFlags(), GVF_SUPPRESS_IMPLICIT_ORDERS);
2056  /* Do not create consecutive duplicates of implicit orders */
2057  Order *prev_order = this->cur_implicit_order_index > 0 ? this->GetOrder(this->cur_implicit_order_index - 1) : (this->GetNumOrders() > 1 ? this->GetLastOrder() : NULL);
2058  if (prev_order == NULL ||
2059  (!prev_order->IsType(OT_IMPLICIT) && !prev_order->IsType(OT_GOTO_STATION)) ||
2060  prev_order->GetDestination() != this->last_station_visited) {
2061 
2062  /* Prefer deleting implicit orders instead of inserting new ones,
2063  * so test whether the right order follows later. In case of only
2064  * implicit orders treat the last order in the list like an
2065  * explicit one, except if the overall number of orders surpasses
2066  * IMPLICIT_ORDER_ONLY_CAP. */
2067  int target_index = this->cur_implicit_order_index;
2068  bool found = false;
2069  while (target_index != this->cur_real_order_index || this->GetNumManualOrders() == 0) {
2070  const Order *order = this->GetOrder(target_index);
2071  if (order == NULL) break; // No orders.
2072  if (order->IsType(OT_IMPLICIT) && order->GetDestination() == this->last_station_visited) {
2073  found = true;
2074  break;
2075  }
2076  target_index++;
2077  if (target_index >= this->orders.list->GetNumOrders()) {
2078  if (this->GetNumManualOrders() == 0 &&
2079  this->GetNumOrders() < IMPLICIT_ORDER_ONLY_CAP) {
2080  break;
2081  }
2082  target_index = 0;
2083  }
2084  if (target_index == this->cur_implicit_order_index) break; // Avoid infinite loop.
2085  }
2086 
2087  if (found) {
2088  if (suppress_implicit_orders) {
2089  /* Skip to the found order */
2090  this->cur_implicit_order_index = target_index;
2091  InvalidateVehicleOrder(this, 0);
2092  } else {
2093  /* Delete all implicit orders up to the station we just reached */
2094  const Order *order = this->GetOrder(this->cur_implicit_order_index);
2095  while (!order->IsType(OT_IMPLICIT) || order->GetDestination() != this->last_station_visited) {
2096  if (order->IsType(OT_IMPLICIT)) {
2097  DeleteOrder(this, this->cur_implicit_order_index);
2098  /* DeleteOrder does various magic with order_indices, so resync 'order' with 'cur_implicit_order_index' */
2099  order = this->GetOrder(this->cur_implicit_order_index);
2100  } else {
2101  /* Skip non-implicit orders, e.g. service-orders */
2102  order = order->next;
2103  this->cur_implicit_order_index++;
2104  }
2105 
2106  /* Wrap around */
2107  if (order == NULL) {
2108  order = this->GetOrder(0);
2109  this->cur_implicit_order_index = 0;
2110  }
2111  assert(order != NULL);
2112  }
2113  }
2114  } else if (!suppress_implicit_orders &&
2115  ((this->orders.list == NULL ? OrderList::CanAllocateItem() : this->orders.list->GetNumOrders() < MAX_VEH_ORDER_ID)) &&
2117  /* Insert new implicit order */
2118  Order *implicit_order = new Order();
2119  implicit_order->MakeImplicit(this->last_station_visited);
2120  InsertOrder(this, implicit_order, this->cur_implicit_order_index);
2121  if (this->cur_implicit_order_index > 0) --this->cur_implicit_order_index;
2122 
2123  /* InsertOrder disabled creation of implicit orders for all vehicles with the same implicit order.
2124  * Reenable it for this vehicle */
2125  uint16 &gv_flags = this->GetGroundVehicleFlags();
2127  }
2128  }
2129  }
2130  this->current_order.MakeLoading(false);
2131  }
2132 
2133  if (this->last_loading_station != INVALID_STATION &&
2134  this->last_loading_station != this->last_station_visited &&
2135  ((this->current_order.GetLoadType() & OLFB_NO_LOAD) == 0 ||
2136  (this->current_order.GetUnloadType() & OUFB_NO_UNLOAD) == 0)) {
2137  IncreaseStats(Station::Get(this->last_loading_station), this, this->last_station_visited);
2138  }
2139 
2140  PrepareUnload(this);
2141 
2142  SetWindowDirty(GetWindowClassForVehicleType(this->type), this->owner);
2144  SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
2145  SetWindowDirty(WC_STATION_VIEW, this->last_station_visited);
2146 
2147  Station::Get(this->last_station_visited)->MarkTilesDirty(true);
2148  this->cur_speed = 0;
2149  this->MarkDirty();
2150 }
2151 
2157 void Vehicle::CancelReservation(StationID next, Station *st)
2158 {
2159  for (Vehicle *v = this; v != NULL; v = v->next) {
2160  VehicleCargoList &cargo = v->cargo;
2161  if (cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0) {
2162  DEBUG(misc, 1, "cancelling cargo reservation");
2163  cargo.Return(UINT_MAX, &st->goods[v->cargo_type].cargo, next);
2164  cargo.SetTransferLoadPlace(st->xy);
2165  }
2166  cargo.KeepAll();
2167  }
2168 }
2169 
2175 {
2176  assert(this->current_order.IsType(OT_LOADING));
2177 
2178  delete this->cargo_payment;
2179  assert(this->cargo_payment == NULL); // cleared by ~CargoPayment
2180 
2181  /* Only update the timetable if the vehicle was supposed to stop here. */
2182  if (this->current_order.GetNonStopType() != ONSF_STOP_EVERYWHERE) UpdateVehicleTimetable(this, false);
2183 
2184  if ((this->current_order.GetLoadType() & OLFB_NO_LOAD) == 0 ||
2185  (this->current_order.GetUnloadType() & OUFB_NO_UNLOAD) == 0) {
2186  if (this->current_order.CanLeaveWithCargo(this->last_loading_station != INVALID_STATION)) {
2187  /* Refresh next hop stats to make sure we've done that at least once
2188  * during the stop and that refit_cap == cargo_cap for each vehicle in
2189  * the consist. */
2190  this->ResetRefitCaps();
2191  LinkRefresher::Run(this);
2192 
2193  /* if the vehicle could load here or could stop with cargo loaded set the last loading station */
2194  this->last_loading_station = this->last_station_visited;
2195  } else {
2196  /* if the vehicle couldn't load and had to unload or transfer everything
2197  * set the last loading station to invalid as it will leave empty. */
2198  this->last_loading_station = INVALID_STATION;
2199  }
2200  }
2201 
2202  this->current_order.MakeLeaveStation();
2203  Station *st = Station::Get(this->last_station_visited);
2204  this->CancelReservation(INVALID_STATION, st);
2205  st->loading_vehicles.remove(this);
2206 
2207  HideFillingPercent(&this->fill_percent_te_id);
2208  trip_occupancy = CalcPercentVehicleFilled(this, NULL);
2209 
2210  if (this->type == VEH_TRAIN && !(this->vehstatus & VS_CRASHED)) {
2211  /* Trigger station animation (trains only) */
2212  if (IsTileType(this->tile, MP_STATION)) {
2214  TriggerStationAnimation(st, this->tile, SAT_TRAIN_DEPARTS);
2215  }
2216 
2217  SetBit(Train::From(this)->flags, VRF_LEAVING_STATION);
2218  }
2219 
2220  this->MarkDirty();
2221 }
2222 
2227 {
2228  for (Vehicle *v = this; v != NULL; v = v->Next()) v->refit_cap = v->cargo_cap;
2229 }
2230 
2236 void Vehicle::HandleLoading(bool mode)
2237 {
2238  switch (this->current_order.GetType()) {
2239  case OT_LOADING: {
2240  uint wait_time = max(this->current_order.GetTimetabledWait() - this->lateness_counter, 0);
2241 
2242  /* Not the first call for this tick, or still loading */
2243  if (mode || !HasBit(this->vehicle_flags, VF_LOADING_FINISHED) || this->current_order_time < wait_time) return;
2244 
2245  this->PlayLeaveStationSound();
2246 
2247  this->LeaveStation();
2248 
2249  /* Only advance to next order if we just loaded at the current one */
2250  const Order *order = this->GetOrder(this->cur_implicit_order_index);
2251  if (order == NULL ||
2252  (!order->IsType(OT_IMPLICIT) && !order->IsType(OT_GOTO_STATION)) ||
2253  order->GetDestination() != this->last_station_visited) {
2254  return;
2255  }
2256  break;
2257  }
2258 
2259  case OT_DUMMY: break;
2260 
2261  default: return;
2262  }
2263 
2264  this->IncrementImplicitOrderIndex();
2265 }
2266 
2272 {
2273  for (const Vehicle *v = this; v != NULL; v = v->Next()) {
2274  if (v->cargo_cap == 0) continue;
2275  SmallPair<CargoID, uint> *pair = capacities.Find(v->cargo_type);
2276  if (pair == capacities.End()) {
2277  pair = capacities.Append();
2278  pair->first = v->cargo_type;
2279  pair->second = v->cargo_cap - v->cargo.StoredCount();
2280  } else {
2281  pair->second += v->cargo_cap - v->cargo.StoredCount();
2282  }
2283  }
2284 }
2285 
2286 uint Vehicle::GetConsistTotalCapacity() const
2287 {
2288  uint result = 0;
2289  for (const Vehicle *v = this; v != NULL; v = v->Next()) {
2290  result += v->cargo_cap;
2291  }
2292  return result;
2293 }
2294 
2302 {
2303  CommandCost ret = CheckOwnership(this->owner);
2304  if (ret.Failed()) return ret;
2305 
2306  if (this->vehstatus & VS_CRASHED) return CMD_ERROR;
2307  if (this->IsStoppedInDepot()) return CMD_ERROR;
2308 
2309  if (this->current_order.IsType(OT_GOTO_DEPOT)) {
2310  bool halt_in_depot = (this->current_order.GetDepotActionType() & ODATFB_HALT) != 0;
2311  if (!!(command & DEPOT_SERVICE) == halt_in_depot) {
2312  /* We called with a different DEPOT_SERVICE setting.
2313  * Now we change the setting to apply the new one and let the vehicle head for the same depot.
2314  * Note: the if is (true for requesting service == true for ordered to stop in depot) */
2315  if (flags & DC_EXEC) {
2316  this->current_order.SetDepotOrderType(ODTF_MANUAL);
2317  this->current_order.SetDepotActionType(halt_in_depot ? ODATF_SERVICE_ONLY : ODATFB_HALT);
2319  }
2320  return CommandCost();
2321  }
2322 
2323  if (command & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
2324  if (flags & DC_EXEC) {
2325  /* If the orders to 'goto depot' are in the orders list (forced servicing),
2326  * then skip to the next order; effectively cancelling this forced service */
2327  if (this->current_order.GetDepotOrderType() & ODTFB_PART_OF_ORDERS) this->IncrementRealOrderIndex();
2328 
2329  if (this->IsGroundVehicle()) {
2330  uint16 &gv_flags = this->GetGroundVehicleFlags();
2332  }
2333 
2334  this->current_order.MakeDummy();
2336  }
2337  return CommandCost();
2338  }
2339 
2340  TileIndex location;
2341  DestinationID destination;
2342  bool reverse;
2343  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};
2344  if (!this->FindClosestDepot(&location, &destination, &reverse)) return_cmd_error(no_depot[this->type]);
2345 
2346  if (flags & DC_EXEC) {
2347  if (this->current_order.IsType(OT_LOADING)) this->LeaveStation();
2348 
2349  if (this->IsGroundVehicle() && this->GetNumManualOrders() > 0) {
2350  uint16 &gv_flags = this->GetGroundVehicleFlags();
2352  }
2353 
2354  this->SetDestTile(location);
2355  this->current_order.MakeGoToDepot(destination, ODTF_MANUAL);
2356  if (!(command & DEPOT_SERVICE)) this->current_order.SetDepotActionType(ODATFB_HALT);
2358 
2359  /* If there is no depot in front and the train is not already reversing, reverse automatically (trains only) */
2360  if (this->type == VEH_TRAIN && (reverse ^ HasBit(Train::From(this)->flags, VRF_REVERSING))) {
2361  DoCommand(this->tile, this->index, 0, DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION);
2362  }
2363 
2364  if (this->type == VEH_AIRCRAFT) {
2365  Aircraft *a = Aircraft::From(this);
2366  if (a->state == FLYING && a->targetairport != destination) {
2367  /* The aircraft is now heading for a different hangar than the next in the orders */
2370  }
2371  }
2372  }
2373 
2374  return CommandCost();
2375 
2376 }
2377 
2382 void Vehicle::UpdateVisualEffect(bool allow_power_change)
2383 {
2384  bool powered_before = HasBit(this->vcache.cached_vis_effect, VE_DISABLE_WAGON_POWER);
2385  const Engine *e = this->GetEngine();
2386 
2387  /* Evaluate properties */
2388  byte visual_effect;
2389  switch (e->type) {
2390  case VEH_TRAIN: visual_effect = e->u.rail.visual_effect; break;
2391  case VEH_ROAD: visual_effect = e->u.road.visual_effect; break;
2392  case VEH_SHIP: visual_effect = e->u.ship.visual_effect; break;
2393  default: visual_effect = 1 << VE_DISABLE_EFFECT; break;
2394  }
2395 
2396  /* Check powered wagon / visual effect callback */
2398  uint16 callback = GetVehicleCallback(CBID_VEHICLE_VISUAL_EFFECT, 0, 0, this->engine_type, this);
2399 
2400  if (callback != CALLBACK_FAILED) {
2401  if (callback >= 0x100 && e->GetGRF()->grf_version >= 8) ErrorUnknownCallbackResult(e->GetGRFID(), CBID_VEHICLE_VISUAL_EFFECT, callback);
2402 
2403  callback = GB(callback, 0, 8);
2404  /* Avoid accidentally setting 'visual_effect' to the default value
2405  * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
2406  if (callback == VE_DEFAULT) {
2407  assert(HasBit(callback, VE_DISABLE_EFFECT));
2408  SB(callback, VE_TYPE_START, VE_TYPE_COUNT, 0);
2409  }
2410  visual_effect = callback;
2411  }
2412  }
2413 
2414  /* Apply default values */
2415  if (visual_effect == VE_DEFAULT ||
2416  (!HasBit(visual_effect, VE_DISABLE_EFFECT) && GB(visual_effect, VE_TYPE_START, VE_TYPE_COUNT) == VE_TYPE_DEFAULT)) {
2417  /* Only train engines have default effects.
2418  * Note: This is independent of whether the engine is a front engine or articulated part or whatever. */
2419  if (e->type != VEH_TRAIN || e->u.rail.railveh_type == RAILVEH_WAGON || !IsInsideMM(e->u.rail.engclass, EC_STEAM, EC_MONORAIL)) {
2420  if (visual_effect == VE_DEFAULT) {
2421  visual_effect = 1 << VE_DISABLE_EFFECT;
2422  } else {
2423  SetBit(visual_effect, VE_DISABLE_EFFECT);
2424  }
2425  } else {
2426  if (visual_effect == VE_DEFAULT) {
2427  /* Also set the offset */
2428  visual_effect = (VE_OFFSET_CENTRE - (e->u.rail.engclass == EC_STEAM ? 4 : 0)) << VE_OFFSET_START;
2429  }
2430  SB(visual_effect, VE_TYPE_START, VE_TYPE_COUNT, e->u.rail.engclass - EC_STEAM + VE_TYPE_STEAM);
2431  }
2432  }
2433 
2434  this->vcache.cached_vis_effect = visual_effect;
2435 
2436  if (!allow_power_change && powered_before != HasBit(this->vcache.cached_vis_effect, VE_DISABLE_WAGON_POWER)) {
2437  ToggleBit(this->vcache.cached_vis_effect, VE_DISABLE_WAGON_POWER);
2438  ShowNewGrfVehicleError(this->engine_type, STR_NEWGRF_BROKEN, STR_NEWGRF_BROKEN_POWERED_WAGON, GBUG_VEH_POWERED_WAGON, false);
2439  }
2440 }
2441 
2442 static const int8 _vehicle_smoke_pos[8] = {
2443  1, 1, 1, 0, -1, -1, -1, 0
2444 };
2445 
2450 static void SpawnAdvancedVisualEffect(const Vehicle *v)
2451 {
2452  uint16 callback = GetVehicleCallback(CBID_VEHICLE_SPAWN_VISUAL_EFFECT, 0, Random(), v->engine_type, v);
2453  if (callback == CALLBACK_FAILED) return;
2454 
2455  uint count = GB(callback, 0, 2);
2456  bool auto_center = HasBit(callback, 13);
2457  bool auto_rotate = !HasBit(callback, 14);
2458 
2459  int8 l_center = 0;
2460  if (auto_center) {
2461  /* For road vehicles: Compute offset from vehicle position to vehicle center */
2462  if (v->type == VEH_ROAD) l_center = -(int)(VEHICLE_LENGTH - RoadVehicle::From(v)->gcache.cached_veh_length) / 2;
2463  } else {
2464  /* For trains: Compute offset from vehicle position to sprite position */
2465  if (v->type == VEH_TRAIN) l_center = (VEHICLE_LENGTH - Train::From(v)->gcache.cached_veh_length) / 2;
2466  }
2467 
2468  Direction l_dir = v->direction;
2469  if (v->type == VEH_TRAIN && HasBit(Train::From(v)->flags, VRF_REVERSE_DIRECTION)) l_dir = ReverseDir(l_dir);
2470  Direction t_dir = ChangeDir(l_dir, DIRDIFF_90RIGHT);
2471 
2472  int8 x_center = _vehicle_smoke_pos[l_dir] * l_center;
2473  int8 y_center = _vehicle_smoke_pos[t_dir] * l_center;
2474 
2475  for (uint i = 0; i < count; i++) {
2476  uint32 reg = GetRegister(0x100 + i);
2477  uint type = GB(reg, 0, 8);
2478  int8 x = GB(reg, 8, 8);
2479  int8 y = GB(reg, 16, 8);
2480  int8 z = GB(reg, 24, 8);
2481 
2482  if (auto_rotate) {
2483  int8 l = x;
2484  int8 t = y;
2485  x = _vehicle_smoke_pos[l_dir] * l + _vehicle_smoke_pos[t_dir] * t;
2486  y = _vehicle_smoke_pos[t_dir] * l - _vehicle_smoke_pos[l_dir] * t;
2487  }
2488 
2489  if (type >= 0xF0) {
2490  switch (type) {
2491  case 0xF1: CreateEffectVehicleRel(v, x_center + x, y_center + y, z, EV_STEAM_SMOKE); break;
2492  case 0xF2: CreateEffectVehicleRel(v, x_center + x, y_center + y, z, EV_DIESEL_SMOKE); break;
2493  case 0xF3: CreateEffectVehicleRel(v, x_center + x, y_center + y, z, EV_ELECTRIC_SPARK); break;
2494  case 0xFA: CreateEffectVehicleRel(v, x_center + x, y_center + y, z, EV_BREAKDOWN_SMOKE_AIRCRAFT); break;
2495  default: break;
2496  }
2497  }
2498  }
2499 }
2500 
2506 {
2507  assert(this->IsPrimaryVehicle());
2508  bool sound = false;
2509 
2510  /* Do not show any smoke when:
2511  * - vehicle smoke is disabled by the player
2512  * - the vehicle is slowing down or stopped (by the player)
2513  * - the vehicle is moving very slowly
2514  */
2515  if (_settings_game.vehicle.smoke_amount == 0 ||
2516  this->vehstatus & (VS_TRAIN_SLOWING | VS_STOPPED) ||
2517  this->cur_speed < 2) {
2518  return;
2519  }
2520 
2521  /* Use the speed as limited by underground and orders. */
2522  uint max_speed = this->GetCurrentMaxSpeed();
2523 
2524  if (this->type == VEH_TRAIN) {
2525  const Train *t = Train::From(this);
2526  /* For trains, do not show any smoke when:
2527  * - the train is reversing
2528  * - is entering a station with an order to stop there and its speed is equal to maximum station entering speed
2529  */
2530  if (HasBit(t->flags, VRF_REVERSING) ||
2532  t->cur_speed >= max_speed)) {
2533  return;
2534  }
2535  }
2536 
2537  const Vehicle *v = this;
2538 
2539  do {
2540  bool advanced = HasBit(v->vcache.cached_vis_effect, VE_ADVANCED_EFFECT);
2542  VisualEffectSpawnModel effect_model = VESM_NONE;
2543  if (advanced) {
2544  effect_offset = VE_OFFSET_CENTRE;
2546  if (effect_model >= VESM_END) effect_model = VESM_NONE; // unknown spawning model
2547  } else {
2549  assert(effect_model != (VisualEffectSpawnModel)VE_TYPE_DEFAULT); // should have been resolved by UpdateVisualEffect
2550  assert_compile((uint)VESM_STEAM == (uint)VE_TYPE_STEAM);
2551  assert_compile((uint)VESM_DIESEL == (uint)VE_TYPE_DIESEL);
2552  assert_compile((uint)VESM_ELECTRIC == (uint)VE_TYPE_ELECTRIC);
2553  }
2554 
2555  /* Show no smoke when:
2556  * - Smoke has been disabled for this vehicle
2557  * - The vehicle is not visible
2558  * - The vehicle is under a bridge
2559  * - The vehicle is on a depot tile
2560  * - The vehicle is on a tunnel tile
2561  * - The vehicle is a train engine that is currently unpowered */
2562  if (effect_model == VESM_NONE ||
2563  v->vehstatus & VS_HIDDEN ||
2564  IsBridgeAbove(v->tile) ||
2565  IsDepotTile(v->tile) ||
2566  IsTunnelTile(v->tile) ||
2567  (v->type == VEH_TRAIN &&
2568  !HasPowerOnRail(Train::From(v)->railtype, GetTileRailType(v->tile)))) {
2569  continue;
2570  }
2571 
2572  EffectVehicleType evt = EV_END;
2573  switch (effect_model) {
2574  case VESM_STEAM:
2575  /* Steam smoke - amount is gradually falling until vehicle reaches its maximum speed, after that it's normal.
2576  * Details: while vehicle's current speed is gradually increasing, steam plumes' density decreases by one third each
2577  * third of its maximum speed spectrum. Steam emission finally normalises at very close to vehicle's maximum speed.
2578  * REGULATION:
2579  * - instead of 1, 4 / 2^smoke_amount (max. 2) is used to provide sufficient regulation to steam puffs' amount. */
2580  if (GB(v->tick_counter, 0, ((4 >> _settings_game.vehicle.smoke_amount) + ((this->cur_speed * 3) / max_speed))) == 0) {
2581  evt = EV_STEAM_SMOKE;
2582  }
2583  break;
2584 
2585  case VESM_DIESEL: {
2586  /* Diesel smoke - thicker when vehicle is starting, gradually subsiding till it reaches its maximum speed
2587  * when smoke emission stops.
2588  * Details: Vehicle's (max.) speed spectrum is divided into 32 parts. When max. speed is reached, chance for smoke
2589  * emission erodes by 32 (1/4). For trains, power and weight come in handy too to either increase smoke emission in
2590  * 6 steps (1000HP each) if the power is low or decrease smoke emission in 6 steps (512 tonnes each) if the train
2591  * isn't overweight. Power and weight contributions are expressed in a way that neither extreme power, nor
2592  * extreme weight can ruin the balance (e.g. FreightWagonMultiplier) in the formula. When the vehicle reaches
2593  * maximum speed no diesel_smoke is emitted.
2594  * REGULATION:
2595  * - up to which speed a diesel vehicle is emitting smoke (with reduced/small setting only until 1/2 of max_speed),
2596  * - in Chance16 - the last value is 512 / 2^smoke_amount (max. smoke when 128 = smoke_amount of 2). */
2597  int power_weight_effect = 0;
2598  if (v->type == VEH_TRAIN) {
2599  power_weight_effect = (32 >> (Train::From(this)->gcache.cached_power >> 10)) - (32 >> (Train::From(this)->gcache.cached_weight >> 9));
2600  }
2601  if (this->cur_speed < (max_speed >> (2 >> _settings_game.vehicle.smoke_amount)) &&
2602  Chance16((64 - ((this->cur_speed << 5) / max_speed) + power_weight_effect), (512 >> _settings_game.vehicle.smoke_amount))) {
2603  evt = EV_DIESEL_SMOKE;
2604  }
2605  break;
2606  }
2607 
2608  case VESM_ELECTRIC:
2609  /* Electric train's spark - more often occurs when train is departing (more load)
2610  * Details: Electric locomotives are usually at least twice as powerful as their diesel counterparts, so spark
2611  * emissions are kept simple. Only when starting, creating huge force are sparks more likely to happen, but when
2612  * reaching its max. speed, quarter by quarter of it, chance decreases until the usual 2,22% at train's top speed.
2613  * REGULATION:
2614  * - in Chance16 the last value is 360 / 2^smoke_amount (max. sparks when 90 = smoke_amount of 2). */
2615  if (GB(v->tick_counter, 0, 2) == 0 &&
2616  Chance16((6 - ((this->cur_speed << 2) / max_speed)), (360 >> _settings_game.vehicle.smoke_amount))) {
2617  evt = EV_ELECTRIC_SPARK;
2618  }
2619  break;
2620 
2621  default:
2622  NOT_REACHED();
2623  }
2624 
2625  if (evt != EV_END && advanced) {
2626  sound = true;
2628  } else if (evt != EV_END) {
2629  sound = true;
2630 
2631  /* The effect offset is relative to a point 4 units behind the vehicle's
2632  * front (which is the center of an 8/8 vehicle). Shorter vehicles need a
2633  * correction factor. */
2634  if (v->type == VEH_TRAIN) effect_offset += (VEHICLE_LENGTH - Train::From(v)->gcache.cached_veh_length) / 2;
2635 
2636  int x = _vehicle_smoke_pos[v->direction] * effect_offset;
2637  int y = _vehicle_smoke_pos[(v->direction + 2) % 8] * effect_offset;
2638 
2639  if (v->type == VEH_TRAIN && HasBit(Train::From(v)->flags, VRF_REVERSE_DIRECTION)) {
2640  x = -x;
2641  y = -y;
2642  }
2643 
2644  CreateEffectVehicleRel(v, x, y, 10, evt);
2645  }
2646  } while ((v = v->Next()) != NULL);
2647 
2648  if (sound) PlayVehicleSound(this, VSE_VISUAL_EFFECT);
2649 }
2650 
2656 {
2657  assert(this != next);
2658 
2659  if (this->next != NULL) {
2660  /* We had an old next vehicle. Update the first and previous pointers */
2661  for (Vehicle *v = this->next; v != NULL; v = v->Next()) {
2662  v->first = this->next;
2663  }
2664  this->next->previous = NULL;
2665  }
2666 
2667  this->next = next;
2668 
2669  if (this->next != NULL) {
2670  /* A new next vehicle. Update the first and previous pointers */
2671  if (this->next->previous != NULL) this->next->previous->next = NULL;
2672  this->next->previous = this;
2673  for (Vehicle *v = this->next; v != NULL; v = v->Next()) {
2674  v->first = this->first;
2675  }
2676  }
2677 }
2678 
2684 void Vehicle::AddToShared(Vehicle *shared_chain)
2685 {
2686  assert(this->previous_shared == NULL && this->next_shared == NULL);
2687 
2688  if (shared_chain->orders.list == NULL) {
2689  assert(shared_chain->previous_shared == NULL);
2690  assert(shared_chain->next_shared == NULL);
2691  this->orders.list = shared_chain->orders.list = new OrderList(NULL, shared_chain);
2692  }
2693 
2694  this->next_shared = shared_chain->next_shared;
2695  this->previous_shared = shared_chain;
2696 
2697  shared_chain->next_shared = this;
2698 
2699  if (this->next_shared != NULL) this->next_shared->previous_shared = this;
2700 
2701  shared_chain->orders.list->AddVehicle(this);
2702 }
2703 
2708 {
2709  /* Remember if we were first and the old window number before RemoveVehicle()
2710  * as this changes first if needed. */
2711  bool were_first = (this->FirstShared() == this);
2712  VehicleListIdentifier vli(VL_SHARED_ORDERS, this->type, this->owner, this->FirstShared()->index);
2713 
2714  this->orders.list->RemoveVehicle(this);
2715 
2716  if (!were_first) {
2717  /* We are not the first shared one, so only relink our previous one. */
2718  this->previous_shared->next_shared = this->NextShared();
2719  }
2720 
2721  if (this->next_shared != NULL) this->next_shared->previous_shared = this->previous_shared;
2722 
2723 
2724  if (this->orders.list->GetNumVehicles() == 1) {
2725  /* When there is only one vehicle, remove the shared order list window. */
2727  InvalidateVehicleOrder(this->FirstShared(), VIWD_MODIFY_ORDERS);
2728  } else if (were_first) {
2729  /* If we were the first one, update to the new first one.
2730  * Note: FirstShared() is already the new first */
2731  InvalidateWindowData(GetWindowClassForVehicleType(this->type), vli.Pack(), this->FirstShared()->index | (1U << 31));
2732  }
2733 
2734  this->next_shared = NULL;
2735  this->previous_shared = NULL;
2736 }
2737 
2738 void VehiclesYearlyLoop()
2739 {
2740  Vehicle *v;
2741  FOR_ALL_VEHICLES(v) {
2742  if (v->IsPrimaryVehicle()) {
2743  /* show warning if vehicle is not generating enough income last 2 years (corresponds to a red icon in the vehicle list) */
2744  Money profit = v->GetDisplayProfitThisYear();
2745  if (v->age >= 730 && profit < 0) {
2747  SetDParam(0, v->index);
2748  SetDParam(1, profit);
2749  AddVehicleAdviceNewsItem(STR_NEWS_VEHICLE_IS_UNPROFITABLE, v->index);
2750  }
2751  AI::NewEvent(v->owner, new ScriptEventVehicleUnprofitable(v->index));
2752  }
2753 
2755  v->profit_this_year = 0;
2757  }
2758  }
2764 }
2765 
2766 
2776 bool CanVehicleUseStation(EngineID engine_type, const Station *st)
2777 {
2778  const Engine *e = Engine::GetIfValid(engine_type);
2779  assert(e != NULL);
2780 
2781  switch (e->type) {
2782  case VEH_TRAIN:
2783  return (st->facilities & FACIL_TRAIN) != 0;
2784 
2785  case VEH_ROAD:
2786  /* For road vehicles we need the vehicle to know whether it can actually
2787  * use the station, but if it doesn't have facilities for RVs it is
2788  * certainly not possible that the station can be used. */
2789  return (st->facilities & (FACIL_BUS_STOP | FACIL_TRUCK_STOP)) != 0;
2790 
2791  case VEH_SHIP:
2792  return (st->facilities & FACIL_DOCK) != 0;
2793 
2794  case VEH_AIRCRAFT:
2795  return (st->facilities & FACIL_AIRPORT) != 0 &&
2797 
2798  default:
2799  return false;
2800  }
2801 }
2802 
2809 bool CanVehicleUseStation(const Vehicle *v, const Station *st)
2810 {
2811  if (v->type == VEH_ROAD) return st->GetPrimaryRoadStop(RoadVehicle::From(v)) != NULL;
2812 
2813  return CanVehicleUseStation(v->engine_type, st);
2814 }
2815 
2822 {
2823  assert(this->IsGroundVehicle());
2824  if (this->type == VEH_TRAIN) {
2825  return &Train::From(this)->gcache;
2826  } else {
2827  return &RoadVehicle::From(this)->gcache;
2828  }
2829 }
2830 
2837 {
2838  assert(this->IsGroundVehicle());
2839  if (this->type == VEH_TRAIN) {
2840  return &Train::From(this)->gcache;
2841  } else {
2842  return &RoadVehicle::From(this)->gcache;
2843  }
2844 }
2845 
2852 {
2853  assert(this->IsGroundVehicle());
2854  if (this->type == VEH_TRAIN) {
2855  return Train::From(this)->gv_flags;
2856  } else {
2857  return RoadVehicle::From(this)->gv_flags;
2858  }
2859 }
2860 
2866 const uint16 &Vehicle::GetGroundVehicleFlags() const
2867 {
2868  assert(this->IsGroundVehicle());
2869  if (this->type == VEH_TRAIN) {
2870  return Train::From(this)->gv_flags;
2871  } else {
2872  return RoadVehicle::From(this)->gv_flags;
2873  }
2874 }
2875 
2884 void GetVehicleSet(VehicleSet &set, Vehicle *v, uint8 num_vehicles)
2885 {
2886  if (v->type == VEH_TRAIN) {
2887  Train *u = Train::From(v);
2888  /* Only include whole vehicles, so start with the first articulated part */
2889  u = u->GetFirstEnginePart();
2890 
2891  /* Include num_vehicles vehicles, not counting articulated parts */
2892  for (; u != NULL && num_vehicles > 0; num_vehicles--) {
2893  do {
2894  /* Include current vehicle in the selection. */
2895  set.Include(u->index);
2896 
2897  /* If the vehicle is multiheaded, add the other part too. */
2898  if (u->IsMultiheaded()) set.Include(u->other_multiheaded_part->index);
2899 
2900  u = u->Next();
2901  } while (u != NULL && u->IsArticulatedPart());
2902  }
2903  }
2904 }
void ViewportAddVehicles(DrawPixelInfo *dpi)
Add the vehicle sprites that should be drawn at a part of the screen.
Definition: vehicle.cpp:1111
Functions related to OTTD&#39;s strings.
void TriggerStationRandomisation(Station *st, TileIndex tile, StationRandomTrigger trigger, CargoID cargo_type)
Trigger station randomisation.
static TileType GetTileType(TileIndex tile)
Get the tiletype of a given tile.
Definition: tile_map.h:98
Road vehicle states.
bool HasVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
Checks whether a vehicle is on a specific location.
Definition: vehicle.cpp:513
VehicleSettings vehicle
options for vehicles
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:326
Functions/types related to NewGRF debugging.
uint16 reliability
Current reliability of the engine.
Definition: engine_base.h:27
CommandCost EnsureNoTrainOnTrackBits(TileIndex tile, TrackBits track_bits)
Tests if a vehicle interacts with the specified track bits.
Definition: vehicle.cpp:601
Date max_age
Maximum age.
Definition: vehicle_base.h:259
uint32 PaletteID
The number of the palette.
Definition: gfx_type.h:20
static bool IsLocalCompany()
Is the current company the local company?
Definition: company_func.h:45
Vehicle * Previous() const
Get the previous vehicle of this vehicle.
Definition: vehicle_base.h:588
Vehicle is stopped by the player.
Definition: vehicle_base.h:33
Time spent processing cargo movement.
VehicleCargoList cargo
The cargo this vehicle is carrying.
Definition: vehicle_base.h:309
byte state
Definition: roadveh.h:89
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition: settings.cpp:77
static void RunVehicleDayProc()
Increases the day counter for all vehicles and calls 1-day and 32-day handlers.
Definition: vehicle.cpp:913
static Titem * GetIfValid(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:257
uint32 motion_counter
counter to occasionally play a vehicle sound.
Definition: vehicle_base.h:296
Money value
Value of the vehicle.
Definition: vehicle_base.h:241
bool _networking
are we in networking mode?
Definition: network.cpp:56
int virtual_left
Virtual left coordinate.
Definition: viewport_type.h:30
void DecreaseVehicleValue(Vehicle *v)
Decrease the value of a vehicle.
Definition: vehicle.cpp:1203
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
void LoadUnloadStation(Station *st)
Load/unload the vehicles in this station according to the order they entered.
Definition: economy.cpp:1900
Data about how and where to blit pixels.
Definition: gfx_type.h:156
virtual void MarkDirty()
Marks the vehicles to be redrawn and updates cached variables.
Definition: vehicle_base.h:364
The information about a vehicle list.
Definition: vehiclelist.h:31
void ShowVisualEffect() const
Draw visual effects (smoke and/or sparks) for a vehicle chain.
Definition: vehicle.cpp:2505
bool UsesWagonOverride(const Vehicle *v)
Check if a wagon is currently using a wagon override.
Definition of link refreshing utility.
StationID targetairport
Airport to go to next.
Definition: aircraft.h:80
static const int VEHICLE_PROFIT_MIN_AGE
Only vehicles older than this have a meaningful profit.
Definition: vehicle_func.h:29
LiveryScheme
List of different livery schemes.
Definition: livery.h:22
A game normally paused.
Definition: openttd.h:59
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition: window.cpp:3179
byte landscape
the landscape we&#39;re currently in
static bool Chance16I(const uint a, const uint b, const uint32 r)
Checks if a given randomize-number is below a given probability.
Money GetDisplayProfitThisYear() const
Gets the profit vehicle had this year.
Definition: vehicle_base.h:566
DirectionByte direction
facing
Definition: vehicle_base.h:271
Base class for roadstops.
Vehicle * hash_tile_next
NOSAVE: Next vehicle in the tile location hash.
Definition: vehicle_base.h:250
Functions related to the autoreplace GUIs.
East.
void ResetRefitCaps()
Reset all refit_cap in the consist to cargo_cap.
Definition: vehicle.cpp:2226
Train is just leaving a station.
Definition: train.h:35
Don&#39;t cancel current goto depot command if any.
Definition: vehicle_type.h:72
const Pair * Find(const T &key) const
Finds given key in this map.
Vehicle has finished loading.
Definition: vehicle_base.h:44
Functions and type for generating vehicle lists.
Aircraft is broken down.
Definition: vehicle_base.h:38
static RoadStopType GetRoadStopType(TileIndex t)
Get the road stop type of this tile.
Definition: station_map.h:57
static EngineID EngineReplacementForCompany(const Company *c, EngineID engine, GroupID group, bool *replace_when_old=NULL)
Retrieve the engine replacement for the given company and original engine type.
CommandCost EnsureNoVehicleOnGround(TileIndex tile)
Ensure there is no vehicle at the ground at the given position.
Definition: vehicle.cpp:539
Functions related to time tabling.
VehiclePool _vehicle_pool("Vehicle")
The pool with all our precious vehicles.
void InvalidateVehicleOrder(const Vehicle *v, int data)
Updates the widgets of a vehicle which contains the order-data.
Definition: order_cmd.cpp:253
Flag for an invalid DiagDirection.
void HandleAircraftEnterHangar(Aircraft *v)
Handle Aircraft specific tasks when an Aircraft enters a hangar.
int height
Screen height of the viewport.
Definition: viewport_type.h:28
static Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:246
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:84
Functions related to dates.
static bool IsInsideMM(const T x, const uint min, const uint max)
Checks if a value is in an interval.
Definition: math_func.hpp:266
Angle of 45 degrees left.
virtual uint Crash(bool flooded=false)
Crash the (whole) vehicle chain.
Definition: vehicle.cpp:261
Vehicle ** hash_viewport_prev
NOSAVE: Previous vehicle in the visual location hash.
Definition: vehicle_base.h:248
Conventional Take Off and Landing, i.e. planes.
Definition: engine_type.h:93
static T ToggleBit(T &x, const uint8 y)
Toggles a bit in a variable.
void Reset()
Remove all items from the list and free allocated memory.
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:332
Sparcs of electric engines.
byte breakdown_delay
Counter for managing breakdown length.
Definition: vehicle_base.h:264
Use default vehicle palette.
Definition: vehicle_base.h:35
Angle of 90 degrees right.
Vehicle is a shadow vehicle.
Definition: vehicle_base.h:37
Smoke of diesel engines.
Base for the train class.
Other order modifications.
Definition: vehicle_gui.h:35
uint8 smoke_amount
amount of smoke/sparks locomotives produce
virtual ~Vehicle()
We want to &#39;destruct&#39; the right class.
Definition: vehicle.cpp:869
static T SetBit(T &x, const uint8 y)
Set a bit in a variable.
Called to spawn visual effects for vehicles.
void Leave(RoadVehicle *rv)
Leave the road stop.
Definition: roadstop.cpp:218
byte pos
Next desired position of the aircraft.
Definition: aircraft.h:78
void SetTransferLoadPlace(TileIndex xy)
Sets loaded_at_xy to the current station for all cargo to be transfered.
Can planes land on this airport type?
Definition: airport.h:148
uint16 cur_speed
current speed
Definition: vehicle_base.h:293
uint16 cached_cargo_age_period
Number of ticks before carried cargo is aged.
Definition: vehicle_base.h:124
static void AddVehicleAdviceNewsItem(StringID string, VehicleID vehicle)
Adds a vehicle-advice news item.
Definition: news_func.h:42
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
Definition: command_func.h:25
Do not show black smoke during a breakdown.
Definition: engine_type.h:160
Data structure describing a sprite.
Definition: spritecache.h:18
No visual effect.
Definition: vehicle_base.h:99
Depot view; Window numbers:
Definition: window_type.h:346
uint16 cargo_age_counter
Ticks till cargo is aged next.
Definition: vehicle_base.h:310
GRFFilePropsBase< NUM_CARGO+2 > grf_prop
Properties related the the grf file.
Definition: engine_base.h:60
Disaster vehicle type.
Definition: vehicle_type.h:34
Functions to be called to log possibly unsafe game events.
Types for recording game performance data.
Both directions faces to the same direction.
uint16 _returned_refit_capacity
Stores the capacity after a refit operation.
Definition: vehicle.cpp:87
OrderList * list
Pointer to the order list for this vehicle.
Definition: vehicle_base.h:321
Train * GetNextUnit() const
Get the next real (non-articulated part and non rear part of dualheaded engine) vehicle in the consis...
Definition: train.h:146
StationID last_loading_station
Last station the vehicle has stopped at and could possibly leave from with any cargo loaded...
Definition: vehicle_base.h:303
byte visual_effect
Bitstuffed NewGRF visual effect data.
Definition: engine_type.h:124
TileIndex dest_tile
Heading for this tile.
Definition: vehicle_base.h:237
Vehicle ** hash_tile_prev
NOSAVE: Previous vehicle in the tile location hash.
Definition: vehicle_base.h:251
uint16 wait_counter
Ticks waiting in front of a signal, ticks being stuck or a counter for forced proceeding through sign...
Definition: train.h:103
Implementation of simple mapping class.
Functions related to vehicles.
Aircraft, helicopters, rotors and their shadows belong to this class.
Definition: aircraft.h:76
static bool IsWagon(EngineID index)
Determine whether an engine type is a wagon (and not a loco).
Definition: engine.cpp:569
bool lost_vehicle_warn
if a vehicle can&#39;t find its destination, show a warning
Definition: settings_type.h:86
void IncrementImplicitOrderIndex()
Increments cur_implicit_order_index, keeps care of the wrap-around and invalidates the GUI...
Definition: vehicle_base.h:800
Trigger platform when train leaves.
static uint TileX(TileIndex tile)
Get the X component of a tile.
Definition: map_func.h:207
void VehicleEnterDepot(Vehicle *v)
Vehicle entirely entered the depot, update its status, orders, vehicle windows, service it...
Definition: vehicle.cpp:1434
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:1888
void Draw(int x, int y, PaletteID default_pal, bool force_pal) const
Draw the sprite sequence.
Definition: vehicle.cpp:128
Vehicle data structure.
Definition: vehicle_base.h:212
UnitID max_aircraft
max planes in game per company
void Clear()
Remove all items from the list.
byte vehicle_breakdowns
likelihood of vehicles breaking down
Definition: settings_type.h:63
Flags flags
Flags for this airport type.
Definition: airport.h:181
void Change(const U &new_value)
Change the value of the variable.
Definition: backup_type.hpp:86
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:24
const T * Begin() const
Get the pointer to the first item (const)
Only service the vehicle.
Definition: order_type.h:109
void PreDestructor()
Destroy all stuff that (still) needs the virtual functions to work properly.
Definition: vehicle.cpp:803
void LeaveStation()
Perform all actions when leaving a station.
Definition: vehicle.cpp:2174
DifficultySettings difficulty
settings related to the difficulty
TrackBitsByte state
The "track" the ship is following.
Definition: ship.h:29
Start or stop this vehicle, and show information about the current state.
Tindex index
Index of this pool item.
Definition: pool_type.hpp:147
Vehicle is flying in the air.
Definition: airport.h:77
A special vehicle is one of the following:
static const int DAY_TICKS
1 day is 74 ticks; _date_fract used to be uint16 and incremented by 885.
Definition: date_type.h:30
PaletteID GetVehiclePalette(const Vehicle *v)
Get the colour map for a vehicle.
Definition: vehicle.cpp:1976
void SetNext(Vehicle *next)
Set the next vehicle of this vehicle.
Definition: vehicle.cpp:2655
void UpdateViewport(bool force_update, bool update_delta)
Update vehicle sprite- and position caches.
Vehicle is unloading cargo.
Definition: vehicle_base.h:45
bool IsMultiheaded() const
Check if the vehicle is a multiheaded engine.
Base for aircraft.
StationID last_station_visited
The last station we stopped at.
Definition: vehicle_base.h:302
#define lastof(x)
Get the last element of an fixed size array.
Definition: depend.cpp:50
bool CanBuildVehicleInfrastructure(VehicleType type)
Check whether we can build infrastructure for the given vehicle type.
Definition: vehicle.cpp:1751
uint16 reliability_spd_dec
Reliability decrease speed.
Definition: vehicle_base.h:262
Electric model.
Definition: vehicle_base.h:102
void UpdateViewport(bool dirty)
Update the vehicle on the viewport, updating the right hash and setting the new coordinates.
Definition: vehicle.cpp:1565
Simple vector template class.
void DeleteVehicleOrders(Vehicle *v, bool keep_orderlist, bool reset_order_indices)
Delete all orders from a vehicle.
Definition: order_cmd.cpp:1926
void MarkTilesDirty(bool cargo_change) const
Marks the tiles of the station as dirty.
Definition: station.cpp:200
A game paused because a (critical) error.
Definition: openttd.h:62
Money GetCost() const
The costs as made up to this moment.
Definition: command_type.h:84
void HandlePathfindingResult(bool path_found)
Handle the pathfinding result, especially the lost status.
Definition: vehicle.cpp:776
bool IsArticulatedVehicleCarryingDifferentCargoes(const Vehicle *v, CargoID *cargo_type)
Tests if all parts of an articulated vehicle are refitted to the same cargo.
void AircraftNextAirportPos_and_Order(Aircraft *v)
set the right pos when heading to other airports after takeoff
The most basic (normal) sprite.
Definition: gfx_type.h:298
Visual effects and wagon power.
#define CLRBITS(x, y)
Clears several bits in a variable.
T * GetFirstEnginePart()
Get the first part of an articulated engine.
static const byte LIT_COMPANY
Show the liveries of your own company.
Definition: livery.h:18
LiveryScheme GetEngineLiveryScheme(EngineID engine_type, EngineID parent_engine_type, const Vehicle *v)
Determines the LiveryScheme for a vehicle.
Definition: vehicle.cpp:1797
First bit that contains the offset (0 = front, 8 = centre, 15 = rear)
Definition: vehicle_base.h:79
Common return value for all commands.
Definition: command_type.h:25
uint32 cached_power
Total power of the consist (valid only for the first engine).
GrfSpecFeature GetGrfSpecFeature(TileIndex tile)
Get the GrfSpecFeature associated with the tile.
void StartSpriteCombine()
Starts a block of sprites, which are "combined" into a single bounding box.
Definition: viewport.cpp:751
RAII class for measuring simple elements of performance.
StationCargoList cargo
The cargo packets of cargo waiting in this station.
Definition: station_base.h:255
static T max(const T a, const T b)
Returns the maximum of two values.
Definition: math_func.hpp:26
void MarkAllViewportsDirty() const
Marks viewports dirty where the vehicle&#39;s image is.
Definition: vehicle.cpp:1606
bool HasRating() const
Does this cargo have a rating at this station?
Definition: station_base.h:273
byte vehstatus
Status.
Definition: vehicle_base.h:317
UnitID GetFreeUnitNumber(VehicleType type)
Get an unused unit number for a vehicle (if allowed).
Definition: vehicle.cpp:1722
Cached, frequently calculated values.
uint StoredCount() const
Returns sum of cargo on board the vehicle (ie not only reserved).
Definition: cargopacket.h:366
uint Return(uint max_move, StationCargoList *dest, StationID next_station)
Returns reserved cargo to the station and removes it from the cache.
Time spent processing aircraft.
static void Reset(PerformanceElement elem)
Store the previous accumulator value and reset for a new cycle of accumulating measurements.
static Train * From(Vehicle *v)
Converts a Vehicle to SpecializedVehicle with type checking.
CompanySettings settings
settings specific for each company
Definition: company_base.h:126
const T * End() const
Get the pointer behind the last valid item (const)
Generates sequence of free UnitID numbers.
bool NeedsAutomaticServicing() const
Checks if the current order should be interrupted for a service-in-depot order.
Definition: vehicle.cpp:253
const Engine * GetEngine() const
Retrieves the engine of the vehicle.
Definition: vehicle.cpp:744
Vehicle * next_shared
pointer to the next vehicle that shares the order
Definition: vehicle_base.h:221
bool IsNormalAircraft() const
Check if the aircraft type is a normal flying device; eg not a rotor or a shadow. ...
Definition: aircraft.h:123
GoodsEntry goods[NUM_CARGO]
Goods at this station.
Definition: station_base.h:472
static const uint TILE_SIZE
Tile size in world coordinates.
Definition: tile_type.h:15
byte VehicleRandomBits()
Get a value for a vehicle&#39;s random_bits.
Definition: vehicle.cpp:363
Use default from engine class.
Definition: vehicle_base.h:85
FreeUnitIDGenerator(VehicleType type, CompanyID owner)
Initializes the structure.
Definition: vehicle.cpp:1682
static uint32 RandomRange(uint32 limit)
Pick a random number between 0 and limit - 1, inclusive.
Definition: random_func.hpp:83
VehicleSpriteSeq sprite_seq
Vehicle appearance.
Definition: vehicle_base.h:280
Direction
Defines the 8 directions on the map.
Maglev engine.
Definition: engine_type.h:39
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.
Vehicle * hash_viewport_next
NOSAVE: Next vehicle in the visual location hash.
Definition: vehicle_base.h:247
OrderDepotActionFlags GetDepotActionType() const
What are we going to do when in the depot.
Definition: order_base.h:139
int8 x_bb_offs
x offset of vehicle bounding box
Definition: vehicle_base.h:284
DepotCommand
Flags to add to p1 for goto depot commands.
Definition: vehicle_type.h:69
uint32 GetGRFID() const
Retrieve the GRF ID of the NewGRF the engine is tied to.
Definition: engine.cpp:162
Money profit_last_year
Profit last year << 8, low 8 bits are fract.
Definition: vehicle_base.h:240
Mono rail engine.
Definition: engine_type.h:38
Southeast.
SmallPair< T, U > * Append(uint to_add=1)
Append an item and return it.
Order * next
Pointer to next order. If NULL, end of list.
Definition: order_base.h:51
EngineID first_engine
Cached EngineID of the front vehicle. INVALID_ENGINE for the front vehicle itself.
Diesel model.
Definition: vehicle_base.h:101
Class to backup a specific variable and restore it later.
Definition: backup_type.hpp:23
Diesel rail engine.
Definition: engine_type.h:36
replace/renew a vehicle while it is in a depot
Definition: command_type.h:314
CompanyByte _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition: company_cmd.cpp:46
Value of offset corresponding to a position above the centre of the vehicle.
Definition: vehicle_base.h:81
bool no_servicing_if_no_breakdowns
don&#39;t send vehicles to depot when breakdowns are disabled
Functions related to (drawing on) viewports.
Pseudo random number generator.
Northeast.
Vehicle ** hash_tile_current
NOSAVE: Cache of the current hash chain.
Definition: vehicle_base.h:252
static const int32 INVALID_COORD
Sentinel for an invalid coordinate.
int8 y_bb_offs
y offset of vehicle bounding box
Definition: vehicle_base.h:285
Angle of 45 degrees right.
byte breakdown_ctr
Counter for managing breakdown events.
Definition: vehicle_base.h:263
Invalid cargo type.
Definition: cargo_type.h:70
Vehicle running normally.
Definition: newgrf_sound.h:24
The vehicle will stop at any station it passes and the destination.
Definition: order_type.h:79
byte subtype
subtype (Filled with values from AircraftSubType/DisasterSubType/EffectVehicleType/GroundVehicleSubty...
Definition: vehicle_base.h:327
void EndSpriteCombine()
Terminates a block of sprites started by StartSpriteCombine.
Definition: viewport.cpp:761
static bool IsBridgeAbove(TileIndex t)
checks if a bridge is set above the ground of this tile
Definition: bridge_map.h:45
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:3297
TrackBits
Bitfield corresponding to Track.
Definition: track_type.h:41
Buses, trucks and trams belong to this class.
Definition: roadveh.h:88
Critical errors, the MessageBox is shown in all cases.
Definition: error.h:26
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:2267
uint16 cargo_cap
total capacity
Definition: vehicle_base.h:307
void VehicleLengthChanged(const Vehicle *u)
Logs a bug in GRF and shows a warning message if this is for the first time this happened.
Definition: vehicle.cpp:331
void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel wl, int x=0, int y=0, const GRFFile *textref_stack_grffile=NULL, uint textref_stack_size=0, const uint32 *textref_stack=NULL)
Display an error message in a window.
Definition: error_gui.cpp:378
VehicleEnterTileProc * vehicle_enter_tile_proc
Called when a vehicle enters a tile.
Definition: tile_cmd.h:156
Shared order list linking together the linked list of orders and the list of vehicles sharing this or...
Definition: order_base.h:252
void SetDParamStr(uint n, const char *str)
This function is used to "bind" a C string to a OpenTTD dparam slot.
Definition: strings.cpp:279
OrderDepotTypeFlags GetDepotOrderType() const
What caused us going to the depot?
Definition: order_base.h:137
Vehicle orders; Window numbers:
Definition: window_type.h:207
Aircraft vehicle type.
Definition: vehicle_type.h:29
Map related accessors for depots.
static void SpawnAdvancedVisualEffect(const Vehicle *v)
Call CBID_VEHICLE_SPAWN_VISUAL_EFFECT and spawn requested effects.
Definition: vehicle.cpp:2450
Some methods of Pool are placed here in order to reduce compilation time and binary size...
Vehicle is crashed.
Definition: vehicle_base.h:39
static uint32 GetRegister(uint i)
Gets the value of a so-called newgrf "register".
void UpdateCache()
Update the caches of this ship.
Definition: ship_cmd.cpp:205
First bit used for the type of effect.
Definition: vehicle_base.h:83
uint32 grf_bugs
NOSAVE: bugs in this GRF in this run,.
TransparencyOption GetTransparencyOption() const
Determines the transparency option affecting the effect.
virtual bool IsPrimaryVehicle() const
Whether this is the primary vehicle in the chain.
Definition: vehicle_base.h:433
static bool IsTileType(TileIndex tile, TileType type)
Checks if a tile is a given tiletype.
Definition: tile_map.h:152
int16 y_offs
Number of pixels to shift the sprite downwards.
Definition: spritecache.h:22
static void DoDrawVehicle(const Vehicle *v)
Add vehicle sprite for drawing to the screen.
Definition: vehicle.cpp:1081
Normal operation.
Definition: train.h:40
Functions related to errors.
UnitID unitnumber
unit number, for display purposes only
Definition: vehicle_base.h:291
int y
x and y position of the vehicle after moving
Definition: vehicle_func.h:78
CommandCost DoCommand(const CommandContainer *container, DoCommandFlag flags)
Shorthand for calling the long DoCommand with a container.
Definition: command.cpp:440
void MakeImplicit(StationID destination)
Makes this order an implicit order.
Definition: order_cmd.cpp:156
byte subtype
Type of aircraft.
Definition: engine_type.h:102
void AgeVehicle(Vehicle *v)
Update age of a vehicle.
Definition: vehicle.cpp:1328
DateFract _date_fract
Fractional part of the day.
Definition: date.cpp:29
void DeleteVehicleNews(VehicleID vid, StringID news)
Delete a news item type about a vehicle.
Definition: news_gui.cpp:797
static size_t GetPoolSize()
Returns first unused index.
Definition: pool_type.hpp:267
West.
Information about GRF, used in the game and (part of it) in savegames.
static bool IsRailStationTile(TileIndex t)
Is this tile a station tile and a rail station?
Definition: station_map.h:103
void ConsistChanged(ConsistChangeFlags allowed_changes)
Recalculates the cached stuff of a train.
Definition: train_cmd.cpp:109
bool IsRefit() const
Is this order a refit order.
Definition: order_base.h:110
UnitID max_roadveh
max trucks in game per company
Simple pair of data.
Internal structure used in openttd - Finite sTate mAchine –> FTA.
Definition: airport.h:191
The vehicle will not stop at any stations it passes including the destination.
Definition: order_type.h:82
bool HasVehicleOnPosXY(int x, int y, void *data, VehicleFromPosProc *proc)
Checks whether a vehicle in on a specific location.
Definition: vehicle.cpp:454
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:185
void MakeDummy()
Makes this order a Dummy order.
Definition: order_cmd.cpp:135
int8 y_offs
y offset for vehicle sprite
Definition: vehicle_base.h:287
GroundVehicleCache * GetGroundVehicleCache()
Access the ground vehicle cache of the vehicle.
Definition: vehicle.cpp:2821
VehicleType
Available vehicle types.
Definition: vehicle_type.h:23
EngineClass engclass
Class of engine for this vehicle.
Definition: engine_type.h:53
void 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:1752
void HideFillingPercent(TextEffectID *te_id)
Hide vehicle loading indicators.
Definition: misc_gui.cpp:628
Do not load anything.
Definition: order_type.h:72
Manually initiated order.
Definition: order_type.h:100
Don&#39;t load anymore during the next load cycle.
Definition: vehicle_base.h:50
North.
uint32 VehicleID
The type all our vehicle IDs have.
Definition: vehicle_type.h:18
UnitID maxid
maximum ID at the moment of constructor call
StringID GetErrorMessage() const
Returns the error message of a command.
Definition: command_type.h:142
Time spend processing road vehicles.
bool IsType(OrderType type) const
Check whether this order is of the given type.
Definition: order_base.h:63
CommandCost TunnelBridgeIsFree(TileIndex tile, TileIndex endtile, const Vehicle *ignore)
Finds vehicle in tunnel / bridge.
Definition: vehicle.cpp:568
DoCommandFlag
List of flags for a command.
Definition: command_type.h:343
VisualEffectSpawnModel
Models for spawning visual effects.
Definition: vehicle_base.h:98
T * Next() const
Get next vehicle in the chain.
byte callback_mask
Bitmask of vehicle callbacks that have to be called.
Definition: engine_type.h:143
simple wagon, not motorized
Definition: engine_type.h:30
Station with truck stops.
Definition: station_type.h:56
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:76
Rail vehicle is a multiple-unit (DMU/EMU)
Definition: engine_type.h:156
bool Succeeded() const
Did this command succeed?
Definition: command_type.h:152
void IncreaseStats(Station *st, CargoID cargo, StationID next_station_id, uint capacity, uint usage, EdgeUpdateMode mode)
Increase capacity for a link stat given by station cargo and next hop.
void PrepareUnload(Vehicle *front_v)
Prepare the vehicle to be unloaded.
Definition: economy.cpp:1248
Can helicopters land on this airport type?
Definition: airport.h:149
Definition of base types and functions in a cross-platform compatible way.
PaletteID GetEnginePalette(EngineID engine_type, CompanyID company)
Get the colour map for an engine.
Definition: vehicle.cpp:1966
static const uint VEHICLE_LENGTH
The length of a vehicle in tile units.
Definition: vehicle_type.h:80
bool IsArticulatedPart() const
Check if the vehicle is an articulated part of an engine.
Definition: vehicle_base.h:892
A number of safeguards to prevent using unsafe methods.
Trigger platform when train leaves.
byte x_extent
x-extent of vehicle bounding box
Definition: vehicle_base.h:281
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:28
void VehicleEnteredDepotThisTick(Vehicle *v)
Adds a vehicle to the list of vehicles that visited a depot this tick.
Definition: vehicle.cpp:895
Vehicle uses two company colours.
Definition: engine_type.h:155
bool HasAnyRailtypesAvail(const CompanyID company)
Test if any buildable railtype is available for a company.
Definition: rail.cpp:198
void DeleteDepotHighlightOfVehicle(const Vehicle *v)
Removes the highlight of a vehicle in a depot window.
Definition: depot_gui.cpp:1119
void DeleteOrder(Vehicle *v, VehicleOrderID sel_ord)
Delete an order but skip the parameter validation.
Definition: order_cmd.cpp:1082
Vehicle refit; Window numbers:
Definition: window_type.h:201
DirDiff
Enumeration for the difference between two directions.
static uint CeilDiv(uint a, uint b)
Computes ceil(a / b) for non-negative a and b.
Definition: math_func.hpp:316
Electric sparks.
Definition: vehicle_base.h:88
Station * GetTargetAirportIfValid(const Aircraft *v)
Returns aircraft&#39;s target station if v->target_airport is a valid station with airport.
struct AirportFTA * layout
state machine for airport
Definition: airport.h:178
byte z_extent
z-extent of vehicle bounding box
Definition: vehicle_base.h:283
byte visual_effect
Bitstuffed NewGRF visual effect data.
Definition: engine_type.h:74
VehicleType type
Vehicle type, ie VEH_ROAD, VEH_TRAIN, etc.
Definition: engine_base.h:42
Valid changes for arranging the consist in a depot.
Definition: train.h:55
Every 16 ticks while the vehicle is running (speed > 0).
Definition: newgrf_sound.h:27
CargoID cargo_type
type of cargo this vehicle is carrying
Definition: vehicle_base.h:305
uint32 engine_renew_money
minimum amount of money before autorenew is used
uint ActionCount(MoveToAction action) const
Returns the amount of cargo designated for a given purpose.
Definition: cargopacket.h:356
CompanyMask company_avail
Bit for each company whether the engine is available for that company.
Definition: engine_base.h:39
void AddToShared(Vehicle *shared_chain)
Adds this vehicle to a shared vehicle chain.
Definition: vehicle.cpp:2684
Change colour mapping of vehicle.
Information about a particular livery.
Definition: livery.h:80
Effect vehicle type (smoke, explosions, sparks, bubbles)
Definition: vehicle_type.h:33
Vehicle view; Window numbers:
Definition: window_type.h:334
static const byte LIT_ALL
Show the liveries of all companies.
Definition: livery.h:19
GroupStatistics group_all[VEH_COMPANY_END]
NOSAVE: Statistics for the ALL_GROUP group.
Definition: company_base.h:127
Functions related to order backups.
Smoke of broken vehicles except aircraft.
bool IsFrontEngine() const
Check if the vehicle is a front engine.
Definition: vehicle_base.h:883
GRFBugs
Encountered GRF bugs.
Definition: newgrf_config.h:44
byte misc_flags
Miscellaneous flags.
Definition: engine_type.h:142
Map accessor functions for bridges.
void FindVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
Find a vehicle from a specific location.
Definition: vehicle.cpp:498
TileIndex tile
Current tile index.
Definition: vehicle_base.h:230
Road vehicle list; Window numbers:
Definition: window_type.h:309
CommandCost CheckOwnership(Owner owner, TileIndex tile)
Check whether the current owner owns something.
static void CountVehicle(const Vehicle *v, int delta)
Update num_vehicle when adding or removing a vehicle.
Definition: group_cmd.cpp:138
static Vehicle * VehicleFromPos(TileIndex tile, void *data, VehicleFromPosProc *proc, bool find_first)
Helper function for FindVehicleOnPos/HasVehicleOnPos.
Definition: vehicle.cpp:469
Money money
Money owned by the company.
Definition: company_base.h:64
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:1785
Vehicle timetable; Window numbers:
Definition: window_type.h:219
Every 16 ticks while the vehicle is stopped (speed == 0).
Definition: newgrf_sound.h:28
bool CanVehicleUseStation(EngineID engine_type, const Station *st)
Can this station be used by the given engine type?
Definition: vehicle.cpp:2776
Steam model.
Definition: vehicle_base.h:100
static const GroupID INVALID_GROUP
Sentinel for invalid groups.
Definition: group_type.h:20
Station view; Window numbers:
Definition: window_type.h:340
OrderLoadFlags GetLoadType() const
How must the consist be loaded?
Definition: order_base.h:129
Base class for all effect vehicles.
Basic functions/variables used all over the place.
static DirDiff DirDifference(Direction d0, Direction d1)
Calculate the difference between two directions.
Service the vehicle and then halt it.
Definition: order_type.h:110
bool IsRearDualheaded() const
Tell if we are dealing with the rear end of a multiheaded engine.
uint16 num_vehicle
Number of vehicles.
Definition: group.h:27
static Direction ChangeDir(Direction d, DirDiff delta)
Change a direction by a given difference.
int8 x_offs
x offset for vehicle sprite
Definition: vehicle_base.h:286
StationFacilityByte facilities
The facilities that this station has.
Sprite sequence for a vehicle part.
Definition: vehicle_base.h:130
uint64 flags
stores which blocks on the airport are taken. was 16 bit earlier on, then 32
Definition: station_base.h:308
Called to determine if a specific colour map should be used for a vehicle instead of the default live...
Road vehicle type.
Definition: vehicle_type.h:27
static T min(const T a, const T b)
Returns the minimum of two values.
Definition: math_func.hpp:42
static bool IsCargoInClass(CargoID c, CargoClass cc)
Does cargo c have cargo class cc?
Definition: cargotype.h:150
byte previous_pos
Previous desired position of the aircraft.
Definition: aircraft.h:79
Station with a dock.
Definition: station_type.h:59
uint16 refit_cap
Capacity left over from before last refit.
Definition: vehicle_base.h:308
Functions related to sound.
byte breakdowns_since_last_service
Counter for the amount of breakdowns.
Definition: vehicle_base.h:265
uint16 reliability
Reliability.
Definition: vehicle_base.h:261
Functions to cache sprites in memory.
uint32 StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:18
Vehicle * First() const
Get the first vehicle of this vehicle chain.
Definition: vehicle_base.h:594
Vehicle&#39;s pathfinder is lost.
Definition: vehicle_base.h:51
bool Failed() const
Did this command fail?
Definition: command_type.h:161
byte tick_counter
Increased by one for each tick.
Definition: vehicle_base.h:314
EffectVehicle * CreateEffectVehicleRel(const Vehicle *v, int x, int y, int z, EffectVehicleType type)
Create an effect vehicle above a particular vehicle.
byte colour2
Second colour, for vehicles with 2CC support.
Definition: livery.h:83
UnitID curid
last ID returned; 0 if none
All ships have this type.
Definition: ship.h:28
void InvalidateAutoreplaceWindow(EngineID e, GroupID id_g)
Rebuild the left autoreplace list if an engine is removed or added.
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:654
bool PlayVehicleSound(const Vehicle *v, VehicleSoundEvent event)
Checks whether a NewGRF wants to play a different vehicle sound effect.
#define return_cmd_error(errcode)
Returns from a function with a specific StringID as error.
Definition: command_func.h:35
byte state
State of the airport.
Definition: aircraft.h:81
int16 engine_renew_months
months before/after the maximum vehicle age a vehicle should be renewed
Base class for all pools.
Definition: pool_type.hpp:83
bool engine_renew
is autorenew enabled
uint16 height
Height of the sprite.
Definition: spritecache.h:19
Ship vehicle type.
Definition: vehicle_type.h:28
static void NewEvent(CompanyID company, ScriptEvent *event)
Queue a new event for an AI.
Definition: ai_core.cpp:233
#define DEBUG(name, level,...)
Output a line of debugging information.
Definition: debug.h:36
&#39;Train&#39; is either a loco or a wagon.
Definition: train.h:88
static bool Chance16(const uint a, const uint b)
Flips a coin with given probability.
TileIndex old_tile
Current tile of the vehicle.
Definition: vehicle_func.h:79
bool IsEngineCountable() const
Check if a vehicle is counted in num_engines in each company struct.
Definition: vehicle.cpp:711
byte breakdown_chance
Current chance of breakdowns.
Definition: vehicle_base.h:266
The vehicle is in a drive-through road stop.
Definition: roadveh.h:52
Diesel fumes.
Definition: vehicle_base.h:87
Livery livery
Custom colour scheme for vehicles in this group.
Definition: group.h:73
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don&#39;t get linker errors.
Definition: pool_func.hpp:224
int left
Screen coordinate left egde of the viewport.
Definition: viewport_type.h:25
void DeleteWindowById(WindowClass cls, WindowNumber number, bool force)
Delete a window by its class and window number (if it is open).
Definition: window.cpp:1143
union Vehicle::@47 orders
The orders currently assigned to the vehicle.
VehicleEnterTileStatus VehicleEnterTile(Vehicle *v, TileIndex tile, int x, int y)
Call the tile callback function for a vehicle entering a tile.
Definition: vehicle.cpp:1670
static void UpdateProfits()
Recompute the profits for all groups.
Definition: group_cmd.cpp:185
void RemoveFromShared()
Removes the vehicle from the shared order list.
Definition: vehicle.cpp:2707
void AddVehicle(Vehicle *v)
Adds the given vehicle to this shared order list.
Definition: order_base.h:354
execute the given command
Definition: command_type.h:345
UnitID max_ships
max ships in game per company
Flag to disable visual effect.
Definition: vehicle_base.h:90
static const EngineID INVALID_ENGINE
Constant denoting an invalid engine.
Definition: engine_type.h:174
bool vehicle_income_warn
if a vehicle isn&#39;t generating income, show a warning
Definition: settings_type.h:88
Steam plumes.
Definition: vehicle_base.h:86
static const GroupID DEFAULT_GROUP
Ungrouped vehicles are in this group.
Definition: group_type.h:19
The vehicle will leave the depot right after arrival (serivce only)
Definition: vehicle_type.h:70
uint16 width
Width of the sprite.
Definition: spritecache.h:20
Functions related to companies.
Called for every vehicle every 32 days (not all on same date though).
RailType GetTileRailType(TileIndex tile)
Return the rail type of tile, or INVALID_RAILTYPE if this is no rail tile.
Definition: rail.cpp:157
GetNewVehiclePosResult GetNewVehiclePos(const Vehicle *v)
Get position information of a vehicle when moving one pixel in the direction it is facing...
Definition: vehicle.cpp:1616
void UpdatePosition()
Update the position of the vehicle.
Definition: vehicle.cpp:1555
static StationID GetStationIndex(TileIndex t)
Get StationID from a tile.
Definition: station_map.h:29
static TileIndex TileVirtXY(uint x, uint y)
Get a tile from the virtual XY-coordinate.
Definition: map_func.h:196
GRFConfig * GetGRFConfig(uint32 grfid, uint32 mask)
Retrieve a NewGRF from the current config by its grfid.
static const PaletteID PALETTE_RECOLOUR_START
First recolour sprite for company colours.
Definition: sprites.h:1543
Functions related to articulated vehicles.
void ErrorUnknownCallbackResult(uint32 grfid, uint16 cbid, uint16 cb_res)
Record that a NewGRF returned an unknown/invalid callback result.
Header file for NewGRF stations.
static T ClrBit(T &x, const uint8 y)
Clears a bit in a variable.
bool IsGroundVehicle() const
Check if the vehicle is a ground vehicle.
Definition: vehicle_base.h:471
GUISettings gui
settings related to the GUI
const GRFFile * GetGRF() const
Retrieve the NewGRF the engine is tied to.
Definition: engine_base.h:140
DestinationID GetDestination() const
Gets the destination of this order.
Definition: order_base.h:96
bool NeedsAutorenewing(const Company *c, bool use_renew_setting=true) const
Function to tell if a vehicle needs to be autorenewed.
Definition: vehicle.cpp:142
void VehicleServiceInDepot(Vehicle *v)
Service a vehicle and all subsequent vehicles in the consist.
Definition: vehicle.cpp:164
GroupID parent
Parent group.
Definition: group.h:76
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:3193
CargoList that is used for vehicles.
Definition: cargopacket.h:283
Time spent processing ships.
Smoke of steam engines.
bool HandleBreakdown()
Handle all of the aspects of a vehicle breakdown This includes adding smoke and sounds, and ending the breakdown when appropriate.
Definition: vehicle.cpp:1262
static void ClearVehicle(const Vehicle *v)
Clear/update the (clone) vehicle from an order backup.
Data structure for viewport, display of a part of the world.
Definition: viewport_type.h:24
static const int MAX_VEHICLE_PIXEL_X
Maximum width of a vehicle in pixels in #ZOOM_LVL_BASE.
Definition: tile_type.h:21
Used for vehicle var 0xFE bit 8 (toggled each time the train is reversed, accurate for first vehicle ...
Definition: train.h:33
uint16 EngineID
Unique identification number of an engine.
Definition: engine_type.h:22
void UpdateVehicleTimetable(Vehicle *v, bool travelling)
Update the timetable for the vehicle.
static CargoSpec * Get(size_t index)
Retrieve cargo details for the given cargo ID.
Definition: cargotype.h:118
CompanyByte _current_company
Company currently doing an action.
Definition: company_cmd.cpp:47
Number of bits used for the effect type.
Definition: vehicle_base.h:84
static Vehicle * EnsureNoVehicleProcZ(Vehicle *v, void *data)
Callback that returns &#39;real&#39; vehicles lower or at height *(int*)data .
Definition: vehicle.cpp:524
Ships list; Window numbers:
Definition: window_type.h:315
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:80
static const PaletteID PALETTE_CRASH
Recolour sprite greying of crashed vehicles.
Definition: sprites.h:1574
Bitflag for a depot.
Definition: track_type.h:59
static Vehicle * GetVehicleTunnelBridgeProc(Vehicle *v, void *data)
Procedure called for every vehicle found in tunnel/bridge in the hash map.
Definition: vehicle.cpp:553
uint32 Pack() const
Pack a VehicleListIdentifier in a single uint32.
Definition: vehiclelist.cpp:23
void DeleteGroupHighlightOfVehicle(const Vehicle *v)
Removes the highlight of a vehicle in a group window.
Definition: group_gui.cpp:1022
Functions related to depots.
void BeginLoading()
Prepare everything to begin the loading when arriving at a station.
Definition: vehicle.cpp:2027
Vehicle * Next() const
Get the next vehicle of this vehicle.
Definition: vehicle_base.h:581
Date date_of_last_service
Last date the vehicle had a service at a depot.
Definition: vehicle_base.h:260
void InsertOrder(Vehicle *v, Order *new_o, VehicleOrderID sel_ord)
Insert a new order but skip the validation.
Definition: order_cmd.cpp:954
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:298
Position information of a vehicle after it moved.
Definition: vehicle_func.h:77
OrderSettings order
settings related to orders
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:2884
void FindVehicleOnPosXY(int x, int y, void *data, VehicleFromPosProc *proc)
Find a vehicle from a specific location.
Definition: vehicle.cpp:438
static const int MAX_VEHICLE_PIXEL_Y
Maximum height of a vehicle in pixels in #ZOOM_LVL_BASE.
Definition: tile_type.h:22
Send the vehicle to the nearest depot.
Definition: order_type.h:111
static uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition: map_func.h:217
static Vehicle * VehicleFromPosXY(int x, int y, void *data, VehicleFromPosProc *proc, bool find_first)
Helper function for FindVehicleOnPos/HasVehicleOnPos.
Definition: vehicle.cpp:411
uint64 block
64 bit blocks (st->airport.flags), should be enough for the most complex airports ...
Definition: airport.h:193
Powered wagon changed poweredness state when not inside a depot.
Definition: newgrf_config.h:47
OwnerByte owner
Which company owns the vehicle?
Definition: vehicle_base.h:273
UnitID NextID()
Returns next free UnitID.
Definition: vehicle.cpp:1708
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:640
static T abs(const T a)
Returns the absolute value of (scalar) variable.
Definition: math_func.hpp:83
turn a train around
Definition: command_type.h:223
TileIndex xy
Base tile of the station.
void GetArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type, CargoTypes *union_mask, CargoTypes *intersection_mask)
Merges the refit_masks of all articulated parts.
static void UpdateAutoreplace(CompanyID company)
Update autoreplace_defined and autoreplace_finished of all statistics of a company.
Definition: group_cmd.cpp:212
static uint GB(const T x, const uint8 s, const uint8 n)
Fetch n bits from x, started at bit s.
bool GamelogGRFBugReverse(uint32 grfid, uint16 internal_id)
Logs GRF bug - rail vehicle has different length after reversing.
Definition: gamelog.cpp:565
Trains list; Window numbers:
Definition: window_type.h:303
Functions related to zooming.
Full load all cargoes of the consist.
Definition: order_type.h:70
void AgeCargo()
Ages the all cargo in this list.
Vehicle * next
pointer to the next vehicle in the chain
Definition: vehicle_base.h:217
void SubtractMoneyFromCompany(CommandCost cost)
Subtract money from the _current_company, if the company is valid.
void DeleteUnreachedImplicitOrders()
Delete all implicit orders which were not reached.
Definition: vehicle.cpp:1988
void ReleaseDisastersTargetingVehicle(VehicleID vehicle)
Notify disasters that we are about to delete a vehicle.
A tile of a station.
Definition: tile_type.h:48
const TileTypeProcs *const _tile_type_procs[16]
Tile callback functions for each type of tile.
Definition: landscape.cpp:62
Invalid transparency option.
Definition: transparency.h:35
SmallMap< Vehicle *, bool, 4 > AutoreplaceMap
List of vehicles that should check for autoreplace this tick.
Definition: vehicle.cpp:691
Vehicle * previous_shared
NOSAVE: pointer to the previous vehicle in the shared order chain.
Definition: vehicle_base.h:222
Reverse the visible direction of the vehicle.
Definition: train.h:30
bool show_track_reservation
highlight reserved tracks.
uint16 _returned_mail_refit_capacity
Stores the mail capacity after a refit operation (Aircraft only).
Definition: vehicle.cpp:88
#define MAX_DAY
The number of days till the last day.
Definition: date_type.h:97
int16 x_offs
Number of pixels to shift the sprite to the right.
Definition: spritecache.h:21
Group data.
Definition: group.h:67
Station with train station.
Definition: station_type.h:55
Totally no unloading will be done.
Definition: order_type.h:62
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function() ...
Definition: pool_type.hpp:216
Vehicle * CheckClickOnVehicle(const ViewPort *vp, int x, int y)
Find the vehicle close to the clicked coordinates.
Definition: vehicle.cpp:1169
virtual void OnNewDay()
Calls the new day handler of the vehicle.
Definition: vehicle_base.h:533
bool HasEngineType() const
Check whether Vehicle::engine_type has any meaning.
Definition: vehicle.cpp:728
Vehicle breaking down.
Definition: newgrf_sound.h:23
Default value to indicate that visual effect should be based on engine class.
Definition: vehicle_base.h:94
Aircraft list; Window numbers:
Definition: window_type.h:321
uint16 & GetGroundVehicleFlags()
Access the ground vehicle flags of the vehicle.
Definition: vehicle.cpp:2851
int32 z_pos
z coordinate.
Definition: vehicle_base.h:270
Vehicle is not visible.
Definition: vehicle_base.h:32
Vehicle details; Window numbers:
Definition: window_type.h:195
Functions/definitions that have something to do with groups.
Functions related to commands.
static bool IsValidID(size_t index)
Tests whether given index is a valid index for station of this type.
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:81
Coordinates of a point in 2D.
Vehicle * previous
NOSAVE: pointer to the previous vehicle in the chain.
Definition: vehicle_base.h:218
uint8 CalcPercentVehicleFilled(const Vehicle *front, StringID *colour)
Calculates how full a vehicle is.
Definition: vehicle.cpp:1375
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-NULL) Titem.
Definition: pool_type.hpp:235
uint16 local_id
id defined by the grf file for this entity
static void CountEngine(const Vehicle *v, int delta)
Update num_engines when adding/removing an engine.
Definition: group_cmd.cpp:161
uint32 GetGRFID() const
Retrieve the GRF ID of the NewGRF the vehicle is tied to.
Definition: vehicle.cpp:764
uint16 UnitID
Type for the company global vehicle unit number.
Base classes related to the economy.
Base for ships.
static WindowClass GetWindowClassForVehicleType(VehicleType vt)
Get WindowClass for vehicle list of given vehicle type.
Definition: vehicle_gui.h:85
void GetConsistFreeCapacities(SmallMap< CargoID, uint > &capacities) const
Get a map of cargoes and free capacities in the consist.
Definition: vehicle.cpp:2271
New vehicles.
Definition: economy_type.h:152
void KeepAll()
Marks all cargo in the vehicle as to be kept.
Definition: cargopacket.h:422
Station with bus stops.
Definition: station_type.h:57
UnitID max_trains
max trains in game per company
Declaration of link graph classes used for cargo distribution.
bool * cache
array of occupied unit id numbers
EffectVehicleType
Effect vehicle types.
Steam rail engine.
Definition: engine_type.h:35
Order * GetOrder(int index) const
Returns order &#39;index&#39; of a vehicle or NULL when it doesn&#39;t exists.
Definition: vehicle_base.h:860
static const StringID INVALID_STRING_ID
Constant representing an invalid string (16bit in case it is used in savegames)
Definition: strings_type.h:19
CommandCost SendToDepot(DoCommandFlag flags, DepotCommand command)
Send this vehicle to the depot using the given command(s).
Definition: vehicle.cpp:2301
uint16 GetVehicleCallback(CallbackID callback, uint32 param1, uint32 param2, EngineID engine, const Vehicle *v)
Evaluate a newgrf callback for vehicles.
const char * GetName() const
Get the name of this grf.
uint8 cached_veh_length
Length of this vehicle in units of 1/VEHICLE_LENGTH of normal length. It is cached because this can b...
static bool IsTunnelTile(TileIndex t)
Is this a tunnel (entrance)?
Definition: tunnel_map.h:35
Airport airport
Tile area the airport covers.
Definition: station_base.h:460
Northwest.
byte y_extent
y-extent of vehicle bounding box
Definition: vehicle_base.h:282
Flag to disable wagon power.
Definition: vehicle_base.h:92
EngineID engine_type
The type of engine used for this vehicle.
Definition: vehicle_base.h:288
byte liveries
options for displaying company liveries, 0=none, 1=self, 2=all
const struct GRFFile * grffile
grf file that introduced this entity
ZoomLevel zoom
The zoom level of the viewport.
Definition: viewport_type.h:35
South.
byte cached_vis_effect
Visual effect to show (see VisualEffect)
Definition: vehicle_base.h:126
Passengers.
Definition: cargotype.h:40
bool disable_unsuitable_building
disable infrastructure building when no suitable vehicles are available
int32 x_pos
x coordinate.
Definition: vehicle_base.h:268
virtual bool Tick()
Calls the tick handler of the vehicle.
Definition: vehicle_base.h:528
uint16 vehicle_flags
Used for gradual loading and other miscellaneous things (.
Definition: base_consist.h:32
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
Functions related to NewGRF provided sounds.
void Restore()
Restore the variable.
Base functions for all AIs.
#define FOR_ALL_VEHICLES(var)
Iterate over all vehicles.
Definition: vehicle_base.h:987
Map accessors for tunnels.
const GRFFile * GetGRF() const
Retrieve the NewGRF the vehicle is tied to.
Definition: vehicle.cpp:754
byte colour1
First colour, for all vehicles.
Definition: livery.h:82
int virtual_top
Virtual top coordinate.
Definition: viewport_type.h:31
GameCreationSettings game_creation
settings used during the creation of a game (map)
Smoke of broken aircraft.
static void VehicleReachedProfitAge(const Vehicle *v)
Add a vehicle to the profit sum of its group.
Definition: group_cmd.cpp:171
Specification of a rectangle with absolute coordinates of all edges.
byte CargoID
Cargo slots to indicate a cargo type within a game.
Definition: cargo_type.h:22
int32 y_pos
y coordinate.
Definition: vehicle_base.h:269
static bool IsInvisibilitySet(TransparencyOption to)
Check if the invisibility option bit is set and if we aren&#39;t in the game menu (there&#39;s never transpar...
Definition: transparency.h:61
Road vehicle is a tram/light rail vehicle.
Definition: engine_type.h:154
Owner
Enum for all companies/owners.
Definition: company_type.h:20
Length of rail vehicle changes when not inside a depot.
Definition: newgrf_config.h:45
Flag for advanced effects.
Definition: vehicle_base.h:91
static bool IsDepotTile(TileIndex tile)
Is the given tile a tile with a depot on it?
Definition: depot_map.h:43
int top
Screen coordinate top edge of the viewport.
Definition: viewport_type.h:26
void ShowCostOrIncomeAnimation(int x, int y, int z, Money cost)
Display animated income or costs on the map.
Definition: misc_gui.cpp:553
Vehicle(VehicleType type=VEH_INVALID)
Vehicle constructor.
Definition: vehicle.cpp:346
VehicleEnterTileStatus
The returned bits of VehicleEnterTile.
Definition: tile_cmd.h:22
One direction is the opposite of the other one.
SpriteID sprite
The &#39;real&#39; sprite.
Definition: gfx_type.h:25
static const VehicleOrderID MAX_VEH_ORDER_ID
Last valid VehicleOrderID.
Definition: order_type.h:25
Money profit_this_year
Profit this year << 8, low 8 bits are fract.
Definition: vehicle_base.h:239
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting)
Definition: window.cpp:3207
This depot order is because of a regular order.
Definition: order_type.h:102
Functions related to news.
uint16 animation_state
State primarily used to change the graphics/behaviour.
Base classes/functions for stations.
VehicleCache vcache
Cache of often used vehicle values.
Definition: vehicle_base.h:330
static Station * Get(size_t index)
Gets station with given index.
Date _date
Current date in days (day counter)
Definition: date.cpp:28
Number of bits used for the offset.
Definition: vehicle_base.h:80
static Direction ReverseDir(Direction d)
Return the reverse of a direction.
Functions related to autoreplacing.
Company view; Window numbers:
Definition: window_type.h:364
Rect coord
NOSAVE: Graphical bounding box of the vehicle, i.e. what to redraw on moves.
Definition: vehicle_base.h:245
TileIndex new_tile
Tile of the vehicle after moving.
Definition: vehicle_func.h:80
Vehicle * first
NOSAVE: pointer to the first vehicle in the chain.
Definition: vehicle_base.h:219
Date age
Age in days.
Definition: vehicle_base.h:258
Southwest.
static bool IsCompanyBuildableVehicleType(VehicleType type)
Is the given vehicle type buildable by a company?
Definition: vehicle_func.h:91
void DeleteNewGRFInspectWindow(GrfSpecFeature feature, uint index)
Delete inspect window for a given feature and index.
This depot order is because of the servicing limit.
Definition: order_type.h:101
VehicleOrderID cur_real_order_index
The index to the current real (non-implicit) order.
Definition: base_consist.h:29
VehicleTypeByte type
Type of vehicle.
Definition: vehicle_type.h:56
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:2236
Class for backupping variables and making sure they are restored later.
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:34
Station data structure.
Definition: station_base.h:446
Functions related to effect vehicles.
static bool IsTransparencySet(TransparencyOption to)
Check if the transparency option bit is set and if we aren&#39;t in the game menu (there&#39;s never transpar...
Definition: transparency.h:50
Time spent processing trains.
uint32 cached_weight
Total weight of the consist (valid only for the first engine).
Disable insertion and removal of automatic orders until the vehicle completes the real order...
Station with an airport.
Definition: station_type.h:58
Train is slowing down.
Definition: vehicle_base.h:36
byte day_counter
Increased by one for each day.
Definition: vehicle_base.h:313
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:833
static bool TracksOverlap(TrackBits bits)
Checks if the given tracks overlap, ie form a crossing.
Definition: track_func.h:655
Order current_order
The current order (+ status, like: loading)
Definition: vehicle_base.h:318
void UpdatePositionAndViewport()
Update the position of the vehicle, and update the viewport.
Definition: vehicle.cpp:1597
static RoadStop * GetByTile(TileIndex tile, RoadStopType type)
Find a roadstop at given tile.
Definition: roadstop.cpp:268
shadow of the aircraft
Definition: aircraft.h:35
void UpdateVisualEffect(bool allow_power_change=true)
Update the cached visual effect.
Definition: vehicle.cpp:2382
GroupID group_id
Index of group Pool array.
Definition: vehicle_base.h:326
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:3279
static const int DAYS_IN_LEAP_YEAR
sometimes, you need one day more...
Definition: date_type.h:32
bool IsEngine() const
Check if a vehicle is an engine (can be first in a consist).
TransparencyOption
Transparency option bits: which position in _transparency_opt stands for which transparency.
Definition: transparency.h:24
GroundVehicleCache gcache
Cache of often calculated values.
Visual effects and wagon power (trains, road vehicles and ships)
CargoID GetRefitCargo() const
Get the cargo to to refit to.
Definition: order_base.h:124
Vehicle is not clickable by the user (shadow vehicles).
Definition: vehicle_base.h:34
SpriteID colourmap
NOSAVE: cached colour mapping.
Definition: vehicle_base.h:254
byte visual_effect
Bitstuffed NewGRF visual effect data.
Definition: engine_type.h:58
Electric rail engine.
Definition: engine_type.h:37
static int GetTileMaxPixelZ(TileIndex tile)
Get top height of the tile.
Definition: tile_map.h:306
Dynamic data of a loaded NewGRF.
Definition: newgrf.h:104
Train vehicle type.
Definition: vehicle_type.h:26
Vehicle visual effect (steam, diesel smoke or electric spark) is shown.
Definition: newgrf_sound.h:26
static void SetDParam(uint n, uint64 v)
Set a string parameter v at index n in the global string parameter array.
Definition: strings_func.h:201
void CancelReservation(StationID next, Station *st)
Return all reserved cargo packets to the station and reset all packets staged for transfer...
Definition: vehicle.cpp:2157
static void SetDepotReservation(TileIndex t, bool b)
Set the reservation state of the depot.
Definition: rail_map.h:271
PaletteID pal
The palette (use PAL_NONE) if not needed)
Definition: gfx_type.h:26
int width
Screen width of the viewport.
Definition: viewport_type.h:27
static Station * GetIfValid(size_t index)
Returns station if the index is a valid index for this station type.
pause the game
Definition: command_type.h:255