diff --git a/src/rail.h b/src/rail.h index b24714f9d9..8f965aa7b0 100644 --- a/src/rail.h +++ b/src/rail.h @@ -807,6 +807,34 @@ static inline Money RailBuildCost(RailType railtype) return (_price.build_rail * _railtype_cost_multiplier[railtype]) >> 3; } +/** + * Calculates the cost of rail conversion + * @param from The railtype we are converting from + * @param to The railtype we are converting to + * @return Cost per TrackBit + */ +static inline Money RailConvertCost(RailType from, RailType to) +{ + /* rail -> el. rail + * calculate the price as 5 / 4 of (cost build el. rail) - (cost build rail) + * (the price of workers to get to place is that 1/4) + */ + if (HasPowerOnRail(from, to)) { + return ((RailBuildCost(to) - RailBuildCost(from)) * 5) >> 2; + } + + /* el. rail -> rail + * calculate the price as 1 / 4 of (cost build el. rail) - (cost build rail) + * (the price of workers is 1 / 4 + price of copper sold to a recycle center) + */ + if (HasPowerOnRail(to, from)) { + return (RailBuildCost(from) - RailBuildCost(to)) >> 2; + } + + /* make the price the same as remove + build new type */ + return RailBuildCost(to) + _price.remove_rail; +} + void *UpdateTrainPowerProc(Vehicle *v, void *data); void DrawTrainDepotSprite(int x, int y, int image, RailType railtype); void DrawDefaultWaypointSprite(int x, int y, RailType railtype); diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index a507f19813..ac0464ea77 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -1201,7 +1201,7 @@ static CommandCost DoConvertRail(TileIndex tile, RailType totype, bool exec) VehicleFromPos(tile, &tile, UpdateTrainPowerProc); } - return CommandCost(RailBuildCost(totype) / 2); + return CommandCost(RailConvertCost(GetRailType(tile), totype) * CountBits(GetTrackBits(tile))); } extern CommandCost DoConvertStationRail(TileIndex tile, RailType totype, bool exec); diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index d8d8e37ce1..c1446c01c1 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -606,7 +606,7 @@ CommandCost DoConvertStreetRail(TileIndex tile, RailType totype, bool exec) VehicleFromPos(tile, &tile, UpdateTrainPowerProc); } - return CommandCost(RailBuildCost(totype) / 2); + return CommandCost(RailConvertCost(GetRailType(tile), totype)); } diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index c240fc9e7f..dabb646469 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -1309,7 +1309,7 @@ CommandCost DoConvertStationRail(TileIndex tile, RailType totype, bool exec) VehicleFromPos(tile, &tile, UpdateTrainPowerProc); } - return CommandCost(RailBuildCost(totype) / 2); + return CommandCost(RailConvertCost(GetRailType(tile), totype)); } /** diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index e0c1270f35..5c4933b682 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -774,7 +774,7 @@ CommandCost DoConvertTunnelBridgeRail(TileIndex tile, RailType totype, bool exec VehicleFromPos(endtile, &endtile, UpdateTrainPowerProc); } - return CommandCost((length + 1) * (RailBuildCost(totype) / 2)); + return CommandCost((length + 1) * RailConvertCost(GetRailType(tile), totype)); } else if (IsBridge(tile) && GetBridgeTransportType(tile) == TRANSPORT_RAIL) { TileIndex endtile = GetOtherBridgeEnd(tile); byte bridge_height = GetBridgeHeight(tile); @@ -806,7 +806,7 @@ CommandCost DoConvertTunnelBridgeRail(TileIndex tile, RailType totype, bool exec } } - return CommandCost((DistanceManhattan(tile, endtile) + 1) * (RailBuildCost(totype) / 2)); + return CommandCost((DistanceManhattan(tile, endtile) + 1) * RailConvertCost(GetRailType(tile), totype)); } else { return CMD_ERROR; }