summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2010-12-12 17:21:49 +0000
committerrubidium <rubidium@openttd.org>2010-12-12 17:21:49 +0000
commita1d923700feba2edf35b2df22b64d56258c7fb5d (patch)
tree95598d2489ab5334bc2af398ddc963005adfe229
parent90e247c84dc1b286096555ae50e2cd0887bd81e1 (diff)
downloadopenttd-a1d923700feba2edf35b2df22b64d56258c7fb5d.tar.xz
(svn r21481) -Codechange: make rail conversion make use of TILE_AREA_LOOP as well
-rw-r--r--src/rail_cmd.cpp267
1 files changed, 128 insertions, 139 deletions
diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp
index 5a502362a..2e88b1eb7 100644
--- a/src/rail_cmd.cpp
+++ b/src/rail_cmd.cpp
@@ -1397,73 +1397,126 @@ CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
if (!ValParamRailtype(totype)) return CMD_ERROR;
if (p1 >= MapSize()) return CMD_ERROR;
- uint ex = TileX(tile);
- uint ey = TileY(tile);
- uint sx = TileX(p1);
- uint sy = TileY(p1);
-
- /* make sure sx,sy are smaller than ex,ey */
- if (ex < sx) Swap(ex, sx);
- if (ey < sy) Swap(ey, sy);
-
TrainList affected_trains;
CommandCost cost(EXPENSES_CONSTRUCTION);
CommandCost error = CommandCost(STR_ERROR_NO_SUITABLE_RAILROAD_TRACK); // by default, there is no track to convert.
- for (uint x = sx; x <= ex; ++x) {
- for (uint y = sy; y <= ey; ++y) {
- TileIndex tile = TileXY(x, y);
- TileType tt = GetTileType(tile);
-
- /* Check if there is any track on tile */
- switch (tt) {
- case MP_RAILWAY:
- break;
- case MP_STATION:
- if (!HasStationRail(tile)) continue;
- break;
- case MP_ROAD:
- if (!IsLevelCrossing(tile)) continue;
- if (RailNoLevelCrossings(totype)) {
- error.MakeError(STR_ERROR_CROSSING_DISALLOWED);
- continue;
+ TileArea ta(tile, p1);
+ TILE_AREA_LOOP(tile, ta) {
+ TileType tt = GetTileType(tile);
+
+ /* Check if there is any track on tile */
+ switch (tt) {
+ case MP_RAILWAY:
+ break;
+ case MP_STATION:
+ if (!HasStationRail(tile)) continue;
+ break;
+ case MP_ROAD:
+ if (!IsLevelCrossing(tile)) continue;
+ if (RailNoLevelCrossings(totype)) {
+ error.MakeError(STR_ERROR_CROSSING_DISALLOWED);
+ continue;
+ }
+ break;
+ case MP_TUNNELBRIDGE:
+ if (GetTunnelBridgeTransportType(tile) != TRANSPORT_RAIL) continue;
+ break;
+ default: continue;
+ }
+
+ /* Original railtype we are converting from */
+ RailType type = GetRailType(tile);
+
+ /* Converting to the same type or converting 'hidden' elrail -> rail */
+ if (type == totype || (_settings_game.vehicle.disable_elrails && totype == RAILTYPE_RAIL && type == RAILTYPE_ELECTRIC)) continue;
+
+ /* Trying to convert other's rail */
+ CommandCost ret = CheckTileOwnership(tile);
+ if (ret.Failed()) {
+ error = ret;
+ continue;
+ }
+
+ SmallVector<Train *, 2> vehicles_affected;
+
+ /* Vehicle on the tile when not converting Rail <-> ElRail
+ * Tunnels and bridges have special check later */
+ if (tt != MP_TUNNELBRIDGE) {
+ if (!IsCompatibleRail(type, totype)) {
+ CommandCost ret = EnsureNoVehicleOnGround(tile);
+ if (ret.Failed()) {
+ error = ret;
+ continue;
+ }
+ }
+ if (flags & DC_EXEC) { // we can safely convert, too
+ TrackBits reserved = GetReservedTrackbits(tile);
+ Track track;
+ while ((track = RemoveFirstTrack(&reserved)) != INVALID_TRACK) {
+ Train *v = GetTrainForReservation(tile, track);
+ if (v != NULL && !HasPowerOnRail(v->railtype, totype)) {
+ /* No power on new rail type, reroute. */
+ FreeTrainTrackReservation(v);
+ *vehicles_affected.Append() = v;
}
- break;
- case MP_TUNNELBRIDGE:
- if (GetTunnelBridgeTransportType(tile) != TRANSPORT_RAIL) continue;
- break;
- default: continue;
+ }
+
+ SetRailType(tile, totype);
+ MarkTileDirtyByTile(tile);
+ /* update power of train on this tile */
+ FindVehicleOnPos(tile, &affected_trains, &UpdateTrainPowerProc);
}
+ }
- /* Original railtype we are converting from */
- RailType type = GetRailType(tile);
+ switch (tt) {
+ case MP_RAILWAY:
+ switch (GetRailTileType(tile)) {
+ case RAIL_TILE_DEPOT:
+ if (flags & DC_EXEC) {
+ /* notify YAPF about the track layout change */
+ YapfNotifyTrackLayoutChange(tile, GetRailDepotTrack(tile));
+
+ /* Update build vehicle window related to this depot */
+ InvalidateWindowData(WC_VEHICLE_DEPOT, tile);
+ InvalidateWindowData(WC_BUILD_VEHICLE, tile);
+ }
+ cost.AddCost(RailConvertCost(type, totype));
+ break;
- /* Converting to the same type or converting 'hidden' elrail -> rail */
- if (type == totype || (_settings_game.vehicle.disable_elrails && totype == RAILTYPE_RAIL && type == RAILTYPE_ELECTRIC)) continue;
+ default: // RAIL_TILE_NORMAL, RAIL_TILE_SIGNALS
+ if (flags & DC_EXEC) {
+ /* notify YAPF about the track layout change */
+ TrackBits tracks = GetTrackBits(tile);
+ while (tracks != TRACK_BIT_NONE) {
+ YapfNotifyTrackLayoutChange(tile, RemoveFirstTrack(&tracks));
+ }
+ }
+ cost.AddCost(RailConvertCost(type, totype) * CountBits(GetTrackBits(tile)));
+ break;
+ }
+ break;
- /* Trying to convert other's rail */
- CommandCost ret = CheckTileOwnership(tile);
- if (ret.Failed()) {
- error = ret;
- continue;
- }
+ case MP_TUNNELBRIDGE: {
+ TileIndex endtile = GetOtherTunnelBridgeEnd(tile);
- SmallVector<Train *, 2> vehicles_affected;
+ /* If both ends of tunnel/bridge are in the range, do not try to convert twice -
+ * it would cause assert because of different test and exec runs */
+ if (endtile < tile && TileX(endtile) >= TileX(ta.tile) && TileX(endtile) < TileX(ta.tile) + ta.w &&
+ TileY(endtile) >= TileY(ta.tile) && TileY(endtile) < TileY(ta.tile) + ta.h) continue;
- /* Vehicle on the tile when not converting Rail <-> ElRail
- * Tunnels and bridges have special check later */
- if (tt != MP_TUNNELBRIDGE) {
- if (!IsCompatibleRail(type, totype)) {
- CommandCost ret = EnsureNoVehicleOnGround(tile);
+ /* When not coverting rail <-> el. rail, any vehicle cannot be in tunnel/bridge */
+ if (!IsCompatibleRail(GetRailType(tile), totype)) {
+ CommandCost ret = TunnelBridgeIsFree(tile, endtile);
if (ret.Failed()) {
error = ret;
continue;
}
}
- if (flags & DC_EXEC) { // we can safely convert, too
- TrackBits reserved = GetReservedTrackbits(tile);
- Track track;
- while ((track = RemoveFirstTrack(&reserved)) != INVALID_TRACK) {
+
+ if (flags & DC_EXEC) {
+ Track track = DiagDirToDiagTrack(GetTunnelBridgeDirection(tile));
+ if (HasTunnelBridgeReservation(tile)) {
Train *v = GetTrainForReservation(tile, track);
if (v != NULL && !HasPowerOnRail(v->railtype, totype)) {
/* No power on new rail type, reroute. */
@@ -1471,105 +1524,41 @@ CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
*vehicles_affected.Append() = v;
}
}
-
SetRailType(tile, totype);
- MarkTileDirtyByTile(tile);
- /* update power of train on this tile */
- FindVehicleOnPos(tile, &affected_trains, &UpdateTrainPowerProc);
- }
- }
+ SetRailType(endtile, totype);
- switch (tt) {
- case MP_RAILWAY:
- switch (GetRailTileType(tile)) {
- case RAIL_TILE_DEPOT:
- if (flags & DC_EXEC) {
- /* notify YAPF about the track layout change */
- YapfNotifyTrackLayoutChange(tile, GetRailDepotTrack(tile));
-
- /* Update build vehicle window related to this depot */
- InvalidateWindowData(WC_VEHICLE_DEPOT, tile);
- InvalidateWindowData(WC_BUILD_VEHICLE, tile);
- }
- cost.AddCost(RailConvertCost(type, totype));
- break;
-
- default: // RAIL_TILE_NORMAL, RAIL_TILE_SIGNALS
- if (flags & DC_EXEC) {
- /* notify YAPF about the track layout change */
- TrackBits tracks = GetTrackBits(tile);
- while (tracks != TRACK_BIT_NONE) {
- YapfNotifyTrackLayoutChange(tile, RemoveFirstTrack(&tracks));
- }
- }
- cost.AddCost(RailConvertCost(type, totype) * CountBits(GetTrackBits(tile)));
- break;
- }
- break;
+ FindVehicleOnPos(tile, &affected_trains, &UpdateTrainPowerProc);
+ FindVehicleOnPos(endtile, &affected_trains, &UpdateTrainPowerProc);
- case MP_TUNNELBRIDGE: {
- TileIndex endtile = GetOtherTunnelBridgeEnd(tile);
+ YapfNotifyTrackLayoutChange(tile, track);
+ YapfNotifyTrackLayoutChange(endtile, track);
- /* If both ends of tunnel/bridge are in the range, do not try to convert twice -
- * it would cause assert because of different test and exec runs */
- if (endtile < tile && TileX(endtile) >= sx && TileX(endtile) <= ex &&
- TileY(endtile) >= sy && TileY(endtile) <= ey) continue;
+ MarkTileDirtyByTile(tile);
+ MarkTileDirtyByTile(endtile);
- /* When not coverting rail <-> el. rail, any vehicle cannot be in tunnel/bridge */
- if (!IsCompatibleRail(GetRailType(tile), totype)) {
- CommandCost ret = TunnelBridgeIsFree(tile, endtile);
- if (ret.Failed()) {
- error = ret;
- continue;
- }
+ if (IsBridge(tile)) {
+ TileIndexDiff delta = TileOffsByDiagDir(GetTunnelBridgeDirection(tile));
+ TileIndex t = tile + delta;
+ for (; t != endtile; t += delta) MarkTileDirtyByTile(t); // TODO encapsulate this into a function
}
+ }
- if (flags & DC_EXEC) {
- Track track = DiagDirToDiagTrack(GetTunnelBridgeDirection(tile));
- if (HasTunnelBridgeReservation(tile)) {
- Train *v = GetTrainForReservation(tile, track);
- if (v != NULL && !HasPowerOnRail(v->railtype, totype)) {
- /* No power on new rail type, reroute. */
- FreeTrainTrackReservation(v);
- *vehicles_affected.Append() = v;
- }
- }
- SetRailType(tile, totype);
- SetRailType(endtile, totype);
-
- FindVehicleOnPos(tile, &affected_trains, &UpdateTrainPowerProc);
- FindVehicleOnPos(endtile, &affected_trains, &UpdateTrainPowerProc);
-
- YapfNotifyTrackLayoutChange(tile, track);
- YapfNotifyTrackLayoutChange(endtile, track);
-
- MarkTileDirtyByTile(tile);
- MarkTileDirtyByTile(endtile);
-
- if (IsBridge(tile)) {
- TileIndexDiff delta = TileOffsByDiagDir(GetTunnelBridgeDirection(tile));
- TileIndex t = tile + delta;
- for (; t != endtile; t += delta) MarkTileDirtyByTile(t); // TODO encapsulate this into a function
- }
- }
+ cost.AddCost((GetTunnelBridgeLength(tile, endtile) + 2) * RailConvertCost(type, totype));
+ break;
+ }
- cost.AddCost((GetTunnelBridgeLength(tile, endtile) + 2) * RailConvertCost(type, totype));
- break;
+ default: // MP_STATION, MP_ROAD
+ if (flags & DC_EXEC) {
+ Track track = ((tt == MP_STATION) ? GetRailStationTrack(tile) : GetCrossingRailTrack(tile));
+ YapfNotifyTrackLayoutChange(tile, track);
}
- default: // MP_STATION, MP_ROAD
- if (flags & DC_EXEC) {
- Track track = ((tt == MP_STATION) ? GetRailStationTrack(tile) : GetCrossingRailTrack(tile));
- YapfNotifyTrackLayoutChange(tile, track);
- }
-
- cost.AddCost(RailConvertCost(type, totype));
- break;
- }
+ cost.AddCost(RailConvertCost(type, totype));
+ break;
+ }
- for (uint i = 0; i < vehicles_affected.Length(); ++i) {
- TryPathReserve(vehicles_affected[i], true);
- }
+ for (uint i = 0; i < vehicles_affected.Length(); ++i) {
+ TryPathReserve(vehicles_affected[i], true);
}
}