Merge branch 'master' into jgrpp

# Conflicts:
#	src/elrail.cpp
#	src/ground_vehicle.hpp
#	src/landscape.cpp
#	src/saveload/afterload.cpp
#	src/saveload/saveload.h
#	src/tile_cmd.h
#	src/town_cmd.cpp
#	src/tunnelbridge_cmd.cpp
This commit is contained in:
Jonathan G Rennison
2023-04-12 19:34:11 +01:00
31 changed files with 775 additions and 179 deletions

View File

@@ -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;