src/tunnelbridge_cmd.cpp
changeset 7539 5f41050498bd
parent 7494 ab05bad37410
child 7548 3a679b6e8b30
equal deleted inserted replaced
7538:3741a86b9036 7539:5f41050498bd
   747  * @return            The cost and state of the operation
   747  * @return            The cost and state of the operation
   748  * @retval CMD_ERROR  An error occured during the operation.
   748  * @retval CMD_ERROR  An error occured during the operation.
   749  */
   749  */
   750 CommandCost DoConvertTunnelBridgeRail(TileIndex tile, RailType totype, bool exec)
   750 CommandCost DoConvertTunnelBridgeRail(TileIndex tile, RailType totype, bool exec)
   751 {
   751 {
   752 	TileIndex endtile;
       
   753 
       
   754 	if (IsTunnel(tile) && GetTunnelTransportType(tile) == TRANSPORT_RAIL) {
   752 	if (IsTunnel(tile) && GetTunnelTransportType(tile) == TRANSPORT_RAIL) {
   755 		uint length;
   753 		uint length;
   756 
   754 		TileIndex endtile;
   757 		if (!CheckTileOwnership(tile)) return CMD_ERROR;
   755 
   758 
   756 		/* If not coverting rail <-> el. rail, any vehicle cannot be in tunnel */
   759 		if (GetRailType(tile) == totype) return CMD_ERROR;
   757 		if (!IsCompatibleRail(GetRailType(tile), totype)) {
   760 
   758 			endtile = CheckTunnelBusy(tile, &length);
   761 		/* 'hidden' elrails can't be downgraded to normal rail when elrails are disabled */
   759 			if (endtile == INVALID_TILE) return CMD_ERROR;
   762 		if (_patches.disable_elrails && totype == RAILTYPE_RAIL && GetRailType(tile) == RAILTYPE_ELECTRIC) return CMD_ERROR;
   760 		} else {
   763 
   761 			endtile = GetOtherTunnelEnd(tile);
   764 		endtile = CheckTunnelBusy(tile, &length);
   762 			length = DistanceManhattan(tile, endtile);
   765 		if (endtile == INVALID_TILE) return CMD_ERROR;
   763 		}
   766 
   764 
   767 		if (exec) {
   765 		if (exec) {
   768 			Track track;
       
   769 			SetRailType(tile, totype);
   766 			SetRailType(tile, totype);
   770 			SetRailType(endtile, totype);
   767 			SetRailType(endtile, totype);
   771 			MarkTileDirtyByTile(tile);
   768 			MarkTileDirtyByTile(tile);
   772 			MarkTileDirtyByTile(endtile);
   769 			MarkTileDirtyByTile(endtile);
   773 
   770 
   774 			track = AxisToTrack(DiagDirToAxis(GetTunnelDirection(tile)));
   771 			Track track = AxisToTrack(DiagDirToAxis(GetTunnelDirection(tile)));
       
   772 
   775 			YapfNotifyTrackLayoutChange(tile, track);
   773 			YapfNotifyTrackLayoutChange(tile, track);
   776 			YapfNotifyTrackLayoutChange(endtile, track);
   774 			YapfNotifyTrackLayoutChange(endtile, track);
   777 		}
   775 
   778 		return CommandCost((length + 1) * (_price.build_rail / 2));
   776 			VehicleFromPos(tile, &tile, UpdateTrainPowerProc);
       
   777 			VehicleFromPos(endtile, &endtile, UpdateTrainPowerProc);
       
   778 		}
       
   779 
       
   780 		return CommandCost((length + 1) * (_price.build_rail >> 1));
   779 	} else if (IsBridge(tile) && GetBridgeTransportType(tile) == TRANSPORT_RAIL) {
   781 	} else if (IsBridge(tile) && GetBridgeTransportType(tile) == TRANSPORT_RAIL) {
   780 
   782 		TileIndex endtile = GetOtherBridgeEnd(tile);
   781 		if (!CheckTileOwnership(tile)) return CMD_ERROR;
       
   782 
       
   783 		endtile = GetOtherBridgeEnd(tile);
       
   784 		byte bridge_height = GetBridgeHeight(tile);
   783 		byte bridge_height = GetBridgeHeight(tile);
   785 
   784 
   786 		if (FindVehicleOnTileZ(tile, bridge_height) != NULL ||
   785 		if (!IsCompatibleRail(GetRailType(tile), totype) &&
       
   786 				(FindVehicleOnTileZ(tile, bridge_height) != NULL ||
   787 				FindVehicleOnTileZ(endtile, bridge_height) != NULL ||
   787 				FindVehicleOnTileZ(endtile, bridge_height) != NULL ||
   788 				IsVehicleOnBridge(tile, endtile, bridge_height)) {
   788 				IsVehicleOnBridge(tile, endtile, bridge_height))) {
   789 			return CMD_ERROR;
   789 			return CMD_ERROR;
   790 		}
   790 		}
   791 
   791 
   792 		if (GetRailType(tile) == totype) return CMD_ERROR;
       
   793 
       
   794 		if (exec) {
   792 		if (exec) {
   795 			TileIndexDiff delta;
       
   796 			Track track;
       
   797 
       
   798 			SetRailType(tile, totype);
   793 			SetRailType(tile, totype);
   799 			SetRailType(endtile, totype);
   794 			SetRailType(endtile, totype);
   800 			MarkTileDirtyByTile(tile);
   795 			MarkTileDirtyByTile(tile);
   801 			MarkTileDirtyByTile(endtile);
   796 			MarkTileDirtyByTile(endtile);
   802 
   797 
   803 			track = AxisToTrack(DiagDirToAxis(GetBridgeRampDirection(tile)));
   798 			Track track = AxisToTrack(DiagDirToAxis(GetBridgeRampDirection(tile)));
       
   799 			TileIndexDiff delta = TileOffsByDiagDir(GetBridgeRampDirection(tile));
       
   800 
   804 			YapfNotifyTrackLayoutChange(tile, track);
   801 			YapfNotifyTrackLayoutChange(tile, track);
   805 			YapfNotifyTrackLayoutChange(endtile, track);
   802 			YapfNotifyTrackLayoutChange(endtile, track);
   806 
   803 
   807 			delta = TileOffsByDiagDir(GetBridgeRampDirection(tile));
   804 			VehicleFromPos(tile, &tile, UpdateTrainPowerProc);
       
   805 			VehicleFromPos(endtile, &endtile, UpdateTrainPowerProc);
       
   806 
   808 			for (tile += delta; tile != endtile; tile += delta) {
   807 			for (tile += delta; tile != endtile; tile += delta) {
   809 				MarkTileDirtyByTile(tile); // TODO encapsulate this into a function
   808 				MarkTileDirtyByTile(tile); // TODO encapsulate this into a function
   810 			}
   809 			}
   811 		}
   810 		}
   812 
   811 
   813 		return CommandCost((DistanceManhattan(tile, endtile) + 1) * (_price.build_rail / 2));
   812 		return CommandCost((DistanceManhattan(tile, endtile) + 1) * (_price.build_rail >> 1));
   814 	} else {
   813 	} else {
   815 		return CMD_ERROR;
   814 		return CMD_ERROR;
   816 	}
   815 	}
   817 }
   816 }
   818 
   817