Macro Help. Events on Target Area of a spell

While SendChatMessage does require a hardware event now, an interesting thing with hardware events is that you can do stuff while a hardware event is happening and get “credit” for it. (In Vanilla I wrote an addon that would cast the instant-cast Inner Fire self buff when you needed it while you were moving around by piggy backing CastSpellByName onto the movement keys.)

And while it’s been almost 14 years since we could CastSpellByName for class buffs, we can still use the same principle in events that happen during hardware events.

This is how my warriors heroic leap:

local key = "SHIFT-C"
if select(2,UnitClass("player"))=="WARRIOR" then
   local button = CreateFrame("Button","HeroicLeapOnUp",nil,"SecureActionButtonTemplate")
   button:RegisterForClicks("AnyDown","AnyUp")
   button:SetAttribute("type","macro")
   SecureHandlerWrapScript(button,"OnClick",button,[[
     if down then
       self:SetAttribute("macrotext","/cast heroic leap")
     else
       self:SetAttribute("macrotext","/stopspelltarget\n/cast [@cursor] heroic leap")
     end
   ]])
   button:RegisterEvent("PLAYER_LOGIN")
   button:SetScript("OnEvent",function(self,event,...)
     SetOverrideBindingClick(self,true,key,"HeroicLeapOnUp")
   end)
end

Rather than hitting a key, moving the reticle where you want to leap and then clicking the mouse; with this you press the key down, move the reticle where you want to leap and then release the key. You’ll leap to wherever the mouse was when you let go. (The @cursor does the same thing but without the ability to use the reticle to target a spot.)

In this scenario you can choose an OnKeyUp or OnAttributeChanged or probably a few other options that are valid during the hardware events that caused them. The following uses OnAttributeChanged because it’s one you wouldn’t intuitively expect to work:

local key = "SHIFT-C"
if select(2,UnitClass("player"))=="WARRIOR" then
   local button = CreateFrame("Button","HeroicLeapOnUp",nil,"SecureActionButtonTemplate")
   button:RegisterForClicks("AnyDown","AnyUp")
   button:SetAttribute("type","macro")
   SecureHandlerWrapScript(button,"OnClick",button,[[
 if down then
   self:SetAttribute("macrotext","/cast heroic leap")
 else
   self:SetAttribute("macrotext","/stopspelltarget\n/cast [@cursor] heroic leap")
 end
   ]])
   button:RegisterEvent("PLAYER_LOGIN")
   button:SetScript("OnEvent",function(self,event,...)
 SetOverrideBindingClick(self,true,key,"HeroicLeapOnUp")
   end)
   button:SetScript("OnAttributeChanged",function(self,attribType,attribValue)
  if (attribValue or ""):match("^/stopspell.+heroic leap$") then
      if GetSpellCooldown(6544)==0 then
          SendChatMessage("Hi there","say")
      end
  end
   end)
   button:SetScript("PostClick",function(self) self:SetAttribute("macrotext",nil) end)
end

The PostClick is there so that if the attribute changes by some other means it won’t trigger a chat when you’re not leaping. For a more practical use I recommend OnKeyUp.

3 Likes