1. #1

    Question Event firing too often - Please help

    Hello,

    I am extremely new to LUA and have worked on this for about five hours now. My code, below, fires when any buff starts or stops. I only want it to fire when the buff listed (in this case, rogue's Feint) completes.

    Code:
    local frame = CreateFrame("Frame")
    local _, _, _, _, _, _, expirationTime = UnitAura("player", "Feint");
    frame:RegisterEvent("UNIT_AURA")
    frame:SetScript("OnEvent", function()
    	if  (expirationTime==nil) then
    		print("Feint is ready!");
    	end
    end)
    Seems like it should be simple, but I'm knocking my head around this and am getting nowhere. Any help would be appreciated.

    Thanks,

    --S

  2. #2
    If you only want to track your aura, use:
    frame:RegisterUnitEvent ("UNIT_AURA", "player")

    There is more ways to check, but RegisterUnitEvent and UnitAura are the faster one.

  3. #3
    Quote Originally Posted by Tercio View Post
    There is more ways to check, but RegisterUnitEvent and UnitAura are the faster one.

    Right, another way could be to use CLEU



    Code:
    local f = CreateFrame("Frame")
    local playerGUID
    
    C_Timer.After(.1, function() -- wait a bit
    	playerGUID = UnitGUID("player")
    end)
    
    function f:OnEvent(event, _, subevent, _, sourceGUID, _, _, _, _, _, _, _, spellID)
    	if subevent == "SPELL_AURA_REMOVED" and sourceGUID == playerGUID and spellID == 1966 then
    		print(GetSpellLink(spellID).." is ready!")
    	end
    end
    
    f:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
    f:SetScript("OnEvent", f.OnEvent)

  4. #4
    The UNIT_AURA event is fired every time an aura is applied, removed or refreshed which means if you are executing code when that event is triggered you will need to account for it, or find a better way to get what you need to know. Ketho's post shows a way to do this, if you only want to know about YOUR aura's then I suggest using
    Code:
    RegisterUnitEvent("UNIT_AURA_APPLIED", "player")
    and
    Code:
    RegisterUnitEvent("UNIT_AURA_REMOVED", "player")
    then check the spellID
    Last edited by kaelyth; 2016-07-13 at 06:49 AM.

  5. #5
    Thank you all very much. I appreciate the information. Being new to LUA (and programming in general), I see that I have much to learn. I will try these when I get back home and see what I can come up with. The code examples and explanations are much appreciated!

    --S

  6. #6
    The Patient Goldpaw's Avatar
    10+ Year Old Account
    Join Date
    Dec 2010
    Location
    Kristiansand, Norway
    Posts
    346
    Quote Originally Posted by sintrigue View Post
    Hello,

    I am extremely new to LUA and have worked on this for about five hours now. My code, below, fires when any buff starts or stops. I only want it to fire when the buff listed (in this case, rogue's Feint) completes.

    Code:
    local frame = CreateFrame("Frame")
    local _, _, _, _, _, _, expirationTime = UnitAura("player", "Feint");
    frame:RegisterEvent("UNIT_AURA")
    frame:SetScript("OnEvent", function()
    	if  (expirationTime==nil) then
    		print("Feint is ready!");
    	end
    end)
    Seems like it should be simple, but I'm knocking my head around this and am getting nowhere. Any help would be appreciated.

    Thanks,

    --S

    Another obvious bug here is that you only read the 'expirationTime' once, and that's when the addon starts. Meaning your function will ALWAYS fire, everytime something about any player's aura fires. Regardless of whether or not you're using unit events or "normal" ones, this bug will cause it to be wrong no matter what happens!

    Also, by using the name of the aura in UnitAura, this will only work for English gaming clients. I would suggest using spellIDs instead, as these will work for all clients, in all regions of the world.

    This is what I would have done. Might be some typos, as I didn't test it. But anyway:

    Code:
    local has_feint -- we will use this to track when Feint is active
    local feint_spellID = 1966 -- spellID of Feint, according to Wowhead
    
    local frame = CreateFrame("Frame")
    frame:RegisterEvent("UNIT_AURA")
    frame:SetScript("OnEvent", function(self, event, ...)
    	-- If we don't use unit events, but the general one, 
    	-- we can still see what unit the event is firing for by 
    	-- checking the first argument passed to the event function!
    	local unit = ...
    	if unit ~= "player" then
    		return
    	end
    
    	local found_feint -- whether or not we'll find it in the loop below
    
    	-- search through all auras for Feint
    	for i = 1,40 do
    		local spellID = select(11, UnitAura("player",i))
    		if spellID == feint_spellID then
    			found_feint = true -- set our local flag to indicate we found it
    			break -- exit the loop if it's found
    		end
    	end
    
    	-- if we found Feint on the player, set the variable that tracks it to true
    	if found_feint and not has_feint then
    		has_feint = true 
    	end
    
    	-- if our variable says we have Feint, but we didn't find it this time,
    	-- that means the Feint buff has run out, and it's time to use the ability again!
    	if has_feint and not found_feint then
    		print("Feint is ready!")
    		has_feint = false 
    	end
    
    end)

  7. #7
    Thank you for the example and for the spellID information. I have updated my code to reflect the spellID and not the name of the spell, as you have demonstrated above. I appreciate the information.

    --S

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •