Enable signals on bridges/tunnels to work with PBS.
This commit is contained in:
@@ -358,7 +358,7 @@ protected:
|
|||||||
if (IsTunnel(m_new_tile)) {
|
if (IsTunnel(m_new_tile)) {
|
||||||
if (!m_is_tunnel) {
|
if (!m_is_tunnel) {
|
||||||
DiagDirection tunnel_enterdir = GetTunnelBridgeDirection(m_new_tile);
|
DiagDirection tunnel_enterdir = GetTunnelBridgeDirection(m_new_tile);
|
||||||
if (tunnel_enterdir != m_exitdir || IsTunnelBridgeExit(m_new_tile)) {
|
if (tunnel_enterdir != m_exitdir) {
|
||||||
m_err = EC_NO_WAY;
|
m_err = EC_NO_WAY;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -366,7 +366,7 @@ protected:
|
|||||||
} else { // IsBridge(m_new_tile)
|
} else { // IsBridge(m_new_tile)
|
||||||
if (!m_is_bridge) {
|
if (!m_is_bridge) {
|
||||||
DiagDirection ramp_enderdir = GetTunnelBridgeDirection(m_new_tile);
|
DiagDirection ramp_enderdir = GetTunnelBridgeDirection(m_new_tile);
|
||||||
if (ramp_enderdir != m_exitdir || IsTunnelBridgeExit(m_new_tile)) {
|
if (ramp_enderdir != m_exitdir) {
|
||||||
m_err = EC_NO_WAY;
|
m_err = EC_NO_WAY;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@@ -936,6 +936,10 @@ static void NPFFollowTrack(AyStar *aystar, OpenListNode *current)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (IsTileType(dst_tile, MP_TUNNELBRIDGE) && IsTunnelBridgeExit(dst_tile) && DiagDirToDiagTrackdir(GetTunnelBridgeDirection(dst_tile)) == dst_trackdir) {
|
||||||
|
/* Entering a signalled bridge/tunnel from the wrong side, equivalent to encountering a one-way signal from the wrong side */
|
||||||
|
break;
|
||||||
|
}
|
||||||
{
|
{
|
||||||
/* We've found ourselves a neighbour :-) */
|
/* We've found ourselves a neighbour :-) */
|
||||||
AyStarNode *neighbour = &aystar->neighbours[i];
|
AyStarNode *neighbour = &aystar->neighbours[i];
|
||||||
|
@@ -244,6 +244,10 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeExit(tile) && DiagDirToDiagTrackdir(GetTunnelBridgeDirection(tile)) == trackdir) {
|
||||||
|
/* Entering a signalled bridge/tunnel from the wrong side, equivalent to encountering a one-way signal from the wrong side */
|
||||||
|
n.m_segment->m_end_segment_reason |= ESRB_DEAD_END;
|
||||||
|
}
|
||||||
return cost;
|
return cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
src/pbs.cpp
10
src/pbs.cpp
@@ -246,6 +246,7 @@ static PBSTileInfo FollowReservation(Owner o, RailTypes rts, TileIndex tile, Tra
|
|||||||
if (IsRailDepotTile(tile)) break;
|
if (IsRailDepotTile(tile)) break;
|
||||||
/* Non-pbs signal? Reservation can't continue. */
|
/* Non-pbs signal? Reservation can't continue. */
|
||||||
if (IsTileType(tile, MP_RAILWAY) && HasSignalOnTrackdir(tile, trackdir) && !IsPbsSignal(GetSignalType(tile, TrackdirToTrack(trackdir)))) break;
|
if (IsTileType(tile, MP_RAILWAY) && HasSignalOnTrackdir(tile, trackdir) && !IsPbsSignal(GetSignalType(tile, TrackdirToTrack(trackdir)))) break;
|
||||||
|
if (IsTileType(tile, MP_TUNNELBRIDGE) && HasWormholeSignals(tile)) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return PBSTileInfo(tile, trackdir, false);
|
return PBSTileInfo(tile, trackdir, false);
|
||||||
@@ -314,7 +315,7 @@ PBSTileInfo FollowTrainReservation(const Train *v, Vehicle **train_on_res)
|
|||||||
if (ftoti.best != NULL) *train_on_res = ftoti.best->First();
|
if (ftoti.best != NULL) *train_on_res = ftoti.best->First();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (*train_on_res == NULL && IsTileType(ftoti.res.tile, MP_TUNNELBRIDGE)) {
|
if (*train_on_res == NULL && IsTileType(ftoti.res.tile, MP_TUNNELBRIDGE) && !HasWormholeSignals(ftoti.res.tile)) {
|
||||||
/* The target tile is a bridge/tunnel, also check the other end tile. */
|
/* The target tile is a bridge/tunnel, also check the other end tile. */
|
||||||
FindVehicleOnPos(GetOtherTunnelBridgeEnd(ftoti.res.tile), &ftoti, FindTrainOnTrackEnum);
|
FindVehicleOnPos(GetOtherTunnelBridgeEnd(ftoti.res.tile), &ftoti, FindTrainOnTrackEnum);
|
||||||
if (ftoti.best != NULL) *train_on_res = ftoti.best->First();
|
if (ftoti.best != NULL) *train_on_res = ftoti.best->First();
|
||||||
@@ -389,6 +390,12 @@ bool IsSafeWaitingPosition(const Train *v, TileIndex tile, Trackdir trackdir, bo
|
|||||||
if (HasSignalOnTrackdir(tile, trackdir) && !IsPbsSignal(GetSignalType(tile, TrackdirToTrack(trackdir)))) return true;
|
if (HasSignalOnTrackdir(tile, trackdir) && !IsPbsSignal(GetSignalType(tile, TrackdirToTrack(trackdir)))) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsTileType(tile, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL) {
|
||||||
|
if (IsTunnelBridgeEntrance(tile)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* 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)->compatible_railtypes);
|
||||||
|
|
||||||
@@ -437,6 +444,7 @@ bool IsWaitingPositionFree(const Train *v, TileIndex tile, Trackdir trackdir, bo
|
|||||||
/* Not reserved and depot or not a pbs signal -> free. */
|
/* Not reserved and depot or not a pbs signal -> free. */
|
||||||
if (IsRailDepotTile(tile)) return true;
|
if (IsRailDepotTile(tile)) return true;
|
||||||
if (IsTileType(tile, MP_RAILWAY) && HasSignalOnTrackdir(tile, trackdir) && !IsPbsSignal(GetSignalType(tile, track))) return true;
|
if (IsTileType(tile, MP_RAILWAY) && HasSignalOnTrackdir(tile, trackdir) && !IsPbsSignal(GetSignalType(tile, track))) return true;
|
||||||
|
if (IsTileType(tile, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL && IsTunnelBridgeEntrance(tile)) return true;
|
||||||
|
|
||||||
/* 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)->compatible_railtypes);
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
#include "track_func.h"
|
#include "track_func.h"
|
||||||
#include "tile_map.h"
|
#include "tile_map.h"
|
||||||
#include "signal_type.h"
|
#include "signal_type.h"
|
||||||
|
#include "tunnelbridge_map.h"
|
||||||
|
|
||||||
|
|
||||||
/** Different types of Rail-related tiles */
|
/** Different types of Rail-related tiles */
|
||||||
@@ -475,8 +476,15 @@ static inline bool HasPbsSignalOnTrackdir(TileIndex tile, Trackdir td)
|
|||||||
*/
|
*/
|
||||||
static inline bool HasOnewaySignalBlockingTrackdir(TileIndex tile, Trackdir td)
|
static inline bool HasOnewaySignalBlockingTrackdir(TileIndex tile, Trackdir td)
|
||||||
{
|
{
|
||||||
return IsTileType(tile, MP_RAILWAY) && HasSignalOnTrackdir(tile, ReverseTrackdir(td)) &&
|
if (IsTileType(tile, MP_RAILWAY) && HasSignalOnTrackdir(tile, ReverseTrackdir(td)) &&
|
||||||
!HasSignalOnTrackdir(tile, td) && IsOnewaySignal(tile, TrackdirToTrack(td));
|
!HasSignalOnTrackdir(tile, td) && IsOnewaySignal(tile, TrackdirToTrack(td))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeExit(tile) &&
|
||||||
|
DiagDirToDiagTrackdir(GetTunnelBridgeDirection(tile)) == td) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -2260,7 +2260,13 @@ static void ClearPathReservation(const Train *v, TileIndex tile, Trackdir track_
|
|||||||
TileIndex end = GetOtherTunnelBridgeEnd(tile);
|
TileIndex end = GetOtherTunnelBridgeEnd(tile);
|
||||||
|
|
||||||
bool free = TunnelBridgeIsFree(tile, end, v).Succeeded();
|
bool free = TunnelBridgeIsFree(tile, end, v).Succeeded();
|
||||||
if (free) {
|
if (HasWormholeSignals(tile)) {
|
||||||
|
SetTunnelBridgeReservation(tile, false);
|
||||||
|
HandleLastTunnelBridgeSignals(tile, end, dir, free);
|
||||||
|
if (_settings_client.gui.show_track_reservation) {
|
||||||
|
MarkTileDirtyByTile(tile);
|
||||||
|
}
|
||||||
|
} else if (free) {
|
||||||
/* Free the reservation only if no other train is on the tiles. */
|
/* Free the reservation only if no other train is on the tiles. */
|
||||||
SetTunnelBridgeReservation(tile, false);
|
SetTunnelBridgeReservation(tile, false);
|
||||||
SetTunnelBridgeReservation(end, false);
|
SetTunnelBridgeReservation(end, false);
|
||||||
@@ -2274,7 +2280,12 @@ static void ClearPathReservation(const Train *v, TileIndex tile, Trackdir track_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (HasWormholeSignals(tile)) HandleLastTunnelBridgeSignals(tile, end, dir, free);
|
} else if (GetTunnelBridgeDirection(tile) == dir && HasWormholeSignals(tile)) {
|
||||||
|
/* cancelling reservation of entry ramp, due to reverse */
|
||||||
|
SetTunnelBridgeReservation(tile, false);
|
||||||
|
if (_settings_client.gui.show_track_reservation) {
|
||||||
|
MarkTileDirtyByTile(tile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (IsRailStationTile(tile)) {
|
} else if (IsRailStationTile(tile)) {
|
||||||
TileIndex new_tile = TileAddByDiagDir(tile, dir);
|
TileIndex new_tile = TileAddByDiagDir(tile, dir);
|
||||||
@@ -2955,6 +2966,12 @@ static bool TrainMovedChangeSignals(TileIndex tile, DiagDirection dir)
|
|||||||
if (!IsPbsSignal(GetSignalType(tile, TrackdirToTrack(trackdir)))) return true;
|
if (!IsPbsSignal(GetSignalType(tile, TrackdirToTrack(trackdir)))) return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeExit(tile) && GetTunnelBridgeDirection(tile) == ReverseDiagDir(dir)) {
|
||||||
|
if (UpdateSignalsOnSegment(tile, dir, GetTileOwner(tile)) == SIGSEG_PBS) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3192,6 +3209,15 @@ static bool IsToCloseBehindTrain(Vehicle *v, TileIndex tile, bool check_endtile)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool CheckTrainStayInWormHolePathReserve(Train *t, TileIndex tile)
|
||||||
|
{
|
||||||
|
TileIndex veh_orig = t->tile;
|
||||||
|
t->tile = tile;
|
||||||
|
bool ok = TryPathReserve(t);
|
||||||
|
t->tile = veh_orig;
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
/** Simulate signals in tunnel - bridge. */
|
/** Simulate signals in tunnel - bridge. */
|
||||||
static bool CheckTrainStayInWormHole(Train *t, TileIndex tile)
|
static bool CheckTrainStayInWormHole(Train *t, TileIndex tile)
|
||||||
{
|
{
|
||||||
@@ -3204,7 +3230,7 @@ static bool CheckTrainStayInWormHole(Train *t, TileIndex tile)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
SigSegState seg_state = _settings_game.pf.reserve_paths ? SIGSEG_PBS : UpdateSignalsOnSegment(tile, INVALID_DIAGDIR, t->owner);
|
SigSegState seg_state = _settings_game.pf.reserve_paths ? SIGSEG_PBS : UpdateSignalsOnSegment(tile, INVALID_DIAGDIR, t->owner);
|
||||||
if (seg_state == SIGSEG_FULL || (seg_state == SIGSEG_PBS && !TryPathReserve(t))) {
|
if (seg_state == SIGSEG_FULL || (seg_state == SIGSEG_PBS && !CheckTrainStayInWormHolePathReserve(t, tile))) {
|
||||||
t->vehstatus |= VS_TRAIN_SLOWING;
|
t->vehstatus |= VS_TRAIN_SLOWING;
|
||||||
t->cur_speed = 0;
|
t->cur_speed = 0;
|
||||||
return true;
|
return true;
|
||||||
@@ -3493,7 +3519,7 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
|
|||||||
} else {
|
} else {
|
||||||
/* Handle signal simulation on tunnel/bridge. */
|
/* Handle signal simulation on tunnel/bridge. */
|
||||||
TileIndex old_tile = TileVirtXY(v->x_pos, v->y_pos);
|
TileIndex old_tile = TileVirtXY(v->x_pos, v->y_pos);
|
||||||
if (old_tile != gp.new_tile && HasWormholeSignals(v->tile) && (v->IsFrontEngine() || v->Next() == NULL)){
|
if (old_tile != gp.new_tile && HasWormholeSignals(v->tile) && (v->IsFrontEngine() || v->Next() == NULL)) {
|
||||||
if (old_tile == v->tile) {
|
if (old_tile == v->tile) {
|
||||||
if (v->IsFrontEngine() && v->force_proceed == 0 && IsTunnelBridgeExit(v->tile)) goto invalid_rail;
|
if (v->IsFrontEngine() && v->force_proceed == 0 && IsTunnelBridgeExit(v->tile)) goto invalid_rail;
|
||||||
/* Entered wormhole set counters. */
|
/* Entered wormhole set counters. */
|
||||||
@@ -3532,6 +3558,7 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
|
|||||||
v->x_pos = gp.x;
|
v->x_pos = gp.x;
|
||||||
v->y_pos = gp.y;
|
v->y_pos = gp.y;
|
||||||
UpdateSignalsOnSegment(old_tile, INVALID_DIAGDIR, v->owner);
|
UpdateSignalsOnSegment(old_tile, INVALID_DIAGDIR, v->owner);
|
||||||
|
SetTunnelBridgeReservation(old_tile, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (distance == 0) v->load_unload_ticks++;
|
if (distance == 0) v->load_unload_ticks++;
|
||||||
@@ -3553,7 +3580,7 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
|
|||||||
if (IsTileType(gp.new_tile, MP_TUNNELBRIDGE) && HasBit(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y), VETS_ENTERED_WORMHOLE)) {
|
if (IsTileType(gp.new_tile, MP_TUNNELBRIDGE) && HasBit(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y), VETS_ENTERED_WORMHOLE)) {
|
||||||
/* Perform look-ahead on tunnel exit. */
|
/* Perform look-ahead on tunnel exit. */
|
||||||
if (v->IsFrontEngine()) {
|
if (v->IsFrontEngine()) {
|
||||||
TryReserveRailTrack(gp.new_tile, DiagDirToDiagTrack(GetTunnelBridgeDirection(gp.new_tile)));
|
if (!HasWormholeSignals(gp.new_tile)) TryReserveRailTrack(gp.new_tile, DiagDirToDiagTrack(GetTunnelBridgeDirection(gp.new_tile)));
|
||||||
CheckNextTrainTile(v);
|
CheckNextTrainTile(v);
|
||||||
}
|
}
|
||||||
/* Prevent v->UpdateInclination() being called with wrong parameters.
|
/* Prevent v->UpdateInclination() being called with wrong parameters.
|
||||||
|
@@ -1598,7 +1598,8 @@ void DrawBridgeMiddle(const TileInfo *ti)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && !IsInvisibilitySet(TO_BRIDGES) && HasTunnelBridgeReservation(rampnorth)) {
|
if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && !IsInvisibilitySet(TO_BRIDGES) && HasTunnelBridgeReservation(rampnorth)
|
||||||
|
&& !HasWormholeSignals(rampnorth)) {
|
||||||
if (rti->UsesOverlay()) {
|
if (rti->UsesOverlay()) {
|
||||||
SpriteID overlay = GetCustomRailSprite(rti, ti->tile, RTSG_OVERLAY);
|
SpriteID overlay = GetCustomRailSprite(rti, ti->tile, RTSG_OVERLAY);
|
||||||
AddSortableSpriteToDraw(overlay + RTO_X + axis, PALETTE_CRASH, ti->x, ti->y, 16, 16, 0, bridge_z, IsTransparencySet(TO_BRIDGES));
|
AddSortableSpriteToDraw(overlay + RTO_X + axis, PALETTE_CRASH, ti->x, ti->y, 16, 16, 0, bridge_z, IsTransparencySet(TO_BRIDGES));
|
||||||
|
Reference in New Issue
Block a user