56 #include "table/strings.h" 
   60 #define GEN_HASH(x, y) ((GB((y), 6 + ZOOM_LVL_SHIFT, 6) << 6) + GB((x), 7 + ZOOM_LVL_SHIFT, 6)) 
   78   bounds->left = bounds->top = bounds->right = bounds->bottom = 0;
 
   79   for (uint i = 0; i < this->count; ++i) {
 
   82       bounds->left = spr->
x_offs;
 
   87       if (spr->
x_offs < bounds->left) bounds->left = spr->
x_offs;
 
   88       if (spr->
y_offs < bounds->top)  bounds->top  = spr->
y_offs;
 
   91       if (right  > bounds->right)  bounds->right  = right;
 
   92       if (bottom > bounds->bottom) bounds->bottom = bottom;
 
  106   for (uint i = 0; i < this->count; ++i) {
 
  107     PaletteID pal = force_pal || !this->seq[i].
pal ? default_pal : this->seq[i].
pal;
 
  169   if (this->ServiceIntervalIsPercent() ?
 
  185   bool pending_replace = 
false;
 
  187   if (needed_money > c->
money) 
return false;
 
  190     bool replace_when_old = 
false;
 
  196     if (replace_when_old && !v->NeedsAutorenewing(c, 
false)) 
continue;
 
  199     uint32 available_cargo_types, union_mask;
 
  202     if (union_mask != 0) {
 
  210         if (!
HasBit(available_cargo_types, cargo_type)) 
continue;
 
  216     pending_replace = 
true;
 
  217     needed_money += 2 * 
Engine::Get(new_engine)->GetCost();
 
  218     if (needed_money > c->
money) 
return false;
 
  221   return pending_replace;
 
  246   for (
Vehicle *v = 
this; v != NULL; v = v->
Next()) {
 
  250     v->MarkAllViewportsDirty();
 
  280   if (grfconfig == NULL) 
return;
 
  294   GetString(buffer, part1, 
lastof(buffer));
 
  295   DEBUG(grf, 0, 
"%s", buffer + 3);
 
  298   GetString(buffer, part2, 
lastof(buffer));
 
  299   DEBUG(grf, 0, 
"%s", buffer + 3);
 
  341   return GB(Random(), 0, 8);
 
  346 const int HASH_BITS = 7;
 
  347 const int HASH_SIZE = 1 << HASH_BITS;
 
  348 const int HASH_MASK = HASH_SIZE - 1;
 
  349 const int TOTAL_HASH_SIZE = 1 << (HASH_BITS * 2);
 
  350 const int TOTAL_HASH_MASK = TOTAL_HASH_SIZE - 1;
 
  354 const int HASH_RES = 0;
 
  356 static Vehicle *_vehicle_tile_hash[TOTAL_HASH_SIZE];
 
  358 static Vehicle *VehicleFromTileHash(
int xl, 
int yl, 
int xu, 
int yu, 
void *data, VehicleFromPosProc *proc, 
bool find_first)
 
  360   for (
int y = yl; ; y = (y + (1 << HASH_BITS)) & (HASH_MASK << HASH_BITS)) {
 
  361     for (
int x = xl; ; x = (x + 1) & HASH_MASK) {
 
  362       Vehicle *v = _vehicle_tile_hash[(x + y) & TOTAL_HASH_MASK];
 
  365         if (find_first && a != NULL) 
return a;
 
  389   const int COLL_DIST = 6;
 
  392   int xl = 
GB((x - COLL_DIST) / 
TILE_SIZE, HASH_RES, HASH_BITS);
 
  393   int xu = 
GB((x + COLL_DIST) / 
TILE_SIZE, HASH_RES, HASH_BITS);
 
  394   int yl = 
GB((y - COLL_DIST) / 
TILE_SIZE, HASH_RES, HASH_BITS) << HASH_BITS;
 
  395   int yu = 
GB((y + COLL_DIST) / 
TILE_SIZE, HASH_RES, HASH_BITS) << HASH_BITS;
 
  397   return VehicleFromTileHash(xl, yl, xu, yu, data, proc, find_first);
 
  447   int x = 
GB(
TileX(tile), HASH_RES, HASH_BITS);
 
  448   int y = 
GB(
TileY(tile), HASH_RES, HASH_BITS) << HASH_BITS;
 
  450   Vehicle *v = _vehicle_tile_hash[(x + y) & TOTAL_HASH_MASK];
 
  452     if (v->
tile != tile) 
continue;
 
  455     if (find_first && a != NULL) 
return a;
 
  505   if (v->
z_pos > z) 
return NULL;
 
  532   if (v == (
const Vehicle *)data) 
return NULL;
 
  564   if ((t->track != rail_bits) && !
TracksOverlap(t->track | rail_bits)) 
return NULL;
 
  588 static void UpdateVehicleTileHash(
Vehicle *v, 
bool remove)
 
  597     int y = 
GB(
TileY(v->
tile), HASH_RES, HASH_BITS) << HASH_BITS;
 
  598     new_hash = &_vehicle_tile_hash[(x + y) & TOTAL_HASH_MASK];
 
  601   if (old_hash == new_hash) 
return;
 
  604   if (old_hash != NULL) {
 
  610   if (new_hash != NULL) {
 
  621 static Vehicle *_vehicle_viewport_hash[0x1000];
 
  623 static void UpdateVehicleViewportHash(
Vehicle *v, 
int x, 
int y)
 
  625   Vehicle **old_hash, **new_hash;
 
  626   int old_x = v->
coord.left;
 
  627   int old_y = v->
coord.top;
 
  629   new_hash = (x == 
INVALID_COORD) ? NULL : &_vehicle_viewport_hash[GEN_HASH(x, y)];
 
  630   old_hash = (old_x == 
INVALID_COORD) ? NULL : &_vehicle_viewport_hash[GEN_HASH(old_x, old_y)];
 
  632   if (old_hash == new_hash) 
return;
 
  635   if (old_hash != NULL) {
 
  641   if (new_hash != NULL) {
 
  649 void ResetVehicleHash()
 
  653   memset(_vehicle_viewport_hash, 0, 
sizeof(_vehicle_viewport_hash));
 
  654   memset(_vehicle_tile_hash, 0, 
sizeof(_vehicle_tile_hash));
 
  657 void ResetVehicleColourMap()
 
  668 static AutoreplaceMap _vehicles_to_autoreplace;
 
  670 void InitializeVehicles()
 
  672   _vehicles_to_autoreplace.
Reset();
 
  676 uint CountVehiclesInChain(
const Vehicle *v)
 
  679   do count++; 
while ((v = v->
Next()) != NULL);
 
  689   switch (this->
type) {
 
  696     default: 
return false; 
 
  706   switch (this->
type) {
 
  711     default: 
return false;
 
  785     st->loading_vehicles.remove(
this);
 
  839   extern void StopGlobalFollowVehicle(
const Vehicle *v);
 
  840   StopGlobalFollowVehicle(
this);
 
  861   UpdateVehicleTileHash(
this, 
true);
 
  891   if (_game_mode != GM_NORMAL) 
return;
 
  896     if (v == NULL) 
continue;
 
  902         if (
HasBit(callback, 0)) {
 
  903           TriggerVehicle(v, VEHICLE_TRIGGER_CALLBACK_32); 
 
  919 void CallVehicleTicks()
 
  921   _vehicles_to_autoreplace.
Clear();
 
  947         if (v->vcache.cached_cargo_age_period != 0) {
 
  949           if (--v->cargo_age_counter == 0) {
 
  951             v->cargo_age_counter = v->vcache.cached_cargo_age_period;
 
  987         if (
GB(v->tick_counter, 0, 4) == 0) {
 
 1002     cur_company.Change(v->owner);
 
 1027     if (error_message == STR_ERROR_AUTOREPLACE_NOTHING_TO_DO || error_message == 
INVALID_STRING_ID) 
continue;
 
 1029     if (error_message == STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY) error_message = STR_ERROR_AUTOREPLACE_MONEY_LIMIT;
 
 1032     if (error_message == STR_ERROR_TRAIN_TOO_LONG_AFTER_REPLACEMENT) {
 
 1033       message = error_message;
 
 1035       message = STR_NEWS_VEHICLE_AUTORENEW_FAILED;
 
 1043   cur_company.Restore();
 
 1067   for (uint i = 0; i < v->
sprite_seq.count; ++i) {
 
 1083   const int l = dpi->left;
 
 1084   const int r = dpi->left + dpi->width;
 
 1085   const int t = dpi->top;
 
 1086   const int b = dpi->top + dpi->height;
 
 1091   if (dpi->width + (70 * ZOOM_LVL_BASE) < (1 << (7 + 6 + ZOOM_LVL_SHIFT))) {
 
 1092     xl = 
GB(l - (70 * ZOOM_LVL_BASE), 7 + ZOOM_LVL_SHIFT, 6);
 
 1093     xu = 
GB(r,                        7 + ZOOM_LVL_SHIFT, 6);
 
 1100   if (dpi->height + (70 * ZOOM_LVL_BASE) < (1 << (6 + 6 + ZOOM_LVL_SHIFT))) {
 
 1101     yl = 
GB(t - (70 * ZOOM_LVL_BASE), 6 + ZOOM_LVL_SHIFT, 6) << 6;
 
 1102     yu = 
GB(b,                        6 + ZOOM_LVL_SHIFT, 6) << 6;
 
 1109   for (
int y = yl;; y = (y + (1 << 6)) & (0x3F << 6)) {
 
 1110     for (
int x = xl;; x = (x + 1) & 0x3F) {
 
 1111       const Vehicle *v = _vehicle_viewport_hash[x + y]; 
 
 1115             l <= v->
coord.right &&
 
 1116             t <= v->
coord.bottom &&
 
 1117             r >= v->
coord.left &&
 
 1118             b >= v->
coord.top) {
 
 1141   uint dist, best_dist = UINT_MAX;
 
 1143   if ((uint)(x -= vp->
left) >= (uint)vp->
width || (uint)(y -= vp->
top) >= (uint)vp->
height) 
return NULL;
 
 1150         x >= v->coord.left && x <= v->coord.right &&
 
 1151         y >= v->coord.top && y <= v->coord.bottom) {
 
 1154         abs(((v->coord.left + v->coord.right) >> 1) - x),
 
 1155         abs(((v->coord.top + v->coord.bottom) >> 1) - y)
 
 1158       if (dist < best_dist) {
 
 1178 static const byte _breakdown_chance[64] = {
 
 1179     3,   3,   3,   3,   3,   3,   3,   3,
 
 1180     4,   4,   5,   5,   6,   6,   7,   7,
 
 1181     8,   8,   9,   9,  10,  10,  11,  11,
 
 1182    12,  13,  13,  13,  13,  14,  15,  16,
 
 1183    17,  19,  21,  25,  28,  31,  34,  37,
 
 1184    40,  44,  48,  52,  56,  60,  64,  68,
 
 1185    72,  80,  90, 100, 110, 120, 130, 140,
 
 1186   150, 170, 190, 210, 230, 250, 250, 250,
 
 1189 void CheckVehicleBreakdown(
Vehicle *v)
 
 1199       v->
cur_speed < 5 || _game_mode == GM_MENU) {
 
 1203   uint32 r = Random();
 
 1258             (train_or_ship ? SND_10_TRAIN_BREAKDOWN : SND_0F_VEHICLE_BREAKDOWN) :
 
 1259             (train_or_ship ? SND_3A_COMEDY_BREAKDOWN_2 : SND_35_COMEDY_BREAKDOWN), 
this);
 
 1322     str = STR_NEWS_VEHICLE_IS_GETTING_OLD;
 
 1323   } 
else if (age == 0) {
 
 1324     str = STR_NEWS_VEHICLE_IS_GETTING_VERY_OLD;
 
 1326     str = STR_NEWS_VEHICLE_IS_GETTING_VERY_OLD_AND;
 
 1350   bool loading = 
false;
 
 1356   assert(colour == NULL || (st != NULL && is_loading));
 
 1362   for (
const Vehicle *v = front; v != NULL; v = v->
Next()) {
 
 1365     if (v->
cargo_cap != 0 && colour != NULL) {
 
 1367       loading |= !order_no_load &&
 
 1374   if (colour != NULL) {
 
 1375     if (unloading == 0 && loading) {
 
 1376       *colour = STR_PERCENT_UP;
 
 1377     } 
else if (unloading == 0 && !loading) {
 
 1378       *colour = STR_PERCENT_NONE;
 
 1379     } 
else if (cars == unloading || !loading) {
 
 1380       *colour = STR_PERCENT_DOWN;
 
 1382       *colour = STR_PERCENT_UP_DOWN;
 
 1387   if (max == 0) 
return 100;
 
 1390   if (count * 2 < max) {
 
 1392     return CeilDiv(count * 100, max);
 
 1395     return (count * 100) / 
max;
 
 1406   assert(v == v->
First());
 
 1442     default: NOT_REACHED();
 
 1459   TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT);
 
 1482         _vehicles_to_autoreplace[v] = 
false;
 
 1488       } 
else if (cost.
GetCost() != 0) {
 
 1504       _vehicles_to_autoreplace[v] = 
false;
 
 1526   UpdateVehicleTileHash(
this, 
false);
 
 1540   new_coord.left   += pt.x;
 
 1541   new_coord.top    += pt.y;
 
 1542   new_coord.right  += pt.x + 2 * ZOOM_LVL_BASE;
 
 1543   new_coord.bottom += pt.y + 2 * ZOOM_LVL_BASE;
 
 1545   UpdateVehicleViewportHash(
this, new_coord.left, new_coord.top);
 
 1548   this->
coord = new_coord;
 
 1555           min(old_coord.left,   this->coord.left),
 
 1556           min(old_coord.top,    this->coord.top),
 
 1557           max(old_coord.right,  this->coord.right),
 
 1558           max(old_coord.bottom, this->coord.bottom));
 
 1587   static const int8 _delta_coord[16] = {
 
 1588     -1,-1,-1, 0, 1, 1, 1, 0, 
 
 1589     -1, 0, 1, 1, 1, 0,-1,-1, 
 
 1603 static const Direction _new_direction_table[] = {
 
 1613   if (y >= v->
y_pos) {
 
 1614     if (y != v->
y_pos) i += 3;
 
 1618   if (x >= v->
x_pos) {
 
 1619     if (x != v->
x_pos) i++;
 
 1656     if (v->
type == type && v->
owner == owner) {
 
 1661   if (this->
maxid == 0) 
return;
 
 1666   this->
cache = CallocT<bool>(this->
maxid + 2);
 
 1670     if (v->
type == type && v->
owner == owner) {
 
 1679   if (this->maxid <= this->
curid) 
return ++this->
curid;
 
 1681   while (this->
cache[++this->curid]) { } 
 
 1700     default: NOT_REACHED();
 
 1733     default: NOT_REACHED();
 
 1740     FOR_ALL_ENGINES_OF_TYPE(e, type) {
 
 1768     default: NOT_REACHED();
 
 1773         engine_type = parent_engine_type;
 
 1778       if (cargo_type == 
CT_INVALID) cargo_type = e->GetDefaultCargoType();
 
 1779       if (cargo_type == 
CT_INVALID) cargo_type = CT_GOODS; 
 
 1783             return LS_PASSENGER_WAGON_STEAM;
 
 1785             switch (RailVehInfo(parent_engine_type)->engclass) {
 
 1786               default: NOT_REACHED();
 
 1787               case EC_STEAM:    
return LS_PASSENGER_WAGON_STEAM;
 
 1788               case EC_DIESEL:   
return LS_PASSENGER_WAGON_DIESEL;
 
 1789               case EC_ELECTRIC: 
return LS_PASSENGER_WAGON_ELECTRIC;
 
 1790               case EC_MONORAIL: 
return LS_PASSENGER_WAGON_MONORAIL;
 
 1791               case EC_MAGLEV:   
return LS_PASSENGER_WAGON_MAGLEV;
 
 1795           return LS_FREIGHT_WAGON;
 
 1800         switch (e->u.rail.engclass) {
 
 1801           default: NOT_REACHED();
 
 1803           case EC_DIESEL:   
return is_mu ? LS_DMU : LS_DIESEL;
 
 1804           case EC_ELECTRIC: 
return is_mu ? LS_EMU : LS_ELECTRIC;
 
 1813         engine_type = parent_engine_type;
 
 1817       if (cargo_type == 
CT_INVALID) cargo_type = e->GetDefaultCargoType();
 
 1818       if (cargo_type == 
CT_INVALID) cargo_type = CT_GOODS; 
 
 1830       if (cargo_type == 
CT_INVALID) cargo_type = e->GetDefaultCargoType();
 
 1831       if (cargo_type == 
CT_INVALID) cargo_type = CT_GOODS; 
 
 1835       switch (e->u.air.subtype) {
 
 1836         case AIR_HELI: 
return LS_HELICOPTER;
 
 1837         case AIR_CTOL: 
return LS_SMALL_PLANE;
 
 1838         case AIR_CTOL | AIR_FAST: 
return LS_LARGE_PLANE;
 
 1839         default: NOT_REACHED();
 
 1865     if (!c->livery[scheme].
in_use) scheme = LS_DEFAULT;
 
 1868   return &c->livery[scheme];
 
 1877   if (map != PAL_NONE) 
return map;
 
 1886       assert_compile(PAL_NONE == 0); 
 
 1887       map = 
GB(callback, 0, 14);
 
 1890       if (!
HasBit(callback, 14)) {
 
 1892         if (v != NULL) 
const_cast<Vehicle *
>(v)->colourmap = map;
 
 1903   if (!
Company::IsValidID(company)) return map;
 
 1907   map += livery->colour1;
 
 1908   if (twocc) map += livery->colour2 * 16;
 
 1911   if (v != NULL) const_cast<
Vehicle *>(v)->colourmap = map;
 
 1923   return GetEngineColourMap(engine_type, company, 
INVALID_ENGINE, NULL);
 
 1957   while (order != NULL) {
 
 1960     if (order->
IsType(OT_IMPLICIT)) {
 
 1966       order = order->
next;
 
 1971     if (order == NULL) {
 
 2008         (in_list == NULL || !in_list->
IsType(OT_IMPLICIT) ||
 
 2013       if (prev_order == NULL ||
 
 2014           (!prev_order->
IsType(OT_IMPLICIT) && !prev_order->
IsType(OT_GOTO_STATION)) ||
 
 2026           if (order == NULL) 
break; 
 
 2032           if (target_index >= this->
orders.list->GetNumOrders()) {
 
 2043           if (suppress_implicit_orders) {
 
 2051               if (order->
IsType(OT_IMPLICIT)) {
 
 2057                 order = order->
next;
 
 2062               if (order == NULL) {
 
 2066               assert(order != NULL);
 
 2069         } 
else if (!suppress_implicit_orders &&
 
 2117       DEBUG(misc, 1, 
"cancelling cargo reservation");
 
 2134   assert(this->cargo_payment == NULL); 
 
 2160   st->loading_vehicles.remove(
this);
 
 2205       if (order == NULL ||
 
 2206           (!order->
IsType(OT_IMPLICIT) && !order->
IsType(OT_GOTO_STATION)) ||
 
 2213     case OT_DUMMY: 
break;
 
 2227   for (
const Vehicle *v = 
this; v != NULL; v = v->
Next()) {
 
 2230     if (pair == capacities.
End()) {
 
 2231       pair = capacities.
Append();
 
 2240 uint Vehicle::GetConsistTotalCapacity()
 const 
 2243   for (
const Vehicle *v = 
this; v != NULL; v = v->
Next()) {
 
 2258   if (ret.
Failed()) 
return ret;
 
 2295   DestinationID destination;
 
 2297   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};
 
 2355       callback = 
GB(callback, 0, 8);
 
 2362       visual_effect = callback;
 
 2394 static const int8 _vehicle_smoke_pos[8] = {
 
 2395   1, 1, 1, 0, -1, -1, -1, 0
 
 2407   uint count = 
GB(callback, 0, 2);
 
 2408   bool auto_center = 
HasBit(callback, 13);
 
 2409   bool auto_rotate = !
HasBit(callback, 14);
 
 2424   int8 x_center = _vehicle_smoke_pos[l_dir] * l_center;
 
 2425   int8 y_center = _vehicle_smoke_pos[t_dir] * l_center;
 
 2427   for (uint i = 0; i < count; i++) {
 
 2429     uint type = 
GB(reg,  0, 8);
 
 2430     int8 x    = 
GB(reg,  8, 8);
 
 2431     int8 y    = 
GB(reg, 16, 8);
 
 2432     int8 z    = 
GB(reg, 24, 8);
 
 2437       x = _vehicle_smoke_pos[l_dir] * l + _vehicle_smoke_pos[t_dir] * t;
 
 2438       y = _vehicle_smoke_pos[t_dir] * l - _vehicle_smoke_pos[l_dir] * t;
 
 2469       this->cur_speed < 2) {
 
 2482     if (
HasBit(t->flags, VRF_REVERSING) ||
 
 2498       if (effect_model >= VESM_END) effect_model = 
VESM_NONE; 
 
 2525     switch (effect_model) {
 
 2549         int power_weight_effect = 0;
 
 2577     if (evt != EV_END && advanced) {
 
 2580     } 
else if (evt != EV_END) {
 
 2588       int x = _vehicle_smoke_pos[v->
direction] * effect_offset;
 
 2589       int y = _vehicle_smoke_pos[(v->
direction + 2) % 8] * effect_offset;
 
 2598   } 
while ((v = v->
Next()) != NULL);
 
 2609   assert(
this != next);
 
 2611   if (this->next != NULL) {
 
 2613     for (
Vehicle *v = this->next; v != NULL; v = v->
Next()) {
 
 2621   if (this->next != NULL) {
 
 2625     for (
Vehicle *v = this->next; v != NULL; v = v->
Next()) {
 
 2666   this->
orders.list->RemoveVehicle(
this);
 
 2676   if (this->
orders.list->GetNumVehicles() == 1) {
 
 2680   } 
else if (were_first) {
 
 2690 void VehiclesYearlyLoop()
 
 2697       if (v->
age >= 730 && profit < 0) {
 
 2844     for (; u != NULL && num_vehicles > 0; num_vehicles--) {
 
 2847         set.Include(u->
index);