diff --git a/rail_cmd.c b/rail_cmd.c index 8afcab6981..94589cc384 100644 --- a/rail_cmd.c +++ b/rail_cmd.c @@ -395,6 +395,7 @@ int32 CmdRemoveSingleRail(int x, int y, uint32 flags, uint32 p1, uint32 p2) TileIndex tile; byte m5; int32 cost = _price.remove_rail; + bool crossing = false; if (!ValParamTrackOrientation(p2)) return CMD_ERROR; trackbit = TrackToTrackBits(track); @@ -453,7 +454,9 @@ int32 CmdRemoveSingleRail(int x, int y, uint32 flags, uint32 p1, uint32 p2) SetTileOwner(tile, _m[tile].m3); break; - case MP_RAILWAY: + case MP_RAILWAY: { + TrackBits present; + if (!IsPlainRailTile(tile)) return CMD_ERROR; @@ -461,6 +464,10 @@ int32 CmdRemoveSingleRail(int x, int y, uint32 flags, uint32 p1, uint32 p2) if (!(GetTrackBits(tile) & trackbit)) return CMD_ERROR; + present = GetTrackBits(tile); + if ((present & trackbit) == 0) return CMD_ERROR; + if (present == (TRACK_BIT_DIAG1 | TRACK_BIT_DIAG2)) crossing = true; + /* Charge extra to remove signals on the track, if they are there */ if (HasSignalOnTrack(tile, track)) cost += DoCommand(x, y, track, 0, flags, CMD_REMOVE_SIGNALS); @@ -478,13 +485,26 @@ int32 CmdRemoveSingleRail(int x, int y, uint32 flags, uint32 p1, uint32 p2) goto skip_mark_dirty; } break; + } default: assert(0); } /* mark_dirty */ - MarkTileDirtyByTile(tile); + if (flags & DC_EXEC) { + MarkTileDirtyByTile(tile); + if (crossing) { + /* crossing is set when only TRACK_BIT_X and TRACK_BIT_Y are set. As we + * are removing one of these pieces, we'll need to update signals for + * both directions explicitly, as after the track is removed it won't + * 'connect' with the other piece. */ + SetSignalsOnBothDir(tile, TRACK_DIAG1); + SetSignalsOnBothDir(tile, TRACK_DIAG2); + } else { + SetSignalsOnBothDir(tile, track); + } + } skip_mark_dirty:;