|
|
|
|
@@ -569,12 +569,12 @@ static uint FixVehicleInclination(Vehicle *v, Direction dir)
|
|
|
|
|
case INVALID_DIR: break;
|
|
|
|
|
default: NOT_REACHED();
|
|
|
|
|
}
|
|
|
|
|
byte entry_z = GetSlopePixelZ(entry_x, entry_y);
|
|
|
|
|
byte entry_z = GetSlopePixelZ(entry_x, entry_y, true);
|
|
|
|
|
|
|
|
|
|
/* Compute middle of the tile. */
|
|
|
|
|
int middle_x = (v->x_pos & ~TILE_UNIT_MASK) + TILE_SIZE / 2;
|
|
|
|
|
int middle_y = (v->y_pos & ~TILE_UNIT_MASK) + TILE_SIZE / 2;
|
|
|
|
|
byte middle_z = GetSlopePixelZ(middle_x, middle_y);
|
|
|
|
|
byte middle_z = GetSlopePixelZ(middle_x, middle_y, true);
|
|
|
|
|
|
|
|
|
|
/* middle_z == entry_z, no height change. */
|
|
|
|
|
if (middle_z == entry_z) return 0;
|
|
|
|
|
@@ -586,6 +586,25 @@ static uint FixVehicleInclination(Vehicle *v, Direction dir)
|
|
|
|
|
return 1U << GVF_GOINGUP_BIT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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
|
|
|
|
|
@@ -1440,7 +1459,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)) {
|
|
|
|
|
} else if (v->z_pos > GetTileMaxPixelZ(TileVirtXY(v->x_pos, v->y_pos))) {
|
|
|
|
|
v->tile = GetNorthernBridgeEnd(v->tile);
|
|
|
|
|
v->UpdatePosition();
|
|
|
|
|
} else {
|
|
|
|
|
@@ -2895,7 +2914,7 @@ bool AfterLoadGame()
|
|
|
|
|
if (!IsTunnelTile(vtile)) continue;
|
|
|
|
|
|
|
|
|
|
/* Are we actually in this tunnel? Or maybe a lower tunnel? */
|
|
|
|
|
if (GetSlopePixelZ(v->x_pos, v->y_pos) != v->z_pos) continue;
|
|
|
|
|
if (GetSlopePixelZ(v->x_pos, v->y_pos, true) != v->z_pos) continue;
|
|
|
|
|
|
|
|
|
|
/* What way are we going? */
|
|
|
|
|
const DiagDirection dir = GetTunnelBridgeDirection(vtile);
|
|
|
|
|
@@ -2974,6 +2993,23 @@ bool AfterLoadGame()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (IsSavegameVersionBefore(SLV_CONSISTENT_PARTIAL_Z) && SlXvIsFeatureMissing(XSLFI_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) {
|
|
|
|
|
@@ -3040,7 +3076,7 @@ bool AfterLoadGame()
|
|
|
|
|
/* In old versions, z_pos was 1 unit lower on bridge heads.
|
|
|
|
|
* However, this invalid state could be converted to new savegames
|
|
|
|
|
* by loading and saving the game in a new version. */
|
|
|
|
|
v->z_pos = GetSlopePixelZ(v->x_pos, v->y_pos);
|
|
|
|
|
v->z_pos = GetSlopePixelZ(v->x_pos, v->y_pos, true);
|
|
|
|
|
DiagDirection dir = GetTunnelBridgeDirection(v->tile);
|
|
|
|
|
if (v->type == VEH_TRAIN && !(v->vehstatus & VS_CRASHED) &&
|
|
|
|
|
v->direction != DiagDirToDir(dir)) {
|
|
|
|
|
@@ -3054,7 +3090,7 @@ bool AfterLoadGame()
|
|
|
|
|
|
|
|
|
|
/* If the vehicle is really above v->tile (not in a wormhole),
|
|
|
|
|
* it should have set v->z_pos correctly. */
|
|
|
|
|
assert(v->tile != TileVirtXY(v->x_pos, v->y_pos) || v->z_pos == GetSlopePixelZ(v->x_pos, v->y_pos));
|
|
|
|
|
assert(v->tile != TileVirtXY(v->x_pos, v->y_pos) || v->z_pos == GetSlopePixelZ(v->x_pos, v->y_pos, true));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Fill Vehicle::cur_real_order_index */
|
|
|
|
|
@@ -4209,6 +4245,14 @@ bool AfterLoadGame()
|
|
|
|
|
AfterLoad_LinkGraphPauseControl();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (SlXvIsFeatureMissing(XSLFI_CONSISTENT_PARTIAL_Z)) {
|
|
|
|
|
CheckGroundVehiclesAtCorrectZ();
|
|
|
|
|
} else {
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
CheckGroundVehiclesAtCorrectZ();
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_game_load_cur_date_ymd = _cur_date_ymd;
|
|
|
|
|
_game_load_date_fract = _date_fract;
|
|
|
|
|
_game_load_tick_skip_counter = _tick_skip_counter;
|
|
|
|
|
|