public PlayerTargetSelector(TargetingSettings settings, Player referer, TargetingOptions options, List <Unit> previousTargets)
            {
                this.settings        = settings;
                this.previousTargets = previousTargets;
                this.options         = options;
                this.referer         = referer;

                switch (options.Distance)
                {
                case TargetingDistance.Any:
                    bestTargetPrevousIndex = int.MaxValue;
                    break;

                case TargetingDistance.Near:
                    bestTargetDistance = float.MaxValue;
                    break;

                case TargetingDistance.Far:
                    bestTargetDistance = float.MinValue;
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(options.Distance));
                }
            }
        public void SelectTarget(TargetingOptions options)
        {
            if (!Player.ExistsIn(World))
            {
                return;
            }

            switch (options.Mode)
            {
            case TargetingMode.Normal:
                using (var selector = new PlayerTargetSelector(targetingSettings, Player, options, previousTargets))
                {
                    Player.Map.VisitInRadius(Player, targetingSettings.TargetRange, selector);
                    input.SelectTarget(selector.BestTarget);
                    if (selector.BestTarget != null)
                    {
                        previousTargets.Remove(selector.BestTarget);
                        previousTargets.Add(selector.BestTarget);
                    }
                    else
                    {
                        previousTargets.Clear();
                    }
                }
                break;

            case TargetingMode.Self:
                if (Player.Target != Player)
                {
                    input.SelectTarget(Player);
                }
                break;

            case TargetingMode.Clear:
                if (Player.Target != null)
                {
                    input.SelectTarget(null);
                }
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(options.Mode), $"Unknown targeting kind: {options.Mode}");
            }
        }