OpenTTD
vehicle.cpp
Go to the documentation of this file.
1 /* $Id: vehicle.cpp 27986 2018-03-11 13:23:26Z frosch $ */
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 
56 #include "table/strings.h"
57 
58 #include "safeguards.h"
59 
60 /* Number of bits in the hash to use from each vehicle coord */
61 static const uint GEN_HASHX_BITS = 6;
62 static const uint GEN_HASHY_BITS = 6;
63 
64 /* Size of each hash bucket */
65 static const uint GEN_HASHX_BUCKET_BITS = 7;
66 static const uint GEN_HASHY_BUCKET_BITS = 6;
67 
68 /* Compute hash for vehicle coord */
69 #define GEN_HASHX(x) GB((x), GEN_HASHX_BUCKET_BITS + ZOOM_LVL_SHIFT, GEN_HASHX_BITS)
70 #define GEN_HASHY(y) (GB((y), GEN_HASHY_BUCKET_BITS + ZOOM_LVL_SHIFT, GEN_HASHY_BITS) << GEN_HASHX_BITS)
71 #define GEN_HASH(x, y) (GEN_HASHY(y) + GEN_HASHX(x))
72 
73 /* Maximum size until hash repeats */
74 static const int GEN_HASHX_SIZE = 1 << (GEN_HASHX_BUCKET_BITS + GEN_HASHX_BITS + ZOOM_LVL_SHIFT);
75 static const int GEN_HASHY_SIZE = 1 << (GEN_HASHY_BUCKET_BITS + GEN_HASHY_BITS + ZOOM_LVL_SHIFT);
76 
77 /* Increments to reach next bucket in hash table */
78 static const int GEN_HASHX_INC = 1;
79 static const int GEN_HASHY_INC = 1 << GEN_HASHX_BITS;
80 
81 /* Mask to wrap-around buckets */
82 static const uint GEN_HASHX_MASK = (1 << GEN_HASHX_BITS) - 1;
83 static const uint GEN_HASHY_MASK = ((1 << GEN_HASHY_BITS) - 1) << GEN_HASHX_BITS;
84 
85 VehicleID _new_vehicle_id;
88 
89 
91 VehiclePool _vehicle_pool("Vehicle");
93 
94 
95 
99 void VehicleSpriteSeq::GetBounds(Rect *bounds) const
100 {
101  bounds->left = bounds->top = bounds->right = bounds->bottom = 0;
102  for (uint i = 0; i < this->count; ++i) {
103  const Sprite *spr = GetSprite(this->seq[i].sprite, ST_NORMAL);
104  if (i == 0) {
105  bounds->left = spr->x_offs;
106  bounds->top = spr->y_offs;
107  bounds->right = spr->width + spr->x_offs - 1;
108  bounds->bottom = spr->height + spr->y_offs - 1;
109  } else {
110  if (spr->x_offs < bounds->left) bounds->left = spr->x_offs;
111  if (spr->y_offs < bounds->top) bounds->top = spr->y_offs;
112  int right = spr->width + spr->x_offs - 1;
113  int bottom = spr->height + spr->y_offs - 1;
114  if (right > bounds->right) bounds->right = right;
115  if (bottom > bounds->bottom) bounds->bottom = bottom;
116  }
117  }
118 }
119 
127 void VehicleSpriteSeq::Draw(int x, int y, PaletteID default_pal, bool force_pal) const
128 {
129  for (uint i = 0; i < this->count; ++i) {
130  PaletteID pal = force_pal || !this->seq[i].pal ? default_pal : this->seq[i].pal;
131  DrawSprite(this->seq[i].sprite, pal, x, y);
132  }
133 }
134 
141 bool Vehicle::NeedsAutorenewing(const Company *c, bool use_renew_setting) const
142 {
143  /* We can always generate the Company pointer when we have the vehicle.
144  * However this takes time and since the Company pointer is often present
145  * when this function is called then it's faster to pass the pointer as an
146  * argument rather than finding it again. */
147  assert(c == Company::Get(this->owner));
148 
149  if (use_renew_setting && !c->settings.engine_renew) return false;
150  if (this->age - this->max_age < (c->settings.engine_renew_months * 30)) return false;
151 
152  /* Only engines need renewing */
153  if (this->type == VEH_TRAIN && !Train::From(this)->IsEngine()) return false;
154 
155  return true;
156 }
157 
164 {
165  assert(v != NULL);
166  SetWindowDirty(WC_VEHICLE_DETAILS, v->index); // ensure that last service date and reliability are updated
167 
168  do {
171  v->reliability = v->GetEngine()->reliability;
172  /* Prevent vehicles from breaking down directly after exiting the depot. */
173  v->breakdown_chance /= 4;
174  v = v->Next();
175  } while (v != NULL && v->HasEngineType());
176 }
177 
185 {
186  /* Stopped or crashed vehicles will not move, as such making unmovable
187  * vehicles to go for service is lame. */
188  if (this->vehstatus & (VS_STOPPED | VS_CRASHED)) return false;
189 
190  /* Are we ready for the next service cycle? */
191  const Company *c = Company::Get(this->owner);
192  if (this->ServiceIntervalIsPercent() ?
193  (this->reliability >= this->GetEngine()->reliability * (100 - this->GetServiceInterval()) / 100) :
194  (this->date_of_last_service + this->GetServiceInterval() >= _date)) {
195  return false;
196  }
197 
198  /* If we're servicing anyway, because we have not disabled servicing when
199  * there are no breakdowns or we are playing with breakdowns, bail out. */
202  return true;
203  }
204 
205  /* Test whether there is some pending autoreplace.
206  * Note: We do this after the service-interval test.
207  * There are a lot more reasons for autoreplace to fail than we can test here reasonably. */
208  bool pending_replace = false;
209  Money needed_money = c->settings.engine_renew_money;
210  if (needed_money > c->money) return false;
211 
212  for (const Vehicle *v = this; v != NULL; v = (v->type == VEH_TRAIN) ? Train::From(v)->GetNextUnit() : NULL) {
213  bool replace_when_old = false;
214  EngineID new_engine = EngineReplacementForCompany(c, v->engine_type, v->group_id, &replace_when_old);
215 
216  /* Check engine availability */
217  if (new_engine == INVALID_ENGINE || !HasBit(Engine::Get(new_engine)->company_avail, v->owner)) continue;
218  /* Is the vehicle old if we are not always replacing? */
219  if (replace_when_old && !v->NeedsAutorenewing(c, false)) continue;
220 
221  /* Check refittability */
222  uint32 available_cargo_types, union_mask;
223  GetArticulatedRefitMasks(new_engine, true, &union_mask, &available_cargo_types);
224  /* Is there anything to refit? */
225  if (union_mask != 0) {
226  CargoID cargo_type;
227  /* We cannot refit to mixed cargoes in an automated way */
228  if (IsArticulatedVehicleCarryingDifferentCargoes(v, &cargo_type)) continue;
229 
230  /* Did the old vehicle carry anything? */
231  if (cargo_type != CT_INVALID) {
232  /* We can't refit the vehicle to carry the cargo we want */
233  if (!HasBit(available_cargo_types, cargo_type)) continue;
234  }
235  }
236 
237  /* Check money.
238  * We want 2*(the price of the new vehicle) without looking at the value of the vehicle we are going to sell. */
239  pending_replace = true;
240  needed_money += 2 * Engine::Get(new_engine)->GetCost();
241  if (needed_money > c->money) return false;
242  }
243 
244  return pending_replace;
245 }
246 
253 {
254  if (this->HasDepotOrder()) return false;
255  if (this->current_order.IsType(OT_LOADING)) return false;
256  if (this->current_order.IsType(OT_GOTO_DEPOT) && this->current_order.GetDepotOrderType() != ODTFB_SERVICE) return false;
257  return NeedsServicing();
258 }
259 
260 uint Vehicle::Crash(bool flooded)
261 {
262  assert((this->vehstatus & VS_CRASHED) == 0);
263  assert(this->Previous() == NULL); // IsPrimaryVehicle fails for free-wagon-chains
264 
265  uint pass = 0;
266  /* Stop the vehicle. */
267  if (this->IsPrimaryVehicle()) this->vehstatus |= VS_STOPPED;
268  /* crash all wagons, and count passengers */
269  for (Vehicle *v = this; v != NULL; v = v->Next()) {
270  /* We do not transfer reserver cargo back, so TotalCount() instead of StoredCount() */
271  if (IsCargoInClass(v->cargo_type, CC_PASSENGERS)) pass += v->cargo.TotalCount();
272  v->vehstatus |= VS_CRASHED;
273  v->MarkAllViewportsDirty();
274  }
275 
276  /* Dirty some windows */
279  SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
280  SetWindowDirty(WC_VEHICLE_DEPOT, this->tile);
281 
282  delete this->cargo_payment;
283  assert(this->cargo_payment == NULL); // cleared by ~CargoPayment
284 
285  return RandomRange(pass + 1); // Randomise deceased passengers.
286 }
287 
288 
297 void ShowNewGrfVehicleError(EngineID engine, StringID part1, StringID part2, GRFBugs bug_type, bool critical)
298 {
299  const Engine *e = Engine::Get(engine);
300  GRFConfig *grfconfig = GetGRFConfig(e->GetGRFID());
301 
302  /* Missing GRF. Nothing useful can be done in this situation. */
303  if (grfconfig == NULL) return;
304 
305  if (!HasBit(grfconfig->grf_bugs, bug_type)) {
306  SetBit(grfconfig->grf_bugs, bug_type);
307  SetDParamStr(0, grfconfig->GetName());
308  SetDParam(1, engine);
309  ShowErrorMessage(part1, part2, WL_CRITICAL);
311  }
312 
313  /* debug output */
314  char buffer[512];
315 
316  SetDParamStr(0, grfconfig->GetName());
317  GetString(buffer, part1, lastof(buffer));
318  DEBUG(grf, 0, "%s", buffer + 3);
319 
320  SetDParam(1, engine);
321  GetString(buffer, part2, lastof(buffer));
322  DEBUG(grf, 0, "%s", buffer + 3);
323 }
324 
331 {
332  /* show a warning once for each engine in whole game and once for each GRF after each game load */
333  const Engine *engine = u->GetEngine();
334  uint32 grfid = engine->grf_prop.grffile->grfid;
335  GRFConfig *grfconfig = GetGRFConfig(grfid);
336  if (GamelogGRFBugReverse(grfid, engine->grf_prop.local_id) || !HasBit(grfconfig->grf_bugs, GBUG_VEH_LENGTH)) {
337  ShowNewGrfVehicleError(u->engine_type, STR_NEWGRF_BROKEN, STR_NEWGRF_BROKEN_VEHICLE_LENGTH, GBUG_VEH_LENGTH, true);
338  }
339 }
340 
346 {
347  this->type = type;
348  this->coord.left = INVALID_COORD;
349  this->group_id = DEFAULT_GROUP;
350  this->fill_percent_te_id = INVALID_TE_ID;
351  this->first = this;
352  this->colourmap = PAL_NONE;
353  this->cargo_age_counter = 1;
354  this->last_station_visited = INVALID_STATION;
355  this->last_loading_station = INVALID_STATION;
356 }
357 
363 {
364  return GB(Random(), 0, 8);
365 }
366 
367 /* Size of the hash, 6 = 64 x 64, 7 = 128 x 128. Larger sizes will (in theory) reduce hash
368  * lookup times at the expense of memory usage. */
369 const int HASH_BITS = 7;
370 const int HASH_SIZE = 1 << HASH_BITS;
371 const int HASH_MASK = HASH_SIZE - 1;
372 const int TOTAL_HASH_SIZE = 1 << (HASH_BITS * 2);
373 const int TOTAL_HASH_MASK = TOTAL_HASH_SIZE - 1;
374 
375 /* Resolution of the hash, 0 = 1*1 tile, 1 = 2*2 tiles, 2 = 4*4 tiles, etc.
376  * Profiling results show that 0 is fastest. */
377 const int HASH_RES = 0;
378 
379 static Vehicle *_vehicle_tile_hash[TOTAL_HASH_SIZE];
380 
381 static Vehicle *VehicleFromTileHash(int xl, int yl, int xu, int yu, void *data, VehicleFromPosProc *proc, bool find_first)
382 {
383  for (int y = yl; ; y = (y + (1 << HASH_BITS)) & (HASH_MASK << HASH_BITS)) {
384  for (int x = xl; ; x = (x + 1) & HASH_MASK) {
385  Vehicle *v = _vehicle_tile_hash[(x + y) & TOTAL_HASH_MASK];
386  for (; v != NULL; v = v->hash_tile_next) {
387  Vehicle *a = proc(v, data);
388  if (find_first && a != NULL) return a;
389  }
390  if (x == xu) break;
391  }
392  if (y == yu) break;
393  }
394 
395  return NULL;
396 }
397 
398 
410 static Vehicle *VehicleFromPosXY(int x, int y, void *data, VehicleFromPosProc *proc, bool find_first)
411 {
412  const int COLL_DIST = 6;
413 
414  /* Hash area to scan is from xl,yl to xu,yu */
415  int xl = GB((x - COLL_DIST) / TILE_SIZE, HASH_RES, HASH_BITS);
416  int xu = GB((x + COLL_DIST) / TILE_SIZE, HASH_RES, HASH_BITS);
417  int yl = GB((y - COLL_DIST) / TILE_SIZE, HASH_RES, HASH_BITS) << HASH_BITS;
418  int yu = GB((y + COLL_DIST) / TILE_SIZE, HASH_RES, HASH_BITS) << HASH_BITS;
419 
420  return VehicleFromTileHash(xl, yl, xu, yu, data, proc, find_first);
421 }
422 
437 void FindVehicleOnPosXY(int x, int y, void *data, VehicleFromPosProc *proc)
438 {
439  VehicleFromPosXY(x, y, data, proc, false);
440 }
441 
453 bool HasVehicleOnPosXY(int x, int y, void *data, VehicleFromPosProc *proc)
454 {
455  return VehicleFromPosXY(x, y, data, proc, true) != NULL;
456 }
457 
468 static Vehicle *VehicleFromPos(TileIndex tile, void *data, VehicleFromPosProc *proc, bool find_first)
469 {
470  int x = GB(TileX(tile), HASH_RES, HASH_BITS);
471  int y = GB(TileY(tile), HASH_RES, HASH_BITS) << HASH_BITS;
472 
473  Vehicle *v = _vehicle_tile_hash[(x + y) & TOTAL_HASH_MASK];
474  for (; v != NULL; v = v->hash_tile_next) {
475  if (v->tile != tile) continue;
476 
477  Vehicle *a = proc(v, data);
478  if (find_first && a != NULL) return a;
479  }
480 
481  return NULL;
482 }
483 
497 void FindVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
498 {
499  VehicleFromPos(tile, data, proc, false);
500 }
501 
512 bool HasVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
513 {
514  return VehicleFromPos(tile, data, proc, true) != NULL;
515 }
516 
523 static Vehicle *EnsureNoVehicleProcZ(Vehicle *v, void *data)
524 {
525  int z = *(int*)data;
526 
527  if (v->type == VEH_DISASTER || (v->type == VEH_AIRCRAFT && v->subtype == AIR_SHADOW)) return NULL;
528  if (v->z_pos > z) return NULL;
529 
530  return v;
531 }
532 
539 {
540  int z = GetTileMaxPixelZ(tile);
541 
542  /* Value v is not safe in MP games, however, it is used to generate a local
543  * error message only (which may be different for different machines).
544  * Such a message does not affect MP synchronisation.
545  */
546  Vehicle *v = VehicleFromPos(tile, &z, &EnsureNoVehicleProcZ, true);
547  if (v != NULL) return_cmd_error(STR_ERROR_TRAIN_IN_THE_WAY + v->type);
548  return CommandCost();
549 }
550 
553 {
554  if (v->type != VEH_TRAIN && v->type != VEH_ROAD && v->type != VEH_SHIP) return NULL;
555  if (v == (const Vehicle *)data) return NULL;
556 
557  return v;
558 }
559 
568 {
569  /* Value v is not safe in MP games, however, it is used to generate a local
570  * error message only (which may be different for different machines).
571  * Such a message does not affect MP synchronisation.
572  */
573  Vehicle *v = VehicleFromPos(tile, const_cast<Vehicle *>(ignore), &GetVehicleTunnelBridgeProc, true);
574  if (v == NULL) v = VehicleFromPos(endtile, const_cast<Vehicle *>(ignore), &GetVehicleTunnelBridgeProc, true);
575 
576  if (v != NULL) return_cmd_error(STR_ERROR_TRAIN_IN_THE_WAY + v->type);
577  return CommandCost();
578 }
579 
580 static Vehicle *EnsureNoTrainOnTrackProc(Vehicle *v, void *data)
581 {
582  TrackBits rail_bits = *(TrackBits *)data;
583 
584  if (v->type != VEH_TRAIN) return NULL;
585 
586  Train *t = Train::From(v);
587  if ((t->track != rail_bits) && !TracksOverlap(t->track | rail_bits)) return NULL;
588 
589  return v;
590 }
591 
601 {
602  /* Value v is not safe in MP games, however, it is used to generate a local
603  * error message only (which may be different for different machines).
604  * Such a message does not affect MP synchronisation.
605  */
606  Vehicle *v = VehicleFromPos(tile, &track_bits, &EnsureNoTrainOnTrackProc, true);
607  if (v != NULL) return_cmd_error(STR_ERROR_TRAIN_IN_THE_WAY + v->type);
608  return CommandCost();
609 }
610 
611 static void UpdateVehicleTileHash(Vehicle *v, bool remove)
612 {
613  Vehicle **old_hash = v->hash_tile_current;
614  Vehicle **new_hash;
615 
616  if (remove) {
617  new_hash = NULL;
618  } else {
619  int x = GB(TileX(v->tile), HASH_RES, HASH_BITS);
620  int y = GB(TileY(v->tile), HASH_RES, HASH_BITS) << HASH_BITS;
621  new_hash = &_vehicle_tile_hash[(x + y) & TOTAL_HASH_MASK];
622  }
623 
624  if (old_hash == new_hash) return;
625 
626  /* Remove from the old position in the hash table */
627  if (old_hash != NULL) {
630  }
631 
632  /* Insert vehicle at beginning of the new position in the hash table */
633  if (new_hash != NULL) {
634  v->hash_tile_next = *new_hash;
636  v->hash_tile_prev = new_hash;
637  *new_hash = v;
638  }
639 
640  /* Remember current hash position */
641  v->hash_tile_current = new_hash;
642 }
643 
644 static Vehicle *_vehicle_viewport_hash[1 << (GEN_HASHX_BITS + GEN_HASHY_BITS)];
645 
646 static void UpdateVehicleViewportHash(Vehicle *v, int x, int y)
647 {
648  Vehicle **old_hash, **new_hash;
649  int old_x = v->coord.left;
650  int old_y = v->coord.top;
651 
652  new_hash = (x == INVALID_COORD) ? NULL : &_vehicle_viewport_hash[GEN_HASH(x, y)];
653  old_hash = (old_x == INVALID_COORD) ? NULL : &_vehicle_viewport_hash[GEN_HASH(old_x, old_y)];
654 
655  if (old_hash == new_hash) return;
656 
657  /* remove from hash table? */
658  if (old_hash != NULL) {
661  }
662 
663  /* insert into hash table? */
664  if (new_hash != NULL) {
665  v->hash_viewport_next = *new_hash;
667  v->hash_viewport_prev = new_hash;
668  *new_hash = v;
669  }
670 }
671 
672 void ResetVehicleHash()
673 {
674  Vehicle *v;
675  FOR_ALL_VEHICLES(v) { v->hash_tile_current = NULL; }
676  memset(_vehicle_viewport_hash, 0, sizeof(_vehicle_viewport_hash));
677  memset(_vehicle_tile_hash, 0, sizeof(_vehicle_tile_hash));
678 }
679 
680 void ResetVehicleColourMap()
681 {
682  Vehicle *v;
683  FOR_ALL_VEHICLES(v) { v->colourmap = PAL_NONE; }
684 }
685 
691 static AutoreplaceMap _vehicles_to_autoreplace;
692 
693 void InitializeVehicles()
694 {
695  _vehicles_to_autoreplace.Reset();
696  ResetVehicleHash();
697 }
698 
699 uint CountVehiclesInChain(const Vehicle *v)
700 {
701  uint count = 0;
702  do count++; while ((v = v->Next()) != NULL);
703  return count;
704 }
705 
711 {
712  switch (this->type) {
713  case VEH_AIRCRAFT: return Aircraft::From(this)->IsNormalAircraft(); // don't count plane shadows and helicopter rotors
714  case VEH_TRAIN:
715  return !this->IsArticulatedPart() && // tenders and other articulated parts
716  !Train::From(this)->IsRearDualheaded(); // rear parts of multiheaded engines
717  case VEH_ROAD: return RoadVehicle::From(this)->IsFrontEngine();
718  case VEH_SHIP: return true;
719  default: return false; // Only count company buildable vehicles
720  }
721 }
722 
728 {
729  switch (this->type) {
730  case VEH_AIRCRAFT: return Aircraft::From(this)->IsNormalAircraft();
731  case VEH_TRAIN:
732  case VEH_ROAD:
733  case VEH_SHIP: return true;
734  default: return false;
735  }
736 }
737 
744 {
745  return Engine::Get(this->engine_type);
746 }
747 
753 const GRFFile *Vehicle::GetGRF() const
754 {
755  return this->GetEngine()->GetGRF();
756 }
757 
763 uint32 Vehicle::GetGRFID() const
764 {
765  return this->GetEngine()->GetGRFID();
766 }
767 
775 void Vehicle::HandlePathfindingResult(bool path_found)
776 {
777  if (path_found) {
778  /* Route found, is the vehicle marked with "lost" flag? */
779  if (!HasBit(this->vehicle_flags, VF_PATHFINDER_LOST)) return;
780 
781  /* Clear the flag as the PF's problem was solved. */
782  ClrBit(this->vehicle_flags, VF_PATHFINDER_LOST);
783  /* Delete the news item. */
784  DeleteVehicleNews(this->index, STR_NEWS_VEHICLE_IS_LOST);
785  return;
786  }
787 
788  /* Were we already lost? */
789  if (HasBit(this->vehicle_flags, VF_PATHFINDER_LOST)) return;
790 
791  /* It is first time the problem occurred, set the "lost" flag. */
792  SetBit(this->vehicle_flags, VF_PATHFINDER_LOST);
793  /* Notify user about the event. */
794  AI::NewEvent(this->owner, new ScriptEventVehicleLost(this->index));
795  if (_settings_client.gui.lost_vehicle_warn && this->owner == _local_company) {
796  SetDParam(0, this->index);
797  AddVehicleAdviceNewsItem(STR_NEWS_VEHICLE_IS_LOST, this->index);
798  }
799 }
800 
803 {
804  if (CleaningPool()) return;
805 
806  if (Station::IsValidID(this->last_station_visited)) {
807  Station *st = Station::Get(this->last_station_visited);
808  st->loading_vehicles.remove(this);
809 
810  HideFillingPercent(&this->fill_percent_te_id);
811  this->CancelReservation(INVALID_STATION, st);
812  delete this->cargo_payment;
813  assert(this->cargo_payment == NULL); // cleared by ~CargoPayment
814  }
815 
816  if (this->IsEngineCountable()) {
818  if (this->IsPrimaryVehicle()) GroupStatistics::CountVehicle(this, -1);
820 
821  if (this->owner == _local_company) InvalidateAutoreplaceWindow(this->engine_type, this->group_id);
823  }
824 
825  if (this->type == VEH_AIRCRAFT && this->IsPrimaryVehicle()) {
826  Aircraft *a = Aircraft::From(this);
828  if (st != NULL) {
829  const AirportFTA *layout = st->airport.GetFTA()->layout;
830  CLRBITS(st->airport.flags, layout[a->previous_pos].block | layout[a->pos].block);
831  }
832  }
833 
834 
835  if (this->type == VEH_ROAD && this->IsPrimaryVehicle()) {
836  RoadVehicle *v = RoadVehicle::From(this);
837  if (!(v->vehstatus & VS_CRASHED) && IsInsideMM(v->state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END)) {
838  /* Leave the drive through roadstop, when you have not already left it. */
840  }
841  }
842 
843  if (this->Previous() == NULL) {
845  }
846 
847  if (this->IsPrimaryVehicle()) {
848  DeleteWindowById(WC_VEHICLE_VIEW, this->index);
849  DeleteWindowById(WC_VEHICLE_ORDERS, this->index);
850  DeleteWindowById(WC_VEHICLE_REFIT, this->index);
851  DeleteWindowById(WC_VEHICLE_DETAILS, this->index);
853  SetWindowDirty(WC_COMPANY, this->owner);
855  }
857 
858  this->cargo.Truncate();
859  DeleteVehicleOrders(this);
861 
862  extern void StopGlobalFollowVehicle(const Vehicle *v);
863  StopGlobalFollowVehicle(this);
864 
866 }
867 
869 {
870  if (CleaningPool()) {
871  this->cargo.OnCleanPool();
872  return;
873  }
874 
875  /* sometimes, eg. for disaster vehicles, when company bankrupts, when removing crashed/flooded vehicles,
876  * it may happen that vehicle chain is deleted when visible */
877  if (!(this->vehstatus & VS_HIDDEN)) this->MarkAllViewportsDirty();
878 
879  Vehicle *v = this->Next();
880  this->SetNext(NULL);
881 
882  delete v;
883 
884  UpdateVehicleTileHash(this, true);
885  UpdateVehicleViewportHash(this, INVALID_COORD, 0);
886  DeleteVehicleNews(this->index, INVALID_STRING_ID);
887  DeleteNewGRFInspectWindow(GetGrfSpecFeature(this->type), this->index);
888 }
889 
895 {
896  /* Vehicle should stop in the depot if it was in 'stopping' state */
897  _vehicles_to_autoreplace[v] = !(v->vehstatus & VS_STOPPED);
898 
899  /* We ALWAYS set the stopped state. Even when the vehicle does not plan on
900  * stopping in the depot, so we stop it to ensure that it will not reserve
901  * the path out of the depot before we might autoreplace it to a different
902  * engine. The new engine would not own the reserved path we store that we
903  * stopped the vehicle, so autoreplace can start it again */
904  v->vehstatus |= VS_STOPPED;
905 }
906 
912 static void RunVehicleDayProc()
913 {
914  if (_game_mode != GM_NORMAL) return;
915 
916  /* Run the day_proc for every DAY_TICKS vehicle starting at _date_fract. */
917  for (size_t i = _date_fract; i < Vehicle::GetPoolSize(); i += DAY_TICKS) {
918  Vehicle *v = Vehicle::Get(i);
919  if (v == NULL) continue;
920 
921  /* Call the 32-day callback if needed */
922  if ((v->day_counter & 0x1F) == 0 && v->HasEngineType()) {
923  uint16 callback = GetVehicleCallback(CBID_VEHICLE_32DAY_CALLBACK, 0, 0, v->engine_type, v);
924  if (callback != CALLBACK_FAILED) {
925  if (HasBit(callback, 0)) {
926  TriggerVehicle(v, VEHICLE_TRIGGER_CALLBACK_32); // Trigger vehicle trigger 10
927  }
928 
929  /* After a vehicle trigger, the graphics and properties of the vehicle could change.
930  * Note: MarkDirty also invalidates the palette, which is the meaning of bit 1. So, nothing special there. */
931  if (callback != 0) v->First()->MarkDirty();
932 
933  if (callback & ~3) ErrorUnknownCallbackResult(v->GetGRFID(), CBID_VEHICLE_32DAY_CALLBACK, callback);
934  }
935  }
936 
937  /* This is called once per day for each vehicle, but not in the first tick of the day */
938  v->OnNewDay();
939  }
940 }
941 
942 void CallVehicleTicks()
943 {
944  _vehicles_to_autoreplace.Clear();
945 
947 
948  Station *st;
949  FOR_ALL_STATIONS(st) LoadUnloadStation(st);
950 
951  Vehicle *v;
952  FOR_ALL_VEHICLES(v) {
953  /* Vehicle could be deleted in this tick */
954  if (!v->Tick()) {
955  assert(Vehicle::Get(vehicle_index) == NULL);
956  continue;
957  }
958 
959  assert(Vehicle::Get(vehicle_index) == v);
960 
961  switch (v->type) {
962  default: break;
963 
964  case VEH_TRAIN:
965  case VEH_ROAD:
966  case VEH_AIRCRAFT:
967  case VEH_SHIP: {
968  Vehicle *front = v->First();
969 
970  if (v->vcache.cached_cargo_age_period != 0) {
972  if (--v->cargo_age_counter == 0) {
973  v->cargo.AgeCargo();
975  }
976  }
977 
978  /* Do not play any sound when crashed */
979  if (front->vehstatus & VS_CRASHED) continue;
980 
981  /* Do not play any sound when in depot or tunnel */
982  if (v->vehstatus & VS_HIDDEN) continue;
983 
984  /* Do not play any sound when stopped */
985  if ((front->vehstatus & VS_STOPPED) && (front->type != VEH_TRAIN || front->cur_speed == 0)) continue;
986 
987  /* Check vehicle type specifics */
988  switch (v->type) {
989  case VEH_TRAIN:
990  if (Train::From(v)->IsWagon()) continue;
991  break;
992 
993  case VEH_ROAD:
994  if (!RoadVehicle::From(v)->IsFrontEngine()) continue;
995  break;
996 
997  case VEH_AIRCRAFT:
998  if (!Aircraft::From(v)->IsNormalAircraft()) continue;
999  break;
1000 
1001  default:
1002  break;
1003  }
1004 
1005  v->motion_counter += front->cur_speed;
1006  /* Play a running sound if the motion counter passes 256 (Do we not skip sounds?) */
1007  if (GB(v->motion_counter, 0, 8) < front->cur_speed) PlayVehicleSound(v, VSE_RUNNING);
1008 
1009  /* Play an alternating running sound every 16 ticks */
1010  if (GB(v->tick_counter, 0, 4) == 0) {
1011  /* Play running sound when speed > 0 and not braking */
1012  bool running = (front->cur_speed > 0) && !(front->vehstatus & (VS_STOPPED | VS_TRAIN_SLOWING));
1014  }
1015 
1016  break;
1017  }
1018  }
1019  }
1020 
1021  Backup<CompanyByte> cur_company(_current_company, FILE_LINE);
1022  for (AutoreplaceMap::iterator it = _vehicles_to_autoreplace.Begin(); it != _vehicles_to_autoreplace.End(); it++) {
1023  v = it->first;
1024  /* Autoreplace needs the current company set as the vehicle owner */
1025  cur_company.Change(v->owner);
1026 
1027  /* Start vehicle if we stopped them in VehicleEnteredDepotThisTick()
1028  * We need to stop them between VehicleEnteredDepotThisTick() and here or we risk that
1029  * they are already leaving the depot again before being replaced. */
1030  if (it->second) v->vehstatus &= ~VS_STOPPED;
1031 
1032  /* Store the position of the effect as the vehicle pointer will become invalid later */
1033  int x = v->x_pos;
1034  int y = v->y_pos;
1035  int z = v->z_pos;
1036 
1041 
1042  if (!IsLocalCompany()) continue;
1043 
1044  if (res.Succeeded()) {
1045  ShowCostOrIncomeAnimation(x, y, z, res.GetCost());
1046  continue;
1047  }
1048 
1049  StringID error_message = res.GetErrorMessage();
1050  if (error_message == STR_ERROR_AUTOREPLACE_NOTHING_TO_DO || error_message == INVALID_STRING_ID) continue;
1051 
1052  if (error_message == STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY) error_message = STR_ERROR_AUTOREPLACE_MONEY_LIMIT;
1053 
1054  StringID message;
1055  if (error_message == STR_ERROR_TRAIN_TOO_LONG_AFTER_REPLACEMENT) {
1056  message = error_message;
1057  } else {
1058  message = STR_NEWS_VEHICLE_AUTORENEW_FAILED;
1059  }
1060 
1061  SetDParam(0, v->index);
1062  SetDParam(1, error_message);
1063  AddVehicleAdviceNewsItem(message, v->index);
1064  }
1065 
1066  cur_company.Restore();
1067 }
1068 
1073 static void DoDrawVehicle(const Vehicle *v)
1074 {
1075  PaletteID pal = PAL_NONE;
1076 
1078 
1079  /* Check whether the vehicle shall be transparent due to the game state */
1080  bool shadowed = (v->vehstatus & VS_SHADOW) != 0;
1081 
1082  if (v->type == VEH_EFFECT) {
1083  /* Check whether the vehicle shall be transparent/invisible due to GUI settings.
1084  * However, transparent smoke and bubbles look weird, so always hide them. */
1086  if (to != TO_INVALID && (IsTransparencySet(to) || IsInvisibilitySet(to))) return;
1087  }
1088 
1090  for (uint i = 0; i < v->sprite_seq.count; ++i) {
1091  PaletteID pal2 = v->sprite_seq.seq[i].pal;
1092  if (!pal2 || (v->vehstatus & VS_CRASHED)) pal2 = pal;
1093  AddSortableSpriteToDraw(v->sprite_seq.seq[i].sprite, pal2, v->x_pos + v->x_offs, v->y_pos + v->y_offs,
1094  v->x_extent, v->y_extent, v->z_extent, v->z_pos, shadowed, v->x_bb_offs, v->y_bb_offs);
1095  }
1096  EndSpriteCombine();
1097 }
1098 
1104 {
1105  /* The bounding rectangle */
1106  const int l = dpi->left;
1107  const int r = dpi->left + dpi->width;
1108  const int t = dpi->top;
1109  const int b = dpi->top + dpi->height;
1110 
1111  /* The hash area to scan */
1112  int xl, xu, yl, yu;
1113 
1114  if (dpi->width + (MAX_VEHICLE_PIXEL_X * ZOOM_LVL_BASE) < GEN_HASHX_SIZE) {
1115  xl = GEN_HASHX(l - MAX_VEHICLE_PIXEL_X * ZOOM_LVL_BASE);
1116  xu = GEN_HASHX(r);
1117  } else {
1118  /* scan whole hash row */
1119  xl = 0;
1120  xu = GEN_HASHX_MASK;
1121  }
1122 
1123  if (dpi->height + (MAX_VEHICLE_PIXEL_Y * ZOOM_LVL_BASE) < GEN_HASHY_SIZE) {
1124  yl = GEN_HASHY(t - MAX_VEHICLE_PIXEL_Y * ZOOM_LVL_BASE);
1125  yu = GEN_HASHY(b);
1126  } else {
1127  /* scan whole column */
1128  yl = 0;
1129  yu = GEN_HASHY_MASK;
1130  }
1131 
1132  for (int y = yl;; y = (y + GEN_HASHY_INC) & GEN_HASHY_MASK) {
1133  for (int x = xl;; x = (x + GEN_HASHX_INC) & GEN_HASHX_MASK) {
1134  const Vehicle *v = _vehicle_viewport_hash[x + y]; // already masked & 0xFFF
1135 
1136  while (v != NULL) {
1137  if (!(v->vehstatus & VS_HIDDEN) &&
1138  l <= v->coord.right &&
1139  t <= v->coord.bottom &&
1140  r >= v->coord.left &&
1141  b >= v->coord.top) {
1142  DoDrawVehicle(v);
1143  }
1144  v = v->hash_viewport_next;
1145  }
1146 
1147  if (x == xu) break;
1148  }
1149 
1150  if (y == yu) break;
1151  }
1152 }
1153 
1161 Vehicle *CheckClickOnVehicle(const ViewPort *vp, int x, int y)
1162 {
1163  Vehicle *found = NULL, *v;
1164  uint dist, best_dist = UINT_MAX;
1165 
1166  if ((uint)(x -= vp->left) >= (uint)vp->width || (uint)(y -= vp->top) >= (uint)vp->height) return NULL;
1167 
1168  x = ScaleByZoom(x, vp->zoom) + vp->virtual_left;
1169  y = ScaleByZoom(y, vp->zoom) + vp->virtual_top;
1170 
1171  FOR_ALL_VEHICLES(v) {
1172  if ((v->vehstatus & (VS_HIDDEN | VS_UNCLICKABLE)) == 0 &&
1173  x >= v->coord.left && x <= v->coord.right &&
1174  y >= v->coord.top && y <= v->coord.bottom) {
1175 
1176  dist = max(
1177  abs(((v->coord.left + v->coord.right) >> 1) - x),
1178  abs(((v->coord.top + v->coord.bottom) >> 1) - y)
1179  );
1180 
1181  if (dist < best_dist) {
1182  found = v;
1183  best_dist = dist;
1184  }
1185  }
1186  }
1187 
1188  return found;
1189 }
1190 
1196 {
1197  v->value -= v->value >> 8;
1199 }
1200 
1201 static const byte _breakdown_chance[64] = {
1202  3, 3, 3, 3, 3, 3, 3, 3,
1203  4, 4, 5, 5, 6, 6, 7, 7,
1204  8, 8, 9, 9, 10, 10, 11, 11,
1205  12, 13, 13, 13, 13, 14, 15, 16,
1206  17, 19, 21, 25, 28, 31, 34, 37,
1207  40, 44, 48, 52, 56, 60, 64, 68,
1208  72, 80, 90, 100, 110, 120, 130, 140,
1209  150, 170, 190, 210, 230, 250, 250, 250,
1210 };
1211 
1212 void CheckVehicleBreakdown(Vehicle *v)
1213 {
1214  int rel, rel_old;
1215 
1216  /* decrease reliability */
1217  v->reliability = rel = max((rel_old = v->reliability) - v->reliability_spd_dec, 0);
1218  if ((rel_old >> 8) != (rel >> 8)) SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
1219 
1220  if (v->breakdown_ctr != 0 || (v->vehstatus & VS_STOPPED) ||
1222  v->cur_speed < 5 || _game_mode == GM_MENU) {
1223  return;
1224  }
1225 
1226  uint32 r = Random();
1227 
1228  /* increase chance of failure */
1229  int chance = v->breakdown_chance + 1;
1230  if (Chance16I(1, 25, r)) chance += 25;
1231  v->breakdown_chance = min(255, chance);
1232 
1233  /* calculate reliability value to use in comparison */
1234  rel = v->reliability;
1235  if (v->type == VEH_SHIP) rel += 0x6666;
1236 
1237  /* reduced breakdowns? */
1238  if (_settings_game.difficulty.vehicle_breakdowns == 1) rel += 0x6666;
1239 
1240  /* check if to break down */
1241  if (_breakdown_chance[(uint)min(rel, 0xffff) >> 10] <= v->breakdown_chance) {
1242  v->breakdown_ctr = GB(r, 16, 6) + 0x3F;
1243  v->breakdown_delay = GB(r, 24, 7) + 0x80;
1244  v->breakdown_chance = 0;
1245  }
1246 }
1247 
1255 {
1256  /* Possible states for Vehicle::breakdown_ctr
1257  * 0 - vehicle is running normally
1258  * 1 - vehicle is currently broken down
1259  * 2 - vehicle is going to break down now
1260  * >2 - vehicle is counting down to the actual breakdown event */
1261  switch (this->breakdown_ctr) {
1262  case 0:
1263  return false;
1264 
1265  case 2:
1266  this->breakdown_ctr = 1;
1267 
1268  if (this->breakdowns_since_last_service != 255) {
1269  this->breakdowns_since_last_service++;
1270  }
1271 
1272  if (this->type == VEH_AIRCRAFT) {
1273  /* Aircraft just need this flag, the rest is handled elsewhere */
1274  this->vehstatus |= VS_AIRCRAFT_BROKEN;
1275  } else {
1276  this->cur_speed = 0;
1277 
1278  if (!PlayVehicleSound(this, VSE_BREAKDOWN)) {
1279  bool train_or_ship = this->type == VEH_TRAIN || this->type == VEH_SHIP;
1280  SndPlayVehicleFx((_settings_game.game_creation.landscape != LT_TOYLAND) ?
1281  (train_or_ship ? SND_10_TRAIN_BREAKDOWN : SND_0F_VEHICLE_BREAKDOWN) :
1282  (train_or_ship ? SND_3A_COMEDY_BREAKDOWN_2 : SND_35_COMEDY_BREAKDOWN), this);
1283  }
1284 
1285  if (!(this->vehstatus & VS_HIDDEN) && !HasBit(EngInfo(this->engine_type)->misc_flags, EF_NO_BREAKDOWN_SMOKE)) {
1287  if (u != NULL) u->animation_state = this->breakdown_delay * 2;
1288  }
1289  }
1290 
1291  this->MarkDirty(); // Update graphics after speed is zeroed
1292  SetWindowDirty(WC_VEHICLE_VIEW, this->index);
1293  SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
1294 
1295  FALLTHROUGH;
1296  case 1:
1297  /* Aircraft breakdowns end only when arriving at the airport */
1298  if (this->type == VEH_AIRCRAFT) return false;
1299 
1300  /* For trains this function is called twice per tick, so decrease v->breakdown_delay at half the rate */
1301  if ((this->tick_counter & (this->type == VEH_TRAIN ? 3 : 1)) == 0) {
1302  if (--this->breakdown_delay == 0) {
1303  this->breakdown_ctr = 0;
1304  this->MarkDirty();
1305  SetWindowDirty(WC_VEHICLE_VIEW, this->index);
1306  }
1307  }
1308  return true;
1309 
1310  default:
1311  if (!this->current_order.IsType(OT_LOADING)) this->breakdown_ctr--;
1312  return false;
1313  }
1314 }
1315 
1321 {
1322  if (v->age < MAX_DAY) {
1323  v->age++;
1325  }
1326 
1327  if (!v->IsPrimaryVehicle() && (v->type != VEH_TRAIN || !Train::From(v)->IsEngine())) return;
1328 
1329  int age = v->age - v->max_age;
1330  if (age == DAYS_IN_LEAP_YEAR * 0 || age == DAYS_IN_LEAP_YEAR * 1 ||
1331  age == DAYS_IN_LEAP_YEAR * 2 || age == DAYS_IN_LEAP_YEAR * 3 || age == DAYS_IN_LEAP_YEAR * 4) {
1332  v->reliability_spd_dec <<= 1;
1333  }
1334 
1336 
1337  /* Don't warn about non-primary or not ours vehicles or vehicles that are crashed */
1338  if (v->Previous() != NULL || v->owner != _local_company || (v->vehstatus & VS_CRASHED) != 0) return;
1339 
1340  /* Don't warn if a renew is active */
1341  if (Company::Get(v->owner)->settings.engine_renew && v->GetEngine()->company_avail != 0) return;
1342 
1343  StringID str;
1344  if (age == -DAYS_IN_LEAP_YEAR) {
1345  str = STR_NEWS_VEHICLE_IS_GETTING_OLD;
1346  } else if (age == 0) {
1347  str = STR_NEWS_VEHICLE_IS_GETTING_VERY_OLD;
1348  } else if (age > 0 && (age % DAYS_IN_LEAP_YEAR) == 0) {
1349  str = STR_NEWS_VEHICLE_IS_GETTING_VERY_OLD_AND;
1350  } else {
1351  return;
1352  }
1353 
1354  SetDParam(0, v->index);
1356 }
1357 
1367 uint8 CalcPercentVehicleFilled(const Vehicle *front, StringID *colour)
1368 {
1369  int count = 0;
1370  int max = 0;
1371  int cars = 0;
1372  int unloading = 0;
1373  bool loading = false;
1374 
1375  bool is_loading = front->current_order.IsType(OT_LOADING);
1376 
1377  /* The station may be NULL when the (colour) string does not need to be set. */
1378  const Station *st = Station::GetIfValid(front->last_station_visited);
1379  assert(colour == NULL || (st != NULL && is_loading));
1380 
1381  bool order_no_load = is_loading && (front->current_order.GetLoadType() & OLFB_NO_LOAD);
1382  bool order_full_load = is_loading && (front->current_order.GetLoadType() & OLFB_FULL_LOAD);
1383 
1384  /* Count up max and used */
1385  for (const Vehicle *v = front; v != NULL; v = v->Next()) {
1386  count += v->cargo.StoredCount();
1387  max += v->cargo_cap;
1388  if (v->cargo_cap != 0 && colour != NULL) {
1389  unloading += HasBit(v->vehicle_flags, VF_CARGO_UNLOADING) ? 1 : 0;
1390  loading |= !order_no_load &&
1391  (order_full_load || st->goods[v->cargo_type].HasRating()) &&
1393  cars++;
1394  }
1395  }
1396 
1397  if (colour != NULL) {
1398  if (unloading == 0 && loading) {
1399  *colour = STR_PERCENT_UP;
1400  } else if (unloading == 0 && !loading) {
1401  *colour = STR_PERCENT_NONE;
1402  } else if (cars == unloading || !loading) {
1403  *colour = STR_PERCENT_DOWN;
1404  } else {
1405  *colour = STR_PERCENT_UP_DOWN;
1406  }
1407  }
1408 
1409  /* Train without capacity */
1410  if (max == 0) return 100;
1411 
1412  /* Return the percentage */
1413  if (count * 2 < max) {
1414  /* Less than 50%; round up, so that 0% means really empty. */
1415  return CeilDiv(count * 100, max);
1416  } else {
1417  /* More than 50%; round down, so that 100% means really full. */
1418  return (count * 100) / max;
1419  }
1420 }
1421 
1427 {
1428  /* Always work with the front of the vehicle */
1429  assert(v == v->First());
1430 
1431  switch (v->type) {
1432  case VEH_TRAIN: {
1433  Train *t = Train::From(v);
1435  /* Clear path reservation */
1436  SetDepotReservation(t->tile, false);
1438 
1440  t->wait_counter = 0;
1441  t->force_proceed = TFP_NONE;
1442  ClrBit(t->flags, VRF_TOGGLE_REVERSE);
1444  break;
1445  }
1446 
1447  case VEH_ROAD:
1449  break;
1450 
1451  case VEH_SHIP: {
1453  Ship *ship = Ship::From(v);
1454  ship->state = TRACK_BIT_DEPOT;
1455  ship->UpdateCache();
1456  ship->UpdateViewport(true, true);
1458  break;
1459  }
1460 
1461  case VEH_AIRCRAFT:
1464  break;
1465  default: NOT_REACHED();
1466  }
1468 
1469  if (v->type != VEH_TRAIN) {
1470  /* Trains update the vehicle list when the first unit enters the depot and calls VehicleEnterDepot() when the last unit enters.
1471  * 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 */
1473  }
1475 
1476  v->vehstatus |= VS_HIDDEN;
1477  v->cur_speed = 0;
1478 
1480 
1481  /* After a vehicle trigger, the graphics and properties of the vehicle could change. */
1482  TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT);
1483  v->MarkDirty();
1484 
1485  if (v->current_order.IsType(OT_GOTO_DEPOT)) {
1487 
1488  const Order *real_order = v->GetOrder(v->cur_real_order_index);
1489 
1490  /* Test whether we are heading for this depot. If not, do nothing.
1491  * Note: The target depot for nearest-/manual-depot-orders is only updated on junctions, but we want to accept every depot. */
1493  real_order != NULL && !(real_order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) &&
1494  (v->type == VEH_AIRCRAFT ? v->current_order.GetDestination() != GetStationIndex(v->tile) : v->dest_tile != v->tile)) {
1495  /* We are heading for another depot, keep driving. */
1496  return;
1497  }
1498 
1499  if (v->current_order.IsRefit()) {
1500  Backup<CompanyByte> cur_company(_current_company, v->owner, FILE_LINE);
1501  CommandCost cost = DoCommand(v->tile, v->index, v->current_order.GetRefitCargo() | 0xFF << 8, DC_EXEC, GetCmdRefitVeh(v));
1502  cur_company.Restore();
1503 
1504  if (cost.Failed()) {
1505  _vehicles_to_autoreplace[v] = false;
1506  if (v->owner == _local_company) {
1507  /* Notify the user that we stopped the vehicle */
1508  SetDParam(0, v->index);
1509  AddVehicleAdviceNewsItem(STR_NEWS_ORDER_REFIT_FAILED, v->index);
1510  }
1511  } else if (cost.GetCost() != 0) {
1512  v->profit_this_year -= cost.GetCost() << 8;
1513  if (v->owner == _local_company) {
1514  ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost.GetCost());
1515  }
1516  }
1517  }
1518 
1520  /* Part of orders */
1522  UpdateVehicleTimetable(v, true);
1524  }
1526  /* Vehicles are always stopped on entering depots. Do not restart this one. */
1527  _vehicles_to_autoreplace[v] = false;
1528  /* Invalidate last_loading_station. As the link from the station
1529  * before the stop to the station after the stop can't be predicted
1530  * we shouldn't construct it when the vehicle visits the next stop. */
1531  v->last_loading_station = INVALID_STATION;
1532  if (v->owner == _local_company) {
1533  SetDParam(0, v->index);
1534  AddVehicleAdviceNewsItem(STR_NEWS_TRAIN_IS_WAITING + v->type, v->index);
1535  }
1536  AI::NewEvent(v->owner, new ScriptEventVehicleWaitingInDepot(v->index));
1537  }
1538  v->current_order.MakeDummy();
1539  }
1540 }
1541 
1542 
1548 {
1549  UpdateVehicleTileHash(this, false);
1550 }
1551 
1557 void Vehicle::UpdateViewport(bool dirty)
1558 {
1559  Rect new_coord;
1560  this->sprite_seq.GetBounds(&new_coord);
1561 
1562  Point pt = RemapCoords(this->x_pos + this->x_offs, this->y_pos + this->y_offs, this->z_pos);
1563  new_coord.left += pt.x;
1564  new_coord.top += pt.y;
1565  new_coord.right += pt.x + 2 * ZOOM_LVL_BASE;
1566  new_coord.bottom += pt.y + 2 * ZOOM_LVL_BASE;
1567 
1568  UpdateVehicleViewportHash(this, new_coord.left, new_coord.top);
1569 
1570  Rect old_coord = this->coord;
1571  this->coord = new_coord;
1572 
1573  if (dirty) {
1574  if (old_coord.left == INVALID_COORD) {
1575  this->MarkAllViewportsDirty();
1576  } else {
1578  min(old_coord.left, this->coord.left),
1579  min(old_coord.top, this->coord.top),
1580  max(old_coord.right, this->coord.right),
1581  max(old_coord.bottom, this->coord.bottom));
1582  }
1583  }
1584 }
1585 
1590 {
1591  this->UpdatePosition();
1592  this->UpdateViewport(true);
1593 }
1594 
1599 {
1600  ::MarkAllViewportsDirty(this->coord.left, this->coord.top, this->coord.right, this->coord.bottom);
1601 }
1602 
1609 {
1610  static const int8 _delta_coord[16] = {
1611  -1,-1,-1, 0, 1, 1, 1, 0, /* x */
1612  -1, 0, 1, 1, 1, 0,-1,-1, /* y */
1613  };
1614 
1615  int x = v->x_pos + _delta_coord[v->direction];
1616  int y = v->y_pos + _delta_coord[v->direction + 8];
1617 
1619  gp.x = x;
1620  gp.y = y;
1621  gp.old_tile = v->tile;
1622  gp.new_tile = TileVirtXY(x, y);
1623  return gp;
1624 }
1625 
1626 static const Direction _new_direction_table[] = {
1627  DIR_N, DIR_NW, DIR_W,
1628  DIR_NE, DIR_SE, DIR_SW,
1629  DIR_E, DIR_SE, DIR_S
1630 };
1631 
1632 Direction GetDirectionTowards(const Vehicle *v, int x, int y)
1633 {
1634  int i = 0;
1635 
1636  if (y >= v->y_pos) {
1637  if (y != v->y_pos) i += 3;
1638  i += 3;
1639  }
1640 
1641  if (x >= v->x_pos) {
1642  if (x != v->x_pos) i++;
1643  i++;
1644  }
1645 
1646  Direction dir = v->direction;
1647 
1648  DirDiff dirdiff = DirDifference(_new_direction_table[i], dir);
1649  if (dirdiff == DIRDIFF_SAME) return dir;
1650  return ChangeDir(dir, dirdiff > DIRDIFF_REVERSE ? DIRDIFF_45LEFT : DIRDIFF_45RIGHT);
1651 }
1652 
1663 {
1664  return _tile_type_procs[GetTileType(tile)]->vehicle_enter_tile_proc(v, tile, x, y);
1665 }
1666 
1674 FreeUnitIDGenerator::FreeUnitIDGenerator(VehicleType type, CompanyID owner) : cache(NULL), maxid(0), curid(0)
1675 {
1676  /* Find maximum */
1677  const Vehicle *v;
1678  FOR_ALL_VEHICLES(v) {
1679  if (v->type == type && v->owner == owner) {
1680  this->maxid = max<UnitID>(this->maxid, v->unitnumber);
1681  }
1682  }
1683 
1684  if (this->maxid == 0) return;
1685 
1686  /* Reserving 'maxid + 2' because we need:
1687  * - space for the last item (with v->unitnumber == maxid)
1688  * - one free slot working as loop terminator in FreeUnitIDGenerator::NextID() */
1689  this->cache = CallocT<bool>(this->maxid + 2);
1690 
1691  /* Fill the cache */
1692  FOR_ALL_VEHICLES(v) {
1693  if (v->type == type && v->owner == owner) {
1694  this->cache[v->unitnumber] = true;
1695  }
1696  }
1697 }
1698 
1701 {
1702  if (this->maxid <= this->curid) return ++this->curid;
1703 
1704  while (this->cache[++this->curid]) { } // it will stop, we reserved more space than needed
1705 
1706  return this->curid;
1707 }
1708 
1715 {
1716  /* Check whether it is allowed to build another vehicle. */
1717  uint max_veh;
1718  switch (type) {
1719  case VEH_TRAIN: max_veh = _settings_game.vehicle.max_trains; break;
1720  case VEH_ROAD: max_veh = _settings_game.vehicle.max_roadveh; break;
1721  case VEH_SHIP: max_veh = _settings_game.vehicle.max_ships; break;
1722  case VEH_AIRCRAFT: max_veh = _settings_game.vehicle.max_aircraft; break;
1723  default: NOT_REACHED();
1724  }
1725 
1727  if (c->group_all[type].num_vehicle >= max_veh) return UINT16_MAX; // Currently already at the limit, no room to make a new one.
1728 
1730 
1731  return gen.NextID();
1732 }
1733 
1734 
1744 {
1745  assert(IsCompanyBuildableVehicleType(type));
1746 
1747  if (!Company::IsValidID(_local_company)) return false;
1749 
1750  UnitID max;
1751  switch (type) {
1752  case VEH_TRAIN: max = _settings_game.vehicle.max_trains; break;
1753  case VEH_ROAD: max = _settings_game.vehicle.max_roadveh; break;
1754  case VEH_SHIP: max = _settings_game.vehicle.max_ships; break;
1755  case VEH_AIRCRAFT: max = _settings_game.vehicle.max_aircraft; break;
1756  default: NOT_REACHED();
1757  }
1758 
1759  /* We can build vehicle infrastructure when we may build the vehicle type */
1760  if (max > 0) {
1761  /* Can we actually build the vehicle type? */
1762  const Engine *e;
1763  FOR_ALL_ENGINES_OF_TYPE(e, type) {
1764  if (HasBit(e->company_avail, _local_company)) return true;
1765  }
1766  return false;
1767  }
1768 
1769  /* We should be able to build infrastructure when we have the actual vehicle type */
1770  const Vehicle *v;
1771  FOR_ALL_VEHICLES(v) {
1772  if (v->owner == _local_company && v->type == type) return true;
1773  }
1774 
1775  return false;
1776 }
1777 
1778 
1786 LiveryScheme GetEngineLiveryScheme(EngineID engine_type, EngineID parent_engine_type, const Vehicle *v)
1787 {
1788  CargoID cargo_type = v == NULL ? (CargoID)CT_INVALID : v->cargo_type;
1789  const Engine *e = Engine::Get(engine_type);
1790  switch (e->type) {
1791  default: NOT_REACHED();
1792  case VEH_TRAIN:
1793  if (v != NULL && parent_engine_type != INVALID_ENGINE && (UsesWagonOverride(v) || (v->IsArticulatedPart() && e->u.rail.railveh_type != RAILVEH_WAGON))) {
1794  /* Wagonoverrides use the colour scheme of the front engine.
1795  * Articulated parts use the colour scheme of the first part. (Not supported for articulated wagons) */
1796  engine_type = parent_engine_type;
1797  e = Engine::Get(engine_type);
1798  /* Note: Luckily cargo_type is not needed for engines */
1799  }
1800 
1801  if (cargo_type == CT_INVALID) cargo_type = e->GetDefaultCargoType();
1802  if (cargo_type == CT_INVALID) cargo_type = CT_GOODS; // The vehicle does not carry anything, let's pick some freight cargo
1803  if (e->u.rail.railveh_type == RAILVEH_WAGON) {
1804  if (!CargoSpec::Get(cargo_type)->is_freight) {
1805  if (parent_engine_type == INVALID_ENGINE) {
1806  return LS_PASSENGER_WAGON_STEAM;
1807  } else {
1808  switch (RailVehInfo(parent_engine_type)->engclass) {
1809  default: NOT_REACHED();
1810  case EC_STEAM: return LS_PASSENGER_WAGON_STEAM;
1811  case EC_DIESEL: return LS_PASSENGER_WAGON_DIESEL;
1812  case EC_ELECTRIC: return LS_PASSENGER_WAGON_ELECTRIC;
1813  case EC_MONORAIL: return LS_PASSENGER_WAGON_MONORAIL;
1814  case EC_MAGLEV: return LS_PASSENGER_WAGON_MAGLEV;
1815  }
1816  }
1817  } else {
1818  return LS_FREIGHT_WAGON;
1819  }
1820  } else {
1821  bool is_mu = HasBit(e->info.misc_flags, EF_RAIL_IS_MU);
1822 
1823  switch (e->u.rail.engclass) {
1824  default: NOT_REACHED();
1825  case EC_STEAM: return LS_STEAM;
1826  case EC_DIESEL: return is_mu ? LS_DMU : LS_DIESEL;
1827  case EC_ELECTRIC: return is_mu ? LS_EMU : LS_ELECTRIC;
1828  case EC_MONORAIL: return LS_MONORAIL;
1829  case EC_MAGLEV: return LS_MAGLEV;
1830  }
1831  }
1832 
1833  case VEH_ROAD:
1834  /* Always use the livery of the front */
1835  if (v != NULL && parent_engine_type != INVALID_ENGINE) {
1836  engine_type = parent_engine_type;
1837  e = Engine::Get(engine_type);
1838  cargo_type = v->First()->cargo_type;
1839  }
1840  if (cargo_type == CT_INVALID) cargo_type = e->GetDefaultCargoType();
1841  if (cargo_type == CT_INVALID) cargo_type = CT_GOODS; // The vehicle does not carry anything, let's pick some freight cargo
1842 
1843  /* Important: Use Tram Flag of front part. Luckily engine_type refers to the front part here. */
1844  if (HasBit(e->info.misc_flags, EF_ROAD_TRAM)) {
1845  /* Tram */
1846  return IsCargoInClass(cargo_type, CC_PASSENGERS) ? LS_PASSENGER_TRAM : LS_FREIGHT_TRAM;
1847  } else {
1848  /* Bus or truck */
1849  return IsCargoInClass(cargo_type, CC_PASSENGERS) ? LS_BUS : LS_TRUCK;
1850  }
1851 
1852  case VEH_SHIP:
1853  if (cargo_type == CT_INVALID) cargo_type = e->GetDefaultCargoType();
1854  if (cargo_type == CT_INVALID) cargo_type = CT_GOODS; // The vehicle does not carry anything, let's pick some freight cargo
1855  return IsCargoInClass(cargo_type, CC_PASSENGERS) ? LS_PASSENGER_SHIP : LS_FREIGHT_SHIP;
1856 
1857  case VEH_AIRCRAFT:
1858  switch (e->u.air.subtype) {
1859  case AIR_HELI: return LS_HELICOPTER;
1860  case AIR_CTOL: return LS_SMALL_PLANE;
1861  case AIR_CTOL | AIR_FAST: return LS_LARGE_PLANE;
1862  default: NOT_REACHED();
1863  }
1864  }
1865 }
1866 
1876 const Livery *GetEngineLivery(EngineID engine_type, CompanyID company, EngineID parent_engine_type, const Vehicle *v, byte livery_setting)
1877 {
1878  const Company *c = Company::Get(company);
1879  LiveryScheme scheme = LS_DEFAULT;
1880 
1881  /* The default livery is always available for use, but its in_use flag determines
1882  * whether any _other_ liveries are in use. */
1883  if (c->livery[LS_DEFAULT].in_use && (livery_setting == LIT_ALL || (livery_setting == LIT_COMPANY && company == _local_company))) {
1884  /* Determine the livery scheme to use */
1885  scheme = GetEngineLiveryScheme(engine_type, parent_engine_type, v);
1886 
1887  /* Switch back to the default scheme if the resolved scheme is not in use */
1888  if (!c->livery[scheme].in_use) scheme = LS_DEFAULT;
1889  }
1890 
1891  return &c->livery[scheme];
1892 }
1893 
1894 
1895 static PaletteID GetEngineColourMap(EngineID engine_type, CompanyID company, EngineID parent_engine_type, const Vehicle *v)
1896 {
1897  PaletteID map = (v != NULL) ? v->colourmap : PAL_NONE;
1898 
1899  /* Return cached value if any */
1900  if (map != PAL_NONE) return map;
1901 
1902  const Engine *e = Engine::Get(engine_type);
1903 
1904  /* Check if we should use the colour map callback */
1906  uint16 callback = GetVehicleCallback(CBID_VEHICLE_COLOUR_MAPPING, 0, 0, engine_type, v);
1907  /* Failure means "use the default two-colour" */
1908  if (callback != CALLBACK_FAILED) {
1909  assert_compile(PAL_NONE == 0); // Returning 0x4000 (resp. 0xC000) coincidences with default value (PAL_NONE)
1910  map = GB(callback, 0, 14);
1911  /* If bit 14 is set, then the company colours are applied to the
1912  * map else it's returned as-is. */
1913  if (!HasBit(callback, 14)) {
1914  /* Update cache */
1915  if (v != NULL) const_cast<Vehicle *>(v)->colourmap = map;
1916  return map;
1917  }
1918  }
1919  }
1920 
1921  bool twocc = HasBit(e->info.misc_flags, EF_USES_2CC);
1922 
1923  if (map == PAL_NONE) map = twocc ? (PaletteID)SPR_2CCMAP_BASE : (PaletteID)PALETTE_RECOLOUR_START;
1924 
1925  /* Spectator has news shown too, but has invalid company ID - as well as dedicated server */
1926  if (!Company::IsValidID(company)) return map;
1927 
1928  const Livery *livery = GetEngineLivery(engine_type, company, parent_engine_type, v, _settings_client.gui.liveries);
1929 
1930  map += livery->colour1;
1931  if (twocc) map += livery->colour2 * 16;
1932 
1933  /* Update cache */
1934  if (v != NULL) const_cast<Vehicle *>(v)->colourmap = map;
1935  return map;
1936 }
1937 
1945 {
1946  return GetEngineColourMap(engine_type, company, INVALID_ENGINE, NULL);
1947 }
1948 
1955 {
1956  if (v->IsGroundVehicle()) {
1957  return GetEngineColourMap(v->engine_type, v->owner, v->GetGroundVehicleCache()->first_engine, v);
1958  }
1959 
1960  return GetEngineColourMap(v->engine_type, v->owner, INVALID_ENGINE, v);
1961 }
1962 
1967 {
1968  if (this->IsGroundVehicle()) {
1969  uint16 &gv_flags = this->GetGroundVehicleFlags();
1970  if (HasBit(gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS)) {
1971  /* Do not delete orders, only skip them */
1973  this->cur_implicit_order_index = this->cur_real_order_index;
1974  InvalidateVehicleOrder(this, 0);
1975  return;
1976  }
1977  }
1978 
1979  const Order *order = this->GetOrder(this->cur_implicit_order_index);
1980  while (order != NULL) {
1981  if (this->cur_implicit_order_index == this->cur_real_order_index) break;
1982 
1983  if (order->IsType(OT_IMPLICIT)) {
1984  DeleteOrder(this, this->cur_implicit_order_index);
1985  /* DeleteOrder does various magic with order_indices, so resync 'order' with 'cur_implicit_order_index' */
1986  order = this->GetOrder(this->cur_implicit_order_index);
1987  } else {
1988  /* Skip non-implicit orders, e.g. service-orders */
1989  order = order->next;
1990  this->cur_implicit_order_index++;
1991  }
1992 
1993  /* Wrap around */
1994  if (order == NULL) {
1995  order = this->GetOrder(0);
1996  this->cur_implicit_order_index = 0;
1997  }
1998  }
1999 }
2000 
2006 {
2007  assert(IsTileType(this->tile, MP_STATION) || this->type == VEH_SHIP);
2008 
2009  if (this->current_order.IsType(OT_GOTO_STATION) &&
2010  this->current_order.GetDestination() == this->last_station_visited) {
2011  this->DeleteUnreachedImplicitOrders();
2012 
2013  /* Now both order indices point to the destination station, and we can start loading */
2014  this->current_order.MakeLoading(true);
2015  UpdateVehicleTimetable(this, true);
2016 
2017  /* Furthermore add the Non Stop flag to mark that this station
2018  * is the actual destination of the vehicle, which is (for example)
2019  * necessary to be known for HandleTrainLoading to determine
2020  * whether the train is lost or not; not marking a train lost
2021  * that arrives at random stations is bad. */
2022  this->current_order.SetNonStopType(ONSF_NO_STOP_AT_ANY_STATION);
2023 
2024  } else {
2025  /* We weren't scheduled to stop here. Insert an implicit order
2026  * to show that we are stopping here.
2027  * While only groundvehicles have implicit orders, e.g. aircraft might still enter
2028  * the 'wrong' terminal when skipping orders etc. */
2029  Order *in_list = this->GetOrder(this->cur_implicit_order_index);
2030  if (this->IsGroundVehicle() &&
2031  (in_list == NULL || !in_list->IsType(OT_IMPLICIT) ||
2032  in_list->GetDestination() != this->last_station_visited)) {
2033  bool suppress_implicit_orders = HasBit(this->GetGroundVehicleFlags(), GVF_SUPPRESS_IMPLICIT_ORDERS);
2034  /* Do not create consecutive duplicates of implicit orders */
2035  Order *prev_order = this->cur_implicit_order_index > 0 ? this->GetOrder(this->cur_implicit_order_index - 1) : (this->GetNumOrders() > 1 ? this->GetLastOrder() : NULL);
2036  if (prev_order == NULL ||
2037  (!prev_order->IsType(OT_IMPLICIT) && !prev_order->IsType(OT_GOTO_STATION)) ||
2038  prev_order->GetDestination() != this->last_station_visited) {
2039 
2040  /* Prefer deleting implicit orders instead of inserting new ones,
2041  * so test whether the right order follows later. In case of only
2042  * implicit orders treat the last order in the list like an
2043  * explicit one, except if the overall number of orders surpasses
2044  * IMPLICIT_ORDER_ONLY_CAP. */
2045  int target_index = this->cur_implicit_order_index;
2046  bool found = false;
2047  while (target_index != this->cur_real_order_index || this->GetNumManualOrders() == 0) {
2048  const Order *order = this->GetOrder(target_index);
2049  if (order == NULL) break; // No orders.
2050  if (order->IsType(OT_IMPLICIT) && order->GetDestination() == this->last_station_visited) {
2051  found = true;
2052  break;
2053  }
2054  target_index++;
2055  if (target_index >= this->orders.list->GetNumOrders()) {
2056  if (this->GetNumManualOrders() == 0 &&
2057  this->GetNumOrders() < IMPLICIT_ORDER_ONLY_CAP) {
2058  break;
2059  }
2060  target_index = 0;
2061  }
2062  if (target_index == this->cur_implicit_order_index) break; // Avoid infinite loop.
2063  }
2064 
2065  if (found) {
2066  if (suppress_implicit_orders) {
2067  /* Skip to the found order */
2068  this->cur_implicit_order_index = target_index;
2069  InvalidateVehicleOrder(this, 0);
2070  } else {
2071  /* Delete all implicit orders up to the station we just reached */
2072  const Order *order = this->GetOrder(this->cur_implicit_order_index);
2073  while (!order->IsType(OT_IMPLICIT) || order->GetDestination() != this->last_station_visited) {
2074  if (order->IsType(OT_IMPLICIT)) {
2075  DeleteOrder(this, this->cur_implicit_order_index);
2076  /* DeleteOrder does various magic with order_indices, so resync 'order' with 'cur_implicit_order_index' */
2077  order = this->GetOrder(this->cur_implicit_order_index);
2078  } else {
2079  /* Skip non-implicit orders, e.g. service-orders */
2080  order = order->next;
2081  this->cur_implicit_order_index++;
2082  }
2083 
2084  /* Wrap around */
2085  if (order == NULL) {
2086  order = this->GetOrder(0);
2087  this->cur_implicit_order_index = 0;
2088  }
2089  assert(order != NULL);
2090  }
2091  }
2092  } else if (!suppress_implicit_orders &&
2093  ((this->orders.list == NULL ? OrderList::CanAllocateItem() : this->orders.list->GetNumOrders() < MAX_VEH_ORDER_ID)) &&
2095  /* Insert new implicit order */
2096  Order *implicit_order = new Order();
2097  implicit_order->MakeImplicit(this->last_station_visited);
2098  InsertOrder(this, implicit_order, this->cur_implicit_order_index);
2099  if (this->cur_implicit_order_index > 0) --this->cur_implicit_order_index;
2100 
2101  /* InsertOrder disabled creation of implicit orders for all vehicles with the same implicit order.
2102  * Reenable it for this vehicle */
2103  uint16 &gv_flags = this->GetGroundVehicleFlags();
2105  }
2106  }
2107  }
2108  this->current_order.MakeLoading(false);
2109  }
2110 
2111  if (this->last_loading_station != INVALID_STATION &&
2112  this->last_loading_station != this->last_station_visited &&
2113  ((this->current_order.GetLoadType() & OLFB_NO_LOAD) == 0 ||
2114  (this->current_order.GetUnloadType() & OUFB_NO_UNLOAD) == 0)) {
2115  IncreaseStats(Station::Get(this->last_loading_station), this, this->last_station_visited);
2116  }
2117 
2118  PrepareUnload(this);
2119 
2120  SetWindowDirty(GetWindowClassForVehicleType(this->type), this->owner);
2122  SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
2123  SetWindowDirty(WC_STATION_VIEW, this->last_station_visited);
2124 
2125  Station::Get(this->last_station_visited)->MarkTilesDirty(true);
2126  this->cur_speed = 0;
2127  this->MarkDirty();
2128 }
2129 
2135 void Vehicle::CancelReservation(StationID next, Station *st)
2136 {
2137  for (Vehicle *v = this; v != NULL; v = v->next) {
2138  VehicleCargoList &cargo = v->cargo;
2139  if (cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0) {
2140  DEBUG(misc, 1, "cancelling cargo reservation");
2141  cargo.Return(UINT_MAX, &st->goods[v->cargo_type].cargo, next);
2142  cargo.SetTransferLoadPlace(st->xy);
2143  }
2144  cargo.KeepAll();
2145  }
2146 }
2147 
2153 {
2154  assert(this->current_order.IsType(OT_LOADING));
2155 
2156  delete this->cargo_payment;
2157  assert(this->cargo_payment == NULL); // cleared by ~CargoPayment
2158 
2159  /* Only update the timetable if the vehicle was supposed to stop here. */
2160  if (this->current_order.GetNonStopType() != ONSF_STOP_EVERYWHERE) UpdateVehicleTimetable(this, false);
2161 
2162  if ((this->current_order.GetLoadType() & OLFB_NO_LOAD) == 0 ||
2163  (this->current_order.GetUnloadType() & OUFB_NO_UNLOAD) == 0) {
2164  if (this->current_order.CanLeaveWithCargo(this->last_loading_station != INVALID_STATION)) {
2165  /* Refresh next hop stats to make sure we've done that at least once
2166  * during the stop and that refit_cap == cargo_cap for each vehicle in
2167  * the consist. */
2168  this->ResetRefitCaps();
2169  LinkRefresher::Run(this);
2170 
2171  /* if the vehicle could load here or could stop with cargo loaded set the last loading station */
2172  this->last_loading_station = this->last_station_visited;
2173  } else {
2174  /* if the vehicle couldn't load and had to unload or transfer everything
2175  * set the last loading station to invalid as it will leave empty. */
2176  this->last_loading_station = INVALID_STATION;
2177  }
2178  }
2179 
2180  this->current_order.MakeLeaveStation();
2181  Station *st = Station::Get(this->last_station_visited);
2182  this->CancelReservation(INVALID_STATION, st);
2183  st->loading_vehicles.remove(this);
2184 
2185  HideFillingPercent(&this->fill_percent_te_id);
2186  trip_occupancy = CalcPercentVehicleFilled(this, NULL);
2187 
2188  if (this->type == VEH_TRAIN && !(this->vehstatus & VS_CRASHED)) {
2189  /* Trigger station animation (trains only) */
2190  if (IsTileType(this->tile, MP_STATION)) {
2192  TriggerStationAnimation(st, this->tile, SAT_TRAIN_DEPARTS);
2193  }
2194 
2195  SetBit(Train::From(this)->flags, VRF_LEAVING_STATION);
2196  }
2197 
2198  this->MarkDirty();
2199 }
2200 
2205 {
2206  for (Vehicle *v = this; v != NULL; v = v->Next()) v->refit_cap = v->cargo_cap;
2207 }
2208 
2214 void Vehicle::HandleLoading(bool mode)
2215 {
2216  switch (this->current_order.GetType()) {
2217  case OT_LOADING: {
2218  uint wait_time = max(this->current_order.GetTimetabledWait() - this->lateness_counter, 0);
2219 
2220  /* Not the first call for this tick, or still loading */
2221  if (mode || !HasBit(this->vehicle_flags, VF_LOADING_FINISHED) || this->current_order_time < wait_time) return;
2222 
2223  this->PlayLeaveStationSound();
2224 
2225  this->LeaveStation();
2226 
2227  /* Only advance to next order if we just loaded at the current one */
2228  const Order *order = this->GetOrder(this->cur_implicit_order_index);
2229  if (order == NULL ||
2230  (!order->IsType(OT_IMPLICIT) && !order->IsType(OT_GOTO_STATION)) ||
2231  order->GetDestination() != this->last_station_visited) {
2232  return;
2233  }
2234  break;
2235  }
2236 
2237  case OT_DUMMY: break;
2238 
2239  default: return;
2240  }
2241 
2242  this->IncrementImplicitOrderIndex();
2243 }
2244 
2250 {
2251  for (const Vehicle *v = this; v != NULL; v = v->Next()) {
2252  if (v->cargo_cap == 0) continue;
2253  SmallPair<CargoID, uint> *pair = capacities.Find(v->cargo_type);
2254  if (pair == capacities.End()) {
2255  pair = capacities.Append();
2256  pair->first = v->cargo_type;
2257  pair->second = v->cargo_cap - v->cargo.StoredCount();
2258  } else {
2259  pair->second += v->cargo_cap - v->cargo.StoredCount();
2260  }
2261  }
2262 }
2263 
2264 uint Vehicle::GetConsistTotalCapacity() const
2265 {
2266  uint result = 0;
2267  for (const Vehicle *v = this; v != NULL; v = v->Next()) {
2268  result += v->cargo_cap;
2269  }
2270  return result;
2271 }
2272 
2280 {
2281  CommandCost ret = CheckOwnership(this->owner);
2282  if (ret.Failed()) return ret;
2283 
2284  if (this->vehstatus & VS_CRASHED) return CMD_ERROR;
2285  if (this->IsStoppedInDepot()) return CMD_ERROR;
2286 
2287  if (this->current_order.IsType(OT_GOTO_DEPOT)) {
2288  bool halt_in_depot = (this->current_order.GetDepotActionType() & ODATFB_HALT) != 0;
2289  if (!!(command & DEPOT_SERVICE) == halt_in_depot) {
2290  /* We called with a different DEPOT_SERVICE setting.
2291  * Now we change the setting to apply the new one and let the vehicle head for the same depot.
2292  * Note: the if is (true for requesting service == true for ordered to stop in depot) */
2293  if (flags & DC_EXEC) {
2294  this->current_order.SetDepotOrderType(ODTF_MANUAL);
2295  this->current_order.SetDepotActionType(halt_in_depot ? ODATF_SERVICE_ONLY : ODATFB_HALT);
2297  }
2298  return CommandCost();
2299  }
2300 
2301  if (command & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
2302  if (flags & DC_EXEC) {
2303  /* If the orders to 'goto depot' are in the orders list (forced servicing),
2304  * then skip to the next order; effectively cancelling this forced service */
2305  if (this->current_order.GetDepotOrderType() & ODTFB_PART_OF_ORDERS) this->IncrementRealOrderIndex();
2306 
2307  if (this->IsGroundVehicle()) {
2308  uint16 &gv_flags = this->GetGroundVehicleFlags();
2310  }
2311 
2312  this->current_order.MakeDummy();
2314  }
2315  return CommandCost();
2316  }
2317 
2318  TileIndex location;
2319  DestinationID destination;
2320  bool reverse;
2321  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};
2322  if (!this->FindClosestDepot(&location, &destination, &reverse)) return_cmd_error(no_depot[this->type]);
2323 
2324  if (flags & DC_EXEC) {
2325  if (this->current_order.IsType(OT_LOADING)) this->LeaveStation();
2326 
2327  if (this->IsGroundVehicle() && this->GetNumManualOrders() > 0) {
2328  uint16 &gv_flags = this->GetGroundVehicleFlags();
2330  }
2331 
2332  this->dest_tile = location;
2333  this->current_order.MakeGoToDepot(destination, ODTF_MANUAL);
2334  if (!(command & DEPOT_SERVICE)) this->current_order.SetDepotActionType(ODATFB_HALT);
2336 
2337  /* If there is no depot in front, reverse automatically (trains only) */
2338  if (this->type == VEH_TRAIN && reverse) DoCommand(this->tile, this->index, 0, DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION);
2339 
2340  if (this->type == VEH_AIRCRAFT) {
2341  Aircraft *a = Aircraft::From(this);
2342  if (a->state == FLYING && a->targetairport != destination) {
2343  /* The aircraft is now heading for a different hangar than the next in the orders */
2346  }
2347  }
2348  }
2349 
2350  return CommandCost();
2351 
2352 }
2353 
2358 void Vehicle::UpdateVisualEffect(bool allow_power_change)
2359 {
2360  bool powered_before = HasBit(this->vcache.cached_vis_effect, VE_DISABLE_WAGON_POWER);
2361  const Engine *e = this->GetEngine();
2362 
2363  /* Evaluate properties */
2364  byte visual_effect;
2365  switch (e->type) {
2366  case VEH_TRAIN: visual_effect = e->u.rail.visual_effect; break;
2367  case VEH_ROAD: visual_effect = e->u.road.visual_effect; break;
2368  case VEH_SHIP: visual_effect = e->u.ship.visual_effect; break;
2369  default: visual_effect = 1 << VE_DISABLE_EFFECT; break;
2370  }
2371 
2372  /* Check powered wagon / visual effect callback */
2374  uint16 callback = GetVehicleCallback(CBID_VEHICLE_VISUAL_EFFECT, 0, 0, this->engine_type, this);
2375 
2376  if (callback != CALLBACK_FAILED) {
2377  if (callback >= 0x100 && e->GetGRF()->grf_version >= 8) ErrorUnknownCallbackResult(e->GetGRFID(), CBID_VEHICLE_VISUAL_EFFECT, callback);
2378 
2379  callback = GB(callback, 0, 8);
2380  /* Avoid accidentally setting 'visual_effect' to the default value
2381  * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
2382  if (callback == VE_DEFAULT) {
2383  assert(HasBit(callback, VE_DISABLE_EFFECT));
2384  SB(callback, VE_TYPE_START, VE_TYPE_COUNT, 0);
2385  }
2386  visual_effect = callback;
2387  }
2388  }
2389 
2390  /* Apply default values */
2391  if (visual_effect == VE_DEFAULT ||
2392  (!HasBit(visual_effect, VE_DISABLE_EFFECT) && GB(visual_effect, VE_TYPE_START, VE_TYPE_COUNT) == VE_TYPE_DEFAULT)) {
2393  /* Only train engines have default effects.
2394  * Note: This is independent of whether the engine is a front engine or articulated part or whatever. */
2395  if (e->type != VEH_TRAIN || e->u.rail.railveh_type == RAILVEH_WAGON || !IsInsideMM(e->u.rail.engclass, EC_STEAM, EC_MONORAIL)) {
2396  if (visual_effect == VE_DEFAULT) {
2397  visual_effect = 1 << VE_DISABLE_EFFECT;
2398  } else {
2399  SetBit(visual_effect, VE_DISABLE_EFFECT);
2400  }
2401  } else {
2402  if (visual_effect == VE_DEFAULT) {
2403  /* Also set the offset */
2404  visual_effect = (VE_OFFSET_CENTRE - (e->u.rail.engclass == EC_STEAM ? 4 : 0)) << VE_OFFSET_START;
2405  }
2406  SB(visual_effect, VE_TYPE_START, VE_TYPE_COUNT, e->u.rail.engclass - EC_STEAM + VE_TYPE_STEAM);
2407  }
2408  }
2409 
2410  this->vcache.cached_vis_effect = visual_effect;
2411 
2412  if (!allow_power_change && powered_before != HasBit(this->vcache.cached_vis_effect, VE_DISABLE_WAGON_POWER)) {
2413  ToggleBit(this->vcache.cached_vis_effect, VE_DISABLE_WAGON_POWER);
2414  ShowNewGrfVehicleError(this->engine_type, STR_NEWGRF_BROKEN, STR_NEWGRF_BROKEN_POWERED_WAGON, GBUG_VEH_POWERED_WAGON, false);
2415  }
2416 }
2417 
2418 static const int8 _vehicle_smoke_pos[8] = {
2419  1, 1, 1, 0, -1, -1, -1, 0
2420 };
2421 
2426 static void SpawnAdvancedVisualEffect(const Vehicle *v)
2427 {
2428  uint16 callback = GetVehicleCallback(CBID_VEHICLE_SPAWN_VISUAL_EFFECT, 0, Random(), v->engine_type, v);
2429  if (callback == CALLBACK_FAILED) return;
2430 
2431  uint count = GB(callback, 0, 2);
2432  bool auto_center = HasBit(callback, 13);
2433  bool auto_rotate = !HasBit(callback, 14);
2434 
2435  int8 l_center = 0;
2436  if (auto_center) {
2437  /* For road vehicles: Compute offset from vehicle position to vehicle center */
2438  if (v->type == VEH_ROAD) l_center = -(int)(VEHICLE_LENGTH - RoadVehicle::From(v)->gcache.cached_veh_length) / 2;
2439  } else {
2440  /* For trains: Compute offset from vehicle position to sprite position */
2441  if (v->type == VEH_TRAIN) l_center = (VEHICLE_LENGTH - Train::From(v)->gcache.cached_veh_length) / 2;
2442  }
2443 
2444  Direction l_dir = v->direction;
2445  if (v->type == VEH_TRAIN && HasBit(Train::From(v)->flags, VRF_REVERSE_DIRECTION)) l_dir = ReverseDir(l_dir);
2446  Direction t_dir = ChangeDir(l_dir, DIRDIFF_90RIGHT);
2447 
2448  int8 x_center = _vehicle_smoke_pos[l_dir] * l_center;
2449  int8 y_center = _vehicle_smoke_pos[t_dir] * l_center;
2450 
2451  for (uint i = 0; i < count; i++) {
2452  uint32 reg = GetRegister(0x100 + i);
2453  uint type = GB(reg, 0, 8);
2454  int8 x = GB(reg, 8, 8);
2455  int8 y = GB(reg, 16, 8);
2456  int8 z = GB(reg, 24, 8);
2457 
2458  if (auto_rotate) {
2459  int8 l = x;
2460  int8 t = y;
2461  x = _vehicle_smoke_pos[l_dir] * l + _vehicle_smoke_pos[t_dir] * t;
2462  y = _vehicle_smoke_pos[t_dir] * l - _vehicle_smoke_pos[l_dir] * t;
2463  }
2464 
2465  if (type >= 0xF0) {
2466  switch (type) {
2467  case 0xF1: CreateEffectVehicleRel(v, x_center + x, y_center + y, z, EV_STEAM_SMOKE); break;
2468  case 0xF2: CreateEffectVehicleRel(v, x_center + x, y_center + y, z, EV_DIESEL_SMOKE); break;
2469  case 0xF3: CreateEffectVehicleRel(v, x_center + x, y_center + y, z, EV_ELECTRIC_SPARK); break;
2470  case 0xFA: CreateEffectVehicleRel(v, x_center + x, y_center + y, z, EV_BREAKDOWN_SMOKE_AIRCRAFT); break;
2471  default: break;
2472  }
2473  }
2474  }
2475 }
2476 
2482 {
2483  assert(this->IsPrimaryVehicle());
2484  bool sound = false;
2485 
2486  /* Do not show any smoke when:
2487  * - vehicle smoke is disabled by the player
2488  * - the vehicle is slowing down or stopped (by the player)
2489  * - the vehicle is moving very slowly
2490  */
2491  if (_settings_game.vehicle.smoke_amount == 0 ||
2492  this->vehstatus & (VS_TRAIN_SLOWING | VS_STOPPED) ||
2493  this->cur_speed < 2) {
2494  return;
2495  }
2496 
2497  /* Use the speed as limited by underground and orders. */
2498  uint max_speed = this->GetCurrentMaxSpeed();
2499 
2500  if (this->type == VEH_TRAIN) {
2501  const Train *t = Train::From(this);
2502  /* For trains, do not show any smoke when:
2503  * - the train is reversing
2504  * - is entering a station with an order to stop there and its speed is equal to maximum station entering speed
2505  */
2506  if (HasBit(t->flags, VRF_REVERSING) ||
2508  t->cur_speed >= max_speed)) {
2509  return;
2510  }
2511  }
2512 
2513  const Vehicle *v = this;
2514 
2515  do {
2516  bool advanced = HasBit(v->vcache.cached_vis_effect, VE_ADVANCED_EFFECT);
2518  VisualEffectSpawnModel effect_model = VESM_NONE;
2519  if (advanced) {
2520  effect_offset = VE_OFFSET_CENTRE;
2522  if (effect_model >= VESM_END) effect_model = VESM_NONE; // unknown spawning model
2523  } else {
2525  assert(effect_model != (VisualEffectSpawnModel)VE_TYPE_DEFAULT); // should have been resolved by UpdateVisualEffect
2526  assert_compile((uint)VESM_STEAM == (uint)VE_TYPE_STEAM);
2527  assert_compile((uint)VESM_DIESEL == (uint)VE_TYPE_DIESEL);
2528  assert_compile((uint)VESM_ELECTRIC == (uint)VE_TYPE_ELECTRIC);
2529  }
2530 
2531  /* Show no smoke when:
2532  * - Smoke has been disabled for this vehicle
2533  * - The vehicle is not visible
2534  * - The vehicle is under a bridge
2535  * - The vehicle is on a depot tile
2536  * - The vehicle is on a tunnel tile
2537  * - The vehicle is a train engine that is currently unpowered */
2538  if (effect_model == VESM_NONE ||
2539  v->vehstatus & VS_HIDDEN ||
2540  IsBridgeAbove(v->tile) ||
2541  IsDepotTile(v->tile) ||
2542  IsTunnelTile(v->tile) ||
2543  (v->type == VEH_TRAIN &&
2544  !HasPowerOnRail(Train::From(v)->railtype, GetTileRailType(v->tile)))) {
2545  continue;
2546  }
2547 
2548  EffectVehicleType evt = EV_END;
2549  switch (effect_model) {
2550  case VESM_STEAM:
2551  /* Steam smoke - amount is gradually falling until vehicle reaches its maximum speed, after that it's normal.
2552  * Details: while vehicle's current speed is gradually increasing, steam plumes' density decreases by one third each
2553  * third of its maximum speed spectrum. Steam emission finally normalises at very close to vehicle's maximum speed.
2554  * REGULATION:
2555  * - instead of 1, 4 / 2^smoke_amount (max. 2) is used to provide sufficient regulation to steam puffs' amount. */
2556  if (GB(v->tick_counter, 0, ((4 >> _settings_game.vehicle.smoke_amount) + ((this->cur_speed * 3) / max_speed))) == 0) {
2557  evt = EV_STEAM_SMOKE;
2558  }
2559  break;
2560 
2561  case VESM_DIESEL: {
2562  /* Diesel smoke - thicker when vehicle is starting, gradually subsiding till it reaches its maximum speed
2563  * when smoke emission stops.
2564  * Details: Vehicle's (max.) speed spectrum is divided into 32 parts. When max. speed is reached, chance for smoke
2565  * emission erodes by 32 (1/4). For trains, power and weight come in handy too to either increase smoke emission in
2566  * 6 steps (1000HP each) if the power is low or decrease smoke emission in 6 steps (512 tonnes each) if the train
2567  * isn't overweight. Power and weight contributions are expressed in a way that neither extreme power, nor
2568  * extreme weight can ruin the balance (e.g. FreightWagonMultiplier) in the formula. When the vehicle reaches
2569  * maximum speed no diesel_smoke is emitted.
2570  * REGULATION:
2571  * - up to which speed a diesel vehicle is emitting smoke (with reduced/small setting only until 1/2 of max_speed),
2572  * - in Chance16 - the last value is 512 / 2^smoke_amount (max. smoke when 128 = smoke_amount of 2). */
2573  int power_weight_effect = 0;
2574  if (v->type == VEH_TRAIN) {
2575  power_weight_effect = (32 >> (Train::From(this)->gcache.cached_power >> 10)) - (32 >> (Train::From(this)->gcache.cached_weight >> 9));
2576  }
2577  if (this->cur_speed < (max_speed >> (2 >> _settings_game.vehicle.smoke_amount)) &&
2578  Chance16((64 - ((this->cur_speed << 5) / max_speed) + power_weight_effect), (512 >> _settings_game.vehicle.smoke_amount))) {
2579  evt = EV_DIESEL_SMOKE;
2580  }
2581  break;
2582  }
2583 
2584  case VESM_ELECTRIC:
2585  /* Electric train's spark - more often occurs when train is departing (more load)
2586  * Details: Electric locomotives are usually at least twice as powerful as their diesel counterparts, so spark
2587  * emissions are kept simple. Only when starting, creating huge force are sparks more likely to happen, but when
2588  * reaching its max. speed, quarter by quarter of it, chance decreases until the usual 2,22% at train's top speed.
2589  * REGULATION:
2590  * - in Chance16 the last value is 360 / 2^smoke_amount (max. sparks when 90 = smoke_amount of 2). */
2591  if (GB(v->tick_counter, 0, 2) == 0 &&
2592  Chance16((6 - ((this->cur_speed << 2) / max_speed)), (360 >> _settings_game.vehicle.smoke_amount))) {
2593  evt = EV_ELECTRIC_SPARK;
2594  }
2595  break;
2596 
2597  default:
2598  NOT_REACHED();
2599  }
2600 
2601  if (evt != EV_END && advanced) {
2602  sound = true;
2604  } else if (evt != EV_END) {
2605  sound = true;
2606 
2607  /* The effect offset is relative to a point 4 units behind the vehicle's
2608  * front (which is the center of an 8/8 vehicle). Shorter vehicles need a
2609  * correction factor. */
2610  if (v->type == VEH_TRAIN) effect_offset += (VEHICLE_LENGTH - Train::From(v)->gcache.cached_veh_length) / 2;
2611 
2612  int x = _vehicle_smoke_pos[v->direction] * effect_offset;
2613  int y = _vehicle_smoke_pos[(v->direction + 2) % 8] * effect_offset;
2614 
2615  if (v->type == VEH_TRAIN && HasBit(Train::From(v)->flags, VRF_REVERSE_DIRECTION)) {
2616  x = -x;
2617  y = -y;
2618  }
2619 
2620  CreateEffectVehicleRel(v, x, y, 10, evt);
2621  }
2622  } while ((v = v->Next()) != NULL);
2623 
2624  if (sound) PlayVehicleSound(this, VSE_VISUAL_EFFECT);
2625 }
2626 
2632 {
2633  assert(this != next);
2634 
2635  if (this->next != NULL) {
2636  /* We had an old next vehicle. Update the first and previous pointers */
2637  for (Vehicle *v = this->next; v != NULL; v = v->Next()) {
2638  v->first = this->next;
2639  }
2640  this->next->previous = NULL;
2641  }
2642 
2643  this->next = next;
2644 
2645  if (this->next != NULL) {
2646  /* A new next vehicle. Update the first and previous pointers */
2647  if (this->next->previous != NULL) this->next->previous->next = NULL;
2648  this->next->previous = this;
2649  for (Vehicle *v = this->next; v != NULL; v = v->Next()) {
2650  v->first = this->first;
2651  }
2652  }
2653 }
2654 
2660 void Vehicle::AddToShared(Vehicle *shared_chain)
2661 {
2662  assert(this->previous_shared == NULL && this->next_shared == NULL);
2663 
2664  if (shared_chain->orders.list == NULL) {
2665  assert(shared_chain->previous_shared == NULL);
2666  assert(shared_chain->next_shared == NULL);
2667  this->orders.list = shared_chain->orders.list = new OrderList(NULL, shared_chain);
2668  }
2669 
2670  this->next_shared = shared_chain->next_shared;
2671  this->previous_shared = shared_chain;
2672 
2673  shared_chain->next_shared = this;
2674 
2675  if (this->next_shared != NULL) this->next_shared->previous_shared = this;
2676 
2677  shared_chain->orders.list->AddVehicle(this);
2678 }
2679 
2684 {
2685  /* Remember if we were first and the old window number before RemoveVehicle()
2686  * as this changes first if needed. */
2687  bool were_first = (this->FirstShared() == this);
2688  VehicleListIdentifier vli(VL_SHARED_ORDERS, this->type, this->owner, this->FirstShared()->index);
2689 
2690  this->orders.list->RemoveVehicle(this);
2691 
2692  if (!were_first) {
2693  /* We are not the first shared one, so only relink our previous one. */
2694  this->previous_shared->next_shared = this->NextShared();
2695  }
2696 
2697  if (this->next_shared != NULL) this->next_shared->previous_shared = this->previous_shared;
2698 
2699 
2700  if (this->orders.list->GetNumVehicles() == 1) {
2701  /* When there is only one vehicle, remove the shared order list window. */
2703  InvalidateVehicleOrder(this->FirstShared(), VIWD_MODIFY_ORDERS);
2704  } else if (were_first) {
2705  /* If we were the first one, update to the new first one.
2706  * Note: FirstShared() is already the new first */
2707  InvalidateWindowData(GetWindowClassForVehicleType(this->type), vli.Pack(), this->FirstShared()->index | (1U << 31));
2708  }
2709 
2710  this->next_shared = NULL;
2711  this->previous_shared = NULL;
2712 }
2713 
2714 void VehiclesYearlyLoop()
2715 {
2716  Vehicle *v;
2717  FOR_ALL_VEHICLES(v) {
2718  if (v->IsPrimaryVehicle()) {
2719  /* show warning if vehicle is not generating enough income last 2 years (corresponds to a red icon in the vehicle list) */
2720  Money profit = v->GetDisplayProfitThisYear();
2721  if (v->age >= 730 && profit < 0) {
2723  SetDParam(0, v->index);
2724  SetDParam(1, profit);
2725  AddVehicleAdviceNewsItem(STR_NEWS_VEHICLE_IS_UNPROFITABLE, v->index);
2726  }
2727  AI::NewEvent(v->owner, new ScriptEventVehicleUnprofitable(v->index));
2728  }
2729 
2731  v->profit_this_year = 0;
2733  }
2734  }
2740 }
2741 
2742 
2752 bool CanVehicleUseStation(EngineID engine_type, const Station *st)
2753 {
2754  const Engine *e = Engine::GetIfValid(engine_type);
2755  assert(e != NULL);
2756 
2757  switch (e->type) {
2758  case VEH_TRAIN:
2759  return (st->facilities & FACIL_TRAIN) != 0;
2760 
2761  case VEH_ROAD:
2762  /* For road vehicles we need the vehicle to know whether it can actually
2763  * use the station, but if it doesn't have facilities for RVs it is
2764  * certainly not possible that the station can be used. */
2765  return (st->facilities & (FACIL_BUS_STOP | FACIL_TRUCK_STOP)) != 0;
2766 
2767  case VEH_SHIP:
2768  return (st->facilities & FACIL_DOCK) != 0;
2769 
2770  case VEH_AIRCRAFT:
2771  return (st->facilities & FACIL_AIRPORT) != 0 &&
2773 
2774  default:
2775  return false;
2776  }
2777 }
2778 
2785 bool CanVehicleUseStation(const Vehicle *v, const Station *st)
2786 {
2787  if (v->type == VEH_ROAD) return st->GetPrimaryRoadStop(RoadVehicle::From(v)) != NULL;
2788 
2789  return CanVehicleUseStation(v->engine_type, st);
2790 }
2791 
2798 {
2799  assert(this->IsGroundVehicle());
2800  if (this->type == VEH_TRAIN) {
2801  return &Train::From(this)->gcache;
2802  } else {
2803  return &RoadVehicle::From(this)->gcache;
2804  }
2805 }
2806 
2813 {
2814  assert(this->IsGroundVehicle());
2815  if (this->type == VEH_TRAIN) {
2816  return &Train::From(this)->gcache;
2817  } else {
2818  return &RoadVehicle::From(this)->gcache;
2819  }
2820 }
2821 
2828 {
2829  assert(this->IsGroundVehicle());
2830  if (this->type == VEH_TRAIN) {
2831  return Train::From(this)->gv_flags;
2832  } else {
2833  return RoadVehicle::From(this)->gv_flags;
2834  }
2835 }
2836 
2842 const uint16 &Vehicle::GetGroundVehicleFlags() const
2843 {
2844  assert(this->IsGroundVehicle());
2845  if (this->type == VEH_TRAIN) {
2846  return Train::From(this)->gv_flags;
2847  } else {
2848  return RoadVehicle::From(this)->gv_flags;
2849  }
2850 }
2851 
2860 void GetVehicleSet(VehicleSet &set, Vehicle *v, uint8 num_vehicles)
2861 {
2862  if (v->type == VEH_TRAIN) {
2863  Train *u = Train::From(v);
2864  /* Only include whole vehicles, so start with the first articulated part */
2865  u = u->GetFirstEnginePart();
2866 
2867  /* Include num_vehicles vehicles, not counting articulated parts */
2868  for (; u != NULL && num_vehicles > 0; num_vehicles--) {
2869  do {
2870  /* Include current vehicle in the selection. */
2871  set.Include(u->index);
2872 
2873  /* If the vehicle is multiheaded, add the other part too. */
2874  if (u->IsMultiheaded()) set.Include(u->other_multiheaded_part->index);
2875 
2876  u = u->Next();
2877  } while (u != NULL && u->IsArticulatedPart());
2878  }
2879  }
2880 }
void ViewportAddVehicles(DrawPixelInfo *dpi)
Add the vehicle sprites that should be drawn at a part of the screen.
Definition: vehicle.cpp:1103
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:89
Road vehicle states.
bool HasVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
Checks whether a vehicle is on a specific location.
Definition: vehicle.cpp:512
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:324
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:600
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:589
Vehicle is stopped by the player.
Definition: vehicle_base.h:33
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:912
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:1195
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:1899
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:2481
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:78
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:3120
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:567
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:2204
Train is just leaving a station.
Definition: train.h:35
Don&#39;t cancel current goto depot command if any.
Definition: vehicle_type.h:70
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:538
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:252
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:83
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:260
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:868
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:76
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:32
Functions to be called to log possibly unsafe game events.
Both directions faces to the same direction.
uint16 _returned_refit_capacity
Stores the capacity after a refit operation.
Definition: vehicle.cpp:86
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:74
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:77
void IncrementImplicitOrderIndex()
Increments cur_implicit_order_index, keeps care of the wrap-around and invalidates the GUI...
Definition: vehicle_base.h:799
Trigger platform when train leaves.
void GetArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type, uint32 *union_mask, uint32 *intersection_mask)
Merges the refit_masks of all articulated parts.
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:1426
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:1876
void Draw(int x, int y, PaletteID default_pal, bool force_pal) const
Draw the sprite sequence.
Definition: vehicle.cpp:127
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:802
void LeaveStation()
Perform all actions when leaving a station.
Definition: vehicle.cpp:2152
DifficultySettings difficulty
settings related to the difficulty
TrackBitsByte state
The "track" the ship is following.
Definition: ship.h:25
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:1954
void SetNext(Vehicle *next)
Set the next vehicle of this vehicle.
Definition: vehicle.cpp:2631
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:1743
bool in_use
Set if this livery should be used instead of the default livery.
Definition: livery.h:77
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:1557
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:1925
void MarkTilesDirty(bool cargo_change) const
Marks the tiles of the station as dirty.
Definition: station.cpp:203
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:775
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:1786
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:785
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:1598
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:1714
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.
static Train * From(Vehicle *v)
Converts a Vehicle to SpecializedVehicle with type checking.
CompanySettings settings
settings specific for each company
Definition: company_base.h:121
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:252
const Engine * GetEngine() const
Retrieves the engine of the vehicle.
Definition: vehicle.cpp:743
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:121
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:362
Use default from engine class.
Definition: vehicle_base.h:85
FreeUnitIDGenerator(VehicleType type, CompanyID owner)
Initializes the structure.
Definition: vehicle.cpp:1674
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:67
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:312
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
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 #EffectVehicles/#TrainSubTypes/#AircraftSubTypes) ...
Definition: vehicle_base.h:327
void EndSpriteCombine()
Terminates a block of sprites started by StartSpriteCombine.
Definition: viewport.cpp:795
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:3238
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:2259
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:330
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:27
Map related accessors for depots.
static void SpawnAdvancedVisualEffect(const Vehicle *v)
Call CBID_VEHICLE_SPAWN_VISUAL_EFFECT and spawn requested effects.
Definition: vehicle.cpp:2426
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:202
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:434
static bool IsTileType(TileIndex tile, TileType type)
Checks if a tile is a give tiletype.
Definition: tile_map.h:143
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:1073
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:436
void MakeImplicit(StationID destination)
Makes this order an implicit order.
Definition: order_cmd.cpp:155
byte subtype
Type of aircraft.
Definition: engine_type.h:102
void AgeVehicle(Vehicle *v)
Update age of a vehicle.
Definition: vehicle.cpp:1320
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:788
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:129
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:453
bool NeedsServicing() const
Check if the vehicle needs to go to a depot in near future (if a opportunity presents itself) for ser...
Definition: vehicle.cpp:184
void MakeDummy()
Makes this order a Dummy order.
Definition: order_cmd.cpp:134
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:2797
VehicleType
Available vehicle types.
Definition: vehicle_type.h:21
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:1872
void HideFillingPercent(TextEffectID *te_id)
Hide vehicle loading indicators.
Definition: misc_gui.cpp:629
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
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:567
DoCommandFlag
List of flags for a command.
Definition: command_type.h:340
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:1247
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:1944
static const uint VEHICLE_LENGTH
The length of a vehicle in tile units.
Definition: vehicle_type.h:78
bool IsArticulatedPart() const
Check if the vehicle is an articulated part of an engine.
Definition: vehicle_base.h:891
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:894
Vehicle uses two company colours.
Definition: engine_type.h:155
void DeleteDepotHighlightOfVehicle(const Vehicle *v)
Removes the highlight of a vehicle in a depot window.
Definition: depot_gui.cpp:1112
void DeleteOrder(Vehicle *v, VehicleOrderID sel_ord)
Delete an order but skip the parameter validation.
Definition: order_cmd.cpp:1081
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:2660
Change colour mapping of vehicle.
Information about a particular livery.
Definition: livery.h:76
Effect vehicle type (smoke, explosions, sparks, bubbles)
Definition: vehicle_type.h:31
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:122
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:882
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:497
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:468
Money money
Money owned by the company.
Definition: company_base.h:64
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:2752
Steam model.
Definition: vehicle_base.h:100
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:26
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:25
Invalid cargo type.
Definition: cargo_type.h:70
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:77
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:595
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:79
UnitID curid
last ID returned; 0 if none
All ships have this type.
Definition: ship.h:24
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:688
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:79
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:26
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:39
&#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:710
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset)
Mark a tile given by its index dirty for repaint.
Definition: viewport.cpp:1904
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
#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:1137
VehicleEnterTileStatus VehicleEnterTile(Vehicle *v, TileIndex tile, int x, int y)
Call the tile callback function for a vehicle entering a tile.
Definition: vehicle.cpp:1662
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:2683
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:342
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:79
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:68
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:1608
void UpdatePosition()
Update the position of the vehicle.
Definition: vehicle.cpp:1547
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:1538
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:472
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:141
void VehicleServiceInDepot(Vehicle *v)
Service a vehicle and all subsequent vehicles in the consist.
Definition: vehicle.cpp:163
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:3134
CargoList that is used for vehicles.
Definition: cargopacket.h:283
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:1254
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:523
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:1569
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:552
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:1015
Functions related to depots.
void BeginLoading()
Prepare everything to begin the loading when arriving at a station.
Definition: vehicle.cpp:2005
Vehicle * Next() const
Get the next vehicle of this vehicle.
Definition: vehicle_base.h:582
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:953
void ShowNewGrfVehicleError(EngineID engine, StringID part1, StringID part2, GRFBugs bug_type, bool critical)
Displays a "NewGrf Bug" error message for a engine, and pauses the game if not networking.
Definition: vehicle.cpp:297
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:2860
void FindVehicleOnPosXY(int x, int y, void *data, VehicleFromPosProc *proc)
Find a vehicle from a specific location.
Definition: vehicle.cpp:437
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:410
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:1700
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.
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:541
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:1966
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:61
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:690
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:87
#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
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:1161
virtual void OnNewDay()
Calls the new day handler of the vehicle.
Definition: vehicle_base.h:534
bool HasEngineType() const
Check whether Vehicle::engine_type has any meaning.
Definition: vehicle.cpp:727
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:2827
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.
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:1367
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:763
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:2249
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:859
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:2279
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
Definition: settings_type.h:92
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:529
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:986
Map accessors for tunnels.
const GRFFile * GetGRF() const
Retrieve the NewGRF the vehicle is tied to.
Definition: vehicle.cpp:753
byte colour1
First colour, for all vehicles.
Definition: livery.h:78
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:554
Vehicle(VehicleType type=VEH_INVALID)
Vehicle constructor.
Definition: vehicle.cpp:345
VehicleEnterTileStatus
The returned bits of VehicleEnterTile.
Definition: tile_cmd.h:22
One direction is the opposite of the other one.
union Vehicle::@46 orders
The orders currently assigned to the vehicle.
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:3148
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:54
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:2214
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
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:633
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:1589
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:2358
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:3220
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:299
Dynamic data of a loaded NewGRF.
Definition: newgrf.h:104
Train vehicle type.
Definition: vehicle_type.h:24
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:2135
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