Getting artifact perks data
I would like to get info about which artifact perks are currently active. So far I have the following code:
lua Code:
However this only works when the ArtifactUI is open and I can't figure out how to open it programmatically. Would appreciate some help on that. |
As a temporary workaround, you can cache your results. Update your cache any time the Artifact UI is open, or appropriate events fire.
|
I need the data for a spell dependency list. Like for marksmanship hunters Windburst applies Deadeye (or Vulnurable) when Mark of the Windrunner is selected. However both IsSpellKnown and IsPlayerSpell return false for Mark of the Windrunner and there is no spell added to the spell book. I can't rely on the user opening the artifact UI but I haven't found another way to get that information.
|
You can open the artifact UI by requesting to socket the artifact through a call like SocketContainerItem or SocketInventoryItem. At that point you should be able to request artifact data.
|
This is an interesting idea!
On second thought, it is probably not nice to open the artifact UI without a user interaction as it could close other UI panels. And I'll have to rescan in case the user changes their spec and equips another artifact. I really hope they'll make the whole C_ArtifactUI API usable without the artifact UI being visible. |
Lua Code:
Here is an example on how it could be used: |
Yeah, you can also just suppress the artifact UI from opening at all by doing something like unregistering the artifact open event from UIParent and then re-registering after you're done with your info.
The problem with the artifact api being available all the time is that a player could have up to 4 artifacts (druids), that's why you have to specify which one you want data on by using the socket function. |
I'm confused, can you not just call LoadAddOn for the load-on-demand Blizzard Addon in question? (Blizzard_ArtifactUI)
|
@Simca you can load the addon, but the C_ArtifactUI API returns just nils while the ArtifactFrame is not open. Or I'm too short sighted to get it.
@dssd yes, but only one artifact can be active at a time per design. And the API could provide just that info. @syncrow HasArtifactEquipped() returns true even if the player has respecced but hasn't changed weapons yet, meaning your code gets potentially wrong information. |
Quote:
|
Quote:
Quote:
|
@Simca Almost the opposite of that is what Rainrider wants I believe. When you use socket item that tells C to prepare artifact data for that artifact. When it's ready it fires the "ARTIFACT_UPDATE" event which Blizzard's Lua code looks for. That's how it knows to load the addon if it isn't already and open the UI. I believe Rainrider wants to just have C prepare the data without opening the Lua UI. That's why I recommended unregistering Blizzard's code from "ARTIFACT_UPDATE" before asking C to load the data for an artifact.
@syncrow I believe it leaves it equipped but in an "unusable" state kind of like if an equipped item reaches 0 durability. |
Quote:
lua Code:
You could use GetInventoryItemQuality("player", INVSLOT_MAINHAND) == LE_ITEM_QUALITY_ARTIFACT and GetInventoryItemEquippedUnusable("player", INVSLOT_MAINHAND) to check whether the right artifact is currently equipped. Also using just SPELLS_CHANGED for tracking changes seems to be enough, at least for my purposes, but I haven't tested this extensively yet. |
Quote:
Pity the API didn't use specID. Edit: As this is something I've needed for my own project, I messed around and wrote a quick libstub library for caching artifact information (including those in your bags). Used some of the code above as a base (credit to your macro Rainrider). Data updates is handled by the library, you only need to call the data functions. This is my first library (woo!) so code could probably be done better. Let me know if you have any issues with it: http://www.wowinterface.com/download...facts-1.0.html |
Quote:
Will check it out for my ArtifactBar in DuffedUI for the tooltip. |
Quote:
|
Quote:
During regular gameplay, I call RefreshPowers() and that only occurs during ARTIFACT_UPDATE. I was originally going to have a force update function, but I don't think that is necessary. Debating on writing a communication portion for sending trait information to other players, however that may be better suited for the addon itself rather than the library. |
Small update to the library. Minor optimisations (aka removed the double caching on first load etc), couple of minor changes to the error logic. More importantly added a new public function for number of powers purchased (which is now cached) which saves overhead.
I now class it as feature complete and looks to be working without issue. Please let me know if you break it. Gathering artifact power to test it during gameplay is rather time consuming :) |
The way you uploaded it, it won't load at all (no ToC file).
You need a way to tell users when data changed. You could use CallbackHandler for this. Your RefreshEquipped() and RefreshBags() are double dipping as SocketInventoryItem and SocketContainerItem will issue ARTIFACT_UPDATE and your event handler will call RefreshPowers() again. As long as you call RefreshEquipped() and RefreshBags() only at PLAYER_ENTERING_WORLD (PEW) you could spare the checks for ArtifactFrame. Your first call to SocketInventoryItem will load the ArtifactUI and from then on you actually open and close ArtifactFrame for every artifact in the player's inventory. This is probably not a problem as the user won't have any open UI panels during PEW. If you change this (by adding a forced update), you will have to consider that the ArtifactFrame listens for ARTIFACT_UPDATE as well. GetPowerPurchased actually returns the number of purchased traits. Maybe GetNumTraitsPurchased would be a better name. Same goes for GetPowers and the like. I know you follow Blizzard's own naming here, but they probably coded that before the UI wording was set in place and didn't care to update the API to reflect that. Also prepending Lib to your addon name would be nice, but this is just my personal taste. As for features, you could also provide the knowledge level and multiplier as those are only available when the ArtifactFrame is shown. They are shared between artifacts. The API for them is C_ArtifactUI.GetArtifactKnowledgeLevel() and C_ArtifactUI.GetArtifactKnowledgeMultiplier(). |
Quote:
The library will work fine if it's embedded and your addon is reacting to events to pull data. I can make it standalone enabled and implement CallBackHandler to fire a cache update event, which will make this a little more friendly for UI display updates. Feature wise, this was more intended towards caching just the traits. However thinking on it, it might be better to simply expand it to cache more of the data provided by C_ArtifactUI API (saves future requests). I'll need to look at the API listing again and see how best to manage what options there are. I don't want the library to take up too much UI time if I can help it. A fair bit of the functions will likely not be needed. Naming wise was to keep it the somewhat similar to Blizzard's, as this partially turns the library into a cached alias for C_ArtifactUI, which is why I've opted to return information in the same format. I did totally do a goof on PowersPurchased (should have used GetTotalPurchasedRanks) :P Quote:
-- One thing I've been debating on is if I should add bank inventory scanning - I'm leaning towards yes, regardless of how unlikely it is for an unscanned artifact to be equipped and used prior to caching that specific artifact. However this is entirely dependant if I can code it such that it doesn't intrude on the user - part of the issue is you can't 'socket' an item whilst it's in the bank. Thanks again. Will keep the update discussion in this thread as I progress :) edit: Quote:
The only issue is that if you have the artifact frame open, then close the bank - the artifact frame will close due to the data caching. I'd rather not have the library do this, but there's no other way to cache a new artifact. Something to muse over. |
After spending way too long fixing a recursive issue, I've finally got an artifact scan implementation that I'm happy to use for both login and bank scanning. I'm currently working on caching relic information and associated reference functions. Hoping to get that finished sometime this week so I can upload the next update.
Next version will be standalone compatible and also have callbacks for cache updates, artifact xp and addon error debugging. There's also some wrapper functions for both the C_ArtifactUI and some related blizzard artifact methods. There may be a couple of name changes to the public library functions. |
I also started a data store library for artifacts. If you are interested take a look at the code.
I still have to figure some stuff out, like changing relics, (un)learning perks and getting artifact knowledge updates without ARTIFACT_UPDATE, but for the most part it seems to be working fine. Also, appearance/model stuff is not handled since I don't see any use in it for now, but if someone needs it, it can be added. |
Quote:
GetNumObtainedArtifacts() includes your bank. Whilst this isn't problematic, it's something you may wish to keep in mind. I'm not sure why you're not getting the correct value right away, as this returns the correct value when called during the PEW event. If you utilise BANK_CLOSE and ARTIFACT_CLOSE events for additional scanning, you'll need to add a small delay with C_Timer.After() in your code for both events. 0.1s is sufficient from what I can tell. The reason is this: If the artifact frame is opened at the same time the bank frame is closed (ie: character and bank frame open, opening an artifact will cause the bank frame to close), you'll cause a stack overflow in the blizzard UI if you're attempting to scan (due to the ARTIFACT_UPDATE event) and store artifact data.You will need to wait for the ARTIFACT_CLOSE event before you can scan, but the scan also needs to wait so that the ARTIFACT_CLOSE event can be properly unregistered - else you'll land with a recursive function call issue when you Clear(). Fun times. |
Quote:
|
1 Attachment(s)
I do exactly as SDPhantom says - look up PrepareForScan() and RestoreStateAfterScan(). They are called only from InitializeScan(), which in turn is called either upon PEW, or PLAYER_EQUIPMENT_CHANGED (PEC), or from ForceUpdate(). Apart from that I only acquire data for the currently viewed artifact when ARTIFACT_UPDATE fires, without interfering with the stock ui, or at ARTIFACT_XP_UPDATE, but the API I use there already returns information without ArtifactFrame beeing open.
The game behaves differently during the initial login and subsequent loading screens. I wrote a simple addon that records every event after PEW until the return value of C_ArtifactUI.GetNumObtainedArtifacts() is what I expect (2 for my test character on the beta). The game loads character data persistently at the initial login and thus it is readily available at subsequent reloads. I'll attach the addon here so you could verify my results and see why I opted for a timeout at PEW, which is somewhat hacky and I don't like it. It someone finds a better way, I'd love that. Yes, C_ArtifactUI.GetNumObtainedArtifacts() includes the bank. My scan accounts for that and it stops when all artifacts are found (see how I propagate numObtained in InitializeScan()). I welcome further comments on the code and thank you for that. Feel free to use whatever you like from it. There is also some documentation here. Also, if someone has an idea how to track hidden currencies, I'd love to know that. The artifact knowledge level is such a currency - see /run print(GetCurrencyLink(1171) or /dump GetCurrencyInfo(1171)). |
Quote:
Quote:
Correct my tired mind though, but it looks like your bank scan doesn't actually activate as there is no event associated with scanning outside PEW, PEC and Force Update? Unless I'm mistaken, bank information is only available whilst the bank tabs are open, and during the first BANK_CLOSE event (neither of which you've registered). Some info on some of your comments: * Traits can be purchased on artifacts that are not equipped, however you must be at the forge with the UI open. ie: open forge with equipped artifact, then shift+right click on unequipped artifact to change. I don't think you can do the same with the trait respeccing, however I haven't specifically tried to break the UI in that way. * Relics are part of the ARTIFACT_UPDATE event. Your ARTIFACT_XP_UPDATE code is redundant in calling ScanTraits(), although this may be entirely based on event order received by the client. You may want to consider shifting thr callback into the main ARTIFACT_UPDATE event as part of your relic scan. Food for thought. Regarding your PEW delayed call: I know that efficiency is a goal and understand the need to break out of the search loop, however if someone has an artifact in their bank you'll end up iterating over all their bag slots anyway. Have you considered using an arbitrary figure for numObtained that is purely used at login so that all bag slots are scanned only for login? Additionally, you're not unregistering your PEW event which only needs to fire once for the initial scan. eg: local numObtained = GetNumObtainedArtifacts() or 10 Or some if then else variant. This is basically what my code does (version currently being worked on). I'll scan everything at login, and future scans only occur if I have outstanding artifacts. I have a search function that picks up unscanned artifacts and places them into an array with bag locations, which is then passed to my scan function that processes them. I'm not terribly worried about scanning artifacts that have just been obtained (PEC), as they basically have no data to begin with and the player buys the first trait at the forge early on. Everything else will get picked up. |
Quote:
Quote:
Quote:
Quote:
Quote:
|
The relics are considered gems. You can get them from the item link. Socketing the relic triggers UNIT_INVENTORY_CHANGED and 3 ARTIFACT_UPDATE. If it is the equipped artifact PLAYER_EQUIPMENT_CHANGED will also fire.
|
Makes sense since it's piggybacking off the Socketting mechanic. It would be nice if there was trait data stored in the itemlink as well, but it's probably handled as a separate database table linked to the unique ID in the itemlink as a primary key. If it is stored somewhere accessible, it's probably a bitfield as the number of ranks are either 0-1 or 0-3, which are convenient values to be efficiently stored in bitfields.
|
@SDPhantom
Code:
:128826::137313:137412:::::110:254:256:9:1:727:210:3:1826:1467:3339:2:1726:1477: Edit: If I do GetItemGem(GetInventoryItemLink("player", INVSLOT_MAINHAND), index) I get the following Gem links. Code:
:137313::::::::110:254:::3:1826:1467:3339::: :numGemFlags:flag(1):...:flag(n-1):upgradeFlag: 3339 appears to be the upgradeFlag for warforged. The second relic is heroic, but there seems to be no upgradeFlag for that. I believe the last flag is the relic type (storm, blood and life here). |
Would you be willing to test LibUtilities to see if the item string parse works with the additions and changes? I want to know if I have bugfixing to do with Legion.
The relevant API is DecodeItemString. |
Quote:
Code:
Dump: value=GetInventoryItemLink("player",16) Code:
Dump: value=LibStub("LibUtilities-1.0"):DecodeItemString(GetInventoryItemLink("player",16)) Fixed:
Thank you, kokomala, for the pointers! Pending:
Do you guys need something else? |
Thank you Rainrider. I take it the lib works as intended then?
Now back to your regularly scheduled topic. |
@myrroddin
The first return should be just "item", but it contains the color too. The 15th return should be a table containing the bonusIDs for the first gem if I understand your documentation correctly, but it isn't. I would have expected the following (the parts that differ are in red): Code:
[1]="item", Edit: LibStub is also not loaded from your lib. Your toc looks for LibStub\LibStub.lua, but it is LibStub\LibStub\LibStub.lua in your wowace package. |
Relic updates are now in as well as the knowledge level tracking. The knowledge multiplier can only be updated when an artifact is viewed, so if I pick a new level I just send a message that the multiplier is probably dirty.
The only two remaining features I consider right now are flagging the active and the banked artifacts. Do you guys need something else? I also would appreciate feedback on code and functionality. Especially on the messaging part. Am I doing it right? Would you do it in another way and why? A simple "it looks ok" is also fine :) Download from GitHub Documentation |
The game will fail to switch artifacts when one of those occurs:
so basically it only changes between two artifacts if both are directly available (speak either equipped or in the bags). Also if you got yourself in a state where you have the wrong artifact equipped, the return of C_ArtifactUI.GetNumObtainedArtifacts() does not account for the inactive equipped artifact. It appears Blizzard scans your complete inventory (including the bank) when you call C_ArtifactUI.GetNumObtainedArtifacts() but excludes the items you cannot use :) |
Will there be any library or addon for sharing artifact progression / information between players?
Since currently it's not possible to get that from the Inspect UI http://www.mmo-champion.com/content/...nd-Order-Halls Quote:
(Edit) it looks like Blizzard doesn't want that information to be freely available (?) http://us.battle.net/wow/en/forum/topic/20745557148 http://www.mmo-champion.com/threads/...nlock-progress Quote:
|
I don't see why not. The addon just needs to cache data and store it in a SavedVar, much like Altoholic does and transmit results when queried.
I have an analyzer I made that scans the artifact and dynamically plots your Artifact Power progression over a bar graph showing the leveling curve. This is in addition to listing all powers with their ranks and bonuses. |
If I understand correctly Ketho is wanting something to tell the progression of characters he doesn't know. It is probably at least to some extent doable through the combat log as the golds are either active abilities or passives with on own effect, so they may have their own combat log entries. Output modifiers won't be that easy, but if you know the perk paths, then you can reconstruct the data at least partially.
|
Caching the artifact data as we are right now is enough to reconstruct the entire artifact, at least perk wise. It's a short jump to writing an extension that utilizes the library to share that data with other players via addon comm.
The option is either to write a plugin library that utilizes the cached information and sends it to other players when requested; or build it into the library itself. Then its up to the addon to do what it wants to do with that information. A plugin library would probably be cleaner, as it would have to handle multiple artifacts/players. --- On another note, my library is kinda on-hold. It's gotten a little out of scope for what I intended and until I can set aside the time to go through and clean up the code and bring it back into scope, there won't be further updates. There's a scanning idea I want to explore when I do that, which removes some of the issues surrounding scanning and GetNumArtifacts(). |
This implies that the player you are inspecting has the library installed :)
|
Quote:
You won't get everyone, but popular mods that include raid/group gear checks would be an easy transition. |
All times are GMT -6. The time now is 01:51 PM. |
vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI