/// <summary>
        /// Finds all targets of a specified type available to this character within a specified range
        /// </summary>
        /// <param name="type"></param>
        /// <param name="radius"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        public CombatController[] FindTargetsOfType(Combat.TargetingParameters type, float radius = 20f, State state = State.Active)
        {
            var hits             = Physics.OverlapSphere(transform.position, radius);
            var availableTargets = (from Collider hit in hits
                                    where hit.GetComponent <CombatController>()
                                    select hit.GetComponent <CombatController>()).ToArray();

            return(FindTargetsOfType(availableTargets, type, state));
        }
        //------------------------------------------------------------------------/
        // Methods
        //------------------------------------------------------------------------/


        /// <summary>
        /// Finds all targets of a specified type available to this character
        /// </summary>
        /// <param name="availableTargets"></param>
        /// <param name="type"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        public CombatController[] FindTargetsOfType(CombatController[] availableTargets, Combat.TargetingParameters type, State state = State.Active)
        {
            CombatController[] targets = null;
            // var targets = new List<CombatController>();
            if (type == Combat.TargetingParameters.Self)
            {
                targets = new CombatController[] { this };
            }
            else if (type == Combat.TargetingParameters.Ally)
            {
                switch (this.faction)
                {
                case CombatController.Faction.Player:
                    targets = FilterTargets(availableTargets, Faction.Player);
                    break;

                case CombatController.Faction.Hostile:
                    targets = FilterTargets(availableTargets, Faction.Hostile);
                    break;

                case CombatController.Faction.Neutral:
                    targets = FilterTargets(availableTargets, Faction.Hostile | Faction.Player);
                    break;
                }
            }
            // ENEMIES0
            else if (type == Combat.TargetingParameters.Enemy)
            {
                switch (this.faction)
                {
                case CombatController.Faction.Player:
                    targets = FilterTargets(availableTargets, Faction.Hostile);
                    break;

                case CombatController.Faction.Hostile:
                    targets = FilterTargets(availableTargets, Faction.Player);
                    break;

                case CombatController.Faction.Neutral:
                    targets = FilterTargets(availableTargets, Faction.Hostile | Faction.Player);
                    break;
                }
            }

            return((from CombatController controller in targets where controller.currentState == state select controller).ToArray());
        }
 /// <summary>
 /// Evaluates a list of possible targets according to this targeting model
 /// </summary>
 /// <param name="caster"></param>
 /// <param name="target"></param>
 /// <param name="type"></param>
 /// <returns></returns>
 public abstract CombatController[] EvaluateTargets(CombatController caster, CombatController[] targets, Combat.TargetingParameters type);
        /// <summary>
        /// Given an array of combatants, filters out those who aren't valid targets for the given targeting parameters.
        /// </summary>
        /// <param name="user"></param>
        /// <param name="availableTargets"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public static CombatController[] FilterTargets(CombatController user, CombatController[] availableTargets, Combat.TargetingParameters type)
        {
            CombatController[] targets = null;

            // Self
            if (type == Combat.TargetingParameters.Self)
            {
                targets = new CombatController[1] {
                    user
                };
            }

            // Allies
            else if (type == Combat.TargetingParameters.Ally)
            {
                switch (user.faction)
                {
                case CombatController.Faction.Player:
                    targets = (from CombatController target in availableTargets where target.faction == CombatController.Faction.Player select target).ToArray();
                    break;

                case CombatController.Faction.Hostile:
                    targets = (from CombatController target in availableTargets where target.faction == CombatController.Faction.Hostile select target).ToArray();
                    break;

                case CombatController.Faction.Neutral:
                    targets = (from CombatController target in availableTargets where target.faction == CombatController.Faction.Neutral select target).ToArray();
                    break;
                }
            }

            // Enemies
            else if (type == Combat.TargetingParameters.Enemy)
            {
                switch (user.faction)
                {
                case CombatController.Faction.Player:
                    targets = (from CombatController target in availableTargets where target.faction == CombatController.Faction.Hostile select target).ToArray();
                    break;

                case CombatController.Faction.Hostile:
                    targets = (from CombatController target in availableTargets where target.faction == CombatController.Faction.Player select target).ToArray();
                    break;

                case CombatController.Faction.Neutral:
                    targets = (from CombatController target in availableTargets
                               where (target.faction == CombatController.Faction.Player || target.faction == CombatController.Faction.Hostile)
                               select target).ToArray();
                    break;
                }
            }

            // Any
            else if (type == Combat.TargetingParameters.Any)
            {
                targets = availableTargets;
            }

            return((from CombatController controller in targets where controller.currentState == CombatController.State.Active select controller).ToArray());
        }
 public override CombatController[] EvaluateTargets(CombatController caster, CombatController[] targets, Combat.TargetingParameters type)
 {
     return(FilterTargets(caster, targets, type).Where(x => Vector3.Distance(x.transform.position, caster.transform.position) <= this.range).ToArray());
 }