Quantcast Need some help with my first addon - WoWInterface
Thread Tools Display Modes
09-28-16, 12:06 PM   #1
luanoob
A Murloc Raider
Join Date: Sep 2016
Posts: 4
Need some help with my first addon

So i wanted a really basic addon for my rogue alt, to tell me when to reroll the «roll the bones» buff.

Basically i wanted this functionality:

When i enter combat i want the text «ROLL THE BONES» to be displayed in the middle of my screen UNTILL i get either True bearing, Shark infested waters OR 2 or more buffs.

I thought that would be really simple, but it's been like 8 hours now and i still dont have it working properly.

So i figured i could ask here and hopefully someone can help me understand what i should do.

Right now it kinda works even though everything i have done is probably wrong, but i get the «ROLL THE BONES» text whenever i activate another buff and not only when im in combat. I figure this is because of the

Lua Code:
  1. textFrame:RegisterEvent("UNIT_AURA")

but i dont understand how exactly im supposed to deal with these frames and events. So if someone could show me a proper way of doing it, i would really appreciate that. All other improvement tips would be great aswell!

Another thing was the text itself, is there not a built in function or something to display the kinda text i want? Do you really need to make it like that from scratch?

Here is the lua file, the first 30 lines is only the code i copy pasted for the fading text.

http://pastebin.com/Ccw1nXi7
  Reply With Quote
09-28-16, 12:19 PM   #2
Sweetsour
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Dec 2014
Posts: 128
Well, UNIT_AURA fires when a unit's auras have changed. So when this fires, it sends you the unit that caused the event to fire. So you'd want to try something like this:

Lua Code:
  1. textFrame:HookScript("OnEvent", function(self, event, ...) -- Use "HookScript" instead
  2.  
  3.  
  4.     if (event == "UNIT_AURA") then -- need to check to only run this code when the event fired is "UNIT_AURA"
  5.         local unit = select(1,...) -- UNIT_AURA returns one arg; being the unit
  6.         local count = 0
  7.      
  8.         if (unit and unit ~= "player") then
  9.             return
  10.         end
  11.  
  12.  
  13.         --  Check player buffs against the roll the bones buffs
  14.         for buff in pairs(buffs) do
  15.             if UnitBuff("player", buff) then
  16.                 count = count + 1
  17.             end
  18.         end
  19.  
  20.         --  Give warning if need to reroll the bones
  21.         if UnitBuff("player", "True Bearing") or UnitBuff("player", "Shark Infested Waters") or count >= 2 then
  22.             textFrame:message("")
  23.         else
  24.             textFrame:message("ROLL THE BONES!!")
  25.         end
  26.     end
  27.  
  28.  
  29.  end)

Last edited by Sweetsour : 09-28-16 at 12:29 PM.
  Reply With Quote
09-28-16, 07:18 PM   #3
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,727
UNIT_AURA fires for all valid units, not just the player. The unit it fires for will be the first argument past the event name itself, and you should check if it is the unit you wish to watch for.

A better method would be to register the event specifically for the player, using
Lua Code:
  1. textframe:RegisterUnitEvent("UNIT_AURA", "player")
Then your addon will only be notified when it fires for your player.
http://wow.gamepedia.com/API_Frame_RegisterUnitEvent

