From c97804461eb696393a9bf4acc2f9b57738349066 Mon Sep 17 00:00:00 2001 From: rubidium Date: Sat, 8 Sep 2007 09:52:02 +0000 Subject: (svn r11059) -Fix [FS#1182]: inconsistency between Rail<->ElRail conversions of different kinds of rail containing tiles (normal rail, stations, depots, etc). Patch by SmatZ. --- src/rail_cmd.cpp | 56 +++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 21 deletions(-) (limited to 'src/rail_cmd.cpp') diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 27ce47cf5..f708fe02f 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -34,6 +34,7 @@ #include "railtypes.h" // include table for railtypes #include "newgrf.h" #include "yapf/yapf.h" +#include "newgrf_engine.h" #include "newgrf_callbacks.h" #include "newgrf_station.h" #include "train.h" @@ -1024,6 +1025,18 @@ CommandCost CmdRemoveSignalTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 typedef CommandCost DoConvertRailProc(TileIndex tile, RailType totype, bool exec); +void *UpdateTrainPowerProc(Vehicle *v, void *data) +{ + /* Similiar checks as in TrainPowerChanged() */ + + if (v->type == VEH_TRAIN && v->tile == *(TileIndex*)data && !IsArticulatedPart(v)) { + const RailVehicleInfo *rvi = RailVehInfo(v->engine_type); + if (GetVehicleProperty(v, 0x0B, rvi->power) != 0) TrainPowerChanged(v->First()); + } + + return NULL; +} + /** * Switches the rail type. * Railtypes are stored on a per-tile basis, not on a per-track basis, so @@ -1036,15 +1049,6 @@ typedef CommandCost DoConvertRailProc(TileIndex tile, RailType totype, bool exec */ static CommandCost DoConvertRail(TileIndex tile, RailType totype, bool exec) { - if (!CheckTileOwnership(tile)) return CMD_ERROR; - - if (GetRailType(tile) == totype) return CMD_ERROR; - - if (!EnsureNoVehicleOnGround(tile) && (!IsCompatibleRail(GetRailType(tile), totype) || IsPlainRailTile(tile))) return CMD_ERROR; - - /* 'hidden' elrails can't be downgraded to normal rail when elrails are disabled */ - if (_patches.disable_elrails && totype == RAILTYPE_RAIL && GetRailType(tile) == RAILTYPE_ELECTRIC) return CMD_ERROR; - /* change type. */ if (exec) { SetRailType(tile, totype); @@ -1057,18 +1061,12 @@ static CommandCost DoConvertRail(TileIndex tile, RailType totype, bool exec) } if (IsTileDepotType(tile, TRANSPORT_RAIL)) { - Vehicle *v; - /* Update build vehicle window related to this depot */ InvalidateWindowData(WC_BUILD_VEHICLE, tile); - - /* update power of trains in this depot */ - FOR_ALL_VEHICLES(v) { - if (v->type == VEH_TRAIN && IsFrontEngine(v) && v->tile == tile && v->u.rail.track == 0x80) { - TrainPowerChanged(v); - } - } } + + /* update power of train engines on this tile */ + VehicleFromPos(tile, &tile, UpdateTrainPowerProc); } return CommandCost(_price.build_rail / 2); @@ -1111,7 +1109,8 @@ CommandCost CmdConvertRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) for (x = sx; x <= ex; ++x) { for (y = sy; y <= ey; ++y) { TileIndex tile = TileXY(x, y); - DoConvertRailProc* proc; + DoConvertRailProc *proc; + RailType totype = (RailType)p2; switch (GetTileType(tile)) { case MP_RAILWAY: proc = DoConvertRail; break; @@ -1121,7 +1120,22 @@ CommandCost CmdConvertRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) default: continue; } - ret = proc(tile, (RailType)p2, false); + /* It is possible that 'type' is invalid when there is no rail on the tile, + * but this situation will be detected in proc() + */ + RailType type = GetRailType(tile); + + /* Not own tile or track is already converted */ + if ((!CheckTileOwnership(tile) || type == totype) || + /* 'hidden' elrails can't be downgraded to normal rail when elrails are disabled */ + (_patches.disable_elrails && totype == RAILTYPE_RAIL && type == RAILTYPE_ELECTRIC) || + /* Vehicle on a tile while not converting Rail <-> ElRail */ + (!IsCompatibleRail(type, totype) && !EnsureNoVehicleOnGround(tile))) { + ret = CMD_ERROR; + continue; + } + + ret = proc(tile, totype, false); if (CmdFailed(ret)) continue; if (flags & DC_EXEC) { @@ -1130,7 +1144,7 @@ CommandCost CmdConvertRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) _additional_cash_required = ret.GetCost(); return cost; } - proc(tile, (RailType)p2, true); + proc(tile, totype, true); } cost.AddCost(ret); } -- cgit v1.2.3-54-g00ecf