Skip to content
View in the app

A better way to browse. Learn more.

WRobot

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Walking into multiple mobs to target far away, pulls 3+

Featured Replies

I've tried writing custom plugins to blacklist with a scan around the NPC it targets and it's still  not even reasonably useful. The radius it checks for attack before being attacked in is so small and blindsided. 

I'll watch it set a path with a node on top of an hostile NPC?

I've added every possible mob in the area to my target list, it will still make the stupidest choices of target, like the mob in the back and run up to range pulling everything.

It will try and  attack another mob if your pet is being hit and not you.

Blacklisted NPCs are treated as if theyre invisible and will 100% kill you while bot attempts to go kill other targets.

 

Why not sort potential targets by  distance? Why not check node paths for nearby enemies when walking, can these be added please?

Gonna dump some code here I've used to experiment, you can adjust it for your own needs:

public class SmartPulls
{

    private static WoWLocalPlayer Me = ObjectManager.Me;
    private static int _checkDistance = 22;
    private static int _frontDistance = 15;

    public static void Start()
    {
        if (PluginSettings.CurrentSetting.SmartPulls)
        {
            FightEvents.OnFightStart += FightValidityCheck;
            Radar3D.OnDrawEvent += Radar3DOnOnDrawEvent;
        }
    }

    private static void Radar3DOnOnDrawEvent()
    {
        if (Radar3D.IsLaunched)
        {
            Vector3 rightPlayerVector = Helper.CalculatePosition(Me.Position,
                -Helper.Atan2Rotation(Me.Position, Me.Position, Me.Rotation), -_checkDistance);
            Vector3 leftPlayerVector = Helper.CalculatePosition(Me.Position,
                -Helper.Atan2Rotation(Me.Position, Me.Position, Me.Rotation), _checkDistance);

            Vector3 rightTargetVector = Helper.CalculatePosition(rightPlayerVector,
                -Helper.Atan2Rotation(Me.Position, rightPlayerVector, 0), _checkDistance + _frontDistance);
            Vector3 leftTargetVector = Helper.CalculatePosition(leftPlayerVector,
                -Helper.Atan2Rotation(Me.Position, leftPlayerVector, 0), -(_checkDistance + _frontDistance));

            Radar3D.DrawCircle(rightPlayerVector, 2.5f, Color.Blue);
            Radar3D.DrawCircle(leftPlayerVector, 2.5f, Color.Green);
            Radar3D.DrawCircle(rightTargetVector, 2.5f, Color.Yellow);
            Radar3D.DrawCircle(leftTargetVector, 2.5f, Color.DarkRed);

            Radar3D.DrawLine(rightPlayerVector, leftPlayerVector, Color.Gold);
            Radar3D.DrawLine(leftPlayerVector, leftTargetVector, Color.Gold);
            Radar3D.DrawLine(leftTargetVector, rightTargetVector, Color.Gold);
            Radar3D.DrawLine(rightTargetVector, rightPlayerVector, Color.Gold);
        }
    }

    public static void Stop()
    {
        FightEvents.OnFightStart -= FightValidityCheck;
        Radar3D.OnDrawEvent -= Radar3DOnOnDrawEvent;
    }

    public static void Pulse()
    {
        if (PluginSettings.CurrentSetting.SmartPulls && !Escape.IsEscaping && Me.Target > 0 && !Fight.InFight && !Me.InCombatFlagOnly && Logging.Status != "Regeneration" && !Me.HaveBuff("Resurrection Sickness"))
        {
            Vector3 rightPlayerVector = Helper.CalculatePosition(Me.Position,
                -Helper.Atan2Rotation(Me.Position, Me.Position, Me.Rotation), -_checkDistance);
            Vector3 leftPlayerVector = Helper.CalculatePosition(Me.Position,
                -Helper.Atan2Rotation(Me.Position, Me.Position, Me.Rotation), _checkDistance);

            Vector3 rightTargetVector = Helper.CalculatePosition(rightPlayerVector,
                -Helper.Atan2Rotation(Me.Position, rightPlayerVector, 0), _checkDistance + _frontDistance);
            Vector3 leftTargetVector = Helper.CalculatePosition(leftPlayerVector,
                -Helper.Atan2Rotation(Me.Position, leftPlayerVector, 0), -(_checkDistance + _frontDistance));

            List<Vector3> boundBox = new List<Vector3>
            {
                rightPlayerVector,
                leftPlayerVector,
                rightTargetVector,
                leftTargetVector
            };
            
            WoWUnit unit = ObjectManager.GetObjectWoWUnit()
                .Where(o => o.IsAlive && o.Reaction == Reaction.Hostile && !o.IsPet && !o.IsPlayer() && o.Guid != Me.Target &&
                            (o.Level >= Me.Level ? o.Level - Me.Level <= 3 : Me.Level - o.Level <= 6) 
                            && VectorHelper.PointInPolygon2D(boundBox, o.Position)
                            && !TraceLine.TraceLineGo(Me.Position, o.Position, CGWorldFrameHitFlags.HitTestSpellLoS)
                            && !wManagerSetting.IsBlackListed(o.Guid))
                .OrderBy(o => o.GetDistance)
                .FirstOrDefault();

            if (unit != null)
            {
                PluginLog.Log($"{unit.Name} is in our way, attacking!");
                MovementManager.StopMoveTo(false, 500);
                ObjectManager.Me.Target = unit.Guid;
                Fight.StartFight(unit.Guid);
                ObjectManager.Me.Target = unit.Guid;
            }
        }
    }
    