Also, you don't need to use HookScript for a frame that you've created. You know which scripts are set to it, which aren't, and what they do. HookScript is good when dealing with other addons' (or the default UI's) frames when you don't want to overwrite (or possibly overwrite) what scripts are already present.
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

  Reply With Quote
09-28-16, 11:29 PM   #4
luanoob
A Murloc Raider
Join Date: Sep 2016
Posts: 4
Originally Posted by Sweetsour View Post
Well, UNIT_AURA fires when a unit's auras have changed. So when this fires, it sends you the unit that caused the event to fire. So you'd want to try something like this:

Lua Code:
  1. Code
Hello and thanks!

I tried your code but the only difference it made was that the text "ROLL THE BONES" showed all the time when not in combat, while before it would pop up whenever i used a buff like sprint when not in combat. So it didnt really fix my problem, since i would only like to have it show when in combat.

Originally Posted by Seerah View Post
UNIT_AURA fires for all valid units, not just the player. The unit it fires for will be the first argument past the event name itself, and you should check if it is the unit you wish to watch for.

A better method would be to register the event specifically for the player, using
Lua Code:
  1. textframe:RegisterUnitEvent("UNIT_AURA", "player")
Then your addon will only be notified when it fires for your player.
http://wow.gamepedia.com/API_Frame_RegisterUnitEvent

Also, you don't need to use HookScript for a frame that you've created. You know which scripts are set to it, which aren't, and what they do. HookScript is good when dealing with other addons' (or the default UI's) frames when you don't want to overwrite (or possibly overwrite) what scripts are already present.
Hey, I tried your suggested changes as well but when changing to
Lua Code:
  1. textframe:RegisterUnitEvent("UNIT_AURA", "player")
the text would not show at all.
  Reply With Quote
09-29-16, 01:01 AM   #5
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 1,918
If you react to PLAYER_REGEN_DISABLED and PLAYER_REGEN_ENABLED events, they fire when you enter or leave combat respectively.

PS: Don't ever run select(1,...), you're wasting CPU time on a call that does absolutely nothing.
__________________
ESOUI AddOns | WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)

Last edited by SDPhantom : 09-29-16 at 01:04 AM.
  Reply With Quote
09-29-16, 01:16 AM   #6
Sweetsour
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Dec 2014
Posts: 128
Originally Posted by SDPhantom View Post
PS: Don't ever run select(1,...), you're wasting CPU time on a call that does absolutely nothing.
Interesting, what would be the more ideal method?
  Reply With Quote
09-29-16, 01:31 AM   #7
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 1,918
If you're storing the value for later use: (Additional values in the vararg are ignored)
Code:
local unit=...


If you're running it through a function and just want the first value to be passed: (Parenthesis trim the value list to only allow the first to pass through)
Code:
somefunc((...))


The reason select(1,...) does nothing is because it's an arg shift function, you're telling it to shift the args so it starts at index 1, which it at the beginning of the vararg list.
__________________
ESOUI AddOns | WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)

Last edited by SDPhantom : 09-29-16 at 01:46 AM.
  Reply With Quote
09-29-16, 01:37 AM   #8
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,214
If you know the ordinal then just pad until you reach it

local x = select(1, ...) becomes
local x = ...

local x = select(3, ...) becomes
local _, _, x = ...

That said, Gello did some testing that seems to have put paid to the myth about "Don't Use select ever" but "if you know the ordinal" why add overhead.
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.

Last edited by Fizzlemizz : 09-29-16 at 01:48 AM.
  Reply With Quote
09-30-16, 04:00 PM   #9
luanoob
A Murloc Raider
Join Date: Sep 2016
Posts: 4
Originally Posted by SDPhantom View Post
If you react to PLAYER_REGEN_DISABLED and PLAYER_REGEN_ENABLED events, they fire when you enter or leave combat respectively.

PS: Don't ever run select(1,...), you're wasting CPU time on a call that does absolutely nothing.
Hey

So i have tried a couple of variants with PLAYER_REGEN_DISABLED\ENABLED. But i cant get the text to show at all when i try to tell it to not show it for out of combat, it wont show in combat either.

Would be really cool if someone could help me with how i should be testing with this event to do it properly.

One example i tried that didn't work:

Lua Code:
  1. textFrame:RegisterEvent("UNIT_AURA")
  2.  textFrame:RegisterEvent("PLAYER_REGEN_DISABLED")
  3.  textFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
  4.  textFrame:SetScript("OnEvent", function(self, event, ...)
  5.  
  6.         local combatcheck = "false"
  7.         local count = 0
  8.  
  9.     if event=="PLAYER_REGEN_DISABLED" then
  10.             combatcheck = "true"
  11.         elseif event =="PLAYER_REGEN_ENABLED" then
  12.             combatcheck = "false"
  13.         end
  14.  
  15.             if (unit and unit ~= "player") then
  16.                  return
  17.             end
  18.  
  19.              --  Check player buffs against the roll the bones buffs
  20.                 for buff in pairs(buffs) do
  21.                         if UnitBuff("player", buff) then
  22.                             count = count + 1
  23.                         end
  24.                 end
  25.  
  26.              --  Give warning if need to reroll the bones
  27.              if combatcheck == "false" then
  28.                   textFrame:message("")
  29.                 elseif combatcheck == "true" and UnitBuff("player", "True Bearing") or UnitBuff("player", "Shark Infested Waters") or count >= 2 then
  30.                      textFrame:message("")
  31.                  else
  32.                      textFrame:message("REROLL THE BONES!!".." "..combatcheck)
  33.                 end
  34.  
  35.  end)
  Reply With Quote
