Go to Page... |
|
Thread Tools | Display Modes |
|
02-17-17, 09:41 PM | #1 |
Programmatically determine instance expansion?
Heyo, new-ish addon dev here wading my way through the WoW API and Lua.
So far so good, although today I spent basically the entire day trying to do what the title suggests: Determine which expansion the instance you're currently inside, belongs to. Somewhat of a mouthful of a sentence, but the idea seems simple enough. Or so I thought, but I've yet to find a way. I got close using some of the Encounter Journal API: EJ_GetTierInfo() returns the full written name of the expansion, provided a "tier", such as 1 (Classic), 2 (Burning Crusade) and so on. And, you can use EJ_GetCurrentTier() to get the tier of the current instance... Except not really. For some bizarre reason, despite GetCurrentInstance returning the current instance that the player is actually inside, GetCurrentTier doesn't. It returns the "tier" selected in the Encounter Journal! And that, in turn, is sadly not consistent. If you enter an instance, it does not change - meaning something like; Lua Code:
TL;DR - I can't for the life of me figure out a way to do this. I really, really really really really don't want to have to maintain a hand-written table of Instance ID/Name -> Expansion relations... Prone to typos, mis-spellings, needs to be updated by hand every time something changes or new content comes out.. Just no. I auto-generate a table of continent names purely programmatically due to this exact reason :\ Anybody has any secret sauce that could help this? |
|
02-18-17, 03:20 AM | #2 |
Your current way of doing what you want won't work the way you want it to, because those functions are designed around the encounter journal.
Something along these lines can get you started. This "should" print the name of the expansion assigned to the instance you zone into in the chat frame. You will have to register it to PLAYER_ENTERING_WORLD Lua Code:
Its a little wonky as it should open the Encounter Journal every time you zone in to an instance, but since I don't see another way to get what you are looking for, its a start at least. Last edited by briskman3000 : 02-18-17 at 03:26 AM. |
|
02-18-17, 11:37 AM | #3 |
How do you intend to handle instances like Scholomance, which was a classic instance, but recreated in Mists of Pandaria?
|
|
02-18-17, 03:23 PM | #4 | |
What exactly are you planning on doing with this info? |
||
02-18-17, 05:13 PM | #5 | ||
You can build a list of instance ids with EJ_SelectTier and EJ_GetInstanceByIndex I don't know when you need that information (loadondemand/events?) but here is an example Lua Code:
Lua Code:
Not sure how it's usually done with the world map, but you can make the EJ set itself to the current dungeon (ref) Unless you meant something else? Lua Code:
Last edited by Ketho : 02-18-17 at 09:10 PM. |
|||
02-18-17, 08:24 PM | #6 | ||||
Thanks a lot for the suggestions thus far, everyone!
I did arrive at the idea of generating a list of all instances indexing it by tier on demand, while I was away from the computer, that does seem to be a pretty good way of doing it, especially since it doesn't mess with the encounter journal, which I'd like to avoid since, well, the player may be using it, have something selected, etc, and I don't want to mess with that. I should be able to just generate the list once per session (something I already do with continent names for example), so it should be fairly benign.
From my testing this is inconsistent at best, resetting the journal view after entering the instance doesn't have repeatable results, if the player has been browsing the journal beforehand. For instance, that ResetDisplay function Blizz themselves use, doesn't correctly reset the Tier, since there isn't actually a way to do that by function. As I said in the OP; GetCurrentTier gets the displayed tier, not the actual player tier. And as best I can find out, there's no way to actually *set* the tier, since .. well, you can't *get* the tier in the first place, so you don't know what to set it to. It's basically the same problem as the other suggestion above, it all ends up with a catch 22. Need to know the tier so we can set the tier so we can know the tier.
I'm basically creating a database of a characters activity over the course of their leveling experience (and after, potentially, but that's not the intent). Logging everything from zones visited, damage done, levelups, instances completed (what I'm working on right now), quests completed, and so on. Everything is logged in pretty high detail - for example I can extrapolate what my average active DPS was for level 67, and I know what zones I visted and how many times in that level, I know how many quests I completed in what zone, and what mob I killed the most of, etc... I guess you could say I'm writing the NSA addon. But actually, there are good intentions behind it! The database will be needed as a component of my actual addon, tentatively named "TellMyStory", which is an addon that will, through all this gathered data, once you hit max level (and assuming you've been running the addon since you created the character), generate a sort of short visual story of your leveling experience. Basically an animated infographic about what you did, when, how, and so on. It'll be able to dynamically figure out some fun facts, and present them in an interesting manner, while keeping it somewhat short (filtering what to show based on a rough "how interesting is this" metric)... Of course, for uber-nerds there will be a "Show me all the stats" button, that will be able to show .. well, all the stats, maybe graphs and pretty things, even those that weren't deemed "interesting" enough to show in the infographic. Thus I need a lot of data, to be able to extrapolate a bunch of interesting stuff. So that's what I'm doing right now, working on a data logging component. I might release that separately if there's any interest in it. All the raw collected data is stored in global table / SavedVariable anyhow, so it's not much of a stretch to build a bit of simplistic API on top. Last edited by Mythricia : 02-18-17 at 08:39 PM. |
|||||
02-19-17, 02:58 PM | #7 |
Your addon sound very interesting, one I would like to try. If you need beta testers, I would be happy to test it.
|
|
02-19-17, 07:58 PM | #8 |
It might take a good while before I have anything concrete to show, I'm learning Lua as I go, but I can definitively see needing some testing later on!
|
|
02-20-17, 11:52 AM | #9 |
I also collect data for my own addon, Historia.
But nearly as much data as you are going to gather. When you are ready to show your addon, I also will be happy to test.
__________________
Better to fail then never have tried at all. |
|
02-23-17, 03:43 AM | #10 |
Alright, it took me 4 days, but I got it all working now. Figured I would share it. I've only been learning Lua and the WoW API for a couple weeks, and I'm a pretty novice programmer in the first place, so this probably took longer than it should have Any critique or hints from experienced peeps is welcome.
But the result is great. I can enter any raid or 5man instance from any expansion on any difficulty, and correctly determine what expansion it belongs to, without any hardcoded names, for neither instances nor expansions. This means, as long as the base API remains the same, this code should work for future expansions, dungeons, raids, without needing updating. In Theory™. Scenarios are not supported, but that's a separate problem all together. This is the code, mind that this is basically a debug version written in isolation, I'm going to clean it up and refactor quite a bit later, but for now, it does what it needs to do. It's pretty littered with comments, for my own organizational sake. You should be able to copy paste this into WowLua and just run it. In summary: First, call GenerateInstanceTable() (no args), to generate the InstanceTable, which is a table of every instance name and instanceID, grouped by type (dungeon, raid) and expansion name. Next, we call GetCurrentInstanceTier() (no args) and you'll get a string containing the in-game name of the expansion in return. In this code, there are some debug things like returning "NotAnInstance" or "UnknownTier" and other weirdness if you're not actually inside an instance, but that was just for debugging. Lua Code:
Last edited by Mythricia : 02-23-17 at 03:53 AM. Reason: Oops, bad variable naming, was potentially overriding lua globals. I'm bad. |
|
02-23-17, 05:16 AM | #11 |
never mind
Last edited by Ketho : 02-23-17 at 06:43 AM. Reason: i give up sorry |
|
02-24-17, 09:48 AM | #12 |
02-24-17, 10:00 AM | #13 | |
Okay here is my post again I understand you still need to clean up and refactor but to be honest, your code is giving me a lot of WTF's, it makes me wonder if my example was even looked at
Unless it's for testing purposes there still are some leaking globals Code:
main (24 instructions, 96 bytes at 00000000007C8370) [5] SETGLOBAL 0 -1 ; GenerateInstanceTable [52] SETGLOBAL 0 -2 ; GetCurrentInstanceTier function (57 instructions, 228 bytes at 00000000007C8880) [54] SETGLOBAL 0 -1 ; InstanceTable [98] SETGLOBAL 12 -12 ; subTable Why create a function and then run it on the fly Code:
-- Second, is it Heroic? If so, skip all of Vanilla. Else, search the entire instance table local startIndex = (function() if difficulty == 2 then return 2 else return 1 end end)() local startIndex = (difficulty == 2) and 2 or 1 Code:
-- Generate a chronologically ordered list of expansion names local tierList = (function() local tt = {} for i=1, EJ_GetNumTiers() do tt[i] = EJ_GetTierInfo(i) end return tt end)() local tierList = {} for i = 1, EJ_GetNumTiers() do tierList[i] = EJ_GetTierInfo(i) end Why not use "party" and "raid" directly instead of changing it back and forth to "Dungeons" and "Raids" Also why string.find instead of a table lookup? But I don't know what you're trying to do here Code:
instTable.trackedTypes = "party, raid" if not string.find(InstanceTable.trackedTypes, instanceType) then return "UnknownInstanceType" end local trackedTypes = { party = true, raid = true, } if not trackedTypes[instanceType] then return "UnknownInstanceType" end This do-end is superfluous Code:
-- Bail out if we're not even in an instance! if not IsInInstance() then do return "NotAnInstance" end end This table structure is overly complicated, why not remap id to tier? Code:
instTable[instanceType][tierName][name] = id instTable[id] = tierId Why not index a hash table instead of iterating through it Code:
-- Perform the actual search, scanning by instanceID, skipping Classic if we're in Heroic for i = startIndex, #tierList do subTable = InstanceTable[searchType][tierList[i]] for k, v in pairs(subTable) do if (instanceID == v) then return tierList[i] end end end return instTable[instanceID] or "UnknownTier" You can use format strings to keep it more readable Code:
print("You are in \""..select(1,GetInstanceInfo()).."\ ("..select(4,GetInstanceInfo())..")\", from the \""..GetCurrentInstanceTier().."\" expansion.") local name, difficultyName = GetInstanceInfo() print( format('You are in "%s (%s)", from the "%s" expansion.', name, difficultyName, GetCurrentInstanceTier()) ) Last edited by Ketho : 02-24-17 at 10:05 AM. |
||
02-23-17, 05:38 AM | #14 |
I don't understand what the extra () at the end of functions is doing. That is not a Lua thing.
And Ketho is correct, there are leaking global variables all over the place. I suggest using this tool to find them. |
|
02-23-17, 06:22 AM | #15 |
Just a quick question passing by..
What would be the actual purpose of EJ_SelectTier(index) function? Neither WoWWiki nor Wowprogramming seem to document this function at the moment I dumped this inside WoW, but looks like it does not return any output. Also, should I install Lua on my PC first before using the tool suggested by myrroddin? Last edited by Layback_ : 02-23-17 at 06:27 AM. |
|
02-23-17, 07:03 AM | #16 | ||
As for the extra ()'s at the end of anonymous functions, try running the code without them. Doesn't run. That's why You need to encapsulate the function, to avoid creating a reference TO the function. I don't want that. I want a reference to the result of the function. And the function won't run if it's not called, so you need to call it, with (). This creates the awful syntax of (function() someCodeHere end)(), which is correct, you can find examples of this in other Lua docs. Lua Code:
I agree it's awful. Trust me, it was not the first thing I tried. Alas it is the only way to create an inline anonymous function inside a variable assignment. I'd be glad to be proven wrong, if you can show an alternative that actually runs (rather than guessing it should run). Sure, I could break out the function, but that's annoying, seeing as it's only going to be called from one place, and one place only.
This is a hacky workaround, but needed to generate a list of all the instances and expansions. Only done once per login in my revised code (not posted here). Basically I crawl the encounter journal to get all the instances and expansions the game has to offer. That's why it doesn't return anything in game - it's simply a UI function that selects a dropdown. This must be done, so that EJ_GetTierInfo() returns the expansion ("tier") name. Should also mention that there were issues with using this code on ZONE_CHANGED_NEW_AREA, it turns out that the Encounter Journal is basically dead during the loading screen, so running my code on the Event trigger, would cause an error, due to my code relying on EJ_GetCurrentInstance() to get the instanceID. Fortunately I had decided to store the instance names in the InstanceTable, so I simply swapped over to scanning for the instance name rather than the ID, since instance name is available during the loading screen, through GetInstanceInfo(). Simple enough fix, and it all works fine now. Instantly on zone-in, a log entry is created. For example "Dungeons -> Wrath of the Lich King -> An'kahet: The Old Kingdom" -> Meaning sub-table. Last edited by Mythricia : 02-23-17 at 07:26 AM. |
|||
02-23-17, 07:56 AM | #17 | |
Lua Code:
Just do: Lua Code:
__________________
Grab your sword and fight the Horde! |
||
02-24-17, 04:15 AM | #18 |
You do not need to install Lua to use that tool; it comes with everything required.
|
|
WoWInterface » Developer Discussions » Lua/XML Help » Programmatically determine instance expansion? |
«
Previous Thread
|
Next Thread
»
|
Display Modes |
Switch to Linear Mode |
Hybrid Mode |
Switch to Threaded Mode |
|
|