public HostileReference SelectNextVictim(Creature attacker, HostileReference currentVictim) { HostileReference currentRef = null; bool found = false; bool noPriorityTargetFound = false; for (var i = 0; i < threatList.Count; i++) { if (found) { break; } currentRef = threatList[i]; Unit target = currentRef.GetTarget(); Cypher.Assert(target); // if the ref has status online the target must be there ! // some units are prefered in comparison to others if (!noPriorityTargetFound && (target.IsImmunedToDamage(attacker.GetMeleeDamageSchoolMask()) || target.HasNegativeAuraWithInterruptFlag(SpellAuraInterruptFlags.TakeDamage))) { if (i != threatList.Count - 1) { // current victim is a second choice target, so don't compare threat with it below if (currentRef == currentVictim) { currentVictim = null; } continue; } else { // if we reached to this point, everyone in the threatlist is a second choice target. In such a situation the target with the highest threat should be attacked. noPriorityTargetFound = true; i = 0; continue; } } if (attacker.CanCreatureAttack(target)) // skip non attackable currently targets { if (currentVictim != null) // select 1.3/1.1 better target in comparison current target { // list sorted and and we check current target, then this is best case if (currentVictim == currentRef || currentRef.GetThreat() <= 1.1f * currentVictim.GetThreat()) { if (currentVictim != currentRef && attacker.CanCreatureAttack(currentVictim.GetTarget())) { currentRef = currentVictim; // for second case, if currentvictim is attackable } found = true; break; } if (currentRef.GetThreat() > 1.3f * currentVictim.GetThreat() || (currentRef.GetThreat() > 1.1f * currentVictim.GetThreat() && attacker.IsWithinMeleeRange(target))) { //implement 110% threat rule for targets in melee range found = true; //and 130% rule for targets in ranged distances break; //for selecting alive targets } } else // select any { found = true; break; } } } if (!found) { currentRef = null; } return(currentRef); }