Fix PBS rail type handling with incorrect GRF rail type compatibility
This commit is contained in:
@@ -369,7 +369,7 @@ PBSTileInfo FollowTrainReservation(const Train *v, Vehicle **train_on_res)
|
|||||||
if (IsRailDepotTile(tile) && !GetDepotReservationTrackBits(tile)) return PBSTileInfo(tile, trackdir, false);
|
if (IsRailDepotTile(tile) && !GetDepotReservationTrackBits(tile)) return PBSTileInfo(tile, trackdir, false);
|
||||||
|
|
||||||
FindTrainOnTrackInfo ftoti;
|
FindTrainOnTrackInfo ftoti;
|
||||||
ftoti.res = FollowReservation(v->owner, GetRailTypeInfo(v->railtype)->compatible_railtypes, tile, trackdir);
|
ftoti.res = FollowReservation(v->owner, GetRailTypeInfo(v->railtype)->all_compatible_railtypes, tile, trackdir);
|
||||||
ftoti.res.okay = IsSafeWaitingPosition(v, ftoti.res.tile, ftoti.res.trackdir, true, _settings_game.pf.forbid_90_deg);
|
ftoti.res.okay = IsSafeWaitingPosition(v, ftoti.res.tile, ftoti.res.trackdir, true, _settings_game.pf.forbid_90_deg);
|
||||||
if (train_on_res != nullptr) {
|
if (train_on_res != nullptr) {
|
||||||
FindVehicleOnPos(ftoti.res.tile, VEH_TRAIN, &ftoti, FindTrainOnTrackEnum);
|
FindVehicleOnPos(ftoti.res.tile, VEH_TRAIN, &ftoti, FindTrainOnTrackEnum);
|
||||||
@@ -406,7 +406,7 @@ Train *GetTrainForReservation(TileIndex tile, Track track)
|
|||||||
assert_msg_tile(HasReservedTracks(tile, TrackToTrackBits(track)), tile, "track: %u", track);
|
assert_msg_tile(HasReservedTracks(tile, TrackToTrackBits(track)), tile, "track: %u", track);
|
||||||
Trackdir trackdir = TrackToTrackdir(track);
|
Trackdir trackdir = TrackToTrackdir(track);
|
||||||
|
|
||||||
RailTypes rts = GetRailTypeInfo(GetTileRailTypeByTrack(tile, track))->compatible_railtypes;
|
RailTypes rts = GetRailTypeInfo(GetTileRailTypeByTrack(tile, track))->all_compatible_railtypes;
|
||||||
|
|
||||||
/* Follow the path from tile to both ends, one of the end tiles should
|
/* Follow the path from tile to both ends, one of the end tiles should
|
||||||
* have a train on it. We need FollowReservation to ignore one-way signals
|
* have a train on it. We need FollowReservation to ignore one-way signals
|
||||||
@@ -514,7 +514,7 @@ bool IsSafeWaitingPosition(const Train *v, TileIndex tile, Trackdir trackdir, bo
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check next tile. For performance reasons, we check for 90 degree turns ourself. */
|
/* Check next tile. For performance reasons, we check for 90 degree turns ourself. */
|
||||||
CFollowTrackRail ft(v, GetRailTypeInfo(v->railtype)->compatible_railtypes);
|
CFollowTrackRail ft(v, GetRailTypeInfo(v->railtype)->all_compatible_railtypes);
|
||||||
|
|
||||||
/* End of track? */
|
/* End of track? */
|
||||||
if (!ft.Follow(tile, trackdir)) {
|
if (!ft.Follow(tile, trackdir)) {
|
||||||
@@ -621,7 +621,7 @@ bool IsWaitingPositionFree(const Train *v, TileIndex tile, Trackdir trackdir, bo
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check the next tile, if it's a PBS signal, it has to be free as well. */
|
/* Check the next tile, if it's a PBS signal, it has to be free as well. */
|
||||||
CFollowTrackRail ft(v, GetRailTypeInfo(v->railtype)->compatible_railtypes);
|
CFollowTrackRail ft(v, GetRailTypeInfo(v->railtype)->all_compatible_railtypes);
|
||||||
|
|
||||||
if (!ft.Follow(tile, trackdir)) return true;
|
if (!ft.Follow(tile, trackdir)) return true;
|
||||||
|
|
||||||
|
@@ -194,6 +194,9 @@ public:
|
|||||||
/** bitmask to the OTHER railtypes on which an engine of THIS railtype can physically travel */
|
/** bitmask to the OTHER railtypes on which an engine of THIS railtype can physically travel */
|
||||||
RailTypes compatible_railtypes;
|
RailTypes compatible_railtypes;
|
||||||
|
|
||||||
|
/** bitmask of all directly or indirectly reachable railtypes in either direction via compatible_railtypes */
|
||||||
|
RailTypes all_compatible_railtypes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bridge offset
|
* Bridge offset
|
||||||
*/
|
*/
|
||||||
|
@@ -69,7 +69,7 @@ void ResetRailTypes()
|
|||||||
{0,0,0,0,0,0,0,0,{}},
|
{0,0,0,0,0,0,0,0,{}},
|
||||||
{0,0,0,0,0,0,0,0},
|
{0,0,0,0,0,0,0,0},
|
||||||
{0,0,0,0,0,0},
|
{0,0,0,0,0,0},
|
||||||
0, RAILTYPES_NONE, RAILTYPES_NONE, 0, 0, 0, RTFB_NONE, 0, 0, 0, 0, 0, 0,
|
0, RAILTYPES_NONE, RAILTYPES_NONE, RAILTYPES_NONE, 0, 0, 0, RTFB_NONE, 0, 0, 0, 0, 0, 0,
|
||||||
RailTypeLabelList(), 0, 0, RAILTYPES_NONE, RAILTYPES_NONE, 0,
|
RailTypeLabelList(), 0, 0, RAILTYPES_NONE, RAILTYPES_NONE, 0,
|
||||||
{}, {} };
|
{}, {} };
|
||||||
for (; i < lengthof(_railtypes); i++) _railtypes[i] = empty_railtype;
|
for (; i < lengthof(_railtypes); i++) _railtypes[i] = empty_railtype;
|
||||||
@@ -149,6 +149,27 @@ void InitRailTypes()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::sort(_sorted_railtypes.begin(), _sorted_railtypes.end(), CompareRailTypes);
|
std::sort(_sorted_railtypes.begin(), _sorted_railtypes.end(), CompareRailTypes);
|
||||||
|
|
||||||
|
for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
|
||||||
|
_railtypes[rt].all_compatible_railtypes = _railtypes[rt].compatible_railtypes;
|
||||||
|
}
|
||||||
|
for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
|
||||||
|
RailTypes compatible = _railtypes[rt].all_compatible_railtypes;
|
||||||
|
RailTypes to_check = compatible;
|
||||||
|
while (to_check) {
|
||||||
|
RailType i = (RailType)FindFirstBit64(to_check);
|
||||||
|
to_check = KillFirstBit(to_check);
|
||||||
|
RailTypes new_types = _railtypes[i].compatible_railtypes & (~compatible);
|
||||||
|
to_check |= new_types;
|
||||||
|
compatible |= new_types;
|
||||||
|
}
|
||||||
|
RailTypes to_update = compatible;
|
||||||
|
while (to_update) {
|
||||||
|
RailType i = (RailType)FindFirstBit64(to_update);
|
||||||
|
to_update = KillFirstBit(to_update);
|
||||||
|
_railtypes[i].all_compatible_railtypes = compatible;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -65,6 +65,9 @@ static const RailtypeInfo _original_railtypes[] = {
|
|||||||
/* Compatible railtypes */
|
/* Compatible railtypes */
|
||||||
RAILTYPES_RAIL | RAILTYPES_ELECTRIC,
|
RAILTYPES_RAIL | RAILTYPES_ELECTRIC,
|
||||||
|
|
||||||
|
/* Computed compatible railtypes */
|
||||||
|
RAILTYPES_NONE,
|
||||||
|
|
||||||
/* bridge offset */
|
/* bridge offset */
|
||||||
0,
|
0,
|
||||||
|
|
||||||
@@ -169,6 +172,9 @@ static const RailtypeInfo _original_railtypes[] = {
|
|||||||
/* Compatible railtypes */
|
/* Compatible railtypes */
|
||||||
RAILTYPES_ELECTRIC | RAILTYPES_RAIL,
|
RAILTYPES_ELECTRIC | RAILTYPES_RAIL,
|
||||||
|
|
||||||
|
/* Computed compatible railtypes */
|
||||||
|
RAILTYPES_NONE,
|
||||||
|
|
||||||
/* bridge offset */
|
/* bridge offset */
|
||||||
0,
|
0,
|
||||||
|
|
||||||
@@ -269,6 +275,9 @@ static const RailtypeInfo _original_railtypes[] = {
|
|||||||
/* Compatible Railtypes */
|
/* Compatible Railtypes */
|
||||||
RAILTYPES_MONO,
|
RAILTYPES_MONO,
|
||||||
|
|
||||||
|
/* Computed compatible railtypes */
|
||||||
|
RAILTYPES_NONE,
|
||||||
|
|
||||||
/* bridge offset */
|
/* bridge offset */
|
||||||
16,
|
16,
|
||||||
|
|
||||||
@@ -369,6 +378,9 @@ static const RailtypeInfo _original_railtypes[] = {
|
|||||||
/* Compatible Railtypes */
|
/* Compatible Railtypes */
|
||||||
RAILTYPES_MAGLEV,
|
RAILTYPES_MAGLEV,
|
||||||
|
|
||||||
|
/* Computed compatible railtypes */
|
||||||
|
RAILTYPES_NONE,
|
||||||
|
|
||||||
/* bridge offset */
|
/* bridge offset */
|
||||||
24,
|
24,
|
||||||
|
|
||||||
|
@@ -2221,7 +2221,7 @@ void ReverseTrainDirection(Train *v)
|
|||||||
TileIndex next_tile = TileVirtXY(v->x_pos, v->y_pos) + TileOffsByDiagDir(axial_dir);
|
TileIndex next_tile = TileVirtXY(v->x_pos, v->y_pos) + TileOffsByDiagDir(axial_dir);
|
||||||
if (next_tile == v->tile || next_tile == GetOtherTunnelBridgeEnd(v->tile)) {
|
if (next_tile == v->tile || next_tile == GetOtherTunnelBridgeEnd(v->tile)) {
|
||||||
Trackdir exit_td = TrackEnterdirToTrackdir(FindFirstTrack(GetAcrossTunnelBridgeTrackBits(next_tile)), ReverseDiagDir(GetTunnelBridgeDirection(next_tile)));
|
Trackdir exit_td = TrackEnterdirToTrackdir(FindFirstTrack(GetAcrossTunnelBridgeTrackBits(next_tile)), ReverseDiagDir(GetTunnelBridgeDirection(next_tile)));
|
||||||
CFollowTrackRail ft(GetTileOwner(next_tile), GetRailTypeInfo(v->railtype)->compatible_railtypes);
|
CFollowTrackRail ft(GetTileOwner(next_tile), GetRailTypeInfo(v->railtype)->all_compatible_railtypes);
|
||||||
if (ft.Follow(next_tile, exit_td)) {
|
if (ft.Follow(next_tile, exit_td)) {
|
||||||
TrackdirBits reserved = ft.m_new_td_bits & TrackBitsToTrackdirBits(GetReservedTrackbits(ft.m_new_tile));
|
TrackdirBits reserved = ft.m_new_td_bits & TrackBitsToTrackdirBits(GetReservedTrackbits(ft.m_new_tile));
|
||||||
if (reserved == TRACKDIR_BIT_NONE) {
|
if (reserved == TRACKDIR_BIT_NONE) {
|
||||||
@@ -2871,7 +2871,7 @@ void FreeTrainTrackReservation(const Train *v, TileIndex origin, Trackdir orig_t
|
|||||||
/* Do not attempt to unreserve out of a signalled tunnel/bridge entrance, as this would unreserve the reservations of another train coming in */
|
/* Do not attempt to unreserve out of a signalled tunnel/bridge entrance, as this would unreserve the reservations of another train coming in */
|
||||||
if (IsTunnelBridgeWithSignalSimulation(tile) && TrackdirExitsTunnelBridge(tile, td) && IsTunnelBridgeSignalSimulationEntranceOnly(tile)) return;
|
if (IsTunnelBridgeWithSignalSimulation(tile) && TrackdirExitsTunnelBridge(tile, td) && IsTunnelBridgeSignalSimulationEntranceOnly(tile)) return;
|
||||||
|
|
||||||
CFollowTrackRail ft(v, GetRailTypeInfo(v->railtype)->compatible_railtypes);
|
CFollowTrackRail ft(v, GetRailTypeInfo(v->railtype)->all_compatible_railtypes);
|
||||||
while (ft.Follow(tile, td)) {
|
while (ft.Follow(tile, td)) {
|
||||||
tile = ft.m_new_tile;
|
tile = ft.m_new_tile;
|
||||||
TrackdirBits bits = ft.m_new_td_bits & TrackBitsToTrackdirBits(GetReservedTrackbits(tile));
|
TrackdirBits bits = ft.m_new_td_bits & TrackBitsToTrackdirBits(GetReservedTrackbits(tile));
|
||||||
@@ -3919,7 +3919,7 @@ static bool CheckTrainStayInWormHolePathReserve(Train *t, TileIndex tile)
|
|||||||
t->tile = tile;
|
t->tile = tile;
|
||||||
t->track = TRACK_BIT_WORMHOLE;
|
t->track = TRACK_BIT_WORMHOLE;
|
||||||
t->direction = TrackdirToDirection(td);
|
t->direction = TrackdirToDirection(td);
|
||||||
CFollowTrackRail ft(GetTileOwner(tile), GetRailTypeInfo(t->railtype)->compatible_railtypes);
|
CFollowTrackRail ft(GetTileOwner(tile), GetRailTypeInfo(t->railtype)->all_compatible_railtypes);
|
||||||
if (ft.Follow(tile, td)) {
|
if (ft.Follow(tile, td)) {
|
||||||
TrackdirBits reserved = ft.m_new_td_bits & TrackBitsToTrackdirBits(GetReservedTrackbits(ft.m_new_tile));
|
TrackdirBits reserved = ft.m_new_td_bits & TrackBitsToTrackdirBits(GetReservedTrackbits(ft.m_new_tile));
|
||||||
if (reserved == TRACKDIR_BIT_NONE) {
|
if (reserved == TRACKDIR_BIT_NONE) {
|
||||||
@@ -3952,7 +3952,7 @@ static bool CheckTrainStayInWormHole(Train *t, TileIndex tile)
|
|||||||
}
|
}
|
||||||
SigSegState seg_state = (_settings_game.pf.reserve_paths || IsTunnelBridgePBS(tile)) ? SIGSEG_PBS : UpdateSignalsOnSegment(tile, INVALID_DIAGDIR, t->owner);
|
SigSegState seg_state = (_settings_game.pf.reserve_paths || IsTunnelBridgePBS(tile)) ? SIGSEG_PBS : UpdateSignalsOnSegment(tile, INVALID_DIAGDIR, t->owner);
|
||||||
if (seg_state != SIGSEG_PBS) {
|
if (seg_state != SIGSEG_PBS) {
|
||||||
CFollowTrackRail ft(GetTileOwner(tile), GetRailTypeInfo(t->railtype)->compatible_railtypes);
|
CFollowTrackRail ft(GetTileOwner(tile), GetRailTypeInfo(t->railtype)->all_compatible_railtypes);
|
||||||
if (ft.Follow(tile, TrackEnterdirToTrackdir(FindFirstTrack(GetAcrossTunnelBridgeTrackBits(tile)), ReverseDiagDir(GetTunnelBridgeDirection(tile))))) {
|
if (ft.Follow(tile, TrackEnterdirToTrackdir(FindFirstTrack(GetAcrossTunnelBridgeTrackBits(tile)), ReverseDiagDir(GetTunnelBridgeDirection(tile))))) {
|
||||||
if (ft.m_new_td_bits != TRACKDIR_BIT_NONE && KillFirstBit(ft.m_new_td_bits) == TRACKDIR_BIT_NONE) {
|
if (ft.m_new_td_bits != TRACKDIR_BIT_NONE && KillFirstBit(ft.m_new_td_bits) == TRACKDIR_BIT_NONE) {
|
||||||
Trackdir td = FindFirstTrackdir(ft.m_new_td_bits);
|
Trackdir td = FindFirstTrackdir(ft.m_new_td_bits);
|
||||||
|
Reference in New Issue
Block a user