Ejemplo n.º 1
0
        /// <summary>
        /// Select the best (up to) <num> targets (in <targetType> order) satisfying <predicate> from the threat list and stores them in <targetList> (which is cleared first).
        /// If <offset> is nonzero, the first <offset> entries in <targetType> order (or MAXTHREAT order, if <targetType> is RANDOM) are skipped.
        /// </summary>
        public List <Unit> SelectTargetList(uint num, SelectAggroTarget targetType, uint offset, ICheck <Unit> selector)
        {
            var targetList = new List <Unit>();

            ThreatManager mgr = GetThreatManager();

            // shortcut: we're gonna ignore the first <offset> elements, and there's at most <offset> elements, so we ignore them all - nothing to do here
            if (mgr.GetThreatListSize() <= offset)
            {
                return(targetList);
            }

            if (targetType == SelectAggroTarget.MaxDistance || targetType == SelectAggroTarget.MinDistance)
            {
                foreach (HostileReference refe in mgr.GetThreatList())
                {
                    if (!refe.IsOnline())
                    {
                        continue;
                    }

                    targetList.Add(refe.GetTarget());
                }
            }
            else
            {
                Unit currentVictim = mgr.GetCurrentVictim();
                if (currentVictim != null)
                {
                    targetList.Add(currentVictim);
                }

                foreach (HostileReference refe in mgr.GetThreatList())
                {
                    if (!refe.IsOnline())
                    {
                        continue;
                    }

                    Unit thisTarget = refe.GetTarget();
                    if (thisTarget != currentVictim)
                    {
                        targetList.Add(thisTarget);
                    }
                }
            }

            // shortcut: the list isn't gonna get any larger
            if (targetList.Count <= offset)
            {
                targetList.Clear();
                return(targetList);
            }

            // right now, list is unsorted for DISTANCE types - re-sort by MAXDISTANCE
            if (targetType == SelectAggroTarget.MaxDistance || targetType == SelectAggroTarget.MinDistance)
            {
                SortByDistance(targetList, targetType == SelectAggroTarget.MinDistance);
            }

            // now the list is MAX sorted, reverse for MIN types
            if (targetType == SelectAggroTarget.MinThreat)
            {
                targetList.Reverse();
            }

            // ignore the first <offset> elements
            while (offset != 0)
            {
                targetList.RemoveAt(0);
                --offset;
            }

            // then finally filter by predicate
            targetList.RemoveAll(unit => !selector.Invoke(unit));

            if (targetList.Count <= num)
            {
                return(targetList);
            }

            if (targetType == SelectAggroTarget.Random)
            {
                targetList = targetList.SelectRandom(num).ToList();
            }
            else
            {
                targetList.Resize(num);
            }

            return(targetList);
        }