Index: src/train_cmd.cpp =================================================================== --- src/train_cmd.cpp (revision 21530) +++ src/train_cmd.cpp (working copy) @@ -2900,20 +2900,18 @@ { Train *first = v->First(); Train *prev; - bool direction_changed = false; // has direction of any part changed? - /* For every vehicle after and including the given vehicle */ + /* For every vehicle after and including the given vehicle. */ for (prev = v->Previous(); v != nomove; prev = v, v = v->Next()) { DiagDirection enterdir = DIAGDIR_BEGIN; - bool update_signals_crossing = false; // will we update signals or crossing state? GetNewVehiclePosResult gp = GetNewVehiclePos(v); if (v->track != TRACK_BIT_WORMHOLE) { - /* Not inside tunnel */ + /* Not inside tunnel. */ if (gp.old_tile == gp.new_tile) { /* Staying in the old tile */ if (v->track == TRACK_BIT_DEPOT) { - /* Inside depot */ + /* Inside depot. */ gp.x = v->x_pos; gp.y = v->y_pos; } else { @@ -2947,7 +2945,7 @@ } else { /* A new tile is about to be entered. */ - /* Determine what direction we're entering the new tile from */ + /* Determine what direction we're entering the new tile from. */ enterdir = DiagdirBetweenTiles(gp.old_tile, gp.new_tile); assert(IsValidDiagDirection(enterdir)); @@ -2983,21 +2981,22 @@ TrackBits bits = TrackdirBitsToTrackBits(trackdirbits); if (_settings_game.pf.forbid_90_deg && prev == NULL) { /* We allow wagons to make 90 deg turns, because forbid_90_deg - * can be switched on halfway a turn + * can be switched on halfway a turn. * Comming out of wormhole there are no 90 deg turns. */ if (v->track != TRACK_BIT_WORMHOLE) bits &= ~TrackCrossesTracks(FindFirstTrack(v->track)); } if (bits == TRACK_BIT_NONE) goto invalid_rail; - /* Check if the new tile constrains tracks that are compatible - * with the current train, if not, bail out. */ - if (!CheckCompatibleRail(v, gp.new_tile)) goto invalid_rail; - TrackBits chosen_track; if (prev == NULL) { - /* Currently the locomotive is active. Determine which one of the - * available tracks to choose */ + /* Currently the locomotive is active */ + + /* Check if the new tile constrains tracks that are compatible + * with the current train, if not, bail out. */ + if (!CheckCompatibleRail(v, gp.new_tile)) goto invalid_rail; + + /* Determine which one of the available tracks to choose */ chosen_track = TrackToTrackBits(ChooseTrainTrack(v, gp.new_tile, enterdir, bits, false, NULL, true)); assert(chosen_track & (bits | GetReservedTrackbits(gp.new_tile))); @@ -3056,17 +3055,10 @@ goto reverse_train_direction; } } else { - /* The wagon is active, simply follow the prev vehicle. */ + /* The wagon is active. */ if (prev->tile == gp.new_tile) { /* Choose the same track as prev */ - if (prev->track == TRACK_BIT_WORMHOLE) { - /* Vehicles entering tunnels enter the wormhole earlier than for bridges. - * However, just choose the track into the wormhole. */ - assert(IsTunnel(prev->tile)); - chosen_track = bits; - } else { - chosen_track = prev->track; - } + chosen_track = prev->track; } else { /* Choose the track that leads to the tile where prev is. * This case is active if 'prev' is already on the second next tile, when 'v' just enters the next tile. @@ -3088,19 +3080,19 @@ chosen_track &= bits; } - /* Make sure chosen track is a valid track */ + /* Make sure chosen track is a valid track. */ assert( chosen_track == TRACK_BIT_X || chosen_track == TRACK_BIT_Y || chosen_track == TRACK_BIT_UPPER || chosen_track == TRACK_BIT_LOWER || chosen_track == TRACK_BIT_LEFT || chosen_track == TRACK_BIT_RIGHT); - /* Update XY to reflect the entrance to the new tile, and select the direction to use */ + /* Update XY to reflect the entrance to the new tile, and select the direction to use. */ const byte *b = _initial_tile_subcoord[FIND_FIRST_BIT(chosen_track)][enterdir]; gp.x = (gp.x & ~0xF) | b[0]; gp.y = (gp.y & ~0xF) | b[1]; Direction chosen_dir = (Direction)b[2]; - /* Call the landscape function and tell it that the vehicle entered the tile */ + /* Call the landscape function and tell it that the vehicle entered the tile. */ uint32 r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y); if (HasBit(r, VETS_CANNOT_ENTER)) { goto invalid_rail; @@ -3117,23 +3109,18 @@ } } - /* Clear any track reservation when the last vehicle leaves the tile */ + /* Clear any track reservation when the last vehicle leaves the tile. */ if (v->Next() == NULL) ClearPathReservation(v, v->tile, v->GetVehicleTrackdir()); v->tile = gp.new_tile; + v->track = chosen_track; + assert(v->track); if (GetTileRailType(gp.new_tile) != GetTileRailType(gp.old_tile)) { v->First()->RailtypeChanged(); } - v->track = chosen_track; - assert(v->track); - - - /* We need to update signal status, but after the vehicle position hash - * has been updated by UpdateInclination() */ - update_signals_crossing = true; - + bool direction_changed = false; // Has direction of any part changed? if (chosen_dir != v->direction) { if (prev == NULL && _settings_game.vehicle.train_acceleration_model == AM_ORIGINAL) { const RailtypeSlowdownParams *rsp = &_railtype_slowdown[v->railtype]; @@ -3144,7 +3131,7 @@ v->direction = chosen_dir; } - if (v->IsFrontEngine()) { + if (prev == NULL) { v->wait_counter = 0; /* If we are approaching a crossing that is reserved, play the sound now. */ @@ -3156,9 +3143,49 @@ } if (HasBit(r, VETS_ENTERED_STATION)) { - /* The new position is the location where we want to stop */ + /* The new position is the location where we want to stop. */ TrainEnterStation(v, r >> VETS_STATION_ID_OFFSET); } + + /* Update image of train, as well as delta XY. */ + v->UpdateDeltaXY(v->direction); + + v->x_pos = gp.x; + v->y_pos = gp.y; + + /* Update the Z position of the vehicle. */ + byte old_z = v->UpdateInclination(true, false); + + if (prev == NULL) { + + if (HasBit(v->gv_flags, GVF_GOINGUP_BIT) || HasBit(v->gv_flags, GVF_GOINGDOWN_BIT)) { + AffectSpeedByZChange(v, old_z); + } + + if (TrainMovedChangeSignals(gp.new_tile, enterdir)) { + /* We are entering a block with PBS signals right now, but + * not through a PBS signal. This means we don't have a + * reservation right now. As a conventional signal will only + * ever be green if no other train is in the block, getting + * a path should always be possible. If the player built + * such a strange network that it is not possible, the train + * will be marked as stuck and the player has to deal with + * the problem. */ + if ((!HasReservedTracks(gp.new_tile, v->track) && + !TryReserveRailTrack(gp.new_tile, FindFirstTrack(v->track))) || + !TryPathReserve(v)) { + MarkTrainAsStuck(v); + } + } + } + /* Signals can only change when the first + * (above) or the last vehicle moves. */ + if (v->Next() == NULL) { + TrainMovedChangeSignals(gp.old_tile, ReverseDiagDir(enterdir)); + if (IsLevelCrossingTile(gp.old_tile)) UpdateLevelCrossing(gp.old_tile); + } + + if (direction_changed) first->tcache.cached_max_curve_speed = first->GetCurveSpeedLimit(); } } else { /* In a wormhole. */ @@ -3180,51 +3207,8 @@ continue; } } - - /* update image of train, as well as delta XY */ - v->UpdateDeltaXY(v->direction); - - v->x_pos = gp.x; - v->y_pos = gp.y; - - /* update the Z position of the vehicle */ - byte old_z = v->UpdateInclination(gp.new_tile != gp.old_tile, false); - - if (prev == NULL) { - /* This is the first vehicle in the train */ - AffectSpeedByZChange(v, old_z); - } - - if (update_signals_crossing) { - if (v->IsFrontEngine()) { - if (TrainMovedChangeSignals(gp.new_tile, enterdir)) { - /* We are entering a block with PBS signals right now, but - * not through a PBS signal. This means we don't have a - * reservation right now. As a conventional signal will only - * ever be green if no other train is in the block, getting - * a path should always be possible. If the player built - * such a strange network that it is not possible, the train - * will be marked as stuck and the player has to deal with - * the problem. */ - if ((!HasReservedTracks(gp.new_tile, v->track) && - !TryReserveRailTrack(gp.new_tile, FindFirstTrack(v->track))) || - !TryPathReserve(v)) { - MarkTrainAsStuck(v); - } - } - } - - /* Signals can only change when the first - * (above) or the last vehicle moves. */ - if (v->Next() == NULL) { - TrainMovedChangeSignals(gp.old_tile, ReverseDiagDir(enterdir)); - if (IsLevelCrossingTile(gp.old_tile)) UpdateLevelCrossing(gp.old_tile); - } - } } - if (direction_changed) first->tcache.cached_max_curve_speed = first->GetCurveSpeedLimit(); - return; invalid_rail: