Monday, January 9, 2012

Self Modifying Macros: When One Focus isn't Enough

There are three main reasons people use their focus targets in macros: to be able to refresh crowd control without switching targets (self explanatory), to be able to refresh a buff on a friendly target without switching targets (earth shield, misdirection, etc.), and last but not least to track buffs/debuffs and/or spell casts of a specific target (i.e. a healer tracking a boss ability with focus target cast bars). The problem I've run into, and I am sure many others have as well, is that some classes could benefit from using their focus target in more than one way. We need a second focus target, and a third...

After much deliberation, preceded by a fair bit of procrastination, I've come up with a fairly elegant solution for "sharing" a single focus target; let's have the macro remember who to target. Self modifying macros have been a crazy idea in the back of my head for quite a long time, but I wasn't sure if it was possible no less feasible. Then I saw a very promising sentence on wowwiki describing the EditMacro function, "If this function is called from within the macro that is edited, the rest of the macro (from the final character's position of the /run command onward) will run the new version." Not only can you edit a macro while it is running, it will continue to run from the point it left off before being edited! This actually turned out to be a little bit of a bummer too, but more on that later.

So I have to write a macro which does what I want, leave room for an unknown player name up to 12 characters, and also leave room for some lua code to change the name on the fly; with only 255 characters total. It actually wasn't that bad, but a few more characters would have allowed for more thorough targeting conditionals.

Right off the bat there are a couple glaring limitations: you can't edit macros in combat and you can't use GUIDs to select targets (or in layman's terms some trash mobs have the same name, which one will your macro target?). I may eventually find a way around the latter, but I am pretty sure that all the target switching LUA functions are protected. Perhaps it's not really an issue either since how often are there multiple mobs in the same pull with the same name when it isn't an AOE group without CC? Still macros aren't going to be a great way to handle crowd control targets, but they are very good way to remember and retarget players; better than focus targets even if you know how annoying it can be to keep losing your focus between sections of the dragon soul raid.

So here's what I got so far: a misdirection macro for hunters and a tricks of the trade macro for rogues. Fully tested on my hunter and I really liked the way I didn't have to clutter up my UI with a focus frame I wasn't really using.

/use [btn:2];[@asecondfocus,help][help][@targettarget,help][@pet]Misdirection
/stopmacro [btn:1][noraid,noparty]
/run i=GetRunningMacro()EditMacro(i,nil,1,gsub(GetMacroBody(i),"%b@,","@"..UnitName("target")..",",1)..(" "):rep(24))

/use [btn:2];[@asecondfocus,help][help][@targettarget,help][]Tricks of the Trade
/stopmacro [btn:1][noraid,noparty]
/run i=GetRunningMacro()EditMacro(i,nil,1,gsub(GetMacroBody(i),"%b@,","@"..UnitName("target")..",",1)..(" "):rep(21))

The first couple lines look like a regular macro you'd find almost anywhere, with a few less checks perhaps (no room for those frills). I first try and target the "focus", then I try the current target and if it is a hostile I try and target it's target (hopefully a tank). For the misdirect macro I also try the pet as a last resort. If all the targeting checks fall through you'll get a hand to pick a target manually (that should almost never happen).

Then comes the LUA code which is run when the macro is right clicked. Could use a modifier instead and make the macro even shorter, but I prefer not to hit it on accident. Not to mention you can only edit macros out of combat so it's not a big deal to have it super accessible. The code is just a little pattern matching to find and replace the name, "asecondfocus" in the macros above, with the name of your current target. I do check to see if your current target is at least in your party/raid before changing it so you can't accidentally target an NPC.

Then comes this interesting block of code at the end that pads out the macro with spaces so that it is always exactly 255 characters long. This is where that "feature" that continues running a macro from where it left off before being edited comes in. If you right click on someone with a longer name that your previous target your macro text would become longer, but your macro continues running from the end of the old macro causing your character to /say those last few characters of the macro; quite annoying. For example if you target someone with a name that was 3 character longer your character would say something like, "s))". The extra spaces are inert so far as the lua code goes and they make sure the macro never changes length.

Enjoy the most advanced aggro redirection macros in existence; short of installing a plugin anyway. I prefer the macros because they are saved on the server so you can flip PCs and they are always there and you never have to update them after a patch.

1 comment:

  1. Made a couple tweaks over the last couple days to the macros. For example they weren't useful in 5-mans without the addition of a noparty check. That was pretty much it, the rest was incrementally shrinking the macros to fit that.