Wowpedia

We have moved to Warcraft Wiki. Click here for information and the new URL.

READ MORE

Wowpedia
Register
Advertisement

2.0 and beyond

Prior to the 2.0 patch, detecting instant spells was a messy affair involving hooking and the use of vague events. However, the client now has the tools needed to accurately and consistently detect instant cast abilities.

Using UNIT_SPELLCAST_SUCCEEDED to track instant casts

The core event here is UNIT_SPELLCAST_SUCCEEDED (hereafter _SUCCEEDED). This event fires whenever a spellcast is completed server end, regardless of whether it is instant, channeled, or cast. Therefore whenever an instant cast has been used successfully, this event will fire. However, the inverse is not true; there are times when _SUCCEEDED will fire but the spell is not instant. The next tool we need is a way to discern whether a spell is instant or not.

Watching for UNIT_SPELLCAST_START and UNIT_SPELLCAST_STOP

All spells eventually trigger _SUCCEEDED so long as they work, but not all trigger _START. Particularly, channeled and cast spells trigger _START, but instant cast spells do not. We can build the following chain of logic, then:

  • If _START is heard, the next _SUCCEEDED will not be an instant spell, unless the spell is interrupted. Once you start casting a spell, it will either finish or be interrupted before an instant cast can occur.
  • Every time a spell is completed, no matter its instant or noninstant nature, _STOP will be heard.
  • For instant spells, _STOP is heard after _SUCCEEDED.

Knowing this, we can detect instant spells by registering for _SUCCEEDED and _START. If _START_ is heard, unregister _SUCCEEDED (as we have to wait for the cast time spell to finish first) and register for _STOP. When _STOP is heard, reregister for _SUCCEEDED. This will ensure that you only hear _SUCCEEDED when a spell is instant cast.

Example code

-- you should replace this with a better one
local print = function (msg)
  DEFAULT_CHAT_FRAME:AddMessage(msg)
end

SampleTrackerFunctions = { }

SampleTracker = CreateFrame("Frame", nil, UIParent)
SampleTracker:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED")
SampleTracker:RegisterEvent("UNIT_SPELLCAST_START")
SampleTracker:SetScript("OnEvent", function (_,e) SampleTrackerFunctions[e]() end)

----
function SampleTrackerFunctions.UNIT_SPELLCAST_SUCCEEDED()
  DEFAULT_CHAT_FRAME:AddMessage("An instant spell has been cast!")
end
----
function SampleTrackerFunctions.UNIT_SPELLCAST_START()
  SampleTracker:UnregisterEvent("UNIT_SPELLCAST_SUCCEEDED")
  SampleTracker:RegisterEvent("UNIT_SPELLCAST_STOP")
end
----
function SampleTrackerFunctions.UNIT_SPELLCAST_STOP()
  SampleTracker:UnregisterEvent("UNIT_SPELLCAST_STOP")
  SampleTracker:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED")
end
Advertisement