Ejemplo n.º 1
0
        public PBEMoveLockPacket(PBEPokemon moveUser, PBEMove lockedMove, PBETarget lockedTargets, PBEMoveLockType moveLockType)
        {
            var bytes = new List <byte>();

            bytes.AddRange(BitConverter.GetBytes(Code));
            bytes.Add((byte)(MoveUser = moveUser.FieldPosition));
            bytes.Add((MoveUserTeam = moveUser.Team).Id);
            bytes.AddRange(BitConverter.GetBytes((ushort)(LockedMove = lockedMove)));
            bytes.Add((byte)(LockedTargets = lockedTargets));
            bytes.Add((byte)(MoveLockType = moveLockType));
            Buffer = BitConverter.GetBytes((short)bytes.Count).Concat(bytes);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Determines whether chosen targets are valid for a given move.
        /// </summary>
        /// <param name="pkmn">The Pokémon that will act.</param>
        /// <param name="move">The move the Pokémon wishes to use.</param>
        /// <param name="targets">The targets bitfield to validate.</param>
        /// <exception cref="ArgumentOutOfRangeException">Thrown when <paramref name="targets"/>, <paramref name="move"/>, <paramref name="pkmn"/>'s <see cref="PBEPokemon.FieldPosition"/>, or <paramref name="pkmn"/>'s <see cref="PBEBattle"/>'s <see cref="BattleFormat"/> is invalid.</exception>
        public static bool AreTargetsValid(PBEPokemon pkmn, PBEMove move, PBETarget targets)
        {
            if (move == PBEMove.None || move >= PBEMove.MAX)
            {
                throw new ArgumentOutOfRangeException(nameof(move));
            }
            PBEMoveTarget possibleTargets = pkmn.GetMoveTargets(move);

            switch (pkmn.Team.Battle.BattleFormat)
            {
            case PBEBattleFormat.Single:
            {
                switch (possibleTargets)
                {
                case PBEMoveTarget.All:
                {
                    if (pkmn.FieldPosition == PBEFieldPosition.Center)
                    {
                        return(targets == (PBETarget.AllyCenter | PBETarget.FoeCenter));
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition));
                    }
                }

                case PBEMoveTarget.AllFoes:
                case PBEMoveTarget.AllFoesSurrounding:
                case PBEMoveTarget.AllSurrounding:
                case PBEMoveTarget.SingleFoeSurrounding:
                case PBEMoveTarget.SingleNotSelf:
                case PBEMoveTarget.SingleSurrounding:
                {
                    if (pkmn.FieldPosition == PBEFieldPosition.Center)
                    {
                        return(targets == PBETarget.FoeCenter);
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition));
                    }
                }

                case PBEMoveTarget.AllTeam:
                case PBEMoveTarget.Self:
                case PBEMoveTarget.SelfOrAllySurrounding:
                {
                    if (pkmn.FieldPosition == PBEFieldPosition.Center)
                    {
                        return(targets == PBETarget.AllyCenter);
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition));
                    }
                }

                case PBEMoveTarget.RandomFoeSurrounding:
                case PBEMoveTarget.SingleAllySurrounding:
                {
                    if (pkmn.FieldPosition == PBEFieldPosition.Center)
                    {
                        return(true);
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition));
                    }
                }

                default: throw new ArgumentOutOfRangeException(nameof(possibleTargets));
                }
            }

            case PBEBattleFormat.Double:
            {
                switch (possibleTargets)
                {
                case PBEMoveTarget.All:
                {
                    if (pkmn.FieldPosition == PBEFieldPosition.Left || pkmn.FieldPosition == PBEFieldPosition.Right)
                    {
                        return(targets == (PBETarget.AllyLeft | PBETarget.AllyRight | PBETarget.FoeLeft | PBETarget.FoeRight));
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition));
                    }
                }

                case PBEMoveTarget.AllFoes:
                case PBEMoveTarget.AllFoesSurrounding:
                {
                    if (pkmn.FieldPosition == PBEFieldPosition.Left || pkmn.FieldPosition == PBEFieldPosition.Right)
                    {
                        return(targets == (PBETarget.FoeLeft | PBETarget.FoeRight));
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition));
                    }
                }

                case PBEMoveTarget.AllTeam:
                {
                    if (pkmn.FieldPosition == PBEFieldPosition.Left || pkmn.FieldPosition == PBEFieldPosition.Right)
                    {
                        return(targets == (PBETarget.AllyLeft | PBETarget.AllyRight));
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition));
                    }
                }

                case PBEMoveTarget.AllSurrounding:
                {
                    if (pkmn.FieldPosition == PBEFieldPosition.Left)
                    {
                        return(targets == (PBETarget.AllyRight | PBETarget.FoeLeft | PBETarget.FoeRight));
                    }
                    else if (pkmn.FieldPosition == PBEFieldPosition.Right)
                    {
                        return(targets == (PBETarget.AllyLeft | PBETarget.FoeLeft | PBETarget.FoeRight));
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition));
                    }
                }

                case PBEMoveTarget.Self:
                {
                    if (pkmn.FieldPosition == PBEFieldPosition.Left)
                    {
                        return(targets == PBETarget.AllyLeft);
                    }
                    else if (pkmn.FieldPosition == PBEFieldPosition.Right)
                    {
                        return(targets == PBETarget.AllyRight);
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition));
                    }
                }

                case PBEMoveTarget.SelfOrAllySurrounding:
                {
                    if (pkmn.FieldPosition == PBEFieldPosition.Left || pkmn.FieldPosition == PBEFieldPosition.Right)
                    {
                        return(targets == PBETarget.AllyLeft || targets == PBETarget.AllyRight);
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition));
                    }
                }

                case PBEMoveTarget.SingleAllySurrounding:
                {
                    if (pkmn.FieldPosition == PBEFieldPosition.Left)
                    {
                        return(targets == PBETarget.AllyRight);
                    }
                    else if (pkmn.FieldPosition == PBEFieldPosition.Right)
                    {
                        return(targets == PBETarget.AllyLeft);
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition));
                    }
                }

                case PBEMoveTarget.SingleFoeSurrounding:
                {
                    if (pkmn.FieldPosition == PBEFieldPosition.Left || pkmn.FieldPosition == PBEFieldPosition.Right)
                    {
                        return(targets == PBETarget.FoeLeft || targets == PBETarget.FoeRight);
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition));
                    }
                }

                case PBEMoveTarget.SingleNotSelf:
                case PBEMoveTarget.SingleSurrounding:
                {
                    if (pkmn.FieldPosition == PBEFieldPosition.Left)
                    {
                        return(targets == PBETarget.AllyRight || targets == PBETarget.FoeLeft || targets == PBETarget.FoeRight);
                    }
                    else if (pkmn.FieldPosition == PBEFieldPosition.Right)
                    {
                        return(targets == PBETarget.AllyLeft || targets == PBETarget.FoeLeft || targets == PBETarget.FoeRight);
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition));
                    }
                }

                case PBEMoveTarget.RandomFoeSurrounding:
                {
                    if (pkmn.FieldPosition == PBEFieldPosition.Left || pkmn.FieldPosition == PBEFieldPosition.Right)
                    {
                        return(true);
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition));
                    }
                }

                default: throw new ArgumentOutOfRangeException(nameof(possibleTargets));
                }
            }

            case PBEBattleFormat.Triple:
            {
                switch (possibleTargets)
                {
                case PBEMoveTarget.All:
                {
                    if (pkmn.FieldPosition == PBEFieldPosition.Left || pkmn.FieldPosition == PBEFieldPosition.Center || pkmn.FieldPosition == PBEFieldPosition.Right)
                    {
                        return(targets == (PBETarget.AllyLeft | PBETarget.AllyCenter | PBETarget.AllyRight | PBETarget.FoeLeft | PBETarget.FoeCenter | PBETarget.FoeRight));
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition));
                    }
                }

                case PBEMoveTarget.AllFoes:
                {
                    if (pkmn.FieldPosition == PBEFieldPosition.Left || pkmn.FieldPosition == PBEFieldPosition.Center || pkmn.FieldPosition == PBEFieldPosition.Right)
                    {
                        return(targets == (PBETarget.FoeLeft | PBETarget.FoeCenter | PBETarget.FoeRight));
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition));
                    }
                }

                case PBEMoveTarget.AllFoesSurrounding:
                {
                    if (pkmn.FieldPosition == PBEFieldPosition.Left)
                    {
                        return(targets == (PBETarget.FoeCenter | PBETarget.FoeRight));
                    }
                    else if (pkmn.FieldPosition == PBEFieldPosition.Center)
                    {
                        return(targets == (PBETarget.FoeLeft | PBETarget.FoeCenter | PBETarget.FoeRight));
                    }
                    else if (pkmn.FieldPosition == PBEFieldPosition.Right)
                    {
                        return(targets == (PBETarget.FoeLeft | PBETarget.FoeCenter));
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition));
                    }
                }

                case PBEMoveTarget.AllSurrounding:
                {
                    if (pkmn.FieldPosition == PBEFieldPosition.Left)
                    {
                        return(targets == (PBETarget.AllyCenter | PBETarget.FoeCenter | PBETarget.FoeRight));
                    }
                    else if (pkmn.FieldPosition == PBEFieldPosition.Center)
                    {
                        return(targets == (PBETarget.AllyLeft | PBETarget.AllyRight | PBETarget.FoeLeft | PBETarget.FoeCenter | PBETarget.FoeRight));
                    }
                    else if (pkmn.FieldPosition == PBEFieldPosition.Right)
                    {
                        return(targets == (PBETarget.AllyCenter | PBETarget.FoeLeft | PBETarget.FoeCenter));
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition));
                    }
                }

                case PBEMoveTarget.AllTeam:
                {
                    if (pkmn.FieldPosition == PBEFieldPosition.Left || pkmn.FieldPosition == PBEFieldPosition.Center || pkmn.FieldPosition == PBEFieldPosition.Right)
                    {
                        return(targets == (PBETarget.AllyLeft | PBETarget.AllyCenter | PBETarget.AllyRight));
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition));
                    }
                }

                case PBEMoveTarget.Self:
                {
                    if (pkmn.FieldPosition == PBEFieldPosition.Left)
                    {
                        return(targets == PBETarget.AllyLeft);
                    }
                    else if (pkmn.FieldPosition == PBEFieldPosition.Center)
                    {
                        return(targets == PBETarget.AllyCenter);
                    }
                    else if (pkmn.FieldPosition == PBEFieldPosition.Right)
                    {
                        return(targets == PBETarget.AllyRight);
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition));
                    }
                }

                case PBEMoveTarget.SelfOrAllySurrounding:
                {
                    if (pkmn.FieldPosition == PBEFieldPosition.Left)
                    {
                        return(targets == PBETarget.AllyLeft || targets == PBETarget.AllyCenter);
                    }
                    else if (pkmn.FieldPosition == PBEFieldPosition.Center)
                    {
                        return(targets == PBETarget.AllyLeft || targets == PBETarget.AllyCenter || targets == PBETarget.AllyRight);
                    }
                    else if (pkmn.FieldPosition == PBEFieldPosition.Right)
                    {
                        return(targets == PBETarget.AllyCenter || targets == PBETarget.AllyRight);
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition));
                    }
                }

                case PBEMoveTarget.SingleAllySurrounding:
                {
                    if (pkmn.FieldPosition == PBEFieldPosition.Left)
                    {
                        return(targets == PBETarget.AllyCenter);
                    }
                    else if (pkmn.FieldPosition == PBEFieldPosition.Center)
                    {
                        return(targets == PBETarget.AllyLeft || targets == PBETarget.AllyRight);
                    }
                    else if (pkmn.FieldPosition == PBEFieldPosition.Right)
                    {
                        return(targets == PBETarget.AllyCenter);
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition));
                    }
                }

                case PBEMoveTarget.SingleFoeSurrounding:
                {
                    if (pkmn.FieldPosition == PBEFieldPosition.Left)
                    {
                        return(targets == PBETarget.FoeCenter || targets == PBETarget.FoeRight);
                    }
                    else if (pkmn.FieldPosition == PBEFieldPosition.Center)
                    {
                        return(targets == PBETarget.FoeLeft || targets == PBETarget.FoeCenter || targets == PBETarget.FoeRight);
                    }
                    else if (pkmn.FieldPosition == PBEFieldPosition.Right)
                    {
                        return(targets == PBETarget.FoeLeft || targets == PBETarget.FoeCenter);
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition));
                    }
                }

                case PBEMoveTarget.SingleNotSelf:
                {
                    if (pkmn.FieldPosition == PBEFieldPosition.Left)
                    {
                        return(targets == PBETarget.AllyCenter || targets == PBETarget.AllyRight || targets == PBETarget.FoeLeft || targets == PBETarget.FoeCenter || targets == PBETarget.FoeRight);
                    }
                    else if (pkmn.FieldPosition == PBEFieldPosition.Center)
                    {
                        return(targets == PBETarget.AllyLeft || targets == PBETarget.AllyRight || targets == PBETarget.FoeLeft || targets == PBETarget.FoeCenter || targets == PBETarget.FoeRight);
                    }
                    else if (pkmn.FieldPosition == PBEFieldPosition.Right)
                    {
                        return(targets == PBETarget.AllyLeft || targets == PBETarget.AllyCenter || targets == PBETarget.FoeLeft || targets == PBETarget.FoeCenter || targets == PBETarget.FoeRight);
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition));
                    }
                }

                case PBEMoveTarget.SingleSurrounding:
                {
                    if (pkmn.FieldPosition == PBEFieldPosition.Left)
                    {
                        return(targets == PBETarget.AllyCenter || targets == PBETarget.FoeCenter || targets == PBETarget.FoeRight);
                    }
                    else if (pkmn.FieldPosition == PBEFieldPosition.Center)
                    {
                        return(targets == PBETarget.AllyLeft || targets == PBETarget.AllyRight || targets == PBETarget.FoeLeft || targets == PBETarget.FoeCenter || targets == PBETarget.FoeRight);
                    }
                    else if (pkmn.FieldPosition == PBEFieldPosition.Right)
                    {
                        return(targets == PBETarget.AllyCenter || targets == PBETarget.FoeLeft || targets == PBETarget.FoeCenter);
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition));
                    }
                }

                case PBEMoveTarget.RandomFoeSurrounding:
                {
                    if (pkmn.FieldPosition == PBEFieldPosition.Left || pkmn.FieldPosition == PBEFieldPosition.Center || pkmn.FieldPosition == PBEFieldPosition.Right)
                    {
                        return(true);
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition));
                    }
                }

                default: throw new ArgumentOutOfRangeException(nameof(possibleTargets));
                }
            }

            case PBEBattleFormat.Rotation:
            {
                switch (possibleTargets)
                {
                case PBEMoveTarget.All:
                {
                    if (pkmn.FieldPosition == PBEFieldPosition.Left || pkmn.FieldPosition == PBEFieldPosition.Center || pkmn.FieldPosition == PBEFieldPosition.Right)
                    {
                        return(targets == (PBETarget.AllyCenter | PBETarget.FoeCenter));
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition));
                    }
                }

                case PBEMoveTarget.AllFoes:
                case PBEMoveTarget.AllFoesSurrounding:
                case PBEMoveTarget.AllSurrounding:
                case PBEMoveTarget.SingleFoeSurrounding:
                case PBEMoveTarget.SingleNotSelf:
                case PBEMoveTarget.SingleSurrounding:
                {
                    if (pkmn.FieldPosition == PBEFieldPosition.Left || pkmn.FieldPosition == PBEFieldPosition.Center || pkmn.FieldPosition == PBEFieldPosition.Right)
                    {
                        return(targets == PBETarget.FoeCenter);
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition));
                    }
                }

                case PBEMoveTarget.AllTeam:
                case PBEMoveTarget.Self:
                case PBEMoveTarget.SelfOrAllySurrounding:
                {
                    if (pkmn.FieldPosition == PBEFieldPosition.Left || pkmn.FieldPosition == PBEFieldPosition.Center || pkmn.FieldPosition == PBEFieldPosition.Right)
                    {
                        return(targets == PBETarget.AllyCenter);
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition));
                    }
                }

                case PBEMoveTarget.RandomFoeSurrounding:
                case PBEMoveTarget.SingleAllySurrounding:
                {
                    if (pkmn.FieldPosition == PBEFieldPosition.Left || pkmn.FieldPosition == PBEFieldPosition.Center || pkmn.FieldPosition == PBEFieldPosition.Right)
                    {
                        return(true);
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition));
                    }
                }

                default: throw new ArgumentOutOfRangeException(nameof(possibleTargets));
                }
            }

            default: throw new ArgumentOutOfRangeException(nameof(pkmn.Team.Battle.BattleFormat));
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Gets all Pokémon that will be hit.
        /// </summary>
        /// <param name="user">The Pokémon that will act.</param>
        /// <param name="requestedTargets">The targets the Pokémon wishes to hit.</param>
        /// <param name="canHitFarCorners">Whether the move can hit far Pokémon in a triple battle.</param>
        static PBEPokemon[] GetRuntimeTargets(PBEPokemon user, PBETarget requestedTargets, bool canHitFarCorners)
        {
            PBETeam opposingTeam = user.Team == user.Team.Battle.Teams[0] ? user.Team.Battle.Teams[1] : user.Team.Battle.Teams[0];

            var targets = new List <PBEPokemon>();

            if (requestedTargets.HasFlag(PBETarget.AllyLeft))
            {
                targets.Add(user.Team.TryGetPokemon(PBEFieldPosition.Left));
            }
            if (requestedTargets.HasFlag(PBETarget.AllyCenter))
            {
                targets.Add(user.Team.TryGetPokemon(PBEFieldPosition.Center));
            }
            if (requestedTargets.HasFlag(PBETarget.AllyRight))
            {
                targets.Add(user.Team.TryGetPokemon(PBEFieldPosition.Right));
            }
            if (requestedTargets.HasFlag(PBETarget.FoeLeft))
            {
                PBEPokemon pkmn = opposingTeam.TryGetPokemon(PBEFieldPosition.Left);
                if (pkmn == null)
                {
                    if (user.Team.Battle.BattleFormat == PBEBattleFormat.Double)
                    {
                        pkmn = opposingTeam.TryGetPokemon(PBEFieldPosition.Right);
                    }
                    else if (user.Team.Battle.BattleFormat == PBEBattleFormat.Triple)
                    {
                        pkmn = opposingTeam.TryGetPokemon(PBEFieldPosition.Center);
                        // Center fainted as well and user can reach far right
                        if (pkmn == null && (user.FieldPosition != PBEFieldPosition.Right || canHitFarCorners))
                        {
                            pkmn = opposingTeam.TryGetPokemon(PBEFieldPosition.Right);
                        }
                    }
                }
                targets.Add(pkmn);
            }
            if (requestedTargets.HasFlag(PBETarget.FoeCenter))
            {
                PBEPokemon pkmn = opposingTeam.TryGetPokemon(PBEFieldPosition.Center);
                // Target fainted, fallback to its teammate
                if (pkmn == null)
                {
                    if (user.Team.Battle.BattleFormat == PBEBattleFormat.Triple)
                    {
                        if (user.FieldPosition == PBEFieldPosition.Left)
                        {
                            pkmn = opposingTeam.TryGetPokemon(PBEFieldPosition.Right);
                            // Right fainted as well and user can reach far left
                            if (pkmn == null && (user.FieldPosition != PBEFieldPosition.Left || canHitFarCorners))
                            {
                                pkmn = opposingTeam.TryGetPokemon(PBEFieldPosition.Left);
                            }
                        }
                        else if (user.FieldPosition == PBEFieldPosition.Right)
                        {
                            pkmn = opposingTeam.TryGetPokemon(PBEFieldPosition.Left);
                            // Left fainted as well and user can reach far right
                            if (pkmn == null && (user.FieldPosition != PBEFieldPosition.Right || canHitFarCorners))
                            {
                                pkmn = opposingTeam.TryGetPokemon(PBEFieldPosition.Right);
                            }
                        }
                        else // Center
                        {
                            PBEPokemon oppLeft  = opposingTeam.TryGetPokemon(PBEFieldPosition.Left),
                                       oppRight = opposingTeam.TryGetPokemon(PBEFieldPosition.Right);
                            // Left is dead but not right
                            if (oppLeft == null && oppRight != null)
                            {
                                pkmn = oppRight;
                            }
                            // Right is dead but not left
                            else if (oppLeft != null && oppRight == null)
                            {
                                pkmn = oppLeft;
                            }
                            // Randomly select left or right
                            else
                            {
                                pkmn = PBEUtils.RNG.NextBoolean() ? oppLeft : oppRight;
                            }
                        }
                    }
                }
                targets.Add(pkmn);
            }
            if (requestedTargets.HasFlag(PBETarget.FoeRight))
            {
                PBEPokemon pkmn = opposingTeam.TryGetPokemon(PBEFieldPosition.Right);
                // Target fainted, fallback to its teammate
                if (pkmn == null)
                {
                    if (user.Team.Battle.BattleFormat == PBEBattleFormat.Double)
                    {
                        pkmn = opposingTeam.TryGetPokemon(PBEFieldPosition.Left);
                    }
                    else if (user.Team.Battle.BattleFormat == PBEBattleFormat.Triple)
                    {
                        pkmn = opposingTeam.TryGetPokemon(PBEFieldPosition.Center);
                        // Center fainted as well and user can reach far left
                        if (pkmn == null && (user.FieldPosition != PBEFieldPosition.Left || canHitFarCorners))
                        {
                            pkmn = opposingTeam.TryGetPokemon(PBEFieldPosition.Left);
                        }
                    }
                }
                targets.Add(pkmn);
            }
            return(targets.Where(p => p != null).Distinct().ToArray()); // Remove duplicate targets
        }