    //don't pull another target if we are already in combat with anyone (e.g. body pulled mobs)
    private static void FightValidityCheck(WoWUnit unit, CancelEventArgs cancelable)
    {
        if (Escape.IsEscaping || ObjectManager.GetObjectWoWUnit().Count(u => u.IsTargetingMeOrMyPet && u.Reaction == Reaction.Hostile) > 0)
        {
            return;
        }
        
        if (CheckForGroup(unit, cancelable))
        {
            MovementManager.StopMoveTo(false, 500);
            cancelable.Cancel = true;
            return;
        }

        if (CheckForClearPath(unit, cancelable))
        {
            MovementManager.StopMoveTo(false, 500);
            cancelable.Cancel = true;
            return;
        }
    }

    private static bool CheckForGroup(WoWUnit unit, CancelEventArgs cancelable)
    {
        // group too large, nothing we can do, stop fight and go away
        int addAmount = ObjectManager.GetObjectWoWUnit().Count(o =>
            o.IsAlive && o.Reaction == Reaction.Hostile && o.Guid != unit.Guid &&
            o.Position.DistanceTo(unit.Position) <= 12 && !o.IsTargetingMeOrMyPetOrPartyMember);
        if (addAmount > 1)
        {
            wManagerSetting.AddBlackList(unit.Guid, 60000);
            Fight.StopFight();
            Lua.LuaDoString("ClearTarget()");
            wManagerSetting.AddBlackListZone(unit.Position, 30 + addAmount * 5);
            PathFinder.ReportBigDangerArea(unit.Position, 30 + addAmount * 5);
            PluginLog.Log("Stopping pull on large group!");
            return true;
        }
        return false;
    }

    private static bool CheckForClearPath(WoWUnit unit, CancelEventArgs cancelable)
    {
        if (Me.InCombatFlagOnly)
        {
            return false;
        }
        
        Vector3 rightPlayerVector = Helper.CalculatePosition(Me.Position, -Helper.Atan2Rotation(unit.Position, Me.Position, 0), _checkDistance);
        Vector3 leftPlayerVector = Helper.CalculatePosition(Me.Position, -Helper.Atan2Rotation(unit.Position, Me.Position, 0), -_checkDistance);
        
        Vector3 rightTargetVector = Helper.CalculatePosition(unit.Position, -Helper.Atan2Rotation(Me.Position, unit.Position, 0), -_checkDistance);
        Vector3 leftTargetVector = Helper.CalculatePosition(unit.Position, -Helper.Atan2Rotation(Me.Position, unit.Position, 0), _checkDistance);

        List<Vector3> boundingBox = new List<Vector3>{rightPlayerVector, leftPlayerVector, rightTargetVector, leftTargetVector};

        if (ObjectManager.GetObjectWoWUnit().FirstOrDefault(o =>
                o.IsAlive && o.Reaction == Reaction.Hostile && o.Guid != unit.Guid && 
                VectorHelper.PointInPolygon2D(boundingBox, o.Position)) != null)
        {
            
            WoWUnit newEnemy = ObjectManager.GetObjectWoWUnit()
                .Where(o => o.IsAlive && o.Reaction == Reaction.Hostile && o.SummonedBy <= 0 && !o.IsPlayer() && o.Guid != unit.Guid && !wManagerSetting.IsBlackListed(o.Guid) && !wManagerSetting.IsBlackListedNpcEntry(o.Entry))
                .OrderBy(o => o.GetDistance)
                .FirstOrDefault();
            if (newEnemy != null)
            {
                wManagerSetting.AddBlackList(unit.Guid, 60000);
                Fight.StopFight();
                Fight.StartFight(newEnemy.Guid);
                PluginLog.Log($"Enemy in the way, can't pull here - pulling {newEnemy.Name} instead");
            }
            return true;
        }
        
        return false;
    }

}

 

  • Author
