Change: make GetPartialZ consistent, meaning Z of adjacent slopes continue

Previously, on a straight line of a one corner up slope with the adjacent
steep sloop the Z would increase one step every two sub pixels, except for one
case where one sub pixel is skipped. Similarly, a steep slope with two
adjacent one corner up slopes, would have a bump in the height line along the
diagonal whenever it enters/leaves the steep slope tile.
This commit is contained in:
Rubidium
2023-02-25 23:58:46 +01:00
committed by rubidium42
parent 1fcd69096c
commit 9d2a0f3d0b
5 changed files with 120 additions and 122 deletions

View File

@@ -527,6 +527,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
@@ -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();