/
--------------------------- |
-- LibSpellName2SID - test1 |
-- Test some base spells |
--------------------------- |
local AddonName, AddonEnv = ...; |
local testsSharedName = AddonName.."-Tests"; |
local LIBSN2SID = AddonEnv.LIBSN2SID or LibStub("LibSpellName2SID-1.1"):NewInstance(testsSharedName); |
local SID = LIBSN2SID.clients[testsSharedName].SID; |
local LSN = LIBSN2SID.clients[testsSharedName].LSN; |
-- local SID = LIBSN2SID.SID; |
-- local LSN = LIBSN2SID.LSN; |
local Frame = CreateFrame("Frame"); |
Frame:RegisterEvent("PLAYER_LOGIN"); -- Not enough data from game til this event fires. |
-- Frame:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED"); -- This talent and/or the one in the line bellow |
-- Frame:RegisterEvent("PLAYER_TALENT_UPDATE"); -- should fire when the player switches spec. |
-- TESTED: Both of these fire Twice on Changing |
-- spec. On Login but "ACTIVE_..." fires Once, |
-- but "PLAYER_TALENT_..." fires Twice. |
-- Frame:RegisterEvent("PLAYER_ENTERING_WORLD"); |
Frame:SetScript("OnEvent", function() |
C_Timer.After(3, function() |
print(testsSharedName.. ": Starting test1 - some base spells."); |
if SID and LSN then |
local startTime = GetTime(); |
print(testsSharedName.. tostring(": SID and LSN found.")); |
local endTime = GetTime(); |
print("print time with tostring(...) = ".. (endTime - startTime).. "ns."); |
startTime = GetTime(); |
print(testsSharedName.. ": SID[\"Auto Attack\"] = ".. tostring(SID["Auto Attack"])); -- |
endTime = GetTime(); |
print(testsSharedName.. "... in ".. endTime - startTime.. "ns."); |
startTime = GetTime(); |
print(testsSharedName.. ": LSN[\"Auto Attack\"] = ".. tostring(LSN["Auto Attack"])); -- |
endTime = GetTime(); |
print(testsSharedName.. "... in ".. endTime - startTime.. "ns."); |
startTime = GetTime(); |
print(testsSharedName.. ": SID[\"Made It Up\"] = ".. tostring(SID["Made It Up"])); -- |
endTime = GetTime(); |
print(testsSharedName.. "... in ".. endTime - startTime.. "ns."); |
startTime = GetTime(); |
print(testsSharedName.. ": LSN[\"Made It Up\"] = ".. tostring(LSN["Made It Up"])); -- |
endTime = GetTime(); |
print(testsSharedName.. "... in ".. endTime - startTime.. "ns."); |
startTime = GetTime(); |
print(testsSharedName.. ": SID[210873] = ".. tostring(SID[210873])); -- |
endTime = GetTime(); |
print(testsSharedName.. "... in ".. endTime - startTime.. "ns."); |
startTime = GetTime(); |
print(testsSharedName.. ": LSN[210873] = ".. tostring(LSN[210873])); -- |
endTime = GetTime(); |
print(testsSharedName.. "... in ".. endTime - startTime.. "ns."); |
startTime = GetTime(); |
print(testsSharedName.. ": SID[6603] = ".. tostring(SID[6603])); |
endTime = GetTime(); |
print(testsSharedName.. "... in ".. endTime - startTime.. "ns."); |
startTime = GetTime(); |
print(testsSharedName.. ": LSN[6603] = ".. tostring(LSN[6603])); |
endTime = GetTime(); |
print(testsSharedName.. "... in ".. endTime - startTime.. "ns."); |
startTime = GetTime(); |
print(testsSharedName.. ": SID[\"Lightning Bolt\"] = ".. tostring(SID["Lightning Bolt"])); -- |
endTime = GetTime(); |
print(testsSharedName.. "... in ".. endTime - startTime.. "ns."); |
startTime = GetTime(); |
print(testsSharedName.. ": LSN[\"Lightning Bolt\"] = ".. tostring(LSN["Lightning Bolt"])); -- |
endTime = GetTime(); |
print(testsSharedName.. "... in ".. endTime - startTime.. "ns."); |
startTime = GetTime(); |
print(testsSharedName.. ": SID[\"Taunt\"] = ".. tostring(SID["Taunt"])); -- |
endTime = GetTime(); |
print(testsSharedName.. "... in ".. endTime - startTime.. "ns."); |
startTime = GetTime(); |
print(testsSharedName.. ": LSN[\"Taunt\"] = ".. tostring(LSN["Taunt"])); -- |
endTime = GetTime(); |
print(testsSharedName.. "... in ".. endTime - startTime.. "ns."); |
else |
print(testsSharedName.. ": SID and/or LSN not found."); |
end |
end); |
end); |
-- Export to addon's environment: |
AddonEnv.LIBSN2SID = LIBSN2SID; |
------------------------------------------ |
-- LibSpellName2SID - test2 |
-- Test "Flyouts" and "Pets" and "Racials" |
------------------------------------------ |
local AddonName, AddonEnv = ...; |
local testsSharedName = AddonName.."-Tests"; |
local LIBSN2SID = AddonEnv.LIBSN2SID or LibStub("LibSpellName2SID-1.1"):NewInstance(testsSharedName); |
local SID = LIBSN2SID.clients[testsSharedName].SID; |
local LSN = LIBSN2SID.clients[testsSharedName].LSN; |
-- local SID = LIBSN2SID.SID; |
-- local LSN = LIBSN2SID.LSN; |
local Frame = CreateFrame("Frame"); |
Frame:RegisterEvent("PLAYER_LOGIN"); -- Not enough data from game til this event fires. |
-- Frame:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED"); -- This talent and/or the one in the line bellow |
-- Frame:RegisterEvent("PLAYER_TALENT_UPDATE"); -- should fire when the player switches spec. |
-- TESTED: Both of these fire Twice on Changing |
-- spec. On Login but "ACTIVE_..." fires Once, |
-- but "PLAYER_TALENT_..." fires Twice. |
-- Frame:RegisterEvent("PLAYER_ENTERING_WORLD"); |
Frame:SetScript("OnEvent", function() |
C_Timer.After(4, function() |
print(testsSharedName.. ": Starting test2 - \"Flyouts\", \"Pets\" and \"Racials\"."); |
if SID and LSN then |
startTime = GetTime(); |
print(testsSharedName.. ": SID[\"Hex\"] = ".. tostring(SID["Hex"])); -- |
endTime = GetTime(); |
print(testsSharedName.. "... in ".. endTime - startTime.. "ns."); |
startTime = GetTime(); |
print(testsSharedName.. ": SID[\"Hex(Spider)\"] = ".. tostring(SID["Hex(Spider)"])); -- |
endTime = GetTime(); |
print(testsSharedName.. "... in ".. endTime - startTime.. "ns."); |
startTime = GetTime(); |
print(testsSharedName.. ": SID[\"Web Spray\"] = ".. tostring(SID["Web Spray"])); -- |
endTime = GetTime(); |
print(testsSharedName.. "... in ".. endTime - startTime.. "ns."); |
startTime = GetTime(); |
print(testsSharedName.. ": SID[\"Gift of the Naaru\"] = ".. tostring(SID["Gift of the Naaru"])); -- |
endTime = GetTime(); |
print(testsSharedName.. "... in ".. endTime - startTime.. "ns."); |
startTime = GetTime() *1000000; |
print(testsSharedName.. ": LSN[\"Hex\"] = ".. tostring(LSN["Hex"])); -- |
endTime = GetTime() *1000000; |
print(testsSharedName.. "... in ".. endTime - startTime.. "ns."); |
startTime = GetTime() *1000000; |
print(testsSharedName.. ": LSN[\"Hex(Spider)\"] = ".. tostring(LSN["Hex(Spider)"])); -- |
endTime = GetTime() *1000000; |
print(testsSharedName.. "... in ".. endTime - startTime.. "ns."); |
startTime = GetTime() *1000000; |
print(testsSharedName.. ": LSN[\"Web Spray\"] = ".. tostring(LSN["Web Spray"])); -- |
endTime = GetTime() *1000000; |
print(testsSharedName.. "... in ".. endTime - startTime.. "ns."); |
startTime = GetTime(); |
print(testsSharedName.. ": LSN[\"Gift of the Naaru\"] = ".. tostring(LSN["Gift of the Naaru"])); -- |
endTime = GetTime(); |
print(testsSharedName.. "... in ".. endTime - startTime.. "ns."); |
else |
print(testsSharedName.. ": SID and/or LSN not found."); |
end |
end); |
end); |
-- Export to addon's environment: |
AddonEnv.LIBSN2SID = LIBSN2SID; |
-------------------------------------------------------- |
-- LibSpellName2SID - test3 |
-- Test Alliance/Horde spells (same name, different IDs) |
-------------------------------------------------------- |
local AddonName, AddonEnv = ...; |
local testsSharedName = AddonName.."-Tests"; |
local LIBSN2SID = AddonEnv.LIBSN2SID or LibStub("LibSpellName2SID-1.1"):NewInstance(testsSharedName); |
local SID = LIBSN2SID.clients[testsSharedName].SID; |
local LSN = LIBSN2SID.clients[testsSharedName].LSN; |
-- local SID = LIBSN2SID.SID; |
-- local LSN = LIBSN2SID.LSN; |
local Frame = CreateFrame("Frame"); |
Frame:RegisterEvent("PLAYER_LOGIN"); -- Not enough data from game til this event fires. |
-- Frame:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED"); -- This talent and/or the one in the line bellow |
-- Frame:RegisterEvent("PLAYER_TALENT_UPDATE"); -- should fire when the player switches spec. |
-- TESTED: Both of these fire Twice on Changing |
-- spec. On Login but "ACTIVE_..." fires Once, |
-- but "PLAYER_TALENT_..." fires Twice. |
-- Frame:RegisterEvent("PLAYER_ENTERING_WORLD"); |
Frame:SetScript("OnEvent", function() |
C_Timer.After(5, function() |
print(testsSharedName.. ": Starting test3 - Alliance/Horde spells (same name, different IDs)."); |
if SID and LSN then |
print(testsSharedName.. ": LSN[\"Portal: Tol Barad(Alliance)\"] = ".. tostring(LSN["Portal: Tol Barad(Alliance)"])); -- |
print(testsSharedName.. ": LSN[\"Portal: Tol Barad(Horde)\"] = ".. tostring(LSN["Portal: Tol Barad(Horde)"])); -- |
print(testsSharedName.. ": LSN[\"Portal: Tol Barad\"] = ".. tostring(LSN["Portal: Tol Barad"])); -- |
print(testsSharedName.. ": SID[\"Portal: Tol Barad(Alliance)\"] = ".. tostring(SID["Portal: Tol Barad(Alliance)"])); -- |
print(testsSharedName.. ": SID[\"Portal: Tol Barad(Horde)\"] = ".. tostring(SID["Portal: Tol Barad(Horde)"])); -- |
print(testsSharedName.. ": SID[\"Portal: Tol Barad\"] = ".. tostring(SID["Portal: Tol Barad"])); -- |
print(testsSharedName.. ": Will now set faction to Alliance."); |
LIBSN2SID.SetFaction("Alliance", testsSharedName); |
print(testsSharedName.. ": LSN[\"Portal: Tol Barad\"] = ".. tostring(LSN["Portal: Tol Barad"])); |
print(testsSharedName.. ": SID[\"Portal: Tol Barad\"] = ".. tostring(SID["Portal: Tol Barad"])); |
print(testsSharedName.. ": Will now set faction to Horde."); |
-- LIBSN2SID.SetFaction("Horde", testsSharedName); |
LIBSN2SID.SetFaction("Horde", testsSharedName); |
print(testsSharedName.. ": LSN[\"Portal: Tol Barad\"] = ".. tostring(LSN["Portal: Tol Barad"])); |
print(testsSharedName.. ": SID[\"Portal: Tol Barad\"] = ".. tostring(SID["Portal: Tol Barad"])); |
print(testsSharedName.. ": Will now set faction back to player\'s."); |
LIBSN2SID.SetFaction((UnitFactionGroup("player")), testsSharedName); |
print(testsSharedName.. ": LSN[\"Portal: Tol Barad\"] = ".. tostring(LSN["Portal: Tol Barad"])); |
print(testsSharedName.. ": SID[\"Portal: Tol Barad\"] = ".. tostring(SID["Portal: Tol Barad"])); |
else |
print(testsSharedName.. ": SID and/or LSN not found."); |
end |
end); |
end); |
-- Export to addon's environment: |
AddonEnv.LIBSN2SID = LIBSN2SID; |
-------------------------------------------------------- |
-- LibSpellName2SID - test4 |
-- Test Removal and re-Registration of library instances |
-------------------------------------------------------- |
local AddonName, AddonEnv = ...; |
local testsSharedName = AddonName.."-Tests"; |
local LIBSN2SID = AddonEnv.LIBSN2SID or LibStub("LibSpellName2SID-1.1"):NewInstance(testsSharedName); |
local SID = LIBSN2SID.clients[testsSharedName].SID; |
local LSN = LIBSN2SID.clients[testsSharedName].LSN; |
-- local SID = LIBSN2SID.SID; |
-- local LSN = LIBSN2SID.LSN; |
local Frame = CreateFrame("Frame"); |
Frame:RegisterEvent("PLAYER_LOGIN"); -- Not enough data from game til this event fires. |
-- Frame:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED"); -- This talent and/or the one in the line bellow |
-- Frame:RegisterEvent("PLAYER_TALENT_UPDATE"); -- should fire when the player switches spec. |
-- TESTED: Both of these fire Twice on Changing |
-- spec. But On Login "ACTIVE_..." fires Once, |
-- whereas "PLAYER_TALENT_..." fires Twice. |
-- Frame:RegisterEvent("PLAYER_ENTERING_WORLD"); |
Frame:SetScript("OnEvent", function() |
C_Timer.After(5, function() |
print(testsSharedName.. ": Starting test4 - Removal and re-Registration of library instances."); |
if SID and LSN then |
print(testsSharedName.. ": LSN[\"Portal: Shattrath(Alliance)\"] = ".. tostring(LSN["Portal: Shattrath(Alliance)"])); -- |
print(testsSharedName.. ": LSN[\"Portal: Shattrath(Horde)\"] = ".. tostring(LSN["Portal: Shattrath(Horde)"])); -- |
print(testsSharedName.. ": LSN[\"Portal: Shattrath\"] = ".. tostring(LSN["Portal: Shattrath"])); -- |
print(testsSharedName.. ": SID[\"Portal: Shattrath(Alliance)\"] = ".. tostring(SID["Portal: Shattrath(Alliance)"])); -- |
print(testsSharedName.. ": SID[\"Portal: Shattrath(Horde)\"] = ".. tostring(SID["Portal: Shattrath(Horde)"])); -- |
print(testsSharedName.. ": SID[\"Portal: Shattrath\"] = ".. tostring(SID["Portal: Shattrath"])); -- |
print(testsSharedName.. ": type(LIBSN2SID) = ".. type(LIBSN2SID)); |
print(testsSharedName.. ": type(LIBSN2SID.clients) = ".. type(LIBSN2SID.clients)); |
print(testsSharedName.. ": type(LIBSN2SID.clients[".. testsSharedName.. "]) = ".. type(LIBSN2SID.clients[testsSharedName])); |
if type(LIBSN2SID) == "table" then |
-- local tableKey = next(LIBSN2SID, nil); |
-- local tableValue; |
-- while tableKey do |
-- tableValue = tostring(LIBSN2SID[tableKey]); |
-- print(testsSharedName.. ": Key = ".. tableKey.. " Value = ".. tableValue); |
-- tableKey = next(LIBSN2SID, tableKey); |
-- end |
-- tableKey, tableValue = nil, nil; |
-- print(testsSharedName.. ": No more values to print."); |
if LIBSN2SID.clients[testsSharedName] then |
local tableKey = next(LIBSN2SID.clients[testsSharedName], nil); |
local tableValue; |
while tableKey do |
tableValue = tostring(LIBSN2SID.clients[testsSharedName][tableKey]); |
print(testsSharedName.. ": Key = ".. tableKey.. " Value = ".. tableValue); |
tableKey = next(LIBSN2SID.clients[testsSharedName], tableKey); |
end |
tableKey, tableValue = nil, nil; |
print(testsSharedName.. ": No more values to print."); |
end |
end |
print(testsSharedName.. ": Will now remove this instance of LibSpellName2SID-1.1 !"); |
LIBSN2SID:RemoveInstance(testsSharedName); |
print(testsSharedName.. ": type(LIBSN2SID) = ".. type(LIBSN2SID)); |
print(testsSharedName.. ": type(LIBSN2SID.clients) = ".. type(LIBSN2SID.clients)); |
print(testsSharedName.. ": type(LIBSN2SID.clients[".. testsSharedName.. "]) = ".. type(LIBSN2SID.clients[testsSharedName])); |
if type(LIBSN2SID) == "table" then |
-- local tableKey = next(LIBSN2SID, nil); |
-- local tableValue; |
-- while tableKey do |
-- tableValue = tostring(LIBSN2SID[tableKey]); |
-- print(testsSharedName.. ": Key = ".. tableKey.. " Value = ".. tableValue); |
-- tableKey = next(LIBSN2SID, tableKey); |
-- end |
-- tableKey, tableValue = nil, nil; |
-- print(testsSharedName.. ": No more values to print."); |
if LIBSN2SID.clients[testsSharedName] then |
local tableKey = next(LIBSN2SID.clients[testsSharedName], nil); |
local tableValue; |
while tableKey do |
tableValue = tostring(LIBSN2SID.clients[testsSharedName][tableKey]); |
print(testsSharedName.. ": Key = ".. tableKey.. " Value = ".. tableValue); |
tableKey = next(LIBSN2SID.clients[testsSharedName], tableKey); |
end |
tableKey, tableValue = nil, nil; |
print(testsSharedName.. ": No more values to print."); |
end |
end |
print(testsSharedName.. ": Will now register a new instance of LibSpellName2SID-1.1 as \"".. testsSharedName.. "\"!"); |
LIBSN2SID = LibStub("LibSpellName2SID-1.1"):NewInstance(testsSharedName); |
print(testsSharedName.. ": SID[\"Auto Attack\"] = ".. tostring(SID["Auto Attack"])); |
print(testsSharedName.. ": LSN[\"Auto Attack\"] = ".. tostring(LSN["Auto Attack"])); |
print(testsSharedName.. ": SID[\"Made It Up\"] = ".. tostring(SID["Made It Up"])); |
print(testsSharedName.. ": LSN[\"Made It Up\"] = ".. tostring(LSN["Made It Up"])); |
print(testsSharedName.. ": SID[\"Hex(Spider)\"] = ".. tostring(SID["Hex(Spider)"])); |
print(testsSharedName.. ": LSN[\"Hex(Spider)\"] = ".. tostring(LSN["Hex(Spider)"])); |
print(testsSharedName.. ": LSN[\"Portal: Shattrath\"] = ".. tostring(LSN["Portal: Shattrath"])); |
print(testsSharedName.. ": SID[\"Portal: Shattrath\"] = ".. tostring(SID["Portal: Shattrath"])); |
else |
print(testsSharedName.. ": SID and/or LSN not found."); |
end |
end); |
end); |
-- Export to addon's environment: |
AddonEnv.LIBSN2SID = LIBSN2SID; |
## Interface: 70000 |
## Title: Lib: LibStub |
## Notes: Universal Library Stub |
## Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel |
## X-Website: http://www.wowace.com/addons/libstub/ |
## X-Category: Library |
## X-License: Public Domain |
## X-Curse-Packaged-Version: 1.0.2-70000 |
## X-Curse-Project-Name: LibStub |
## X-Curse-Project-ID: libstub |
## X-Curse-Repository-ID: wow/libstub/mainline |
LibStub.lua |
-- $Id: LibStub.lua 103 2014-10-16 03:02:50Z mikk $ |
-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/addons/libstub/ for more info |
-- LibStub is hereby placed in the Public Domain |
-- Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke |
local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS! |
local LibStub = _G[LIBSTUB_MAJOR] |
-- Check to see is this version of the stub is obsolete |
if not LibStub or LibStub.minor < LIBSTUB_MINOR then |
LibStub = LibStub or {libs = {}, minors = {} } |
_G[LIBSTUB_MAJOR] = LibStub |
LibStub.minor = LIBSTUB_MINOR |
-- LibStub:NewLibrary(major, minor) |
-- major (string) - the major version of the library |
-- minor (string or number ) - the minor version of the library |
-- |
-- returns nil if a newer or same version of the lib is already present |
-- returns empty library object or old library object if upgrade is needed |
function LibStub:NewLibrary(major, minor) |
assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)") |
minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.") |
local oldminor = self.minors[major] |
if oldminor and oldminor >= minor then return nil end |
self.minors[major], self.libs[major] = minor, self.libs[major] or {} |
return self.libs[major], oldminor |
end |
-- LibStub:GetLibrary(major, [silent]) |
-- major (string) - the major version of the library |
-- silent (boolean) - if true, library is optional, silently return nil if its not found |
-- |
-- throws an error if the library can not be found (except silent is set) |
-- returns the library object if found |
function LibStub:GetLibrary(major, silent) |
if not self.libs[major] and not silent then |
error(("Cannot find a library instance of %q."):format(tostring(major)), 2) |
end |
return self.libs[major], self.minors[major] |
end |
-- LibStub:IterateLibraries() |
-- |
-- Returns an iterator for the currently registered libraries |
function LibStub:IterateLibraries() |
return pairs(self.libs) |
end |
setmetatable(LibStub, { __call = LibStub.GetLibrary }) |
end |
--------------------- |
-- LibspellName2SID (deprecated) / LibSpellName2SID |
-- V.10000: 2009 originally by Twobits[1], as part of ReadySpells[2] |
-- 2010 edited by benots4[3] |
-- 2017 published as an addon of its own by aallkkaa[4] |
-- V.10001 - 10103: 2017-2019 WoW 7.3.x to 8.x versions by aallkkaa [4] |
-- |
-- [1] https://www.wowinterface.com/forums/member.php?userid=139157 |
-- https://www.curseforge.com/members/twobits |
-- [2] https://www.curseforge.com/wow/addons/readyspells (Twobits' 3.x version: |
-- 2009) |
-- [3] https://www.wowinterface.com/forums/member.php?action=getinfo&userid=201937 |
-- [4] https://www.wowinterface.com/forums/member.php?u=335646 |
-------------------------------- |
-- -- -- API: -- -- -- |
---------------------- |
-- -- ENABLE IN YOUR ADDON -- -- |
-- local LibSpellName2SID = LibStub("LibSpellName2SID-1.1"):NewInstance(AddonName (STRING)) |
-- -- REMOVE FROM YOUR ADDON -- -- |
-- LibSpellName2SID:RemoveInstance(AddonName (STRING), DontErrorOnInexistentInstanceName (BOOLEAN)) |
-- -- USABLE METATABLES AND FUNCTIONS -- -- |
-- LibSpellName2SID.clients[testsSharedName].SID["EnglishSpellName"] -- Spell ID of English Spell |
-- Name (STRING) |
-- LibSpellName2SID.clients[testsSharedName].LSN["EnglishSpellName"] -- Localized Spell Name of |
-- English Spell Name (STRING) |
-- LibSpellName2SID.SetFaction(faction (STRING), AddonName (STRING)) -- Set the faction to look up |
-- spells for (when applicable) |
-- -- (OPTIONAL, BUT RECOMMENDED) LOCAL ALIAS -- -- |
-- local SID = LibSpellName2SID.clients[AddonName].SID -- Useage: SID["EnglishSpellName"] |
-- local LSN = LibSpellName2SID.clients[AddonName].LSN -- Useage: LSN["EnglishSpellName"] |
-- -- CURRENTLY UNAVAILABLE -- -- |
-- LibSpellName2SID:GetNumSpells() -- Get the number of spells in the database - TEMPORARILY OUT |
--------------------- |
-- Initialization -- |
-------------------- |
-- Library's version values -- |
local LibSpellName2SID_MAJOR = "LibSpellName2SID-1.1"; |
local LibSpellName2SID_MINOR = 10103; |
-- DataSource -- |
-- gameBuild = 29981 |
-- clientLocale = enUS |
-- Register with LibStub -- |
assert(LibStub, LibSpellName2SID_MAJOR.. "-".. LibSpellName2SID_MINOR.." requires LibStub."); |
local oldLibSN2SID, oldMinor = LibStub:NewLibrary(LibSpellName2SID_MAJOR, LibSpellName2SID_MINOR); |
if oldLibSN2SID == nil then -- newer or same version of the lib is already present |
return; -- Nothing needs to be done |
else -- no old lib or upgrade is needed |
if oldMinor and (oldMinor < LibSpellName2SID_MINOR) then -- old library object, upgrade needed |
LibSN2SID = oldLibSN2SID; |
if oldLibSN2SID.libFrame then -- Reuse old lib's frame if available |
oldLibSN2SID.libFrame:UnregisterAllEvents(); |
LibSN2SID.libFrame = oldLibSN2SID.libFrame; |
else |
LibSN2SID.libFrame = CreateFrame("Frame"); |
end |
else -- no old lib, return from LibStub:NewLibrary is an empty table |
LibSN2SID = oldLibSN2SID; |
LibSN2SID.libFrame = CreateFrame("Frame"); |
end |
end |
-- Set the library database contents -- |
--------------------------------------- |
LibSN2SID.minor = LibSpellName2SID_MINOR; |
if LibSN2SID.DB then -- Clear old version's contents, if applicable |
wipe(LibSN2SID.DB); |
end |
LibSN2SID.DB = { |
["General"] = { |
["Others"] = { |
["Auto Attack"] = 6603, |
["Auto Shot"] = 75, |
["Cooking Fire"] = 818, |
["Herbalism Skills"] = 193290, |
["Honorable Medallion"] = 195710, |
["Mining Skills"] = 2656, |
["Revive Battle Pets"] = 125439, |
["Shoot"] = 5019, |
["Wartime Ability"] = 264739, |
}, |
["Racials"] = { |
["Draenei"] = { |
["Gift of the Naaru"] = 59548, |
}, |
["DarkIronDwarf"] = { |
["Fireblood"] = 265221, |
["Mole Machine"] = 265225, |
}, |
["Worgen"] = { |
["Running Wild"] = 87840, |
["Darkflight"] = 68992, |
["Two Forms"] = 68996, |
}, |
["Pandaren"] = { |
["Quaking Palm"] = 107079, |
}, |
["Scourge"] = { |
["Will of the Forsaken"] = 7744, |
["Cannibalize"] = 20577, |
}, |
["Orc"] = { |
["Blood Fury"] = 20572, |
}, |
["Gnome"] = { |
["Escape Artist"] = 20589, |
}, |
["Tauren"] = { |
["War Stomp"] = 20549, |
}, |
["Troll"] = { |
["Berserking"] = 26297, |
}, |
["BloodElf"] = { |
["Arcane Torrent"] = 129597, |
}, |
["VoidElf"] = { |
["Spatial Rift"] = 256948, |
}, |
["NightElf"] = { |
["Shadowmeld"] = 58984, |
}, |
["Dwarf"] = { |
["Stoneform"] = 20594, |
}, |
["Human"] = { |
["Every Man for Himself"] = 59752, |
}, |
["LightforgedDraenei"] = { |
["Forge of Light"] = 259930, |
["Light's Judgment"] = 255647, |
}, |
["Goblin"] = { |
["Rocket Barrage"] = 69041, |
["Rocket Jump"] = 69070, |
["Pack Hobgoblin"] = 69046, |
}, |
["Nightborne"] = { |
["Arcane Pulse"] = 260364, |
["Cantrips"] = 255661, |
}, |
["HighmountainTauren"] = { |
["Bull Rush"] = 255654, |
}, |
["KulTiran"] = { |
["Haymaker"] = 287712, |
}, |
["MagharOrc"] = { |
["Ancestral Call"] = 274738, |
}, |
["ZandalariTroll"] = { |
["Embrace of the Loa"] = 292752, |
["Regeneratin'"] = 291944, |
["Pterrordax Swoop"] = 281954, |
}, |
}, |
["ZoneAbilities"] = { |
["Artillery Strike"] = 162075, |
["Call to Arms"] = 161676, |
["Champion's Honor"] = 164221, |
["Combat Ally"] = 211390, |
["Fel Heart Bond"] = 248011, |
["Frostwolf War Wolf"] = 164222, |
["Garrison Ability"] = 161691, |
["Guardian Orb"] = 161767, |
["Home Away from Home"] = 168487, |
["Light's Judgment"] = 247427, |
["Logging"] = 167895, |
["Shroud of Arcane Echoes"] = 248779, |
["Smuggling Run!"] = 170108, |
["Summon Lightforged Warframe"] = 250436, |
["Summon Mechashredder 5000"] = 164050, |
["Telaari Siege Engine"] = 160240, |
["Telaari Talbuk"] = 165803, |
["Vindicaar Matrix Crystal"] = 251463, |
}, |
["GuildPerks"] = { |
["Mobile Banking"] = 83958, |
}, |
}, |
["DEATHKNIGHT"] = { |
["Frost_Talents"] = { |
["Wraith Walk"] = 212552, |
["Blinding Sleet"] = 207167, |
["Frostscythe"] = 207230, |
["Death Pact"] = 48743, |
["Horn of Winter"] = 57330, |
["Asphyxiate"] = 108194, |
["Breath of Sindragosa"] = 152279, |
["Frostwyrm's Fury"] = 279302, |
["Glacial Advance"] = 194913, |
}, |
["Unholy"] = { |
["Anti-Magic Shell"] = 48707, |
["Apocalypse"] = 275699, |
["Army of the Dead"] = 42650, |
["Chains of Ice"] = 45524, |
["Control Undead"] = 111673, |
["Corpse Exploder"] = 127344, |
["Dark Command"] = 56222, |
["Dark Transformation"] = 63560, |
["Death Coil"] = 47541, |
["Death Gate"] = 50977, |
["Death Grip"] = 49576, |
["Death Strike"] = 49998, |
["Death and Decay"] = 43265, |
["Death's Advance"] = 48265, |
["Festering Strike"] = 85948, |
["Icebound Fortitude"] = 48792, |
["Mind Freeze"] = 47528, |
["Outbreak"] = 77575, |
["Path of Frost"] = 3714, |
["Raise Ally"] = 61999, |
["Raise Dead"] = 46584, |
["Runeforging"] = 53428, |
["Scourge Strike"] = 55090, |
}, |
["Blood"] = { |
["Anti-Magic Shell"] = 48707, |
["Asphyxiate"] = 221562, |
["Blood Boil"] = 50842, |
["Control Undead"] = 111673, |
["Corpse Exploder"] = 127344, |
["Dancing Rune Weapon"] = 49028, |
["Dark Command"] = 56222, |
["Death Gate"] = 50977, |
["Death Grip"] = 49576, |
["Death Strike"] = 49998, |
["Death and Decay"] = 43265, |
["Death's Advance"] = 48265, |
["Death's Caress"] = 195292, |
["Gorefiend's Grasp"] = 108199, |
["Heart Strike"] = 206930, |
["Icebound Fortitude"] = 48792, |
["Marrowrend"] = 195182, |
["Mind Freeze"] = 47528, |
["Path of Frost"] = 3714, |
["Raise Ally"] = 61999, |
["Runeforging"] = 53428, |
["Vampiric Blood"] = 55233, |
}, |
["Pets"] = { |
["Ghoul"] = { |
["Gnaw"] = 47481, |
["Claw"] = 47468, |
["Huddle"] = 47484, |
["Leap"] = 47482, |
}, |
}, |
["Frost"] = { |
["Anti-Magic Shell"] = 48707, |
["Chains of Ice"] = 45524, |
["Control Undead"] = 111673, |
["Corpse Exploder"] = 127344, |
["Dark Command"] = 56222, |
["Death Gate"] = 50977, |
["Death Grip"] = 49576, |
["Death Strike"] = 49998, |
["Death's Advance"] = 48265, |
["Empower Rune Weapon"] = 47568, |
["Frost Strike"] = 49143, |
["Howling Blast"] = 49184, |
["Icebound Fortitude"] = 48792, |
["Mind Freeze"] = 47528, |
["Obliterate"] = 49020, |
["Path of Frost"] = 3714, |
["Pillar of Frost"] = 51271, |
["Raise Ally"] = 61999, |
["Remorseless Winter"] = 196770, |
["Runeforging"] = 53428, |
}, |
["Blood_Talents"] = { |
["Tombstone"] = 219809, |
["Wraith Walk"] = 212552, |
["Rune Tap"] = 194679, |
["Blooddrinker"] = 206931, |
["Bonestorm"] = 194844, |
["Rune Strike"] = 210764, |
["Consumption"] = 274156, |
["Mark of Blood"] = 206940, |
}, |
["Unholy_PVPTalents"] = { |
["Dark Simulacrum"] = 77606, |
["Lichborne"] = 287081, |
["Transfusion"] = 288977, |
["Gladiator's Medallion"] = 208683, |
["Necrotic Strike"] = 223829, |
["Anti-Magic Zone"] = 51052, |
["Reanimation"] = 210128, |
["Raise Abomination"] = 288853, |
}, |
["Unholy_Talents"] = { |
["Summon Gargoyle"] = 49206, |
["Wraith Walk"] = 212552, |
["Clawing Shadows"] = 207311, |
["Epidemic"] = 207317, |
["Death Pact"] = 48743, |
["Unholy Blight"] = 115989, |
["Asphyxiate"] = 108194, |
["Defile"] = 152280, |
["Soul Reaper"] = 130736, |
["Unholy Frenzy"] = 207289, |
}, |
["Blood_PVPTalents"] = { |
["Dark Simulacrum"] = 77606, |
["Lichborne"] = 287081, |
["Transfusion"] = 288977, |
["Gladiator's Medallion"] = 208683, |
["Necrotic Strike"] = 223829, |
["Anti-Magic Zone"] = 51052, |
["Reanimation"] = 210128, |
["Raise Abomination"] = 288853, |
}, |
["Frost_PVPTalents"] = { |
["Dark Simulacrum"] = 77606, |
["Lichborne"] = 287081, |
["Transfusion"] = 288977, |
["Gladiator's Medallion"] = 208683, |
["Necrotic Strike"] = 223829, |
["Anti-Magic Zone"] = 51052, |
["Reanimation"] = 210128, |
["Raise Abomination"] = 288853, |
}, |
["METADATA"] = { |
["Specs"] = { |
["Unholy"] = 252, |
["Frost"] = 251, |
["Blood"] = 250, |
}, |
}, |
}, |
["DEMONHUNTER"] = { |
["Havoc_Talents"] = { |
["Nemesis"] = 206491, |
["Dark Slash"] = 258860, |
["Netherwalk"] = 196555, |
["Fel Eruption"] = 211881, |
["Felblade"] = 232893, |
["Fel Barrage"] = 258925, |
["Immolation Aura"] = 258920, |
}, |
["Vengeance_Talents"] = { |
["Fracture"] = 263642, |
["Sigil of Chains"] = 202138, |
["Fel Devastation"] = 212084, |
["Felblade"] = 232893, |
["Soul Barrier"] = 263648, |
["Spirit Bomb"] = 247454, |
}, |
["Havoc"] = { |
["Blur"] = 198589, |
["Chaos Nova"] = 179057, |
["Torment"] = 281854, |
["Metamorphosis"] = 191427, |
["Demon's Bite"] = 162243, |
["Darkness"] = 196718, |
["Eye Beam"] = 198013, |
["Chaos Strike"] = 162794, |
["Spectral Sight"] = 188501, |
["Fel Rush"] = 195072, |
["Disrupt"] = 183752, |
["Consume Magic"] = 278326, |
["Glide"] = 131347, |
["Throw Glaive"] = 185123, |
["Vengeful Retreat"] = 198793, |
["Blade Dance"] = 188499, |
["Imprison"] = 217832, |
}, |
["Vengeance"] = { |
["Soul Cleave"] = 162794, |
["Torment"] = 198589, |
["Fiery Brand"] = 179057, |
["Metamorphosis"] = 191427, |
["Shear"] = 203782, |
["Imprison"] = 217832, |
["Demon Spikes"] = 198793, |
["Spectral Sight"] = 188501, |
["Sigil of Misery"] = 207684, |
["Disrupt"] = 183752, |
["Consume Magic"] = 278326, |
["Glide"] = 131347, |
["Throw Glaive"] = 185123, |
["Sigil of Flame"] = 188499, |
["Infernal Strike"] = 195072, |
["Sigil of Silence"] = 202137, |
["Immolation Aura"] = 198013, |
}, |
["Vengeance_PVPTalents"] = { |
["Tormentor"] = 207029, |
["Gladiator's Medallion"] = 208683, |
["Illidan's Grasp"] = 205630, |
["Demonic Trample"] = 205629, |
["Reverse Magic"] = 205604, |
}, |
["Havoc_PVPTalents"] = { |
["Tormentor"] = 207029, |
["Gladiator's Medallion"] = 208683, |
["Illidan's Grasp"] = 205630, |
["Demonic Trample"] = 205629, |
["Reverse Magic"] = 205604, |
}, |
["METADATA"] = { |
["Specs"] = { |
["Havoc"] = 577, |
["Vengeance"] = 581, |
}, |
}, |
}, |
["DRUID"] = { |
["Restoration_PVPTalents"] = { |
["Thorns"] = 236696, |
["Overrun"] = 202246, |
["Gladiator's Medallion"] = 208683, |
["Faerie Swarm"] = 209749, |
["Alpha Challenge"] = 207017, |
["Demoralizing Roar"] = 201664, |
["Cyclone"] = 209753, |
}, |
["Feral_Talents"] = { |
["Mass Entanglement"] = 102359, |
["Brutal Slash"] = 202028, |
["Savage Roar"] = 52610, |
["Typhoon"] = 132469, |
["Feral Frenzy"] = 274837, |
["Tiger Dash"] = 252216, |
["Wild Charge"] = 102401, |
["Incarnation: King of the Jungle"] = 102543, |
["Mighty Bash"] = 5211, |
["Renewal"] = 108238, |
["Primal Wrath"] = 285381, |
}, |
["Feral"] = { |
["Stampeding Roar"] = 106898, |
["Skull Bash"] = 106839, |
["Entangling Roots"] = 339, |
["Mangle"] = 33917, |
["Charm Woodland Creature"] = 127757, |
["Hibernate"] = 2637, |
["Shred"] = 5221, |
["Tiger's Fury"] = 5217, |
["Remove Corruption"] = 2782, |
["Rebirth"] = 20484, |
["Treant Form"] = 114282, |
["Thrash"] = 106832, |
["Travel Form"] = 783, |
["Prowl"] = 5215, |
["Regrowth"] = 8936, |
["Ferocious Bite"] = 22568, |
["Growl"] = 6795, |
["Revive"] = 50769, |
["Swipe"] = 213764, |
["Rake"] = 1822, |
["Rip"] = 1079, |
["Cat Form"] = 768, |
["Maim"] = 22570, |
["Berserk"] = 106951, |
["Dreamwalk"] = 193753, |
["Moonfire"] = 8921, |
["Teleport: Moonglade"] = 18960, |
["Dash"] = 1850, |
["Flap"] = 164862, |
["Survival Instincts"] = 61336, |
["Bear Form"] = 5487, |
["Stag Form"] = 210053, |
["Soothe"] = 2908, |
}, |
["Feral_PVPTalents"] = { |
["Thorns"] = 236696, |
["Overrun"] = 202246, |
["Gladiator's Medallion"] = 208683, |
["Faerie Swarm"] = 209749, |
["Alpha Challenge"] = 207017, |
["Demoralizing Roar"] = 201664, |
["Cyclone"] = 209753, |
}, |
["METADATA"] = { |
["Specs"] = { |
["Feral"] = 103, |
["Balance"] = 102, |
["Guardian"] = 104, |
["Restoration"] = 105, |
}, |
}, |
["Restoration"] = { |
["Swiftmend"] = 18562, |
["Solar Wrath"] = 5176, |
["Revitalize"] = 212040, |
["Nature's Cure"] = 88423, |
["Mangle"] = 33917, |
["Efflorescence"] = 145205, |
["Charm Woodland Creature"] = 127757, |
["Hibernate"] = 2637, |
["Shred"] = 5221, |
["Rebirth"] = 20484, |
["Treant Form"] = 114282, |
["Travel Form"] = 783, |
["Prowl"] = 5215, |
["Tranquility"] = 740, |
["Wild Growth"] = 48438, |
["Lifebloom"] = 33763, |
["Ursol's Vortex"] = 102793, |
["Revive"] = 50769, |
["Growl"] = 6795, |
["Regrowth"] = 8936, |
["Bear Form"] = 5487, |
["Dash"] = 1850, |
["Innervate"] = 29166, |
["Entangling Roots"] = 339, |
["Soothe"] = 2908, |
["Cat Form"] = 768, |
["Barkskin"] = 22812, |
["Teleport: Moonglade"] = 18960, |
["Stag Form"] = 210053, |
["Moonfire"] = 8921, |
["Dreamwalk"] = 193753, |
["Ironbark"] = 102342, |
["Rejuvenation"] = 774, |
["Flap"] = 164862, |
["Sunfire"] = 93402, |
}, |
["Balance"] = { |
["Solar Wrath"] = 190984, |
["Prowl"] = 5215, |
["Lunar Strike"] = 194153, |
["Regrowth"] = 8936, |
["Innervate"] = 29166, |
["Bear Form"] = 5487, |
["Celestial Alignment"] = 194223, |
["Growl"] = 6795, |
["Entangling Roots"] = 339, |
["Revive"] = 50769, |
["Teleport: Moonglade"] = 18960, |
["Flap"] = 164862, |
["Mangle"] = 33917, |
["Starsurge"] = 78674, |
["Charm Woodland Creature"] = 127757, |
["Hibernate"] = 2637, |
["Rebirth"] = 20484, |
["Moonkin Form"] = 24858, |
["Shred"] = 5221, |
["Soothe"] = 2908, |
["Starfall"] = 191034, |
["Remove Corruption"] = 2782, |
["Moonfire"] = 8921, |
["Barkskin"] = 22812, |
["Cat Form"] = 768, |
["Stag Form"] = 210053, |
["Treant Form"] = 114282, |
["Dreamwalk"] = 193753, |
["Dash"] = 1850, |
["Sunfire"] = 93402, |
["Solar Beam"] = 78675, |
["Travel Form"] = 783, |
}, |
["Guardian"] = { |
["Swiftmend"] = 18562, |
["Stampeding Roar"] = 106898, |
["Skull Bash"] = 106839, |
["Entangling Roots"] = 339, |
["Mangle"] = 33917, |
["Charm Woodland Creature"] = 127757, |
["Hibernate"] = 2637, |
["Shred"] = 5221, |
["Remove Corruption"] = 2782, |
["Rebirth"] = 20484, |
["Ironfur"] = 192081, |
["Thrash"] = 106832, |
["Travel Form"] = 783, |
["Prowl"] = 5215, |
["Regrowth"] = 8936, |
["Wild Growth"] = 48438, |
["Growl"] = 6795, |
["Maul"] = 6807, |
["Revive"] = 50769, |
["Frenzied Regeneration"] = 22842, |
["Dreamwalk"] = 193753, |
["Incapacitating Roar"] = 99, |
["Bear Form"] = 5487, |
["Dash"] = 1850, |
["Soothe"] = 2908, |
["Cat Form"] = 768, |
["Barkskin"] = 22812, |
["Swipe"] = 213764, |
["Teleport: Moonglade"] = 18960, |
["Moonfire"] = 8921, |
["Stag Form"] = 210053, |
["Survival Instincts"] = 61336, |
["Rejuvenation"] = 774, |
["Flap"] = 164862, |
["Treant Form"] = 114282, |
}, |
["Restoration_Talents"] = { |
["Mass Entanglement"] = 102359, |
["Flourish"] = 197721, |
["Typhoon"] = 132469, |
["Mighty Bash"] = 5211, |
["Wild Charge"] = 102401, |
["Tiger Dash"] = 252216, |
["Cenarion Ward"] = 102351, |
["Incarnation: Tree of Life"] = 33891, |
["Renewal"] = 108238, |
}, |
["Balance_Talents"] = { |
["Force of Nature"] = 205636, |
["New Moon"] = 274281, |
["Stellar Flare"] = 202347, |
["Mass Entanglement"] = 102359, |
["Typhoon"] = 132469, |
["Warrior of Elune"] = 202425, |
["Mighty Bash"] = 5211, |
["Wild Charge"] = 102401, |
["Tiger Dash"] = 252216, |
["Fury of Elune"] = 202770, |
["Incarnation: Chosen of Elune"] = 102560, |
["Renewal"] = 108238, |
}, |
["Guardian_PVPTalents"] = { |
["Thorns"] = 236696, |
["Overrun"] = 202246, |
["Gladiator's Medallion"] = 208683, |
["Faerie Swarm"] = 209749, |
["Alpha Challenge"] = 207017, |
["Demoralizing Roar"] = 201664, |
["Cyclone"] = 209753, |
}, |
["Balance_PVPTalents"] = { |
["Thorns"] = 236696, |
["Overrun"] = 202246, |
["Gladiator's Medallion"] = 208683, |
["Faerie Swarm"] = 209749, |
["Alpha Challenge"] = 207017, |
["Demoralizing Roar"] = 201664, |
["Cyclone"] = 209753, |
}, |
["Guardian_Talents"] = { |
["Mass Entanglement"] = 102359, |
["Bristling Fur"] = 155835, |
["Lunar Beam"] = 204066, |
["Pulverize"] = 80313, |
["Typhoon"] = 132469, |
["Mighty Bash"] = 5211, |
["Wild Charge"] = 102401, |
["Ursol's Vortex"] = 102793, |
["Tiger Dash"] = 252216, |
["Incarnation: Guardian of Ursoc"] = 102558, |
}, |
}, |
["HUNTER"] = { |
["Beast Mastery_Talents"] = { |
["Dire Beast"] = 120679, |
["Chimaera Shot"] = 53209, |
["Camouflage"] = 199483, |
["A Murder of Crows"] = 131894, |
["Binding Shot"] = 109248, |
["Stampede"] = 201430, |
["Barrage"] = 120360, |
["Spitting Cobra"] = 194407, |
}, |
["Marksmanship_Talents"] = { |
["Piercing Shot"] = 198670, |
["Camouflage"] = 199483, |
["Serpent Sting"] = 271788, |
["Explosive Shot"] = 212431, |
["Double Tap"] = 260402, |
["Hunter's Mark"] = 257284, |
["Binding Shot"] = 109248, |
["A Murder of Crows"] = 131894, |
["Barrage"] = 120360, |
}, |
["Marksmanship"] = { |
["Pet Utility"] = 103, |
["Flare"] = 1543, |
["Rapid Fire"] = 257044, |
["Command Pet"] = 272651, |
["Feign Death"] = 5384, |
["Arcane Shot"] = 185358, |
["Feed Pet"] = 6991, |
["Aimed Shot"] = 19434, |
["Tar Trap"] = 187698, |
["Multi-Shot"] = 257620, |
["Aspect of the Turtle"] = 186265, |
["Disengage"] = 781, |
["Trueshot"] = 288613, |
["Beast Lore"] = 1462, |
["Counter Shot"] = 147362, |
["Tame Beast"] = 1515, |
["Bursting Shot"] = 186387, |
["Eagle Eye"] = 6197, |
["Steady Shot"] = 56641, |
["Aspect of the Cheetah"] = 186257, |
["Exhilaration"] = 109304, |
["Call Pet"] = 9, |
["Misdirection"] = 34477, |
["Concussive Shot"] = 5116, |
["Freezing Trap"] = 187650, |
["Dismiss Pet"] = 2641, |
}, |
["Flyouts"] = { |
["Call Pet"] = { |
["Call Pet 3"] = 83243, |
["Call Pet 4"] = 83244, |
["Call Pet 5"] = 83245, |
["Call Pet 2"] = 83242, |
["Call Pet 1"] = 883, |
}, |
["Pet Utility"] = { |
["Beast Lore"] = 1462, |
["Feed Pet"] = 6991, |
["Tame Beast"] = 1515, |
["Dismiss Pet"] = 2641, |
["Revive Pet"] = 982, |
}, |
}, |
["Pets"] = { |
["Ferocity"] = { |
["Bite"] = 17253, |
["Primal Rage"] = 264667, |
["Smack"] = 49966, |
["Dash"] = 61684, |
["Claw"] = 16827, |
["Growl"] = 2649, |
}, |
["Mechanical"] = { |
["Defense Matrix"] = 263868, |
}, |
["Worm"] = { |
["Acid Spit"] = 263446, |
["Burrow Attack"] = 93433, |
}, |
["Stag"] = { |
["Nature's Grace"] = 264266, |
}, |
["Wasp"] = { |
["Toxic Sting"] = 263858, |
}, |
["Quilen"] = { |
["Stone Armor"] = 160049, |
["Eternal Guardian"] = 267922, |
}, |
["Basilisk"] = { |
["Petrifying Gaze"] = 263841, |
}, |
["Silithid"] = { |
["Tendon Rip"] = 160065, |
["Dune Strider"] = 280151, |
}, |
["Lizard"] = { |
["Grievous Bite"] = 279362, |
}, |
["Water Strider"] = { |
["Soothing Water"] = 264262, |
["Surface Trot"] = 126311, |
}, |
["Ravager"] = { |
["Ravage"] = 263857, |
}, |
["Scorpid"] = { |
["Deadly Sting"] = 160060, |
}, |
["Scalehide"] = { |
["Scale Shield"] = 263865, |
}, |
["Oxen"] = { |
["Niuzao's Fortitude"] = 264023, |
}, |
["Hydra"] = { |
["Acid Bite"] = 263863, |
}, |
["Bear"] = { |
["Rest"] = 94019, |
}, |
["Beetle"] = { |
["Harden Carapace"] = 90339, |
}, |
["Chimaera"] = { |
["Froststorm Breath"] = 92380, |
["Frost Breath"] = 54644, |
}, |
["Clefthoof"] = { |
["Thick Hide"] = 160057, |
["Blood of the Rhino"] = 280069, |
}, |
["Cunning"] = { |
["Bite"] = 17253, |
["Smack"] = 49966, |
["Dash"] = 61684, |
["Claw"] = 16827, |
["Master's Call"] = 53271, |
["Growl"] = 2649, |
}, |
["Dog"] = { |
["Lock Jaw"] = 263423, |
}, |
["Bird of Prey"] = { |
["Talon Rend"] = 263852, |
["Trick"] = 94022, |
}, |
["Pterrordax"] = { |
["Updraft"] = 160007, |
["Ancient Hide"] = 279399, |
}, |
["Crocolisk"] = { |
["Ankle Crack"] = 50433, |
}, |
["Hyena"] = { |
["Infected Bite"] = 263853, |
}, |
["Dragonhawk"] = { |
["Dragon's Guile"] = 263887, |
}, |
["Devilsaur"] = { |
["Feast"] = 159953, |
["Monstrous Bite"] = 54680, |
}, |
["Feathermane"] = { |
["Feather Flurry"] = 263916, |
["Updraft"] = 160007, |
}, |
["Fox"] = { |
["Play"] = 90347, |
["Agile Reflexes"] = 160011, |
}, |
["Monkey"] = { |
["Primal Agility"] = 160044, |
}, |
["Gorilla"] = { |
["Silverback"] = 263939, |
}, |
["Warp Stalker"] = { |
["Warp Time"] = 35346, |
}, |
["Sporebat"] = { |
["Spore Cloud"] = 264056, |
}, |
["Moth"] = { |
["Serenity Dust"] = 264055, |
}, |
["Serpent"] = { |
["Serpent's Swiftness"] = 263904, |
}, |
["Cat"] = { |
["Catlike Reflexes"] = 263892, |
["Prowl"] = 24450, |
}, |
["Bat"] = { |
["Sonic Blast"] = 264263, |
}, |
["Carrion Bird"] = { |
["Bloody Screech"] = 24423, |
}, |
["Wolf"] = { |
["Furious Bite"] = 263840, |
}, |
["Toad"] = { |
["Swarm of Flies"] = 279336, |
}, |
["Krolusk"] = { |
["Bulwark"] = 279410, |
}, |
["Shale Spider"] = { |
["Solid Shell"] = 160063, |
}, |
["Riverbeast"] = { |
["Gruesome Bite"] = 160018, |
}, |
["Tallstrider"] = { |
["Dust Cloud"] = 50285, |
}, |
["Spider"] = { |
["Web Spray"] = 160067, |
}, |
["Crab"] = { |
["Pin"] = 50245, |
}, |
["Nether Ray"] = { |
["Nether Shock"] = 264264, |
}, |
["Core Hound"] = { |
["Obsidian Skin"] = 263867, |
["Molten Hide"] = 159788, |
}, |
["Crane"] = { |
["Chi-Ji's Tranquility"] = 264028, |
["Trick"] = 126259, |
}, |
["Boar"] = { |
["Bristle"] = 263869, |
}, |
["Rodent"] = { |
["Gnaw"] = 263856, |
["Rest"] = 126364, |
}, |
["Wind Serpent"] = { |
["Winged Agility"] = 264360, |
}, |
["Turtle"] = { |
["Shell Shield"] = 26064, |
}, |
["Direhorn"] = { |
["Gore"] = 263861, |
}, |
["Raptor"] = { |
["Savage Rend"] = 263854, |
}, |
["Spirit Beast"] = { |
["Spirit Walk"] = 90328, |
["Spirit Shock"] = 264265, |
["Spirit Mend"] = 90361, |
}, |
["Tenacity"] = { |
["Bite"] = 17253, |
["Smack"] = 49966, |
["Dash"] = 61684, |
["Claw"] = 16827, |
["Survival of the Fittest"] = 264735, |
["Growl"] = 2649, |
}, |
["Blood Beast"] = { |
["Blood Bolt"] = 288962, |
}, |
}, |
["Survival"] = { |
["Harpoon"] = 190925, |
["Flare"] = 1543, |
["Command Pet"] = 272651, |
["Kill Command"] = 259489, |
["Feign Death"] = 5384, |
["Misdirection"] = 34477, |
["Muzzle"] = 187707, |
["Feed Pet"] = 6991, |
["Call Pet"] = 9, |
["Tar Trap"] = 187698, |
["Freezing Trap"] = 187650, |
["Dismiss Pet"] = 2641, |
["Disengage"] = 781, |
["Raptor Strike"] = 186270, |
["Coordinated Assault"] = 266779, |
["Aspect of the Eagle"] = 186289, |
["Beast Lore"] = 1462, |
["Tame Beast"] = 1515, |
["Aspect of the Cheetah"] = 186257, |
["Intimidation"] = 19577, |
["Carve"] = 187708, |
["Eagle Eye"] = 6197, |
["Exhilaration"] = 109304, |
["Pet Utility"] = 103, |
["Aspect of the Turtle"] = 186265, |
["Wildfire Bomb"] = 259495, |
["Wing Clip"] = 195645, |
["Serpent Sting"] = 259491, |
}, |
["Marksmanship_PVPTalents"] = { |
["Spider Sting"] = 202914, |
["Dire Beast: Basilisk"] = 205691, |
["Hi-Explosive Trap"] = 236776, |
["Viper Sting"] = 202797, |
["Scorpid Sting"] = 202900, |
["Gladiator's Medallion"] = 208683, |
["Dire Beast: Hawk"] = 208652, |
["Interlope"] = 248518, |
["Roar of Sacrifice"] = 53480, |
}, |
["Survival_PVPTalents"] = { |
["Spider Sting"] = 202914, |
["Dire Beast: Basilisk"] = 205691, |
["Hi-Explosive Trap"] = 236776, |
["Viper Sting"] = 202797, |
["Scorpid Sting"] = 202900, |
["Gladiator's Medallion"] = 208683, |
["Dire Beast: Hawk"] = 208652, |
["Interlope"] = 248518, |
["Roar of Sacrifice"] = 53480, |
}, |
["Survival_Talents"] = { |
["Flanking Strike"] = 269751, |
["Chakrams"] = 259391, |
["Camouflage"] = 199483, |
["A Murder of Crows"] = 131894, |
["Butchery"] = 212436, |
["Steel Trap"] = 162488, |
["Mongoose Bite"] = 259387, |
["Binding Shot"] = 109248, |
}, |
["Beast Mastery_PVPTalents"] = { |
["Spider Sting"] = 202914, |
["Dire Beast: Basilisk"] = 205691, |
["Hi-Explosive Trap"] = 236776, |
["Viper Sting"] = 202797, |
["Scorpid Sting"] = 202900, |
["Gladiator's Medallion"] = 208683, |
["Dire Beast: Hawk"] = 208652, |
["Interlope"] = 248518, |
["Roar of Sacrifice"] = 53480, |
}, |
["Beast Mastery"] = { |
["Pet Utility"] = 103, |
["Cobra Shot"] = 193455, |
["Command Pet"] = 272651, |
["Kill Command"] = 34026, |
["Feign Death"] = 5384, |
["Misdirection"] = 34477, |
["Master's Call"] = 272651, |
["Feed Pet"] = 6991, |
["Survival of the Fittest"] = 272651, |
["Call Pet"] = 9, |
["Dismiss Pet"] = 2641, |
["Tar Trap"] = 187698, |
["Multi-Shot"] = 2643, |
["Aspect of the Turtle"] = 186265, |
["Disengage"] = 781, |
["Primal Rage"] = 272651, |
["Flare"] = 1543, |
["Aspect of the Wild"] = 193530, |
["Counter Shot"] = 147362, |
["Tame Beast"] = 1515, |
["Eagle Eye"] = 6197, |
["Intimidation"] = 19577, |
["Beast Lore"] = 1462, |
["Aspect of the Cheetah"] = 186257, |
["Exhilaration"] = 109304, |
["Mend Pet"] = 136, |
["Barbed Shot"] = 217200, |
["Concussive Shot"] = 5116, |
["Freezing Trap"] = 187650, |
["Bestial Wrath"] = 19574, |
}, |
["METADATA"] = { |
["Specs"] = { |
["Marksmanship"] = 254, |
["Beast Mastery"] = 253, |
["Survival"] = 255, |
}, |
}, |
}, |
["MAGE"] = { |
["Fire_PVPTalents"] = { |
["Ice Form"] = 198144, |
["Gladiator's Medallion"] = 208683, |
["Mass Invisibility"] = 198158, |
["Temporal Shield"] = 198111, |
}, |
["Frost_Talents"] = { |
["Ice Nova"] = 157997, |
["Ebonbolt"] = 257537, |
["Glacial Spike"] = 199786, |
["Mirror Image"] = 55342, |
["Rune of Power"] = 116011, |
["Ring of Frost"] = 113724, |
["Ice Floes"] = 108839, |
["Shimmer"] = 212653, |
["Comet Storm"] = 153595, |
["Ray of Frost"] = 205021, |
}, |
["Arcane_Talents"] = { |
["Mirror Image"] = 55342, |
["Rune of Power"] = 116011, |
["Nether Tempest"] = 114923, |
["Charged Up"] = 205032, |
["Ring of Frost"] = 113724, |
["Arcane Orb"] = 153626, |
["Shimmer"] = 212653, |
["Arcane Familiar"] = 205022, |
["Supernova"] = 157980, |
}, |
["Flyouts"] = { |
["Polymorph Variants"] = { |
["Polymorph(Peacock)"] = 161372, |
["Polymorph(Rabbit)"] = 61721, |
["Polymorph(Monkey)"] = 161354, |
["Polymorph(Direhorn)"] = 277787, |
["Polymorph(Porcupine)"] = 126819, |
["Polymorph(Black Cat)"] = 61305, |
["Polymorph(Turtle)"] = 28271, |
["Polymorph(Turkey)"] = 61780, |
["Polymorph(Penguin)"] = 161355, |
["Polymorph(Pig)"] = 28272, |
["Polymorph(Serpent)"] = 61025, |
["Polymorph(Bumblebee)"] = 277792, |
["Polymorph(Polar Bear Cub)"] = 161353, |
}, |
["Portal"] = { |
["Portal: Exodar"] = 32266, |
["Portal: Stonard"] = 49361, |
["Portal: Undercity"] = 11418, |
["Portal: Vale of Eternal Blossoms(Horde)"] = 132626, |
["Portal: Vale of Eternal Blossoms(Alliance)"] = 132620, |
["Ancient Portal: Dalaran"] = 120146, |
["Portal: Stormwind"] = 10059, |
["Portal: Warspear"] = 176244, |
["Portal: Theramore"] = 49360, |
["Portal: Thunder Bluff"] = 11420, |
["Portal: Darnassus"] = 11419, |
["Portal: Silvermoon"] = 32267, |
["Portal: Tol Barad(Alliance)"] = 88345, |
["Portal: Orgrimmar"] = 11417, |
["Portal: Shattrath(Horde)"] = 35717, |
["Portal: Dazar'alor"] = 281402, |
["Portal: Tol Barad(Horde)"] = 88346, |
["Portal: Stormshield"] = 176246, |
["Portal: Shattrath(Alliance)"] = 33691, |
["Portal: Dalaran - Broken Isles"] = 224871, |
["Portal: Boralus"] = 281400, |
["Portal: Dalaran - Northrend"] = 53142, |
["Portal: Ironforge"] = 11416, |
}, |
["Teleport"] = { |
["Teleport: Dalaran - Northrend"] = 53140, |
["Teleport: Vale of Eternal Blossoms(Horde)"] = 132627, |
["Teleport: Stonard"] = 49358, |
["Teleport: Stormshield"] = 176248, |
["Teleport: Darnassus"] = 3565, |
["Teleport: Vale of Eternal Blossoms(Alliance)"] = 132621, |
["Teleport: Dalaran - Broken Isles"] = 224869, |
["Teleport: Boralus"] = 281403, |
["Teleport: Stormwind"] = 3561, |
["Teleport: Hall of the Guardian"] = 193759, |
["Teleport: Shattrath(Horde)"] = 35715, |
["Teleport: Dazar'alor"] = 281404, |
["Teleport: Tol Barad(Horde)"] = 88344, |
["Teleport: Shattrath(Alliance)"] = 33690, |
["Teleport: Tol Barad(Alliance)"] = 88342, |
["Teleport: Orgrimmar"] = 3567, |
["Teleport: Ironforge"] = 3562, |
["Teleport: Warspear"] = 176242, |
["Teleport: Theramore"] = 49359, |
["Teleport: Silvermoon"] = 32272, |
["Teleport: Undercity"] = 3563, |
["Ancient Teleport: Dalaran"] = 120145, |
["Teleport: Exodar"] = 32271, |
["Teleport: Thunder Bluff"] = 3566, |
}, |
}, |
["Pets"] = { |
["Water Elemental"] = { |
["Freeze"] = 33395, |
["Waterbolt"] = 31707, |
}, |
}, |
["Frost"] = { |
["Arcane Intellect"] = 1459, |
["Blizzard"] = 190356, |
["Frostbolt"] = 116, |
["Frozen Orb"] = 84714, |
["Polymorph"] = 118, |
["Cold Snap"] = 235219, |
["Remove Curse"] = 475, |
["Ice Lance"] = 108853, |
["Polymorph(Sheep)"] = 118, |
["Counterspell"] = 2139, |
["Ice Barrier"] = 11426, |
["Time Warp"] = 80353, |
["Portal"] = 12, |
["Teleport"] = 8, |
["Icy Veins"] = 12472, |
["Summon Water Elemental"] = 31687, |
["Polymorph Variants"] = 92, |
["Conjure Refreshment"] = 190336, |
["Flurry"] = 44614, |
["Blink"] = 1953, |
["Slow Fall"] = 130, |
["Ice Block"] = 45438, |
["Frost Nova"] = 122, |
["Spellsteal"] = 30449, |
["Cone of Cold"] = 120, |
["Invisibility"] = 66, |
}, |
["Frost_PVPTalents"] = { |
["Ice Form"] = 198144, |
["Gladiator's Medallion"] = 208683, |
["Mass Invisibility"] = 198158, |
["Temporal Shield"] = 198111, |
}, |
["Arcane"] = { |
["Arcane Blast"] = 30451, |
["Arcane Intellect"] = 1459, |
["Arcane Explosion"] = 1449, |
["Prismatic Barrier"] = 235450, |
["Polymorph"] = 118, |
["Presence of Mind"] = 205025, |
["Remove Curse"] = 475, |
["Slow"] = 31589, |
["Arcane Power"] = 12042, |
["Polymorph(Sheep)"] = 118, |
["Conjure Refreshment"] = 190336, |
["Time Warp"] = 80353, |
["Portal"] = 12, |
["Teleport"] = 8, |
["Evocation"] = 12051, |
["Arcane Missiles"] = 5143, |
["Polymorph Variants"] = 92, |
["Counterspell"] = 2139, |
["Ice Block"] = 45438, |
["Blink"] = 1953, |
["Slow Fall"] = 130, |
["Greater Invisibility"] = 110959, |
["Frost Nova"] = 122, |
["Arcane Barrage"] = 44425, |
["Spellsteal"] = 30449, |
["Displacement"] = 195676, |
}, |
["Arcane_PVPTalents"] = { |
["Ice Form"] = 198144, |
["Gladiator's Medallion"] = 208683, |
["Mass Invisibility"] = 198158, |
["Temporal Shield"] = 198111, |
}, |
["Fire"] = { |
["Fireball"] = 133, |
["Arcane Intellect"] = 1459, |
["Fire Blast"] = 108853, |
["Polymorph"] = 118, |
["Pyroblast"] = 11366, |
["Remove Curse"] = 475, |
["Scorch"] = 2948, |
["Flamestrike"] = 2120, |
["Conjure Refreshment"] = 190336, |
["Time Warp"] = 80353, |
["Portal"] = 12, |
["Teleport"] = 8, |
["Polymorph(Sheep)"] = 118, |
["Combustion"] = 190319, |
["Polymorph Variants"] = 92, |
["Frost Nova"] = 122, |
["Ice Block"] = 45438, |
["Blink"] = 1953, |
["Slow Fall"] = 130, |
["Dragon's Breath"] = 31661, |
["Counterspell"] = 2139, |
["Blazing Barrier"] = 235313, |
["Spellsteal"] = 30449, |
["Invisibility"] = 66, |
}, |
["Fire_Talents"] = { |
["Phoenix Flames"] = 257541, |
["Blast Wave"] = 157981, |
["Meteor"] = 153561, |
["Ring of Frost"] = 113724, |
["Mirror Image"] = 55342, |
["Rune of Power"] = 116011, |
["Shimmer"] = 212653, |
["Living Bomb"] = 44457, |
}, |
["METADATA"] = { |
["Specs"] = { |
["Fire"] = 63, |
["Frost"] = 64, |
["Arcane"] = 62, |
}, |
}, |
}, |
["MONK"] = { |
["Windwalker_Talents"] = { |
["Chi Burst"] = 123986, |
["Rushing Jade Wind"] = 116847, |
["Fist of the White Tiger"] = 261947, |
["Energizing Elixir"] = 115288, |
["Ring of Peace"] = 116844, |
["Chi Torpedo"] = 115008, |
["Chi Wave"] = 115098, |
["Diffuse Magic"] = 122783, |
["Dampen Harm"] = 122278, |
["Tiger's Lust"] = 116841, |
["Invoke Xuen, the White Tiger"] = 123904, |
["Whirling Dragon Punch"] = 152175, |
["Serenity"] = 152173, |
}, |
["Mistweaver_Talents"] = { |
["Chi Burst"] = 123986, |
["Diffuse Magic"] = 122783, |
["Invoke Chi-Ji, the Red Crane"] = 198664, |
["Song of Chi-Ji"] = 198898, |
["Ring of Peace"] = 116844, |
["Chi Torpedo"] = 115008, |
["Refreshing Jade Wind"] = 196725, |
["Mana Tea"] = 197908, |
["Summon Jade Serpent Statue"] = 115313, |
["Tiger's Lust"] = 116841, |
["Healing Elixir"] = 122281, |
["Dampen Harm"] = 122278, |
["Chi Wave"] = 115098, |
}, |
["Mistweaver"] = { |
["Life Cocoon"] = 116849, |
["Thunder Focus Tea"] = 116680, |
["Resuscitate"] = 115178, |
["Vivify"] = 116670, |
["Renewing Mist"] = 115151, |
["Leg Sweep"] = 119381, |
["Detox"] = 115450, |
["Roll"] = 109132, |
["Soothing Mist"] = 115175, |
["Transcendence"] = 101643, |
["Revival"] = 115310, |
["Zen Pilgrimage"] = 126892, |
["Spinning Crane Kick"] = 101546, |
["Rising Sun Kick"] = 107428, |
["Crackling Jade Lightning"] = 117952, |
["Provoke"] = 115546, |
["Paralysis"] = 115078, |
["Tiger Palm"] = 100780, |
["Blackout Kick"] = 100784, |
["Enveloping Mist"] = 124682, |
["Transcendence: Transfer"] = 119996, |
["Reawaken"] = 212051, |
["Fortifying Brew"] = 243435, |
["Essence Font"] = 191837, |
}, |
["Brewmaster"] = { |
["Resuscitate"] = 115178, |
["Blackout Strike"] = 205523, |
["Breath of Fire"] = 115181, |
["Vivify"] = 116670, |
["Expel Harm"] = 115072, |
["Detox"] = 218164, |
["Roll"] = 109132, |
["Spear Hand Strike"] = 116705, |
["Zen Meditation"] = 115176, |
["Transcendence"] = 101643, |
["Tiger Palm"] = 100780, |
["Fortifying Brew"] = 115203, |
["Zen Pilgrimage"] = 126892, |
["Paralysis"] = 115078, |
["Crackling Jade Lightning"] = 117952, |
["Purifying Brew"] = 119582, |
["Provoke"] = 115546, |
["Transcendence: Transfer"] = 119996, |
["Keg Smash"] = 121253, |
["Leg Sweep"] = 119381, |
["Ironskin Brew"] = 115308, |
}, |
["Windwalker"] = { |
["Fists of Fury"] = 113656, |
["Resuscitate"] = 115178, |
["Vivify"] = 116670, |
["Touch of Death"] = 115080, |
["Leg Sweep"] = 119381, |
["Detox"] = 218164, |
["Roll"] = 109132, |
["Touch of Karma"] = 122470, |
["Spear Hand Strike"] = 116705, |
["Storm, Earth, and Fire"] = 137639, |
["Zen Pilgrimage"] = 126892, |
["Transcendence"] = 101643, |
["Flying Serpent Kick"] = 101545, |
["Tiger Palm"] = 100780, |
["Crackling Jade Lightning"] = 117952, |
["Transcendence: Transfer"] = 119996, |
["Blackout Kick"] = 100784, |
["Provoke"] = 115546, |
["Paralysis"] = 115078, |
["Rising Sun Kick"] = 107428, |
["Spinning Crane Kick"] = 101546, |
["Disable"] = 116095, |
}, |
["Mistweaver_PVPTalents"] = { |
["Gladiator's Medallion"] = 208683, |
["Fortifying Brew"] = 201318, |
["Tigereye Brew"] = 247483, |
["Reverse Harm"] = 287771, |
["Grapple Weapon"] = 233759, |
}, |
["Windwalker_PVPTalents"] = { |
["Gladiator's Medallion"] = 208683, |
["Fortifying Brew"] = 201318, |
["Tigereye Brew"] = 247483, |
["Reverse Harm"] = 287771, |
["Grapple Weapon"] = 233759, |
}, |
["Brewmaster_Talents"] = { |
["Chi Burst"] = 123986, |
["Summon Black Ox Statue"] = 115315, |
["Black Ox Brew"] = 115399, |
["Ring of Peace"] = 116844, |
["Chi Torpedo"] = 115008, |
["Chi Wave"] = 115098, |
["Dampen Harm"] = 122278, |
["Invoke Niuzao, the Black Ox"] = 132578, |
["Tiger's Lust"] = 116841, |
["Healing Elixir"] = 122281, |
["Guard"] = 115295, |
["Rushing Jade Wind"] = 116847, |
}, |
["Brewmaster_PVPTalents"] = { |
["Gladiator's Medallion"] = 208683, |
["Fortifying Brew"] = 201318, |
["Tigereye Brew"] = 247483, |
["Reverse Harm"] = 287771, |
["Grapple Weapon"] = 233759, |
}, |
["METADATA"] = { |
["Specs"] = { |
["Mistweaver"] = 270, |
["Brewmaster"] = 268, |
["Windwalker"] = 269, |
}, |
}, |
}, |
["PALADIN"] = { |
["Protection"] = { |
["Divine Shield"] = 642, |
["Guardian of Ancient Kings"] = 86659, |
["Judgment"] = 275779, |
["Light of the Protector"] = 184092, |
["Hand of Reckoning"] = 62124, |
["Hammer of Justice"] = 853, |
["Consecration"] = 26573, |
["Avenging Wrath"] = 31884, |
["Blessing of Sacrifice"] = 6940, |
["Rebuke"] = 96231, |
["Blessing of Freedom"] = 1044, |
["Blessing of Protection"] = 1022, |
["Lay on Hands"] = 633, |
["Shield of the Righteous"] = 53600, |
["Redemption"] = 7328, |
["Cleanse Toxins"] = 213644, |
["Hammer of the Righteous"] = 53595, |
["Flash of Light"] = 19750, |
["Avenger's Shield"] = 31935, |
["Ardent Defender"] = 31850, |
["Divine Steed"] = 190784, |
}, |
["Holy"] = { |
["Divine Shield"] = 642, |
["Holy Light"] = 82326, |
["Cleanse"] = 4987, |
["Judgment"] = 275773, |
["Redemption"] = 7328, |
["Holy Shock"] = 20473, |
["Hand of Reckoning"] = 62124, |
["Hammer of Justice"] = 853, |
["Consecration"] = 26573, |
["Beacon of Light"] = 53563, |
["Divine Protection"] = 498, |
["Blessing of Protection"] = 1022, |
["Avenging Wrath"] = 31884, |
["Light of the Martyr"] = 183998, |
["Absolution"] = 212056, |
["Blessing of Freedom"] = 1044, |
["Light of Dawn"] = 85222, |
["Blessing of Sacrifice"] = 6940, |
["Aura Mastery"] = 31821, |
["Flash of Light"] = 19750, |
["Crusader Strike"] = 35395, |
["Lay on Hands"] = 633, |
["Divine Steed"] = 190784, |
}, |
["Protection_PVPTalents"] = { |
["Cleansing Light"] = 236186, |
["Hammer of Reckoning"] = 247675, |
["Blessing of Sanctuary"] = 210256, |
["Gladiator's Medallion"] = 208683, |
}, |
["Holy_Talents"] = { |
["Holy Avenger"] = 105809, |
["Blinding Light"] = 115750, |
["Beacon of Faith"] = 156910, |
["Bestow Faith"] = 223306, |
["Light's Hammer"] = 114158, |
["Rule of Law"] = 214202, |
["Beacon of Virtue"] = 200025, |
["Avenging Crusader"] = 216331, |
["Holy Prism"] = 114165, |
["Repentance"] = 20066, |
}, |
["Holy_PVPTalents"] = { |
["Cleansing Light"] = 236186, |
["Hammer of Reckoning"] = 247675, |
["Blessing of Sanctuary"] = 210256, |
["Gladiator's Medallion"] = 208683, |
}, |
["Retribution_Talents"] = { |
["Word of Glory"] = 210191, |
["Blinding Light"] = 115750, |
["Hammer of Wrath"] = 24275, |
["Justicar's Vengeance"] = 215661, |
["Wake of Ashes"] = 255937, |
["Inquisition"] = 84963, |
["Crusade"] = 231895, |
["Consecration"] = 205228, |
["Eye for an Eye"] = 205191, |
["Execution Sentence"] = 267798, |
["Repentance"] = 20066, |
}, |
["Retribution_PVPTalents"] = { |
["Cleansing Light"] = 236186, |
["Hammer of Reckoning"] = 247675, |
["Blessing of Sanctuary"] = 210256, |
["Gladiator's Medallion"] = 208683, |
}, |
["Protection_Talents"] = { |
["Bastion of Light"] = 204035, |
["Blessing of Spellwarding"] = 204018, |
["Blinding Light"] = 115750, |
["Blessed Hammer"] = 204019, |
["Seraphim"] = 152262, |
["Hand of the Protector"] = 213652, |
["Aegis of Light"] = 204150, |
["Repentance"] = 20066, |
}, |
["Retribution"] = { |
["Divine Shield"] = 642, |
["Avenging Wrath"] = 31884, |
["Divine Storm"] = 53385, |
["Shield of Vengeance"] = 184662, |
["Judgment"] = 20271, |
["Redemption"] = 7328, |
["Hand of Reckoning"] = 62124, |
["Hammer of Justice"] = 853, |
["Rebuke"] = 96231, |
["Greater Blessing of Kings"] = 203538, |
["Hand of Hindrance"] = 183218, |
["Blade of Justice"] = 184575, |
["Lay on Hands"] = 633, |
["Blessing of Freedom"] = 1044, |
["Blessing of Protection"] = 1022, |
["Templar's Verdict"] = 85256, |
["Cleanse Toxins"] = 213644, |
["Flash of Light"] = 19750, |
["Crusader Strike"] = 35395, |
["Greater Blessing of Wisdom"] = 203539, |
["Divine Steed"] = 190784, |
}, |
["METADATA"] = { |
["Specs"] = { |
["Protection"] = 66, |
["Holy"] = 65, |
["Retribution"] = 70, |
}, |
}, |
}, |
["PRIEST"] = { |
["Shadow"] = { |
["Purify Disease"] = 213634, |
["Resurrection"] = 2006, |
["Shackle Undead"] = 9484, |
["Shadow Word: Pain"] = 589, |
["Fade"] = 586, |
["Mind Vision"] = 2096, |
["Shadowform"] = 232698, |
["Silence"] = 15487, |
["Dispersion"] = 47585, |
["Mind Sear"] = 48045, |
["Mind Blast"] = 8092, |
["Vampiric Embrace"] = 15286, |
["Void Eruption"] = 228260, |
["Mind Flay"] = 15407, |
["Shadow Mend"] = 186263, |
["Mind Control"] = 605, |
["Power Word: Fortitude"] = 21562, |
["Psychic Scream"] = 8122, |
["Leap of Faith"] = 73325, |
["Power Word: Shield"] = 17, |
["Levitate"] = 1706, |
["Dispel Magic"] = 528, |
["Vampiric Touch"] = 34914, |
["Shadowfiend"] = 34433, |
["Mass Dispel"] = 32375, |
}, |
["Shadow_PVPTalents"] = { |
["Dark Archangel"] = 197871, |
["Archangel"] = 197862, |
["Premonition"] = 209780, |
["Gladiator's Medallion"] = 208683, |
}, |
["Holy_Talents"] = { |
["Circle of Healing"] = 204883, |
["Divine Star"] = 110744, |
["Shining Force"] = 204263, |
["Binding Heal"] = 32546, |
["Halo"] = 120517, |
["Holy Word: Salvation"] = 265202, |
["Apotheosis"] = 200183, |
["Angelic Feather"] = 121536, |
}, |
["Holy_PVPTalents"] = { |
["Dark Archangel"] = 197871, |
["Archangel"] = 197862, |
["Premonition"] = 209780, |
["Gladiator's Medallion"] = 208683, |
}, |
["METADATA"] = { |
["Specs"] = { |
["Discipline"] = 256, |
["Holy"] = 257, |
["Shadow"] = 258, |
}, |
}, |
["Discipline"] = { |
["Power Word: Radiance"] = 194509, |
["Resurrection"] = 2006, |
["Shackle Undead"] = 9484, |
["Rapture"] = 47536, |
["Holy Nova"] = 132157, |
["Fade"] = 586, |
["Mind Vision"] = 2096, |
["Mass Dispel"] = 32375, |
["Shadow Word: Pain"] = 589, |
["Shadowfiend"] = 34433, |
["Desperate Prayer"] = 19236, |
["Power Word: Shield"] = 17, |
["Levitate"] = 1706, |
["Flash Heal"] = 2061, |
["Power Word: Fortitude"] = 21562, |
["Shadow Mend"] = 2061, |
["Mind Control"] = 605, |
["Penance"] = 47540, |
["Psychic Scream"] = 8122, |
["Leap of Faith"] = 73325, |
["Mass Resurrection"] = 212036, |
["Smite"] = 585, |
["Dispel Magic"] = 528, |
["Purify"] = 527, |
["Pain Suppression"] = 33206, |
["Power Word: Barrier"] = 62618, |
}, |
["Discipline_PVPTalents"] = { |
["Dark Archangel"] = 197871, |
["Archangel"] = 197862, |
["Premonition"] = 209780, |
["Gladiator's Medallion"] = 208683, |
}, |
["Holy"] = { |
["Renew"] = 139, |
["Resurrection"] = 2006, |
["Shackle Undead"] = 9484, |
["Holy Nova"] = 132157, |
["Symbol of Hope"] = 64901, |
["Fade"] = 586, |
["Mind Vision"] = 2096, |
["Mass Dispel"] = 32375, |
["Purify"] = 527, |
["Holy Word: Serenity"] = 2050, |
["Prayer of Healing"] = 596, |
["Smite"] = 585, |
["Desperate Prayer"] = 19236, |
["Holy Fire"] = 14914, |
["Levitate"] = 1706, |
["Flash Heal"] = 2061, |
["Power Word: Fortitude"] = 21562, |
["Holy Word: Chastise"] = 88625, |
["Mass Resurrection"] = 212036, |
["Holy Word: Sanctify"] = 34861, |
["Psychic Scream"] = 8122, |
["Leap of Faith"] = 73325, |
["Divine Hymn"] = 64843, |
["Guardian Spirit"] = 47788, |
["Dispel Magic"] = 528, |
["Mind Control"] = 605, |
["Heal"] = 2060, |
["Prayer of Mending"] = 33076, |
}, |
["Discipline_Talents"] = { |
["Evangelism"] = 246287, |
["Schism"] = 214621, |
["Mindbender"] = 123040, |
["Halo"] = 120517, |
["Shadow Covenant"] = 204065, |
["Angelic Feather"] = 121536, |
["Power Word: Solace"] = 129250, |
["Divine Star"] = 110744, |
["Shining Force"] = 204263, |
["Luminous Barrier"] = 271466, |
["Purge the Wicked"] = 204197, |
}, |
["Shadow_Talents"] = { |
["Mindbender"] = 200174, |
["Dark Void"] = 263346, |
["Void Torrent"] = 263165, |
["Shadow Word: Death"] = 32379, |
["Shadow Crash"] = 205385, |
["Shadow Word: Void"] = 205351, |
["Psychic Horror"] = 64044, |
["Mind Bomb"] = 205369, |
["Surrender to Madness"] = 193223, |
["Dark Ascension"] = 280711, |
}, |
}, |
["ROGUE"] = { |
["Subtlety_PVPTalents"] = { |
["Death from Above"] = 269513, |
["Neurotoxin"] = 206328, |
["Gladiator's Medallion"] = 208683, |
["Shiv"] = 248744, |
["Smoke Bomb"] = 212182, |
["Plunder Armor"] = 198529, |
["Dismantle"] = 207777, |
}, |
["Assassination_PVPTalents"] = { |
["Death from Above"] = 269513, |
["Neurotoxin"] = 206328, |
["Gladiator's Medallion"] = 208683, |
["Shiv"] = 248744, |
["Smoke Bomb"] = 212182, |
["Plunder Armor"] = 198529, |
["Dismantle"] = 207777, |
}, |
["Assassination"] = { |
["Sprint"] = 2983, |
["Evasion"] = 5277, |
["Garrote"] = 703, |
["Cloak of Shadows"] = 31224, |
["Vanish"] = 1856, |
["Envenom"] = 32645, |
["Tricks of the Trade"] = 57934, |
["Crimson Vial"] = 185311, |
["Shadowstep"] = 36554, |
["Rupture"] = 1943, |
["Wound Poison"] = 8679, |
["Feint"] = 1966, |
["Stealth"] = 1784, |
["Crippling Poison"] = 3408, |
["Vendetta"] = 79140, |
["Mutilate"] = 1329, |
["Pick Pocket"] = 921, |
["Blind"] = 2094, |
["Poisoned Knife"] = 185565, |
["Pick Lock"] = 1804, |
["Sinister Strike"] = 1752, |
["Shroud of Concealment"] = 114018, |
["Distract"] = 1725, |
["Fan of Knives"] = 51723, |
["Kidney Shot"] = 408, |
["Sap"] = 6770, |
["Eviscerate"] = 196819, |
["Kick"] = 1766, |
["Poisons"] = 66, |
["Cheap Shot"] = 1833, |
["Deadly Poison"] = 2823, |
}, |
["Assassination_Talents"] = { |
["Crimson Tempest"] = 121411, |
["Blindside"] = 111240, |
["Toxic Blade"] = 245388, |
["Exsanguinate"] = 200806, |
["Marked for Death"] = 137619, |
}, |
["Subtlety"] = { |
["Sprint"] = 2983, |
["Evasion"] = 5277, |
["Backstab"] = 53, |
["Symbols of Death"] = 212283, |
["Eviscerate"] = 196819, |
["Shadowstep"] = 36554, |
["Shadow Blades"] = 121471, |
["Shadowstrike"] = 185438, |
["Cloak of Shadows"] = 31224, |
["Vanish"] = 1856, |
["Tricks of the Trade"] = 57934, |
["Feint"] = 1966, |
["Kidney Shot"] = 408, |
["Pick Pocket"] = 921, |
["Blind"] = 2094, |
["Sap"] = 6770, |
["Pick Lock"] = 1804, |
["Shadow Dance"] = 185313, |
["Shroud of Concealment"] = 114018, |
["Distract"] = 1725, |
["Stealth"] = 1784, |
["Shuriken Storm"] = 197835, |
["Nightblade"] = 195452, |
["Shuriken Toss"] = 114014, |
["Kick"] = 1766, |
["Poisons"] = 66, |
["Cheap Shot"] = 1833, |
["Crimson Vial"] = 185311, |
}, |
["Flyouts"] = { |
["Poisons"] = { |
["Leeching Poison"] = 108211, |
["Crippling Poison"] = 3408, |
["Deadly Poison"] = 2823, |
["Wound Poison"] = 8679, |
["Agonizing Poison"] = 200802, |
}, |
}, |
["Outlaw_PVPTalents"] = { |
["Death from Above"] = 269513, |
["Neurotoxin"] = 206328, |
["Gladiator's Medallion"] = 208683, |
["Shiv"] = 248744, |
["Smoke Bomb"] = 212182, |
["Plunder Armor"] = 198529, |
["Dismantle"] = 207777, |
}, |
["Outlaw_Talents"] = { |
["Slice and Dice"] = 5171, |
["Ghostly Strike"] = 196937, |
["Blade Rush"] = 271877, |
["Marked for Death"] = 137619, |
["Killing Spree"] = 51690, |
}, |
["Outlaw"] = { |
["Sprint"] = 2983, |
["Vanish"] = 1856, |
["Riposte"] = 199754, |
["Pistol Shot"] = 185763, |
["Crimson Vial"] = 185311, |
["Cloak of Shadows"] = 31224, |
["Between the Eyes"] = 199804, |
["Dispatch"] = 2098, |
["Grappling Hook"] = 195457, |
["Stealth"] = 1784, |
["Poisons"] = 66, |
["Feint"] = 1966, |
["Ambush"] = 8676, |
["Blind"] = 2094, |
["Roll the Bones"] = 193316, |
["Pick Lock"] = 1804, |
["Shroud of Concealment"] = 114018, |
["Sinister Strike"] = 193315, |
["Distract"] = 1725, |
["Adrenaline Rush"] = 13750, |
["Gouge"] = 1776, |
["Sap"] = 6770, |
["Pick Pocket"] = 921, |
["Kick"] = 1766, |
["Tricks of the Trade"] = 57934, |
["Cheap Shot"] = 1833, |
["Blade Flurry"] = 13877, |
}, |
["Subtlety_Talents"] = { |
["Secret Technique"] = 280719, |
["Marked for Death"] = 137619, |
["Gloomblade"] = 200758, |
["Shuriken Tornado"] = 277925, |
}, |
["METADATA"] = { |
["Specs"] = { |
["Outlaw"] = 260, |
["Subtlety"] = 261, |
["Assassination"] = 259, |
}, |
}, |
}, |
["SHAMAN"] = { |
["Restoration_PVPTalents"] = { |
["Counterstrike Totem"] = 204331, |
["Thundercharge"] = 204366, |
["Gladiator's Medallion"] = 208683, |
["Skyfury Totem"] = 204330, |
["Ethereal Form"] = 210918, |
["Lightning Lasso"] = 204437, |
["Grounding Totem"] = 204336, |
}, |
["Elemental"] = { |
["Astral Shift"] = 108271, |
["Healing Surge"] = 8004, |
["Ghost Wolf"] = 2645, |
["Flame Shock"] = 188389, |
["Thunderstorm"] = 51490, |
["Earth Elemental"] = 198103, |
["Earthquake"] = 61882, |
["Fire Elemental"] = 198067, |
["Ancestral Spirit"] = 2008, |
["Water Walking"] = 546, |
["Capacitor Totem"] = 192058, |
["Earthbind Totem"] = 2484, |
["Hex"] = 51514, |
["Far Sight"] = 6196, |
["Purge"] = 370, |
["Cleanse Spirit"] = 51886, |
["Hex Variants"] = 106, |
["Frost Shock"] = 196840, |
["Lightning Bolt"] = 188196, |
["Bloodlust"] = 2825, |
["Heroism"] = 32182, |
["Lava Burst"] = 51505, |
["Wind Shear"] = 57994, |
["Astral Recall"] = 556, |
["Hex(Frog)"] = 51514, |
["Tremor Totem"] = 8143, |
["Chain Lightning"] = 188443, |
["Earth Shock"] = 8042, |
}, |
["METADATA"] = { |
["Specs"] = { |
["Enhancement"] = 263, |
["Elemental"] = 262, |
["Restoration"] = 264, |
}, |
}, |
["Flyouts"] = { |
["Hex Variants"] = { |
["Hex(Wicker Mongrel)"] = 277784, |
["Hex(Skeletal Hatchling)"] = 269352, |
["Hex(Zandalari Tendonripper)"] = 277778, |
["Hex(Spider)"] = 211004, |
["Hex(Compy)"] = 210873, |
["Hex(Cockroach)"] = 211015, |
["Hex(Snake)"] = 211010, |
}, |
}, |
["Pets"] = { |
["Storm Elemental"] = { |
["Call Lightning"] = 157348, |
["Eye of the Storm"] = 157375, |
["Wind Gust"] = 157331, |
}, |
["Fire Elemental"] = { |
["Meteor"] = 117588, |
["Immolate"] = 118297, |
["Fire Blast"] = 57984, |
}, |
["Earth Elemental"] = { |
["Angered Earth"] = 36213, |
["Pulverize"] = 118345, |
["Harden Skin"] = 118337, |
}, |
}, |
["Enhancement_PVPTalents"] = { |
["Counterstrike Totem"] = 204331, |
["Thundercharge"] = 204366, |
["Gladiator's Medallion"] = 208683, |
["Skyfury Totem"] = 204330, |
["Ethereal Form"] = 210918, |
["Lightning Lasso"] = 204437, |
["Grounding Totem"] = 204336, |
}, |
["Enhancement"] = { |
["Astral Shift"] = 108271, |
["Healing Surge"] = 188070, |
["Crash Lightning"] = 187874, |
["Lava Lash"] = 60103, |
["Ghost Wolf"] = 2645, |
["Hex(Frog)"] = 51514, |
["Flametongue"] = 193796, |
["Earth Elemental"] = 198103, |
["Ancestral Spirit"] = 2008, |
["Water Walking"] = 546, |
["Capacitor Totem"] = 192058, |
["Earthbind Totem"] = 2484, |
["Hex"] = 51514, |
["Feral Spirit"] = 51533, |
["Heroism"] = 32182, |
["Frostbrand"] = 196834, |
["Hex Variants"] = 106, |
["Far Sight"] = 6196, |
["Cleanse Spirit"] = 51886, |
["Bloodlust"] = 2825, |
["Purge"] = 370, |
["Lightning Bolt"] = 187837, |
["Wind Shear"] = 57994, |
["Astral Recall"] = 556, |
["Stormstrike"] = 17364, |
["Spirit Walk"] = 58875, |
["Tremor Totem"] = 8143, |
["Rockbiter"] = 193786, |
}, |
["Elemental_PVPTalents"] = { |
["Counterstrike Totem"] = 204331, |
["Thundercharge"] = 204366, |
["Gladiator's Medallion"] = 208683, |
["Skyfury Totem"] = 204330, |
["Ethereal Form"] = 210918, |
["Lightning Lasso"] = 204437, |
["Grounding Totem"] = 204336, |
}, |
["Elemental_Talents"] = { |
["Liquid Magma Totem"] = 192222, |
["Totem Mastery"] = 210643, |
["Icefury"] = 210714, |
["Wind Rush Totem"] = 192077, |
["Earth Shield"] = 974, |
["Storm Elemental"] = 192249, |
["Stormkeeper"] = 191634, |
["Ascendance"] = 114050, |
["Ancestral Guidance"] = 108281, |
["Elemental Blast"] = 117014, |
}, |
["Restoration_Talents"] = { |
["Earthen Wall Totem"] = 198838, |
["Wind Rush Totem"] = 192077, |
["Ancestral Protection Totem"] = 207399, |
["Earth Shield"] = 974, |
["Unleash Life"] = 73685, |
["Wellspring"] = 197995, |
["Cloudburst Totem"] = 157153, |
["Ascendance"] = 114052, |
["Downpour"] = 207778, |
["Earthgrab Totem"] = 51485, |
}, |
["Restoration"] = { |
["Astral Shift"] = 108271, |
["Tremor Totem"] = 8143, |
["Ghost Wolf"] = 2645, |
["Healing Wave"] = 77472, |
["Healing Tide Totem"] = 108280, |
["Earth Elemental"] = 198103, |
["Ancestral Vision"] = 212048, |
["Flame Shock"] = 188838, |
["Spiritwalker's Grace"] = 79206, |
["Earthbind Totem"] = 2484, |
["Chain Heal"] = 1064, |
["Capacitor Totem"] = 192058, |
["Purge"] = 370, |
["Water Walking"] = 546, |
["Spirit Link Totem"] = 98008, |
["Far Sight"] = 6196, |
["Hex"] = 51514, |
["Purify Spirit"] = 77130, |
["Heroism"] = 32182, |
["Healing Rain"] = 73920, |
["Hex Variants"] = 106, |
["Lava Burst"] = 51505, |
["Lightning Bolt"] = 403, |
["Bloodlust"] = 2825, |
["Riptide"] = 61295, |
["Hex(Frog)"] = 51514, |
["Wind Shear"] = 57994, |
["Astral Recall"] = 556, |
["Ancestral Spirit"] = 2008, |
["Healing Stream Totem"] = 5394, |
["Chain Lightning"] = 421, |
["Healing Surge"] = 8004, |
}, |
["Enhancement_Talents"] = { |
["Fury of Air"] = 197211, |
["Wind Rush Totem"] = 192077, |
["Earth Shield"] = 974, |
["Lightning Shield"] = 192106, |
["Totem Mastery"] = 262395, |
["Sundering"] = 197214, |
["Ascendance"] = 114051, |
["Feral Lunge"] = 196884, |
["Earthen Spike"] = 188089, |
}, |
}, |
["WARLOCK"] = { |
["Affliction_Talents"] = { |
["Grimoire of Sacrifice"] = 108503, |
["Siphon Life"] = 63106, |
["Mortal Coil"] = 6789, |
["Demonic Circle"] = 268358, |
["Drain Soul"] = 198590, |
["Phantom Singularity"] = 205179, |
["Dark Soul: Misery"] = 113860, |
["Haunt"] = 48181, |
["Vile Taint"] = 278350, |
["Deathbolt"] = 264106, |
["Burning Rush"] = 111400, |
["Dark Pact"] = 108416, |
}, |
["Destruction_Talents"] = { |
["Grimoire of Sacrifice"] = 108503, |
["Dark Pact"] = 108416, |
["Mortal Coil"] = 6789, |
["Demonic Circle"] = 268358, |
["Channel Demonfire"] = 196447, |
["Shadowburn"] = 17877, |
["Cataclysm"] = 152108, |
["Dark Soul: Instability"] = 113858, |
["Burning Rush"] = 111400, |
["Soul Fire"] = 6353, |
}, |
["Affliction"] = { |
["Corruption"] = 172, |
["Shadowfury"] = 30283, |
["Soulstone"] = 20707, |
["Command Demon"] = 119898, |
["Summon Darkglare"] = 205180, |
["Agony"] = 980, |
["Ritual of Summoning"] = 698, |
["Health Funnel"] = 755, |
["Eye of Kilrogg"] = 126, |
["Fear"] = 5782, |
["Demonic Gateway"] = 111771, |
["Create Soulwell"] = 29893, |
["Unending Breath"] = 5697, |
["Drain Life"] = 234153, |
["Unstable Affliction"] = 30108, |
["Shadow Bolt"] = 232670, |
["Summon Succubus"] = 712, |
["Create Healthstone"] = 6201, |
["Unending Resolve"] = 104773, |
["Seed of Corruption"] = 27243, |
["Banish"] = 710, |
["Summon Demon"] = 10, |
["Enslave Demon"] = 1098, |
["Summon Felhunter"] = 691, |
}, |
["Flyouts"] = { |
["Summon Demon"] = { |
["Summon Imp"] = 688, |
["Summon Wrathguard"] = 112870, |
["Summon Voidlord"] = 112867, |
["Summon Felhunter"] = 691, |
["Summon Voidwalker"] = 697, |
["Summon Succubus"] = 712, |
["Summon Shivarra"] = 112868, |
["Summon Observer"] = 112869, |
["Summon Fel Imp"] = 112866, |
["Summon Felguard"] = 30146, |
}, |
}, |
["Pets"] = { |
["Voidlord"] = { |
["Suffering"] = 119907, |
["Consuming Shadows"] = 3716, |
["Shadow Bulwark"] = 17767, |
["Void Shield"] = 115236, |
["Threatening Presence"] = 134477, |
}, |
["Voidwalker"] = { |
["Suffering"] = 17735, |
["Consuming Shadows"] = 3716, |
["Threatening Presence"] = 134477, |
["Shadow Bulwark"] = 17767, |
}, |
["Shivarra"] = { |
["Mesmerize"] = 115268, |
["Lesser Invisibility"] = 7870, |
["Bladedance"] = 115748, |
["Fellash"] = 115770, |
}, |
["Fel Imp"] = { |
["Felbolt"] = 115746, |
["Cauterize Master"] = 119905, |
["Sear Magic"] = 115276, |
["Flee"] = 89792, |
}, |
["Wrathguard"] = { |
["Mortal Cleave"] = 115625, |
["Threatening Presence"] = 134477, |
["Wrathstorm"] = 115831, |
["Axe Toss"] = 89766, |
["Pursuit"] = 30151, |
}, |
["Succubus"] = { |
["Seduction"] = 6358, |
["Lesser Invisibility"] = 7870, |
["Lash of Pain"] = 7814, |
["Whiplash"] = 6360, |
}, |
["Felguard"] = { |
["Threatening Presence"] = 134477, |
["Felstorm"] = 89751, |
["Axe Toss"] = 89766, |
["Pursuit"] = 30151, |
["Legion Strike"] = 30213, |
}, |
["Felhunter"] = { |
["Shadow Bite"] = 54049, |
["Spell Lock"] = 19647, |
["Devour Magic"] = 19505, |
}, |
["Observer"] = { |
["Optical Blast"] = 115781, |
["Devour Magic"] = 19505, |
["Tongue Lash"] = 115778, |
}, |
["Imp"] = { |
["Flee"] = 89792, |
["Singe Magic"] = 89808, |
["Firebolt"] = 3110, |
}, |
}, |
["Destruction_PVPTalents"] = { |
["Call Felhunter"] = 212619, |
["Singe Magic"] = 212623, |
["Curse of Fragility"] = 199954, |
["Curse of Tongues"] = 199890, |
["Curse of Shadows"] = 234877, |
["Call Observer"] = 201996, |
["Nether Ward"] = 212295, |
["Curse of Weakness"] = 199892, |
["Gladiator's Medallion"] = 208683, |
["Soulshatter"] = 212356, |
["Call Fel Lord"] = 212459, |
["Demon Armor"] = 285933, |
["Casting Circle"] = 221703, |
}, |
["Destruction"] = { |
["Shadowfury"] = 30283, |
["Soulstone"] = 20707, |
["Command Demon"] = 119898, |
["Immolate"] = 348, |
["Conflagrate"] = 17962, |
["Ritual of Summoning"] = 698, |
["Health Funnel"] = 755, |
["Eye of Kilrogg"] = 126, |
["Fear"] = 5782, |
["Summon Infernal"] = 1122, |
["Create Soulwell"] = 29893, |
["Demonic Gateway"] = 111771, |
["Unending Breath"] = 5697, |
["Incinerate"] = 29722, |
["Drain Life"] = 234153, |
["Enslave Demon"] = 1098, |
["Unending Resolve"] = 104773, |
["Summon Succubus"] = 712, |
["Create Healthstone"] = 6201, |
["Havoc"] = 80240, |
["Summon Felhunter"] = 691, |
["Chaos Bolt"] = 116858, |
["Summon Demon"] = 10, |
["Banish"] = 710, |
["Rain of Fire"] = 5740, |
}, |
["Demonology_PVPTalents"] = { |
["Call Felhunter"] = 212619, |
["Singe Magic"] = 212623, |
["Curse of Fragility"] = 199954, |
["Curse of Tongues"] = 199890, |
["Curse of Shadows"] = 234877, |
["Call Observer"] = 201996, |
["Nether Ward"] = 212295, |
["Curse of Weakness"] = 199892, |
["Gladiator's Medallion"] = 208683, |
["Soulshatter"] = 212356, |
["Call Fel Lord"] = 212459, |
["Demon Armor"] = 285933, |
["Casting Circle"] = 221703, |
}, |
["Demonology"] = { |
["Call Dreadstalkers"] = 104316, |
["Singe Magic"] = 119898, |
["Soulstone"] = 20707, |
["Command Demon"] = 119898, |
["Create Soulwell"] = 29893, |
["Summon Demonic Tyrant"] = 265187, |
["Ritual of Summoning"] = 698, |
["Health Funnel"] = 755, |
["Eye of Kilrogg"] = 126, |
["Axe Toss"] = 119898, |
["Shadow Bulwark"] = 119898, |
["Demonbolt"] = 264178, |
["Fear"] = 5782, |
["Implosion"] = 196277, |
["Enslave Demon"] = 1098, |
["Demonic Gateway"] = 111771, |
["Shadow Bolt"] = 686, |
["Hand of Gul'dan"] = 105174, |
["Banish"] = 710, |
["Unending Breath"] = 5697, |
["Seduction"] = 119898, |
["Summon Succubus"] = 712, |
["Create Healthstone"] = 6201, |
["Unending Resolve"] = 104773, |
["Drain Life"] = 234153, |
["Summon Felhunter"] = 691, |
["Summon Demon"] = 10, |
["Spell Lock"] = 119898, |
["Shadowfury"] = 30283, |
}, |
["Demonology_Talents"] = { |
["Dark Pact"] = 108416, |
["Demonic Strength"] = 267171, |
["Demonic Circle"] = 268358, |
["Soul Strike"] = 264057, |
["Summon Vilefiend"] = 264119, |
["Grimoire: Felguard"] = 111898, |
["Nether Portal"] = 267217, |
["Doom"] = 265412, |
["Mortal Coil"] = 6789, |
["Power Siphon"] = 264130, |
["Burning Rush"] = 111400, |
["Bilescourge Bombers"] = 267211, |
}, |
["Affliction_PVPTalents"] = { |
["Call Felhunter"] = 212619, |
["Singe Magic"] = 212623, |
["Curse of Fragility"] = 199954, |
["Curse of Tongues"] = 199890, |
["Curse of Shadows"] = 234877, |
["Call Observer"] = 201996, |
["Nether Ward"] = 212295, |
["Curse of Weakness"] = 199892, |
["Gladiator's Medallion"] = 208683, |
["Soulshatter"] = 212356, |
["Call Fel Lord"] = 212459, |
["Demon Armor"] = 285933, |
["Casting Circle"] = 221703, |
}, |
["METADATA"] = { |
["Specs"] = { |
["Demonology"] = 266, |
["Affliction"] = 265, |
["Destruction"] = 267, |
}, |
}, |
}, |
["WARRIOR"] = { |
["Protection"] = { |
["Shield Slam"] = 23922, |
["Intimidating Shout"] = 5246, |
["Avatar"] = 107574, |
["Berserker Rage"] = 18499, |
["Shield Block"] = 2565, |
["Taunt"] = 355, |
["Shockwave"] = 46968, |
["Devastate"] = 20243, |
["Shield Wall"] = 871, |
["Ignore Pain"] = 190456, |
["Demoralizing Shout"] = 1160, |
["Rallying Cry"] = 97462, |
["Last Stand"] = 12975, |
["Intercept"] = 198304, |
["Spell Reflection"] = 23920, |
["Battle Shout"] = 6673, |
["Revenge"] = 6572, |
["Pummel"] = 6552, |
["Heroic Leap"] = 6544, |
["Victory Rush"] = 34428, |
["Heroic Throw"] = 57755, |
["Thunder Clap"] = 6343, |
}, |
["Arms_Talents"] = { |
["Warbreaker"] = 262161, |
["Rend"] = 772, |
["Skullsplitter"] = 260643, |
["Defensive Stance"] = 197690, |
["Deadly Calm"] = 262228, |
["Impending Victory"] = 202168, |
["Storm Bolt"] = 107570, |
["Ravager"] = 152277, |
["Cleave"] = 845, |
["Avatar"] = 107574, |
}, |
["Fury"] = { |
["Taunt"] = 355, |
["Intimidating Shout"] = 5246, |
["Execute"] = 5308, |
["Whirlwind"] = 190411, |
["Rampage"] = 184367, |
["Piercing Howl"] = 12323, |
["Bloodthirst"] = 23881, |
["Raging Blow"] = 85288, |
["Recklessness"] = 1719, |
["Rallying Cry"] = 97462, |
["Battle Shout"] = 6673, |
["Charge"] = 100, |
["Pummel"] = 6552, |
["Enraged Regeneration"] = 184364, |
["Heroic Leap"] = 6544, |
["Victory Rush"] = 34428, |
["Heroic Throw"] = 57755, |
["Berserker Rage"] = 18499, |
}, |
["Fury_Talents"] = { |
["Impending Victory"] = 202168, |
["Storm Bolt"] = 107570, |
["Bladestorm"] = 46924, |
["Dragon Roar"] = 118000, |
["Siegebreaker"] = 280772, |
["Furious Slash"] = 100130, |
}, |
["Protection_PVPTalents"] = { |
["Spell Reflection"] = 216890, |
["Death Wish"] = 199261, |
["Gladiator's Medallion"] = 208683, |
["Disarm"] = 236077, |
["Sharpen Blade"] = 198817, |
["War Banner"] = 236320, |
["Duel"] = 236273, |
}, |
["Fury_PVPTalents"] = { |
["Spell Reflection"] = 216890, |
["Death Wish"] = 199261, |
["Gladiator's Medallion"] = 208683, |
["Disarm"] = 236077, |
["Sharpen Blade"] = 198817, |
["War Banner"] = 236320, |
["Duel"] = 236273, |
}, |
["Arms_PVPTalents"] = { |
["Spell Reflection"] = 216890, |
["Death Wish"] = 199261, |
["Gladiator's Medallion"] = 208683, |
["Disarm"] = 236077, |
["Sharpen Blade"] = 198817, |
["War Banner"] = 236320, |
["Duel"] = 236273, |
}, |
["Arms"] = { |
["Battle Shout"] = 6673, |
["Intimidating Shout"] = 5246, |
["Execute"] = 163201, |
["Whirlwind"] = 1680, |
["Mortal Strike"] = 12294, |
["Berserker Rage"] = 18499, |
["Overpower"] = 7384, |
["Hamstring"] = 1715, |
["Sweeping Strikes"] = 260708, |
["Rallying Cry"] = 97462, |
["Colossus Smash"] = 167105, |
["Charge"] = 100, |
["Die by the Sword"] = 118038, |
["Bladestorm"] = 227847, |
["Slam"] = 1464, |
["Pummel"] = 6552, |
["Heroic Leap"] = 6544, |
["Victory Rush"] = 34428, |
["Heroic Throw"] = 57755, |
["Taunt"] = 355, |
}, |
["Protection_Talents"] = { |
["Dragon Roar"] = 118000, |
["Ravager"] = 228920, |
["Impending Victory"] = 202168, |
["Storm Bolt"] = 107570, |
}, |
["METADATA"] = { |
["Specs"] = { |
["Fury"] = 72, |
["Arms"] = 71, |
["Protection"] = 73, |
}, |
}, |
}, |
}; |
-- Helper functions: Default lookup priorities, etc -- |
------------------------------------------------------ |
LibSN2SID.libLocal = { |
playerUniversalClassName = "", -- Player only, gathered upon PLAYER_LOGIN |
playerUniversalRaceName = "", -- Player only, gathered upon PLAYER_LOGIN |
petFamily = "", |
FactionSpells = { |
-- currrentFaction = "", |
["Alliance"] = { |
["MAGE"] = { |
["Flyouts"] = { |
["Portal"] = { |
["Portal: Vale of Eternal Blossoms"] = 132620, |
["Portal: Shattrath"] = 33691, |
["Portal: Tol Barad"] = 88345, |
}, |
["Teleport"] = { |
["Teleport: Vale of Eternal Blossoms"] = 132621, |
["Teleport: Shattrath"] = 33690, |
["Teleport: Tol Barad"] = 88342, |
}, |
}, |
}, |
}, |
["Horde"] = { |
["MAGE"] = { |
["Flyouts"] = { |
["Portal"] = { |
["Portal: Vale of Eternal Blossoms"] = 132626, |
["Portal: Shattrath"] = 35717, |
["Portal: Tol Barad"] = 88346, |
}, |
["Teleport"] = { |
["Teleport: Vale of Eternal Blossoms"] = 132627, |
["Teleport: Shattrath"] = 35715, |
["Teleport: Tol Barad"] = 88344, |
}, |
}, |
}, |
}, |
["Neutral"] = { -- For Pandarens who haven't chosen their faction yet |
}, |
}, |
}; |
LibSN2SID.SetFaction = function(faction, instanceName) -- TODO: Move to section "API" bellow ! |
-- print(LibSpellName2SID_MAJOR.. ": 2. Player faction = ".. tostring(faction)); |
assert((faction == "Alliance") or (faction == "Horde") or (faction == "Neutral"), "Bad argument #1 to LibSpellName2SID.SetFaction(); must be either \"Alliance\" or \"Horde\" (or possibly \"Neutral\")."); |
if not LibSN2SID.clients then |
LibSN2SID.clients = {}; |
end |
if not LibSN2SID.clients[instanceName] then |
assert(instanceName == LibSpellName2SID_MAJOR, "Bad argument #2 to LibSpellName2SID.SetFaction(); must be a registered instance of ".. LibSpellName2SID_MAJOR); |
end |
-- print(LibSpellName2SID_MAJOR.. ": LibSpellName2SID.SetFaction called with instanceName = ".. tostring(instanceName)); |
-- print(LibSpellName2SID_MAJOR.. ": 2. Player currrentFaction = ".. tostring(LibSN2SID.libLocal.FactionSpells.currrentFaction)); |
if not LibSN2SID.clients[instanceName].SID then |
LibSN2SID.clients[instanceName].SID = {}; |
LibSN2SID.clients[instanceName].LSN = {}; |
end |
if not LibSN2SID.clients[instanceName].SID.FactionSpells then |
LibSN2SID.clients[instanceName].SID.FactionSpells = {}; |
LibSN2SID.clients[instanceName].LSN.FactionSpells = {}; |
end |
if not LibSN2SID.clients[instanceName].SID.FactionSpells.currentFaction then |
LibSN2SID.clients[instanceName].SID.FactionSpells.currentFaction = ""; |
LibSN2SID.clients[instanceName].LSN.FactionSpells.currentFaction = ""; |
end |
-- Sanity checks and fallback setups done. Now put the new faction spells into place if needed |
if faction ~= LibSN2SID.clients[instanceName].SID.FactionSpells.currentFaction then |
LibSN2SID.clients[instanceName].SID.FactionSpells.currentFaction = faction; |
LibSN2SID.clients[instanceName].LSN.FactionSpells.currentFaction = faction; |
local factionSpells_table = LibSN2SID.libLocal.FactionSpells[faction]; -- For human readers |
-- Copy the spells from the apropriate table of faction sepcifics table to this lib instance |
local classIndex = 1; |
local classKey = (next(factionSpells_table, nil)); |
if not classKey then -- "Neutral" faction has no ... faction spells. |
return false; |
end |
if not LibSN2SID.clients[instanceName].SID.FactionSpells[classKey] then |
LibSN2SID.clients[instanceName].SID.FactionSpells[classKey] = {}; |
LibSN2SID.clients[instanceName].LSN.FactionSpells[classKey] = {}; |
end |
while classKey do |
-- print(LibSpellName2SID_MAJOR.. ": ".. classIndex.. ": ".. classKey); |
-- print(LibSpellName2SID_MAJOR.. ": type of factionSpells_table[classKey] = ".. tostring(type(factionSpells_table[classKey]))); |
local specIndex = 1; |
local specKey = (next(factionSpells_table[classKey], nil)); |
if not LibSN2SID.clients[instanceName].SID.FactionSpells[classKey][specKey] then |
LibSN2SID.clients[instanceName].SID.FactionSpells[classKey][specKey] = {}; |
LibSN2SID.clients[instanceName].LSN.FactionSpells[classKey][specKey] = {}; |
end |
while specKey do |
-- print(LibSpellName2SID_MAJOR.. ": ".. classIndex.. ".".. specIndex.. ": ".. tostring(specKey)); |
local contentIndex = 1; |
local contentKey = (next(factionSpells_table[classKey][specKey], nil)); |
while contentKey do |
-- print(LibSpellName2SID_MAJOR.. ": ".. classIndex.. ".".. specIndex.. ".".. contentIndex.. ": ".. contentKey); |
if type(factionSpells_table[classKey][specKey][contentKey]) == "table" then -- "Flyouts"->Button or "Pets"->Pet |
local spellIndex = 1; |
local spellKey = (next(factionSpells_table[classKey][specKey][contentKey], nil)); |
if not LibSN2SID.clients[instanceName].SID.FactionSpells[classKey][specKey][contentKey] then |
LibSN2SID.clients[instanceName].SID.FactionSpells[classKey][specKey][contentKey] = {}; |
LibSN2SID.clients[instanceName].LSN.FactionSpells[classKey][specKey][contentKey] = {}; |
end |
while spellKey do |
-- print(LibSpellName2SID_MAJOR.. ": ".. classIndex.. ".".. specIndex.. ".".. contentIndex.. ".".. spellIndex.. ": ".. spellKey); |
LibSN2SID.clients[instanceName].SID.FactionSpells[classKey][specKey][contentKey][spellKey] = factionSpells_table[classKey][specKey][contentKey][spellKey]; |
LibSN2SID.clients[instanceName].LSN.FactionSpells[classKey][specKey][contentKey][spellKey] = factionSpells_table[classKey][specKey][contentKey][spellKey]; |
-- print(LibSpellName2SID_MAJOR.. ": LibSN2SID.DB\[".. classKey.. "\]\[".. specKey.. "\]\[".. contentKey.. "\]\[".. |
spellKey = (next(factionSpells_table[classKey][specKey][contentKey], spellKey)); |
spellIndex = spellIndex + 1; |
end |
else |
LibSN2SID.clients[instanceName].SID.FactionSpells[classKey][specKey][contentKey] = factionSpells_table[classKey][specKey][contentKey]; |
LibSN2SID.clients[instanceName].LSN.FactionSpells[classKey][specKey][contentKey] = factionSpells_table[classKey][specKey][contentKey]; |
end |
contentKey = (next(factionSpells_table[classKey][specKey], contentKey)); |
contentIndex = contentIndex + 1; |
end |
specKey = (next(factionSpells_table[classKey], specKey)); |
specIndex = specIndex + 1; |
end |
classKey = (next(factionSpells_table, classKey)); |
classIndex = classIndex + 1; |
end |
end |
end |
LibSN2SID.libLocal.SetDefaultFaction = function(instanceName) |
local instanceName = instanceName or LibSpellName2SID_MAJOR; |
if instanceName == LibSpellName2SID_MAJOR then |
LibSN2SID.clients[LibSpellName2SID_MAJOR] = {}; |
end |
local englishFaction, _ = UnitFactionGroup("player"); |
-- print(LibSpellName2SID_MAJOR.. ": 1. Player faction = ".. tostring(englishFaction)); |
LibSN2SID.SetFaction(englishFaction, instanceName); |
if instanceName == LibSpellName2SID_MAJOR then |
-- for k, v in pairs(LibSN2SID.clients) do |
local instName = (next(LibSN2SID.clients, nil)); |
while instName do |
if (instName ~= LibSpellName2SID_MAJOR) then |
if (not LibSN2SID.clients[instName].FactionSpells) or (not LibSN2SID.clients[instName].FactionSpells.currentFaction) or (LibSN2SID.clients[instName].FactionSpells.currentFaction == "") then |
-- print(LibSpellName2SID_MAJOR.. ": Default faction set to reserved instance name \'".. LibSpellName2SID_MAJOR.. "\'. Will now set the same faction to instance ".. instName); |
LibSN2SID.SetFaction(englishFaction, instName); |
end |
end |
instName = (next(LibSN2SID.clients, instName)); |
end |
end |
end |
LibSN2SID.libLocal.GetEnglishSpecialisationName = function(specID, ...) -- Any class/spec |
-- Arguments (1 to 2): |
-- specID (number) *mandatory - Specialisation ID for which we want to get the English Name. |
-- universalClassName (string) *optional - Class where the specialisation should be found; |
-- Defaults to the current Player's class. |
-- Returns (2): |
-- engSpecName (string): English name for the given Specialisation; Nil if the spec wasn't |
-- found. |
-- uniClassName (string): Non-localised name of the Class the spec belongs to (given as arg2 |
-- or otherwise discovered if the given class was wrong or nil). Nil if the spec wasn't |
-- found. |
-- |
-- Look first in the provided universal class name (or the player class if argument is missing) |
local lookupFirstInClass = ... or LibSN2SID.libLocal.playerUniversalClassName; |
for engSpecName, DBspecID in pairs(LibSN2SID.DB[lookupFirstInClass].METADATA.Specs) do |
if DBspecID == specID then |
return engSpecName, lookupFirstInClass; |
end |
end |
-- Look up the specialisation ID in all other classes |
local generalTabName = (GetSpellTabInfo(1)); |
local uniClassName = (next(LibSN2SID.DB, nil)); |
while uniClassName do |
if (uniClassName ~= generalTabName) and (uniClassName ~= lookupFirstInClass) then |
for engSpecName, DBspecID in pairs(LibSN2SID.DB[uniClassName].METADATA.Specs) do |
-- print(uniClassName); |
if DBspecID == specID then |
return engSpecName, uniClassName; |
end |
end |
end |
uniClassName = (next(LibSN2SID.DB, uniClassName)); |
end |
-- Could not find the given specID in the database |
return nil, nil; |
end |
LibSN2SID.libLocal.GetActiveEnglishSpecialisationName = function() -- Player only |
-- Returns(3): |
-- engSpecName (string) - English name for the active Player Specialisation; Nil if no spec |
-- is active (e.g. if character level < 10). |
-- uniClassName (string) - Non-localised name of the Player Class. Nil if no active spec. |
-- activeSpecID (number) - Specialisation ID for the active spec. Nil if no active spec. |
-- |
local activeSpecIndex = (GetSpecialization()); |
-- print(tostring(activeSpecIndex)); |
if activeSpecIndex then |
local activeSpecID = (GetSpecializationInfo(activeSpecIndex)); |
-- print(tostring(activeSpecID)); |
return LibSN2SID.libLocal.GetEnglishSpecialisationName(activeSpecID, LibSN2SID.libLocal.playerUniversalClassName), activeSpecID; |
else |
return nil, nil, nil; -- Player does not have an active specialisation |
end |
end |
LibSN2SID.libLocal.LookupOrder_table = {}; -- Any class/spec |
-- Order to lookup spells in the DB: |
-- 1st: Player's class: |
-- 1.1. Active spec baseline spells; |
-- 1.2. Active spec Talents' spells; |
-- 1.3. Active spec PvP Talents' spells; |
-- 1.4. Flyouts (if there are spells for); |
-- 1.5. Pets (if there are spells for); |
-- 1.5.1. Current pet specialization (if there is one) spells; NOT properly working, pet family |
-- 1.5.2. Current pet fmaily (if there is one) spells; gets bumped up above pet specicalization |
-- 1.6. Other specs' baseline spells; |
-- 1.7. Other specs' Talents' spells; |
-- 1.8. Other specs' PvP Talents' spells; |
-- 2nd: GeneralTab; |
-- 3rd: Other classes: |
-- 3.1. Each spec baseline spells; |
-- 3.2. Each spec Talents' spells; |
-- 3.3. Each spec PvP Talents' spells; |
-- 3.4. Flyouts (if there are spells for); |
-- 3.5. Pets (if there are spells for). |
LibSN2SID.libLocal.setCurrentPetFirstInLookupOrder = function() |
local classKey = LibSN2SID.libLocal.playerUniversalClassName; |
if LibSN2SID.libLocal.LookupOrder_table[classKey].Pets then |
wipe(LibSN2SID.libLocal.LookupOrder_table[classKey].Pets); |
else |
local index = (LibSN2SID.DB[classKey].Flyouts and 5) or 4; |
tinsert(LibSN2SID.libLocal.LookupOrder_table[classKey], index, "Pets"); |
LibSN2SID.libLocal.LookupOrder_table[classKey].Pets = {}; |
end |
local petSpecName; |
if classKey == "HUNTER" then |
local petSpecIndex = (GetSpecialization(false, true)); |
petSpecName = (petSpecIndex == 1 and "Ferocity") or (petSpecIndex == 2 and |
"Tenacity") or (petSpecIndex == 3 and "Cunning") or nil; |
-- print(tostring(petSpecIndex).. " : ".. tostring(petSpecName)); |
end |
local petKey = (next(LibSN2SID.DB[classKey].Pets, nil)); |
while petKey do |
if petSpecName and petKey == petSpecName then |
tinsert(LibSN2SID.libLocal.LookupOrder_table[classKey].Pets, 1, petKey); |
elseif LibSN2SID.libLocal.petFamily and petKey == LibSN2SID.libLocal.petFamily then |
local index = (petSpecName and LibSN2SID.libLocal.LookupOrder_table[classKey].Pets[petSpecName] and 2) or 1; |
tinsert(LibSN2SID.libLocal.LookupOrder_table[classKey].Pets, index, petKey); |
else |
tinsert(LibSN2SID.libLocal.LookupOrder_table[classKey].Pets, petKey); |
end |
petKey = (next(LibSN2SID.DB[classKey].Pets, petKey)); |
end |
end |
LibSN2SID.libLocal.SetLookupOrder = function() |
-- LibSN2SID.libLocal.LookupOrder_table = {}; -- Reset the table |
wipe(LibSN2SID.libLocal.LookupOrder_table); -- Reset the table |
local classOrderIndex = 1; |
local classKey = (next(LibSN2SID.DB, nil)); |
-- print(tostring(classKey)); |
while classKey do |
if classKey == LibSN2SID.libLocal.playerUniversalClassName then -- Current player class |
tinsert(LibSN2SID.libLocal.LookupOrder_table, 1, classKey); |
LibSN2SID.libLocal.LookupOrder_table[classKey] = {}; |
-- print(tostring(LibSN2SID.libLocal.LookupOrder_table[1])); |
-- Order specs et al |
local playerActiveEnglishSpecName = (LibSN2SID.libLocal.GetActiveEnglishSpecialisationName()); |
-- print("Active SpecName = ".. tostring(playerActiveEnglishSpecName)); |
local specKey = (next(LibSN2SID.DB[classKey].METADATA.Specs, nil)); |
while specKey do |
if specKey == playerActiveEnglishSpecName then |
tinsert(LibSN2SID.libLocal.LookupOrder_table[classKey], 1, specKey); |
tinsert(LibSN2SID.libLocal.LookupOrder_table[classKey], 2, specKey.."_Talents"); |
tinsert(LibSN2SID.libLocal.LookupOrder_table[classKey], 3, specKey.."_PVPTalents"); |
-- print(tostring(LibSN2SID.libLocal.LookupOrder_table[classKey][1]).. " *"); |
-- elseif LibSN2SID.DB[classKey].METADATA.Specs[specKey] then |
else |
tinsert(LibSN2SID.libLocal.LookupOrder_table[classKey], specKey); |
tinsert(LibSN2SID.libLocal.LookupOrder_table[classKey], specKey.."_Talents"); |
tinsert(LibSN2SID.libLocal.LookupOrder_table[classKey], specKey.."_PVPTalents"); |
end |
specKey = (next(LibSN2SID.DB[classKey].METADATA.Specs, specKey)); |
end |
if LibSN2SID.DB[classKey].Flyouts then |
tinsert(LibSN2SID.libLocal.LookupOrder_table[classKey], 4, "Flyouts"); |
LibSN2SID.libLocal.LookupOrder_table[classKey].Flyouts = {}; |
local flyoutButtonKey = (next(LibSN2SID.DB[classKey].Flyouts, nil)); |
while flyoutButtonKey do |
tinsert(LibSN2SID.libLocal.LookupOrder_table[classKey].Flyouts, flyoutButtonKey); |
flyoutButtonKey = (next(LibSN2SID.DB[classKey].Flyouts, flyoutButtonKey)); |
end |
end |
if LibSN2SID.DB[classKey].Pets then |
LibSN2SID.libLocal.setCurrentPetFirstInLookupOrder(); |
end |
elseif classKey ~= "General" then -- Other classes |
tinsert(LibSN2SID.libLocal.LookupOrder_table, classKey); |
-- print(tostring(LibSN2SID.libLocal.LookupOrder_table[classOrderIndex])); |
LibSN2SID.libLocal.LookupOrder_table[classKey] = {}; |
local specKey = (next(LibSN2SID.DB[classKey].METADATA.Specs, nil)); |
while specKey do |
-- local numSpecSubTables = 3; -- Unless we also have Flyouts, making it 4 or more |
tinsert(LibSN2SID.libLocal.LookupOrder_table[classKey], specKey); |
tinsert(LibSN2SID.libLocal.LookupOrder_table[classKey], specKey.."_Talents"); |
tinsert(LibSN2SID.libLocal.LookupOrder_table[classKey], specKey.."_PVPTalents"); |
specKey = (next(LibSN2SID.DB[classKey].METADATA.Specs, specKey)); |
end |
if LibSN2SID.DB[classKey].Flyouts then |
tinsert(LibSN2SID.libLocal.LookupOrder_table[classKey], "Flyouts"); |
LibSN2SID.libLocal.LookupOrder_table[classKey].Flyouts = {}; |
local flyoutButtonKey = (next(LibSN2SID.DB[classKey].Flyouts, nil)); |
while flyoutButtonKey do |
-- print(LibSpellName2SID_MAJOR.. ": ".. tostring(flyoutButtonKey)); |
tinsert(LibSN2SID.libLocal.LookupOrder_table[classKey].Flyouts, flyoutButtonKey); |
flyoutButtonKey = (next(LibSN2SID.DB[classKey].Flyouts, flyoutButtonKey)); |
end |
end |
if LibSN2SID.DB[classKey].Pets then |
tinsert(LibSN2SID.libLocal.LookupOrder_table[classKey], "Pets"); |
LibSN2SID.libLocal.LookupOrder_table[classKey].Pets = {}; |
local petKey = (next(LibSN2SID.DB[classKey].Pets, nil)); |
while petKey do |
tinsert(LibSN2SID.libLocal.LookupOrder_table[classKey].Pets, petKey); |
petKey = (next(LibSN2SID.DB[classKey].Pets, petKey)); |
end |
end |
end |
classKey = (next(LibSN2SID.DB, classKey)); |
classOrderIndex = classOrderIndex + 1; |
end |
tinsert(LibSN2SID.libLocal.LookupOrder_table, 2, "General"); |
LibSN2SID.libLocal.LookupOrder_table["General"] = {}; |
local categoryKey = (next(LibSN2SID.DB.General, nil)); |
while categoryKey do |
if categoryKey == "Racials" then |
tinsert(LibSN2SID.libLocal.LookupOrder_table.General, "Racials"); |
LibSN2SID.libLocal.LookupOrder_table.General.Racials = {}; |
local racialKey = (next(LibSN2SID.DB.General.Racials, nil)); |
while racialKey do |
if racialKey == LibSN2SID.libLocal.playerUniversalRaceName then |
tinsert(LibSN2SID.libLocal.LookupOrder_table.General.Racials, 1, racialKey); |
else |
tinsert(LibSN2SID.libLocal.LookupOrder_table.General.Racials, racialKey); |
end |
racialKey = (next(LibSN2SID.DB.General.Racials, racialKey)); |
end |
-- elseif categoryKey ~= "METADATA" then -- Currentlu not in the database |
else |
tinsert(LibSN2SID.libLocal.LookupOrder_table.General, categoryKey); |
end |
categoryKey = (next(LibSN2SID.DB.General, categoryKey)); |
end |
end |
-- API -- |
--------- |
-- Return SpellID of the English Spell Name -- |
LibSN2SID.libLocal.instanceSID = {}; |
LibSN2SID.libLocal.instanceSID.stub = { ["stub"] = 0 }; |
LibSN2SID.libLocal.instanceSID.metaT = {}; |
LibSN2SID.libLocal.instanceSID.new = function(instObj) |
setmetatable(instObj, LibSN2SID.libLocal.instanceSID.metaT); |
return instObj; |
end |
LibSN2SID.libLocal.instanceSID.metaT.__index = function(tbl, engSpellName) -- If spell name not found in 'tbl'. |
local paramType = type(engSpellName); |
-- print(LibSpellName2SID_MAJOR.. ": ".. engSpellName.. " is a ".. paramType); |
if (paramType == "string") then |
for classIndex = 1, #LibSN2SID.libLocal.LookupOrder_table do |
local classKey = LibSN2SID.libLocal.LookupOrder_table[classIndex]; |
-- print(LibSpellName2SID_MAJOR.. ": ".. tostring(classKey)); |
for specIndex = 1, #(LibSN2SID.libLocal.LookupOrder_table[classKey]) do |
local specKey = LibSN2SID.libLocal.LookupOrder_table[classKey][specIndex]; |
local spID = LibSN2SID.DB[classKey][specKey][engSpellName] or nil; |
if spID then |
return spID; -- FOUND IT! |
end |
-- if specKey == "Flyouts" or specKey == "Pets" then |
if LibSN2SID.libLocal.LookupOrder_table[classKey][specKey] ~= nil and type(LibSN2SID.libLocal.LookupOrder_table[classKey][specKey]) == "table" then |
local subTableKey = (next(LibSN2SID.DB[classKey][specKey], nil)); |
while subTableKey do |
-- print(tostring(classKey).. " ".. tostring(specKey).. " ".. tostring(subTableKey)); |
local spID = LibSN2SID.DB[classKey][specKey][subTableKey][engSpellName] or nil; |
if spID then |
return spID; -- FOUND IT! |
end |
subTableKey = (next(LibSN2SID.DB[classKey][specKey], subTableKey)); |
end |
end |
if tbl and tbl.FactionSpells and tbl.FactionSpells[classKey] and tbl.FactionSpells[classKey][specKey] then |
-- print(LibSpellName2SID_MAJOR.. ": Looking for \'".. engSpellName.. "\' in client: ".. instanceName); |
local spID = tbl.FactionSpells[classKey][specKey][engSpellName] or nil; |
if spID then |
return spID; -- FOUND IT! |
end |
if LibSN2SID.libLocal.LookupOrder_table[classKey][specKey] ~= nil and type(LibSN2SID.libLocal.LookupOrder_table[classKey][specKey]) == "table" then |
local subTableKey = (next(tbl.FactionSpells[classKey][specKey], nil)); |
while subTableKey do |
-- print(tostring(classKey).. " ".. tostring(specKey).. " ".. tostring(subTableKey)); |
local spID = tbl.FactionSpells[classKey][specKey][subTableKey][engSpellName] or nil; |
if spID then |
return spID; -- FOUND IT! |
end |
subTableKey = (next(tbl.FactionSpells[classKey][specKey], subTableKey)); |
end |
end |
end |
end |
end |
-- Didn't find the given spell name in our database. So try and get it from game API |
local locSpellName, _, _, _, _, _, spID = GetSpellInfo(engSpellName); |
return spID; |
elseif (paramType == "number") then |
local locSpellName = (GetSpellInfo(engSpellName)); |
-- print(tostring(locSpellName)); |
if locSpellName then |
return engSpellName; |
else |
return nil; |
end |
else |
-- TODO: error() ? |
return nil; |
end |
end |
-- Return Localised Name of the English Spell Name -- |
LibSN2SID.libLocal.instanceLSN = {}; |
LibSN2SID.libLocal.instanceLSN.stub = { ["stub"] = 0 }; |
LibSN2SID.libLocal.instanceLSN.metaT = {}; |
LibSN2SID.libLocal.instanceLSN.new = function(instObj) |
setmetatable(instObj, LibSN2SID.libLocal.instanceLSN.metaT); |
return instObj; |
end |
LibSN2SID.libLocal.instanceLSN.metaT.__index = function(tbl, engSpellName) |
-- print("LSN __index"); |
local paramType = type(engSpellName); |
-- print(LibSpellName2SID_MAJOR.. ": ".. engSpellName.. " is a ".. paramType); |
if paramType == "string" then |
for classIndex = 1, #LibSN2SID.libLocal.LookupOrder_table do |
local classKey = LibSN2SID.libLocal.LookupOrder_table[classIndex]; |
-- print(LibSpellName2SID_MAJOR.. ": ".. tostring(classKey)); |
for specIndex = 1, #(LibSN2SID.libLocal.LookupOrder_table[classKey]) do |
local specKey = LibSN2SID.libLocal.LookupOrder_table[classKey][specIndex]; |
-- print(LibSpellName2SID_MAJOR.. ": ".. tostring(specKey)); |
local spID = LibSN2SID.DB[classKey][specKey][engSpellName] or nil; |
if spID then |
-- print("Found in ".. classKey.. ": ".. specKey); |
local locSpellName = (GetSpellInfo(spID)); -- Localised spell name |
return locSpellName; -- FOUND IT! |
end |
if LibSN2SID.libLocal.LookupOrder_table[classKey][specKey] ~= nil and type(LibSN2SID.libLocal.LookupOrder_table[classKey][specKey]) == "table" then |
local subTableKey = (next(LibSN2SID.DB[classKey][specKey], nil)); |
while subTableKey do |
-- print(tostring(classKey).. " ".. tostring(specKey).. " ".. tostring(subTableKey)); |
local spID = LibSN2SID.DB[classKey][specKey][subTableKey][engSpellName] or nil; |
if spID then |
local locSpellName = (GetSpellInfo(spID)); -- Localised spell name |
return locSpellName; -- FOUND IT! |
end |
subTableKey = (next(LibSN2SID.DB[classKey][specKey], subTableKey)); |
end |
end |
if tbl and tbl.FactionSpells and tbl.FactionSpells[classKey] and tbl.FactionSpells[classKey][specKey] then |
-- print(LibSpellName2SID_MAJOR.. ": Looking for \'".. engSpellName.. "\' in client: ".. instanceName); |
local spID = tbl.FactionSpells[classKey][specKey][engSpellName] or nil; |
if spID then |
local locSpellName = (GetSpellInfo(spID)); -- Localised spell name |
return locSpellName; -- FOUND IT! |
end |
if LibSN2SID.libLocal.LookupOrder_table[classKey][specKey] ~= nil and type(LibSN2SID.libLocal.LookupOrder_table[classKey][specKey]) == "table" then |
local subTableKey = (next(tbl.FactionSpells[classKey][specKey], nil)); |
while subTableKey do |
-- print(tostring(classKey).. " ".. tostring(specKey).. " ".. tostring(subTableKey)); |
local spID = tbl.FactionSpells[classKey][specKey][subTableKey][engSpellName] or nil; |
if spID then |
local locSpellName = (GetSpellInfo(spID)); -- Localised spell name |
return locSpellName; -- FOUND IT! |
end |
subTableKey = (next(tbl.FactionSpells[classKey][specKey], subTableKey)); |
end |
end |
end |
end |
end |
-- Didn't find the given spell name in our database. So try and get it from game API |
local locSpellName, _, _, _, _, _, spID = GetSpellInfo(engSpellName); |
return locSpellName; |
elseif paramType == "number" then |
local locSpellName = (GetSpellInfo(engSpellName)); |
-- print(locSpellName); |
return locSpellName; |
else |
-- TODO: error() ? |
return nil; |
end |
end |
-- Blizzard events used by the library -- |
----------------------------------------- |
LibSN2SID.libFrame:RegisterEvent("PLAYER_LOGIN"); |
LibSN2SID.libLocal.lookupOrderTableInitialized = false; |
LibSN2SID.libFrame:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED"); -- This talent and/or the one in the line bellow |
LibSN2SID.libFrame:RegisterEvent("PLAYER_TALENT_UPDATE"); -- should fire when the player switches spec. |
LibSN2SID.libFrame:RegisterUnitEvent("UNIT_PET", "player"); -- Fired when a unit's pet changes. |
LibSN2SID.libFrame:RegisterEvent("PET_SPECIALIZATION_CHANGED"); -- Fired upon pet's specialisation changes. |
LibSN2SID.libFrame:SetScript("OnEvent", function(self, event) |
if event == "PLAYER_LOGIN" or event == "PLAYER_ENTERING_WORLD" then |
local stubVal; |
stubVal, LibSN2SID.libLocal.playerUniversalClassName = UnitClass("player"); |
stubVal, LibSN2SID.libLocal.playerUniversalRaceName = UnitRace("player"); |
LibSN2SID.libLocal.SetDefaultFaction(instanceName); |
if UnitExists("pet") then -- Get current Pet data to build the corresponding lookup table |
LibSN2SID.libLocal.petFamily = UnitCreatureFamily("pet"); |
end |
LibSN2SID.libLocal.SetLookupOrder(); |
LibSN2SID.libLocal.lookupOrderTableInitialized = true; |
elseif LibSN2SID.libLocal.lookupOrderTableInitialized then |
if event == "UNIT_PET" or event == "PET_SPECIALIZATION_CHANGED" then |
if not LibSN2SID.libLocal.playerUniversalClassName or not LibSN2SID.libLocal.LookupOrder_table[LibSN2SID.libLocal.playerUniversalClassName] then |
return; -- Build lookup table for Pet only after we built the lookup table for Class |
end |
LibSN2SID.libLocal.petFamily = UnitCreatureFamily("pet"); |
if not LibSN2SID.libLocal.petFamily then -- UNIT_PET fires several times when a pet |
return; -- is lost and when a new one is called; we'll get the new pet |
end -- info eventually, but we'll wait til it's up. |
LibSN2SID.libLocal.setCurrentPetFirstInLookupOrder(); |
else |
LibSN2SID.libLocal.SetLookupOrder(); |
end |
end |
-- for i = 1, #LibSN2SID.libLocal.LookupOrder_table do |
-- local classKey = LibSN2SID.libLocal.LookupOrder_table[i]; |
-- print(LibSpellName2SID_MAJOR.. ": ".. i.. ". ".. tostring(classKey)); |
-- for ii = 1, #(LibSN2SID.libLocal.LookupOrder_table[classKey]) do |
-- local specKey = LibSN2SID.libLocal.LookupOrder_table[classKey][ii]; |
-- print(LibSpellName2SID_MAJOR.. ": ".. i.. ".".. ii.. ". ".. tostring(specKey)); |
-- if type(LibSN2SID.libLocal.LookupOrder_table[classKey][specKey]) == "table" then |
-- for iii = 1, #(LibSN2SID.libLocal.LookupOrder_table[classKey][specKey]) do |
-- local subTableKey = LibSN2SID.libLocal.LookupOrder_table[classKey][specKey][iii]; |
-- print(LibSpellName2SID_MAJOR.. ": ".. i.. ".".. ii.. ".".. iii.. ". ".. tostring(subTableKey)); |
-- end |
-- end |
-- end |
-- end |
end); |
-- Library Instances Registration and Removal -- |
------------------------------------------------ |
-- Register a new instance of this library |
function LibSN2SID:NewInstance(instanceName) |
-- print(LibSpellName2SID_MAJOR.. ": Just started function LibSN2SID:NewInstance(".. instanceName.. ")"); |
if (type(instanceName) ~= "string") or (instanceName == "") then |
error("Must provide a valid instanceName (unique string) to the new library instance of ".. LibSpellName2SID_MAJOR.. "."); |
elseif instanceName == LibSpellName2SID_MAJOR then |
error("Cannot create a new instance of ".. LibSpellName2SID_MAJOR.. "with the name".. LibSpellName2SID_MAJOR.. " (that name is reserved)."); |
elseif LibSN2SID.clients and LibSN2SID.clients[instanceName] then |
error("Will not create a duplicate instance of ".. LibSpellName2SID_MAJOR.. ", with the already existing name: ".. instanceName.. "."); |
end |
LibSN2SID.clients = LibSN2SID.clients or {}; |
LibSN2SID.clients[instanceName] = {}; |
LibSN2SID.clients[instanceName].SID = LibSN2SID.clients[instanceName].SID or {}; |
LibSN2SID.clients[instanceName].LSN = LibSN2SID.clients[instanceName].LSN or {}; |
LibSN2SID.clients[instanceName].SID = LibSN2SID.libLocal.instanceSID.new(LibSN2SID.clients[instanceName].SID); |
LibSN2SID.clients[instanceName].LSN = LibSN2SID.libLocal.instanceLSN.new(LibSN2SID.clients[instanceName].LSN); |
return LibSN2SID; |
end |
-- Remove an instance of this library, if the data isn't needed anymore |
function LibSN2SID:RemoveInstance(instanceName, ...) |
-- print(LibSpellName2SID_MAJOR.. ": RemoveInstance: ".. tostring(instanceName)); |
local DontErrorOnInexistentInstanceName = ... or false; |
if (type(instanceName) ~= "string") or (instanceName == "") then |
error("Must provide a valid instanceName (string) of the ".. LibSpellName2SID_MAJOR.. " library, to cleanup."); |
elseif instanceName == LibSpellName2SID_MAJOR then |
error("Will not remove base-instance \"".. instanceName.. "\" of library ".. LibSpellName2SID_MAJOR.. "."); |
elseif (not LibSN2SID.clients) or (not LibSN2SID.clients[instanceName]) then |
if DontErrorOnInexistentInstanceName then |
return false; |
else |
error("Cannot clean up instance of ".. LibSpellName2SID_MAJOR.. ", with name: ".. instanceName.. " (non existent)."); |
end |
end |
LibSN2SID.clients[instanceName] = nil; |
return LibSN2SID.clients[instanceName]; |
end |
-- Get the number of spells in the database |
-- TODO: Redo for new DB structure in 10008+ ! |
-- function LibSN2SID:GetNumSpells() |
-- error("This function is not implemented in the current versions of ".. LibSpellName2SID_MAJOR.. ": ".. LibAlkaTest_MINOR); |
-- local count = 0; |
-- for _ in pairs(LibSN2SID.DB) do |
-- count = count + 1; |
-- end |
-- return count; |
-- end |
------------------------------------------ |
-- print(LibSpellName2SID_MAJOR.. ": LibSN2SID.DB has ".. LibSN2SID.GetNumSpells().. " keys."); |
## Interface: 80105 |
## Title: Lib: SpellName2SID-1.1 |
## Notes: Table of English Spell Names and corresponding Spell IDs |
## Version: 1.1.03 |
## LoadOnDemand: 1 |
## Author: aallkkaa |
## X-Original-Author: twobits |
## X-Credits: benots4 |
## X-Category: Library |
## X-WoWI-ID: 24509 |
LibStub\LibStub.lua |
LibSpellName2SID-1.1\LibSpellName2SID-1.1.lua |
#test1.lua |
#test2.lua |
#test3.lua |
#test4.lua |
-- V.10000: 2009 originally by Twobits[1], as part of ReadySpells[2] |
-- 2010 edited by benots4[3] |
-- 2017 published as an addon of its own by aallkkaa[4] |
-- V.10001 - 10102: 2017-2019 WoW 7.3.x to 8.0.1 versions by aallkkaa [4] |
-- V.10001 - 10103: 2017-2019 WoW 7.3.x to 8.x versions by aallkkaa [4] |
-- |
-- [1] https://www.wowinterface.com/forums/member.php?userid=139157 |
-- https://www.curseforge.com/members/twobits |
-- Library's version values -- |
local LibSpellName2SID_MAJOR = "LibSpellName2SID-1.1"; |
local LibSpellName2SID_MINOR = 10102; |
local LibSpellName2SID_MINOR = 10103; |
-- DataSource -- |
-- gameBuild = 29981 |
["Survival of the Fittest"] = 264735, |
["Growl"] = 2649, |
}, |
["Blood Beast"] = { |
["Blood Bolt"] = 288962, |
}, |
}, |
["Survival"] = { |
["Harpoon"] = 190925, |
## Interface: 80105 |
## Title: Lib: SpellName2SID-1.1 |
## Notes: Table of English Spell Names and corresponding Spell IDs |
## Version: 1.1.02 |
## Version: 1.1.03 |
## LoadOnDemand: 1 |
## Author: aallkkaa |
## X-Original-Author: twobits |
---------- |
-- (C) 2017-2019 by aallkkaa |
-- http://www.wowinterface.com/forums/member.php?action=getinfo&userid=335646 |
-- |
-- LibSpellName2SID-1.1: Populator |
-- Notes: Populates the library's database |
-- http://svn.wowinterface.com/listing.php?repname=LibSpellName2ID&path=%2Fpopulator%2F#_populator_ |
---------- |
local AddonName, AddonEnv = ...; |
-- Local copies of the saved variables' tables: SpellNamesAndIDs, SpellNamesAndIDs_PASSIVES and DEBUG_messages |
local SN2SID_table, SN2SID_PASSIVES_table, DEBUGmsgs; |
-- Variables for debugging |
local DBG_CurrentEvent = "" -- Event last fired when a task is being done |
-- WoW Expansion/Patch constants |
local NumberOfTalentTiers = 7; -- Current number of talent tiers - WoW-7.x.y and 8.x.y |
-- local NumberOfPVPTalentTiers = 6; -- Current number of PVP talent tiers - WoW-7.x.y |
local NumberOfPVPTalentSlots = 4; -- Current number of PVP talent tiers - WoW-8.x.y |
-- (Usually) One-time ferched values |
local generalTabName, universalRaceName, universalClassName; |
local petFamily, petSpec; |
-- "Manually" added/modified spells - normally AFTER regular update functions were called |
local postUpdate_Spells2Add = { |
["General"] = { |
["ZoneAbilities"] = { |
-- TODO: Maybe a hooksecurefunc(ZoneAbilityFrame, "Show", function())? |
-- Also check: /dump Enum.ZoneAbilityType |
-- Dump: value=Enum.ZoneAbilityType |
-- [1]={ |
-- Argus=2, |
-- OrderHall=1, |
-- Garrison=0 |
-- } |
-- |
-- Draenor -- These are never added to the Spellbook |
["Garrison Ability"] = 161691, -- Cast the Garrison/Outpost ability active on the zone |
["Call to Arms"] = 161676, -- Shadowmoon Valley / Frostfire Ridge |
["Champion's Honor"] = 164221, -- Gorgrond outpost |
["Summon Mechashredder 5000"] = 164050, -- Gorgrond outpost |
["Telaari Siege Engine"] = 160240, -- Nagrand |
["Telaari Talbuk"] = 165803, -- Nagrand (Alliance) |
["Frostwolf War Wolf"] = 164222, -- Nagrand (Horde) |
["Home Away from Home"] = 168487, -- Spires of Arak |
["Smuggling Run!"] = 170108, -- Spires of Arak |
["Artillery Strike"] = 162075, -- Talador outpost |
["Guardian Orb"] = 161767, -- Talador outpost |
["Logging"] = 167895, -- Mark lumber for gathering in Draenor (requires logging camp) |
-- Broken Isles |
["Combat Ally"] = 211390, |
-- Argus |
["Vindicaar Matrix Crystal"] = 251463, -- Cast the one active of the other four |
["Light's Judgment"] = 247427, -- Same name, different ID, than that of the Lightforged |
-- Draenei Racial spell. |
["Summon Lightforged Warframe"] = 250436, |
["Fel Heart Bond"] = 248011, -- Passive workings? - tooltip says "Instant" |
["Shroud of Arcane Echoes"] = 248779, |
}, |
}, |
["DEATHKNIGHT"] = { |
["Blood"] = { |
["Corpse Exploder"] = 127344, -- Cosmetic ability learned from tome |
}, |
["Frost"] = { |
["Corpse Exploder"] = 127344, -- Cosmetic ability learned from tome |
}, |
["Unholy"] = { |
["Corpse Exploder"] = 127344, -- Cosmetic ability learned from tome |
}, |
--[[ |
["Pets"] = { |
["Ghoul"] = { |
-- The spell "Dark Transformation" used to temporarily change the Ghoul's regular |
-- abilities into different ones (different names and IDs). Dark Transformation is |
-- still in the game and still modifies the Ghoul's abilities, but these changes are |
-- now "rolled into" the Ghoul's standard abilities; the old different ones can still |
-- be referenced by their old spell IDs, but no longer by their names (even though |
-- GetSpellInfo()* does return the spell name if queried through its ID). |
-- Bottomline: For the purpose of doing anything with using these spells' name as |
-- arguments, they are no longer existent. |
-- * C_Spell.DoesSpellExist(spellID) works for these spells, DoesSpellExist("spellName") |
-- does not. |
-- ["Sweeping Claws"] = 91778, |
-- ["Monstrous Blow"] = 91797, |
-- ["Shambling Rush"] = 91802, |
-- ["Putrid Bulwark"] = 91837, |
-- The regular spells: |
["Claw"] = 47468, |
["Gnaw"] = 47481, |
["Leap"] = 47482, |
["Huddle"] = 47484, |
}, |
-- The Unholy spec talent "Sludge Belcher" which summoned an Abomination instead of a |
-- Ghoul before 8.0.1 is no longer ingame. I.e. this type of DK pet is now gone. |
-- ["Abomination"] = { -- If the talent 'Sludge Belcher' is taken, the Ghoul becomes an |
-- -- 'Abomination' instead. |
-- ["Cleaver"] = 212333, |
-- ["Smash"] = 212336, |
-- ["Hook"] = 212468, |
-- ["Protective Bile"] = 212384, |
-- -- 'Abomination' + 'Dark Transformation': |
44 -- ["Vile Gas"] = 212338, |
-- ["Gastric Bloat"] = 212383, |
-- }, |
}, |
]]-- |
}, |
["DRUID"] = { -- The two different teleports + Abilities learned from Tomes |
["Balance"] = { |
-- The two different teleports |
["Teleport: Moonglade"] = 18960, -- BEFORE the Legion Druid quest that gives: |
["Dreamwalk"] = 193753, -- AFTER the Legion Druid quest: [98 - 110] To The Dreamgrove . |
-- The Minimap ability "Track Humanoids" is NOT on the Spellbook. It does have a spell |
-- ID that returns its name and all when passed as argument to GetSpellInfo(), but the |
-- spell name itself is not recognized by GetSpellBookItemInfo(). Thus we will NOT add |
-- it to our database. |
-- ["Track Humanoids"] = 19883 |
-- Abilities learned from Tomes |
["Charm Woodland Creature"] = 127757, -- Turn a critter into a minion for 1 hour |
["Flap"] = 164862, -- Requires Moonkin Form; channeled, NO CD other than Global |
["Stag Form"] = 210053, -- Proper shapeshift (unlike Treant?) == Ground Travel Form |
-- ["Track Beasts"] = 210065, -- Cat Form only, can be simultaneous with "Track |
-- Humanoids", but suffers from the same exact |
-- not-in-Spellbook issue; hence excluded from the DB. |
["Treant Form"] = 114282, -- Shapeshift form, appearance only (?); Reportedly randomly |
-- switches position with Moonkin Form (WoW-7.0.2 in the |
-- Stance Bar (relog and respec); unsure if fixed later on) |
-- "Nature's Beacon" is a (Druid-only) TOY |
}, |
["Feral"] = { |
-- The two different teleports |
["Teleport: Moonglade"] = 18960, -- BEFORE the Legion Druid quest that gives: |
["Dreamwalk"] = 193753, -- AFTER the Legion Druid quest: [98 - 110] "To The Dreamgrove". |
-- The Minimap ability "Track Humanoids" is NOT on the Spellbook. It does have a spell |
-- ID that returns its name and all when passed as argument to GetSpellInfo(), but the |
-- spell name itself is not recognized by GetSpellBookItemInfo(). Thus we will NOT add |
-- it to our database. |
-- ["Track Humanoids"] = 19883 |
-- Abilities learned from Tomes |
["Charm Woodland Creature"] = 127757, -- Turn a critter into a minion for 1 hour |
["Flap"] = 164862, -- Requires Moonkin Form; channeled, NO CD other than Global |
["Stag Form"] = 210053, -- Proper shapeshift (unlike Treant?) == Ground Travel Form |
-- ["Track Beasts"] = 210065, -- Cat Form only, can be simultaneous with "Track |
-- Humanoids", but suffers from the same exact |
-- not-in-Spellbook issue; hence excluded from the DB. |
["Treant Form"] = 114282, -- Shapeshift form, appearance only (?); Reportedly randomly |
-- switches position with Moonkin Form (WoW-7.0.2 in the |
-- Stance Bar (relog and respec); unsure if fixed later on) |
-- "Nature's Beacon" is a (Druid-only) TOY |
}, |
["Guardian"] = { |
-- The two different teleports |
["Teleport: Moonglade"] = 18960, -- BEFORE the Legion Druid quest that gives: |
["Dreamwalk"] = 193753, -- AFTER the Legion Druid quest: [98 - 110] "To The Dreamgrove". |
-- The Minimap ability "Track Humanoids" is NOT on the Spellbook. It does have a spell |
-- ID that returns its name and all when passed as argument to GetSpellInfo(), but the |
-- spell name itself is not recognized by GetSpellBookItemInfo(). Thus we will NOT add |
-- it to our database. |
-- ["Track Humanoids"] = 19883 |
-- Abilities learned from Tomes |
-- Abilities learned from Tomes |
["Charm Woodland Creature"] = 127757, -- Turn a critter into a minion for 1 hour |
["Flap"] = 164862, -- Requires Moonkin Form; channeled, NO CD other than Global |
["Stag Form"] = 210053, -- Proper shapeshift (unlike Treant?) == Ground Travel Form |
-- ["Track Beasts"] = 210065, -- Cat Form only, can be simultaneous with "Track |
-- Humanoids", but suffers from the same exact |
-- not-in-Spellbook issue; hence excluded from the DB.s |
["Treant Form"] = 114282, -- Shapeshift form, appearance only (?); Reportedly randomly |
-- switches position with Moonkin Form (WoW-7.0.2 in the |
-- Stance Bar (relog and respec); unsure if fixed later on) |
-- "Nature's Beacon" is a (Druid-only) TOY |
}, |
["Restoration"] = { |
-- The two different teleports |
["Teleport: Moonglade"] = 18960, -- BEFORE the Legion Druid quest that gives: |
["Dreamwalk"] = 193753, -- AFTER the Legion Druid quest: [98 - 110] "To The Dreamgrove". |
-- The Minimap ability "Track Humanoids" is NOT on the Spellbook. It does have a spell |
-- ID that returns its name and all when passed as argument to GetSpellInfo(), but the |
-- spell name itself is not recognized by GetSpellBookItemInfo(). Thus we will NOT add |
-- it to our database. |
-- ["Track Humanoids"] = 19883 |
-- Abilities learned from Tomes |
["Charm Woodland Creature"] = 127757, -- Turn a critter into a minion for 1 hour |
["Flap"] = 164862, -- Requires Moonkin Form; channeled, NO CD other than Global |
["Stag Form"] = 210053, -- Proper shapeshift (unlike Treant?) == Ground Travel Form |
-- ["Track Beasts"] = 210065, -- Cat Form only, can be simultaneous with "Track |
-- Humanoids", but suffers from the same exact |
-- not-in-Spellbook issue; hence excluded from the DB. |
["Treant Form"] = 114282, -- Shapeshift form, appearance only (?); Reportedly randomly |
-- switches position with Moonkin Form (WoW-7.0.2 in the |
-- Stance Bar (relog and respec); unsure if fixed later on) |
-- "Nature's Beacon" is a (Druid-only) TOY |
}, |
}, |
["HUNTER"] = { |
-- TODO: SPECS -- |
["Beast Mastery"] = { |
["Call Pet"] = 9, |
["Pet Utility"] = 103, |
}, |
["Marksmanship"] = { |
["Call Pet"] = 9, |
["Pet Utility"] = 103, |
}, |
["Survival"] = { |
["Call Pet"] = 9, |
["Pet Utility"] = 103, |
}, |
["FlyoutsTOGET"] = { |
["Call Pet"] = 9, |
["Pet Utility"] = 103, |
}, |
["Pets"] = { |
-- https://www.wowhead.com/battle-for-azeroth-hunter-pet-guide#hunter-pet-family-list-tenacity |
["Ferocity"] = { |
-- Some pets Bite, some pets Claw and some pets Smack |
["Bite"] = 17253, |
["Claw"] = 16827, |
["Smack"] = 49966, |
-- Specialization ability |
["Primal Rage"] = 264667, |
-- All Hunter pets (regardless of spec or family) have these two Basic abilities: |
["Dash"] = 61684, |
["Growl"] = 2649, |
}, |
["Tenacity"] = { |
-- - Some pets Bite, some pets Claw and some pets Smack |
["Bite"] = 17253, |
["Claw"] = 16827, |
["Smack"] = 49966, |
-- Specialization ability |
["Survival of the Fittest"] = 272679, |
-- All Hunter pets (regardless of spec or family) have these two Basic abilities: |
["Dash"] = 61684, |
["Growl"] = 2649, |
}, |
["Cunning"] = { |
-- - Some pets Bite, some pets Claw and some pets Smack |
["Bite"] = 17253, |
["Claw"] = 16827, |
["Smack"] = 49966, |
-- Specialization ability |
["Master's Call"] = 53271, |
-- All Hunter pets (regardless of spec or family) have these two Basic abilities: |
["Dash"] = 61684, |
["Growl"] = 2649, |
}, |
-- We categorize Hunter Pet spells mainly by their specialiZations, but some pet |
-- families also have Special abilites. And yes, same-name diff-ID spells do occur. |
-- Spell types: Special, Bonus and Exotic |
-- NB: The comment "8.x" bellow denotes I checked the pet on wowhead.com (or ingame) |
-- during WoW 8.x, NOT that they were introduced only in WoW 8.x (though of course some |
-- were). |
["Basilisk"] = { -- 8.x |
["Petrifying Gaze"] = 263841, |
}, |
["Bat"] = { -- 8.x |
["Sonic Blast"] = 264263, |
}, |
["Bear"] = { -- 8.x |
["Rest"] = 94019, |
}, |
["Beetle"] = { -- 8.x |
["Harden Carapace"] = 90339, |
}, |
["Bird of Prey"] = { -- 8.x |
["Talon Rend"] = 263852, |
["Trick"] = 94022, |
}, |
["Blood Beast"] = { -- 8.1 |
["Blood Bolt"] = 288962, |
}, |
["Boar"] = { -- 8.x |
["Bristle"] = 263869, |
}, |
["Carrion Bird"] = { -- 8.x |
["Bloody Screech"] = 24423, |
}, |
["Cat"] = { -- 8.x |
["Catlike Reflexes"] = 263892, |
["Prowl"] = 24450, |
}, |
["Chimaera"] = { -- 8.x |
["Frost Breath"] = 54644, |
["Froststorm Breath"] = 92380, |
}, |
["Clefthoof"] = { -- 8.x |
["Thick Hide"] = 160057, |
["Blood of the Rhino"] = 280069, |
}, |
["Core Hound"] = { -- 8.x |
["Obsidian Skin"] = 263867, |
["Molten Hide"] = 159788, |
}, |
["Crab"] = { -- 8.x |
["Pin"] = 50245, |
}, |
["Crane"] = { -- 8.x |
["Chi-Ji's Tranquility"] = 264028, |
["Trick"] = 126259, |
}, |
["Crocolisk"] = { -- 8.x |
["Ankle Crack"] = 50433, |
}, |
["Devilsaur"] = { -- 8.x |
["Feast"] = 159953, |
["Monstrous Bite"] = 54680, |
}, |
["Direhorn"] = { -- 8.x |
["Gore"] = 263861, |
}, |
["Dog"] = { -- 8.x |
["Lock Jaw"] = 263423, |
}, |
["Dragonhawk"] ={ -- 8.x |
["Dragon's Guile"] = 263887, |
}, |
["Feathermane"] ={ -- 8.x |
["Feather Flurry"] = 263916, |
["Updraft"] = 160007, |
}, |
["Fox"] = { -- 8.x |
["Agile Reflexes"] = 160011, |
["Play"] = 90347, |
}, |
["Gorilla"] = { -- 8.x |
["Silverback"] = 263939, |
}, |
["Hydra"] = { -- 8.x |
["Acid Bite"] = 263863, |
}, |
["Hyena"] = { -- 8.x |
["Infected Bite"] = 263853, |
}, |
["Krolusk"] = { -- 8.x |
["Bulwark"] = 279410, |
}, |
["Lizard"] = { -- 8.x |
["Grievous Bite"] = 279362, |
}, |
["Mechanical"] = { -- 8.x |
["Defense Matrix"] = 263868, |
}, |
["Monkey"] = { -- 8.x |
["Primal Agility"] = 160044, |
}, |
["Moth"] = { -- 8.x |
["Serenity Dust"] = 264055, |
}, |
["Nether Ray"] = { -- 8.x |
["Nether Shock"] = 264264, |
}, |
["Oxen"] = { -- 8.x |
["Niuzao's Fortitude"] = 264023, |
}, |
["Pterrordax"] = { -- 8.x |
["Ancient Hide"] = 279399, |
["Updraft"] = 160007, |
}, |
["Quilen"] = { -- 8.x |
["Eternal Guardian"] = 267922, |
["Stone Armor"] = 160049, |
}, |
["Raptor"] = { -- 8.x |
["Savage Rend"] = 263854, |
}, |
["Ravager"] = { -- 8.x |
["Ravage"] = 263857, |
}, |
["Riverbeast"] = { -- 8.x |
["Gruesome Bite"] = 160018, |
}, |
["Rodent"] = { -- 8.x |
["Gnaw"] = 263856, |
["Rest"] = 126364, |
}, |
-- ["Rylak"] = { -- Rylak have been merged into Chimaera in 8.x |
-- ["Updraft"] = 160007, |
-- }, |
["Scalehide"] = { -- 8.x |
["Scale Shield"] = 263865, |
}, |
["Scorpid"] = { -- 8.x |
["Deadly Sting"] = 160060, |
}, |
["Serpent"] = { -- 8.x |
["Serpent's Swiftness"] = 263904, |
}, |
["Shale Spider"] = { -- 8.x |
["Solid Shell"] = 160063, |
}, |
["Silithid"] = { -- 8.x |
["Tendon Rip"] = 160065, |
["Dune Strider"] = 280151, |
}, |
["Spider"] = { -- 8.x |
["Web Spray"] = 160067, |
}, |
["Spirit Beast"] = { -- 8.x |
["Spirit Shock"] = 264265, |
["Spirit Mend"] = 90361, |
["Spirit Walk"] = 90328, |
}, |
["Sporebat"] = { -- 8.x |
["Spore Cloud"] = 264056, |
}, |
["Stag"] = { -- 8.x |
["Nature's Grace"] = 264266, |
}, |
["Tallstrider"] = { -- 8.x |
["Dust Cloud"] = 50285, |
}, |
["Toad"] = { -- 8.x |
["Swarm of Flies"] = 279336, |
}, |
["Turtle"] = { -- 8.x |
["Shell Shield"] = 26064, |
}, |
["Warp Stalker"] = { -- 8.x |
["Warp Time"] = 35346, |
}, |
["Wasp"] = { -- 8.x |
["Toxic Sting"] = 263858, |
}, |
["Water Strider"] = { -- 8.x |
["Soothing Water"] = 264262, |
["Surface Trot"] = 126311, |
}, |
["Wind Serpent"] = { -- 8.x |
["Winged Agility"] = 264360, |
}, |
["Wolf"] = { -- 8.x |
["Furious Bite"] = 263840, |
}, |
["Worm"] = { -- 8.x |
["Acid Spit"] = 263446, |
["Burrow Attack"] = 93433, |
}, |
}, |
}, |
["MAGE"] = { |
["Arcane"] = { |
["Polymorph Variants"] = 92, |
}, |
["Fire"] = { |
["Polymorph Variants"] = 92, |
}, |
["Frost"] = { |
["Polymorph Variants"] = 92, |
}, |
["FlyoutsTOGET"] = { |
["Polymorph Variants"] = 92, |
}, |
["Flyouts"] = { |
-- Polymorph Variants are now fetchable (all the ones currently ingame) from the game, |
-- regardless of whether the Mage has them or not (all, some, one or even none). |
-- BUT the Mage must have learned at least one Polymorph variant for us to fetch them |
-- normally; otherwise the "Polymorph Variants" flyout-button does not appear in the |
-- SpellBook. |
-- However, you can pass the Flyout-button ("Polymorph Variants")'s Spell ID to |
-- GetFlyoutSlotInfo(Flyout-SpellID, FlyoutSlot) and retrieve the variants even if the |
-- character has learned none of them yet. The Spell Id for Polymorph Variants is: 92. |
-- GetFlyoutSlotInfo() returns 5 values: |
-- 1. SpellID |
-- 2. SpellID again (same as in 1) |
-- 3. Unknown boolean |
-- 4. Spell name (e.g. "Polymorph") |
-- 5. Unknown number (0 for the first two slots of GetFlyoutSlotInfo(92, FlyoutSlot) |
-- Testing the above returned SpellID=61305 for GetFlyoutSlotInfo(92, 1). |
-- GetSpellInfo(61305) on a Mage with NO Polymorph variants learned, returns the correct |
-- information for Polymorph(Black Cat), as retrieved with this addon, on another |
-- Mage with one Polymorph variant learned. GetFlyoutSlotInfo(92, 2) on the ignorant |
-- Mage returns the spell ID for Polymorph(Monkey). |
-- TODO: Implement a way to fetch the Mage Polymorph Variants (as well as the Shaman Hex |
-- Variants), even if the character does not know any, by using the logic above (and |
-- bellow if needed). |
--[[ |
["Polymorph Variants"] = { -- Polymorph variants (including the default "Sheep") are |
-- all called "Polymorph" but, like the Shaman Hex, these |
-- spells do bear information about the variant's flavor |
-- via GetSpellInfo(), on its 2nd return value (spell |
-- "rank" / spell subname). This subname can be suffixed |
-- onto the spell name to specify the variant, as in e.g. |
-- "Polymorph(Sheep)". It can be passed as argument to |
-- GetSpellInfo() as well as the console/macro "/cast" |
-- command. |
-- Since WoW 8.0.1, the 2nd return value is now no longer |
-- guaranteed to be provided upon calling GetSpellInfo(). |
-- The value can however be retrieved via the new Spell |
-- Mixin API (that was introduced with that patch), after a |
-- delay. But the former use of"Polymorph(Sheep)" and etc |
-- as argument to GetSpellInfo(), or the "/cast" command, |
-- still works, with no need to explicitly use the new |
-- Spell Mixin API, as it did before. |
-- |
-- WoW build 29981 (8.1.5): The following were all fetched |
-- fetched from the server: |
["Polymorph(Black Cat)"] = 61305, |
["Polymorph(Bumblebee)"] = 277792, |
["Polymorph(Direhorn)"] = 277787, |
["Polymorph(Monkey)"] = 161354, |
["Polymorph(Peacock)"] = 161372, |
["Polymorph(Penguin)"] = 161355, |
["Polymorph(Pig)"] = 28272, |
["Polymorph(Polar Bear Cub)"] = 161353, |
["Polymorph(Porcupine)"] = 126819, |
["Polymorph(Rabbit)"] = 61721, |
["Polymorph(Serpent)"] = 61025, |
["Polymorph(Turkey)"] = 61780, |
["Polymorph(Turtle)"] = 28271, |
}, |
]]-- |
-- The 'Portal: ' and 'Teleport: ' flyouts have (mostly) different destinations for |
-- Alliance and for Horde Magi. Thus, we'll add them all here (incl. faction-shared): |
["Portal"] = { |
["Portal: Exodar"] = 32266, -- Alliance only |
["Portal: Stonard"] = 49361, -- Horde only |
["Portal: Undercity"] = 11418, -- Horde only |
["Portal: Vale of Eternal Blossoms(Alliance)"] = 132620, -- Added: "(Alliance)" |
["Portal: Vale of Eternal Blossoms(Horde)"] = 132626, -- Added: "(Horde)" |
["Ancient Portal: Dalaran"] = 120146, -- Dalaran Crater (way ABOVE it! -> FALL!) |
["Portal: Tol Barad(Alliance)"] = 88345, -- Added: "(Alliance)" |
["Portal: Tol Barad(Horde)"] = 88346, -- Added: "(Horde)" |
["Portal: Shattrath(Alliance)"] = 33691, -- Added: "(Alliance)" |
["Portal: Shattrath(Horde)"] = 35717, -- Added: "(Horde)" |
["Portal: Warspear"] = 176244, -- Horde only |
["Portal: Theramore"] = 49360, -- Alliance only |
["Portal: Thunder Bluff"] = 11420, -- Horde only |
["Portal: Darnassus"] = 11419, -- Alliance only |
["Portal: Silvermoon"] = 32267, -- Horde only |
["Portal: Dalaran - Northrend"] = 53142, |
["Portal: Stormwind"] = 10059, -- Alliance only |
["Portal: Stormshield"] = 176246, -- Alliance only |
["Portal: Dalaran - Broken Isles"] = 224871, |
["Portal: Orgrimmar"] = 11417, -- Horde only |
["Portal: Ironforge"] = 11416, -- Alliance only |
["Portal: Dalaran - Broken Isles"] = 224871, |
["Portal: Boralus"] = 281400, -- Alliance only |
["Portal: Dazar'alor"] = 281402, -- Horde only |
}, |
["Teleport"] = { |
["Teleport: Vale of Eternal Blossoms(Alliance)"] = 132621, -- Added: "(Alliance)" |
["Teleport: Vale of Eternal Blossoms(Horde)"] = 132627, -- Added: (Horde) |
["Teleport: Dalaran - Northrend"] = 53140, |
["Teleport: Shattrath(Alliance)"] = 33690, -- Added: "(Alliance)" |
["Teleport: Shattrath(Horde)"] = 35715, -- Added: "(Horde)" |
["Teleport: Stonard"] = 49358, -- Horde only |
["Teleport: Stormshield"] = 176248, -- Alliance only |
["Teleport: Darnassus"] = 3565, -- Alliance only |
["Teleport: Dalaran - Broken Isles"] = 224869, |
["Teleport: Stormwind"] = 3561, -- Alliance only |
["Teleport: Hall of the Guardian"] = 193759, -- Mage Class Hall |
["Teleport: Tol Barad(Alliance)"] = 88342, -- Added: "(Alliance)" |
["Teleport: Tol Barad(Horde)"] = 88344, -- Added: "(Horde)" |
["Teleport: Orgrimmar"] = 3567, -- Horde only |
["Teleport: Ironforge"] = 3562, -- Alliance only |
["Teleport: Warspear"] = 176242, -- Horde only |
["Teleport: Theramore"] = 49359, -- Alliance only |
["Teleport: Silvermoon"] = 32272, -- Horde only |
["Teleport: Undercity"] = 3563, -- Horde only |
["Ancient Teleport: Dalaran"] = 120145, -- Dalaran Crater (way ABOVE it! -> FALL!) |
["Teleport: Exodar"] = 32271, -- Alliance only |
["Teleport: Thunder Bluff"] = 3566, -- Horde only |
["Teleport: Boralus"] = 281403, -- Alliance only |
["Teleport: Dazar'alor"] = 281404, -- Horde only |
}, |
}, |
-- Get the Pets spell from a high level Frost Mage instead |
--[[ |
["Pets"] = { |
["Water Elemental"] = { -- Frost specialization only |
["Freeze"] = 33395, |
["Waterbolt"] = 31707, |
}, |
}, |
]]-- |
}, |
-- All Rogue Poisons are fetchable from the logged in character. The bellow is no longer needed. |
["ROGUE"] = { |
["Assassination"] = { |
["Poisons"] = 66, |
}, |
["Subtlety"] = { |
["Poisons"] = 66, |
}, |
["Outlaw"] = { |
["Poisons"] = 66, |
}, |
["FlyoutsTOGET"] = { |
["Poisons"] = 66, |
}, |
--[[ |
["Flyouts"] = { |
["Poisons"] = { -- Since WoW 7.0, (I think) Assassintation specialization only. But, at |
-- least on WoW 8.1.5, on the SpellBook of all three specializations. |
["Agonizing Poison"] = 200802, |
["Crippling Poison"] = 3408, |
["Deadly Poison"] = 2823, |
["Leeching Poison"] = 108211, |
["Wound Poison"] = 8679, |
}, |
}, |
]]-- |
}, |
["SHAMAN"] = { |
["Elemental"] = { |
["Bloodlust"] = 2825, -- Horde |
["Heroism"] = 32182, -- Alliance |
["Hex Variants"] = 106, |
}, |
["Enhancement"] = { |
["Bloodlust"] = 2825, -- Horde |
["Heroism"] = 32182, -- Alliance |
["Hex Variants"] = 106, |
}, |
["Restoration"] = { |
["Bloodlust"] = 2825, -- Horde |
["Heroism"] = 32182, -- Alliance |
["Hex Variants"] = 106, |
}, |
-- Hex Variants are now fetchable (all the ones currently ingame) from the game, |
-- regardless of whether the Shaman has them or not (all, some, one or even none). |
-- BUT the Shaman must have learned at least one Hex variant for us to fetch them |
-- normally; otherwise the "Hex Variants" flyout-button does not appear in the |
-- SpellBook. |
-- However, you can pass the Flyout-button ("Hex Variants")'s Spell ID to |
-- GetFlyoutSlotInfo(Flyout-SpellID, FlyoutSlot) and retrieve the variants even if the |
-- character has learned none of them yet. The Spell Id for Hex Variants is: 106. |
-- GetFlyoutSlotInfo() returns 5 values: |
-- 1. SpellID |
-- 2. SpellID again (same as in 1) |
-- 3. Unknown boolean |
-- 4. Spell name (e.g. "Hex") |
-- 5. Unknown number (0 for the first two slots of GetFlyoutSlotInfo(106, FlyoutSlot) |
-- Testing the above returned SpellID=210873 for GetFlyoutSlotInfo(106, 1). |
-- GetSpellInfo(210873) on a Shaman with NO Hex variants learned, returns the correct |
-- information for Hex(Compy), as retrieved with this addon, on another Shaman with |
-- some Hex variants learned. GetFlyoutSlotInfo(106, 2) on the ignorant Shaman returns |
-- the spell ID for Hex(Cockroach). |
-- TODO: Implement a way to fetch the Shaman Hex Variants (as well as the Mage Polymorph |
-- Variants), even if the character does not know any, by using the logic above (and |
-- bellow if needed). |
["FlyoutsTOGET"] = { |
["Hex Variants"] = 106, |
}, |
--[[ |
["Flyouts"] = { |
["Hex Variants"] = { -- Hex variants (including the default "Frog") are all |
-- called "Hex" but, (since WoW 8.1.5 or earlier) like the |
-- Mage Polymorph, these spells do bear information |
-- about the variant's flavor via GetSpellInfo(), on its |
-- 2nd return value (spell "rank" / spell subname). This |
-- subname can be suffixed onto the spell name to specify |
-- the variant, as in e.g. "Hex(Frog)". It can be passed as |
-- argument to GetSpellInfo() as well as the console/macro |
-- "/cast" command. |
-- Since WoW 8.0.1, the 2nd return value is now no longer |
-- guaranteed to be provided upon calling GetSpellInfo(). |
-- The value can however be retrieved via the new Spell |
-- Mixin API (that was introduced with that patch), after a |
-- delay. But the use of "Hex(Frog)" and etc as argument |
-- to GetSpellInfo(), or the "/cast" command, still works, |
-- with no need to explicitly use the new Spell Mixin API. |
["Hex(Cockroach)"] = 211015, |
["Hex(Compy)"] = 210873, |
["Hex(Skeletal Hatchling)"] = 269352, |
["Hex(Snake)"] = 211010, |
["Hex(Spider)"] = 211004, |
["Hex(Wicker Mongrel)"] = 277784, -- Alliance only |
["Hex(Zandalari Tendonripper)"] = 277778, -- Horde only |
}, |
}, |
]]-- |
["Pets"] = { -- In WoW 7.x.y, only the Elemental specialization has pets, which are only |
-- controllable if the talent "Primal Elementalist"(5,2) is active (they're |
-- guardians (no spells castable by the player) otherwise). On top of that, |
-- although the Earth Elemental is always available to the Elemental Shaman |
-- , the Fire and Storm elementals are mutually exclusive (Fire Elemental |
-- becomes Storm Elemental if the talent "Storm Elemental" is chosen). |
-- TL;DR: Better make sure the spells bellow are added, rather than going |
-- through the gimmick of swithcing the talents every time we update the |
-- SHAMAN lists of spells. |
["Earth Elemental"] = { |
["Angered Earth"] = 36213, -- Taunt |
["Harden Skin"] = 118337, -- -40% damage taken by the Shaman |
["Pulverize"] = 118345, -- Stun |
}, |
["Fire Elemental"] = { |
["Fire Blast"] = 57984, |
["Immolate"] = 118297, |
["Meteor"] = 117588, |
}, |
["Storm Elemental"] = { |
["Call Lightning"] = 157348, |
["Eye of the Storm"] = 157375, |
["Wind Gust"] = 157331, |
}, |
}, |
}, |
["WARLOCK"] = { |
["Affliction"] = { |
["Summon Demon"] = 10, |
}, |
["Demonology"] = { |
["Summon Demon"] = 10, |
}, |
["Destruction"] = { |
["Summon Demon"] = 10, |
}, |
["FlyoutsTOGET"] = { |
["Summon Demon"] = 10, |
}, |
["Pets"] = { -- Spells of the glyph-enhanced versions of the regular Warlock Demons. |
-- NB: We're including spells that remain the same on both versions of the |
-- demon. |
["Fel Imp"] = { |
["Felbolt"] = 115746, -- Fel Imp |
["Sear Magic"] = 115276, -- Fel Imp |
["Cauterize Master"] = 119905, -- Fel Imp & Imp |
["Flee"] = 89792, -- Fel Imp & Imp |
}, |
["Voidlord"] = { |
["Void Shield"] = 115236, -- Voidlord |
["Suffering"] = 119907, -- Voidlord & Voidwalker |
["Consuming Shadows"] = 3716, -- Voidlord & Voidwalker |
["Shadow Bulwark"] = 17767, -- Voidlord & Voidwalker |
["Threatening Presence"] = 134477, -- Voidlord & Voidwalker |
}, |
["Observer"] = { |
["Optical Blast"] = 115781, -- Observer |
["Tongue Lash"] = 115778, -- Observer |
["Devour Magic"] = 19505, -- Observer & Felhunter |
}, |
["Shivarra"] = { |
["Bladedance"] = 115748, -- Shivarra |
["Fellash"] = 115770, -- Shivarra |
["Mesmerize"] = 115268, -- Shivarra |
["Lesser Invisibility"] = 7870, -- Shivarra & Succubus |
}, |
["Wrathguard"] = { |
["Mortal Cleave"] = 115625, -- Wrathguard |
["Wrathstorm"] = 115831, -- Wrathguard |
["Axe Toss"] = 89766, -- Wrathguard & Felguard |
["Pursuit"] = 30151, -- Wrathguard & Felguard |
["Threatening Presence"] = 134477 -- Wrathguard & Felguard |
}, |
}, |
}, |
}; |
local postUpdate_Spells2Add_PASSIVES = { |
["General"] = { |
["Riding"] = { |
["Draenor Pathfinder"] = 191645, -- One rank only -- Flying -- USABLE |
["Apprentice Riding"] = 33388, |
["Broken Isles Pathfinder(Rank 1)"] = 226342, -- +20% mounted speed -- USABLE |
["Broken Isles Pathfinder(Rank 2)"] = 233368, -- Flying -- USABLE |
["Broken Isles Pathfinder"] = 233368, -- Flying -- USABLE |
["Expert Riding"] = 34090, |
["Journeyman Riding"] = 33391, |
["Artisan Riding"] = 34091, |
["Master Riding"] = 90265, |
["Battle for Azeroth Pathfinder"] = 281576, -- +20% mounted speed -- USABLE |
["Battle for Azeroth Pathfinder(Rank 1)"] = 281576, -- +20% mounted speed -- USABLE |
}, |
["ZoneAbilities"] = { |
-- Draenor |
["Dragoon"] = 169605, |
["Swift Recovery"] = 169608, |
["Trading Pact"] = 170200, |
["Upgrades"] = 170733, |
}, |
}, |
--[[ |
-- NB: See reason to no longer be hardcoding this in the Active Spells section above. |
["DEATHKNIGHT"] = { |
["Pets"] = { |
-- With talent 'Sludge Belcher': |
["Ghoul"] = { |
["Avoidance"] = 62137, |
}, |
-- The Unholy spec talent "Sludge Belcher" which summoned an Abomination instead of a |
-- Ghoul before 8.0.1 is no longer ingame. |
-- ["Abomination"] = { |
-- ["Avoidance"] = 62137, |
-- }, |
}, |
}, |
]]-- |
["HUNTER"] = { |
["Pets"] = { |
-- NB: The comment "8.x" bellow denotes I checked the pet on wowhead.com (or ingame) |
-- during WoW 8.x, NOT that they were introduced only in WoW 8.x (though of course some |
-- were). |
-- Specializations |
["Ferocity"] = { -- 8.x |
["Avoidance"] = 65220, -- Present on a lvl 14 Hunter |
["Predator's Thirst"] = 264663, -- Present on a lvl 14 Hunter |
}, |
["Tenacity"] = { -- 8.x |
["Avoidance"] = 65220, -- Present on a lvl 14 Hunter |
["Endurance Training"] = 264662, -- Present on a lvl 14 Hunter |
}, |
["Cunning"] = { -- 8.x |
["Avoidance"] = 65220, -- Present on a lvl 14 Hunter |
["Pathfinding"] = 264656, -- Present on a lvl 14 Hunter |
}, |
-- Families |
["Bear"] = { -- 8.x |
["Thick Fur"] = 263934, |
}, |
["Gorilla"] = { -- 8.x |
["Silverback"] = 263939, |
}, |
["Krolusk"] = { -- 8.x |
["Calcified Carapace"] = 279254, |
}, |
["Shale Spider"] = { -- 8.x |
["Shimmering Shale"] = 279259, |
}, |
}, |
}, |
["MAGE"] = { |
["Pets"] = { |
["Water Elemental"] = { -- Frost specialization only |
["Avoidance"] = 65220, |
}, |
}, |
}, |
["WARLOCK"] = { |
["Pets"] = { -- Spells of the glyph-enhanced versions of the regular Warlock Demons. |
-- NB: We're including spells that remain the same on both versions. |
["Fel Imp"] = { |
["Avoidance"] = 32233, -- Fel Imp & Imp |
}, |
["Voidlord"] = { |
["Avoidance"] = 32233, -- Voidlord & Voidwalker |
["Void Reflexes"] = 117225, -- Voidlord & Voidwalker |
}, |
["Observer"] = { |
["Avoidance"] = 32233, -- Observer & Felhunter |
}, |
["Shivarra"] = { |
["Avoidance"] = 32233, -- Shivarra & Succubus |
}, |
["Wrathguard"] = { |
["Avoidance"] = 32233, -- Wrathguard & Felguard |
["Void Reflexes"] = 117225, -- Wrathguard & Felguard |
}, |
}, |
}, |
}; |
-- Functions to store information about the dataSource (how up to date it is) and other metadata -- |
---------------------------------------------------------------------------------------------------- |
-- Update the General tab dataSource + raceBuilds -- |
local updateGeneralTabMetadata_func = function(curLocale, gameBuild, charLevel) |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updateGeneralTabMetadata_func: START"); |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": Check whether GeneralTab\'s Metadata needs update"); |
if not updateGeneralTabMetadata then |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": GeneralTab\'s Metadata does NOT need update."); |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updateGeneralTabMetadata_func: END"); |
return; |
end |
tinsert(DEBUGmsgs[DBG_CurrentEvent], "GeneralTab\'s Metadata DOES need update."); |
-- print(AddonName.. ": Will now check whether the GeneralTab Metadata needs updating."); |
-- Actively-cast spells |
if charLevel > SN2SID_table[generalTabName].METADATA.dataSource.charLevel then |
SN2SID_table[generalTabName].METADATA.dataSource.charLevel = charLevel; |
if charLevel > SN2SID_table[generalTabName].METADATA.dataSource.charMaxLevel then |
SN2SID_table[generalTabName].METADATA.dataSource.charMaxLevel = charLevel; |
end |
updateGeneralSpells = true; |
end |
if gameBuild > SN2SID_table[generalTabName].METADATA.dataSource.gameBuild then |
SN2SID_table[generalTabName].METADATA.dataSource.gameBuild = gameBuild; |
-- Highest charLevel stored upon the most recent gameBuild |
SN2SID_table[generalTabName].METADATA.dataSource.charLevel = charLevel; |
-- Highest charLevel ever stored is kept in [...].charMaxLevel |
updateGeneralSpells = true; |
end |
if (not SN2SID_table[generalTabName].METADATA.raceBuilds[universalRaceName]) or |
(gameBuild > SN2SID_table[generalTabName].METADATA.raceBuilds[universalRaceName]) then |
SN2SID_table[generalTabName].METADATA.raceBuilds[universalRaceName] = gameBuild; |
updateGeneralSpells = true; |
end |
-- Passive spells |
if charLevel > SN2SID_PASSIVES_table[generalTabName].METADATA.dataSource.charLevel then |
SN2SID_PASSIVES_table[generalTabName].METADATA.dataSource.charLevel = charLevel; |
if charLevel > SN2SID_PASSIVES_table[generalTabName].METADATA.dataSource.charMaxLevel then |
SN2SID_PASSIVES_table[generalTabName].METADATA.dataSource.charMaxLevel = charLevel; |
end |
updateGeneralSpells = true; |
end |
if gameBuild > SN2SID_PASSIVES_table[generalTabName].METADATA.dataSource.gameBuild then |
SN2SID_PASSIVES_table[generalTabName].METADATA.dataSource.gameBuild = gameBuild; |
-- Highest charLevel stored upon the most recent gameBuild |
SN2SID_PASSIVES_table[generalTabName].METADATA.dataSource.charLevel = charLevel; |
-- Highest charLevel ever stored is kept in [...].charMaxLevel |
updateGeneralSpells = true; |
end |
if (not SN2SID_PASSIVES_table[generalTabName].METADATA.raceBuilds[universalRaceName]) or |
(gameBuild > SN2SID_PASSIVES_table[generalTabName].METADATA.raceBuilds[universalRaceName]) then |
SN2SID_PASSIVES_table[generalTabName].METADATA.raceBuilds[universalRaceName] = gameBuild; |
updateGeneralSpells = true; |
end |
updateGeneralTabMetadata = false; |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updateGeneralTabMetadata_func: END"); |
end |
-- Update the Class dataSource -- |
local updateClassMetadata_func = function(curLocale, gameBuild, charLevel) |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updateClassMetadata_func: START"); |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": Check whether ".. universalClassName.. "\'s Metadata needs update."); |
if not updateClassMetadata then |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": ".. universalClassName.. "\'s Metadata does NOT need update."); |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updateClassMetadata_func: END"); |
return; |
end |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": ".. universalClassName.. "\'s Metadata DOES need update."); |
-- print(AddonName.. ": Will now check whether the ".. universalClassName.. " Metadata needs updating."); |
-- Actively-cast spells |
if charLevel > SN2SID_table[universalClassName].METADATA.dataSource.charLevel then |
SN2SID_table[universalClassName].METADATA.dataSource.charLevel = charLevel; |
if charLevel > SN2SID_table[universalClassName].METADATA.dataSource.charMaxLevel then |
SN2SID_table[universalClassName].METADATA.dataSource.charMaxLevel = charLevel; |
end |
updateClassSpells = true; |
end |
if gameBuild > SN2SID_table[universalClassName].METADATA.dataSource.gameBuild then |
SN2SID_table[universalClassName].METADATA.dataSource.gameBuild = gameBuild; |
SN2SID_table[universalClassName].METADATA.dataSource.charLevel = charLevel; |
updateClassSpells = true; |
end |
-- Passive spells |
if charLevel > SN2SID_PASSIVES_table[universalClassName].METADATA.dataSource.charLevel then |
SN2SID_PASSIVES_table[universalClassName].METADATA.dataSource.charLevel = charLevel; |
if charLevel > SN2SID_PASSIVES_table[universalClassName].METADATA.dataSource.charMaxLevel then |
SN2SID_PASSIVES_table[universalClassName].METADATA.dataSource.charMaxLevel = charLevel; |
end |
updateClassSpells = true; |
end |
if gameBuild > SN2SID_PASSIVES_table[universalClassName].METADATA.dataSource.gameBuild then |
SN2SID_PASSIVES_table[universalClassName].METADATA.dataSource.gameBuild = gameBuild; |
SN2SID_PASSIVES_table[universalClassName].METADATA.dataSource.charLevel = charLevel; |
updateClassSpells = true; |
end |
updateClassMetadata = false; |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updateClassMetadata_func: END"); |
end |
---- Functions to update the lists of Spell Names and their IDs ---- |
-------------------------------------------------------------------- |
-- Update the PvE Talents' lists of spells |
local updateTalentSpells_func = function(ClassNumSpecs, ClassSpecNames2IDs) |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updateTalentSpells_func: START"); |
if not updateClassSpells then -- Sanity check |
return; |
end |
for i = 1, ClassNumSpecs do |
-- Create "SpecName_Talents" subtables if they doesn't exist yet |
local specID, locSpecName = GetSpecializationInfo(i); |
if locSpecName then -- Sanity check |
-- print(AddonName.. ": locSpecName = ".. locSpecName); |
-- Actives |
-- if not SN2SID_table[universalClassName][locSpecName.."_Talents"] then |
-- SN2SID_table[universalClassName][locSpecName.."_Talents"] = {}; |
-- end |
-- Passives |
-- if not SN2SID_PASSIVES_table[universalClassName][locSpecName.."_Talents"] then |
-- SN2SID_PASSIVES_table[universalClassName][locSpecName.."_Talents"] = {}; |
-- end |
else |
-- print(AddonName.. ": PVE: NO specialization has been selected for this character!"); |
return; |
end |
-- Populate the "SpecName_Talents" subtables |
for ii = 1, NumberOfTalentTiers do |
for iii = 1, 3 do |
local _, spellName, _, _, _, spellID, _, _, _, _, _ = GetTalentInfoBySpecialization(i, ii, iii); |
if spellName then |
if IsPassiveSpell(spellID) then |
if SN2SID_PASSIVES_table[universalClassName][locSpecName.."_Talents"] then |
SN2SID_PASSIVES_table[universalClassName][locSpecName.."_Talents"][spellName] = spellID; |
else |
SN2SID_PASSIVES_table[universalClassName][locSpecName.."_Talents"] = { [spellName] = spellID, }; |
end |
else |
if SN2SID_table[universalClassName][locSpecName.."_Talents"] then |
SN2SID_table[universalClassName][locSpecName.."_Talents"][spellName] = spellID; |
else |
SN2SID_table[universalClassName][locSpecName.."_Talents"] = { [spellName] = spellID, }; |
end |
end |
end |
end |
end |
-- NB: There is NO WAY to store a key-value pairs table of non-integer keys in ordered/ |
-- sorted mode in Lua. |
-- At most, you could extract all keys and sort them in an array-like table (NO PAIRS!), |
-- and then fetch the keys in order from that array-table and then the corresponding values |
-- from another tab le (the original, unordered/unsorted key-value pairs table). |
-- The function from https://wow.gamepedia.com/Orderedpairs gets you the ordered values |
-- from the unordered table in running-time, but cannot be used to change the stored data, |
-- just like the extract-keys-then-sort-them method above. |
-- Thus, it's not possible to store the data in an easy to visually (or OS-based) diff two |
-- versions of a database, as I wished. |
end |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updateTalentSpells_func: END"); |
end |
-- Update the PvP Talents' lists of spells |
local updatePVPTalentSpells_func = function(ClassNumSpecs, ClassSpecNames2IDs) |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updatePVPTalentSpells_func: START"); |
if not updateClassSpells then -- Sanity check |
return; |
end |
for i = 1, ClassNumSpecs do |
-- Create "SpecName_PVPTalents" subtables if they don't exist yet |
local specID, locSpecName = GetSpecializationInfo(i); |
if locSpecName then -- Sanity check |
-- print(AddonName.. ": locSpecName = ".. locSpecName); |
-- Actives |
if not SN2SID_table[universalClassName][locSpecName.."_PVPTalents"] then |
SN2SID_table[universalClassName][locSpecName.."_PVPTalents"] = {}; |
end |
-- Passives |
if not SN2SID_PASSIVES_table[universalClassName][locSpecName.."_PVPTalents"] then |
SN2SID_PASSIVES_table[universalClassName][locSpecName.."_PVPTalents"] = {}; |
end |
else |
-- print(AddonName.. ": PVP: NO specialization has been selected for this character!"); |
return; |
end |
-- Populate the "SpecName_PVPTalents" subtables |
for ii = 1, NumberOfPVPTalentSlots do |
local talentOptions = C_SpecializationInfo.GetPvpTalentSlotInfo(ii).availableTalentIDs; |
for iii = 1, #talentOptions do |
-- local _, spellName, _, _, _, spellID, _, _, _, _, _ = GetPvpTalentInfoBySpecialization(i, ii, iii); |
local talentID = talentOptions[iii]; |
local _, spellName, _, _, _, spellID, _, _, _, _, _ = GetPvpTalentInfoByID(talentID); |
-- print(AddonName.. ": PVPTalent spellName = ".. tostring(spellName)); |
if spellName then |
if IsPassiveSpell(spellID) then |
SN2SID_PASSIVES_table[universalClassName][locSpecName.."_PVPTalents"][spellName] = spellID; |
else |
SN2SID_table[universalClassName][locSpecName.."_PVPTalents"][spellName] = spellID; |
end |
end |
end |
end |
end |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updatePVPTalentSpells_func: END"); |
end |
local armorSkills, weaponSkills; |
-- Helper functions to function updateSpellbookSpells_func() -- |
local addSpellbookSpellToGeneral_func = function(spellName, spellSubName, spellID) |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": addSpellbookSpellToGeneral_func: START"); |
-- Store Passive and Active abilities into their own separate tables |
if IsPassiveSpell(spellID) then |
if spellName == "Armor Skills" then |
armorSkills = spellID; |
elseif spellName == "Weapon Skills" then |
weaponSkills = spellID; |
elseif strfind(spellName, "Riding") or strfind(spellName, "Pathfinder") then |
if not SN2SID_PASSIVES_table[generalTabName].Riding then |
SN2SID_PASSIVES_table[generalTabName].Riding = { [spellName] = spellID }; |
else |
SN2SID_PASSIVES_table[generalTabName].Riding[spellName] = spellID; |
end |
-- NB: See "NB" for non-passive spells bellow |
elseif spellSubName and strfind(spellSubName, "Racial") then |
if not SN2SID_PASSIVES_table[generalTabName].Racials[universalRaceName] then |
SN2SID_PASSIVES_table[generalTabName].Racials[universalRaceName] = { [spellName] = spellID }; |
else |
SN2SID_PASSIVES_table[generalTabName].Racials[universalRaceName][spellName] = spellID; |
end |
elseif spellSubName and strfind(spellSubName, "Guild") then |
if not SN2SID_PASSIVES_table[generalTabName].GuildPerks then |
SN2SID_PASSIVES_table[generalTabName].GuildPerks = { [spellName] = spellID }; |
else |
SN2SID_PASSIVES_table[generalTabName].GuildPerks[spellName] = spellID; |
end |
-- Will now test for the hardcoded ZoneAbilities, to place them in the correct subcategory |
elseif postUpdate_Spells2Add_PASSIVES.General.ZoneAbilities[spellName] then |
if not SN2SID_table[generalTabName].ZoneAbilities then |
SN2SID_PASSIVES_table[generalTabName].ZoneAbilities = { [spellName] = spellID }; |
else |
SN2SID_PASSIVES_table[generalTabName].ZoneAbilities[spellName] = spellID; |
end |
-- All other spells go into the "Others" subcategory |
elseif not SN2SID_PASSIVES_table[generalTabName].Others then |
SN2SID_PASSIVES_table[generalTabName].Others = { [spellName] = spellID }; |
else |
SN2SID_PASSIVES_table[generalTabName].Others[spellName] = spellID; |
end |
else |
-- NB: Switched the order of checks: Before, we were checking for the presence of the spell |
-- in our list of hardcoded Zone spells first. Now, we do that test last, as there is at |
-- least one instance of a spell with the same name, but different IDs, that is a Racial |
-- (that we fetch from the server) and also a hardcoded Zone ability: "Light's Judgment". |
if spellSubName and strfind(spellSubName, "Racial") then |
if not SN2SID_table[generalTabName].Racials[universalRaceName] then |
SN2SID_table[generalTabName].Racials[universalRaceName] = { [spellName] = spellID }; |
else |
SN2SID_table[generalTabName].Racials[universalRaceName][spellName] = spellID; |
end |
elseif spellSubName and strfind(spellSubName, "Guild") then |
if not SN2SID_table[generalTabName].GuildPerks then |
SN2SID_table[generalTabName].GuildPerks = { [spellName] = spellID }; |
else |
SN2SID_table[generalTabName].GuildPerks[spellName] = spellID; |
end |
-- Will now test for the hardcoded ZoneAbilities, to place them in the correct subcategory |
elseif postUpdate_Spells2Add.General.ZoneAbilities[spellName] then |
if not SN2SID_table[generalTabName].ZoneAbilities then |
SN2SID_table[generalTabName].ZoneAbilities = { [spellName] = spellID }; |
else |
SN2SID_table[generalTabName].ZoneAbilities[spellName] = spellID; |
end |
-- All other spells go into the "Others" subcategory |
elseif not SN2SID_table[generalTabName].Others then |
SN2SID_table[generalTabName].Others = { [spellName] = spellID }; |
else |
SN2SID_table[generalTabName].Others[spellName] = spellID; |
end |
end |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": addSpellbookSpellToGeneral_func: END"); |
end |
local addPolymorphOrHexFlyoutSpell_func = function(flyoutButton, flyoutSpellName, flyoutSpellSubname, flyoutSpellID) |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": addPolymorphOrHexFlyoutSpell_func: START"); |
local flyoutSpellFullName = flyoutSpellName.. "(".. flyoutSpellSubname.. ")"; |
if not SN2SID_table[universalClassName].Flyouts[flyoutButton][flyoutSpellFullName] |
or SN2SID_table[universalClassName].Flyouts[flyoutButton][flyoutSpellFullName] ~= flyoutSpellID then |
-- print(AddonName.. "Adding flyout spellFullName ".. flyoutSpellFullName.. " = ".. flyoutSpellID); |
SN2SID_table[universalClassName].Flyouts[flyoutButton][flyoutSpellFullName] = flyoutSpellID; |
end |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": addPolymorphOrHexFlyoutSpell_func: END"); |
end |
local addFlyoutSpells_func = function(flyoutButtonName, flyoutButtonID) |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": addFlyoutSpells_func: START"); |
-- print(AddonName.. ": SpellID ".. flyoutButtonID.. " on SpecTab ".. i.. ", Pos ".. ii.. " is a FLYOUT button."); |
-- NB: Creating SN2SID_table[universalClassName].Flyouts either via |
-- SN2SID_table[universalClassName].Flyouts = []; or via |
-- tinsert(SN2SID_table[universalClassName], "Flyouts"); was causing a bug where the same |
-- table would have two "Flyouts" fields: one with the correct values and another empty |
-- (as if it were a simple member of an array). So we create a STUB value if needed and |
-- later remove it when we're done adding the spells. |
if not SN2SID_table[universalClassName].Flyouts then |
SN2SID_table[universalClassName].Flyouts = { ["STUB"] = 0, }; |
end |
if (flyoutButtonName == "Portal") or (flyoutButtonName == "Teleport") then |
-- There are spells with the same Name but different IDs, depending on the |
-- character's faction, when it comes to Portals and Teleports. Hence, for now, |
-- we add them only in Post. TODO: Fetch them here as well, but check that they |
-- are not one of those (known) smae-name, diff-IDs cases (in that case do not add |
-- them here, only in post). |
else |
-- Insert the flyout spell in its proper table |
if not SN2SID_table[universalClassName].Flyouts[flyoutButtonName] then |
-- print(AddonName.. ": Adding Flyouts.".. flyoutButtonName.. " to ".. universalClassName); |
SN2SID_table[universalClassName].Flyouts[flyoutButtonName] = { ["STUB"] = 0, }; |
-- else |
-- print(AddonName.. ": Flyouts.".. flyoutButtonName.. " is already in ".. universalClassName); |
end |
local _, _, numFlyouts, flyoutKnown = GetFlyoutInfo(flyoutButtonID); |
-- print(AddonName.. ": ".. flyoutButtonName.. " | ".. flyoutButtonID.. " | Number of Slots = ".. numFlyouts); |
for flyoutSlot = 1, numFlyouts do |
-- local flyoutSpellID, overrideSpellID, flyoutSlotKnown, slotSpecID = GetFlyoutSlotInfo(flyoutButtonID, flyoutSlot); |
local flyoutSpellID, _, _, _ = GetFlyoutSlotInfo(flyoutButtonID, flyoutSlot); |
local flyoutSpellName, flyoutSpellSubname, _, _, _, _, _ = GetSpellInfo(flyoutSpellID); |
if flyoutButtonName == "Polymorph Variants" or flyoutButtonName == "Hex Variants" then |
-- Mage "Polymorph Variants", and Shaman "Hex Variants", |
-- are all called "Polymorph" or "Hex", respectively. But |
-- they have a subname specifying the variant AND can be |
-- addressed by suffixing the subname in parenthesis, as |
-- in e.g. "Polymorph(Sheep)" or "Hex(Frog)". We'll do just |
-- that and store their names as "name(subname)". |
if (flyoutSpellSubname == nil) or (flyoutSpellSubname == "") then |
-- print(AddonName.. ": ".. tostring(flyoutSpellName).. " = ".. tostring(flyoutSpellID)); |
-- TODO #1: Make a table, LOCAL-TO-FILE, to store |
-- all the delayedFlyoutSpellInfo tables amd name |
-- each one "delayedFlyoutSpellInfo"..flyoutSpellID . |
-- Create an access to the info that will be fetched |
local delayedFlyoutSpellInfo = Spell:CreateFromSpellID(flyoutSpellID); |
-- Actually get the info and use it to update our DB |
delayedFlyoutSpellInfo:ContinueOnSpellLoad(function() |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": delayedFlyoutSpellInfo:ContinueOnSpellLoad: START"); |
-- print(AddonName.. ": Will now get the previously delayed information about flyoutSpellID: ".. flyoutSpellID); |
-- Although we should only need to update spellSubName, we might |
-- have fetched a new spellName + spellID by now. Thus, we'll |
-- update those fields too. |
-- TODO #2: Pass the three |
-- "delayedFlyoutSpellInfo"..flyoutSpellID:Some() |
-- values bellow as arguments to |
-- addPolymorphOrHexFlyoutSpell_func(...) |
flyoutSpellName = delayedFlyoutSpellInfo:GetSpellName(); |
flyoutSpellSubname = delayedFlyoutSpellInfo:GetSpellSubtext(); -- Mandatory |
flyoutSpellID = delayedFlyoutSpellInfo:GetSpellID(); |
addPolymorphOrHexFlyoutSpell_func(flyoutButtonName, flyoutSpellName, flyoutSpellSubname, flyoutSpellID); |
-- TODO #3: Clean up! I.e.: |
-- SaidMasterTable["delayedFlyoutSpellInfo"..flyoutSpellID] = nil; |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": delayedFlyoutSpellInfo:ContinueOnSpellLoad: END"); |
end); |
else |
-- print(AddonName.. ": ".. tostring(flyoutSpellName).. " = ".. tostring(flyoutSpellID)); |
addPolymorphOrHexFlyoutSpell_func(flyoutButtonName, flyoutSpellName, flyoutSpellSubname, flyoutSpellID); |
end |
-- Add the default Plymorph(Sheep) and Hex(Frog) to the spell lists |
if universalClassName == MAGE then |
SN2SID_table.MAGE.Arcane["Polymorph(Sheep)"] = SN2SID_table.MAGE.Arcane["Polymorph"] or nil; |
SN2SID_table.MAGE.Fire["Polymorph(Sheep)"] = SN2SID_table.MAGE.Fire["Polymorph"] or nil; |
SN2SID_table.MAGE.Frost["Polymorph(Sheep)"] = SN2SID_table.MAGE.Frost["Polymorph"] or nil; |
end |
if universalClassName == SHAMAN then |
SN2SID_table.SHAMAN.Elemental["Hex(Frog)"] = SN2SID_table.SHAMAN.Elemental["Hex"] or nil; |
SN2SID_table.SHAMAN.Enhancement["Hex(Frog)"] = SN2SID_table.SHAMAN.Enhancement["Hex"] or nil; |
SN2SID_table.SHAMAN.Restoration["Hex(Frog)"] = SN2SID_table.SHAMAN.Restoration["Hex"] or nil; |
end |
elseif flyoutSpellName and (not SN2SID_table[universalClassName].Flyouts[flyoutButtonName][flyoutSpellName]) |
or flyoutSpellName and (SN2SID_table[universalClassName].Flyouts[flyoutButtonName][flyoutSpellName] ~= flyoutSpellID) then |
-- print(AddonName.. ": ".. tostring(flyoutSpellName).. " = ".. tostring(flyoutSpellID)); |
SN2SID_table[universalClassName].Flyouts[flyoutButtonName][flyoutSpellName] = flyoutSpellID; |
end |
end |
SN2SID_table[universalClassName].Flyouts[flyoutButtonName]["STUB"] = nil; |
end |
-- Get rid of the STUB table member that was added upon its creation |
SN2SID_table[universalClassName].Flyouts["STUB"] = nil; |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": addFlyoutSpells_func: END"); |
end |
-- -- |
-- Update the Spellbook's GeneralTab and ClassTabs lists of spells |
local updateSpellbookSpells_func = function(ClassNumSpecs, ClassSpecNames2IDs) |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updateSpellbookSpells_func: START"); |
-- "Armor Skills" and "Weapon Skills" are found on the Spellbook's General tab, but are indeed |
-- different from one class to the other. Therefore, we'll save them into local variables upon |
-- fetching the General tab spells and then insert them into the Class Specialisations' tables. |
-- local armorSkills, weaponSkills; |
-- General tab spells |
-- if updateGeneralSpells then -- In current addon version, always true |
local stubVal; |
stubVal, universalRaceName = UnitRace("player"); |
if not SN2SID_table[generalTabName].Racials then |
SN2SID_table[generalTabName].Racials = {}; |
end |
if not SN2SID_PASSIVES_table[generalTabName].Racials then |
SN2SID_PASSIVES_table[generalTabName].Racials = {}; |
end |
if not SN2SID_PASSIVES_table[generalTabName].Riding then |
SN2SID_PASSIVES_table[generalTabName].Riding = {}; |
end |
if not SN2SID_table[generalTabName].GuildPerks then |
SN2SID_table[generalTabName].GuildPerks = {}; |
end |
if not SN2SID_PASSIVES_table[generalTabName].GuildPerks then |
SN2SID_PASSIVES_table[generalTabName].GuildPerks = {}; |
end |
if not SN2SID_table[generalTabName].Others then |
SN2SID_table[generalTabName].Others = {}; |
end |
if not SN2SID_PASSIVES_table[generalTabName].Others then |
SN2SID_PASSIVES_table[generalTabName].Others = {}; |
end |
generalTabName, _, offset, numEntries, _, _, _ = GetSpellTabInfo(1); |
-- name, texture, offset, numEntries, isGuild, offspecID = GetSpellTabInfo(tabIndex) |
for i = offset +1, offset +numEntries do |
local spellName, spellSubName = GetSpellBookItemName(i, BOOKTYPE_SPELL); |
if spellName then |
local _, spellID = GetSpellBookItemInfo(i, BOOKTYPE_SPELL); |
if (spellSubName == nil) or (spellSubName == "") then |
local delayedSpellInfo = Spell:CreateFromSpellID(spellID); |
-- I presume we don't actually need to cancel the request for the additional |
-- information, i.e. presume once the information is given to us through the |
-- function delayedSpellInfo:ContinueOnSpellLoad(), there will be no further |
-- activity regarding this- But, just in case, we'll set up a function to |
-- cancel the request after we got the information we need. |
-- |
-- RESULT: The request-cancel function is being run BEFORE the requestFulfilled |
-- one! But it's still storing the value NO PROB AT ALL! So, maybe we can just |
-- do the whole add-spell-to-DB thing upon request cancelation? TODO: TRY IT! |
-- |
-- FURTHER TESTING: Using only :ContinueWithCancelOnSpellLoad(), without |
-- :ContinueOnSpellLoad(), does work. But the only spells added this way seem |
-- to be spells that don't actually have a Spell Subname (with the eventual |
-- exception of "Passive" spells). It would therefore seem we (usually?) get |
-- every spell's subname from GetSpellBookItemName(). So, this test is not |
-- conclusive. :-( |
-- Better revert this to have both :ContinueWithCancelOnSpellLoad() and |
-- ContinueOnSpellLoad() be run; ContinueOnSpellLoad() is run anyway after |
-- ContinueWithCancelOnSpellLoad, so it should be alright... ? |
-- |
-- MORE TESTING: With the 'Cache' folder and the saved variables' file deleted, |
-- the results are the same (with calling only :ContinueWithCancelOnSpellLoad() |
-- w/ no call to :ContinueOnSpellLoad() ). I will (again) revert to using both |
-- functions, for the sake of safity. |
-- |
-- local spellDataLoadedCancelFunc = delayedSpellInfo:ContinueWithCancelOnSpellLoad(function() |
-- We don't need to do anything upon canceling the request |
-- print(AddonName.. ": Now cancelling the request for delayed information about spell ID: ".. spellID); |
-- end); |
-- Actually get the information and use it to update our database: |
delayedSpellInfo:ContinueOnSpellLoad(function() |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": delayedSpellInfo:ContinueOnSpellLoad: START"); |
-- print(AddonName.. ": Will now get the previously delayed information about spell ID: ".. spellID); |
-- Although we should only need to update spellSubName, we might |
-- have fetched a new spellName + spellID by now. Thus, we'll |
-- update those fields too. |
spellName = delayedSpellInfo:GetSpellName(); |
spellSubName = delayedSpellInfo:GetSpellSubtext(); -- Mandatory |
spellID = delayedSpellInfo:GetSpellID(); |
addSpellbookSpellToGeneral_func(spellName, spellSubName, spellID); |
-- Now cancel the request: |
-- spellDataLoadedCancelFunc(); |
-- spellDataLoadedCancelFunc = nil; -- for safety! |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": delayedSpellInfo:ContinueOnSpellLoad: END"); |
end); |
--[[ |
local spellDataLoadedCancelFunc = delayedSpellInfo:ContinueWithCancelOnSpellLoad(function() |
-- We don't need to do anything upon canceling the request |
-- print(AddonName.. ": Now cancelling the request for delayed information about spell ID: ".. spellID); |
-- Although we should only need to update spellSubName, we might |
-- have fetched a new spellName + spellID by now. Thus, we'll |
-- update those fields too. |
spellName = delayedSpellInfo:GetSpellName(); |
spellSubName = delayedSpellInfo:GetSpellSubtext(); -- Mandatory |
spellID = delayedSpellInfo:GetSpellID(); |
addSpellbookSpellToGeneral_func(spellName, spellSubName, spellID); |
spellDataLoadedCancelFunc = nil; -- for safety! |
end); |
]]-- |
else |
addSpellbookSpellToGeneral_func(spellName, spellSubName, spellID); |
end |
-- -- |
end |
end |
-- end |
-- Class spells |
-- if updateClassSpells then |
-- updateTalentSpells_func(SN2SID_table, SN2SID_PASSIVES_table, universalClassName, ClassNumSpecs, ClassSpecNames2IDs); |
-- updateTalentSpells_func(universalClassName, ClassNumSpecs, ClassSpecNames2IDs); |
updateTalentSpells_func(ClassNumSpecs, ClassSpecNames2IDs); |
-- updatePVPTalentSpells_func(SN2SID_table, SN2SID_PASSIVES_table, universalClassName, ClassNumSpecs, ClassSpecNames2IDs); |
updatePVPTalentSpells_func(ClassNumSpecs, ClassSpecNames2IDs); |
for i = 2, (ClassNumSpecs +1) do |
-- Get the current tab's first spell's index, total number of spells therein and specID |
local _, _, offset, numEntries, _, _, _, specID = GetSpellTabInfo(i); |
if specID then -- Sanity check |
local _, locSpecName = GetSpecializationInfoByID(specID); |
--- Create SpecName subtables and SpecName_Talents subtables if they doesn't exist yet |
if locSpecName then -- Sanity check |
if not SN2SID_table[universalClassName][locSpecName] then |
SN2SID_table[universalClassName][locSpecName] = {}; |
end |
if not SN2SID_PASSIVES_table[universalClassName][locSpecName] then |
SN2SID_PASSIVES_table[universalClassName][locSpecName] = {}; |
end |
end |
-- Populate |
-- print(AddonName.. ": numEntries = ".. numEntries); |
for ii = offset +1, offset +numEntries do |
-- local spellName, spellSubName = GetSpellBookItemName(ii, BOOKTYPE_SPELL); |
local spellName = (GetSpellBookItemName(ii, BOOKTYPE_SPELL)); |
-- We actually don't use spellSubName on the population of the Class-spells list |
-- (or at least currently we don't) ; thus we don't need to use the SpellMixin |
-- API to retrieve it later; I.e. in this for loop, spellSubName is a stub val. |
if spellName then |
local spellType, spellID = GetSpellBookItemInfo(ii, BOOKTYPE_SPELL); |
-- Store Passive and Active abilities into their own separate tables IF they |
-- are not already stored in the respective Talents' tables. |
if IsPassiveSpell(spellID) and ((not SN2SID_PASSIVES_table[universalClassName][locSpecName.."_Talents"]) |
or (not SN2SID_PASSIVES_table[universalClassName][locSpecName.."_Talents"][spellName])) then |
-- print(AddonName.. ": Will add Passive: ".. spellName.. " / ID: ".. spellID); |
if not SN2SID_PASSIVES_table[universalClassName][locSpecName] then |
SN2SID_PASSIVES_table[universalClassName][locSpecName] ={ [spellName] = spellID, }; |
else |
SN2SID_PASSIVES_table[universalClassName][locSpecName][spellName] = spellID; |
end |
elseif (not SN2SID_table[universalClassName][locSpecName.."_Talents"]) |
or (not SN2SID_table[universalClassName][locSpecName.."_Talents"][spellName]) then |
-- print(AddonName.. ": Will add: ".. spellName.. " / ID: ".. spellID); |
if not SN2SID_table[universalClassName][locSpecName] then |
SN2SID_table[universalClassName][locSpecName] = { [spellName] = spellID, }; |
else |
SN2SID_table[universalClassName][locSpecName][spellName] = spellID; |
end |
end |
-- If it's a Flyout type of button (e.g. Mage Polymorph variants, Hunter Pet |
-- Utility spells, etc), then fetch the spells that ... fly out. |
if spellType == "FLYOUT" then |
addFlyoutSpells_func(spellName, spellID); |
--[[ |
-- print(AddonName.. ": SpellID ".. spellID.. " on SpecTab ".. i.. ", Pos ".. ii.. " is a FLYOUT button."); |
-- NB: Creating SN2SID_table[universalClassName].Flyouts either via |
-- SN2SID_table[universalClassName].Flyouts = []; or via |
-- tinsert(SN2SID_table[universalClassName], "Flyouts"); was causing |
-- a bug where the same table would have two "Flyouts" fields: one with |
-- the correct values and another empty (as if it were a simple member |
-- of an array). So we create a STUB value if needed and later remove |
-- it when we're done adding the spells. |
if not SN2SID_table[universalClassName].Flyouts then |
SN2SID_table[universalClassName].Flyouts = { ["STUB"] = 0, }; |
end |
if (spellName == "Portal") or (spellName == "Teleport") then |
--break; -- There are spells with the same Name but different IDs, |
-- depending on the character's faction, when it comes to |
-- Portals and Teleports. Hence, for now, we add them only |
-- in Post. TODO: Fetch them here as well, but check that |
-- they are not one of those (known) smae-name, diff-IDs |
-- cases (in that case do not add them here, only in post). |
else |
-- Insert the flyout spell in its proper table |
if not SN2SID_table[universalClassName].Flyouts[spellName] then |
-- print(AddonName.. ": Adding Flyouts.".. spellName.. " to ".. universalClassName); |
SN2SID_table[universalClassName].Flyouts[spellName] = {}; |
-- else |
-- print(AddonName.. ": Flyouts.".. spellName.. " is already in ".. universalClassName); |
end |
local _, _, numFlyouts, flyoutKnown = GetFlyoutInfo(spellID); |
for flyoutSlot = 1, numFlyouts do |
-- local flyoutSpellID, overrideSpellID, flyoutSlotKnown, slotSpecID = GetFlyoutSlotInfo(spellID, flyoutSlot); |
local flyoutSpellID, _, _, _ = GetFlyoutSlotInfo(spellID, flyoutSlot); |
local flyoutSpellName, flyoutSpellSubname, _, _, _, _, _ = GetSpellInfo(flyoutSpellID); |
-- print(AddonName.. ": ".. tostring(flyoutSpellID).. " = ".. tostring(flyoutSpellName)); |
if spellName == "Polymorph Variants" or spellName == "Hex Variants" then |
-- Mage "Polymorph Variants", and Shaman "Hex Variants", |
-- are all called "Polymorph" or "Hex", respectively. But |
-- they have a subname specifying the variant AND can be |
-- addressed by suffixing the subname in parenthesis, as |
-- in e.g. "Polymorph(Sheep)" or "Hex(Frog)". We'll do just |
-- that and store their names as "name(subname)". |
if (flyoutSpellSubname == nil) or (flyoutSpellSubname == "") then |
-- TODO #1: Make a table, LOCAL-TO-FILE, to store |
-- all the delayedFlyoutSpellInfo tables amd name |
-- each one "delayedFlyoutSpellInfo"..flyoutSpellID . |
-- Create an access to the info that will be fetched |
local delayedFlyoutSpellInfo = Spell:CreateFromSpellID(flyoutSpellID); |
-- Actually get the info and use it to update our DB |
delayedFlyoutSpellInfo:ContinueOnSpellLoad(function() |
-- print(AddonName.. ": Will now get the previously delayed information about flyoutSpellID: ".. flyoutSpellID); |
-- Although we should only need to update spellSubName, we might |
-- have fetched a new spellName + spellID by now. Thus, we'll |
-- update those fields too. |
-- TODO #2: Pass the three |
-- "delayedFlyoutSpellInfo"..flyoutSpellID:Some() |
-- values bellow as arguments to |
-- addPolymorphOrHexFlyoutSpell_func(...) |
flyoutSpellName = delayedFlyoutSpellInfo:GetSpellName(); |
flyoutSpellSubname = delayedFlyoutSpellInfo:GetSpellSubtext(); -- Mandatory |
flyoutSpellID = delayedFlyoutSpellInfo:GetSpellID(); |
addPolymorphOrHexFlyoutSpell_func(spellName, flyoutSpellName, flyoutSpellSubname, flyoutSpellID); |
-- TODO #3: Clean up! I.e.: |
-- SaidMasterTable["delayedFlyoutSpellInfo"..flyoutSpellID] = nil; |
end); |
else |
addPolymorphOrHexFlyoutSpell_func(spellName, flyoutSpellName, flyoutSpellSubname, flyoutSpellID); |
end |
-- Add the default Plymorph(Sheep) and Hex(Frog) to the spell lists |
SN2SID_table.MAGE.Arcane["Polymorph(Sheep)"] = SN2SID_table.MAGE.Arcane["Polymorph"] or nil; |
SN2SID_table.MAGE.Fire["Polymorph(Sheep)"] = SN2SID_table.MAGE.Fire["Polymorph"] or nil; |
SN2SID_table.MAGE.Frost["Polymorph(Sheep)"] = SN2SID_table.MAGE.Frost["Polymorph"] or nil; |
SN2SID_table.SHAMAN.Elemental["Hex(Frog)"] = SN2SID_table.SHAMAN.Elemental["Hex"] or nil; |
SN2SID_table.SHAMAN.Enhancement["Hex(Frog)"] = SN2SID_table.SHAMAN.Enhancement["Hex"] or nil; |
SN2SID_table.SHAMAN.Restoration["Hex(Frog)"] = SN2SID_table.SHAMAN.Restoration["Hex"] or nil; |
elseif flyoutSpellName and (not SN2SID_table[universalClassName].Flyouts[spellName][flyoutSpellName]) |
or flyoutSpellName and (SN2SID_table[universalClassName].Flyouts[spellName][flyoutSpellName] ~= flyoutSpellID) then |
-- print(AddonName.. ": ".. tostring(flyoutSpellName).. " = ".. tostring(flyoutSpellID)); |
SN2SID_table[universalClassName].Flyouts[spellName][flyoutSpellName] = flyoutSpellID; |
end |
end |
end |
-- Get rid of the STUB table member that was added upon its creation |
SN2SID_table[universalClassName].Flyouts["STUB"] = nil; |
]]-- |
end |
end |
end |
SN2SID_PASSIVES_table[universalClassName][locSpecName]["Armor Skills"] = armorSkills; |
-- print(AddonName.. ": Added Armor Skills = ".. armorSkills); |
SN2SID_PASSIVES_table[universalClassName][locSpecName]["Weapon Skills"] = weaponSkills; |
-- print(AddonName.. ": Added Weapon Skills = ".. weaponSkills); |
end |
end |
updateClassSpells = false; |
-- end |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updateSpellbookSpells_func: END"); |
end |
-- Update the Pet-Spellbook and PetActionBar's spells -- |
-- Table of spellnames to exclude from storage |
local PetSpellNameExclusions = { PET_ASSIST, PET_ACTION_ATTACK, PET_DEFENSIVE,PET_ACTION_FOLLOW, |
PET_ACTION_MOVE_TO, PET_PASSIVE, "Stay" }; |
-- TABLE ABOVE: The 7 default actions for which GetSpellInfo() returns |
-- nil. QUESTION: Would it be desirable to save these spell references, |
-- which names would be the tokens (string) above? |
-- Add one Pet Spell to the apropriate subtable |
local addSpellbookPetSpell_func = function(spellName, spellSubName, spellID) |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": addSpellbookPetSpell_func: START"); |
local isPassive = IsPassiveSpell(spellID); |
if strfind(spellSubName, "Special") or strfind(spellSubName, "Bonus") or strfind(spellSubName, "Exotic") then -- Pet Family ability |
if isPassive then |
print(AddonName.. ": Add ".. petFamily.. " Passive : ".. spellName); |
-- if SN2SID_PASSIVES_table[universalClassName].Pets[petFamily] == nil then |
if not SN2SID_PASSIVES_table[universalClassName].Pets[petFamily] then |
SN2SID_PASSIVES_table[universalClassName].Pets[petFamily] = { [spellName] = spellID, }; |
else |
SN2SID_PASSIVES_table[universalClassName].Pets[petFamily][spellName] = spellID; |
end |
else |
print(AddonName.. ": Add ".. petFamily.. " : ".. spellName); |
if not SN2SID_table[universalClassName].Pets[petFamily] then |
SN2SID_table[universalClassName].Pets[petFamily] = { [spellName] = spellID, }; |
else |
SN2SID_table[universalClassName].Pets[petFamily][spellName] = spellID; |
end |
end |
-- elseif (strfind(spellSubName, "Basic") or (not isPassive)) and not |
-- (strfind(spellSubName, "Ferocity") or strfind(spellSubName, "Tenacity") |
-- or strfind(spellSubName, "Cunning")) then -- All three Pet Specializations |
elseif strfind(spellSubName, "Basic") or ((not isPassive) and not |
(strfind(spellSubName, "Ferocity") or strfind(spellSubName, "Tenacity") |
or strfind(spellSubName, "Cunning"))) then -- All three Pet Specializations |
print(AddonName.. ": Add All Specs : ".. spellName); |
-- if SN2SID_table[universalClassName].Pets["Ferocity"] == nil then |
if not SN2SID_table[universalClassName].Pets["Ferocity"] then |
SN2SID_table[universalClassName].Pets["Ferocity"] = { [spellName] = spellID, }; |
else |
SN2SID_table[universalClassName].Pets["Ferocity"][spellName] = spellID; |
end |
-- if SN2SID_table[universalClassName].Pets["Tenacity"] == nil then |
if not SN2SID_table[universalClassName].Pets["Tenacity"] then |
SN2SID_table[universalClassName].Pets["Tenacity"] = { [spellName] = spellID, }; |
else |
SN2SID_table[universalClassName].Pets["Tenacity"][spellName] = spellID; |
end |
-- if SN2SID_table[universalClassName].Pets["Cunning"] == nil then |
if not SN2SID_table[universalClassName].Pets["Cunning"] then |
SN2SID_table[universalClassName].Pets["Cunning"] = { [spellName] = spellID, }; |
else |
SN2SID_table[universalClassName].Pets["Cunning"][spellName] = spellID; |
end |
-- end |
elseif isPassive and (not (strfind(spellSubName, "Ferocity") or strfind(spellSubName, "Tenacity") |
or strfind(spellSubName, "Cunning"))) then |
print(AddonName.. ": Add All Specs Passive : ".. spellName); |
-- if SN2SID_PASSIVES_table[universalClassName].Pets["Ferocity"] == nil then |
if not SN2SID_PASSIVES_table[universalClassName].Pets["Ferocity"] then |
SN2SID_PASSIVES_table[universalClassName].Pets["Ferocity"] = { [spellName] = spellID, }; |
else |
SN2SID_PASSIVES_table[universalClassName].Pets["Ferocity"][spellName] = spellID; |
end |
-- if SN2SID_PASSIVES_table[universalClassName].Pets["Tenacity"] == nil then |
if not SN2SID_PASSIVES_table[universalClassName].Pets["Tenacity"] then |
SN2SID_PASSIVES_table[universalClassName].Pets["Tenacity"] = { [spellName] = spellID, }; |
else |
SN2SID_PASSIVES_table[universalClassName].Pets["Tenacity"][spellName] = spellID; |
end |
-- if SN2SID_PASSIVES_table[universalClassName].Pets["Cunning"] == nil then |
if not SN2SID_PASSIVES_table[universalClassName].Pets["Cunning"] then |
SN2SID_PASSIVES_table[universalClassName].Pets["Cunning"] = { [spellName] = spellID, }; |
else |
SN2SID_PASSIVES_table[universalClassName].Pets["Cunning"][spellName] = spellID; |
end |
else |
if strfind(spellSubName, "Ferocity") then -- Ferocity |
if isPassive then |
print(AddonName.. ": Add Ferocity Passive : ".. spellName); |
-- if SN2SID_PASSIVES_table[universalClassName].Pets["Ferocity"] == nil then |
if not SN2SID_PASSIVES_table[universalClassName].Pets["Ferocity"] then |
SN2SID_PASSIVES_table[universalClassName].Pets["Ferocity"] = { [spellName] = spellID, }; |
else |
SN2SID_PASSIVES_table[universalClassName].Pets["Ferocity"][spellName] = spellID; |
end |
else |
print(AddonName.. ": Add Ferocity : ".. spellName); |
-- if SN2SID_table[universalClassName].Pets["Ferocity"] == nil then |
if not SN2SID_table[universalClassName].Pets["Ferocity"] then |
SN2SID_table[universalClassName].Pets["Ferocity"] = { [spellName] = spellID, }; |
else |
SN2SID_table[universalClassName].Pets["Ferocity"][spellName] = spellID; |
end |
end |
-- end |
elseif strfind(spellSubName, "Tenacity") then -- Tenacity |
if isPassive then |
print(AddonName.. ": Add Tenacity Passive : ".. spellName); |
-- if SN2SID_PASSIVES_table[universalClassName].Pets["Tenacity"] == nil then |
if not SN2SID_PASSIVES_table[universalClassName].Pets["Tenacity"] then |
SN2SID_PASSIVES_table[universalClassName].Pets["Tenacity"] = { [spellName] = spellID, }; |
else |
SN2SID_PASSIVES_table[universalClassName].Pets["Tenacity"][spellName] = spellID; |
end |
else |
print(AddonName.. ": Add Tenacity : ".. spellName); |
-- if SN2SID_table[universalClassName].Pets["Tenacity"] == nil then |
if not SN2SID_table[universalClassName].Pets["Tenacity"] then |
SN2SID_table[universalClassName].Pets["Tenacity"] = { [spellName] = spellID, }; |
else |
SN2SID_table[universalClassName].Pets["Tenacity"][spellName] = spellID; |
end |
end |
-- end |
elseif strfind(spellSubName, "Cunning") then -- Cunning |
if isPassive then |
print(AddonName.. ": Add Cunning Passive : ".. spellName); |
-- if SN2SID_PASSIVES_table[universalClassName].Pets["Cunning"] == nil then |
if not SN2SID_PASSIVES_table[universalClassName].Pets["Cunning"] then |
SN2SID_PASSIVES_table[universalClassName].Pets["Cunning"] = { [spellName] = spellID, }; |
else |
SN2SID_PASSIVES_table[universalClassName].Pets["Cunning"][spellName] = spellID; |
end |
else |
print(AddonName.. ": Add Cunning : ".. spellName); |
-- if SN2SID_table[universalClassName].Pets["Cunning"] == nil then |
if not SN2SID_table[universalClassName].Pets["Cunning"] then |
SN2SID_table[universalClassName].Pets["Cunning"] = { [spellName] = spellID, }; |
else |
SN2SID_table[universalClassName].Pets["Cunning"][spellName] = spellID; |
end |
end |
end |
end |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": addSpellbookPetSpell_func: END"); |
end |
-- Pet Spells update function |
local updatePetSpellNames = function() |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updatePetSpellNames: START"); |
-- print(AddonName.. ": Fetching Pet spells"); |
-- local petHasSpellsConfirmed = false; |
-- NOTES: |
-- GetSpellInfo(spellName) is the most reliable way to get the SpellID for a give SpellName, 7th |
-- return value. BUT we need to get a list of spell names first, and that's where the other two |
-- Blizzard functions, GetPetActionInfo(buttonNumber) and GetSpellBookItemName(SpellbookIndex, |
-- BOOKTYPE_PET), come in. |
-- |
-- GetPetActionInfo(buttonNumber) only retrieves information for spells on the PetActionBar; |
-- given that there might be other Pet Spells - on the PetSpellbook - we will later need to get |
-- them using other means. But first we will get these spells from the bar, for these reasons: |
-- - One thing to note is the 'isToken' return value from GetPetActionInfo(). This value will be |
-- true if the spell is one of the 7 standard spells that every controllable pet gets: Assist, |
-- Attack, Defensive, Follow, Move To, Passive, Stay. This flag is NOT returned by any of the |
-- the other functions we get info on PetSpells from. Again, unfortunately, GetPetActionInfo() |
-- only returns info on spells in the PetActionBar and not all PetSpells are in there. |
-- Another important thing to note is that Temporary Controllable-pets (e.g. the Elemental |
-- Shaman pets, if the talent 'Primal Elementalist' is active) do not have any spells in a |
-- spellbook; but all their spells should be on the PetActionBar. Thus GetPetActionInfo is the |
-- only way - and the only way needed - to get info on these pets' spells. |
-- |
-- GetSpellBookItemInfo() not only does not return anything for Temporary Controllable-pets, it |
-- also seems BUGGED, as it returns weird values for Pet SpellIDs (9 or 10 digits long numbers, |
-- sometimes negatives!). |
-- GetSpellBookItemName() (other function) however returns correct SpellNames and is rather |
-- exaustive as far as getting them for permanent pets. |
-- local petName = GetUnitName("pet", nil); |
-- local petFamily = UnitCreatureFamily("pet"); |
petFamily = UnitCreatureFamily("pet"); |
if (not petFamily) or (petFamily == "") then -- First time UNIT_PET fires, the info on the Pet hasn't been loaded yet |
return; -- UNIT_PET fires two to three times when a new pet is summoned. |
end |
print(AddonName.. ": Pet Family = ".. tostring(petFamily)); |
local _, isHunterPet = HasPetUI(); |
if isHunterPet then -- Hunter Pets, unlike all others, have specializations, so we'll handle |
-- their spells differently |
local curPetSpecIndex = GetSpecialization(false, true); |
local stubVal; |
stubVal, petSpec = GetSpecializationInfo(curPetSpecIndex or 1, false, true); |
print(AddonName.. ": Pet Spec #".. tostring(curPetSpecIndex).. "; Pet Family: ".. tostring(petFamily)); |
-- GetSpellBookItemName(SpellbookIndex, BOOKTYPE_PET) + GetSpellInfo(spellName) -- |
if HasPetSpells() then -- I.e. whether there is a Pet Spellbook. WARNING: Returns 'true' for |
-- classes which have pets but are too low level to have control |
-- over them; e.g. Hunters and Warlocks under Level 10. |
print(AddonName.. ": Getting SBook spells for pet: ".. petFamily); |
local i = 0; |
repeat |
i = i + 1; |
local spellName, spellSubName = GetSpellBookItemName(i, BOOKTYPE_PET); |
-- print(AddonName.. ": Book: ".. tostring(spellName).. " ; ".. tostring(spellSubName)); |
if spellName then |
-- No isToken flag from GetPetActionInfo() here, so do the check ourselves |
local isToken = false; |
if PetSpellNameExclusions[spellName] then |
isToken = true; |
end |
if not isToken then |
local _, _, _, _, _, _, spellID = GetSpellInfo(spellName); |
-- local isPassive = IsPassiveSpell(spellID); |
if spellID then -- Sanity check |
-- NEW for 1.0.14 -- |
if (not spellSubName) or (spellSubName == "") then |
local delayedSpellInfo = Spell:CreateFromSpellID(spellID); |
-- I presume we don't actually need to cancel the request for the additional |
-- information, i.e. presume once the information is given to us through the |
-- function delayedSpellInfo:ContinueOnSpellLoad(), there will be no further |
-- activity regarding this- But, just in case, we'll set up a function to |
-- cancel the request after we got the information we need. |
-- local spellDataLoadedCancelFunc = delayedSpellInfo:ContinueWithCancelOnSpellLoad(function() -- We don't need to do anything upon canceling the request |
-- print(AddonName.. ": Now cancelling the request for delayed information about spell ID: ".. spellID); |
-- end); |
-- Actually get the information and use it to update our database: |
delayedSpellInfo:ContinueOnSpellLoad(function() |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": delayedSpellInfo: START"); |
-- print(AddonName.. ": Will now get the previously delayed information about spell ID: ".. spellID); |
-- Although we should only need to update spellSubName, we might |
-- have fetched a new spellName + spellID by now. Thus, we'll |
-- update those fields too. |
spellName = delayedSpellInfo:GetSpellName(); |
spellSubName = delayedSpellInfo:GetSpellSubtext(); -- Mandatory |
spellID = delayedSpellInfo:GetSpellID(); |
addSpellbookPetSpell_func(spellName, spellSubName, spellID); |
-- Now cancel the request: |
-- spellDataLoadedCancelFunc(); |
-- spellDataLoadedCancelFunc = nil; -- for safety! |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": delayedSpellInfo: END"); |
end); |
else |
addSpellbookPetSpell_func(spellName, spellSubName, spellID); |
end |
-- -- |
-- else |
-- print(AddonName.. ": Pet spell #".. i.. ": NO ID!"); |
end |
-- else |
-- print(AddonName.. ": Pet spell #".. i.." is a token."); |
end |
end |
until spellName == nil; |
-- petHasSpellsConfirmed = true; |
end |
-- GetSpellBookItemName(SpellbookIndex, BOOKTYPE_PET) + GetSpellInfo(spellName) -- |
elseif HasPetSpells() then -- I.e. whether there is a Pet Spellbook. WARNING: Will return TRUE |
-- for all characters whose classes have pets, regardless of |
-- whether or not the character's level is high enough to have |
-- control over them; e.g. TRUE for Warlocks under Level 10. |
print(AddonName.. ": Getting SBook spells for pet: ".. petFamily); |
local i = 0; |
repeat |
i = i + 1; |
-- local spellName, spellSubName = GetSpellBookItemName(i, BOOKTYPE_PET); |
local spellName = (GetSpellBookItemName(i, BOOKTYPE_PET)); |
-- NB: We don't actually use the value of 'spellSubName' within the current scope; |
-- the value is a stub. Thus there is no need to use the SpellMixin API here. |
-- print(AddonName.. ": Book: ".. tostring(spellName)); |
if spellName then |
local isToken = false; |
if PetSpellNameExclusions[spellName] then |
isToken = true; |
end |
if not isToken then |
-- local _, spellID = GetSpellBookItemInfo(i, BOOKTYPE_PET); |
local _, _, _, _, _, _, spellID = GetSpellInfo(spellName); |
if spellID then -- Sanity check |
if IsPassiveSpell(spellID) then |
-- if SN2SID_PASSIVES_table[universalClassName].Pets[petFamily] == nil then |
if not SN2SID_PASSIVES_table[universalClassName].Pets[petFamily] then |
SN2SID_PASSIVES_table[universalClassName].Pets[petFamily] = { [spellName] = spellID, }; |
else |
SN2SID_PASSIVES_table[universalClassName].Pets[petFamily][spellName] = spellID; |
end |
else |
-- if SN2SID_table[universalClassName].Pets[petFamily] == nil then |
if not SN2SID_table[universalClassName].Pets[petFamily] then |
SN2SID_table[universalClassName].Pets[petFamily] = { [spellName] = spellID, }; |
else |
SN2SID_table[universalClassName].Pets[petFamily][spellName] = spellID; |
end |
end |
end |
end |
end |
until spellName == nil; |
-- petHasSpellsConfirmed = true; |
end |
-- GetPetActionInfo(buttonNumber) + GetSpellInfo(spellName) -- |
if (not isHunterPet) and PetHasActionBar() then -- As all controllable pets are marked to have. Note: HasPetUI() |
-- returns 'true' for classes which have pets but are too low level |
-- to have control over them; e.g. Warlocks under Level 10. |
-- PetHasActionBar() only returns 1 if a PetActionBar actually |
-- should be shown (but regardless of the result of :IsShown). |
print(AddonName.. ": Getting ABar spells for pet: ".. petFamily); |
for i = 1, NUM_PET_ACTION_SLOTS do |
-- local spellName, spellSubName, _, isToken, _, _, _ = GetPetActionInfo(i); |
local spellName, _, _, isToken, _, _, _ = GetPetActionInfo(i); |
-- NB: We don't actually use the value of 'spellSubName' within the current scope; |
-- the value is a stub. Thus there is no need to use the SpellMixin API here. |
-- print(AddonName.. ": BarButton".. i..": ".. tostring(spellName)); |
if spellName and (not isToken) then |
local _, _, _, _, _, _, spellID = GetSpellInfo(spellName); |
if spellID then -- Sanity check |
if IsPassiveSpell(spellID) then |
if not SN2SID_PASSIVES_table[universalClassName].Pets[petFamily] then |
SN2SID_PASSIVES_table[universalClassName].Pets[petFamily] = { [spellName] = spellID, }; |
else |
SN2SID_PASSIVES_table[universalClassName].Pets[petFamily][spellName] = spellID; |
end |
else |
if not SN2SID_table[universalClassName].Pets[petFamily] then |
SN2SID_table[universalClassName].Pets[petFamily] = { [spellName] = spellID, }; |
else |
SN2SID_table[universalClassName].Pets[petFamily][spellName] = spellID; |
end |
end |
end |
end |
end |
-- petHasSpellsConfirmed = true; |
end |
-- print(AddonName.. ": Fetched? ".. tostring(petHasSpellsConfirmed)); |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updatePetSpellNames: END"); |
end |
local addSpellsPostUpdate = function() |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": addSpellsPostUpdate: START"); |
if postUpdate_Spells2Add and SN2SID_table then -- Sanity check |
for key, value in pairs(postUpdate_Spells2Add) do |
if key == "General" or key == universalClassName then -- Only add hardcoded spells for |
-- GeneralTab or Current Class |
for keyk, valuev in pairs(value) do |
if keyk == "FlyoutsTOGET" then |
-- print(AddonName.. ": Will get flyout spells for FlyoutButtonName ".. keykk.. " with ID ".. valuevv); |
-- addFlyoutSpells_func(keyk, valuev); |
for keykk, valuevv in pairs(valuev) do |
addFlyoutSpells_func(keykk, valuevv); |
end |
elseif not SN2SID_table[key][keyk] then -- specName(..somethingMaybe) |
-- OR "FlyoutsTOGET" OR |
-- "Flyouts" OR "Pets" OR |
-- someGeneralTabCategory. |
-- print(AddonName.. ": Adding: ".. tostring(valuev)); |
SN2SID_table[key][keyk] = valuev; |
elseif type(valuev) == "table" then |
for keykk, valuevv in pairs(valuev) do |
if not SN2SID_table[key][keyk][keykk] then -- Spell OR Flyouts_spell OR |
-- PetFamily is not on the |
-- target table yet |
-- print(AddonName.. ": Adding: ".. tostring(valuevv)); |
SN2SID_table[key][keyk][keykk] = valuevv; |
end |
if type(valuevv) == "table" then -- Flyouts_spell OR PetFamily |
for keykkk, valuevvv in pairs(valuevv) do |
if not SN2SID_table[key][keyk][keykk][keykkk] then |
-- Flyouts_spell_Spell OR |
-- PetFamily_spell is not |
-- yet on the table. |
-- print(AddonName.. ": Adding: ".. tostring(valuevvv)); |
SN2SID_table[key][keyk][keykk][keykkk] = valuevvv; |
end |
end |
end |
end |
end |
end |
end |
end |
end |
if postUpdate_Spells2Add_PASSIVES and SN2SID_PASSIVES_table then |
for key, value in pairs(postUpdate_Spells2Add_PASSIVES) do |
if key == "General" or key == universalClassName then -- Only add hardcoded spells for |
-- GeneralTab or Current Class |
for keyk, valuev in pairs(value) do |
-- if SN2SID_PASSIVES_table[key][keyk] == nil then -- "Spells" OR specName(..somethingMaybe) OR |
if not SN2SID_PASSIVES_table[key][keyk] then -- "Spells" OR specName(..somethingMaybe) OR |
-- "Pets" is not on the target table yet |
-- print(AddonName.. ": Adding: ".. tostring(valuev)); |
SN2SID_PASSIVES_table[key][keyk] = valuev; |
elseif type(valuev) == "table" then -- "Spells" OR specName(..somethingMaybe) OR |
-- "Pets" table |
for keykk, valuevv in pairs(valuev) do |
-- if SN2SID_PASSIVES_table[key][keyk][keykk] == nil then -- Spell OR Flyouts_spell OR |
if not SN2SID_PASSIVES_table[key][keyk][keykk] then -- Spell OR Flyouts_spell OR |
-- PetFamily is not on the |
-- target table yet |
-- print(AddonName.. ": Adding: ".. tostring(valuevv)); |
SN2SID_PASSIVES_table[key][keyk][keykk] = valuevv; |
elseif type(valuevv) == "table" then -- Flyouts_spell OR PetFamily |
for keykkk, valuevvv in pairs(valuevv) do |
-- if SN2SID_PASSIVES_table[key][keyk][keykk][keykkk] == nil then -- Flyouts_spell_Spell OR |
if not SN2SID_PASSIVES_table[key][keyk][keykk][keykkk] then -- Flyouts_spell_Spell OR |
-- PetFamily_spell is not |
-- on the target table yet |
-- print(AddonName.. ": Adding: ".. tostring(valuevvv)); |
SN2SID_PASSIVES_table[key][keyk][keykk][keykkk] = valuevvv; |
end |
end |
end |
end |
end |
end |
end |
end |
end |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": addSpellsPostUpdate: END"); |
end |
-- -- -- RUNTIME -- -- -- |
------------------------- |
-- Frame to listen to game events |
local SN2SID_frame, SN2SID_events = CreateFrame("Frame", nil), {}; |
-- NB: When ADDON_LOADED fires, the SpellBook etc aren't available yet, only upon PLAYER_LOGIN. |
SN2SID_frame:RegisterEvent("PLAYER_LOGIN"); |
-- Function to call upon PLAYER_LOGIN (see bottom of file) |
local lsn2sidpStartup = function() |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": lsn2sidpStartup: START"); |
-- Startup -- |
print(AddonName.. ": Startup!"); |
-- Copy the global saved-variables tables to our local tables |
SN2SID_table = AddonEnv.SpellNamesAndIDs or SpellNamesAndIDs or {}; |
SN2SID_PASSIVES_table = AddonEnv.SpellNamesAndIDs_PASSIVES or SpellNamesAndIDs_PASSIVES or {}; |
-- DEBUGmsgs = AddonEnv.DEBUG_messages or DEBUG_messages or {}; |
-- tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Print tables\' tostring to console: START"); |
-- print(AddonName.. ": AddonEnv.SpellNamesAndIDs = ".. tostring(AddonEnv.SpellNamesAndIDs)); -- nil |
-- print(AddonName.. ": AddonEnv.SpellNamesAndIDs_PASSIVES = ".. tostring(AddonEnv.SpellNamesAndIDs_PASSIVES)); -- nil |
-- print(AddonName.. ": AddonEnv.DEBUG_messages = ".. tostring(AddonEnv.DEBUG_messages)); -- nil |
-- print(AddonName.. ": SpellNamesAndIDs = ".. tostring(SpellNamesAndIDs)); -- TableA |
-- print(AddonName.. ": SpellNamesAndIDs_PASSIVES = ".. tostring(SpellNamesAndIDs_PASSIVES)); -- TableB |
-- print(AddonName.. ": DEBUG_messages = ".. tostring(DEBUG_messages)); -- TableB |
-- print(AddonName.. ": SN2SID_table = ".. tostring(SN2SID_table));-- TableA |
-- print(AddonName.. ": SN2SID_PASSIVES_table = ".. tostring(SN2SID_PASSIVES_table)); -- TableB |
-- print(AddonName.. ": DEBUGmsgs = ".. tostring(DEBUGmsgs)); -- TableB |
-- tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Print tables\' tostring to console: END"); |
-- -- Metadata fields: Data source, Class', ... -- -- |
-- Data source -- |
-- We're only interested in storing the English names, at least for now |
local curLocale = GetLocale(); |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Got: curLocale = ".. curLocale); |
if ( curLocale ~= "enUS") then |
SN2SID_frame:UnregisterAllEvents(); |
error(AddonName.. " only retrieves data from English (enUS or enGB) clients."); |
-- return; |
end |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Validated: curLocale"); |
local stubVal; |
stubVal, universalRaceName = UnitRace("player"); |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Got: universalRaceName (no validation needed) = ".. universalRaceName); |
-- Self-explanatory: |
local _, gameBuild = GetBuildInfo(); |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Got: gameBuild"); |
-- For some reason, the variable gameBuild is being saved as a string; convert to number: |
gameBuild = tonumber(gameBuild); |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Validated that gameBuild is a number. gameBuild = ".. gameBuild.. ": Done."); |
local charLevel = UnitLevel("player"); |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Got: charLevel (no validation needed) = ".. charLevel); |
-- Spells in the General tab: Racial abilities, etc |
-- local generalTabName = (GetSpellTabInfo(1)); -- Tab#1 = General |
generalTabName = (GetSpellTabInfo(1)); -- Tab#1 = General |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Got: generalTabName (no validation needed) = ".. generalTabName); |
-- Class stuff -- |
-- local universalClassName = select(2, UnitClass("player")); -- Locale-independent Class name |
stubVal, universalClassName = UnitClass("player"); -- Locale-independent Class name |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Got: universalClassName (no validation needed) = ".. universalClassName); |
local ClassNumSpecs = GetNumSpecializations(false, false); -- Number of Specialisations |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Got: ClassNumSpecs (no validation needed) = ".. ClassNumSpecs); |
-- Ordered list of Class specs' IDs and Names -- Do we still use this? |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Order list of Class specs' IDs and Names: START"); |
local specID, specName = GetSpecializationInfo(1); |
local ClassSpecNames2IDs = {}; |
for i = 1, ClassNumSpecs do |
local specID, specName = GetSpecializationInfo(i); |
ClassSpecNames2IDs[specName] = specID; |
end |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Order list of Class specs' IDs and Names: END"); |
---- Check the tables' skeleton structure and build whatever may be missing ---- |
-- |
if not SN2SID_table then -- sanity check |
error(AddonName.. "Local copy of saved variables is missing."); |
-- return; |
end |
if not SN2SID_PASSIVES_table then -- sanity check |
error(AddonName.. "Local copy of saved variables is missing."); |
-- return; |
end |
-- |
-- If needed, create and populate the Metadata subtables; -- |
-- Flag spell-lists for update if applicable -- |
-- |
-- General tab skeleton + dataSource + raceBuilds |
-- NB: We separate the two types of tables in two if-loops for the sake of sanity-keep (against |
-- e.g. manual edits to the file). |
if not SN2SID_table[generalTabName] then |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Create the ".. generalTabName.. " dataSource for Active spells: START"); |
print(AddonName.. ": Will now create the ".. generalTabName.. " dataSource for Active spells."); |
SN2SID_table[generalTabName] = {}; |
SN2SID_table[generalTabName].METADATA = {}; |
SN2SID_table[generalTabName].METADATA.dataSource = { |
clientLocale = curLocale, -- Currently always enUS |
gameBuild = gameBuild, |
charLevel = charLevel, |
charMaxLevel = charLevel, |
}; |
SN2SID_table[generalTabName].METADATA.raceBuilds = { [universalRaceName] = gamebuild }; |
-- We've just created and populated the GeneralTabMetadata, hence no need to update |
updateGeneralTabMetadata = false; |
updateGeneralSpells = true; -- Do populate the actual list of spells |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Create the ".. generalTabName.. " dataSource for Active spells: END"); |
else |
updateGeneralTabMetadata = true; -- Will check whether it's updated; if not, will update; |
-- The function which checks above var will also flag for Spells-list update if needed. |
end |
if not SN2SID_PASSIVES_table[generalTabName] then |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Create the ".. generalTabName.. " dataSource for Passive spells: START"); |
print(AddonName.. ": Will now create the ".. generalTabName.. " dataSource for Passive spells."); |
SN2SID_PASSIVES_table[generalTabName] = {}; |
SN2SID_PASSIVES_table[generalTabName].METADATA = {}; |
SN2SID_PASSIVES_table[generalTabName].METADATA.dataSource = { |
clientLocale = curLocale, -- Currently always enUS |
gameBuild = gameBuild, |
charLevel = charLevel, |
charMaxLevel = charLevel, |
}; |
SN2SID_PASSIVES_table[generalTabName].METADATA.raceBuilds = { [universalRaceName] = gamebuild }; |
-- We've just created and populated the GeneralTabMetadata, hence no need to update ... |
updateGeneralTabMetadata = false; -- And this seems redundant. Keep it 'cause I'll forget it otherwise... |
updateGeneralSpells = true; -- Do populate the actual list of spells |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Create the ".. generalTabName.. " dataSource for Passive spells: END"); |
else |
updateGeneralTabMetadata = true; -- Will check whether it's updated, if not will update; |
-- The function which checks above var will also flag for Spells-list update if needed. |
end |
-- Run the update function (does both Active and Passive trees) |
updateGeneralTabMetadata_func(curLocale, gameBuild, charLevel); |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Updated the ".. generalTabName.. " Metadata \(or not\!\) for both Active and Passive spells."); |
-- Class spells' Metadata (dataSource only; class Specs will be handled afterwards) |
if not SN2SID_table[universalClassName] then |
print(AddonName.. ": Will now create the ".. universalClassName.. "'s table and dataSource for Active spells."); |
SN2SID_table[universalClassName] = {}; |
else |
updateClassMetadata = true; -- Will check whether it's updated and if not, will update; |
-- The function which checks above var will also flag for Spells-list update if needed. |
end |
if not SN2SID_table[universalClassName].METADATA then |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Create the ".. universalClassName.. " dataSource for Active spells: START"); |
SN2SID_table[universalClassName].METADATA = {}; |
SN2SID_table[universalClassName].METADATA.dataSource = { |
clientLocale = curLocale, -- Currently always enUS |
gameBuild = gameBuild, |
charLevel = charLevel, |
charMaxLevel = charLevel, |
}; |
-- We've just created and populated the Class' dataSource fields, hence no need to update; |
-- Class Specs fields are updated in another if-clause, further ahead. |
updateClassMetadata = false; |
updateClassSpells = true; -- Do populate the actual list of spells. |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Create the ".. universalClassName.. " dataSource for Active spells: END"); |
else |
updateClassMetadata = true; -- Will check whether it's updated and if not, will update; |
-- The function which checks above var will also flag for Spells-list update if needed. |
end |
if not SN2SID_PASSIVES_table[universalClassName] then |
print(AddonName.. ": Will now create the ".. universalClassName.. "'s table and dataSource for Passive spells."); |
SN2SID_PASSIVES_table[universalClassName] = {}; |
else |
updateClassMetadata = true; |
-- The function which checks above var will also flag for Spells-list update if needed. |
end |
if not SN2SID_PASSIVES_table[universalClassName].METADATA then |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Create the ".. universalClassName.. " dataSource for Passive spells: START"); |
SN2SID_PASSIVES_table[universalClassName].METADATA = {}; |
SN2SID_PASSIVES_table[universalClassName].METADATA.dataSource = { |
clientLocale = curLocale, -- Currently always enUS |
gameBuild = gameBuild, |
charLevel = charLevel, |
charMaxLevel = charLevel, |
}; |
-- We've just created and populated the Class' dataSource fields, hence no need to update; |
-- Class Specs fields are updated in another if-clause, further ahead. |
updateClassMetadata = false; |
updateClassSpells = true; -- Do populate the actual list of spells. |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Create the ".. universalClassName.. " dataSource for Passive spells: END"); |
else |
updateClassMetadata = true; -- Will check whether it's updated and if not, will update; |
-- The function which checks above var will also flag for Spells-list update if needed. |
end |
-- Do the actual update of the Class Metadata (dataSource only now; Specs will be handled next) |
-- updateClassMetadata_func(SN2SID_table, SN2SID_PASSIVES_table, curLocale, gameBuild, universalClassName, charLevel); |
-- updateClassMetadata_func(curLocale, gameBuild, universalClassName, charLevel); |
updateClassMetadata_func(curLocale, gameBuild, charLevel); |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Ran updateClassMetadata_func()."); |
-- If needed, create and populate Class Specs' Active and Passive Spells -- |
-- Flag spell-lists for update if applicable -- |
if not SN2SID_table[universalClassName].METADATA.Specs then |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Create the ".. universalClassName.. " \'Specs\' (Actives) tables: START"); |
print(AddonName.. ": Will now create the ".. universalClassName.. "'s \'Specs\' (Actives) tables."); |
for i = 1, ClassNumSpecs do |
local specID, specName = GetSpecializationInfo(i); |
-- ClassSpecNames2IDs[i] = { specID, specName }; |
ClassSpecNames2IDs[specName] = specID; |
-- print(AddonName.. ": ".. i.. " = ".. specID.. " = ".. specName); -- For reference |
-- local specString = "Spec"..specID; |
if not SN2SID_table[universalClassName].METADATA.Specs then |
SN2SID_table[universalClassName].METADATA.Specs = {}; |
SN2SID_table[universalClassName].METADATA.Specs[specName] = specID; -- Reference |
SN2SID_table[universalClassName][specName] = {}; -- For "[SpellName] = SpellID" |
elseif not SN2SID_table[universalClassName].METADATA.Specs[i] then |
SN2SID_table[universalClassName].METADATA.Specs[specName] = specID; -- Reference |
SN2SID_table[universalClassName][specName] = {}; -- For "[SpellName] = SpellID" |
end |
end |
updateClassSpells = true; -- Do populate the actual list of spells. |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Create the ".. universalClassName.. " \'Specs\' (Actives) tables: END"); |
end |
if not SN2SID_PASSIVES_table[universalClassName].METADATA.Specs then |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Create the ".. universalClassName.. " \'Specs\' (Passives) tables: START"); |
print(AddonName.. ": Will now create the ".. universalClassName.. "'s \'Specs\' (Passives) tables."); |
for i = 1, ClassNumSpecs do |
local specID, specName = GetSpecializationInfo(i); |
-- ClassSpecNames2IDs[i] = { specID, specName }; |
ClassSpecNames2IDs[specName] = specID; |
-- print(AddonName.. ": ".. i.. " = ".. specID.. " = ".. specName); -- For reference |
if not SN2SID_PASSIVES_table[universalClassName].METADATA.Specs then |
SN2SID_PASSIVES_table[universalClassName].METADATA.Specs = {}; |
SN2SID_PASSIVES_table[universalClassName].METADATA.Specs[specName] = specID; -- Ref. |
SN2SID_PASSIVES_table[universalClassName][specName] = {}; -- "[SpellName] = SpellID" |
elseif not SN2SID_PASSIVES_table[universalClassName].METADATA.Specs[i] then |
SN2SID_PASSIVES_table[universalClassName].METADATA.Specs[specName] = specID; -- Ref. |
SN2SID_PASSIVES_table[universalClassName][specName] = {}; -- "[SpellName] = SpellID" |
end |
end |
updateClassSpells = true; -- Do populate the actual list of spells. |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Create the ".. universalClassName.. " \'Specs\' (Passives) tables: END"); |
end |
-- Update General (always ATM) and Class SpellNames2SIDs (both Actives and Passives) -- |
updateClassSpells = true; |
-- updateSpellbookSpells_func(SN2SID_table, SN2SID_PASSIVES_table, generalTabName, universalClassName, ClassNumSpecs, ClassSpecNames2IDs); |
-- updateSpellbookSpells_func(generalTabName, universalClassName, ClassNumSpecs, ClassSpecNames2IDs); |
-- updateSpellbookSpells_func(universalClassName, ClassNumSpecs, ClassSpecNames2IDs); |
updateSpellbookSpells_func(ClassNumSpecs, ClassSpecNames2IDs); |
-- Pet spells will only be available when a pet is out, so wait for it, i.e. wait for UNIT_PET |
-- to fire for "player". |
-- Set up Other Event-Handlers -- |
--------------------------------- |
function SN2SID_events:PLAYER_TALENT_UPDATE(self) |
DBG_CurrentEvent = "PLAYER_TALENT_UPDATE"; |
DEBUGmsgs["PLAYER_TALENT_UPDATE"] = { tostring(GetTime()).. ": PLAYER_TALENT_UPDATE: START", } |
-- updateGeneralSpells = true; -- unneeded, placeholder for future version |
updateClassSpells = true; |
-- updateSpellbookSpells_func(SN2SID_table, SN2SID_PASSIVES_table, generalTabName, universalClassName, ClassNumSpecs, ClassSpecNames2IDs); |
-- updateSpellbookSpells_func(generalTabName, universalClassName, ClassNumSpecs, ClassSpecNames2IDs); |
-- updateSpellbookSpells_func(universalClassName, ClassNumSpecs, ClassSpecNames2IDs); |
updateSpellbookSpells_func(ClassNumSpecs, ClassSpecNames2IDs); |
tinsert(DEBUGmsgs["PLAYER_TALENT_UPDATE"], tostring(GetTime()).. ": PLAYER_TALENT_UPDATE: END"); |
end |
function SN2SID_events:PLAYER_LEVEL_UP(self, ...) |
DBG_CurrentEvent = "PLAYER_LEVEL_UP"; |
DEBUGmsgs["PLAYER_LEVEL_UP"] = { tostring(GetTime()).. ": PLAYER_LEVEL_UP: START", } |
-- UnitLevel("player") doesn't update its result soon enough to have it indicate the *new* |
-- char level in response to this event. OTH, this event does provide arguments but, |
-- whatever they are, they're NOT the new char leve, for sure. Might be best to just flag |
-- for update on Logout. But we'll still do it here, for now. |
updateGeneralTabMetadata = true; -- Maybe useful. |
updateClassMetadata = true; -- Stuff like talents only become available at level 10. |
-- updateClassMetadata_func(SN2SID_table, SN2SID_PASSIVES_table, curLocale, gameBuild, universalClassName, charLevel); |
updateClassMetadata_func(curLocale, gameBuild, charLevel); |
updateGeneralTabMetadata = true; -- Maybe useful. |
updateClassMetadata = true; -- Stuff like talents only become available at level 10. |
tinsert(DEBUGmsgs["PLAYER_LEVEL_UP"], tostring(GetTime()).. ": PLAYER_LEVEL_UP: END"); |
end |
-- Update pets' existence and spells when one comes up for "player" |
-- NB: Fires after PLAYER_LOGIN if the player already has a pet out. NO LONGER SO as of game |
-- build 26365 and later; I only got this event to fire on 'Pet Dismiss' and 'Summon Pet' button |
-- clicks. Also, see BUG described bellow! |
-- fire on 'Pet Dismiss' and 'Summon Pet' button clicks. Also, see BUG described bellow! |
-- function SN2SID_events:UNIT_PET(self, ...) |
function SN2SID_events:UNIT_PET(...) |
local arg1 = ...; |
print(AddonName.. ": UNIT_PET fired with arg1 = ".. tostring(arg1)); |
if (not arg1) or (arg1 ~= "player") then |
return; |
end |
DBG_CurrentEvent = "UNIT_PET"; |
DEBUGmsgs["UNIT_PET"] = { tostring(GetTime()).. ": UNIT_PET: START", } |
if not SN2SID_table[universalClassName].Pets then |
SN2SID_table[universalClassName].Pets = {}; |
end |
if not SN2SID_PASSIVES_table[universalClassName].Pets then |
SN2SID_PASSIVES_table[universalClassName].Pets = {}; |
end |
-- updatePetSpellNames(SN2SID_table, SN2SID_PASSIVES_table, universalClassName); |
-- updatePetSpellNames(universalClassName); |
updatePetSpellNames(); |
tinsert(DEBUGmsgs["UNIT_PET"], tostring(GetTime()).. ": UNIT_PET: END"); |
end |
function SN2SID_events:PLAYER_LOGOUT(self) |
DBG_CurrentEvent = "PLAYER_LOGOUT"; |
-- Set up DEBUG = { LOGOUT = {} } subtable of messages |
if not DEBUGmsgs["PLAYER_LOGOUT"] then |
DEBUGmsgs["PLAYER_LOGOUT"] = { |
tostring(GetTime()).. ": PLAYER_LOGOUT: START", |
tostring(GetTime()).. ": DEBUGmsgs.PLAYER_LOGOUT created.", |
}; |
else |
DEBUGmsgs["PLAYER_LOGOUT"] = { |
tostring(GetTime()).. ": PLAYER_LOGOUT: START", |
tostring(GetTime()).. ": DEBUGmsgs.PLAYER_LOGOUT cleared.", |
}; |
end |
-- Bring everything up to date |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Update some variables\' values: START"); |
charLevel = UnitLevel("player"); |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": charLevel's value = ".. tostring(charLevel)); |
updateGeneralTabMetadata = true; |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": updateGeneralTabMetadata's value = ".. tostring(updateGeneralTabMetadata)); |
updateClassMetadata = true; |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": updateClassMetadata's value = ".. tostring(updateClassMetadata)); |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Update some variables\' values: END"); |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Update Metadata: START"); |
updateGeneralTabMetadata_func(curLocale, gameBuild, charLevel); |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Updated GeneralTab Metadata."); |
updateClassMetadata_func(curLocale, gameBuild, charLevel); |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Updated ".. universalClassName.. " Metadata."); |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Update Metadata: END"); |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Update Spellbook spells: START"); |
updateSpellbookSpells_func(ClassNumSpecs, ClassSpecNames2IDs); |
if SN2SID_table[universalClassName].Pets or SN2SID_PASSIVES_table[universalClassName].Pets |
or UnitExists("pet") then |
updatePetSpellNames(); |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Updated Pet spells."); |
else |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": NO Pet Spells to get."); |
end |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Update Spellbook spells: END"); |
-- "Manually" add spells we cannot (or is not convenient to) get automatically |
-- REENABLE THIS AFTER TEST: |
addSpellsPostUpdate(); |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Added hardcoded spells to General and Class tables."); |
-- Copy our local tables to the global saved-variables tables -- |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Copy session\'s Active and Passive Spells' tables to SavedVariables: START"); |
if AddonEnv.SpellNamesAndIDs then |
AddonEnv.SpellNamesAndIDs = SN2SID_table; |
else |
SpellNamesAndIDs = SN2SID_table; |
end |
if AddonEnv.SpellNamesAndIDs_PASSIVES then |
AddonEnv.SpellNamesAndIDs_PASSIVES = SN2SID_PASSIVES_table; |
else |
SpellNamesAndIDs_PASSIVES = SN2SID_PASSIVES_table; |
end |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Copy session\'s Active and Passive Spells' tables to SavedVariables: END"); |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Copy the DEBUG messages to SavedVariables: START"); |
if AddonEnv.DEBUG_messages then |
AddonEnv.DEBUG_messages = DEBUGmsgs; |
else |
DEBUG_messages = DEBUGmsgs; |
end |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Copy the DEBUG messages to SavedVariables: END"); |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": PLAYER_LOGOUT: END"); |
end |
-- Unregister the event (handler) in which we are now running |
SN2SID_frame:UnregisterEvent("PLAYER_LOGIN"); |
-- Set the post-PLAYER_LOGIN event-handlers and Register the respective events |
SN2SID_frame:SetScript("OnEvent", function(self, event, ...) |
SN2SID_events[event](self, ...); |
end); |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Unregistered Event: PLAYER_LOGIN"); |
for k, v in pairs(SN2SID_events) do |
if k == "UNIT_PET" then |
SN2SID_frame:RegisterUnitEvent("UNIT_PET", "player"); |
else |
SN2SID_frame:RegisterEvent(k); |
end |
-- if SN2SID_frame:IsEventRegistered(k) then |
-- print(AddonName.. ": Registered event: ".. tostring(k)); |
-- end |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Registered Event: ".. k); |
end |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], (GetTime()).. ": PLAYER_LOGIN: END"); |
end |
-- PLAYER_LOGIN event handler; we set up the other events when this one fires -- |
SN2SID_frame:SetScript("OnEvent", function(self, event) |
DBG_CurrentEvent = "PLAYER_LOGIN"; |
DEBUGmsgs = AddonEnv.DEBUG_messages or DEBUG_messages or {}; |
if not DEBUGmsgs then |
DEBUGmsgs = { |
["PLAYER_LOGIN"] = { |
tostring(GetTime()).. ": PLAYER_LOGIN: START", |
tostring(GetTime()).. ": Will startup in 5 seconds time.", |
}, |
}; |
else |
DEBUGmsgs["PLAYER_LOGIN"] = { |
tostring(GetTime()).. ": PLAYER_LOGIN: START", |
tostring(GetTime()).. ": Will startup in 5 seconds time.", |
}; |
end |
C_Timer.After(5, lsn2sidpStartup); |
end); |
## Interface: 80105 |
## Title: LibSpellName2SID-1.1: Populator (DEV) |
## Notes: Get all spells from a character and save them to file. |
## Author: aallkkaa |
## Version: 1.1.03 |
## SavedVariables: SpellNamesAndIDs, SpellNamesAndIDs_PASSIVES, DEBUG_messages |
## DefaultState: disabled |
## X-Category: Development |
LibSpellName2SID-1.1-Populator.lua |
---------- |
local AddonName, AddonEnv = ...; |
-- Local copies of the saved variables' tables: SpellNamesAndIDs and SpellNamesAndIDs_PASSIVES |
local SN2SID_table, SN2SID_PASSIVES_table; |
-- Local copies of the saved variables' tables: SpellNamesAndIDs, SpellNamesAndIDs_PASSIVES and DEBUG_messages |
local SN2SID_table, SN2SID_PASSIVES_table, DEBUGmsgs; |
-- Variables for debugging |
local DBG_CurrentEvent = "" -- Event last fired when a task is being done |
-- WoW Expansion/Patch constants |
local NumberOfTalentTiers = 7; -- Current number of talent tiers - WoW-7.x.y and 8.x.y |
-- local NumberOfPVPTalentTiers = 6; -- Current number of PVP talent tiers - WoW-7.x.y |
}, |
}, |
["HUNTER"] = { |
-- TODO: SPECS -- |
["Beast Mastery"] = { |
["Call Pet"] = 9, |
["Pet Utility"] = 103, |
}, |
["Marksmanship"] = { |
["Call Pet"] = 9, |
["Pet Utility"] = 103, |
}, |
["Survival"] = { |
["Call Pet"] = 9, |
["Pet Utility"] = 103, |
}, |
["FlyoutsTOGET"] = { |
["Call Pet"] = 9, |
["Pet Utility"] = 103, |
}, |
["Pets"] = { |
-- https://www.wowhead.com/battle-for-azeroth-hunter-pet-guide#hunter-pet-family-list-tenacity |
["Ferocity"] = { |
["Talon Rend"] = 263852, |
["Trick"] = 94022, |
}, |
["Blood Beast"] = { -- 8.1 |
["Blood Bolt"] = 288962, |
}, |
["Boar"] = { -- 8.x |
["Bristle"] = 263869, |
}, |
}, |
}, |
["MAGE"] = { |
["Arcane"] = { |
["Polymorph Variants"] = 92, |
}, |
["Fire"] = { |
["Polymorph Variants"] = 92, |
}, |
["Frost"] = { |
["Polymorph Variants"] = 92, |
}, |
["FlyoutsTOGET"] = { |
["Polymorph Variants"] = 92, |
}, |
["Flyouts"] = { |
-- Polymorph Variants are now fetchable (all the ones currently ingame) from the game, |
-- regardless of whether the Mage has them or not (all, some, one or even none). |
["Teleport: Dazar'alor"] = 281404, -- Horde only |
}, |
}, |
-- Get the Pets spell from a high level Frost Mage instead |
--[[ |
["Pets"] = { |
["Water Elemental"] = { -- Frost specialization only |
["Freeze"] = 33395, |
["Waterbolt"] = 31707, |
}, |
}, |
]]-- |
}, |
-- All Rogue Poisons are fetchable from the logged in character. The bellow is no longer needed. |
--[[ |
["ROGUE"] = { |
["Assassination"] = { |
["Poisons"] = 66, |
}, |
["Subtlety"] = { |
["Poisons"] = 66, |
}, |
["Outlaw"] = { |
["Poisons"] = 66, |
}, |
["FlyoutsTOGET"] = { |
["Poisons"] = 66, |
}, |
--[[ |
["Flyouts"] = { |
["Poisons"] = { -- Since WoW 7.0, (I think) Assassintation specialization only. But, at |
-- least on WoW 8.1.5, on the SpellBook of all three specializations. |
["Wound Poison"] = 8679, |
}, |
}, |
]]-- |
}, |
]]-- |
["SHAMAN"] = { |
["Elemental"] = { |
["Bloodlust"] = 2825, -- Horde |
["Heroism"] = 32182, -- Alliance |
["Hex Variants"] = 106, |
}, |
["Enhancement"] = { |
["Bloodlust"] = 2825, -- Horde |
["Heroism"] = 32182, -- Alliance |
["Hex Variants"] = 106, |
}, |
["Restoration"] = { |
["Bloodlust"] = 2825, -- Horde |
["Heroism"] = 32182, -- Alliance |
["Hex Variants"] = 106, |
}, |
-- Hex Variants are now fetchable (all the ones currently ingame) from the game, |
-- regardless of whether the Shaman has them or not (all, some, one or even none). |
-- TODO: Implement a way to fetch the Shaman Hex Variants (as well as the Mage Polymorph |
-- Variants), even if the character does not know any, by using the logic above (and |
-- bellow if needed). |
["FlyoutsTOGET"] = { |
["Hex Variants"] = 106, |
}, |
--[[ |
["Flyouts"] = { |
["Hex Variants"] = { -- Hex variants (including the default "Frog") are all |
}, |
]]-- |
["Pets"] = { -- In WoW 7.x.y, only the Elemental specialization has pets, which are only |
-- controllable if the talent "Primal Elementalist"(5,2) is active (they're |
-- guardians (no spells castable by the player) otherwise). On top of that, |
-- although the Earth Elemental is always available to the Elemental Shaman |
-- , the Fire and Storm elementals are mutually exclusive (Fire Elemental |
-- becomes Storm Elemental if the talent "Storm Elemental" is chosen). |
-- TL;DR: Better make sure the spells bellow are added, rather than going |
-- through the gimmick of swithcing the talents every time we update the |
-- SHAMAN lists of spells. |
-- controllable if the talent "Primal Elementalist"(5,2) is active (they're |
-- guardians (no spells castable by the player) otherwise). On top of that, |
-- although the Earth Elemental is always available to the Elemental Shaman |
-- , the Fire and Storm elementals are mutually exclusive (Fire Elemental |
-- becomes Storm Elemental if the talent "Storm Elemental" is chosen). |
-- TL;DR: Better make sure the spells bellow are added, rather than going |
-- through the gimmick of swithcing the talents every time we update the |
-- SHAMAN lists of spells. |
["Earth Elemental"] = { |
["Angered Earth"] = 36213, -- Taunt |
["Harden Skin"] = 118337, -- -40% damage taken by the Shaman |
}, |
}, |
["WARLOCK"] = { |
["Affliction"] = { |
["Summon Demon"] = 10, |
}, |
["Demonology"] = { |
["Summon Demon"] = 10, |
}, |
["Destruction"] = { |
["Summon Demon"] = 10, |
}, |
["FlyoutsTOGET"] = { |
["Summon Demon"] = 10, |
}, |
["Pets"] = { -- Spells of the glyph-enhanced versions of the regular Warlock Demons. |
-- NB: We're including spells that remain the same on both versions of the |
-- demon. |
---------------------------------------------------------------------------------------------------- |
-- Update the General tab dataSource + raceBuilds -- |
-- local updateGeneralTabMetadata_func = function(SN2SID_table, SN2SID_PASSIVES_table, curLocale, gameBuild, universalRaceName, generalTabName, charLevel) |
-- local updateGeneralTabMetadata_func = function(curLocale, gameBuild, universalRaceName, generalTabName, charLevel) |
-- local updateGeneralTabMetadata_func = function(curLocale, gameBuild, universalRaceName, charLevel) |
local updateGeneralTabMetadata_func = function(curLocale, gameBuild, charLevel) |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updateGeneralTabMetadata_func: START"); |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": Check whether GeneralTab\'s Metadata needs update"); |
if not updateGeneralTabMetadata then |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": GeneralTab\'s Metadata does NOT need update."); |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updateGeneralTabMetadata_func: END"); |
return; |
end |
tinsert(DEBUGmsgs[DBG_CurrentEvent], "GeneralTab\'s Metadata DOES need update."); |
-- print(AddonName.. ": Will now check whether the GeneralTab Metadata needs updating."); |
-- Actively-cast spells |
if charLevel > SN2SID_table[generalTabName].METADATA.dataSource.charLevel then |
updateGeneralSpells = true; |
end |
updateGeneralTabMetadata = false; |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updateGeneralTabMetadata_func: END"); |
end |
-- Update the Class dataSource -- |
-- local updateClassMetadata_func = function(SN2SID_table, SN2SID_PASSIVES_table, curLocale, gameBuild, universalClassName, charLevel) |
-- local updateClassMetadata_func = function(curLocale, gameBuild, universalClassName, charLevel) |
local updateClassMetadata_func = function(curLocale, gameBuild, charLevel) |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updateClassMetadata_func: START"); |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": Check whether ".. universalClassName.. "\'s Metadata needs update."); |
if not updateClassMetadata then |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": ".. universalClassName.. "\'s Metadata does NOT need update."); |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updateClassMetadata_func: END"); |
return; |
end |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": ".. universalClassName.. "\'s Metadata DOES need update."); |
-- print(AddonName.. ": Will now check whether the ".. universalClassName.. " Metadata needs updating."); |
-- Actively-cast spells |
if charLevel > SN2SID_table[universalClassName].METADATA.dataSource.charLevel then |
updateClassSpells = true; |
end |
updateClassMetadata = false; |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updateClassMetadata_func: END"); |
end |
---- Functions to update the lists of Spell Names and their IDs ---- |
-------------------------------------------------------------------- |
-- Update the Talents' lists of spells |
-- local updateTalentSpells_func = function(SN2SID_table, SN2SID_PASSIVES_table, universalClassName, ClassNumSpecs, ClassSpecNames2IDs) |
-- local updateTalentSpells_func = function(universalClassName, ClassNumSpecs, ClassSpecNames2IDs) |
-- Update the PvE Talents' lists of spells |
local updateTalentSpells_func = function(ClassNumSpecs, ClassSpecNames2IDs) |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updateTalentSpells_func: START"); |
if not updateClassSpells then -- Sanity check |
return; |
end |
-- SN2SID_PASSIVES_table[universalClassName][locSpecName.."_Talents"] = {}; |
-- end |
else |
print(AddonName.. ": PVE: NO specialization has been selected for this character!"); |
-- print(AddonName.. ": PVE: NO specialization has been selected for this character!"); |
return; |
end |
-- Populate the "SpecName_Talents" subtables |
-- and then fetch the keys in order from that array-table and then the corresponding values |
-- from another tab le (the original, unordered/unsorted key-value pairs table). |
-- The function from https://wow.gamepedia.com/Orderedpairs gets you the ordered values |
-- form the unordered table in running-time, but cannot be used to change the stored data, |
-- from the unordered table in running-time, but cannot be used to change the stored data, |
-- just like the extract-keys-then-sort-them method above. |
-- Thus, it's not possible to store the data in an easy to visually (or OS-based) diff two |
-- versions of a database, as I wished. |
end |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updateTalentSpells_func: END"); |
end |
-- local updatePVPTalentSpells_func = function(SN2SID_table, SN2SID_PASSIVES_table, universalClassName, ClassNumSpecs, ClassSpecNames2IDs) |
-- local updatePVPTalentSpells_func = function(universalClassName, ClassNumSpecs, ClassSpecNames2IDs) |
-- Update the PvP Talents' lists of spells |
local updatePVPTalentSpells_func = function(ClassNumSpecs, ClassSpecNames2IDs) |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updatePVPTalentSpells_func: START"); |
if not updateClassSpells then -- Sanity check |
return; |
end |
SN2SID_PASSIVES_table[universalClassName][locSpecName.."_PVPTalents"] = {}; |
end |
else |
print(AddonName.. ": PVP: NO specialization has been selected for this character!"); |
-- print(AddonName.. ": PVP: NO specialization has been selected for this character!"); |
return; |
end |
-- Populate the "SpecName_PVPTalents" subtables |
end |
end |
end |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updatePVPTalentSpells_func: END"); |
end |
local armorSkills, weaponSkills; |
-- Helper functions to function updateSpellbookSpells_func() -- |
local addSpellbookSpellToGeneral_func = function(spellName, spellSubName, spellID) |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": addSpellbookSpellToGeneral_func: START"); |
-- Store Passive and Active abilities into their own separate tables |
if IsPassiveSpell(spellID) then |
if spellName == "Armor Skills" then |
-- in our list of hardcoded Zone spells first. Now, we do that test last, as there is at |
-- least one instance of a spell with the same name, but different IDs, that is a Racial |
-- (that we fetch from the server) and also a hardcoded Zone ability: "Light's Judgment". |
if spellSubName and strfind(spellSubName, "Racial") then |
if spellSubName and strfind(spellSubName, "Racial") then |
if not SN2SID_table[generalTabName].Racials[universalRaceName] then |
SN2SID_table[generalTabName].Racials[universalRaceName] = { [spellName] = spellID }; |
else |
SN2SID_table[generalTabName].GuildPerks[spellName] = spellID; |
end |
-- Will now test for the hardcoded ZoneAbilities, to place them in the correct subcategory |
elseif postUpdate_Spells2Add.General.ZoneAbilities[spellName] then |
if not SN2SID_table[generalTabName].ZoneAbilities then |
SN2SID_table[generalTabName].ZoneAbilities = { [spellName] = spellID }; |
else |
SN2SID_table[generalTabName].ZoneAbilities[spellName] = spellID; |
end |
elseif postUpdate_Spells2Add.General.ZoneAbilities[spellName] then |
if not SN2SID_table[generalTabName].ZoneAbilities then |
SN2SID_table[generalTabName].ZoneAbilities = { [spellName] = spellID }; |
else |
SN2SID_table[generalTabName].ZoneAbilities[spellName] = spellID; |
end |
-- All other spells go into the "Others" subcategory |
elseif not SN2SID_table[generalTabName].Others then |
elseif not SN2SID_table[generalTabName].Others then |
SN2SID_table[generalTabName].Others = { [spellName] = spellID }; |
else |
SN2SID_table[generalTabName].Others[spellName] = spellID; |
end |
end |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": addSpellbookSpellToGeneral_func: END"); |
end |
local addPolymorphOrHexFlyoutSpell_func = function(flyoutButton, flyoutSpellName, flyoutSpellSubname, flyoutSpellID) |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": addPolymorphOrHexFlyoutSpell_func: START"); |
local flyoutSpellFullName = flyoutSpellName.. "(".. flyoutSpellSubname.. ")"; |
if not SN2SID_table[universalClassName].Flyouts[flyoutButton][flyoutSpellFullName] |
or SN2SID_table[universalClassName].Flyouts[flyoutButton][flyoutSpellFullName] ~= flyoutSpellID then |
-- print(AddonName.. "Adding flyout spellFullName ".. flyoutSpellFullName.. " = ".. flyoutSpellID); |
SN2SID_table[universalClassName].Flyouts[flyoutButton][flyoutSpellFullName] = flyoutSpellID; |
end |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": addPolymorphOrHexFlyoutSpell_func: END"); |
end |
local addFlyoutSpells_func = function(flyoutButtonName, flyoutButtonID) |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": addFlyoutSpells_func: START"); |
-- print(AddonName.. ": SpellID ".. flyoutButtonID.. " on SpecTab ".. i.. ", Pos ".. ii.. " is a FLYOUT button."); |
-- NB: Creating SN2SID_table[universalClassName].Flyouts either via |
-- SN2SID_table[universalClassName].Flyouts = []; or via |
-- tinsert(SN2SID_table[universalClassName], "Flyouts"); was causing a bug where the same |
-- table would have two "Flyouts" fields: one with the correct values and another empty |
-- (as if it were a simple member of an array). So we create a STUB value if needed and |
-- later remove it when we're done adding the spells. |
if not SN2SID_table[universalClassName].Flyouts then |
SN2SID_table[universalClassName].Flyouts = { ["STUB"] = 0, }; |
end |
if (flyoutButtonName == "Portal") or (flyoutButtonName == "Teleport") then |
-- There are spells with the same Name but different IDs, depending on the |
-- character's faction, when it comes to Portals and Teleports. Hence, for now, |
-- we add them only in Post. TODO: Fetch them here as well, but check that they |
-- are not one of those (known) smae-name, diff-IDs cases (in that case do not add |
-- them here, only in post). |
else |
-- Insert the flyout spell in its proper table |
if not SN2SID_table[universalClassName].Flyouts[flyoutButtonName] then |
-- print(AddonName.. ": Adding Flyouts.".. flyoutButtonName.. " to ".. universalClassName); |
SN2SID_table[universalClassName].Flyouts[flyoutButtonName] = { ["STUB"] = 0, }; |
-- else |
-- print(AddonName.. ": Flyouts.".. flyoutButtonName.. " is already in ".. universalClassName); |
end |
local _, _, numFlyouts, flyoutKnown = GetFlyoutInfo(flyoutButtonID); |
-- print(AddonName.. ": ".. flyoutButtonName.. " | ".. flyoutButtonID.. " | Number of Slots = ".. numFlyouts); |
for flyoutSlot = 1, numFlyouts do |
-- local flyoutSpellID, overrideSpellID, flyoutSlotKnown, slotSpecID = GetFlyoutSlotInfo(flyoutButtonID, flyoutSlot); |
local flyoutSpellID, _, _, _ = GetFlyoutSlotInfo(flyoutButtonID, flyoutSlot); |
local flyoutSpellName, flyoutSpellSubname, _, _, _, _, _ = GetSpellInfo(flyoutSpellID); |
if flyoutButtonName == "Polymorph Variants" or flyoutButtonName == "Hex Variants" then |
-- Mage "Polymorph Variants", and Shaman "Hex Variants", |
-- are all called "Polymorph" or "Hex", respectively. But |
-- they have a subname specifying the variant AND can be |
-- addressed by suffixing the subname in parenthesis, as |
-- in e.g. "Polymorph(Sheep)" or "Hex(Frog)". We'll do just |
-- that and store their names as "name(subname)". |
if (flyoutSpellSubname == nil) or (flyoutSpellSubname == "") then |
-- print(AddonName.. ": ".. tostring(flyoutSpellName).. " = ".. tostring(flyoutSpellID)); |
-- TODO #1: Make a table, LOCAL-TO-FILE, to store |
-- all the delayedFlyoutSpellInfo tables amd name |
-- each one "delayedFlyoutSpellInfo"..flyoutSpellID . |
-- Create an access to the info that will be fetched |
local delayedFlyoutSpellInfo = Spell:CreateFromSpellID(flyoutSpellID); |
-- Actually get the info and use it to update our DB |
delayedFlyoutSpellInfo:ContinueOnSpellLoad(function() |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": delayedFlyoutSpellInfo:ContinueOnSpellLoad: START"); |
-- print(AddonName.. ": Will now get the previously delayed information about flyoutSpellID: ".. flyoutSpellID); |
-- Although we should only need to update spellSubName, we might |
-- have fetched a new spellName + spellID by now. Thus, we'll |
-- update those fields too. |
-- TODO #2: Pass the three |
-- "delayedFlyoutSpellInfo"..flyoutSpellID:Some() |
-- values bellow as arguments to |
-- addPolymorphOrHexFlyoutSpell_func(...) |
flyoutSpellName = delayedFlyoutSpellInfo:GetSpellName(); |
flyoutSpellSubname = delayedFlyoutSpellInfo:GetSpellSubtext(); -- Mandatory |
flyoutSpellID = delayedFlyoutSpellInfo:GetSpellID(); |
addPolymorphOrHexFlyoutSpell_func(flyoutButtonName, flyoutSpellName, flyoutSpellSubname, flyoutSpellID); |
-- TODO #3: Clean up! I.e.: |
-- SaidMasterTable["delayedFlyoutSpellInfo"..flyoutSpellID] = nil; |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": delayedFlyoutSpellInfo:ContinueOnSpellLoad: END"); |
end); |
else |
-- print(AddonName.. ": ".. tostring(flyoutSpellName).. " = ".. tostring(flyoutSpellID)); |
addPolymorphOrHexFlyoutSpell_func(flyoutButtonName, flyoutSpellName, flyoutSpellSubname, flyoutSpellID); |
end |
-- Add the default Plymorph(Sheep) and Hex(Frog) to the spell lists |
if universalClassName == MAGE then |
SN2SID_table.MAGE.Arcane["Polymorph(Sheep)"] = SN2SID_table.MAGE.Arcane["Polymorph"] or nil; |
SN2SID_table.MAGE.Fire["Polymorph(Sheep)"] = SN2SID_table.MAGE.Fire["Polymorph"] or nil; |
SN2SID_table.MAGE.Frost["Polymorph(Sheep)"] = SN2SID_table.MAGE.Frost["Polymorph"] or nil; |
end |
if universalClassName == SHAMAN then |
SN2SID_table.SHAMAN.Elemental["Hex(Frog)"] = SN2SID_table.SHAMAN.Elemental["Hex"] or nil; |
SN2SID_table.SHAMAN.Enhancement["Hex(Frog)"] = SN2SID_table.SHAMAN.Enhancement["Hex"] or nil; |
SN2SID_table.SHAMAN.Restoration["Hex(Frog)"] = SN2SID_table.SHAMAN.Restoration["Hex"] or nil; |
end |
elseif flyoutSpellName and (not SN2SID_table[universalClassName].Flyouts[flyoutButtonName][flyoutSpellName]) |
or flyoutSpellName and (SN2SID_table[universalClassName].Flyouts[flyoutButtonName][flyoutSpellName] ~= flyoutSpellID) then |
-- print(AddonName.. ": ".. tostring(flyoutSpellName).. " = ".. tostring(flyoutSpellID)); |
SN2SID_table[universalClassName].Flyouts[flyoutButtonName][flyoutSpellName] = flyoutSpellID; |
end |
end |
SN2SID_table[universalClassName].Flyouts[flyoutButtonName]["STUB"] = nil; |
end |
-- Get rid of the STUB table member that was added upon its creation |
SN2SID_table[universalClassName].Flyouts["STUB"] = nil; |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": addFlyoutSpells_func: END"); |
end |
-- -- |
-- Update the Spellbook's GeneralTab and ClassTabs lists of spells |
-- local updateSpellbookSpells_func = function(SN2SID_table, SN2SID_PASSIVES_table, generalTabName, universalClassName, ClassNumSpecs, ClassSpecNames2IDs) |
-- local updateSpellbookSpells_func = function(generalTabName, universalClassName, ClassNumSpecs, ClassSpecNames2IDs) |
-- local updateSpellbookSpells_func = function(universalClassName, ClassNumSpecs, ClassSpecNames2IDs) |
local updateSpellbookSpells_func = function(ClassNumSpecs, ClassSpecNames2IDs) |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updateSpellbookSpells_func: START"); |
-- "Armor Skills" and "Weapon Skills" are found on the Spellbook's General tab, but are indeed |
-- different from one class to the other. Therefore, we'll save them into local variables upon |
-- fetching the General tab spells and then insert them into the Class Specialisations' tables. |
-- General tab spells |
-- if updateGeneralSpells then -- In current addon version, always true |
-- local _, universalRaceName = UnitRace("player"); |
local stubVal; |
stubVal, universalRaceName = UnitRace("player"); |
if not SN2SID_table[generalTabName].Racials then |
if not SN2SID_PASSIVES_table[generalTabName].Others then |
SN2SID_PASSIVES_table[generalTabName].Others = {}; |
end |
-- local generalTabName, _, offset, numEntries, _, _, _ = GetSpellTabInfo(1); |
generalTabName, _, offset, numEntries, _, _, _ = GetSpellTabInfo(1); |
-- name, texture, offset, numEntries, isGuild, offspecID = GetSpellTabInfo(tabIndex) |
for i = offset +1, offset +numEntries do |
local spellName, spellSubName = GetSpellBookItemName(i, BOOKTYPE_SPELL); |
if spellName then |
local _, spellID = GetSpellBookItemInfo(i, BOOKTYPE_SPELL); |
-- NEW for 1.0.14 -- |
if (spellSubName == nil) or (spellSubName == "") then |
local delayedSpellInfo = Spell:CreateFromSpellID(spellID); |
-- I presume we don't actually need to cancel the request for the additional |
-- end); |
-- Actually get the information and use it to update our database: |
delayedSpellInfo:ContinueOnSpellLoad(function() |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": delayedSpellInfo:ContinueOnSpellLoad: START"); |
-- print(AddonName.. ": Will now get the previously delayed information about spell ID: ".. spellID); |
-- Although we should only need to update spellSubName, we might |
-- have fetched a new spellName + spellID by now. Thus, we'll |
-- Now cancel the request: |
-- spellDataLoadedCancelFunc(); |
-- spellDataLoadedCancelFunc = nil; -- for safety! |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": delayedSpellInfo:ContinueOnSpellLoad: END"); |
end); |
--[[ |
local spellDataLoadedCancelFunc = delayedSpellInfo:ContinueWithCancelOnSpellLoad(function() |
-- If it's a Flyout type of button (e.g. Mage Polymorph variants, Hunter Pet |
-- Utility spells, etc), then fetch the spells that ... fly out. |
if spellType == "FLYOUT" then |
addFlyoutSpells_func(spellName, spellID); |
--[[ |
-- print(AddonName.. ": SpellID ".. spellID.. " on SpecTab ".. i.. ", Pos ".. ii.. " is a FLYOUT button."); |
-- NB: Creating SN2SID_table[universalClassName].Flyouts either via |
-- SN2SID_table[universalClassName].Flyouts = []; or via |
end |
-- Get rid of the STUB table member that was added upon its creation |
SN2SID_table[universalClassName].Flyouts["STUB"] = nil; |
]]-- |
end |
end |
end |
end |
updateClassSpells = false; |
-- end |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updateSpellbookSpells_func: END"); |
end |
-- which names would be the tokens (string) above? |
-- Add one Pet Spell to the apropriate subtable |
-- local addSpellbookPetSpell_func = function(spellName, spellSubName, spellID, petFamily) |
local addSpellbookPetSpell_func = function(spellName, spellSubName, spellID) |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": addSpellbookPetSpell_func: START"); |
local isPassive = IsPassiveSpell(spellID); |
if strfind(spellSubName, "Special") or strfind(spellSubName, "Bonus") or strfind(spellSubName, "Exotic") then -- Pet Family ability |
if isPassive then |
end |
end |
end |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": addSpellbookPetSpell_func: END"); |
end |
-- Pet Spells update function |
-- local updatePetSpellNames = function(SN2SID_table, SN2SID_PASSIVES_table, universalClassName) |
local updatePetSpellNames = function() |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updatePetSpellNames: START"); |
-- print(AddonName.. ": Fetching Pet spells"); |
-- local petHasSpellsConfirmed = false; |
-- NOTES: |
-- end); |
-- Actually get the information and use it to update our database: |
delayedSpellInfo:ContinueOnSpellLoad(function() |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": delayedSpellInfo: START"); |
-- print(AddonName.. ": Will now get the previously delayed information about spell ID: ".. spellID); |
-- Although we should only need to update spellSubName, we might |
-- have fetched a new spellName + spellID by now. Thus, we'll |
-- Now cancel the request: |
-- spellDataLoadedCancelFunc(); |
-- spellDataLoadedCancelFunc = nil; -- for safety! |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": delayedSpellInfo: END"); |
end); |
else |
addSpellbookPetSpell_func(spellName, spellSubName, spellID); |
-- petHasSpellsConfirmed = true; |
end |
-- print(AddonName.. ": Fetched? ".. tostring(petHasSpellsConfirmed)); |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updatePetSpellNames: END"); |
end |
-- local addSpellsPostUpdate = function(SN2SID_table, SN2SID_PASSIVES_table, generalTabName, universalClassName) |
-- local addSpellsPostUpdate = function(SN2SID_table, SN2SID_PASSIVES_table) |
local addSpellsPostUpdate = function() |
-- Sanity check |
if (postUpdate_Spells2Add ~= nil) and (SN2SID_table ~= nil) then |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": addSpellsPostUpdate: START"); |
if postUpdate_Spells2Add and SN2SID_table then -- Sanity check |
for key, value in pairs(postUpdate_Spells2Add) do |
-- if SN2SID_table[key] == nil then -- Sanity check, key == "General" OR universalClassName |
if not SN2SID_table[key] then -- Sanity check, key == "General" OR universalClassName |
-- print(AddonName.. ": Adding: ".. tostring(value)); |
SN2SID_table[key] = value |
elseif type(value) == "table" then -- Should always be 'true' i.e. always either |
-- specName(..somethingMaybe) OR "Flyouts" OR |
-- "Pets" OR someGeneralTabCategory. |
if key == "General" or key == universalClassName then -- Only add hardcoded spells for |
-- GeneralTab or Current Class |
for keyk, valuev in pairs(value) do |
-- if SN2SID_table[key][keyk] == nil then -- specName(..somethingMaybe) OR |
if not SN2SID_table[key][keyk] then -- specName(..somethingMaybe) OR |
-- "Flyouts" OR "Pets" OR |
-- someGeneralTabCategory. |
if keyk == "FlyoutsTOGET" then |
-- print(AddonName.. ": Will get flyout spells for FlyoutButtonName ".. keykk.. " with ID ".. valuevv); |
-- addFlyoutSpells_func(keyk, valuev); |
for keykk, valuevv in pairs(valuev) do |
addFlyoutSpells_func(keykk, valuevv); |
end |
elseif not SN2SID_table[key][keyk] then -- specName(..somethingMaybe) |
-- OR "FlyoutsTOGET" OR |
-- "Flyouts" OR "Pets" OR |
-- someGeneralTabCategory. |
-- print(AddonName.. ": Adding: ".. tostring(valuev)); |
SN2SID_table[key][keyk] = valuev; |
elseif type(valuev) == "table" then -- |
-- |
elseif type(valuev) == "table" then |
for keykk, valuevv in pairs(valuev) do |
-- if SN2SID_table[key][keyk][keykk] == nil then -- Spell OR Flyouts_spell OR |
if not SN2SID_table[key][keyk][keykk] then -- Spell OR Flyouts_spell OR |
-- PetFamily is not on the |
-- target table yet |
if not SN2SID_table[key][keyk][keykk] then -- Spell OR Flyouts_spell OR |
-- PetFamily is not on the |
-- target table yet |
-- print(AddonName.. ": Adding: ".. tostring(valuevv)); |
SN2SID_table[key][keyk][keykk] = valuevv; |
end |
if type(valuevv) == "table" then -- Flyouts_spell OR PetFamily |
for keykkk, valuevvv in pairs(valuevv) do |
-- if SN2SID_table[key][keyk][keykk][keykkk] == nil then -- Flyouts_spell_Spell OR |
if not SN2SID_table[key][keyk][keykk][keykkk] then -- Flyouts_spell_Spell OR |
-- PetFamily_spell is not |
-- on the target table yet |
for keykkk, valuevvv in pairs(valuevv) do |
if not SN2SID_table[key][keyk][keykk][keykkk] then |
-- Flyouts_spell_Spell OR |
-- PetFamily_spell is not |
-- yet on the table. |
-- print(AddonName.. ": Adding: ".. tostring(valuevvv)); |
SN2SID_table[key][keyk][keykk][keykkk] = valuevvv; |
end |
end |
end |
end |
end |
end |
end |
end |
end |
if (postUpdate_Spells2Add_PASSIVES ~= nil) and (SN2SID_PASSIVES_table ~= nil) then |
if postUpdate_Spells2Add_PASSIVES and SN2SID_PASSIVES_table then |
for key, value in pairs(postUpdate_Spells2Add_PASSIVES) do |
-- if SN2SID_PASSIVES_table[key] == nil then -- Sanity check, key == "General" OR universalClassName |
if not SN2SID_PASSIVES_table[key] then -- Sanity check, key == "General" OR universalClassName |
-- print(AddonName.. ": Adding: ".. tostring(value)); |
SN2SID_PASSIVES_table[key] = value; |
elseif type(value) == "table" then -- Should always be 'true' i.e. always either "Spells" |
-- OR specName(..somethingMaybe) OR "Pets" |
if key == "General" or key == universalClassName then -- Only add hardcoded spells for |
-- GeneralTab or Current Class |
for keyk, valuev in pairs(value) do |
-- if SN2SID_PASSIVES_table[key][keyk] == nil then -- "Spells" OR specName(..somethingMaybe) OR |
if not SN2SID_PASSIVES_table[key][keyk] then -- "Spells" OR specName(..somethingMaybe) OR |
end |
end |
end |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": addSpellsPostUpdate: END"); |
end |
-- Function to call upon PLAYER_LOGIN (see bottom of file) |
local lsn2sidpStartup = function() |
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": lsn2sidpStartup: START"); |
-- Startup -- |
print(AddonName.. ": Startup!"); |
-- Copy the global saved-variables tables to our local tables |
-- local SN2SID_table = AddonEnv.SpellNamesAndIDs or SpellNamesAndIDs or {}; |
-- local SN2SID_PASSIVES_table = AddonEnv.SpellNamesAndIDs_PASSIVES or SpellNamesAndIDs_PASSIVES or {}; |
SN2SID_table = AddonEnv.SpellNamesAndIDs or SpellNamesAndIDs or {}; |
SN2SID_PASSIVES_table = AddonEnv.SpellNamesAndIDs_PASSIVES or SpellNamesAndIDs_PASSIVES or {}; |
-- DEBUGmsgs = AddonEnv.DEBUG_messages or DEBUG_messages or {}; |
-- tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Print tables\' tostring to console: START"); |
-- print(AddonName.. ": AddonEnv.SpellNamesAndIDs = ".. tostring(AddonEnv.SpellNamesAndIDs)); -- nil |
-- print(AddonName.. ": AddonEnv.SpellNamesAndIDs_PASSIVES = ".. tostring(AddonEnv.SpellNamesAndIDs_PASSIVES)); -- nil |
-- print(AddonName.. ": AddonEnv.DEBUG_messages = ".. tostring(AddonEnv.DEBUG_messages)); -- nil |
-- print(AddonName.. ": SpellNamesAndIDs = ".. tostring(SpellNamesAndIDs)); -- TableA |
-- print(AddonName.. ": SpellNamesAndIDs_PASSIVES = ".. tostring(SpellNamesAndIDs_PASSIVES)); -- TableB |
-- print(AddonName.. ": DEBUG_messages = ".. tostring(DEBUG_messages)); -- TableB |
-- print(AddonName.. ": SN2SID_table = ".. tostring(SN2SID_table));-- TableA |
-- print(AddonName.. ": SN2SID_PASSIVES_table = ".. tostring(SN2SID_PASSIVES_table)); -- TableB |
-- print(AddonName.. ": DEBUGmsgs = ".. tostring(DEBUGmsgs)); -- TableB |
-- tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Print tables\' tostring to console: END"); |
-- -- Metadata fields: Data source, Class', ... -- -- |
-- Data source -- |
-- We're only interested in storing the English names, at least for now |
local curLocale = GetLocale(); |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Got: curLocale = ".. curLocale); |
if ( curLocale ~= "enUS") then |
SN2SID_frame:UnregisterAllEvents(); |
error(AddonName.. " only retrieves data from English (enUS or enGB) clients."); |
return; |
-- return; |
end |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Validated: curLocale"); |
local stubVal; |
stubVal, universalRaceName = UnitRace("player"); |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Got: universalRaceName (no validation needed) = ".. universalRaceName); |
-- Self-explanatory: |
local _, gameBuild = GetBuildInfo(); |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Got: gameBuild"); |
-- For some reason, the variable gameBuild is being saved as a string; convert to number: |
gameBuild = tonumber(gameBuild); |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Validated that gameBuild is a number. gameBuild = ".. gameBuild.. ": Done."); |
local charLevel = UnitLevel("player"); |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Got: charLevel (no validation needed) = ".. charLevel); |
-- Spells in the General tab: Racial abilities, etc |
-- local generalTabName = (GetSpellTabInfo(1)); -- Tab#1 = General |
generalTabName = (GetSpellTabInfo(1)); -- Tab#1 = General |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Got: generalTabName (no validation needed) = ".. generalTabName); |
-- Class stuff -- |
-- local universalClassName = select(2, UnitClass("player")); -- Locale-independent Class name |
stubVal, universalClassName = UnitClass("player"); -- Locale-independent Class name |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Got: universalClassName (no validation needed) = ".. universalClassName); |
local ClassNumSpecs = GetNumSpecializations(false, false); -- Number of Specialisations |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Got: ClassNumSpecs (no validation needed) = ".. ClassNumSpecs); |
-- Ordered list of Class specs' IDs and Names -- Do we still use this? |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Order list of Class specs' IDs and Names: START"); |
local specID, specName = GetSpecializationInfo(1); |
local ClassSpecNames2IDs = {}; |
for i = 1, ClassNumSpecs do |
local specID, specName = GetSpecializationInfo(i); |
ClassSpecNames2IDs[specName] = specID; |
end |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Order list of Class specs' IDs and Names: END"); |
---- Check the tables' skeleton structure and build whatever may be missing ---- |
-- |
if not SN2SID_table then -- sanity check |
error(AddonName.. "Local copy of saved variables is missing."); |
return; |
-- return; |
end |
if not SN2SID_PASSIVES_table then -- sanity check |
error(AddonName.. "Local copy of saved variables is missing."); |
return; |
-- return; |
end |
-- |
-- If needed, create and populate the Metadata subtables; -- |
-- NB: We separate the two types of tables in two if-loops for the sake of sanity-keep (against |
-- e.g. manual edits to the file). |
if not SN2SID_table[generalTabName] then |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Create the ".. generalTabName.. " dataSource for Active spells: START"); |
print(AddonName.. ": Will now create the ".. generalTabName.. " dataSource for Active spells."); |
SN2SID_table[generalTabName] = {}; |
-- SN2SID_table[generalTabName].Spells = {}; |
SN2SID_table[generalTabName].METADATA = {}; |
SN2SID_table[generalTabName].METADATA.dataSource = { |
clientLocale = curLocale, -- Currently always enUS |
-- We've just created and populated the GeneralTabMetadata, hence no need to update |
updateGeneralTabMetadata = false; |
updateGeneralSpells = true; -- Do populate the actual list of spells |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Create the ".. generalTabName.. " dataSource for Active spells: END"); |
else |
updateGeneralTabMetadata = true; -- Will check whether it's updated; if not, will update; |
-- The function which checks above var will also flag for Spells-list update if needed. |
end |
if not SN2SID_PASSIVES_table[generalTabName] then |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Create the ".. generalTabName.. " dataSource for Passive spells: START"); |
print(AddonName.. ": Will now create the ".. generalTabName.. " dataSource for Passive spells."); |
SN2SID_PASSIVES_table[generalTabName] = {}; |
-- SN2SID_PASSIVES_table[generalTabName].Spells = {}; |
SN2SID_PASSIVES_table[generalTabName].METADATA = {}; |
SN2SID_PASSIVES_table[generalTabName].METADATA.dataSource = { |
clientLocale = curLocale, -- Currently always enUS |
}; |
SN2SID_PASSIVES_table[generalTabName].METADATA.raceBuilds = { [universalRaceName] = gamebuild }; |
-- We've just created and populated the GeneralTabMetadata, hence no need to update ... |
if not updateGeneralTabMetadata then -- ... unless it's needed for the Active spells |
updateGeneralTabMetadata = false; -- And this seems redundant. Keep it 'cause I'll forget it otherwise... |
end |
updateGeneralTabMetadata = false; -- And this seems redundant. Keep it 'cause I'll forget it otherwise... |
updateGeneralSpells = true; -- Do populate the actual list of spells |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Create the ".. generalTabName.. " dataSource for Passive spells: END"); |
else |
updateGeneralTabMetadata = true; -- Will check whether it's updated, if not will update; |
-- The function which checks above var will also flag for Spells-list update if needed. |
end |
-- Run the update function (does both Active and Passive trees), delayed |
-- updateGeneralTabMetadata_func(SN2SID_table, SN2SID_PASSIVES_table, curLocale, gameBuild, universalRaceName, generalTabName, charLevel); |
-- updateGeneralTabMetadata_func(curLocale, gameBuild, universalRaceName, generalTabName, charLevel); |
-- updateGeneralTabMetadata_func(curLocale, gameBuild, universalRaceName, charLevel); |
-- Run the update function (does both Active and Passive trees) |
updateGeneralTabMetadata_func(curLocale, gameBuild, charLevel); |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Updated the ".. generalTabName.. " Metadata \(or not\!\) for both Active and Passive spells."); |
-- Class spells' Metadata (dataSource only; class Specs will be handled afterwards) |
if not SN2SID_table[universalClassName] then |
SN2SID_table[universalClassName] = {}; |
else |
updateClassMetadata = true; -- Will check whether it's updated and if not, will update; |
-- The function which checks above var will also flag for Spells-list update if needed. |
-- The function which checks above var will also flag for Spells-list update if needed. |
end |
if not SN2SID_table[universalClassName].METADATA then |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Create the ".. universalClassName.. " dataSource for Active spells: START"); |
SN2SID_table[universalClassName].METADATA = {}; |
SN2SID_table[universalClassName].METADATA.dataSource = { |
clientLocale = curLocale, -- Currently always enUS |
-- Class Specs fields are updated in another if-clause, further ahead. |
updateClassMetadata = false; |
updateClassSpells = true; -- Do populate the actual list of spells. |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Create the ".. universalClassName.. " dataSource for Active spells: END"); |
else |
updateClassMetadata = true; -- Will check whether it's updated and if not, will update; |
-- The function which checks above var will also flag for Spells-list update if needed. |
end |
if not SN2SID_PASSIVES_table[universalClassName] then |
print(AddonName.. ": Will now create the ".. universalClassName.. "'s table and dataSource for Passive spells."); |
SN2SID_PASSIVES_table[universalClassName] = {}; |
SN2SID_PASSIVES_table[universalClassName].METADATA = {}; |
SN2SID_PASSIVES_table[universalClassName].METADATA.dataSource = { |
clientLocale = curLocale, -- Currently always enUS |
gameBuild = gameBuild, |
charLevel = charLevel, |
charMaxLevel = charLevel, |
}; |
if not updateClassMetadata then -- See above, in the Actives snippet |
updateClassMetadata = false; |
end |
updateClassSpells = true; -- Do populate the actual list of spells. |
else |
updateClassMetadata = true; |
-- The function which checks above var will also flag for Spells-list update if needed. |
end |
if not SN2SID_PASSIVES_table[universalClassName].METADATA then |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Create the ".. universalClassName.. " dataSource for Passive spells: START"); |
SN2SID_PASSIVES_table[universalClassName].METADATA = {}; |
SN2SID_PASSIVES_table[universalClassName].METADATA.dataSource = { |
clientLocale = curLocale, -- Currently always enUS |
-- Class Specs fields are updated in another if-clause, further ahead. |
updateClassMetadata = false; |
updateClassSpells = true; -- Do populate the actual list of spells. |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Create the ".. universalClassName.. " dataSource for Passive spells: END"); |
else |
updateClassMetadata = true; -- Will check whether it's updated and if not, will update; |
-- The function which checks above var will also flag for Spells-list update if needed. |
-- updateClassMetadata_func(SN2SID_table, SN2SID_PASSIVES_table, curLocale, gameBuild, universalClassName, charLevel); |
-- updateClassMetadata_func(curLocale, gameBuild, universalClassName, charLevel); |
updateClassMetadata_func(curLocale, gameBuild, charLevel); |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Ran updateClassMetadata_func()."); |
-- If needed, create and populate Class Specs' Active and Passive Spells -- |
-- Flag spell-lists for update if applicable -- |
if not SN2SID_table[universalClassName].METADATA.Specs then |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Create the ".. universalClassName.. " \'Specs\' (Actives) tables: START"); |
print(AddonName.. ": Will now create the ".. universalClassName.. "'s \'Specs\' (Actives) tables."); |
for i = 1, ClassNumSpecs do |
local specID, specName = GetSpecializationInfo(i); |
end |
end |
updateClassSpells = true; -- Do populate the actual list of spells. |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Create the ".. universalClassName.. " \'Specs\' (Actives) tables: END"); |
end |
if not SN2SID_PASSIVES_table[universalClassName].METADATA.Specs then |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Create the ".. universalClassName.. " \'Specs\' (Passives) tables: START"); |
print(AddonName.. ": Will now create the ".. universalClassName.. "'s \'Specs\' (Passives) tables."); |
for i = 1, ClassNumSpecs do |
local specID, specName = GetSpecializationInfo(i); |
end |
end |
updateClassSpells = true; -- Do populate the actual list of spells. |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Create the ".. universalClassName.. " \'Specs\' (Passives) tables: END"); |
end |
-- Update General (always ATM) and Class SpellNames2SIDs (both Actives and Passives) -- |
--------------------------------- |
function SN2SID_events:PLAYER_TALENT_UPDATE(self) |
DBG_CurrentEvent = "PLAYER_TALENT_UPDATE"; |
DEBUGmsgs["PLAYER_TALENT_UPDATE"] = { tostring(GetTime()).. ": PLAYER_TALENT_UPDATE: START", } |
-- updateGeneralSpells = true; -- unneeded, placeholder for future version |
updateClassSpells = true; |
-- updateSpellbookSpells_func(SN2SID_table, SN2SID_PASSIVES_table, generalTabName, universalClassName, ClassNumSpecs, ClassSpecNames2IDs); |
-- updateSpellbookSpells_func(generalTabName, universalClassName, ClassNumSpecs, ClassSpecNames2IDs); |
-- updateSpellbookSpells_func(universalClassName, ClassNumSpecs, ClassSpecNames2IDs); |
updateSpellbookSpells_func(ClassNumSpecs, ClassSpecNames2IDs); |
tinsert(DEBUGmsgs["PLAYER_TALENT_UPDATE"], tostring(GetTime()).. ": PLAYER_TALENT_UPDATE: END"); |
end |
function SN2SID_events:PLAYER_LEVEL_UP(self, ...) |
DBG_CurrentEvent = "PLAYER_LEVEL_UP"; |
DEBUGmsgs["PLAYER_LEVEL_UP"] = { tostring(GetTime()).. ": PLAYER_LEVEL_UP: START", } |
-- UnitLevel("player") doesn't update its result soon enough to have it indicate the *new* |
-- char level in response to this event. OTH, this event does provide arguments but, |
-- whatever they are, they're NOT the new char leve, for sure. Might be best to just flag |
updateClassMetadata_func(curLocale, gameBuild, charLevel); |
updateGeneralTabMetadata = true; -- Maybe useful. |
updateClassMetadata = true; -- Stuff like talents only become available at level 10. |
tinsert(DEBUGmsgs["PLAYER_LEVEL_UP"], tostring(GetTime()).. ": PLAYER_LEVEL_UP: END"); |
end |
-- Update pets' existence and spells when one comes up for "player" |
if (not arg1) or (arg1 ~= "player") then |
return; |
end |
DBG_CurrentEvent = "UNIT_PET"; |
DEBUGmsgs["UNIT_PET"] = { tostring(GetTime()).. ": UNIT_PET: START", } |
if not SN2SID_table[universalClassName].Pets then |
SN2SID_table[universalClassName].Pets = {}; |
end |
-- updatePetSpellNames(SN2SID_table, SN2SID_PASSIVES_table, universalClassName); |
-- updatePetSpellNames(universalClassName); |
updatePetSpellNames(); |
tinsert(DEBUGmsgs["UNIT_PET"], tostring(GetTime()).. ": UNIT_PET: END"); |
end |
-- WoW 8.0.1: PET_SPECIALIZATION_CHANGED doesn't seem to be firing anymore |
--[[ |
-- Switch Hunter pet's specialisation |
-- function SN2SID_events:PET_SPECIALIZATION_CHANGED(self, ...) |
function SN2SID_events:PET_SPECIALIZATION_CHANGED(...) |
local arg1 = ...; |
print(AddonName.. ": PET_SPECIALIZATION_CHANGED fired with arg1 = ".. tostring(arg1)); |
if arg1 and arg1 ~= "player" then |
return; |
function SN2SID_events:PLAYER_LOGOUT(self) |
DBG_CurrentEvent = "PLAYER_LOGOUT"; |
-- Set up DEBUG = { LOGOUT = {} } subtable of messages |
if not DEBUGmsgs["PLAYER_LOGOUT"] then |
DEBUGmsgs["PLAYER_LOGOUT"] = { |
tostring(GetTime()).. ": PLAYER_LOGOUT: START", |
tostring(GetTime()).. ": DEBUGmsgs.PLAYER_LOGOUT created.", |
}; |
else |
DEBUGmsgs["PLAYER_LOGOUT"] = { |
tostring(GetTime()).. ": PLAYER_LOGOUT: START", |
tostring(GetTime()).. ": DEBUGmsgs.PLAYER_LOGOUT cleared.", |
}; |
end |
if not SN2SID_table[universalClassName].Pets then |
SN2SID_table[universalClassName].Pets = {}; |
end |
-- updatePetSpellNames(SN2SID_table, SN2SID_PASSIVES_table, universalClassName); |
-- updatePetSpellNames(universalClassName); |
updatePetSpellNames(); |
end |
]]-- |
function SN2SID_events:PLAYER_LOGOUT(self) |
-- Bring everything up to date |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Update some variables\' values: START"); |
charLevel = UnitLevel("player"); |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": charLevel's value = ".. tostring(charLevel)); |
updateGeneralTabMetadata = true; |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": updateGeneralTabMetadata's value = ".. tostring(updateGeneralTabMetadata)); |
updateClassMetadata = true; |
-- updateGeneralTabMetadata_func(SN2SID_table, SN2SID_PASSIVES_table, curLocale, gameBuild, universalRaceName, generalTabName, charLevel); |
-- updateClassMetadata_func(SN2SID_table, SN2SID_PASSIVES_table, curLocale, gameBuild, universalClassName, charLevel); |
-- updateSpellbookSpells_func(SN2SID_table, SN2SID_PASSIVES_table, generalTabName, universalClassName, ClassNumSpecs, ClassSpecNames2IDs); |
-- updateGeneralTabMetadata_func(curLocale, gameBuild, universalRaceName, generalTabName, charLevel); |
-- updateGeneralTabMetadata_func(curLocale, gameBuild, universalRaceName, charLevel); |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": updateClassMetadata's value = ".. tostring(updateClassMetadata)); |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Update some variables\' values: END"); |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Update Metadata: START"); |
updateGeneralTabMetadata_func(curLocale, gameBuild, charLevel); |
-- updateClassMetadata_func(curLocale, gameBuild, universalClassName, charLevel); |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Updated GeneralTab Metadata."); |
updateClassMetadata_func(curLocale, gameBuild, charLevel); |
-- updateSpellbookSpells_func(generalTabName, universalClassName, ClassNumSpecs, ClassSpecNames2IDs); |
-- updateSpellbookSpells_func(universalClassName, ClassNumSpecs, ClassSpecNames2IDs); |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Updated ".. universalClassName.. " Metadata."); |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Update Metadata: END"); |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Update Spellbook spells: START"); |
updateSpellbookSpells_func(ClassNumSpecs, ClassSpecNames2IDs); |
-- NB: UNIT_PET fires upon summoning new pets; but NOT upon switching Hunters' Pet-Specs. |
if SN2SID_table[universalClassName].Pets or SN2SID_PASSIVES_table[universalClassName].Pets |
or UnitExists("pet") then |
-- updatePetSpellNames(SN2SID_table, SN2SID_PASSIVES_table, universalClassName); |
-- updatePetSpellNames(universalClassName); |
updatePetSpellNames(); |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Updated Pet spells."); |
else |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": NO Pet Spells to get."); |
end |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Update Spellbook spells: END"); |
-- "Manually" add spells we cannot (or is not convenient to) get automatically |
-- REENABLE THIS AFTER TEST: |
addSpellsPostUpdate(); |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Added hardcoded spells to General and Class tables."); |
-- Copy our local tables to the global saved-variables tables -- |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Copy session\'s Active and Passive Spells' tables to SavedVariables: START"); |
if AddonEnv.SpellNamesAndIDs then |
AddonEnv.SpellNamesAndIDs = SN2SID_table; |
else |
else |
SpellNamesAndIDs_PASSIVES = SN2SID_PASSIVES_table; |
end |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Copy session\'s Active and Passive Spells' tables to SavedVariables: END"); |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Copy the DEBUG messages to SavedVariables: START"); |
if AddonEnv.DEBUG_messages then |
AddonEnv.DEBUG_messages = DEBUGmsgs; |
else |
DEBUG_messages = DEBUGmsgs; |
end |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Copy the DEBUG messages to SavedVariables: END"); |
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": PLAYER_LOGOUT: END"); |
end |
-- Unregister the event (handler) in which we are now running |
SN2SID_frame:SetScript("OnEvent", function(self, event, ...) |
SN2SID_events[event](self, ...); |
end); |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Unregistered Event: PLAYER_LOGIN"); |
for k, v in pairs(SN2SID_events) do |
if k == "UNIT_PET" then |
SN2SID_frame:RegisterUnitEvent("UNIT_PET", "player"); |
-- if SN2SID_frame:IsEventRegistered(k) then |
-- print(AddonName.. ": Registered event: ".. tostring(k)); |
-- end |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], tostring(GetTime()).. ": Registered Event: ".. k); |
end |
tinsert(DEBUGmsgs["PLAYER_LOGIN"], (GetTime()).. ": PLAYER_LOGIN: END"); |
end |
-- PLAYER_LOGIN event handler; we set up the other events when this one fires -- |
SN2SID_frame:SetScript("OnEvent", function(self, event) |
C_Timer.After(3, lsn2sidpStartup); |
DBG_CurrentEvent = "PLAYER_LOGIN"; |
DEBUGmsgs = AddonEnv.DEBUG_messages or DEBUG_messages or {}; |
if not DEBUGmsgs then |
DEBUGmsgs = { |
["PLAYER_LOGIN"] = { |
tostring(GetTime()).. ": PLAYER_LOGIN: START", |
tostring(GetTime()).. ": Will startup in 5 seconds time.", |
}, |
}; |
else |
DEBUGmsgs["PLAYER_LOGIN"] = { |
tostring(GetTime()).. ": PLAYER_LOGIN: START", |
tostring(GetTime()).. ": Will startup in 5 seconds time.", |
}; |
end |
C_Timer.After(5, lsn2sidpStartup); |
end); |
## Title: LibSpellName2SID-1.1: Populator (DEV) |
## Notes: Get all spells from a character and save them to file. |
## Author: aallkkaa |
## Version: 1.1.01 |
## SavedVariables: SpellNamesAndIDs, SpellNamesAndIDs_PASSIVES |
## Version: 1.1.03 |
## SavedVariables: SpellNamesAndIDs, SpellNamesAndIDs_PASSIVES, DEBUG_messages |
## DefaultState: disabled |
## X-Category: Development |