/// <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); }