diff options
-rw-r--r-- | rail_cmd.c | 82 | ||||
-rw-r--r-- | rail_map.h | 5 |
2 files changed, 39 insertions, 48 deletions
diff --git a/rail_cmd.c b/rail_cmd.c index c9d6cd2f6..eaec7bee9 100644 --- a/rail_cmd.c +++ b/rail_cmd.c @@ -393,83 +393,69 @@ int32 CmdRemoveSingleRail(int x, int y, uint32 flags, uint32 p1, uint32 p2) tile = TileVirtXY(x, y); - if (!IsTileType(tile, MP_TUNNELBRIDGE) && !IsTileType(tile, MP_STREET) && !IsTileType(tile, MP_RAILWAY)) - return CMD_ERROR; - - if (_current_player != OWNER_WATER && !CheckTileOwnership(tile)) - return CMD_ERROR; - - // allow building rail under bridge - if (!IsTileType(tile, MP_TUNNELBRIDGE) && !EnsureNoVehicle(tile)) - return CMD_ERROR; - - switch (GetTileType(tile)) - { + switch (GetTileType(tile)) { case MP_TUNNELBRIDGE: if (!IsBridge(tile) || !IsBridgeMiddle(tile) || !IsTransportUnderBridge(tile) || GetTransportTypeUnderBridge(tile) != TRANSPORT_RAIL || GetRailBitsUnderBridge(tile) != trackbit || + (_current_player != OWNER_WATER && !CheckTileOwnership(tile)) || !EnsureNoVehicleZ(tile, TilePixelHeight(tile))) { return CMD_ERROR; } - if (!(flags & DC_EXEC)) - return _price.remove_rail; - - SetClearUnderBridge(tile); + if (flags & DC_EXEC) SetClearUnderBridge(tile); break; case MP_STREET: { - if (!IsLevelCrossing(tile)) return CMD_ERROR; - - /* This is a crossing, let's check if the direction is correct */ - if (GetCrossingRailBits(tile) != trackbit) return CMD_ERROR; - - if (!(flags & DC_EXEC)) - return _price.remove_rail; + if (!IsLevelCrossing(tile) || + GetCrossingRailBits(tile) != trackbit || + (_current_player != OWNER_WATER && !CheckTileOwnership(tile)) || + !EnsureNoVehicle(tile)) { + return CMD_ERROR; + } - MakeRoadNormal(tile, _m[tile].m3, GetCrossingRoadBits(tile), _m[tile].m2); + if (flags & DC_EXEC) { + MakeRoadNormal(tile, _m[tile].m3, GetCrossingRoadBits(tile), _m[tile].m2); + } break; } - case MP_RAILWAY: - if (!IsPlainRailTile(tile)) - return CMD_ERROR; + case MP_RAILWAY: { + TrackBits present; - /* See if the track to remove is actually there */ - if (!(GetTrackBits(tile) & trackbit)) + if (!IsPlainRailTile(tile) || + (_current_player != OWNER_WATER && !CheckTileOwnership(tile)) || + !EnsureNoVehicle(tile)) { return CMD_ERROR; + } + + present = GetTrackBits(tile); + if ((present & trackbit) == 0) return CMD_ERROR; /* 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); - if (!(flags & DC_EXEC)) - return cost; - - /* We remove the trackbit here. */ - _m[tile].m5 &= ~trackbit; - - if (GetTrackBits(tile) == 0) { - /* The tile has no tracks left, it is no longer a rail tile */ - DoClearSquare(tile); - /* XXX: This is an optimisation, right? Is it really worth the ugly goto? */ - goto skip_mark_dirty; + if (flags & DC_EXEC) { + present ^= trackbit; + if (present == 0) { + DoClearSquare(tile); + } else { + SetTrackBits(tile, present); + } } break; + } - default: - assert(0); + default: return CMD_ERROR; } - /* mark_dirty */ - MarkTileDirtyByTile(tile); - -skip_mark_dirty:; - - SetSignalsOnBothDir(tile, track); + if (flags & DC_EXEC) { + MarkTileDirtyByTile(tile); + SetSignalsOnBothDir(tile, track); + } return cost; } diff --git a/rail_map.h b/rail_map.h index 1f88113c0..5a3828282 100644 --- a/rail_map.h +++ b/rail_map.h @@ -110,6 +110,11 @@ static inline TrackBits GetTrackBits(TileIndex tile) return (TrackBits)GB(_m[tile].m5, 0, 6); } +static inline void SetTrackBits(TileIndex t, TrackBits b) +{ + SB(_m[t].m5, 0, 6, b); +} + static inline DiagDirection GetRailDepotDirection(TileIndex t) { |