Пример #1
0
        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();
                Contract.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);
        }