12 hours ago, Matenia said:

Gonna dump some code here I've used to experiment, you can adjust it for your own needs:


public class SmartPulls
{

    private static WoWLocalPlayer Me = ObjectManager.Me;
    private static int _checkDistance = 22;
    private static int _frontDistance = 15;

    public static void Start()
    {
        if (PluginSettings.CurrentSetting.SmartPulls)
        {
            FightEvents.OnFightStart += FightValidityCheck;
            Radar3D.OnDrawEvent += Radar3DOnOnDrawEvent;
        }
    }

    private static void Radar3DOnOnDrawEvent()
    {
        if (Radar3D.IsLaunched)
        {
            Vector3 rightPlayerVector = Helper.CalculatePosition(Me.Position,
                -Helper.Atan2Rotation(Me.Position, Me.Position, Me.Rotation), -_checkDistance);
            Vector3 leftPlayerVector = Helper.CalculatePosition(Me.Position,
                -Helper.Atan2Rotation(Me.Position, Me.Position, Me.Rotation), _checkDistance);

            Vector3 rightTargetVector = Helper.CalculatePosition(rightPlayerVector,
                -Helper.Atan2Rotation(Me.Position, rightPlayerVector, 0), _checkDistance + _frontDistance);
            Vector3 leftTargetVector = Helper.CalculatePosition(leftPlayerVector,
                -Helper.Atan2Rotation(Me.Position, leftPlayerVector, 0), -(_checkDistance + _frontDistance));

            Radar3D.DrawCircle(rightPlayerVector, 2.5f, Color.Blue);
            Radar3D.DrawCircle(leftPlayerVector, 2.5f, Color.Green);
            Radar3D.DrawCircle(rightTargetVector, 2.5f, Color.Yellow);
            Radar3D.DrawCircle(leftTargetVector, 2.5f, Color.DarkRed);

            Radar3D.DrawLine(rightPlayerVector, leftPlayerVector, Color.Gold);
            Radar3D.DrawLine(leftPlayerVector, leftTargetVector, Color.Gold);
            Radar3D.DrawLine(leftTargetVector, rightTargetVector, Color.Gold);
            Radar3D.DrawLine(rightTargetVector, rightPlayerVector, Color.Gold);
        }
    }

    public static void Stop()
    {
        FightEvents.OnFightStart -= FightValidityCheck;
        Radar3D.OnDrawEvent -= Radar3DOnOnDrawEvent;
    }

    public static void Pulse()
    {
        if (PluginSettings.CurrentSetting.SmartPulls && !Escape.IsEscaping && Me.Target > 0 && !Fight.InFight && !Me.InCombatFlagOnly && Logging.Status != "Regeneration" && !Me.HaveBuff("Resurrection Sickness"))
        {
            Vector3 rightPlayerVector = Helper.CalculatePosition(Me.Position,
                -Helper.Atan2Rotation(Me.Position, Me.Position, Me.Rotation), -_checkDistance);
            Vector3 leftPlayerVector = Helper.CalculatePosition(Me.Position,
                -Helper.Atan2Rotation(Me.Position, Me.Position, Me.Rotation), _checkDistance);

            Vector3 rightTargetVector = Helper.CalculatePosition(rightPlayerVector,
                -Helper.Atan2Rotation(Me.Position, rightPlayerVector, 0), _checkDistance + _frontDistance);
            Vector3 leftTargetVector = Helper.CalculatePosition(leftPlayerVector,
                -Helper.Atan2Rotation(Me.Position, leftPlayerVector, 0), -(_checkDistance + _frontDistance));

            List<Vector3> boundBox = new List<Vector3>
            {
                rightPlayerVector,
                leftPlayerVector,
                rightTargetVector,
                leftTargetVector
            };
            
            WoWUnit unit = ObjectManager.GetObjectWoWUnit()
                .Where(o => o.IsAlive && o.Reaction == Reaction.Hostile && !o.IsPet && !o.IsPlayer() && o.Guid != Me.Target &&
                            (o.Level >= Me.Level ? o.Level - Me.Level <= 3 : Me.Level - o.Level <= 6) 
                            && VectorHelper.PointInPolygon2D(boundBox, o.Position)
                            && !TraceLine.TraceLineGo(Me.Position, o.Position, CGWorldFrameHitFlags.HitTestSpellLoS)
                            && !wManagerSetting.IsBlackListed(o.Guid))
                .OrderBy(o => o.GetDistance)
                .FirstOrDefault();

            if (unit != null)
            {
                PluginLog.Log($"{unit.Name} is in our way, attacking!");
                MovementManager.StopMoveTo(false, 500);
                ObjectManager.Me.Target = unit.Guid;
                Fight.StartFight(unit.Guid);
                ObjectManager.Me.Target = unit.Guid;
            }
        }
    }
    
