/// <summary>
        /// Links the given slave device to the closest master device.
        /// <para>If the distance to the closest master device exceeds the multitool connection's range,
        /// then the slave's master device will be set as <c>null</c>.</para>
        /// <remarks><see cref="InitDeviceLists(MultitoolConnectionType)"/> is assumed to have been run.</remarks>
        /// </summary>
        /// <returns>The distance to the closest master device, connected or not. <c>-1</c> if no masters found.</returns>
        public static float TryLinkSlaveToClosestMaster(IMultitoolSlaveable slave)
        {
            if (Masters.Count < 1)
            {
                return(-1);
            }

            SortMastersToPosition(slave.gameObject.transform.position);

            float distance = Vector3.Distance(slave.gameObject.transform.position, Masters[0].gameObject.transform.position);

            slave.SetMasterEditor(distance > Masters[0].MaxDistance ? null : Masters[0]);

            return(distance);
        }
        /// <summary>
        /// Links the given slave device to the next master device in the given direction.
        /// <para>If the distance to the closest master device exceeds the multitool connection's range,
        /// then no action will take place.</para>
        /// <remarks><see cref="InitDeviceLists(MultitoolConnectionType)"/> is assumed to have been run.</remarks>
        /// </summary>
        /// <param name="direction">Expecting <c>1</c> for the next closest device, <c>-1</c> for closer.</param>
        /// <returns>The distance to the next master device. <c>-1</c> if no masters found.</returns>
        public static float TryLinkToNextMaster(IMultitoolSlaveable slave, int direction)
        {
            if (Masters.Count < 1)
            {
                return(-1);
            }

            SortMastersToPosition(slave.gameObject.transform.position);

            var index = slave.Master == null ? 0 : Masters.IndexOf(slave.Master);

            index = Mathf.Clamp(index + direction, 0, Masters.Count - 1);
            var master   = Masters[index];
            var distance = Vector3.Distance(slave.gameObject.transform.position, master.gameObject.transform.position);

            if (distance <= master.MaxDistance)
            {
                slave.SetMasterEditor(master);
            }

            return(distance);
        }
        public override void OnInspectorGUI()
        {
            // Render default inspector for the component.
            base.OnInspectorGUI();

            EditorGUILayout.HelpBox("You can connect all slave devices at once via\n`Tools/Mapping/Device Linker`.", MessageType.Info);

            // Don't show connection elements; not relevant to runtime or prefab edit mode.
            if (Application.isPlaying || PrefabStageUtility.GetCurrentPrefabStage() != null)
            {
                return;
            }

            DeviceLinker.InitDeviceLists(thisDevice.ConType);

            if (thisDevice.RequireLink && thisDevice.Master == null)
            {
                EditorGUILayout.HelpBox("Not connected to any master device!", MessageType.Warning);
            }

            GUILayout.Label("Connect to a master device:");

            GUILayout.BeginHorizontal();
            if (GUILayout.Button("Closest"))
            {
                closestMasterDistance = DeviceLinker.TryLinkSlaveToClosestMaster(thisDevice);
                Save();
            }
            if (thisDevice.Master != null)
            {
                if (GUILayout.Button("Closer"))
                {
                    DeviceLinker.TryLinkToNextMaster(thisDevice, -1);
                    Save();
                }
                else if (GUILayout.Button("Further"))
                {
                    DeviceLinker.TryLinkToNextMaster(thisDevice, 1);
                    Save();
                }
            }
            GUILayout.EndHorizontal();

            if (closestMasterDistance == -1)
            {
                GUILayout.Label($"No master devices found!", EditorUIUtils.LabelStyle);
            }
            else if (closestMasterDistance > DeviceLinker.Masters[0].MaxDistance)
            {
                GUILayout.Label($"Closest master device is <b>{closestMasterDistance, 0:N}</b> tiles away, " +
                                $"but this exceeds the maximum distance of <b>{DeviceLinker.Masters[0].MaxDistance}</b>!", EditorUIUtils.LabelStyle);
            }

            if (thisDevice.Master != null)
            {
                GUILayout.BeginHorizontal();
                var distance = Vector3.Distance(thisDevice.gameObject.transform.position, thisDevice.Master.gameObject.transform.position);
                GUILayout.Label($"Connected to <b>{thisDevice.Master.gameObject.name}</b> " +
                                $"(distance of <b>{distance, 0:N}</b> tiles).", EditorUIUtils.LabelStyle);
                if (GUILayout.Button("Clear", GUILayout.Width(EditorGUIUtility.currentViewWidth / 4)))
                {
                    thisDevice.SetMasterEditor(null);
                    Save();
                }
                GUILayout.EndHorizontal();
            }
        }