What's new
  • Visit Rebornbuddy
  • Visit Panda Profiles
  • Visit LLamamMagic
  • Visit Resources
  • Visit Downloads
  • Visit Portal

Problem with ThreatInfo

handnavi

Well-Known Member
Joined
Jan 15, 2010
Messages
2,489
Reaction score
59
Hi!
I wrote a simple function, that should return a WoWUnit, if another player of my group reaches atleast 85% of my aggro.
It seems, that it doesnt work very well. Did i something wrong? Or does ThreatInfo.RawPercent fail alot? Sometimes it works, sometimes it throws really funny numbers.

Here is my code:

Code:
        public WoWUnit PlayerNuke()
        {
            foreach (WoWPlayer d in Me.PartyMembers)
            {
                if (d.Guid != StyxWoW.Me.Guid)
                {
                    if (d.CurrentTarget != null && d.CurrentTarget.IsAlive && !d.CurrentTarget.IsPlayer && (d.CurrentTarget.IsTargetingMyPartyMember || d.IsTargetingMeOrPet))
                    {
                        if (d.CurrentTarget.ThreatInfo.RawPercent > 85 && d.CurrentTarget.ThreatInfo.ThreatValue > 1000)
                        {
                            return d.CurrentTarget;
                        }
                    }
                }
            }
            return null;
        }
 
Would be interested to hear if you come up with a solution. I have tried but ended up with the same results.
 
Take a look at Singular TankTargeting class:

Code:
#region Revision Info

// This file is part of Singular - A community driven Honorbuddy CC
// $Author: raphus $
// $Date: 2011-03-20 20:04:10 +0100 (s?, 20 mar 2011) $
// $HeadURL: http://svn.apocdev.com/singular/tags/v1/Singular/TankTargeting.cs $
// $LastChangedBy: raphus $
// $LastChangedDate: 2011-03-20 20:04:10 +0100 (s?, 20 mar 2011) $
// $LastChangedRevision: 195 $
// $Revision: 195 $

#endregion

using System.Collections.Generic;
using System.Linq;

using Styx;
using Styx.Logic;
using Styx.Logic.Combat;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;

namespace Singular
{
    /*
     * Targeting works like so, in order of being called
     * 
     * GetInitialObjectList - Return a list of initial objects for the targeting to use.
     * RemoveTargetsFilter - Remove anything that doesn't belong in the list.
     * IncludeTargetsFilter - If you want to include units regardless of the remove filter
     * WeighTargetsFilter - Weigh each target in the list.     
     *
     */

    internal class TankTargeting : Targeting
    {
        static TankTargeting()
        {
            Instance = new TankTargeting();
            Instance.NeedToTaunt = new List<WoWUnit>();
        }

        public new static TankTargeting Instance { get; set; }
        public List<WoWUnit> NeedToTaunt { get; private set; }

        protected override List<WoWObject> GetInitialObjectList()
        {
            return ObjectManager.GetObjectsOfType<WoWUnit>(false, false).Cast<WoWObject>().ToList();
        }

        protected override void DefaultRemoveTargetsFilter(List<WoWObject> units)
        {
            for (int i = units.Count - 1; i >= 0; i--)
            {
                if (!units[i].IsValid)
                {
                    units.RemoveAt(i);
                    continue;
                }

                WoWUnit u = units[i].ToUnit();

                if (u.IsFriendly || u.Dead || u.IsPet() || !u.Combat || IsCrowdControlled(u))
                {
                    units.RemoveAt(i);
                    continue;
                }

                if (u.CurrentTarget != null)
                {
                    WoWUnit tar = u.CurrentTarget;
                    if (tar.IsPlayer && tar.IsHostile)
                    {
                        units.RemoveAt(i);
                        continue;
                    }
                }
            }
        }

        protected override void DefaultIncludeTargetsFilter(List<WoWObject> incomingUnits, HashSet<WoWObject> outgoingUnits)
        {
            foreach (WoWObject i in incomingUnits)
            {
                outgoingUnits.Add(i);
            }
        }

        protected override void DefaultTargetWeight(List<TargetPriority> units)
        {
            NeedToTaunt.Clear();
            List<WoWPlayer> members = StyxWoW.Me.IsInRaid ? StyxWoW.Me.RaidMembers : StyxWoW.Me.PartyMembers;
            foreach (TargetPriority p in units)
            {
                WoWUnit u = p.Object.ToUnit();

                // I have 1M threat -> nearest party has 990k -> leaves 10k difference. Subtract 10k
                // I have 1M threat -> nearest has 400k -> Leaves 600k difference -> subtract 600k
                // The further the difference, the less the unit is weighted.
                // If they have MORE threat than I do, the number is -10k -> which subtracted = +10k weight.
                int aggroDiff = GetAggroDifferenceFor(u, members);
                p.Score -= aggroDiff;

                // If we have NO threat on the mob. Taunt the fucking thing.
                // Don't taunt fleeing mobs!
                if (aggroDiff < 0 && !u.Fleeing)
                {
                    NeedToTaunt.Add(u);
                }
            }
        }

        private bool IsCrowdControlled(WoWUnit unit)
        {
            Dictionary<string, WoWAura>.ValueCollection auras = unit.Auras.Values;

            return auras.Any(
                a => a.Spell.Mechanic == WoWSpellMechanic.Banished ||
                     a.Spell.Mechanic == WoWSpellMechanic.Charmed ||
                     a.Spell.Mechanic == WoWSpellMechanic.Horrified ||
                     a.Spell.Mechanic == WoWSpellMechanic.Incapacitated ||
                     a.Spell.Mechanic == WoWSpellMechanic.Polymorphed ||
                     a.Spell.Mechanic == WoWSpellMechanic.Sapped ||
                     a.Spell.Mechanic == WoWSpellMechanic.Shackled ||
                     a.Spell.Mechanic == WoWSpellMechanic.Asleep ||
                     a.Spell.Mechanic == WoWSpellMechanic.Frozen
                     );
        }

        private int GetAggroDifferenceFor(WoWUnit unit, IEnumerable<WoWPlayer> partyMembers)
        {
            uint myThreat = unit.ThreatInfo.ThreatValue;
            uint highestParty = (from p in partyMembers
                                 let tVal = unit.GetThreatInfoFor(p).ThreatValue
                                 orderby tVal descending
                                 select tVal).FirstOrDefault();

            int result = (int)myThreat - (int)highestParty;
            return result;
        }
		
    }
}
 
Back
Top