Jump to content

[Solved] Target Switching using Grinder in Vanilla 1.12.1 5785


Recommended Posts

I have put together a few vanilla fightclasses which are working well with the Party and WRotation addons.  I've stitched them in C# using Matenia's framework and a patchwork of other code gleaned from this site.

I have a tank class, a healing class and a dps class.  They are configured thusly:

tank - uses Grinder product to follow a path, pick targets and murder things.
healer - uses Party product to follow and heal tank
dps - uses Party product to follow and assist tank

While using the Grinder product, I need to give the tank the ability to switch from its current target to taunt units that are attacking/targeting partymembers in mid-fight.  Currently the behavior is

  1. Acquire target
  2. Kill target
  3. Attack & kill remaining adds
  4. Goto 1.

When I am manually driving the tank using WRotation, I can manually pick targets at will.  I am able to switch from my current target to another without any constraints.  The healer follows and heals, the dps follows and assists.  The tank even rushes to assist partymembers AFTER the current target dies thanks to the Party product.

The problem is that when I use the Grinder product, I am unable to get my tank fightclass to switch targets DURING the fight to taunt adds off the others.  I am currently attempting this from the fightclass .DLL.

I have a series of functions inside the TANK FIGHTCLASS to ascertain if there are targets that need to be taunted off partymembers.

public static void CMD_Priotarg()
{
	WoWUnit target = GetHighPriorityUnit(25); // Returns GUID of 1st mob within 25 yds that is targeting a partymember
	if (target != null && target.Guid >= 0UL && target.IsAlive && target.GetDistance <= 25)
	{
		LuaPrint(target.Name + " is attacking a partymember.  Switching!");
		CombatUtil.TargetUnit(target);
		MovementManager.Face(target);
	}
}

   
If there's a mob that is targeting party members and needs to be taunted off them, GetHighPriorityUnit() spits out the mob's WoWUnit GUID and I use Matenia's CombatUtil.TargetUnit() function to switch to it.  I have the CMD_Priotarg() function bound to a hotkey defined by the fightclass.  It is currently working with WRotation.

I followed these two threads for guidance.

https://wrobot.eu/forums/topic/7658-prioritize-low-hp-targets/

https://wrobot.eu/forums/topic/7681-left-click-unit/

This does not work if I am using the Grinder product.  The issue is that Grinder owns the targeting.  I've put the function above in a subroutine that ticks alongside the rotation in Matenia's framework.  When it is triggered and GetHighPriorityUnit() returns a valid WoWUnit GUID, the tank will switch targets to that mob's GUID for a second, then immediately snap back to the original target.

So I found this thread

"OK, that probably means that I should be doing this via a fightloop event," I thought.

That thread referenced a few event driven fightloop code examples that are much more elegant than my CMD_Priotarg() example.  But they all yield the same unwanted behavior.  WRobot still acquires the new target and immediately switches back to the original target:

public void Initialize()
{
  try
  {
    ...
      FightEvents.OnFightLoop += new FightEvents.FightTargetHandler(Methods.FightEvents_OnFightLoop_Taunt);
    ...
    }
}

...

private static void FightEvents_OnFightLoop_Taunt(WoWUnit unit, CancelEventArgs cancelable)
{
  // If running Grinder, Gatherer or Automaton, switch to targets that are targeting partymembers
  if ((OffensiveWarrior.productCategory == "Grinder" 
       || OffensiveWarrior.productCategory == "Automaton"
       || OffensiveWarrior.productCategory == "Gatherer") && woWPlayer.IsPartyMember)
  {
    unit = Methods.GetHighPriorityUnit(8); // gets all units attacking you

    // if a mob is attacking a partymember and we haven't switched targets in the last 5sec
    if (unit != null && unit.Guid > 0UL && Methods.LastTargetSwitch.AddSeconds(5) < DateTime.Now) 
    {
      Methods.LuaPrint("FightEvents_OnFightLoop: switchTarget");

      CombatUtil.TargetUnit(attacker);
      Methods.LastTargetSwitch = DateTime.Now;
    }
  }
}

This results in the same snap back targeting behavior while running Grinder.  Works fine when using the WRotation product.

TL;DR:
I can reliably get a fightclass to switch targets after combat has been initiated when using the WRotation product.  Can the same be done with the Grinder product?  If not, is a workaround possible?

Edited by srazdokunebil
Problem was solved.
Link to comment
Share on other sites

If you're using the fightloop, you need to move to the target and switch it constantly. That's not how you wanna do this. You wanna stop the fight and restart it with the new mob. Look at my PartyHelper plugin, code is right there.

Edit: Smokie, before desperately trying to increment your post count at all cost, maybe read what the OP is actually asking.

Edited by Matenia
Link to comment
Share on other sites

..parsing AssistLeader() in FightAssist.cs from PartyHelper:

public static void AssistLeader()
{
  WoWPlayer leader = ObjectManager.GetObjectWoWPlayer().FirstOrDefault(p => p.Name == PartyFollow.LeaderName);
  if (leader == null || leader.Target == 0 || ObjectManager.Me.Target == leader.Target || leader.TargetObject.IsDead ||
      leader.TargetObject.Reaction >= Reaction.Friendly || !leader.TargetObject.IsAttackable || !IsCloseEnoughToLeader() || Me.HaveBuff("Food") || Me.HaveBuff("Drink")
      || wManagerSetting.IsBlackListed(leader.Target) || Logging.Status == "Regeneration")
  {
    return;
  }

  Fight.StopFight();
  ObjectManager.Me.Target = leader.Target;
  Fight.StartFight(leader.Target, false);
}

I simply transcribed the Fight.StopFight() and Fight.StartFight() functions into FightEvents_OnFightLoop_Taunt():

    public static void FightEvents_OnFightLoop_Taunt(WoWUnit unit, CancelEventArgs cancelable)
    {
        // If running Grinder, Gatherer or Automaton, switch to targets that are targeting partymembers
        if ((OffensiveWarrior.productCategory == "Grinder"
             || OffensiveWarrior.productCategory == "Automaton"
             || OffensiveWarrior.productCategory == "Gatherer"))
        {
            unit = Methods.GetHighPriorityUnit(8); // returns WOWUnit GUID of closest unit attacking a partymember

            // if a mob is attacking a partymember and we haven't switched targets in the last 5sec
            if (unit != null && unit.Guid > 0UL && Methods._lastTargetSwitch.AddSeconds(8) < DateTime.Now)
            {
                Methods.LuaPrint("FightEvents_OnFightLoop_Taunt switching target to: " + unit.Guid);
                Fight.StopFight();
                ObjectManager.Me.Target = unit.Guid;
                Fight.StartFight(unit.Guid, false);
                Methods._lastTargetSwitch = DateTime.Now;
            }
        }
    }

This works flawlessly.  Thank you Matenia!

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...