diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -528,6 +528,25 @@ static uint FixVehicleInclination(Vehicl } /** + * Check whether the ground vehicles are at the correct Z-coordinate. When they + * are not, this will cause all kinds of problems later on as the vehicle might + * not get onto bridges and so on. + */ +static void CheckGroundVehiclesAtCorrectZ() +{ + for (Vehicle *v : Vehicle::Iterate()) { + if (v->IsGroundVehicle()) { + /* + * Either the vehicle is not actually on the given tile, i.e. it is + * in the wormhole of a bridge or a tunnel, or the Z-coordinate must + * be the same as when it would be recalculated right now. + */ + assert(v->tile != TileVirtXY(v->x_pos, v->y_pos) || v->z_pos == GetSlopePixelZ(v->x_pos, v->y_pos, true)); + } + } +} + +/** * Checks for the possibility that a bridge may be on this tile * These are in fact all the tile types on which a bridge can be found * @param t The tile to analyze @@ -1249,7 +1268,7 @@ bool AfterLoadGame() case DIAGDIR_SW: if ((v->x_pos & 0xF) != TILE_SIZE - 1) continue; break; case DIAGDIR_NW: if ((v->y_pos & 0xF) != 0) continue; break; } - } else if (v->z_pos > GetSlopePixelZ(v->x_pos, v->y_pos, true)) { + } else if (v->z_pos > GetTileMaxPixelZ(TileVirtXY(v->x_pos, v->y_pos))) { v->tile = GetNorthernBridgeEnd(v->tile); v->UpdatePosition(); } else { @@ -2594,6 +2613,24 @@ bool AfterLoadGame() } } + + if (IsSavegameVersionBefore(SLV_CONSISTENT_PARTIAL_Z)) { + /* + * The logic of GetPartialPixelZ has been changed, so the resulting Zs on + * the map are consistent. This requires that the Z position of some + * vehicles is updated to reflect this new situation. + * + * This needs to be before SLV_158, because that performs asserts using + * GetSlopePixelZ which internally uses GetPartialPixelZ. + */ + for (Vehicle *v : Vehicle::Iterate()) { + if (v->IsGroundVehicle() && TileVirtXY(v->x_pos, v->y_pos) == v->tile) { + /* Vehicle is on the ground, and not in a wormhole. */ + v->z_pos = GetSlopePixelZ(v->x_pos, v->y_pos, true); + } + } + } + if (IsSavegameVersionBefore(SLV_158)) { for (Vehicle *v : Vehicle::Iterate()) { switch (v->type) { @@ -3228,6 +3265,8 @@ bool AfterLoadGame() AfterLoadLinkGraphs(); + CheckGroundVehiclesAtCorrectZ(); + /* Start the scripts. This MUST happen after everything else except * starting a new company. */ StartScripts();