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.