mirror of https://github.com/OpenTTD/OpenTTD
Change: Make ships stop in locks to move up/down instead of following the slope.
parent
8e7fe3973f
commit
0b10678050
|
@ -55,6 +55,7 @@
|
||||||
#include "../order_backup.h"
|
#include "../order_backup.h"
|
||||||
#include "../error.h"
|
#include "../error.h"
|
||||||
#include "../disaster_vehicle.h"
|
#include "../disaster_vehicle.h"
|
||||||
|
#include "../ship.h"
|
||||||
|
|
||||||
|
|
||||||
#include "saveload_internal.h"
|
#include "saveload_internal.h"
|
||||||
|
@ -3045,6 +3046,42 @@ bool AfterLoadGame()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsSavegameVersionBefore(SLV_SHIPS_STOP_IN_LOCKS)) {
|
||||||
|
/* Move ships from lock slope to upper or lower position. */
|
||||||
|
Ship *s;
|
||||||
|
FOR_ALL_SHIPS(s) {
|
||||||
|
/* Suitable tile? */
|
||||||
|
if (!IsTileType(s->tile, MP_WATER) || !IsLock(s->tile) || GetLockPart(s->tile) != LOCK_PART_MIDDLE) continue;
|
||||||
|
|
||||||
|
/* We don't need to adjust position when at the tile centre */
|
||||||
|
int x = s->x_pos & 0xF;
|
||||||
|
int y = s->y_pos & 0xF;
|
||||||
|
if (x == 8 && y == 8) continue;
|
||||||
|
|
||||||
|
/* Test if ship is on the second half of the tile */
|
||||||
|
bool second_half;
|
||||||
|
DiagDirection shipdiagdir = DirToDiagDir(s->direction);
|
||||||
|
switch (shipdiagdir) {
|
||||||
|
default: NOT_REACHED();
|
||||||
|
case DIAGDIR_NE: second_half = x < 8; break;
|
||||||
|
case DIAGDIR_NW: second_half = y < 8; break;
|
||||||
|
case DIAGDIR_SW: second_half = x > 8; break;
|
||||||
|
case DIAGDIR_SE: second_half = y > 8; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
DiagDirection slopediagdir = GetInclinedSlopeDirection(GetTileSlope(s->tile));
|
||||||
|
|
||||||
|
/* Heading up slope == passed half way */
|
||||||
|
if ((shipdiagdir == slopediagdir) == second_half) {
|
||||||
|
/* On top half of lock */
|
||||||
|
s->z_pos = GetTileMaxZ(s->tile) * (int)TILE_HEIGHT;
|
||||||
|
} else {
|
||||||
|
/* On lower half of lock */
|
||||||
|
s->z_pos = GetTileZ(s->tile) * (int)TILE_HEIGHT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Station acceptance is some kind of cache */
|
/* Station acceptance is some kind of cache */
|
||||||
if (IsSavegameVersionBefore(SLV_127)) {
|
if (IsSavegameVersionBefore(SLV_127)) {
|
||||||
Station *st;
|
Station *st;
|
||||||
|
|
|
@ -289,6 +289,7 @@ enum SaveLoadVersion : uint16 {
|
||||||
SLV_SHIP_ROTATION, ///< 204 PR#7065 Add extra rotation stages for ships.
|
SLV_SHIP_ROTATION, ///< 204 PR#7065 Add extra rotation stages for ships.
|
||||||
|
|
||||||
SLV_GROUP_LIVERIES, ///< 205 PR#7108 Livery storage change and group liveries.
|
SLV_GROUP_LIVERIES, ///< 205 PR#7108 Livery storage change and group liveries.
|
||||||
|
SLV_SHIPS_STOP_IN_LOCKS, ///< 206 PR#7150 Ship/lock movement changes.
|
||||||
|
|
||||||
SL_MAX_VERSION, ///< Highest possible saveload version
|
SL_MAX_VERSION, ///< Highest possible saveload version
|
||||||
};
|
};
|
||||||
|
|
|
@ -550,6 +550,56 @@ static const byte _ship_subcoord[4][6][3] = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test if a ship is in the centre of a lock and should move up or down.
|
||||||
|
* @param v Ship being tested.
|
||||||
|
* @return 0 if ship is not moving in lock, or -1 to move down, 1 to move up.
|
||||||
|
*/
|
||||||
|
static int ShipTestUpDownOnLock(const Ship *v)
|
||||||
|
{
|
||||||
|
/* Suitable tile? */
|
||||||
|
if (!IsTileType(v->tile, MP_WATER) || !IsLock(v->tile) || GetLockPart(v->tile) != LOCK_PART_MIDDLE) return 0;
|
||||||
|
|
||||||
|
/* Must be at the centre of the lock */
|
||||||
|
if ((v->x_pos & 0xF) != 8 || (v->y_pos & 0xF) != 8) return 0;
|
||||||
|
|
||||||
|
DiagDirection diagdir = GetInclinedSlopeDirection(GetTileSlope(v->tile));
|
||||||
|
assert(IsValidDiagDirection(diagdir));
|
||||||
|
|
||||||
|
if (DirToDiagDir(v->direction) == diagdir) {
|
||||||
|
/* Move up */
|
||||||
|
return (v->z_pos < GetTileMaxZ(v->tile) * (int)TILE_HEIGHT) ? 1 : 0;
|
||||||
|
} else {
|
||||||
|
/* Move down */
|
||||||
|
return (v->z_pos > GetTileZ(v->tile) * (int)TILE_HEIGHT) ? -1 : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test and move a ship up or down in a lock.
|
||||||
|
* @param v Ship to move.
|
||||||
|
* @return true iff ship is moving up or down in a lock.
|
||||||
|
*/
|
||||||
|
static bool ShipMoveUpDownOnLock(Ship *v)
|
||||||
|
{
|
||||||
|
/* Moving up/down through lock */
|
||||||
|
int dz = ShipTestUpDownOnLock(v);
|
||||||
|
if (dz == 0) return false;
|
||||||
|
|
||||||
|
if (v->cur_speed != 0) {
|
||||||
|
v->cur_speed = 0;
|
||||||
|
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((v->tick_counter & 7) == 0) {
|
||||||
|
v->z_pos += dz;
|
||||||
|
v->UpdatePosition();
|
||||||
|
v->UpdateViewport(true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static void ShipController(Ship *v)
|
static void ShipController(Ship *v)
|
||||||
{
|
{
|
||||||
uint32 r;
|
uint32 r;
|
||||||
|
@ -583,6 +633,8 @@ static void ShipController(Ship *v)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ShipMoveUpDownOnLock(v)) return;
|
||||||
|
|
||||||
if (!ShipAccelerate(v)) return;
|
if (!ShipAccelerate(v)) return;
|
||||||
|
|
||||||
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
|
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
|
||||||
|
@ -707,7 +759,6 @@ static void ShipController(Ship *v)
|
||||||
/* update image of ship, as well as delta XY */
|
/* update image of ship, as well as delta XY */
|
||||||
v->x_pos = gp.x;
|
v->x_pos = gp.x;
|
||||||
v->y_pos = gp.y;
|
v->y_pos = gp.y;
|
||||||
v->z_pos = GetSlopePixelZ(gp.x, gp.y);
|
|
||||||
|
|
||||||
getout:
|
getout:
|
||||||
v->UpdatePosition();
|
v->UpdatePosition();
|
||||||
|
|
Loading…
Reference in New Issue