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