09-30-16, 05:23 PM   #10
Sweetsour
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Dec 2014
Posts: 128
Lua Code:
  1. textFrame:RegisterEvent("UNIT_AURA")
  2.  textFrame:RegisterEvent("PLAYER_REGEN_DISABLED")
  3.  textFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
  4.  textFrame:SetScript("OnEvent", function(self, event, ...)
  5.  
  6.         local combatcheck = "false"
  7.         local count = 0
  8.  
  9.     if event=="PLAYER_REGEN_DISABLED" then
  10.             combatcheck = true -- change to boolean
  11.         elseif event =="PLAYER_REGEN_ENABLED" then
  12.             combatcheck = false -- change to boolean
  13.         end
  14.  
  15.             if (unit and unit ~= "player") then
  16.                  return
  17.             end
  18.  
  19.              --  Check player buffs against the roll the bones buffs
  20.                 for buff in pairs(buffs) do
  21.                         if UnitBuff("player", buff) then
  22.                             count = count + 1
  23.                         end
  24.                 end
  25.  
  26.              --  Give warning if need to reroll the bones
  27.              if not combatcheck then -- same thing as cooldown == false
  28.                   textFrame:message("")
  29.                 elseif combatcheck and (UnitBuff("player", "True Bearing") or UnitBuff("player", "Shark Infested Waters") or count >= 2) then
  30.                      textFrame:message("")
  31.                  else
  32.                      textFrame:message("REROLL THE BONES!!".." "..tostring(combatcheck)) -- need to convert booldean to string to concatenate
  33.                 end
  34.  
  35.  end)

Made changes to lines 10, 12, 27, and 29.

In the last elseif (line 29), try encapsulating the "or" conditions within brackets.
  Reply With Quote
09-30-16, 05:23 PM   #11
sticklord
A Wyrmkin Dreamwalker
AddOn Author - Click to view addons
Join Date: Aug 2014
Posts: 57
Hey.

The reason why it's not working is because you made your "combatcheck" local inside the onevent function. So every time the UNIT_AURA event fires, combatcheck will be false. Also, there a boolean data type you can use instead of string. (true/false without the quotation mark)

Try this:
Lua Code:
  1. local combatcheck = false
  2.  
  3. textFrame:RegisterUnitEvent("UNIT_AURA", "player")
  4. textFrame:RegisterEvent("PLAYER_REGEN_DISABLED")
  5. textFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
  6. textFrame:SetScript("OnEvent", function(self, event, ...)
  7.  
  8.     if event=="PLAYER_REGEN_DISABLED" then
  9.         combatcheck = true
  10.  
  11.     elseif event =="PLAYER_REGEN_ENABLED" then
  12.         combatcheck = false
  13.     end
  14.  
  15.     local count = 0
  16.     for buff in pairs(buffs) do
  17.         if UnitBuff("player", buff) then
  18.             count = count + 1
  19.         end
  20.     end
  21.  
  22.     --  Give warning if need to reroll the bones
  23.     if not combatcheck then
  24.         textFrame:message("")
  25.     elseif UnitBuff("player", "True Bearing") or UnitBuff("player", "Shark Infested Waters") or count >= 2 then
  26.         textFrame:message("")
  27.     else
  28.         textFrame:message("REROLL THE BONES!!".." "..tostring(combatcheck))
  29.     end
  30. end)

Last edited by sticklord : 09-30-16 at 05:25 PM.
  Reply With Quote
10-01-16, 01:58 AM   #12
luanoob
A Murloc Raider
Join Date: Sep 2016
Posts: 4
Originally Posted by Sweetsour View Post
Lua Code:
  1. Code

Made changes to lines 10, 12, 27, and 29.

In the last elseif (line 29), try encapsulating the "or" conditions within brackets.
Originally Posted by sticklord View Post
Hey.

The reason why it's not working is because you made your "combatcheck" local inside the onevent function. So every time the UNIT_AURA event fires, combatcheck will be false. Also, there a boolean data type you can use instead of string. (true/false without the quotation mark)

Try this:
Lua Code:
  1. local combatcheck = false
  2.  
  3. textFrame:RegisterUnitEvent("UNIT_AURA", "player")
  4. textFrame:RegisterEvent("PLAYER_REGEN_DISABLED")
  5. textFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
  6. textFrame:SetScript("OnEvent", function(self, event, ...)
  7.  
  8.     if event=="PLAYER_REGEN_DISABLED" then
  9.         combatcheck = true
  10.  
  11.     elseif event =="PLAYER_REGEN_ENABLED" then
  12.         combatcheck = false
  13.     end
  14.  
  15.     local count = 0
  16.     for buff in pairs(buffs) do
  17.         if UnitBuff("player", buff) then
  18.             count = count + 1
  19.         end
  20.     end
  21.  
  22.     --  Give warning if need to reroll the bones
  23.     if not combatcheck then
  24.         textFrame:message("")
  25.     elseif UnitBuff("player", "True Bearing") or UnitBuff("player", "Shark Infested Waters") or count >= 2 then
  26.         textFrame:message("")
  27.     else
  28.         textFrame:message("REROLL THE BONES!!".." "..tostring(combatcheck))
  29.     end
  30. end)
That did it
Thanks a lot guys, really appreciate it!
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Need some help with my first addon

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off