39 #include "table/strings.h" 
   51 static const byte _vehicle_initial_x_fract[4] = {10, 8, 4,  8};
 
   52 static const byte _vehicle_initial_y_fract[4] = { 8, 4, 8, 10};
 
   55 bool IsValidImageIndex<VEH_TRAIN>(uint8 image_index)
 
   57   return image_index < 
lengthof(_engine_sprite_base);
 
   74   if (!
HasBit(direction, 0) && track != state_dir_table[diagdir]) {
 
  101       for (
const Train *u = v, *w = v->
Next(); w != NULL; u = w, w = w->
Next()) {
 
  104               max(
abs(u->x_pos - w->x_pos), 
abs(u->y_pos - w->y_pos)) != u->CalcNextVehicleOffset()) ||
 
  131   uint16 max_speed = UINT16_MAX;
 
  140   bool train_can_tilt = 
true;
 
  142   for (
Train *u = 
this; u != NULL; u = u->
Next()) {
 
  146     assert(u->First() == 
this);
 
  149     u->gcache.first_engine = 
this == u ? 
INVALID_ENGINE : first_engine;
 
  150     u->railtype = rvi_u->railtype;
 
  152     if (u->IsEngine()) first_engine = u->engine_type;
 
  156     this->InvalidateNewGRFCache();
 
  157     u->InvalidateNewGRFCache();
 
  160   for (
Train *u = 
this; u != NULL; u = u->
Next()) {
 
  164     u->InvalidateNewGRFCache();
 
  167   for (
Train *u = 
this; u != NULL; u = u->
Next()) {
 
  168     const Engine *e_u = u->GetEngine();
 
  174     u->tcache.cached_override = GetWagonOverrideSpriteSet(u->engine_type, u->cargo_type, u->gcache.first_engine);
 
  177     u->colourmap = PAL_NONE;
 
  180     u->UpdateVisualEffect(
true);
 
  190     if (!u->IsArticulatedPart()) {
 
  193       if (rvi_u->
power > 0) {
 
  207         if (speed != 0) max_speed = 
min(speed, max_speed);
 
  214       if (u->cargo_cap > new_cap) u->cargo.Truncate(new_cap);
 
  215       u->refit_cap = 
min(new_cap, u->refit_cap);
 
  216       u->cargo_cap = new_cap;
 
  225     if (e_u->
GetGRF() != NULL && e_u->
GetGRF()->grf_version >= 8) {
 
  241       u->gcache.cached_veh_length = veh_len;
 
  249     u->InvalidateNewGRFCache();
 
  298     default: NOT_REACHED();
 
  309       stop = *station_length;
 
  325   assert(this->
First() == 
this);
 
  327   static const int absolute_max_speed = UINT16_MAX;
 
  328   int max_speed = absolute_max_speed;
 
  332   int curvecount[2] = {0, 0};
 
  339   for (
const Vehicle *u = 
this; u->
Next() != NULL; u = u->
Next(), pos++) {
 
  341     Direction next_dir = u->Next()->direction;
 
  351         sum += pos - lastpos;
 
  352         if (pos - lastpos == 1 && max_speed > 88) {
 
  365   if (numcurve > 0 && max_speed > 88) {
 
  366     if (curvecount[0] == 1 && curvecount[1] == 1) {
 
  367       max_speed = absolute_max_speed;
 
  370       max_speed = 232 - (13 - 
Clamp(sum, 1, 12)) * (13 - 
Clamp(sum, 1, 12));
 
  374   if (max_speed != absolute_max_speed) {
 
  381       max_speed += max_speed / 5;
 
  407       int distance_to_go = station_ahead / 
TILE_SIZE - (station_length - stop_at) / 
TILE_SIZE;
 
  409       if (distance_to_go > 0) {
 
  410         int st_max_speed = 120;
 
  412         int delta_v = this->
cur_speed / (distance_to_go + 1);
 
  413         if (max_speed > (this->
cur_speed - delta_v)) {
 
  414           st_max_speed = this->
cur_speed - (delta_v / 10);
 
  417         st_max_speed = 
max(st_max_speed, 25 * distance_to_go);
 
  418         max_speed = 
min(max_speed, st_max_speed);
 
  423   for (
const Train *u = 
this; u != NULL; u = u->
Next()) {
 
  425       max_speed = 
min(max_speed, 61);
 
  457   int reference_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
 
  458   int vehicle_pitch = 0;
 
  461   if (e->
GetGRF() != NULL && is_custom_sprite(e->u.rail.image_index)) {
 
  466   if (offset != NULL) {
 
  475   assert(IsValidImageIndex<VEH_TRAIN>(spritenum));
 
  476   return ((direction + _engine_sprite_add[spritenum]) & _engine_sprite_and[spritenum]) + _engine_sprite_base[
spritenum];
 
  491   if (is_custom_sprite(spritenum)) {
 
  492     GetCustomVehicleSprite(
this, (
Direction)(direction + 4 * IS_CUSTOM_SECONDHEAD_SPRITE(spritenum)), image_type, result);
 
  498   assert(IsValidImageIndex<VEH_TRAIN>(spritenum));
 
  499   SpriteID sprite = GetDefaultTrainSprite(spritenum, direction);
 
  510   uint8 spritenum = e->u.rail.image_index;
 
  512   if (is_custom_sprite(spritenum)) {
 
  513     GetCustomVehicleIcon(engine, dir, image_type, result);
 
  515       if (e->
GetGRF() != NULL) {
 
  521     spritenum = 
Engine::Get(engine)->original_image_index;
 
  524   if (rear_head) spritenum++;
 
  526   result->
Set(GetDefaultTrainSprite(spritenum, 
DIR_W));
 
  536     GetRailIcon(engine, 
false, yf, image_type, &seqf);
 
  537     GetRailIcon(engine, 
true, yr, image_type, &seqr);
 
  543     preferred_x = 
Clamp(preferred_x,
 
  551     GetRailIcon(engine, 
false, y, image_type, &seq);
 
  555     preferred_x = 
Clamp(preferred_x,
 
  577   GetRailIcon(engine, 
false, y, image_type, &seq);
 
  582   width  = 
UnScaleGUI(rect.right - rect.left + 1);
 
  583   height = 
UnScaleGUI(rect.bottom - rect.top + 1);
 
  588     GetRailIcon(engine, 
true, y, image_type, &seq);
 
  593     height = max<uint>(height, 
UnScaleGUI(rect.bottom - rect.top + 1));
 
  594     xoffs  = xoffs - 
ScaleGUITrad(TRAININFO_DEFAULT_VEHICLE_WIDTH) / 2;
 
  632     v->
z_pos = GetSlopePixelZ(x, y);
 
  646     v->railtype = rvi->railtype;
 
  657     _new_vehicle_id = v->
index;
 
  668       if (w->
tile == tile &&              
 
  696 static void AddRearEngineToMultiheadedTrain(
Train *v)
 
  714   u->railtype = v->railtype;
 
  726   v->other_multiheaded_part = u;
 
  727   u->other_multiheaded_part = v;
 
  761     v->
z_pos = GetSlopePixelZ(x, y);
 
  778     v->railtype = rvi->railtype;
 
  779     _new_vehicle_id = v->
index;
 
  798       AddRearEngineToMultiheadedTrain(v);
 
  816 static Train *FindGoodVehiclePos(
const Train *src)
 
  822   FOR_ALL_TRAINS(dst) {
 
  828         if (t == NULL) 
return dst;
 
  846   for (; t != NULL; t = t->
Next()) *list.
Append() = t;
 
  856   if (list.
Length() == 0) 
return;
 
  860   for (
Train **iter = list.
Begin(); iter != list.
End(); iter++) {
 
  917     if (u == t->other_multiheaded_part) 
continue;
 
  933   if (chain == NULL) 
return;
 
  967   if ((src          != NULL && src->
IsEngine()          ? 1 : 0) +
 
  968       (dst          != NULL && dst->
IsEngine()          ? 1 : 0) -
 
  969       (original_src != NULL && original_src->
IsEngine() ? 1 : 0) -
 
  970       (original_dst != NULL && original_dst->
IsEngine() ? 1 : 0) <= 0) {
 
 1037         if (head->
GetGRF()->grf_version < 8) {
 
 1038           if (callback == 0xFD) error = STR_ERROR_INCOMPATIBLE_RAIL_TYPES;
 
 1042           if (callback < 0x400) {
 
 1052                 error = STR_ERROR_INCOMPATIBLE_RAIL_TYPES;
 
 1086   if (ret.
Failed()) 
return ret;
 
 1088   if (ret.
Failed()) 
return ret;
 
 1105   if (*src_head == *dst_head) {
 
 1109   } 
else if (*dst_head == NULL) {
 
 1115   if (src == *src_head) {
 
 1122     *src_head = move_chain ? NULL :
 
 1146   if (head == NULL) 
return;
 
 1180   bool move_chain = 
HasBit(p1, 20);
 
 1186   if (ret.
Failed()) 
return ret;
 
 1194     dst = src->
IsEngine() ? NULL : FindGoodVehiclePos(src);
 
 1200     if (ret.
Failed()) 
return ret;
 
 1219     dst_head = dst->
First();
 
 1230   if (move_chain && src_head == dst_head) 
return CommandCost();
 
 1243   TrainList original_src;
 
 1244   TrainList original_dst;
 
 1252   Train *original_src_head = src_head;
 
 1253   Train *original_dst_head = (dst_head == src_head ? NULL : dst_head);
 
 1258   bool original_src_head_front_engine = original_src_head->
IsFrontEngine();
 
 1259   bool original_dst_head_front_engine = original_dst_head != NULL && original_dst_head->
IsFrontEngine();
 
 1326     if (original_src_head != src && dst_head == src) {
 
 1373   bool sell_chain = 
HasBit(data, 0);
 
 1387   Train *sell_head = NULL;
 
 1457     static const int _sign_table[] =
 
 1470     this->
y_offs -= half_shorten * _sign_table[direction + 1];
 
 1474     switch (direction) {
 
 1539   uint16 flag1 = *swap_flag1;
 
 1540   uint16 flag2 = *swap_flag2;
 
 1607   for (a = v; l != 0; l--) a = a->
Next();
 
 1608   for (b = v; r != 0; r--) b = b->
Next();
 
 1618     Swap(a->track, b->track);
 
 1707     if (new_state && sound) {
 
 1741   uint length = CountVehiclesInChain(v);
 
 1743   while (length > 2) {
 
 1745     first = first->
Next();
 
 1774   if (leave != NULL) {
 
 1790   uint length = CountVehiclesInChain(v);
 
 1794   bool nomove = (dep == NULL); 
 
 1796   while (length > 2) {
 
 1799     if (base == dep) 
break;
 
 1802     if (last == dep) nomove = 
true;
 
 1805     first = first->
Next();
 
 1810     for (
int i = 0; i < differential; i++) 
TrainController(first, (nomove ? last->
Next() : NULL));
 
 1834   int r = CountVehiclesInChain(v) - 1;  
 
 1852   ClrBit(v->flags, VRF_REVERSING);
 
 1920   if (ret.
Failed()) 
return ret;
 
 1926       return_cmd_error(STR_ERROR_CAN_T_REVERSE_DIRECTION_RAIL_VEHICLE_MULTIPLE_UNITS);
 
 1953         while (last->
Next() != NULL) last = last->
Next();
 
 1995   if (ret.
Failed()) 
return ret;
 
 2031     default: NOT_REACHED();
 
 2047   if (location    != NULL) *location    = tfdd.
tile;
 
 2049   if (reverse     != NULL) *reverse     = tfdd.
reverse;
 
 2057   static const SoundFx sfx[] = {
 
 2068   SndPlayVehicleFx(sfx[RailVehInfo(engtype)->engclass], 
this);
 
 2089     case OT_GOTO_WAYPOINT:
 
 2095     case OT_LEAVESTATION:
 
 2140   for (
const Train *u = v; u != NULL; u = u->
Next()) {
 
 2153   if (v->force_proceed == 
TFP_NONE) {
 
 2273     for (
const Train *u = v; u != NULL; u = u->
Next()) {
 
 2281   while (ft.
Follow(tile, td)) {
 
 2316 static const byte _initial_tile_subcoord[6][4][3] = {
 
 2317 {{ 15, 8, 1 }, { 0, 0, 0 }, { 0, 8, 5 }, { 0,  0, 0 }},
 
 2318 {{  0, 0, 0 }, { 8, 0, 3 }, { 0, 0, 0 }, { 8, 15, 7 }},
 
 2319 {{  0, 0, 0 }, { 7, 0, 2 }, { 0, 7, 6 }, { 0,  0, 0 }},
 
 2320 {{ 15, 8, 2 }, { 0, 0, 0 }, { 0, 0, 0 }, { 8, 15, 6 }},
 
 2321 {{ 15, 7, 0 }, { 8, 0, 4 }, { 0, 0, 0 }, { 0,  0, 0 }},
 
 2322 {{  0, 0, 0 }, { 0, 0, 0 }, { 0, 8, 4 }, { 7, 15, 0 }},
 
 2343     default: NOT_REACHED();
 
 2360   while (ft.
Follow(tile, cur_td)) {
 
 2388       if (enterdir != NULL) *enterdir = ft.
m_exitdir;
 
 2405   if (ft.m_err == CFollowTrackRail::EC_OWNER || ft.m_err == CFollowTrackRail::EC_NO_WAY) {
 
 2415   while (tile != stopped || cur_td != stopped_td) {
 
 2416     if (!ft.
Follow(tile, cur_td)) 
break;
 
 2450     default: NOT_REACHED();
 
 2460   StationID      old_last_station_visited;
 
 2462   bool           suppress_implicit_orders;
 
 2478     this->v->
dest_tile = this->old_dest_tile;
 
 2492     if (skip_first) ++this->index;
 
 2498       if (this->index >= this->v->
GetNumOrders()) this->index = 0;
 
 2501       assert(order != NULL);
 
 2507         case OT_GOTO_STATION:
 
 2508         case OT_GOTO_WAYPOINT:
 
 2511         case OT_CONDITIONAL: {
 
 2539   bool changed_signal = 
false;
 
 2543   if (got_reservation != NULL) *got_reservation = 
false;
 
 2555       do_track_reservation = 
true;
 
 2556       changed_signal = 
true;
 
 2558     } 
else if (!do_track_reservation) {
 
 2566   if (do_track_reservation) {
 
 2574     if (res_dest.okay) {
 
 2576       if (got_reservation != NULL) *got_reservation = 
true;
 
 2599     orders.SwitchToNextOrder(
false);
 
 2603       v->tile == v->dest_tile))) {
 
 2604     orders.SwitchToNextOrder(
true);
 
 2609     bool      path_found = 
true;
 
 2612     Track next_track = 
DoTrainPathfind(v, new_tile, dest_enterdir, tracks, path_found, do_track_reservation, &res_dest);
 
 2613     if (new_tile == tile) best_track = next_track;
 
 2618   if (!do_track_reservation) 
return best_track;
 
 2635       if (got_reservation != NULL) *got_reservation = 
true;
 
 2644   if (got_reservation != NULL) *got_reservation = 
true;
 
 2657     if (orders.SwitchToNextOrder(
true)) {
 
 2660       DoTrainPathfind(v, next_tile, exitdir, reachable, path_found, 
true, &cur_dest);
 
 2662         res_dest = cur_dest;
 
 2663         if (res_dest.okay) 
continue;
 
 2667         if (got_reservation != NULL) *got_reservation = 
false;
 
 2668         changed_signal = 
false;
 
 2676       if (got_reservation != NULL) *got_reservation = 
false;
 
 2677       changed_signal = 
false;
 
 2722   if (other_train != NULL && other_train->
index != v->
index) {
 
 2727   if (origin.
okay && (v->
tile != origin.
tile || first_tile_okay)) {
 
 2746   bool res_made = 
false;
 
 2747   ChooseTrainTrack(v, new_tile, exitdir, reachable, 
true, &res_made, mark_as_stuck);
 
 2764 static bool CheckReverseTrain(
const Train *v)
 
 2778     default: NOT_REACHED();
 
 2808   } 
while ((v = v->
Next()) != NULL);
 
 2825     default: NOT_REACHED();
 
 2845   if (!(st->had_vehicle_of_type & 
HVOT_TRAIN)) {
 
 2849       STR_NEWS_FIRST_TRAIN_ARRIVAL,
 
 2868 static inline bool CheckCompatibleRail(
const Train *v, 
TileIndex tile)
 
 2885   {256 / 4, 256 / 2, 256 / 4, 2}, 
 
 2886   {256 / 4, 256 / 2, 256 / 4, 2}, 
 
 2887   {0,       256 / 2, 256 / 4, 2}, 
 
 2901   if (old_z < v->z_pos) {
 
 2905     if (spd <= v->gcache.cached_max_track_speed) v->
cur_speed = spd;
 
 2917       if (!IsPbsSignal(GetSignalType(tile, 
TrackdirToTrack(trackdir)))) 
return true;
 
 2926   for (
const Train *u = 
this; u != NULL; u = u->
Next()) {
 
 2955     for (
const Train *v = 
this; v != NULL; v = v->
Next()) {
 
 3029   if (coll == tcc->
v) 
return NULL;
 
 3038   uint hash = (y_diff + 7) | (x_diff + 7);
 
 3039   if (hash & ~15) 
return NULL;
 
 3043   if (x_diff * x_diff + y_diff * y_diff > min_diff * min_diff) 
return NULL;
 
 3082   if (tcc.
num == 0) 
return false;
 
 3087   ModifyStationRatingAround(v->
tile, v->
owner, -160, 30);
 
 3118   bool direction_changed = 
false; 
 
 3121   for (prev = v->
Previous(); v != nomove; prev = v, v = v->
Next()) {
 
 3123     bool update_signals_crossing = 
false; 
 
 3175         if (!CheckCompatibleRail(v, gp.
new_tile)) 
goto invalid_rail;
 
 3201           if ((red_signals & chosen_track) && v->force_proceed == 
TFP_NONE) {
 
 3211               v->progress = 255 - 100;
 
 3216               v->progress = 255 - 10;
 
 3224                 if (!
HasVehicleOnPos(o_tile, &exitdir, &CheckTrainAtSignal)) 
return false;
 
 3234               v->wait_counter = 0;
 
 3237             goto reverse_train_direction;
 
 3249               chosen_track = bits;
 
 3251               chosen_track = prev->track;
 
 3269             chosen_track = _connecting_track[enterdir][exitdir];
 
 3271           chosen_track &= bits;
 
 3281         const byte *b = _initial_tile_subcoord[
FIND_FIRST_BIT(chosen_track)][enterdir];
 
 3282         gp.x = (gp.x & ~0xF) | b[0];
 
 3283         gp.
y = (gp.
y & ~0xF) | b[1];
 
 3309           v->track = chosen_track;
 
 3315         update_signals_crossing = 
true;
 
 3317         if (chosen_dir != v->direction) {
 
 3323           direction_changed = 
true;
 
 3324           v->direction = chosen_dir;
 
 3327         if (v->IsFrontEngine()) {
 
 3328           v->wait_counter = 0;
 
 3346         if (v->IsFrontEngine()) {
 
 3358         v->UpdatePosition();
 
 3359         if ((v->vehstatus & 
VS_HIDDEN) == 0) v->Vehicle::UpdateViewport(
true);
 
 3365     v->UpdateDeltaXY(v->direction);
 
 3369     v->UpdatePosition();
 
 3379     if (update_signals_crossing) {
 
 3380       if (v->IsFrontEngine()) {
 
 3381         if (TrainMovedChangeSignals(gp.
new_tile, enterdir)) {
 
 3400       if (v->Next() == NULL) {
 
 3416   if (prev != NULL) 
error(
"Disconnecting train");
 
 3418 reverse_train_direction:
 
 3420     v->wait_counter = 0;
 
 3445       *trackbits |= train_tbits;
 
 3467   for (; v->
Next() != NULL; v = v->
Next()) u = v;
 
 3525   static const DirDiff delta[] = {
 
 3543   } 
while ((v = v->
Next()) != NULL);
 
 3560   if (state <= 200 && 
Chance16R(1, 7, r)) {
 
 3561     int index = (r * 10 >> 16);
 
 3575     } 
while ((u = u->
Next()) != NULL);
 
 3581     bool ret = v->
Next() != NULL;
 
 3591   225, 210, 195, 180, 165, 150, 135, 120, 105, 90, 75, 60, 45, 30, 15, 15
 
 3606   uint x = v->
x_pos & 0xF;
 
 3607   uint y = v->
y_pos & 0xF;
 
 3612     case DIR_N : x = ~x + ~y + 25; 
break;
 
 3614     case DIR_NE: x = ~x + 16;      
break;
 
 3615     case DIR_E : x = ~x + y + 9;   
break;
 
 3616     case DIR_SE: x = y;            
break;
 
 3617     case DIR_S : x = x + y - 7;    
break;
 
 3618     case DIR_W : x = ~y + x + 9;   
break;
 
 3636   uint16 break_speed = _breakdown_speeds[x & 0xF];
 
 3637   if (break_speed < v->cur_speed) v->
cur_speed = break_speed;
 
 3690       !CheckCompatibleRail(v, tile)) {
 
 3713     uint16 break_speed = _breakdown_speeds[
GB(~t, 4, 4)];
 
 3714     if (break_speed < v->cur_speed) v->
cur_speed = break_speed;
 
 3756 static bool TrainLocoHandler(
Train *v, 
bool mode)
 
 3763   if (v->force_proceed != 
TFP_NONE) {
 
 3833       if (v->force_proceed == 
TFP_NONE) 
return true;
 
 3871       if (j < adv_spd || v->cur_speed == 0) 
break;
 
 3875       if ((order_type == OT_GOTO_WAYPOINT || order_type == OT_GOTO_STATION) &&
 
 3885   for (
Train *u = v; u != NULL; u = u->
Next()) {
 
 3903   const Train *v = 
this;
 
 3907     if (e->u.rail.running_cost_class == INVALID_PRICE) 
continue;
 
 3910     if (cost_factor == 0) 
continue;
 
 3915     cost += 
GetPrice(e->u.rail.running_cost_class, cost_factor, e->
GetGRF());
 
 3934     if (!TrainLocoHandler(
this, 
false)) 
return false;
 
 3936     return TrainLocoHandler(
this, 
true);
 
 3964     default: NOT_REACHED();
 
 4002     CheckVehicleBreakdown(
this);