    //don't pull another target if we are already in combat with anyone (e.g. body pulled mobs)
    private static void FightValidityCheck(WoWUnit unit, CancelEventArgs cancelable)
    {
        if (Escape.IsEscaping || ObjectManager.GetObjectWoWUnit().Count(u => u.IsTargetingMeOrMyPet && u.Reaction == Reaction.Hostile) > 0)
        {
            return;
        }
        
        if (CheckForGroup(unit, cancelable))
        {
            MovementManager.StopMoveTo(false, 500);
            cancelable.Cancel = true;
            return;
        }

        if (CheckForClearPath(unit, cancelable))
        {
            MovementManager.StopMoveTo(false, 500);
            cancelable.Cancel = true;
            return;
        }
    }

    private static bool CheckForGroup(WoWUnit unit, CancelEventArgs cancelable)
    {
        // group too large, nothing we can do, stop fight and go away
        int addAmount = ObjectManager.GetObjectWoWUnit().Count(o =>
            o.IsAlive && o.Reaction == Reaction.Hostile && o.Guid != unit.Guid &&
            o.Position.DistanceTo(unit.Position) <= 12 && !o.IsTargetingMeOrMyPetOrPartyMember);
        if (addAmount > 1)
        {
            wManagerSetting.AddBlackList(unit.Guid, 60000);
            Fight.StopFight();
            Lua.LuaDoString("ClearTarget()");
            wManagerSetting.AddBlackListZone(unit.Position, 30 + addAmount * 5);
            PathFinder.ReportBigDangerArea(unit.Position, 30 + addAmount * 5);
            PluginLog.Log("Stopping pull on large group!");
            return true;
        }
        return false;
    }

    private static bool CheckForClearPath(WoWUnit unit, CancelEventArgs cancelable)
    {
        if (Me.InCombatFlagOnly)
        {
            return false;
        }
        
        Vector3 rightPlayerVector = Helper.CalculatePosition(Me.Position, -Helper.Atan2Rotation(unit.Position, Me.Position, 0), _checkDistance);
        Vector3 leftPlayerVector = Helper.CalculatePosition(Me.Position, -Helper.Atan2Rotation(unit.Position, Me.Position, 0), -_checkDistance);
        
        Vector3 rightTargetVector = Helper.CalculatePosition(unit.Position, -Helper.Atan2Rotation(Me.Position, unit.Position, 0), -_checkDistance);
        Vector3 leftTargetVector = Helper.CalculatePosition(unit.Position, -Helper.Atan2Rotation(Me.Position, unit.Position, 0), _checkDistance);

        List<Vector3> boundingBox = new List<Vector3>{rightPlayerVector, leftPlayerVector, rightTargetVector, leftTargetVector};

        if (ObjectManager.GetObjectWoWUnit().FirstOrDefault(o =>
                o.IsAlive && o.Reaction == Reaction.Hostile && o.Guid != unit.Guid && 
                VectorHelper.PointInPolygon2D(boundingBox, o.Position)) != null)
        {
            
            WoWUnit newEnemy = ObjectManager.GetObjectWoWUnit()
                .Where(o => o.IsAlive && o.Reaction == Reaction.Hostile && o.SummonedBy <= 0 && !o.IsPlayer() && o.Guid != unit.Guid && !wManagerSetting.IsBlackListed(o.Guid) && !wManagerSetting.IsBlackListedNpcEntry(o.Entry))
                .OrderBy(o => o.GetDistance)
                .FirstOrDefault();
            if (newEnemy != null)
            {
                wManagerSetting.AddBlackList(unit.Guid, 60000);
                Fight.StopFight();
                Fight.StartFight(newEnemy.Guid);
                PluginLog.Log($"Enemy in the way, can't pull here - pulling {newEnemy.Name} instead");
            }
            return true;
        }
        
        return false;
    }

}

 

Wish I could tip you mate, thanks so much.

Create an account or sign in to comment

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.