WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (https://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   Need some help with my first addon (https://www.wowinterface.com/forums/showthread.php?t=54555)

luanoob 09-28-16 12:06 PM

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

Sweetsour 09-28-16 12:19 PM

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)

Seerah 09-28-16 07:18 PM

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.

luanoob 09-28-16 11:29 PM

Quote:

Originally Posted by Sweetsour (Post 319442)
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.

Quote:

Originally Posted by Seerah (Post 319452)
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.

SDPhantom 09-29-16 01:01 AM

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.

Sweetsour 09-29-16 01:16 AM

Quote:

Originally Posted by SDPhantom (Post 319456)
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?

SDPhantom 09-29-16 01:31 AM

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.

Fizzlemizz 09-29-16 01:37 AM

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.

luanoob 09-30-16 04:00 PM

Quote:

Originally Posted by SDPhantom (Post 319456)
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)

Sweetsour 09-30-16 05:23 PM

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.

sticklord 09-30-16 05:23 PM

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)

luanoob 10-01-16 01:58 AM

Quote:

Originally Posted by Sweetsour (Post 319532)
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.

Quote:

Originally Posted by sticklord (Post 319533)
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:D
Thanks a lot guys, really appreciate it!


All times are GMT -6. The time now is 04:43 PM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI