Thread Tools Display Modes
11-11-16, 02:42 PM   #1
_Max_Cavalera_
A Fallenroot Satyr
 
_Max_Cavalera_'s Avatar
Join Date: Dec 2007
Posts: 28
Learning, need help

Hey guys,

I started a little addon for educational purposes. I'm trying to do everything I can for my self because that's the way I usually learn best, but I just hit a strange wall.

My addon is working as intended... when it works.... because some times it just ignores the events that start it up so... it just doesn't work until one of the other events hits.

I'm sure i'm making a huge mistake somewhere, as I said, I'm just learning, it's my first ever try.

My intention isn't really for anyone to fix it, just to give me some hints on what I'm doing wrong so I can learn

Thank you

edit:. Oh btw, in case you use the addon to see how it looks, that's not at all how it's gonna look, I just made 2 lines of info available to test out if it was "printing" what I wanted xD This is a VERY early stage addon.

edit:. I completely forgot to say that the event that seems to be some times ignored is only the initial one, in my case the PLAYER_LOGIN.
I also tried PLAYER_ENTERING_WORLD and have the same problem, some times it works, some times it doesn't.

I've seen it happen on the PLAYER_SPECIALIZATION_CHANGED but it's VERY rare, but it's probably from the same reason.

The rest of them seem to work well every time, every time I use an artifact power item I look at the addon and it seems to always update instantly to that event.

Last edited by _Max_Cavalera_ : 01-17-17 at 01:49 PM.
  Reply With Quote
11-11-16, 03:38 PM   #2
MunkDev
A Scalebane Royal Guard
 
MunkDev's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2015
Posts: 431
Lua Code:
  1. function frame:m4xEventHandler(self, event, ...)
  2.     if ( HasArtifactEquipped() ) then
  3.         frame:m4xArtifact_PopulateValues()
  4.     end
  5. end

Lua Code:
  1. function frame:m4xEventHandler(event, ...)
  2.     if ( HasArtifactEquipped() ) then
  3.         self:m4xArtifact_PopulateValues()
  4.     end
  5. end

Colon syntax in a function implies the first argument is self. This probably won't fix your problem though as nothing in that function actually uses the event information.
__________________
  Reply With Quote
11-11-16, 04:10 PM   #3
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
Most ArtifactUI data isn't available when PLAYER_LOGIN fires. As the ArtifactUI is built off the old socketing system, you need to attempt to socket an artifact using SocketInventoryItem() or SocketContainerItem() and wait for ARTIFACT_UPDATE to fire before you can get meaningful data.

You might want to get an error display addon like Swatter or BugSack as the Blizzard default error handler is terrible at reporting errors on login.

PS: Since 7.0, textures don't support setting them to a solid color via :SetTexture() anymore. This functionality was split off into a new function :SetColorTexture().
__________________
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)
  Reply With Quote
11-11-16, 04:12 PM   #4
_Max_Cavalera_
A Fallenroot Satyr
 
_Max_Cavalera_'s Avatar
Join Date: Dec 2007
Posts: 28
I completely forgot to say that the event that seems to be some times ignored is only the initial one, in my case the PLAYER_LOGIN.
I also tried PLAYER_ENTERING_WORLD and have the same problem, some times it works, some times it doesn't.

I've seen it happen on the PLAYER_SPECIALIZATION_CHANGED but it's VERY rare, but it's probably from the same reason.

The rest of them seem to work well every time, every time I use an artifact power item I look at the addon and it seems to always update instantly to that event.

I'm gonna add this to the original post.

Originally Posted by SDPhantom View Post
Most ArtifactUI data isn't available when PLAYER_LOGIN fires. As the ArtifactUI is built off the old socketing system, you need to attempt to socket an artifact using SocketInventoryItem() or SocketContainerItem() and wait for ARTIFACT_UPDATE to fire before you can get meaningful data.

You might want to get an error display addon like Swatter or BugSack as the Blizzard default error handler is terrible at reporting errors on login.

PS: Since 7.0, textures don't support setting them to a solid color via :SetTexture() anymore. This functionality was split off into a new function :SetColorTexture().
I am using bugsack, isn't reporting anything from that.

The strange thing about that PLAYER_LOGIN not having the ArtifactUI data is that some times it works, so how is it working those times?

Thanks for the tip on the texture thing, i'm going to check it out.

Last edited by _Max_Cavalera_ : 11-11-16 at 04:18 PM.
  Reply With Quote
11-11-16, 04:25 PM   #5
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
When you reload the UI, the game doesn't clear the data it caches from server inquiries, so that data would remain available through the reload. The only time this data is cleared is when you log out.

Digging through Blizzard's ArtifactWatchBar, all you really need to watch for are UNIT_INVENTORY_CHANGED (for UnitID player) and ARTIFACT_XP_UPDATE if you're just sticking with the XP system. If you're going to look into scanning traits, you'll run into the situation I explained previously.



Note artifacts can be unequipped and spec changes don't directly contribute to data being updated about the newly equipped artifact. This is still the change in player's inventory. To illustrate this, here's an example of what goes on when you switch specs.
Code:
Client: Switch Specs
Server: Switching Now (Client displays progress bar)
Server: Switching Complete
Client fires PLAYER_SPECIALIZATION_CHANGED
Client: Equip New Artifact
Server: Item Equipped
Client fires UNIT_INVENTORY_CHANGED (UnitID = player)
__________________
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 : 11-11-16 at 04:42 PM.
  Reply With Quote
11-11-16, 05:09 PM   #6
_Max_Cavalera_
A Fallenroot Satyr
 
_Max_Cavalera_'s Avatar
Join Date: Dec 2007
Posts: 28
I'm not counting reloads as a login, when I said it some times works I mean actual logins, going out to char select and going in again.

As for the specialization change, initially I was using UNIT_INVENTORY_CHANGED, but since that happens every time you loot something or anything changes in the inventory, in my mind it wasn't really an efficient way of doing it. It pretty much causes a memory leak, no? Not that it would ever be a problem per se, we're talking a few kb but still...

And like I said, PLAYER_SPECIALIZATION_CHANGED seems to work 99% of the time, which is why it is as strange as the PLAYER_LOGIN working some times and others not.

My mindset to having chosen PLAYER_SPECIALIZATION_CHANGED in the first place was, I'm never really going to unequip my artifact, it's the only weapon now. I also can't equip any other artifact without changing the specialization and changing it automatically changes to the correct artifact. So it seemed like the perfect solution.
  Reply With Quote
11-11-16, 10:39 PM   #7
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
UNIT_INVENTORY_CHANGED fires when you equip, swap, or unequip an item. BAG_UPDATE is the event that fires when you loot, drop, or move items around in your bags. The idea of an event firing causing a memory leak is a misconception. Code not properly releasing objects that they allocated memory for is what causes memory leaks. Lua uses a garbage collection system that runs once in a while to clear out data that's no longer in use. The problem with your data usage wasn't how frequent the code was run, but recreating expensive data structures when you didn't need to. Furthermore, with UNIT_* functions, you can use :RegisterUnitEvent() instead of :RegisterEvent() to only respond to the event firing for a specific unit rather than everyone in your party/raid. For example, this is the bare minimum for your code to function properly and efficiently.

Lua Code:
  1. local KnowledgeMultipliers={
  2.     25, 50, 90, 140, 200,
  3.     275, 375, 500, 650, 850,
  4.     1100, 1400, 1775, 2250, 2850,
  5.     3600, 4550, 5700, 7200, 9000,
  6.     11300, 14200, 17800, 22300, 24900,
  7. };
  8.  
  9. local MainFrame=CreateFrame("Frame","M4xArtifactFrame",UIParent);
  10. local ExpText=MainFrame:CreateFontString(nil,"OVERLAY","GameFontHighlightSmall");
  11. ExpText:SetPoint("TOPLEFT",UIParent,"TOPLEFT");--   This is the object we're anchoring everything to
  12. ExpText:SetText("Initializing...");
  13.  
  14. --  This will twist your thinking, but you can set the points of your parents to a child as long as you don't create any circular references, as in points depending on each other.
  15. MainFrame:SetAllPoints(ExpText);
  16.  
  17. local Background=MainFrame:CreateTexture(nil,"BACKGROUND");
  18. Background:SetColorTexture(0,0,0,0.2);
  19. Background:SetAllPoints(ExpText);
  20.  
  21. MainFrame:RegisterUnitEvent("UNIT_INVENTORY_CHANGED","player");
  22. MainFrame:RegisterEvent("ARTIFACT_XP_UPDATE");
  23. MainFrame:SetScript("OnEvent",function(self,event,...)
  24.     local itemid,_,_,_,exp,lvl=C_ArtifactUI.GetEquippedArtifactInfo()
  25.     if itemid then
  26.         local available,tonext=0,C_ArtifactUI.GetCostForPointAtRank(lvl);
  27.         local _,knowledge=GetCurrencyInfo(1171);
  28.         while exp>=tonext do exp,lvl,available,tonext=exp-tonext,lvl+1,available+1,C_ArtifactUI.GetCostForPointAtRank(lvl+1); end
  29.  
  30. --      %5$d and %6$d force grab integers from the 5th and 6th parameters respectively
  31.         ExpText:SetFormattedText("AP |cff00ff00%d/%d (%.0f%%)|r"..(available>0 and " (+%d)" or "").."\nAK |cff00ff00%5$d (+%6$d%%)|r",exp,tonext,100*exp/tonext,available,knowledge,KnowledgeMultipliers[knowledge]);
  32.     end
  33.  
  34.     MainFrame:SetShown(itemid and true or false);-- Typecast to boolean
  35. end);
__________________
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 : 11-11-16 at 10:45 PM.
  Reply With Quote
11-12-16, 07:46 AM   #8
_Max_Cavalera_
A Fallenroot Satyr
 
_Max_Cavalera_'s Avatar
Join Date: Dec 2007
Posts: 28
Originally Posted by SDPhantom View Post
UNIT_INVENTORY_CHANGED fires when you equip, swap, or unequip an item. BAG_UPDATE is the event that fires when you loot, drop, or move items around in your bags.
Well... I completely messed that one up, was probably using BAG_UPDATE, no wonder it wasn't a good choice

You've been a huge help, I've learned a lot so far, thank you for that.

I'm going to study the code and apply those ideas maybe later today if I have time. In any case, when I have it working I'll post an update here.

Once again thank you for your help

edit:. Apparently I WAS using UNIT_INVENTORY_CHANGED and it does fire when you loot stuff
I even made a video to show you.

edit:. I know I'm a bother xD But I'm just like this, I NEEEED to know why stuff does one thing and then another and how it works.

So I did some testing, and apparently, the game fires some events completely randomly or whatever and that's why PLAYER_SPECIALIZATION_CHANGED some times works and other times doesn't.

Here's a pic of my test



I chose those events because they seemed to be the most important when changing spec.
As you can see, it worked when PLAYER_SPECIALIZATION_CHANGED was the last event to fire (or should I say, when it happens AFTER UNIT_INVENTORY_CHANGED), which doesn't happen always. In my test it did like 8 out of 10 times.

The spellcast succeeded ones are, one from finishing changing the spec, the other one is from the passive hidden effect that changes the artifact weapon automatically. I have no idea why some times events for the same thing fire twice, because even though two of those spellcast events aren't the same as they're doing different things, the other ones are "re-fires" of one of those two

I did exactly the same thing every time, didn't move or anything, had the spec window open, choose spec, clicked apply, let it finish, choose another spec, clicked apply, let it finish, etc etc etc... all specs have their artifact weapon in the bag available.

Last edited by _Max_Cavalera_ : 11-12-16 at 12:34 PM.
  Reply With Quote
11-12-16, 12:16 PM   #9
Lombra
A Molten Giant
 
Lombra's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 554
Didn't really read the thread thoroughly, but use PLAYER_EQUIPMENT_CHANGED if you want to track equipment changes.
__________________
Grab your sword and fight the Horde!
  Reply With Quote
11-12-16, 01:50 PM   #10
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
UNIT_INVENTORY_CHANGED seems to be bugged and firing when you loot an item you don't already have or split a stack. PLAYER_EQUIPMENT_CHANGED would be interchangeable and doesn't appear to be affected by this bug.
__________________
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)
  Reply With Quote
11-13-16, 10:39 AM   #11
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Originally Posted by SDPhantom View Post
Lua Code:
  1. MainFrame:SetShown(itemid and true or false);-- Typecast to boolean
Not specifically related to anything, but another, less verbose way to do that would be:

Lua Code:
  1. MainFrame:SetShown(not not itemid); -- Typecast to boolean
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
11-13-16, 12:21 PM   #12
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
Originally Posted by Phanx View Post
Lua Code:
  1. MainFrame:SetShown(not not itemid); -- Typecast to boolean
I saw this in Blizzard code recently and thought it harder to follow.
__________________
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)
  Reply With Quote
11-13-16, 12:50 PM   #13
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,860
Originally Posted by SDPhantom View Post
I saw this in Blizzard code recently and thought it harder to follow.
I think it is, too. And it doesn't save on anything other than space.
__________________
"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
11-13-16, 02:04 PM   #14
Lombra
A Molten Giant
 
Lombra's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 554
Unless it for some reason can be false; "itemid ~= nil".
__________________
Grab your sword and fight the Horde!
  Reply With Quote
11-13-16, 09:34 PM   #15
_Max_Cavalera_
A Fallenroot Satyr
 
_Max_Cavalera_'s Avatar
Join Date: Dec 2007
Posts: 28
I haven't had any time today to implement anything but I wanted to stop by to thank you guys for the help and keeping the discussion alive

btw, by my limited tests, PLAYER_EQUIPMENT_CHANGED seems to be the best solution so far for my "problem"
  Reply With Quote
11-14-16, 01:09 PM   #16
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
Originally Posted by Lombra View Post
Unless it for some reason can be false; "itemid ~= nil".
The API is consistent in returning nil if doesn't have any data. Checking for nil specifically is overboard in this case and is a waste of CPU resources on an extra operation or two.
__________________
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)
  Reply With Quote
11-14-16, 02:14 PM   #17
Lombra
A Molten Giant
 
Lombra's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 554
Originally Posted by SDPhantom View Post
The API is consistent in returning nil if doesn't have any data. Checking for nil specifically is overboard in this case and is a waste of CPU resources on an extra operation or two.
Sure, but since we were talking readability I prefer that expression personally.
__________________
Grab your sword and fight the Horde!
  Reply With Quote
11-14-16, 05:05 PM   #18
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,860
But nil isn't the same as false.
__________________
"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
11-15-16, 12:19 AM   #19
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
Again, differentiating false in this situation is overkill. The API never returns false in place of a value that isn't normally boolean. As a matter of fact, API that returns data often doesn't provide any returns when there isn't any available, not even nil. However, when Lua attempts to assign no value to a variable, it ends up assigning nil anyway.
__________________
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 : 11-15-16 at 12:35 AM.
  Reply With Quote
11-15-16, 09:17 AM   #20
_Max_Cavalera_
A Fallenroot Satyr
 
_Max_Cavalera_'s Avatar
Join Date: Dec 2007
Posts: 28
ok, i've been reading the code you put up (thanks once again for that), i'm implementing it right now, have a few questions though since I'm doing this to learn, implementing without knowing why or what something does isn't really an option xD

I'll start at the end since people always like to start at the beginning

Lua Code:
  1. MainFrame:SetShown(itemid and true or false);

Can you explain this line to me? I think that it's supposed to be, show frame if itemID exists?! but I don't get how the and true or false works.

Backgrounds... do I really need them? I know I had one, I made it because I was learning from a book and it listed the background as something to use when making a frame but as you know mine wasn't even working and i didn't even notice it because it was already supposed to be almost invisible at 0.2 alpha.
It works without one so I guess there's no problem in not having one? Or can it create problems?

Can you explain why %5$d and %6$d is needed to grab the 5th and 6th parameter when the position of those in the string are the 5th and 6th? Shouldn't they already pick up the right ones with just %d? Or is it \n that breaks that?
By the way, I didn't know I could do that so, thanks

EDIT:. ok I understand this one now I think, it's because of the (available>0 and " (+%d)" or ""), they MIGHT or MIGHT NOT be the 5th and 6th... damn I'm dumb...

And finally,

Lua Code:
  1. (available>0 and " (+%d)" or "")

You have this on the formatted text, I guess it's supposed to be if available > 0 do the first one else do the other one?!?! So it's like an IF statement to use inside strings?

How does it work? From what you have I think it's (if condition and then or else) but the fact that the if condition is followed by and seems so strange to me xD

Last edited by _Max_Cavalera_ : 11-15-16 at 10:16 AM.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Learning, need help

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